























@@ -7,6 +7,7 @@ import { afterEach, describe, expect, it, vi } from "vitest";
77import type { OpenClawConfig } from "../config/types.openclaw.js";
88import type { AuthProfileStore } from "./auth-profiles.js";
99import type { ModelCatalogEntry } from "./model-catalog.types.js";
10+import { publishProviderAuthWarmSnapshot } from "./model-provider-auth-state.js";
10111112const modelCatalogMocks = vi.hoisted(() => ({
1213loadModelCatalog: vi.fn<(params?: unknown) => Promise<ModelCatalogEntry[]>>(),
@@ -82,10 +83,16 @@ const {
8283 buildCurrentProviderAuthStateSnapshot,
8384 createProviderAuthChecker,
8485 hasAuthForModelProvider,
85- warmCurrentProviderAuthState,
8686 warmCurrentProviderAuthStateOffMainThread,
8787} = await import("./model-provider-auth.js");
888889+async function publishCurrentProviderAuthStateSnapshot(
90+cfg: OpenClawConfig,
91+options?: Parameters<typeof buildCurrentProviderAuthStateSnapshot>[1],
92+): Promise<void> {
93+publishProviderAuthWarmSnapshot(await buildCurrentProviderAuthStateSnapshot(cfg, options));
94+}
95+8996describe("prepared provider auth state", () => {
9097afterEach(() => {
9198clearCurrentProviderAuthState();
@@ -102,7 +109,7 @@ describe("prepared provider auth state", () => {
102109]);
103110modelAuthMocks.hasRuntimeAvailableProviderAuth.mockReturnValue(false);
104111105-await warmCurrentProviderAuthState(cfg);
112+await publishCurrentProviderAuthStateSnapshot(cfg);
106113107114expect(modelAuthMocks.createRuntimeProviderAuthLookup).toHaveBeenCalledTimes(1);
108115const firstLookup =
@@ -119,7 +126,7 @@ describe("prepared provider auth state", () => {
119126]);
120127modelAuthMocks.hasRuntimeAvailableProviderAuth.mockReturnValue(false);
121128122-await warmCurrentProviderAuthState(cfg);
129+await publishCurrentProviderAuthStateSnapshot(cfg);
123130124131expect(modelCatalogMocks.loadModelCatalog).toHaveBeenCalledWith({
125132config: cfg,
@@ -193,7 +200,7 @@ describe("prepared provider auth state", () => {
193200({ provider }) => provider === "openai",
194201);
195202196-await warmCurrentProviderAuthState(cfg);
203+await publishCurrentProviderAuthStateSnapshot(cfg);
197204expect(modelAuthMocks.hasRuntimeAvailableProviderAuth).toHaveBeenCalledTimes(2);
198205199206// Flip the underlying answer; if the prepared map is consulted first,
@@ -217,7 +224,7 @@ describe("prepared provider auth state", () => {
217224]);
218225// Warm with the broad answer: provider has CLI/synthetic auth.
219226modelAuthMocks.hasRuntimeAvailableProviderAuth.mockReturnValue(true);
220-await warmCurrentProviderAuthState(cfg);
227+await publishCurrentProviderAuthStateSnapshot(cfg);
221228expect(modelAuthMocks.hasRuntimeAvailableProviderAuth).toHaveBeenCalledTimes(1);
222229223230// Flip the underlying compute to false. A narrow-scope caller must NOT
@@ -306,7 +313,7 @@ describe("prepared provider auth state", () => {
306313{ id: "gpt", name: "gpt", provider: "openai" },
307314]);
308315modelAuthMocks.hasRuntimeAvailableProviderAuth.mockReturnValue(true);
309-await warmCurrentProviderAuthState(cfg);
316+await publishCurrentProviderAuthStateSnapshot(cfg);
310317expect(modelAuthMocks.hasRuntimeAvailableProviderAuth).toHaveBeenCalledTimes(1);
311318312319modelAuthMocks.hasRuntimeAvailableProviderAuth.mockReturnValue(false);
@@ -322,7 +329,7 @@ describe("prepared provider auth state", () => {
322329{ id: "gpt", name: "gpt", provider: "openai" },
323330]);
324331modelAuthMocks.hasRuntimeAvailableProviderAuth.mockReturnValue(true);
325-await warmCurrentProviderAuthState(cfg);
332+await publishCurrentProviderAuthStateSnapshot(cfg);
326333expect(modelAuthMocks.hasRuntimeAvailableProviderAuth).toHaveBeenCalledTimes(1);
327334328335// Per-agent picker calls pass an agent-specific workspaceDir that the
@@ -349,64 +356,25 @@ describe("prepared provider auth state", () => {
349356expect(modelAuthMocks.hasRuntimeAvailableProviderAuth).toHaveBeenCalledTimes(2);
350357});
351358352-it("does not publish an older warm after the prepared auth state is cleared", async () => {
353-const firstCfg = { gateway: { port: 18789 } } as OpenClawConfig;
354-const secondCfg = { gateway: { port: 19001 } } as OpenClawConfig;
355-let resolveFirstCatalog: ((catalog: ModelCatalogEntry[]) => void) | undefined;
356-let resolveSecondCatalog: ((catalog: ModelCatalogEntry[]) => void) | undefined;
357-modelCatalogMocks.loadModelCatalog
358-.mockReturnValueOnce(
359-new Promise<ModelCatalogEntry[]>((resolve) => {
360-resolveFirstCatalog = resolve;
361-}),
362-)
363-.mockReturnValueOnce(
364-new Promise<ModelCatalogEntry[]>((resolve) => {
365-resolveSecondCatalog = resolve;
366-}),
367-);
368-modelAuthMocks.hasRuntimeAvailableProviderAuth.mockImplementation(
369-({ cfg }) => cfg === firstCfg,
370-);
371-372-const firstWarm = warmCurrentProviderAuthState(firstCfg);
373-await Promise.resolve();
374-clearCurrentProviderAuthState();
375-const secondWarm = warmCurrentProviderAuthState(secondCfg);
376-377-resolveSecondCatalog?.([{ id: "gpt", name: "gpt", provider: "openai" }]);
378-await secondWarm;
379-resolveFirstCatalog?.([{ id: "gpt", name: "gpt", provider: "openai" }]);
380-await firstWarm;
381-expect(modelAuthMocks.hasRuntimeAvailableProviderAuth).toHaveBeenCalledTimes(1);
382-383-modelAuthMocks.hasRuntimeAvailableProviderAuth.mockReturnValue(true);
384-await expect(hasAuthForModelProvider({ provider: "openai", cfg: secondCfg })).resolves.toBe(
385-false,
386-);
387-expect(modelAuthMocks.hasRuntimeAvailableProviderAuth).toHaveBeenCalledTimes(1);
388-await expect(hasAuthForModelProvider({ provider: "openai", cfg: firstCfg })).resolves.toBe(
389-true,
390-);
391-expect(modelAuthMocks.hasRuntimeAvailableProviderAuth).toHaveBeenCalledTimes(2);
392-});
393-394-it("does not publish a warm that is cancelled before completion", async () => {
359+it("returns an empty warm snapshot when cancelled before publication", async () => {
395360const cfg = {} as OpenClawConfig;
396361let cancelled = false;
397362modelCatalogMocks.loadModelCatalog.mockResolvedValue([
398363{ id: "gpt", name: "gpt", provider: "openai" },
399364]);
400365modelAuthMocks.hasRuntimeAvailableProviderAuth.mockReturnValue(true);
401366402-await warmCurrentProviderAuthState(cfg, { isCancelled: () => cancelled });
367+await publishCurrentProviderAuthStateSnapshot(cfg, { isCancelled: () => cancelled });
403368await expect(hasAuthForModelProvider({ provider: "openai", cfg })).resolves.toBe(true);
404369expect(modelAuthMocks.hasRuntimeAvailableProviderAuth).toHaveBeenCalledTimes(1);
405370406371clearCurrentProviderAuthState();
407372modelAuthMocks.hasRuntimeAvailableProviderAuth.mockClear();
408373cancelled = true;
409-await warmCurrentProviderAuthState(cfg, { isCancelled: () => cancelled });
374+const cancelledSnapshot = await buildCurrentProviderAuthStateSnapshot(cfg, {
375+isCancelled: () => cancelled,
376+});
377+expect(cancelledSnapshot).toEqual({ agents: [] });
410378411379modelAuthMocks.hasRuntimeAvailableProviderAuth.mockReturnValue(false);
412380await expect(hasAuthForModelProvider({ provider: "openai", cfg })).resolves.toBe(false);
@@ -426,7 +394,10 @@ describe("prepared provider auth state", () => {
426394return false;
427395});
428396429-await warmCurrentProviderAuthState(cfg, { isCancelled: () => cancelled });
397+const snapshot = await buildCurrentProviderAuthStateSnapshot(cfg, {
398+isCancelled: () => cancelled,
399+});
400+expect(snapshot).toEqual({ agents: [] });
430401expect(modelAuthMocks.hasRuntimeAvailableProviderAuth).toHaveBeenCalledTimes(1);
431402432403modelAuthMocks.hasRuntimeAvailableProviderAuth.mockClear();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。