Sub-agents stream `assistant.reasoning_delta` but never emit the `assistant.reasoning` close event documented as always-sent
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 45/100
- Tipo de issue
- Error
- Claridad
- Bastante claro
- Estado de actividad
- Tranquilo
- Stack tecnológico
- javascript, python
Línea de trabajo
Comienza en sdk/index.js alrededor de createAgentCallbackBridge (~L4554) y compáralo con la ruta del agente principal cerca de ~L4541. Revisa session-events.schema.json en las líneas 520-522 y el contrato del README, y luego determina si los sub-agents deberían emitir un evento assistant.reasoning equivalente o documentar la forma de assistant.message. La tarea está terminada cuando el comportamiento elegido se haya implementado de forma coherente y se haya verificado con respecto a la secuencia de eventos reasoningId descrita.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
Per the Python SDK README:
Note:
assistant.messageandassistant.reasoning(final events) are always sent regardless of streaming setting.
And per the schema docstring on AssistantReasoningDeltaData.reasoningId (session-events.schema.json line 520-522):
Reasoning block ID this delta belongs to, matching the corresponding
assistant.reasoningevent.
In practice, sub-agents stream assistant.reasoning_delta events (with agentId set on the event), but the matching assistant.reasoning close is never emitted. Instead the reasoning content lands in the sub-agent's assistant.message.reasoningText / reasoningOpaque fields. Consumers that rely on the documented per-reasoningId close event end up with permanently-orphaned streaming reasoning blocks for every sub-agent turn.
Environment
@github/copilot(CLI bundle):1.0.49github-copilot-sdk(Python):1.0.0b4- Default provider (not BYOK)
- Reasoning model in use (Claude Opus / Sonnet via the default backend)
What I'd expect (per docs)
For every sub-agent reasoning block: one or more assistant.reasoning_delta events with a given reasoningId, followed by exactly one assistant.reasoning event carrying that same reasoningId and the complete content — symmetric with master-agent reasoning.
What actually happens
Code path (built bundle, sdk/index.js ~ L4554, inside createAgentCallbackBridge):
case "reasoning":
u.reasoningId && u.deltaContent &&
this.emitEphemeral("assistant.reasoning_delta",
{ reasoningId: u.reasoningId, deltaContent: u.deltaContent }, r);
// ...later, when the sub-agent's response completes:
this.emit("assistant.message",
{ parentToolCallId: r, messageId: kr(), ..., reasoningOpaque, reasoningText }, r);
// No paired emit("assistant.reasoning", ...) here.
Compare to the main-agent path (sdk/index.js ~ L4541) which does:
this.emit("assistant.message", { ... });
Ho && this.emitEphemeral("assistant.reasoning", { reasoningId: Ho, content: Yi ?? "" });
So the close emit is conditional on the main-agent code path and absent from the sub-agent bridge.
Empirical evidence
Across six debug-mode session JSONL transcripts (~17K reasoning_delta events total) captured from a production run with multiple custom sub-agents (planner, implementer, profiler_agent):
- Every
assistant.reasoning_deltacarrying a sub-agent'sagentIdis never followed by a matchingassistant.reasoning. - Sub-agent
assistant.messageevents for those same turns do carry non-emptyreasoningText(often several KB) andreasoningOpaque, so the data is being retained — it just travels via the message payload instead of the documented close event. - The two log files in the same run that contain no sub-agent activity (master-only) have zero orphan reasoning streams. The four files with sub-agent activity have 25 orphan streams collectively. The pattern is deterministic and 1:1 with sub-agent boundaries.
Suggested fixes (either or both)
- Behavior fix: also emit
assistant.reasoningfrom the sub-agent bridge afterendCurrentStreamingMessage, mirroring the main-agent path. This keeps the documented contract (1:1reasoning_delta→assistant.reasoning) and matches downstream consumer expectations. - Documentation fix: if the embed-in-
assistant.messageshape is intentional for sub-agents, document it explicitly onAssistantReasoningDeltaData(e.g. "for sub-agent reasoning, the closingassistant.messageevent for the sameagentIdcarries the complete content inreasoningText/reasoningOpaque; no separateassistant.reasoningevent is emitted") and in the streaming-events guide referenced by #922.
Related: #922 (CLOSED — "Extended thinking/reasoning events not firing for OpenAI and Anthropic models via Copilot SDK"), #1064 (CLOSED — "BYOK Anthropic provider missing multiple session events ... reasoning ..."). Same family of bug but neither covers this specific main-vs-sub-agent asymmetry on the default provider.
Happy to provide the full JSONL fixtures if helpful.
- Lenguaje dominante
- Java
- Estrellas
- 10.5k
- Forks
- 1.5k
- Merge medio
- 1 d 9 h
- PR fusionados (30 d)
- 131
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de github/copilot-sdk
-
agentic-workflows
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
github/copilot-sdk#2709 · 1 comentario ·
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 78/100
github/copilot-sdk#2673 ·
-
bug testing
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
github/copilot-sdk#2628 ·
-
agentic-workflows
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
github/copilot-sdk#2627 · 1 comentario ·
-
agentic-workflows
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
github/copilot-sdk#2493 ·
Todos los issues de github/copilot-sdk
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
elastic/gradle-plugins#157 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
cryptomator/hub#497 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
johanhaleby/occurrent#1120 ·