@@ -1169,18 +1169,13 @@ async function openLegal(target) {
11691169 await vscode . env . openExternal ( vscode . Uri . parse ( 'https://levelcode.ai' + path ) ) ;
11701170}
11711171
1172- /** Human "≈ turns left" formatting (e.g. 8044 → "8k", 375 → "375"). */
1173- function fmtTurns ( n ) {
1174- n = Number ( n ) || 0 ;
1175- return n >= 1000 ? ( Math . round ( n / 100 ) / 10 ) + 'k' : String ( n ) ;
1176- }
1177-
11781172/**
11791173 * The LevelCode Cloud model menu (gateway mode, signed in). Fetches the plan's roster from the backend
1180- * (GET /account/models): LIVE models (confirmed price) are selectable with their credit multiplier +
1181- * ≈ turns-left on the remaining budget; STAGED models (frontier, assumption-priced) are shown 🔒 as
1182- * "coming soon"; the free tier surfaces an Upgrade CTA. The backend re-checks entitlement, so a
1183- * client selection can never over-reach the plan.
1174+ * (GET /account/models): LIVE models (confirmed price) are selectable; STAGED models (frontier,
1175+ * assumption-priced) are shown 🔒 as "coming soon"; the free tier surfaces an Upgrade CTA. Rows are
1176+ * deliberately NAME-ONLY — the id, context, credit multiplier and ≈turns-left were debug detail that
1177+ * buried the model name, so they were dropped (the plan + remaining credits stay in the placeholder).
1178+ * The backend re-checks entitlement, so a client selection can never over-reach the plan.
11841179 */
11851180async function pickCloudModel ( ) {
11861181 const roster = await fetchCloudRoster ( ) ;
@@ -1195,46 +1190,38 @@ async function pickCloudModel() {
11951190 const items = [ { label : 'LevelCode Cloud · ' + plan , kind : vscode . QuickPickItemKind . Separator } ] ;
11961191 // Auto (paid only): the gateway picks the cheapest engine per turn — free margin for the user.
11971192 if ( paid ) {
1198- items . push ( {
1199- label : ( active === GATEWAY_AUTO_MODEL ? '$(check) ' : '' ) + '$(sparkle) ' + GATEWAY_AUTO_LABEL ,
1200- description : GATEWAY_AUTO_MODEL ,
1201- detail : 'Routes each turn to the best-value engine · saves credits' ,
1202- _cloud : GATEWAY_AUTO_MODEL
1203- } ) ;
1193+ items . push ( { label : ( active === GATEWAY_AUTO_MODEL ? '$(check) ' : '' ) + '$(sparkle) ' + GATEWAY_AUTO_LABEL , _cloud : GATEWAY_AUTO_MODEL } ) ;
12041194 }
12051195 if ( models . length ) {
12061196 for ( const m of models ) {
1207- const ctxK = Math . round ( ( m . context || 0 ) / 1000 ) + 'K ctx' ;
12081197 if ( m . live ) {
1209- const turns = ( m . turns_left != null ) ? ' · ≈' + fmtTurns ( m . turns_left ) + ' turns left' : '' ;
1210- items . push ( {
1211- label : ( m . id === active ? '$(check) ' : '' ) + m . label ,
1212- description : m . id ,
1213- detail : m . multiplier + '× credits · ' + ctxK + turns ,
1214- _cloud : m . id
1215- } ) ;
1198+ // Name only — the model name is the whole point of the row. id/ctx/multiplier/turns removed.
1199+ items . push ( { label : ( m . id === active ? '$(check) ' : '' ) + m . label , _cloud : m . id } ) ;
12161200 } else {
1217- items . push ( { label : '$(lock) ' + m . label , description : m . id , detail : m . multiplier + '× credits · ' + ctxK + ' · coming soon' , _soon : true } ) ;
1201+ // Staged: not selectable yet — "coming soon" is the one kept hint; _name backs the info toast.
1202+ items . push ( { label : '$(lock) ' + m . label , description : 'coming soon' , _soon : true , _name : m . label } ) ;
12181203 }
12191204 }
12201205 } else {
12211206 // Offline / roster unavailable — minimal fallback so the menu still works.
1222- items . push ( { label : ( active === GATEWAY_FREE_MODEL ? '$(check) ' : '' ) + GATEWAY_FREE_LABEL , description : GATEWAY_FREE_MODEL , _cloud : GATEWAY_FREE_MODEL } ) ;
1223- if ( paid ) { items . push ( { label : ( active === GATEWAY_PRO_MODEL ? '$(check) ' : '' ) + GATEWAY_PRO_LABEL , description : GATEWAY_PRO_MODEL , _cloud : GATEWAY_PRO_MODEL } ) ; }
1207+ items . push ( { label : ( active === GATEWAY_FREE_MODEL ? '$(check) ' : '' ) + GATEWAY_FREE_LABEL , _cloud : GATEWAY_FREE_MODEL } ) ;
1208+ if ( paid ) { items . push ( { label : ( active === GATEWAY_PRO_MODEL ? '$(check) ' : '' ) + GATEWAY_PRO_LABEL , _cloud : GATEWAY_PRO_MODEL } ) ; }
12241209 }
12251210 if ( ! paid ) {
1226- items . push ( { label : '$(rocket) Upgrade to Pro' , description : 'Kimi K2.7 Code + the full model roster' , _upgrade : true } ) ;
1211+ items . push ( { label : '$(rocket) Upgrade to Pro' , description : 'unlock the full roster' , _upgrade : true } ) ;
12271212 }
12281213 items . push ( { label : 'Other' , kind : vscode . QuickPickItemKind . Separator } ) ;
1229- items . push ( { label : '$(key) Use my own key (BYOK)…' , description : 'Turn off the metered gateway in settings ' , _action : 'byokSettings' } ) ;
1214+ items . push ( { label : '$(key) Use my own key (BYOK)…' , description : 'turn off the metered gateway' , _action : 'byokSettings' } ) ;
12301215
1216+ // Name-forward filtering: match the label only (no hidden id/description matching), so typing "opus"
1217+ // narrows to the Opus rows and nothing else.
12311218 const pick = await vscode . window . showQuickPick ( items , {
12321219 placeHolder : 'LevelCode Cloud model · Plan: ' + plan + credits ,
1233- matchOnDescription : true
1220+ matchOnDescription : false
12341221 } ) ;
12351222 if ( ! pick ) { return ; }
12361223 if ( pick . _upgrade ) { await openUpgrade ( ) ; return ; }
1237- if ( pick . _soon ) { vscode . window . showInformationMessage ( 'LevelCode Cloud: ' + ( pick . description || 'that model' ) + ' is coming soon — pricing is being finalized.' ) ; return ; }
1224+ if ( pick . _soon ) { vscode . window . showInformationMessage ( 'LevelCode Cloud: ' + ( pick . _name || 'that model' ) + ' is coming soon — pricing is being finalized.' ) ; return ; }
12381225 if ( pick . _action === 'byokSettings' ) { vscode . commands . executeCommand ( 'workbench.action.openSettings' , 'levelcode.ai.providerMode' ) ; return ; }
12391226 if ( pick . _cloud ) {
12401227 await aiConfig ( ) . update ( 'cloudModel' , pick . _cloud , vscode . ConfigurationTarget . Global ) ;
0 commit comments