dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
English | 中文
Assemble a working AI agent from one sentence — and be able to hand it over.
dsh-assembler is a DeepSeek Harness (DSH) plugin. You describe the agent you want in plain language ("build me a support bot that can look up orders, open tickets, and hand off to a human"); the assembler matches parts from a capability catalog, emits an agent preset, and then proves it works by running it in a real session. New sessions pick that preset from the roster and go.
The catalog grows through an induction pipeline: open-source libraries, public APIs, a client's own HTTP interfaces, and a client's documents all enter through one command each — and only past a quality gate. No glue code, only configuration.
How it works, from your seat: you describe the agent you want in one sentence. The assistant first shows you the architecture — capabilities, data model, workflow, and any gaps the catalog cannot cover (each gap is your call: build the missing part on the spot, degrade, or drop it) — and waits for your go-ahead. Parts are then found by instant catalog search, with every candidate priced (what its manual adds to the agent's prompt each turn, whether it spawns a process, which credentials it needs). The preset is emitted deterministically with every safety gate intact, and an independent examiner proves it works by running it in a real session before it reaches you — together with its web page, a supply-chain BOM, and a self-check pack it can re-run after any later change.
No graduation penalty: everything is a real, inspectable artifact — parts are ordinary processes with pinned provenance, a delivered agent is a git-diffable text composition plus its BOM, and the execution layer is framework-agnostic. Outgrow the assembler and you keep everything: the parts keep running, the presets keep mounting, nothing is held hostage.
| Catalog | 103 parts / 311 tools — 71 library-backed, 27 service-backed, 5 first-party (index/catalog.yml) |
| Verification | every assembly ends with an independent black-box probe in a real session; every web page passes a reachability gate and a live-session loop gate |
| Wall time | a single agent typically lands in minutes, verification included |
selfcheck.json beside the preset, so the agent can be re-examined with the same probe after any later change. find → assemble → **verify**, on by default. The probe fails fast and honestly: an agent that asks the (absent) user for help is scored FAIL with the question quoted back, and every probe turn narrates its tool actions live.<preset>/gaps/: the spec, the real induction-pipeline commands to build the missing part, and the exact re-assemble command that closes the loop. The writing of the missing part is handed to the calling agent (which has a full coding harness); the assembly spine stays deterministic, and the verdict always comes from the assembler's own black-box probe.<preset>/progress.log; a live console page (/assembler/ui/_console) polls it so a slow assembly is a visible, timestamped trail — "stuck or working?" answered at a glance — not a silent spinner. Selection, emission, probe rounds, per-turn tool actions and a 20s heartbeat all scroll there.via: knowledge) — a client's manuals, SOPs and product catalogues enter as static teaching material, past a retrieval-hit gate (a probe question whose expected snippet cannot be found is refused), and are copied into the preset's kb/ at assembly time. The handover is one self-contained directory.listTools still succeeds, and a call returns an actionable error (which variable, what for, where to get it). On the assembly side: assembly succeeds, the probe degrades to SKIPPED with configuration guidance. Optional credentials (GitHub public reads, polite-pool mailtos) take the anonymous path and do not hold verification back.catalogs/<client>/ carries its own generated/, index/, capabilities.yml and knowledge/. One client's parts cannot surface in another's assembly, because isolation is by separate files, not by a filter someone can forget.repo@rev; a service has no bytes to pin, so it pins terms + rate limit + data licence instead — and those travel into the BOM, because a client's compliance desk asks about them first.parts.lock.yml beside the preset: per part its origin, licence, verified status and the serverName actually mounted, plus knowledge sources with versions and the pending-credential list.Assembly does not stop at the preset — every agent also gets an operable web frontend, served same-origin by the assembler on the host (/assembler/ui/<preset>). The page speaks the host's public wire (session.create / session.prompt / events.mux) and shares the same agent and the same durable workspace as the DSH conversation view; it pulls current state on open.
Each screenshot below is the real product of a single assembly (real assembly, real data, real capture — verdict lines quoted verbatim):
任务管理助手 … 要一个可以拖拽的任务看板页面→ 自动验证:PASS · 前端验收:页面门+环路门 PASS
How it works:
via: frontend) — 7 templates: chat console (default for every preset), form desk, data desk, dashboard, drag-and-drop kanban, approval desk, file desk; the matcher picks exactly one by interaction shapedata.db) and pre-builds its schema, so frontend sessions and DSH conversations write the same storeemit_app lays down a locked-vocabulary frontend skeleton (Vite + React + shadcn/ui + a fixed comms SDK, with record-desk and kanban starter pages you can copy whole), the assistant writes any page shape inside the single free zone src/pages/ against a PAGE-SPEC (every action routed face/wire/ai-thin/local); verify_app examines black-box through five gates (build / skeleton-lock / pages-lint / asset reach / behavior: face actions really execute SQL with effect assertions, wire actions run real-session probes), and deploy_app publishes into the preset same-origin with a snapshot for one-call rollback. Measured: a custom kanban's face round-trip at 5.1ms; the page and the chat sessions still share one ledger (two-faced delivery), the handoff proven by an independent examiner (one face writes, the other reads back)┌───────── Induction pipeline (supply chain) ────────────────────────────┐
│ OSS library / public API / client OpenAPI / client documents │
│ → slice capabilities → MCP adapter → gate (smoke / retrieval) → catalog │
└───────────────────────────────────────────────────────────────────────┘
↓
┌───────── Assembly (capability consumption) ───────────────────────────┐
│ capabilities.yml (public or client) + parallel federation │
│ → instant parts search (priced candidates) → orchestrator decides │
│ → deterministic emission + BOM + knowledge copied into kb/ │
│ → independent verification: probe in a real session → PASS/FAIL │
└───────────────────────────────────────────────────────────────────────┘
↓
┌───────── Delivery (FDE) ──────────────────────────────────────────────┐
│ multi-agent suite: emit_preset per agent, pinned to one sharedDb │
│ → verify_shared_data handoff exam (one writes, another reads back) │
│ → every agent carries its own parts.lock.yml BOM record │
└───────────────────────────────────────────────────────────────────────┘
↓
┌───────── Runtime (the harness's territory) ───────────────────────────┐
│ session picks the preset → DSH mounts each row → agent calls the parts │
└───────────────────────────────────────────────────────────────────────┘
The assembler is a Cordis plugin and its output is a Cordis composition manifest (one preset row = one plugin instance); parts are external MCP server processes bridged by @deepseek-ai/dsh-mcp-client. The assembler exists only at assembly time — once a session is running its process is gone and nothing changes.
Add the plugin to a DSH profile's patch layer (e.g. ~/.dsh/profiles/web/cordis.patch.yml):
- insert:
- id: dsh-assembler
name: '@dsh-external/dsh-assembler'
Dependency: "@dsh-external/dsh-assembler": "link:/path/to/dsh-assembler".
Some service parts need the operator's contact details (SEC mandates a contactable User-Agent; Crossref/OpenAlex polite pools want a mailto). Copy .env.example to .env and fill in your own — not credentials, but not anyone else's address either.
Open the DSH web UI and just say it:
帮我装配一个记账 agent:随手记收支,按月汇总,能设预算超支提醒,有查账网页
You will be shown the architecture (and any catalog gaps, each yours to decide) before anything is built; after your go-ahead the agent assembles, an independent probe verifies it in a real session, and you get the preset id, the verdict with evidence, and a web page at /assembler/ui/<preset>. Artifacts land in ~/.dsh/.agent-presets/<preset>/ — parts.lock.yml (BOM), selfcheck.json, progress.log.
Just ask for a suite of agents in one session — "give me a set of ops agents: one for support, one for reconciliation, one for inventory, one for content, all sharing the same product/order data". The assistant splits the request into focused agents, assembles and verifies each (emit_preset pins every member to one shared sharedDb), and the handoff itself is examined independently (verify_shared_data: one agent writes a record, a different agent reads it back — the reader's instruction may not contain the answer, the copy gate). Each agent's parts.lock.yml is its delivery record: verdict, part provenance, pending credentials, knowledge versions — all grown from artifacts.
dsh-assembler/
├── src/
│ ├── index.ts # assembly core: catalog, federation, deterministic emission, BOM, equipment, knowledge
│ ├── orchestrated-tools.ts # the tool surface: parts search · deterministic emit · independent examiner
│ ├── verify.ts # assemble-then-verify: probe machinery (single/scenario) + real-session driver
│ ├── capability-index.ts # BM25 parts search backend
│ ├── persona-lint.ts # mechanical persona checks
│ ├── frontend.ts # frontend lane: template emission + same-origin route + live console
│ └── client/ # browser half: assembly console tab in the DSH sidebar
├── capabilities.yml # ★ public catalog: capability entries + mcp-servers + requiredSecrets
├── index/ # ★ public part index (origin/licence/terms) + smoke reports
├── generated/ # ★ part library: 80+ MCP adapter servers, one directory each
├── catalogs/<client>/ # ★ client-private catalog: its own generated/ index/ capabilities.yml knowledge/
├── bench/results/ # assembly-quality ledgers (run-tagged, committed)
├── presets/
│ └── agent-template.yml # preset template ({{persona}}/{{packageRows}}/{{extraRows}}/{{param:k}})
└── scripts/
├── index-add.mjs # ★ induction pipeline CLI
└── link-dsh.mjs # link DSH peer packages
Four kinds of capability:
via | Source | Example |
|---|---|---|
package | a tool from this repo / an own plugin package | crm-query |
harness | a DSH built-in tool | content-search |
mcp | MCP server tools (federated at assembly time) | mcp-weather-forecast-current-weather, 229 of them |
knowledge | client teaching material (copied into kb/) | acme-policies-kb |
103 parts / 311 tools — 71 library-backed, 27 service-backed, 5 first-party.
| Part | Tools | Source | Licence / terms | Credentials |
|---|---|---|---|---|
| package-registry | package-info package-versions check-license | npm + PyPI registries | registry ToS | none |
| weather-forecast | current-weather daily-forecast | Open-Meteo | CC-BY-4.0 | none |
| currency-rates | latest-rates historical-rate convert-amount | Frankfurter (ECB data) | Public-Domain-ECB | none |
| geocode | geocode-address reverse-geocode | OpenStreetMap Nominatim | ODbL-1.0 | none |
| public-holidays | list-holidays is-workday available-countries | Nager.Date | MIT | none |
| worldbank-data | country-indicator common-indicators | World Bank Open Data | CC-BY-4.0 | none |
| sec-filings | lookup-cik company-filings | U.S. SEC EDGAR | Public-Domain-US-Gov | none |
| scholar-search | search-published search-preprints doi-lookup | Crossref + arXiv | CC0-1.0 / arXiv terms | none |
| wiki-facts | page-summary search-entity entity-facts | Wikimedia (Wikipedia + Wikidata) | CC-BY-SA-4.0 | none |
| research-graph | search-works work-citations author-works | OpenAlex | CC0-1.0 | none |
| feishu-messaging | send-message list-chats feishu-capabilities | 飞书开放平台 | Feishu API ToS | FEISHU_APP_ID FEISHU_APP_SECRET |
| slack-messaging | post-message list-channels slack-capabilities | Slack API | Slack API ToS | SLACK_BOT_TOKEN |
| github-issues | list-issues get-issue create-issue github-capabilities | GitHub REST API | GitHub ToS | GITHUB_TOKEN (optional) |
binary-write(write-binary-file) · crypto-hash(hash-text, hmac-sign, generate-uuid) · compress-gzip(compress, decompress) · dns-lookup(resolve-domain, reverse-lookup) · book-intake(browser→workspace file channel + epub parsing) · webhook-intake(inbound event intake) · ai-call(standalone AI completion for apps) · static-deploy(publish a built site as an agent page) · app-scaffold(official create-vite scaffolding)
| Domain | Parts (tool count) |
|---|---|
| Documents & office | pdf-generate(4) · pdf-extract(3) · pdf-report(1) · docx-generate(3) · docx-extract(2) · pptx-generate(1) · excel-read-write(4) · zip-archive(4) |
| Data formats | csv-parse(3) · yaml-convert(2) · toml-parse(2) · xml-parse(3) · json-query(2) · json-schema-validate(2) · html-parse(4) · html-to-text(4) |
| Text processing | markdown-render(3) · html-to-markdown(1) · readability-extract(2) · text-diff(3) · template-render(4) · fuzzy-search(4) · text-encoding(2) |
| Chinese language | pinyin-convert(2) · chinese-convert(2) · word-segment(2) · num-to-chinese(2) |
| Computation | math-eval(2) · currency-calc(4) · number-format(4) · semver-check(3) · geo-distance(3) · color-convert(2) |
| Time & calendars | date-format(4) · cron-parse(2) · calendar-parse(3) · calendar-generate(4) · rrule-expand(2) |
| Databases | sqlite-query(3) · mysql-query(4) · postgres-query(4) |
| Network & messaging | http-request(4) · email-send(4) · email-fetch(4) · rss-parse(4) |
| Media & recognition | image-process(4) · ocr-parse(3) · qrcode-generate(4) · barcode-generate(2) · exif-read(1) · file-type-detect(1) |
| Security & validation | jwt-decode(2) · ip-utils(2) · string-validate(2) · fake-data(2) · phone-parse(2) |
| Engineering tools | github-api(4) · browser-automate(4) · url-slugify(3) · transliterate(2) · safe-filename(2) |