Streaming (SSE)#
O endpoint .../messages/stream responde com Content-Type: text/event-stream
(Cache-Control: no-cache, X-Accel-Buffering: no), status 200 imediato. O
formato de cada evento é:
event: <nome>
data: <json>
O agente responde token a token; os chips de ferramenta acendem ao vivo; o resumo de raciocínio aparece antes da resposta. Há duas famílias de evento.
POSTConsumir um stream#
curl -N -X POST \
https://agents-api.catcher.one/v1/agent-runtime/AGENT_ID/sessions/sess_a1b2c3/messages/stream \
-H "X-Agent-Token: prt_SEU_RUNTIME_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "content": "Resuma os 3 últimos pedidos." }'
Sequência real de eventos num turno com ferramentas:
event: start
data: {"run_id":"9f2c…","user_message":{"id":"…","role":"user","content":"Resuma os 3 últimos pedidos.","…":"…"}}
event: tool_call_start
data: {"type":"tool_call_start","tool_call":{"index":0,"id":"tc_1","name":"brain_search","arguments":"{\"q\":\"últimos pedidos\"}"}}
event: tool_call_result
data: {"type":"tool_call_result","tool_result":{"id":"tc_1","name":"brain_search","is_error":false,"output":"…","duration_ms":142}}
event: text_delta
data: {"type":"text_delta","text":"Os três últimos"}
event: text_delta
data: {"type":"text_delta","text":" pedidos foram…"}
event: round_usage
data: {"type":"round_usage","round_usage":{"usage":{"input_tokens":812,"output_tokens":143,"total_tokens":955}}}
event: done
data: {"type":"done","rounds":2,"stop_reason":"end_turn","cost":{"total_cost_usd":0.0144},"usage":{"input_tokens":812,"output_tokens":143,"total_tokens":955}}
event: complete
data: {"run_id":"9f2c…","assistant_message":{"id":"…","role":"assistant","content":"Os três últimos pedidos foram…","run_id":"9f2c…","…":"…"},"usage":{"input_tokens":812,"output_tokens":143,"total_tokens":955},"tool_calls":[…]}
GETCatálogo de eventos#
| Evento | Origem | data |
|---|---|---|
start |
API (sempre 1º) | { run_id, user_message } |
thinking |
engine / single-shot | { type: "thinking", text } — resumo de raciocínio |
text_delta |
engine / single-shot | { type: "text_delta", text } — fragmento da resposta |
tool_call_start |
engine | { type, tool_call: { index, id, name, arguments } } |
tool_call_delta |
engine | { type, tool_call: { index, id, arguments } } — fragmento dos argumentos |
tool_call_result |
engine | { type, tool_result: { id, name, is_error, output, duration_ms } } |
round_usage |
engine | { type, round_usage: { usage: {…} } } |
done |
engine (verbatim) | { type, rounds, stop_reason, cost: {…}, usage: {…}, rounds_usage: […] } |
| — | — | stop_reason terminal: completed (resposta final), max_rounds (bateu o teto de rounds), timeout (esgotou o wall clock do turno), error (falha real), user_aborted (parado via POST …/stop). Os três primeiros significam que o trabalho feito até ali é real — reagir com retry/aprofundar, não escalar. |
complete |
API (sempre último no sucesso) | { run_id, assistant_message, usage, tool_calls } |
error |
API / engine | { error } (ou { type: "error", error }) |
O nome do evento de texto é text_delta (não "token"), e o de raciocínio é
thinking. No fim de um turno com sucesso o cliente vê dois eventos
terminais — o done do engine (repassado verbatim) e o complete da API — e pode
usar qualquer um dos dois como sinal de fim. Um turno não-agêntico (single-shot,
sem ferramentas) emite start, então thinking (se houver), text_delta com a
resposta inteira, e complete.