
























@@ -3822,6 +3822,85 @@ describe("runCodexAppServerAttempt", () => {
38223822expect(result.promptError).toBeNull();
38233823});
382438243825+it("keeps turn request activity active until elicitation handling resolves", async () => {
3826+const harness = createStartedThreadHarness();
3827+const bridgedResponse = {
3828+action: "accept",
3829+content: null,
3830+_meta: null,
3831+} as const;
3832+let resolveBridge!: (value: typeof bridgedResponse) => void;
3833+const bridgePromise = new Promise<typeof bridgedResponse>((resolve) => {
3834+resolveBridge = resolve;
3835+});
3836+vi.spyOn(elicitationBridge, "handleCodexAppServerElicitationRequest").mockImplementation(
3837+async () => await bridgePromise,
3838+);
3839+const params = createParams(
3840+path.join(tempDir, "session.jsonl"),
3841+path.join(tempDir, "workspace"),
3842+);
3843+params.timeoutMs = 500;
3844+const onRunProgress = vi.fn();
3845+params.onRunProgress = onRunProgress;
3846+3847+const run = runCodexAppServerAttempt(params, {
3848+turnCompletionIdleTimeoutMs: 1_000,
3849+turnAssistantCompletionIdleTimeoutMs: 1_000,
3850+turnTerminalIdleTimeoutMs: 1_000,
3851+});
3852+await harness.waitForMethod("turn/start");
3853+3854+const response = harness.handleServerRequest({
3855+id: "request-pending-elicitation",
3856+method: "mcpServer/elicitation/request",
3857+params: {
3858+threadId: "thread-1",
3859+turnId: "turn-1",
3860+mode: "form",
3861+message: "Approve?",
3862+requestedSchema: { type: "object", properties: {} },
3863+serverName: "server-1",
3864+_meta: null,
3865+},
3866+});
3867+await vi.waitFor(
3868+() =>
3869+expect(onRunProgress).toHaveBeenCalledWith(
3870+expect.objectContaining({
3871+reason: "request:mcpServer/elicitation/request:start",
3872+}),
3873+),
3874+fastWait,
3875+);
3876+await new Promise((resolve) => setTimeout(resolve, 60));
3877+expect(
3878+onRunProgress.mock.calls.some(
3879+([event]) =>
3880+(event as { reason?: string }).reason ===
3881+"request:mcpServer/elicitation/request:response",
3882+),
3883+).toBe(false);
3884+3885+resolveBridge(bridgedResponse);
3886+await expect(response).resolves.toEqual(bridgedResponse);
3887+await vi.waitFor(
3888+() =>
3889+expect(onRunProgress).toHaveBeenCalledWith(
3890+expect.objectContaining({
3891+reason: "request:mcpServer/elicitation/request:response",
3892+}),
3893+),
3894+fastWait,
3895+);
3896+await harness.completeTurn({ threadId: "thread-1", turnId: "turn-1" });
3897+3898+const result = await run;
3899+expect(result.aborted).toBe(false);
3900+expect(result.timedOut).toBe(false);
3901+expect(result.promptError).toBeNull();
3902+});
3903+38253904it("counts pending user input requests as turn attempt progress", async () => {
38263905const harness = createStartedThreadHarness();
38273906const params = createParams(
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。