fix: make OPENAI_API_KEY optional for playground to allow client-provided keys

- Make OPENAI_API_KEY optional in env validation
- Move OpenAI client initialization from module level to runtime
- Accept API key from client UI (Settings sidebar) or server env
- Return clear error message if no API key is provided
- Fixes Vercel build failure due to missing env var at build time

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ajax Davis 2025-12-04 13:22:23 +10:00
parent 8b5757c9aa
commit cc14476a36
2 changed files with 21 additions and 7 deletions

View file

@ -10,11 +10,6 @@ export const runtime = 'nodejs';
export const dynamic = 'force-dynamic';
export const maxDuration = 60;
// Initialize OpenAI provider
const openai = createOpenAI({
apiKey: env.OPENAI_API_KEY,
});
// Add conversation state tracking (in-memory for MVP)
// biome-ignore lint/suspicious/noExplicitAny: Tool types from AI SDK are complex
const conversationStates = new Map<string, { loadedTools: Record<string, any> }>();
@ -35,6 +30,25 @@ export async function POST(request: NextRequest) {
console.log(`🔑 Conversation ID: ${conversationId}`);
console.log(`🔐 Client env vars: ${Object.keys(clientEnv).length} keys`);
// Initialize OpenAI with client-provided or server API key
const apiKey = clientEnv.OPENAI_API_KEY || env.OPENAI_API_KEY;
if (!apiKey) {
return new Response(
JSON.stringify({
success: false,
error: 'OPENAI_API_KEY is required. Please add it in the Settings sidebar.',
}),
{
status: 400,
headers: { 'Content-Type': 'application/json' },
}
);
}
const openai = createOpenAI({
apiKey,
});
// Get or create conversation state
if (!conversationStates.has(conversationId)) {
console.log('✨ Creating new conversation state');

View file

@ -2,6 +2,6 @@ import { createEnv } from '@tpmjs/env';
import { z } from 'zod';
export const env = createEnv({
// Server-only
OPENAI_API_KEY: z.string().min(1),
// Server-only (optional for playground - can be provided by client UI)
OPENAI_API_KEY: z.string().min(1).optional(),
});