




















11import type { AgentMessage } from "@earendil-works/pi-agent-core";
2-import type { AssistantMessage, UserMessage, Usage } from "@earendil-works/pi-ai";
2+import type { AssistantMessage, ThinkingContent, UserMessage, Usage } from "@earendil-works/pi-ai";
33import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
44import {
55expectOpenAIResponsesStrictSanitizeCall,
@@ -1494,6 +1494,87 @@ describe("sanitizeSessionHistory", () => {
14941494},
14951495);
149614961497+it("strips invalid direct Anthropic thinking signatures from prior assistant turns when a user follows up", async () => {
1498+setNonGoogleModelApi();
1499+1500+const messages = castAgentMessages([
1501+makeUserMessage("first"),
1502+makeAssistantMessage([
1503+{
1504+type: "thinking",
1505+thinking: "empty signature",
1506+signature: "",
1507+} as unknown as ThinkingContent,
1508+{ type: "thinking", thinking: "blank signature", thinkingSignature: " " },
1509+]),
1510+makeUserMessage("second"),
1511+]);
1512+1513+const result = await sanitizeAnthropicHistory({
1514+provider: "anthropic",
1515+modelApi: "anthropic-messages",
1516+ messages,
1517+modelId: "claude-sonnet-4-6",
1518+});
1519+1520+expect((result[1] as Extract<AgentMessage, { role: "assistant" }>).content).toEqual([
1521+{ type: "text", text: OMITTED_ASSISTANT_REASONING_TEXT },
1522+]);
1523+});
1524+1525+it.each([
1526+{
1527+provider: "anthropic",
1528+modelApi: "anthropic-messages",
1529+label: "anthropic",
1530+},
1531+{
1532+provider: "amazon-bedrock",
1533+modelApi: "bedrock-converse-stream",
1534+label: "bedrock",
1535+},
1536+])(
1537+"preserves active tool-turn thinking signatures for $label even when a tool result follows",
1538+async ({ provider, modelApi }) => {
1539+setNonGoogleModelApi();
1540+1541+const messages = castAgentMessages([
1542+makeUserMessage("look up the answer"),
1543+makeAssistantMessage([
1544+{
1545+type: "thinking",
1546+thinking: "call the tool",
1547+signature: "",
1548+} as unknown as ThinkingContent,
1549+{ type: "toolCall", id: "call_1", name: "lookup", arguments: {} },
1550+]),
1551+castAgentMessage({
1552+role: "toolResult",
1553+toolCallId: "call_1",
1554+toolName: "lookup",
1555+content: [{ type: "text", text: "42" }],
1556+isError: false,
1557+}),
1558+]);
1559+1560+const result = await sanitizeAnthropicHistory({
1561+ provider,
1562+ modelApi,
1563+ messages,
1564+modelId: "claude-sonnet-4-6",
1565+});
1566+1567+expect((result[1] as Extract<AgentMessage, { role: "assistant" }>).content).toEqual([
1568+{
1569+type: "thinking",
1570+thinking: "call the tool",
1571+signature: "",
1572+},
1573+{ type: "toolCall", id: "call_1", name: "lookup", arguments: {} },
1574+]);
1575+},
1576+);
1577+14971578it.each([
14981579{
14991580provider: "anthropic",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。