dsh-web-search-ddg
aooyoo
Zero-token DuckDuckGo search provider for the DeepSeek Harness (DSH) web seam — local headless browser, no API key, no m…
PROJECT TOPICS
PROJECT README
Use DeepSeek Harness from Agent Client Protocol clients such as Zed and Backchat.
The adapter composes the harness in-process and maps its session-event log
onto the full ACP vocabulary: streamed text and reasoning, tool calls with
diffs and display terminals, plans, permission requests, session modes,
config options, slash commands, skills, and MCP servers. Credentials never
touch your editor config — it reuses the key you saved in the dsh Web UI, or
dsh-acp login saves one to the same store.
| A · Standalone server | B · dsh profile plugin | |
|---|---|---|
| Best for | Getting started in one command | Living inside your dsh setup |
| Install | npm i -g @openma/deepseek-harness-acp |
dsh plugin --profile acp add -w @openma/deepseek-harness-acp |
| Zed runs | dsh-acp |
dsh --profile acp |
| Harness | Your installed dsh — or the vendored fallback when none exists | The dsh that owns the profile |
| Composition | dsh-base + this bundle (profile machinery booted in-process) | dsh-base + this bundle + your profile's own patches |
Both shapes share $DSH_HOME: the same credential store, settings, presets,
and session logs as dsh web — conversations started in the Web UI can be
listed and loaded from the editor.
npm install -g @openma/deepseek-harness-acp
dsh-acp login # interactive; or save the key in the dsh Web UI
// Zed settings.json
{
"agent_servers": {
"DeepSeek Harness": { "command": "dsh-acp" }
}
}
Self-contained: it finds your DeepSeek Harness via --dsh-path / DSH_PATH,
its own tree, ./node_modules, dsh on PATH, or npm root -g — and ships a
vendored harness runtime as the last candidate, so it works out of the box
and always prefers the dsh you installed. When a real
$DSH_HOME/profiles/acp exists, that profile owns the composition.
npm install -g @deepseek-ai/dsh
dsh web # save your API key once
dsh plugin --profile acp add -w @openma/deepseek-harness-acp
// Zed settings.json
{
"agent_servers": {
"DeepSeek Harness": { "command": "dsh", "args": ["--profile", "acp"] }
}
}
This creates $DSH_HOME/profiles/acp and registers the package's
dsh.bundle patch: the bridge mounts over @deepseek-ai/dsh-base — the same
product baseline as dsh web, with the module-reload watcher off. Extend the
profile in $DSH_HOME/profiles/acp/cordis.patch.yml like any other dsh
profile.
No keys in editor config, no secrets pasted into chat. ACP clients follow
the protocol: initialize advertises three Agent Auth methods.
api-key, or api-key:<provider> when more than one
route is live. The client may pass _meta["api-key"].apiKey.browser. The adapter opens a localhost sign-in page;
the secret never travels over ACP. Hidden when NO_BROWSER is set.gateway, only when the client opts in with
clientCapabilities.auth._meta.gateway === true. The client sends
_meta.gateway { baseUrl, headers, providerName? }.The adapter writes credentials to the harness store. Missing credentials
fail session/new and session/prompt with auth_required (-32000).
Logout is the ACP logout method.
$DSH_HOME/.credentials.yaml (mode 600),
the file the dsh Web UI writes; hot-reloaded. Save a key with
dsh-acp login [--provider <route>], or the Web UI (Settings → Models).DEEPSEEK_API_KEY / DEEPSEEK_BASE_URL (and
the matching ANTHROPIC_API_KEY / OPENAI_API_KEY for those routes) in
the environment that launches the agent.The credential gate is the current provider route. An Anthropic-only store is enough for an Anthropic session; a DeepSeek key does not unlock another provider.
promptCapabilities.image is advertised when the composition mounts ctx.attachments (dsh-base does). ACP image blocks are validated, stored with saveImage, and kept in wire order with surrounding text. resource_link stays a textual file pointer.read-only / workspace-write / danger-full-access, each a named {sandbox, approval} pair recorded as a durable session fact (also exposed as a config option for clients that only render those).agentPresets, an uncategorized config option id: "agent" lists the roster (standard / code / minimal / cordis, plus user copies). Switching rebuilds the agent live with history preserved. Authoring (copy/rm) stays on the Web settings page; there is no /preset slash./status, /model) plus the harness command registry (/compact, /goal, /permission, /plan, …) executed without a model turn, plus skills (/skill-name — the harness's own invocation gesture). Login and logout are ACP methods, not chat commands.todo_write snapshots as ACP plans; token accounting as usage_update and per-turn usage.session/load with full history replay, session/list, silent restore when a client prompts an old session after an agent restart, titles as session_info_update.mcpServers mount @deepseek-ai/dsh-mcp-client instances (stdio + streamable HTTP); tools join as mcp__<server>__<tool>; a failing server never takes the session down.session/cancel interrupts the live turn through the harness agent.Flags win over environment variables, which win over defaults. All optional —
with no flags, sessions follow your product defaults (settings.yaml).
| Flag | Env | Default | Purpose |
|---|---|---|---|
--dsh-path |
DSH_PATH |
auto-detect | DeepSeek Harness installation |
--provider |
DSH_PROVIDER |
product default | Provider route override |
--model |
DSH_MODEL |
product default | Model override |
--max-tokens |
DSH_MAX_TOKENS |
provider default | Per-request output-token cap |
--permission-mode |
DSH_PERMISSION_MODE |
workspace-write |
Initial permission preset |
--reasoning-effort |
DSH_REASONING_EFFORT |
product default | off / high / max |
| — | DEEPSEEK_API_KEY |
— | API credential (fallback to the credential store) |
| — | DEEPSEEK_BASE_URL |
DeepSeek endpoint | OpenAI-compatible endpoint override |
| — | DSH_ACP_DEBUG |
off | Verbose stderr diagnostics |
Subcommands: dsh-acp login [api-key] (interactive when omitted; input never
echoes), dsh-acp update (self-update via npm).
Sessions start in workspace-write: bash and file mutations are confined to
the session's cwd (plus shared temp roots), and a model retry requesting
wider access raises an ACP permission request. Always allow (this
session) flips the approval policy to never for that session.
danger-full-access disables both the sandbox and the prompts — use it only
in disposable checkouts or containers. Each level is one durable preset
(sandbox + approval together), the same three the Web UI offers.
ACP client (Zed, …)
│ ACP JSON-RPC over stdio
▼
dsh-acp
├─ src/profile-boot.ts boots the harness's own profile machinery
│ (dsh-base + this bundle + $DSH_HOME layers)
├─ src/harness.ts host discovery (DSH_PATH → cwd → PATH → npm -g → vendored)
└─ src/bridge/ the ACP bridge (a cordis plugin)
├─ index.ts sessions, prompts, cancel, modes, options,
│ commands, credentials, MCP mounts
├─ translate.ts session-event → ACP update projection (pure)
├─ history.ts stored-log replay for session/load (pure)
└─ prompt.ts ACP prompt blocks → harness content blocks (pure)
▼
your @deepseek-ai/dsh installation (agent spine, llm, persistence, sandbox,
tools, presets, skills, compaction, …)
The bridge consumes the harness session/event firehose — the same
append-only log persistence stores — so live streaming, history replay, and
session/list agree by construction. All harness modules, including cordis
itself, load from one host tree: plugin and service identity is never split
across copies.
npm install # dev deps include the harness packages (types + tests)
npm run typecheck # tsc --noEmit
npm test # vitest: unit + e2e smoke (boots the real composition; no model calls)
npm run build # esbuild → dist/
To also run the e2e suite against a standalone host install:
npm install --prefix /tmp/dsh-host @deepseek-ai/dsh
DSH_ACP_TEST_HOST=/tmp/dsh-host npm test
Keep the profile your editor uses on the published package, and point a second profile at this worktree via a pnpm symlink:
dsh plugin --profile acp add -w @openma/deepseek-harness-acp # stable
dsh plugin --profile acp-test add -w "link:$PWD" # dev (symlink)
The dev loop is npm run build + restart — dist/ and cordis.patch.yml
are read through the link. (pnpm treats file: as a copy install and caches
same-version tarballs; link: avoids both.)
{
"agent_servers": {
"DeepSeek Harness": { "command": "dsh", "args": ["--profile", "acp"] },
"DeepSeek Harness (dev)": { "command": "dsh", "args": ["--profile", "acp-test"] }
}
}
Apache-2.0.
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。