mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:50:43 +00:00
fix(status): tolerate malformed session model refs
This commit is contained in:
@@ -29,6 +29,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Fixes
|
||||
|
||||
- Status/sessions: ignore malformed non-string persisted session provider/model metadata instead of throwing while rendering status summaries. Thanks @vincentkoc.
|
||||
- CLI/config: remove only the targeted array element for `openclaw config unset array[index]` instead of replaying the unset during config write and deleting the shifted next element. Fixes #76290. Thanks @SymbolStar and @vincentkoc.
|
||||
- Agents/tools: stop treating `tools.deny: ["write"]` as an implicit `apply_patch` deny; operators who want to block patch writes should deny `apply_patch` or `group:fs` explicitly. Fixes #76749. (#76795) Thanks @Nek-12 and @hclsys.
|
||||
- Plugins/release: verify published plugin npm tarballs expose compiled runtime entries after publish, catching TS-only package artifacts before release closeout. Thanks @vincentkoc.
|
||||
|
||||
@@ -448,6 +448,18 @@ describe("model-selection", () => {
|
||||
model: "anthropic/claude-haiku-4.5",
|
||||
});
|
||||
});
|
||||
|
||||
it("ignores malformed persisted model metadata instead of throwing", () => {
|
||||
expect(
|
||||
resolvePersistedSelectedModelRef({
|
||||
defaultProvider: "anthropic",
|
||||
runtimeProvider: { provider: "openai" },
|
||||
runtimeModel: false,
|
||||
overrideProvider: ["openrouter"],
|
||||
overrideModel: 123,
|
||||
}),
|
||||
).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("inferUniqueProviderFromConfiguredModels", () => {
|
||||
|
||||
@@ -4,7 +4,10 @@ import {
|
||||
toAgentModelListLike,
|
||||
} from "../config/model-input.js";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalString,
|
||||
} from "../shared/string-coerce.js";
|
||||
import {
|
||||
resolveAgentConfig,
|
||||
resolveAgentEffectiveModelPrimary,
|
||||
@@ -80,13 +83,13 @@ export { isCliProvider } from "./model-selection-cli.js";
|
||||
|
||||
export function resolvePersistedOverrideModelRef(params: {
|
||||
defaultProvider: string;
|
||||
overrideProvider?: string;
|
||||
overrideModel?: string;
|
||||
overrideProvider?: unknown;
|
||||
overrideModel?: unknown;
|
||||
allowPluginNormalization?: boolean;
|
||||
}): ModelRef | null {
|
||||
const defaultProvider = params.defaultProvider.trim();
|
||||
const overrideProvider = params.overrideProvider?.trim();
|
||||
const overrideModel = params.overrideModel?.trim();
|
||||
const overrideProvider = normalizeOptionalString(params.overrideProvider);
|
||||
const overrideModel = normalizeOptionalString(params.overrideModel);
|
||||
if (!overrideModel) {
|
||||
return null;
|
||||
}
|
||||
@@ -107,15 +110,15 @@ export function resolvePersistedOverrideModelRef(params: {
|
||||
*/
|
||||
export function resolvePersistedModelRef(params: {
|
||||
defaultProvider: string;
|
||||
runtimeProvider?: string;
|
||||
runtimeModel?: string;
|
||||
overrideProvider?: string;
|
||||
overrideModel?: string;
|
||||
runtimeProvider?: unknown;
|
||||
runtimeModel?: unknown;
|
||||
overrideProvider?: unknown;
|
||||
overrideModel?: unknown;
|
||||
allowPluginNormalization?: boolean;
|
||||
}): ModelRef | null {
|
||||
const defaultProvider = params.defaultProvider.trim();
|
||||
const runtimeProvider = params.runtimeProvider?.trim();
|
||||
const runtimeModel = params.runtimeModel?.trim();
|
||||
const runtimeProvider = normalizeOptionalString(params.runtimeProvider);
|
||||
const runtimeModel = normalizeOptionalString(params.runtimeModel);
|
||||
if (runtimeModel) {
|
||||
if (runtimeProvider) {
|
||||
return { provider: runtimeProvider, model: runtimeModel };
|
||||
@@ -144,10 +147,10 @@ export function resolvePersistedModelRef(params: {
|
||||
*/
|
||||
export function resolvePersistedSelectedModelRef(params: {
|
||||
defaultProvider: string;
|
||||
runtimeProvider?: string;
|
||||
runtimeModel?: string;
|
||||
overrideProvider?: string;
|
||||
overrideModel?: string;
|
||||
runtimeProvider?: unknown;
|
||||
runtimeModel?: unknown;
|
||||
overrideProvider?: unknown;
|
||||
overrideModel?: unknown;
|
||||
allowPluginNormalization?: boolean;
|
||||
}): ModelRef | null {
|
||||
const override = resolvePersistedOverrideModelRef({
|
||||
|
||||
@@ -106,4 +106,18 @@ describe("statusSummaryRuntime.resolveSessionModelRef", () => {
|
||||
model: "gpt-5.4",
|
||||
});
|
||||
});
|
||||
|
||||
it("falls back to configured defaults when persisted session model fields are malformed", () => {
|
||||
expect(
|
||||
statusSummaryRuntime.resolveSessionModelRef(cfg, {
|
||||
modelProvider: { provider: "openai" },
|
||||
model: false,
|
||||
providerOverride: ["anthropic"],
|
||||
modelOverride: 123,
|
||||
} as never),
|
||||
).toEqual({
|
||||
provider: "anthropic",
|
||||
model: "claude-sonnet-4-6",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user