Before submitting
Is your feature request related to a problem? Please describe.
When the OpenRouter provider is pointed at a reasoning model (e.g. GLM-4.5-Air, DeepSeek-R1), reasoning is on by default, which hurts an observation-extraction workload that doesn't need it:
- Slow processing — single-session generation takes several minutes because every request spends time in the thinking phase.
- Empty responses — intermittent
[ERROR] [SDK] Empty response from OpenRouter / Empty OpenRouter init response. On a longer observation task the reasoning phase can consume the entire max_tokens: 4096 budget, leaving zero tokens for the final answer in choices[0].message.content, so the worker treats the response as empty.
A probe against GLM-4.5-Air shows how lopsided this is — for a trivial reply it burns ~89 of 90 completion tokens on reasoning:
POST /chat/completions
messages:[{role:user, content:"Think briefly, then reply with exactly: PONG"}]
max_tokens: 2048
→ message { content:"PONG", reasoning_content:"We are being asked to think..." }
→ usage.completion_tokens = 90 (content ≈ 1 token, reasoning ≈ 89 tokens)
claude-mem only reads choices[0].message.content, so all reasoning tokens are discarded overhead.
Root cause — the OpenRouter request body is hard-coded with no reasoning control, and there is no settings key to influence it. src/services/worker/OpenRouterProvider.ts (671de5e):
body: JSON.stringify({
model,
messages,
temperature: 0.3, // Lower temperature for structured extraction
max_tokens: 4096,
}),
No reasoning / reasoning_effort / max_completion_tokens field is sent, so reasoning behavior is decided entirely by the model's default (on, for reasoning models).
Describe the solution you'd like
Add a setting that maps to OpenRouter's unified reasoning parameter:
| Setting |
Values |
Default |
Effect |
CLAUDE_MEM_OPENROUTER_REASONING_EFFORT |
none / minimal / low / medium / high |
unset (model default) |
When set, emits reasoning: { effort } in the request body. none disables reasoning. |
This mirrors how CLAUDE_MEM_OPENROUTER_MAX_CONTEXT_MESSAGES already makes a previously hard-coded behavior tunable (#2416 is a good precedent for this kind of "make the hard-coded configurable" change).
Ideally the field would be emitted only when the model advertises support for it (via OpenRouter's supported_parameters), to avoid HTTP 400 on models that reject reasoning.
Describe alternatives you've considered
- Switch to a non-reasoning model — works, but users have to discover on their own that claude-mem can't disable reasoning, and some provider plans (e.g. Zhipu GLM Coding Plan) ship primarily reasoning models.
- Raise
max_tokens — doesn't address the wasted reasoning tokens or the latency, and the field is hard-coded today anyway.
Additional context
Before submitting
reasoning,reasoning_effort,empty response openrouter) and confirmed this is not a duplicate.Is your feature request related to a problem? Please describe.
When the OpenRouter provider is pointed at a reasoning model (e.g. GLM-4.5-Air, DeepSeek-R1), reasoning is on by default, which hurts an observation-extraction workload that doesn't need it:
[ERROR] [SDK] Empty response from OpenRouter/Empty OpenRouter init response. On a longer observation task the reasoning phase can consume the entiremax_tokens: 4096budget, leaving zero tokens for the final answer inchoices[0].message.content, so the worker treats the response as empty.A probe against GLM-4.5-Air shows how lopsided this is — for a trivial reply it burns ~89 of 90 completion tokens on reasoning:
claude-mem only reads
choices[0].message.content, so all reasoning tokens are discarded overhead.Root cause — the OpenRouter request body is hard-coded with no reasoning control, and there is no settings key to influence it.
src/services/worker/OpenRouterProvider.ts(671de5e):No
reasoning/reasoning_effort/max_completion_tokensfield is sent, so reasoning behavior is decided entirely by the model's default (on, for reasoning models).Describe the solution you'd like
Add a setting that maps to OpenRouter's unified
reasoningparameter:CLAUDE_MEM_OPENROUTER_REASONING_EFFORTnone/minimal/low/medium/highreasoning: { effort }in the request body.nonedisables reasoning.This mirrors how
CLAUDE_MEM_OPENROUTER_MAX_CONTEXT_MESSAGESalready makes a previously hard-coded behavior tunable (#2416 is a good precedent for this kind of "make the hard-coded configurable" change).Ideally the field would be emitted only when the model advertises support for it (via OpenRouter's
supported_parameters), to avoid HTTP 400 on models that rejectreasoning.Describe alternatives you've considered
max_tokens— doesn't address the wasted reasoning tokens or the latency, and the field is hard-coded today anyway.Additional context
reasoning: { effort: "none" }disables reasoning).worker-service.cjs) and currentmainOpenRouterProvider.ts.CLAUDE_MEM_PROVIDER=openrouterviaCLAUDE_MEM_OPENROUTER_BASE_URL→ Zhipu GLM Coding Plan, modelglm-4.5-air(reasoning: true, context 131072, cost $0).