DeepSeek Harness
@telemai/dsh-plugin adds telem_search and telem_fetch as native tools in
DeepSeek Harness, registered globally so
every agent preset sees them.
Prerequisites
Section titled “Prerequisites”- Node.js 22+
- pnpm on your
PATH—dsh plugininstalls into a profile through pnpm. - DSH installed —
dshon yourPATH, with the profile you use (weborheadless) initialized.
Install
Section titled “Install”-
Get an API key in the Telem console, under API keys in your project — see Authentication.
-
Install into your profile. DSH installs plugins per profile; repeat with
--profile headlessif you use that one too. -
Set your key. Export
TELEM_API_KEY, add it to$DSH_HOME/.credentials.yaml, or runnpm create @telemai— the plugin reads all three (see Credentials).
dsh plugin --profile web add @telemai/dsh-pluginexport TELEM_API_KEY=... # your key (or run `npm create @telemai`)Confirm: dsh --profile web --dump-config lists a telem row, and the model
now has telem_search and telem_fetch.
What you get
Section titled “What you get”Two tools:
telem_search— runs one or more searchqueriesas a single Telem interaction and returns every provider’s results, provider-attributed, in one normalized envelope.telem_fetch— reads up to 5 whole web pages in one call, fetched as one interaction and rendered one section per URL.
Both run through DSH’s own tool runtime: arguments are validated by DSH, cancellation and DSH’s tool timeout policy apply, and oversized results follow DSH’s spill policy. Each result carries the backend session id in the tool’s durable metadata (visible in DSH’s session log and UI), never in the model text.
The plugin tells the model to prefer telem_search over an overlapping
public-web search tool unless you ask otherwise, Telem is unavailable, or the
task needs a capability Telem does not expose. That is soft preference
only — the plugin does not disable DSH’s built-in web_search. To make Telem
the only search tool:
- headless / TUI profiles:
tool-webis a host row in DSH’s base bundle — add- id: tool-webwithdisabled: trueto your profile’scordis.patch.yml. - Web profile: the host row is already off there and each shipped,
read-only preset mounts
tool-webper session — copy the preset you use into$DSH_HOME/.agent-presets/without that row.
DSH’s built-in web_fetch is off by default.
Configuration
Section titled “Configuration”One file, every harness. Telem options live in .telem/telem.json — a
project one you can commit so the whole team inherits it, and a user one at
~/.telem/telem.json — the same pair the
opencode, pi,
Hermes and Claude Skill
surfaces read. On DSH the project is the calling agent’s session directory.
{ "tier": "extended", "providersInclude": ["exa", "brave"]}The three keys most people reach for:
| File key | Env fallback | Meaning |
|---|---|---|
tier |
TELEM_TIER |
Named result-field tier: minimalist, default, extended, or max |
fields |
TELEM_FIELDS (comma-separated) |
Explicit normalized fields; mutually exclusive with tier |
providersInclude |
TELEM_PROVIDERS_INCLUDE (comma-separated) |
Replace the deployment’s provider set |
Full parameter reference → — every key, its env fallback and how the levels compose.
DSH resolves per key and per call, with one level above the files that no other surface has — the plugin’s own row in your profile patch:
- this plugin’s row config in your profile patch;
<project>/.telem/telem.json;~/.telem/telem.json;TELEM_*environment variables.
Edit a file and the next search picks it up, no restart. Nothing configured means the server’s defaults; a malformed file or an ignored key is reported on stderr once per edit. Unlike opencode and pi, DSH has no deprecated host-specific config file — there was never one to keep reading.
Plugin-level config is the telem row in
~/.dsh/profiles/<profile>/cordis.patch.yml (or $DSH_HOME/cordis.patch.yml
for every profile). A patch replaces the row’s whole config, so restate
every key you keep:
- id: telem config: tier: max searchTimeoutMs: 60000 # enforced by DSH's timeout policy (default 60000) fetchTimeoutMs: 60000 apiKeyEnv: TELEM_API_KEY # a credential NAME, never a valueCredentials
Section titled “Credentials”TELEM_BASE_URL (or the plugin’s baseUrl) defaults to the hosted service at
https://router.telem.ai. Credentials have no config-file key and are resolved
on every call, in this order:
- DSH’s credential service, asked for
TELEM_API_KEY(or theapiKeyEnvyou configure) — process environment, then$DSH_HOME/.credentials.yaml, then.envfiles; TELEM_API_KEYin the environment;~/.telem/credentials.json, the filenpm create @telemaiwrites (it may also setbaseUrl).
A rotated key reaches the next call with no restart. The key is never written
to cordis.patch.yml, argv, logs, or tool output.
Subagents
Section titled “Subagents”In-process subagents (spawn/fork) inherit the tools, and every search they make
carries a frozen snapshot of the parent conversation as trajectory lineage.
Out-of-process backends (subagent-acp, subagent-claude-code,
subagent-codex, subagent-dsh-sdk) run without this plugin — no Telem tools
there and no lineage.
Troubleshooting
Section titled “Troubleshooting”401 Missing API key
Section titled “401 Missing API key”Nothing in the credential chain resolved a key. Export TELEM_API_KEY, add it
to $DSH_HOME/.credentials.yaml, or run npm create @telemai.
answered without the V2 normalized contract
Section titled “answered without the V2 normalized contract”The backend at TELEM_BASE_URL predates the normalized search response the
plugin reads. Upgrade the backend, or point TELEM_BASE_URL at a current
deployment — this is a deliberate hard stop rather than a silent empty result.
dsh plugin add exits 127
Section titled “dsh plugin add exits 127”pnpm is not on your PATH. DSH installs plugins into a profile through pnpm.
Tools missing inside a subagent
Section titled “Tools missing inside a subagent”The child composition’s toolFilter hides global tools, or the child runs out
of process — the out-of-process backends listed under
Subagents never load this plugin.