deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
INSTALL REFERENCE
dsh plugin --profile web add github:tkdfs/dsh-ptc-auto-preset
该命令指向仓库当前默认分支;尚无绑定当前 commit 的完整验证结果。
PROJECT README
A resident DSH agent preset: in PTC (Code Mode) sessions, it automatically assigns the model and reasoning effort for every request according to the current work phase.
中文文档: README.zh-CN.md
| Phase | Trigger | Model | Reasoning effort |
|---|---|---|---|
| Plan/architecture | Plan mode on, or the message contains 设计/架构/规划/方案/计划/接口/重构 (or English design/architecture/plan/refactor, etc.) |
deepseek-v4-pro |
max |
| Implement/fix tests | Default (no keyword hit) | deepseek-v4-pro |
high |
| Mechanical edits | Message contains 文案/机械性/补全/整理/重命名/格式化/迁移/注释/标注 (or English rename/formatting, etc.) |
deepseek-v4-flash |
high |
All keywords and gears are configurable in the ptc-assign row's config inside
agent.cordis.yml — no code changes needed.
Copy this whole directory to:
${DSH_HOME:-$HOME/.dsh}/.agent-presets/ptc-auto/
(The preset id = the directory name ptc-auto; renaming the directory = changing the id.)
After copying, start a new session and pick 「PTC 模式(自动分配)」 in the preset picker
(recommended: "set as default"). Verify with /ptc status.
You can also let an AI deploy it — paste this to your AI assistant:
Clone https://github.com/tkdfs/dsh-ptc-auto-preset into
${DSH_HOME:-$HOME/.dsh}/.agent-presets/ptc-auto/, keeping the directory nameptc-auto.
The clone target is all it takes; the directory name becomes the preset id. Then start a new session and pick the preset in the picker.
/ptc status: show the current gear, the classification basis and diagnostics
(claims/preSteps/requestSteps/trace/lastError)./ptc auto|plan|implement|mechanical|off: manually pin a gear or turn auto-assign off.ptc_assign: invoked by the model when the user asks in natural language
to adjust the gear./ptc auto resumes.installModelSelection), which registers before the preset mounts and wraps the outermost
agent/request waterfall — any waterfall rewrite registered later gets overridden by it.agent/inbox/claimed (when a message is claimed, before the system prompt is
assembled), it writes the target config into the session's persisted request/header
event — which is exactly the source the session selection layer reads. After writing, the
request immediately executes with the assigned config, keeping the UI picker, session log,
and restart recovery consistent automatically.agent/pre-step is kept as a backup write point (after assembly; on Web it usually no-ops
due to skip-same, but it still works on runtimes without a session selection layer).ptc-assign.vN.js, and update that
row's name: in agent.cordis.yml. Why: the resident agent only detects a new generation
by the mtime of agent.cordis.yml, and Node ESM caches plugin modules by URL — editing
a file in place leaves the new generation loading old code (cost us several rounds of
debugging).config in agent.cordis.yml; after touching the yml, start
a new session and the new generation applies.agentPresets.standingKeyFor('ptc-auto') mount check (mounted OK), then a
real-session round (or a controlled mock agent).| Symptom | Root cause | Fix |
|---|---|---|
| Auto-assign never took effect; every request used the session default gear | The session selection layer overrode the waterfall rewrite | Rewrite the persisted request/header |
| New generation didn't load new plugin code | ESM caches by URL + generation detection only looks at agent.cordis.yml | Versioned filenames + touch the yml |
| pre-step header write was one step too late | System prompt assembly happens before pre-step | Move the main write point to inbox/claimed |
| Misclassification ("好的" judged as plan gear) | Injected messages (skill catalog, runtime snapshot, etc.) were treated as the last user message | Only accept human messages with source.kind === 'user' |
Verification result (reconciled against real session logs): the synthesized header
(sys:false) is written before the loop's own request header; all three test segments hit —
implement→pro+high, mechanical→flash+high, plan→pro+max.
Symptom: when the first message (or the first after each gear shift) is sent, the model picker in the UI still shows the session's old gear, making it look like "auto-assign didn't take effect" — yet the reply's actual reasoning depth / log records are the new gear.
Verdict: purely a display issue, not an execution issue. Reconciled message-by-message
against session logs: the synthesized request header is written before the loop's own request
header, and requests actually execute with the assigned gear (evidence: the first plan-mode
reply is already a full max-gear deep-thinking stream; request/header's
provider/model/reasoningEffort are all correct).
Root cause: the UI model picker is pull-based; it re-fetches the session model from the server only when:
This plugin is an external writer (it directly mutates the session's persisted
request/header), and the product has no "request header changed → push a picker refresh"
channel, so the picker stays at the last pulled state.
Impact & workaround:
/ptc status.Alternative fix (not adopted): build a resident client-side sync plugin (subscribe to
session events → re-pull sessions.models) so the picker refreshes in real time on every
message. Not adopted because: it requires building a client plugin package, bundling it,
integrating into the deployment and maintaining it across upgrades — cost is disproportionate
to the benefit; the behavior itself is correct, and the display just lags one "open the menu"
gesture.
preset.yml — preset display metadata (name/description)agent.cordis.yml — composition file: full PTC mode (code preset) capabilities + the
ptc-assign rowplugins/ptc-assign.v4.js — plugin implementation: claimed/pre-step writes, the /ptc
command, the ptc_assign tool, diagnostic stateCLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。