fix(ui): tolerate absent chat-event messages in text extractors (#111918)

This commit is contained in:
Peter Steinberger
2026-07-20 10:33:20 -07:00
committed by GitHub
parent febeb6ac12
commit 271e6b7391
2 changed files with 30 additions and 1 deletions
+19 -1
View File
@@ -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();
}
});
});
+11
View File
@@ -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;