Skip to content

fix: preserve explicit input modality override in mergeProviderModels (#74552)#1

Draft
samson1357924 wants to merge 11 commits intomainfrom
fix/merge-logic
Draft

fix: preserve explicit input modality override in mergeProviderModels (#74552)#1
samson1357924 wants to merge 11 commits intomainfrom
fix/merge-logic

Conversation

@samson1357924
Copy link
Copy Markdown
Owner

Summary

When a user configures input: ['text', 'image'] in openclaw.json, the merge logic in mergeProviderModels was incorrectly falling back to the system default input: ['text'] instead of preserving the user's explicit configuration.

Root Cause

The check "input" in explicitModel could fail to detect explicitly set input values due to deserialization edge cases, causing the system to fall back to implicitModel.input (the system default).

Fix

Changed the check from:

input: "input" in explicitModel ? explicitModel.input : implicitModel.input,

To:

input: explicitModel.input !== undefined ? explicitModel.input : implicitModel.input,

This ensures that any explicitly set input value (including empty arrays) is preserved during the merge process, rather than being overwritten by the system default.

Testing

The existing test case preserves explicit input modality overrides when implicit metadata has the same model id in src/agents/models-config.merge.test.ts validates this behavior.

Related Issue

Fixes openclaw#74552
Fixes openclaw#65431 (related model capability misdetection)

bek91 and others added 11 commits May 2, 2026 22:27
Resolve bare official external plugin IDs through the official catalog before generic npm fallback, preserving explicit npm semantics and catalog integrity through the hook-pack fallback.\n\nFixes openclaw#76373.\n\nThanks @bek91 and @vincentkoc.
When a user configures input: ['text', 'image'] in openclaw.json, the merge
logic should preserve this configuration over the system default (input: ['text']).

Previously, the check 'input in explicitModel' could fail to detect
explicitly set input values due to deserialization edge cases, causing
the system to fall back to implicitModel.input. This change uses
'explicitModel.input !== undefined' to ensure any explicitly set input
value (including empty arrays) is preserved.

Fixes openclaw#74552
…penclaw#76406)

* fix(gateway): read-only fast path for models.list catalog loading

The gateway model catalog refresh calls loadModelCatalog without
readOnly, triggering ensureOpenClawModelsJson (60-70s), full PI SDK
registry instantiation, auth storage discovery, and live provider
plugin augmentation on every Control UI list/refresh. None of this
is needed for a read-only UI listing.

Three changes:

1. Gateway catalog refresh now passes readOnly: true to loadModelCatalog.
2. In readOnly mode, skip augmentModelCatalogWithProviderPlugins — live
   provider discovery is explicit admin/background work, not a UI list
   operation.
3. Add a persisted models.json fast path: when readOnly is true, first
   try reading the existing models.json directly and converting
   providers.<provider>.models[] to catalog rows. Falls back to the
   full PI registry path if the file is missing or unreadable.

Observed improvement on a production install:
  loadGatewayModelCatalog: 967 entries / 4651ms → 89 entries / 8ms
  Live models.list during startup: ~18s → ~2s

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(gateway): preserve full model catalog view

* fix(agents): preserve read-only catalog defaults

* fix(agents): preserve provider catalog defaults

---------

Co-authored-by: Marvinthebored <peter@lindsey.jp>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
…hesis fallback (openclaw#76428)

* fix(openai-codex): honor providerConfig.baseUrl in dynamic-model synthesis fallback

The synthesis fallback in resolveCodexForwardCompatModel hardcoded
OPENAI_CODEX_BASE_URL when the model registry had no template row to
clone, which meant openai-codex providers configured with a custom
baseUrl (e.g. a local proxy that forwards Codex traffic) silently
fell back to api.openai.com / chatgpt.com - bypassing the proxy and
typically failing the auth contract.

Synthesis now reads ctx.providerConfig.baseUrl when present, with the
existing OPENAI_CODEX_BASE_URL constant as the fallback. No effect on
template-clone or registry-find paths, which already inherit the
configured baseUrl through the cloned template.

* docs(changelog): add Unreleased Fixes entry for openclaw#76428 codex synthesis baseUrl honor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

5 participants