mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-08-29 04:26:38 +00:00
Merge pull request #3079 from deepseek-harness/worktree/3077-model-selector-names-only
fix(web): hide model selector descriptions
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/client/ui-model-selection/README.md
|
||||
README.md: 929d23ad4af1fe41e1cc7398ef432e73ca2a7a94
|
||||
README.zh.md: 23e786d9e490b0739498a3e83703b42ebc345cbd
|
||||
README.md: 1cefc8b0b0a569f6bc20a0fedab692710b39df43
|
||||
README.zh.md: 272110006f58a5db70a439e78629a1675d349abf
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
Model selection plugin, browser half: TWO entries over ONE per-session directory owned by `ModelDirectoryResolver` (`ctx.modelDirectories`). For ordinary sessions, the `/model` popupSelect contribution (registered through `ctx.commandUi`) and the composer's named `conversation.input.model` seat both load the session's advisory directory through `session.models` and submit through `session.selectModel` via the same `ModelDirectory` instance. The compact composer trigger opens a two-level Model/Effort menu: models stay provider-grouped, while the selected exact model supplies its adapter-owned effort names, descriptions, and default. `/model` applies the selected model's default effort, and the composer can then choose any advertised effort.
|
||||
Model selection plugin, browser half: TWO entries over ONE per-session directory owned by `ModelDirectoryResolver` (`ctx.modelDirectories`). For ordinary sessions, the `/model` popupSelect contribution (registered through `ctx.commandUi`) and the composer's named `conversation.input.model` seat both load the session's advisory directory through `session.models` and submit through `session.selectModel` via the same `ModelDirectory` instance. The compact composer trigger opens a two-level Model/Effort menu: models stay provider-grouped, while the selected exact model supplies its adapter-owned effort names and default. The menu renders model and effort names only; catalog descriptions remain available to other consumers. `/model` applies the selected model's default effort, and the composer can then choose any advertised effort.
|
||||
|
||||
The Host-reported provider/model/reasoning `ModelSelection` is the single selection fact, but it is echoed only when the exact provider/model pair remains in the advertised groups; an absent catalog row leaves the routable selection intact while the trigger prompts `Select model`, no stale row is synthesized, and no Effort row is shown until the user picks an advertised model. Directory loads and selections share a generation counter so an older response never overwrites a newer one; a connection reset drops every resident projection and repulls the Host-restored selection before display. Provider-local metadata failures list inline while usable groups stay selectable, and selection failures retain the prior selection and directory.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
模型选择插件(浏览器侧):**两个入口共用一份会话级目录**,由 `ModelDirectoryResolver`(`ctx.modelDirectories`)持有。对于普通会话,`/model` popupSelect 贡献项(经 `ctx.commandUi` 注册)与 composer 的具名 `conversation.input.model` slot 都通过同一个 `ModelDirectory` 实例,经 `session.models` 加载会话的建议目录,并经 `session.selectModel` 提交。紧凑型 composer 触发器会打开两级 Model/Effort 菜单:模型仍按提供方分组,所选具体模型则提供由其适配器持有的推理强度名称、说明和默认值。`/model` 应用所选模型的默认推理强度,composer 随后可以选择任一已公布的推理强度。
|
||||
模型选择插件(浏览器侧):**两个入口共用一份会话级目录**,由 `ModelDirectoryResolver`(`ctx.modelDirectories`)持有。对于普通会话,`/model` popupSelect 贡献项(经 `ctx.commandUi` 注册)与 composer 的具名 `conversation.input.model` slot 都通过同一个 `ModelDirectory` 实例,经 `session.models` 加载会话的建议目录,并经 `session.selectModel` 提交。紧凑型 composer 触发器会打开两级 Model/Effort 菜单:模型仍按提供方分组,所选具体模型则提供由其适配器持有的推理强度名称和默认值。菜单只呈现模型与推理强度名称;目录中的说明仍可供其他消费方使用。`/model` 应用所选模型的默认推理强度,composer 随后可以选择任一已公布的推理强度。
|
||||
|
||||
Host 报告的 `ModelSelection` 是唯一的选择事实,其中包含提供方、模型与推理(reasoning)强度;但只有当该提供方/模型对仍在已公布分组中时才会回显。目录行缺席时,可路由的选择保持不变,但触发器会提示 `Select model`;系统不会合成陈旧行,且在用户选择已公布的模型之前不会显示 Effort 行。目录加载与选择共享一个代次计数器,旧响应不会覆盖新结果;连接重置会丢弃所有常驻目录投影,并在显示前重新拉取 Host 恢复的选择。各提供方的元数据获取失败会内联列出,同时可用分组仍可选择;选择失败会保留先前的选择和目录。
|
||||
|
||||
|
||||
@@ -207,15 +207,6 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.description {
|
||||
overflow: hidden;
|
||||
color: var(--dsw-alias-label-tertiary);
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.check {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
|
||||
@@ -33,7 +33,6 @@ interface EffortChoice {
|
||||
key: string
|
||||
effort: string | undefined
|
||||
label: string
|
||||
description?: string
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,7 +96,6 @@ export function ModelSelect(
|
||||
key: `effort:${effort.id}`,
|
||||
effort: effort.id,
|
||||
label: effort.name,
|
||||
...effort.description === undefined ? {} : { description: effort.description },
|
||||
})),
|
||||
], [reasoning, t])
|
||||
const busy = state.status === 'selecting'
|
||||
@@ -303,9 +301,6 @@ export function ModelSelect(
|
||||
>
|
||||
<span className={css.optionCopy}>
|
||||
<span className={css.modelName}>{model.name}</span>
|
||||
{model.description !== undefined && (
|
||||
<span className={css.description}>{model.description}</span>
|
||||
)}
|
||||
</span>
|
||||
<span className={css.check}>
|
||||
{selected ? <IconCheckOutline16 /> : null}
|
||||
@@ -346,9 +341,6 @@ export function ModelSelect(
|
||||
>
|
||||
<span className={css.optionCopy}>
|
||||
<span className={css.modelName}>{level.label}</span>
|
||||
{level.description !== undefined && (
|
||||
<span className={css.description}>{level.description}</span>
|
||||
)}
|
||||
</span>
|
||||
<span className={css.check}>
|
||||
{effectiveEffort === level.effort ? <IconCheckOutline16 /> : null}
|
||||
|
||||
@@ -36,7 +36,12 @@ function state(overrides: Partial<ModelDirectoryState> = {}): ModelDirectoryStat
|
||||
groups: [{
|
||||
id: 'deepseek-official',
|
||||
name: 'DeepSeek',
|
||||
models: [{ id: 'deepseek-v4-flash', name: 'DeepSeek-V4-Flash', reasoning }],
|
||||
models: [{
|
||||
id: 'deepseek-v4-flash',
|
||||
name: 'DeepSeek-V4-Flash',
|
||||
description: 'Fast catalog description',
|
||||
reasoning,
|
||||
}],
|
||||
}],
|
||||
failures: [],
|
||||
status: 'ready',
|
||||
@@ -48,7 +53,7 @@ function state(overrides: Partial<ModelDirectoryState> = {}): ModelDirectoryStat
|
||||
afterEach(cleanup)
|
||||
|
||||
describe('ModelSelect reasoning effort', () => {
|
||||
it('renders adapter metadata and submits the effort as part of the session selection', async () => {
|
||||
it('renders effort names without descriptions and submits the effort as part of the session selection', async () => {
|
||||
const directory = createSnapshotStore<ModelDirectoryState>(state())
|
||||
const select = vi.fn(async (selection: ModelSelection) => {
|
||||
directory.set(state({ current: selection }))
|
||||
@@ -69,7 +74,8 @@ describe('ModelSelect reasoning effort', () => {
|
||||
fireEvent.click(trigger)
|
||||
fireEvent.click(screen.getByRole('menuitem', { name: /推理等级/ }))
|
||||
expect(screen.getAllByRole('menuitemradio').map(item => item.textContent))
|
||||
.toEqual(['Off', 'High', 'MaxLargest budget'])
|
||||
.toEqual(['Off', 'High', 'Max'])
|
||||
expect(screen.queryByText('Largest budget')).toBeNull()
|
||||
|
||||
fireEvent.click(screen.getByRole('menuitemradio', { name: /Max/ }))
|
||||
await waitFor(() => {
|
||||
@@ -133,6 +139,7 @@ describe('ModelSelect reasoning effort', () => {
|
||||
fireEvent.click(screen.getByRole('menuitem', { name: /模型/ }))
|
||||
expect(screen.queryByRole('menuitemradio', { name: 'removed-model' })).toBeNull()
|
||||
expect(screen.getByRole('menuitemradio', { name: 'DeepSeek-V4-Flash' })).toBeTruthy()
|
||||
expect(screen.queryByText('Fast catalog description')).toBeNull()
|
||||
})
|
||||
|
||||
it('shows loading until the catalog and Session projection are both ready', async () => {
|
||||
|
||||
Reference in New Issue
Block a user