fix: tolerate anthropic relays that omit text deltas - #3207
fix: tolerate anthropic relays that omit text deltas#3207rootkiller6788 wants to merge 3 commits into
Conversation
Some Anthropic-compatible relays stream text blocks and text_delta events without a text field. The stream converter then yields a text part with undefined text, which the v2 loop publishes as an assistant.delta event without a delta field, crashing the TUI renderer with a trim() on undefined. Coerce missing text to an empty string in both the v2 and kosong Anthropic stream converters (matching the existing thinking ?? '' pattern), and defensively coerce a non-string delta in the TUI session event handlers.
🦋 Changeset detectedLatest commit: a2f0e09 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a0fdafe1e0
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| { type: 'message_stop' }, | ||
| ]); | ||
|
|
||
| (provider as any)._client.messages.create = vi.fn().mockResolvedValue(stream) as never; |
There was a problem hiding this comment.
Stub the relay through the public client factory
This regression test reaches into the private _client field, so a refactor of the provider's client storage or initialization would break the test even if streaming behavior remains correct. Construct the provider with the supported clientFactory boundary instead; the existing collectAnthropicStreamParts helper already does this and can exercise the same malformed relay events through generate() without depending on private implementation details.
Useful? React with 👍 / 👎.
…ctory Follow-up to review: the new test poked the provider's private _client to inject the mock stream, so any change to how the client is stored would break the test even when streaming stays correct. Rework it to reuse collectAnthropicStreamParts, which stubs the SDK through the public clientFactory boundary, like the neighbouring empty-thinking tests.
|
Done — reworked the test to go through clientFactory via the existing collectAnthropicStreamParts helper, so it no longer pokes the private _client. Event sequence/assertions unchanged (text:'' / text:'' / text:'ok'). Verified vitest run test/anthropic.test.ts → 289 passed. |
Closes #2924
Problem
Some Anthropic-compatible relays stream
content_block_start(text) andtext_deltaevents without thetextfield. The stream converter then yields{ type: 'text', text: undefined }, the v2 loop forwardspart.textverbatim as the delta, and JSON serialization drops thedeltakey; the TUI renderer crashes withCannot read properties of undefined (reading 'trim').Verified against the current source:
packages/agent-core-v2/src/kosong/provider/bases/anthropic/anthropic.tsyieldstext: block.text/text: delta.textunguarded (whilethinkingalready falls back to?? '').packages/agent-core-v2/src/agent/loop/loopService.tsforwardspart.textverbatim as the delta.apps/kimi-code/src/tui/controllers/session-event-handler.tscallsevent.delta.trim()on boththinking.deltaandassistant.delta.Fix
''in both the v2 andpackages/kosongAnthropic stream converters, matching the existingthinking ?? ''pattern.''in the TUI handlers so a malformed wire record can never crash the renderer.Test
Regression test in
packages/kosong/test/anthropic.test.tsfeedscontent_block_start/text_deltaevents that omittext; it fails on the old code (yieldstext: undefined) and passes after the fix. Fullpackages/kosongsuite: 49 files / 1366 tests green.