Skip to content

Commit ba372c3

Browse files
authored
Feat/assistant refinements 3 (supabase#31015)
* limit local storage messages * add tool for getting database functions * reduce loading jitter in assistant
1 parent d100be4 commit ba372c3

File tree

4 files changed

+59
-8
lines changed

4 files changed

+59
-8
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ export const AIAssistant = ({
336336
)}
337337
</div>
338338
</div>
339-
{!includeSchemaMetadata && (
339+
{!includeSchemaMetadata && selectedOrganization && (
340340
<Admonition
341341
type="default"
342342
title="Project metadata is not shared"
@@ -345,7 +345,7 @@ export const AIAssistant = ({
345345
? 'Your organization has the HIPAA addon and will not send any project metadata with your prompts.'
346346
: 'The Assistant can improve the quality of the answers if you send project metadata along with your prompts. Opt into sending anonymous data to share your schema and table definitions.'
347347
}
348-
className="border-0 border-b rounded-none"
348+
className="border-0 border-b rounded-none bg-background"
349349
>
350350
{!hasHipaaAddon && (
351351
<Button

apps/studio/data/database-functions/database-functions-query.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,20 @@ const pgMetaFunctionsList = pgMeta.functions.list()
1616

1717
export async function getDatabaseFunctions(
1818
{ projectRef, connectionString }: DatabaseFunctionsVariables,
19-
signal?: AbortSignal
19+
signal?: AbortSignal,
20+
headersInit?: HeadersInit
2021
) {
22+
let headers = new Headers(headersInit)
23+
2124
const { result } = await executeSql(
2225
{
2326
projectRef,
2427
connectionString,
2528
sql: pgMetaFunctionsList.sql,
2629
queryKey: ['database-functions'],
2730
},
28-
signal
31+
signal,
32+
headers
2933
)
3034

3135
return result as DatabaseFunction[]

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

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { getDatabasePolicies } from 'data/database-policies/database-policies-qu
66
import { getEntityDefinitionsSql } from 'data/database/entity-definitions-query'
77
import { executeSql } from 'data/sql/execute-sql-query'
88
import { processSql, renderSupabaseJs } from '@supabase/sql-to-rest'
9+
import { getDatabaseFunctions } from 'data/database-functions/database-functions-query'
910

1011
export const getTools = ({
1112
projectRef,
@@ -342,5 +343,49 @@ export const getTools = ({
342343
`
343344
},
344345
}),
346+
getFunctions: tool({
347+
description: 'Get database functions for one or more schemas',
348+
parameters: z.object({
349+
schemas: z.array(z.string()).describe('The schema names to get the functions for'),
350+
}),
351+
execute: async ({ schemas }) => {
352+
try {
353+
const data = includeSchemaMetadata
354+
? await getDatabaseFunctions(
355+
{
356+
projectRef,
357+
connectionString,
358+
},
359+
undefined,
360+
{
361+
'Content-Type': 'application/json',
362+
...(authorization && { Authorization: authorization }),
363+
}
364+
)
365+
: []
366+
367+
// Filter functions by requested schemas
368+
const filteredFunctions = data.filter((func) => schemas.includes(func.schema))
369+
370+
const formattedFunctions = filteredFunctions
371+
.map(
372+
(func) => `
373+
Function Name: "${func.name}"
374+
Schema: ${func.schema}
375+
Arguments: ${func.argument_types}
376+
Return Type: ${func.return_type}
377+
Language: ${func.language}
378+
Definition: ${func.definition}
379+
`
380+
)
381+
.join('\n')
382+
383+
return formattedFunctions
384+
} catch (error) {
385+
console.error('Failed to fetch functions:', error)
386+
return `Failed to fetch functions: ${error}`
387+
}
388+
},
389+
}),
345390
}
346391
}

apps/studio/state/app-state.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,12 @@ export const appState = proxy({
222222
// Set up localStorage subscription
223223
if (typeof window !== 'undefined') {
224224
subscribe(appState, () => {
225-
localStorage.setItem(
226-
LOCAL_STORAGE_KEYS.AI_ASSISTANT_STATE,
227-
JSON.stringify(appState.aiAssistantPanel)
228-
)
225+
const state = {
226+
...appState.aiAssistantPanel,
227+
// limit to 20 messages so as to not overflow the context window
228+
messages: appState.aiAssistantPanel.messages?.slice(-20),
229+
}
230+
localStorage.setItem(LOCAL_STORAGE_KEYS.AI_ASSISTANT_STATE, JSON.stringify(state))
229231
})
230232
}
231233

0 commit comments

Comments
 (0)