refactor(agent): snapshot harness turn state

This commit is contained in:
Mario Zechner
2026-05-09 23:34:46 +02:00
parent 76131673d3
commit 322759a3f0
8 changed files with 587 additions and 305 deletions

View File

@@ -894,6 +894,79 @@ describe("agentLoop with AgentMessage", () => {
expect(parallelObserved).toBe(true);
});
it("should use prepareNextTurn snapshot before continuing", async () => {
const toolSchema = Type.Object({ value: Type.String() });
const tool: AgentTool<typeof toolSchema, { value: string }> = {
name: "echo",
label: "Echo",
description: "Echo tool",
parameters: toolSchema,
async execute(_toolCallId, params) {
return {
content: [{ type: "text", text: `echoed: ${params.value}` }],
details: { value: params.value },
};
},
};
const context: AgentContext = {
systemPrompt: "first prompt",
messages: [],
tools: [tool],
};
let convertedSecondTurnSystemPrompt = "";
let prepared = false;
const config: AgentLoopConfig = {
model: createModel(),
convertToLlm: identityConverter,
prepareNextTurn: async ({ context: currentContext }) => {
if (prepared) return undefined;
prepared = true;
return {
context: {
systemPrompt: "second prompt",
messages: currentContext.messages.slice(),
tools: currentContext.tools,
},
};
},
};
let llmCalls = 0;
const stream = agentLoop([createUserMessage("echo something")], context, config, undefined, (_model, ctx) => {
llmCalls++;
if (llmCalls === 2) {
convertedSecondTurnSystemPrompt = ctx.systemPrompt ?? "";
}
const mockStream = new MockAssistantStream();
queueMicrotask(() => {
if (llmCalls === 1) {
mockStream.push({
type: "done",
reason: "toolUse",
message: createAssistantMessage(
[{ type: "toolCall", id: "tool-1", name: "echo", arguments: { value: "hello" } }],
"toolUse",
),
});
} else {
mockStream.push({
type: "done",
reason: "stop",
message: createAssistantMessage([{ type: "text", text: "done" }]),
});
}
});
return mockStream;
});
for await (const _event of stream) {
// consume
}
expect(llmCalls).toBe(2);
expect(convertedSecondTurnSystemPrompt).toBe("second prompt");
});
it("should stop after the current turn when shouldStopAfterTurn returns true", async () => {
const toolSchema = Type.Object({ value: Type.String() });
const executed: string[] = [];