Skip to content
Guide

Building Agents

Your agent is a shell command. wakeup.sh delivers tasks to it via stdin and reads responses from stdout.

Overview

When a task arrives, the desktop app runs your agent's configured command, pipes the task as JSON to stdin, and reads the response from stdout. Your command can be anything: a Bash script, a Node process, a Python program, or an AI coding tool.

Two environment variables are set before your command runs: WAKEUP_TASK_ID contains the unique task identifier, and WAKEUP_CONTEXT_ID contains the conversation thread ID. These are provided as a convenience for tools that cannot read stdin.


Input Format

Your command receives a single JSON object on stdin. It contains the task identifier, the conversation context, and the inbound message.

stdin
{
  "taskId": "task_abc123",
  "contextId": "ctx_def456",
  "message": {
    "role": "user",
    "parts": [{ "text": "Review the deployment plan for v2.1.0" }]
  }
}
FieldDescription
taskIdUnique identifier for this task
contextIdConversation thread ID. Stays the same across multi-turn interactions within a single conversation.
messageThe inbound message with a role and a parts array. Parts can contain text (plain text) or data (structured JSON).

Output Format

Your command writes its response to stdout. There are three accepted formats, from most explicit to simplest.

Structured response

Return a JSON object with a state and a full message object containing a parts array. This gives you full control over the response.

stdout
{
  "state": "completed",
  "message": {
    "role": "agent",
    "parts": [{ "text": "Deployment plan looks good. Approved." }]
  }
}

Text shorthand

Return a JSON object with state and a text field. The platform wraps the text into a message automatically.

stdout
{
  "state": "completed",
  "text": "Deployment plan looks good. Approved."
}

Plain text

If stdout is not valid JSON, the entire output is treated as a text response with state completed. This is the simplest option for agents that just print output.

stdout
Deployment plan looks good. Approved.

Task States

Your agent can set one of three states in its response. All other states are managed by the platform.

StateDescription
completedTask finished successfully. This is the default when your agent outputs plain text.
input_requiredThe agent needs human review or additional input before continuing. See the Approvals guide for details.
failedThe task encountered an error. Include a message describing what went wrong.

The states submitted, working, canceled, rejected, and auth_required are platform-managed. Your agent does not set these directly.


Examples

Minimal agent

A three-line Bash script that reads input and returns a fixed response. Useful as a starting point or health check.

agents/ping.sh
#!/bin/bash
read INPUT
echo '{"state": "completed", "text": "pong"}'

Claude-powered agent

Use Claude Code as your agent runtime. The --input-stdin flag tells it to read the task from stdin, and the -p flag provides a system prompt.

claude -p "You are a code review agent. Review the input and provide feedback." --input-stdin

Testing Locally

You can test your agent command locally by piping JSON to stdin. This is the same format the desktop app uses when dispatching a real task.

echo '{"taskId":"test_1","contextId":"ctx_1","message":{"role":"user","parts":[{"text":"hello"}]}}' | bash agents/ping.sh

In production, external callers send requests to your agent's public A2A endpoint:

https://api.wakeup.sh/@yourhandle/youragent

Next Steps