

























@@ -5,6 +5,7 @@ import { castAgentMessage, castAgentMessages } from "../test-helpers/agent-messa
55import {
66OMITTED_ASSISTANT_REASONING_TEXT,
77assessLastAssistantMessage,
8+dropReasoningFromHistory,
89dropThinkingBlocks,
910isAssistantMessageWithContent,
1011sanitizeThinkingForRecovery,
@@ -157,6 +158,105 @@ describe("dropThinkingBlocks", () => {
157158});
158159});
159160161+describe("dropReasoningFromHistory", () => {
162+it("returns the original reference when no thinking blocks are present", () => {
163+const messages: AgentMessage[] = [
164+castAgentMessage({ role: "user", content: "hello" }),
165+castAgentMessage({ role: "assistant", content: [{ type: "text", text: "world" }] }),
166+];
167+168+const result = dropReasoningFromHistory(messages);
169+expect(result).toBe(messages);
170+});
171+172+it("strips assistant reasoning from prior completed turns", () => {
173+const messages: AgentMessage[] = [
174+castAgentMessage({ role: "user", content: "first" }),
175+castAgentMessage({
176+role: "assistant",
177+content: [
178+{ type: "thinking", thinking: "private" },
179+{ type: "text", text: "visible" },
180+],
181+}),
182+castAgentMessage({ role: "user", content: "second" }),
183+];
184+185+const result = dropReasoningFromHistory(messages);
186+const assistant = result[1] as AssistantMessage;
187+188+expect(result).not.toBe(messages);
189+expect(assistant.content).toEqual([{ type: "text", text: "visible" }]);
190+});
191+192+it("uses omitted-reasoning text when a completed assistant turn is reasoning-only", () => {
193+const messages: AgentMessage[] = [
194+castAgentMessage({ role: "user", content: "first" }),
195+castAgentMessage({
196+role: "assistant",
197+content: [{ type: "thinking", thinking: "private" }],
198+}),
199+castAgentMessage({ role: "user", content: "second" }),
200+];
201+202+const result = dropReasoningFromHistory(messages);
203+const assistant = result[1] as AssistantMessage;
204+205+expect(assistant.content).toEqual([{ type: "text", text: OMITTED_ASSISTANT_REASONING_TEXT }]);
206+});
207+208+it("preserves reasoning for the active tool-call continuation after the latest user turn", () => {
209+const messages: AgentMessage[] = [
210+castAgentMessage({ role: "user", content: "look up the answer" }),
211+castAgentMessage({
212+role: "assistant",
213+content: [
214+{ type: "thinking", thinking: "call the tool" },
215+{ type: "toolCall", id: "call123456", name: "lookup", arguments: {} },
216+],
217+}),
218+castAgentMessage({
219+role: "toolResult",
220+toolCallId: "call123456",
221+toolName: "lookup",
222+content: "42",
223+}),
224+];
225+226+const result = dropReasoningFromHistory(messages);
227+228+expect(result).toBe(messages);
229+});
230+231+it("strips reasoning from old tool-call turns once a later user turn starts", () => {
232+const messages: AgentMessage[] = [
233+castAgentMessage({ role: "user", content: "look up the answer" }),
234+castAgentMessage({
235+role: "assistant",
236+content: [
237+{ type: "thinking", thinking: "call the tool" },
238+{ type: "toolCall", id: "call123456", name: "lookup", arguments: {} },
239+],
240+}),
241+castAgentMessage({
242+role: "toolResult",
243+toolCallId: "call123456",
244+toolName: "lookup",
245+content: "42",
246+}),
247+castAgentMessage({ role: "assistant", content: [{ type: "text", text: "42" }] }),
248+castAgentMessage({ role: "user", content: "thanks" }),
249+];
250+251+const result = dropReasoningFromHistory(messages);
252+const assistant = result[1] as AssistantMessage;
253+254+expect(assistant.content).toEqual([
255+{ type: "toolCall", id: "call123456", name: "lookup", arguments: {} },
256+]);
257+});
258+});
259+160260describe("stripInvalidThinkingSignatures", () => {
161261it("returns the original reference when no invalid thinking signatures are present", () => {
162262const messages: AgentMessage[] = [
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。