

















@@ -2399,6 +2399,91 @@ describe("AcpSessionManager", () => {
23992399expect(currentMeta.identity?.agentSessionId).toBe("agent-fresh");
24002400});
240124012402+it("reconciles oneshot ACP identity from runtime status before closing after a turn", async () => {
2403+const runtimeState = createRuntime();
2404+runtimeState.ensureSession.mockResolvedValue({
2405+sessionKey: "agent:codex:acp:session-1",
2406+backend: "acpx",
2407+runtimeSessionName: "runtime-1",
2408+backendSessionId: "acpx-oneshot",
2409+});
2410+runtimeState.getStatus.mockResolvedValue({
2411+summary: "status=done",
2412+backendSessionId: "acpx-oneshot",
2413+agentSessionId: "agent-oneshot",
2414+details: { status: "done" },
2415+});
2416+hoisted.requireAcpRuntimeBackendMock.mockReturnValue({
2417+id: "acpx",
2418+runtime: runtimeState.runtime,
2419+});
2420+2421+let currentMeta: SessionAcpMeta | undefined;
2422+hoisted.readAcpSessionEntryMock.mockImplementation((paramsUnknown: unknown) => {
2423+const sessionKey =
2424+(paramsUnknown as { sessionKey?: string }).sessionKey ?? "agent:codex:acp:session-1";
2425+return {
2426+ sessionKey,
2427+storeSessionKey: sessionKey,
2428+acp: currentMeta,
2429+};
2430+});
2431+hoisted.upsertAcpSessionMetaMock.mockImplementation(async (paramsUnknown: unknown) => {
2432+const params = paramsUnknown as {
2433+mutate: (
2434+current: SessionAcpMeta | undefined,
2435+entry: { acp?: SessionAcpMeta } | undefined,
2436+) => SessionAcpMeta | null | undefined;
2437+};
2438+const next = params.mutate(currentMeta, { acp: currentMeta });
2439+if (next) {
2440+currentMeta = next;
2441+}
2442+return {
2443+sessionId: "session-1",
2444+updatedAt: Date.now(),
2445+acp: currentMeta,
2446+};
2447+});
2448+2449+const manager = new AcpSessionManager();
2450+await manager.initializeSession({
2451+cfg: baseCfg,
2452+sessionKey: "agent:codex:acp:session-1",
2453+agent: "codex",
2454+mode: "oneshot",
2455+});
2456+2457+expect(currentMeta?.identity).toMatchObject({
2458+state: "pending",
2459+acpxSessionId: "acpx-oneshot",
2460+source: "ensure",
2461+});
2462+2463+await manager.runTurn({
2464+cfg: baseCfg,
2465+sessionKey: "agent:codex:acp:session-1",
2466+text: "do work",
2467+mode: "prompt",
2468+requestId: "run-1",
2469+});
2470+2471+expect(runtimeState.getStatus).toHaveBeenCalledTimes(2);
2472+expect(runtimeState.close).toHaveBeenCalledWith({
2473+handle: expect.objectContaining({
2474+backendSessionId: "acpx-oneshot",
2475+agentSessionId: "agent-oneshot",
2476+}),
2477+reason: "oneshot-complete",
2478+});
2479+expect(currentMeta?.identity).toMatchObject({
2480+state: "resolved",
2481+acpxSessionId: "acpx-oneshot",
2482+agentSessionId: "agent-oneshot",
2483+source: "status",
2484+});
2485+});
2486+24022487it("reconciles pending ACP identities during startup scan", async () => {
24032488const runtimeState = createRuntime();
24042489runtimeState.getStatus.mockResolvedValue({
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。