# dsh-tool-retriever

English | [中文](README.zh-CN.md)

`dsh-tool-retriever` is an early-alpha DeepSeek Harness plugin that registers a real `tool_search` tool. It reads the calling agent's live Tool Registry and ranks the visible tool schemas with normalized exact-name matching and field-aware BM25.

## Status and compatibility

This package is pre-release software. Version `0.0.1-alpha.0` targets these host contracts exactly:

- DeepSeek Harness tool packages: `0.1.0-rc.6`
- `@deepseek-ai/cordis`: `4.0.1`
- Node.js: `^22.19.0 || >=24.0.0`

This alpha is intentionally lexical. It supports same-language matching over names, descriptions, and input schemas. It does not use aliases, dictionaries, query translation, generated descriptions, embeddings, or LLM query rewriting. A Chinese query therefore finds a tool described in Chinese, but is not expected to find an English-only tool with unrelated tokens.

It also does not restrict the tools visible to the agent. All original tools remain available; `tool_search` only returns ranked candidates. Multilingual dense retrieval and dynamic Top-K activation are planned for `0.1.x`.

## Install

After the npm alpha is published, install it into a DSH profile:

```sh
dsh plugin --profile <profile> add dsh-tool-retriever@next
```

The package declares its bundle patch, so DSH adds it to the profile's ordered bundle list. The selected profile must already include the DSH `tools` service, as the standard headless and web profiles do.

For a packed prerelease artifact:

```sh
dsh plugin --profile <profile> add ./dsh-tool-retriever-0.0.1-alpha.0.tgz
```

Inspect the effective configuration before booting a long-lived app:

```sh
dsh --profile <profile> --dump-config
```

## Model-facing contract

The registered input stays deliberately small:

```ts
interface ToolSearchInput {
  query: string
}
```

`query` should describe the needed capability in the user's original language while retaining specific tool names, product names, identifiers, and operations.

The result is a stable JSON value:

```ts
interface ToolSearchOutput {
  query: string
  catalogSize: number
  results: Array<{
    name: string
    description: string
    rank: number
    score: number
    exact: boolean
    bm25: number
    matchedFields: Array<'name' | 'description' | 'parameterName' | 'parameterDescription'>
  }>
}
```

The registry is read at execution time. Tools registered or removed after plugin startup are reflected by the next search. `tool_search` itself is excluded from the searchable catalog.

An empty or whitespace-only query returns a materialized tool error. A query with no lexical match succeeds with an empty `results` array.

## Configuration

The bundle ships these defaults:

```yaml
topK: 8
bm25K1: 1.2
bm25B: 0.75
fieldWeights:
  name: 4
  description: 2
  parameterName: 1.5
  parameterDescription: 1
```

`topK` accepts integers from 1 through 32. Field weights may be zero. `bm25K1` accepts `0.01` through `10`, and `bm25B` accepts `0` through `1`.

DSH patch layers replace a row's complete `config` value rather than deep-merging nested values. When overriding the plugin row, restate every setting you need to retain.

## Lifecycle and data handling

The plugin holds no external process, model, cache, file, or network resource. Each call projects only the tool name, original description, and input parameter schema returned by `tools.schemas(agent)`. It registers one tool in the Cordis plugin fiber and returns the registry's exact disposer, so unloading the plugin removes `tool_search`.

## Development

```sh
pnpm install
pnpm run verify:self-contained
pnpm run typecheck
pnpm test
pnpm run build
pnpm run prepare
pnpm pack --dry-run --json
```

See [CONTRIBUTING.md](CONTRIBUTING.md), [SECURITY.md](SECURITY.md), and [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).

## License

[MIT](LICENSE)
