(params: Record<string, unknown>, context: ToolExecutionContext)
| 120 | } |
| 121 | |
| 122 | async function handler(params: Record<string, unknown>, context: ToolExecutionContext): Promise<ToolResult> { |
| 123 | if (!context.dataProvider) throw new Error('render_chart requires a data provider') |
| 124 | |
| 125 | const hasSql = typeof params.sql === 'string' && params.sql.trim().length > 0 |
| 126 | const hasRows = Array.isArray(params.rows) |
| 127 | if (!hasSql && !hasRows) throw new Error('render_chart requires either sql or rows') |
| 128 | |
| 129 | const maxRows = normalizeMaxRows(params.maxRows) |
| 130 | let rows: Record<string, unknown>[] |
| 131 | let truncated: boolean |
| 132 | |
| 133 | if (hasRows) { |
| 134 | const normalized = normalizeRows(params.rows, maxRows) |
| 135 | rows = normalized.rows |
| 136 | truncated = normalized.truncated |
| 137 | } else { |
| 138 | const sql = normalizeSql(params.sql, maxRows) |
| 139 | const sqlParams = normalizeParams(params.params) |
| 140 | const fetchedRows = await context.dataProvider.executeParameterizedSql<Record<string, unknown>>(sql, sqlParams) |
| 141 | truncated = fetchedRows.length > maxRows |
| 142 | rows = truncated ? fetchedRows.slice(0, maxRows) : fetchedRows |
| 143 | } |
| 144 | |
| 145 | const chart = buildChartPayload(rows, params.chartSpec, { truncated }) |
| 146 | |
| 147 | return { |
| 148 | content: summarizeChartForModel(chart.spec.type, chart.spec.title, rows, truncated, context.locale), |
| 149 | data: { |
| 150 | rowCount: rows.length, |
| 151 | truncated, |
| 152 | chartType: chart.spec.type, |
| 153 | title: chart.spec.title, |
| 154 | }, |
| 155 | chart, |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | export const renderChartTool: ToolDefinition = { |
| 160 | name: 'render_chart', |
nothing calls this directly
no test coverage detected