fix(title): fall back to configured provider for title generation - #263
philippecottier wants to merge 1 commit into
Conversation
|
@philippecottier is attempting to deploy a commit to the Adam Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
1 issue found across 1 file
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/routes/api/title-generator.ts">
<violation number="1" location="src/routes/api/title-generator.ts:48">
P2: When a self-host is configured with only `OPENAI_API_KEY`, this selector skips it and returns `New Conversation`. Add a direct OpenAI branch or include that key in the documented provider selection.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| }); | ||
| } | ||
|
|
||
| if (process.env.OPENROUTER_API_KEY) { |
There was a problem hiding this comment.
P2: When a self-host is configured with only OPENAI_API_KEY, this selector skips it and returns New Conversation. Add a direct OpenAI branch or include that key in the documented provider selection.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/routes/api/title-generator.ts, line 48:
<comment>When a self-host is configured with only `OPENAI_API_KEY`, this selector skips it and returns `New Conversation`. Add a direct OpenAI branch or include that key in the documented provider selection.</comment>
<file context>
@@ -25,6 +26,78 @@ function textFromParts(parts: unknown): string {
+ });
+ }
+
+ if (process.env.OPENROUTER_API_KEY) {
+ const response = await fetch(
+ 'https://openrouter.ai/api/v1/chat/completions',
</file context>
|
| * Anthropic stays the default (unchanged for the hosted app), but self-hosters | ||
| * who only have an OpenAI/OpenRouter or Google key would otherwise get every | ||
| * conversation stuck on "New Conversation", since the previous implementation | ||
| * always called Anthropic. Fall back to those providers when no Anthropic key | ||
| * is set. Returns null when no provider is available. |
There was a problem hiding this comment.
Direct OpenAI Remains Unsupported
For an installation configured only with the documented OPENAI_API_KEY, this function checks neither that key nor a direct OpenAI provider. It falls through to null, so conversations remain stuck on “New Conversation” despite the comment claiming support for “OpenAI/OpenRouter.” Add direct OpenAI handling or correct the claimed supported configuration.
| async function generateTitleText(text: string): Promise<string | null> { | ||
| if (process.env.ANTHROPIC_API_KEY) { | ||
| return createAnthropicText({ | ||
| model: 'claude-haiku-4-5-20251001', | ||
| maxTokens: 100, | ||
| system: TITLE_SYSTEM_PROMPT, | ||
| content: text, | ||
| }); | ||
| } | ||
|
|
||
| if (process.env.OPENROUTER_API_KEY) { | ||
| const response = await fetch( | ||
| 'https://openrouter.ai/api/v1/chat/completions', | ||
| { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`, | ||
| }, | ||
| body: JSON.stringify({ | ||
| model: 'openai/gpt-5.6-sol', | ||
| max_tokens: 100, | ||
| messages: [ | ||
| { role: 'system', content: TITLE_SYSTEM_PROMPT }, | ||
| { role: 'user', content: text }, | ||
| ], | ||
| }), | ||
| }, | ||
| ); | ||
| if (!response.ok) { | ||
| throw new Error(`openrouter ${response.status}`); | ||
| } | ||
| const data = (await response.json()) as { | ||
| choices?: Array<{ message?: { content?: string } }>; | ||
| }; | ||
| return data.choices?.[0]?.message?.content ?? null; | ||
| } | ||
|
|
||
| if (process.env.GOOGLE_API_KEY) { | ||
| const response = await fetch( | ||
| `https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash:generateContent?key=${process.env.GOOGLE_API_KEY}`, | ||
| { | ||
| method: 'POST', | ||
| headers: { 'Content-Type': 'application/json' }, | ||
| body: JSON.stringify({ | ||
| systemInstruction: { parts: [{ text: TITLE_SYSTEM_PROMPT }] }, | ||
| contents: [{ role: 'user', parts: [{ text }] }], | ||
| generationConfig: { maxOutputTokens: 100 }, | ||
| }), | ||
| }, | ||
| ); | ||
| if (!response.ok) { | ||
| throw new Error(`google ${response.status}`); | ||
| } | ||
| const data = (await response.json()) as { | ||
| candidates?: Array<{ content?: { parts?: Array<{ text?: string }> } }>; | ||
| }; | ||
| return data.candidates?.[0]?.content?.parts?.[0]?.text ?? null; | ||
| } | ||
|
|
||
| return null; | ||
| } |
There was a problem hiding this comment.
The new provider selection, request, error, and response-parsing branches have no tests covering each key configuration and returned title. Because failures are deliberately converted into “New Conversation,” a broken request shape or routing regression would look exactly like the original bug. Add mocked tests that assert the actual title for Anthropic, OpenRouter, Google, and no-provider configurations.
The title generator always called Anthropic, so self-hosted instances configured with only an OpenAI/OpenRouter or Google key had every conversation stuck on "New Conversation". Keep Anthropic as the default, then fall back to OpenRouter and Google based on the configured API key.
2bd797c to
7f33da6
Compare
|
Thanks — addressed the review. Google's API key is now sent in the On direct OpenAI: the chat has no direct-OpenAI provider ( |
Problem
The title generator (
src/routes/api/title-generator.ts) always called Anthropic, so a self-hosted instance configured with only an OpenAI/OpenRouter or Google key had every conversation stuck on "New Conversation" — the request failed silently.Fix
Keep Anthropic as the default (no change for the hosted service), then fall back to OpenRouter then Google based on the configured API key, returning
null(→ "New Conversation") if none is set. Provider selection readsprocess.env; no new dependencies.Notes
gemini-3.8-flash).tsc -b,eslint, andprettierall pass.Summary by cubic
Title generation now uses the configured provider instead of always calling Anthropic, so self-hosted instances with only OpenRouter or Google credentials can generate conversation titles.
"New Conversation"when no key is configured or generation fails.Written for commit 7f33da6. Summary will update on new commits.