← back to Dear Bubbe Nextjs
deploy(bubbe.ai): OpenAI-primary chat, drop standalone for next start, strip em-dash key override from ecosystem
242ce89970d2756399f3c35d7c2211dd41253ea6 · 2026-07-16 11:58:27 -0700 · Steve Abrams
- chat: OpenAI gpt-3.5-turbo primary (fast, funded), Ollama last-resort (Anthropic out of credits)
- next.config: disable output:standalone so `next start` serves + loads .env.local
- ecosystem: remove hardcoded ANTHROPIC_API_KEY placeholder (em-dash crashed every request); keys come from .env.local; USE_ANTHROPIC=0
Files touched
M app/api/chat/route.tsM ecosystem.config.jsM next.config.ts
Diff
commit 242ce89970d2756399f3c35d7c2211dd41253ea6
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Jul 16 11:58:27 2026 -0700
deploy(bubbe.ai): OpenAI-primary chat, drop standalone for next start, strip em-dash key override from ecosystem
- chat: OpenAI gpt-3.5-turbo primary (fast, funded), Ollama last-resort (Anthropic out of credits)
- next.config: disable output:standalone so `next start` serves + loads .env.local
- ecosystem: remove hardcoded ANTHROPIC_API_KEY placeholder (em-dash crashed every request); keys come from .env.local; USE_ANTHROPIC=0
---
app/api/chat/route.ts | 55 +++++++++++++++++++++++++--------------------------
ecosystem.config.js | 7 +++++--
next.config.ts | 4 ++--
3 files changed, 34 insertions(+), 32 deletions(-)
diff --git a/app/api/chat/route.ts b/app/api/chat/route.ts
index 279e4e2..3bddadd 100644
--- a/app/api/chat/route.ts
+++ b/app/api/chat/route.ts
@@ -79,38 +79,37 @@ async function getAIResponse(systemPrompt: string, messages: Array<{role: 'user'
// fall through to local
}
}
+ // Primary: OpenAI (fast + funded). Ollama is the local last-resort fallback.
try {
- console.log('[AI_RESPONSE] Using local Ollama...')
- const { content } = await ollamaChat(messages as any, {
- system: augmentedSystem,
- maxTokens: 120,
- temperature: 0.85,
+ console.log('[OPENAI] Primary...')
+ const openaiMessages = [
+ { role: 'system' as const, content: augmentedSystem },
+ ...messages.map(m => ({ role: m.role as 'user' | 'assistant', content: m.content }))
+ ]
+ const response = await openai.chat.completions.create({
+ model: 'gpt-3.5-turbo',
+ max_tokens: 80,
+ messages: openaiMessages
})
- const cleaned = content.trim()
- console.log('[OLLAMA] Success:', cleaned.substring(0, 100))
- return cleaned
- } catch (ollamaError: any) {
- console.log('[OLLAMA] Failed, using OpenAI fallback:', ollamaError.message)
-
- // Fallback to OpenAI
- try {
- console.log('[OPENAI] Using fallback...')
- const openaiMessages = [
- { role: 'system' as const, content: systemPrompt + '\n\nABSOLUTE REQUIREMENTS:\n1. Your response MUST end with a complete sentence\n2. ALWAYS END WITH A QUESTION - an invasive, personal question!\n3. NEVER cut off mid-sentence!\n4. Questions should be about marriage, money, weight, job, or family!' },
- ...messages.map(m => ({ role: m.role as 'user' | 'assistant', content: m.content }))
- ]
-
- const response = await openai.chat.completions.create({
- model: 'gpt-3.5-turbo',
- max_tokens: 80,
- messages: openaiMessages
- })
-
- const responseText = response.choices[0]?.message?.content || "Oy vey, technical problems! How much money do you have in your bank account anyway?"
+ const responseText = response.choices[0]?.message?.content
+ if (responseText) {
console.log('[OPENAI] Success:', responseText.substring(0, 100))
return responseText
- } catch (openaiError: any) {
- console.log('[OPENAI] Also failed:', openaiError.message)
+ }
+ throw new Error('empty openai response')
+ } catch (openaiError: any) {
+ console.log('[OPENAI] Failed, trying local Ollama:', openaiError.message)
+ try {
+ const { content } = await ollamaChat(messages as any, {
+ system: augmentedSystem,
+ maxTokens: 120,
+ temperature: 0.85,
+ })
+ const cleaned = content.trim()
+ console.log('[OLLAMA] Success:', cleaned.substring(0, 100))
+ return cleaned
+ } catch (ollamaError: any) {
+ console.log('[OLLAMA] Also failed:', ollamaError.message)
// Last resort fallback
return "Listen here, schmuck! The computers are acting up - maybe if you paid me more this wouldn't happen! When are you getting married already?"
}
diff --git a/ecosystem.config.js b/ecosystem.config.js
index ba86d09..b05f11d 100644
--- a/ecosystem.config.js
+++ b/ecosystem.config.js
@@ -3,11 +3,14 @@ module.exports = {
name: 'bubbe',
script: 'npm',
args: 'start',
+ cwd: '/root/Projects/dear-bubbe-nextjs',
env: {
PORT: 3011,
NODE_ENV: 'production',
- ELEVENLABS_API_KEY: process.env.ELEVENLABS_API_KEY || '',
- ANTHROPIC_API_KEY: '<REDACTED — see secrets-manager>'
+ // API keys are loaded from .env.local (do NOT hardcode here — a stale
+ // placeholder with an em-dash used to override the real key and crash chat).
+ // USE_ANTHROPIC=1 only when the Anthropic account has credits; OpenAI is primary.
+ USE_ANTHROPIC: '0'
}
}]
}
diff --git a/next.config.ts b/next.config.ts
index 6d72bc3..6587434 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -2,8 +2,8 @@ import type { NextConfig } from "next";
const nextConfig: NextConfig = {
// Configuration options
- output: 'standalone',
- outputFileTracingRoot: __dirname,
+ // output: 'standalone', // disabled: pm2 runs `next start`, which needs a normal build + auto-loads .env.local
+ // outputFileTracingRoot: __dirname,
poweredByHeader: false,
compress: true,
← 9778c1c security: redact/env-ify remaining ELEVENLABS_API_KEY copies
·
back to Dear Bubbe Nextjs
·
feat(bubbe.ai): free chat — 3 messages before Google sign-in c7ca51c →