feat(ai): add shared contentText utility (#6840)
Co-authored-by: Armin Ronacher <armin.ronacher@active-4.com>
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
### Added
|
||||
|
||||
- Added `contentText` for extracting joined text from message content.
|
||||
- Added a shared `uuidv7` utility for time-ordered identifiers.
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -41,6 +41,7 @@ export * from "./utils/event-stream.ts";
|
||||
export * from "./utils/json-parse.ts";
|
||||
export * from "./utils/overflow.ts";
|
||||
export * from "./utils/retry.ts";
|
||||
export { contentText } from "./utils/text.ts";
|
||||
export * from "./utils/typebox-helpers.ts";
|
||||
export { uuidv7 } from "./utils/uuid.ts";
|
||||
export * from "./utils/validation.ts";
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import type { ImageContent, TextContent, ThinkingContent, ToolCall } from "../types.ts";
|
||||
|
||||
type Content = TextContent | ImageContent | ThinkingContent | ToolCall;
|
||||
|
||||
/** Extract and join text from message content. */
|
||||
export function contentText(content: string | readonly Content[], separator = "\n"): string {
|
||||
if (typeof content === "string") return content;
|
||||
return content
|
||||
.filter((block) => block.type === "text")
|
||||
.map((block) => block.text)
|
||||
.join(separator);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { type AssistantMessage, contentText, type ToolResultMessage } from "../src/index.ts";
|
||||
|
||||
const content: AssistantMessage["content"] = [
|
||||
{ type: "thinking", thinking: "reasoning" },
|
||||
{ type: "text", text: "first" },
|
||||
{ type: "toolCall", id: "1", name: "read", arguments: {} },
|
||||
{ type: "text", text: "second" },
|
||||
];
|
||||
|
||||
describe("contentText", () => {
|
||||
it("extracts assistant text blocks", () => {
|
||||
expect(contentText(content)).toBe("first\nsecond");
|
||||
});
|
||||
|
||||
it("supports custom separators", () => {
|
||||
expect(contentText(content, "")).toBe("firstsecond");
|
||||
});
|
||||
|
||||
it("passes string content through", () => {
|
||||
expect(contentText("hello")).toBe("hello");
|
||||
});
|
||||
|
||||
it("extracts text from tool-result content", () => {
|
||||
const toolResultContent: ToolResultMessage["content"] = [
|
||||
{ type: "text", text: "first" },
|
||||
{ type: "image", data: "...", mimeType: "image/png" },
|
||||
{ type: "text", text: "second" },
|
||||
];
|
||||
|
||||
expect(contentText(toolResultContent, "")).toBe("firstsecond");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user