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.ru.md CHANGED
@@ -12,30 +12,27 @@
12
12
 
13
13
  Если работать в DSH подольше, рано или поздно упираешься в две вещи: сессия тяжелеет с каждым сообщением — история раздувает контекст до сотен тысяч токенов, модель начинает забывать, тормозить и дорожать, а ручной /compact при каждом сжатии ещё и теряет детали; и главная модель всё делает сама — прочитать файл, прогнать тест, сверить данные: всё она грызёт сама, медленно и дорого, хотя большая часть этой работы по праву досталась бы дешёвой модели.
14
14
 
15
- dsh-switchman — плагин для [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH). После установки главная модель перестаёт «делать всё сама» и становится диспетчером: замеряет уровень воды, выбирает полосу, раздаёт задачи, принимает работу. Это не новая модель, а свод правил диспетчеризации, пристёгнутый к DSH, плюс страница настроек. Конкретно он делает восемь вещей:
15
+ dsh-switchman — плагин для [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH). После установки главная модель по-прежнему работает сама — просто делает это с большим разбором: лёгкую мелочёвку отправляет на дешёвые полосы, срочное и сложное через маршрутизацию намерений приземляет на подходящую модель, а себе оставляет только то, что действительно требует личного участия; отсекает лишнее и дистиллирует суть — переваренные участки разговора сворачиваются в компактные резюме, уровень воды следит за каждым расходом, и контекст путешествует всегда налегке; а когда нагрузка превышает одну пару рук, приглашает постоянных товарищей по команде, которые делят работу на общей доске задач, пока он занимается диспетчеризацией и приёмкой. Это не новая модель, а свод правил диспетчеризации, пристёгнутый к DSH, плюс страница настроек. Конкретно он делает девять вещей:
16
16
 
17
- **1. Уровень воды в контексте: длинная сессия не переполняется.** Каждый ход подсчитывает токены сессии в реальном времени, и три линии уровня ужесточаются по нарастающей: 80k (soft, настраивается) подсказывает «пора делегировать»; 95k (hard) урезает бюджет разового чтения и подталкивает к завершению; 150k (force) запускает автоматическую передачу — записывает документ передачи (append-only лог сессии — сам по себе полная резервная копия), сжимает контекст и будит сессию, работа не обрывается. Фоновые субагенты, которые ещё бегут в момент передачи, тоже не теряются: id, описания задач и пути к отчётам записываются в документ передачи, и продолжившаяся сессия знает, куда идти за отчётами, а не раздаёт работу заново. У каждого отправленного субагента свой жёсткий потолок: доработав до него, он завершается резюме HANDOFF. Если автоматическое вмешательство работает не так, как вам нужно, возьмите управление в свои руки в любой момент: `/ctx-pause` останавливает все действия по уровню (замер продолжает работать, хвостовая строка уровня в реальном времени переключается на paused — вмешательство просто перестаёт действовать), `/ctx-resume` всё возвращает в любой момент — после перезапуска DSH вмешательство тоже вернётся само, вы временно отпускаете, а не выключаете навсегда; `/ctx-handover` не ждёт, пока уровень дойдёт до верха, и запускает ту же передачу по требованию — записать документ передачи, сжать контекст, разбудить сессию (сессию сначала подводят к границе простоя, поэтому результат может занять несколько минут).
17
+ **1. Автоматическая обрезка контекста: сессия длиннеет, стоимость остаётся плоской.** Ручной `/compact` заставляет ждать, теряет детали и пробивает prompt-кэш поставщика. Движок обрезки автоматизирует всё это: переваренные участки разговора на границах простоя сворачиваются в компактные детерминированные резюме (пишет их side-модель; под аварийным давлением свёртка механическая, без вызова модели), и с тех пор каждый исходящий запрос собирается заново из состояния свёртки — блоки резюме замещают свёрнутые участки, живой хвост сохраняется слово в слово. Сохранённый лог сессии никогда не переписывается, и стрим в разгаре никто не трогает. Свёртки только добавляются, а сборка детерминирована: сериализованный префикс между свёртками байт в байт неизменен, и кэш поставщика продолжает попадать; любой внутренний сбой уходит в fail-open к прозрачному пропуску — битого запроса не будет. Три полностью автоматические ступени (рост / давление / авария) плюс advisory-режим, где свёртку делает сама модель — механика внизу, в разделе «Автоматическая обрезка контекста».
18
18
 
19
- **2. Шесть пулов диспетчеризации: под каждую работу — своя модель.** Лёгкий пул (economy — мелкие массовые задачи), механический (mechanical — шаблонные переработки), основной (main — повседневный кодинг), пул высокой сложности (hard — тяжёлые рассуждения и крупные рефакторинги), мультимодальный (vision — чтение картинок), пул ревью (review — независимая проверка). На странице настроек отмечаете кандидатов, расставляете приоритеты (можно с привязкой к ступеням S/A/B/C) и для каждого маршрута отдельно фиксируете reasoning effort — выпадающий список ступеней берётся из уровней, которые модель реально поддерживает, а не из трёх универсальных. Каждый ход промпт главной модели несёт с собой таблицу рекомендаций `[SWITCHMAN:POOLS]`, и работа раздаётся по ней. У режима исполнения три состояния: off / advice / enforce (enforce = модель вне пула просто отклоняется).
19
+ **2. Уровень воды в контексте: длинная сессия не переполняется.** Каждый ход подсчитывает токены сессии в реальном времени, и три линии уровня ужесточаются по нарастающей: 80k (soft, настраивается) подсказывает «пора делегировать»; 100k (hard) урезает бюджет разового чтения и подталкивает к завершению; 200k (force) запускает автоматическую передачу — записывает документ передачи (append-only лог сессии — сам по себе полная резервная копия), сжимает контекст и будит сессию, работа не обрывается. Фоновые субагенты, которые ещё бегут в момент передачи, тоже не теряются: id, описания задач и пути к отчётам записываются в документ передачи, и продолжившаяся сессия знает, куда идти за отчётами, а не раздаёт работу заново; у каждого отправленного субагента к тому же свой жёсткий потолок: доработав до него, он завершается резюме HANDOFF. Уровень воды читает вид после обрезки — то, что модель реально видит, — поэтому сильно свёрнутая сессия больше не застревает на высоких линиях. Если автоматика не по руке: `/ctx-pause` останавливает все действия (замер продолжает работать), `/ctx-resume` возвращает всё в любой момент — и после перезапуска вернётся само; `/ctx-handover` запускает ту же передачу по требованию, не дожидаясь потолка.
20
20
 
21
- **3. Режим Agent Teams: от работы в одиночку — к своей команде.** По умолчанию выключен: сразу после установки это просто лёгкая диспетчеризация через subagent. На странице настроек два независимых переключателя:
21
+ **3. Маршрутизация намерений: сообщение приходит — модель сама занимает своё место.** Стоит выбрать «Авто (маршрутизация намерений)» для сессии, и каждое сообщение пользователя сначала типирует маленькая модель-классификатор, приземляя его на самого подходящего кандидата — у каждого кандидата однострочная заметка о способностях, она помогает выбору. Решение закреплено за ход: пока уверенности не хватает или окно кэша ещё открыто, текущая модель остаётся (её prompt-кэш продолжает работать); переключение происходит только когда уверенности достаточно или текущей модели нет среди кандидатов. Само переключение тихое, на уровне вызова — никакого шума «модель переключена» в сессии, а чип над полем ввода показывает текущий маршрут и уверенность в реальном времени. Классификатором годятся и небольшие decision-модели, и обычные чат-модели; кандидаты, пороги и окно кэша всегда на расстоянии одной страницы настроек.
22
22
 
23
- - **Режим команды агентов** — при включении внедряет командный регламент (делегирование по умолчанию + многоуровневая проверка + дисциплина общей доски задач) и автоматически включает Agent Teams в DSH: главная модель может нанимать постоянных товарищей по команде (`spawn_teammate`), ставить им задачи на общей доске (`team_task_*`) и обмениваться с ними сообщениями. Когда заводить команду, решает чёткая дисциплина: параллельные независимые подзадачи, объёмная самодостаточная работа, уже высокий уровень воды в главном контексте, потребность разделить роли; разовая точечная разведка по-прежнему идёт через subagent. Если выключить переключатель обратно, от командных пунктов не останется и следа, а инструменты команды из уже работающих сессий не изымаются.
24
- - **Синхронизация белого списка моделей субагентов** — в DSH есть белый список авторизации «разрешить агентам выбирать модели для субагентов»: если маршрут выбран в пуле, но не авторизован, явное назначение его главной моделью будет отклонено (в командном режиме он помечается ⚠). Включите этот переключатель — и объединение шести пулов целиком запишется в белый список: настраивать дважды не нужно, switchman остаётся единственным источником истины. Белый список применяется по снимку «новая сессия»: синхронизация действует только на сессии, открытые после неё.
23
+ **4. Режим Agent Teams: от работы в одиночку — к своей команде.** По умолчанию выключен: сразу после установки это просто лёгкая диспетчеризация через subagent. На странице настроек два независимых переключателя: **Режим команды агентов** — при включении внедряет командный регламент (делегирование по умолчанию + многоуровневая проверка + дисциплина общей доски задач) и автоматически включает Agent Teams в DSH: главная модель может нанимать постоянных товарищей по команде (`spawn_teammate`), ставить им задачи на общей доске (`team_task_*`) и обмениваться с ними сообщениями. Когда заводить команду, решает чёткая дисциплина: параллельные независимые подзадачи, объёмная самодостаточная работа, уже высокий уровень воды в главном контексте, потребность разделить роли; разовая точечная разведка по-прежнему идёт через subagent. Если выключить переключатель обратно, от командных пунктов не останется и следа, а инструменты команды из уже работающих сессий не изымаются. **Синхронизация белого списка моделей субагентов** — в DSH есть белый список авторизации «разрешить агентам выбирать модели для субагентов»: если маршрут выбран в пуле, но не авторизован, явное назначение его главной моделью будет отклонено (в командном режиме он помечается ⚠). Включите этот переключатель — и объединение шести пулов целиком запишется в белый список: настраивать дважды не нужно, switchman остаётся единственным источником истины. Белый список применяется по снимку «новая сессия»: синхронизация действует только на сессии, открытые после неё.
25
24
 
26
- В шапке сессии — наглядная обратная связь: значок ⚡ «автономная команда», ◇ с фактической моделью текущей сессии; когда идёт автоматическая передача, появляется живая подсказка «идёт передача · запись документа передачи / сжатие контекста / пробуждение продолжения».
25
+ **5. Шесть пулов диспетчеризации: под каждую работу — своя модель.** Лёгкий пул (economy — мелкие массовые задачи), механический (mechanical — шаблонные переработки), основной (main — повседневный кодинг), пул высокой сложности (hard — тяжёлые рассуждения и крупные рефакторинги), мультимодальный (vision — чтение картинок), пул ревью (review — независимая проверка). На странице настроек отмечаете кандидатов, расставляете приоритеты (можно с привязкой к ступеням S/A/B/C) и для каждого маршрута отдельно фиксируете reasoning effort — выпадающий список ступеней берётся из уровней, которые модель реально поддерживает, а не из трёх универсальных. Каждый ход промпт главной модели несёт с собой таблицу рекомендаций `[SWITCHMAN:POOLS]`, и работа раздаётся по ней. У режима исполнения три состояния: off / advice / enforce (enforce = модель вне пула просто отклоняется).
27
26
 
28
- **4. Языковые предпочтения: спросит один раз — запомнит навсегда.** Три выпадающих списка: язык ответов, комментариев в коде и документов; область действия — глобальная или по проекту (`.switchman/lang.json`). Настраивать не обязательно: при первом использовании спросят один раз — на языке интерфейса вашего DSH — и запомнят; дальше каждая сессия соблюдает выбор автоматически.
27
+ **6. Языковые предпочтения: спросит один раз — запомнит навсегда.** Три выпадающих списка: язык ответов, комментариев в коде и документов; область действия — глобальная или по проекту (`.switchman/lang.json`). Настраивать не обязательно: при первом использовании спросят один раз — на языке интерфейса вашего DSH — и запомнят; дальше каждая сессия соблюдает выбор автоматически.
29
28
 
30
- **5. Язык интерфейса: плагин говорит и на вашем языке.** В самом верху страницы настроек появился раздел «Интерфейс» с выпадающим списком «Язык интерфейса» (ключ настройки `uiLocale`): «Авто» (по умолчанию — следует языку приложения DeepSeek Harness) или любой из языков интерфейса плагина, всегда под своим эндонимом, без перевода. Переключается только интерфейс самого плагина — значок в шапке, панель главной страницы и страница настроек, — но не язык приложения DSH: предпросмотр мгновенный, без перезапуска; сохранение запоминает выбор; следующий запуск восстанавливает его; любой сбой возвращает язык приложения; а все словари лежат внутри бандла — ничего скачивать не нужно.
29
+ **7. Язык интерфейса: плагин говорит и на вашем языке.** В самом верху страницы настроек появился раздел «Интерфейс» с выпадающим списком «Язык интерфейса» (ключ настройки `uiLocale`): «Авто» (следует языку приложения DeepSeek Harness; по умолчанию — упрощённый китайский) или любой из языков интерфейса плагина, всегда под своим эндонимом, без перевода. Переключается только интерфейс самого плагина — значок в шапке, панель главной страницы и страница настроек, — но не язык приложения DSH: предпросмотр мгновенный, без перезапуска; сохранение запоминает выбор; следующий запуск восстанавливает его; любой сбой возвращает язык приложения; а все словари лежат внутри бандла — ничего скачивать не нужно.
31
30
 
32
- **6. Многоуровневая проверка: изменено — проверено.** Изменения больше 20 строк уходят тестировщику на проверку; изменения больше 300 строк или затрагивающие ядро / безопасность / согласованность данных — дополнительно независимому ревьюеру. Модель ревьюера подбирают, привязываясь к модели агента, написавшего этот diff, и стараются её обойти; если пул другого выхода не оставляет, в заключении прямо заявляется DOWNGRADED. Скажете «не использовать команду» — всё мгновенно вернётся к одиночной работе.
31
+ **8. Многоуровневая проверка: изменено — проверено.** Изменения больше 20 строк уходят тестировщику на проверку; изменения больше 300 строк или затрагивающие ядро / безопасность / согласованность данных — дополнительно независимому ревьюеру. Модель ревьюера подбирают, привязываясь к модели агента, написавшего этот diff, и стараются её обойти; если пул другого выхода не оставляет, в заключении прямо заявляется DOWNGRADED. Скажете «не использовать команду» — всё мгновенно вернётся к одиночной работе.
33
32
 
34
- **7. `/vision`: картинки по зубам даже чисто текстовой модели.** Когда главная модель не читает изображения, DSH прямо на входе отклоняет сообщения с картинками. Прикрепите картинку и введите `/vision что не так на этой картинке` — изображение будет отдано на чтение модели из мультимодального пула, а вывод вернётся в текущую сессию. Над полем ввода заранее подсказывают: «текущая модель не умеет читать изображения»; если прямая отправка картинки отклонена, она один раз автоматически переоформляется в `/vision` и уходит повторно — вручную ничего переписывать не нужно; если мультимодальный пул не настроен, команда откажется и подскажет, что настроить.
33
+ **9. `/vision`: картинки по зубам даже чисто текстовой модели.** Когда главная модель не читает изображения, DSH прямо на входе отклоняет сообщения с картинками. Прикрепите картинку и введите `/vision что не так на этой картинке` — изображение будет отдано на чтение модели из мультимодального пула, а вывод вернётся в текущую сессию. Над полем ввода заранее подсказывают: «текущая модель не умеет читать изображения»; если прямая отправка картинки отклонена, она один раз автоматически переоформляется в `/vision` и уходит повторно — вручную ничего переписывать не нужно; если мультимодальный пул не настроен, команда откажется и подскажет, что настроить.
35
34
 
36
- **8. Маршрутизация по намерению: нужная модель выбирается сама.** На странице настроек появляется раздел «Маршрутизация по намерению»: главный переключатель (по умолчанию выключен; для включения нужны классификатор и хотя бы один кандидат), маршрут маленькой модели-классификатора (provider + model + необязательный effort — подходят и решающие модели типа TypeSafe Jev, и обычные разговорные, вывод парсится нестрого), выбор типа классификатора из трёх (auto / decision / chat), независимый список моделей-кандидатов (для каждого: provider + model + необязательный effort + одна строка описания способностей), окно кэша в секундах (по умолчанию 300, подогнано под промпт-кэши поставщиков ~5 минут), порог уверенности для переключения (по умолчанию 80), тайм-аут классификации (по умолчанию 60000 мс), количество сообщений истории (по умолчанию 6) и символьный бюджет (по умолчанию 2400), а также необязательная запасная модель (с отдельной необязательной фиксацией effort; если он не задан, используется effort по умолчанию выбранной запасной модели, независимо от effort классификатора). В селекторе моделей под группой «Auto · Switchman» появляется вход «Auto» (клиент отрисовывает его локализованно — «Авто (маршрутизация по намерению)» на русском); после выбора классификатор оценивает каждое сообщение пользователя, и решение фиксируется на этот ход: если уверенности не хватает или окно кэша ещё открыто, текущая модель остаётся (её кэш переиспользуется); переключение происходит, только когда уверенность высока или текущей модели нет среди кандидатов. Смена проходит бесшумно на уровне вызова — в сессию не вставляется сообщение «модель переключена». Над полем ввода — чип состояния (при автороутинге он показывает текущую модель маршрута и уверенность последнего решения); кандидаты и пороги всегда можно посмотреть на странице настроек.
37
-
38
- Всего одна модель? Всё равно стоит поставить — контроль уровня воды и многоуровневая проверка от числа моделей не зависят, и длинная сессия на одной модели выигрывает от них ничуть не меньше.
35
+ Всего одна модель? Всё равно стоит поставить — автоматическая обрезка, контроль уровня воды и многоуровневая проверка от числа моделей не зависят, и длинная сессия на одной модели выигрывает от них ничуть не меньше. Маршрутизация намерений обретает смысл только при нескольких кандидатах моделей: держите её выключенной, пока не расширите состав.
39
36
 
40
37
  ## Встроенные навыки
41
38
 
@@ -75,7 +72,7 @@ dsh-switchman — плагин для [DeepSeek Harness](https://github.com/deep
75
72
  - **Пулы диспетчеризации** — шесть карточек в два ряда по три: сверху лёгкий / механический / основной; снизу высокосложный / мультимодальный / рецензентский. На каждой карточке отмечаются кандидаты, сгруппированные по поставщикам; отметьте «ручной порядок» — карточка станет нумерованным списком приоритетов, порядок меняется кнопками ↑ ↓ ×; рядом с каждым маршрутом можно зафиксировать reasoning effort (по умолчанию «следовать полосе»). Сводная строка сверху обновляется в реальном времени; на снимке: «пулов настроено: 4/6 · позиций в рейтинге: 2 · режим advice».
76
73
  - **Рейтинг по способностям + режим исполнения** — объединение моделей, выбранных в шести пулах, отсортировано по способности, сильнейшие впереди (на снимке glm-5.3 закреплён на ступени S, glm-5.3-flash — на A); порядок можно менять, лишние убирать; режим исполнения — advice / enforce (enforce = модель вне пула просто отклоняется).
77
74
  - **Команда агентов** — оба переключателя, командный режим и синхронизация белого списка, по умолчанию выключены; на снимке включены, под каждым — строка состояния синхронизации.
78
- - **Уровень воды в контексте** — три порога (на снимке 80000 / 120000 / 150000), бюджет разового чтения (3000), поведение жёсткого порога (пропустить с ограничением / заблокировать), переключатель автоматической передачи и отдельный потолок для субагентов — всё в этом разделе. Внизу строка команд: `/ctx-pause` приостановить вмешательство · `/ctx-resume` возобновить · `/ctx-handover` записать документ передачи и передать управление прямо сейчас (команда подводит сессию к границе простоя и только потом сжимает контекст, результат может занять несколько минут).
75
+ - **Уровень воды в контексте** — три порога (на снимке 80000 / 100000 / 200000), бюджет разового чтения (3500), поведение жёсткого порога (пропустить с ограничением / заблокировать), переключатель автоматической передачи и отдельный потолок для субагентов — всё в этом разделе. Внизу строка команд: `/ctx-pause` приостановить вмешательство · `/ctx-resume` возобновить · `/ctx-handover` записать документ передачи и передать управление прямо сейчас (команда подводит сессию к границе простоя и только потом сжимает контекст, результат может занять несколько минут).
79
76
  - **Маршрутизация по намерению** — главный переключатель, маршрут маленькой модели-классификатора, тип классификатора (auto / decision / chat), независимый список кандидатов (у каждого строка описания способностей), окно кэша / порог уверенности / тайм-аут / бюджет истории и необязательная запасная модель. После включения в селекторе моделей появляется локализованный вход «Авто (маршрутизация по намерению)», а над полем ввода — чип с моделью маршрута и уверенностью.
80
77
 
81
78
  4. **Проверьте** — в шапке сессии появился значок ⚡ «автономная команда» (рядом ◇ показывает модель текущей сессии); либо спросите модель напрямую: «как называется последний раздел твоего системного промпта?» — в ответе должен прозвучать регламент dsh-switchman.
@@ -92,19 +89,19 @@ bash <install-dir>/skills/db-query/scripts/setup.sh
92
89
 
93
90
  Ниже — полный набор значений сразу после новой установки (авторитетный источник: zod-схема в `host/config.js`).
94
91
 
95
- **Интерфейс и языки**: `uiLocale` = `auto` (следует языку приложения DSH); `langScope` = `global`; `langConversation/Comments/Docs` = пусто (спросят один раз в первой сессии и запомнят; язык комментариев и документов следует языку разговора).
92
+ **Интерфейс и языки**: `uiLocale` = `zh` (упрощённый китайский; `auto` следует языку приложения DSH); `langScope` = `project`; `langConversation` = `zh-CN`; `langComments/Docs` = пусто (заводское значение; если очистить, спросят один раз в первой сессии и запомнят; язык комментариев и документов следует языку разговора).
96
93
 
97
94
  **Пулы диспетчеризации**: у всех шести полос (economy/mechanical/main/hard/vision/review) кандидаты пусты (= системные модели по умолчанию, без вмешательства); ручной порядок и закреплённый effort выключены/пусты; `dispatchEnforce` = `advice` (только совет, без принуждения).
98
95
 
99
- **Уровень воды в контексте**: soft `80000` / hard `95000` / force `150000` токенов; бюджет разового чтения `3000`; поведение при превышении бюджета `cap` (обрезать с предупреждением); `wmAutoHandover` = включён (на force — запись документа передачи + сжатие автоматически); жёсткий потолок субагентов = включён (общие 150k).
96
+ **Уровень воды в контексте**: soft `80000` / hard `100000` / force `200000` токенов; бюджет разового чтения `3500`; поведение при превышении бюджета `cap` (обрезать с предупреждением); `wmAutoHandover` = включён (на force — запись документа передачи + сжатие автоматически); жёсткий потолок субагентов = включён (общие 200k).
100
97
 
101
- **Agent Teams**: `teamsMode` = выключен; `syncWhitelist` = выключен (два переключателя независимы друг от друга).
98
+ **Agent Teams**: `teamsMode` = включён; `syncWhitelist` = включён (два переключателя независимы друг от друга).
102
99
 
103
- **Маршрутизация по намерению** (по умолчанию недоступна; нужны классификатор + хотя бы один кандидат + включённый главный переключатель): `intentEnabled` = выключен (пока выключен, вход Auto скрыт, а сессии, где Auto уже выбран, идут по цепочке запасных моделей); маршрут классификатора не задан; тип классификатора `chat`; список кандидатов пуст (предустановленные категории участвуют в маршрутизации, только если у них указана модель); окно кэша `300` с / порог уверенности для переключения `80` / тайм-аут классификации `60000` мс; история `6` сообщений / `2400` символов; `intentContextWindow` = `200000`.
100
+ **Маршрутизация по намерению** (по умолчанию недоступна; нужны классификатор + хотя бы один кандидат + включённый главный переключатель): `intentEnabled` = выключен (пока выключен, вход Auto скрыт, а сессии, где Auto уже выбран, идут по цепочке запасных моделей); маршрут классификатора не задан; тип классификатора `chat`; список кандидатов пуст (предустановленные категории участвуют в маршрутизации, только если у них указана модель); окно кэша `300` с / порог уверенности для переключения `80` / тайм-аут классификации `60000` мс; история `6` сообщений / `2400` символов; `intentContextWindow` = `250000`.
104
101
 
105
- **Обрезка контекста**: `trimEnabled` = включено; `trimMode` = `auto` (полностью автоматически); ворота роста `22500` + прирост `25000` токенов; давление `65%` / авария `95%`; advisory-напоминания `65%` / `95%`; защищённый хвост `10` сообщений; потолок частоты fold-ов `30` в час; боковая модель не задана (наследует модель сессии) — подробности в разделе «Автоматическая обрезка контекста» ниже.
102
+ **Обрезка контекста**: `trimEnabled` = включено; `trimMode` = `advisory` (напоминания + инструменты fold; модель сессии сворачивает сама — для полностью автоматического режима `auto`); ворота роста `22500` + прирост `45000` токенов; давление `45%` / авария `90%`; advisory-напоминания `50%` / `80%`; защищённый хвост `6` сообщений; потолок частоты fold-ов `30` в час; боковая модель не задана (наследует модель сессии) — подробности в разделе «Автоматическая обрезка контекста» ниже.
106
103
 
107
- **Что важно знать из коробки**: ① то, что маршрутизация по намерению недоступна из коробки, — намеренное решение; включается в три шага (классификатор, кандидаты, переключатель); ② эффективное окно Auto из коробки равно 200000 — защитная планка гарантирует 0.8×окна ≥ force (150000), поэтому линия сжатия ядра (160000) всегда стоит после линии плавной передачи (150000); ③ заметнее всего из коробки троица уровней: 80k напоминает делегировать / 95k ужимает чтение / 150k сам передаёт управление (документ + сжатие) — без каких-либо настроек.
104
+ **Что важно знать из коробки**: ① то, что маршрутизация по намерению недоступна из коробки, — намеренное решение; включается в три шага (классификатор, кандидаты, переключатель); ② эффективное окно Auto из коробки равно 250000 — защитная планка гарантирует 0.8×окна ≥ force (200000), поэтому линия сжатия ядра (200000) совпадает с линией плавной передачи (200000); ③ заметнее всего из коробки троица уровней: 80k напоминает делегировать / 100k ужимает чтение / 200k сам передаёт управление (документ + сжатие) — без каких-либо настроек.
108
105
 
109
106
  ## Автоматическая обрезка контекста
110
107
 
@@ -113,23 +110,25 @@ bash <install-dir>/skills/db-query/scripts/setup.sh
113
110
  Уровни автоматизации (`trimMode`):
114
111
 
115
112
  - **`off`** — только измерения: сэмплирование расхода и попаданий кэша продолжается; без баннера и без fold-ов.
116
- - **`advisory`** — модель сессии сворачивает сама: ей открываются инструменты `ctx_trim_fold` и `ctx_trim_status` плюс заголовок протокола. Когда давление сессии достигает `trimAdvisoryPercent` эффективного окна, движок добавляет закреплённое напоминание свернуть контекст в виде суффикса `user/message` в конец активной поверхности сессии (не в system-заголовок dispatch-а) — повторяет сразу при переходе в critical и удаляет, когда давление опускается ниже линии.
117
- - **`auto`** (по умолчанию) — всё вышеперечисленное плюс автоматические fold-ы на границе простоя, тремя ступенями: ворота роста (рост > `trimGrowthTokens`, отсчитываемый от низшей точки после последнего fold-а — этот якорь сохраняет ворота взведёнными после fold-ов, фиксирующихся на высоких точках view — И непрерывный сжимаемый прирост ≥ `trimIncrementTokens`), ступень давления (`trimPressurePercent` окна контекста) и аварийная ступень (`trimEmergencyPercent` — механический fold с собственным охлаждением).
113
+ - **`advisory`** (по умолчанию) — модель сессии сворачивает сама: ей открываются инструменты `ctx_trim_fold` и `ctx_trim_status` плюс заголовок протокола. Когда давление сессии достигает `trimAdvisoryPercent` эффективного окна, движок добавляет закреплённое напоминание свернуть контекст в виде суффикса `user/message` в конец активной поверхности сессии (не в system-заголовок dispatch-а) — повторяет сразу при переходе в critical и удаляет, когда давление опускается ниже линии. На критической линии движок сам выполняет один механический аварийный fold (куладдаун 90 с, `trimCriticalRelief` = вкл).
114
+ - **`auto`** — всё вышеперечисленное плюс автоматические fold-ы на границе простоя, тремя ступенями: ворота роста (рост > `trimGrowthTokens`, отсчитываемый от низшей точки после последнего fold-а — этот якорь сохраняет ворота взведёнными после fold-ов, фиксирующихся на высоких точках view — И непрерывный сжимаемый прирост ≥ `trimIncrementTokens`), ступень давления (`trimPressurePercent` окна контекста) и аварийная ступень (`trimEmergencyPercent` — механический fold с собственным охлаждением).
118
115
 
119
116
  Все ключи живут в разделе Настройки → dsh-switchman; значения по умолчанию — из `host/config.js`:
120
117
 
121
118
  | Ключ | По умолчанию | Смысл |
122
119
  | --- | --- | --- |
123
120
  | `trimEnabled` | `true` | Главный выключатель. ВЫКЛ полностью отключает fold-ы и метрики (слушатель вырождается в чистый pass-through). |
124
- | `trimMode` | `auto` | `off` только измерения / `advisory` fold-ы по решению модели / `auto` fold-ы по решению системы. |
121
+ | `trimMode` | `advisory` | `off` только измерения / `advisory` fold-ы по решению модели / `auto` fold-ы по решению системы. |
125
122
  | `trimGrowthTokens` | `22500` | Ворота роста: fold, когда исходящая view выросла на столько с прошлого fold-а. |
126
- | `trimIncrementTokens` | `25000` | Спутник ворот: непрерывный сжимаемый прирост тоже должен достичь этого размера. |
127
- | `trimPressurePercent` | `65` | Ступень давления: fold, когда использование view достигает этого процента окна контекста. |
128
- | `trimEmergencyPercent` | `95` | Аварийная ступень: принудительный механический fold (без вызова боковой модели) на этом проценте. |
129
- | `trimAdvisoryPercent` | `65` | Линия advisory-напоминания: при достижении этой доли эффективного окна движок предлагает модели немедленно сложить контекст через `ctx_trim_fold` (только режим advisory). |
130
- | `trimAdvisoryCriticalPercent` | `95` | Критическая линия: при её достижении напоминание повторяется сразу, минуя 10-минутный троттлинг той же полосы. |
123
+ | `trimIncrementTokens` | `45000` | Спутник ворот: непрерывный сжимаемый прирост тоже должен достичь этого размера. |
124
+ | `trimPressurePercent` | `45` | Ступень давления: fold, когда использование view достигает этого процента окна контекста. |
125
+ | `trimEmergencyPercent` | `90` | Аварийная ступень: принудительный механический fold (без вызова боковой модели) на этом проценте. |
126
+ | `trimAdvisoryPercent` | `50` | Линия advisory-напоминания: при достижении этой доли эффективного окна движок предлагает модели немедленно сложить контекст через `ctx_trim_fold` (только режим advisory). |
127
+ | `trimAdvisoryCriticalPercent` | `80` | Критическая линия: при её достижении напоминание повторяется сразу, минуя 10-минутный троттлинг той же полосы. |
131
128
  | `trimWindowTokens` | `0` | Эффективный лимит окна для расчёта уровней: считается от min(окно модели, лимит). `0` = следует за `wmForceTokens`. |
132
- | `trimProtectedTail` | `10` | Последние N сообщений никогда не сворачиваются. |
129
+ | `trimCriticalRelief` | `true` | Аварийное relief при критической линии advisory: на критической линии движок сам выполняет одно механическое (как emergency) сворачивание, кулдаун 90 с. |
130
+ | — | — | Проценты trim несравнимы со счётчиком контекста у поля ввода: trim делит последний оплаченный prompt (max от view/wire) на эффективное окно (с лимитом), а счётчик показывает прогноз следующего prompt на полное окно модели. |
131
+ | `trimProtectedTail` | `6` | Последние N сообщений никогда не сворачиваются. |
133
132
  | `trimMaxFoldsPerHour` | `30` | Потолок частоты fold-ов боковой модели за скользящий час (аварийные не в счёт). |
134
133
  | `trimSideModel` | не задан | Маршрут боковой модели, пишущей резюме. Пусто = следовать provider/model сессии, не наследуя effort вызова; этот маршрут также используют ladder distillation. Effort резюме можно закрепить отдельно; без фиксации метаданные модели определяют минимальный доступный уровень reasoning, а для моделей только с переключателем вкл./выкл. выбирается off. Если reasoning не поддерживается или метаданные недоступны, effort не отправляется и сохраняется поведение модели/адаптера по умолчанию. |
135
134
  | `trimFoldFallbackModel` | не задан | Маршрут повторной попытки, если боковая модель резюме не сработала; pressure-fold затем деградирует до механического. Пусто = без резерва. У вручную выбранной запасной модели fold-а независимый effort; если он не задан, применяется та же рекомендация по метаданным, что для модели резюме, а при отсутствии метаданных — умолчание самой модели. Выбирайте маршрут с запасом по кулдаунам, риск-контролю и параллелизму. |
@@ -138,7 +137,7 @@ bash <install-dir>/skills/db-query/scripts/setup.sh
138
137
 
139
138
  **Пути срабатывания.** Проверки ступеней выполняются на границе простоя и — как запасной путь для хостов, где события статуса простоя недостижимы — после завершения каждого потока модели (не чаще одной оценки в 60 с на сессию). Каждое решение — и fold-ы, и no-op-ы — дописывается одной строкой `key=value` (с отметкой времени) в `decisions.log` внутри каталога состояния fold-ов (см. `trimStateDir`), что даёт fold-ам офлайн-журнал аудита; словарь строк (`view-applied`, строки решений/исходов fold-ов, `surface-replace`, `surface-replace skipped reason=…`) перечислен в [docs/context-trim.md](./docs/context-trim.md).
140
139
 
141
- **Правда провода и установившийся режим.** Строки решений несут `view=<n>` и, после того как ответ пришёл, `wire=<n>` — реальный промпт провайдера (некэшированный вход + чтение кэша + запись кэша, сэмплированные из usage-события потока). Оценка view считает только массив сообщений и всегда читается меньше провода на фиксированный оверхед (измерено ≈ 17.3k: системный промпт + схемы инструментов + persona), поэтому ступени давления и аварии оценивают по `max(view, wire)`, и только `wire` — это измерение размера промпта. На окне 150k здоровая пилообразная кривая ведёт провод от ≈ 40k сразу после fold ↔ 64–97.5k на следующем (≈27%–65% окна), один fold на ~25k сырого прироста, причём потолок удерживается около 97.5k ступенью давления, а не окном. Если `view` растёт, а строка `surface-replace` так и не появляется, читайте строки пропуска (`incomplete-seqs`, `no-service`, `compaction-lock`).
140
+ **Правда провода и установившийся режим.** Строки решений несут `view=<n>` и, после того как ответ пришёл, `wire=<n>` — реальный промпт провайдера (некэшированный вход + чтение кэша + запись кэша, сэмплированные из usage-события потока). Оценка view считает только массив сообщений и всегда читается меньше провода на фиксированный оверхед (измерено ≈ 17.3k: системный промпт + схемы инструментов + persona), поэтому ступени давления и аварии оценивают по `max(view, wire)`, и только `wire` — это измерение размера промпта. На окне 200k здоровая пилообразная кривая ведёт провод от ≈ 40k сразу после fold ↔ 64–90k на следующем (≈20%–45% окна), один fold на ~45k сырого прироста, причём потолок удерживается около 90k ступенью давления, а не окном. Если `view` растёт, а строка `surface-replace` так и не появляется, читайте строки пропуска (`incomplete-seqs`, `no-service`, `compaction-lock`).
142
141
 
143
142
  **Эпохи сжатия на стороне хоста.** Ссылки fold привязаны к идентификаторам сообщений и хешам содержимого, поэтому сжатие, выполненное самим хостом и заменяющее повторно отправляемую историю, старит весь журнал разом: ни один блок не находит своей позиции, view молча откатывается к исходной истории (fail-open — в журнал решений записывается `view-applied applied=0`), а плагин при следующем запросе перепривязывает базовую линию роста к виду после сжатия. Таким образом, сжатие хоста — запасной слой обрезки последней инстанции, а fold плагина выполняет тонкую работу внутри одной эпохи хоста. Некоторые диспетчеры передают полностью замороженные массивы запросов или объекты опций (текущий агентный луп глубоко замораживает собранные запросы); для них `injectView` фиксирует исход в журнале решений: `nothing-to-apply` (ни одного найденного fold-блока — сырая история и ЕСТЬ view), `in-place`/`swapped` (свёрнутое представление ушло с запросом) или `none` (fold существовал, но замороженный диспетчер не смог его нести — по проводу идёт сырая история). **Surface replace — путь доставки, когда он доступен** (`surfaceFold`, по умолчанию включён): на серийной границе `agent/turn-stopping` плюс холостая проходка плагин дописывает хост-стильное событие учёта shadow-price и ОДНО замещающее событие `user/message` с `surfaceOp {op:'replace', startSeq, endSeq}`, где `sourceEventSeqs` покрывает каждый затенённый узел поверхности, — тот же механизм, которым пользуется сжатие самого хоста, — так что зафиксированный fold доходит до провода с уровня источника, замороженные диспетчеры включительно. Пока недавние диспетчеры сессии пишут `none`, плагин считает view чисто измерительным: уровень воды вместо этого меряет присланную провайдером сумму (ступень force и автоматическая передача продолжают работать), циклы fold-ов приостанавливаются, не сжигая вызовы суммаризатора, а баннер обрезки помечает строку `wire=raw` (folds not shipping; watermark reads the tally); хосты без surface-механизма (или с выключенным флагом) сохраняют ровно это прежнее поведение.
144
143
 
@@ -163,6 +162,12 @@ bash <install-dir>/skills/db-query/scripts/setup.sh
163
162
  - Строки протокола (`[SWITCHMAN:LANG|POOLS|WATERMARK|TEAMS]`) намеренно оставлены на английском и стабильны побайтово — не локализуйте их.
164
163
  - `npm pack --dry-run` должен сохранять аудированную форму: 60 файлов / ~380 kB (~1,26 МБ распаковано; `docs/` исключён).
165
164
 
165
+ ## Загрузки
166
+
167
+ Все загрузки npm с момента первого релиза, накопительно — построено по официальному [npm downloads API](https://api.npmjs.org/) и ежедневно обновляется GitHub Actions ([скрипт графика](scripts/downloads-chart.mjs)):
168
+
169
+ ![Кумулятивные загрузки npm для dsh-switchman](docs/assets/downloads.svg)
170
+
166
171
  ## License
167
172
 
168
173
  MIT
package/README.zh-TW.md CHANGED
@@ -12,30 +12,27 @@
12
12
 
13
13
  用 DSH 幹活久了有兩件煩心事:一是對話越聊越重,上下文被歷史撐到幾十萬 token,模型開始忘事、變慢、變貴,手動 /compact 又丟細節;二是主力模型什麼都自己幹,查個檔案、跑個測試、對個資料都是它在啃,大半活其實該交給便宜模型。
14
14
 
15
- dsh-switchman 是一個 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(DSH)外掛。裝上之後,主模型從「親自幹活」變成調度員:量水位、選車道、派任務、盯驗收。它不是新模型,是一套掛在 DSH 上的調度規程加一個設定頁,一共做八件事:
15
+ dsh-switchman 是一個 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(DSH)外掛。裝上之後,主模型仍然親自幹活——只是幹得更聰明:輕的雜務丟給便宜的車道,急事難事由意圖路由送到合適的模型,真正值得親自動手的才留給自己;削掉贅肉、蒸餾本質——消化過的對話折成精煉摘要,水位計盯著每一筆開銷,上下文一路輕裝;忙不過來時就拉常駐隊友上船,在共享任務看板上分工,自己退到調度與驗收。它不是新模型,是一套掛在 DSH 上的調度規程加一個設定頁,一共做九件事:
16
16
 
17
- **1. 上下文水位:長對話不撐爆。** 每輪即時統計對話 token,三條水位線逐級加碼:80k(soft,可調)提醒「該委派了」;95k(hard)收緊單次讀取預算、引導收尾;150k(force)自動交接——寫交接文件(附加式對話日誌本身就是完整備份)、壓縮上下文、喚醒續跑,任務不斷線。交接那一刻還在跑的背景子代理也不會丟:id、任務、報告路徑都寫進交接文件,續跑的對話知道去哪收報告,不會重複派工。每個子代理自帶獨立硬上限,到頂寫完 HANDOFF 摘要退場。自動干預不合手時可臨時接管:`/ctx-pause` 停掉全部水位動作(量測照跑、尾部水位線轉成 paused,只是不動手),`/ctx-resume` 隨時恢復——重新啟動 DSH 後干預也會自動回來,是臨時放手,不是永久關閉;`/ctx-handover` 不等水位到頂,主動發起同一次交接:寫交接文件、壓縮上下文、喚醒續跑(對話先被引導到閒置邊界,結果可能要等幾分鐘)。
17
+ **1. 自動上下文裁剪:對話越聊越長,成本始終壓平。** 手動 `/compact` 要人等、丟細節、還把供應商的 prompt 快取打穿。裁剪引擎把這些全部自動化:消化過的對話段落在閒置邊界折成緊湊的確定性摘要(由 side 模型執筆;緊急壓力下改為無模型的機械折疊),此後每個發出的請求都從摺疊狀態重建——摘要塊頂替被摺疊的段落,活著的尾部一字不動。落盤的對話日誌永不改寫,串流中的請求也決不碰。摺疊只增不減、重建是確定性的,因此兩次摺疊之間序列化前綴逐位元組不變,供應商快取持續命中;任何內部故障一律 fail-open 回退為透明直通——絕不發出損壞的請求。三檔全自動(成長閘門/壓力/緊急)之外還有一檔 advisory,由模型自己動手折疊——機制詳見文末「自動上下文裁剪」一節。
18
18
 
19
- **2. 六個派發池:什麼活配什麼模型。** 輕量池(批次小活)、機械池(模板化改寫)、主力池(日常編碼)、高難池(高難推理與大規模重構)、多模態池(看圖)、複審池(獨立驗證)。設定頁裡勾候選、排優先順序、標 S/A/B/C 級,還能給每條路線單獨釘選思考強度——強度下拉來自該模型真實支援的級別,不是通用三級。主模型每輪提示詞裡都帶著一張 `[SWITCHMAN:POOLS]` 推薦表,照表派工。執行模式三態:關閉 / 建議 / 強制(強制 = 池外模型直接拒絕)。
19
+ **2. 上下文水位:長對話不撐爆。** 每輪即時統計對話 token,三條水位線逐級加碼:80k(soft,可調)提醒「該委派了」;100k(hard)收緊單次讀取預算、引導收尾;200k(force)自動交接——寫交接文件(附加式對話日誌本身就是完整備份)、壓縮上下文、喚醒續跑,任務不斷線。交接那一刻還在跑的背景子代理也不會丟:id、任務、報告路徑都寫進交接文件,續跑的對話知道去哪收報告,不會重複派工;每個子代理另帶獨立硬上限,到頂寫完 HANDOFF 摘要退場。水位線讀的是裁剪後的視圖——模型真正看到的東西——所以折疊得再兇的對話也不會被釘死在高水位上。自動干預不合手時:`/ctx-pause` 停掉全部水位動作(量測照跑),`/ctx-resume` 隨時恢復——重啟後也會自己回來;`/ctx-handover` 不等水位到頂,直接發起同一場交接。
20
20
 
21
- **3. Agent Teams 模式:從單幹到帶團隊。** 預設關閉,裝完就是輕量的 subagent 派發。設定頁兩個獨立開關:
21
+ **3. 意圖路由:訊息一進來,模型自己就位。** 給會話選上「自動(意圖路由)」,每條使用者訊息先由一個小分類模型判型,落到最合適的候選上——每個候選帶一行能力備註,供判斷參考。決定按輪生效:信心不足或快取視窗還開著,就沿用當前模型(它的 prompt 快取繼續吃);只有信心足夠、或當前模型不在候選之列時才切換。切換在調用層靜默完成,會話裡不會出現「已切換模型」的噪音;輸入框上方的膠囊即時顯示當前路由與信心。分類器用小型決策模型或通用聊天模型都行;候選、閾值與快取視窗隨時在設定頁調整。
22
22
 
23
- - **代理團隊模式**——打開後注入團隊規程(預設委派 + 分級驗證 + 共享任務板紀律),並自動啟用 DSH 的 Agent Teams:主模型可以拉常駐隊友(`spawn_teammate`)、往共享任務板派工(`team_task_*`)、和隊友互傳訊息。什麼時候組團隊有明確紀律:可並行的獨立子任務、量大且自包含、主上下文水位已高、需要角色分離;一次性的單點調查仍走 subagent。再關掉開關,團隊條款零殘留,也不會撤走正在執行的對話裡的團隊工具。
24
- - **同步子代理模型白名單**——DSH 有張「允許 Agent 為子代理選擇模型」的授權白名單:池裡選了但沒授權的路線,點名派發會被拒(團隊模式下會標 ⚠)。打開這個開關,六個池的聯集整體寫入那張白名單——switchman 做唯一事實來源,不用兩邊重複設定。白名單按「新建對話」快照生效,同步只對之後新開的對話起作用。
23
+ **4. Agent Teams 模式:從單幹到帶團隊。** 預設關閉,裝完就是輕量的 subagent 派發。設定頁兩個獨立開關: **代理團隊模式**——打開後注入團隊規程(預設委派 + 分級驗證 + 共享任務板紀律),並自動啟用 DSH 的 Agent Teams:主模型可以拉常駐隊友(`spawn_teammate`)、往共享任務板派工(`team_task_*`)、和隊友互傳訊息。什麼時候組團隊有明確紀律:可並行的獨立子任務、量大且自包含、主上下文水位已高、需要角色分離;一次性的單點調查仍走 subagent。再關掉開關,團隊條款零殘留,也不會撤走正在執行的對話裡的團隊工具。 **同步子代理模型白名單**——DSH 有張「允許 Agent 為子代理選擇模型」的授權白名單:池裡選了但沒授權的路線,點名派發會被拒(團隊模式下會標 ⚠)。打開這個開關,六個池的聯集整體寫入那張白名單——switchman 做唯一事實來源,不用兩邊重複設定。白名單按「新建對話」快照生效,同步只對之後新開的對話起作用。
25
24
 
26
- 對話標頭有直觀回饋:⚡「自主團隊」徽章、◇ 目前對話實際模型;自動交接進行時出現「交接進行中 · 寫入交接文件 / 壓縮上下文 / 喚醒續接」的即時提示。
25
+ **5. 六個派發池:什麼活配什麼模型。** 輕量池(批次小活)、機械池(模板化改寫)、主力池(日常編碼)、高難池(高難推理與大規模重構)、多模態池(看圖)、複審池(獨立驗證)。設定頁裡勾候選、排優先順序、標 S/A/B/C 級,還能給每條路線單獨釘選思考強度——強度下拉來自該模型真實支援的級別,不是通用三級。主模型每輪提示詞裡都帶著一張 `[SWITCHMAN:POOLS]` 推薦表,照表派工。執行模式三態:關閉 / 建議 / 強制(強制 = 池外模型直接拒絕)。
27
26
 
28
- **4. 語言偏好:問一次,記一輩子。** 回覆、程式碼註解、文件三種語言各一個下拉,作用域可選全域或按專案(`.switchman/lang.json`)。不設也行——首次用到時用你 DSH 介面的語言問一次,記住後每個對話自動遵守。
27
+ **6. 語言偏好:問一次,記一輩子。** 回覆、程式碼註解、文件三種語言各一個下拉,作用域可選全域或按專案(`.switchman/lang.json`)。不設也行——首次用到時用你 DSH 介面的語言問一次,記住後每個對話自動遵守。
29
28
 
30
- **5. 介面語言:外掛自己也說你的話。** 設定頁頂部的「介面」區裡一個「介面語言」下拉(設定鍵 `uiLocale`):自動(預設,跟隨 DeepSeek Harness 應用程式語言),或手動選任一內建介面語言——選項一律顯示語言原名、不作翻譯。它只切換本外掛自己的介面(徽章、首頁面板、設定頁),不動 DSH 應用程式語言:選中即即時預覽、無須重新啟動,儲存後記住、下次啟動自動還原,任何失敗都回退到應用程式語言;字典全部內建在外掛包裡,無須下載。
29
+ **7. 介面語言:外掛自己也說你的話。** 設定頁頂部的「介面」區裡一個「介面語言」下拉(設定鍵 `uiLocale`):自動(跟隨 DeepSeek Harness 應用程式語言;出廠預設為簡體中文),或手動選任一內建介面語言——選項一律顯示語言原名、不作翻譯。它只切換本外掛自己的介面(徽章、首頁面板、設定頁),不動 DSH 應用程式語言:選中即即時預覽、無須重新啟動,儲存後記住、下次啟動自動還原,任何失敗都回退到應用程式語言;字典全部內建在外掛包裡,無須下載。
31
30
 
32
- **6. 分級驗證:改完必查。** 超過 20 行的改動交 tester 驗證;超過 300 行、或動了核心 / 安全 / 資料一致性邏輯,再交一個 reviewer 獨立複審。複審模型錨定「寫出這份 diff 的代理」所用的模型來選,盡量避開;池裡實在避不開時,會在結論裡聲明 DOWNGRADED。你說一句「不要用團隊」,它立刻退回單幹。
31
+ **8. 分級驗證:改完必查。** 超過 20 行的改動交 tester 驗證;超過 300 行、或動了核心 / 安全 / 資料一致性邏輯,再交一個 reviewer 獨立複審。複審模型錨定「寫出這份 diff 的代理」所用的模型來選,盡量避開;池裡實在避不開時,會在結論裡聲明 DOWNGRADED。你說一句「不要用團隊」,它立刻退回單幹。
33
32
 
34
- **7. `/vision`:純文字模型也能處理圖。** 主力模型讀不了圖時,DSH 會在入口直接拒掉帶圖訊息。貼上圖、輸入 `/vision 這張圖錯在哪`,圖片會被交給多模態池的模型去讀,結論回到目前對話。輸入框上方會提前提示「目前模型不支援讀圖」;直接傳圖被拒時,自動改寫成 `/vision` 重送一次,不用手動重來;多模態池沒設時指令會拒絕並給出設定指引。
33
+ **9. `/vision`:純文字模型也能處理圖。** 主力模型讀不了圖時,DSH 會在入口直接拒掉帶圖訊息。貼上圖、輸入 `/vision 這張圖錯在哪`,圖片會被交給多模態池的模型去讀,結論回到目前對話。輸入框上方會提前提示「目前模型不支援讀圖」;直接傳圖被拒時,自動改寫成 `/vision` 重送一次,不用手動重來;多模態池沒設時指令會拒絕並給出設定指引。
35
34
 
36
- **8. 意圖識別自動選模型:訊息進來,模型自動落位。** 設定頁新增【意圖識別】分組:主開關(預設關閉,開啟需設定分類器並至少一個候選)、分類器小模型路由(provider + model + 可選 effort,TypeSafe Jev 類決策模型與通用對話模型都支援,輸出寬容解析)、分類器類型三選(auto / decision / chat)、獨立候選模型清單(每個候選 provider + model + 可選 effort + 一句能力描述)、快取視窗秒數(預設 300,對齊廠商 prompt cache 約 5 分鐘)、切換信心閾值(預設 80)、分類逾時(預設 60000ms)、歷史訊息則數(預設 6)與字元預算(預設 2400)、可選備援模型(可獨立固定可選 effort;未固定時使用所選備援模型的預設 effort,與分類器 effort 分開)。模型選擇器出現「Auto · Switchman」分組下的「Auto」入口(用戶端渲染為在地化的「自動(意圖識別)」);選中後每條使用者訊息先由分類器判定最合適的候選,同一輪鎖定決策:信心不足或仍在快取視窗內時優先沿用目前模型(快取續用),信心足夠高或目前模型不在候選裡才切換;切換在呼叫層靜默完成,不往對話裡插「模型已切換」。輸入框上方有狀態 chip(自動路由時顯示目前路由模型與上次決策信心),候選與閾值隨時回設定頁查看。
37
-
38
- 只有一個模型也值得裝——水位控制和分級驗證與模型數量無關,單模型長對話同樣受益。
35
+ 只有一個模型也值得裝——自動裁剪、水位控制和分級驗證與模型數量無關,單模型長對話同樣受益。意圖路由要有多個模型候選才發揮作用,隊伍擴編前先關著。
39
36
 
40
37
  ## 隨附技能
41
38
 
@@ -75,7 +72,7 @@ dsh-switchman 是一個 [DeepSeek Harness](https://github.com/deepseek-ai/deepse
75
72
  - **派發池**——六張卡片兩行三列:上排輕量、機械、主力,下排高難、多模態、複審。卡片按供應商分組勾候選模型;勾上「手動排序」變成編號優先清單,用 ↑ ↓ × 調順序;每條路線可釘思考強度(預設「跟隨泳道」)。頂部彙總行即時更新,圖中即「已設定 4/6 池 · 排名 2 項 · 模式 建議」。
76
73
  - **能力排序 + 執行模式**——六池選中模型的聯集按能力排序、最強在前(圖中 glm-5.3 錨 S 級、glm-5.3-flash 錨 A 級),可調序、可刪減;執行模式建議 / 強制(強制 = 池外模型直接拒絕)。
77
74
  - **代理團隊**——團隊模式與白名單同步兩個開關,預設全關;圖中為開啟狀態,開關下方有同步狀態行。
78
- - **上下文水位**——三級閾值(圖中 80000 / 120000 / 150000)、單次讀取預算(3000)、hard 級行為(限流放行 / 攔截)、自動交接開關、子代理獨立上限,都在這區。底部一行指令:`/ctx-pause` 暫停干預 · `/ctx-resume` 恢復 · `/ctx-handover` 立即交接(它會把對話引導到閒置邊界再壓縮,結果可能要等幾分鐘)。
75
+ - **上下文水位**——三級閾值(圖中 80000 / 100000 / 200000)、單次讀取預算(3500)、hard 級行為(限流放行 / 攔截)、自動交接開關、子代理獨立上限,都在這區。底部一行指令:`/ctx-pause` 暫停干預 · `/ctx-resume` 恢復 · `/ctx-handover` 立即交接(它會把對話引導到閒置邊界再壓縮,結果可能要等幾分鐘)。
79
76
  - **意圖識別**——主開關、分類器小模型路由、分類器類型(auto / decision / chat)、獨立候選清單(每項附一句能力描述)、快取視窗 / 信心閾值 / 分類逾時 / 歷史訊息預算、可選備援模型。開啟後模型選擇器出現「自動(意圖識別)」入口,輸入框上方顯示目前路由模型與信心 chip。
80
77
 
81
78
  4. **驗證**——對話標頭出現 ⚡「自主團隊」徽章(旁邊 ◇ 顯示目前對話模型);或者直接問模型「你系統提示詞最後一段的標題是什麼」,答案應提到 dsh-switchman 規程。
@@ -92,19 +89,19 @@ bash <安裝目錄>/skills/db-query/scripts/setup.sh
92
89
 
93
90
  以下為新安裝後的全部預設值(權威來源:`host/config.js` 的 zod schema)。
94
91
 
95
- **介面與語言**:`uiLocale` = `auto`(跟隨 DSH 應用程式語言);`langScope` = `global`;`langConversation/Comments/Docs` = 空(首次對話問一次後記住;註解與文件語言跟隨對話語言)。
92
+ **介面與語言**:`uiLocale` = `zh`(簡體中文,出廠預設;`auto` 跟隨 DSH 應用程式語言);`langScope` = `project`;`langConversation` = `zh-CN`,`langComments/Docs` = 空(出廠預設;清空後首次對話問一次後記住;註解與文件語言跟隨對話語言)。
96
93
 
97
94
  **派發池**:六條泳道(economy/mechanical/main/hard/vision/review)候選均為空(= 用系統預設模型,不干預);手動排序與 effort 釘選均為關/空;`dispatchEnforce` = `advice`(建議不強制)。
98
95
 
99
- **上下文水位**:soft `80000` / hard `95000` / force `150000` tokens;單次讀取預算 `3000`;超預算行為 `cap`(截斷加警告);`wmAutoHandover` = 開(force 級自動寫交接文件+壓縮);子代理硬上限 = 開(共享 150k)。
96
+ **上下文水位**:soft `80000` / hard `100000` / force `200000` tokens;單次讀取預算 `3500`;超預算行為 `cap`(截斷加警告);`wmAutoHandover` = 開(force 級自動寫交接文件+壓縮);子代理硬上限 = 開(共享 200k)。
100
97
 
101
- **Agent Teams**:`teamsMode` = 關;`syncWhitelist` = 關(兩者相互獨立)。
98
+ **Agent Teams**:`teamsMode` = 開;`syncWhitelist` = 開(兩者相互獨立)。
102
99
 
103
- **意圖識別**(預設不可用,需設定分類器 + 至少一個候選 + 打開主開關):`intentEnabled` = 關(關閉時 Auto 入口隱藏,已選 Auto 的對話走備援鏈);分類器路由未設定;分類器類型 `chat`;候選清單空(預置分類需填模型才參與路由);快取視窗 `300` 秒 / 切換信心閾值 `80` / 分類逾時 `60000` ms;歷史 `6` 則 / `2400` 字元;`intentContextWindow` = `200000`。
100
+ **意圖識別**(預設不可用,需設定分類器 + 至少一個候選 + 打開主開關):`intentEnabled` = 關(關閉時 Auto 入口隱藏,已選 Auto 的對話走備援鏈);分類器路由未設定;分類器類型 `chat`;候選清單空(預置分類需填模型才參與路由);快取視窗 `300` 秒 / 切換信心閾值 `80` / 分類逾時 `60000` ms;歷史 `6` 則 / `2400` 字元;`intentContextWindow` = `250000`。
104
101
 
105
- **上下文裁剪**:`trimEnabled` = 開;`trimMode` = `auto`(全自動);增長閘門 `22500` token + 增量 `25000` token;壓力 `65%` / 緊急 `95%`;advisory 提醒 `65%` / `95%`;保護尾部 `10` 則;折疊節奏上限每小時 `30` 次;side model 未設定(繼承對話模型)——詳見下文「自動上下文裁剪」一節。
102
+ **上下文裁剪**:`trimEnabled` = 開;`trimMode` = `advisory`(提醒+摺疊工具,模型自行摺疊;全自動需切回 `auto`);增長閘門 `22500` token + 增量 `45000` token;壓力 `45%` / 緊急 `90%`;advisory 提醒 `50%` / `80%`;保護尾部 `6` 則;折疊節奏上限每小時 `30` 次;side model 未設定(繼承對話模型)——詳見下文「自動上下文裁剪」一節。
106
103
 
107
- **開箱要點**:① 意圖識別開箱不可用是有意設計,三步開啟(分類器、候選、開關);② Auto 有效視窗開箱即為 200000——護欄保證 0.8×視窗 ≥ force 級(150000),核心壓縮線(160000)永遠在平滑交接線(150000)之後;③ 開箱最有感的是水位三件套:80k 提醒委派 / 95k 收斂讀取 / 150k 自動交接(寫文件+壓縮),無須任何設定。
104
+ **開箱要點**:① 意圖識別開箱不可用是有意設計,三步開啟(分類器、候選、開關);② Auto 有效視窗開箱即為 250000——護欄保證 0.8×視窗 ≥ force 級(200000),核心壓縮線(200000)恰好落在平滑交接線(200000)上;③ 開箱最有感的是水位三件套:80k 提醒委派 / 100k 收斂讀取 / 200k 自動交接(寫文件+壓縮),無須任何設定。
108
105
 
109
106
  ## 自動上下文裁剪
110
107
 
@@ -113,23 +110,25 @@ bash <安裝目錄>/skills/db-query/scripts/setup.sh
113
110
  自動化層級(`trimMode`):
114
111
 
115
112
  - **`off`**——只測量:用量與快取命中取樣照常執行;無橫幅、無折疊。
116
- - **`advisory`**——對話模型自己折疊:向其暴露 `ctx_trim_fold` 與 `ctx_trim_status` 工具和協定頭。對話壓力達到有效視窗的 `trimAdvisoryPercent` 時,引擎將一次性固定摺疊提醒作為 `user/message` 後綴追加到即時對話 surface 尾端(不修改本次派發的 system 頭)——升級到 critical 立即重發,壓力回落到線下後清除。
117
- - **`auto`**(預設)——以上全部,外加閒置邊界上的自動折疊,分三級:增長閘門(自上次折疊後的低谷起算的增長 > `trimGrowthTokens`——該錨點保證高位折疊後閘門依然有效——且連續可壓縮增量 ≥ `trimIncrementTokens`)、壓力級(上下文視窗的 `trimPressurePercent`)、緊急級(`trimEmergencyPercent`——帶獨立冷卻的機械折疊)。
113
+ - **`advisory`**(預設)——對話模型自己折疊:向其暴露 `ctx_trim_fold` 與 `ctx_trim_status` 工具和協定頭。對話壓力達到有效視窗的 `trimAdvisoryPercent` 時,引擎將一次性固定摺疊提醒作為 `user/message` 後綴追加到即時對話 surface 尾端(不修改本次派發的 system 頭)——升級到 critical 立即重發,壓力回落到線下後清除。壓力到達臨界線時,引擎自身會執行一次機械救援摺疊(90 秒冷卻,`trimCriticalRelief` = 開)。
114
+ - **`auto`**——以上全部,外加閒置邊界上的自動折疊,分三級:增長閘門(自上次折疊後的低谷起算的增長 > `trimGrowthTokens`——該錨點保證高位折疊後閘門依然有效——且連續可壓縮增量 ≥ `trimIncrementTokens`)、壓力級(上下文視窗的 `trimPressurePercent`)、緊急級(`trimEmergencyPercent`——帶獨立冷卻的機械折疊)。
118
115
 
119
116
  所有鍵位於 設定 → dsh-switchman;預設值出自 `host/config.js`:
120
117
 
121
118
  | 鍵 | 預設值 | 含義 |
122
119
  | --- | --- | --- |
123
120
  | `trimEnabled` | `true` | 總開關。關閉後折疊與度量全部停用(監聽器退化為純透傳)。 |
124
- | `trimMode` | `auto` | `off` 只測量 / `advisory` 模型自折 / `auto` 系統自動折。 |
121
+ | `trimMode` | `advisory` | `off` 只測量 / `advisory` 模型自折 / `auto` 系統自動折。 |
125
122
  | `trimGrowthTokens` | `22500` | 增長閘門:出站 view 自上次 fold 以來增長到該值即觸發折疊。 |
126
- | `trimIncrementTokens` | `25000` | 閘門搭檔:連續可壓縮增量也須達到該規模。 |
127
- | `trimPressurePercent` | `65` | 壓力級:view 用量達到上下文視窗該百分比即折疊。 |
128
- | `trimEmergencyPercent` | `95` | 緊急級:到該百分比強制機械折疊(無 side model 呼叫)。 |
129
- | `trimAdvisoryPercent` | `65` | advisory 提醒線:壓力達到有效視窗的該百分比時,引擎提醒模型立即用 `ctx_trim_fold` 摺疊(僅 advisory 模式)。 |
130
- | `trimAdvisoryCriticalPercent` | `95` | critical 提醒線:到線立即重發提醒,不受 10 分鐘同檔節流限制。 |
123
+ | `trimIncrementTokens` | `45000` | 閘門搭檔:連續可壓縮增量也須達到該規模。 |
124
+ | `trimPressurePercent` | `45` | 壓力級:view 用量達到上下文視窗該百分比即折疊。 |
125
+ | `trimEmergencyPercent` | `90` | 緊急級:到該百分比強制機械折疊(無 side model 呼叫)。 |
126
+ | `trimAdvisoryPercent` | `50` | advisory 提醒線:壓力達到有效視窗的該百分比時,引擎提醒模型立即用 `ctx_trim_fold` 摺疊(僅 advisory 模式)。 |
127
+ | `trimAdvisoryCriticalPercent` | `80` | critical 提醒線:到線立即重發提醒,不受 10 分鐘同檔節流限制。 |
131
128
  | `trimWindowTokens` | `0` | 視窗上限:壓力與緊急檔按 min(模型視窗, 上限) 計算。`0` = 跟隨 `wmForceTokens`。 |
132
- | `trimProtectedTail` | `10` | 最後 N 則訊息永不折疊。 |
129
+ | `trimCriticalRelief` | `true` | advisory 臨界紓緩:到達 critical 線時引擎自行執行一次機械(緊急檔式)摺疊,90 秒冷卻。 |
130
+ | — | — | trim 百分比與輸入框旁的上下文面板不可直接比較:trim 按最近一次實付 prompt(max(view, wire))除以有效視窗(含上限)計算,面板顯示的是計量器對下一次 prompt 的預測值除以模型全視窗。 |
131
+ | `trimProtectedTail` | `6` | 最後 N 則訊息永不折疊。 |
133
132
  | `trimMaxFoldsPerHour` | `30` | 每滾動小時 side model 折疊的節奏上限(緊急級豁免)。 |
134
133
  | `trimSideModel` | 未設定 | 寫摘要的 side model 路由。留空 = 跟隨對話目前 provider/model,不繼承呼叫的 effort;ladder distillation 也使用此路由。摘要 effort 可獨立手動固定;未固定時依模型 metadata 建議最低啟用的 reasoning 層級,僅有開/關選項時選 off。不支援 reasoning 或 metadata 不可用時不傳 effort,沿用模型/配接器預設行為。 |
135
134
  | `trimFoldFallbackModel` | 未設定 | 摘要 side model 失敗時摺疊改用的重試路由;壓力檔仍失敗則退回機械摺疊。留空 = 無備援。手動選擇的折疊備援模型可獨立固定 effort;未設定時依與摘要模型相同的模型 metadata 規則建議,metadata 缺失則使用該模型預設值。盡量選擇冷卻、風控與並行餘量充足的路由。 |
@@ -138,7 +137,7 @@ bash <安裝目錄>/skills/db-query/scripts/setup.sh
138
137
 
139
138
  **觸發路徑。** 級別檢查在閒置邊界上執行;在閒置狀態事件不可達的宿主上,兜底改為在每次模型串流完成後也檢查一次(每個對話節流為每 60 秒至多評估一次)。每個決策——fold 與 no-op 皆然——都會作為一行帶時間戳的 `key=value` 附加進裁剪狀態目錄(見 `trimStateDir`)下的 `decisions.log`,為 fold 留下離線稽核軌跡;列詞彙(`view-applied`、fold 決策/結果列、`surface-replace`、`surface-replace skipped reason=…`)收錄於 [docs/context-trim.md](./docs/context-trim.md)。
140
139
 
141
- **線上真值與穩態。** 決策列攜帶 `view=<n>`,回應落地後還會帶上 `wire=<n>`——真實的廠商提示詞(未快取輸入 + 快取讀取 + 快取寫入,從串流的 usage 事件取樣得到)。view 估算只統計 messages 陣列,而且總是比線上讀數小一個固定額外開銷(實測 ≈ 17.3k:系統提示詞 + 工具 schema + persona),所以壓力級與緊急級按 `max(view, wire)` 評估,只有 `wire` 才是提示詞大小的讀數。150k 視窗下,健康的鋸齒波在每次 fold 剛結束時線上 ≈ 40k ↔ 下次 fold 時 64–97.5k(佔視窗的 ≈27%–65%),每 ~25k 原始增長折疊一次,上限由壓力級而非視窗釘在 97.5k 附近。若 `view` 持續攀升卻從不出現 `surface-replace` 列,就去讀跳過列(`incomplete-seqs`、`no-service`、`compaction-lock`)。
140
+ **線上真值與穩態。** 決策列攜帶 `view=<n>`,回應落地後還會帶上 `wire=<n>`——真實的廠商提示詞(未快取輸入 + 快取讀取 + 快取寫入,從串流的 usage 事件取樣得到)。view 估算只統計 messages 陣列,而且總是比線上讀數小一個固定額外開銷(實測 ≈ 17.3k:系統提示詞 + 工具 schema + persona),所以壓力級與緊急級按 `max(view, wire)` 評估,只有 `wire` 才是提示詞大小的讀數。200k 視窗下,健康的鋸齒波在每次 fold 剛結束時線上 ≈ 40k ↔ 下次 fold 時 64–90k(佔視窗的 ≈20%–45%),每 ~45k 原始增長折疊一次,上限由壓力級而非視窗釘在 90k 附近。若 `view` 持續攀升卻從不出現 `surface-replace` 列,就去讀跳過列(`incomplete-seqs`、`no-service`、`compaction-lock`)。
142
141
 
143
142
  **宿主壓縮紀元。** fold 引用錨定在訊息 id 與內容雜湊上,因此宿主自身的壓縮一旦替換了重發歷史,整本帳就會同時老化:所有塊都無法定位,view 靜默回退為原始歷史(fail-open——決策日誌會記錄 `view-applied applied=0`),外掛在下一次請求時把增長基線重錨到壓縮後的視圖。宿主壓縮因此是兜底的裁剪層,外掛 fold 負責單一宿主紀元內的細粒度工作。 部分派發改用完全凍結的請求陣列或選項物件(目前的 agent loop 會深凍結裝配好的請求);對這類派發,`injectView` 會在決策日誌裡報告結果:`nothing-to-apply`(沒有定位到 fold 塊——原始歷史本身就是 view)、`in-place`/`swapped`(fold view 已隨請求送出)或 `none`(fold 存在但凍結的派發帶不動它——線上送出原始歷史)。**Surface replace 是可用時的發送路徑**(`surfaceFold`,預設開啟):在序列的 `agent/turn-stopping` 邊界外加一次閒置清掃,外掛追加宿主風格的 shadow-price 計量事件與一條攜帶 `surfaceOp {op:'replace', startSeq, endSeq}` 的 `user/message` 替換事件,`sourceEventSeqs` 覆蓋被遮蔽的每個表面節點——與宿主自身壓縮用的是同一機制——已提交的 fold 由此從源頭直達線上,凍結派發也不例外。當某對話近期派發都記錄 `none` 時,外掛把 view 當作僅供計量:水位改用服務商上報的計數(force 檔與自動交接照常運作),fold 循環暫停、不再空燒 summarizer 呼叫,裁剪橫幅以 `wire=raw`(folds not shipping; watermark reads the tally)標記該行;沒有 surface 機制的宿主(或開關關閉時)保持的正是這套舊行為。
144
143
 
@@ -163,6 +162,12 @@ bash <安裝目錄>/skills/db-query/scripts/setup.sh
163
162
  - 協定行(`[SWITCHMAN:LANG|POOLS|WATERMARK|TEAMS]`)刻意保持英文且位元組穩定——不要在地化。
164
163
  - `npm pack --dry-run` 應保持稽核過的 60 個檔案 / ~380 kB 形態(解壓後 ~1.26 MB,`docs/` 不進包)。
165
164
 
165
+ ## 下載量
166
+
167
+ 自首次發布以來的 npm 累計下載量 — 資料來自官方 [npm downloads API](https://api.npmjs.org/),由 GitHub Actions 每日自動重繪([圖表腳本](scripts/downloads-chart.mjs)):
168
+
169
+ ![dsh-switchman 的 npm 累計下載量](docs/assets/downloads.svg)
170
+
166
171
  ## License
167
172
 
168
173
  MIT