From 00a07dc95a8d2a101ed86b560effef6f6e8b84a5 Mon Sep 17 00:00:00 2001 From: Hammer Date: Tue, 27 Jan 2026 22:45:06 +0000 Subject: [PATCH] Add OpenAI support, default to gpt-4o-mini --- bun.lock | 5 +++++ docker-compose.yml | 1 + package.json | 1 + src/services/ai.ts | 13 ++++++++++--- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/bun.lock b/bun.lock index 65e5a71..9031342 100644 --- a/bun.lock +++ b/bun.lock @@ -9,6 +9,7 @@ "@elysiajs/cors": "^1.4.1", "@langchain/anthropic": "^1.3.12", "@langchain/core": "^1.1.17", + "@langchain/openai": "^1.2.3", "better-auth": "^1.4.17", "drizzle-orm": "^0.45.1", "elysia": "^1.4.22", @@ -110,6 +111,8 @@ "@langchain/core": ["@langchain/core@1.1.17", "", { "dependencies": { "@cfworker/json-schema": "^4.0.2", "ansi-styles": "^5.0.0", "camelcase": "6", "decamelize": "1.2.0", "js-tiktoken": "^1.0.12", "langsmith": ">=0.4.0 <1.0.0", "mustache": "^4.2.0", "p-queue": "^6.6.2", "uuid": "^10.0.0", "zod": "^3.25.76 || ^4" } }, "sha512-g7/kcKbKEwNZSyyT7aT0utxn7wTOtKErqz0cL6VjrV4v/aOb9g+dKcfj17YkSm42YQmJp/rB2IXGc17vQPEBqA=="], + "@langchain/openai": ["@langchain/openai@1.2.3", "", { "dependencies": { "js-tiktoken": "^1.0.12", "openai": "^6.16.0", "zod": "^3.25.76 || ^4" }, "peerDependencies": { "@langchain/core": "^1.0.0" } }, "sha512-+bKR4+Obz5a/NHEw0bAm3f/s4k0cXc/g46ZRRXqjcyDYP+9wFarItvGNn6DEEk5S7pGp1QqApAQNt9IZk1Ic1Q=="], + "@noble/ciphers": ["@noble/ciphers@2.1.1", "", {}, "sha512-bysYuiVfhxNJuldNXlFEitTVdNnYUc+XNJZd7Qm2a5j1vZHgY+fazadNFWFaMK/2vye0JVlxV3gHmC0WDfAOQw=="], "@noble/hashes": ["@noble/hashes@2.0.1", "", {}, "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw=="], @@ -212,6 +215,8 @@ "non-error": ["non-error@0.1.0", "", {}, "sha512-TMB1uHiGsHRGv1uYclfhivcnf0/PdFp2pNqRxXjncaAsjYMoisaQJI+SSZCqRq+VliwRTC8tsMQfmrWjDMhkPQ=="], + "openai": ["openai@6.16.0", "", { "peerDependencies": { "ws": "^8.18.0", "zod": "^3.25 || ^4.0" }, "optionalPeers": ["ws", "zod"], "bin": { "openai": "bin/cli" } }, "sha512-fZ1uBqjFUjXzbGc35fFtYKEOxd20kd9fDpFeqWtsOZWiubY8CZ1NAlXHW3iathaFvqmNtCWMIsosCuyeI7Joxg=="], + "openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="], "p-finally": ["p-finally@1.0.0", "", {}, "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow=="], diff --git a/docker-compose.yml b/docker-compose.yml index ec88c7c..1dd031d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -28,6 +28,7 @@ services: ALLOWED_ORIGINS: ${ALLOWED_ORIGINS:-http://localhost:3000,http://localhost:8080} BETTER_AUTH_SECRET: ${BETTER_AUTH_SECRET} ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY} + OPENAI_API_KEY: ${OPENAI_API_KEY} RESEND_API_KEY: ${RESEND_API_KEY} DEFAULT_FROM_EMAIL: ${DEFAULT_FROM_EMAIL:-onboarding@resend.dev} depends_on: diff --git a/package.json b/package.json index c95b358..6fd8a25 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "@elysiajs/cors": "^1.4.1", "@langchain/anthropic": "^1.3.12", "@langchain/core": "^1.1.17", + "@langchain/openai": "^1.2.3", "better-auth": "^1.4.17", "drizzle-orm": "^0.45.1", "elysia": "^1.4.22", diff --git a/src/services/ai.ts b/src/services/ai.ts index 71ebd6c..47ae160 100644 --- a/src/services/ai.ts +++ b/src/services/ai.ts @@ -1,11 +1,19 @@ import { ChatAnthropic } from '@langchain/anthropic'; +import { ChatOpenAI } from '@langchain/openai'; import { ChatPromptTemplate } from '@langchain/core/prompts'; import { StringOutputParser } from '@langchain/core/output_parsers'; export type AIProvider = 'anthropic' | 'openai'; // Get model based on provider -function getModel(provider: AIProvider = 'anthropic') { +function getModel(provider: AIProvider = 'openai') { + if (provider === 'openai') { + return new ChatOpenAI({ + modelName: 'gpt-4o-mini', + openAIApiKey: process.env.OPENAI_API_KEY, + }); + } + if (provider === 'anthropic') { return new ChatAnthropic({ modelName: 'claude-sonnet-4-20250514', @@ -13,8 +21,7 @@ function getModel(provider: AIProvider = 'anthropic') { }); } - // Add OpenAI support later - throw new Error(`Provider ${provider} not yet supported`); + throw new Error(`Provider ${provider} not supported`); } // Email generation prompt