dsh-switchman 1.8.1 → 1.9.0
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 +41 -1
- package/README.es.md +41 -1
- package/README.fr.md +41 -1
- package/README.it.md +41 -1
- package/README.ja.md +41 -1
- package/README.ko.md +41 -1
- package/README.md +41 -1
- package/README.pt.md +41 -1
- package/README.ru.md +41 -1
- package/README.zh-TW.md +41 -1
- package/README.zh.md +41 -1
- package/client.js +399 -2
- package/cordis.patch.yml +32 -0
- package/host/config.js +40 -0
- package/host/context-trim/fork.js +168 -0
- package/host/context-trim/index.js +830 -0
- package/host/context-trim/metrics.js +104 -0
- package/host/context-trim/state.js +241 -0
- package/host/context-trim/summarizer.js +179 -0
- package/host/context-trim/trigger.js +122 -0
- package/host/context-trim/view.js +316 -0
- package/host/context-watch.js +22 -2
- package/host/subagent-model.js +1 -1
- package/index.js +15 -1
- package/package.json +4 -1
package/README.ru.md
CHANGED
|
@@ -102,8 +102,48 @@ bash <install-dir>/skills/db-query/scripts/setup.sh
|
|
|
102
102
|
|
|
103
103
|
**Маршрутизация по намерению** (по умолчанию недоступна; нужны классификатор + хотя бы один кандидат + включённый главный переключатель): `intentEnabled` = выключен (пока выключен, вход Auto скрыт, а сессии, где Auto уже выбран, идут по цепочке запасных моделей); маршрут классификатора не задан; тип классификатора `chat`; список кандидатов пуст (предустановленные категории участвуют в маршрутизации, только если у них указана модель); окно кэша `300` с / порог уверенности для переключения `80` / тайм-аут классификации `60000` мс; история `6` сообщений / `2400` символов; `intentContextWindow` = `200000`.
|
|
104
104
|
|
|
105
|
+
**Обрезка контекста**: `trimEnabled` = включено; `trimMode` = `auto` (полностью автоматически); ворота роста `22500` + прирост `50000` токенов; давление `60%` / авария `95%`; защищённый хвост `6` сообщений; потолок частоты fold-ов `6` в час; боковая модель не задана (наследует модель сессии) — подробности в разделе «Автоматическая обрезка контекста» ниже.
|
|
106
|
+
|
|
105
107
|
**Что важно знать из коробки**: ① то, что маршрутизация по намерению недоступна из коробки, — намеренное решение; включается в три шага (классификатор, кандидаты, переключатель); ② эффективное окно Auto из коробки равно 200000 — защитная планка гарантирует 0.8×окна ≥ force (150000), поэтому линия сжатия ядра (160000) всегда стоит после линии плавной передачи (150000); ③ заметнее всего из коробки троица уровней: 80k напоминает делегировать / 120k ужимает чтение / 150k сам делает резервную копию и передаёт управление — без каких-либо настроек.
|
|
106
108
|
|
|
109
|
+
## Автоматическая обрезка контекста
|
|
110
|
+
|
|
111
|
+
Длинные сессии остаются дешёвыми: прожитые диапазоны разговора сворачиваются (fold) в компактные детерминированные резюме — полностью автоматически и без разрушения кэша промптов провайдера. На границе простоя движок обрезки (`host/context-trim/`) выбирает диапазоны, стоящие fold, боковая модель пишет резюме (только при аварийном давлении срабатывает механический fold без вызова боковой модели), и fold фиксируется в состоянии fold-ов сессии. С этого момента каждый исходящий запрос пересобирается из этого состояния — блоки резюме заменяют свёрнутые диапазоны, живой хвост остаётся нетронутым. Хранимая сессия никогда не переписывается, и посреди стрима ничего не происходит.
|
|
112
|
+
|
|
113
|
+
Уровни автоматизации (`trimMode`):
|
|
114
|
+
|
|
115
|
+
- **`off`** — только измерения: сэмплирование расхода и попаданий кэша продолжается; без баннера и без fold-ов.
|
|
116
|
+
- **`advisory`** — модель сессии сворачивает сама: ей открываются инструменты `ctx_trim_fold` и `ctx_trim_status` плюс заголовок протокола.
|
|
117
|
+
- **`auto`** (по умолчанию) — всё вышеперечисленное плюс автоматические fold-ы на границе простоя, тремя ступенями: ворота роста (рост ≥ `trimGrowthTokens`, отсчитываемый от низшей точки после последнего fold-а — этот якорь сохраняет ворота взведёнными после fold-ов, фиксирующихся на высоких точках view — И непрерывный сжимаемый прирост ≥ `trimIncrementTokens`), ступень давления (`trimPressurePercent` окна контекста) и аварийная ступень (`trimEmergencyPercent` — механический fold с собственным охлаждением).
|
|
118
|
+
|
|
119
|
+
Все ключи живут в разделе Настройки → dsh-switchman; значения по умолчанию — из `host/config.js`:
|
|
120
|
+
|
|
121
|
+
| Ключ | По умолчанию | Смысл |
|
|
122
|
+
| --- | --- | --- |
|
|
123
|
+
| `trimEnabled` | `true` | Главный выключатель. ВЫКЛ полностью отключает fold-ы и метрики (слушатель вырождается в чистый pass-through). |
|
|
124
|
+
| `trimMode` | `auto` | `off` только измерения / `advisory` fold-ы по решению модели / `auto` fold-ы по решению системы. |
|
|
125
|
+
| `trimGrowthTokens` | `22500` | Ворота роста: fold, когда исходящая view выросла на столько с прошлого fold-а. |
|
|
126
|
+
| `trimIncrementTokens` | `50000` | Спутник ворот: непрерывный сжимаемый прирост тоже должен достичь этого размера. |
|
|
127
|
+
| `trimPressurePercent` | `60` | Ступень давления: fold, когда использование view достигает этого процента окна контекста. |
|
|
128
|
+
| `trimEmergencyPercent` | `95` | Аварийная ступень: принудительный механический fold (без вызова боковой модели) на этом проценте. |
|
|
129
|
+
| `trimWindowTokens` | `0` | Эффективный лимит окна для расчёта уровней: считается от min(окно модели, лимит). `0` = следует за `wmForceTokens`. |
|
|
130
|
+
| `trimProtectedTail` | `6` | Последние N сообщений никогда не сворачиваются. |
|
|
131
|
+
| `trimMaxFoldsPerHour` | `6` | Потолок частоты fold-ов боковой модели за скользящий час (аварийные не в счёт). |
|
|
132
|
+
| `trimSideModel` | не задан | Маршрут боковой модели, пишущей резюме. Пусто = унаследовать текущую модель сессии. |
|
|
133
|
+
| `trimStateDir` | не задан | Переопределяет каталог состояния fold-ов. Пусто = `<dshHome>/.dsh-switchman/state/trim/`. |
|
|
134
|
+
|
|
135
|
+
**Пути срабатывания.** Проверки ступеней выполняются на границе простоя и — как запасной путь для хостов, где события статуса простоя недостижимы — после завершения каждого потока модели (не чаще одной оценки в 60 с на сессию). Каждое решение — и fold-ы, и no-op-ы — дописывается одной JSON-строкой в `decisions.log` внутри каталога состояния fold-ов (см. `trimStateDir`), что даёт fold-ам офлайн-журнал аудита.
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
**Эпохи сжатия на стороне хоста.** Ссылки fold привязаны к идентификаторам сообщений и хешам содержимого, поэтому сжатие, выполненное самим хостом и заменяющее повторно отправляемую историю, старит весь журнал разом: ни один блок не находит своей позиции, view молча откатывается к исходной истории (fail-open — в журнал решений записывается `view-applied applied=0`), а плагин при следующем запросе перепривязывает базовую линию роста к виду после сжатия. Таким образом, сжатие хоста — запасной слой обрезки последней инстанции, а fold плагина выполняет тонкую работу внутри одной эпохи хоста. Некоторые диспетчеры передают полностью замороженные массивы запросов или объекты опций; для них плагин корректно деградирует (`injected=none` в журнале решений), а изменяемый диспетчер, порождающий ответ модели, по-прежнему получает свёрнутое представление.
|
|
139
|
+
**Как fold-ы берегут попадания кэша.** Каждый fold один раз переплачивает префикс; цель — амортизированная стоимость, а не стопроцентное попадание. Движок соблюдает контракт кэша: fold-ы только добавляются — frontier движется только вперёд, замороженная зона больше не редактируется; view пересобирается детерминированно из (история, состояние fold-ов), поэтому сериализованный префикс между fold-ами остаётся побайтово тем же и кэш провайдера продолжает попадать; границы fold-а никогда не разрывают пару tool-call ассистента и его результат; последние `trimProtectedTail` сообщений освобождены от свёртки; и всё отказывает открыто — внутренняя ошибка вырождается в pass-through, но не в сломанный запрос.
|
|
140
|
+
|
|
141
|
+
**Арбитраж компакции.** Два автоматических триммера поверх одной истории резюмировали бы её дважды и разрушали бы frontier друг друга, поэтому `cordis.patch.yml` ставит `auto: false` на строки `dsh-compaction-basic` хоста: context-trim становится единственным смысловым триммером. Ручной `/compact` продолжает работать, а передача уровня force (она одалживает именно этот ручной путь) остаётся нетронутой. Восстановление после переполнения переходит к обрезке: попытка сверх окна падает один раз, затем аварийная ступень сворачивает view, чтобы следующая попытка поместилась.
|
|
142
|
+
|
|
143
|
+
**Наследование при fork-е.** Форкнутая сессия (fork субагента или резервная копия передачи) наследует состояние fold-ов родителя по принципу copy-on-fork — но только если состояние родителя существует и история ребёнка реально разрешает frontier родителя; иначе ребёнок стартует с чистого листа. Одно наследование на ребёнка, идемпотентно между перезапусками.
|
|
144
|
+
|
|
145
|
+
**Баннер уровней читает view.** Баннер уровней показывает число токенов исходящей view (то, что модель реально видит после свёртки) вместо накопленного счётчика, так что сильно свёрнутая сессия больше не пригвождает уровень к ступени hard.
|
|
146
|
+
|
|
107
147
|
## Как это работает
|
|
108
148
|
|
|
109
149
|
- Host-половина (`index.js` + `host/`) внедряет побайтово стабильные секции системного промпта (язык / полосы / протокол уровня воды / команда) плюс живую строку уровня через хвостовой runtime-context-снимок (канал, который только дописывает, а не переписывает начало промпта, поэтому промпт-кэш поставщика остаётся целым), а также двойной шлюз бюджета чтения и enforce и четыре слэш-команды (ctx-тройка + `/vision`). Все настройки после сохранения вступают в силу при следующей сборке промпта — без перезапуска.
|
|
@@ -113,7 +153,7 @@ bash <install-dir>/skills/db-query/scripts/setup.sh
|
|
|
113
153
|
|
|
114
154
|
## Обслуживание
|
|
115
155
|
|
|
116
|
-
- Если после обновления DSH изменился список плагинов заводских пресетов, пересинхронизируйте `cordis.patch.yml` из новых `presets/*.patch.yml` (сохранив doctrine suffix) и переустановите.
|
|
156
|
+
- Если после обновления DSH изменился список плагинов заводских пресетов, пересинхронизируйте `cordis.patch.yml` из новых `presets/*.patch.yml` (сохранив doctrine suffix и арбитраж компакции — `auto: false` в строках `compaction-basic`) и переустановите.
|
|
117
157
|
- Строки протокола (`[SWITCHMAN:LANG|POOLS|WATERMARK|TEAMS]`) намеренно оставлены на английском и стабильны побайтово — не локализуйте их.
|
|
118
158
|
- `npm pack --dry-run` должен сохранять аудированную форму: 50 файлов / ~205 kB (скриншоты из `docs/` в пакет не входят).
|
|
119
159
|
|
package/README.zh-TW.md
CHANGED
|
@@ -102,8 +102,48 @@ bash <安裝目錄>/skills/db-query/scripts/setup.sh
|
|
|
102
102
|
|
|
103
103
|
**意圖識別**(預設不可用,需設定分類器 + 至少一個候選 + 打開主開關):`intentEnabled` = 關(關閉時 Auto 入口隱藏,已選 Auto 的對話走備援鏈);分類器路由未設定;分類器類型 `chat`;候選清單空(預置分類需填模型才參與路由);快取視窗 `300` 秒 / 切換信心閾值 `80` / 分類逾時 `60000` ms;歷史 `6` 則 / `2400` 字元;`intentContextWindow` = `200000`。
|
|
104
104
|
|
|
105
|
+
**上下文裁剪**:`trimEnabled` = 開;`trimMode` = `auto`(全自動);增長閘門 `22500` token + 增量 `50000` token;壓力 `60%` / 緊急 `95%`;保護尾部 `6` 則;折疊節奏上限每小時 `6` 次;side model 未設定(繼承對話模型)——詳見下文「自動上下文裁剪」一節。
|
|
106
|
+
|
|
105
107
|
**開箱要點**:① 意圖識別開箱不可用是有意設計,三步開啟(分類器、候選、開關);② Auto 有效視窗開箱即為 200000——護欄保證 0.8×視窗 ≥ force 級(150000),核心壓縮線(160000)永遠在平滑交接線(150000)之後;③ 開箱最有感的是水位三件套:80k 提醒委派 / 120k 收斂讀取 / 150k 自動備份交接,無須任何設定。
|
|
106
108
|
|
|
109
|
+
## 自動上下文裁剪
|
|
110
|
+
|
|
111
|
+
長對話也能保持便宜:已被消化掉的對話區間會被折疊成緊湊的確定性摘要——全自動完成,且不破壞服務商提示詞快取。在閒置邊界上,裁剪引擎(`host/context-trim/`)挑出值得折疊的區間,由 side model 寫出摘要(僅在緊急壓力下才改走無 side model 呼叫的機械折疊),並把 fold 提交進該對話的折疊狀態。此後每個出站請求都從該狀態重建——摘要塊頂替被折疊的區間,活動尾部原樣保留。儲存的對話從不被改寫,也絕不在串流過程中動手。
|
|
112
|
+
|
|
113
|
+
自動化層級(`trimMode`):
|
|
114
|
+
|
|
115
|
+
- **`off`**——只測量:用量與快取命中取樣照常執行;無橫幅、無折疊。
|
|
116
|
+
- **`advisory`**——對話模型自己折疊:向其暴露 `ctx_trim_fold` 與 `ctx_trim_status` 工具和協定頭。
|
|
117
|
+
- **`auto`**(預設)——以上全部,外加閒置邊界上的自動折疊,分三級:增長閘門(自上次折疊後的低谷起算的增長 ≥ `trimGrowthTokens`——該錨點保證高位折疊後閘門依然有效——且連續可壓縮增量 ≥ `trimIncrementTokens`)、壓力級(上下文視窗的 `trimPressurePercent`)、緊急級(`trimEmergencyPercent`——帶獨立冷卻的機械折疊)。
|
|
118
|
+
|
|
119
|
+
所有鍵位於 設定 → dsh-switchman;預設值出自 `host/config.js`:
|
|
120
|
+
|
|
121
|
+
| 鍵 | 預設值 | 含義 |
|
|
122
|
+
| --- | --- | --- |
|
|
123
|
+
| `trimEnabled` | `true` | 總開關。關閉後折疊與度量全部停用(監聽器退化為純透傳)。 |
|
|
124
|
+
| `trimMode` | `auto` | `off` 只測量 / `advisory` 模型自折 / `auto` 系統自動折。 |
|
|
125
|
+
| `trimGrowthTokens` | `22500` | 增長閘門:出站 view 自上次 fold 以來增長到該值即觸發折疊。 |
|
|
126
|
+
| `trimIncrementTokens` | `50000` | 閘門搭檔:連續可壓縮增量也須達到該規模。 |
|
|
127
|
+
| `trimPressurePercent` | `60` | 壓力級:view 用量達到上下文視窗該百分比即折疊。 |
|
|
128
|
+
| `trimEmergencyPercent` | `95` | 緊急級:到該百分比強制機械折疊(無 side model 呼叫)。 |
|
|
129
|
+
| `trimWindowTokens` | `0` | 視窗上限:壓力與緊急檔按 min(模型視窗, 上限) 計算。`0` = 跟隨 `wmForceTokens`。 |
|
|
130
|
+
| `trimProtectedTail` | `6` | 最後 N 則訊息永不折疊。 |
|
|
131
|
+
| `trimMaxFoldsPerHour` | `6` | 每滾動小時 side model 折疊的節奏上限(緊急級豁免)。 |
|
|
132
|
+
| `trimSideModel` | 未設定 | 寫摘要的 side model 路由。留空 = 繼承對話目前模型。 |
|
|
133
|
+
| `trimStateDir` | 未設定 | 折疊狀態目錄覆蓋。留空 = `<dshHome>/.dsh-switchman/state/trim/`。 |
|
|
134
|
+
|
|
135
|
+
**觸發路徑。** 級別檢查在閒置邊界上執行;在閒置狀態事件不可達的宿主上,兜底改為在每次模型串流完成後也檢查一次(每個對話節流為每 60 秒至多評估一次)。每個決策——fold 與 no-op 皆然——都會作為一行 JSON 附加進裁剪狀態目錄(見 `trimStateDir`)下的 `decisions.log`,為 fold 留下離線稽核軌跡。
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
**宿主壓縮紀元。** fold 引用錨定在訊息 id 與內容雜湊上,因此宿主自身的壓縮一旦替換了重發歷史,整本帳就會同時老化:所有塊都無法定位,view 靜默回退為原始歷史(fail-open——決策日誌會記錄 `view-applied applied=0`),外掛在下一次請求時把增長基線重錨到壓縮後的視圖。宿主壓縮因此是兜底的裁剪層,外掛 fold 負責單一宿主紀元內的細粒度工作。 部分派發的請求陣列或選項物件是宿主凍結的:對這些派發外掛 fail-open(決策日誌記 `injected=none`),真正產出模型回應的可變派發仍會收到摺疊視圖。
|
|
139
|
+
**fold 如何保住快取命中。** 每次 fold 都要為前綴重付一次;目標是攤銷成本,不是滿分命中率。引擎守住快取契約:fold 只附加——frontier 只前進,凍結區永不再改;view 由(歷史, 折疊狀態)確定性重建,因此兩次 fold 之間序列化前綴位元組不變,服務商快取持續命中;fold 邊界絕不把 assistant 的 tool-call 與其 tool 結果拆開;最後 `trimProtectedTail` 則訊息豁免;一切皆 fail-open——內部出錯退化為透傳,絕不產生壞請求。
|
|
140
|
+
|
|
141
|
+
**壓縮仲裁。** 兩個自動裁剪器搶同一份歷史會互相重複摘要、互相摧毀 frontier,因此 `cordis.patch.yml` 給宿主的 `dsh-compaction-basic` 行設了 `auto: false`:context-trim 成為唯一語義裁剪器。手動 `/compact` 照常可用,force 級交接(借用的正是這條手動路徑)不受影響。溢出恢復改由裁剪承擔:超視窗的那次嘗試失敗一次,隨後緊急級折好 view,下一次嘗試就能裝下。
|
|
142
|
+
|
|
143
|
+
**fork 繼承。** 被 fork 的對話(子代理 fork 或交接備份)按 copy-on-fork 繼承父對話的折疊狀態——但僅當父狀態存在且子對話歷史確實能解析到父 frontier;否則子對話從乾淨狀態起步。每個子對話只繼承一次,跨重啟冪等。
|
|
144
|
+
|
|
145
|
+
**水位讀的是 view。** 水位橫幅報的是出站 view 的 token 數(折疊後模型真正看到的部分),不再是儲存側計數,重度折疊的對話因此不會再把水位釘死在 hard 級。
|
|
146
|
+
|
|
107
147
|
## 運作原理
|
|
108
148
|
|
|
109
149
|
- Host 半(`index.js` + `host/`)注入位元組恆定的系統提示詞段(語言 / 泳道 / 水位協定 / 團隊),即時水位線改走尾部 runtime-context 快照通道(只附加、不改寫提示詞頭部,廠商 prompt cache 不受影響)、讀取預算與 enforce 雙閘、四個斜線指令(ctx 三件套 + `/vision`)。設定儲存後下一輪提示詞組裝即生效,無須重新啟動。
|
|
@@ -113,7 +153,7 @@ bash <安裝目錄>/skills/db-query/scripts/setup.sh
|
|
|
113
153
|
|
|
114
154
|
## 維護須知
|
|
115
155
|
|
|
116
|
-
- DSH 升級後若出廠預設外掛清單有變,從新的 `presets/*.patch.yml` 重新同步 `cordis.patch.yml`(保留 doctrine suffix
|
|
156
|
+
- DSH 升級後若出廠預設外掛清單有變,從新的 `presets/*.patch.yml` 重新同步 `cordis.patch.yml`(保留 doctrine suffix 與壓縮仲裁——`compaction-basic` 行上的 `auto: false`),然後重裝。
|
|
117
157
|
- 協定行(`[SWITCHMAN:LANG|POOLS|WATERMARK|TEAMS]`)刻意保持英文且位元組穩定——不要在地化。
|
|
118
158
|
- `npm pack --dry-run` 應保持稽核過的 50 個檔案 / ~205 kB 形態(`docs/` 截圖不進包)。
|
|
119
159
|
|
package/README.zh.md
CHANGED
|
@@ -102,8 +102,48 @@ bash <安装目录>/skills/db-query/scripts/setup.sh
|
|
|
102
102
|
|
|
103
103
|
**意图识别**(默认不可用,需配置分类器 + 至少一个候选 + 打开主开关):`intentEnabled` = 关(关闭时 Auto 入口隐藏,已选 Auto 的会话走兜底链);分类器路由未设置;分类器类型 `chat`;候选列表空(预置分类需填模型才参与路由);缓存窗口 `300` 秒 / 切换置信度 `80` / 分类超时 `60000` ms;历史 `6` 条 / `2400` 字符;`intentContextWindow` = `200000`。
|
|
104
104
|
|
|
105
|
+
**上下文裁剪**:`trimEnabled` = 开;`trimMode` = `auto`(全自动);增长闸门 `22500` token + 增量 `50000` token;压力 `60%` / 紧急 `95%`;保护尾部 `6` 条;折叠节奏上限每小时 `6` 次;side model 未设置(继承会话模型)——详见下文「自动上下文裁剪」一节。
|
|
106
|
+
|
|
105
107
|
**开箱要点**:① 意图识别开箱不可用是有意设计,三步开启(分类器、候选、开关);② Auto 有效窗口开箱即为 200000——护栏保证 0.8×窗口 ≥ force 档(150000),核心压缩线(160000)永远在平滑交接线(150000)之后;③ 开箱最有感的是水位三件套:80k 提醒委派 / 120k 收敛读取 / 150k 自动备份交接,无需任何设置。
|
|
106
108
|
|
|
109
|
+
## 自动上下文裁剪
|
|
110
|
+
|
|
111
|
+
长会话也能保持便宜:已被消化掉的对话区间会被折叠成紧凑的确定性摘要——全自动完成,且不破坏服务商提示词缓存。在空闲边界上,裁剪引擎(`host/context-trim/`)挑出值得折叠的区间,由 side model 写出摘要(仅在紧急压力下才改走无 side model 调用的机械折叠),并把 fold 提交进该会话的折叠状态。此后每个出站请求都从该状态重建——摘要块顶替被折叠的区间,活动尾部原样保留。存储的会话从不被改写,也绝不在流式过程中动手。
|
|
112
|
+
|
|
113
|
+
自动化层级(`trimMode`):
|
|
114
|
+
|
|
115
|
+
- **`off`**——只测量:用量与缓存命中采样照常运行;无横幅、无折叠。
|
|
116
|
+
- **`advisory`**——会话模型自己折叠:向其暴露 `ctx_trim_fold` 与 `ctx_trim_status` 工具和协议头。
|
|
117
|
+
- **`auto`**(默认)——以上全部,外加空闲边界上的自动折叠,分三档:增长闸门(自上次折叠后的低谷起算的增长 ≥ `trimGrowthTokens`——该锚点保证高位折叠后闸门依然有效——且连续可压缩增量 ≥ `trimIncrementTokens`)、压力档(上下文窗口的 `trimPressurePercent`)、紧急档(`trimEmergencyPercent`——带独立冷却的机械折叠)。
|
|
118
|
+
|
|
119
|
+
所有键位于 设置 → dsh-switchman;默认值出自 `host/config.js`:
|
|
120
|
+
|
|
121
|
+
| 键 | 默认值 | 含义 |
|
|
122
|
+
| --- | --- | --- |
|
|
123
|
+
| `trimEnabled` | `true` | 总开关。关闭后折叠与度量全部停用(监听器退化为纯透传)。 |
|
|
124
|
+
| `trimMode` | `auto` | `off` 只测量 / `advisory` 模型自折 / `auto` 系统自动折。 |
|
|
125
|
+
| `trimGrowthTokens` | `22500` | 增长闸门:出站 view 自上次 fold 以来增长到该值即触发折叠。 |
|
|
126
|
+
| `trimIncrementTokens` | `50000` | 闸门搭档:连续可压缩增量也须达到该规模。 |
|
|
127
|
+
| `trimPressurePercent` | `60` | 压力档:view 用量达到上下文窗口该百分比即折叠。 |
|
|
128
|
+
| `trimEmergencyPercent` | `95` | 紧急档:到该百分比强制机械折叠(无 side model 调用)。 |
|
|
129
|
+
| `trimWindowTokens` | `0` | 窗口上限:压力与紧急档按 min(模型窗口, 上限) 计算。`0` = 跟随 `wmForceTokens`。 |
|
|
130
|
+
| `trimProtectedTail` | `6` | 最后 N 条消息永不折叠。 |
|
|
131
|
+
| `trimMaxFoldsPerHour` | `6` | 每滚动小时 side model 折叠的节奏上限(紧急档豁免)。 |
|
|
132
|
+
| `trimSideModel` | 未设置 | 写摘要的 side model 路由。留空 = 继承会话当前模型。 |
|
|
133
|
+
| `trimStateDir` | 未设置 | 折叠状态目录覆盖。留空 = `<dshHome>/.dsh-switchman/state/trim/`。 |
|
|
134
|
+
|
|
135
|
+
**触发路径。** 档位检查在空闲边界上运行;在空闲状态事件不可达的宿主上,兜底改为在每次模型流式完成后也检查一次(每个会话节流为每 60 秒至多评估一次)。每个决策——fold 与 no-op 皆然——都会作为一行 JSON 追加进裁剪状态目录(见 `trimStateDir`)下的 `decisions.log`,为 fold 留下离线审计轨迹。
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
**宿主压缩纪元。** fold 引用锚定在消息 id 与内容哈希上,因此宿主自身的压缩一旦替换了重发历史,整本账就会同时老化:所有块都无法定位,view 静默回退为原始历史(fail-open——决策日志会记录 `view-applied applied=0`),插件在下一次请求时把增长基线重锚到压缩后的视图。宿主压缩因此是兜底的裁剪层,插件 fold 负责单个宿主纪元内的细粒度工作。 部分派发的请求数组或选项对象是宿主冻结的:对这些派发插件 fail-open(决策日志记 `injected=none`),真正产出模型响应的可变派发仍会收到折叠视图。
|
|
139
|
+
**fold 如何保住缓存命中。** 每次 fold 都要为前缀重付一次;目标是摊销成本,不是满分命中率。引擎守住缓存契约:fold 只追加——frontier 只前进,冻结区永不再改;view 由(历史, 折叠状态)确定性重建,因此两次 fold 之间序列化前缀字节不变,服务商缓存持续命中;fold 边界绝不把 assistant 的 tool-call 与其 tool 结果拆开;最后 `trimProtectedTail` 条消息豁免;一切皆 fail-open——内部出错退化为透传,绝不产生坏请求。
|
|
140
|
+
|
|
141
|
+
**压缩仲裁。** 两个自动裁剪器抢同一份历史会互相重复摘要、互相摧毁 frontier,因此 `cordis.patch.yml` 给宿主的 `dsh-compaction-basic` 行设了 `auto: false`:context-trim 成为唯一语义裁剪器。手动 `/compact` 照常可用,force 档交接(借用的正是这条手动路径)不受影响。溢出恢复改由裁剪承担:超窗的那次尝试失败一次,随后紧急档折好 view,下一次尝试就能装下。
|
|
142
|
+
|
|
143
|
+
**fork 继承。** 被 fork 的会话(子代理 fork 或交接备份)按 copy-on-fork 继承父会话的折叠状态——但仅当父状态存在且子会话历史确实能解析到父 frontier;否则子会话从干净状态起步。每个子会话只继承一次,跨重启幂等。
|
|
144
|
+
|
|
145
|
+
**水位读的是 view。** 水位横幅报的是出站 view 的 token 数(折叠后模型真正看到的部分),不再是存储侧计数,重度折叠的会话因此不会再把水位钉死在 hard 档。
|
|
146
|
+
|
|
107
147
|
## 工作原理
|
|
108
148
|
|
|
109
149
|
- Host 半(`index.js` + `host/`)注入字节恒定的系统提示词段(语言 / 泳道 / 水位协议 / 团队),实时水位行改走尾部 runtime-context 快照通道(只追加、不改写提示词头部,供应商提示词缓存不受影响)、读预算与 enforce 双闸、四个斜杠命令(ctx 三件套 + `/vision`)。设置保存后下一轮提示词装配即生效,无需重启。
|
|
@@ -113,7 +153,7 @@ bash <安装目录>/skills/db-query/scripts/setup.sh
|
|
|
113
153
|
|
|
114
154
|
## 维护注意
|
|
115
155
|
|
|
116
|
-
- DSH 升级后若出厂预设插件列表有变,从新的 `presets/*.patch.yml` 重新同步 `cordis.patch.yml`(保留 doctrine suffix
|
|
156
|
+
- DSH 升级后若出厂预设插件列表有变,从新的 `presets/*.patch.yml` 重新同步 `cordis.patch.yml`(保留 doctrine suffix 与压缩仲裁——`compaction-basic` 行上的 `auto: false`),然后重装。
|
|
117
157
|
- 协议行(`[SWITCHMAN:LANG|POOLS|WATERMARK|TEAMS]`)刻意保持英文且字节稳定——不要本地化。
|
|
118
158
|
- `npm pack --dry-run` 应保持审计过的 50 文件 / ~205 kB 形态(`docs/` 截图不进包)。
|
|
119
159
|
- **零运行时依赖——硬性不变量。** 宿主侧包(`@deepseek-ai/schemastery`、cordis 等)只允许声明为 `peerDependencies`,由运行中的 DSH 用它自己的副本满足。普通 `dependencies` 会被物理安装进 profile 工作区(`<profile>/node_modules/…`),从而对同处 profile 的其他插件遮蔽宿主副本——1.7.0 把 schemastery 声明为普通依赖时,正是这个机制让 dshmarket 插件市场崩溃(一个进程里出现两份 schemastery,市场产生的 schema 与宿主不再同类)。`scripts/validate.mjs` 会在 `dependencies` 再次出现时直接失败;因此安装、升级、卸载 dsh-switchman 都不会再影响 dshmarket 或任何其他社区包在运行时解析到的模块。
|