























@@ -29,7 +29,6 @@ vi.mock("../process/supervisor/index.js", () => ({
2929let markBackgrounded: typeof import("./bash-process-registry.js").markBackgrounded;
3030let buildExecExitOutcome: typeof import("./bash-tools.exec-runtime.js").buildExecExitOutcome;
3131let detectCursorKeyMode: typeof import("./bash-tools.exec-runtime.js").detectCursorKeyMode;
32-let emitExecSystemEvent: typeof import("./bash-tools.exec-runtime.js").emitExecSystemEvent;
3332let formatExecFailureReason: typeof import("./bash-tools.exec-runtime.js").formatExecFailureReason;
3433let renderExecUpdateText: typeof import("./bash-tools.exec-runtime.js").renderExecUpdateText;
3534let resolveExecTarget: typeof import("./bash-tools.exec-runtime.js").resolveExecTarget;
@@ -40,7 +39,6 @@ beforeAll(async () => {
4039({
4140 buildExecExitOutcome,
4241 detectCursorKeyMode,
43- emitExecSystemEvent,
4442 formatExecFailureReason,
4543 renderExecUpdateText,
4644 resolveExecTarget,
@@ -472,150 +470,6 @@ describe("exec notifyOnExit suppression", () => {
472470});
473471});
474472475-describe("emitExecSystemEvent", () => {
476-beforeEach(() => {
477-requestHeartbeatMock.mockClear();
478-enqueueSystemEventMock.mockClear();
479-});
480-481-it("scopes heartbeat wake to the event session key", () => {
482-emitExecSystemEvent("Exec finished", {
483-sessionKey: "agent:ops:main",
484-contextKey: "exec:run-1",
485-deliveryContext: {
486-channel: "telegram",
487-to: "telegram:-100123:topic:47",
488-threadId: 47,
489-},
490-});
491-492-expect(enqueueSystemEventMock).toHaveBeenCalledWith("Exec finished", {
493-sessionKey: "agent:ops:main",
494-contextKey: "exec:run-1",
495-deliveryContext: {
496-channel: "telegram",
497-to: "telegram:-100123:topic:47",
498-threadId: 47,
499-},
500-});
501-const heartbeat = requireHeartbeatCall();
502-expect(heartbeat.coalesceMs).toBe(0);
503-expect(heartbeat.reason).toBe("exec-event");
504-expect(heartbeat.sessionKey).toBe("agent:ops:main");
505-});
506-507-it("remaps cron-run event enqueue and wake targets to the drained agent main session", () => {
508-emitExecSystemEvent("Exec finished", {
509-sessionKey: "agent:ops:cron:nightly:run:run-1",
510-contextKey: "exec:run-cron",
511-mainKey: "primary",
512-});
513-514-expect(enqueueSystemEventMock).toHaveBeenCalledWith("Exec finished", {
515-sessionKey: "agent:ops:primary",
516-contextKey: "exec:run-cron",
517-});
518-expect(requestHeartbeatMock).toHaveBeenCalledTimes(1);
519-const [[heartbeatParams]] = requestHeartbeatMock.mock.calls as unknown as Array<
520-[{ coalesceMs?: number; reason?: string; sessionKey?: string }]
521->;
522-expect(heartbeatParams.coalesceMs).toBe(0);
523-expect(heartbeatParams.reason).toBe("exec-event");
524-expect(heartbeatParams.sessionKey).toBe("agent:ops:primary");
525-});
526-527-it("routes global-scope cron-run events to the global queue and preserves the agent wake target", () => {
528-emitExecSystemEvent("Exec finished", {
529-sessionKey: "agent:ops:cron:nightly:run:run-1:subagent:worker",
530-contextKey: "exec:run-global",
531-sessionScope: "global",
532-});
533-534-expect(enqueueSystemEventMock).toHaveBeenCalledWith("Exec finished", {
535-sessionKey: "global",
536-contextKey: "exec:run-global",
537-});
538-expect(requestHeartbeatMock).toHaveBeenCalledTimes(1);
539-const [[heartbeatParams]] = requestHeartbeatMock.mock.calls as unknown as Array<
540-[{ agentId?: string; coalesceMs?: number; reason?: string }]
541->;
542-expect(heartbeatParams.agentId).toBe("ops");
543-expect(heartbeatParams.coalesceMs).toBe(0);
544-expect(heartbeatParams.reason).toBe("exec-event");
545-expect(requireHeartbeatCall()).not.toHaveProperty("sessionKey");
546-});
547-548-it("routes single-owner dmScope=main direct exec events to the agent main session", () => {
549-emitExecSystemEvent("Exec finished", {
550-sessionKey: "agent:main:telegram:default:direct:123",
551-contextKey: "exec:run-dm",
552-deliveryContext: {
553-channel: "telegram",
554-to: "123",
555-},
556-eventRouting: {
557-dmScope: "main",
558-allowFrom: ["123"],
559-channel: "telegram",
560-accountId: "default",
561-},
562-});
563-564-expect(enqueueSystemEventMock).toHaveBeenCalledWith("Exec finished", {
565-sessionKey: "agent:main:main",
566-contextKey: "exec:run-dm",
567-deliveryContext: {
568-channel: "telegram",
569-to: "123",
570-},
571-});
572-expect(requestHeartbeatMock).toHaveBeenCalledTimes(1);
573-const heartbeat = requireHeartbeatCall();
574-expect(heartbeat.coalesceMs).toBe(0);
575-expect(heartbeat.reason).toBe("exec-event");
576-expect(heartbeat.sessionKey).toBe("agent:main:main");
577-});
578-579-it("keeps wake unscoped for non-agent session keys", () => {
580-emitExecSystemEvent("Exec finished", {
581-sessionKey: "global",
582-contextKey: "exec:run-global",
583-});
584-585-expect(enqueueSystemEventMock).toHaveBeenCalledWith("Exec finished", {
586-sessionKey: "global",
587-contextKey: "exec:run-global",
588-});
589-const heartbeat = requireHeartbeatCall();
590-expect(heartbeat.coalesceMs).toBe(0);
591-expect(heartbeat.reason).toBe("exec-event");
592-});
593-594-it("ignores events without a session key", () => {
595-emitExecSystemEvent("Exec finished", {
596-sessionKey: " ",
597-contextKey: "exec:run-2",
598-});
599-600-expect(enqueueSystemEventMock).not.toHaveBeenCalled();
601-expect(requestHeartbeatMock).not.toHaveBeenCalled();
602-});
603-604-it("skips heartbeat wake for subagent session keys", () => {
605-emitExecSystemEvent("Exec finished", {
606-sessionKey: "agent:main:subagent:abc-123",
607-contextKey: "exec:run-sub",
608-});
609-610-expect(enqueueSystemEventMock).toHaveBeenCalledWith("Exec finished", {
611-sessionKey: "agent:main:subagent:abc-123",
612-contextKey: "exec:run-sub",
613-deliveryContext: undefined,
614-});
615-expect(requestHeartbeatMock).not.toHaveBeenCalled();
616-});
617-});
618-619473describe("formatExecFailureReason", () => {
620474it("formats timeout guidance with the configured timeout", () => {
621475expect(
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。