





















@@ -1,4 +1,5 @@
11import { afterEach, describe, expect, test } from "vitest";
2+import { resetProviderAuthAliasMapCacheForTest } from "../agents/provider-auth-aliases.js";
23import type { OpenClawConfig } from "../config/config.js";
34import type { SessionEntry } from "../config/sessions.js";
45import { createEmptyPluginRegistry } from "../plugins/registry-empty.js";
@@ -108,6 +109,7 @@ function createAllowlistedAnthropicModelCfg(): OpenClawConfig {
108109109110describe("gateway sessions patch", () => {
110111afterEach(() => {
112+resetProviderAuthAliasMapCacheForTest();
111113resetPluginRuntimeStateForTest();
112114});
113115@@ -271,7 +273,7 @@ describe("gateway sessions patch", () => {
271273expectPatchError(result, "invalid elevatedLevel");
272274});
273275274-test("clears auth overrides when model patch changes", async () => {
276+test("preserves same-provider auth overrides when model patch changes", async () => {
275277const store: Record<string, SessionEntry> = {
276278"agent:main:main": {
277279sessionId: "sess",
@@ -294,6 +296,151 @@ describe("gateway sessions patch", () => {
294296);
295297expect(entry.providerOverride).toBe("anthropic");
296298expect(entry.modelOverride).toBe("claude-sonnet-4-6");
299+expect(entry.authProfileOverride).toBe("anthropic:default");
300+expect(entry.authProfileOverrideSource).toBe("user");
301+expect(entry.authProfileOverrideCompactionCount).toBe(3);
302+});
303+304+test("preserves auth overrides for provider-auth aliases when model patch changes", async () => {
305+const store: Record<string, SessionEntry> = {
306+"agent:main:main": {
307+sessionId: "sess-alias",
308+updatedAt: 1,
309+providerOverride: "byteplus",
310+modelOverride: "seedance-1-0-lite-t2v-250428",
311+authProfileOverride: "byteplus:work",
312+authProfileOverrideSource: "user",
313+authProfileOverrideCompactionCount: 2,
314+} as SessionEntry,
315+};
316+const entry = expectPatchOk(
317+await runPatch({
318+ store,
319+patch: { key: MAIN_SESSION_KEY, model: "byteplus-plan/ark-code-latest" },
320+loadGatewayModelCatalog: async () => [
321+{ provider: "byteplus-plan", id: "ark-code-latest", name: "ark-code-latest" },
322+],
323+}),
324+);
325+expect(entry.providerOverride).toBe("byteplus-plan");
326+expect(entry.modelOverride).toBe("ark-code-latest");
327+expect(entry.authProfileOverride).toBe("byteplus:work");
328+expect(entry.authProfileOverrideSource).toBe("user");
329+expect(entry.authProfileOverrideCompactionCount).toBe(2);
330+});
331+332+test("preserves unprefixed auth overrides when existing provider matches model patch", async () => {
333+const store: Record<string, SessionEntry> = {
334+"agent:main:main": {
335+sessionId: "sess-unprefixed-same-provider",
336+updatedAt: 1,
337+providerOverride: "anthropic",
338+modelOverride: "claude-opus-4-6",
339+authProfileOverride: "work",
340+authProfileOverrideSource: "user",
341+authProfileOverrideCompactionCount: 4,
342+} as SessionEntry,
343+};
344+const entry = expectPatchOk(
345+await runPatch({
346+ store,
347+patch: { key: MAIN_SESSION_KEY, model: "anthropic/claude-sonnet-4-6" },
348+loadGatewayModelCatalog: async () => [
349+{ provider: "anthropic", id: "claude-sonnet-4-6", name: "sonnet" },
350+],
351+}),
352+);
353+expect(entry.providerOverride).toBe("anthropic");
354+expect(entry.modelOverride).toBe("claude-sonnet-4-6");
355+expect(entry.authProfileOverride).toBe("work");
356+expect(entry.authProfileOverrideSource).toBe("user");
357+expect(entry.authProfileOverrideCompactionCount).toBe(4);
358+});
359+360+test("preserves unprefixed auth overrides when existing provider is the default", async () => {
361+const store: Record<string, SessionEntry> = {
362+"agent:main:main": {
363+sessionId: "sess-unprefixed-default-provider",
364+updatedAt: 1,
365+authProfileOverride: "work",
366+authProfileOverrideSource: "user",
367+authProfileOverrideCompactionCount: 4,
368+} as SessionEntry,
369+};
370+const entry = expectPatchOk(
371+await runPatch({
372+cfg: {
373+agents: {
374+defaults: {
375+model: { primary: "anthropic/claude-opus-4-6" },
376+},
377+},
378+} as OpenClawConfig,
379+ store,
380+patch: { key: MAIN_SESSION_KEY, model: "anthropic/claude-sonnet-4-6" },
381+loadGatewayModelCatalog: async () => [
382+{ provider: "anthropic", id: "claude-sonnet-4-6", name: "sonnet" },
383+],
384+}),
385+);
386+expect(entry.providerOverride).toBe("anthropic");
387+expect(entry.modelOverride).toBe("claude-sonnet-4-6");
388+expect(entry.authProfileOverride).toBe("work");
389+expect(entry.authProfileOverrideSource).toBe("user");
390+expect(entry.authProfileOverrideCompactionCount).toBe(4);
391+});
392+393+test("clears unprefixed auth overrides when model patch changes provider", async () => {
394+const store: Record<string, SessionEntry> = {
395+"agent:main:main": {
396+sessionId: "sess-unprefixed-provider-change",
397+updatedAt: 1,
398+providerOverride: "anthropic",
399+modelOverride: "claude-opus-4-6",
400+authProfileOverride: "work",
401+authProfileOverrideSource: "user",
402+authProfileOverrideCompactionCount: 4,
403+} as SessionEntry,
404+};
405+const entry = expectPatchOk(
406+await runPatch({
407+ store,
408+patch: { key: MAIN_SESSION_KEY, model: "openai/gpt-5.4" },
409+loadGatewayModelCatalog: async () => [
410+{ provider: "openai", id: "gpt-5.4", name: "gpt-5.4" },
411+],
412+}),
413+);
414+expect(entry.providerOverride).toBe("openai");
415+expect(entry.modelOverride).toBe("gpt-5.4");
416+expect(entry.authProfileOverride).toBeUndefined();
417+expect(entry.authProfileOverrideSource).toBeUndefined();
418+expect(entry.authProfileOverrideCompactionCount).toBeUndefined();
419+});
420+421+test("clears provider-prefixed auth overrides when model patch changes provider", async () => {
422+const store: Record<string, SessionEntry> = {
423+"agent:main:main": {
424+sessionId: "sess-provider-change",
425+updatedAt: 1,
426+providerOverride: "anthropic",
427+modelOverride: "claude-opus-4-6",
428+authProfileOverride: "anthropic:default",
429+authProfileOverrideSource: "user",
430+authProfileOverrideCompactionCount: 3,
431+} as SessionEntry,
432+};
433+const entry = expectPatchOk(
434+await runPatch({
435+ store,
436+patch: { key: MAIN_SESSION_KEY, model: "openai/gpt-5.4" },
437+loadGatewayModelCatalog: async () => [
438+{ provider: "openai", id: "gpt-5.4", name: "gpt-5.4" },
439+],
440+}),
441+);
442+expect(entry.providerOverride).toBe("openai");
443+expect(entry.modelOverride).toBe("gpt-5.4");
297444expect(entry.authProfileOverride).toBeUndefined();
298445expect(entry.authProfileOverrideSource).toBeUndefined();
299446expect(entry.authProfileOverrideCompactionCount).toBeUndefined();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。