























@@ -307,6 +307,94 @@ describe("CodexAppServerEventProjector", () => {
307307expect(result.replayMetadata.replaySafe).toBe(true);
308308});
309309310+it("records canonical OpenAI Codex app-server turns with Codex local attribution", async () => {
311+const params = await createParams();
312+const projector = await createProjector({
313+ ...params,
314+provider: "openai",
315+modelId: "gpt-5.5",
316+model: {
317+ ...createCodexTestModel("openai"),
318+id: "gpt-5.5",
319+name: "gpt-5.5",
320+api: "openai-responses",
321+} as EmbeddedRunAttemptParams["model"],
322+runtimePlan: {
323+auth: {},
324+observability: {
325+resolvedRef: "openai/gpt-5.5",
326+provider: "openai",
327+modelId: "gpt-5.5",
328+harnessId: "codex",
329+},
330+prompt: {
331+resolveSystemPromptContribution: () => undefined,
332+},
333+tools: {
334+normalize: (tools: unknown[]) => tools,
335+logDiagnostics: () => undefined,
336+},
337+} as unknown as EmbeddedRunAttemptParams["runtimePlan"],
338+});
339+340+await projector.handleNotification(
341+turnCompleted([{ type: "agentMessage", id: "msg-1", text: "done" }]),
342+);
343+344+const result = projector.buildResult(buildEmptyToolTelemetry());
345+346+expect(result.lastAssistant?.provider).toBe("openai-codex");
347+expect(result.lastAssistant?.api).toBe("openai-codex-responses");
348+expect(result.lastAssistant?.model).toBe("gpt-5.5");
349+});
350+351+it("preserves OpenAI attribution for Codex app-server OpenAI API-key fallback profiles", async () => {
352+const params = await createParams();
353+const projector = await createProjector({
354+ ...params,
355+provider: "openai",
356+authProfileId: "openai:work",
357+modelId: "gpt-5.5",
358+model: {
359+ ...createCodexTestModel("openai"),
360+id: "gpt-5.5",
361+name: "gpt-5.5",
362+api: "openai-responses",
363+} as EmbeddedRunAttemptParams["model"],
364+runtimePlan: {
365+auth: {
366+providerForAuth: "openai",
367+authProfileProviderForAuth: "openai",
368+harnessAuthProvider: "openai-codex",
369+forwardedAuthProfileId: "openai:work",
370+},
371+observability: {
372+resolvedRef: "openai/gpt-5.5",
373+provider: "openai",
374+modelId: "gpt-5.5",
375+harnessId: "codex",
376+},
377+prompt: {
378+resolveSystemPromptContribution: () => undefined,
379+},
380+tools: {
381+normalize: (tools: unknown[]) => tools,
382+logDiagnostics: () => undefined,
383+},
384+} as unknown as EmbeddedRunAttemptParams["runtimePlan"],
385+});
386+387+await projector.handleNotification(
388+turnCompleted([{ type: "agentMessage", id: "msg-1", text: "done" }]),
389+);
390+391+const result = projector.buildResult(buildEmptyToolTelemetry());
392+393+expect(result.lastAssistant?.provider).toBe("openai");
394+expect(result.lastAssistant?.api).toBe("openai-responses");
395+expect(result.lastAssistant?.model).toBe("gpt-5.5");
396+});
397+310398it("preserves inbound sender metadata on the mirrored user prompt", async () => {
311399const params = await createParams();
312400const projector = await createProjector({
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。