Skip to content

Feature request: support disabling reasoning for OpenRouter / OpenAI-compatible providers #2995

Description

@collforkj

Before submitting

  • I searched existing issues (queries: 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:

  1. Slow processing — single-session generation takes several minutes because every request spends time in the thinking phase.
  2. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions