fix: responses stream events - #3838
Conversation
|
tejas ghatte seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
📝 WalkthroughWalkthroughAdds per-output TextBuffers across Anthropic, Bedrock, Cohere, and Gemini stream converters to accumulate text deltas and emit the complete buffered text in final "done" events; Anthropic also skips tools with empty names. ChangesText buffering for accumulated text in done events
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (2.12.2)level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies" Comment |
This stack of pull requests is managed by Graphite. Learn more about stacking. |
Confidence Score: 5/5Safe to merge; the changes are targeted streaming-state fixes with no broad interface changes and correct pool lifecycle handling across all four providers. The text-buffer accumulation pattern is applied consistently, pool acquire and flush paths both reset the new map field, the delete-after-done approach avoids stale state within a stream, and the nil-tool guard in convertBifrostToolToAnthropic is handled correctly by its caller. No new concurrency concerns are introduced. core/providers/cohere/responses.go — the two ToolPlan output_item.done paths unconditionally emit a content block even when accumulated text is empty (noted in a prior review thread). Important Files Changed
Reviews (6): Last reviewed commit: "fix: responses stream events" | Re-trigger Greptile |
8688282 to
8bf07c3
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@core/providers/anthropic/responses.go`:
- Around line 5239-5242: The guard that skips tools currently checks only for
nil or empty string (tool.Name == nil || *tool.Name == "") but should also treat
whitespace-only names as missing; update the check in the skip-tools block to
use strings.TrimSpace on *tool.Name (e.g., if tool.Name == nil ||
strings.TrimSpace(*tool.Name) == "" { return nil }) and add the strings import
if not already present so whitespace-only names are rejected before sending tool
definitions upstream.
- Around line 1345-1349: The code is unconditionally persisting fallback
doneItem into state.OutputItems which can pollute response.completed; wrap the
cloning/storage (the block that clones doneItem, clones doneItem.Content, sets
cloned.Content and assigns state.OutputItems[outputIndex] = &cloned) with a
guard that ensures the synthesized fallback is a text-only item (e.g., check
doneItem.Content is non-nil and that the content type/mime or text field
indicates plain text — use the project's canonical field such as Content.Type or
Content.Mime or presence of Content.Text). Only when that text-only check passes
perform the clone/store; otherwise skip modifying state.OutputItems so non-text
reasoning/MCP paths do not get persisted.
In `@core/providers/bedrock/responses.go`:
- Around line 816-818: The TextBuffers accumulation currently does repeated
string concatenation (state.TextBuffers[outputIndex] += text) causing quadratic
copies; change TextBuffers from map[int]string (or []string) to
map[int]*strings.Builder (or []*strings.Builder), initialize per-output builders
where outputs are created, replace every place that appends (e.g., where
state.TextBuffers[outputIndex] += text and similar at line ~845) with
builder.WriteString(text), and when emitting the done event (where accText :=
state.TextBuffers[outputIndex] around ~1289) call accText := builder.String()
(and delete the builder entry if needed). Update references to state.ItemIDs and
outputIndex accordingly so you locate the correct builder for each output.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: c422b722-aee0-48e8-a3b7-34abd22a6f29
📒 Files selected for processing (4)
core/providers/anthropic/responses.gocore/providers/bedrock/responses.gocore/providers/cohere/responses.gocore/providers/gemini/responses.go
8bf07c3 to
ea20dcd
Compare
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
core/providers/bedrock/responses.go (1)
392-460: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick winAdd table-driven coverage for both text close paths.
This behavior now exists in two separate branches: closing text before a tool block starts, and closing text during
FinalizeBedrockStream. Please add focused table-driven tests for both so regressions don't bring back emptyoutput_text.done/output_item.donepayloads or miss buffer cleanup.As per coding guidelines, "Apply standard Go review practices: small interfaces, clear error wrapping, context propagation, race-safe shared state, goroutine/channel cleanup, and table-driven tests for behavior changes."
Also applies to: 1289-1357
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@core/providers/bedrock/responses.go` around lines 392 - 460, Add table-driven tests that exercise both code paths that close buffered text: (1) the branch that emits output_text.done/output_item.done when closing text before a tool block starts and (2) the branch exercised by FinalizeBedrockStream. For each table case, set up state.TextBuffers with a variety of prevOutputIndex/prevAccText values (including empty and non-empty), call the code-path (the handler that emits output_text.done / content_part.done / output_item.done and FinalizeBedrockStream), and assert that responses contain non-empty Text and ContentBlocks when prevAccText is non-empty, that no empty output_text.done or output_item.done payloads are emitted, and that the corresponding entry is removed from state.TextBuffers after the call; parameterize cases for empty vs non-empty buffers and for invoking the close logic directly vs via FinalizeBedrockStream to prevent regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@core/providers/bedrock/responses.go`:
- Around line 392-460: Add table-driven tests that exercise both code paths that
close buffered text: (1) the branch that emits output_text.done/output_item.done
when closing text before a tool block starts and (2) the branch exercised by
FinalizeBedrockStream. For each table case, set up state.TextBuffers with a
variety of prevOutputIndex/prevAccText values (including empty and non-empty),
call the code-path (the handler that emits output_text.done / content_part.done
/ output_item.done and FinalizeBedrockStream), and assert that responses contain
non-empty Text and ContentBlocks when prevAccText is non-empty, that no empty
output_text.done or output_item.done payloads are emitted, and that the
corresponding entry is removed from state.TextBuffers after the call;
parameterize cases for empty vs non-empty buffers and for invoking the close
logic directly vs via FinalizeBedrockStream to prevent regressions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 1834ff66-08e4-426a-9a9f-3090434e9b00
📒 Files selected for processing (4)
core/providers/anthropic/responses.gocore/providers/bedrock/responses.gocore/providers/cohere/responses.gocore/providers/gemini/responses.go
ea20dcd to
0a83eca
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
core/providers/anthropic/responses.go (1)
5249-5255:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winReject whitespace-only tool names too.
" "still passes this guard and gets forwarded as a custom tool name, which Anthropic will reject the same way it rejects an empty name. Trim before the emptiness check.As per coding guidelines, validate untrusted input before provider calls.💡 Suggested fix
- if tool.Name == nil || *tool.Name == "" { + if tool.Name == nil || strings.TrimSpace(*tool.Name) == "" { return nil }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@core/providers/anthropic/responses.go` around lines 5249 - 5255, The guard that skips tools with empty names only checks for nil or exact empty string, but does not reject whitespace-only names; update the validation in the code that inspects tool.Name (before constructing AnthropiсTool) to trim the string and treat it as empty if all whitespace (e.g., call strings.TrimSpace on *tool.Name) so that whitespace-only names are rejected the same way as "" — ensure this change is applied where tool.Name is read and before creating/setting anthropicTool.Name.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@core/providers/cohere/responses.go`:
- Around line 340-341: When closing a synthetic tool-plan item you clear
state.ToolPlanOutputIndex but leave state.ContentIndexToOutputIndex[0] pointing
to that output index; update both tool-plan close sites (the blocks that delete
from state.TextBuffers and set state.ToolPlanOutputIndex = nil) to also delete
state.ContentIndexToOutputIndex[0] so the mapping is removed, preventing
getOrCreateOutputIndex() from reusing a closed output index; apply the same
deletion in both locations mentioned and ensure any code relying on
ContentIndexToOutputIndex checks for existence after this cleanup.
---
Duplicate comments:
In `@core/providers/anthropic/responses.go`:
- Around line 5249-5255: The guard that skips tools with empty names only checks
for nil or exact empty string, but does not reject whitespace-only names; update
the validation in the code that inspects tool.Name (before constructing
AnthropiсTool) to trim the string and treat it as empty if all whitespace (e.g.,
call strings.TrimSpace on *tool.Name) so that whitespace-only names are rejected
the same way as "" — ensure this change is applied where tool.Name is read and
before creating/setting anthropicTool.Name.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 280b84b6-9f5b-435a-88d3-f92e52fc45a9
📒 Files selected for processing (4)
core/providers/anthropic/responses.gocore/providers/bedrock/responses.gocore/providers/cohere/responses.gocore/providers/gemini/responses.go
0a83eca to
9a60961
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@core/providers/cohere/responses.go`:
- Around line 340-344: When closing the synthetic tool-plan item, don’t just
delete state.ContentIndexToOutputIndex[0] and state.TextBuffers[outputIndex];
you must reserve/advance the global output counter so the next
getOrCreateOutputIndex() cannot re-use the same output index. Update the
tear-down in the block that currently sets state.ToolPlanOutputIndex = nil to
also advance state.CurrentOutputIndex past the released outputIndex (or set
CurrentOutputIndex = max(CurrentOutputIndex, outputIndex+1)) and then clear
state.ToolPlanOutputIndex, ensuring getOrCreateOutputIndex() will allocate a new
unique index for subsequent real content/tool items.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 7ad85204-be16-46b3-b52d-118162ccdd38
📒 Files selected for processing (4)
core/providers/anthropic/responses.gocore/providers/bedrock/responses.gocore/providers/cohere/responses.gocore/providers/gemini/responses.go
Merge activity
|
## Summary `output_text.done`, `content_part.done`, and `output_item.done` stream events were being emitted with empty text content instead of the full accumulated text. This PR fixes that by introducing a `TextBuffers` map in each provider's stream state to accumulate text deltas as they arrive, then populating the done events with the complete text. Additionally, tools with a `nil` or empty name are now skipped before being sent to Anthropic, which previously caused Anthropic to reject the request. ## Changes - Added `TextBuffers map[int]string` to the stream state structs for Anthropic, Bedrock, and Cohere providers, accumulating text deltas keyed by output index - Updated `output_text.done`, `content_part.done`, and `output_item.done` events across all four providers (Anthropic, Bedrock, Cohere, Gemini) to include the full accumulated text in their payloads rather than empty strings - Populated `ContentBlocks` in `output_item.done` messages with the actual text content block instead of an empty slice - Cleaned up `TextBuffers` entries via `delete` after emitting done events to avoid stale state - Ensured `TextBuffers` is properly initialized and cleared in pool acquire/flush paths - Skipped Anthropic tool conversion when `tool.Name` is `nil` or empty to prevent Anthropic API rejections ## Type of change - [x] Bug fix ## Affected areas - [x] Core (Go) - [x] Providers/Integrations ## How to test ```sh go test ./... ``` Stream a response from each affected provider (Anthropic, Bedrock, Cohere, Gemini) using the Responses API and verify that: - `output_text.done` events contain the full assembled text - `content_part.done` events include a `Part` with the full text - `output_item.done` events include a `Content.ContentBlocks` array with the complete text block - Sending a tool with no name to Anthropic no longer causes a request rejection ## Breaking changes - [ ] Yes - [x] No ## Security considerations None. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [ ] I added/updated tests where appropriate - [ ] I updated documentation where needed - [ ] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Streaming responses now accumulate per-output text and include full text in final completion events (avoids empty text/content blocks) across provider integrations. * Tool entries with missing or empty names are skipped during processing. * Stream state pooling lifecycle fixed to prevent cross-request text reuse by allocating, clearing, and releasing per-output text buffers between requests. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/maximhq/bifrost/pull/3838?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary This PR releases **core v1.5.14**, **framework v1.3.14**, **transports v1.5.6**, and bumps all dependent plugins to their respective `.14` patch versions. It delivers a broad set of new capabilities across MCP authentication, key rotation, OTel metrics, Bedrock/Anthropic compatibility, and UI improvements, alongside a number of targeted bug fixes and refactors. ## Changes - **Direct API Key Header** — Providers can now receive an API key passed directly via a request header (#3817) - **MCP Per-User Auth** — Introduced `MCPCredentialStore` abstraction, per-user MCP credential reconciliation, and a new per-user header auth type with lazy-auth submission flow (#3656, #3702, #3703, #3704, #3705) - **MCP TLS Configuration** — Added configurable TLS (`insecureSkipVerify`, `caCertPem`) for HTTP/SSE MCP client connections (#3779, #3783) - **MCP Sessions Management** — Filter, search, and pagination on the MCP sessions list API and table, plus a `can_reauth` identity gate (#3823, #3824, #3825) - **Key Rotation** — Keys now rotate on 401/402/403 responses; returns `502 upstream_credentials_exhausted` when all keys are permanently exhausted. Added `triggered_rotation` to `KeyAttemptRecord` and tightened `bifrost_key_rotation_events_total` semantics (#3430, #3491) - **OTel Metrics** — Added OTel spec-compatible metrics (backward compatible) with provider cache and semantic cache attributes in metrics export (#3865, #3816) - **Opus 4.8 Support** — System message handling and general compatibility for Opus 4.8 (#3868, #3878) - **Dimension Rankings** — New `GetDimensionRankings` API and dashboard tabs for team, customer, BU, and user rankings (#3766) - **Model Pricing Attributes** — `additional_attributes` field on model pricing rows with management API and UI editor (#3829) - **Prompt Cache Retention** — Added prompt cache retention parameter on responses requests (#3810) - **Tool Call Execution UI** — Inline tool-call execution, stop streaming, bulk execute/submit, and a redesigned tool-call UI (#3837, #3843) - **Sheet Navigation** — Prev/next keyboard navigation and URL state across virtual key, MCP client, and routing rule sheets (#3739, #3740, #3744, #3745) - **Bedrock Tool Name Truncation** — Truncate Bedrock function/tool names to the provider length limit - **Bedrock Guardrails** — Set guardrail config in Bedrock requests built from responses (#3862) - **Anthropic Tool Use** — Default `tool_use` input to `{}` when arguments are absent (#3880) - **Responses Streaming** — Fixed responses stream events (#3838) - **Compat Flow** — Fixed missing parameter parsing on the compat flow (#3881) - **Passthrough API Version** — Set a default API version in passthrough requests as a fallback (#3853) - **Virtual Key Updates** — Avoid overriding optional fields during virtual key update (#3855) - **User-Mode Flows** — Gate user-mode flows on caller `user_id`, skip temp token mint, and unify flow/credential kind filtering for pending flows (#3841, #3859) - **Partial Tool Calls** — Handle partial tool call execution failures and return successful results (#3849) - **URL Query Escaping** — Support escaped characters in URL query parameters (#3826) - **MCP Auth Errors** — Inline banner and retry support for MCP auth-required errors (#3856) - **Renamed Resolvers** — `staticHeadersResolver`/`serverOAuthResolver` renamed to `sharedHeadersResolver`/`sharedOAuthResolver` (#3840) - **Starlark Nested Tool Calls** — Exposed `RunWithPluginPipeline` on `ClientManager` and routed Starlark nested tool calls through the canonical plugin gate (#3794) - **Deferred-Fill OAuth Removed** — Removed deferred-fill user-mode OAuth flow support (#3839) - **Go 1.26.3** — Upgraded toolchain to Go 1.26.3 (#3782) ## Type of change - [x] Bug fix - [x] Feature - [x] Refactor - [ ] Documentation - [x] Chore/CI ## Affected areas - [x] Core (Go) - [x] Transports (HTTP) - [x] Providers/Integrations - [x] Plugins - [x] UI (React) - [ ] Docs ## How to test ```sh # Core/Transports go version # should report go1.26.3 go test ./... # UI cd ui pnpm i || npm i pnpm test || npm test pnpm build || npm run build ``` - Validate MCP per-user auth by configuring a per-user header auth type and confirming credentials are stored and reconciled on virtual key and MCP client changes. - Validate key rotation by triggering a 401/402/403 from an upstream provider and confirming rotation occurs; exhaust all keys and confirm a `502 upstream_credentials_exhausted` is returned. - Validate OTel metrics output includes `provider_cache` and `semantic_cache` attributes. - Validate Bedrock requests with tool names exceeding the provider limit are truncated correctly. - Validate Opus 4.8 system message handling by sending a request with a system message to an Opus 4.8 endpoint. ## Breaking changes - [x] Yes - [ ] No The deferred-fill user-mode OAuth flow has been removed (#3839). Any integrations relying on that flow must migrate to the new per-user credential store approach. The `staticHeadersResolver` and `serverOAuthResolver` identifiers have been renamed to `sharedHeadersResolver` and `sharedOAuthResolver` respectively (#3840); any direct references must be updated. ## Related issues #3817, #3656, #3702, #3703, #3704, #3705, #3779, #3783, #3823, #3824, #3825, #3430, #3491, #3865, #3816, #3868, #3878, #3766, #3829, #3810, #3837, #3843, #3739, #3740, #3744, #3745, #3862, #3880, #3838, #3881, #3853, #3855, #3841, #3859, #3849, #3826, #3856, #3840, #3794, #3839, #3782, #3724, #3814, #3836, #3869, #3886 ## Security considerations - MCP per-user credentials are stored via the new `MCPCredentialStore` abstraction; ensure the backing store is appropriately access-controlled and that credential values are encrypted at rest. - The direct API key header feature passes provider secrets via HTTP headers; ensure TLS is enforced on all ingress paths and that headers are not logged in plaintext. - User-mode flows are now gated on `caller user_id` and temp token minting is skipped where appropriate, reducing the surface for privilege escalation. - TLS configuration for MCP HTTP/SSE connections supports `insecureSkipVerify`; this should only be enabled in controlled environments. ## Checklist - [x] I read `docs/contributing/README.md` and followed the guidelines - [x] I added/updated tests where appropriate - [x] I updated documentation where needed - [x] I verified builds succeed (Go and UI) - [x] I verified the CI pipeline passes locally if applicable
## ✨ Features - **Direct API Key Header** - Pass a provider API key directly via request header (#3817) - **MCP Per-User Authentication** - New per-user header auth type with credential storage and lazy-auth submission flow (#3703, #3704, #3705) - **MCP TLS Configuration** - Configurable TLS (insecureSkipVerify, caCertPem) for HTTP/SSE MCP client connections (#3779, #3783) - **MCP Sessions Management** - Filter, search, and pagination on the MCP sessions list API and table, plus a can_reauth identity gate (#3823, #3824, #3825) - **Tool Call Execution UI** - Inline tool-call execution, stop streaming, bulk execute/submit, and a redesigned tool-call UI (#3837, #3843) - **Dimension Rankings Dashboard** - New dashboard tabs for team, customer, BU, and user rankings, backed by a GetDimensionRankings API (#3766) - **Model Pricing Attributes** - additional_attributes on model pricing rows with management API and UI editor (#3829) - **Prompt Cache Retention** - Prompt cache retention parameter on responses requests (#3810) - **Opus 4.8 Support** - System message handling and compatibility for Opus 4.8 (#3878, #3868) - **Key Rotation** - Rotate keys on 401/402/403 and return 502 upstream_credentials_exhausted when all keys are permanently dead (#3491) - **OTel Metrics** - OTel spec compatible metrics plus provider and semantic cache attributes in metrics export (#3865, #3816) - **Sheet Navigation** - Prev/next keyboard navigation and URL state across virtual key, MCP client, and routing rule sheets (#3739, #3740, #3744, #3745) - **Go 1.26.3** - Upgraded toolchain to Go 1.26.3 (#3782) ## 🐞 Fixed - **Bedrock Tool Names** - Truncate Bedrock function/tool names to the provider length limit - **Bedrock Guardrails** - Set guardrail config in Bedrock request built from responses (#3862) - **Anthropic Tool Use** - Default Anthropic tool_use input to {} when arguments are absent (#3880) - **Responses Streaming** - Fixed responses stream events (#3838) - **Compat Flow** - Fixed missing parameter parsing on the compat flow (#3881) - **Passthrough API Version** - Set a default API version in passthrough requests as a fallback (#3853) - **Virtual Key Updates** - Avoid overriding optional fields during virtual key update (#3855) - **User-Mode Flows** - Gate user-mode flows on caller user_id, skip temp token mint, and unify flow/credential kind filtering for pending flows (#3841, #3859) - **Partial Tool Calls** - Handle partial tool call execution failures and return successful results (#3849) - **URL Query Escaping** - Support escaped characters in URL query parameters (#3826) - **MCP Auth Errors** - Inline banner and retry support for MCP auth-required errors (#3856) - **JSON Editor Height** - Cap JSON editor max height at 400px in message views (#3842)

Summary
output_text.done,content_part.done, andoutput_item.donestream events were being emitted with empty text content instead of the full accumulated text. This PR fixes that by introducing aTextBuffersmap in each provider's stream state to accumulate text deltas as they arrive, then populating the done events with the complete text.Additionally, tools with a
nilor empty name are now skipped before being sent to Anthropic, which previously caused Anthropic to reject the request.Changes
TextBuffers map[int]stringto the stream state structs for Anthropic, Bedrock, and Cohere providers, accumulating text deltas keyed by output indexoutput_text.done,content_part.done, andoutput_item.doneevents across all four providers (Anthropic, Bedrock, Cohere, Gemini) to include the full accumulated text in their payloads rather than empty stringsContentBlocksinoutput_item.donemessages with the actual text content block instead of an empty sliceTextBuffersentries viadeleteafter emitting done events to avoid stale stateTextBuffersis properly initialized and cleared in pool acquire/flush pathstool.Nameisnilor empty to prevent Anthropic API rejectionsType of change
Affected areas
How to test
go test ./...Stream a response from each affected provider (Anthropic, Bedrock, Cohere, Gemini) using the Responses API and verify that:
output_text.doneevents contain the full assembled textcontent_part.doneevents include aPartwith the full textoutput_item.doneevents include aContent.ContentBlocksarray with the complete text blockBreaking changes
Security considerations
None.
Checklist
docs/contributing/README.mdand followed the guidelinesSummary by CodeRabbit