File size: 2,882 Bytes
e249c6d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | // Verifies the small lifecycle callback adapter used during agent attempts.
import { describe, expect, it } from "vitest";
import {
createAgentAttemptLifecycleCallbacks,
type AgentAttemptLifecycleState,
} from "./attempt-callbacks.js";
describe("createAgentAttemptLifecycleCallbacks", () => {
it("tracks user-message persistence without closing over the agent command scope", () => {
const state: AgentAttemptLifecycleState = {
currentTurnUserMessagePersisted: false,
lifecycleFinishing: false,
lifecycleEnded: false,
};
const callbacks = createAgentAttemptLifecycleCallbacks(state);
// The callback mutates only the shared lifecycle state object; it should not
// need access to the wider runAgentAttempt closure.
callbacks.onUserMessagePersisted?.({
role: "user",
content: "hello",
timestamp: Date.now(),
});
expect(state.currentTurnUserMessagePersisted).toBe(true);
expect(state.lifecycleEnded).toBe(false);
});
it("tracks terminal lifecycle phases", async () => {
const state = {
currentTurnUserMessagePersisted: false,
lifecycleFinishing: false,
lifecycleEnded: false,
};
const callbacks = createAgentAttemptLifecycleCallbacks(state);
await callbacks.onAgentEvent({ stream: "lifecycle", data: { phase: "start" } });
expect(state.lifecycleEnded).toBe(false);
await callbacks.onAgentEvent({ stream: "lifecycle", data: { phase: "end" } });
expect(state.lifecycleEnded).toBe(true);
});
it("retains deferred lifecycle errors without marking the attempt terminal", async () => {
const state: AgentAttemptLifecycleState = {
currentTurnUserMessagePersisted: false,
lifecycleFinishing: false,
lifecycleEnded: false,
};
const callbacks = createAgentAttemptLifecycleCallbacks(state);
await callbacks.onAgentEvent({
stream: "lifecycle",
data: { phase: "finishing", error: "provider failed" },
});
expect(state.lifecycleError).toBe("provider failed");
expect(state.lifecycleFinishing).toBe(true);
expect(state.lifecycleEnded).toBe(false);
});
it("replaces a failed candidate lifecycle when a retry starts", async () => {
const state: AgentAttemptLifecycleState = {
currentTurnUserMessagePersisted: true,
lifecycleError: "provider failed",
lifecycleErrorObservation: { provider: "openai", httpStatus: 502 },
lifecycleFinishing: true,
lifecycleEnded: false,
};
const callbacks = createAgentAttemptLifecycleCallbacks(state);
await callbacks.onAgentEvent({ stream: "lifecycle", data: { phase: "start" } });
expect(state).toEqual({
currentTurnUserMessagePersisted: true,
lifecycleError: undefined,
lifecycleErrorObservation: undefined,
lifecycleFinishing: false,
lifecycleEnded: false,
});
});
});
|