dsh-switchman 1.11.0 → 1.11.2
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 +6 -6
- package/README.es.md +6 -6
- package/README.fr.md +6 -6
- package/README.it.md +6 -6
- package/README.ja.md +6 -6
- package/README.ko.md +6 -6
- package/README.md +6 -6
- package/README.pt.md +6 -6
- package/README.ru.md +6 -6
- package/README.zh-TW.md +6 -6
- package/README.zh.md +6 -6
- package/client.js +76 -9
- package/cordis.patch.yml +30 -1
- package/host/config.js +28 -13
- package/host/context-trim/index.js +53 -12
- package/host/context-trim/metrics.js +17 -11
- package/host/context-trim/summarizer.js +38 -7
- package/host/context-trim/trigger.js +3 -3
- package/host/context-watch.js +83 -9
- package/host/dispatch.js +251 -8
- package/host/routes.js +44 -8
- package/host/teams.js +4 -2
- package/host/tool-args-sanitize.js +106 -0
- package/index.js +10 -0
- package/package.json +1 -1
package/README.de.md
CHANGED
|
@@ -102,7 +102,7 @@ Alles Folgende sind die vollständigen Werte direkt nach der Neuinstallation (ma
|
|
|
102
102
|
|
|
103
103
|
**Intent-Routing** (ab Werk unbrauchbar; nötig sind Klassifikator + mindestens ein Kandidat + der Hauptschalter): `intentEnabled` = aus (ist er aus, bleibt der Auto-Eintrag verborgen, und Sessions, die bereits Auto gewählt hatten, laufen über die Fallback-Kette); Klassifikator-Route nicht gesetzt; Klassifikatortyp `chat`; Kandidatenliste leer (die mitgelieferten Kategorien nehmen erst mit eingetragenem Modell am Routing teil); Cache-Fenster `300` s / Umschalt-Vertrauensschwelle `80` / Klassifikations-Timeout `60000` ms; Verlauf `6` Nachrichten / `2400` Zeichen; `intentContextWindow` = `200000`.
|
|
104
104
|
|
|
105
|
-
**Kontext-Trimming**: `trimEnabled` = an; `trimMode` = `auto` (vollautomatisch); Wachstumsschwelle `22500` + Zuwachs `
|
|
105
|
+
**Kontext-Trimming**: `trimEnabled` = an; `trimMode` = `auto` (vollautomatisch); Wachstumsschwelle `22500` + Zuwachs `25000` Tokens; Druck `65%` / Notfall `95%`; geschütztes Ende `10` Nachrichten; Fold-Takt-Obergrenze `30` pro Stunde; Nebenmodell nicht gesetzt (erbt das Session-Modell) — Details im Abschnitt „Automatisches Kontext-Trimming“ unten.
|
|
106
106
|
|
|
107
107
|
**Out-of-the-Box-Anmerkungen**: ① dass Intent-Routing ab Werk unbrauchbar ist, ist Absicht — drei Schritte zum Einschalten (Klassifikator, Kandidaten, Schalter); ② das wirksame Auto-Fenster steht ab Werk auf 200000 — die Leitplanke garantiert 0.8×Fenster ≥ force (150000), die Kern-Komprimierlinie (160000) liegt also stets hinter der Linie der weichen Übergabe (150000); ③ am spürbarsten ab Werk ist das Wasserstands-Trio: 80k mahnt zur Delegation / 95k strafft das Lesen / 150k übergibt automatisch (Dokument schreiben + Komprimierung) — ganz ohne Einstellungen.
|
|
108
108
|
|
|
@@ -123,12 +123,12 @@ Alle Schlüssel liegen unter Einstellungen → dsh-switchman; Defaults aus `host
|
|
|
123
123
|
| `trimEnabled` | `true` | Hauptschalter. AUS deaktiviert Folds und Metriken komplett (der Listener wird zum reinen Durchreichen). |
|
|
124
124
|
| `trimMode` | `auto` | `off` nur messen / `advisory` modellgetriebene Folds / `auto` systemgetriebene Folds. |
|
|
125
125
|
| `trimGrowthTokens` | `22500` | Wachstumsschwelle: falte, wenn die ausgehende View seit dem letzten Fold so viel gewachsen ist. |
|
|
126
|
-
| `trimIncrementTokens` | `
|
|
127
|
-
| `trimPressurePercent` | `
|
|
126
|
+
| `trimIncrementTokens` | `25000` | Schwellen-Begleiter: der zusammenhängende komprimierbare Zuwachs muss ebenfalls diese Größe erreichen. |
|
|
127
|
+
| `trimPressurePercent` | `65` | Druckstufe: falte, wenn die View-Nutzung diesen Prozentsatz des Kontextfensters erreicht. |
|
|
128
128
|
| `trimEmergencyPercent` | `95` | Notfallstufe: erzwungener mechanischer Fold (kein Nebenmodell-Aufruf) bei diesem Prozentsatz. |
|
|
129
129
|
| `trimWindowTokens` | `0` | Effektives Fensterlimit für die Stufenberechnung: gerechnet gegen min(Modellfenster, Limit). `0` = folgt `wmForceTokens`. |
|
|
130
|
-
| `trimProtectedTail` | `
|
|
131
|
-
| `trimMaxFoldsPerHour` | `
|
|
130
|
+
| `trimProtectedTail` | `10` | Die letzten N Nachrichten werden nie gefaltet. |
|
|
131
|
+
| `trimMaxFoldsPerHour` | `30` | Fold-Takt-Obergrenze pro rollierender Stunde für Nebenmodell-Folds (Notfall-Folds ausgenommen). |
|
|
132
132
|
| `trimSideModel` | nicht gesetzt | Route des zusammenfassenden Nebenmodells. Leer = das aktuelle Session-Modell erben. |
|
|
133
133
|
| `trimFoldFallbackModel` | nicht gesetzt | Route, mit der der Fold den Zusammenfassungs-Versuch wiederholt; scheitert auch sie, degradiert ein Pressure-Fold zu mechanischem Folding. Leer = kein Fallback. Route mit Spielraum bei Cooldowns, Risikokontrolle und Concurrency wählen. |
|
|
134
134
|
| `trimStateDir` | nicht gesetzt | Überschreibt das Fold-Zustandsverzeichnis. Leer = `<dshHome>/.dsh-switchman/state/trim/`. |
|
|
@@ -136,7 +136,7 @@ Alle Schlüssel liegen unter Einstellungen → dsh-switchman; Defaults aus `host
|
|
|
136
136
|
|
|
137
137
|
**Trigger-Pfade.** Stufenprüfungen laufen an der Leerlauf-Grenze und — als Fallback für Hosts, auf denen Leerlauf-Status-Ereignisse nicht erreichbar sind — nach jedem Modell-Stream-Abschluss (auf eine Auswertung pro 60 s und Session gedrosselt). Jede Entscheidung — Folds wie No-ops gleichermaßen — wird als eine zeitgestempelte `key=value`-Zeile an `decisions.log` im Fold-Zustandsverzeichnis (siehe `trimStateDir`) angehängt und gibt Folds so eine Offline-Prüfspur; das Zeilenvokabular (`view-applied`, Fold-Entscheidungs-/Ergebniszeilen, `surface-replace`, `surface-replace skipped reason=…`) ist in [docs/context-trim.md](./docs/context-trim.md) katalogisiert.
|
|
138
138
|
|
|
139
|
-
**Leitungs-Wahrheit und stabiler Zustand.** Entscheidungszeilen tragen `view=<n>` und, sobald eine Antwort eingetroffen ist, `wire=<n>` — den echten Anbieter-Prompt (ungecachter Input + Cache-Read + Cache-Write, entnommen aus dem Usage-Event des Streams). Die View-Schätzung zählt nur das Messages-Array und liest immer um den festen Overhead kleiner als die Leitung (gemessen ≈ 17.3k: System-Prompt + Tool-Schemas + Persona); Druck- und Notfallstufe werten daher auf `max(view, wire)` aus, und nur `wire` ist eine Prompt-Größenmessung. In einem 150k-Fenster läuft der gesunde Sägezahn direkt nach einem Fold auf Leitung ≈ 40k ↔
|
|
139
|
+
**Leitungs-Wahrheit und stabiler Zustand.** Entscheidungszeilen tragen `view=<n>` und, sobald eine Antwort eingetroffen ist, `wire=<n>` — den echten Anbieter-Prompt (ungecachter Input + Cache-Read + Cache-Write, entnommen aus dem Usage-Event des Streams). Die View-Schätzung zählt nur das Messages-Array und liest immer um den festen Overhead kleiner als die Leitung (gemessen ≈ 17.3k: System-Prompt + Tool-Schemas + Persona); Druck- und Notfallstufe werten daher auf `max(view, wire)` aus, und nur `wire` ist eine Prompt-Größenmessung. In einem 150k-Fenster läuft der gesunde Sägezahn direkt nach einem Fold auf Leitung ≈ 40k ↔ 64–97.5k beim nächsten (≈27%–65% des Fensters), ein Fold pro ~25k Rohwachstum, wobei die Obergrenze eher von der Druckstufe als vom Fenster nahe 97.5k festgehalten wird. Steigt `view`, ohne dass je eine `surface-replace`-Zeile erscheint, lies die Skip-Zeilen (`incomplete-seqs`, `no-service`, `compaction-lock`).
|
|
140
140
|
|
|
141
141
|
**Host-Kompaktions-Epochen.** Fold-Verweise sind an Nachrichten-IDs und Inhalts-Hashes verankert; ersetzt der Host selbst den erneut gesendeten Verlauf, veralten sämtliche Blöcke auf einmal: keiner findet mehr seine Position, die View fällt still auf den Rohverlauf zurück (fail-open — das Entscheidungsprotokoll vermerkt `view-applied applied=0`), und das Plugin verankert seine Wachstumsbaseline bei der nächsten Anfrage auf der Sicht nach der Kompaktion. Die Host-Kompaktion ist damit die Backstop-Trimschicht; die Plugin-Folds leisten die feingranulare Arbeit innerhalb einer Host-Epoche. Manche Dispatches übergeben vollständig eingefrorene Anfrage-Arrays oder Optionsobjekte (die aktuelle Agent-Loop friert die zusammengesetzten Anfragen tief ein); für sie meldet `injectView` das Ergebnis im Entscheidungsprotokoll: `nothing-to-apply` (keine lokalisierbaren Fold-Blöcke — der Rohverlauf IST die View), `in-place`/`swapped` (der Fold-View wurde ausgeliefert) oder `none` (ein Fold existierte, aber der eingefrorene Dispatch konnte ihn nicht tragen — auf die Leitung geht der Rohverlauf). **Surface Replace ist der Auslieferungsweg, wann immer er verfügbar ist** (`surfaceFold`, standardmäßig an): an der seriellen `agent/turn-stopping`-Grenze plus einem Idle-Sweep hängt das Plugin das host-typische Shadow-Price-Messereignis und EIN `user/message`-Ersatzereignis an, das `surfaceOp {op:'replace', startSeq, endSeq}` trägt und mit `sourceEventSeqs` jeden überdeckten Oberflächen-Knoten abdeckt — derselbe Mechanismus, den die Host-Kompaktion selbst nutzt —, sodass ein committeter Fold aus der Quellschicht auf die Leitung gelangt, eingefrorene Dispatches eingeschlossen. Solange die letzten Dispatches einer Session `none` vermerken, behandelt das Plugin die View als reines Messobjekt: Der Wasserstand liest stattdessen die vom Anbieter gemeldete Zählung (force-Stufe und Auto-Übergabe arbeiten weiter), Fold-Zyklen pausieren, statt Summarizer-Aufrufe zu verbrennen, und das Trim-Banner markiert die Zeile mit `wire=raw` (folds not shipping; watermark reads the tally); Hosts ohne den Surface-Mechanismus (oder mit ausgeschaltetem Flag) behalten genau dieses alte Verhalten.
|
|
142
142
|
|
package/README.es.md
CHANGED
|
@@ -102,7 +102,7 @@ Esto es todo el conjunto de valores tras una instalación nueva (fuente autorita
|
|
|
102
102
|
|
|
103
103
|
**Enrutado por intención** (no disponible de fábrica; hacen falta clasificador + al menos un candidato + encender el interruptor maestro): `intentEnabled` = apagado (apagado, la entrada Auto queda oculta y las sesiones que ya la tenían elegida caen en la cadena de respaldo); ruta del clasificador sin configurar; tipo de clasificador `chat`; lista de candidatos vacía (las categorías preinstaladas solo entran en el enrutado cuando se les asigna un modelo); ventana de caché `300` s / umbral de confianza para el cambio `80` / timeout de clasificación `60000` ms; historial de `6` mensajes / `2400` caracteres; `intentContextWindow` = `200000`.
|
|
104
104
|
|
|
105
|
-
**Recorte de contexto**: `trimEnabled` = encendido; `trimMode` = `auto` (totalmente automático); compuerta de crecimiento `22500` + incremento `
|
|
105
|
+
**Recorte de contexto**: `trimEnabled` = encendido; `trimMode` = `auto` (totalmente automático); compuerta de crecimiento `22500` + incremento `25000` tokens; presión `65%` / emergencia `95%`; cola protegida `10` mensajes; tope de cadencia de folds `30` por hora; modelo secundario sin definir (hereda el modelo de la sesión) — detalles en la sección «Recorte automático del contexto» más abajo.
|
|
106
106
|
|
|
107
107
|
**Notas de serie**: ① que el enrutado por intención no venga disponible de serie es intencionado: tres pasos para activarlo (clasificador, candidatos, interruptor); ② la ventana efectiva de Auto vale 200000 de serie — la barrera de seguridad garantiza 0.8×ventana ≥ force (150000), así que la línea de compactación del núcleo (160000) queda siempre por detrás de la línea de entrega suave (150000); ③ lo más perceptible de serie es el trío de niveles: 80k avisa de delegar / 95k aprieta la lectura / 150k entrega automáticamente (documento + compactación) — sin tocar ningún ajuste.
|
|
108
108
|
|
|
@@ -123,12 +123,12 @@ Todas las claves viven en Ajustes → dsh-switchman; los valores por defecto sal
|
|
|
123
123
|
| `trimEnabled` | `true` | Interruptor maestro. Apagado desactiva folds y métricas por completo (el listener degenera en puro paso a través). |
|
|
124
124
|
| `trimMode` | `auto` | `off` solo medir / `advisory` folds dictados por el modelo / `auto` folds dictados por el sistema. |
|
|
125
125
|
| `trimGrowthTokens` | `22500` | Compuerta de crecimiento: pliega cuando la view saliente crezca esto desde el último fold. |
|
|
126
|
-
| `trimIncrementTokens` | `
|
|
127
|
-
| `trimPressurePercent` | `
|
|
126
|
+
| `trimIncrementTokens` | `25000` | Compañera de la compuerta: el incremento comprimible contiguo también debe alcanzar este tamaño. |
|
|
127
|
+
| `trimPressurePercent` | `65` | Escalón de presión: pliega cuando el uso de la view alcance este porcentaje de la ventana de contexto. |
|
|
128
128
|
| `trimEmergencyPercent` | `95` | Escalón de emergencia: fold mecánico forzado (sin llamada al modelo secundario) a este porcentaje. |
|
|
129
129
|
| `trimWindowTokens` | `0` | Límite de ventana efectivo para el cálculo de niveles: se calcula sobre min(ventana del modelo, límite). `0` = sigue a `wmForceTokens`. |
|
|
130
|
-
| `trimProtectedTail` | `
|
|
131
|
-
| `trimMaxFoldsPerHour` | `
|
|
130
|
+
| `trimProtectedTail` | `10` | Los últimos N mensajes nunca se pliegan. |
|
|
131
|
+
| `trimMaxFoldsPerHour` | `30` | Tope de cadencia de folds por hora móvil para el modelo secundario (los de emergencia quedan exentos). |
|
|
132
132
|
| `trimSideModel` | sin definir | Ruta del modelo secundario que escribe los resúmenes. Vacía = heredar el modelo actual de la sesión. |
|
|
133
133
|
| `trimFoldFallbackModel` | sin definir | Ruta de reintento cuando falla el modelo secundario de resúmenes; un fold de presión degrada entonces a mecánico. Vacía = sin respaldo. Elige una ruta con margen en cooldowns, control de riesgo y concurrencia. |
|
|
134
134
|
| `trimStateDir` | sin definir | Anula el directorio del estado de folds. Vacía = `<dshHome>/.dsh-switchman/state/trim/`. |
|
|
@@ -136,7 +136,7 @@ Todas las claves viven en Ajustes → dsh-switchman; los valores por defecto sal
|
|
|
136
136
|
|
|
137
137
|
**Rutas de activación.** Las comprobaciones de escalones se ejecutan en el límite de inactividad y, como respaldo para hosts donde los eventos de estado de inactividad son inalcanzables, tras cada finalización del flujo del modelo (limitadas a una evaluación cada 60 s por sesión). Cada decisión — folds y no-ops por igual — se añade como una línea `key=value` con marca de tiempo a `decisions.log` en el directorio del estado de folds (véase `trimStateDir`), dando a los folds una pista de auditoría fuera de línea; el vocabulario de filas (`view-applied`, filas de decisión/resultado de folds, `surface-replace`, `surface-replace skipped reason=…`) está catalogado en [docs/context-trim.md](./docs/context-trim.md).
|
|
138
138
|
|
|
139
|
-
**Verdad del cable y estado estacionario.** Las filas de decisión llevan `view=<n>` y, una vez que una respuesta ha llegado, `wire=<n>` — el prompt real del proveedor (entrada sin caché + lectura de caché + escritura de caché, muestreado del evento de uso del stream). La estimación de la view cuenta solo el array de mensajes y siempre lee menos que el cable por la sobrecarga fija (medida ≈ 17.3k: system prompt + esquemas de herramientas + persona), así que los escalones de presión y emergencia evalúan sobre `max(view, wire)`, y solo `wire` es una lectura del tamaño del prompt. En una ventana de 150k, el diente de sierra sano marca el cable en ≈ 40k justo después de un fold ↔
|
|
139
|
+
**Verdad del cable y estado estacionario.** Las filas de decisión llevan `view=<n>` y, una vez que una respuesta ha llegado, `wire=<n>` — el prompt real del proveedor (entrada sin caché + lectura de caché + escritura de caché, muestreado del evento de uso del stream). La estimación de la view cuenta solo el array de mensajes y siempre lee menos que el cable por la sobrecarga fija (medida ≈ 17.3k: system prompt + esquemas de herramientas + persona), así que los escalones de presión y emergencia evalúan sobre `max(view, wire)`, y solo `wire` es una lectura del tamaño del prompt. En una ventana de 150k, el diente de sierra sano marca el cable en ≈ 40k justo después de un fold ↔ 64–97.5k en el siguiente (≈27%–65% de la ventana), un fold por cada ~25k de crecimiento bruto, con el techo fijado cerca de 97.5k por el escalón de presión y no por la ventana. Si `view` sube sin que aparezca nunca una fila `surface-replace`, lee las filas de omisión (`incomplete-seqs`, `no-service`, `compaction-lock`).
|
|
140
140
|
|
|
141
141
|
**Épocas de compactación del host.** Las referencias de fold se anclan en ids de mensaje y hashes de contenido, de modo que una compactación del propio host que reemplace el historial reenviado hace envejecer el libro entero de golpe: ningún bloque localiza su posición, la vista retrocede silenciosamente al historial sin plegar (fail-open — el registro de decisiones anota `view-applied applied=0`) y el plugin reancla su línea base de crecimiento en la vista posterior a la compactación en la siguiente petición. La compactación del host es así la capa de recorte de último recurso; los folds del plugin hacen el trabajo fino dentro de una época del host. Algunos despachos entregan matrices de solicitud u objetos de opciones totalmente congelados (el bucle de agente actual congela en profundidad las peticiones ya montadas); para ellos, `injectView` informa del resultado en el registro de decisiones: `nothing-to-apply` (no hay bloques de fold localizados — el historial sin plegar ES la vista), `in-place`/`swapped` (la vista plegada viajó con la petición) o `none` (había un fold, pero el despacho congelado no podía llevarlo — por el cable va el historial sin plegar). **El reemplazo de superficie es la ruta de envío cuando está disponible** (`surfaceFold`, activado por defecto): en el límite serial `agent/turn-stopping` más un barrido de inactividad, el plugin añade el evento de medición shadow-price al estilo del host y UN reemplazo `user/message` que lleva `surfaceOp {op:'replace', startSeq, endSeq}` con `sourceEventSeqs` cubriendo cada nodo de superficie sombreado — el mismo mecanismo que usa la propia compactación del host —, de modo que un fold confirmado llega al cable desde el nivel de origen, despachos congelados incluidos. Mientras los despachos recientes de una sesión registran `none`, el plugin trata la vista como solo-medición: el nivel de agua mide en su lugar la cuenta que reporta el proveedor (el escalón force y la entrega automática siguen funcionando), los ciclos de fold se pausan en vez de quemar llamadas al resumidor, y el banner de recorte marca la línea con `wire=raw` (folds not shipping; watermark reads the tally); los hosts sin el mecanismo de superficie (o con la opción apagada) se quedan exactamente con ese comportamiento antiguo.
|
|
142
142
|
|
package/README.fr.md
CHANGED
|
@@ -102,7 +102,7 @@ Voici l'ensemble complet des valeurs juste après une installation neuve (source
|
|
|
102
102
|
|
|
103
103
|
**Routage par intention** (indisponible par défaut ; il exige un classifieur + au moins un candidat + l'interrupteur général) : `intentEnabled` = désactivé (désactivé, l'entrée Auto reste cachée et les sessions déjà passées en Auto empruntent la chaîne de repli) ; route du classifieur non définie ; type de classifieur `chat` ; liste de candidats vide (les catégories préinstallées ne participent au routage qu'une fois un modèle renseigné) ; fenêtre de cache `300` s / seuil de confiance du basculement `80` / timeout de classification `60000` ms ; historique de `6` messages / `2400` caractères ; `intentContextWindow` = `200000`.
|
|
104
104
|
|
|
105
|
-
**Trim de contexte** : `trimEnabled` = activé ; `trimMode` = `auto` (entièrement automatique) ; porte de croissance `22500` + incrément `
|
|
105
|
+
**Trim de contexte** : `trimEnabled` = activé ; `trimMode` = `auto` (entièrement automatique) ; porte de croissance `22500` + incrément `25000` tokens ; pression `65%` / urgence `95%` ; queue protégée `10` messages ; plafond de cadence des folds `30` par heure ; modèle annexe non défini (hérite du modèle de la session) — détails dans la section « Trim automatique du contexte » ci-dessous.
|
|
106
106
|
|
|
107
107
|
**À savoir dès l'installation** : ① l'indisponibilité du routage par intention en sortie d'usine est un choix délibéré — trois étapes pour l'activer (classifieur, candidats, interrupteur) ; ② la fenêtre effective d'Auto vaut 200000 dès l'usine — le garde-fou garantit 0.8×fenêtre ≥ force (150000), si bien que la ligne de compactage cœur (160000) se situe toujours après la ligne de remise en douceur (150000) ; ③ l'effet le plus tangible dès l'usine est le trio de niveaux : 80k rappelle de déléguer / 95k resserre la lecture / 150k remet automatiquement (document + compactage) — sans aucun réglage.
|
|
108
108
|
|
|
@@ -123,12 +123,12 @@ Toutes les clés vivent dans Réglages → dsh-switchman ; les valeurs par défa
|
|
|
123
123
|
| `trimEnabled` | `true` | Interrupteur maître. Désactivé, folding et métriques s'arrêtent totalement (le listener se dégrade en simple passage). |
|
|
124
124
|
| `trimMode` | `auto` | `off` mesure seule / `advisory` folds pilotés par le modèle / `auto` folds pilotés par le système. |
|
|
125
125
|
| `trimGrowthTokens` | `22500` | Porte de croissance : on plie quand la view sortante a grandi d'autant depuis le dernier fold. |
|
|
126
|
-
| `trimIncrementTokens` | `
|
|
127
|
-
| `trimPressurePercent` | `
|
|
126
|
+
| `trimIncrementTokens` | `25000` | Compagnon de la porte : l'incrément compressible contigu doit aussi atteindre cette taille. |
|
|
127
|
+
| `trimPressurePercent` | `65` | Palier de pression : on plie quand l'usage de la view atteint ce pourcentage de la fenêtre de contexte. |
|
|
128
128
|
| `trimEmergencyPercent` | `95` | Palier d'urgence : fold mécanique forcé (sans appel de modèle annexe) à ce pourcentage. |
|
|
129
129
|
| `trimWindowTokens` | `0` | Plafond de fenêtre effectif pour le calcul des paliers : calculé sur min(fenêtre du modèle, plafond). `0` = suit `wmForceTokens`. |
|
|
130
|
-
| `trimProtectedTail` | `
|
|
131
|
-
| `trimMaxFoldsPerHour` | `
|
|
130
|
+
| `trimProtectedTail` | `10` | Les N derniers messages ne sont jamais repliés. |
|
|
131
|
+
| `trimMaxFoldsPerHour` | `30` | Plafond de cadence des folds par heure glissante pour le modèle annexe (les folds d'urgence en sont exemptés). |
|
|
132
132
|
| `trimSideModel` | non définie | Route du modèle annexe qui écrit les résumés. Vide = hériter du modèle courant de la session. |
|
|
133
133
|
| `trimFoldFallbackModel` | non définie | Route de relance quand le modèle annexe de résumé échoue ; un fold de pression dégrade alors en mécanique. Vide = pas de repli. Choisir une route avec de la marge sur cooldowns, contrôle de risque et concurrence. |
|
|
134
134
|
| `trimStateDir` | non défini | Redéfinit le répertoire d'état des folds. Vide = `<dshHome>/.dsh-switchman/state/trim/`. |
|
|
@@ -136,7 +136,7 @@ Toutes les clés vivent dans Réglages → dsh-switchman ; les valeurs par défa
|
|
|
136
136
|
|
|
137
137
|
**Chemins de déclenchement.** Les vérifications de paliers s'exécutent à la frontière d'inactivité et, en repli pour les hôtes où les événements d'état d'inactivité sont inaccessibles, après chaque fin de flux du modèle (limitées à une évaluation par 60 s et par session). Chaque décision — folds comme no-ops — est ajoutée comme une ligne `key=value` horodatée à `decisions.log` dans le répertoire d'état des folds (voir `trimStateDir`), donnant aux folds une piste d'audit hors ligne; le vocabulaire des lignes (`view-applied`, lignes de décision/résultat de fold, `surface-replace`, `surface-replace skipped reason=…`) est catalogué dans [docs/context-trim.md](./docs/context-trim.md).
|
|
138
138
|
|
|
139
|
-
**Vérité du fil et régime stationnaire.** Les lignes de décision portent `view=<n>` et, une fois qu'une réponse est arrivée, `wire=<n>` — le prompt réel du fournisseur (entrée non cachée + lecture de cache + écriture de cache, échantillonné depuis l'événement d'usage du stream). L'estimation de la view ne compte que le tableau de messages et lit toujours moins que le fil, du surcoût fixe (mesuré ≈ 17.3k : system prompt + schémas d'outils + persona), donc les paliers de pression et d'urgence évaluent sur `max(view, wire)`, et seul `wire` est une lecture de la taille du prompt. Sur une fenêtre de 150k, la dent de scie saine fait tourner le fil à ≈ 40k juste après un fold ↔
|
|
139
|
+
**Vérité du fil et régime stationnaire.** Les lignes de décision portent `view=<n>` et, une fois qu'une réponse est arrivée, `wire=<n>` — le prompt réel du fournisseur (entrée non cachée + lecture de cache + écriture de cache, échantillonné depuis l'événement d'usage du stream). L'estimation de la view ne compte que le tableau de messages et lit toujours moins que le fil, du surcoût fixe (mesuré ≈ 17.3k : system prompt + schémas d'outils + persona), donc les paliers de pression et d'urgence évaluent sur `max(view, wire)`, et seul `wire` est une lecture de la taille du prompt. Sur une fenêtre de 150k, la dent de scie saine fait tourner le fil à ≈ 40k juste après un fold ↔ 64–97.5k au suivant (≈27%–65% de la fenêtre), un fold par ~25k de croissance brute, le plafond étant arrimé près de 97.5k par le palier de pression plutôt que par la fenêtre. Si `view` monte sans qu'aucune ligne `surface-replace` n'apparaisse jamais, lisez les lignes d'omission (`incomplete-seqs`, `no-service`, `compaction-lock`).
|
|
140
140
|
|
|
141
141
|
**Époques de compactage de l'hôte.** Les références de fold sont ancrées dans les identifiants de messages et les hachages de contenu ; quand l'hôte compacte lui-même l'historique renvoyé, tout le registre vieillit d'un coup : plus aucun bloc ne se localise, la vue retombe silencieusement sur l'historique brut (fail-open — le journal des décisions note `view-applied applied=0`), et le plugin ré-ancre sa base de croissance sur la vue post-compaction à la requête suivante. La compaction de l'hôte est donc la couche de rognage de dernier recours ; les folds du plugin font le travail fin au sein d'une époque de l'hôte. Certains dispatches remettent des tableaux de requête ou des objets d'options entièrement gelés (la boucle d'agent actuelle gèle en profondeur les requêtes assemblées) ; pour eux, `injectView` rapporte l'issue dans le journal des décisions : `nothing-to-apply` (aucun bloc de fold localisé — l'historique brut EST la vue), `in-place`/`swapped` (la vue pliée est partie avec la requête) ou `none` (un fold existait mais le dispatch gelé ne pouvait pas le transporter — l'historique brut part sur le fil). **Le remplacement de surface est le chemin d'expédition quand il est disponible** (`surfaceFold`, activé par défaut) : à la frontière sérielle `agent/turn-stopping` plus un balayage d'inactivité, le plugin ajoute l'événement de mesure shadow-price à la manière de l'hôte et UN remplacement `user/message` portant `surfaceOp {op:'replace', startSeq, endSeq}` avec des `sourceEventSeqs` couvrant chaque nœud de surface masqué — le même mécanisme que celui de la compaction de l'hôte elle-même —, de sorte qu'un fold validé rejoint le fil depuis le niveau source, dispatches gelés compris. Tant que les dispatches récents d'une session consignent `none`, le plugin traite la vue comme une simple mesure : le niveau d'eau lit à la place le total rapporté par le fournisseur (le palier force et la remise automatique continuent de fonctionner), les cycles de fold se mettent en pause au lieu de brûler des appels au résumeur, et la bannière de rognage marque la ligne avec `wire=raw` (folds not shipping; watermark reads the tally) ; les hôtes sans le mécanisme de surface (ou avec l'option désactivée) gardent exactement cet ancien comportement.
|
|
142
142
|
|
package/README.it.md
CHANGED
|
@@ -102,7 +102,7 @@ Questi sono tutti i valori così come si presentano dopo una nuova installazione
|
|
|
102
102
|
|
|
103
103
|
**Instradamento per intent** (non disponibile per predefinito; servono classificatore + almeno un candidato + l'interruttore principale): `intentEnabled` = spento (spento, la voce Auto resta nascosta e le sessioni che l'avevano già scelta percorrono la catena di fallback); route del classificatore non impostata; tipo di classificatore `chat`; lista dei candidati vuota (le categorie preinstallate entrano nell'instradamento solo con un modello assegnato); finestra di cache `300` s / soglia di confidenza del cambio `80` / timeout di classificazione `60000` ms; cronologia di `6` messaggi / `2400` caratteri; `intentContextWindow` = `200000`.
|
|
104
104
|
|
|
105
|
-
**Trim del contesto**: `trimEnabled` = acceso; `trimMode` = `auto` (del tutto automatico); cancello di crescita `22500` + incremento `
|
|
105
|
+
**Trim del contesto**: `trimEnabled` = acceso; `trimMode` = `auto` (del tutto automatico); cancello di crescita `22500` + incremento `25000` token; pressione `65%` / emergenza `95%`; coda protetta `10` messaggi; tetto di cadenza dei fold `30` all'ora; modello secondario non impostato (eredita il modello della sessione) — dettagli nella sezione «Trim automatico del contesto» più sotto.
|
|
106
106
|
|
|
107
107
|
**Note di serie**: ① l'instradamento per intent non disponibile di serie è una scelta voluta — tre passi per attivarlo (classificatore, candidati, interruttore); ② la finestra effettiva di Auto vale di serie 200000 — la barriera di sicurezza garantisce 0.8×finestra ≥ force (150000), così la linea di compattazione del cuore (160000) resta sempre dopo la linea di consegna morbida (150000); ③ di serie la cosa più percettibile è il terzetto di soglie: 80k ricorda di delegare / 95k stringe la lettura / 150k consegna da sola (documento + compattazione) — senza alcuna impostazione.
|
|
108
108
|
|
|
@@ -123,12 +123,12 @@ Tutte le chiavi stanno in Impostazioni → dsh-switchman; i valori predefiniti v
|
|
|
123
123
|
| `trimEnabled` | `true` | Interruttore principale. Spento disattiva fold e metriche del tutto (il listener degrada a puro pass-through). |
|
|
124
124
|
| `trimMode` | `auto` | `off` solo misura / `advisory` fold guidati dal modello / `auto` fold guidati dal sistema. |
|
|
125
125
|
| `trimGrowthTokens` | `22500` | Cancello di crescita: ripiega quando la view in uscita è cresciuta di tanto dall'ultimo fold. |
|
|
126
|
-
| `trimIncrementTokens` | `
|
|
127
|
-
| `trimPressurePercent` | `
|
|
126
|
+
| `trimIncrementTokens` | `25000` | Compagno del cancello: anche l'incremento comprimibile contiguo deve raggiungere questa taglia. |
|
|
127
|
+
| `trimPressurePercent` | `65` | Scalino di pressione: ripiega quando l'uso della view raggiunge questa percentuale della finestra di contesto. |
|
|
128
128
|
| `trimEmergencyPercent` | `95` | Scalino di emergenza: fold meccanico forzato (nessuna chiamata al modello secondario) a questa percentuale. |
|
|
129
129
|
| `trimWindowTokens` | `0` | Limite di finestra effettivo per il calcolo delle soglie: calcolato su min(finestra del modello, limite). `0` = segue `wmForceTokens`. |
|
|
130
|
-
| `trimProtectedTail` | `
|
|
131
|
-
| `trimMaxFoldsPerHour` | `
|
|
130
|
+
| `trimProtectedTail` | `10` | Gli ultimi N messaggi non vengono mai ripiegati. |
|
|
131
|
+
| `trimMaxFoldsPerHour` | `30` | Tetto di cadenza dei fold per ora mobile per il modello secondario (quelli di emergenza ne sono esenti). |
|
|
132
132
|
| `trimSideModel` | non impostata | Route del modello secondario che scrive i riassunti. Vuota = eredita il modello attuale della sessione. |
|
|
133
133
|
| `trimFoldFallbackModel` | non impostata | Route di ripiego quando il modello secondario dei riassunti fallisce; un fold di pressione degrada quindi a meccanico. Vuota = nessun fallback. Scegli una route con margine su cooldown, risk control e concorrenza. |
|
|
134
134
|
| `trimStateDir` | non impostata | Sostituisce la directory dello stato dei fold. Vuota = `<dshHome>/.dsh-switchman/state/trim/`. |
|
|
@@ -136,7 +136,7 @@ Tutte le chiavi stanno in Impostazioni → dsh-switchman; i valori predefiniti v
|
|
|
136
136
|
|
|
137
137
|
**Percorsi di attivazione.** I controlli degli scalini girano al confine di inattività e, come ripiego per gli host dove gli eventi di stato di inattività non sono raggiungibili, dopo ogni completamento del flusso del modello (limitati a una valutazione ogni 60 s per sessione). Ogni decisione — fold e no-op allo stesso modo — viene aggiunta come una riga `key=value` con timestamp a `decisions.log` nella directory dello stato dei fold (vedi `trimStateDir`), dando ai fold una traccia di audit offline; il vocabolario delle righe (`view-applied`, righe di decisione/esito dei fold, `surface-replace`, `surface-replace skipped reason=…`) è catalogato in [docs/context-trim.md](./docs/context-trim.md).
|
|
138
138
|
|
|
139
|
-
**Verità del filo e stato stazionario.** Le righe di decisione portano `view=<n>` e, una volta arrivata una risposta, `wire=<n>` — il prompt reale del provider (input non in cache + lettura cache + scrittura cache, campionato dall'evento di utilizzo dello stream). La stima della view conta solo l'array di messaggi e legge sempre meno del filo, della misura dell'overhead fisso (misurato ≈ 17.3k: system prompt + schemi degli strumenti + persona), quindi gli scalini di pressione e di emergenza valutano su `max(view, wire)`, e solo `wire` è una lettura della dimensione del prompt. Su una finestra da 150k l'andamento a dente di sega sano porta il filo a ≈ 40k subito dopo un fold ↔
|
|
139
|
+
**Verità del filo e stato stazionario.** Le righe di decisione portano `view=<n>` e, una volta arrivata una risposta, `wire=<n>` — il prompt reale del provider (input non in cache + lettura cache + scrittura cache, campionato dall'evento di utilizzo dello stream). La stima della view conta solo l'array di messaggi e legge sempre meno del filo, della misura dell'overhead fisso (misurato ≈ 17.3k: system prompt + schemi degli strumenti + persona), quindi gli scalini di pressione e di emergenza valutano su `max(view, wire)`, e solo `wire` è una lettura della dimensione del prompt. Su una finestra da 150k l'andamento a dente di sega sano porta il filo a ≈ 40k subito dopo un fold ↔ 64–97.5k al successivo (≈27%–65% della finestra), un fold ogni ~25k di crescita grezza, con il tetto fissato vicino a 97.5k dallo scalino di pressione anziché dalla finestra. Se `view` sale senza che compaia mai una riga `surface-replace`, leggi le righe di salto (`incomplete-seqs`, `no-service`, `compaction-lock`).
|
|
140
140
|
|
|
141
141
|
**Epoche di compattazione dell'host.** I riferimenti dei fold sono ancorati a id dei messaggi e hash dei contenuti; quando l'host compatta esso stesso la cronologia reinviata, l'intero registro invecchia in un colpo: nessun blocco si localizza, la vista retrocede silenziosamente alla cronologia grezza (fail-open — il registro delle decisioni annota `view-applied applied=0`) e il plugin re-ancora la sua baseline di crescita sulla vista post-compattazione alla richiesta successiva. La compattazione dell'host è quindi lo strato di taglio di ultima istanza; i fold del plugin fanno il lavoro fine all'interno di un'epoca dell'host. Alcuni dispatch consegnano array di richiesta o oggetti opzioni completamente congelati (l'attuale loop d'agente congela in profondità le richieste assemblate); per essi `injectView` riporta l'esito nel registro delle decisioni: `nothing-to-apply` (nessun blocco di fold localizzato — la cronologia grezza È la vista), `in-place`/`swapped` (la vista piegata è partita con la richiesta) oppure `none` (esisteva un fold ma il dispatch congelato non poteva portarlo — sul filo va la cronologia grezza). **La sostituzione di superficie è la via di spedizione quando disponibile** (`surfaceFold`, attivo per impostazione predefinita): al confine seriale `agent/turn-stopping` più una spazzata di inattività, il plugin aggiunge l'evento di misurazione shadow-price in stile host e UNA sostituzione `user/message` che porta `surfaceOp {op:'replace', startSeq, endSeq}` con `sourceEventSeqs` che copre ogni nodo di superficie in ombra — lo stesso meccanismo usato dalla compattazione dell'host stessa — cosicché un fold confermato raggiunge il filo dal livello sorgente, dispatch congelati compresi. Finché i dispatch recenti di una sessione registrano `none`, il plugin tratta la vista come sola misurazione: il livello dell'acqua misura invece il conteggio riportato dal provider (lo scalino force e la consegna automatica continuano a funzionare), i cicli di fold si mettono in pausa invece di bruciare chiamate al riassuntore, e il banner di taglio contrassegna la riga con `wire=raw` (folds not shipping; watermark reads the tally); gli host senza il meccanismo di superficie (o con il flag spento) mantengono esattamente quel comportamento legacy.
|
|
142
142
|
|
package/README.ja.md
CHANGED
|
@@ -102,7 +102,7 @@ bash <インストールディレクトリ>/skills/db-query/scripts/setup.sh
|
|
|
102
102
|
|
|
103
103
|
**意図認識**(既定では利用不可。分類器+候補最低1つ+マスタートグルのオンが必要):`intentEnabled` = オフ(オフの間は Auto エントリが隠れ、Auto を選んでいたセッションはフォールバックチェーンへ流れる)。分類器ルートは未設定。分類器タイプは `chat`。候補リストは空(プリセット分類はモデルを埋めないとルーティングに参加しない)。キャッシュウィンドウ `300` 秒 / 切替信頼度 `80` / 分類タイムアウト `60000` ms。履歴 `6` 件 / `2400` 文字。`intentContextWindow` = `200000`。
|
|
104
104
|
|
|
105
|
-
**コンテキストトリム**:`trimEnabled` = オン;`trimMode` = `auto`(完全自動);成長ゲート `22500` + インクリメント `
|
|
105
|
+
**コンテキストトリム**:`trimEnabled` = オン;`trimMode` = `auto`(完全自動);成長ゲート `22500` + インクリメント `25000` トークン;圧力 `65%` / 緊急 `95%`;保護テール `10` 件;fold ペース上限は毎時 `30` 回;サイドモデルは未設定(セッションモデルを継承)——詳細は下の「自動コンテキストトリム」節で。
|
|
106
106
|
|
|
107
107
|
**初期状態のポイント**:① 意図認識が既定で使えないのは意図的な設計で、有効化は3ステップ(分類器、候補、トグル)。② Auto の実効ウィンドウは既定で 200000——ガードレールにより 0.8×ウィンドウ ≥ force 段(150000)が保証され、コア圧縮線(160000)は常にスムーズ引き継ぎ線(150000)より後ろにある。③ 既定でいちばん体感できるのは水位の3点セット:80k で委譲を促し、95k で読み取りを収束させ、150k で自動引き継ぎ(文書作成+圧縮)。設定は一切不要。
|
|
108
108
|
|
|
@@ -123,12 +123,12 @@ bash <インストールディレクトリ>/skills/db-query/scripts/setup.sh
|
|
|
123
123
|
| `trimEnabled` | `true` | マスタースイッチ。OFF で fold とメトリクスを完全停止(リスナーは純パススルーに退化)。 |
|
|
124
124
|
| `trimMode` | `auto` | `off` 計測のみ / `advisory` モデル駆動 fold / `auto` システム駆動 fold。 |
|
|
125
125
|
| `trimGrowthTokens` | `22500` | 成長ゲート:前回の fold 以降にアウトバウンド view がこれだけ増えたら fold。 |
|
|
126
|
-
| `trimIncrementTokens` | `
|
|
127
|
-
| `trimPressurePercent` | `
|
|
126
|
+
| `trimIncrementTokens` | `25000` | ゲートの同伴条件:連続圧縮可能インクリメントもこの規模に達する必要あり。 |
|
|
127
|
+
| `trimPressurePercent` | `65` | 圧力段:view 使用量がコンテキストウィンドウのこの割合に達したら fold。 |
|
|
128
128
|
| `trimEmergencyPercent` | `95` | 緊急段:この割合で機械 fold を強制(サイドモデル呼び出しなし)。 |
|
|
129
129
|
| `trimWindowTokens` | `0` | ティア計算の実効ウィンドウ上限:min(モデルウィンドウ, 上限) で計算。`0` = `wmForceTokens` に追従。 |
|
|
130
|
-
| `trimProtectedTail` | `
|
|
131
|
-
| `trimMaxFoldsPerHour` | `
|
|
130
|
+
| `trimProtectedTail` | `10` | 最後の N メッセージは決して fold されない。 |
|
|
131
|
+
| `trimMaxFoldsPerHour` | `30` | ローリング1時間あたりのサイドモデル fold ペース上限(緊急段は対象外)。 |
|
|
132
132
|
| `trimSideModel` | 未設定 | サマリを書くサイドモデルのルート。空欄 = セッションの現在モデルを継承。 |
|
|
133
133
|
| `trimFoldFallbackModel` | 未設定 | サマリのサイドモデルが失敗したときに折り畳みが再試行するルート。プレッシャー段でも失敗すると機械折り畳みに縮退。空欄 = フォールバックなし。クールダウン・リスク制御・同時実行に余裕のあるルートを推奨。 |
|
|
134
134
|
| `trimStateDir` | 未設定 | fold 状態ディレクトリの上書き。空欄 = `<dshHome>/.dsh-switchman/state/trim/`。 |
|
|
@@ -136,7 +136,7 @@ bash <インストールディレクトリ>/skills/db-query/scripts/setup.sh
|
|
|
136
136
|
|
|
137
137
|
**トリガーパス。** 段階チェックはアイドル境界で走り、アイドル状態イベントが届かないホストへのフォールバックとして、各モデルストリーム完了後にも走る(セッションごとに 60 秒につき 1 回の評価へスロットル)。すべての決定——fold も no-op も同様に——は、fold 状態ディレクトリ(`trimStateDir` を参照)内の `decisions.log` へ タイムスタンプ付きの 1 行の `key=value` として追記され、fold にオフラインの監査証跡を与える;行の語彙(`view-applied`、fold の決定/結果行、`surface-replace`、`surface-replace skipped reason=…`)は [docs/context-trim.md](./docs/context-trim.md) に一覧化されています。
|
|
138
138
|
|
|
139
|
-
**回線の真実と定常状態。** 決定行は `view=<n>` を持ち、応答が着地した後は `wire=<n>` も持つ——実際のプロバイダプロンプト(非キャッシュ入力 + キャッシュ読み取り + キャッシュ書き込み、ストリームの usage イベントからサンプリング)である。view の推定はメッセージ配列だけを数えるため、固定オーバーヘッド(実測 ≈ 17.3k:システムプロンプト + ツールスキーマ + persona)の分だけ常に回線より小さく読める。したがって圧力段と緊急段は `max(view, wire)` で評価し、プロンプトサイズの計測となるのは `wire` だけである。150k ウィンドウでは、健全なノコギリ波は fold 直後に回線 ≈ 40k ↔ 次の fold で
|
|
139
|
+
**回線の真実と定常状態。** 決定行は `view=<n>` を持ち、応答が着地した後は `wire=<n>` も持つ——実際のプロバイダプロンプト(非キャッシュ入力 + キャッシュ読み取り + キャッシュ書き込み、ストリームの usage イベントからサンプリング)である。view の推定はメッセージ配列だけを数えるため、固定オーバーヘッド(実測 ≈ 17.3k:システムプロンプト + ツールスキーマ + persona)の分だけ常に回線より小さく読める。したがって圧力段と緊急段は `max(view, wire)` で評価し、プロンプトサイズの計測となるのは `wire` だけである。150k ウィンドウでは、健全なノコギリ波は fold 直後に回線 ≈ 40k ↔ 次の fold で 64–97.5k(ウィンドウの ≈27%–65%)を往復し、生の成長 ~25k ごとに fold 1 回、天井はウィンドウではなく圧力段によって 97.5k 付近に固定される。`surface-replace` 行が一度も現れないのに `view` が上昇する場合は、スキップ行(`incomplete-seqs`, `no-service`, `compaction-lock`)を読む。
|
|
140
140
|
|
|
141
141
|
**ホスト圧縮エポック。** fold の参照はメッセージ id と内容ハッシュにアンカーされるため、ホスト側の圧縮が再送履歴を置き換えると帳簿全体が一度に老化します。すべてのブロックが位置を特定できなくなり、view は元の履歴へ静かにフォールバックし(fail-open —— 決定ログには `view-applied applied=0` が記録されます)、プラグインは次のリクエストで成長ベースラインを圧縮後のビューに再アンカーします。ホスト圧縮は最後のバックストップとなるトリム層であり、プラグインの fold は単一ホストエポック内のきめ細かい作業を担います。 一部のディスパッチは、完全に凍結されたリクエスト配列やオプションオブジェクトを渡されます(現在のエージェントループは組み立て済みリクエストをディープフリーズします)。そのようなディスパッチについて、`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}` を運ぶ 1 件の `user/message` 置換イベントを追記します。`sourceEventSeqs` は影となる表面ノードをすべてカバーします——ホスト自身の圧縮と同じ機構なので、コミット済みの fold はソース層から回線へ届き、凍結ディスパッチも例外ではありません。セッションの最近のディスパッチが `none` を記録している間、プラグインは view を計測専用と扱います:水位は代わりにプロバイダ報告の集計を測り(force 段階と自動引き継ぎは働き続け)、fold サイクルはサマライザ呼び出しを空焼きせず一時停止し、トリムバナーは当該行に `wire=raw`(folds not shipping; watermark reads the tally)の印を付けます。surface 機構を持たないホスト(またはフラグが off の場合)は、まさにこの従来動作を保ちます。
|
|
142
142
|
|
package/README.ko.md
CHANGED
|
@@ -102,7 +102,7 @@ bash <설치-디렉터리>/skills/db-query/scripts/setup.sh
|
|
|
102
102
|
|
|
103
103
|
**의도 인식**(기본은 사용 불가. 분류기 + 후보 최소 1개 + 마스터 토글 켜기가 필요): `intentEnabled` = 끔(꺼져 있으면 Auto 항목은 숨겨지고, Auto를 선택해 둔 세션은 폴백 체인으로 흐른다). 분류기 라우트 미설정. 분류기 유형 `chat`. 후보 목록은 빈 상태(프리셋 분류는 모델을 채워야 라우팅에 참여). 캐시 창 `300`초 / 전환 신뢰도 `80` / 분류 타임아웃 `60000`ms. 히스토리 `6`건 / `2400`자. `intentContextWindow` = `200000`.
|
|
104
104
|
|
|
105
|
-
**컨텍스트 트림**: `trimEnabled` = 켬; `trimMode` = `auto`(완전 자동); 성장 게이트 `22500` + 증분 `
|
|
105
|
+
**컨텍스트 트림**: `trimEnabled` = 켬; `trimMode` = `auto`(완전 자동); 성장 게이트 `22500` + 증분 `25000` 토큰; 압력 `65%` / 비상 `95%`; 보호 테일 `10`건; fold 케이던스 상한 시간당 `30`회; 사이드 모델 미설정(세션 모델 상속) — 자세한 내용은 아래 "자동 컨텍스트 트림" 절에서.
|
|
106
106
|
|
|
107
107
|
**기본 상태에서 알아둘 점**: ① 의도 인식이 기본으로 불가능한 것은 의도된 설계고, 세 단계로 켠다(분류기, 후보, 토글). ② Auto의 실효 창은 기본값이 200000이다 — 가드레일이 0.8×창 ≥ force 단계(150000)를 보장하므로, 코어 압축선(160000)은 언제나 부드러운 인계선(150000)보다 뒤에 있다. ③ 기본 상태에서 가장 체감되는 건 수위 3종 세트다: 80k에 위임 알림 / 95k에 읽기 수렴 / 150k에 자동 인계(문서 작성 + 압축) — 설정은 아무것도 필요 없다.
|
|
108
108
|
|
|
@@ -123,12 +123,12 @@ bash <설치-디렉터리>/skills/db-query/scripts/setup.sh
|
|
|
123
123
|
| `trimEnabled` | `true` | 마스터 스위치. 끄면 fold와 메트릭이 완전히 정지한다(리스너는 순수 패스스루로 퇴화). |
|
|
124
124
|
| `trimMode` | `auto` | `off` 측정만 / `advisory` 모델 주도 fold / `auto` 시스템 주도 fold. |
|
|
125
125
|
| `trimGrowthTokens` | `22500` | 성장 게이트: 지난 fold 이후 아웃바운드 view가 이만큼 자라면 fold. |
|
|
126
|
-
| `trimIncrementTokens` | `
|
|
127
|
-
| `trimPressurePercent` | `
|
|
126
|
+
| `trimIncrementTokens` | `25000` | 게이트 동반 조건: 연속 압축 가능 증분도 이 규모에 달해야 한다. |
|
|
127
|
+
| `trimPressurePercent` | `65` | 압력 단계: view 사용량이 컨텍스트 창의 이 백분율에 달하면 fold. |
|
|
128
128
|
| `trimEmergencyPercent` | `95` | 비상 단계: 이 백분율에서 기계 fold 강제(사이드 모델 호출 없음). |
|
|
129
129
|
| `trimWindowTokens` | `0` | 티어 계산의 유효 윈도우 상한: min(모델 윈도우, 상한)으로 계산. `0` = `wmForceTokens`를 따름. |
|
|
130
|
-
| `trimProtectedTail` | `
|
|
131
|
-
| `trimMaxFoldsPerHour` | `
|
|
130
|
+
| `trimProtectedTail` | `10` | 마지막 N개 메시지는 절대 fold되지 않는다. |
|
|
131
|
+
| `trimMaxFoldsPerHour` | `30` | 롤링 1시간당 사이드 모델 fold 케이던스 상한(비상 단계는 제외). |
|
|
132
132
|
| `trimSideModel` | 미설정 | 요약을 쓰는 사이드 모델 라우트. 비어 있으면 세션의 현재 모델을 상속. |
|
|
133
133
|
| `trimFoldFallbackModel` | 미설정 | 요약 사이드 모델 실패 시 폴드가 재시도하는 라우트. 프레셔 단계에서도 실패하면 기계 폴드로 강등. 비어 있으면 폴백 없음. 쿨다운·리스크 컨트롤·동시 실행에 여유가 있는 라우트 권장. |
|
|
134
134
|
| `trimStateDir` | 미설정 | fold 상태 디렉터리 재정의. 비어 있으면 `<dshHome>/.dsh-switchman/state/trim/`. |
|
|
@@ -136,7 +136,7 @@ bash <설치-디렉터리>/skills/db-query/scripts/setup.sh
|
|
|
136
136
|
|
|
137
137
|
**트리거 경로.** 단계 검사는 유휴 경계에서 돌아가고, 유휴 상태 이벤트가 도달하지 않는 호스트를 위한 폴백으로 각 모델 스트림 완료 후에도 돌아간다(세션당 60초에 한 번 평가로 스로틀링). 모든 결정 — fold든 no-op든 마찬가지 — 는 fold 상태 디렉터리(`trimStateDir` 참조) 안의 `decisions.log`에 한 줄의 `key=value`(타임스탬프 포함)로 추가되어 fold에 오프라인 감사 추적을 제공한다; 행 어휘(`view-applied`, fold 결정/결과 행, `surface-replace`, `surface-replace skipped reason=…`)는 [docs/context-trim.md](./docs/context-trim.md)에 정리되어 있다.
|
|
138
138
|
|
|
139
|
-
**회선의 진실과 정상 상태.** 결정 행은 `view=<n>`를 담고, 응답이 도착한 뒤에는 `wire=<n>`도 담는다 — 실제 프로바이더 프롬프트(비캐시 입력 + 캐시 읽기 + 캐시 쓰기, 스트림의 usage 이벤트에서 샘플링)이다. view 추정은 messages 배열만 세므로 고정 오버헤드(실측 ≈ 17.3k: 시스템 프롬프트 + 도구 스키마 + persona)만큼 항상 회선보다 작게 읽힌다. 따라서 압력 단계와 비상 단계는 `max(view, wire)`로 평가하며, 프롬프트 크기 측정은 `wire`뿐이다. 150k 창에서 건강한 톱니파는 fold 직후 회선 ≈ 40k ↔ 다음 fold에서
|
|
139
|
+
**회선의 진실과 정상 상태.** 결정 행은 `view=<n>`를 담고, 응답이 도착한 뒤에는 `wire=<n>`도 담는다 — 실제 프로바이더 프롬프트(비캐시 입력 + 캐시 읽기 + 캐시 쓰기, 스트림의 usage 이벤트에서 샘플링)이다. view 추정은 messages 배열만 세므로 고정 오버헤드(실측 ≈ 17.3k: 시스템 프롬프트 + 도구 스키마 + persona)만큼 항상 회선보다 작게 읽힌다. 따라서 압력 단계와 비상 단계는 `max(view, wire)`로 평가하며, 프롬프트 크기 측정은 `wire`뿐이다. 150k 창에서 건강한 톱니파는 fold 직후 회선 ≈ 40k ↔ 다음 fold에서 64–97.5k(창의 ≈27%–65%)를 오가고, 원시 성장 ~25k마다 fold가 한 번 일어나며, 상한은 창이 아니라 압력 단계에 의해 97.5k 근처로 고정된다. `surface-replace` 행이 한 번도 나타나지 않는데 `view`가 오르면, 스킵 행(`incomplete-seqs`, `no-service`, `compaction-lock`)을 읽어라.
|
|
140
140
|
|
|
141
141
|
**호스트 압축 에포크.** fold 참조는 메시지 id와 내용 해시에 고정되므로, 호스트 자체의 압축이 재전송 기록을 대체하면 장부 전체가 한꺼번에 노후됩니다. 모든 블록이 위치를 찾지 못하고, view는 조용히 원본 기록으로 폴백하며(fail-open — 결정 로그에 `view-applied applied=0`가 기록됨), 플러그인은 다음 요청에서 성장 기준선을 압축 후 뷰에 다시 고정합니다. 호스트 압축이 최후의 트림 계층이고, 플러그인 fold는 하나의 호스트 에포크 안에서 세밀한 작업을 담당합니다. 일부 디스패치는 완전히 동결된 요청 배열이나 옵션 객체를 건네받습니다(현재 에이전트 루프는 조립된 요청을 딥프리즈합니다). 이런 디스패치에 대해 `injectView`는 결과를 결정 로그에 보고합니다: `nothing-to-apply`(위치를 찾은 fold 블록이 없음 — 원본 기록이 곧 view임), `in-place`/`swapped`(fold된 뷰를 실어 보냄), 또는 `none`(fold가 존재했지만 동결된 디스패치는 그것을 실을 수 없음 — 회선에는 원본 기록이 흐름). **Surface replace는 사용 가능할 때의 발송 경로입니다**(`surfaceFold`, 기본값 켬): 직렬 `agent/turn-stopping` 경계에 유휴 스윕을 더한 시점에, 플러그인은 호스트 방식의 shadow-price 계량 이벤트와 `surfaceOp {op:'replace', startSeq, endSeq}`를 실은 단 한 건의 `user/message` 치환 이벤트를 덧붙입니다. `sourceEventSeqs`는 가려진 표면 노드 전부를 커버합니다 — 호스트 자체 압축이 쓰는 바로 그 메커니즘이라, 커밋된 fold는 소스 계층에서 회선까지 도달하며 동결 디스패치도 예외가 아닙니다. 세션의 최근 디스패치가 `none`을 기록하는 동안, 플러그인은 view를 계측 전용으로 취급합니다: 수위는 대신 프로바이더가 보고한 집계를 재고(force 단계와 자동 인계는 계속 동작하며), fold 사이클은 요약기 호출을 태우지 않고 일시 중지하며, 트림 배너는 해당 줄에 `wire=raw`(folds not shipping; watermark reads the tally) 표식을 붙입니다. surface 메커니즘이 없는 호스트(또는 플래그가 꺼진 경우)는 정확히 이 구동 동작을 유지합니다.
|
|
142
142
|
|
package/README.md
CHANGED
|
@@ -102,7 +102,7 @@ Everything below is the full set of defaults after a fresh install (authoritativ
|
|
|
102
102
|
|
|
103
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; `intentContextWindow` = `200000`.
|
|
104
104
|
|
|
105
|
-
**Context trim**: `trimEnabled` = on; `trimMode` = `auto` (fully automatic); growth gate `22500` tokens + increment `
|
|
105
|
+
**Context trim**: `trimEnabled` = on; `trimMode` = `auto` (fully automatic); growth gate `22500` tokens + increment `25000` tokens; pressure `65%` / emergency `95%`; protected tail `10` messages; fold cadence cap `30` per hour; side model unset (inherits the session model); **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
106
|
|
|
107
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 200000 out of the box — the guardrail guarantees 0.8×window ≥ force (150000), so the core compaction line (160000) always sits after the smooth-handover line (150000); ③ the most tangible out-of-the-box effect is the watermark trio: 80k nudges delegation / 95k tightens reading / 150k backs up and hands over automatically — no configuration needed.
|
|
108
108
|
|
|
@@ -123,12 +123,12 @@ All keys live in Settings → dsh-switchman; defaults from `host/config.js`:
|
|
|
123
123
|
| `trimEnabled` | `true` | Master switch. OFF disables folding and metrics entirely (the listener degrades to a pure pass-through). |
|
|
124
124
|
| `trimMode` | `auto` | `off` measure only / `advisory` model-driven folds / `auto` system-driven folds. |
|
|
125
125
|
| `trimGrowthTokens` | `22500` | Growth gate: fold when the outbound view grew this much since the last fold. |
|
|
126
|
-
| `trimIncrementTokens` | `
|
|
127
|
-
| `trimPressurePercent` | `
|
|
126
|
+
| `trimIncrementTokens` | `25000` | Gate companion: the contiguous compressible increment must also reach this size. |
|
|
127
|
+
| `trimPressurePercent` | `65` | Pressure tier: fold when view usage reaches this percent of the context window. |
|
|
128
128
|
| `trimEmergencyPercent` | `95` | Emergency tier: forced mechanical fold (no side-model call) at this percent. |
|
|
129
129
|
| `trimWindowTokens` | `0` | Effective-window cap for tier math: tiers are computed against min(model window, cap). `0` = follow `wmForceTokens`. |
|
|
130
|
-
| `trimProtectedTail` | `
|
|
131
|
-
| `trimMaxFoldsPerHour` | `
|
|
130
|
+
| `trimProtectedTail` | `10` | The last N messages are never folded. |
|
|
131
|
+
| `trimMaxFoldsPerHour` | `30` | Side-model fold cadence cap per rolling hour (emergency folds are exempt). |
|
|
132
132
|
| `trimSideModel` | unset | Route for the summary side model. Empty = inherit the session's current model. |
|
|
133
133
|
| `trimFoldFallbackModel` | unset | Route the fold retries on when the summary side model fails; a pressure fold then degrades to a mechanical one. Empty = no fallback leg. Pick a route with headroom on cooldowns, risk control, and concurrency limits. |
|
|
134
134
|
| `trimStateDir` | unset | Fold-state directory override. Empty = `<dshHome>/.dsh-switchman/state/trim/`. |
|
|
@@ -136,7 +136,7 @@ All keys live in Settings → dsh-switchman; defaults from `host/config.js`:
|
|
|
136
136
|
|
|
137
137
|
**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).
|
|
138
138
|
|
|
139
|
-
**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 150k window the healthy sawtooth runs wire ≈ 40k just after a fold ↔
|
|
139
|
+
**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 150k window the healthy sawtooth runs wire ≈ 40k just after a fold ↔ 64–97.5k at the next one (≈27%–65% of the window), one fold per ~25k of raw growth, with the ceiling pinned near 97.5k 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`).
|
|
140
140
|
|
|
141
141
|
**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.
|
|
142
142
|
|
package/README.pt.md
CHANGED
|
@@ -102,7 +102,7 @@ Estes são todos os valores logo depois de uma instalação nova (fonte autorita
|
|
|
102
102
|
|
|
103
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` = `200000`.
|
|
104
104
|
|
|
105
|
-
**Trim de contexto**: `trimEnabled` = ligado; `trimMode` = `auto` (totalmente automático); portão de crescimento `22500` + incremento `
|
|
105
|
+
**Trim de contexto**: `trimEnabled` = ligado; `trimMode` = `auto` (totalmente automático); portão de crescimento `22500` + incremento `25000` tokens; pressão `65%` / emergência `95%`; cauda protegida `10` 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
106
|
|
|
107
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 200000 — o guard-rail garante 0.8×janela ≥ force (150000), então a linha de compactação do núcleo (160000) fica sempre depois da linha de entrega suave (150000); ③ o que mais se sente de fábrica é o trio de níveis: 80k lembra de delegar / 95k aperta a leitura / 150k entrega sozinho (documento + compactação) — sem nenhuma configuração.
|
|
108
108
|
|
|
@@ -123,12 +123,12 @@ Todas as chaves ficam em Configurações → dsh-switchman; os padrões vêm de
|
|
|
123
123
|
| `trimEnabled` | `true` | Chave mestra. Desligado desativa folds e métricas por completo (o listener degrada a puro pass-through). |
|
|
124
124
|
| `trimMode` | `auto` | `off` só medição / `advisory` folds conduzidos pelo modelo / `auto` folds conduzidos pelo sistema. |
|
|
125
125
|
| `trimGrowthTokens` | `22500` | Portão de crescimento: dobra quando a view de saída crescer isso desde o último fold. |
|
|
126
|
-
| `trimIncrementTokens` | `
|
|
127
|
-
| `trimPressurePercent` | `
|
|
126
|
+
| `trimIncrementTokens` | `25000` | Companheiro do portão: o incremento comprimível contíguo também precisa alcançar esse tamanho. |
|
|
127
|
+
| `trimPressurePercent` | `65` | Degrau de pressão: dobra quando o uso da view alcança essa porcentagem da janela de contexto. |
|
|
128
128
|
| `trimEmergencyPercent` | `95` | Degrau de emergência: fold mecânico forçado (sem chamada ao modelo secundário) nessa porcentagem. |
|
|
129
129
|
| `trimWindowTokens` | `0` | Limite de janela efetivo para o cálculo dos níveis: calculado sobre min(janela do modelo, limite). `0` = segue `wmForceTokens`. |
|
|
130
|
-
| `trimProtectedTail` | `
|
|
131
|
-
| `trimMaxFoldsPerHour` | `
|
|
130
|
+
| `trimProtectedTail` | `10` | As últimas N mensagens nunca são dobradas. |
|
|
131
|
+
| `trimMaxFoldsPerHour` | `30` | Teto de cadência de folds por hora rolante para o modelo secundário (os de emergência ficam fora). |
|
|
132
132
|
| `trimSideModel` | não definida | Rota do modelo secundário que escreve os resumos. Vazia = herdar o modelo atual da sessão. |
|
|
133
133
|
| `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. Escolha uma rota com folga em cooldowns, controle de risco e concorrência. |
|
|
134
134
|
| `trimStateDir` | não definido | Sobrepõe o diretório do estado de folds. Vazio = `<dshHome>/.dsh-switchman/state/trim/`. |
|
|
@@ -136,7 +136,7 @@ Todas as chaves ficam em Configurações → dsh-switchman; os padrões vêm de
|
|
|
136
136
|
|
|
137
137
|
**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).
|
|
138
138
|
|
|
139
|
-
**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 150k o dente-de-serra saudável deixa o fio em ≈ 40k logo após um fold ↔
|
|
139
|
+
**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 150k o dente-de-serra saudável deixa o fio em ≈ 40k logo após um fold ↔ 64–97.5k no seguinte (≈27%–65% da janela), um fold a cada ~25k de crescimento bruto, com o teto fixado perto de 97.5k 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`).
|
|
140
140
|
|
|
141
141
|
**É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.
|
|
142
142
|
|
package/README.ru.md
CHANGED
|
@@ -102,7 +102,7 @@ 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` + прирост `
|
|
105
|
+
**Обрезка контекста**: `trimEnabled` = включено; `trimMode` = `auto` (полностью автоматически); ворота роста `22500` + прирост `25000` токенов; давление `65%` / авария `95%`; защищённый хвост `10` сообщений; потолок частоты fold-ов `30` в час; боковая модель не задана (наследует модель сессии) — подробности в разделе «Автоматическая обрезка контекста» ниже.
|
|
106
106
|
|
|
107
107
|
**Что важно знать из коробки**: ① то, что маршрутизация по намерению недоступна из коробки, — намеренное решение; включается в три шага (классификатор, кандидаты, переключатель); ② эффективное окно Auto из коробки равно 200000 — защитная планка гарантирует 0.8×окна ≥ force (150000), поэтому линия сжатия ядра (160000) всегда стоит после линии плавной передачи (150000); ③ заметнее всего из коробки троица уровней: 80k напоминает делегировать / 95k ужимает чтение / 150k сам передаёт управление (документ + сжатие) — без каких-либо настроек.
|
|
108
108
|
|
|
@@ -123,12 +123,12 @@ bash <install-dir>/skills/db-query/scripts/setup.sh
|
|
|
123
123
|
| `trimEnabled` | `true` | Главный выключатель. ВЫКЛ полностью отключает fold-ы и метрики (слушатель вырождается в чистый pass-through). |
|
|
124
124
|
| `trimMode` | `auto` | `off` только измерения / `advisory` fold-ы по решению модели / `auto` fold-ы по решению системы. |
|
|
125
125
|
| `trimGrowthTokens` | `22500` | Ворота роста: fold, когда исходящая view выросла на столько с прошлого fold-а. |
|
|
126
|
-
| `trimIncrementTokens` | `
|
|
127
|
-
| `trimPressurePercent` | `
|
|
126
|
+
| `trimIncrementTokens` | `25000` | Спутник ворот: непрерывный сжимаемый прирост тоже должен достичь этого размера. |
|
|
127
|
+
| `trimPressurePercent` | `65` | Ступень давления: fold, когда использование view достигает этого процента окна контекста. |
|
|
128
128
|
| `trimEmergencyPercent` | `95` | Аварийная ступень: принудительный механический fold (без вызова боковой модели) на этом проценте. |
|
|
129
129
|
| `trimWindowTokens` | `0` | Эффективный лимит окна для расчёта уровней: считается от min(окно модели, лимит). `0` = следует за `wmForceTokens`. |
|
|
130
|
-
| `trimProtectedTail` | `
|
|
131
|
-
| `trimMaxFoldsPerHour` | `
|
|
130
|
+
| `trimProtectedTail` | `10` | Последние N сообщений никогда не сворачиваются. |
|
|
131
|
+
| `trimMaxFoldsPerHour` | `30` | Потолок частоты fold-ов боковой модели за скользящий час (аварийные не в счёт). |
|
|
132
132
|
| `trimSideModel` | не задан | Маршрут боковой модели, пишущей резюме. Пусто = унаследовать текущую модель сессии. |
|
|
133
133
|
| `trimFoldFallbackModel` | не задан | Маршрут повторной попытки, если боковая модель резюме не сработала; pressure-fold затем деградирует до механического. Пусто = без резерва. Выбирайте маршрут с запасом по кулдаунам, риск-контролю и параллелизму. |
|
|
134
134
|
| `trimStateDir` | не задан | Переопределяет каталог состояния fold-ов. Пусто = `<dshHome>/.dsh-switchman/state/trim/`. |
|
|
@@ -136,7 +136,7 @@ bash <install-dir>/skills/db-query/scripts/setup.sh
|
|
|
136
136
|
|
|
137
137
|
**Пути срабатывания.** Проверки ступеней выполняются на границе простоя и — как запасной путь для хостов, где события статуса простоя недостижимы — после завершения каждого потока модели (не чаще одной оценки в 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).
|
|
138
138
|
|
|
139
|
-
**Правда провода и установившийся режим.** Строки решений несут `view=<n>` и, после того как ответ пришёл, `wire=<n>` — реальный промпт провайдера (некэшированный вход + чтение кэша + запись кэша, сэмплированные из usage-события потока). Оценка view считает только массив сообщений и всегда читается меньше провода на фиксированный оверхед (измерено ≈ 17.3k: системный промпт + схемы инструментов + persona), поэтому ступени давления и аварии оценивают по `max(view, wire)`, и только `wire` — это измерение размера промпта. На окне 150k здоровая пилообразная кривая ведёт провод от ≈ 40k сразу после fold ↔
|
|
139
|
+
**Правда провода и установившийся режим.** Строки решений несут `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
140
|
|
|
141
141
|
**Эпохи сжатия на стороне хоста.** Ссылки 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-механизма (или с выключенным флагом) сохраняют ровно это прежнее поведение.
|
|
142
142
|
|
package/README.zh-TW.md
CHANGED
|
@@ -102,7 +102,7 @@ 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 + 增量 `
|
|
105
|
+
**上下文裁剪**:`trimEnabled` = 開;`trimMode` = `auto`(全自動);增長閘門 `22500` token + 增量 `25000` token;壓力 `65%` / 緊急 `95%`;保護尾部 `10` 則;折疊節奏上限每小時 `30` 次;side model 未設定(繼承對話模型)——詳見下文「自動上下文裁剪」一節。
|
|
106
106
|
|
|
107
107
|
**開箱要點**:① 意圖識別開箱不可用是有意設計,三步開啟(分類器、候選、開關);② Auto 有效視窗開箱即為 200000——護欄保證 0.8×視窗 ≥ force 級(150000),核心壓縮線(160000)永遠在平滑交接線(150000)之後;③ 開箱最有感的是水位三件套:80k 提醒委派 / 95k 收斂讀取 / 150k 自動交接(寫文件+壓縮),無須任何設定。
|
|
108
108
|
|
|
@@ -123,12 +123,12 @@ bash <安裝目錄>/skills/db-query/scripts/setup.sh
|
|
|
123
123
|
| `trimEnabled` | `true` | 總開關。關閉後折疊與度量全部停用(監聽器退化為純透傳)。 |
|
|
124
124
|
| `trimMode` | `auto` | `off` 只測量 / `advisory` 模型自折 / `auto` 系統自動折。 |
|
|
125
125
|
| `trimGrowthTokens` | `22500` | 增長閘門:出站 view 自上次 fold 以來增長到該值即觸發折疊。 |
|
|
126
|
-
| `trimIncrementTokens` | `
|
|
127
|
-
| `trimPressurePercent` | `
|
|
126
|
+
| `trimIncrementTokens` | `25000` | 閘門搭檔:連續可壓縮增量也須達到該規模。 |
|
|
127
|
+
| `trimPressurePercent` | `65` | 壓力級:view 用量達到上下文視窗該百分比即折疊。 |
|
|
128
128
|
| `trimEmergencyPercent` | `95` | 緊急級:到該百分比強制機械折疊(無 side model 呼叫)。 |
|
|
129
129
|
| `trimWindowTokens` | `0` | 視窗上限:壓力與緊急檔按 min(模型視窗, 上限) 計算。`0` = 跟隨 `wmForceTokens`。 |
|
|
130
|
-
| `trimProtectedTail` | `
|
|
131
|
-
| `trimMaxFoldsPerHour` | `
|
|
130
|
+
| `trimProtectedTail` | `10` | 最後 N 則訊息永不折疊。 |
|
|
131
|
+
| `trimMaxFoldsPerHour` | `30` | 每滾動小時 side model 折疊的節奏上限(緊急級豁免)。 |
|
|
132
132
|
| `trimSideModel` | 未設定 | 寫摘要的 side model 路由。留空 = 繼承對話目前模型。 |
|
|
133
133
|
| `trimFoldFallbackModel` | 未設定 | 摘要 side model 失敗時摺疊改用的重試路由;壓力檔仍失敗則退回機械摺疊。留空 = 無備援。盡量選擇冷卻、風控與並行餘量充足的路由。 |
|
|
134
134
|
| `trimStateDir` | 未設定 | 折疊狀態目錄覆蓋。留空 = `<dshHome>/.dsh-switchman/state/trim/`。 |
|
|
@@ -136,7 +136,7 @@ bash <安裝目錄>/skills/db-query/scripts/setup.sh
|
|
|
136
136
|
|
|
137
137
|
**觸發路徑。** 級別檢查在閒置邊界上執行;在閒置狀態事件不可達的宿主上,兜底改為在每次模型串流完成後也檢查一次(每個對話節流為每 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)。
|
|
138
138
|
|
|
139
|
-
**線上真值與穩態。** 決策列攜帶 `view=<n>`,回應落地後還會帶上 `wire=<n>`——真實的廠商提示詞(未快取輸入 + 快取讀取 + 快取寫入,從串流的 usage 事件取樣得到)。view 估算只統計 messages 陣列,而且總是比線上讀數小一個固定額外開銷(實測 ≈ 17.3k:系統提示詞 + 工具 schema + persona),所以壓力級與緊急級按 `max(view, wire)` 評估,只有 `wire` 才是提示詞大小的讀數。150k 視窗下,健康的鋸齒波在每次 fold 剛結束時線上 ≈ 40k ↔ 下次 fold 時
|
|
139
|
+
**線上真值與穩態。** 決策列攜帶 `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
140
|
|
|
141
141
|
**宿主壓縮紀元。** 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 機制的宿主(或開關關閉時)保持的正是這套舊行為。
|
|
142
142
|
|
package/README.zh.md
CHANGED
|
@@ -102,7 +102,7 @@ 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 + 增量 `
|
|
105
|
+
**上下文裁剪**:`trimEnabled` = 开;`trimMode` = `auto`(全自动);增长闸门 `22500` token + 增量 `25000` token;压力 `65%` / 紧急 `95%`;保护尾部 `10` 条;折叠节奏上限每小时 `30` 次;side model 未设置(继承会话模型)——详见下文「自动上下文裁剪」一节。
|
|
106
106
|
|
|
107
107
|
**开箱要点**:① 意图识别开箱不可用是有意设计,三步开启(分类器、候选、开关);② Auto 有效窗口开箱即为 200000——护栏保证 0.8×窗口 ≥ force 档(150000),核心压缩线(160000)永远在平滑交接线(150000)之后;③ 开箱最有感的是水位三件套:80k 提醒委派 / 95k 收敛读取 / 150k 自动交接(写文档+压缩),无需任何设置。
|
|
108
108
|
|
|
@@ -123,12 +123,12 @@ bash <安装目录>/skills/db-query/scripts/setup.sh
|
|
|
123
123
|
| `trimEnabled` | `true` | 总开关。关闭后折叠与度量全部停用(监听器退化为纯透传)。 |
|
|
124
124
|
| `trimMode` | `auto` | `off` 只测量 / `advisory` 模型自折 / `auto` 系统自动折。 |
|
|
125
125
|
| `trimGrowthTokens` | `22500` | 增长闸门:出站 view 自上次 fold 以来增长到该值即触发折叠。 |
|
|
126
|
-
| `trimIncrementTokens` | `
|
|
127
|
-
| `trimPressurePercent` | `
|
|
126
|
+
| `trimIncrementTokens` | `25000` | 闸门搭档:连续可压缩增量也须达到该规模。 |
|
|
127
|
+
| `trimPressurePercent` | `65` | 压力档:view 用量达到上下文窗口该百分比即折叠。 |
|
|
128
128
|
| `trimEmergencyPercent` | `95` | 紧急档:到该百分比强制机械折叠(无 side model 调用)。 |
|
|
129
129
|
| `trimWindowTokens` | `0` | 窗口上限:压力与紧急档按 min(模型窗口, 上限) 计算。`0` = 跟随 `wmForceTokens`。 |
|
|
130
|
-
| `trimProtectedTail` | `
|
|
131
|
-
| `trimMaxFoldsPerHour` | `
|
|
130
|
+
| `trimProtectedTail` | `10` | 最后 N 条消息永不折叠。 |
|
|
131
|
+
| `trimMaxFoldsPerHour` | `30` | 每滚动小时 side model 折叠的节奏上限(紧急档豁免)。 |
|
|
132
132
|
| `trimSideModel` | 未设置 | 写摘要的 side model 路由。留空 = 继承会话当前模型。 |
|
|
133
133
|
| `trimFoldFallbackModel` | 未设置 | 摘要 side model 失败时折叠改用的重试路由;压力档仍失败则退回机械折叠。留空 = 无兜底。尽量选择冷却、风控与并发余量充足的路由。 |
|
|
134
134
|
| `trimStateDir` | 未设置 | 折叠状态目录覆盖。留空 = `<dshHome>/.dsh-switchman/state/trim/`。 |
|
|
@@ -136,7 +136,7 @@ bash <安装目录>/skills/db-query/scripts/setup.sh
|
|
|
136
136
|
|
|
137
137
|
**触发路径。** 档位检查在空闲边界上运行;在空闲状态事件不可达的宿主上,兜底改为在每次模型流式完成后也检查一次(每个会话节流为每 60 秒至多评估一次)。每个决策——fold 与 no-op 皆然——都以「ISO 时间戳 + `key=value` 字段」的形式追加一行到裁剪状态目录(见 `trimStateDir`)下的 `decisions.log`,为 fold 留下离线审计轨迹;行词汇(`view-applied`、fold 决策/结果行、`surface-replace`、`surface-replace skipped reason=…`)收录于 [docs/context-trim.md](./docs/context-trim.md)。
|
|
138
138
|
|
|
139
|
-
**线上真值与稳态。** 决策行携带 `view=<n>`,响应落地后还会带上 `wire=<n>`——真实的供应商提示词(未缓存输入 + 缓存读取 + 缓存写入,从流的 usage 事件采样得到)。view 估算只统计 messages 数组,并且总是比线上读数小一个固定开销(实测 ≈ 17.3k:系统提示词 + 工具 schema + persona),所以压力档与紧急档按 `max(view, wire)` 评估,只有 `wire` 才是提示词大小的读数。150k 窗口下,健康的锯齿波在每次 fold 刚结束时线上 ≈ 40k ↔ 下次 fold 时
|
|
139
|
+
**线上真值与稳态。** 决策行携带 `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
140
|
|
|
141
141
|
**宿主压缩纪元。** 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 档与自动交接照常工作)。折叠只在 surface 通道同样不可用时才暂停——由持久的可用性探测判定(会话在线且暴露 `append`/`surface.nodes`、没有打开的 compaction 锁),与「最近是否发过货」无关,因此重启不再把引擎冻住。只有当该会话从未成功发出过任何 surface 替换时,裁剪横幅才以 `wire=raw`(folds not shipping; watermark reads the tally)标记该行;没有 surface 机制的宿主(或开关关闭时)保持的正是这套旧行为。
|
|
142
142
|
|