Welcome to the User Options Strategy. If you are building a configurable software system, one of the first challenges you face is: "What choices should I actually show the user?"
This chapter explains how the model project decides which AI models (like Claude Sonnet, Opus, or Haiku) appear in the settings menu.
Imagine a high-end restaurant.
If a standard guest walks in, the waiter hands them the Standard Menu. If a VIP (Pro Subscriber) walks in, the waiter hands them a menu that includes the "Chef's Specials" (like 1 Million Context models).
The goal of this strategy is to ensure users only see options they are allowed to use, preventing confusion and errors later.
ModelOption
Before we look at the logic, let's look at the data structure. Every item on our menu is a ModelOption. It tells the UI what to display.
// modelOptions.ts
export type ModelOption = {
value: string | null // The ID sent to the API (e.g., 'opus')
label: string // What the user sees (e.g., 'Claude 3 Opus')
description: string // Small text below the label
// ... extra UI hints
}
The core logic lives in modelOptions.ts. Instead of a static list, we use a function called getModelOptionsBase that builds the array dynamically.
Every user gets a "Default" option. This is safe, recommended, and changes automatically behind the scenes so the user doesn't have to worry about version numbers.
// modelOptions.ts
export function getDefaultOptionForUser(fastMode = false): ModelOption {
// Check if user is a subscriber
if (isClaudeAISubscriber()) {
return {
value: null, // Null often implies "System Default"
label: 'Default (recommended)',
description: 'Intelligent agent that picks the best model.',
}
}
// ... logic for other user types
}
If the user pays for a subscription, they get access to powerful models like Opus or Sonnet with 1M Context.
// modelOptions.ts - Simplified Logic
if (isClaudeAISubscriber()) {
const options = [getDefaultOptionForUser()]
// Check if they have access to special 1M context features
if (checkSonnet1mAccess()) {
options.push(getMaxSonnet46_1MOption())
}
// Add standard models
options.push(MaxHaiku45Option)
return options
}
Explanation: We start with the default. Then, we ask checkSonnet1mAccess(): "Is this user allowed to use the huge context window?" If yes, we push that option onto the menu array.
Users who use their own API keys (PAYG) often care deeply about price. For them, the description field changes to show costs.
// modelOptions.ts
function getHaiku45Option(): ModelOption {
const is3P = getAPIProvider() !== 'firstParty' // 3rd Party API
return {
value: 'haiku',
label: 'Haiku',
// We dynamically add pricing info for API users!
description: `Haiku 4.5 ยท Fastest${is3P ? '' : ` ยท $0.25/M tokens`}`,
}
}
How does the system assemble this? It happens in real-time when the settings menu is requested.
The check1mAccess.ts file is crucial here. It acts as the "Bouncer" for specific high-end features.
// check1mAccess.ts
export function checkOpus1mAccess(): boolean {
// If the system globally disabled 1M context, say no.
if (is1mContextDisabled()) {
return false
}
// If they are a subscriber, check if their account has extra usage enabled.
if (isClaudeAISubscriber()) {
return isExtraUsageEnabled()
}
// API users usually have access by default (they pay per token).
return true
}
Sometimes, advanced users want to use a specific model version not listed on the standard menu. The strategy handles this by looking at environment variables or cached configurations.
// modelOptions.ts (Simplified)
const customOpus = process.env.ANTHROPIC_DEFAULT_OPUS_MODEL
// If a custom model string exists, show it instead of the generic one
if (is3P && customOpus) {
options.push({
value: 'opus',
label: 'Custom Opus',
description: `Targeting: ${customOpus}`
})
}
This allows the system to support "Secret Menu" items (new models released by Anthropic) without rewriting the entire UI code, simply by updating a configuration string.
The User Options Strategy is the first line of defense in user configuration.
check1mAccess).ModelOption list tailored specifically to that user.By filtering options before the user sees them, we prevent the user from selecting a model they can't actually pay for or access.
However, displaying the menu is only half the battle. What happens if a user tries to hack the request or use an old config file? We need to validate their choice.
Next Chapter: Gatekeeping & Validation
Generated by Code IQ