Sub-agents stream `assistant.reasoning_delta` but never emit the `assistant.reasoning` close event documented as always-sent
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 45/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Ít trao đổi
- Công nghệ
- javascript, python
Hướng nghiên cứu
Bắt đầu trong sdk/index.js, quanh createAgentCallbackBridge (~L4554), và so sánh với luồng main-agent gần ~L4541. Xem xét session-events.schema.json ở các dòng 520-522 và contract trong README, sau đó xác định liệu sub-agents có nên phát ra một sự kiện assistant.reasoning tương ứng hay tài liệu hóa dạng của assistant.message. Hoàn tất khi hành vi được chọn đã được triển khai nhất quán và được xác minh dựa trên chuỗi sự kiện reasoningId đã mô tả.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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.
- Ngôn ngữ chính
- Java
- Star
- 10.5k
- Fork
- 1.5k
- Merge trung bình
- 1 ngày 9 giờ
- Pull request đã merge (30 ngày)
- 130
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của github/copilot-sdk
-
agentic-workflows
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
github/copilot-sdk#2760 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
github/copilot-sdk#2759 ·
-
documentation
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 85/100
github/copilot-sdk#2758 ·
-
agentic-workflows
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
github/copilot-sdk#2709 · 1 bình luận ·
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 78/100
github/copilot-sdk#2673 ·
Tất cả issue của github/copilot-sdk
Issue tương tự
-
awaiting triage bug Causes friction Hop Gui P1 P2 Transforms
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
apache/flink-agents#1152 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
jenkinsci/blueocean-plugin#5417 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
objectionary/eo-graphs#75 ·