Part of the free/non-profit pivot (follows PRs #400–#404). BragDoc is now free; AI features should run on each user's own LLM API key instead of the platform's OPENAI_API_KEY.
Summary
- New shared
packages/ai (@bragdoc/ai) provider factory, lifted from the CLI's createLLMFromConfig (OpenAI, Anthropic, Google, DeepSeek, Ollama, OpenAI-compatible), with the Google env-var mutation hack replaced by an explicit-key constructor
- New
user_llm_config table storing AES-256-GCM-encrypted keys (WebCrypto, HKDF-derived from a new BYOK_ENCRYPTION_KEY secret — Cloudflare Workers-safe), one row per provider, key hint (last 4) for display, never returned to the client
- Settings UI on the Account page: provider + key + model, verified with a live probe on save
- Central
resolveModelForUser(user, task) replaces the frozen model singletons in apps/web/lib/ai/index.ts; singletons are deleted so the compiler surfaces every call site. Typed no_api_key error → UI CTAs linking to settings
- Demo users fall through to the platform key; embeddings stay on the platform key in v1 (OpenAI-only API, fixed 1536-d vectors, trivial cost) so Workstreams keeps working regardless of the user's chat provider
- Marketing site: add "add your API key in Settings" to how-it-works/get-started flows, FAQ, CLI docs page
Full SPEC.md and PLAN.md in tasks/ directory.
Part of the free/non-profit pivot (follows PRs #400–#404). BragDoc is now free; AI features should run on each user's own LLM API key instead of the platform's
OPENAI_API_KEY.Summary
packages/ai(@bragdoc/ai) provider factory, lifted from the CLI'screateLLMFromConfig(OpenAI, Anthropic, Google, DeepSeek, Ollama, OpenAI-compatible), with the Google env-var mutation hack replaced by an explicit-key constructoruser_llm_configtable storing AES-256-GCM-encrypted keys (WebCrypto, HKDF-derived from a newBYOK_ENCRYPTION_KEYsecret — Cloudflare Workers-safe), one row per provider, key hint (last 4) for display, never returned to the clientresolveModelForUser(user, task)replaces the frozen model singletons inapps/web/lib/ai/index.ts; singletons are deleted so the compiler surfaces every call site. Typedno_api_keyerror → UI CTAs linking to settingsFull SPEC.md and PLAN.md in tasks/ directory.