






















@@ -39,6 +39,7 @@ vi.mock("openclaw/plugin-sdk/agent-runtime", () => ({
3939let listCodexAppServerModels: typeof import("./models.js").listCodexAppServerModels;
4040let clearSharedCodexAppServerClient: typeof import("./shared-client.js").clearSharedCodexAppServerClient;
4141let clearSharedCodexAppServerClientIfCurrent: typeof import("./shared-client.js").clearSharedCodexAppServerClientIfCurrent;
42+let clearSharedCodexAppServerClientIfCurrentAndWait: typeof import("./shared-client.js").clearSharedCodexAppServerClientIfCurrentAndWait;
4243let createIsolatedCodexAppServerClient: typeof import("./shared-client.js").createIsolatedCodexAppServerClient;
4344let getSharedCodexAppServerClient: typeof import("./shared-client.js").getSharedCodexAppServerClient;
4445let resetSharedCodexAppServerClientForTests: typeof import("./shared-client.js").resetSharedCodexAppServerClientForTests;
@@ -111,6 +112,7 @@ describe("shared Codex app-server client", () => {
111112({
112113 clearSharedCodexAppServerClient,
113114 clearSharedCodexAppServerClientIfCurrent,
115+ clearSharedCodexAppServerClientIfCurrentAndWait,
114116 createIsolatedCodexAppServerClient,
115117 getSharedCodexAppServerClient,
116118 resetSharedCodexAppServerClientForTests,
@@ -476,6 +478,44 @@ describe("shared Codex app-server client", () => {
476478expect(second.process.stdin.destroyed).toBe(true);
477479});
478480481+it("waits only for the shared client that is still current", async () => {
482+const first = createClientHarness();
483+const second = createClientHarness();
484+vi.spyOn(CodexAppServerClient, "start")
485+.mockReturnValueOnce(first.client)
486+.mockReturnValueOnce(second.client);
487+const firstCloseAndWait = vi.spyOn(first.client, "closeAndWait");
488+const secondCloseAndWait = vi.spyOn(second.client, "closeAndWait");
489+490+const firstList = listCodexAppServerModels({
491+timeoutMs: 1000,
492+agentDir: "/tmp/openclaw-agent-one",
493+});
494+await sendInitializeResult(first, "openclaw/0.125.0 (macOS; test)");
495+await sendEmptyModelList(first);
496+await expect(firstList).resolves.toEqual({ models: [] });
497+498+const secondList = listCodexAppServerModels({
499+timeoutMs: 1000,
500+agentDir: "/tmp/openclaw-agent-two",
501+});
502+await sendInitializeResult(second, "openclaw/0.125.0 (macOS; test)");
503+await sendEmptyModelList(second);
504+await expect(secondList).resolves.toEqual({ models: [] });
505+506+await expect(
507+clearSharedCodexAppServerClientIfCurrentAndWait(first.client, {
508+exitTimeoutMs: 25,
509+forceKillDelayMs: 5,
510+}),
511+).resolves.toBe(true);
512+513+expect(firstCloseAndWait).toHaveBeenCalledTimes(1);
514+expect(secondCloseAndWait).not.toHaveBeenCalled();
515+expect(first.process.stdin.destroyed).toBe(true);
516+expect(second.process.stdin.destroyed).toBe(false);
517+});
518+479519it("uses a fresh websocket Authorization header after shared-client token rotation", async () => {
480520const server = new WebSocketServer({ host: "127.0.0.1", port: 0 });
481521const authHeaders: Array<string | undefined> = [];
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。