dsh-yingnao
Yingnao (硬脑) plugin for DeepSeek Harness — let your agent govern a local disk: see what's still dark, search it, follow semantic neighbours, and dispatch reversible, cost-aware governance jobs.
- Stars
- 1
- Language
- TypeScript
- Created
- Sep 7, 2026
- Updated
- Sep 7, 2026
Introduction
dsh-yingnao
Bring Yingnao (硬脑) into DeepSeek Harness.
Yingnao indexes a local disk: your files never move, only the index goes into a database. With this plugin your DSH agent can see how much of that disk is still dark, search it, follow semantic neighbours to material you'd never think to search for, and dispatch governance jobs — instead of only reading dashboards.
Requires Yingnao running locally. https://github.com/qiuyiwu1989-star/yingnao No API key: it manages your own machine. The UI and returned content are in Chinese.
Install
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:qiuyiwu1989-star/dsh-yingnao
Build output ships in the repository, so no dependency build scripts need to be allowed. Restart the profile afterwards.
Start Yingnao's index service (the desktop client does this for you, or run python3 app.py).
The plugin talks to http://127.0.0.1:5050 by default.
Six tools
Yingnao's HTTP surface has a dozen-odd endpoints. This plugin registers 6 — a client's job is not to mirror the server, it is to present the right shape. Hand a model a long list of endpoint names and its default strategy becomes "call whichever returns the most", which blows up its own context before it can think about which tool it should have used.
| Tool | When to use it |
|---|---|
yingnao_overview | First step, before governing anything. How much of the disk is still dark, and how much of what's "processed" is actually usable |
yingnao_search | Find files. Degrades rather than fails — files with no extractable text still match on name and path, and say so |
yingnao_related | Take one file, find what's semantically near it. Measurably the most reliable capability here |
yingnao_inspect | One file's metadata, body text and quality verdict. Check this before quoting anything |
yingnao_govern | Dispatch a governance job, or check progress. This is the hand — and it has a boundary |
yingnao_call | Escape hatch, not the main road |
Why related beats search here
Measured on a real 76k-file archive:
file → file 0.819 two decks genuinely on one thread
query → file 0.639 a good hit
query → file 0.609 a clear miss (matched someone else's memoir)
File-to-file scores run high because both sides are whole documents; a one-sentence query carries far less signal. So the same 0.639 is a good result in search and a weak one in related — the plugin uses two separate vocabularies rather than one shared threshold, because sharing one would mislead both the model and the user.
The practical upshot for an agent: when gathering material, search for one anchor document,
then related outward. That surfaces the drafts and earlier versions you would never have
thought to query for.
The boundary on yingnao_govern
Two classes of governance action are not the agent's to decide:
- ones that cost money (OCR re-extraction, LLM labelling)
- ones that move the user's real files (inbox archiving)
Yingnao marks these needs_confirm. Dispatching one only queues it — it will not run until
the user confirms in the desktop client. The tool says so plainly rather than reporting success.
Everything else (quality checks, codepoint normalisation) runs immediately and is reversible: those jobs write a full backup manifest before touching anything.
If you don't want the agent able to dispatch anything at all, set allowGovern: false and
yingnao_govern degrades to read-only.
Configuration
- insert:
- id: yingnao
name: 'dsh-yingnao'
config:
endpoint: 'http://127.0.0.1:5050' # Yingnao's local index service
timeoutMs: 60000 # queries cross an SSH tunnel; can be slow
passthrough: true # false = don't register yingnao_call
allowGovern: true # false = yingnao_govern becomes read-only
YINGNAO_ENDPOINT overrides the endpoint if you'd rather not put it in config.
Errors are classified so the model can act on them
Not a stack trace — a sentence the model can change its behaviour on:
| Kind | What the model should do |
|---|---|
offline | Yingnao isn't running. Retrying won't help — tell the user to open it |
tunnel | Service is up but can't reach the database. May recover; retry once later |
notfound | Change the argument, don't retry as-is |
server | Retry once; if it keeps failing, tell the user |
Pairs with dsh-deepbrain
Install both and one agent holds two complementary layers: judgments with evidence chains from DeepBrain, and the raw material those judgments came from, sitting on your own disk.
"Write me a piece on creativity education" → pull what you've said on it across meetings from DeepBrain → pull the source decks and drafts from Yingnao → write from both.
License
MIT