Skip to content

Fix OpenAI streams with empty tool_calls arrays - #996

Draft
lc4t wants to merge 1 commit into
craft-ai-agents:mainfrom
lc4t:lc4t/fix-empty-tool-calls-sse
Draft

Fix OpenAI streams with empty tool_calls arrays#996
lc4t wants to merge 1 commit into
craft-ai-agents:mainfrom
lc4t:lc4t/fix-empty-tool-calls-sse

Conversation

@lc4t

@lc4t lc4t commented Jul 28, 2026

Copy link
Copy Markdown

Summary

  • preserve OpenAI-compatible SSE chunks whose deltas contain an empty tool_calls array
  • add regression coverage for content and terminal chunks with tool_calls: []
  • document the user-visible fix in the pending release notes

Root cause

The OpenAI SSE interceptor treated any present delta.tool_calls value as a handled tool-call delta. Because empty arrays are truthy in JavaScript, providers that include tool_calls: [] on ordinary content or terminal chunks caused those chunks to be suppressed. Pi then received [DONE] without the upstream finish_reason: "stop" chunk and reported Stream ended without finish_reason.

Changes

  • require delta.tool_calls to contain at least one entry before entering the tool-call buffering path
  • verify that content, finish_reason: "stop", and [DONE] pass through when tool_calls is empty
  • retain the existing behavior for non-empty, repeated, parallel, and shifted-index tool calls

Testing

  • bun test across the OpenAI interceptor SSE, relay, hint, response-repair, and validation suites: 43 passed, 0 failed
  • bun run typecheck:shared
  • replayed an OpenAI-compatible SSE stream through the interceptor and confirmed content, finish_reason: "stop", and [DONE] are all preserved
  • git diff --check

Validation note

bun run typecheck:all could not complete because the v0.11.2 checkout does not contain the root tsconfig.base.json referenced by several package configs. The affected packages/shared typecheck passes.

Fixes #995

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom OpenAI-compatible endpoint validation fails with "Stream ended without finish_reason"

1 participant