Managed-Agent API¶
/houmao/agents/* is the maintained Houmao-owned control and inspection surface for managed agents. It unifies TUI-backed managed agents discovered from the shared registry and passive-server-managed native headless agents under one identity namespace. The route family keeps coarse orchestration state, transport-specific detail, request submission, gateway proxying, pair-owned mailbox follow-up, and transport-neutral stop behavior on the maintained server API, while durable headless turn artifacts stay on the headless /turns/* routes.
houmao-passive-server is the maintained shared coordination plane for this surface. An attached healthy gateway becomes the live per-agent control plane behind that same public API. Callers do not switch route families when a gateway attaches; passive-server keeps the public contracts stable and changes only the backing control path.
For the maintained server boundary that exposes these routes, use houmao-passive-server. For passive-server listener and headless state layout, use the passive-server runtime layout section in that page. For the live sidecar HTTP surface that the managed-agent gateway routes project or proxy, use Agent Gateway Reference.
Route Families¶
| Surface | Routes | Applies to | Notes |
|---|---|---|---|
| Discovery and summary state | GET /houmao/agents, GET /houmao/agents/{agent_ref}, GET /houmao/agents/{agent_ref}/state, GET /houmao/agents/{agent_ref}/history |
TUI and headless | Summary state stays coarse and transport-neutral; history stays bounded and coarse |
| Detailed inspection | GET /houmao/agents/{agent_ref}/state/detail |
TUI and headless | Returns one shared envelope with a transport-discriminated detail payload |
| Transport-neutral request submission | POST /houmao/agents/{agent_ref}/requests |
TUI and headless | Official prompt and interrupt surface across both transports |
| Gateway proxy, direct prompt control, raw gateway-owned TUI inspection, gateway-mediated requests, headless session control, and notifier control | GET /houmao/agents/{agent_ref}/gateway, POST /houmao/agents/{agent_ref}/gateway/attach, POST /houmao/agents/{agent_ref}/gateway/detach, POST /houmao/agents/{agent_ref}/gateway/control/prompt, GET /houmao/agents/{agent_ref}/gateway/control/headless/state, POST /houmao/agents/{agent_ref}/gateway/control/headless/next-prompt-session, GET /houmao/agents/{agent_ref}/gateway/tui/state, GET /houmao/agents/{agent_ref}/gateway/tui/history, POST /houmao/agents/{agent_ref}/gateway/tui/note-prompt, POST /houmao/agents/{agent_ref}/gateway/requests, GET|PUT|DELETE /houmao/agents/{agent_ref}/gateway/mail-notifier |
TUI and headless | POST /gateway/control/prompt is immediate "send now or refuse now" control; POST /gateway/requests remains the queued gateway surface; gateway/control/headless/* is headless only; passive-server returns not-implemented for remote gateway attach/detach because those remain same-host manager operations |
| Pair-owned mailbox follow-up | GET /houmao/agents/{agent_ref}/mail/status, GET /houmao/agents/{agent_ref}/mail/resolve-live, POST /houmao/agents/{agent_ref}/mail/list, POST /houmao/agents/{agent_ref}/mail/peek, POST /houmao/agents/{agent_ref}/mail/read, POST /houmao/agents/{agent_ref}/mail/send, POST /houmao/agents/{agent_ref}/mail/post, POST /houmao/agents/{agent_ref}/mail/reply, POST /houmao/agents/{agent_ref}/mail/mark, POST /houmao/agents/{agent_ref}/mail/move, POST /houmao/agents/{agent_ref}/mail/archive |
TUI and headless when mailbox capability is present | These routes require pair-owned mailbox capability plus an eligible live gateway |
| Stop, native headless lifecycle, and durable turn detail | POST /houmao/agents/{agent_ref}/stop, POST /houmao/agents/headless/launches, POST /houmao/agents/{agent_ref}/turns, POST /houmao/agents/{agent_ref}/interrupt, GET /houmao/agents/{agent_ref}/turns/{turn_id}, GET /houmao/agents/{agent_ref}/turns/{turn_id}/events, GET /houmao/agents/{agent_ref}/turns/{turn_id}/artifacts/stdout, GET /houmao/agents/{agent_ref}/turns/{turn_id}/artifacts/stderr |
Stop applies to TUI and headless; turn detail is headless only | TUI stop reuses the managed session-delete lifecycle; durable headless turn evidence stays on /turns/* |
Identity And Alias Resolution¶
tracked_agent_id is the canonical managed-agent identity returned by the API. Route lookups also resolve through explicit aliases when they are unique.
Supported aliases include:
tracked_agent_id- TUI
terminal_id - TUI
session_name - runtime
runtime_session_idwhen present agent_nameagent_id
Alias resolution applies consistently across GET /houmao/agents/{agent_ref}, /state, /state/detail, /history, /requests, /stop, /gateway/*, and /mail/*. Ambiguous aliases are rejected explicitly instead of silently selecting one managed agent.
Summary State¶
GET /houmao/agents/{agent_ref}/state is the coarse shared state surface. It is meant for orchestration, availability checks, and quick inspection without transport-specific parsing.
The response includes:
identity: transport discriminator plus managed-agent identity fieldsavailability: coarse operability summaryturn: shared current-turn posture and optional active turn idlast_turn: shared coarse result summarydiagnostics: structured availability or recovery detailsmailbox: redacted mailbox posture when the managed agent has mailbox supportgateway: redacted gateway posture when gateway capability is known
Representative summary behavior:
- TUI agents expose coarse turn posture without requiring callers to interpret the raw tracked terminal payload.
- Headless agents expose coarse turn posture without requiring callers to read raw turn artifacts.
- When an attached gateway is healthy, summary and detail projection prefer the gateway HTTP read surface.
- When no live gateway is attached, or when direct fallback is the only safe option, the same routes continue projecting from passive observation or runtime state.
/historystays bounded and coarse for both transports; it is not a second durable per-turn store.- TUI-backed
/historyis derived from bounded in-memory recent transitions, while headless/historyis derived from persisted passive-server-owned turn records.
Detailed State¶
GET /houmao/agents/{agent_ref}/state/detail returns one shared envelope:
tracked_agent_ididentitysummary_statedetail
detail is discriminated by transport.
TUI detail¶
TUI detail is a curated projection, not a second raw terminal contract. It includes:
terminal_idcanonical_terminal_state_routecanonical_terminal_history_route- tracked
diagnostics - optional
probe_snapshot - optional
parsed_surface - tracked
surface stability
The maintained raw passive TUI inspection surface is exposed through /houmao/agents/{agent_ref}/state/detail. When an attached gateway owns live tracking, the exact raw gateway-owned inspection surface is exposed separately through /houmao/agents/{agent_ref}/gateway/tui/state and /houmao/agents/{agent_ref}/gateway/tui/history.
For attached eligible TUI sessions, the live tracked state served here is gateway-owned and projected back through passive-server. When no live gateway owns that session, passive-server falls back to its registry-driven observer.
Headless detail¶
Headless detail is execution-centric and intentionally does not fabricate TUI parser concepts. It includes:
runtime_resumabletmux_session_livecan_accept_prompt_nowinterruptible- optional
chat_sessionstate withcurrent,startup_default, and gateway-ownednext_prompt_overridewhen that view is sourced from a live gateway-backed control plane - shared
turn - shared
last_turn active_turn_started_at_utcactive_turn_interrupt_requested_at_utclast_turn_statuslast_turn_started_at_utclast_turn_completed_at_utclast_turn_completion_sourcelast_turn_returncodelast_turn_history_summarylast_turn_error- optional redacted
mailbox - optional redacted
gateway - structured
diagnostics
This route is the canonical rich inspection surface for managed headless agents when a caller needs current runtime posture without scraping stdout, stderr, or exit-code files.
tmux_session_live is diagnostic only. Terminal headless status, readiness for the next managed prompt, and last-turn timestamps reconcile from authoritative active-turn state plus durable turn artifacts such as the persisted exitcode file. last_turn_completion_source remains optional diagnostic metadata when it can be recovered.
For attached healthy headless gateways, passive-server reads live control posture from the gateway HTTP surface before building this response. Durable turn records and turn reconciliation still remain passive-server-owned when passive-server owns the headless agent.
Transport-Neutral Request Submission¶
POST /houmao/agents/{agent_ref}/requests is the official prompt and interrupt surface across both transports.
The request body is typed by request_kind.
Prompt submission:
{
"request_kind": "submit_prompt",
"prompt": "Summarize the current state.",
"execution": {
"model": {
"name": "claude-3-7-sonnet",
"reasoning": {
"level": 7
}
}
}
}
Interrupt submission:
Accepted responses use one shared envelope:
{
"success": true,
"tracked_agent_id": "claude-headless-1",
"request_id": "mreq-123",
"request_kind": "submit_prompt",
"disposition": "accepted",
"detail": "accepted",
"headless_turn_id": "turn-1",
"headless_turn_index": 1
}
Important rules:
dispositionisacceptedwhen the request caused or targeted real work, andno_opwhen an interrupt request found no active interruptible work.headless_turn_idandheadless_turn_indexare present only when the accepted request created or targeted a managed headless turn.- TUI prompt submission prefers a healthy attached gateway and falls back to the direct transport only when no live gateway currently owns safe prompt admission for that session.
- Headless prompt submission keeps passive-server-owned durable turn creation and turn-record authority, then prefers attached gateway admission when a healthy gateway owns live headless control.
- Headless prompt routes accept optional request-scoped
execution.model.nameplus optionalexecution.model.reasoning.levelas a tool/model-specific preset index. - Request-scoped execution overrides merge with launch-resolved defaults for the current headless turn only and never rewrite the stored manifest or later live state.
- TUI-backed prompt submission rejects any
executionpayload with HTTP422instead of silently dropping it. - Discovery of a gateway does not change the public request contract; callers still use
/houmao/agents/{agent_ref}/requests.
Observable admission and failure semantics:
- HTTP
422: invalid request shape or other request validation failure - HTTP
409: headless prompt submission conflicts with an already-active managed headless turn - HTTP
503: the addressed managed agent is not currently operable for the requested action - HTTP
200withdisposition = "no_op": an interrupt request found no active interruptible TUI or headless work
The dedicated POST /houmao/agents/{agent_ref}/interrupt route still exists for headless-only best-effort interrupt delivery, but new cross-transport callers should prefer POST /houmao/agents/{agent_ref}/requests.
Gateway Lifecycle, Gateway-Mediated Requests, And Notifier Control¶
Managed-agent gateway routes project the same gateway status, raw TUI tracking state, prompt-note provenance hook, and notifier state used by the live sidecar.
GET /houmao/agents/{agent_ref}/gateway returns the same GatewayStatusV1 shape used by the direct gateway status surface. It can therefore report a seeded offline not_attached status even when no live sidecar exists yet.
POST /houmao/agents/{agent_ref}/gateway/attach is present on passive-server for route-shape compatibility but returns not implemented. Gateway attach and detach are same-host operations; use houmao-mgr agents single --agent-id <id> gateway attach|detach or houmao-mgr agents self gateway attach|detach on the host that owns the tmux session.
Important attach behavior:
- local attach is idempotent when a healthy live gateway is already attached for the same managed agent
- local attach accepts optional
tui_tracking_timingswith positive-second overrides forwatch_poll_interval_seconds,stability_threshold_seconds,completion_stability_seconds,unknown_to_stalled_timeout_seconds,stale_active_recovery_seconds, andfinal_stable_active_recovery_seconds.stale_active_recovery_secondsgoverns how long the gateway waits before treating a stuck active turn as stale; this is related to but distinct from the managed-agent recovery system that handles broken tmux sessions. See Degraded and Stale Active Recovery. - same-session attach resolves the current tmux session from
HOUMAO_MANIFEST_PATHfirst and fromHOUMAO_AGENT_IDplus shared registry as a fallback - explicit attach resolves the group-level
agents single --agent-name <friendly-name>oragents single --agent-id <authoritative-id>selector through maintained manager targeting rules
POST /houmao/agents/{agent_ref}/gateway/detach is likewise not a remote passive-server action. Use local manager detach on the owning host.
GET /houmao/agents/{agent_ref}/gateway/tui/state proxies the raw HoumaoTerminalStateResponse exposed by the live gateway tracker for that managed agent.
GET /houmao/agents/{agent_ref}/gateway/tui/history proxies the gateway-owned bounded in-memory snapshot-history surface. This route is intentionally different from coarse managed-agent /history and from terminal transition /history: it returns recent raw tracked snapshots, capped in memory by the live gateway tracker.
POST /houmao/agents/{agent_ref}/gateway/tui/note-prompt records explicit prompt-note provenance on the live gateway tracker without enqueueing a gateway request.
POST /houmao/agents/{agent_ref}/gateway/requests proxies live gateway submit_prompt and interrupt requests. It rejects the request explicitly when no eligible live gateway is attached instead of silently falling back to the transport-neutral /requests surface. For submit_prompt, the same optional headless-only execution.model shape is accepted here and rejected with HTTP 422 for TUI-backed targets.
POST /houmao/agents/{agent_ref}/gateway/control/prompt is the immediate "send now or refuse now" gateway-control surface. It accepts the same optional headless-only execution.model.name plus optional execution.model.reasoning.level (>=0, interpreted against the resolved tool/model ladder) payload as the queued submit_prompt surface, applies the override to exactly the current prompt admission, and rejects the request with HTTP 422 when the resolved target is TUI-backed. Partial overrides merge with launch-resolved defaults through the shared headless resolution helper.
POST /houmao/agents/{agent_ref}/gateway/control/send-keys proxies the live gateway raw control-input route. It carries the same <[key-name]> grammar and escape_special_keys behavior as the direct gateway POST /v1/control/send-keys contract.
GET|PUT|DELETE /houmao/agents/{agent_ref}/gateway/mail-notifier proxy the live gateway notifier control surface for that managed agent. These routes require a live attached gateway; they return HTTP 503 when no live gateway is currently attached or when the live gateway health check fails. The proxy preserves notifier appendix_text unchanged: status returns the live gateway's effective appendix, omitted fields stay omitted on PUT, non-empty strings replace the runtime appendix, and appendix_text="" clears it. Status also returns the effective context_error_policy and pre_notification_context_action. PUT accepts those fields to select degraded-context handling and optional pre-notification compaction through the live gateway contract.
The default documented prompt path is houmao-mgr agents single --agent-name <friendly-name> prompt ... for selected agents or houmao-mgr agents self prompt ... for the current managed session over POST /houmao/agents/{agent_ref}/requests. That surface keeps working across direct and gateway-backed control modes. houmao-mgr agents single --agent-name <friendly-name> gateway prompt ... is the explicit gateway-mediated alternative when live-gateway admission and queue semantics matter and the caller wants to require a live gateway instead of letting the server choose the safe backing path. Scoped gateway send-keys, tui, and mail-notifier commands use agents single ... gateway ... for selected-agent targeting and agents self gateway ... for current-session targeting. When a friendly name is ambiguous, operators should retry with --agent-id <authoritative-id>.
Pair-Owned Mail Follow-Up¶
GET /houmao/agents/{agent_ref}/mail/status, GET /houmao/agents/{agent_ref}/mail/resolve-live, POST /houmao/agents/{agent_ref}/mail/list, POST /houmao/agents/{agent_ref}/mail/peek, POST /houmao/agents/{agent_ref}/mail/read, POST /houmao/agents/{agent_ref}/mail/send, POST /houmao/agents/{agent_ref}/mail/post, POST /houmao/agents/{agent_ref}/mail/reply, POST /houmao/agents/{agent_ref}/mail/mark, POST /houmao/agents/{agent_ref}/mail/move, and POST /houmao/agents/{agent_ref}/mail/archive let callers perform mailbox follow-up through the managed-agent API without discovering the live gateway host or port.
Important boundary rules:
- these routes require pair-owned mailbox capability on the addressed managed agent
- they also require an eligible live gateway to be attached
- they coexist with
GET|PUT|DELETE /houmao/agents/{agent_ref}/gateway/mail-notifier gateway/mail-notifierremains background notifier configuration, whilemail/*is the foreground mailbox-operation surfacePOST /mail/readreads one selected message and marks it read, whilePOST /mail/mark,POST /mail/move, andPOST /mail/archiveexpose explicit foreground lifecycle updates for selectedmessage_refvaluesPOST /mail/send,POST /mail/post, andPOST /mail/replyaccept the optional canonical-envelope fieldsnotify_block(typed sub-model{"text": str, "placement": "append" | "prepend"}with text capped at 512 chars; auto-extracted from a```houmao-notifybody fence withplacement="append"when omitted) andnotify_auth(currently onlyscheme="none"is accepted at envelope validation; non-noneschemes return HTTP422with the canonicalverifier not yet supportederror). The gateway notifier rendersnotify_block.textinto the receiver's wake-up prompt at the requested placement subject to the configured trust posture (notify_block_render,notify_block_auth_mode,notify_block_auth_verifier). Seedocs/reference/gateway/contracts/protocol-and-state.mdfor the configurable knobs anddocs/reference/mailbox/contracts/canonical-model.mdfor the canonical envelope semantics including the auto-mirror invariant.
Observable availability semantics:
- HTTP
503: no eligible live gateway is attached, the gateway health check fails, or the managed agent does not expose pair-owned mailbox capability - HTTP
4xxfrom the live gateway is forwarded when the mailbox request shape is invalid or the requested mailbox action is rejected downstream
Native Headless Lifecycle And Durable Turn Inspection¶
POST /houmao/agents/headless/launches launches a passive-server-managed native headless agent.
The resolved launch request requires:
toolworking_directoryagent_def_dirbrain_manifest_pathrole_name
Optional launch fields:
agent_nameagent_idheadless_display_styleheadless_display_detailmailbox
headless_display_style defaults to plain and headless_display_detail defaults to concise for managed headless sessions. These controls affect live bridge rendering and later CLI replay semantics; they do not change the raw provider artifacts.
Launch-time gateway flags are intentionally not part of this contract. Gateway attach and detach remain same-host scoped houmao-mgr agents single/self ... gateway ... actions.
For managed headless agents, durable post-turn inspection stays on the /turns/* family:
POST /houmao/agents/{agent_ref}/turnsaccepts one managed headless prompt turn and returns a durable turn handle; it now also accepts optionalchat_sessionwithmode = "auto" | "new" | "current" | "tool_last_or_new" | "exact"andidrequired only formode = "exact". Note:autoandcurrentare gateway-level selectors (GatewayChatSessionSelectorMode) resolved by the gateway before dispatch; the internal headless turn API accepts onlynew,tool_last_or_new, andexactPOST /houmao/agents/{agent_ref}/turnsalso accepts optional request-scopedexecution.model.nameplus optionalexecution.model.reasoning.level(>=0, interpreted against the resolved tool/model ladder). The override is applied only to the submitted turn and does not persist as agent state.GET /houmao/agents/{agent_ref}/turns/{turn_id}reports persisted turn statusGET /houmao/agents/{agent_ref}/turns/{turn_id}/eventsreturns canonical semantic headless event records with normalized assistant, action, completion, provider, and session semanticsGET /houmao/agents/{agent_ref}/turns/{turn_id}/artifacts/stdoutand/stderrexpose the durable raw provider artifacts directly
/history remains bounded and coarse even for headless agents. Durable headless detail lives on /turns/*, not on /history.
CLI Reference¶
The managed-agent API routes are also reachable through the houmao-mgr CLI:
- scoped agents gateway — gateway lifecycle and explicit live-gateway request commands
- scoped agents turn — managed headless turn submission and inspection
- scoped agents mail — managed-agent mailbox follow-up commands
Scoped houmao-mgr agents single/self ... prompt shares the transport-neutral /requests surface and accepts the same headless-only request-scoped --model plus optional --reasoning-level overrides.