Add multi-provider LLM support with model selection

- Support OpenRouter, OpenAI, and Anthropic providers
- Fetch available models after entering API key
- OpenRouter sorted by price (cheapest first)
- Store provider, model, and key per user
- Update reflections API to use selected provider/model

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Gemini Agent
2026-01-24 12:23:31 +00:00
parent 9711baf54e
commit 83ee6eefec
8 changed files with 952 additions and 124 deletions

View File

@@ -15,7 +15,9 @@ export async function GET() {
.select({
reminderEnabled: schema.users.reminderEnabled,
reminderTime: schema.users.reminderTime,
hasLlmKey: schema.users.llmApiKey,
llmProvider: schema.users.llmProvider,
llmApiKey: schema.users.llmApiKey,
llmModel: schema.users.llmModel,
})
.from(schema.users)
.where(eq(schema.users.id, user.id))
@@ -28,7 +30,9 @@ export async function GET() {
return NextResponse.json({
reminderEnabled: users[0].reminderEnabled === 1,
reminderTime: users[0].reminderTime || "20:00",
hasLlmKey: Boolean(users[0].hasLlmKey),
llmProvider: users[0].llmProvider || null,
hasLlmKey: Boolean(users[0].llmApiKey),
llmModel: users[0].llmModel || null,
});
} catch (error) {
console.error("Failed to fetch settings:", error);
@@ -55,11 +59,18 @@ export async function PATCH(request: NextRequest) {
updates.reminderTime = body.reminderTime;
}
if (typeof body.llmProvider === "string") {
updates.llmProvider = body.llmProvider || null;
}
if (typeof body.llmApiKey === "string") {
// Store the API key (in production, encrypt this)
updates.llmApiKey = body.llmApiKey || null;
}
if (typeof body.llmModel === "string") {
updates.llmModel = body.llmModel || null;
}
if (Object.keys(updates).length === 0) {
return NextResponse.json({ error: "No updates provided" }, { status: 400 });
}