Skip to content
dsh.fish
Bundle

@lovstudio/dsh-search-model

Composer model seat takeover: sticky search + fuzzy matching over the shared model directory

Source
lovstudio
License
MIT
Updated
Updated 14 hours ago

Readme

# @lovstudio/dsh-search-model

Search-enabled composer model seat for the DeepSeek Harness web GUI.

The built-in composer model seat (`conversation.input.model`) only lists
provider-grouped models. This plugin takes over that single seat cell with a
ModelSelect that adds a **pinned search field** and **fuzzy matching** while
keeping the built-in package running underneath — the `/model` popup and the
shared per-session model directory still come from
`@deepseek-ai/dsh-client-ui-model-selection`.

What the takeover adds:

- **Sticky search** — the field is pinned above the scrolling option list, so
  typing filters while rows scroll and the field never leaves the viewport.
- **Fuzzy matching** — each whitespace-separated term matches as a plain
  substring, a separator-free spelling (`v4pro` finds `deepseek-v4-pro`), or
  an ordered subsequence **within one** provider/model name or id (`v4p` still
  finds `deepseek-v4-pro`); order is preserved, never permuted. Descriptions
  are intentionally not searchable (this surface never shows them), and a
  query with no hits shows a distinct "no matching models" message instead of
  the catalog-empty copy.
- **Keyboard + ARIA** — entering the pane focuses the search; ArrowUp/Down
  enter the visible rows at the correct edge; Escape is staged (clear query →
  back to the Model/Effort root → close). The model list owns its own
  `role="menu"` region so the textbox never sits inside a menu.

## How it takes over the seat

`conversation.input.model` is a `single` slot; occupants coexist at distinct
priorities and the lowest live entry renders. The built-in registers at the
default priority `0`; this plugin registers the same seat at priority `-100`,
so its ModelSelect renders while the built-in package keeps providing the
`modelDirectories` service and the `/model` command. No data logic is copied:
the seat's injected directory/load/select face is built over the shared
`ctx.modelDirectories` service, so the takeover shares one catalog and one
session projection with the `/model` popup.

Removing the plugin restores the built-in seat exactly.

## Install

Install the prebuilt GitHub package into the DSH web profile:

```sh
npx @deepseek-ai/dsh plugin --profile web add -w github:lovstudio/dsh-search-model
```

Then restart the web profile so the new client bundle is served:

```sh
npx @deepseek-ai/dsh web
```

For a pinned release, use `github:lovstudio/dsh-search-model#v0.2.1`.
The repository includes its built entry points, so installation does not run
a `prepare` script or require build approvals.

Version 0.2.1 fixes a missing `remote.session` service dependency that could
crash the composer model seat when opening an uncached session.

## Load gate

After installing, open the web GUI, click the composer model seat (e.g.
`DeepSeek-V4-Flash · High`), drill into the model list and confirm the search
field with the placeholder `Search by name or ID` appears above the groups.
Typing `v4p` should narrow to `DeepSeek-V4-Pro` rows while other models stay
hidden — that proves the takeover bundle, not the built-in seat, is rendering.

Install

dsh plugin --profile web add github:lovstudio/dsh-search-model

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source