Skip to content

Commit 2bcc17d

Browse files
SaxonFjoshenlim
andauthored
Feat/assistant convert supabasejs (supabase#30648)
* add ability to convert sql to js * remove console * Merge master + small style fix --------- Co-authored-by: Joshen Lim <[email protected]>
1 parent 78d0755 commit 2bcc17d

File tree

5 files changed

+57
-13
lines changed

5 files changed

+57
-13
lines changed

apps/studio/components/ui/AIAssistantPanel/Message.tsx

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { PropsWithChildren } from 'react'
33
import ReactMarkdown from 'react-markdown'
44
import remarkGfm from 'remark-gfm'
55

6-
import { cn, markdownComponents, WarningIcon } from 'ui'
6+
import { cn, markdownComponents, WarningIcon, CodeBlock } from 'ui'
77
import CollapsibleCodeBlock from './CollapsibleCodeBlock'
88
import { SqlSnippet } from './SqlSnippet'
99

@@ -56,20 +56,38 @@ export const Message = function Message({
5656
components={{
5757
...markdownComponents,
5858
pre: (props: any) => {
59-
return readOnly ? (
60-
<div className="mb-1 -mt-2">
61-
<CollapsibleCodeBlock
62-
value={props.children[0].props.children[0]}
63-
language="sql"
59+
const language = props.children[0].props.className?.replace('language-', '') || 'sql'
60+
61+
if (language === 'sql') {
62+
return readOnly ? (
63+
<div className="mb-1 -mt-2">
64+
<CollapsibleCodeBlock
65+
value={props.children[0].props.children[0]}
66+
language="sql"
67+
hideLineNumbers
68+
/>
69+
</div>
70+
) : (
71+
<SqlSnippet
72+
readOnly={readOnly}
73+
isLoading={isLoading}
74+
sql={props.children[0].props.children}
75+
/>
76+
)
77+
}
78+
79+
return (
80+
<div className="-mx-8">
81+
<CodeBlock
6482
hideLineNumbers
83+
value={props.children[0].props.children}
84+
language={language}
85+
className={cn(
86+
'max-h-96 max-w-none block !bg-transparent !py-3 !px-3.5 prose dark:prose-dark border-0 border-t border-b text-foreground !rounded-none w-full',
87+
'[&>code]:m-0 [&>code>span]:flex [&>code>span]:flex-wrap [&>code]:block [&>code>span]:text-foreground'
88+
)}
6589
/>
6690
</div>
67-
) : (
68-
<SqlSnippet
69-
readOnly={readOnly}
70-
isLoading={isLoading}
71-
sql={props.children[0].props.children}
72-
/>
7391
)
7492
},
7593
ol: (props: any) => {

apps/studio/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"@supabase/pg-meta": "*",
4343
"@supabase/realtime-js": "2.10.2",
4444
"@supabase/shared-types": "0.1.74",
45+
"@supabase/sql-to-rest": "^0.1.6",
4546
"@supabase/supabase-js": "^2.44.3",
4647
"@tanstack/react-query": "4.35.7",
4748
"@tanstack/react-query-devtools": "4.35.7",

apps/studio/pages/api/ai/sql/generate-v3.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ async function handlePost(req: NextApiRequest, res: NextApiResponse) {
6868
model: openai('gpt-4o-mini'),
6969
maxSteps: 5,
7070
system: `
71-
You are a Supabase Postgres expert who can do three things.
71+
You are a Supabase Postgres expert who can do the following things.
7272
7373
# You generate and debug SQL
7474
The generated SQL (must be valid SQL), and must adhere to the following:
@@ -105,6 +105,9 @@ async function handlePost(req: NextApiRequest, res: NextApiResponse) {
105105
- Default to create or replace whenever possible for updating an existing function, otherwise use the alter function statement
106106
Please make sure that all queries are valid Postgres SQL queries
107107
108+
# You convert sql to supabase-js client code
109+
Use the convertSqlToSupabaseJs tool to convert select sql to supabase-js client code. If conversion isn't supported, build a postgres function instead and suggest using supabase-js to call it via "const { data, error } = await supabase.rpc('echo', { say: '👋'})"
110+
108111
Follow these instructions:
109112
- First look at the list of provided schemas and if needed, get more information about a schema. You will almost always need to retrieve information about the public schema before answering a question. If the question is about users, also retrieve the auth schema.
110113

apps/studio/pages/api/ai/sql/tools.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { z } from 'zod'
55
import { getDatabasePolicies } from 'data/database-policies/database-policies-query'
66
import { getEntityDefinitionsSql } from 'data/database/entity-definitions-query'
77
import { executeSql } from 'data/sql/execute-sql-query'
8+
import { processSql, renderSupabaseJs } from '@supabase/sql-to-rest'
89

910
export const getTools = ({
1011
projectRef,
@@ -47,6 +48,25 @@ export const getTools = ({
4748
}
4849
},
4950
}),
51+
convertSqlToSupabaseJs: tool({
52+
description: 'Convert an sql query into supabase-js client code',
53+
parameters: z.object({
54+
sql: z
55+
.string()
56+
.describe(
57+
'The sql statement to convert. Only a subset of statements are supported currently. '
58+
),
59+
}),
60+
execute: async ({ sql }) => {
61+
try {
62+
const statement = await processSql(sql)
63+
const { code } = await renderSupabaseJs(statement)
64+
return code
65+
} catch (error) {
66+
return `Failed to convert SQL: ${error}`
67+
}
68+
},
69+
}),
5070
getRlsKnowledge: tool({
5171
description:
5272
'Get existing policies and examples and instructions on how to write RLS policies',

package-lock.json

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)