### One-time Setup for Chef Project Development Source: https://github.com/get-convex/chef/blob/main/DEVELOPMENT.md This section details the initial setup required to start developing the Chef project. It involves cloning the repository, setting up the Node.js environment using nvm, installing pnpm, and configuring Convex development tools and environment variables. ```shell git clone git@github.com:get-convex/chef.git cd chef nvm install nvm use npm install -g pnpm pnpm i npx vercel link --scope convex-dev --project chef -y npx vercel env pull echo 'VITE_CONVEX_URL=placeholder' >> .env.local npx convex dev --configure existing --team convex --project chef --once ``` -------------------------------- ### Local Big-Brain Development Setup for Chef Source: https://github.com/get-convex/chef/blob/main/DEVELOPMENT.md Steps to set up the local development environment when working against a local 'big-brain' instance. This involves running multiple services, configuring environment variables, and starting the Chef development server. ```shell # just run-big-brain-for-chef-dev # just run-dash # Switch chef .env.local env vars to the dev variants (from 1Password) # Set VITE_CONVEX_URL to 'placeholder' and remove CONVEX_URL # just convex-bb dev # Set VITE_CONVEX_SITE_URL to match the newly updated VITE_CONVEX_URL (but .convex.site instead) # npm run dev ``` -------------------------------- ### Set Up Local Environment for Chef Source: https://github.com/get-convex/chef/blob/main/README.md This set of commands installs and uses a specific Node.js version via nvm, installs pnpm globally, installs project dependencies, and creates a local environment file with a placeholder for the Convex URL. It concludes with starting the Convex development server. ```bash nvm install nvm use npm install -g pnpm pnpm i echo 'VITE_CONVEX_URL=placeholder' >> .env.local npx convex dev --once ``` -------------------------------- ### Local Development Workflow for Chef Project Source: https://github.com/get-convex/chef/blob/main/DEVELOPMENT.md Instructions for running the Chef project locally. This involves installing dependencies, starting the development server with pnpm, and running the Convex development environment in a separate terminal. It also highlights specific URL and port requirements for the development server. ```shell pnpm i pnpm run dev # and in another terminal, npx convex dev # now visit http://127.0.0.1:5173 ``` -------------------------------- ### Generate Messages with Chefshot Source: https://github.com/get-convex/chef/blob/main/chefshot/README.md This example demonstrates how to use Chefshot to generate messages for a given prompt, saving them to a file. It requires the Convex development server to be running and the project to be built and started. ```bash npx convex dev --once; pnpm run build; pnpm run start; # and then in another terminal npx chefshot generate "Let's make a chat app" --messages-file foo.json --prod | jq ``` -------------------------------- ### Deploying from Staging to Release Branch Source: https://github.com/get-convex/chef/blob/main/DEVELOPMENT.md Commands to push changes from the `staging` branch to the `release` branch, initiating a deployment to the production environment. This step is followed by manual testing and confirmation. ```shell git checkout staging git pull git push origin staging:release ``` -------------------------------- ### Deploying from Main to Staging Branch Source: https://github.com/get-convex/chef/blob/main/DEVELOPMENT.md Commands to push changes from the `main` branch to the `staging` branch, initiating a deployment to the staging environment. This is a manual step in the release process. ```shell git checkout main git pull git push origin main:staging ``` -------------------------------- ### Running Tests in Chef Project Source: https://github.com/get-convex/chef/blob/main/DEVELOPMENT.md Command to execute the test suite for the Chef project. This helps ensure that new changes have not introduced regressions. ```shell pnpm run test ``` -------------------------------- ### Rebuilding Chef Project Template Source: https://github.com/get-convex/chef/blob/main/DEVELOPMENT.md Command used when working on the template for the Chef project. Running this command provides directions on how to rebuild the template. ```shell npm run rebuild-template ``` -------------------------------- ### Formatting and Linting Fixes for Chef Project Source: https://github.com/get-convex/chef/blob/main/DEVELOPMENT.md Command to automatically fix linting and formatting issues in the Chef project, ensuring code consistency before committing changes. ```shell pnpm run lint:fix ``` -------------------------------- ### Typechecking Chef Project Code Source: https://github.com/get-convex/chef/blob/main/DEVELOPMENT.md Command to perform typechecking on the Chef project's codebase, helping to catch potential type-related errors. ```shell pnpm run typecheck ``` -------------------------------- ### Verify Token Usage with TypeScript Source: https://context7.com/get-convex/chef/llms.txt Checks the user's token quota before allowing API responses. It makes a GET request to the Convex provisioning API and returns the usage status, quota, and plan details. Dependencies include `fetch` API. ```typescript // app/lib/.server/usage.ts export async function checkTokenUsage( provisionHost: string, token: string, teamSlug: string, deploymentName: string | undefined ) { const url = new URL(`${provisionHost}/api/chef_usage`); url.searchParams.set('teamSlug', teamSlug); if (deploymentName) { url.searchParams.set('deploymentName', deploymentName); } const response = await fetch(url.toString(), { headers: { Authorization: `Bearer ${token}`, }, }); if (!response.ok) { return { status: 'error' as const, httpStatus: response.status }; } const data = await response.json(); return { status: 'success' as const, centitokensUsed: data.centitokensUsed, centitokensQuota: data.centitokensQuota, isTeamDisabled: data.isTeamDisabled, isPaidPlan: data.isPaidPlan, }; } // Usage in chat endpoint const usageCheck = await checkTokenUsage( 'https://api.convex.dev', 'convex_token_abc123', 'my-team', 'happy-animal-123' ); if (usageCheck.status === 'success' && usageCheck.centitokensUsed >= usageCheck.centitokensQuota) { console.log('Quota exhausted, use user API key'); } ``` -------------------------------- ### Call a Convex Mutation Function from React Source: https://github.com/get-convex/chef/blob/main/convex/README.md This example demonstrates how to call a Convex mutation function from a React component using the `useMutation` hook. It shows both fire-and-forget usage and how to handle the promise returned by the mutation to access its result. ```typescript const mutation = useMutation(api.functions.myMutationFunction); function handleButtonPress() { // fire and forget, the most common way to use mutations mutation({ first: "Hello!", second: "me" }); // OR // use the result once the mutation has completed mutation({ first: "Hello!", second: "me" }).then((result) => console.log(result)); } ``` -------------------------------- ### Call a Convex Query Function from React Source: https://github.com/get-convex/chef/blob/main/convex/README.md This example shows how to invoke a Convex query function from a React component using the `useQuery` hook. It passes the necessary arguments to the query. The `api` object is assumed to be generated by the Convex build process. ```typescript const data = useQuery(api.functions.myQueryFunction, { first: 10, second: "hello", }); ``` -------------------------------- ### Load Compressed Chat History via Convex HTTP Route Source: https://context7.com/get-convex/chef/llms.txt Retrieves compressed chat history from a Convex backend using a GET request to a custom HTTP route. It handles decompression (LZ4) and JSON parsing to return message history. Dependencies include Convex `http` actions and `decompressWithLz4`. ```typescript // convex/http.ts http.route({ path: "/initial_messages", method: "GET", handler: httpAction(async (ctx, request) => { const url = new URL(request.url); const sessionId = url.searchParams.get("sessionId"); const chatId = url.searchParams.get("chatId"); const storageState = await ctx.runQuery( internal.messages.getLatestChatMessageStorageState, { sessionId, chatId } ); if (!storageState?.storageId) { return new Response(JSON.stringify({ messages: [] }), { status: 200, headers: { "Content-Type": "application/json" }, }); } const blob = await ctx.storage.get(storageState.storageId); const compressed = await blob.arrayBuffer(); const decompressed = await decompressWithLz4(compressed); const messages = JSON.parse(new TextDecoder().decode(decompressed)); return new Response(JSON.stringify({ messages }), { status: 200, headers: { "Content-Type": "application/json" }, }); }), }); // Client usage const loadMessages = async () => { const response = await fetch( `https://deployment.convex.cloud/initial_messages?sessionId=k97e2h4&chatId=abc123` ); const { messages } = await response.json(); console.log('Loaded', messages.length, 'messages'); }; ``` -------------------------------- ### Clone and Navigate to Chef Project Directory Source: https://github.com/get-convex/chef/blob/main/README.md These bash commands clone the Chef GitHub repository and change the current directory to the newly cloned project. This is the initial step for setting up Chef locally. ```bash git clone https://github.com/get-convex/chef.git cd chef ``` -------------------------------- ### Run Chef Backend and Frontend Development Servers Source: https://github.com/get-convex/chef/blob/main/README.md These commands initiate the development servers for both the Chef backend (using Convex) and the frontend. Running these commands in separate terminals is necessary to have Chef fully operational locally. ```bash pnpm run dev ## in another terminal npx convex dev ``` -------------------------------- ### Add API Keys for Model Providers Source: https://github.com/get-convex/chef/blob/main/README.md This section details how to add API keys for various AI model providers (Anthropic, Google, OpenAI, XAI) to the `.env.local` file. These keys enable the code generation capabilities within Chef. Users can also add their own keys via the Chef settings page. ```env ANTHROPIC_API_KEY= GOOGLE_API_KEY= OPENAI_API_KEY= XAI_API_KEY= ``` -------------------------------- ### Upload Project Snapshot Source: https://context7.com/get-convex/chef/llms.txt An HTTP endpoint for storing filesystem snapshots of a project, associating them with a specific chat and session. ```APIDOC ## POST /upload_snapshot ### Description HTTP endpoint for storing filesystem snapshots. ### Method POST ### Endpoint /upload_snapshot ### Parameters #### Path Parameters None #### Query Parameters - **sessionId** (string) - Required - The ID of the session. - **chatId** (string) - Required - The ID of the chat. #### Request Body - **blob** (Blob) - Required - The filesystem snapshot data. ### Request Example ```javascript const response = await fetch( `https://your-deployment.convex.cloud/upload_snapshot?sessionId=k97e2h4&chatId=abc123`, { method: 'POST', body: filesData, // Assuming filesData is a Blob headers: { 'Content-Type': 'application/octet-stream' } } ); const { snapshotId } = await response.json(); console.log('Snapshot stored:', snapshotId); ``` ### Response #### Success Response (200) - **snapshotId** (string) - The ID of the stored snapshot. #### Response Example ```json { "snapshotId": "storage_xyz789" } ``` ``` -------------------------------- ### Create Share Link Source: https://context7.com/get-convex/chef/llms.txt Generates a shareable fork point for a chat or project by creating a unique code associated with a project snapshot. ```APIDOC ## POST /api/shares ### Description Generates a shareable fork point for a chat/project. ### Method POST ### Endpoint /api/shares ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **sessionId** (string) - Required - The ID of the session. - **id** (string) - Required - The ID of the chat or project. ### Request Example ```json { "sessionId": "k97e2h4j5k6l7m8n9p0q1r2s", "id": "my-chat-id" } ``` ### Response #### Success Response (200) - **code** (string) - The unique code generated for the shareable link. #### Response Example ```json { "code": "a1b2c3d4e5f6" } ``` ### Usage Example ```javascript const result = await convex.mutation(api.share.create, { sessionId: "k97e2h4j5k6l7m8n9p0q1r2s", id: "my-chat-id" }); const shareUrl = `https://chef.convex.dev/create/${result.code}`; console.log('Share at:', shareUrl); ``` ``` -------------------------------- ### Initialize Chat Session with Convex Project Source: https://context7.com/get-convex/chef/llms.txt This function initializes a new chat session and optionally provisions a Convex project for the user. It checks for existing sessions and creates a new one if none is found. Requires session ID, chat ID, and optional project initialization parameters including team slug and WorkOS access token. ```typescript // convex/messages.ts import { mutation } from "./_generated/server"; import { v } from "convex/values"; export const initializeChat = mutation({ args: { sessionId: v.id("sessions"), id: v.string(), projectInitParams: v.optional( v.object({ teamSlug: v.string(), workosAccessToken: v.string(), }), ), }, handler: async (ctx, args) => { const { id, sessionId, projectInitParams } = args; let existing = await getChatByIdOrUrlIdEnsuringAccess(ctx, { id: args.id, sessionId: args.sessionId }); if (existing) { return; } await createNewChat(ctx, { id, sessionId, projectInitParams, }); }, }); // Usage from client const initChat = async () => { await convex.mutation(api.messages.initializeChat, { sessionId: "k97e2h4j5k6l7m8n9p0q1r2s", id: "550e8400-e29b-41d4-a716-446655440000", projectInitParams: { teamSlug: "my-team", workosAccessToken: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } }); }; ``` -------------------------------- ### Deploy to Convex Tool for Application Deployment Source: https://context7.com/get-convex/chef/llms.txt An AI tool used for deploying applications to Convex and initiating the development server. This tool should be executed after files have been written and the app is complete, or after any subsequent changes. ```typescript // chef-agent/tools/deploy.ts import type { Tool } from 'ai'; import { z } from 'zod'; export const deployTool: Tool = { description: `Deploy the app to Convex and start the Vite development server. Execute this tool after writing files to the filesystem and the app is complete. After initially writing the app, you MUST execute this tool after making any changes.`, parameters: z.object({}), }; // AI invokes this during generation // Example tool call: { "toolName": "deploy", "args": {} } // The tool triggers: // 1. npx convex deploy // 2. npm run build (if needed) // 3. Starts dev server ``` -------------------------------- ### Initialize Chat Session Source: https://context7.com/get-convex/chef/llms.txt Creates a new chat session and optionally provisions a Convex project for the user. This mutation is defined in `convex/messages.ts`. ```APIDOC ## POST /convex/messages/initializeChat ### Description Initializes a new chat session and can provision a new Convex project. ### Method POST ### Endpoint /convex/messages/initializeChat ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **sessionId** (ID) - Required - The ID of the session. - **id** (String) - Required - A unique identifier for the chat. - **projectInitParams** (Object) - Optional - Parameters for initializing the project. - **teamSlug** (String) - Required (if projectInitParams is present) - The team slug for the project. - **workosAccessToken** (String) - Required (if projectInitParams is present) - The WorkOS access token. ### Request Example ```json { "sessionId": "k97e2h4j5k6l7m8n9p0q1r2s", "id": "550e8400-e29b-41d4-a716-446655440000", "projectInitParams": { "teamSlug": "my-team", "workosAccessToken": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } } ``` ### Response #### Success Response (200) Returns void upon successful initialization. #### Response Example (No response body for successful mutation) ``` -------------------------------- ### Debug Chefshot Generation Source: https://github.com/get-convex/chef/blob/main/chefshot/README.md This snippet shows how to debug Chefshot's message generation process. It involves running the Convex development server and then executing Chefshot with specific flags for debugging, such as `--dev` and `--no-headless`. ```bash npx convex dev --once; pnpm run dev # and then in another terminal npx chefshot generate "Let's make a chat app" --dev --no-headless ``` -------------------------------- ### Register Convex OAuth Connection Source: https://context7.com/get-convex/chef/llms.txt Links a chat to a provisioned Convex deployment by storing connection details and credentials. ```APIDOC ## INTERNAL MUTATION: registerConvexOAuthConnection ### Description Links a chat to a provisioned Convex deployment. ### Method INTERNAL MUTATION ### Endpoint (Internal - Not directly callable via HTTP) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **sessionId** (ID) - Required - The ID of the session. - **chatId** (ID) - Required - The ID of the chat. - **projectSlug** (string) - Required - The slug of the Convex project. - **teamSlug** (string) - Required - The slug of the Convex team. - **deploymentUrl** (string) - Required - The URL of the Convex deployment. - **deploymentName** (string) - Required - The name of the Convex deployment. - **projectDeployKey** (string) - Required - The deployment key for the Convex project. ### Request Example (Internal Trigger) ```javascript await ctx.scheduler.runAfter(0, internal.sessions.registerConvexOAuthConnection, { sessionId: session._id, chatId: chat._id, projectSlug: "my-project", teamSlug: "my-team", deploymentUrl: "https://happy-animal-123.convex.cloud", deploymentName: "happy-animal-123", projectDeployKey: "prod:happy-animal-123|1a2b3c4d5e6f" }); ``` ### Response #### Success Response (No explicit return value specified, operation modifies database state) #### Response Example (N/A) ``` -------------------------------- ### Execute Node.js Code in WebContainers Source: https://github.com/get-convex/chef/blob/main/proxy/README.md Demonstrates how to execute short Node.js scripts within WebContainers, bypassing limitations with stdin and file writing. This approach is useful for running proxy logic or other short-lived scripts. ```shell node -e 'the(proxy); code()' ``` ```shell echo 'the(proxy); code() > /tmp/proxy.cjs' ``` -------------------------------- ### Convex Agent with Multi-Provider LLM Orchestration Source: https://context7.com/get-convex/chef/llms.txt Orchestrates AI model calls using various LLM providers with support for tools, system prompts, and usage tracking. It takes chat history and configuration to generate responses and can stream results. ```typescript // app/lib/.server/llm/convex-agent.ts import { streamText } from 'ai'; import { getProvider } from '~/lib/.server/llm/provider'; import { deployTool } from 'chef-agent/tools/deploy'; import { editTool } from 'chef-agent/tools/edit'; import { viewTool } from 'chef-agent/tools/view'; export async function convexAgent(args: { chatInitialId: string; firstUserMessage: boolean; messages: Message[]; modelProvider: 'Anthropic' | 'OpenAI' | 'Google' | 'XAI' | 'Bedrock'; modelChoice: string | undefined; userApiKey: string | undefined; shouldDisableTools: boolean; recordUsageCb: (lastMessage: Message, usage: LanguageModelUsage) => Promise; featureFlags: { enableResend: boolean }; }) { const provider = getProvider( args.userApiKey, args.modelProvider, args.modelChoice ); const tools = { deploy: deployTool, edit: editTool, view: viewTool, npmInstall: npmInstallTool, lookupDocs: lookupDocsTool(), getConvexDeploymentName: getConvexDeploymentNameTool, }; const result = await streamText({ model: provider, messages: args.messages, tools: args.shouldDisableTools ? undefined : tools, maxSteps: 30, onFinish: async ({ usage, response }) => { await args.recordUsageCb(response.messages[0], usage); } }); return result.toDataStreamResponse(); } // Usage example const response = await convexAgent({ chatInitialId: '550e8400-e29b-41d4-a716-446655440000', firstUserMessage: true, messages: [{ role: 'user', content: 'Add dark mode' }], modelProvider: 'Anthropic', modelChoice: 'claude-sonnet-4-0', userApiKey: 'sk-ant-api03-வுகளை', shouldDisableTools: false, recordUsageCb: async (msg, usage) => { console.log('Tokens used:', usage.totalTokens); }, featureFlags: { enableResend: true } }); ``` -------------------------------- ### Upload Project Snapshot HTTP Endpoint (TypeScript) Source: https://context7.com/get-convex/chef/llms.txt An HTTP POST endpoint for storing filesystem snapshots. It accepts `sessionId` and `chatId` as URL search parameters and the snapshot data as a Blob in the request body. The snapshot is stored using Convex's storage, and its ID is saved along with session and chat information. It returns the storage ID of the uploaded snapshot. ```typescript // convex/http.ts import { httpRouter } from "convex/server"; import { httpAction } from "./_generated/server"; const http = httpRouter(); http.route({ path: "/upload_snapshot", method: "POST", handler: httpAction(async (ctx, request) => { const url = new URL(request.url); const sessionId = url.searchParams.get("sessionId"); const chatId = url.searchParams.get("chatId"); if (!sessionId || !chatId) { throw new ConvexError("sessionId and chatId required"); } const blob = await request.blob(); const storageId = await ctx.storage.store(blob); await ctx.runMutation(internal.snapshot.saveSnapshot, { sessionId: sessionId as Id<"sessions"> chatId: chatId as Id<"chats"> storageId, }); return new Response(JSON.stringify({ snapshotId: storageId }), { status: 200, headers: { "Content-Type": "application/json" }, }); }), }); // Client usage const uploadSnapshot = async (filesData: Blob) => { const response = await fetch( `https://your-deployment.convex.cloud/upload_snapshot?sessionId=k97e2h4&chatId=abc123`, { method: 'POST', body: filesData, headers: { 'Content-Type': 'application/octet-stream' } } ); const { snapshotId } = await response.json(); console.log('Snapshot stored:', snapshotId); }; ``` -------------------------------- ### Record API Token Usage with TypeScript Source: https://context7.com/get-convex/chef/llms.txt Logs token consumption to the Convex provisioning system. It sends a POST request with usage details (prompt, completion, total tokens) and model information. Dependencies include `fetch` API and `JSON.stringify`. ```typescript // app/lib/.server/usage.ts export async function recordUsage( provisionHost: string, token: string, teamSlug: string, deploymentName: string | undefined, usage: { promptTokens: number; completionTokens: number; totalTokens: number; }, modelProvider: string, modelId: string ) { const url = new URL(`${provisionHost}/api/record_chef_usage`); await fetch(url.toString(), { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ teamSlug, deploymentName, promptTokens: usage.promptTokens, completionTokens: usage.completionTokens, modelProvider, modelId, }), }); } // Usage after LLM completion await recordUsage( 'https://api.convex.dev', 'convex_token_abc123', 'my-team', 'happy-animal-123', { promptTokens: 1250, completionTokens: 850, totalTokens: 2100 }, 'Anthropic', 'claude-sonnet-4-0' ); ``` -------------------------------- ### Save Production Messages with Chefshot Source: https://github.com/get-convex/chef/blob/main/chefshot/README.md This command saves messages obtained from a prompt directly into a specified JSON file in a production environment. It's a simpler version of message generation focused on capturing output. ```bash npx chefshot "Let's make a chat app!" --messages-file foo.json --prod ``` -------------------------------- ### Chat API Endpoint Source: https://context7.com/get-convex/chef/llms.txt The main endpoint for streaming AI responses, handling tool execution, and tracking token usage. This is a Remix action accessible at `/api/chat`. ```APIDOC ## POST /api/chat ### Description Handles chat messages, streams AI responses, executes tools, and tracks token usage. ### Method POST ### Endpoint /api/chat ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **messages** (Array) - Required - An array of message objects representing the conversation history. - **role** (String) - Required - The role of the message sender (e.g., 'user', 'assistant'). - **content** (String) - Required - The content of the message. - **firstUserMessage** (Boolean) - Required - Indicates if this is the first message from the user. - **chatInitialId** (String) - Required - The ID of the chat session. - **token** (String) - Required - Authentication token for the user. - **teamSlug** (String) - Required - The team slug associated with the chat. - **deploymentName** (String) - Optional - The name of the deployment. - **modelProvider** (String) - Required - The AI model provider (e.g., 'Anthropic', 'OpenAI'). - **modelChoice** (String) - Required - The specific AI model to use (e.g., 'claude-sonnet-4-0'). - **userApiKey** (Object) - Optional - The user's API key configuration. - **preference** (String) - Required - The preference for API key usage (e.g., 'quotaExhausted'). - **value** (String) - Required - The API key value. - **shouldDisableTools** (Boolean) - Optional - Whether to disable tool execution. - **collapsedMessages** (Boolean) - Optional - Whether messages should be collapsed by default. - **featureFlags** (Object) - Optional - Feature flags for the chat session. - **enableResend** (Boolean) - Optional - Enables the Resend feature. ### Request Example ```json { "messages": [ { "role": "user", "content": "Build a todo app with Convex" } ], "firstUserMessage": true, "chatInitialId": "550e8400-e29b-41d4-a716-446655440000", "token": "convex_token_abc123", "teamSlug": "my-team", "deploymentName": "my-deployment", "modelProvider": "Anthropic", "modelChoice": "claude-sonnet-4-0", "userApiKey": { "preference": "quotaExhausted", "value": "sk-ant-api03-..." }, "shouldDisableTools": false, "collapsedMessages": false, "featureFlags": { "enableResend": true } } ``` ### Response #### Success Response (200) Streams text chunks representing the AI's response. The response is streamed as a sequence of text chunks. #### Response Example ``` AI response: This is the first part of the response. AI response: This is the second part of the response. ``` ``` -------------------------------- ### Generate Share Link for Chat/Project (TypeScript) Source: https://context7.com/get-convex/chef/llms.txt Creates a unique shareable link for a given chat or project session. It generates a unique code, retrieves the latest snapshot, and stores share information including snapshot and chat history IDs. This function requires access to chat data and storage, and ensures the project has been previously saved. ```typescript // convex/share.ts import { mutation } from "./_generated/server"; import { v } from "convex/values"; export const create = mutation({ args: { sessionId: v.id("sessions"), id: v.string(), }, handler: async (ctx, { sessionId, id }) => { const chat = await getChatByIdOrUrlIdEnsuringAccess(ctx, { id, sessionId }); if (!chat) throw new ConvexError("Chat not found"); const code = await generateUniqueCode(ctx.db); const storageState = await getLatestChatMessageStorageState(ctx, { _id: chat._id, subchatIndex: chat.lastSubchatIndex, }); if (!storageState?.snapshotId) { throw new ConvexError("Your project has never been saved."); } await ctx.db.insert("shares", { chatId: chat._id, snapshotId: storageState.snapshotId, chatHistoryId: storageState.storageId, code, lastMessageRank: storageState.lastMessageRank, lastSubchatIndex: chat.lastSubchatIndex, }); return { code }; }, }); // Usage const shareProject = async () => { const result = await convex.mutation(api.share.create, { sessionId: "k97e2h4j5k6l7m8n9p0q1r2s", id: "my-chat-id" }); const shareUrl = `https://chef.convex.dev/create/${result.code}`; console.log('Share at:', shareUrl); // https://chef.convex.dev/create/a1b2c3 }; ``` -------------------------------- ### Register Convex OAuth Connection (TypeScript) Source: https://context7.com/get-convex/chef/llms.txt Links a chat to a provisioned Convex deployment by registering OAuth connection details. It requires session and chat IDs, along with project/team slugs, deployment URL, and deployment name. This mutation updates the chat record with connection details and inserts credentials into a separate table. It's typically triggered internally after an OAuth callback. ```typescript // convex/sessions.ts import { internalMutation } from "./_generated/server"; import { v } from "convex/values"; export const registerConvexOAuthConnection = internalMutation({ args: { sessionId: v.id("sessions"), chatId: v.id("chats"), projectSlug: v.string(), teamSlug: v.string(), deploymentUrl: v.string(), deploymentName: v.string(), projectDeployKey: v.string(), }, handler: async (ctx, args) => { const chat = await getChatByIdOrUrlIdEnsuringAccess(ctx, { id: args.chatId, sessionId: args.sessionId, }); if (!chat) throw new ConvexError("Chat not found"); await ctx.db.patch(args.chatId, { convexProject: { kind: "connected", projectSlug: args.projectSlug, teamSlug: args.teamSlug, deploymentUrl: args.deploymentUrl, deploymentName: args.deploymentName, }, }); await ctx.db.insert("convexProjectCredentials", { projectSlug: args.projectSlug, teamSlug: args.teamSlug, projectDeployKey: args.projectDeployKey, }); }, }); // Triggered internally after OAuth callback await ctx.scheduler.runAfter(0, internal.sessions.registerConvexOAuthConnection, { sessionId: session._id, chatId: chat._id, projectSlug: "my-project", teamSlug: "my-team", deploymentUrl: "https://happy-animal-123.convex.cloud", deploymentName: "happy-animal-123", projectDeployKey: "prod:happy-animal-123|1a2b3c4d5e6f" }); ``` -------------------------------- ### Chat API Endpoint for Streaming Responses Source: https://context7.com/get-convex/chef/llms.txt This is the main API endpoint for handling chat interactions. It streams AI responses, manages tool execution, and tracks token usage. It accepts a POST request with chat messages, initial chat ID, authentication token, team slug, deployment name, model provider and choice, user API key, and feature flags. The response is streamed as chunks of text. ```typescript // app/routes/api.chat.ts import type { ActionFunctionArgs } from '@vercel/remix'; import { chatAction } from '~/lib/.server/chat'; export async function action(args: ActionFunctionArgs) { return chatAction(args); } // Client-side usage const sendMessage = async () => { const response = await fetch('/api/chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ messages: [ { role: 'user', content: 'Build a todo app with Convex' } ], firstUserMessage: true, chatInitialId: '550e8400-e29b-41d4-a716-446655440000', token: 'convex_token_abc123', teamSlug: 'my-team', deploymentName: 'my-deployment', modelProvider: 'Anthropic', modelChoice: 'claude-sonnet-4-0', userApiKey: { preference: 'quotaExhausted', value: 'sk-ant-api03-...' }, shouldDisableTools: false, collapsedMessages: false, featureFlags: { enableResend: true } }) }); const reader = response.body.getReader(); const decoder = new TextDecoder(); while (true) { const { done, value } = await reader.read(); if (done) break; const chunk = decoder.decode(value); console.log('AI response:', chunk); } }; ``` -------------------------------- ### Chefshot Authentication Environment Variables Source: https://github.com/get-convex/chef/blob/main/chefshot/README.md Chefshot requires specific environment variables for authentication with username/password dashboard logins. These variables (`CHEF_EVAL_USER_PASSWORD`, `CHEF_EVAL_USER_EMAIL`) can be obtained using `npx vercel env pull` from the root repository directory. ```bash CHEF_EVAL_USER_PASSWORD CHEF_EVAL_USER_EMAIL ``` -------------------------------- ### Configure Chef Environment Variables for Convex Deployment Source: https://github.com/get-convex/chef/blob/main/README.md These environment variables are crucial for configuring the Chef application to interact with the Convex deployment. They include the Convex API host, OAuth client ID and secret, and a WorkOS client ID. These should be set in the Convex dashboard's environment variable settings. ```env BIG_BRAIN_HOST=https://api.convex.dev CONVEX_OAUTH_CLIENT_ID= CONVEX_OAUTH_CLIENT_SECRET= WORKOS_CLIENT_ID= ``` -------------------------------- ### Store Compressed Chat Messages with TypeScript Source: https://context7.com/get-convex/chef/llms.txt Persists compressed chat message history to a Convex backend. It uses LZ4 compression and sends the data via POST requests to a Convex HTTP endpoint. Dependencies include a `compressWithLz4` function. ```typescript // Client-side compression and storage import { compressWithLz4 } from '~/lib/compression'; async function storeMessages( messages: Message[], chatId: string, sessionId: string, convexUrl: string ) { const serialized = JSON.stringify(messages); const compressed = await compressWithLz4(new TextEncoder().encode(serialized)); const response = await fetch(`${convexUrl}/store_chat`, { method: 'POST', headers: { 'Content-Type': 'application/octet-stream' }, body: compressed, }); const params = new URLSearchParams({ sessionId, chatId, lastMessageRank: messages.length.toString(), subchatIndex: '0', }); await fetch(`${convexUrl}/store_chat?${params}`, { method: 'POST', body: compressed, }); } // Usage await storeMessages( [ { role: 'user', content: 'Build a todo app' }, { role: 'assistant', content: 'I'll create a todo app...' } ], 'abc123', 'k97e2h4j5k6l7m8n9p0q1r2s', 'https://happy-animal-123.convex.cloud' ); ``` -------------------------------- ### Edit File Tool for Code Generation Source: https://context7.com/get-convex/chef/llms.txt An AI tool designed for making precise edits within files during the code generation process. It allows for replacing a specific fragment of text with new text, requiring knowledge of the file's current content. ```typescript // chef-agent/tools/edit.ts import type { Tool } from 'ai'; import { z } from 'zod'; export const editTool: Tool = { description: `Replace a string of text that appears exactly once in a file with a new string of text. Use this tool when fixing a bug or making a small tweak to a file. You MUST know a file's current contents before using this tool.`, parameters: z.object({ path: z.string().describe('The absolute path to the file to edit.'), old: z.string().describe('The fragment of text to replace. Must be less than 1024 characters.'), new: z.string().describe('The new fragment of text. Must be less than 1024 characters.'), }), }; // AI invokes this tool during code generation // Example tool call from AI: { "toolName": "edit", "args": { "path": "/src/App.tsx", "old": "const [count, setCount] = useState(0);", "new": "const [count, setCount] = useState(0);\n const [darkMode, setDarkMode] = useState(false);" } } ``` -------------------------------- ### Define a Convex Mutation Function with Argument Validation (TypeScript) Source: https://github.com/get-convex/chef/blob/main/convex/README.md This snippet illustrates defining a mutation function in Convex using TypeScript. It includes argument validation for string inputs and demonstrates inserting data into the database using `ctx.db.insert()`. The function can optionally return a value, such as the newly created record. ```typescript import { mutation } from "./_generated/server"; import { v } from "convex/values"; export const myMutationFunction = mutation({ // Validators for arguments. args: { first: v.string(), second: v.string(), }, // Function implementation. handler: async (ctx, args) => { // Insert or modify documents in the database here. // Mutations can also read from the database like queries. // See https://docs.convex.dev/database/writing-data. const message = { body: args.first, author: args.second }; const id = await ctx.db.insert("messages", message); // Optionally, return a value from your mutation. return await ctx.db.get(id); }, }); ``` -------------------------------- ### Define a Convex Query Function with Argument Validation (TypeScript) Source: https://github.com/get-convex/chef/blob/main/convex/README.md This snippet demonstrates how to define a query function in Convex using TypeScript. It includes argument validation with `v.number()` and `v.string()`, and shows how to read data from the database and process arguments within the handler. Dependencies include `convex/query` and `convex/values`. ```typescript import { query } from "./_generated/server"; import { v } from "convex/values"; export const myQueryFunction = query({ // Validators for arguments. args: { first: v.number(), second: v.string(), }, // Function implementation. handler: async (ctx, args) => { // Read the database as many times as you need here. // See https://docs.convex.dev/database/reading-data. const documents = await ctx.db.query("tablename").collect(); // Arguments passed from the client are properties of the args object. console.log(args.first, args.second); // Write arbitrary JavaScript here: filter, aggregate, build derived data, // remove non-public properties, or create new objects. return documents; }, }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.