diff --git a/integration-tests/cli/qwen-serve-live-journal-recovery.test.ts b/integration-tests/cli/qwen-serve-live-journal-recovery.test.ts index f15b03464e4..9ae67e60d37 100644 --- a/integration-tests/cli/qwen-serve-live-journal-recovery.test.ts +++ b/integration-tests/cli/qwen-serve-live-journal-recovery.test.ts @@ -81,6 +81,15 @@ describe('qwen serve live journal recovery', () => { expect(replayText).toContain('chunk-19'); await prompt; + + // Gate the fixture's session-close ack: the only other consumer of + // this path is the opt-in loadtest, so without this call a drifted + // close method name or missing close handler would surface only in + // the post-merge E2E workflow (ack-shape drift is absorbed by the + // daemon's cancel fallback and is not observable from the client). + await expect( + activeDaemon.client.closeSession(created.sessionId), + ).resolves.toBeUndefined(); } finally { await activeDaemon?.dispose(); activeDaemon = undefined; diff --git a/integration-tests/fixtures/mock-acp-child/agent.mjs b/integration-tests/fixtures/mock-acp-child/agent.mjs index 5e1ad0ee216..f99e8de7fc1 100644 --- a/integration-tests/fixtures/mock-acp-child/agent.mjs +++ b/integration-tests/fixtures/mock-acp-child/agent.mjs @@ -55,6 +55,12 @@ delete process.env[PRIVATE_EXTERNAL_TOOL_GUARD_PROVIDER_ENV]; const externalToolGuardRequired = externalToolGuardMarker === EXTERNAL_TOOL_GUARD_REQUIRED_VALUE; +// SERVE_CONTROL_EXT_METHODS.sessionClose from @qwen-code/acp-bridge/status, +// hardcoded because that module runtime-imports @qwen-code/qwen-code-core +// and would pull core's whole barrel into this lightweight fixture. Drift +// fails loudly: the daemon's session close errors when this stops matching. +const SESSION_CLOSE_EXT_METHOD = 'qwen/control/session/close'; + new AgentSideConnection( (connection) => ({ async initialize() { @@ -119,6 +125,17 @@ new AgentSideConnection( }, async cancel() {}, + + async extMethod(method, params) { + if (method === SESSION_CLOSE_EXT_METHOD) { + // The daemon's DELETE /session/:id forwards this ext method down the + // ACP channel; ack with the production success shape so teardown + // completes. The mock keeps no per-session state to drain. + const { sessionId } = params; + return { sessionId, closed: true }; + } + throw RequestError.methodNotFound(method); + }, }), ndJsonStream(Writable.toWeb(process.stdout), Readable.toWeb(process.stdin)), );