Problem
POST /v1/agents/run returns a transcript field whose level of detail (and shape) depends on the spawn mode, so the same logical run is not comparable across modes. Verified against the current code and a live demo against POST /v1/agents/run:
spawn |
executor |
transcript content |
none |
DirectExecutor (in-process) |
Single summary entry (llm.call, agent.run, or agent.stream) with model + aggregate token counts. Individual LLM turns and tool calls inside the agent loop are not listed. |
local |
SubprocessExecutor |
Pass-through from the subprocess child, defaulting to a 2-message [{role: "user", ...}, {role: "assistant", ...}] pair (prompt + final text). Different shape, no typed events. |
ephemeral |
SandboxExecutor |
Per-event list with canonical typed entries (tool_call, tool_result, thinking, result, error, see TranscriptEvent in cloud_agents.workflow.core.models). The only mode that records individual tool calls. |
References:
- Endpoint returns
StepResult.transcript verbatim: src/app/endpoints/agents.py (run_agent_handler, transcript field of the response body).
DirectExecutor single-entry transcripts: direct.py (llm.call / agent.run / agent.stream).
SubprocessExecutor child default transcript: subprocess_child.py (setdefault("transcript", [{role: user...}, {role: assistant...}])).
- Canonical event model:
TranscriptEvent / normalize_transcript_events in cloud_agents.workflow.core.models.
Why it matters
- Demos and consumers cannot rely on
transcript to show tool use unless they happen to use spawn: ephemeral.
- Any transcript consumer (UI, audit, eval) must special-case three shapes/granularities.
Proposal
Emit the same per-event canonical transcript (tool_call, tool_result, thinking, result, error) for spawn: none and spawn: local as spawn: ephemeral already does, so the transcript response field has parity across modes. Where an executor genuinely cannot produce an event type, document the gap rather than silently returning a coarser shape.
Acceptance
Problem
POST /v1/agents/runreturns atranscriptfield whose level of detail (and shape) depends on thespawnmode, so the same logical run is not comparable across modes. Verified against the current code and a live demo againstPOST /v1/agents/run:spawnnoneDirectExecutor(in-process)llm.call,agent.run, oragent.stream) with model + aggregate token counts. Individual LLM turns and tool calls inside the agent loop are not listed.localSubprocessExecutor[{role: "user", ...}, {role: "assistant", ...}]pair (prompt + final text). Different shape, no typed events.ephemeralSandboxExecutortool_call,tool_result,thinking,result,error, seeTranscriptEventincloud_agents.workflow.core.models). The only mode that records individual tool calls.References:
StepResult.transcriptverbatim:src/app/endpoints/agents.py(run_agent_handler,transcriptfield of the response body).DirectExecutorsingle-entry transcripts:direct.py(llm.call/agent.run/agent.stream).SubprocessExecutorchild default transcript:subprocess_child.py(setdefault("transcript", [{role: user...}, {role: assistant...}])).TranscriptEvent/normalize_transcript_eventsincloud_agents.workflow.core.models.Why it matters
transcriptto show tool use unless they happen to usespawn: ephemeral.Proposal
Emit the same per-event canonical transcript (
tool_call,tool_result,thinking,result,error) forspawn: noneandspawn: localasspawn: ephemeralalready does, so thetranscriptresponse field has parity across modes. Where an executor genuinely cannot produce an event type, document the gap rather than silently returning a coarser shape.Acceptance
none,local, andephemeral.docs/cloud-agents-integration.htmlor the endpoint description).docs/cloud-agents-demo-curl.sh) transcripts reflect the unified shape.