dsh-switchman 1.11.6 → 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/README.de.md +36 -31
- package/README.es.md +36 -31
- package/README.fr.md +36 -31
- package/README.it.md +36 -31
- package/README.ja.md +36 -31
- package/README.ko.md +36 -31
- package/README.md +37 -32
- package/README.pt.md +36 -31
- package/README.ru.md +36 -31
- package/README.zh-TW.md +36 -31
- package/README.zh.md +36 -31
- package/client.js +355 -26
- package/cordis.patch.yml +10 -10
- package/host/config.js +64 -33
- package/host/context-trim/index.js +539 -60
- package/host/context-trim/state.js +3 -2
- package/host/context-trim/surface.js +5 -1
- package/host/context-watch.js +12 -7
- package/host/intent.js +41 -4
- package/host/lang.js +4 -2
- package/host/ptc-bindings.js +510 -0
- package/host/ptc-guard.js +9 -1
- package/host/routes.js +110 -34
- package/host/teams.js +61 -15
- package/host/vision.js +24 -3
- package/index.js +5 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,30 +12,27 @@
|
|
|
12
12
|
|
|
13
13
|
Two pains creep in once you've worked in DSH for a while. First, sessions get heavier the longer they run: history bloats the context into hundreds of thousands of tokens, the model starts forgetting, slowing down, costing more — and a manual /compact loses detail. Second, the main model does everything itself: chasing files, running tests, reconciling data — most of that work belongs on a cheaper model.
|
|
14
14
|
|
|
15
|
-
dsh-switchman is a plugin for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH). Once installed, the main model
|
|
15
|
+
dsh-switchman is a plugin for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH). Once installed, the main model keeps doing the work itself — just smarter about it: it chooses its battles, handing small chores to cheap lanes and letting intent routing land urgent or hard work on the right model, stepping in personally only where it counts; it sheds bloat and keeps the essence — digested history folds into compact summaries while the watermark meters every spend, keeping context lean; and when the load outgrows one pair of hands, it pulls in standing teammates to divide the work on a shared task board and steps back to dispatch and verify. It's not a new model — it's a dispatch doctrine hooked onto DSH plus a settings page, and it does nine things:
|
|
16
16
|
|
|
17
|
-
**1.
|
|
17
|
+
**1. Automatic context trimming: sessions grow longer, costs stay flat.** A manual `/compact` waits on you, loses detail, and punches through the vendor's prompt cache. The trim engine automates all of it: digested stretches of the conversation are folded into compact deterministic summaries at idle boundaries (written by a side model, or folded mechanically without one under emergency pressure), and every outbound request is rebuilt from the fold state from then on — summary blocks stand in for the folded ranges, the live tail kept verbatim. The stored session log is never rewritten, and nothing touches the stream mid-flight. Folds are append-only and the rebuild is deterministic, so the serialized prefix stays byte-identical between folds and vendor caches keep hitting; any internal failure fails open into pass-through — never a malformed request. Three fully automatic tiers (growth gate / pressure / emergency), plus an advisory mode where the model folds on its own — the mechanics live in the "Automatic context trim" section at the bottom.
|
|
18
18
|
|
|
19
|
-
**2.
|
|
19
|
+
**2. Context watermark: long sessions don't blow up.** Every turn counts session tokens in real time, and three escalating lines tighten the screws: 80k (soft, adjustable) nudges "time to delegate"; 100k (hard) shrinks the single-read budget and steers toward wrap-up; 200k (force) hands over automatically — writes the handover document (the append-only session log is the full-fidelity backup), compacts the context, wakes the session to continue, task unbroken. Background subagents still running at handover aren't lost: their ids, tasks, and report paths go into the handover document, so the resumed session knows where to collect reports and never dispatches twice; every subagent also carries its own hard cap and exits after writing its HANDOFF summary. The watermark reads the post-trim view — what the model actually sees — so heavily folded sessions are no longer pinned at the high lines. When the automatics don't suit you: `/ctx-pause` stops all actions (measurement keeps running), `/ctx-resume` restores them any time — and they come back on their own after a restart; `/ctx-handover` starts the same handover on demand, no waiting for the ceiling.
|
|
20
20
|
|
|
21
|
-
**3.
|
|
21
|
+
**3. Intent routing: messages come in, models fall into place.** Pick "Auto (intent routing)" for the session and every user message is first typed by a small classifier model, landing on the best-fitting candidate — each candidate carries a one-line capability note to steer the call. The decision locks for the turn: when confidence is lacking or the cache window is still open, the current model stays (its prompt cache keeps paying off); switching happens only when confidence is high enough or the current model isn't among the candidates. The switch completes silently at the call layer — no "model switched" noise in the session — while a chip above the input box shows the live route and confidence. Decision-style small models and general chat models both work as the classifier; candidates, thresholds, and the cache window are always one settings page away.
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
- **Subagent model whitelist sync** — DSH keeps an authorization whitelist "allow agents to pick models for subagents": routes chosen in a pool but not authorized get rejected when dispatched by name (marked ⚠ in teams mode). Flip this toggle and the union of all six pools is written into that whitelist wholesale — switchman becomes the single source of truth, no double configuration. The whitelist takes effect as a per-new-session snapshot; the sync only affects sessions started afterwards.
|
|
23
|
+
**4. Agent Teams: from solo to a team.** Off by default — after install it's lightweight subagent dispatch; build a team when you want one. Two independent toggles on the settings page: **Agent teams** injects the team doctrine (delegate by default + tiered verification + shared task-board discipline) and enables DSH's Agent Teams automatically — the main model can pull standing teammates (`spawn_teammate`), put work on the shared task board (`team_task_*`), and message teammates. When to form a team follows clear discipline: parallelizable independent subtasks, bulky self-contained work, a high main-context watermark, a need for role separation; one-off single-point investigations still go to a subagent. Switch it off and the team clauses vanish without residue, and tools are never yanked from sessions still running. **Subagent model whitelist sync** writes the union of all six pools wholesale into DSH's authorization whitelist — switchman becomes the single source of truth, no double configuration (effective as a per-new-session snapshot).
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
**5. Six dispatch pools: the right model for every job.** Economy (batch small chores), mechanical (template rewrites), main (day-to-day coding), hard (hard reasoning and large refactors), vision (images), review (independent verification). On the settings page you tick candidates, order priorities, grade S/A/B/C, and pin a per-route thinking effort — the effort dropdown lists the levels that model actually supports, not a generic three. Every turn's prompt carries a `[SWITCHMAN:POOLS]` recommendation table, and the main model dispatches by it. Three enforcement modes: off / advice / force (force = out-of-pool models get rejected outright).
|
|
27
26
|
|
|
28
|
-
**
|
|
27
|
+
**6. Language preferences: ask once, remember forever.** One dropdown each for replies, code comments, and documents; scope is global or per-project (`.switchman/lang.json`). Skipping is fine — on first use you're asked once in your DSH interface language, and every session obeys the answer afterwards.
|
|
29
28
|
|
|
30
|
-
**
|
|
29
|
+
**7. Interface language: the plugin itself speaks your language.** In the "Interface" section atop the settings page sits the "Interface language" dropdown (setting key `uiLocale`): Auto (follows the DeepSeek Harness app language; factory default: Simplified Chinese), or any built-in interface language picked by hand — options always appear under the language's own endonym, never translated. It switches only the plugin's own interface (badge, home panel, settings page), never the DSH app language: selecting previews live with no restart, the choice is remembered after save and restored on the next launch, and any failure falls back to the app language; the dictionaries ship inline in the plugin bundle, nothing to download.
|
|
31
30
|
|
|
32
|
-
**
|
|
31
|
+
**8. Tiered verification: every change gets checked.** Changes over 20 lines go to a tester; over 300 lines, or touching core / security / data-consistency logic, additionally to an independent reviewer. The review model is picked anchored on the model of "the agent that wrote the diff", avoiding it where possible; when the pool can't, the conclusion declares DOWNGRADED. Say "don't use the team" once and it drops back to solo instantly.
|
|
33
32
|
|
|
34
|
-
**
|
|
33
|
+
**9. `/vision`: text-only models can still handle images.** When the main model can't read images, DSH rejects image-bearing messages at the gate. Paste the image, type `/vision what's wrong with this image`, and the image goes to a vision-pool model; the verdict comes back into the current session. A heads-up "current model can't read images" appears above the input box; when a direct image send is rejected, the message is rewritten as `/vision` and resent automatically — no manual redo; with no vision pool configured the command refuses and points to the settings.
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
Worth installing even with a single model — watermark control and tiered verification don't care how many models you have, and long single-model sessions benefit just the same.
|
|
35
|
+
Worth installing even with a single model — automatic trimming, watermark control, and tiered verification don't care how many models you have, and long single-model sessions benefit just the same; intent routing only means something with multiple model candidates, so leave it switched off until you scale up the roster.
|
|
39
36
|
|
|
40
37
|
## Bundled skills
|
|
41
38
|
|
|
@@ -75,7 +72,7 @@ Worth installing even with a single model — watermark control and tiered verif
|
|
|
75
72
|
- **Dispatch pools** — six cards in two rows of three: economy, mechanical, main on top; hard, vision, review below. Tick candidate models grouped by provider; tick "manual order" and a card becomes a numbered priority list reorderable with ⤒ (Move to top), ↑, ↓, ×; every route can pin a thinking effort (default "follow lane"). The summary line at the top updates live — in the shot: "4/6 pools configured · 2 ranked · mode advice".
|
|
76
73
|
- **Capability ranking + enforcement mode** — the union of selected models across the six pools, ranked by capability, strongest first (the shot anchors glm-5.3 at S and glm-5.3-flash at A), reorderable and removable; enforcement mode advice / force (force = out-of-pool models rejected outright).
|
|
77
74
|
- **Agent teams** — the two toggles for team mode and whitelist sync, both off by default; in the shot they're on, with a sync status line beneath the toggle.
|
|
78
|
-
- **Context watermark** — the three thresholds (80000 /
|
|
75
|
+
- **Context watermark** — the three thresholds (80000 / 100000 / 200000 in the shot), the single-read budget (3500), hard-tier behavior (throttle-pass / block), the auto-handover toggle, and subagent independent caps all live here. Bottom command row: `/ctx-pause` pause intervention · `/ctx-resume` resume · `/ctx-handover` write the handover doc and compact now (it steers the session to an idle boundary before compacting — the result can take a few minutes).
|
|
79
76
|
- **Intent Routing** — the master switch, the classifier's small-model route, the classifier type (auto / decision / chat), the independent candidate list (each with a one-line capability note), cache window / confidence threshold / classification timeout / history budget, and an optional fallback model with its own optional effort pin (empty = use that model's default). Once enabled, the model picker gains the localized "Auto (intent routing)" entry, and a status chip above the input box shows the routed model and confidence.
|
|
80
77
|
|
|
81
78
|
4. **Verify** — the ⚡ "autonomous team" badge appears in the session header (with ◇ beside it showing the session's current model); or simply ask the model "what's the heading of the last section of your system prompt" — the answer should mention the dsh-switchman doctrine.
|
|
@@ -92,19 +89,19 @@ bash <install-dir>/skills/db-query/scripts/setup.sh
|
|
|
92
89
|
|
|
93
90
|
Everything below is the full set of defaults after a fresh install (authoritative source: the zod schema in `host/config.js`).
|
|
94
91
|
|
|
95
|
-
**Interface and languages**: `uiLocale` = `auto`
|
|
92
|
+
**Interface and languages**: `uiLocale` = `zh` (Simplified Chinese; `auto` follows the DSH app language); `langScope` = `project`; `langConversation` = `zh-CN`; `langComments/Docs` = empty (factory default; if cleared, asked once in the first session and then remembered; the comment and document languages follow the conversation language).
|
|
96
93
|
|
|
97
94
|
**Dispatch pools**: all six lanes (economy/mechanical/main/hard/vision/review) start with empty candidates (= the system default models, no intervention); manual ordering and pinned effort are off/empty; `dispatchEnforce` = `advice` (advisory only, nothing enforced).
|
|
98
95
|
|
|
99
|
-
**Context watermark**: soft `80000` / hard `
|
|
96
|
+
**Context watermark**: soft `80000` / hard `100000` / force `200000` tokens; single-read budget `3500`; over-budget behavior `cap` (truncate with a warning); `wmAutoHandover` = on (at force, automatic handover: write doc + compact); the subagent hard cap = on (sharing 200k).
|
|
100
97
|
|
|
101
|
-
**Agent Teams**: `teamsMode` =
|
|
98
|
+
**Agent Teams**: `teamsMode` = on; `syncWhitelist` = on (the two toggles are independent of each other).
|
|
102
99
|
|
|
103
|
-
**Intent routing** (unavailable by default; needs a classifier + at least one candidate + the master switch on): `intentEnabled` = off (while off, the Auto entry stays hidden and sessions already on Auto fall through the fallback chain); the classifier route is unset; the classifier type is `chat`; the candidate list is empty (the preset categories join routing only once given a model); cache window `300` s / switch confidence threshold `80` / classification timeout `60000` ms; history `6` messages / `2400` characters; optional `intentFallbackRoute` is unset, and its own effort is model-default when later configured; `intentContextWindow` = `
|
|
100
|
+
**Intent routing** (unavailable by default; needs a classifier + at least one candidate + the master switch on): `intentEnabled` = off (while off, the Auto entry stays hidden and sessions already on Auto fall through the fallback chain); the classifier route is unset; the classifier type is `chat`; the candidate list is empty (the preset categories join routing only once given a model); cache window `300` s / switch confidence threshold `80` / classification timeout `60000` ms; history `6` messages / `2400` characters; optional `intentFallbackRoute` is unset, and its own effort is model-default when later configured; `intentContextWindow` = `250000`.
|
|
104
101
|
|
|
105
|
-
**Context trim**: `trimEnabled` = on; `trimMode` = `auto`
|
|
102
|
+
**Context trim**: `trimEnabled` = on; `trimMode` = `advisory` (nudges + fold tools; the session model folds itself — switch to `auto` for fully automatic idle-boundary folds); growth gate `22500` tokens + increment `45000` tokens; pressure `45%` / emergency `90%`; advisory nudge `50%` / `80%`; protected tail `6` messages; fold cadence cap `30` per hour; side model unset (follows the session provider/model, not the session call's effort); without an explicit effort pin, use the lowest enabled reasoning level from model metadata, choose `off` for toggle-only models, and omit effort when reasoning is unsupported or metadata is unavailable (model default). Ladder distillation shares that route and policy; a configured fold-fallback route has an independent effort pin with the same model-aware default. **Ladder folding on** — T2 distills accumulated T1 summaries (8000-token mass, ≥3 blocks), T3 distills T2 (6000-token mass, ≥2 blocks); the engine never shows the model a water level, percentage, or progress number — details in the "Automatic context trim" section below and [docs/ladder-fold.md](./docs/ladder-fold.md).
|
|
106
103
|
|
|
107
|
-
**Out-of-the-box notes**: ① intent routing being unavailable out of the box is by design — three steps to switch it on (classifier, candidates, the master switch); ② Auto's effective window is
|
|
104
|
+
**Out-of-the-box notes**: ① intent routing being unavailable out of the box is by design — three steps to switch it on (classifier, candidates, the master switch); ② Auto's effective window is 250000 out of the box — the guardrail guarantees 0.8×window ≥ force (200000), and the core compaction line (200000) lands exactly on the smooth-handover line (200000); ③ the most tangible out-of-the-box effect is the watermark trio: 80k nudges delegation / 100k tightens reading / 200k backs up and hands over automatically — no configuration needed.
|
|
108
105
|
|
|
109
106
|
## Automatic context trim
|
|
110
107
|
|
|
@@ -113,23 +110,25 @@ Long sessions stay cheap: consumed conversation ranges are folded into compact d
|
|
|
113
110
|
Automation levels (`trimMode`):
|
|
114
111
|
|
|
115
112
|
- **`off`** — measure only: usage and cache-hit sampling still runs; no banner, no folds.
|
|
116
|
-
- **`advisory`** — the session model folds itself: the `ctx_trim_fold` and `ctx_trim_status` tools plus the protocol head are exposed for it. When session pressure reaches `trimAdvisoryPercent` of the effective window the engine appends a one-off pinned fold nudge as a `user/message` suffix to the live session surface tail (not the dispatch system head) — it is re-spoken immediately on escalation to critical and pruned once pressure falls back below the line.
|
|
117
|
-
- **`auto`**
|
|
113
|
+
- **`advisory`** (default) — the session model folds itself: the `ctx_trim_fold` and `ctx_trim_status` tools plus the protocol head are exposed for it. When session pressure reaches `trimAdvisoryPercent` of the effective window the engine appends a one-off pinned fold nudge as a `user/message` suffix to the live session surface tail (not the dispatch system head) — it is re-spoken immediately on escalation to critical and pruned once pressure falls back below the line. At the critical line the engine itself performs one mechanical relief fold (90 s cooldown, `trimCriticalRelief` = on).
|
|
114
|
+
- **`auto`** — everything above plus automatic folds at the idle boundary, in three tiers: a growth gate (growth > `trimGrowthTokens` measured from the last fold's post-fold low — the anchor that keeps the gate armed after folds committing at high view points — AND a contiguous compressible increment ≥ `trimIncrementTokens`; the increment floor is what actually binds), a pressure tier (`trimPressurePercent` of the context window), and an emergency tier (`trimEmergencyPercent` — a mechanical fold with its own cooldown). Pressure and emergency usage is measured on `max(view, wire)`, i.e. on the real provider prompt when it is known.
|
|
118
115
|
|
|
119
116
|
All keys live in Settings → dsh-switchman; defaults from `host/config.js`:
|
|
120
117
|
|
|
121
118
|
| Key | Default | Meaning |
|
|
122
119
|
| --- | --- | --- |
|
|
123
120
|
| `trimEnabled` | `true` | Master switch. OFF disables folding and metrics entirely (the listener degrades to a pure pass-through). |
|
|
124
|
-
| `trimMode` | `
|
|
121
|
+
| `trimMode` | `advisory` | `off` measure only / `advisory` model-driven folds / `auto` system-driven folds. |
|
|
125
122
|
| `trimGrowthTokens` | `22500` | Growth gate: fold when the outbound view grew this much since the last fold. |
|
|
126
|
-
| `trimIncrementTokens` | `
|
|
127
|
-
| `trimPressurePercent` | `
|
|
128
|
-
| `trimEmergencyPercent` | `
|
|
129
|
-
| `trimAdvisoryPercent` | `
|
|
130
|
-
| `trimAdvisoryCriticalPercent` | `
|
|
123
|
+
| `trimIncrementTokens` | `45000` | Gate companion: the contiguous compressible increment must also reach this size. |
|
|
124
|
+
| `trimPressurePercent` | `45` | Pressure tier: fold when view usage reaches this percent of the context window. |
|
|
125
|
+
| `trimEmergencyPercent` | `90` | Emergency tier: forced mechanical fold (no side-model call) at this percent. |
|
|
126
|
+
| `trimAdvisoryPercent` | `50` | Advisory nudge line: when pressure reaches this percent of the effective window, the engine nudges the model to fold now with `ctx_trim_fold` (advisory mode only). |
|
|
127
|
+
| `trimAdvisoryCriticalPercent` | `80` | Critical nudge line: reaching it re-speaks the nudge immediately, bypassing the 10-minute same-band throttle. |
|
|
131
128
|
| `trimWindowTokens` | `0` | Effective-window cap for tier math: tiers are computed against min(model window, cap). `0` = follow `wmForceTokens`. |
|
|
132
|
-
| `
|
|
129
|
+
| `trimCriticalRelief` | `true` | Advisory critical relief: at the critical line the engine itself performs one mechanical (emergency-style) fold, on a 90 s cooldown. |
|
|
130
|
+
| — | — | Trim percentages are not comparable with the composer's context meter: trim divides the last paid prompt (max of view/wire) by the effective window (cap included), while the meter shows the meter's projected next prompt over the model's full window. |
|
|
131
|
+
| `trimProtectedTail` | `6` | The last N messages are never folded. |
|
|
133
132
|
| `trimMaxFoldsPerHour` | `30` | Side-model fold cadence cap per rolling hour (emergency folds are exempt). |
|
|
134
133
|
| `trimSideModel` | unset | Route for the summary side model. Empty follows the session provider/model only, not its effort. The independent effort pin defaults to the lowest enabled reasoning level from model metadata; toggle-only models use `off`, while unsupported reasoning or missing metadata omits the effort and leaves the model default. Ladder distillations share the route and policy. |
|
|
135
134
|
| `trimFoldFallbackModel` | unset | Route used when a summary call fails; a pressure fold then degrades to mechanical if the retry also fails. Its effort pin is independent; when unset, use the same model-aware recommendation as the summary route. Empty = no fallback leg. |
|
|
@@ -138,7 +137,7 @@ All keys live in Settings → dsh-switchman; defaults from `host/config.js`:
|
|
|
138
137
|
|
|
139
138
|
**Trigger paths.** Tier checks run at the idle boundary and, as a fallback for hosts where idle status events are unreachable, after each model-stream completion (throttled to one evaluation per 60 s per session). Every decision — folds and no-ops alike — is appended as one timestamped `key=value` line to `decisions.log` in the trim state directory (see `trimStateDir`), giving folds an offline audit trail; the row vocabulary (`view-applied`, fold decision/outcome rows, `surface-replace`, `surface-replace skipped reason=…`) is catalogued in [docs/context-trim.md](./docs/context-trim.md).
|
|
140
139
|
|
|
141
|
-
**Wire truth and steady state.** Decision rows carry `view=<n>` and, once a response has landed, `wire=<n>` — the real provider prompt (uncached input + cache read + cache write, sampled from the stream's usage event). The view estimate counts the messages array only and always reads smaller than the wire by the fixed overhead (measured ≈ 17.3k: system prompt + tool schemas + persona), so pressure and emergency tiers evaluate on `max(view, wire)`, and only `wire` is a prompt-size reading. On a
|
|
140
|
+
**Wire truth and steady state.** Decision rows carry `view=<n>` and, once a response has landed, `wire=<n>` — the real provider prompt (uncached input + cache read + cache write, sampled from the stream's usage event). The view estimate counts the messages array only and always reads smaller than the wire by the fixed overhead (measured ≈ 17.3k: system prompt + tool schemas + persona), so pressure and emergency tiers evaluate on `max(view, wire)`, and only `wire` is a prompt-size reading. On a 200k window the healthy sawtooth runs wire ≈ 40k just after a fold ↔ 64–90k at the next one (≈20%–45% of the window), one fold per ~45k of raw growth, with the ceiling pinned near 90k by the pressure tier rather than by the window. If `view` climbs while no `surface-replace` row ever appears, read the skip rows (`incomplete-seqs`, `no-service`, `compaction-lock`).
|
|
142
141
|
|
|
143
142
|
**Host-compaction epochs.** Fold refs are anchored in message ids and content hashes, so a host-side compaction that replaces the re-send history ages the whole ledger out at once: no block locates, the view silently falls back to raw history (fail-open — the decision log records `view-applied applied=0`), and the plugin re-anchors its growth baseline at the post-compaction view on the next request. The host compaction is thus the backstop trim layer, and plugin folds do the fine-grained work within one host epoch. Some dispatches hand out fully frozen request arrays or option objects (the current agent loop deep-freezes assembled requests); for those `injectView` reports the outcome in the decision log: `nothing-to-apply` (no located fold blocks — raw history IS the view), `in-place`/`swapped` (the fold view shipped), or `none` (a fold existed but the frozen dispatch could not carry it — the wire ships raw history). **Surface replace is the shipping path when available** (`surfaceFold`, default on): at the serial `agent/turn-stopping` boundary plus an idle sweep, the plugin appends the host-style shadow-price metering event and ONE `user/message` replacement carrying `surfaceOp {op:'replace', startSeq, endSeq}` with `sourceEventSeqs` covering every shadowed surface node — the same mechanism the host's own compaction uses — so a committed fold reaches the wire from the source level, frozen dispatches included. While a session's recent dispatches log `none`, the view is meter-only: the watermark measures the provider-reported tally instead (so the force tier and the auto-handover keep working). Folding pauses only when the surface channel is unusable as well — a durable capability probe (live session exposing `append`/`surface.nodes`, no open compaction lock), never a recency window, so a restart no longer freezes the engine. The banner marks the line with `wire=raw` only when no fold block has ever shipped a surface replacement, so a session with a shipped block stays quiet across restarts; hosts without the surface mechanism (or with the flag off) keep exactly the legacy behavior.
|
|
144
143
|
|
|
@@ -172,6 +171,12 @@ All keys live in Settings → dsh-switchman; defaults from `host/config.js`:
|
|
|
172
171
|
|
|
173
172
|
The tiered folding design (T1/T2/T3) was inspired by [billion-context](https://github.com/ranxianglei/billion-context) — thank you for open-sourcing the idea.
|
|
174
173
|
|
|
174
|
+
## Downloads
|
|
175
|
+
|
|
176
|
+
All-time npm downloads since the first release, cumulative — drawn from the official [npm downloads API](https://api.npmjs.org/) and refreshed daily by GitHub Actions ([chart script](scripts/downloads-chart.mjs)):
|
|
177
|
+
|
|
178
|
+

|
|
179
|
+
|
|
175
180
|
## License
|
|
176
181
|
|
|
177
|
-
MIT
|
|
182
|
+
MIT
|
package/README.pt.md
CHANGED
|
@@ -12,30 +12,27 @@
|
|
|
12
12
|
|
|
13
13
|
Se você trabalha com o DSH, com o tempo esbarra em duas coisas: a sessão fica cada vez mais pesada — o histórico empurra o contexto para centenas de milhares de tokens, o modelo começa a esquecer, fica lento e caro, e o /compact manual compacta perdendo detalhes no processo; e o modelo principal faz tudo sozinho — consultar um arquivo, rodar um teste, conferir dados: é sempre ele que mastiga tudo, lento e caro, sendo que a maior parte desse trabalho caberia a um modelo barato.
|
|
14
14
|
|
|
15
|
-
dsh-switchman é um plugin para o [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH). Depois de instalado, o modelo principal
|
|
15
|
+
dsh-switchman é um plugin para o [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH). Depois de instalado, o modelo principal continua trabalhando por conta própria — só que com mais critério: escolhe as brigas dele, manda os serviços pequenos para faixas baratas e deixa o roteamento por intenção aterrissar o urgente ou o difícil no modelo certo, reservando para si só o que realmente merece um toque pessoal; descarta o inchado e destila o essencial — as partes já digeridas da conversa se dobram em resumos compactos enquanto o nível de água mede cada gasto, e o contexto viaja sempre leve; e quando a carga ultrapassa um único par de mãos, recruta companheiros permanentes que dividem o trabalho num quadro de tarefas compartilhado, enquanto ele fica com o despacho e a conferência. Não é um modelo novo: é um regulamento de despacho plugado ao DSH mais uma interface de configuração. Em concreto, ele faz nove coisas:
|
|
16
16
|
|
|
17
|
-
**1.
|
|
17
|
+
**1. Trim automático do contexto: a sessão fica mais longa, o custo fica plano.** Um `/compact` manual faz você esperar, perde detalhes e atravessa a cache de prompt do fornecedor. O motor de trim automatiza tudo isso: as partes já digeridas da conversa são dobradas em resumos deterministas e compactos nas fronteiras de inatividade (quem escreve é um side model; sob pressão de emergência a dobra é mecânica, sem chamada de modelo), e a partir daí cada requisição de saída é reconstruída a partir do estado das dobras — blocos de resumo substituem as partes dobradas, a cauda viva fica palavra por palavra. O log de sessão salvo nunca é reescrito, e nada toca o stream em pleno curso. As dobras são só append e a reconstrução é determinística: o prefixo serializado fica idêntico byte a byte entre dobras e a cache do fornecedor continua acertando; qualquer falha interna cai em fail-open para o repasse transparente — nunca uma requisição quebrada. Três níveis totalmente automáticos (crescimento / pressão / emergência), mais um modo advisory em que o próprio modelo dobra — a mecânica está no fim, na seção “Trim automático do contexto”.
|
|
18
18
|
|
|
19
|
-
**2.
|
|
19
|
+
**2. Nível de água do contexto: sessões longas não estouram.** A cada turno ele conta os tokens da sessão em tempo real, e três limiares apertam em degraus: 80k (soft, ajustável) lembra que “é hora de delegar”; 100k (hard) aperta o orçamento de leitura por chamada e empurra para encerrar; 200k (force) dispara o handover automático — escrita do documento de handover (o log de sessão append-only é a cópia completa), contexto compactado, sessão despertada para continuar: a tarefa não cai no meio. Nem os subagents em segundo plano que ainda estiverem rodando no momento da entrega se perdem: id, descrição da tarefa e caminho do relatório vão para o documento de handover, e a sessão retomada sabe onde coletar os relatórios em vez de despachar o mesmo trabalho de novo; cada subagent enviado carrega ainda um teto próprio e independente e, ao atingi-lo, sai depois de escrever o resumo HANDOFF. O nível lê a visão depois do trim — o que o modelo realmente vê —, então uma sessão muito dobrada não fica mais presa nos limiares altos. Se o automático não estiver do seu jeito: `/ctx-pause` interrompe todas as ações (a medição continua), `/ctx-resume` retoma a qualquer momento — e depois de reiniciar volta sozinho; `/ctx-handover` dispara sob demanda o mesmo handover, sem esperar o teto.
|
|
20
20
|
|
|
21
|
-
**3.
|
|
21
|
+
**3. Roteamento por intenção: chega a mensagem, o modelo toma seu posto.** Ao escolher “Auto (roteamento por intenção)” para a sessão, cada mensagem do usuário passa primeiro por um pequeno modelo classificador, que a faz aterrissar no candidato mais adequado — cada candidato traz uma nota de capacidades de uma linha para orientar a escolha. A decisão vale para o turno: se a confiança não chega ou a janela de cache ainda está aberta, o modelo atual permanece (a cache de prompt dele segue rendendo); só se troca quando a confiança sobra ou o modelo atual não está entre os candidatos. A troca acontece em silêncio na camada de chamada — nenhum barulho de “modelo trocado” na sessão — enquanto um chip acima da caixa de entrada mostra rota e confiança em tempo real. Como classificador servem tanto pequenos modelos de decisão quanto modelos de chat genéricos; candidatos, limiares e janela de cache ficam sempre a uma página de configurações de distância.
|
|
22
22
|
|
|
23
|
-
- **Modo Agent Teams** — ao ligar, injeta a doutrina de equipe (delegar por padrão + verificação em níveis + disciplina do quadro de tarefas compartilhado) e habilita automaticamente os Agent Teams do DSH: o modelo principal pode recrutar colegas permanentes (`spawn_teammate`), despachar trabalho para o quadro compartilhado (`team_task_*`) e trocar mensagens com eles. Há uma disciplina clara sobre quando formar a equipe: subtarefas independentes paralelizáveis, trabalho volumoso e autossuficiente, nível de água do contexto principal já alto, necessidade de separar papéis; investigações pontuais de uma vez só continuam pelo subagent. Desligando a chave de novo, as cláusulas de equipe somem sem resíduo, e as ferramentas de equipe nas sessões em andamento não são recolhidas.
|
|
24
|
-
- **Sincronização da whitelist de modelos de subagent** — o DSH tem uma whitelist de autorização “Permitir que os agents escolham modelos para os subagents”: rotas escolhidas nos pools mas não autorizadas são recusadas quando o modelo principal as nomeia explicitamente (no modo equipe, são marcadas com ⚠). Com esta chave ligada, a união dos seis pools é gravada de uma vez nessa whitelist — sem configurar dos dois lados: o switchman é a única fonte da verdade. A whitelist vale como snapshot por “nova sessão”: a sincronização só alcança as sessões abertas depois.
|
|
23
|
+
**4. Modo Agent Teams: do trabalho solo para comandar uma equipe.** Desligado por padrão: recém-instalado, o trabalho corre no despacho leve via subagent. Na página de configurações, duas chaves independentes: **Modo Agent Teams** — ao ligar, injeta a doutrina de equipe (delegar por padrão + verificação em níveis + disciplina do quadro de tarefas compartilhado) e habilita automaticamente os Agent Teams do DSH: o modelo principal pode recrutar colegas permanentes (`spawn_teammate`), despachar trabalho para o quadro compartilhado (`team_task_*`) e trocar mensagens com eles. Há uma disciplina clara sobre quando formar a equipe: subtarefas independentes paralelizáveis, trabalho volumoso e autossuficiente, nível de água do contexto principal já alto, necessidade de separar papéis; investigações pontuais de uma vez só continuam pelo subagent. Desligando a chave de novo, as cláusulas de equipe somem sem resíduo, e as ferramentas de equipe nas sessões em andamento não são recolhidas. **Sincronização da whitelist de modelos de subagent** — o DSH tem uma whitelist de autorização “Permitir que os agents escolham modelos para os subagents”: rotas escolhidas nos pools mas não autorizadas são recusadas quando o modelo principal as nomeia explicitamente (no modo equipe, são marcadas com ⚠). Com esta chave ligada, a união dos seis pools é gravada de uma vez nessa whitelist — sem configurar dos dois lados: o switchman é a única fonte da verdade. A whitelist vale como snapshot por “nova sessão”: a sincronização só alcança as sessões abertas depois.
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
**5. Seis pools de despacho: a cada trabalho, o seu modelo.** Pool leve (economy, trabalho pequeno em lote), pool mecânico (mechanical, reescritas de molde), pool principal (main, codificação do dia a dia), pool difícil (hard, raciocínio pesado e refatoração em grande escala), pool multimodal (vision, leitura de imagens), pool de revisão (review, verificação independente). Na página de configurações você marca os candidatos, ordena as prioridades (com níveis opcionais S/A/B/C) e fixa um reasoning effort por rota — o dropdown lista os níveis que aquele modelo realmente suporta, não três níveis genéricos. A cada turno, o prompt do modelo principal carrega uma tabela de recomendações `[SWITCHMAN:POOLS]`: o trabalho é despachado seguindo a tabela. O modo de execução tem três estados: off / advice / enforce (enforce = modelos fora do pool são recusados na hora).
|
|
27
26
|
|
|
28
|
-
**
|
|
27
|
+
**6. Preferências de idioma: pergunta uma vez, lembra para sempre.** Um dropdown para cada um dos três idiomas — respostas, comentários de código, documentos — com escopo à escolha: global ou por projeto (`.switchman/lang.json`). Pode deixar em branco: no primeiro uso perguntam uma vez, no idioma da interface do DSH, e daí em diante toda sessão segue sozinha.
|
|
29
28
|
|
|
30
|
-
**
|
|
29
|
+
**7. Idioma da interface: o plugin também fala o seu idioma.** No topo da página de configurações entra uma nova seção “Interface” com um dropdown “Idioma da interface” (chave de configuração `uiLocale`): Automático (segue o idioma do app DeepSeek Harness; chinês simplificado por padrão) ou qualquer um dos idiomas da interface do plugin, sempre pelo endônimo, nunca traduzido. Ele troca só a interface do próprio plugin — o badge do cabeçalho, o painel da página inicial e a página de configurações —, não o idioma do app DSH: a prévia é imediata, sem reinício; ao salvar, a escolha fica guardada; o próximo início a restaura; qualquer falha volta ao idioma do app; e todos os dicionários vêm dentro do bundle, sem download.
|
|
31
30
|
|
|
32
|
-
**
|
|
31
|
+
**8. Verificação em níveis: mudou, testa.** Alterações acima de 20 linhas vão para um tester validar; acima de 300 linhas, ou quando tocam lógica central / segurança / consistência de dados, entra também um reviewer com revisão independente. O modelo do reviewer é escolhido ancorando no modelo do “agent que escreveu o diff”, evitando-o sempre que possível; se no pool não dá para evitá-lo, a conclusão declara DOWNGRADED. Basta dizer “não use equipes” e ele volta na hora a trabalhar sozinho.
|
|
33
32
|
|
|
34
|
-
**
|
|
33
|
+
**9. `/vision`: até modelo somente texto lida com imagens.** Quando o modelo principal não sabe ler imagens, o DSH recusa na entrada as mensagens que as trazem. Você anexa a imagem e digita `/vision onde está o erro nesta imagem`: a imagem é entregue à leitura de um modelo do pool multimodal, e a conclusão volta para a sessão atual. Acima da caixa de entrada aparece antes o aviso “o modelo atual não suporta leitura de imagens”; se um envio direto da imagem for recusado, a mensagem é reescrita uma vez para `/vision` e reenviada sozinha, sem precisar refazer à mão; sem pool multimodal configurado, o comando recusa e indica como configurar.
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
Só um modelo? Ainda vale a pena instalar — o controle do nível de água e a verificação em níveis não ligam para quantos modelos você tem, e sessões longas de modelo único se beneficiam do mesmo jeito.
|
|
35
|
+
Só um modelo? Ainda vale a pena instalar — trim automático, controle do nível de água e verificação em níveis não ligam para quantos modelos você tem, e sessões longas de modelo único se beneficiam do mesmo jeito. O roteamento por intenção só faz sentido com vários candidatos de modelo: deixe desligado até ampliar o elenco.
|
|
39
36
|
|
|
40
37
|
## Skills embutidas
|
|
41
38
|
|
|
@@ -75,7 +72,7 @@ Só um modelo? Ainda vale a pena instalar — o controle do nível de água e a
|
|
|
75
72
|
- **Pools de despacho** — seis cards em duas fileiras de três: em cima leve / mecânico / principal; embaixo difícil / multimodal / revisão. Em cada card você marca os candidatos agrupados por provider; marque “ordem manual” e ele vira uma lista de prioridade numerada, reordenável com ↑ ↓ ×; ao lado de cada rota dá para fixar o reasoning effort (padrão “seguir a faixa”). A linha de resumo no topo se atualiza em tempo real; na captura: “4/6 pools configurados · 2 no ranking · modo advice”.
|
|
76
73
|
- **Ranking de capacidade + modo de execução** — a união dos modelos escolhidos nos seis pools, ordenada por capacidade com os mais fortes na frente (na captura glm-5.3 ancorado em S e glm-5.3-flash ancorado em A); dá para reordenar e cortar; o modo de execução vai de advice / enforce (enforce = modelos fora do pool são recusados na hora).
|
|
77
74
|
- **Equipe de agentes** — as duas chaves, modo equipe e sincronização da whitelist, começam desligadas; na captura estão ligadas, e abaixo de cada uma há uma linha de status de sincronização.
|
|
78
|
-
- **Nível de água do contexto** — os três limiares (na captura 80000 /
|
|
75
|
+
- **Nível de água do contexto** — os três limiares (na captura 80000 / 100000 / 200000), o orçamento de leitura por chamada (3500), o comportamento do limiar hard (deixa passar com limitação / bloqueia), a chave do handover automático e o teto independente dos subagents ficam todos nesta área. Uma linha de comandos embaixo: `/ctx-pause` pausa as intervenções · `/ctx-resume` retoma · `/ctx-handover` escreve o documento e entrega na hora (ele conduz a sessão até o limite de inatividade antes de compactar: o resultado pode levar alguns minutos).
|
|
79
76
|
- **Roteamento por intenção** — a chave mestra, a rota do modelo pequeno do classificador, o tipo de classificador (auto / decision / chat), a lista de candidatos independente (cada um com sua nota de capacidade), janela de cache / limiar de confiança / timeout / orçamento de histórico e um modelo de fallback opcional. Ligado, o seletor de modelos ganha a entrada localizada “Automático (roteamento por intenção)” e acima da caixa de entrada aparece o chip com o modelo roteado e a confiança.
|
|
80
77
|
|
|
81
78
|
4. **Verifique** — no cabeçalho da sessão aparece o badge ⚡ “Equipe autônoma” (ao lado, o ◇ mostra o modelo da sessão atual); ou pergunte direto ao modelo “qual é o título da última seção do seu system prompt?” — a resposta deve mencionar a doutrina dsh-switchman.
|
|
@@ -92,19 +89,19 @@ bash <install-dir>/skills/db-query/scripts/setup.sh
|
|
|
92
89
|
|
|
93
90
|
Estes são todos os valores logo depois de uma instalação nova (fonte autoritativa: o esquema zod em `host/config.js`).
|
|
94
91
|
|
|
95
|
-
**Interface e idiomas**: `uiLocale` = `auto`
|
|
92
|
+
**Interface e idiomas**: `uiLocale` = `zh` (chinês simplificado; `auto` segue o idioma do app DSH); `langScope` = `project`; `langConversation` = `zh-CN`; `langComments/Docs` = vazios (valor de fábrica; se vazio, pergunta uma vez na primeira sessão e fica guardado; o idioma de comentários e documentos segue o da conversa).
|
|
96
93
|
|
|
97
94
|
**Pools de despacho**: as seis faixas (economy/mechanical/main/hard/vision/review) começam sem candidatos (= os modelos padrão do sistema, sem intervenção); ordem manual e effort fixado desligados/vazios; `dispatchEnforce` = `advice` (só aconselha, não obriga).
|
|
98
95
|
|
|
99
|
-
**Nível de água do contexto**: soft `80000` / hard `
|
|
96
|
+
**Nível de água do contexto**: soft `80000` / hard `100000` / force `200000` tokens; orçamento de leitura por chamada `3500`; comportamento ao estourar o orçamento `cap` (corta e avisa); `wmAutoHandover` = ligado (no force, escrita do documento de handover + compactação automáticas); o teto dos subagents = ligado (200k compartilhadas).
|
|
100
97
|
|
|
101
|
-
**Agent Teams**: `teamsMode` =
|
|
98
|
+
**Agent Teams**: `teamsMode` = ligado; `syncWhitelist` = ligado (as duas chaves são independentes entre si).
|
|
102
99
|
|
|
103
|
-
**Roteamento por intenção** (indisponível por padrão; são precisos classificador + pelo menos um candidato + ligar a chave mestra): `intentEnabled` = desligado (desligado, a entrada Auto fica oculta e as sessões que já a tinham escolhido caem na cadeia de fallback); rota do classificador sem definir; tipo de classificador `chat`; lista de candidatos vazia (as categorias pré-instaladas só entram no roteamento com um modelo preenchido); janela de cache `300` s / limiar de confiança da troca `80` / timeout de classificação `60000` ms; histórico de `6` mensagens / `2400` caracteres; `intentContextWindow` = `
|
|
100
|
+
**Roteamento por intenção** (indisponível por padrão; são precisos classificador + pelo menos um candidato + ligar a chave mestra): `intentEnabled` = desligado (desligado, a entrada Auto fica oculta e as sessões que já a tinham escolhido caem na cadeia de fallback); rota do classificador sem definir; tipo de classificador `chat`; lista de candidatos vazia (as categorias pré-instaladas só entram no roteamento com um modelo preenchido); janela de cache `300` s / limiar de confiança da troca `80` / timeout de classificação `60000` ms; histórico de `6` mensagens / `2400` caracteres; `intentContextWindow` = `250000`.
|
|
104
101
|
|
|
105
|
-
**Trim de contexto**: `trimEnabled` = ligado; `trimMode` = `
|
|
102
|
+
**Trim de contexto**: `trimEnabled` = ligado; `trimMode` = `advisory` (avisos + ferramentas de dobra; o modelo da sessão dobra-se sozinho — para o modo totalmente automático, `auto`); portão de crescimento `22500` + incremento `45000` tokens; pressão `45%` / emergência `90%`; avisos advisory `50%` / `80%`; cauda protegida `6` mensagens; teto de cadência de folds `30` por hora; modelo secundário não definido (herda o modelo da sessão) — detalhes na seção «Trim automático do contexto» abaixo.
|
|
106
103
|
|
|
107
|
-
**Observações de fábrica**: ① o roteamento por intenção vir indisponível de fábrica é proposital — três passos para ligar (classificador, candidatos, chave); ② a janela efetiva do Auto já nasce em
|
|
104
|
+
**Observações de fábrica**: ① o roteamento por intenção vir indisponível de fábrica é proposital — três passos para ligar (classificador, candidatos, chave); ② a janela efetiva do Auto já nasce em 250000 — o guard-rail garante 0.8×janela ≥ force (200000), então a linha de compactação do núcleo (200000) cai exatamente sobre a linha de entrega suave (200000); ③ o que mais se sente de fábrica é o trio de níveis: 80k lembra de delegar / 100k aperta a leitura / 200k entrega sozinho (documento + compactação) — sem nenhuma configuração.
|
|
108
105
|
|
|
109
106
|
## Trim automático do contexto
|
|
110
107
|
|
|
@@ -113,23 +110,25 @@ Sessões longas ficam baratas: os trechos já consumidos da conversa viram resum
|
|
|
113
110
|
Níveis de automação (`trimMode`):
|
|
114
111
|
|
|
115
112
|
- **`off`** — só medição: a amostragem de uso e de acertos de cache continua rodando; sem banner, sem folds.
|
|
116
|
-
- **`advisory`** — o modelo da sessão dobra sozinho: as ferramentas `ctx_trim_fold` e `ctx_trim_status` mais o cabeçalho de protocolo ficam expostas. Quando a pressão da sessão atinge `trimAdvisoryPercent` da janela efetiva, o motor acrescenta um lembrete de dobra fixado como sufixo `user/message` ao final da surface ativa da sessão (não ao cabeçalho system do despacho) — repetido imediatamente ao escalar para crítico e removido quando a pressão volta abaixo da linha.
|
|
117
|
-
- **`auto`**
|
|
113
|
+
- **`advisory`** (padrão) — o modelo da sessão dobra sozinho: as ferramentas `ctx_trim_fold` e `ctx_trim_status` mais o cabeçalho de protocolo ficam expostas. Quando a pressão da sessão atinge `trimAdvisoryPercent` da janela efetiva, o motor acrescenta um lembrete de dobra fixado como sufixo `user/message` ao final da surface ativa da sessão (não ao cabeçalho system do despacho) — repetido imediatamente ao escalar para crítico e removido quando a pressão volta abaixo da linha. Na linha crítica o próprio motor executa uma dobra mecânica de alívio (arrefecimento de 90 s, `trimCriticalRelief` = ligado).
|
|
114
|
+
- **`auto`** — tudo isso mais folds automáticos na fronteira de ociosidade, em três degraus: um portão de crescimento (crescimento > `trimGrowthTokens` medido a partir da mínima pós-dobra do último fold — a âncora que mantém o portão armado após dobras confirmadas em pontos altos da view — E um incremento comprimível contíguo ≥ `trimIncrementTokens`), um degrau de pressão (`trimPressurePercent` da janela de contexto) e um degrau de emergência (`trimEmergencyPercent` — um fold mecânico com cooldown próprio).
|
|
118
115
|
|
|
119
116
|
Todas as chaves ficam em Configurações → dsh-switchman; os padrões vêm de `host/config.js`:
|
|
120
117
|
|
|
121
118
|
| Chave | Padrão | Significado |
|
|
122
119
|
| --- | --- | --- |
|
|
123
120
|
| `trimEnabled` | `true` | Chave mestra. Desligado desativa folds e métricas por completo (o listener degrada a puro pass-through). |
|
|
124
|
-
| `trimMode` | `
|
|
121
|
+
| `trimMode` | `advisory` | `off` só medição / `advisory` folds conduzidos pelo modelo / `auto` folds conduzidos pelo sistema. |
|
|
125
122
|
| `trimGrowthTokens` | `22500` | Portão de crescimento: dobra quando a view de saída crescer isso desde o último fold. |
|
|
126
|
-
| `trimIncrementTokens` | `
|
|
127
|
-
| `trimPressurePercent` | `
|
|
128
|
-
| `trimEmergencyPercent` | `
|
|
129
|
-
| `trimAdvisoryPercent` | `
|
|
130
|
-
| `trimAdvisoryCriticalPercent` | `
|
|
123
|
+
| `trimIncrementTokens` | `45000` | Companheiro do portão: o incremento comprimível contíguo também precisa alcançar esse tamanho. |
|
|
124
|
+
| `trimPressurePercent` | `45` | Degrau de pressão: dobra quando o uso da view alcança essa porcentagem da janela de contexto. |
|
|
125
|
+
| `trimEmergencyPercent` | `90` | Degrau de emergência: fold mecânico forçado (sem chamada ao modelo secundário) nessa porcentagem. |
|
|
126
|
+
| `trimAdvisoryPercent` | `50` | Linha de lembrete advisory: ao atingir essa porcentagem da janela efetiva, o motor insta o modelo a dobrar já com `ctx_trim_fold` (somente modo advisory). |
|
|
127
|
+
| `trimAdvisoryCriticalPercent` | `80` | Linha crítica: ao atingi-la, repete o lembrete de imediato, contornando o limite de 10 minutos na mesma faixa. |
|
|
131
128
|
| `trimWindowTokens` | `0` | Limite de janela efetivo para o cálculo dos níveis: calculado sobre min(janela do modelo, limite). `0` = segue `wmForceTokens`. |
|
|
132
|
-
| `
|
|
129
|
+
| `trimCriticalRelief` | `true` | Alívio crítico advisory: ao atingir a linha crítica, o próprio motor executa uma dobra mecânica (estilo emergência), com cooldown de 90 s. |
|
|
130
|
+
| — | — | As porcentagens do trim não são comparáveis ao medidor de contexto do compositor: o trim divide o último prompt pago (máximo de view/wire) pela janela efetiva (limite incluído); o medidor mostra a projeção do próximo prompt sobre a janela completa do modelo. |
|
|
131
|
+
| `trimProtectedTail` | `6` | As últimas N mensagens nunca são dobradas. |
|
|
133
132
|
| `trimMaxFoldsPerHour` | `30` | Teto de cadência de folds por hora rolante para o modelo secundário (os de emergência ficam fora). |
|
|
134
133
|
| `trimSideModel` | não definida | Rota do modelo secundário que escreve os resumos. Vazia = seguir o provider/model da sessão, sem herdar o effort da chamada; a ladder distillation também usa esta rota. O effort do resumo aceita um pin manual independente; se não fixado, os metadados do modelo recomendam o nível de reasoning habilitado mais baixo; se o modelo só tiver interruptor sim/não, escolhe-se off. Se não houver suporte a reasoning ou os metadados não estiverem disponíveis, nenhum effort é enviado e prevalece o comportamento padrão do modelo/adaptador. |
|
|
135
134
|
| `trimFoldFallbackModel` | não definida | Rota de nova tentativa quando o modelo secundário de resumos falha; um fold de pressão degrada então para mecânico. Vazia = sem fallback. O modelo de fallback do fold escolhido manualmente tem um pin de effort independente; sem pin, usa a mesma recomendação por metadados do modelo de resumo e, sem metadados, o padrão do modelo. Escolha uma rota com folga em cooldowns, controle de risco e concorrência. |
|
|
@@ -138,7 +137,7 @@ Todas as chaves ficam em Configurações → dsh-switchman; os padrões vêm de
|
|
|
138
137
|
|
|
139
138
|
**Caminhos do gatilho.** As verificações de degraus rodam na fronteira de ociosidade e, como fallback para hosts onde os eventos de estado de ociosidade são inalcançáveis, após cada conclusão do fluxo do modelo (limitadas a uma avaliação a cada 60 s por sessão). Cada decisão — folds e no-ops igualmente — é anexada como uma linha `key=value` com timestamp a `decisions.log` no diretório do estado de folds (veja `trimStateDir`), dando aos folds uma trilha de auditoria offline; o vocabulário de linhas (`view-applied`, linhas de decisão/resultado de folds, `surface-replace`, `surface-replace skipped reason=…`) está catalogado em [docs/context-trim.md](./docs/context-trim.md).
|
|
140
139
|
|
|
141
|
-
**Verdade do fio e estado estacionário.** As linhas de decisão carregam `view=<n>` e, depois que uma resposta chega, `wire=<n>` — o prompt real do provedor (entrada sem cache + leitura de cache + escrita de cache, amostrado do evento de uso do stream). A estimativa da view conta apenas o array de mensagens e sempre lê menos que o fio, pelo overhead fixo (medido ≈ 17.3k: system prompt + esquemas de ferramentas + persona), então os degraus de pressão e de emergência avaliam sobre `max(view, wire)`, e só `wire` é uma leitura do tamanho do prompt. Numa janela de
|
|
140
|
+
**Verdade do fio e estado estacionário.** As linhas de decisão carregam `view=<n>` e, depois que uma resposta chega, `wire=<n>` — o prompt real do provedor (entrada sem cache + leitura de cache + escrita de cache, amostrado do evento de uso do stream). A estimativa da view conta apenas o array de mensagens e sempre lê menos que o fio, pelo overhead fixo (medido ≈ 17.3k: system prompt + esquemas de ferramentas + persona), então os degraus de pressão e de emergência avaliam sobre `max(view, wire)`, e só `wire` é uma leitura do tamanho do prompt. Numa janela de 200k o dente-de-serra saudável deixa o fio em ≈ 40k logo após um fold ↔ 64–90k no seguinte (≈20%–45% da janela), um fold a cada ~45k de crescimento bruto, com o teto fixado perto de 90k pelo degrau de pressão em vez da janela. Se `view` sobe sem que nenhuma linha `surface-replace` apareça, leia as linhas de salto (`incomplete-seqs`, `no-service`, `compaction-lock`).
|
|
142
141
|
|
|
143
142
|
**Épocas de compactação do host.** As referências de fold são ancoradas em ids de mensagens e hashes de conteúdo; quando o próprio host compacta o histórico reenviado, o livro inteiro envelhece de uma vez: nenhum bloco se localiza, a view retrocede silenciosamente ao histórico bruto (fail-open — o registro de decisões anota `view-applied applied=0`) e o plugin reancora sua linha de base de crescimento na view pós-compactação na requisição seguinte. A compactação do host é, assim, a camada de aparo de último recurso; os folds do plugin fazem o trabalho fino dentro de uma época do host. Alguns despachos entregam arrays de solicitação ou objetos de opções totalmente congelados (o laço de agente atual congela em profundidade as requisições montadas); para eles, o `injectView` informa o resultado no registro de decisões: `nothing-to-apply` (nenhum bloco de fold localizado — o histórico bruto É a view), `in-place`/`swapped` (a view dobrada seguiu com a requisição) ou `none` (havia um fold, mas o despacho congelado não podia carregá-lo — o histórico bruto segue pelo fio). **A substituição de superfície é o caminho de envio quando disponível** (`surfaceFold`, ativado por padrão): na fronteira serial `agent/turn-stopping` mais uma varredura de ociosidade, o plugin anexa o evento de medição shadow-price no estilo do host e UM replacement `user/message` carregando `surfaceOp {op:'replace', startSeq, endSeq}` com `sourceEventSeqs` cobrindo cada nó de superfície sombreado — o mesmo mecanismo que a própria compactação do host usa —, de modo que um fold confirmado chega ao fio a partir do nível de origem, despachos congelados incluídos. Enquanto os despachos recentes de uma sessão registram `none`, o plugin trata a view como somente medição: o nível de água mede em vez disso a contagem relatada pelo provedor (o degrau force e a entrega automática continuam funcionando), os ciclos de fold pausam em vez de queimar chamadas ao resumidor, e o banner de aparo marca a linha com `wire=raw` (folds not shipping; watermark reads the tally); hosts sem o mecanismo de superfície (ou com a flag desligada) mantêm exatamente esse comportamento antigo.
|
|
144
143
|
|
|
@@ -163,6 +162,12 @@ Todas as chaves ficam em Configurações → dsh-switchman; os padrões vêm de
|
|
|
163
162
|
- As linhas de protocolo (`[SWITCHMAN:LANG|POOLS|WATERMARK|TEAMS]`) ficam deliberadamente em inglês e estáveis a byte — não as localize.
|
|
164
163
|
- `npm pack --dry-run` deve continuar na forma auditada de 60 arquivos / ~380 kB (~1,26 MB descompactado; `docs/` fica de fora).
|
|
165
164
|
|
|
165
|
+
## Downloads
|
|
166
|
+
|
|
167
|
+
Todos os downloads do npm desde a primeira publicação, acumulados — desenhados a partir da [API oficial de downloads do npm](https://api.npmjs.org/) e atualizados diariamente pelo GitHub Actions ([script do gráfico](scripts/downloads-chart.mjs)):
|
|
168
|
+
|
|
169
|
+

|
|
170
|
+
|
|
166
171
|
## License
|
|
167
172
|
|
|
168
173
|
MIT
|