README
dsh-plugin-dbgraph
Database structure the agent already knows, so it answers with one tool call instead of five.
A DeepSeek Harness plugin that indexes a remote
database's catalog — every table, column, comment, key, index, and a bounded sample of enum
literals — into a local SQLite index under ~/.dsh/dbgraph. The model reads that index (and a digest
of it placed directly in the system prompt) instead of spending round-trips on SHOW TABLES and
DESCRIBE, then fetches the actual values with exactly one network call.
The problem it removes
Without an index, answering "what is 张三's password?" looks like this:
1. SHOW TABLES ← network round-trip
2. DESCRIBE sys_user ← network round-trip
3. SELECT ... WHERE status = 1 ← wrong: status is a varchar
4. SELECT ... WHERE status = 'paid' ← guess corrected
5. 2,000 rows into the transcript ← context burned
Four model round-trips, four network round-trips, two wrong guesses. The expensive part is not the database — it is the model's turns. Each one costs seconds; a 100 ms query does not.
With dbgraph:
1. dbgraph find {entity:'用户', fields:['密码'], where:{name:'张三'}}
← one row, and the answer says which table and column it used
Structure local, data online
| Where | Why | |
|---|---|---|
| Tables, columns, comments, keys, indexes, enum samples, row estimates | Local index | Zero network, usable offline, no credential needed to ask what a column means |
| Actual row values | Always the server | A cached password is not a fast password, it is a wrong one |
Nothing derived from business data is persisted. The one data-shaped field is enum_values_json, a
SELECT DISTINCT … LIMIT n sample that teaches the model whether status holds 'paid' or 1.
Layout
packages/
bundle cordis.patch.yml — mounts everything as one profile layer
service ctx.dbgraph: the vocabulary, the dialect registry, the index protocol
catalog one DatabaseDialect per engine (SQLite, MySQL; PostgreSQL/MongoDB/Redis to follow)
store ~/.dsh/dbgraph: connections.json, the index writer, the reader, the resolver
tool the two model tools, /dbgraph, and the prompt digest
crates/
dbgraph-indexer the index write path in Rust (normalize + terms + SQLite)
Why the write path is Rust
node:sqlite is a synchronous API. Writing ten thousand columns through it blocks the event loop for
as long as the write takes — this is the same wall dsh-plugin-codegraph and
dsh-plugin-sessiongraph hit, and both moved their kernels behind napi AsyncTask to get past it.
crates/dbgraph-indexer does the same: normalization, term generation, and the SQLite write run on
libuv's thread pool, so a rebuild never stalls the host.
Measured on one machine, same catalog, same fixed clock — 500 tables / 10,000 columns:
| writer | write | index file | longest event-loop block |
|---|---|---|---|
| JavaScript | 1992 ms | 8.46 MiB | 1992 ms (the whole write) |
Rust (AsyncTask) |
218 ms | 8.41 MiB | 33.6 ms |
9.1× faster, and the blocking cost drops 59× — which is the number that matters, because a two-second stall is two seconds of the host doing nothing else.
The two writers are checked against each other rather than trusted: given the same catalog and the
same fixed now, objects, columns, edges, terms, and search (rowids included) must match
row for row, and only meta.writer may differ. Fixture expectations are generated by running the
JavaScript writer, never hand-written, so a change on either side that is not mirrored fails the
build.
The JavaScript writer is therefore not an optimization fallback — it is the parity reference and the degradation path (no Rust toolchain, no addon, a throwing call, an unparsable answer all fall back to it, once and quietly).
Two things that had to be measured, not assumed
node:sqlitecontentless FTS5 stores nothing you can read back. Every column —UNINDEXEDones included — returnsNULL; onlyrowidandranksurvive. The index therefore uses a contentful table, whereobject_id UNINDEXEDreads back verbatim. (The FTS5 column grammar is alsocolumn-name [UNINDEXED]: a type name in front is a parse error.)unicode61treats a run of Chinese as one token. Store广告点击verbatim andMATCH '广告'finds nothing. Sotextholds a pre-tokenized stream — camel/digit boundaries for ASCII, bigrams for CJK — and queries go through the same tokenizer, joined withOR(a space means phrase, not any of these).
Picking a writer
dbgraph_index takes writer: 'auto' | 'js' | 'rust':
js— the JavaScript writer, always. Never touches the addon.rust— the native writer only; a missing artifact or a throwing call fails the run rather than quietly producing a slower index.auto(default) — native when available; a missing artifact, a rejected call, or an unreadable report logs once per process and falls back to JavaScript.
DSH_DBGRAPH_RUST_ADDON points at an artifact explicitly: a test hook for the fallback path, and an
escape hatch for a deployment that keeps the addon outside crates/. Resolution order is: that
environment variable, then the platform package (dsh-plugin-dbgraph-indexer-<platform>, an
optionalDependency that npm installs on the matching OS), then
crates/dbgraph-indexer/artifacts/dbgraph-indexer.<platform>-<arch>.node for a working copy.
A platform package without its .node inside falls through to the next candidate rather than failing:
a checkout that was never built and a published package always behave the same way to the caller.
scripts/build-native.mjs builds the current platform into both places, and the five platform
packages are workspace members until they are published.
更多「開發者工具」外掛
dsh-our-free-model
作者 ebony-vinyl
在 dsh 里装上这个插件即可,无需登录、注册或填 API Key,就能使用包括 DeepSeek V4.1 Flash、Kimi K3 在内的前沿模型——完全免费,不限量。 All you do is install this plugin in dsh: no login, no sign-up, no API key — the frontier models are just there, DeepSeek V4.1 Flash and Kimi K3 among them. Completely free, with no usage cap.
dsh-routing-suite
作者 yjh051108
DeepSeek Harness(dsh)路由套件:先装运行时注入器,再加载任务感知的推理模式路由预设(已实测 P1-P23)。
dsh-ops
作者 t-auto
A toolkit for low-level operations in DSH, designed to reduce token usage and task execution time / DSH 底层操作工具插件,旨在减少 Token 消耗与任务耗时
brooks-lint
作者 hyhmrright
基于 12 本经典工程书籍的 AI 代码评审工具,提供腐化风险诊断、书籍引用、严重度标签及 6 种分析模式。
