openclaw - 💡(How to fix) Fix Feature: pass-through extra_body for openai-completions adapter [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#69717Fetched 2026-04-22 07:49:03
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
1
Author
Participants

Allow users to configure arbitrary provider-specific request-body fields via agents.defaults.models["<prov>/<id>"].params.extra_body (or extraBody). These fields should be merged into the outgoing JSON payload for models using the openai-completions adapter.

Error Message

allowed but logged at warn level, so power users can override if needed

Root Cause

Allow users to configure arbitrary provider-specific request-body fields via agents.defaults.models["<prov>/<id>"].params.extra_body (or extraBody). These fields should be merged into the outgoing JSON payload for models using the openai-completions adapter.

Fix Action

Fix / Workaround

Allow users to configure arbitrary provider-specific request-body fields via agents.defaults.models["<prov>/<id>"].params.extra_body (or extraBody). These fields should be merged into the outgoing JSON payload for models using the openai-completions adapter.

function createExtraBodyWrapper(baseStreamFn, extraBody) {
  const underlying = baseStreamFn ?? streamSimple;
  return (model, context, options) => {
    if (model.api !== "openai-completions") return underlying(model, context, options);
    if (!extraBody || typeof extraBody !== "object") return underlying(model, context, options);
    return streamWithPayloadPatch(underlying, model, context, options, (payloadObj) => {
      for (const [k, v] of Object.entries(extraBody)) {
        if (v !== undefined) payloadObj[k] = v;
      }
    });
  };
}

A working out-of-tree patch using streamWithPayloadPatch is already deployed locally in ~/.openclaw/patches/extra-body-passthrough.patch.js — happy to port it into a PR if useful.

Code Example

function createExtraBodyWrapper(baseStreamFn, extraBody) {
  const underlying = baseStreamFn ?? streamSimple;
  return (model, context, options) => {
    if (model.api !== "openai-completions") return underlying(model, context, options);
    if (!extraBody || typeof extraBody !== "object") return underlying(model, context, options);
    return streamWithPayloadPatch(underlying, model, context, options, (payloadObj) => {
      for (const [k, v] of Object.entries(extraBody)) {
        if (v !== undefined) payloadObj[k] = v;
      }
    });
  };
}

---

{
  "agents": {
    "defaults": {
      "models": {
        "dashscope/qwen3.6-max-preview": {
          "alias": "Qwen 3.6 Max Preview",
          "params": {
            "extra_body": {
              "preserve_thinking": true,
              "enable_thinking": true
            }
          }
        }
      }
    }
  }
}
RAW_BUFFERClick to expand / collapse

Feature Request: pass-through extra_body for openai-completions adapter

Summary

Allow users to configure arbitrary provider-specific request-body fields via agents.defaults.models["<prov>/<id>"].params.extra_body (or extraBody). These fields should be merged into the outgoing JSON payload for models using the openai-completions adapter.

Motivation

Many OpenAI-compatible providers expose non-standard parameters that must be set in the request body. Examples:

ProviderModelParamPurpose
DashScope / Alibabaqwen3.6-max-previewpreserve_thinkingRetain <think> blocks across multi-turn agent loops
DashScope / Alibabaqwen3-max-preview, qwen3.5-*enable_thinkingToggle internal reasoning mode
SiliconFlow / Moonshotvariousalready handled in-tree via createMoonshotThinkingWrapper(reference: existing precedent)
OpenRoutermanyprovider, route, transformsRouting hints
Fireworksvariousmax_reasoning_tokens, response_format.schemaReasoning + schema

Currently, createStreamFnWithExtraParams only whitelists a fixed set (temperature, maxTokens, transport, openaiWsWarmup, cachedContent, cacheRetention), and applyPostPluginStreamWrappers adds a single parallel_tool_calls override. Users cannot add new provider-specific params without modifying the OpenClaw source.

Proposed change

Add a generic wrapper analogous to createParallelToolCallsWrapper:

function createExtraBodyWrapper(baseStreamFn, extraBody) {
  const underlying = baseStreamFn ?? streamSimple;
  return (model, context, options) => {
    if (model.api !== "openai-completions") return underlying(model, context, options);
    if (!extraBody || typeof extraBody !== "object") return underlying(model, context, options);
    return streamWithPayloadPatch(underlying, model, context, options, (payloadObj) => {
      for (const [k, v] of Object.entries(extraBody)) {
        if (v !== undefined) payloadObj[k] = v;
      }
    });
  };
}

Wire it into applyPostPluginStreamWrappers by reading resolveAliasedParamValue(sources, "extra_body", "extraBody").

Scope initially to openai-completions (where the need is greatest). Future extension: allow on openai-responses and anthropic-messages behind per-adapter validation.

Config shape

{
  "agents": {
    "defaults": {
      "models": {
        "dashscope/qwen3.6-max-preview": {
          "alias": "Qwen 3.6 Max Preview",
          "params": {
            "extra_body": {
              "preserve_thinking": true,
              "enable_thinking": true
            }
          }
        }
      }
    }
  }
}

Backward compatible — only activates when extra_body is present.

Safety considerations

  • Collisions with core fields (e.g. messages, model, tools) should be allowed but logged at warn level, so power users can override if needed but accidental shadowing is visible.
  • No value sanitization required beyond basic type check: users explicitly opt in via config; schema validation should only check object-ness.
  • Keys with undefined values are skipped.

Reference implementation

A working out-of-tree patch using streamWithPayloadPatch is already deployed locally in ~/.openclaw/patches/extra-body-passthrough.patch.js — happy to port it into a PR if useful.

Tests

  • Unit: createExtraBodyWrapper merges keys, skips on non-openai-completions, skips undefined values, passes through when extra_body is empty.
  • Integration: end-to-end stream against a mock openai-compatible endpoint asserts payload contains the extra keys.

extent analysis

TL;DR

To implement the pass-through extra_body feature for the openai-completions adapter, add a generic wrapper function createExtraBodyWrapper and integrate it into applyPostPluginStreamWrappers.

Guidance

  • Implement the createExtraBodyWrapper function as proposed, which merges arbitrary provider-specific request-body fields into the outgoing JSON payload.
  • Integrate this wrapper into applyPostPluginStreamWrappers by reading resolveAliasedParamValue(sources, "extra_body", "extraBody").
  • Ensure the config shape is as specified, allowing users to configure extra_body for specific models.
  • Implement unit and integration tests to verify the functionality, including key merging, skipping on non-openai-completions, and passing through when extra_body is empty.

Example

function createExtraBodyWrapper(baseStreamFn, extraBody) {
  // implementation as proposed
}

Notes

The proposed change is backward compatible and only activates when extra_body is present in the config. It allows collisions with core fields but logs a warning to prevent accidental shadowing.

Recommendation

Apply the proposed workaround by implementing the createExtraBodyWrapper function and integrating it into applyPostPluginStreamWrappers, as this provides the necessary functionality for passing through extra_body for the openai-completions adapter.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix Feature: pass-through extra_body for openai-completions adapter [1 participants]