test: cover tool call hydration preview
This commit is contained in:
@@ -26,15 +26,9 @@ import { baseColors, theme } from "@/styles/theme";
|
||||
import { Colors } from "@/constants/theme";
|
||||
import * as Clipboard from "expo-clipboard";
|
||||
import type { TodoEntry } from "@/types/stream";
|
||||
import {
|
||||
extractCommandDetails,
|
||||
extractEditEntries,
|
||||
extractReadEntries,
|
||||
type CommandDetails,
|
||||
type EditEntry,
|
||||
type ReadEntry,
|
||||
} from "@/utils/tool-call-parsers";
|
||||
import type { CommandDetails, EditEntry, ReadEntry } from "@/utils/tool-call-parsers";
|
||||
import { DiffViewer } from "./diff-viewer";
|
||||
import { resolveToolCallPreview } from "./tool-call-preview";
|
||||
|
||||
interface UserMessageProps {
|
||||
message: string;
|
||||
@@ -1010,12 +1004,17 @@ export const ToolCall = memo(function ToolCall({
|
||||
parsedCommandDetails,
|
||||
onOpenDetails,
|
||||
}: ToolCallProps) {
|
||||
const fallbackEditEntries = useMemo(() => extractEditEntries(args, result), [args, result]);
|
||||
const editEntries = parsedEditEntries ?? fallbackEditEntries;
|
||||
const fallbackReadEntries = useMemo(() => extractReadEntries(result, args), [args, result]);
|
||||
const readEntries = parsedReadEntries ?? fallbackReadEntries;
|
||||
const fallbackCommandDetails = useMemo(() => extractCommandDetails(args, result), [args, result]);
|
||||
const commandDetails = parsedCommandDetails ?? fallbackCommandDetails;
|
||||
const { editEntries, readEntries, commandDetails } = useMemo(
|
||||
() =>
|
||||
resolveToolCallPreview({
|
||||
args,
|
||||
result,
|
||||
parsedEditEntries,
|
||||
parsedReadEntries,
|
||||
parsedCommandDetails,
|
||||
}),
|
||||
[args, result, parsedEditEntries, parsedReadEntries, parsedCommandDetails]
|
||||
);
|
||||
|
||||
const primaryEditEntry = editEntries[0];
|
||||
const primaryReadEntry = readEntries[0];
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { resolveToolCallPreview } from "./tool-call-preview";
|
||||
import type { CommandDetails, EditEntry, ReadEntry } from "@/utils/tool-call-parsers";
|
||||
|
||||
describe("resolveToolCallPreview", () => {
|
||||
it("prefers parsed hydration payloads when provided", () => {
|
||||
const parsedEdits: EditEntry[] = [
|
||||
{
|
||||
filePath: "README.md",
|
||||
diffLines: [
|
||||
{ type: "header", content: "@@ -1 +1 @@" },
|
||||
{ type: "remove", content: "-Old" },
|
||||
{ type: "add", content: "+New" },
|
||||
],
|
||||
},
|
||||
];
|
||||
const parsedReads: ReadEntry[] = [
|
||||
{
|
||||
filePath: "README.md",
|
||||
content: "# Hydrated\nFinal text\n",
|
||||
},
|
||||
];
|
||||
const parsedCommand: CommandDetails = {
|
||||
command: "ls",
|
||||
cwd: "/tmp/hydrated",
|
||||
output: "README.md\npackages\n",
|
||||
exitCode: 0,
|
||||
};
|
||||
|
||||
const preview = resolveToolCallPreview({
|
||||
parsedEditEntries: parsedEdits,
|
||||
parsedReadEntries: parsedReads,
|
||||
parsedCommandDetails: parsedCommand,
|
||||
});
|
||||
|
||||
expect(preview.editEntries).toBe(parsedEdits);
|
||||
expect(preview.readEntries).toBe(parsedReads);
|
||||
expect(preview.commandDetails).toBe(parsedCommand);
|
||||
});
|
||||
|
||||
it("falls back to derived parser output when hydration metadata is missing", () => {
|
||||
const args = {
|
||||
type: "mcp_tool_use",
|
||||
id: "call_fallback",
|
||||
name: "apply_patch",
|
||||
server: "editor",
|
||||
input: {
|
||||
file_path: "README.md",
|
||||
patch: "*** Begin Patch\n*** Update File: README.md\n@@\n-Old\n+New\n*** End Patch",
|
||||
},
|
||||
};
|
||||
const result = {
|
||||
changes: [
|
||||
{
|
||||
file_path: "README.md",
|
||||
previous_content: "Old\n",
|
||||
content: "New\n",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const preview = resolveToolCallPreview({
|
||||
args,
|
||||
result,
|
||||
});
|
||||
|
||||
expect(preview.editEntries[0]?.diffLines.length).toBeGreaterThan(0);
|
||||
expect(
|
||||
preview.editEntries[0]?.diffLines.some((line) => line.content.includes("+New"))
|
||||
).toBe(true);
|
||||
expect(preview.commandDetails).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,40 @@
|
||||
import {
|
||||
extractCommandDetails,
|
||||
extractEditEntries,
|
||||
extractReadEntries,
|
||||
type CommandDetails,
|
||||
type EditEntry,
|
||||
type ReadEntry,
|
||||
} from "@/utils/tool-call-parsers";
|
||||
|
||||
export type ToolCallPreviewSource = {
|
||||
args?: unknown;
|
||||
result?: unknown;
|
||||
parsedEditEntries?: EditEntry[] | undefined;
|
||||
parsedReadEntries?: ReadEntry[] | undefined;
|
||||
parsedCommandDetails?: CommandDetails | null | undefined;
|
||||
};
|
||||
|
||||
export type ToolCallPreview = {
|
||||
editEntries: EditEntry[];
|
||||
readEntries: ReadEntry[];
|
||||
commandDetails: CommandDetails | null | undefined;
|
||||
};
|
||||
|
||||
export function resolveToolCallPreview({
|
||||
args,
|
||||
result,
|
||||
parsedEditEntries,
|
||||
parsedReadEntries,
|
||||
parsedCommandDetails,
|
||||
}: ToolCallPreviewSource): ToolCallPreview {
|
||||
const fallbackEditEntries = extractEditEntries(args, result);
|
||||
const fallbackReadEntries = extractReadEntries(result, args);
|
||||
const fallbackCommandDetails = extractCommandDetails(args, result);
|
||||
|
||||
return {
|
||||
editEntries: parsedEditEntries ?? fallbackEditEntries,
|
||||
readEntries: parsedReadEntries ?? fallbackReadEntries,
|
||||
commandDetails: parsedCommandDetails ?? fallbackCommandDetails,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user