feat(panel): add Host model picker under the composer - #91
zzalancelot wants to merge 4 commits into
Conversation
Map session.models to session/modelCatalog so connected Hosts expose their routable models, and replace chip tags with an upward menu on a dedicated row beneath the input.
| await api.call({ | ||
| rpcId: crypto.randomUUID(), | ||
| method: 'session.selectModel', | ||
| payload: { sessionId, ...selection }, | ||
| signal: call.signal, | ||
| }) | ||
| } catch { | ||
| // The prompt still proceeds; the Host keeps its deployment default. | ||
| } | ||
| } |
There was a problem hiding this comment.
Deferred selection failures are ignored
For a provisional session, the picker reports the model as selected before the Host applies it. When the first prompt materializes the session, this code ignores both a non-OK session.selectModel result and thrown errors, then sends the prompt anyway. If the Host rejects the model because its route is no longer available, the prompt silently runs with the deployment default even though the composer shows the requested model as active. Propagate the selection failure instead of sending the prompt with a different model.
| case 'session.models': | ||
| // Host Typert exposes session/modelCatalog (no args). Adapt ModelCatalog | ||
| // into the panel's { current, routable, groups } directory shape. | ||
| return { | ||
| namespace: 'session', | ||
| method: 'modelCatalog', | ||
| args: {}, | ||
| adapt: adaptModelCatalog, | ||
| } |
There was a problem hiding this comment.
Host default replaces session selection
session.models accepts a session ID, but this adapter discards it and maps the argument-less host-wide catalog's default model to the session-specific current field. When an existing session has selected another model, resuming or refreshing it therefore marks the deployment default as selected and misleads the user about which model the next prompt will use. The current model needs to come from session state, such as the model-selection projection, rather than modelCatalog.default.
83287c0 to
295a061
Compare
Pending settle timeouts survived useRealTimers() and later hit document after jsdom was torn down, which made the full vitest run fail CI with an unhandled ReferenceError.
295a061 to
146b6bc
Compare
Summary
session.modelsto Host Typertsession/modelCatalogand adapts the catalog into the panel directory shape, including provisional (deferred) sessions.deepseek-official) without requiring a relay profile first.Test plan
dsh web, reload the extension from~/.dsh/browser-extensionpnpm --filter @yuxianglin/dsh-bridge-browser test -- session-deferral.spec.ts remote-host-api.spec.tspnpm --filter dsh-browser-extension exec vitest run tests/panel-styles.spec.tsThe PR does not yet appear safe to merge because two unresolved model-selection defects can misrepresent or ignore the model that will execute the next prompt.
Findings
Summary
Adds a Host model picker beneath the composer and bridges Host model catalogs into the panel’s session-model directory shape.
Diagram
sequenceDiagram participant Panel participant Deferral as Session Deferral participant Adapter as Remote Host Adapter participant Host Panel->>Deferral: session.models(sessionId) alt provisional session Deferral->>Adapter: session.models Adapter->>Host: session/modelCatalog Host-->>Adapter: host-wide catalog/default Adapter-->>Deferral: adapted directory Deferral-->>Panel: catalog plus pending selection else materialized session Deferral->>Adapter: session.models(sessionId) Adapter->>Host: session/modelCatalog Host-->>Panel: adapted host-wide directory end Panel->>Deferral: session.selectModel(selection) alt provisional session Deferral-->>Panel: selection recorded Panel->>Deferral: first session.prompt Deferral->>Host: session.create Deferral->>Host: session.selectModel Deferral->>Host: session.prompt else materialized session Deferral->>Host: session.selectModel endReviews (3) · Last reviewed commit: "fix(content): clear selection watcher ti..."