WendyOS Docs

Persistent agents and A2A

Run Wendy agents independently of chat and wake them with tasks or sensor events.

Persistent agents and A2A

wendy agent serve hosts a durable task queue for one agent. Run multiple service instances with separate configurations, ports, and state directories for parallel reasoning, perception, control, or fleet work. Each instance has its own profile, model connection, memory, tool policy, and event triggers. Each processes one task at a time and can delegate a bounded batch of local children.

The service can run on a developer computer, VM, or device. workspace refers to the computer hosting the service; device selects the Wendy device its tools connect to. The LLM endpoint can be local or hosted independently of that choice. Closing wendy chat does not stop a separately running service.

Start a service

Generate a configuration, then replace the model ID with one served by your endpoint:

wendy agent example > agent.json

workspace resolves relative to the configuration file. The example has an empty allow_tools list. Reads and memory saves can run; mutations require an exact entry in allow_tools. For example, allowing container_exec grants execution inside device containers. It is a broad capability, including whatever the container's OS permissions permit. Tool policies are not OS sandboxes.

Keep the access token in the environment. For a local shell:

export WENDY_AGENT_TOKEN="$(openssl rand -hex 32)"
wendy agent serve --config ./agent.json --state-dir ./agent-state

In a second terminal with the same token:

wendy agent send --prompt "Inspect current device health" --wait
wendy agent tasks
wendy agent get --task TASK_ID
wendy agent cancel --task TASK_ID

The service requires a token even on loopback. The default listener is 127.0.0.1:8787. Remote listeners require --tls-cert and --tls-key; set --public-url to the reachable HTTPS base URL. Alternatively, use an SSH or Wendy tunnel to the loopback listener, or a TLS reverse proxy. Authentication uses Authorization: Bearer TOKEN. All authenticated callers share this service's task namespace and tool authority. Use separate service instances and credentials for separate trust boundaries.

Durable tasks and event triggers

The service writes each accepted task before acknowledging it. Queued tasks resume after a restart. Tasks that were working when the process died become failed with an instruction to inspect effects before retrying. This prevents automatic repetition of a possibly completed device action. It does not provide exactly-once execution of external effects.

Cancellation requests stop active model and tool work, but cannot undo completed effects. The next task waits until the canceled worker returns. Queued sensor events expire before execution if their observations have become stale.

The default task timeout is 600 seconds. task_timeout_seconds accepts 1-3600. At most 64 tasks can be pending. max_tasks controls retained tasks, defaults to 200, and accepts 1-1000. New submissions remove the oldest retained terminal task when needed. The last 4096 message/event receipts suppress duplicate submissions; reusing an ID with different content returns a conflict. Reusing an ID whose retained task has expired also returns a conflict while its receipt remains. Use wendy agent send --request-id ID to reuse a submission ID across client retries. agent_remote requires a stable request_id when sending a task. State belongs to the exact configuration that created it. Use a new state directory when changing configuration, so queued work cannot silently acquire a new model, profile, device, or tool policy.

Sensor workers send observations to POST /events. The example configuration contains this trigger:

{
  "type": "person.detected",
  "source": "front-camera",
  "min_confidence": 0.85,
  "consecutive": 3,
  "max_gap_seconds": 2,
  "cooldown_seconds": 30,
  "max_age_seconds": 10,
  "prompt": "Inspect this observation and report whether assistance is needed."
}

Post an event with a unique ID, source timestamp, and the model's confidence:

wendy agent event --file observation.json
{
  "id": "front-camera-frame-123",
  "type": "person.detected",
  "source": "front-camera",
  "timestamp": "2026-09-16T10:00:00Z",
  "confidence": 0.93,
  "data": {"track_id": 7, "frame_reference": "frame-123.jpg"}
}

Use the actual observation timestamp. Workers must publish low-confidence observations too if they should break a consecutive sequence. A gap longer than max_gap_seconds resets the sequence. Duplicate IDs do not advance it. Stale, future, or out-of-order observations do not trigger reasoning. Threshold state and cooldown survive service restarts. An event below the threshold returns accepted: false with a reason; an accepted event returns its durable task ID.

Continuous camera/audio/LiDAR inference runs in deployed workers. Sensor agents can select pinned models, download them, and configure workers through authorized Wendy/container tools. Confidence thresholds belong to the selected model and application. The agent service does not itself decode live media, allocate GPUs, or implement actuator loops. Device-control agents supervise local motion controllers, which own resource limits, motion arbitration, watchdogs, and stops.

Remote agents through A2A

The service implements the text task operations of the A2A 1.0 HTTP+JSON binding:

EndpointOperation
GET /.well-known/agent-card.jsonPublic discovery card
POST /message:sendSubmit a text task
GET /tasks/{id}Read task status and artifacts
GET /tasksList retained tasks with pagination
POST /tasks/{id}:cancelRequest cancellation

Send A2A-Version: 1.0. Messages use role: "ROLE_USER", messageId, and parts: [{"text": "..."}]. configuration.returnImmediately: true returns the task without waiting. Otherwise the request waits for a terminal result. Tasks use the A2A TASK_STATE_* values and return text artifacts. The implementation supports fresh tasks with optional context IDs, not continuation of an existing task. Context IDs group tasks; they do not restore conversation transcripts. Streaming, push notifications, binary parts, JSON-RPC, and extended cards are not supported or advertised. See the A2A specification.

Chat can submit tasks to named peers configured by the user:

{
  "robot-brain": {
    "url": "https://robot.example:8787",
    "token_env": "ROBOT_AGENT_TOKEN",
    "description": "Reasoning agent on the warehouse robot"
  }
}
wendy chat --profile fleet --agent-peers ./peers.json

The agent_remote tool submits, polls, or cancels tasks. It requires approval and accepts a peer name, never a model-supplied URL or credential. Remote tasks use the destination service's tool policy. They survive the submitting chat and must be canceled explicitly. The same peer map can appear under peers in a service configuration; allow agent_remote there to authorize unattended remote delegation. Wendy services carry a delegation counter between peers and stop after four remote hops. Third-party agents must preserve that metadata for this limit to span their delegation. Local children cannot recursively spawn more agents or submit peer tasks. Per-profile child models use the agent_models map in service config.

Start on boot

Run the foreground service under your OS service manager or as a Wendy application with persistent storage. For a Linux host with the CLI installed at /usr/local/bin/wendy, an example systemd unit is:

[Unit]
Description=Wendy device reasoning agent
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=wendy
EnvironmentFile=/etc/wendy/device-brain.env
ExecStart=/usr/local/bin/wendy agent serve --config /etc/wendy/device-brain.json --state-dir /var/lib/wendy/device-brain
Restart=on-failure
RestartSec=5
TimeoutStopSec=30

[Install]
WantedBy=multi-user.target

Create the service account and writable state directory, give that account access to its workspace and device credentials, and restrict the environment file to that account. Set WENDY_AGENT_TOKEN and any configured model keys in the environment file. Install the unit and enable it through systemd. When deploying in a Wendy container, mount --state-dir on persistent storage and supply model and agent credentials through the application's environment configuration.

Trust and observation data

Clients and services require tokens of at least 16 characters. Generate random tokens and use separate credentials for each peer. Plain HTTP trusts local processes, including a process that takes over a forwarded port. Wendy pins localhost HTTP URLs and listeners to 127.0.0.1; remote access requires HTTPS or an authenticated tunnel. Origin-header rejection only limits browser requests. The bearer secret grants the service's shared task and tool authority.

Sensor event payloads are sent to the configured model, including hosted models. Redact sensitive fields at the producer. Wendy quotes the payload as untrusted JSON and adds system instructions that observations cannot authorize actions. Keep mutation allowlists narrow; prompt formatting is not an authorization boundary.

Delegation depth bounds cooperative peers. It does not authenticate peers or prevent a malicious peer from resetting its counter. Establish peer trust and credentials separately, and apply network rate limits to remote services.

Agent URLs must be origins without a path prefix, such as https://agent.example. Task-list pages may contain fewer tasks than pageSize to stay within the 1 MiB response limit. Follow nextPageToken until it is empty.

Sensor ingress admits 10 new events per second with a burst of 10, shared across sources. Excess events receive HTTP 429 with Retry-After: 1 before any state write. Producers must sample or back off; camera-rate streams should send derived observations rather than every frame. Retrying an already recorded event does not consume this budget. The limiter resets on service restart.

Agent model map keys must be exact profile names, without surrounding whitespace.

On this page