/** * Chart Tool for Notes * Allows AI to generate inline charts from note data */ import { tool } from 'ai' import { z } from 'zod' import { toolRegistry } from './registry' import { prisma } from '@/lib/prisma' // Simple chart insertion tool - does everything in one call toolRegistry.register({ name: 'insert_chart', description: 'Generate a chart and insert it directly into a note. Use when the user asks for a chart, graph, or visualization.', isInternal: true, buildTool: (ctx) => tool({ description: `Generate a chart and insert it directly into the note content. Available chart types: - "bar": Vertical bar chart (default for comparisons) - "horizontal-bar": Horizontal bar chart (use when labels are long) - "line": Line chart (use for time series or trends) - "area": Area chart (filled line chart) - "pie": Pie chart (use for proportions/percentages) - "radar": Radar chart (use for comparing multiple dimensions) IMPORTANT: When the user asks for a chart/graph/visualization: 1. Extract the data from the note or user request 2. Choose the appropriate chart type based on the data 3. Generate the chart markdown using this format: \`\`\`chart {chartType} {title} {label1}: {value1} {label2}: {value2} ... \`\`\` Example for "show sales by month": \`\`\`chart bar Sales by Month Jan: 5000 Feb: 7500 Mar: 6200 \`\`\` 4. Call this tool with the noteId, the chart markdown, and where to insert it`, inputSchema: z.object({ noteId: z.string().describe('The note ID to update'), chartMarkdown: z.string().describe('The complete chart markdown block to insert (including the ```chart fences)'), insertLocation: z.enum(['append', 'prepend']).default('append').describe('append: add to end, prepend: add to start'), }), execute: async ({ noteId, chartMarkdown, insertLocation }) => { try { const note = await prisma.note.findFirst({ where: { id: noteId, userId: ctx.userId }, select: { content: true }, }) if (!note) return { error: 'Note not found' } const updatedContent = insertLocation === 'append' ? `${note.content}\n\n${chartMarkdown}` : `${chartMarkdown}\n\n${note.content}` await prisma.note.update({ where: { id: noteId }, data: { content: updatedContent }, }) return { success: true, message: `Chart ${insertLocation === 'append' ? 'appended' : 'prepended'} to note.`, chartMarkdown, } } catch (e: any) { return { success: false, error: `Failed: ${e.message}` } } }, }), })