README.md
August 25, 2026 · View on GitHub
dsh-advisor
Turn advisor for DSH — evaluates each turn (default: on error) via LLM and renders a full-width light-blue advice card in the chat.

A host+client bundle plugin for DeepSeek Harness. The host half listens to session/event for turn/end, calls ctx.llm.stream() with a configurable prompt, and appends advisor/eval (log-only). The browser half registers a ConversationNodeDefinition for advisor/eval and a keyed conversation.chat.node renderer (advisor) — a full-width card in harmonious blue (#e3eefc/#3b6ea5, no traffic-light colors) with verdict icon differentiation.
- Log-only evaluation. The verdict is appended as
advisor/eval— a log-only node with no surfaceOp, so the agent never sees it. - Errors by default.
evaluateOn: ['error'](default) means only failed turns cost an LLM call;['all']opts into every turn. - Harmonious, not alarming. One blue family (#e3eefc / #3b6ea5) with icon-only verdict differentiation — no red/yellow/green traffic lights.
- One-line install. Built
lib/is committed, sodsh plugin addworks without a build step.
Install
dsh plugin --profile web add github:haoliangwu/dsh-advisor
Built lib/ is committed, so the git install is one line — no prepare script, no allowBuilds permission. Restart dsh --profile web after install (bundle layer stacks compose at boot).
Configure
In your profile's cordis.patch.yml (~/.dsh/profiles/web/cordis.patch.yml):
- id: dsh-advisor
config:
# When to evaluate: ['error'] (default) or ['all']
evaluateOn: ['error']
# Optional explicit route; fallback is session's current model (request/header)
provider: deepseek-official
model: deepseek-chat
# Optional prompt template with {turn} and {transcript} placeholders
promptTemplate: |
Evaluate turn {turn}...
Transcript:
{transcript}
evaluateOn accepts any turn/end reason kind (completed, error, aborted, blocked, max-tokens, interrupted) or all. An empty list disables evaluation.
promptTemplate defaults to a hard-coded JSON template that requests {"verdict":"ok"|"needs-attention"|"off-track","issues":[],"advice":"..."}. JSON parse failures degrade to needs-attention with advice set to raw output.
Disable entirely:
- id: dsh-advisor
disabled: true
How it works
- Host:
ctx.on('session/event')filtersturn/endbyevaluateOn; builds a short transcript fromsession.deriveMessages()(last 10) and therequestHeader/requestContextroute (or explicitprovider/model); callsctx.llm.stream()and parses verdict/issues/advice; appendsadvisor/evallog-only (no surfaceOp, ignorable). - Client:
ConversationNodeDefinition(kind: advisor,target: chat) matchesadvisor/evalper turn and builds achatNode('advisor', …);AdvisorCardrenders a full-width light-blue card with blue-family icons (○ / ◐ / ◉) and locale-aware verdict labels (advisornamespace, zh/en). - Card styling: background
#e3eefc, border#c3dbf5, text#3b6ea5family; icon variants differentiate verdicts within the same hue (light fill → solid fill), never red/yellow/green.
Build from source
pnpm install
pnpm build # emits lib/index.js, lib/invariant.js, lib/client.js + sourcemaps
pnpm typecheck # tsc --noEmit
lib/ is committed so git installs work without a build step. After changing source, run pnpm build and commit the updated lib/.
License
MIT