Add OpenRouter provider routing params#84579
Conversation
|
Codex review: needs maintainer review before merge. Workflow note: Future ClawSweeper reviews update this same comment in place. How this review workflow works
Summary Reproducibility: not applicable. this is a feature PR rather than a broken-behavior report. Source inspection shows current main already has per-model routing, while the PR adds the new provider-wide default path and payload serialization tests. PR rating Rank-up moves:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. Real behavior proof Risk before merge
Maintainer options:
Next step before merge Security Review detailsBest possible solution: Land the provider-owned hook if maintainers accept provider-wide OpenRouter routing defaults as intentional upgrade behavior, with focused tests covering default, per-model, and explicit override precedence. Do we have a high-confidence way to reproduce the issue? Not applicable; this is a feature PR rather than a broken-behavior report. Source inspection shows current main already has per-model routing, while the PR adds the new provider-wide default path and payload serialization tests. Is this the best way to solve the issue? Yes, the provider-owned Label changes:
Label justifications:
What I checked:
Likely related people:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 9c00268914b9. |
|
ClawSweeper PR egg ✨ Hatched: 🥚 common Velvet Lint Imp Hatch commandComment Hatchability rules:
Rarity: 🥚 common. What is this egg doing here?
|
The 94ac563 dep bump moved oxlint to 1.65.0 (with unicorn no-useless-fallback-in-spread enforced), and the OpenRouter provider routing helper added in #84579 (merged into main after this branch opened) uses '...(value ?? {})' on records that may be undefined. Spreading undefined already yields {}, so the empty fallbacks are redundant. Drop them so check-lint and check-additional-extension-bundled go green.
…reads
`...(x ?? {})` and `...(cond ? {x} : {})` patterns trip oxlint's
`unicorn/no-useless-fallback-in-spread` rule because spreading `undefined`/
`false`/`null` into an object literal is already a no-op — the empty-object
fallback adds nothing. Removing the fallbacks restores `check-additional-
extension-bundled` to green; the lint regression was introduced by openclaw#84579 and
has been failing on every PR rebased onto current main since.
Behavior unchanged: `{ ...undefined }` evaluates to `{}` exactly like
`{ ...({} ?? {}) }`, and the conditional `provider: providerRouting` is now
set imperatively when truthy, matching the prior contract that only attaches
the key when a routing record is present.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
(cherry picked from commit 251c419)
…reads
`...(x ?? {})` and `...(cond ? {x} : {})` patterns trip oxlint's
`unicorn/no-useless-fallback-in-spread` rule because spreading `undefined`/
`false`/`null` into an object literal is already a no-op — the empty-object
fallback adds nothing. Removing the fallbacks restores `check-additional-
extension-bundled` to green; the lint regression was introduced by openclaw#84579 and
has been failing on every PR rebased onto current main since.
Behavior unchanged: `{ ...undefined }` evaluates to `{}` exactly like
`{ ...({} ?? {}) }`, and the conditional `provider: providerRouting` is now
set imperatively when truthy, matching the prior contract that only attaches
the key when a routing record is present.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
(cherry picked from commit 251c419)
* fix(errors): dedupe identical messages when traversing error .cause chain (openclaw#84556) Merged via squash. Prepared head SHA: 46aa27f Co-authored-by: RomneyDa <6581799+RomneyDa@users.noreply.github.com> Co-authored-by: altaywtf <9790196+altaywtf@users.noreply.github.com> Reviewed-by: @altaywtf * fix(cli): gate exported subcli descriptors (openclaw#84519) Summary: - This PR filters exported sub-CLI descriptors through the private-QA gate, centralizes that filter, adds regr ... ge, and carries small validation repairs in workspace glob and tunnel-timeout tests plus a changelog entry. - Reproducibility: yes. Current-main source shows the raw SUB_CLI_DESCRIPTORS export can include qa while the helper surfaces filter it, and src/cli/argv.ts consumes that export for root command policy. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(cli): gate exported subcli descriptors - PR branch already contained follow-up commit before automerge: fix(clawsweeper): address review for automerge-openclaw-openclaw-8451… Validation: - ClawSweeper review passed for head ba197a6. - Required merge gates passed before the squash merge. Prepared head SHA: ba197a6 Review: openclaw#84519 (comment) Co-authored-by: Zhaocun <zhaocunsun@gmail.com> Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com> * fix(doctor): migrate invalid thinking formats (openclaw#84626) * fix(cron-cli): bound loadCronJobForShow pagination (openclaw#83856) (openclaw#83989) Summary: - Adds a 50-page and advancing-`nextOffset` guard to `loadCronJobForShow`, exports that helper for regression tests, and adds an unreleased changelog entry. - Reproducibility: yes. Current main is source-reproducible because `loadCronJobForShow` loops while `hasMore` ... ed numeric `nextOffset`; the PR discussion also includes terminal before/after proof for the same CLI path. Automerge notes: - No ClawSweeper repair was needed after automerge opt-in. Validation: - ClawSweeper review passed for head 7828b4b. - Required merge gates passed before the squash merge. Prepared head SHA: 7828b4b Review: openclaw#83989 (comment) Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com> * fix(config): accept execApprovals.enabled="auto" in zod schema * fix: honour tool error suppression for mutating tools (openclaw#81561) Merged via squash. Prepared head SHA: 7462a86 Co-authored-by: moeedahmed <5780040+moeedahmed@users.noreply.github.com> Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com> Reviewed-by: @jalehman * Add OpenRouter provider routing params (openclaw#84579) Co-authored-by: Alex Knight <15041791+amknight@users.noreply.github.com> * Preserve AGENTS.md policy during bootstrap truncation (openclaw#82921) Fixes openclaw#82920 * chore: regenerate base config schema Updated after MODEL_THINKING_FORMATS changed from z.union literals to z.enum, and session/session.agentToAgent gained detailed help text. * Revert "Add OpenRouter provider routing params (openclaw#84579)" This reverts commit 53254dc. --------- Co-authored-by: Dallin Romney <dallinromney@gmail.com> Co-authored-by: RomneyDa <6581799+RomneyDa@users.noreply.github.com> Co-authored-by: altaywtf <9790196+altaywtf@users.noreply.github.com> Co-authored-by: Zhaocun Sun <zhaocunsun@gmail.com> Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com> Co-authored-by: Gio Della-Libera <giodl73@gmail.com> Co-authored-by: yaoyi1222 <yaoyi_1222@163.com> Co-authored-by: Sarah Fortune <sarah.fortune@gmail.com> Co-authored-by: Moeed Ahmed <drmoeedahmed@gmail.com> Co-authored-by: moeedahmed <5780040+moeedahmed@users.noreply.github.com> Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com> Co-authored-by: Alex Knight <aknight@atlassian.com> Co-authored-by: Alex Knight <15041791+amknight@users.noreply.github.com> Co-authored-by: Galin Iliev <iliev@galcho.com>
Co-authored-by: Alex Knight <15041791+amknight@users.noreply.github.com>
Co-authored-by: Alex Knight <15041791+amknight@users.noreply.github.com>
Co-authored-by: Alex Knight <15041791+amknight@users.noreply.github.com>
Co-authored-by: Alex Knight <15041791+amknight@users.noreply.github.com>
Co-authored-by: Alex Knight <15041791+amknight@users.noreply.github.com>
Co-authored-by: Alex Knight <15041791+amknight@users.noreply.github.com>
Co-authored-by: Alex Knight <15041791+amknight@users.noreply.github.com>
Co-authored-by: Alex Knight <15041791+amknight@users.noreply.github.com>
Co-authored-by: Alex Knight <15041791+amknight@users.noreply.github.com>
Co-authored-by: Alex Knight <15041791+amknight@users.noreply.github.com>
Co-authored-by: Alex Knight <15041791+amknight@users.noreply.github.com>
Summary
models.providers.openrouter.params.provider.providerpayload and documents the supported config path.Verification
node scripts/run-vitest.mjs extensions/openrouter/index.test.ts src/agents/pi-embedded-runner-extraparams-openrouter.test.tsgit diff --check -- CHANGELOG.md docs/gateway/config-agents.md docs/providers/openrouter.md extensions/openrouter/index.test.ts extensions/openrouter/index.ts extensions/openrouter/stream.tsgit diff --no-index --check /dev/null extensions/openrouter/provider-routing.tsautoreview clean: no accepted/actionable findings reportedOPENCLAW_STATE_DIR, OpenRouter key supplied via process stdin, debug capture enabled, andopenclaw agent --json --agent main --session-id e2e-openrouter-routing-success --model openrouter/auto --thinking off --message "Reply with exactly: OR_ROUTING_OK" --timeout 180Real behavior proof
Behavior addressed: OpenRouter provider-routing config now has a documented provider-wide path and is serialized into the OpenRouter request
providerpayload for chat-completions routes.Real environment tested: Real local OpenClaw Gateway from this branch on macOS, using a disposable state dir,
openrouter/auto, and a live OpenRouter API key supplied only through process stdin/environment.Exact steps or command run after this patch: Initialized disposable local config with
openclaw onboard --non-interactive --accept-risk --mode local --auth-choice skip --gateway-bind loopback --gateway-port 19179 --no-install-daemon --skip-channels --skip-search --skip-skills --skip-health, patchedmodels.providers.openrouter.params.provider, startedopenclaw gateway run --force --auth none --bind loopback --port 19179 --allow-unconfigured --verbosewith direct debug capture enabled, then ranopenclaw agent --json --agent main --session-id e2e-openrouter-routing-success --model openrouter/auto --thinking off --message "Reply with exactly: OR_ROUTING_OK" --timeout 180.Evidence after fix: Debug capture recorded outbound
POST https://openrouter.ai/api/v1/chat/completionswithAuthorizationpresent, modelopenrouter/auto,stream: true, and payloadprovider: { sort: "latency", data_collection: "deny" }; the corresponding OpenRouter response was HTTP 200text/event-stream. A prior capture with per-modelrequire_parameters: truerecordedprovider: { sort: "latency", data_collection: "deny", require_parameters: true }and OpenRouter returned its provider-routing 404, confirming the merged model-level knob was transmitted.Observed result after fix: The local Gateway completed the live agent turn successfully and returned exactly
OR_ROUTING_OK.What was not tested: A broad OpenRouter provider matrix and non-OpenRouter custom proxy routes were not exercised.