mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 11:30:44 +00:00
* fix(models): block stale openai-codex/gpt-5.4-mini inline entries via unconditional suppression (#74451) Suppress explicitly user-configured openai-codex/gpt-5.4-mini inline entries so a stale models config written by `openclaw doctor --fix` cannot bypass the manifest capability block and cause repeated assistant-turn failures when the runtime switches to that model on ChatGPT-backed Codex accounts. Adds `unconditionalOnly` flag to `buildManifestBuiltInModelSuppressionResolver` and a `shouldUnconditionallySuppress` helper. Inside `resolveExplicitModelWithRegistry`, inline matches are now gated on unconditional suppressions (no `when` clause) before returning. Conditional suppressions such as the qwen Coding Plan endpoint guard remain bypassable by explicit user configuration, preserving the existing `resolves explicitly configured qwen3.6-plus before Coding Plan built-in suppression` behaviour. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(changelog): add missing reporter attribution for #74451 models suppression fix * docs: credit codex mini suppression contributors --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Shakker <shakkerdroid@gmail.com>
106 lines
3.3 KiB
TypeScript
106 lines
3.3 KiB
TypeScript
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
|
import {
|
|
buildManifestBuiltInModelSuppressionResolver,
|
|
resolveManifestBuiltInModelSuppression,
|
|
} from "../plugins/manifest-model-suppression.js";
|
|
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
|
|
import { normalizeProviderId } from "./provider-id.js";
|
|
|
|
function resolveBuiltInModelSuppressionFromManifest(params: {
|
|
provider?: string | null;
|
|
id?: string | null;
|
|
baseUrl?: string | null;
|
|
config?: OpenClawConfig;
|
|
unconditionalOnly?: boolean;
|
|
}) {
|
|
const provider = normalizeProviderId(params.provider ?? "");
|
|
const modelId = normalizeLowercaseStringOrEmpty(params.id);
|
|
if (!provider || !modelId) {
|
|
return undefined;
|
|
}
|
|
return resolveManifestBuiltInModelSuppression({
|
|
provider,
|
|
id: modelId,
|
|
...(params.config ? { config: params.config } : {}),
|
|
...(params.baseUrl ? { baseUrl: params.baseUrl } : {}),
|
|
unconditionalOnly: params.unconditionalOnly,
|
|
env: process.env,
|
|
});
|
|
}
|
|
|
|
function resolveBuiltInModelSuppression(params: {
|
|
provider?: string | null;
|
|
id?: string | null;
|
|
baseUrl?: string | null;
|
|
config?: OpenClawConfig;
|
|
}) {
|
|
const manifestResult = resolveBuiltInModelSuppressionFromManifest(params);
|
|
if (manifestResult?.suppress) {
|
|
return manifestResult;
|
|
}
|
|
const provider = normalizeProviderId(params.provider ?? "");
|
|
const modelId = normalizeLowercaseStringOrEmpty(params.id);
|
|
if (!provider || !modelId) {
|
|
return undefined;
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
export function shouldSuppressBuiltInModelFromManifest(params: {
|
|
provider?: string | null;
|
|
id?: string | null;
|
|
config?: OpenClawConfig;
|
|
}) {
|
|
return resolveBuiltInModelSuppressionFromManifest(params)?.suppress ?? false;
|
|
}
|
|
|
|
export function shouldSuppressBuiltInModel(params: {
|
|
provider?: string | null;
|
|
id?: string | null;
|
|
baseUrl?: string | null;
|
|
config?: OpenClawConfig;
|
|
}) {
|
|
return resolveBuiltInModelSuppression(params)?.suppress ?? false;
|
|
}
|
|
|
|
// Checks only unconditional suppressions (no `when` clause). Used for inline
|
|
// model entries where user configuration may override conditional suppressions
|
|
// (e.g. custom endpoint overrides) but not absolute provider capability blocks.
|
|
export function shouldUnconditionallySuppress(params: {
|
|
provider?: string | null;
|
|
id?: string | null;
|
|
config?: OpenClawConfig;
|
|
}): boolean {
|
|
return (
|
|
resolveBuiltInModelSuppressionFromManifest({ ...params, unconditionalOnly: true })?.suppress ??
|
|
false
|
|
);
|
|
}
|
|
|
|
export function buildSuppressedBuiltInModelError(params: {
|
|
provider?: string | null;
|
|
id?: string | null;
|
|
baseUrl?: string | null;
|
|
config?: OpenClawConfig;
|
|
}): string | undefined {
|
|
return resolveBuiltInModelSuppression(params)?.errorMessage;
|
|
}
|
|
|
|
export function buildShouldSuppressBuiltInModel(params: {
|
|
config?: OpenClawConfig;
|
|
}): (input: { provider?: string | null; id?: string | null; baseUrl?: string | null }) => boolean {
|
|
const resolver = buildManifestBuiltInModelSuppressionResolver({
|
|
config: params.config,
|
|
env: process.env,
|
|
});
|
|
|
|
return (input) => {
|
|
const provider = normalizeProviderId(input.provider ?? "");
|
|
const id = normalizeLowercaseStringOrEmpty(input.id);
|
|
if (!provider || !id) {
|
|
return false;
|
|
}
|
|
return resolver({ ...input, provider, id })?.suppress ?? false;
|
|
};
|
|
}
|