


























@@ -5,6 +5,14 @@ import { buildCodexMediaUnderstandingProvider } from "./media-understanding-prov
55import type { CodexAppServerClient } from "./src/app-server/client.js";
66import type { CodexServerNotification, JsonValue } from "./src/app-server/protocol.js";
778+const sharedClientMocks = vi.hoisted(() => ({
9+createIsolatedCodexAppServerClient: vi.fn(),
10+}));
11+12+vi.mock("./src/app-server/shared-client.js", () => ({
13+createIsolatedCodexAppServerClient: sharedClientMocks.createIsolatedCodexAppServerClient,
14+}));
15+816function codexModel(inputModalities: string[] = ["text", "image"]) {
917return {
1018id: "gpt-5.4",
@@ -169,6 +177,7 @@ function createFakeClient(options?: {
169177requestHandlers.add(handler);
170178return () => requestHandlers.delete(handler);
171179},
180+close: vi.fn(),
172181} as unknown as CodexAppServerClient;
173182174183return { client, requests, approvalResponses };
@@ -178,13 +187,24 @@ describe("codex media understanding provider", () => {
178187afterEach(() => {
179188vi.useRealTimers();
180189vi.restoreAllMocks();
190+sharedClientMocks.createIsolatedCodexAppServerClient.mockReset();
181191});
182192183193it("runs image understanding through a bounded Codex app-server turn", async () => {
184194const { client, requests } = createFakeClient();
195+const clientFactory = vi.fn(
196+async (_startOptions, _authProfileId, _agentDir, _config) => client,
197+);
185198const provider = buildCodexMediaUnderstandingProvider({
186-clientFactory: async () => client,
199+ clientFactory,
187200});
201+const cfg = {
202+auth: {
203+order: {
204+openai: ["openai:work"],
205+},
206+},
207+};
188208189209const result = await provider.describeImage?.({
190210buffer: Buffer.from("image-bytes"),
@@ -194,7 +214,7 @@ describe("codex media understanding provider", () => {
194214model: "gpt-5.4",
195215prompt: "Describe briefly.",
196216timeoutMs: 30_000,
197-cfg: {},
217+ cfg,
198218agentDir: "/tmp/openclaw-agent",
199219});
200220@@ -204,6 +224,12 @@ describe("codex media understanding provider", () => {
204224"thread/start",
205225"turn/start",
206226]);
227+expect(clientFactory).toHaveBeenCalledWith(
228+expect.any(Object),
229+undefined,
230+"/tmp/openclaw-agent",
231+cfg,
232+);
207233expect(requests[1]?.params).toEqual({
208234model: "gpt-5.4",
209235modelProvider: "openai",
@@ -236,6 +262,62 @@ describe("codex media understanding provider", () => {
236262});
237263});
238264265+it("treats a blank agent directory as absent when starting the app-server", async () => {
266+const { client, requests } = createFakeClient();
267+const clientFactory = vi.fn(async () => client);
268+const provider = buildCodexMediaUnderstandingProvider({ clientFactory });
269+const cfg = {};
270+271+await provider.describeImage?.({
272+buffer: Buffer.from("image-bytes"),
273+fileName: "image.png",
274+mime: "image/png",
275+provider: "codex",
276+model: "gpt-5.4",
277+timeoutMs: 30_000,
278+ cfg,
279+agentDir: " ",
280+});
281+282+expect(clientFactory).toHaveBeenCalledWith(expect.any(Object), undefined, undefined, cfg);
283+expect(requests[1]?.params).toEqual(expect.objectContaining({ cwd: process.cwd() }));
284+expect(requests[2]?.params).toEqual(expect.objectContaining({ cwd: process.cwd() }));
285+});
286+287+it("passes the scoped auth store into isolated app-server startup", async () => {
288+const { client } = createFakeClient();
289+sharedClientMocks.createIsolatedCodexAppServerClient.mockResolvedValue(client);
290+const provider = buildCodexMediaUnderstandingProvider();
291+const authStore = {
292+version: 1,
293+profiles: {
294+"openai:scoped": {
295+type: "oauth" as const,
296+provider: "openai",
297+access: "scoped-access",
298+refresh: "scoped-refresh",
299+expires: Date.now() + 60_000,
300+},
301+},
302+};
303+304+await provider.describeImage?.({
305+buffer: Buffer.from("image-bytes"),
306+fileName: "image.png",
307+mime: "image/png",
308+provider: "codex",
309+model: "gpt-5.4",
310+timeoutMs: 30_000,
311+cfg: {},
312+ authStore,
313+agentDir: "/tmp/openclaw-agent",
314+});
315+316+expect(sharedClientMocks.createIsolatedCodexAppServerClient).toHaveBeenCalledWith(
317+expect.objectContaining({ authProfileStore: authStore }),
318+);
319+});
320+239321it("clamps oversized image understanding turn timeouts", async () => {
240322const setTimeoutSpy = vi.spyOn(globalThis, "setTimeout");
241323try {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。