mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 02:06:43 +00:00
fix(ui): tolerate absent chat-event messages in text extractors (#111918)
This commit is contained in:
@@ -1,7 +1,12 @@
|
||||
// @vitest-environment node
|
||||
// Control UI tests cover message extract behavior.
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { extractText, extractTextCached, extractThinkingCached } from "./message-extract.ts";
|
||||
import {
|
||||
extractRawText,
|
||||
extractText,
|
||||
extractTextCached,
|
||||
extractThinkingCached,
|
||||
} from "./message-extract.ts";
|
||||
|
||||
describe("extractTextCached", () => {
|
||||
it("matches extractText output", () => {
|
||||
@@ -137,3 +142,16 @@ describe("extractThinkingCached", () => {
|
||||
expect(extractThinkingCached(message)).toBe("Plan A");
|
||||
});
|
||||
});
|
||||
|
||||
describe("nullish messages", () => {
|
||||
// Chat events can arrive without a message (tool-only or heartbeat finals);
|
||||
// every unknown-typed extractor must read that as "no text", not throw.
|
||||
it("returns null instead of throwing for absent messages", () => {
|
||||
for (const message of [undefined, null]) {
|
||||
expect(extractText(message)).toBeNull();
|
||||
expect(extractTextCached(message)).toBeNull();
|
||||
expect(extractRawText(message)).toBeNull();
|
||||
expect(extractThinkingCached(message)).toBeNull();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -29,6 +29,11 @@ function processMessageText(text: string, role: string): string {
|
||||
}
|
||||
|
||||
export function extractText(message: unknown): string | null {
|
||||
// Chat events may carry no message at all (tool-only or heartbeat finals);
|
||||
// a nullish message means "no text", never a crash.
|
||||
if (message == null) {
|
||||
return null;
|
||||
}
|
||||
const m = message as Record<string, unknown>;
|
||||
const role = typeof m.role === "string" ? m.role : "";
|
||||
const raw =
|
||||
@@ -53,6 +58,9 @@ export function extractTextCached(message: unknown): string | null {
|
||||
}
|
||||
|
||||
function extractThinking(message: unknown): string | null {
|
||||
if (message == null) {
|
||||
return null;
|
||||
}
|
||||
const m = message as Record<string, unknown>;
|
||||
const content = m.content;
|
||||
const parts: string[] = [];
|
||||
@@ -84,6 +92,9 @@ export function extractThinkingCached(message: unknown): string | null {
|
||||
}
|
||||
|
||||
export function extractRawText(message: unknown): string | null {
|
||||
if (message == null) {
|
||||
return null;
|
||||
}
|
||||
const m = message as Record<string, unknown>;
|
||||
const role = normalizeLowercaseStringOrEmpty(m.role);
|
||||
const content = m.content;
|
||||
|
||||
Reference in New Issue
Block a user