import { afterEach, describe, expect, it, vi } from "vitest" ;
import {
__testing,
abortActiveReplyRuns,
createReplyOperation,
isReplyRunActiveForSessionId,
queueReplyRunMessage,
replyRunRegistry,
resolveActiveReplyRunSessionId,
waitForReplyRunEndBySessionId,
} from "./reply-run-registry.js" ;
describe("reply run registry" , () => {
afterEach(() => {
__testing.resetReplyRunRegistry();
vi.restoreAllMocks();
});
it("keeps ownership stable by sessionKey while sessionId rotates" , async () => {
vi.useFakeTimers();
try {
const operation = createReplyOperation({
sessionKey: "agent:main:main" ,
sessionId: "session-old" ,
resetTriggered: false ,
});
const oldWaitPromise = waitForReplyRunEndBySessionId("session-old" , 1 _000 );
operation.updateSessionId("session-new" );
expect(replyRunRegistry.isActive("agent:main:main" )).toBe(true );
expect(resolveActiveReplyRunSessionId("agent:main:main" )).toBe("session-new" );
expect(isReplyRunActiveForSessionId("session-old" )).toBe(false );
expect(isReplyRunActiveForSessionId("session-new" )).toBe(true );
let settled = false ;
void oldWaitPromise.then(() => {
settled = true ;
});
await vi.advanceTimersByTimeAsync(100 );
expect(settled).toBe(false );
operation.complete();
await expect(oldWaitPromise).resolves.toBe(true );
} finally {
await vi.runOnlyPendingTimersAsync();
vi.useRealTimers();
}
});
it("clears queued operations immediately on user abort" , () => {
const operation = createReplyOperation({
sessionKey: "agent:main:main" ,
sessionId: "session-queued" ,
resetTriggered: false ,
});
expect(replyRunRegistry.isActive("agent:main:main" )).toBe(true );
operation.abortByUser();
expect(operation.result).toEqual({ kind: "aborted" , code: "aborted_by_user" });
expect(replyRunRegistry.isActive("agent:main:main" )).toBe(false );
});
it("queues messages only through the active running backend" , async () => {
const queueMessage = vi.fn(async () => {});
const operation = createReplyOperation({
sessionKey: "agent:main:main" ,
sessionId: "session-running" ,
resetTriggered: false ,
});
operation.attachBackend({
kind: "embedded" ,
cancel: vi.fn(),
isStreaming: () => true ,
queueMessage,
});
expect(queueReplyRunMessage("session-running" , "before running" )).toBe(false );
operation.setPhase("running" );
expect(queueReplyRunMessage("session-running" , "hello" )).toBe(true );
expect(queueMessage).toHaveBeenCalledWith("hello" );
});
it("aborts compacting runs through the registry compatibility helper" , () => {
const compactingOperation = createReplyOperation({
sessionKey: "agent:main:main" ,
sessionId: "session-compacting" ,
resetTriggered: false ,
});
compactingOperation.setPhase("preflight_compacting" );
const runningOperation = createReplyOperation({
sessionKey: "agent:main:other" ,
sessionId: "session-running" ,
resetTriggered: false ,
});
runningOperation.setPhase("running" );
expect(abortActiveReplyRuns({ mode: "compacting" })).toBe(true );
expect(compactingOperation.result).toEqual({ kind: "aborted" , code: "aborted_for_restart" });
expect(runningOperation.result).toBeNull();
});
});
Messung V0.5 in Prozent C=98 H=98 G=97
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland