Skip to content

fix(providers): gate MiMo bare-call recovery on a terminal signal and limit DeepSeek upload roles - #7396

Merged
lidge-jun merged 3 commits into
devfrom
fix/provider-adapters-2.90-followup
Oct 19, 2026
Merged

lidge-jun merged 3 commits into
devfrom
fix/provider-adapters-2.90-followup

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

Summary

This is a follow-up to #7394 (B4a, already merged). It fixes the two Codex review findings on that PR, both confirmed real:

  • P1, MiMo bare-call recovery on a cut stream (src/adapters/openai-chat.ts:341): a MiMo stream that closed after a complete bare <tool_call> block, but before finish_reason or [DONE], reached the EOF flush with user-facing output. Standalone recovery then emitted an executable freeform call, such as exec, from a possibly truncated response, even though structured calls on the same path are refused as possible truncation. Recovery now runs only after a terminal signal; otherwise the block stays visible text. openai-chat.ts stays at 822 lines: flushToolCalls takes a terminal flag that defaults to true, and the EOF site passes sawFinish.
  • P2, DeepSeek uploads from rejected roles (src/server/responses/deepseek-image-files.ts:61): the item.role check also matched system and assistant messages, so their images were uploaded and kept on DeepSeek for an hour, although DeepSeek rejects images in those roles. Uploads are now limited to user and developer messages plus the two tool-output types. This only matters when a model has opted in with deepseekImageFiles.

Verification

Based on origin/dev 74463a2. Tests ran with the pinned Bun 1.4.3.

  • bun run typecheck, bun run structure:check, bun run privacy:scan: pass
  • bun test --isolate tests/adapters/openai/ tests/providers/deepseek-image-files.test.ts tests/test-layout.test.ts tests/test-layout-tooling.test.ts tests/ci-workflows/file-size-ratchet.test.ts: 936 pass / 0 fail (42 files)
  • Each of the two new regression tests (a stream cut without a terminal signal never executes a bare block and images in roles DeepSeek rejects are never uploaded) fails with the src/ changes stashed and passes with them.
  • Pushed with --no-verify: this host's local pre-push hook runs the full bun run test, which cannot pass here because of environment-only launcher failures (described in fix(providers): carry Gemini, MiMo, DeepSeek, Mistral, opencode-go and audio adapter fixes for 2.90 #7394). A full suite was not run locally; CI covers it.
  • src/adapters/openai-chat.ts: 822 lines (baseline cap 822).

Co-authored-by: shirruy 63145023+shirruy@users.noreply.github.com
Co-authored-by: fontanierh 14199823+fontanierh@users.noreply.github.com

Review follow-ups after opening

  • Codex P1 on the first fix: content arriving after finish_reason kept standalone recovery enabled, so a later cut-off block could still execute at EOF or [DONE]. The first terminal flush is now the only recovery decision. A regression test covering both the EOF and [DONE] tails fails without the fix. bun test --isolate tests/adapters/openai/: 884 pass / 0 fail.

  • CI's red cold-spawn warm-up coverage shard is not from this PR. It fails the same way on clean origin/dev dbb908f (fix(oauth): harden OAuth login/import, quota diagnostics, service/update paths and shim token handling (B5) #7397 added codex-shim-bypass-token.test.ts without a disposition). The codex-shim-windows-revision failure in one shard passes locally on dev, and this PR touches no shim code.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

lidge-jun and others added 2 commits October 20, 2026 06:52
A MiMo stream that closed after a complete bare block but before
finish_reason or [DONE] reached the EOF flush with user-facing output,
and standalone recovery emitted an executable call that structured calls
on the same path would have refused as possible truncation. Recover only
after a terminal signal; otherwise the block stays visible text.

Co-authored-by: shirruy <63145023+shirruy@users.noreply.github.com>
System and assistant message images were uploaded and persisted even
though DeepSeek rejects images in those roles. Restrict uploads to user
and developer messages plus tool outputs.

Co-authored-by: fontanierh <14199823+fontanierh@users.noreply.github.com>
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner October 19, 2026 21:52
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-19T21:54:58.701673Z 7a03be2 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Oct 19, 2026
@coderabbitai

coderabbitai Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: lidge-jun/opencodex/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 207ddae7-0dd0-4ff4-92a3-b01efb4fa0de
📥 Commits

Reviewing files that changed from the base of the PR and between 7a03be2 and 01c55e5.

📒 Files selected for processing: 3
  • src/adapters/openai-chat/standalone-bare-tool-calls.ts
  • structure/providers/mimo-bare-calls.md
  • tests/adapters/openai/openai-chat-standalone-bare-block.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.

📝 Walkthrough

Standalone bare-call recovery now requires a terminal flush. DeepSeek image selection now reads message content only from user and developer roles. Tests and documentation cover both changes.

Changes: Standalone bare-call stream handling

Layer / File(s) Summary
Gate recovery on terminal flush
src/adapters/openai-chat.ts, src/adapters/openai-chat/standalone-bare-tool-calls.ts, tests/adapters/openai/openai-chat-standalone-bare-block.test.ts, structure/providers/mimo-bare-calls.md
flushToolCalls receives terminal status, and standalone bare-call recovery requires a terminal flush. The buffer disables recovery after its first terminal flush. Tests verify that a bare block does not emit a tool-call start event when the stream ends without a terminal signal or when the block arrives after finish_reason: "stop". The documentation describes the unterminated-stream behavior.

DeepSeek image role filtering

Layer / File(s) Summary
Restrict selected image roles
src/server/responses/deepseek-image-files.ts, tests/providers/deepseek-image-files.test.ts, docs-site/src/content/docs/reference/configuration/providers.md
Image selection reads message content only from user and developer roles. Function-call and custom-tool-call outputs continue to use output. Tests cover system and assistant roles, and the provider documentation states the role restriction.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 01c55

Bare-call recovery now depends on a terminal signal, and opted-in DeepSeek image conversion is limited to supported roles. The inspected changes leave no concrete merge-blocking risk.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 5 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title accurately summarizes both primary changes: terminal-signal gating for MiMo bare-call recovery and role restrictions for DeepSeek image uploads. It is specific, concise, and clearly related …
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title accurately summarizes both primary changes: terminal-signal gating for MiMo bare-call recovery and role restrictions for DeepSeek image uploads. It is specific, concise, and clearly related to the pull request.

Full details: Docstring Coverage

Explanation

Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 5 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

  • Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 2
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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: 7a03be2f65

ℹ️ 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".

return;
}
if ((yield* flushToolCalls()) === "terminate") return;
if ((yield* flushToolCalls(sawFinish)) === "terminate") return; // A cut stream never synthesizes a bare call.

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 Require the terminal signal to follow the bare block

When a provider emits finish_reason and then sends another content delta before EOF, finishReason remains set, so this passes true even though the candidate bare block arrived after the only terminal signal. The earlier finish flush finds no candidate and leaves standalone recovery enabled, allowing a later cut-off <tool_call> to execute—the truncated-response hazard this change is intended to prevent. Track terminal state relative to newly ingested content, or disable recovery after the first terminal flush, instead of using the response-wide sawFinish value.

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

Useful? React with 👍 / 👎.

…covery decision

Content that arrives after finish_reason kept standalone recovery
enabled, so a later cut-off block could still execute at EOF or [DONE].

Co-authored-by: shirruy <63145023+shirruy@users.noreply.github.com>
@lidge-jun
lidge-jun merged commit 3069192 into dev Oct 19, 2026
37 of 41 checks passed
@lidge-jun
lidge-jun deleted the fix/provider-adapters-2.90-followup branch October 19, 2026 22:25
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