Repository navigation
Preserve tool outcomes and fix streamed call assembly - #1349
Conversation
Assemble complete streamed tool calls and refusals after successful stream completion. Preserve completed and unexecuted tool outcomes before terminal errors, including buffered runs, concurrent batches, and approval resumption. Document per-call image history and add regression coverage without changing non-streaming defaults or introducing new public APIs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
API consistency review
Changed Go contractNo exported API changes (per the PR description). Observable behavior changes:
Upstream evidence reviewedNo upstream sources were independently reviewed in this run. The PR description cites the .NET MEAI OpenAI adapter and AssessmentI could not complete a verified comparison with the .NET and Python implementations, so I am reporting no findings. The PR states that Go deliberately preserves partial tool outcomes on cancellation, where .NET lets the exception escape before building the batch result. Maintainers should confirm that this divergence is acceptable and check the Python OpenAI streaming tool-call handling manually. No parity label was added.
|
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved issues allow truncated OpenAI streams to trigger execution of unfinished tool calls and tool-loop failures to label messages with stale conversation IDs.
2 open issues
What changed in this PR
This PR improves streamed OpenAI response assembly and preserves partial tool outcomes when automatic invocation stops, without adding public APIs.
Changes:
- Assemble tool calls and refusals after streaming ends, preserving text, usage, metadata, and raw chunks.
- Emit completed and unexecuted tool outcomes before terminal errors, including buffered runs and approval resumption.
- Document and test injected-image retention through serialized external history.
| File | Description |
|---|---|
provider/openaiprovider/chat.go |
Emit accumulated tool calls and refusals after streaming. |
provider/openaiprovider/chat_test.go |
Cover packed calls, interleaved arguments, refusals, and stream failures. |
docs/agent-harness.md |
Explain partial outcomes, cancellation, and external history. |
agent/messageinjection.go |
Document persistence requirements for injected content. |
agent/messageinjection_test.go |
Test serialized image history across tool rounds. |
agent/harness/toolautocall/autocall.go |
Preserve tool outcomes and buffered updates before terminal errors. |
agent/harness/toolautocall/autocall_test.go |
Cover cancellation, approvals, concurrent outcomes, and provider failures. |
Review effort: Balanced
| if len(acc.Choices) == 0 { | ||
| return | ||
| } | ||
| choice := acc.Choices[0] |
| if runErr == nil { | ||
| response.ConversationID = finalConversationID | ||
| } |


Summary
Fix the SDK behavior behind the streaming and cancellation workarounds documented in dkr290/agenticgo#49.
ResponseStream.Collecterror behavior unchanged. No new public APIs or options..NET comparison
Checked stable Agent Framework
dotnet-1.27.0(4d1674b78951d6fd127ada532660514637f906e9), which uses Microsoft.Extensions.AI 10.10.0 and its OpenAI adapter 10.10.1.Validation
provider/openaiprovider,agent/harness/toolautocall, andagent.