DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

tkdfs /

dsh-ptc-auto-preset

Topic repository only

DSH preset: auto-assigns model + reasoning effort per work phase in PTC sessions — plan→pro+max, implement→pro+high, mechanical→flash+high.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@2e705e0b

PTC Auto-Assign (ptc-auto preset)

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

Rules (from PROJECT.md §7 recommended config)

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.

Install

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 name ptc-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.

Usage

  • Auto-effective: every message shifts gears by phase before it is sent; the first message already applies.
  • /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.
  • Model-side tool ptc_assign: invoked by the model when the user asks in natural language to adjust the gear.
  • Manual model-selection protection: after manually picking a model in the UI, the plugin detects the deviation and auto-pauses (pins); /ptc auto resumes.
  • Known display lag: see "Known issue: UI picker display lag" below.

Implementation mechanism (must read for maintainers)

  1. In Web sessions, the model is decided by the "session selection layer" (api-proxy's installModelSelection), which registers before the preset mounts and wraps the outermost agent/request waterfall — any waterfall rewrite registered later gets overridden by it.
  2. Therefore this plugin does not compete on the waterfall; instead, at 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.
  3. 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).

Maintenance conventions (pitfalls we hit; must follow)

  1. When changing plugin code you must rename the file: 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).
  2. For rule gears, only edit the config in agent.cordis.yml; after touching the yml, start a new session and the new generation applies.
  3. Verify: agentPresets.standingKeyFor('ptc-auto') mount check (mounted OK), then a real-session round (or a controlled mock agent).

Debug history (2026-08-14)

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.

Known issue: UI picker display lag

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:

  1. opening the picker menu;
  2. manually selecting a model;
  3. reconnecting after a disconnect;
  4. the adapter catalog (llm/adapters-updated) or the settings document (settings/document-updated) changes.

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:

  • Impact: display layer only; it does not affect actual model/reasoning-effort execution, nor session logs/restart recovery.
  • Workaround: to check the real gear — open the picker menu once (triggers a re-pull) or just /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.

File list

  • preset.yml — preset display metadata (name/description)
  • agent.cordis.yml — composition file: full PTC mode (code preset) capabilities + the ptc-assign row
  • plugins/ptc-assign.v4.js — plugin implementation: claimed/pre-step writes, the /ptc command, the ptc_assign tool, diagnostic state
—/ 5

No ratings yet

Manifest verification required

Commit 2e705e0beaef

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout