Skip to content

fix(openai-chat): recover complete tool calls at EOF on the opencode-go lane - #2271

Merged
lidge-jun merged 1 commit into
devfrom
codex/goal-stream-drops
Aug 21, 2026
Merged

lidge-jun merged 1 commit into
devfrom
codex/goal-stream-drops

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Aug 21, 2026 •

Copy link
Copy Markdown
Owner

Summary

Fixes the two #2260 stream-drop symptoms on the opencode-go lane (Codex App /goal against opencode-go/deepseek-v4-flash):

  • Symptom A ('undeclared client tool update_plan'): already fixed on dev by 5f2b939 (Codex 0.147 functions-namespace flattening) — now locked with a real-server regression proving update_plan stays declared through the Responses->Chat translation and is accepted by the bridge. The undeclared-tool guard itself is untouched.
  • Symptom B ('ended without a terminal signal — possible truncation'): reproduced on dev (red repro: a COMPLETE tool-call delta followed by EOF without finish_reason/[DONE] errored as truncation). New narrow opt-in openaiChatEofTolerance on the provider contract, enabled for opencode-go in the registry: EOF is accepted only when every pending call has a non-empty name and complete JSON-object arguments; partial JSON, missing arguments, and empty streams still fail as truncation.

Verification

  • Red reproduction recorded (2/1 fail pre-fix), then 264/0 + 186/0 across the guard/bridge/router/adapter suites; tsc + privacy:scan green.
  • Full-suite authority runs on the release host as the aggregate gate (local full-suite run hit the known memory-pathology flake; focused suites and the real-server regression are green).

Checklist

Summary by CodeRabbit

  • New Features

    • Improved OpenAI-compatible streaming for gateways that end cleanly after complete tool calls without sending a terminal signal.
    • Complete tool calls now finish successfully, while incomplete or invalid arguments continue to report truncation errors.
    • Added provider-level configuration to control EOF tolerance for supported gateways.
  • Bug Fixes

    • Resolved tool-call handling issues for opencode-go goal streaming, including plan updates and clean completion events.
  • Tests

    • Added coverage for successful complete calls and failures caused by incomplete arguments.

@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner August 21, 2026 06:26
@lidge-jun lidge-jun added the bug Something isn't working label Aug 21, 2026
@lidge-jun
lidge-jun merged commit 08cc2ac into dev Aug 21, 2026
6 of 7 checks passed
@lidge-jun lidge-jun mentioned this pull request Aug 21, 2026
2 tasks done
@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@coderabbitai

coderabbitai Bot commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f18d5999-96b7-4279-8e15-dd80b9afe57e

📥 Commits

Reviewing files that changed from the base of the PR and between ca376d9 and 66d0b66.

📒 Files selected for processing (9)
  • src/adapters/openai-chat.ts
  • src/lab/subject/behavior-fingerprint.ts
  • src/providers/derive.ts
  • src/providers/registry.ts
  • src/router.ts
  • src/routing/compatibility/behavior.ts
  • src/types/provider.ts
  • tests/provider-registry-parity.test.ts
  • tests/server-opencode-go-goal-streaming.test.ts

📝 Walkthrough

Walkthrough

The OpenAI Chat adapter now validates tool-call arguments and supports opt-in clean EOF handling. The opencode-go registry enables this policy, routing propagates it, fingerprints record it, and streaming tests cover complete and incomplete calls.

Changes

OpenAI Chat EOF handling

Layer / File(s) Summary
Tool-call validation and EOF handling
src/adapters/openai-chat.ts, src/types/provider.ts
At lines 1566–1575, pending tool calls require names, string arguments, non-empty content, and complete JSON objects. At lines 1836–1844, enabled providers flush complete calls at EOF and emit done; incomplete calls retain truncation errors.
Provider policy propagation and fingerprinting
src/providers/registry.ts, src/providers/derive.ts, src/router.ts, src/lab/subject/behavior-fingerprint.ts, src/routing/compatibility/behavior.ts
The registry defines the policy and enables it for opencode-go at lines 1283–1285. Provider derivation and routing preserve explicit values and backfill undefined values. Behavior normalization and fingerprints expose the effective policy.
Streaming validation
tests/server-opencode-go-goal-streaming.test.ts, tests/provider-registry-parity.test.ts
The tests cover declared update_plan calls, successful EOF after complete arguments, truncation after incomplete arguments, and registry parity.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client as /goal client
  participant Router as router
  participant Registry as opencode-go registry
  participant Adapter as openai-chat adapter
  participant Upstream as chat-completions upstream

  Client->>Router: POST /v1/responses with update_plan
  Router->>Registry: resolve provider policy
  Registry-->>Router: openaiChatEofTolerance=true
  Router->>Adapter: process OpenAI Chat stream
  Adapter->>Upstream: send declared tool definitions
  Upstream-->>Adapter: tool-call argument deltas
  Upstream-->>Adapter: EOF without terminal marker
  Adapter-->>Client: completed function call and response.completed
Loading

Suggested reviewers: ingwannu

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/goal-stream-drops

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 66d0b660fa

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/types/provider.ts
* when every pending call has a non-empty name and complete JSON-object arguments;
* incomplete JSON, missing arguments, and empty streams remain truncation errors.
*/
openaiChatEofTolerance?: boolean;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Document the new EOF-tolerance provider option

This adds a public OcxProviderConfig option and changes the built-in opencode-go streaming behavior, but the provider configuration reference does not mention openaiChatEofTolerance alongside the analogous anthropicEofTolerance. Operators of other affected OpenAI-compatible gateways therefore cannot discover the opt-in or its fail-closed constraints; add it to the English configuration table and keep the translated references consistent.

AGENTS.md reference: src/AGENTS.md:L28-L28

Useful? React with 👍 / 👎.

@lidge-jun
lidge-jun deleted the codex/goal-stream-drops branch August 26, 2026 04:12
agentHits pushed a commit to agentHits/opencodex that referenced this pull request Sep 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant