mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 09:22:45 +00:00
fix(agents): guard promoteThinkingTagsToBlocks against malformed content entries (#35143)
Merged via squash.
Prepared head SHA: 3971122f5f
Co-authored-by: Sid-Qin <201593046+Sid-Qin@users.noreply.github.com>
Co-authored-by: shakkernerd <165377636+shakkernerd@users.noreply.github.com>
Reviewed-by: @shakkernerd
This commit is contained in:
@@ -3,6 +3,7 @@ import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
extractAssistantText,
|
||||
formatReasoningMessage,
|
||||
promoteThinkingTagsToBlocks,
|
||||
stripDowngradedToolCallText,
|
||||
} from "./pi-embedded-utils.js";
|
||||
|
||||
@@ -549,6 +550,39 @@ describe("stripDowngradedToolCallText", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("promoteThinkingTagsToBlocks", () => {
|
||||
it("does not crash on malformed null content entries", () => {
|
||||
const msg = makeAssistantMessage({
|
||||
role: "assistant",
|
||||
content: [null as never, { type: "text", text: "<thinking>hello</thinking>ok" }],
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
expect(() => promoteThinkingTagsToBlocks(msg)).not.toThrow();
|
||||
const types = msg.content.map((b: { type?: string }) => b?.type);
|
||||
expect(types).toContain("thinking");
|
||||
expect(types).toContain("text");
|
||||
});
|
||||
|
||||
it("does not crash on undefined content entries", () => {
|
||||
const msg = makeAssistantMessage({
|
||||
role: "assistant",
|
||||
content: [undefined as never, { type: "text", text: "no tags here" }],
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
expect(() => promoteThinkingTagsToBlocks(msg)).not.toThrow();
|
||||
});
|
||||
|
||||
it("passes through well-formed content unchanged when no thinking tags", () => {
|
||||
const msg = makeAssistantMessage({
|
||||
role: "assistant",
|
||||
content: [{ type: "text", text: "hello world" }],
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
promoteThinkingTagsToBlocks(msg);
|
||||
expect(msg.content).toEqual([{ type: "text", text: "hello world" }]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("empty input handling", () => {
|
||||
it("returns empty string", () => {
|
||||
const helpers = [formatReasoningMessage, stripDowngradedToolCallText];
|
||||
|
||||
@@ -333,7 +333,9 @@ export function promoteThinkingTagsToBlocks(message: AssistantMessage): void {
|
||||
if (!Array.isArray(message.content)) {
|
||||
return;
|
||||
}
|
||||
const hasThinkingBlock = message.content.some((block) => block.type === "thinking");
|
||||
const hasThinkingBlock = message.content.some(
|
||||
(block) => block && typeof block === "object" && block.type === "thinking",
|
||||
);
|
||||
if (hasThinkingBlock) {
|
||||
return;
|
||||
}
|
||||
@@ -342,6 +344,10 @@ export function promoteThinkingTagsToBlocks(message: AssistantMessage): void {
|
||||
let changed = false;
|
||||
|
||||
for (const block of message.content) {
|
||||
if (!block || typeof block !== "object" || !("type" in block)) {
|
||||
next.push(block);
|
||||
continue;
|
||||
}
|
||||
if (block.type !== "text") {
|
||||
next.push(block);
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user