diff --git a/src/commands/doctor-legacy-config.migrations.test.ts b/src/commands/doctor-legacy-config.migrations.test.ts index 4acf83c5262..f5d0f0e30ff 100644 --- a/src/commands/doctor-legacy-config.migrations.test.ts +++ b/src/commands/doctor-legacy-config.migrations.test.ts @@ -759,6 +759,28 @@ describe("normalizeCompatibilityConfigValues", () => { ]); }); + it("does not report talk provider normalization for semantically identical key ordering differences", () => { + const input = { + talk: { + interruptOnSpeech: true, + silenceTimeoutMs: 1500, + providers: { + elevenlabs: { + apiKey: "secret-key", + voiceId: "voice-123", + modelId: "eleven_v3", + }, + }, + provider: "elevenlabs", + }, + }; + + const res = normalizeCompatibilityConfigValues(input); + + expect(res.config).toEqual(input); + expect(res.changes).toEqual([]); + }); + it("migrates tools.message.allowCrossContextSend to canonical crossContext settings", () => { const res = normalizeCompatibilityConfigValues({ tools: { diff --git a/src/commands/doctor-legacy-config.ts b/src/commands/doctor-legacy-config.ts index 0e5c89c47f7..d34cb54433f 100644 --- a/src/commands/doctor-legacy-config.ts +++ b/src/commands/doctor-legacy-config.ts @@ -1,5 +1,6 @@ import { migrateVoiceCallLegacyConfigInput } from "../../extensions/voice-call/config-api.js"; import { normalizeProviderId } from "../agents/model-selection.js"; +import { isDeepStrictEqual } from "node:util"; import { shouldMoveSingleAccountChannelKey } from "../channels/plugins/setup-helpers.js"; import type { OpenClawConfig } from "../config/config.js"; import { resolveNormalizedProviderModelMaxTokens } from "../config/defaults.js"; @@ -386,7 +387,7 @@ export function normalizeCompatibilityConfigValues(cfg: OpenClawConfig): { return; } - const sameShape = JSON.stringify(normalizedTalk) === JSON.stringify(rawTalk); + const sameShape = isDeepStrictEqual(normalizedTalk, rawTalk); if (sameShape) { return; }