|
1 | 1 | import capitalize from 'lodash-es/capitalize.js' |
2 | 2 | import * as React from 'react' |
3 | 3 | import { useCallback, useMemo, useState } from 'react' |
| 4 | +import { has1mContext } from '../utils/context.js' |
4 | 5 | import { useExitOnCtrlCDWithKeybindings } from 'src/hooks/useExitOnCtrlCDWithKeybindings.js' |
5 | 6 | import { |
6 | 7 | type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, |
@@ -83,6 +84,23 @@ export function ModelPicker({ |
83 | 84 | isFastModeEnabled() ? s.fastMode : false, |
84 | 85 | ) |
85 | 86 |
|
| 87 | + const [marked1MValues, setMarked1MValues] = useState<Set<string>>( |
| 88 | + () => new Set(has1mContext(initialValue) ? [initialValue.replace(/\[1m\]/i, '')] : []) |
| 89 | + ) |
| 90 | + |
| 91 | + const handleToggle1M = useCallback(() => { |
| 92 | + if (!focusedValue || focusedValue === NO_PREFERENCE) return |
| 93 | + setMarked1MValues(prev => { |
| 94 | + const next = new Set(prev) |
| 95 | + if (next.has(focusedValue)) { |
| 96 | + next.delete(focusedValue) |
| 97 | + } else { |
| 98 | + next.add(focusedValue) |
| 99 | + } |
| 100 | + return next |
| 101 | + }) |
| 102 | + }, [focusedValue]) |
| 103 | + |
86 | 104 | const [hasToggledEffort, setHasToggledEffort] = useState(false) |
87 | 105 | const effortValue = useAppState(s => s.effortValue) |
88 | 106 | const [effort, setEffort] = useState<EffortLevel | undefined>( |
@@ -136,6 +154,7 @@ export function ModelPicker({ |
136 | 154 | opt => opt.value === focusedValue, |
137 | 155 | )?.label |
138 | 156 | const focusedModel = resolveOptionModel(focusedValue) |
| 157 | + const is1MMarked = focusedValue !== undefined && focusedValue !== NO_PREFERENCE && marked1MValues.has(focusedValue) |
139 | 158 | const focusedSupportsEffort = focusedModel |
140 | 159 | ? modelSupportsEffort(focusedModel) |
141 | 160 | : false |
@@ -178,6 +197,7 @@ export function ModelPicker({ |
178 | 197 | { |
179 | 198 | 'modelPicker:decreaseEffort': () => handleCycleEffort('left'), |
180 | 199 | 'modelPicker:increaseEffort': () => handleCycleEffort('right'), |
| 200 | + 'modelPicker:toggle1M': () => handleToggle1M(), |
181 | 201 | }, |
182 | 202 | { context: 'ModelPicker' }, |
183 | 203 | ) |
@@ -215,7 +235,11 @@ export function ModelPicker({ |
215 | 235 | onSelect(null, selectedEffort) |
216 | 236 | return |
217 | 237 | } |
218 | | - onSelect(value, selectedEffort) |
| 238 | + // Apply or strip [1m] suffix based on user toggle |
| 239 | + const wants1M = marked1MValues.has(value) |
| 240 | + const baseValue = value.replace(/\[1m\]/i, '') |
| 241 | + const finalValue = wants1M ? `${baseValue}[1m]` : baseValue |
| 242 | + onSelect(finalValue, selectedEffort) |
219 | 243 | } |
220 | 244 |
|
221 | 245 | const content = ( |
@@ -270,6 +294,17 @@ export function ModelPicker({ |
270 | 294 | {focusedModelName ? ` for ${focusedModelName}` : ''} |
271 | 295 | </Text> |
272 | 296 | )} |
| 297 | + {is1MMarked ? ( |
| 298 | + <Text dimColor> |
| 299 | + <EffortLevelIndicator effort={'high'} /> 1M context on |
| 300 | + <Text color="subtle"> · Space to toggle</Text> |
| 301 | + </Text> |
| 302 | + ) : ( |
| 303 | + <Text color="subtle"> |
| 304 | + <EffortLevelIndicator effort={undefined} /> 1M context off |
| 305 | + {focusedModelName ? ` for ${focusedModelName}` : ''} |
| 306 | + </Text> |
| 307 | + )} |
273 | 308 | </Box> |
274 | 309 |
|
275 | 310 | {isFastModeEnabled() ? ( |
|
0 commit comments