Spaces:
Runtime error
Runtime error
| import { tool } from "ai"; | |
| import { z } from "zod"; | |
| /** | |
| * Tools for the Embed Studio AI. These return instructions that the | |
| * frontend executes on the EmbedStore (Y.Map). The backend never | |
| * touches the Yjs document directly. | |
| */ | |
| export const embedTools = { | |
| createEmbed: tool({ | |
| description: | |
| "Create or fully replace an HTML embed chart. Use when building a new chart from scratch " + | |
| "or when changes are so extensive that a full rewrite is cleaner than patching. " + | |
| "The HTML must be a self-contained fragment following D3 embed conventions " + | |
| "(root div + scoped style + IIFE script).", | |
| inputSchema: z.object({ | |
| html: z | |
| .string() | |
| .describe( | |
| "Complete self-contained HTML fragment (root div + scoped style + IIFE script)", | |
| ), | |
| title: z | |
| .string() | |
| .optional() | |
| .describe("Short descriptive title for the chart"), | |
| source: z | |
| .string() | |
| .optional() | |
| .describe("Data source attribution"), | |
| filename: z | |
| .string() | |
| .optional() | |
| .describe( | |
| "Descriptive file name slug for this chart, WITHOUT extension " + | |
| "(e.g. 'attention-heatmap', 'model-accuracy', 'sales-by-region'). " + | |
| "Use kebab-case, ASCII only, concise (2-4 words, <40 chars). " + | |
| "REQUIRED on the first createEmbed call for a new chart - the " + | |
| "client will slugify it, ensure uniqueness, and rename the file " + | |
| "automatically. Omit on subsequent calls that only update the " + | |
| "existing chart (the current name will be kept).", | |
| ), | |
| }), | |
| }), | |
| patchEmbed: tool({ | |
| description: | |
| "Replace a specific block of code in the current chart HTML. " + | |
| "Use for targeted edits (color change, label update, data tweak, bug fix). " + | |
| "Always prefer this over createEmbed when modifying an existing chart. " + | |
| "The search string must be an exact verbatim excerpt from the current HTML " + | |
| "(whitespace included). Call readEmbed first if unsure of the exact content.", | |
| inputSchema: z.object({ | |
| search: z | |
| .string() | |
| .describe( | |
| "Exact verbatim excerpt from the current chart HTML to find and replace. " + | |
| "Must be long enough to be unique (at least 3-5 lines of context).", | |
| ), | |
| replace: z | |
| .string() | |
| .describe("The new code that replaces the search block"), | |
| }), | |
| }), | |
| readEmbed: tool({ | |
| description: | |
| "Read the full current chart HTML. Use before calling patchEmbed " + | |
| "to verify the exact content, or to understand the current structure before editing.", | |
| inputSchema: z.object({}), | |
| }), | |
| listDataFiles: tool({ | |
| description: | |
| "List all data files (CSV, TSV, JSON, NDJSON, TXT) the user has " + | |
| "attached to this document. Returns one line per file with name, " + | |
| "extension, size, row count, and column names when available. " + | |
| "Call this when the user mentions data, a dataset, or wants to " + | |
| "visualize content from a specific file.", | |
| inputSchema: z.object({}), | |
| }), | |
| readDataFile: tool({ | |
| description: | |
| "Read the full raw content of a data file previously listed by " + | |
| "listDataFiles. Use this to inspect the exact structure, sample " + | |
| "values, or to embed small datasets directly into the chart. Large " + | |
| "files may be truncated - prefer loading via fetch from " + | |
| "/data/<name> for charts that rely on the full dataset.", | |
| inputSchema: z.object({ | |
| name: z | |
| .string() | |
| .describe("Exact file name as returned by listDataFiles (e.g. 'sales.csv')"), | |
| }), | |
| }), | |
| }; | |