Unverified 提交 f9c21979 authored 作者: Will Chen's avatar Will Chen 提交者: GitHub

Refactor Supabase prompt to use dynamic code injection (#2222)

Changed the Supabase prompt from using $$SUPABASE_CLIENT_CODE$$ placeholder replacement to dynamically constructing the system prompt with the actual Supabase client code. This is more reliable and removes the need for post-processing the AI response. Changes: - Convert SUPABASE_AVAILABLE_SYSTEM_PROMPT to getSupabaseAvailableSystemPrompt() function - Pass supabaseClientCode parameter when constructing system prompt - Remove response chunk processing that replaced $$SUPABASE_CLIENT_CODE$$ - Update prompt to instruct AI to write to appropriate file path instead of hardcoding <dyad-write> - Update test fixture to contain actual expected Supabase client code <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Refactors Supabase integration to embed real client code directly in the system prompt, eliminating placeholder replacement and making generation deterministic. > > - Replace `SUPABASE_AVAILABLE_SYSTEM_PROMPT` with `getSupabaseAvailableSystemPrompt(supabaseClientCode)` and update instructions to create `src/integrations/supabase/client.ts` and add `@supabase/supabase-js` > - In `chat_stream_handlers.ts` and `token_count_handlers.ts`, fetch `supabaseClientCode` via `getSupabaseClientCode` and append `getSupabaseAvailableSystemPrompt(...)` to `systemPrompt` > - Remove response-time placeholder replacement logic for `$$SUPABASE_CLIENT_CODE$$` in streaming handler > - Update e2e fixture `generate-supabase-client.md` to include the concrete client implementation > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit dfec59bfd59df71af534db92b4d8f1a6f1606047. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Refactors the Supabase prompt to inject the real client code into the system prompt, replacing the $$SUPABASE_CLIENT_CODE$$ placeholder. This removes response post-processing and makes client file creation more reliable. - **Refactors** - Replace SUPABASE_AVAILABLE_SYSTEM_PROMPT constant with getSupabaseAvailableSystemPrompt(supabaseClientCode). - Build the system prompt with supabaseClientCode in chat and token count handlers. - Remove placeholder replacement from chat stream response handling. - Update prompt to embed the actual client code, instruct the correct file path, and add the @supabase/supabase-js dependency. - Update e2e fixture to include the expected Supabase client code. <sup>Written for commit dfec59bfd59df71af534db92b4d8f1a6f1606047. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: 's avatarClaude <noreply@anthropic.com>
上级 b7425105
BEGIN BEGIN
<dyad-write path="src/integrations/supabase/client.ts" description="Creating a supabase client."> <dyad-write path="src/integrations/supabase/client.ts" description="Creating a supabase client.">
$$SUPABASE_CLIENT_CODE$$ // This file is automatically generated. Do not edit it directly.
import { createClient } from '@supabase/supabase-js';
const SUPABASE_URL = "https://fake-project-id.supabase.co";
const SUPABASE_PUBLISHABLE_KEY = "test-publishable-key";
// Import the supabase client like this:
// import { supabase } from "@/integrations/supabase/client";
export const supabase = createClient(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY);
</dyad-write> </dyad-write>
END END
...@@ -22,7 +22,7 @@ import { ...@@ -22,7 +22,7 @@ import {
} from "../../prompts/system_prompt"; } from "../../prompts/system_prompt";
import { getThemePrompt } from "../../shared/themes"; import { getThemePrompt } from "../../shared/themes";
import { import {
SUPABASE_AVAILABLE_SYSTEM_PROMPT, getSupabaseAvailableSystemPrompt,
SUPABASE_NOT_AVAILABLE_SYSTEM_PROMPT, SUPABASE_NOT_AVAILABLE_SYSTEM_PROMPT,
} from "../../prompts/supabase_prompt"; } from "../../prompts/supabase_prompt";
import { getDyadAppPath } from "../../paths/paths"; import { getDyadAppPath } from "../../paths/paths";
...@@ -663,9 +663,14 @@ ${componentSnippet} ...@@ -663,9 +663,14 @@ ${componentSnippet}
updatedChat.app?.supabaseProjectId && updatedChat.app?.supabaseProjectId &&
isSupabaseConnected(settings) isSupabaseConnected(settings)
) { ) {
const supabaseClientCode = await getSupabaseClientCode({
projectId: updatedChat.app.supabaseProjectId,
organizationSlug:
updatedChat.app.supabaseOrganizationSlug ?? null,
});
systemPrompt += systemPrompt +=
"\n\n" + "\n\n" +
SUPABASE_AVAILABLE_SYSTEM_PROMPT + getSupabaseAvailableSystemPrompt(supabaseClientCode) +
"\n\n" + "\n\n" +
// For local agent, we will explicitly fetch the database context when needed. // For local agent, we will explicitly fetch the database context when needed.
(settings.selectedChatMode === "local-agent" (settings.selectedChatMode === "local-agent"
...@@ -962,20 +967,6 @@ This conversation includes one or more image attachments. When the user uploads ...@@ -962,20 +967,6 @@ This conversation includes one or more image attachments. When the user uploads
}: { }: {
fullResponse: string; fullResponse: string;
}) => { }) => {
if (
fullResponse.includes("$$SUPABASE_CLIENT_CODE$$") &&
updatedChat.app?.supabaseProjectId
) {
const supabaseClientCode = await getSupabaseClientCode({
projectId: updatedChat.app?.supabaseProjectId,
organizationSlug:
updatedChat.app?.supabaseOrganizationSlug ?? null,
});
fullResponse = fullResponse.replace(
"$$SUPABASE_CLIENT_CODE$$",
supabaseClientCode,
);
}
// Store the current partial response // Store the current partial response
partialResponses.set(req.chatId, fullResponse); partialResponses.set(req.chatId, fullResponse);
// Save to DB (in case user is switching chats during the stream) // Save to DB (in case user is switching chats during the stream)
......
...@@ -7,13 +7,16 @@ import { ...@@ -7,13 +7,16 @@ import {
} from "../../prompts/system_prompt"; } from "../../prompts/system_prompt";
import { getThemePrompt } from "../../shared/themes"; import { getThemePrompt } from "../../shared/themes";
import { import {
SUPABASE_AVAILABLE_SYSTEM_PROMPT, getSupabaseAvailableSystemPrompt,
SUPABASE_NOT_AVAILABLE_SYSTEM_PROMPT, SUPABASE_NOT_AVAILABLE_SYSTEM_PROMPT,
} from "../../prompts/supabase_prompt"; } from "../../prompts/supabase_prompt";
import { getDyadAppPath } from "../../paths/paths"; import { getDyadAppPath } from "../../paths/paths";
import log from "electron-log"; import log from "electron-log";
import { extractCodebase } from "../../utils/codebase"; import { extractCodebase } from "../../utils/codebase";
import { getSupabaseContext } from "../../supabase_admin/supabase_context"; import {
getSupabaseContext,
getSupabaseClientCode,
} from "../../supabase_admin/supabase_context";
import { TokenCountParams } from "../ipc_types"; import { TokenCountParams } from "../ipc_types";
import { TokenCountResult } from "../ipc_types"; import { TokenCountResult } from "../ipc_types";
...@@ -76,7 +79,12 @@ export function registerTokenCountHandlers() { ...@@ -76,7 +79,12 @@ export function registerTokenCountHandlers() {
let supabaseContext = ""; let supabaseContext = "";
if (chat.app?.supabaseProjectId) { if (chat.app?.supabaseProjectId) {
systemPrompt += "\n\n" + SUPABASE_AVAILABLE_SYSTEM_PROMPT; const supabaseClientCode = await getSupabaseClientCode({
projectId: chat.app.supabaseProjectId,
organizationSlug: chat.app.supabaseOrganizationSlug ?? null,
});
systemPrompt +=
"\n\n" + getSupabaseAvailableSystemPrompt(supabaseClientCode);
supabaseContext = await getSupabaseContext({ supabaseContext = await getSupabaseContext({
supabaseProjectId: chat.app.supabaseProjectId, supabaseProjectId: chat.app.supabaseProjectId,
organizationSlug: chat.app.supabaseOrganizationSlug ?? null, organizationSlug: chat.app.supabaseOrganizationSlug ?? null,
......
...@@ -2,23 +2,24 @@ ...@@ -2,23 +2,24 @@
// which is Apache 2.0 licensed and copyrighted to Jijun Leng // which is Apache 2.0 licensed and copyrighted to Jijun Leng
// https://github.com/jjleng/code-panda/blob/61f1fa514c647de1a8d2ad7f85102d49c6db2086/LICENSE // https://github.com/jjleng/code-panda/blob/61f1fa514c647de1a8d2ad7f85102d49c6db2086/LICENSE
export const SUPABASE_AVAILABLE_SYSTEM_PROMPT = ` export function getSupabaseAvailableSystemPrompt(supabaseClientCode: string) {
return `
# Supabase Instructions # Supabase Instructions
The user has Supabase available for their app so use it for any auth, database or server-side functions. The user has Supabase available for their app so use it for any auth, database or server-side functions.
Make sure supabase client exists at src/integrations/supabase/client.ts. If it doesn't exist, create it. ## Supabase Client Setup
NOTE: I will replace $$SUPABASE_CLIENT_CODE$$ with the actual code. IF you need to write "src/integrations/supabase/client.ts", Check if a Supabase client exists at \`src/integrations/supabase/client.ts\`.
make sure you ALSO add this dependency: @supabase/supabase-js.
Example output: **If it doesn't exist**, do both of the following:
<dyad-write path="src/integrations/supabase/client.ts" description="Creating a supabase client."> 1. **Create the client file** at \`src/integrations/supabase/client.ts\` (or the most appropriate path for the project structure) with this code:
$$SUPABASE_CLIENT_CODE$$ \`\`\`typescript
</dyad-write> ${supabaseClientCode}
\`\`\`
<dyad-add-dependency packages="@supabase/supabase-js"></dyad-add-dependency> 2. **Add the dependency** \`@supabase/supabase-js\` to the project.
## Auth ## Auth
...@@ -404,6 +405,7 @@ serve(async (req) => { ...@@ -404,6 +405,7 @@ serve(async (req) => {
}) })
</dyad-write> </dyad-write>
`; `;
}
export const SUPABASE_NOT_AVAILABLE_SYSTEM_PROMPT = ` export const SUPABASE_NOT_AVAILABLE_SYSTEM_PROMPT = `
If the user wants to use supabase or do something that requires auth, database or server-side functions (e.g. loading API keys, secrets), If the user wants to use supabase or do something that requires auth, database or server-side functions (e.g. loading API keys, secrets),
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论