























@@ -64,6 +64,11 @@ const acpManagerMocks = vi.hoisted(() => ({
6464cancelSession: vi.fn(async () => {}),
6565}));
666667+const runtimeAbortMocks = vi.hoisted(() => ({
68+abortEmbeddedPiRun: vi.fn(() => true),
69+resolveActiveEmbeddedRunSessionId: vi.fn(() => undefined as string | undefined),
70+}));
71+6772vi.mock("../../acp/control-plane/manager.js", () => ({
6873getAcpSessionManager: () => ({
6974resolveSession: acpManagerMocks.resolveSession,
@@ -110,6 +115,8 @@ describe("abort detection", () => {
110115sessionKey: string;
111116from: string;
112117to: string;
118+senderId?: string;
119+commandSource?: "native" | "text";
113120targetSessionKey?: string;
114121messageSid?: string;
115122timestamp?: number;
@@ -124,6 +131,8 @@ describe("abort detection", () => {
124131Surface: "telegram",
125132From: params.from,
126133To: params.to,
134+ ...(params.senderId ? { SenderId: params.senderId } : {}),
135+ ...(params.commandSource ? { CommandSource: params.commandSource } : {}),
127136 ...(params.targetSessionKey ? { CommandTargetSessionKey: params.targetSessionKey } : {}),
128137 ...(params.messageSid ? { MessageSid: params.messageSid } : {}),
129138 ...(typeof params.timestamp === "number" ? { Timestamp: params.timestamp } : {}),
@@ -176,7 +185,8 @@ describe("abort detection", () => {
176185resolveSession: acpManagerMocks.resolveSession,
177186cancelSession: acpManagerMocks.cancelSession,
178187}) as never) as never,
179-abortEmbeddedPiRun: () => true,
188+abortEmbeddedPiRun: runtimeAbortMocks.abortEmbeddedPiRun,
189+resolveActiveEmbeddedRunSessionId: runtimeAbortMocks.resolveActiveEmbeddedRunSessionId,
180190getLatestSubagentRunByChildSessionKey:
181191subagentRegistryMocks.getLatestSubagentRunByChildSessionKey,
182192listSubagentRunsForController: subagentRegistryMocks.listSubagentRunsForRequester,
@@ -196,6 +206,8 @@ describe("abort detection", () => {
196206commandQueueMocks.clearCommandLane.mockClear().mockReturnValue(1);
197207acpManagerMocks.resolveSession.mockReset().mockReturnValue({ kind: "none" });
198208acpManagerMocks.cancelSession.mockReset().mockResolvedValue(undefined);
209+runtimeAbortMocks.abortEmbeddedPiRun.mockReset().mockReturnValue(true);
210+runtimeAbortMocks.resolveActiveEmbeddedRunSessionId.mockReset().mockReturnValue(undefined);
199211subagentRegistryMocks.getLatestSubagentRunByChildSessionKey.mockReset().mockReturnValue(null);
200212});
201213@@ -393,6 +405,37 @@ describe("abort detection", () => {
393405expect(result.handled).toBe(true);
394406});
395407408+it("fast-aborts authorized text slash stop commands before they queue", async () => {
409+const sessionKey = "telegram:123";
410+const sessionId = "session-123";
411+const activeSessionId = "session-active";
412+const { root, cfg } = await createAbortConfig({
413+sessionIdsByKey: { [sessionKey]: sessionId },
414+});
415+cfg.commands = {
416+ ...cfg.commands,
417+ownerAllowFrom: ["telegram:123"],
418+};
419+runtimeAbortMocks.resolveActiveEmbeddedRunSessionId.mockReturnValue(activeSessionId);
420+enqueueQueuedFollowupRun({ root, cfg, sessionId, sessionKey });
421+expect(getFollowupQueueDepth(sessionKey)).toBe(1);
422+423+const result = await runStopCommand({
424+ cfg,
425+ sessionKey,
426+from: "telegram:123",
427+to: "telegram:123",
428+senderId: "123",
429+commandSource: "text",
430+});
431+432+expect(result.handled).toBe(true);
433+expect(runtimeAbortMocks.resolveActiveEmbeddedRunSessionId).toHaveBeenCalledWith(sessionKey);
434+expect(runtimeAbortMocks.abortEmbeddedPiRun).toHaveBeenCalledWith(activeSessionId);
435+expect(getFollowupQueueDepth(sessionKey)).toBe(0);
436+expectSessionLaneCleared(sessionKey);
437+});
438+396439it("fast-abort clears queued followups and session lane", async () => {
397440const sessionKey = "telegram:123";
398441const sessionId = "session-123";
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。