import { TLUiDialogProps, TldrawUiButton, TldrawUiButtonLabel, TldrawUiDialogBody, TldrawUiDialogCloseButton, TldrawUiDialogFooter, TldrawUiDialogHeader, TldrawUiDialogTitle, TldrawUiInput, } from "tldraw" import React from "react" import { PROVIDERS, AI_PERSONALITIES, OLLAMA_MODELS } from "../lib/settings" import { useAuth } from "../context/AuthContext" import { getOllamaConfig } from "../lib/clientConfig" export function SettingsDialog({ onClose }: TLUiDialogProps) { const { session } = useAuth() const [apiKeys, setApiKeys] = React.useState(() => { try { // First try to get user-specific API keys if logged in if (session.authed && session.username) { const userApiKeys = localStorage.getItem(`${session.username}_api_keys`) if (userApiKeys) { try { const parsed = JSON.parse(userApiKeys) if (parsed.keys) { return parsed.keys } } catch (e) { // Continue to fallback } } } // Fallback to global API keys const stored = localStorage.getItem("openai_api_key") if (stored) { try { const parsed = JSON.parse(stored) if (parsed.keys) { return parsed.keys } } catch (e) { // Fallback to old format return { openai: stored } } } return { openai: '', anthropic: '', google: '' } } catch (e) { return { openai: '', anthropic: '', google: '' } } }) const [personality, setPersonality] = React.useState(() => { try { // First try to get user-specific settings if logged in if (session.authed && session.username) { const userApiKeys = localStorage.getItem(`${session.username}_api_keys`) if (userApiKeys) { try { const parsed = JSON.parse(userApiKeys) if (parsed.personality) { return parsed.personality } } catch (e) { // Continue to fallback } } } // Fallback to global settings const stored = localStorage.getItem("openai_api_key") if (stored) { try { const parsed = JSON.parse(stored) if (parsed.personality) { return parsed.personality } } catch (e) { // Continue to fallback } } return 'web-developer' } catch (e) { return 'web-developer' } }) const [ollamaModel, setOllamaModel] = React.useState(() => { try { // First try to get user-specific settings if logged in if (session.authed && session.username) { const userApiKeys = localStorage.getItem(`${session.username}_api_keys`) if (userApiKeys) { try { const parsed = JSON.parse(userApiKeys) if (parsed.ollamaModel) { return parsed.ollamaModel } } catch (e) { // Continue to fallback } } } // Fallback to global settings const stored = localStorage.getItem("openai_api_key") if (stored) { try { const parsed = JSON.parse(stored) if (parsed.ollamaModel) { return parsed.ollamaModel } } catch (e) { // Continue to fallback } } return 'llama3.1:8b' } catch (e) { return 'llama3.1:8b' } }) // Check if Ollama is configured const ollamaConfig = getOllamaConfig() const handleKeyChange = (provider: string, value: string) => { const newKeys = { ...apiKeys, [provider]: value } setApiKeys(newKeys) saveSettings(newKeys, personality, ollamaModel) } const handlePersonalityChange = (newPersonality: string) => { setPersonality(newPersonality) saveSettings(apiKeys, newPersonality, ollamaModel) } const handleOllamaModelChange = (newModel: string) => { setOllamaModel(newModel) saveSettings(apiKeys, personality, newModel) } const saveSettings = (keys: any, personalityValue: string, ollamaModelValue: string) => { // Save to localStorage with the new structure const settings = { keys: keys, provider: 'openai', // Default provider models: Object.fromEntries(PROVIDERS.map((provider) => [provider.id, provider.models[0]])), ollamaModel: ollamaModelValue, personality: personalityValue, } // If user is logged in, save to user-specific storage if (session.authed && session.username) { localStorage.setItem(`${session.username}_api_keys`, JSON.stringify(settings)) // Also save to global storage as fallback localStorage.setItem("openai_api_key", JSON.stringify(settings)) } else { localStorage.setItem("openai_api_key", JSON.stringify(settings)) } } const validateKey = (provider: string, key: string) => { const providerConfig = PROVIDERS.find(p => p.id === provider) if (providerConfig && key.trim()) { return providerConfig.validate(key) } return true } return ( <> AI Settings
{/* AI Personality Selector */}
{/* Ollama Model Selector - Only show if Ollama is configured */} {ollamaConfig && (
🦙

Private AI Model

FREE

Running on your private server. No API key needed - select quality vs speed.

Server: {ollamaConfig.url} Model size: {OLLAMA_MODELS.find(m => m.id === ollamaModel)?.size || 'Unknown'}
)} {/* API Keys Section */}

Cloud API Keys

{ollamaConfig ? "Optional fallback - used when private AI is unavailable." : "Enter API keys to use cloud AI services."}

{PROVIDERS.map((provider) => (
{provider.models[0]}
handleKeyChange(provider.id, value)} /> {apiKeys[provider.id] && !validateKey(provider.id, apiKeys[provider.id]) && (
Invalid API key format
)}
))}
{/* Close API Keys Section */}
Note: API keys are stored locally in your browser. Make sure to use keys with appropriate usage limits for your needs.
Close ) }