Skip to content

fix(agent-runtime): backfill reasoning_content for relayed DeepSeek models - #232

Merged
vastsa merged 1 commit into
vastsa:mainfrom
L4XB:fix/reasoning-content-backfill-relay
Sep 11, 2026
Merged

fix(agent-runtime): backfill reasoning_content for relayed DeepSeek models#232
vastsa merged 1 commit into
vastsa:mainfrom
L4XB:fix/reasoning-content-backfill-relay

Conversation

@L4XB

@L4XB L4XB commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Refs #223 (the backfill part, "B" in the report)

Problem

In @earendil-works/pi-ai convertMessages() (dist/api/openai-completions.js) the reasoning_content: "" backfill is guarded by

if (compat.requiresReasoningContentOnAssistantMessages && model.reasoning && assistantMsg.reasoning_content === undefined)

model.reasoning is false for a DeepSeek model reached through a relay (not in the models.dev catalogue, no thinkingLevels), so even with the compat flag set the backfill never ran. A session whose history contains some assistant turns with thinking and some without was sent as a mix; as the report measured, DeepSeek rejects the mix with HTTP 400 and accepts all-or-none.

Change

The repo already patches pi-ai (patches/@earendil-works__pi-ai@0.85.1.patch), so the patch is extended (via pnpm patch / pnpm patch-commit, hence the pnpm-lock.yaml hash change):

  • after the message loop in convertMessages(), if compat.requiresReasoningContentOnAssistantMessages is set and any assistant message ends up with a non-empty reasoning_content, every other assistant message gets reasoning_content: "".
  • The existing per-message backfill for models flagged reasoning is untouched, and a history without any thinking is left exactly as before (no reasoning_content at all).

Not included: the report's part "A" (treating any model whose id contains deepseek as a DeepSeek target). deepseekRequestCompat() in packages/shared/src/provider-presets.ts already matches on the provider key or a deepseek.com base URL; widening that to arbitrary relay base URLs by model id is a product decision I did not want to take here.

Tests

packages/agent-runtime/src/reasoning-content-backfill.test.ts calls the exported convertMessages with a reasoning: false model and the DeepSeek compat:

  • one assistant turn with thinking plus one without → ["let me think", ""];
  • no thinking anywhere → [undefined, undefined].

Verified locally: vitest run src/reasoning-content-backfill.test.ts (2 passed), tsc -p tsconfig.json --noEmit in packages/agent-runtime, pnpm install applies the updated patch.

…odels

pi-ai only gave assistant messages without thinking an empty
reasoning_content when the model was flagged `reasoning`. A DeepSeek
model reached through a relay is not in the catalogue, so the flag is
false, the backfill never ran, and a history in which only some turns
carry thinking was sent as is; DeepSeek answers that mix with HTTP 400
while all-or-none is accepted (vastsa#223).

Extend the pnpm patch on @earendil-works/pi-ai: after converting the
messages, whenever any assistant message carries reasoning_content, the
remaining assistant messages get an empty one. The per-message backfill
for flagged models is unchanged.
Copilot AI lite review requested due to automatic review settings September 11, 2026 08:14

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@vercel

vercel Bot commented Sep 11, 2026

Copy link
Copy Markdown

@L4XB is attempting to deploy a commit to the vastsa's projects Team on Vercel.

A member of the Team first needs to authorize it.

@vastsa
vastsa merged commit 370f076 into vastsa:main Sep 11, 2026
2 of 3 checks passed
@vastsa

vastsa commented Sep 11, 2026

Copy link
Copy Markdown
Owner

Reviewed and merged as commit 370f076. The change is scoped to the patched pi-ai OpenAI-completions replay path: when DeepSeek-compatible history contains a non-empty reasoning_content on any assistant turn, missing assistant turns receive an empty value, while all-no-thinking histories remain unchanged. Validation passed: focused regression 2/2, agent-runtime typecheck, all 353 agent-runtime tests, and protocol smoke E2E 18/18 (2 live-model cases skipped because credentials were not configured). CI JS and Rust checks were green; the Vercel status requires deployment authorization and was not a code failure.

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.

3 participants