mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:40:44 +00:00
test(agents): share validate turns helpers
This commit is contained in:
@@ -32,6 +32,21 @@ function makeDualToolAnthropicTurns(nextUserContent: unknown[]) {
|
||||
]);
|
||||
}
|
||||
|
||||
function makeSignedThinkingGatewayToolCall(toolId: string) {
|
||||
return [
|
||||
{ type: "thinking", thinking: "internal", thinkingSignature: "sig_1" },
|
||||
{ type: "toolCall", id: toolId, name: "gateway", arguments: {} },
|
||||
];
|
||||
}
|
||||
|
||||
function expectAssistantToolCallsOmitted(result: AgentMessage[], expectedLength: number) {
|
||||
expect(result).toHaveLength(expectedLength);
|
||||
expect((result[1] as { role?: unknown }).role).toBe("assistant");
|
||||
expect((result[1] as { content?: unknown[] }).content).toEqual([
|
||||
{ type: "text", text: "[tool calls omitted]" },
|
||||
]);
|
||||
}
|
||||
|
||||
describe("validate turn edge cases", () => {
|
||||
it("returns empty array unchanged", () => {
|
||||
expect(validateGeminiTurns([])).toEqual([]);
|
||||
@@ -530,10 +545,7 @@ describe("validateAnthropicTurns strips dangling tool_use blocks", () => {
|
||||
{ role: "user", content: [{ type: "text", text: "Use tool" }] },
|
||||
{
|
||||
role: "assistant",
|
||||
content: [
|
||||
{ type: "thinking", thinking: "internal", thinkingSignature: "sig_1" },
|
||||
{ type: "toolCall", id: "tool-1", name: "gateway", arguments: {} },
|
||||
],
|
||||
content: makeSignedThinkingGatewayToolCall("tool-1"),
|
||||
},
|
||||
{
|
||||
role: "toolResult",
|
||||
@@ -549,10 +561,7 @@ describe("validateAnthropicTurns strips dangling tool_use blocks", () => {
|
||||
|
||||
expect(result).toHaveLength(4);
|
||||
const assistantContent = (result[1] as { content?: unknown[] }).content;
|
||||
expect(assistantContent).toEqual([
|
||||
{ type: "thinking", thinking: "internal", thinkingSignature: "sig_1" },
|
||||
{ type: "toolCall", id: "tool-1", name: "gateway", arguments: {} },
|
||||
]);
|
||||
expect(assistantContent).toEqual(makeSignedThinkingGatewayToolCall("tool-1"));
|
||||
});
|
||||
|
||||
it("drops signed-thinking turns when the only matching tool result is embedded in user content", () => {
|
||||
@@ -561,7 +570,7 @@ describe("validateAnthropicTurns strips dangling tool_use blocks", () => {
|
||||
{
|
||||
role: "assistant",
|
||||
content: [
|
||||
{ type: "thinking", thinking: "internal", thinkingSignature: "sig_1" },
|
||||
makeSignedThinkingGatewayToolCall("tool-1")[0],
|
||||
{ type: "toolUse", id: "tool-1", name: "gateway", arguments: {} },
|
||||
],
|
||||
},
|
||||
@@ -576,11 +585,7 @@ describe("validateAnthropicTurns strips dangling tool_use blocks", () => {
|
||||
|
||||
const result = validateAnthropicTurns(msgs);
|
||||
|
||||
expect(result).toHaveLength(3);
|
||||
expect((result[1] as { role?: unknown }).role).toBe("assistant");
|
||||
expect((result[1] as { content?: unknown[] }).content).toEqual([
|
||||
{ type: "text", text: "[tool calls omitted]" },
|
||||
]);
|
||||
expectAssistantToolCallsOmitted(result, 3);
|
||||
});
|
||||
|
||||
it("preserves signed-thinking turns when a trusted tool result carries both stale and current id aliases", () => {
|
||||
@@ -588,10 +593,7 @@ describe("validateAnthropicTurns strips dangling tool_use blocks", () => {
|
||||
{ role: "user", content: [{ type: "text", text: "Use tool" }] },
|
||||
{
|
||||
role: "assistant",
|
||||
content: [
|
||||
{ type: "thinking", thinking: "internal", thinkingSignature: "sig_1" },
|
||||
{ type: "toolCall", id: "tool-current", name: "gateway", arguments: {} },
|
||||
],
|
||||
content: makeSignedThinkingGatewayToolCall("tool-current"),
|
||||
},
|
||||
{
|
||||
role: "toolResult",
|
||||
@@ -607,10 +609,9 @@ describe("validateAnthropicTurns strips dangling tool_use blocks", () => {
|
||||
const result = validateAnthropicTurns(msgs);
|
||||
|
||||
expect(result).toHaveLength(4);
|
||||
expect((result[1] as { content?: unknown[] }).content).toEqual([
|
||||
{ type: "thinking", thinking: "internal", thinkingSignature: "sig_1" },
|
||||
{ type: "toolCall", id: "tool-current", name: "gateway", arguments: {} },
|
||||
]);
|
||||
expect((result[1] as { content?: unknown[] }).content).toEqual(
|
||||
makeSignedThinkingGatewayToolCall("tool-current"),
|
||||
);
|
||||
});
|
||||
|
||||
it("drops signed-thinking turns whose sibling tool calls are dangling", () => {
|
||||
@@ -618,21 +619,14 @@ describe("validateAnthropicTurns strips dangling tool_use blocks", () => {
|
||||
{ role: "user", content: [{ type: "text", text: "Use tool" }] },
|
||||
{
|
||||
role: "assistant",
|
||||
content: [
|
||||
{ type: "thinking", thinking: "internal", thinkingSignature: "sig_1" },
|
||||
{ type: "toolCall", id: "tool-1", name: "gateway", arguments: {} },
|
||||
],
|
||||
content: makeSignedThinkingGatewayToolCall("tool-1"),
|
||||
},
|
||||
{ role: "user", content: [{ type: "text", text: "Continue" }] },
|
||||
]);
|
||||
|
||||
const result = validateAnthropicTurns(msgs);
|
||||
|
||||
expect(result).toHaveLength(3);
|
||||
expect((result[1] as { role?: unknown }).role).toBe("assistant");
|
||||
expect((result[1] as { content?: unknown[] }).content).toEqual([
|
||||
{ type: "text", text: "[tool calls omitted]" },
|
||||
]);
|
||||
expectAssistantToolCallsOmitted(result, 3);
|
||||
});
|
||||
|
||||
it("does not trust future tool results with the right id but the wrong tool name", () => {
|
||||
@@ -640,10 +634,7 @@ describe("validateAnthropicTurns strips dangling tool_use blocks", () => {
|
||||
{ role: "user", content: [{ type: "text", text: "Use tool" }] },
|
||||
{
|
||||
role: "assistant",
|
||||
content: [
|
||||
{ type: "thinking", thinking: "internal", thinkingSignature: "sig_1" },
|
||||
{ type: "toolCall", id: "tool-1", name: "gateway", arguments: {} },
|
||||
],
|
||||
content: makeSignedThinkingGatewayToolCall("tool-1"),
|
||||
},
|
||||
{
|
||||
role: "toolResult",
|
||||
@@ -657,10 +648,7 @@ describe("validateAnthropicTurns strips dangling tool_use blocks", () => {
|
||||
|
||||
const result = validateAnthropicTurns(msgs);
|
||||
|
||||
expect(result).toHaveLength(4);
|
||||
expect((result[1] as { content?: unknown[] }).content).toEqual([
|
||||
{ type: "text", text: "[tool calls omitted]" },
|
||||
]);
|
||||
expectAssistantToolCallsOmitted(result, 4);
|
||||
});
|
||||
|
||||
it("drops redacted-thinking turns whose sibling tool calls are dangling", () => {
|
||||
|
||||
Reference in New Issue
Block a user