Skip to content

Commit 634147d

Browse files
authored
Merge pull request #25 from MHaggis/MHaggis/fix-link-previews
Fix account Auto model label for free-tier routing
2 parents 5248ca6 + 4fe568e commit 634147d

5 files changed

Lines changed: 48 additions & 6 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ Uses app-managed OpenRouter routing with your **Preferred Model** setting in `/a
106106

107107
| Preferred Model | Routed model |
108108
|---|---|
109-
| `auto` | `anthropic/claude-sonnet-4-6` |
109+
| `auto` | Free model pool (default: `nvidia/nemotron-3-super-120b-a12b:free`) |
110110
| `claude` | `anthropic/claude-sonnet-4-6` |
111111
| `claude-opus` | `anthropic/claude-opus-4-6` |
112112
| `gpt` | `openai/gpt-5.4` |

web/app/(app)/account/account-form.tsx

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ interface AccountFormProps {
1010
hasOpenaiKey: boolean;
1111
hasOpenrouterKey: boolean;
1212
preferredModel: string;
13+
tier: string;
1314
}
1415

15-
export function AccountForm({ displayName, hasClaudeKey, hasOpenaiKey, hasOpenrouterKey, preferredModel }: AccountFormProps) {
16+
export function AccountForm({ displayName, hasClaudeKey, hasOpenaiKey, hasOpenrouterKey, preferredModel, tier }: AccountFormProps) {
1617
const router = useRouter();
1718
const [name, setName] = useState(displayName);
1819
const [claudeKey, setClaudeKey] = useState('');
@@ -24,6 +25,21 @@ export function AccountForm({ displayName, hasClaudeKey, hasOpenaiKey, hasOpenro
2425
const [claudeSet, setClaudeSet] = useState(hasClaudeKey);
2526
const [openaiSet, setOpenaiSet] = useState(hasOpenaiKey);
2627
const [openrouterSet, setOpenrouterSet] = useState(hasOpenrouterKey);
28+
const isProOrAdmin = tier === 'pro' || tier === 'admin';
29+
const isFreeNoByok = !isProOrAdmin && !claudeSet && !openaiSet && !openrouterSet;
30+
31+
let autoOptionLabel = 'Auto (Default routing)';
32+
if (claudeSet) {
33+
autoOptionLabel = 'Auto (ignored while Claude BYOK key is set)';
34+
} else if (openaiSet) {
35+
autoOptionLabel = 'Auto (ignored while OpenAI BYOK key is set)';
36+
} else if (openrouterSet) {
37+
autoOptionLabel = 'Auto (Claude Sonnet 4.6)';
38+
} else if (isProOrAdmin) {
39+
autoOptionLabel = 'Auto (Free model pool default)';
40+
} else if (isFreeNoByok) {
41+
autoOptionLabel = 'Auto (Nemotron 3 Super 120B - Free default)';
42+
}
2743

2844
async function handleSave() {
2945
setSaving(true);
@@ -130,12 +146,22 @@ export function AccountForm({ displayName, hasClaudeKey, hasOpenaiKey, hasOpenro
130146
onChange={(e) => setModel(e.target.value)}
131147
className="w-full bg-bg2 border border-border focus:border-amber/50 rounded-[var(--radius-button)] px-4 py-2.5 text-text outline-none font-[family-name:var(--font-mono)] text-sm"
132148
>
133-
<option value="auto">Auto (Claude Sonnet 4.6)</option>
149+
<option value="auto">{autoOptionLabel}</option>
134150
<option value="claude">Claude Sonnet 4.6</option>
135151
<option value="claude-opus">Claude Opus 4.6</option>
136152
<option value="gpt">GPT-5.4</option>
137153
<option value="gpt-codex">GPT-5.3 Codex</option>
138154
</select>
155+
{isFreeNoByok && (
156+
<p className="text-text-dim text-xs mt-2">
157+
Free tier currently uses the free model pool with default <code className="text-amber">nvidia/nemotron-3-super-120b-a12b:free</code>.
158+
</p>
159+
)}
160+
{!openrouterSet && isProOrAdmin && (
161+
<p className="text-text-dim text-xs mt-2">
162+
On {tier.toUpperCase()}, <code className="text-amber">auto</code> uses the free model pool. Pick Claude/GPT explicitly to force frontier models.
163+
</p>
164+
)}
139165
</div>
140166

141167
{/* Claude API Key */}

web/app/(app)/account/page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ export default async function AccountPage() {
119119
hasOpenaiKey={!!profile?.openai_api_key_encrypted}
120120
hasOpenrouterKey={!!profile?.openrouter_api_key_encrypted}
121121
preferredModel={profile?.preferred_model || 'auto'}
122+
tier={profile?.tier || 'free'}
122123
/>
123124
</div>
124125
</div>

web/app/api/chat/route.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,15 @@ export async function POST(request: NextRequest) {
124124
const modelInfo = getModelRoutingInfo(profile);
125125
const modelConfig = getModelConfig(profile);
126126
let modelUsed = modelInfo.model;
127-
const isFree = profile?.tier !== 'pro' && profile?.tier !== 'admin' && !profile?.claude_api_key_encrypted && !profile?.openai_api_key_encrypted && !profile?.openrouter_api_key_encrypted;
127+
const hasByokKeys = !!(profile?.claude_api_key_encrypted || profile?.openai_api_key_encrypted || profile?.openrouter_api_key_encrypted);
128+
const useFreeModelPool = modelInfo.model.endsWith(':free') && !hasByokKeys;
128129

129130
// For free tier: pre-fetch relevant data and inject into context (free models don't support tool calling)
130131
// For pro/BYOK: use tool calling for dynamic data lookup
131132
let systemPrompt = buildSystemPrompt();
132133
let content: string;
133134

134-
if (isFree) {
135+
if (useFreeModelPool) {
135136
const lastUserMsg = messages[messages.length - 1]?.content || '';
136137

137138
// For data-heavy queries, build the response with REAL DATA first,
@@ -197,8 +198,12 @@ Write a brief 2-3 sentence analysis of this data. Focus on: what looks good, wha
197198
}
198199

199200
if (!responseData || responseData.error) {
201+
const isProOrAdmin = profile?.tier === 'pro' || profile?.tier === 'admin';
202+
const busyMessage = isProOrAdmin
203+
? 'Your Auto setting is using the free model pool, and those models are busy right now. Try again in a moment, or choose a specific model (Claude/GPT) in Account Settings.'
204+
: 'The free AI models are currently busy. Please try again in a moment, or upgrade to Pro: https://github.com/sponsors/MHaggis';
200205
return new Response(
201-
`The free AI models are currently busy. Please try again in a moment, or upgrade to Pro: https://github.com/sponsors/MHaggis`,
206+
busyMessage,
202207
{ status: 429 }
203208
);
204209
}

web/lib/ai/router.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,16 @@ export function getModelRoutingInfo(profile: UserProfile | null): ModelRoutingIn
101101
}
102102

103103
if (profile?.tier === 'pro' || profile?.tier === 'admin') {
104+
if (profile.preferred_model === 'auto') {
105+
return {
106+
source: profile.tier === 'admin' ? 'admin' : 'pro',
107+
provider: 'openrouter',
108+
model: FREE_MODEL,
109+
modelLabel: getModelLabel(FREE_MODEL),
110+
note: 'Auto uses the free model pool by default. Pick Claude/GPT explicitly to use frontier models.',
111+
fallbackModels: FREE_MODELS,
112+
};
113+
}
104114
const model = PRO_MODELS[profile.preferred_model] || PRO_MODELS['auto'];
105115
return {
106116
source: profile.tier === 'admin' ? 'admin' : 'pro',

0 commit comments

Comments
 (0)