TT-Wang/dsh-assembler

dsh-assembler

仓库尚未提供可用的公开描述。

Uncategorized

dsh-assembler — Vibe Assembly for DSH

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.


At a glance

Catalog103 parts / 311 tools — 71 library-backed, 27 service-backed, 5 first-party (index/catalog.yml)
Verificationevery 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 timea single agent typically lands in minutes, verification included

What it does

  • Just talk — describe the agent in any DSH session. The assistant reviews the architecture with you (gaps included — each one is your decision), finds parts by instant search, assembles, and hands over only what an independent probe has verified.
  • Assemble-then-verify — after emitting a preset, the assembler derives an acceptance probe, runs it in a real session bound to that preset, and judges the reply against content-bearing marks. A FAIL comes back with evidence — which turn, which missing acceptance mark, what the agent actually replied — so the fix is surgical (swap a part, tighten the persona, re-emit under the same name) rather than a blind retry; a PASS also drops a 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.
  • Multi-turn scenario probes — the deriver picks the probe shape itself: one turn for pure-compute agents, a 2–4 turn scenario when the requirement implies work that outlives a turn (bookkeeping, filing, tracking). Scenario turns run in one session, and a later turn queries what an earlier turn wrote. Judgement stays black-box: replies only, never the trajectory.
  • Multi-agent teams — ask for a suite ("one agent for support, one for reconciliation, one for inventory — all on the same product/order data") and the agents are assembled one by one against one shared database, then the handoff itself is proven: an independent probe has one agent write a record and a different agent read it back.
  • Gap work orders — when selection reports a capability the catalog cannot yet cover, the assembler writes an actionable work order to <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.
  • Assembly console (live) — every assembly dual-writes its action chain to <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.
  • Knowledge packs (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.
  • Credential contract (interface first, key later) — parts declare the environment variable they need and what it is for; the value never enters a preset. Unconfigured, a part still starts, 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.
  • Client-private catalogs — 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.
  • Service-backed parts — 13 live data services are wired in (weather, FX, geocoding, holidays, macro data, SEC filings, scholarly search, wiki facts, research graph, package intel, Feishu, Slack, GitHub Issues). A library part pins 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 BOM — every assembly emits 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.
  • Federation cache — each part's tool list is cached under (connection config + adapter file fingerprint): cold ~5s, warm 0.002s.
  • persona lint — mechanical checks on the persona text: every tool it names must be in the mounted surface, step-numbered choreography is rejected, length is bounded.
  • Constitution & design notes — docs/CONSTITUTION.md (vibe assembly governed as a programming language, nine articles each with a test) · DESIGN.md states what the assembler does, what it deliberately does not, and where the boundary sits.

Every assembly ships a web UI

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

Kanban (dark)

Approval desk

Data desk

Chat console

How it works:

  • Frontend template parts (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 shape
  • Look — built on Franken UI (the no-build HTML port of shadcn/ui, MIT), vendored locally — zero CDN dependency for offline/intranet delivery; auto light/dark
  • Page↔agent contract — pages embed a ```json fence contract in their prompts (no persona coupling); replies render as boards/tables/stat cards
  • Frontends are verified too — assemble-then-verify gains two frontend gates: page gate (HTTP 200 + slots filled) and loop gate (a real session opened with the page's exact parameters must echo a token); carried runs re-run the page gate only
  • One durable ledger — the equipment lane pins the default database (workspace data.db) and pre-builds its schema, so frontend sessions and DSH conversations write the same store
  • Pages the templates can't cover get written — the scaffold writer's seat: emit_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)

Architecture

┌───────── 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.


Quick start

1. Install

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.

2. Assemble one agent

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.

3. Deliver a whole team (the FDE path)

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.


Layout

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

The capability catalog

Four kinds of capability:

viaSourceExample
packagea tool from this repo / an own plugin packagecrm-query
harnessa DSH built-in toolcontent-search
mcpMCP server tools (federated at assembly time)mcp-weather-forecast-current-weather, 229 of them
knowledgeclient teaching material (copied into kb/)acme-policies-kb

103 parts / 311 tools — 71 library-backed, 27 service-backed, 5 first-party.

Service-backed parts — live data and external systems

PartToolsSourceLicence / termsCredentials
package-registrypackage-info package-versions check-licensenpm + PyPI registriesregistry ToSnone
weather-forecastcurrent-weather daily-forecastOpen-MeteoCC-BY-4.0none
currency-rateslatest-rates historical-rate convert-amountFrankfurter (ECB data)Public-Domain-ECBnone
geocodegeocode-address reverse-geocodeOpenStreetMap NominatimODbL-1.0none
public-holidayslist-holidays is-workday available-countriesNager.DateMITnone
worldbank-datacountry-indicator common-indicatorsWorld Bank Open DataCC-BY-4.0none
sec-filingslookup-cik company-filingsU.S. SEC EDGARPublic-Domain-US-Govnone
scholar-searchsearch-published search-preprints doi-lookupCrossref + arXivCC0-1.0 / arXiv termsnone
wiki-factspage-summary search-entity entity-factsWikimedia (Wikipedia + Wikidata)CC-BY-SA-4.0none
research-graphsearch-works work-citations author-worksOpenAlexCC0-1.0none
feishu-messagingsend-message list-chats feishu-capabilities飞书开放平台Feishu API ToSFEISHU_APP_ID FEISHU_APP_SECRET
slack-messagingpost-message list-channels slack-capabilitiesSlack APISlack API ToSSLACK_BOT_TOKEN
github-issueslist-issues get-issue create-issue github-capabilitiesGitHub REST APIGitHub ToSGITHUB_TOKEN (optional)

First-party parts — thin shells over Node built-ins, zero third-party deps

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)

Library-backed parts, by domain

DomainParts (tool count)
Documents & officepdf-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 formatscsv-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 processingmarkdown-render(3) · html-to-markdown(1) · readability-extract(2) · text-diff(3) · template-render(4) · fuzzy-search(4) · text-encoding(2)
Chinese languagepinyin-convert(2) · chinese-convert(2) · word-segment(2) · num-to-chinese(2)
Computationmath-eval(2) · currency-calc(4) · number-format(4) · semver-check(3) · geo-distance(3) · color-convert(2)
Time & calendarsdate-format(4) · cron-parse(2) · calendar-parse(3) · calendar-generate(4) · rrule-expand(2)
Databasessqlite-query(3) · mysql-query(4) · postgres-query(4)
Network & messaginghttp-request(4) · email-send(4) · email-fetch(4) · rss-parse(4)
Media & recognitionimage-process(4) · ocr-parse(3) · qrcode-generate(4) · barcode-generate(2) · exif-read(1) · file-type-detect(1)
Security & validationjwt-decode(2) · ip-utils(2) · string-validate(2) · fake-data(2) · phone-parse(2)
Engineering toolsgithub-api(4) · browser-automate(4) · url-slugify(3) · transliterate(2) · safe-filename(2)