Bug: reasoning_content is replayed in the request history, causing tool-call markup leakage
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 66/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- typescript
調査の方向性
まず、セッション履歴がプロバイダーへのリクエストペイロードにどのように組み立てられるかを追跡し、次にアシスタントのメッセージが reasoning_content を保持する箇所を見つけてください。そのフィールドが後続のリクエストで送信されるか、またリクエスト構築経路に推論モデル向けのテストがあるかを確認してください。履歴では表示用の推論を引き続き保持でき、リクエストではそれを省略し、その動作を回帰テストで確認できれば完了です。
索引モデルが issue の本文から書いたものです。
説明
opencode persists the model's reasoning_content (chain-of-thought) in the session history and sends it back in every subsequent request. DeepSeek's API states that reasoning_content is the current turn's CoT and must not be passed back.
Impact: with reasoning models (e.g. deepseek-v4.1-flash), the model imitates patterns from its own past reasoning - including malformed tool-call markup - so tool calls are silently lost (tool_calls == 0, finish_reason == "stop"). It is self-reinforcing: the more it leaks, the more that markup appears in reasoning.
A/B (one captured opencode request, 1011 messages / 4.78 MB, replayed to the same endpoint with a "write a ~120-line script" instruction appended):
| variant | leak rate |
|---|---|
with reasoning_content |
4 / 5 |
without reasoning_content |
0 / 5 |
| last 300 msgs, with | 2 / 5 |
| last 300 msgs, without | 0 / 5 |
"Leak" is defined strictly as: markup inside delta.content and tool_calls == 0 and finish_reason == "stop".
Observed message structure in the captured request: assistant messages 480, of which reasoning_content present in 480.
Excluded by A/B: max_tokens (256k vs 128k -> 4/5 vs 4/5), system prompt content, temperature, tool_choice, parallel_tool_calls, thinking/reasoning_effort fields, and endpoint (official api.deepseek.com vs the opencode gateway). The dose-response (100 msgs 0/5 -> 300 msgs 2-3/5 -> 1009 msgs 4/5) is fully explained by the replayed CoT.
A different client (CodeBuddy) with the same model and the same real leaked-text corpus in a 1.13 MB history does not reproduce it (0/5).
Suggested fix: do not send reasoning_content back when building the request payload (keep it for UI display only); optionally gate behind a provider/model capability flag.
Reproduction: run a long session with a reasoning model, then ask it to write a long file - occasionally the tool call is emitted as text; re-sending the same request with reasoning_content stripped removes the failure (0/5 vs 4/5).
Environment: opencode 2.0.30 (Windows), providers opencode-go and official deepseek, model deepseek-v4.1-flash (variant max).
- 主要言語
- TypeScript
- スター
- 215k
- フォーク
- 28.9k
- 平均マージ
- 7時間 53分
- マージ済み PR(30日)
- 278
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
anomalyco/opencode のほかの issue
-
pending close triaging
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
anomalyco/opencode#56765 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
anomalyco/opencode#56735 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
anomalyco/opencode#56663 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
pending close triaging
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
anomalyco/opencode#56625 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
anomalyco/opencode#56624 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
anomalyco/opencode の issue をすべて見る
似ている issue
-
難易度 1/5 1時間未満 初心者へのやさしさ 65/100
521xueweihan/HelloGitHub#4025 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
voidzero-dev/void#478 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 69/100
Small-tailqwq/dsh-deep-whale#207 ·
メンテナーはふだん 1 日以内に返信
-
The inspector never shows the instances field, so scaling out is unreachable対応中かも @Mrkewl が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
xevrion/breakscale#96 ·
メンテナーはふだん 4 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
Flux159/mcp-server-kubernetes#384 ·