Skip to content

[Bug]: No config key to override dropReasoningFromHistory for openai-completions providers #88068

@syncword

Description

@syncword

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

All openai-completions models have their reasoning/thinking blocks stripped from replayed conversation history by default, except two models in a whitelist - with no way to override.

Steps to reproduce

  1. Use a custom model provider with openai-completions, and a model that emits reasoning blocks e.g. reasoning_content.
  2. Observe the reasoning blocks are unconditionally stripped from the context in later turns. There is currently no config key to override this behavior.

Expected behavior

Some models, e.g. Qwen3.6 series, make use of preserve_thinking and leverage reasoning content from prior turns. This requires the reasoning content be retained across turns. I was going to file as an RFE but unconditionally stripping all reasoning content seems to me more like a bug.

The issue #81058 suggested workaround (dropReasoningFromHistory: false in provider config) — does not work. The key is not in the schema (additionalProperties: false on provider schema), so validation rejects it.

Actual behavior

All openai-completions models have their reasoning/thinking blocks stripped from replayed conversation history by default, except two models in a whitelist - with no way to override.

OpenClaw version

2026.5.28

Operating system

Ubuntu 24.04

Install method

npm global

Model

Qwen3.6-35B-A3B

Provider / routing chain

openclaw -> llama.cpp (openai-completions API)

Additional provider/model setup details

No response

Logs, screenshots, and evidence

In `buildUnownedProviderTransportReplayFallback()` (attempt.tool-run-context.js), the transcript policy for `openai-completions` is hardcoded:


// Line ~577
...isStrictOpenAiCompatible ? { dropReasoningFromHistory: !requiresReasoningContentReplay(params.modelId) } : {}


This means `dropReasoningFromHistory: true` for all `openai-completions` models unless the model ID matches one of:
- `kimi-for-coding`, `kimi-k2.5`, `kimi-k2.6`, `kimi-k2-thinking`, `kimi-k2-thinking-turbo`
- `mimo-v2-pro`, `mimo-v2-omni`, `mimo-v2.5`, `mimo-v2.5-pro`, `mimo-v2.6-pro`

The `mergeTranscriptPolicy()` function already supports the override:


// Line ~618
...typeof policy.dropReasoningFromHistory === "boolean" ? { dropReasoningFromHistory: policy.dropReasoningFromHistory } : {}


But there is **no config path** that flows into `resolveTranscriptPolicy()` to provide that override. The `params` object is built from the runtime context, not from `openclaw.json`.

Impact and severity

Affected: users of openai-completions endpoint and a custom model provider
Severity: at best annoying, at worst can block workflow
Frequency: always
Consequence: degrades model response quality when in thinking mode

Additional information

Proposed Fix

Add a config path to models.providers.* (and optionally models.providers.*.models.*) that flows into resolveTranscriptPolicy().

Option A: Provider-level config

{
  "models": {
    "providers": {
      "my-provider": {
        "api": "openai-completions",
        "transcriptPolicy": {
          "dropReasoningFromHistory": false
        }
      }
    }
  }
}

Option B: Direct key (simpler)

{
  "models": {
    "providers": {
      "my-provider": {
        "api": "openai-completions",
        "dropReasoningFromHistory": false
      }
    }
  }
}

Option C: Per-model config (most granular)

{
  "models": {
    "providers": {
      "my-provider": {
        "api": "openai-completions",
        "models": [
          {
            "id": "my-model",
            "reasoning": true,
            "transcriptPolicy": {
              "dropReasoningFromHistory": false
            }
          }
        ]
      }
    }
  }
}

Files to Modify

  1. Schema (config.schema): Add transcriptPolicy (object with dropReasoningFromHistory?: boolean) to models.providers.* and/or models.providers.*.models.*

  2. resolveTranscriptPolicy() (attempt.tool-run-context.js): Read the config-level transcriptPolicy from the provider/model context and pass it into mergeTranscriptPolicy() so it can override the hardcoded fallback defaults.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.bugSomething isn't workingbug:behaviorIncorrect behavior without a crashclawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions