diff --git a/src/web/public/constants.js b/src/web/public/constants.js index cafb1a7a..42dabac0 100644 --- a/src/web/public/constants.js +++ b/src/web/public/constants.js @@ -2151,8 +2151,9 @@ const CLI_ID_PATTERN = /^[a-z][a-z0-9-]{0,23}$/; * are dropped and the length capped here too, and callers render it with * textContent. The tooltip says where a model that is not the CLI's own report * came from, so it never claims more than the server knows: one the session - * was launched with may have been switched since, and a custom endpoint's - * model is the endpoint's, whatever the CLI calls it. + * was launched with may have been switched since, one read from the CLI's + * config is what it is configured to run, and a custom endpoint's model is the + * endpoint's, whatever the CLI calls it. * * @param {object} session - a session from app.sessions * @param {Array<{id: string, label?: string}>} [catalog] - window.__codemanCliCatalog @@ -2177,7 +2178,9 @@ function describeSessionHarness(session, catalog) { ? ' (set at launch)' : source === 'custom-endpoint' ? ' (custom endpoint)' - : ''; + : source === 'config' + ? ' (from config)' + : ''; const title = [label, model].filter(Boolean).join(' \u00B7 ') + qualifier; return { id, label, model, title }; } diff --git a/src/web/public/i18n.js b/src/web/public/i18n.js index 80e02d3e..e103575e 100644 --- a/src/web/public/i18n.js +++ b/src/web/public/i18n.js @@ -1063,6 +1063,7 @@ // and model names pass through untranslated. [/^(.+) \(set at launch\)$/, (_m, names) => `${names}(启动时设定)`], [/^(.+) \(custom endpoint\)$/, (_m, names) => `${names}(自定义端点)`], + [/^(.+) \(from config\)$/, (_m, names) => `${names}(来自配置)`], // The Run button's mode codes ("Run CC", "Run SH", "Run OC" ...; a registry // CLI's shortBadge too). Exact entries win first ("Run Shell", "Run OMP"). [/^Run ([A-Z][A-Z0-9]{1,5})$/, (_m, code) => `运行 ${code}`], diff --git a/test/tile-grid-chrome.test.ts b/test/tile-grid-chrome.test.ts index 7a3f2dda..9f989932 100644 --- a/test/tile-grid-chrome.test.ts +++ b/test/tile-grid-chrome.test.ts @@ -182,6 +182,10 @@ describe('the harness logo and the model', () => { app._renderTileChrome(); expect(logoOf('s-b').title).toBe('Claude Code \u00B7 haiku (set at launch)'); expect(logoOf('s-c').title).toBe('Claude Code \u00B7 qwen3.8-27b (custom endpoint)'); + app.sessions.get('s-a').displayModel = { model: 'qwen3.8-27b', source: 'config' }; + app._renderTileChrome(); + expect(logoOf('s-a').title).toBe('DeepSeek \u00B7 qwen3.8-27b (from config)'); + expect(modelNameOf('s-a').textContent).toBe('qwen3.8-27b'); expect(modelNameOf('s-b').textContent).toBe('haiku'); }); diff --git a/test/tile-grid-i18n.test.ts b/test/tile-grid-i18n.test.ts index 3718e7f0..edd024c0 100644 --- a/test/tile-grid-i18n.test.ts +++ b/test/tile-grid-i18n.test.ts @@ -153,6 +153,10 @@ async function exercise() { displayModel: { model: 'qwen3.8-27b', source: 'custom-endpoint' }, }); app.sessions.get('s-6').displayModel = { model: 'Haiku 4.5', source: 'statusline' }; + Object.assign(app.sessions.get('s-4'), { + mode: 'deepseek', + displayModel: { model: 'qwen3.8-27b', source: 'config' }, + }); let pill = 'idle'; app._sidebarRichRow = () => ({ state: pill, pill, since: { at: 1 } }); app._mobileOverviewStampText = () => '3m'; @@ -324,6 +328,7 @@ describe('every tile grid string the code puts on screen translates to zh-CN', ( 'DeepSeek \u00B7 qwen3.8-27b', 'Claude Code \u00B7 haiku (set at launch)', 'Codex \u00B7 qwen3.8-27b (custom endpoint)', + 'DeepSeek \u00B7 qwen3.8-27b (from config)', 'Claude Code \u00B7 Haiku 4.5', 'Claude Code', ])