dsh-switchman 1.11.5 → 1.11.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cordis.patch.yml CHANGED
@@ -136,6 +136,9 @@
136
136
  name: '@deepseek-ai/dsh-tool-schedule'
137
137
  - id: skill-filesystem
138
138
  name: '@deepseek-ai/dsh-skill-filesystem'
139
+ config:
140
+ customSkillDirs:
141
+ - !!js process.getBuiltinModule('node:path').join(process.getBuiltinModule('node:path').dirname(process.getBuiltinModule('node:module').createRequire(baseUrl).resolve('@deepseek-ai/dsh-agent-preset/package.json')), 'skills')
139
142
  - id: tool-skill
140
143
  name: '@deepseek-ai/dsh-tool-skill'
141
144
  - id: command-goal
@@ -196,6 +199,8 @@
196
199
  config:
197
200
  - id: tool-subagent-control
198
201
  name: '@deepseek-ai/dsh-tool-subagent-control'
202
+ config:
203
+ interrupt: false
199
204
  - id: tool-subagent
200
205
  name: '@deepseek-ai/dsh-tool-subagent'
201
206
  config:
@@ -227,6 +232,8 @@
227
232
  searchTimeoutMs: 60000
228
233
  - id: present
229
234
  name: '@deepseek-ai/dsh-tool-present'
235
+ - id: tool-office
236
+ name: '@deepseek-ai/dsh-tool-office'
230
237
  - id: tool-plugin-manager
231
238
  name: '@deepseek-ai/dsh-plugin-manager/tools'
232
239
  disabled: !!js "!ctx.get('profileContext')"
@@ -335,6 +342,8 @@
335
342
  config:
336
343
  - id: tool-subagent-control
337
344
  name: '@deepseek-ai/dsh-tool-subagent-control'
345
+ config:
346
+ interrupt: false
338
347
  - id: tool-subagent
339
348
  name: '@deepseek-ai/dsh-tool-subagent'
340
349
  config:
@@ -370,6 +379,8 @@
370
379
  name: '@deepseek-ai/dsh-tool-executor-ptc'
371
380
  - id: present
372
381
  name: '@deepseek-ai/dsh-tool-present'
382
+ - id: tool-office
383
+ name: '@deepseek-ai/dsh-tool-office'
373
384
  - id: tool-plugin-manager
374
385
  name: '@deepseek-ai/dsh-plugin-manager/tools'
375
386
  disabled: true
@@ -488,7 +499,7 @@
488
499
  name: '@deepseek-ai/dsh-persona'
489
500
  config:
490
501
  prefix: >-
491
- You are a coding agent powered by the {{model}} model.
502
+ You are a coding agent powered by the {{model}} model. You help the user customize DeepSeek Harness itself.
492
503
  suffix: *switchman-team-suffix
493
504
  - id: agent-instructions
494
505
  name: '@deepseek-ai/dsh-agent-instructions'
@@ -572,6 +583,8 @@
572
583
  config:
573
584
  - id: tool-subagent-control
574
585
  name: '@deepseek-ai/dsh-tool-subagent-control'
586
+ config:
587
+ interrupt: false
575
588
  - id: tool-subagent
576
589
  name: '@deepseek-ai/dsh-tool-subagent'
577
590
  config:
@@ -637,9 +650,9 @@
637
650
  langScope: project
638
651
  dispatchEnforce: advice
639
652
  wmSoftTokens: 80000
640
- wmHardTokens: 95000
641
- wmForceTokens: 150000
642
- wmReadBudgetTokens: 3000
653
+ wmHardTokens: 100000
654
+ wmForceTokens: 200000
655
+ wmReadBudgetTokens: 3500
643
656
  wmDenyMode: cap
644
657
  wmAutoHandover: true
645
658
  wmSubagentCap: true
@@ -648,15 +661,18 @@
648
661
  teamsMode: true
649
662
  syncWhitelist: true
650
663
  trimEnabled: true
651
- trimMode: auto
664
+ trimMode: advisory
652
665
  trimGrowthTokens: 22500
653
- trimIncrementTokens: 25000
654
- trimPressurePercent: 65
655
- trimEmergencyPercent: 95
666
+ trimIncrementTokens: 45000
667
+ trimPressurePercent: 45
668
+ trimEmergencyPercent: 90
669
+ trimAdvisoryPercent: 50
670
+ trimAdvisoryCriticalPercent: 80
656
671
  trimWindowTokens: 0
657
- trimProtectedTail: 10
672
+ trimProtectedTail: 6
658
673
  trimMaxFoldsPerHour: 30
659
674
  trimLadderEnabled: true
675
+ trimProtectTaskIntent: true
660
676
  trimLadderT2Tokens: 8000
661
677
  trimLadderT2MinBlocks: 3
662
678
  trimLadderT3Tokens: 6000
package/host/config.js CHANGED
@@ -84,15 +84,16 @@ export const Config = z.object({
84
84
  * the plugin UI into that locale (extra locales resolve
85
85
  * client-side from the inline EXTRA_UI_DICTS table, falling back
86
86
  * to English). */
87
- uiLocale: z.union(["auto", "en", "zh", "zh-TW", "ja", "ko", "de", "es", "fr", "it", "pt", "ru"]).default("auto").volatile(),
87
+ uiLocale: z.union(["auto", "en", "zh", "zh-TW", "ja", "ko", "de", "es", "fr", "it", "pt", "ru"]).default("zh").volatile(),
88
88
 
89
89
  // --- Phase 1: project language preference -----------------------------
90
90
  /** Where the three language slots live: "global" = these profile-level
91
91
  * fields below; "project" = each project's .switchman/lang.json (per
92
92
  * session cwd; missing file = ask once per session and save there). */
93
- langScope: z.union(["global", "project"]).default("global").volatile(),
94
- /** Language for conversational replies. Empty = ask once, then remember. */
95
- langConversation: z.string().default("").volatile(),
93
+ langScope: z.union(["global", "project"]).default("project").volatile(),
94
+ /** Language for conversational replies (shipped default zh-CN). Empty =
95
+ * ask once, then remember. */
96
+ langConversation: z.string().default("zh-CN").volatile(),
96
97
  /** Language for code comments. Empty = follow langConversation. */
97
98
  langComments: z.string().default("").volatile(),
98
99
  /** Language for documents the agent authors. Empty = follow langConversation. */
@@ -131,23 +132,22 @@ export const Config = z.object({
131
132
 
132
133
  // --- Phase 3: context watermark control --------------------------------
133
134
  /** Soft watermark: advisory banner + delegation nudge (tokens). */
134
- wmSoftTokens: z.number().min(1000).default(80000).volatile(),
135
- /** Hard watermark: read budget tightens, wrap-up advised (tokens). 95k
136
- * sits just under the trim pressure line (65% of the 150k window ≈
137
- * 97.5k): past
138
- * this point the fold engine is already folding, so per-call read
139
- * budgets must tighten at the SAME boundary — agent sessions grow in
140
- * PULSES (one large file read = tens of thousands of tokens injected
141
- * at once, faster than any fold can commit), and the read budget is
142
- * the only preventive valve on the pulse source. */
143
- wmHardTokens: z.number().min(2000).default(95000).volatile(),
135
+ wmSoftTokens: z.number().min(1000).max(10000000).default(80000).volatile(),
136
+ /** Hard watermark: read budget tightens, wrap-up advised (tokens). 100k
137
+ * sits just above the trim pressure line (45% of the 200k effective
138
+ * cap = 90k): by the time the hard tier tightens, the fold engine is
139
+ * already folding — the read budget stays the preventive valve on the
140
+ * pulse source: agent sessions grow in PULSES (one large file read =
141
+ * tens of thousands of tokens injected at once, faster than any fold
142
+ * can commit). */
143
+ wmHardTokens: z.number().min(2000).max(10000000).default(100000).volatile(),
144
144
  /** Force watermark: handover document + compaction (tokens). */
145
- wmForceTokens: z.number().min(3000).default(150000).volatile(),
145
+ wmForceTokens: z.number().min(3000).max(10000000).default(200000).volatile(),
146
146
  /** Per-TURN read budget (inspection C16 — the name predates the turn
147
147
  * accounting): read/glob/grep/bash results accumulate against it within
148
148
  * one turn; the account resets after 15 idle minutes and the pre/post
149
149
  * gates act at 2.4× this value (CEILING_MULTIPLE in context-watch.js). */
150
- wmReadBudgetTokens: z.number().min(200).default(3000).volatile(),
150
+ wmReadBudgetTokens: z.number().min(200).max(10000000).default(3500).volatile(),
151
151
  /** Hard-tier behavior: cap reads and advise, or deny outright. */
152
152
  wmDenyMode: z.union(["cap", "deny"]).default("cap").volatile(),
153
153
  /** Force tier triggers the handover (document + compaction) automatically. */
@@ -155,7 +155,7 @@ export const Config = z.object({
155
155
  /** Cap subagent contexts at wmSubagentForceTokens. */
156
156
  wmSubagentCap: z.boolean().default(true).volatile(),
157
157
  /** Subagent hard cap; 0 = share wmForceTokens. */
158
- wmSubagentForceTokens: z.number().min(0).default(0).volatile(),
158
+ wmSubagentForceTokens: z.number().min(0).max(10000000).default(0).volatile(),
159
159
  /** Scale subagent watermark tiers to the subagent's own model window:
160
160
  * force = min(static force [or wmSubagentForceTokens], window × ratio);
161
161
  * soft/hard shrink by the same factor to preserve tier spacing. The ratio
@@ -173,15 +173,19 @@ export const Config = z.object({
173
173
  * doctrine, no whitelist detection (the DSH factory conservative team
174
174
  * policy takes over); the bundle is never disabled and the whitelist is
175
175
  * never cleared. */
176
- teamsMode: z.boolean().default(false).volatile(),
177
- /** Replace-sync the six-pool union into DSH's subagent model-selection
178
- * whitelist (`subagent-model-selection-settings`) whenever the teams
176
+ teamsMode: z.boolean().default(true).volatile(),
177
+ /** Replace-sync the dispatch model union (the six pools plus modelRank)
178
+ * into DSH's subagent model-selection whitelist
179
+ * (`subagent-model-selection-settings`) whenever the teams
179
180
  * orchestration runs — an INDEPENDENT switch: it does not require
180
181
  * teamsMode, and teamsMode alone does not sync. switchman is the single
181
182
  * source of truth: the deduplicated union overwrites allowedModels
182
- * wholesale. The whitelist only applies to top-level sessions composed
183
+ * wholesale. modelRank belongs in the union because its head is the
184
+ * dispatch fallback route and enforce mode denies anything outside
185
+ * "pools or modelRank" — leaving it out would strand that route.
186
+ * The whitelist only applies to top-level sessions composed
183
187
  * afterwards. */
184
- syncWhitelist: z.boolean().default(false).volatile(),
188
+ syncWhitelist: z.boolean().default(true).volatile(),
185
189
 
186
190
  // --- Intent recognition: classifier-routed "auto" model ----------------
187
191
  /** Master switch for intent routing (design: .dsh-switchman/plans/
@@ -238,7 +242,7 @@ export const Config = z.object({
238
242
  * ceil(wmForceTokens / 0.8) so the smooth handover always fires before
239
243
  * the 0.8×-window auto-compaction (see effectiveContextWindow in
240
244
  * host/intent.js). */
241
- intentContextWindow: z.number().min(1024).default(200000).volatile(),
245
+ intentContextWindow: z.number().min(1024).default(250000).volatile(),
242
246
  /** Optional fallback route after classification fails when no prior route
243
247
  * is available; empty = the first candidate. An optional effort pin
244
248
  * overrides the fallback model's default. */
@@ -254,19 +258,48 @@ export const Config = z.object({
254
258
  * "advisory" = expose ctx_trim_fold/ctx_trim_status + the protocol head
255
259
  * so the session model can fold itself, "auto" = everything plus
256
260
  * idle-boundary automatic folds (growth gate / pressure / emergency). */
257
- trimMode: z.union(["off", "advisory", "auto"]).default("auto").volatile(),
261
+ trimMode: z.union(["off", "advisory", "auto"]).default("advisory").volatile(),
258
262
  /** Growth gate (tier a): fold when the outbound-view estimate grew this
259
263
  * much since the last fold. */
260
264
  trimGrowthTokens: z.number().min(1000).default(22500).volatile(),
261
265
  /** Growth gate companion: the contiguous compressible increment must
262
266
  * also reach this many estimated tokens (chars/4 heuristic). */
263
- trimIncrementTokens: z.number().min(1000).default(25000).volatile(),
267
+ trimIncrementTokens: z.number().min(1000).default(45000).volatile(),
264
268
  /** Pressure tier (tier b): fold when view usage reaches this percent of
265
269
  * the context window (requires a resolvable window; otherwise skipped). */
266
- trimPressurePercent: z.number().min(1).max(100).default(65).volatile(),
270
+ trimPressurePercent: z.number().min(5).max(100).default(45).volatile(),
267
271
  /** Emergency tier (tier c): forced MECHANICAL fold (no side-model call)
268
272
  * at this percent of the window; cooldown-gated. */
269
- trimEmergencyPercent: z.number().min(1).max(100).default(95).volatile(),
273
+ trimEmergencyPercent: z.number().min(5).max(100).default(90).volatile(),
274
+ /** Advisory mode speak line: the model is nudged to fold when pressure
275
+ * reaches this percent of the window (default sits below the protocol's
276
+ * own 80% fold line, nudging while folding headroom is still comfortable). */
277
+ trimAdvisoryPercent: z.number().min(5).max(100).default(50).volatile(),
278
+ /** Advisory mode escalation line: at this percent the nudge escalates to a
279
+ * fold-down-this-turn order; must stay above trimAdvisoryPercent (an
280
+ * inverted or out-of-range pair falls back to 50/80). */
281
+ trimAdvisoryCriticalPercent: z.number().min(5).max(100).default(80).volatile(),
282
+ /** [2026-11-15]-[advisory critical relief fold]-[at the critical advisory
283
+ * line the engine itself performs ONE mechanical (emergency-style) fold,
284
+ * 90 s cooldown (EMERGENCY_COOLDOWN_MS), instead of only nudging — the
285
+ * 2026-11-14 turn-25 incident (nudges ignored, 74%→99% in 28 minutes)
286
+ * burned the window down to host compaction. Off restores nudge-only
287
+ * advisory mode.] */
288
+ trimCriticalRelief: z.boolean().default(true).volatile(),
289
+ /** [2026-11-15]-[per-band nudge repeat]-[a spoken advisory nudge slides
290
+ * under the growing turn tail and becomes background noise; the repeat
291
+ * now re-pins the nudge at the new tail this many ms after the last
292
+ * speak (critical band halves it, floor 45 s). Old behavior: one
293
+ * repeat per 10 minutes. 5000..3600000 sane; out-of-range falls back
294
+ * to 120000.] */
295
+ trimAdvisoryRepeatMs: z.number().min(5000).max(3600000).default(120000).volatile(),
296
+ /** [2026-11-15]-[verbose debug log]-[the turn-25 + window-unknown
297
+ * incidents both hid inside silent gates that outcomes-only logging
298
+ * cannot see. On, every engine step, gate evaluation and decision path
299
+ * writes a debug row to decisions.log; off keeps the key decision rows
300
+ * only. Exceptions log full detail (message + stack frames) regardless
301
+ * of this switch.] */
302
+ trimVerboseLog: z.boolean().default(false).volatile(),
270
303
  /** [2026-11-07]-[growth/increment constants are absolute tokens
271
304
  * calibrated for the default 150k effective window]-[scaling
272
305
  * trimWindowTokens down without scaling trimGrowthTokens /
@@ -277,13 +310,16 @@ export const Config = z.object({
277
310
  * 2026-11-09 steady-growth recalibration — one fold per ~22.5k of new
278
311
  * work instead of one every ~2 minutes; pressure pins the 50-100k band
279
312
  * ceiling).]
313
+ * [2026-11-14]-[shipped defaults recalibrated to the 200k force
314
+ * window]-[increment 45000 ≈ window/4.4, growth 22500 ≈ window × 0.11;
315
+ * pressure/emergency 45%/90%, advisory 50%/90%, hard watermark 100k.]
280
316
  * Effective-window cap for the tier math: tier points are computed
281
317
  * against min(model-resolved window, cap). 0 = auto (cap follows
282
318
  * wmForceTokens, so folds always fire ahead of the handover tier). */
283
319
  trimWindowTokens: z.number().min(0).default(0).volatile(),
284
320
  /** Last N messages of a history are never folded (the live tail the
285
321
  * next model call reasons over). */
286
- trimProtectedTail: z.number().min(0).max(100).default(10).volatile(),
322
+ trimProtectedTail: z.number().min(0).max(100).default(6).volatile(),
287
323
  /** Side-model fold cadence cap per rolling hour (emergency mechanical
288
324
  * folds are exempt; they have their own cooldown). 30 sits just above
289
325
  * the pure T1 demand of continuous full-rate generation (~27 folds/hour
@@ -306,6 +342,12 @@ export const Config = z.object({
306
342
  * T2/T3 distillation tiers. T1 raw-range folds are governed by
307
343
  * trimMode; the ladder only adds the summary-maintenance tiers. */
308
344
  trimLadderEnabled: z.boolean().default(true).volatile(),
345
+ /** Protect the task-intent segment (the first user message's whole
346
+ * segment) from raw folds. true (default) keeps the anti-drift guard;
347
+ * false lets the intent segment enter computeFoldableRange's candidate
348
+ * span like any other raw content. The system-head clamp is unaffected
349
+ * either way. */
350
+ trimProtectTaskIntent: z.boolean().default(true).volatile(),
309
351
  /** Ladder T2 gate: minimum active-T1 summary token mass before a T2
310
352
  * distillation fires (the need signal — bili #379: block count alone
311
353
  * is not a need signal). */
@@ -319,8 +361,11 @@ export const Config = z.object({
319
361
  /** Ladder T3 companion floor: a T3 condensation merges at least this
320
362
  * many active T2 blocks. */
321
363
  trimLadderT3MinBlocks: z.number().min(2).max(200).default(2).volatile(),
322
- /** Explicit ledger state directory. Empty = <dshHome>/.dsh-switchman/
323
- * state/trim/. */
364
+ /** Explicit ledger state directory (absolute, or relative inside the
365
+ * plugin root). Must stay under <dshHome>/.dsh-switchman/state/trim/
366
+ * (or the OS temp root, for throwaway test state); anything else is
367
+ * refused and the default root is used. Empty =
368
+ * <dshHome>/.dsh-switchman/state/trim/. */
324
369
  trimStateDir: z.string().default("").volatile(),
325
370
  /** Ship committed folds onto the session surface: append the host-style
326
371
  * shadow-price + surfaceOp replace event pair so folds reach the wire