source dump of claude code
at main 162 lines 5.5 kB view raw
1// biome-ignore-all assist/source/organizeImports: ANT-ONLY import markers must not be reordered 2import type { Theme } from './theme.js' 3import { feature } from 'bun:bundle' 4import { getFeatureValue_CACHED_MAY_BE_STALE } from '../services/analytics/growthbook.js' 5import { getCanonicalName } from './model/model.js' 6import { get3PModelCapabilityOverride } from './model/modelSupportOverrides.js' 7import { getAPIProvider } from './model/providers.js' 8import { getSettingsWithErrors } from './settings/settings.js' 9 10export type ThinkingConfig = 11 | { type: 'adaptive' } 12 | { type: 'enabled'; budgetTokens: number } 13 | { type: 'disabled' } 14 15/** 16 * Build-time gate (feature) + runtime gate (GrowthBook). The build flag 17 * controls code inclusion in external builds; the GB flag controls rollout. 18 */ 19export function isUltrathinkEnabled(): boolean { 20 if (!feature('ULTRATHINK')) { 21 return false 22 } 23 return getFeatureValue_CACHED_MAY_BE_STALE('tengu_turtle_carbon', true) 24} 25 26/** 27 * Check if text contains the "ultrathink" keyword. 28 */ 29export function hasUltrathinkKeyword(text: string): boolean { 30 return /\bultrathink\b/i.test(text) 31} 32 33/** 34 * Find positions of "ultrathink" keyword in text (for UI highlighting/notification) 35 */ 36export function findThinkingTriggerPositions(text: string): Array<{ 37 word: string 38 start: number 39 end: number 40}> { 41 const positions: Array<{ word: string; start: number; end: number }> = [] 42 // Fresh /g literal each call — String.prototype.matchAll copies lastIndex 43 // from the source regex, so a shared instance would leak state from 44 // hasUltrathinkKeyword's .test() into this call on the next render. 45 const matches = text.matchAll(/\bultrathink\b/gi) 46 47 for (const match of matches) { 48 if (match.index !== undefined) { 49 positions.push({ 50 word: match[0], 51 start: match.index, 52 end: match.index + match[0].length, 53 }) 54 } 55 } 56 57 return positions 58} 59 60const RAINBOW_COLORS: Array<keyof Theme> = [ 61 'rainbow_red', 62 'rainbow_orange', 63 'rainbow_yellow', 64 'rainbow_green', 65 'rainbow_blue', 66 'rainbow_indigo', 67 'rainbow_violet', 68] 69 70const RAINBOW_SHIMMER_COLORS: Array<keyof Theme> = [ 71 'rainbow_red_shimmer', 72 'rainbow_orange_shimmer', 73 'rainbow_yellow_shimmer', 74 'rainbow_green_shimmer', 75 'rainbow_blue_shimmer', 76 'rainbow_indigo_shimmer', 77 'rainbow_violet_shimmer', 78] 79 80export function getRainbowColor( 81 charIndex: number, 82 shimmer: boolean = false, 83): keyof Theme { 84 const colors = shimmer ? RAINBOW_SHIMMER_COLORS : RAINBOW_COLORS 85 return colors[charIndex % colors.length]! 86} 87 88// TODO(inigo): add support for probing unknown models via API error detection 89// Provider-aware thinking support detection (aligns with modelSupportsISP in betas.ts) 90export function modelSupportsThinking(model: string): boolean { 91 const supported3P = get3PModelCapabilityOverride(model, 'thinking') 92 if (supported3P !== undefined) { 93 return supported3P 94 } 95 if (process.env.USER_TYPE === 'ant') { 96 if (resolveAntModel(model.toLowerCase())) { 97 return true 98 } 99 } 100 // IMPORTANT: Do not change thinking support without notifying the model 101 // launch DRI and research. This can greatly affect model quality and bashing. 102 const canonical = getCanonicalName(model) 103 const provider = getAPIProvider() 104 // 1P and Foundry: all Claude 4+ models (including Haiku 4.5) 105 if (provider === 'foundry' || provider === 'firstParty') { 106 return !canonical.includes('claude-3-') 107 } 108 // 3P (Bedrock/Vertex): only Opus 4+ and Sonnet 4+ 109 return canonical.includes('sonnet-4') || canonical.includes('opus-4') 110} 111 112// @[MODEL LAUNCH]: Add the new model to the allowlist if it supports adaptive thinking. 113export function modelSupportsAdaptiveThinking(model: string): boolean { 114 const supported3P = get3PModelCapabilityOverride(model, 'adaptive_thinking') 115 if (supported3P !== undefined) { 116 return supported3P 117 } 118 const canonical = getCanonicalName(model) 119 // Supported by a subset of Claude 4 models 120 if (canonical.includes('opus-4-6') || canonical.includes('sonnet-4-6')) { 121 return true 122 } 123 // Exclude any other known legacy models (allowlist above catches 4-6 variants first) 124 if ( 125 canonical.includes('opus') || 126 canonical.includes('sonnet') || 127 canonical.includes('haiku') 128 ) { 129 return false 130 } 131 // IMPORTANT: Do not change adaptive thinking support without notifying the 132 // model launch DRI and research. This can greatly affect model quality and 133 // bashing. 134 135 // Newer models (4.6+) are all trained on adaptive thinking and MUST have it 136 // enabled for model testing. DO NOT default to false for first party, otherwise 137 // we may silently degrade model quality. 138 139 // Default to true for unknown model strings on 1P and Foundry (because Foundry 140 // is a proxy). Do not default to true for other 3P as they have different formats 141 // for their model strings. 142 const provider = getAPIProvider() 143 return provider === 'firstParty' || provider === 'foundry' 144} 145 146export function shouldEnableThinkingByDefault(): boolean { 147 if (process.env.MAX_THINKING_TOKENS) { 148 return parseInt(process.env.MAX_THINKING_TOKENS, 10) > 0 149 } 150 151 const { settings } = getSettingsWithErrors() 152 if (settings.alwaysThinkingEnabled === false) { 153 return false 154 } 155 156 // IMPORTANT: Do not change default thinking enabled value without notifying 157 // the model launch DRI and research. This can greatly affect model quality and 158 // bashing. 159 160 // Enable thinking by default unless explicitly disabled. 161 return true 162}