mirror of
https://github.com/supabase/supabase.git
synced 2026-10-18 23:59:08 +03:00
## Summary
Migrates four more assistant tools to the contract + `.server.ts`
pattern used by the notebook tools. Each tool now declares its schemas,
opt-in level, approval and model-visible output once.
## Changes
* Add contracts and server factories for `execute_sql`,
`deploy_edge_function`, `rename_chat`, `load_knowledge`;
`getStudioTools` now composes them.
* Add `execute-sql-output.ts` (output schema, `toModelRows`,
`NO_DATA_PERMISSIONS`) and `knowledge-topics.ts` (topic names + UI
labels, replacing the copy in `Message.Parts.utils.ts`).
* Delete `executeSqlSanitizer` and `ALL_TOOL_SANITIZERS`; history replay
goes through `sanitizeContractPart` only.
* Drop the four tools from `TOOL_CATEGORY_MAP`; the UI and evals import
schemas from the contracts; `rename_chat` input casts now use the
contract type.
## Deviations worth reviewing
* `execute_sql` replay: a bare-array legacy output is stamped `schema`
via a union transform (still hidden from the model, still shown in the
UI). A malformed non-array output is now dropped, where before it passed
through at the data level.
* The "no data permission" message now reaches the model as a JSON
string value instead of a text part. The text the model sees is
unchanged.
* `deploy_edge_function` output is now strictly `{ success: boolean }`
in the UI parse (was optional/passthrough).
37 lines
1.7 KiB
TypeScript
37 lines
1.7 KiB
TypeScript
import { z } from 'zod'
|
|
|
|
import { executeSqlOutputSchema, toModelExecuteSqlOutput } from './execute-sql-output'
|
|
import type { ToolContract } from './types'
|
|
import { fixSqlBackslashEscapes } from '@/lib/ai/util'
|
|
|
|
const inputSchema = z.object({
|
|
// Transform at parse time so the corrected SQL is what gets stored in
|
|
// toolCall.input — ensuring evals and logs reflect what actually runs.
|
|
sql: z.string().describe('The SQL statement to execute.').transform(fixSqlBackslashEscapes),
|
|
label: z.string().describe('A short 2-4 word label for the SQL statement.'),
|
|
chartConfig: z
|
|
.object({
|
|
view: z.enum(['table', 'chart']).describe('How to render the results after execution'),
|
|
xAxis: z.string().optional().describe('The column to use for the x-axis of the chart.'),
|
|
yAxis: z.string().optional().describe('The column to use for the y-axis of the chart.'),
|
|
})
|
|
.describe('Chart configuration for rendering the results'),
|
|
isWriteQuery: z
|
|
.boolean()
|
|
.default(false)
|
|
.describe(
|
|
'Whether the SQL statement performs a write operation or has side effects. Set true for INSERT/UPDATE/DELETE/DDL and for SELECT statements that call side-effecting functions, such as select cron.schedule(...), cron.unschedule(...), or functions that create, modify, schedule, enqueue, notify, or trigger work.'
|
|
),
|
|
})
|
|
|
|
export const contract = {
|
|
name: 'execute_sql',
|
|
description:
|
|
'Asks the user to execute a SQL statement and return the results. Requires user approval before executing.',
|
|
inputSchema,
|
|
outputSchema: executeSqlOutputSchema,
|
|
minOptInLevel: null,
|
|
needsApproval: true,
|
|
toModelOutput: toModelExecuteSqlOutput,
|
|
} as const satisfies ToolContract
|