mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-28 06:51:16 +08:00
fix(models): consolidate provider and model into /model command
This commit is contained in:
41
ui-tui/package-lock.json
generated
41
ui-tui/package-lock.json
generated
@@ -124,6 +124,7 @@
|
|||||||
"integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
|
"integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "^7.29.0",
|
"@babel/code-frame": "^7.29.0",
|
||||||
"@babel/generator": "^7.29.0",
|
"@babel/generator": "^7.29.0",
|
||||||
@@ -501,31 +502,6 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@emnapi/core": {
|
|
||||||
"version": "1.10.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
|
|
||||||
"integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@emnapi/wasi-threads": "1.2.1",
|
|
||||||
"tslib": "^2.4.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@emnapi/runtime": {
|
|
||||||
"version": "1.10.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
|
|
||||||
"integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"tslib": "^2.4.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@emnapi/wasi-threads": {
|
"node_modules/@emnapi/wasi-threads": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
|
||||||
@@ -1700,6 +1676,7 @@
|
|||||||
"integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==",
|
"integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~7.19.0"
|
"undici-types": "~7.19.0"
|
||||||
}
|
}
|
||||||
@@ -1710,6 +1687,7 @@
|
|||||||
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
|
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"csstype": "^3.2.2"
|
"csstype": "^3.2.2"
|
||||||
}
|
}
|
||||||
@@ -1720,6 +1698,7 @@
|
|||||||
"integrity": "sha512-eSkwoemjo76bdXl2MYqtxg51HNwUSkWfODUOQ3PaTLZGh9uIWWFZIjyjaJnex7wXDu+TRx+ATsnSxdN9YWfRTQ==",
|
"integrity": "sha512-eSkwoemjo76bdXl2MYqtxg51HNwUSkWfODUOQ3PaTLZGh9uIWWFZIjyjaJnex7wXDu+TRx+ATsnSxdN9YWfRTQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/regexpp": "^4.12.2",
|
"@eslint-community/regexpp": "^4.12.2",
|
||||||
"@typescript-eslint/scope-manager": "8.58.1",
|
"@typescript-eslint/scope-manager": "8.58.1",
|
||||||
@@ -1749,6 +1728,7 @@
|
|||||||
"integrity": "sha512-gGkiNMPqerb2cJSVcruigx9eHBlLG14fSdPdqMoOcBfh+vvn4iCq2C8MzUB89PrxOXk0y3GZ1yIWb9aOzL93bw==",
|
"integrity": "sha512-gGkiNMPqerb2cJSVcruigx9eHBlLG14fSdPdqMoOcBfh+vvn4iCq2C8MzUB89PrxOXk0y3GZ1yIWb9aOzL93bw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "8.58.1",
|
"@typescript-eslint/scope-manager": "8.58.1",
|
||||||
"@typescript-eslint/types": "8.58.1",
|
"@typescript-eslint/types": "8.58.1",
|
||||||
@@ -2066,6 +2046,7 @@
|
|||||||
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
|
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
@@ -2468,6 +2449,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"baseline-browser-mapping": "^2.10.12",
|
"baseline-browser-mapping": "^2.10.12",
|
||||||
"caniuse-lite": "^1.0.30001782",
|
"caniuse-lite": "^1.0.30001782",
|
||||||
@@ -3203,6 +3185,7 @@
|
|||||||
"integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==",
|
"integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.8.0",
|
"@eslint-community/eslint-utils": "^4.8.0",
|
||||||
"@eslint-community/regexpp": "^4.12.1",
|
"@eslint-community/regexpp": "^4.12.1",
|
||||||
@@ -3334,6 +3317,7 @@
|
|||||||
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/colinhacks"
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
}
|
}
|
||||||
@@ -4242,6 +4226,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ink-text-input/-/ink-text-input-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ink-text-input/-/ink-text-input-6.0.0.tgz",
|
||||||
"integrity": "sha512-Fw64n7Yha5deb1rHY137zHTAbSTNelUKuB5Kkk2HACXEtwIHBCf9OH2tP/LQ9fRYTl1F0dZgbW0zPnZk6FA9Lw==",
|
"integrity": "sha512-Fw64n7Yha5deb1rHY137zHTAbSTNelUKuB5Kkk2HACXEtwIHBCf9OH2tP/LQ9fRYTl1F0dZgbW0zPnZk6FA9Lw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": "^5.3.0",
|
"chalk": "^5.3.0",
|
||||||
"type-fest": "^4.18.2"
|
"type-fest": "^4.18.2"
|
||||||
@@ -5678,6 +5663,7 @@
|
|||||||
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
@@ -5787,6 +5773,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz",
|
||||||
"integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==",
|
"integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@@ -6611,6 +6598,7 @@
|
|||||||
"integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==",
|
"integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "~0.27.0",
|
"esbuild": "~0.27.0",
|
||||||
"get-tsconfig": "^4.7.5"
|
"get-tsconfig": "^4.7.5"
|
||||||
@@ -6737,6 +6725,7 @@
|
|||||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
@@ -6846,6 +6835,7 @@
|
|||||||
"integrity": "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==",
|
"integrity": "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lightningcss": "^1.32.0",
|
"lightningcss": "^1.32.0",
|
||||||
"picomatch": "^4.0.4",
|
"picomatch": "^4.0.4",
|
||||||
@@ -7261,6 +7251,7 @@
|
|||||||
"integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
|
"integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/colinhacks"
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,28 @@ describe('createSlashHandler', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('honors TUI picker session scope without adding --global', async () => {
|
||||||
|
patchUiState({ sid: 'sid-abc' })
|
||||||
|
|
||||||
|
const ctx = buildCtx({
|
||||||
|
gateway: {
|
||||||
|
...buildGateway(),
|
||||||
|
rpc: vi.fn(() => Promise.resolve({ value: 'anthropic/claude-sonnet-4.6' }))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(
|
||||||
|
createSlashHandler(ctx)(
|
||||||
|
'/model anthropic/claude-sonnet-4.6 --provider openrouter --tui-session'
|
||||||
|
)
|
||||||
|
).toBe(true)
|
||||||
|
expect(ctx.gateway.rpc).toHaveBeenCalledWith('config.set', {
|
||||||
|
key: 'model',
|
||||||
|
session_id: 'sid-abc',
|
||||||
|
value: 'anthropic/claude-sonnet-4.6 --provider openrouter'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it('does not duplicate --global for explicit persistent model switches', () => {
|
it('does not duplicate --global for explicit persistent model switches', () => {
|
||||||
patchUiState({ sid: 'sid-abc' })
|
patchUiState({ sid: 'sid-abc' })
|
||||||
const ctx = buildCtx()
|
const ctx = buildCtx()
|
||||||
|
|||||||
@@ -17,12 +17,29 @@ import type { SlashCommand } from '../types.js'
|
|||||||
|
|
||||||
const GLOBAL_MODEL_FLAG_RE = /(?:^|\s)--global(?:\s|$)/
|
const GLOBAL_MODEL_FLAG_RE = /(?:^|\s)--global(?:\s|$)/
|
||||||
|
|
||||||
|
/** Stripped before `config.set`; TUI model picker uses this for session-scoped switches. */
|
||||||
|
const TUI_SESSION_MODEL_RE = /(?:^|\s)--tui-session(?:\s|$)/
|
||||||
|
|
||||||
const persistedModelArg = (arg: string) => {
|
const persistedModelArg = (arg: string) => {
|
||||||
const trimmed = arg.trim()
|
const trimmed = arg.trim()
|
||||||
|
|
||||||
return !trimmed || GLOBAL_MODEL_FLAG_RE.test(trimmed) ? trimmed : `${trimmed} --global`
|
return !trimmed || GLOBAL_MODEL_FLAG_RE.test(trimmed) ? trimmed : `${trimmed} --global`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const modelValueForConfigSet = (arg: string) => {
|
||||||
|
const trimmed = arg.trim()
|
||||||
|
|
||||||
|
if (!trimmed) {
|
||||||
|
return trimmed
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TUI_SESSION_MODEL_RE.test(trimmed)) {
|
||||||
|
return trimmed.replace(/\s*--tui-session\b\s*/g, ' ').replace(/\s+/g, ' ').trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
return persistedModelArg(trimmed)
|
||||||
|
}
|
||||||
|
|
||||||
export const sessionCommands: SlashCommand[] = [
|
export const sessionCommands: SlashCommand[] = [
|
||||||
{
|
{
|
||||||
aliases: ['bg', 'btw'],
|
aliases: ['bg', 'btw'],
|
||||||
@@ -60,7 +77,7 @@ export const sessionCommands: SlashCommand[] = [
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx.gateway
|
ctx.gateway
|
||||||
.rpc<ConfigSetResponse>('config.set', { key: 'model', session_id: ctx.sid, value: persistedModelArg(arg) })
|
.rpc<ConfigSetResponse>('config.set', { key: 'model', session_id: ctx.sid, value: modelValueForConfigSet(arg) })
|
||||||
.then(
|
.then(
|
||||||
ctx.guarded<ConfigSetResponse>(r => {
|
ctx.guarded<ConfigSetResponse>(r => {
|
||||||
if (!r.value) {
|
if (!r.value) {
|
||||||
|
|||||||
@@ -662,7 +662,7 @@ export function useMainApp(gw: GatewayClient) {
|
|||||||
|
|
||||||
const onModelSelect = useCallback((value: string) => {
|
const onModelSelect = useCallback((value: string) => {
|
||||||
patchOverlayState({ modelPicker: false })
|
patchOverlayState({ modelPicker: false })
|
||||||
slashRef.current(`/model ${value} --global`)
|
slashRef.current(`/model ${value}`)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const hasReasoning = useTurnSelector(state => Boolean(state.reasoning.trim()))
|
const hasReasoning = useTurnSelector(state => Boolean(state.reasoning.trim()))
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ export function ModelPicker({ gw, onCancel, onSelect, sessionId, t }: ModelPicke
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
setModelIdx(0)
|
setModelIdx(0)
|
||||||
|
setStage('provider')
|
||||||
setErr('')
|
setErr('')
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
})
|
})
|
||||||
@@ -110,7 +111,9 @@ export function ModelPicker({ gw, onCancel, onSelect, sessionId, t }: ModelPicke
|
|||||||
const model = models[modelIdx]
|
const model = models[modelIdx]
|
||||||
|
|
||||||
if (provider && model) {
|
if (provider && model) {
|
||||||
onSelect(`${model} --provider ${provider.slug}${persistGlobal ? ' --global' : ''}`)
|
onSelect(
|
||||||
|
`${model} --provider ${provider.slug}${persistGlobal ? ' --global' : ' --tui-session'}`
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
setStage('provider')
|
setStage('provider')
|
||||||
}
|
}
|
||||||
@@ -136,7 +139,9 @@ export function ModelPicker({ gw, onCancel, onSelect, sessionId, t }: ModelPicke
|
|||||||
setProviderIdx(next)
|
setProviderIdx(next)
|
||||||
}
|
}
|
||||||
} else if (provider && models[offset + n - 1]) {
|
} else if (provider && models[offset + n - 1]) {
|
||||||
onSelect(`${models[offset + n - 1]} --provider ${provider.slug}${persistGlobal ? ' --global' : ''}`)
|
onSelect(
|
||||||
|
`${models[offset + n - 1]} --provider ${provider.slug}${persistGlobal ? ' --global' : ' --tui-session'}`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -173,11 +178,15 @@ export function ModelPicker({ gw, onCancel, onSelect, sessionId, t }: ModelPicke
|
|||||||
return (
|
return (
|
||||||
<Box flexDirection="column" width={width}>
|
<Box flexDirection="column" width={width}>
|
||||||
<Text bold color={t.color.amber} wrap="truncate-end">
|
<Text bold color={t.color.amber} wrap="truncate-end">
|
||||||
Select Provider
|
Select provider (step 1/2)
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<Text color={t.color.dim} wrap="truncate-end">
|
<Text color={t.color.dim} wrap="truncate-end">
|
||||||
Current model: {currentModel || '(unknown)'}
|
Full model IDs on the next step · Enter to continue
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text color={t.color.dim} wrap="truncate-end">
|
||||||
|
Current: {currentModel || '(unknown)'}
|
||||||
</Text>
|
</Text>
|
||||||
<Text color={t.color.label} wrap="truncate-end">
|
<Text color={t.color.label} wrap="truncate-end">
|
||||||
{provider?.warning ? `warning: ${provider.warning}` : ' '}
|
{provider?.warning ? `warning: ${provider.warning}` : ' '}
|
||||||
@@ -225,11 +234,11 @@ export function ModelPicker({ gw, onCancel, onSelect, sessionId, t }: ModelPicke
|
|||||||
return (
|
return (
|
||||||
<Box flexDirection="column" width={width}>
|
<Box flexDirection="column" width={width}>
|
||||||
<Text bold color={t.color.amber} wrap="truncate-end">
|
<Text bold color={t.color.amber} wrap="truncate-end">
|
||||||
Select Model
|
Select model (step 2/2)
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<Text color={t.color.dim} wrap="truncate-end">
|
<Text color={t.color.dim} wrap="truncate-end">
|
||||||
{names[providerIdx] || '(unknown provider)'}
|
{names[providerIdx] || '(unknown provider)'} · Esc back
|
||||||
</Text>
|
</Text>
|
||||||
<Text color={t.color.label} wrap="truncate-end">
|
<Text color={t.color.label} wrap="truncate-end">
|
||||||
{provider?.warning ? `warning: ${provider.warning}` : ' '}
|
{provider?.warning ? `warning: ${provider.warning}` : ' '}
|
||||||
@@ -254,6 +263,8 @@ export function ModelPicker({ gw, onCancel, onSelect, sessionId, t }: ModelPicke
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const prefix = modelIdx === idx ? '▸ ' : row === currentModel ? '* ' : ' '
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Text
|
<Text
|
||||||
bold={modelIdx === idx}
|
bold={modelIdx === idx}
|
||||||
@@ -262,7 +273,7 @@ export function ModelPicker({ gw, onCancel, onSelect, sessionId, t }: ModelPicke
|
|||||||
key={`${provider?.slug ?? 'prov'}:${idx}:${row}`}
|
key={`${provider?.slug ?? 'prov'}:${idx}:${row}`}
|
||||||
wrap="truncate-end"
|
wrap="truncate-end"
|
||||||
>
|
>
|
||||||
{modelIdx === idx ? '▸ ' : ' '}
|
{prefix}
|
||||||
{i + 1}. {row}
|
{i + 1}. {row}
|
||||||
</Text>
|
</Text>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -42,6 +42,14 @@ export function useCompletion(input: string, blocked: boolean, gw: GatewayClient
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `/model` / `/provider` use the two-step ModelPicker (real curated IDs).
|
||||||
|
// Slash completion here only showed short aliases + vendor/family meta.
|
||||||
|
if (isSlash && /^\/(?:model|provider)(?:\s|$)/.test(input)) {
|
||||||
|
clear()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const pathReplace = input.length - (pathWord?.length ?? 0)
|
const pathReplace = input.length - (pathWord?.length ?? 0)
|
||||||
|
|
||||||
const t = setTimeout(() => {
|
const t = setTimeout(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user