Managed-Agent API¶
/houmao/agents/* is the official Houmao-owned control and inspection surface for managed agents. It unifies TUI-backed managed agents and server-managed native headless agents under one identity namespace. The route family keeps coarse orchestration state, transport-specific detail, request submission, server-owned gateway lifecycle, pair-owned mailbox follow-up, and transport-neutral stop behavior on the server, while durable headless turn artifacts stay on the headless /turns/* routes.
houmao-server is the 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; the server keeps the public contracts stable and changes only the backing control path.
For the pair boundary that exposes these routes, use Houmao Server Pair. For the durable server-owned filesystem artifacts behind native headless authority and turn records, use Houmao Server. 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 lifecycle, 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 |
| Pair-owned mailbox follow-up | GET /houmao/agents/{agent_ref}/mail/status, POST /houmao/agents/{agent_ref}/mail/check, POST /houmao/agents/{agent_ref}/mail/send, POST /houmao/agents/{agent_ref}/mail/reply, POST /houmao/agents/{agent_ref}/mail/state |
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 direct server 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 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 canonical raw server-owned TUI inspection surface remains /houmao/terminals/{terminal_id}/state. 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 houmao-server. When no live gateway owns that session, the server falls back to its direct tracker.
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, the server reads live control posture from the gateway HTTP surface before building this response. Durable turn records and turn reconciliation still remain server-owned.
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 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 the official post-launch gateway attach action.
Important attach behavior:
- attach is idempotent when a healthy live gateway is already attached for the same managed agent
- 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 - attach returns HTTP
409when reconciliation is required or the underlying attach reports an already-in-use conflict - attach returns HTTP
503when runtime control is not resumable or gateway startup fails for an unavailable reason
For pair-managed houmao_server_rest sessions, operators normally reach this route through houmao-mgr agents gateway attach.
- explicit mode resolves either
--agent-name <friendly-name>or--agent-id <authoritative-id>through the managed-agent selector contract first and then calls the managed-agent gateway attach route - explicit tmux-session mode resolves
--target-tmux-session <tmux-session-name>locally from that tmux session's manifest-backed authority and then uses the persisted managed-agent route target - current-session mode runs inside the target tmux session, resolves the manifest through
HOUMAO_MANIFEST_PATHor shared-registry fallback fromHOUMAO_AGENT_ID, requires ahoumao_server_restmanifest authority, and uses its persistedgateway_authority.attach.api_base_urlplusgateway_authority.attach.managed_agent_refas the authoritative route target - current-session attach is not ready until the delegated launch has completed managed-agent registration on that same persisted server
- for same-session
houmao_server_restattach, tmux window0remains the contractual agent surface while any non-zero auxiliary gateway window remains implementation detail except for the exact live handle recorded ingateway/run/current-instance.json
POST /houmao/agents/{agent_ref}/gateway/detach removes the live sidecar when one is attached and returns the updated gateway status. The managed agent remains gateway-capable after detach because persisted manifest-backed attach authority stays in place.
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 default documented prompt path remains houmao-mgr agents prompt --agent-name <friendly-name> ... over POST /houmao/agents/{agent_ref}/requests. That surface keeps working across direct and gateway-backed control modes. houmao-mgr agents gateway prompt --agent-name <friendly-name> ... 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. houmao-mgr agents gateway send-keys ..., houmao-mgr agents gateway tui ..., and houmao-mgr agents gateway mail-notifier ... follow the same managed-agent selector rules outside tmux, the same explicit --target-tmux-session local-resolution rules from an ordinary shell, and the same manifest-first current-session resolution rules inside tmux. 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, POST /houmao/agents/{agent_ref}/mail/check, POST /houmao/agents/{agent_ref}/mail/send, POST /houmao/agents/{agent_ref}/mail/reply, and POST /houmao/agents/{agent_ref}/mail/state 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/stateis the shared foreground state-update route; in v1 it is intentionally one-way and is used to mark one processedmessage_refread
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 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 lifecycle remains a later explicit /gateway/attach action.
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:
- houmao-mgr agents gateway — gateway lifecycle and explicit live-gateway request commands
- houmao-mgr agents turn — managed headless turn submission and inspection
- houmao-mgr agents mail — managed-agent mailbox follow-up commands
houmao-mgr agents prompt shares the transport-neutral /requests surface and accepts the same headless-only request-scoped --model plus optional --reasoning-level overrides.