fix(provider): stabilize LM Studio Qwen requests#26744
fix(provider): stabilize LM Studio Qwen requests#26744ipogosov wants to merge 1 commit intoanomalyco:devfrom
Conversation
|
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
|
The following comment was made by an LLM, it may be inaccurate: Based on my search results, here are the potentially related PRs:
The most directly related appears to be PR #15732 since it specifically deals with LM Studio provider behavior. The others address related prompt caching and message stability concerns that may overlap with your Qwen request stabilization work. |
|
Thanks for updating your PR! It now meets our contributing guidelines. 👍 |
|
Thanks for updating your PR! It now meets our contributing guidelines. 👍 |
Issue for this PR
Closes #26750
Type of change
What does this PR do?
LM Studio's prefix cache only hits when the tokenized prompt prefix is byte-stable across turns. When OpenCode replays a Qwen / QwQ-family model's conversation history through LM Studio's OpenAI-compatible endpoint, two things make that prefix unstable:
reasoningcontent gets re-rendered differently by the Qwen chat template once a new user message is appended, so the same historical assistant turn tokenizes differently the second time it is in the prompt.role: "tool"messages get rendered inconsistently by Qwen-style templates, while<tool_response>...</tool_response>blocks embedded in the surrounding turn render stably.This PR makes the model-visible history stable for that specific provider/model shape, without changing behavior for non-Qwen OpenAI-compatible backends or for Anthropic/OpenAI proper:
<tool_response>blocks. In the outgoing OpenAI-compatible JSON body, rawrole: "tool"messages are converted into<tool_response>...</tool_response>text wrapped onto the previous turn for Qwen/QwQ-like LM Studio models. Non-Qwen targets keep the normal OpenAI-compatible tool-message shape.providerOptionsso the underlying provider/SDK only sees standard fields.There are tests covering both the default normalization behavior and the opt-out (i.e. that a non-Qwen LM Studio model is not affected). The change is gated by provider+model detection; it does not run for Anthropic, OpenAI, or arbitrary OpenAI-compatible endpoints.
This is intentionally separate from the plan-mode reminder persistence fix in the sibling PR. That one is a general OpenCode history-stability bug; this PR is provider/model compatibility behavior for LM Studio Qwen-style chat templates.
How did you verify your code works?
bun typecheckfrompackages/opencodebun test test/provider/transform.test.ts— covers the default tool-message-to-<tool_response>rewrite for LM Studio Qwen-shaped requests, the reasoning-strip on replayed assistant turns, and the opt-out path for non-Qwen models so they keep the standard OpenAI-compatible shape.Screenshots / recordings
N/A, non-UI change.
Checklist