From 80e5707c766c8ee803a88159f70196915d373b28 Mon Sep 17 00:00:00 2001 From: yan-shcherbakov Date: Mon, 26 May 2025 10:46:07 +0300 Subject: [PATCH 1/5] feat: Add provider and model selector to agent config. --- .../0010_tranquil_squirrel_girl.sql | 2 + drizzle-templates/meta/0010_snapshot.json | 182 ++++ drizzle-templates/meta/_journal.json | 7 + drizzle/meta/0023_snapshot.json | 796 ++++++++++++++++++ src/app/api/chat/route.ts | 2 +- src/app/api/llm/models/route.ts | 27 + src/app/api/llm/providers/route.ts | 25 + src/data/server/db-schema.ts | 2 + src/lib/llm-provider.ts | 22 +- 9 files changed, 1061 insertions(+), 4 deletions(-) create mode 100644 drizzle-templates/0010_tranquil_squirrel_girl.sql create mode 100644 drizzle-templates/meta/0010_snapshot.json create mode 100644 drizzle/meta/0023_snapshot.json create mode 100644 src/app/api/llm/models/route.ts create mode 100644 src/app/api/llm/providers/route.ts diff --git a/drizzle-templates/0010_tranquil_squirrel_girl.sql b/drizzle-templates/0010_tranquil_squirrel_girl.sql new file mode 100644 index 00000000..b6998ecb --- /dev/null +++ b/drizzle-templates/0010_tranquil_squirrel_girl.sql @@ -0,0 +1,2 @@ +ALTER TABLE `agents` ADD `llmProvider` text;--> statement-breakpoint +ALTER TABLE `agents` ADD `llmModel` text; \ No newline at end of file diff --git a/drizzle-templates/meta/0010_snapshot.json b/drizzle-templates/meta/0010_snapshot.json new file mode 100644 index 00000000..101d616f --- /dev/null +++ b/drizzle-templates/meta/0010_snapshot.json @@ -0,0 +1,182 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "72edd5be-dee7-4479-9081-c6dcb39e81db", + "prevId": "32dafa3e-fb56-4423-b94d-875ae02b80db", + "tables": { + "agents": { + "name": "agents", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "displayName": { + "name": "displayName", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "options": { + "name": "options", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "events": { + "name": "events", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "tools": { + "name": "tools", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "flows": { + "name": "flows", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "published": { + "name": "published", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "defaultFlow": { + "name": "defaultFlow", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "inputs": { + "name": "inputs", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "agents": { + "name": "agents", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "expectedResult": { + "name": "expectedResult", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "safetyRules": { + "name": "safetyRules", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "locale": { + "name": "locale", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "agentType": { + "name": "agentType", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "llmProvider": { + "name": "llmProvider", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "llmModel": { + "name": "llmModel", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updatedAt": { + "name": "updatedAt", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "extra": { + "name": "extra", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": {} + } +} \ No newline at end of file diff --git a/drizzle-templates/meta/_journal.json b/drizzle-templates/meta/_journal.json index 4050c6b4..e03eccd9 100644 --- a/drizzle-templates/meta/_journal.json +++ b/drizzle-templates/meta/_journal.json @@ -71,6 +71,13 @@ "when": 1741281961082, "tag": "0009_worried_lockheed", "breakpoints": true + }, + { + "idx": 10, + "version": "6", + "when": 1745831549017, + "tag": "0010_tranquil_squirrel_girl", + "breakpoints": true } ] } \ No newline at end of file diff --git a/drizzle/meta/0023_snapshot.json b/drizzle/meta/0023_snapshot.json new file mode 100644 index 00000000..7b92b009 --- /dev/null +++ b/drizzle/meta/0023_snapshot.json @@ -0,0 +1,796 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "1fb6f1af-220d-43a4-8723-7cddfddae4ba", + "prevId": "435aa0a1-c1dc-45cd-8dc8-d77f248d4e3c", + "tables": { + "agents": { + "name": "agents", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "displayName": { + "name": "displayName", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "options": { + "name": "options", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "events": { + "name": "events", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "tools": { + "name": "tools", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "flows": { + "name": "flows", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "published": { + "name": "published", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "defaultFlow": { + "name": "defaultFlow", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "inputs": { + "name": "inputs", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "agents": { + "name": "agents", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "expectedResult": { + "name": "expectedResult", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "safetyRules": { + "name": "safetyRules", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "locale": { + "name": "locale", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "agentType": { + "name": "agentType", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "llmProvider": { + "name": "llmProvider", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "llmModel": { + "name": "llmModel", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updatedAt": { + "name": "updatedAt", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "extra": { + "name": "extra", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "attachments": { + "name": "attachments", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "displayName": { + "name": "displayName", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "safeNameIdentifier": { + "name": "safeNameIdentifier", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "mimeType": { + "name": "mimeType", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "assignedTo": { + "name": "assignedTo", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "json": { + "name": "json", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "extra": { + "name": "extra", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "size": { + "name": "size", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "storageKey": { + "name": "storageKey", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updatedAt": { + "name": "updatedAt", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "calendarEvents": { + "name": "calendarEvents", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "start": { + "name": "start", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "end": { + "name": "end", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "exclusive": { + "name": "exclusive", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "location": { + "name": "location", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "agentId": { + "name": "agentId", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "participants": { + "name": "participants", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updatedAt": { + "name": "updatedAt", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "sessionId": { + "name": "sessionId", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "calendarEvents_agentId_agents_id_fk": { + "name": "calendarEvents_agentId_agents_id_fk", + "tableFrom": "calendarEvents", + "tableTo": "agents", + "columnsFrom": [ + "agentId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "config": { + "name": "config", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updatedAt": { + "name": "updatedAt", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "keys": { + "name": "keys", + "columns": { + "keyLocatorHash": { + "name": "keyLocatorHash", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "displayName": { + "name": "displayName", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "databaseIdHash": { + "name": "databaseIdHash", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "keyHash": { + "name": "keyHash", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "keyHashParams": { + "name": "keyHashParams", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "encryptedMasterKey": { + "name": "encryptedMasterKey", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "acl": { + "name": "acl", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "extra": { + "name": "extra", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "expiryDate": { + "name": "expiryDate", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updatedAt": { + "name": "updatedAt", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "results": { + "name": "results", + "columns": { + "agentId": { + "name": "agentId", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sessionId": { + "name": "sessionId", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "userName": { + "name": "userName", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "userEmail": { + "name": "userEmail", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "format": { + "name": "format", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updatedAt": { + "name": "updatedAt", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "finalizedAt": { + "name": "finalizedAt", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "results_agentId_agents_id_fk": { + "name": "results_agentId_agents_id_fk", + "tableFrom": "results", + "tableTo": "agents", + "columnsFrom": [ + "agentId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "results_sessionId_sessions_id_fk": { + "name": "results_sessionId_sessions_id_fk", + "tableFrom": "results", + "tableTo": "sessions", + "columnsFrom": [ + "sessionId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "sessions": { + "name": "sessions", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "agentId": { + "name": "agentId", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "userName": { + "name": "userName", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "userEmail": { + "name": "userEmail", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "acceptTerms": { + "name": "acceptTerms", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "completionTokens": { + "name": "completionTokens", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "promptTokens": { + "name": "promptTokens", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "messages": { + "name": "messages", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "updatedAt": { + "name": "updatedAt", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + }, + "finalizedAt": { + "name": "finalizedAt", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "sessions_agentId_agents_id_fk": { + "name": "sessions_agentId_agents_id_fk", + "tableFrom": "sessions", + "tableTo": "agents", + "columnsFrom": [ + "agentId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "terms": { + "name": "terms", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "code": { + "name": "code", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "signature": { + "name": "signature", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ip": { + "name": "ip", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ua": { + "name": "ua", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "signedAt": { + "name": "signedAt", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": {} + } +} \ No newline at end of file diff --git a/src/app/api/chat/route.ts b/src/app/api/chat/route.ts index ab8b3917..554784f4 100644 --- a/src/app/api/chat/route.ts +++ b/src/app/api/chat/route.ts @@ -154,7 +154,7 @@ export async function POST(req: NextRequest) { }); const result = await streamText({ - model: llmProviderSetup(), + model: llmProviderSetup(agent.llmProvider || undefined, agent.llmModel || undefined), maxSteps: 10, onError: (error) => { console.error('Error in streaming:', error); diff --git a/src/app/api/llm/models/route.ts b/src/app/api/llm/models/route.ts new file mode 100644 index 00000000..b616b980 --- /dev/null +++ b/src/app/api/llm/models/route.ts @@ -0,0 +1,27 @@ +import { getDefaultModels } from '@/lib/llm-provider'; +import { authorizeRequestContext } from "@/lib/authorization-api"; +import { getErrorMessage } from "@/lib/utils"; +import { NextRequest, NextResponse } from 'next/server'; + +export async function GET(req: NextRequest, res: NextResponse) { + try { + // Authorize the request + await authorizeRequestContext(req, res); + + const searchParams = req.nextUrl.searchParams; + const provider = searchParams.get('provider'); + + if (!provider) { + return Response.json({ error: 'Provider parameter is required' }, { status: 400 }); + } + + const models = getDefaultModels(provider); + return Response.json({ models }); + } catch (error) { + console.error('Error fetching LLM models:', error); + return Response.json( + { error: 'Failed to fetch LLM models', message: getErrorMessage(error) }, + { status: error.message?.includes("Unauthorized") ? 401 : 500 } + ); + } +} \ No newline at end of file diff --git a/src/app/api/llm/providers/route.ts b/src/app/api/llm/providers/route.ts new file mode 100644 index 00000000..33c4c180 --- /dev/null +++ b/src/app/api/llm/providers/route.ts @@ -0,0 +1,25 @@ +import { getAvailableProviders } from "@/lib/llm-provider"; +import { authorizeRequestContext } from "@/lib/authorization-api"; +import { getErrorMessage } from "@/lib/utils"; +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(req: NextRequest, res: NextResponse) { + try { + // Authorize the request + const requestContext = await authorizeRequestContext(req, res); + + console.log("Request context:", requestContext); + + const providers = getAvailableProviders(); + return Response.json({ providers }); + } catch (error) { + console.error("Error fetching LLM providers:", error); + return Response.json( + { + error: "Failed to fetch LLM providers", + message: getErrorMessage(error), + }, + { status: error.message?.includes("Unauthorized") ? 401 : 500 } + ); + } +} diff --git a/src/data/server/db-schema.ts b/src/data/server/db-schema.ts index 8f351689..40da323e 100644 --- a/src/data/server/db-schema.ts +++ b/src/data/server/db-schema.ts @@ -26,6 +26,8 @@ export const agents = sqliteTable('agents', { status: text('status'), locale: text('locale'), agentType: text('agentType'), + llmProvider: text('llmProvider'), + llmModel: text('llmModel'), createdAt: text('createdAt').notNull().default(sql`CURRENT_TIMESTAMP`), updatedAt: text('updatedAt').notNull().default(sql`CURRENT_TIMESTAMP`), icon: text('icon'), diff --git a/src/lib/llm-provider.ts b/src/lib/llm-provider.ts index 4b97c377..bf52d3b1 100644 --- a/src/lib/llm-provider.ts +++ b/src/lib/llm-provider.ts @@ -24,8 +24,8 @@ const llmConfigurations: Record = { }, }; -export function llmProviderSetup() { - const providerType = process.env.LLM_PROVIDER as LLMProviderType; +export function llmProviderSetup(selectedProvider?: string, selectedModel?: string) { + const providerType = (selectedProvider || process.env.LLM_PROVIDER) as LLMProviderType; const configuration = llmConfigurations[providerType || "openai"]; if (!configuration) { @@ -35,7 +35,23 @@ export function llmProviderSetup() { ); } - const { provider, model, settings } = configuration; + const { provider, settings } = configuration; + const model = selectedModel || configuration.model; return provider(model, settings); } + +export function getAvailableProviders(): string[] { + return Object.values(LLMProviderType); +} + +export function getDefaultModels(provider: string): string[] { + switch (provider) { + case LLMProviderType.OPENAI: + return ["gpt-4o", "gpt-4-turbo", "gpt-3.5-turbo"]; + case LLMProviderType.OLLAMA: + return ["llama3.1", "gemma", "mistral"]; + default: + return []; + } +} From b3eb1c699092381cdb205cf30f6cf246fe489dd3 Mon Sep 17 00:00:00 2001 From: yan-shcherbakov Date: Mon, 26 May 2025 11:08:54 +0300 Subject: [PATCH 2/5] wip 1 --- .../admin/agent/[id]/general/page.tsx | 2 + src/components/llm-config-select.tsx | 162 ++++++++++++++++++ src/data/client/models.ts | 10 ++ src/data/dto.ts | 2 + 4 files changed, 176 insertions(+) create mode 100644 src/components/llm-config-select.tsx diff --git a/src/app/[locale]/admin/agent/[id]/general/page.tsx b/src/app/[locale]/admin/agent/[id]/general/page.tsx index 20a9bb01..fd887e20 100644 --- a/src/app/[locale]/admin/agent/[id]/general/page.tsx +++ b/src/app/[locale]/admin/agent/[id]/general/page.tsx @@ -25,6 +25,7 @@ import { AttachmentUploader } from '@/components/attachment-uploader'; import { DatabaseContext } from '@/contexts/db-context'; import { SaaSContext } from '@/contexts/saas-context'; import ZoomableImage from '@/components/zoomable-image'; +import { LLMConfigSelect } from '@/components/llm-config-select'; export function onAgentSubmit(agent: Agent | null, watch: UseFormWatch>, setValue: UseFormSetValue>, getValues: UseFormGetValues>, updateAgent: (agent: Agent, setAsCurrent: boolean) => Promise, t: TFunction<"translation", undefined>, router: any, editors: Record>) { // eslint-disable-next-line @@ -248,6 +249,7 @@ export default function GeneralPage() { +