dsh-fast 0.2.9 → 0.2.11

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/CHANGELOG.md CHANGED
@@ -5,6 +5,35 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.2.11] - 2026-09-10
9
+
10
+ ### Changed
11
+
12
+ - Pin the `@deepseek-ai/dsh-*` dev/test dependencies to the published `0.1.5-rc.1` line and record `0.1.5-rc.1` in `dshWorkshop.compatibility.dshVersions`; the monthly Compat workflow now runs against `0.1.5-rc.1`. The peer range `>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0` is unchanged, so no supported host line is dropped.
13
+
14
+ ### Docs
15
+
16
+ - Refresh the five-language README compatibility baseline to `dsh-v0.1.5-rc.1` (verified 2026-09-10).
17
+
18
+ ## [0.2.10] - 2026-09-09
19
+
20
+ ### Fixed
21
+
22
+ - Read the system prompt from the session surface on `0.1.5-alpha.1`: it is now surface node 0 (a `system/message`) instead of `EpochHeader.system`, which the envelope type no longer declares. The collector takes the last non-empty system node (an empty node is dormant and never restores older text), mirroring the host agent loop, and prices it with the same per-block heuristic as `dsh-token-meter`'s `estimateSystemMessage`.
23
+ - Price the meter's conversation surface net of the system prompt on `0.1.5-alpha.1`: `tokenMeter.measure().surfaceTokens` now includes the system node, so subtracting `systemTokens` keeps the prompt out of the surface bucket (it was counted in both) and stops it from inflating the `thresholds.surfaceTokens` signal.
24
+ - Mount `SessionProjection` in the test harness: `TokenMeter` injects `sessionProjections` on `0.1.5-alpha.1`, so the meter silently stayed unmounted and the meter branch had zero coverage. The harness now fails loudly when the meter does not mount.
25
+
26
+ ### Changed
27
+
28
+ - Adapt to DeepSeek Harness `0.1.5-alpha.1` (public tag commit `5dda764ed3`): devDependencies pin `0.1.5-alpha.1`, peers widen to `>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0` (the prerelease tuple in the old single range never matched `0.1.5-alpha.1`), `dshWorkshop.compatibility.dshVersions` lists both lines, and the compat workflow pins `@deepseek-ai/dsh` / `dsh-base` / `dsh-headless` at `0.1.5-alpha.1`.
29
+ - The `0.1.2-rc.1` line stays supported at runtime: when no `system/message` node exists, the collector still prices the legacy `header.system` string through a structural read, and it does not subtract it from the meter surface (legacy meters never contained the prompt).
30
+ - `context.surfaceTokens` is now conversation history only, so the system/tools/surface buckets no longer double-count the prompt. Samples persisted in the `dsh_fast` domain before this release were written under the old surface semantics: trends that cross this version step change definition.
31
+
32
+ ### Docs
33
+
34
+ - Five-language READMEs: host baseline `dsh-v0.1.5-alpha.1` (verified 2026-09-09), the composite peer range and the `0.1.5-alpha.1` devDependency pins, the "system prompt is one bucket" limitation (it is surface node 0 now), and the surface-token definition.
35
+ - AGENTS.md, THIRD_PARTY_NOTICES.md, the issue template, and the compat/CI workflow labels refreshed to the `0.1.5-alpha.1` baseline.
36
+
8
37
  ## [0.2.9] - 2026-09-08
9
38
 
10
39
  ### Docs
package/README.es.md CHANGED
@@ -9,6 +9,7 @@
9
9
 
10
10
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
11
11
  [![DSH plugin](https://img.shields.io/badge/dsh--plugin-✅-green)](https://github.com/topics/dsh-plugin)
12
+ [![dsh-doctor](https://raw.githubusercontent.com/PerryLink/dsh-plugin-doctor/main/badges/PerryLink__dsh-fast.svg)](https://github.com/PerryLink/dsh-plugin-doctor#verified-徽章)
12
13
  [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
13
14
  [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-fast/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-fast/actions)
14
15
  [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-fast?label=version)](https://github.com/PerryLink/dsh-fast/releases)
@@ -23,17 +24,16 @@
23
24
 
24
25
  ## Compatibility
25
26
 
26
- - DeepSeek Harness `dsh-v0.1.3-alpha.1` (peers fijados a `0.1.2-rc.1`).
27
- 0.1.2-rc.1 (adaptado el 2026-09-02): el sobre de sesión conserva su campo ignorable solo para compatibilidad de lectura de logs almacenados - Session.append aún no puede estamparlo, por lo que el comportamiento de la puerta no cambia. Verificado el 2026-09-06 contra el checkout master de dsh-v0.1.3-alpha.1 (cadena de puertas completa + smoke de instalación de profile).
27
+ - DeepSeek Harness `dsh-v0.1.5-rc.1` (adaptado el 2026-09-09; commit público de la etiqueta `183f08e9c6`): el system prompt es ahora el nodo 0 de la superficie (un `system/message`) en lugar de un campo del sobre de la petición, así que el informe lo lee de la superficie y descuenta su precio de la superficie del token meter. Verificado el 2026-09-10 con los peers publicados `0.1.5-rc.1` (cadena de puertas local completa); el workflow compat mensual repite el smoke de instalación de profile con los mismos pines.
28
28
  - Node `^22.19.0 || >=24.0.0`, solo ESM (`"type": "module"`).
29
- - Peers: `@deepseek-ai/cordis ^4.0.2`, `@deepseek-ai/schemastery ^3.18.2`, y `@deepseek-ai/dsh-session`, `@deepseek-ai/dsh-tools`, `@deepseek-ai/dsh-commands`, `@deepseek-ai/dsh-compaction`, `@deepseek-ai/dsh-storage-domain` en `>=0.1.2-rc.1 <0.2.0`.
29
+ - Peers: `@deepseek-ai/cordis ^4.0.2`, `@deepseek-ai/schemastery ^3.18.2`, y `@deepseek-ai/dsh-session`, `@deepseek-ai/dsh-tools`, `@deepseek-ai/dsh-commands`, `@deepseek-ai/dsh-compaction`, `@deepseek-ai/dsh-storage-domain` en `>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0` (devDependencies fijan `0.1.5-rc.1`); la línea `0.1.2-rc.1` sigue soportada en ejecución mediante un fallback estructural al `header.system` anterior a 0.1.5.
30
30
 
31
31
  ## What you get
32
32
 
33
33
  - **Tiempo de carga de sesión** — latencia publicación→primera petición, clasificada `open` (nueva) o `restore` (con semilla/reanudada), más el número de eventos semilla.
34
34
  - **Recuento de spill** — cuántos resultados de herramienta se volcaron a un artefacto de sesión (detectado por el aviso persistente de spill).
35
35
  - **Recuento y motivo de compaction** — total, separado `manual` (comando) vs `automatic` (presión), y tokens sombreados totales.
36
- - **Volumen de contexto inyectado** — tokens de system-prompt (AGENTS.md + skills + persona), schema de herramientas y superficie, con sus porcentajes.
36
+ - **Volumen de contexto inyectado** — tokens de system-prompt (AGENTS.md + skills + persona), schema de herramientas y superficie, con sus porcentajes; la superficie es solo historial de conversación (en `0.1.5-alpha.1` la superficie del meter incluye el nodo de sistema, que dsh-fast descuenta).
37
37
  - **Tasa de aciertos de caché LLM** — tokens input / cache-read / cache-write / output agregados y la tasa derivada.
38
38
  - **Sugerencias de optimización** — basadas en umbrales (recortar skills, ajustar schemas, compactar antes, activar caché de prompts, activar spill-policy…).
39
39
  - **Muestreo asíncrono** — plegado O(1) por evento; el muestreo corre en un temporizador, nunca en la ruta de append.
@@ -104,7 +104,7 @@ Todos los ajustes son campos Schemastery `Config`; valores inválidos fallan la
104
104
 
105
105
  - **Dominio de almacenamiento, no eventos de sesión** — el `Session.append` de rc.2 no ofrece marcador `ignorable` ni superficie de registro de eventos externa; un evento `fast/*` haría que el coordinador de persistencia rechace el log al restaurar. Las métricas van al dominio de almacenamiento; los eventos crudos siguen siendo la fuente reconstruible.
106
106
  - **La detección de spill es heurística** — lee el aviso persistente (`Full … stored at:`); no hay evento de sesión dedicado.
107
- - **El system prompt es un solo cajón** — AGENTS.md, skills y persona forman el system prompt ensamblado; no hay contabilidad por sección.
107
+ - **El system prompt es un solo cajón** — AGENTS.md, skills y persona forman el system prompt ensamblado; desde `0.1.5-alpha.1` es el nodo 0 de la superficie (un `system/message`) y no trae contabilidad por sección, así que se reportan juntos.
108
108
  - **El tiempo de carga empieza en la publicación** — la lectura de disco de una restauración ocurre antes de `session/created`; la duración reportada es publicación→primera petición.
109
109
 
110
110
  ## Development
package/README.hi.md CHANGED
@@ -9,6 +9,7 @@
9
9
 
10
10
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
11
11
  [![DSH plugin](https://img.shields.io/badge/dsh--plugin-✅-green)](https://github.com/topics/dsh-plugin)
12
+ [![dsh-doctor](https://raw.githubusercontent.com/PerryLink/dsh-plugin-doctor/main/badges/PerryLink__dsh-fast.svg)](https://github.com/PerryLink/dsh-plugin-doctor#verified-徽章)
12
13
  [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
13
14
  [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-fast/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-fast/actions)
14
15
  [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-fast?label=version)](https://github.com/PerryLink/dsh-fast/releases)
@@ -23,17 +24,16 @@
23
24
 
24
25
  ## Compatibility
25
26
 
26
- - DeepSeek Harness `dsh-v0.1.3-alpha.1` (peers `0.1.2-rc.1` पर पिन किए गए)।
27
- 0.1.2-rc.1 (2026-09-02 को अनुकूलित): सत्र लिफ़ाफ़ा अपना ignorable फ़ील्ड केवल संग्रहीत-लॉग पठन संगतता के लिए रखता है - Session.append अभी भी इसे स्टैम्प नहीं कर सकता, इसलिए गेट व्यवहार अपरिवर्तित है। 2026-09-06 को dsh-v0.1.3-alpha.1 master checkout के विरुद्ध सत्यापित (पूर्ण गेट शृंखला + profile इंस्टॉल स्मोक)।
27
+ - DeepSeek Harness `dsh-v0.1.5-rc.1` (2026-09-09 को अनुकूलित; सार्वजनिक tag commit `183f08e9c6`): system prompt अब अनुरोध लिफ़ाफ़े के फ़ील्ड के बजाय सतह का नोड 0 (एक `system/message`) है, इसलिए रिपोर्ट उसे सतह से पढ़ती है और token meter की सतह से उसका मूल्य घटा देती है। 2026-09-10 को प्रकाशित `0.1.5-rc.1` peers के साथ सत्यापित (पूर्ण स्थानीय गेट शृंखला); मासिक compat workflow उन्हीं pins के साथ profile इंस्टॉल स्मोक दोहराता है।
28
28
  - Node `^22.19.0 || >=24.0.0`, केवल ESM (`"type": "module"`)।
29
- - Peers: `@deepseek-ai/cordis ^4.0.2`, `@deepseek-ai/schemastery ^3.18.2`, और `@deepseek-ai/dsh-session`, `@deepseek-ai/dsh-tools`, `@deepseek-ai/dsh-commands`, `@deepseek-ai/dsh-compaction`, `@deepseek-ai/dsh-storage-domain` (`>=0.1.2-rc.1 <0.2.0`)।
29
+ - Peers: `@deepseek-ai/cordis ^4.0.2`, `@deepseek-ai/schemastery ^3.18.2`, और `@deepseek-ai/dsh-session`, `@deepseek-ai/dsh-tools`, `@deepseek-ai/dsh-commands`, `@deepseek-ai/dsh-compaction`, `@deepseek-ai/dsh-storage-domain` (`>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0`; devDependencies `0.1.5-rc.1` पर पिन); `0.1.2-rc.1` पंक्ति रनटाइम पर pre-0.1.5 `header.system` के संरचनात्मक fallback से अभी भी समर्थित है।
30
30
 
31
31
  ## What you get
32
32
 
33
33
  - **सत्र लोड समय** — प्रकाशन→पहली अनुरोध विलंबता, `open` (नया) बनाम `restore` (seed/पुनः आरंभ) में वर्गीकृत, साथ में seed घटना गणना।
34
34
  - **spill हिट गणना** — कितने टूल परिणाम सत्र-स्कोप artifact में spill हुए (स्थायी spill सूचना से पता लगाया गया)।
35
35
  - **compaction गणना और कारण** — कुल, `manual` (कमांड) बनाम `automatic` (दबाव) में विभाजित, और कुल shadowed टोकन।
36
- - **इंजेक्ट किए गए संदर्भ की मात्रा** — system-prompt (AGENTS.md + skills + persona), टूल schema और सतह टोकन, उनके हिस्सों के साथ।
36
+ - **इंजेक्ट किए गए संदर्भ की मात्रा** — system-prompt (AGENTS.md + skills + persona), टूल schema और सतह टोकन, उनके हिस्सों के साथ; सतह केवल बातचीत इतिहास है (`0.1.5-alpha.1` में meter की सतह में system नोड शामिल होता है, जिसे dsh-fast घटा देता है)।
37
37
  - **LLM कैश हिट दर** — provider usage से एकत्र input / cache-read / cache-write / output टोकन और व्युत्पन्न दर।
38
38
  - **अनुकूलन सुझाव** — थ्रेशोल्ड-आधारित (skills छाँटें, टूल schema कसें, पहले compact करें, प्रॉम्प्ट कैश सक्षम करें, spill-policy सक्षम करें…)।
39
39
  - **अतुल्यकालिक नमूनाकरण** — प्रति घटना O(1) fold; नमूनाकरण टाइमर पर चलता है, append पाथ पर कभी नहीं।
@@ -104,7 +104,7 @@ dsh plugin --profile demo remove dsh-fast # हटाएँ
104
104
 
105
105
  - **स्टोरेज डोमेन, सत्र घटनाएँ नहीं** — rc.2 का `Session.append` `ignorable` मार्कर या बाहरी घटना-पंजीकरण सतह नहीं देता; कस्टम `fast/*` घटना पुनर्स्थापना पर लॉग को अस्वीकार करवा देती। इसलिए मेट्रिक्स स्टोरेज डोमेन में जाते हैं; कच्ची घटनाएँ पुनर्निर्माण-योग्य स्रोत बनी रहती हैं।
106
106
  - **spill पहचान अनुमानी है** — यह स्थायी सूचना (`Full … stored at:`) पढ़ती है; कोई समर्पित सत्र घटना नहीं है।
107
- - **system prompt एक ही बकेट है** — AGENTS.md, skills और persona असेंबल किए गए system prompt का हिस्सा हैं; header में प्रति-अनुभाग गणना नहीं होती।
107
+ - **system prompt एक ही बकेट है** — AGENTS.md, skills और persona असेंबल किए गए system prompt का हिस्सा हैं; `0.1.5-alpha.1` से यह सतह का नोड 0 (एक `system/message`) है और प्रति-अनुभाग गणना नहीं रखता, इसलिए इन्हें एक साथ रिपोर्ट किया जाता है।
108
108
  - **लोड समय प्रकाशन से शुरू होता है** — पुनर्स्थापना का डिस्क-रीड `session/created` से पहले होता है; रिपोर्ट की गई अवधि प्रकाशन→पहली अनुरोध है।
109
109
 
110
110
  ## Development
package/README.md CHANGED
@@ -12,6 +12,7 @@
12
12
 
13
13
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
14
14
  [![DSH plugin](https://img.shields.io/badge/dsh--plugin-✅-green)](https://github.com/topics/dsh-plugin)
15
+ [![dsh-doctor](https://raw.githubusercontent.com/PerryLink/dsh-plugin-doctor/main/badges/PerryLink__dsh-fast.svg)](https://github.com/PerryLink/dsh-plugin-doctor#verified-徽章)
15
16
  [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
16
17
  [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-fast/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-fast/actions)
17
18
  [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-fast?label=version)](https://github.com/PerryLink/dsh-fast/releases)
@@ -26,16 +27,16 @@
26
27
 
27
28
  ## Compatibility
28
29
 
29
- - DeepSeek Harness `dsh-v0.1.3-alpha.1` (adapted 2026-09-04): the session envelope keeps its ignorable field for stored-log read compatibility only - Session.append still cannot stamp it, so audit-gate behavior is unchanged. Verified 2026-09-06 against the dsh-v0.1.3-alpha.1 master checkout (full gate chain + profile install smoke).
30
+ - DeepSeek Harness `dsh-v0.1.5-rc.1` (adapted 2026-09-09; public tag commit `183f08e9c6`): the system prompt is surface node 0 (a `system/message`) instead of a request-envelope field, so the report reads it from the surface and prices the meter's surface net of it. Verified 2026-09-10 with the published `0.1.5-rc.1` peers (full local gate chain); the monthly compat workflow re-runs the profile install smoke against the same pins.
30
31
  - Node `^22.19.0 || >=24.0.0`, ESM only (`"type": "module"`).
31
- - Peer dependencies: `@deepseek-ai/cordis ^4.0.2`, `@deepseek-ai/schemastery ^3.18.2`, and `@deepseek-ai/dsh-session`, `@deepseek-ai/dsh-tools`, `@deepseek-ai/dsh-commands`, `@deepseek-ai/dsh-compaction`, `@deepseek-ai/dsh-storage-domain` at `>=0.1.2-rc.1 <0.2.0`.
32
+ - Peer dependencies: `@deepseek-ai/cordis ^4.0.2`, `@deepseek-ai/schemastery ^3.18.2`, and `@deepseek-ai/dsh-session`, `@deepseek-ai/dsh-tools`, `@deepseek-ai/dsh-commands`, `@deepseek-ai/dsh-compaction`, `@deepseek-ai/dsh-storage-domain` at `>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0` (devDependencies pin `0.1.5-rc.1`); the `0.1.2-rc.1` line stays supported at runtime through a structural fallback to the pre-0.1.5 `header.system`.
32
33
 
33
34
  ## What you get
34
35
 
35
36
  - **Session load timing** — publication-to-first-request latency, classified `open` (fresh) vs `restore` (seeded/resumed), plus the restored seed-event count.
36
37
  - **Spill-hit statistics** — how many tool results were spilled to a session-scoped artifact (detected from the durable spill notice).
37
38
  - **Compaction count and trigger** — total compactions, split `manual` (slash command) vs `automatic` (pressure), and total shadowed tokens.
38
- - **Context-injection volume** — system-prompt (AGENTS.md + skills + persona), tool-schema, and surface tokens with their shares of the total.
39
+ - **Context-injection volume** — system-prompt (AGENTS.md + skills + persona), tool-schema, and surface tokens with their shares of the total; the surface bucket is conversation history only (the meter's surface includes the system node on `0.1.5-alpha.1`, which dsh-fast subtracts).
39
40
  - **LLM cache hit rate** — input / cache-read / cache-write / output tokens aggregated from provider usage, plus the derived hit rate.
40
41
  - **Optimization suggestions** — threshold-driven notes (trim skills, tighten tool schemas, compact earlier, enable prompt caching, enable spill-policy, …).
41
42
  - **Async sampling** — metrics are folded O(1) per event and snapshotted on a timer, never on the append path.
@@ -106,7 +107,7 @@ All tunables are Schemastery `Config` fields; invalid values fail the profile lo
106
107
 
107
108
  - **Storage domain, not session events** — rc.2 `Session.append` offers no `ignorable` marker and no external event-registration surface, so a custom `fast/*` session event would make the persistence coordinator refuse the log on restore. Metrics are therefore persisted to the storage domain; the raw events remain the reconstructable source of truth.
108
109
  - **Spill detection is heuristic** — it reads the durable spill notice (`Full … stored at:`); no dedicated session event exists.
109
- - **System prompt is one bucket** — AGENTS.md, skill directory, and persona are all part of the assembled system prompt; the header carries no per-section token accounting, so they are reported together.
110
+ - **System prompt is one bucket** — AGENTS.md, skill directory, and persona are all part of the assembled system prompt; since `0.1.5-alpha.1` it is surface node 0 (a `system/message`) and carries no per-section token accounting, so they are reported together.
110
111
  - **Load timing starts at publication** — the disk-read portion of a restore happens before `session/created` (owned by `sessionPersistence`) and is not observable from this plugin's allowed events; the reported duration is publication-to-first-request.
111
112
 
112
113
  ## Development
package/README.pt.md CHANGED
@@ -9,6 +9,7 @@
9
9
 
10
10
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
11
11
  [![DSH plugin](https://img.shields.io/badge/dsh--plugin-✅-green)](https://github.com/topics/dsh-plugin)
12
+ [![dsh-doctor](https://raw.githubusercontent.com/PerryLink/dsh-plugin-doctor/main/badges/PerryLink__dsh-fast.svg)](https://github.com/PerryLink/dsh-plugin-doctor#verified-徽章)
12
13
  [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
13
14
  [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-fast/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-fast/actions)
14
15
  [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-fast?label=version)](https://github.com/PerryLink/dsh-fast/releases)
@@ -23,17 +24,16 @@
23
24
 
24
25
  ## Compatibility
25
26
 
26
- - DeepSeek Harness `dsh-v0.1.3-alpha.1` (peers fixados em `0.1.2-rc.1`).
27
- 0.1.2-rc.1 (adaptado em 2026-09-02): o envelope de sessão mantém seu campo ignorable apenas para compatibilidade de leitura de logs armazenados - o Session.append ainda não consegue estampá-lo, então o comportamento da porta não muda. Verificado em 2026-09-06 contra o checkout master do dsh-v0.1.3-alpha.1 (cadeia completa de portas + smoke de instalação de profile).
27
+ - DeepSeek Harness `dsh-v0.1.5-rc.1` (adaptado em 2026-09-09; commit público da tag `183f08e9c6`): o system prompt agora é o nó 0 da superfície (um `system/message`) em vez de um campo do envelope da requisição, então o relatório o lê da superfície e desconta seu preço da superfície do token meter. Verificado em 2026-09-10 com os peers publicados `0.1.5-rc.1` (cadeia completa de portas local); o workflow compat mensal repete o smoke de instalação de profile com os mesmos pins.
28
28
  - Node `^22.19.0 || >=24.0.0`, somente ESM (`"type": "module"`).
29
- - Peers: `@deepseek-ai/cordis ^4.0.2`, `@deepseek-ai/schemastery ^3.18.2`, e `@deepseek-ai/dsh-session`, `@deepseek-ai/dsh-tools`, `@deepseek-ai/dsh-commands`, `@deepseek-ai/dsh-compaction`, `@deepseek-ai/dsh-storage-domain` em `>=0.1.2-rc.1 <0.2.0`.
29
+ - Peers: `@deepseek-ai/cordis ^4.0.2`, `@deepseek-ai/schemastery ^3.18.2`, e `@deepseek-ai/dsh-session`, `@deepseek-ai/dsh-tools`, `@deepseek-ai/dsh-commands`, `@deepseek-ai/dsh-compaction`, `@deepseek-ai/dsh-storage-domain` em `>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0` (devDependencies fixam `0.1.5-rc.1`); a linha `0.1.2-rc.1` continua suportada em execução por um fallback estrutural ao `header.system` anterior ao 0.1.5.
30
30
 
31
31
  ## What you get
32
32
 
33
33
  - **Tempo de carga da sessão** — latência publicação→primeira requisição, classificada `open` (nova) ou `restore` (com semente/retomada), mais a contagem de eventos de semente.
34
34
  - **Contagem de spill** — quantos resultados de ferramenta foram descarregados em um artefato de sessão (detectado pelo aviso persistente de spill).
35
35
  - **Contagem e motivo de compaction** — total, separado `manual` (comando) vs `automatic` (pressão), e total de tokens sombreados.
36
- - **Volume de contexto injetado** — tokens de system-prompt (AGENTS.md + skills + persona), schema de ferramentas e superfície, com suas proporções.
36
+ - **Volume de contexto injetado** — tokens de system-prompt (AGENTS.md + skills + persona), schema de ferramentas e superfície, com suas proporções; a superfície é apenas histórico de conversa (no `0.1.5-alpha.1` a superfície do meter inclui o nó de sistema, que o dsh-fast desconta).
37
37
  - **Taxa de acertos do cache LLM** — tokens input / cache-read / cache-write / output agregados e a taxa derivada.
38
38
  - **Sugestões de otimização** — baseadas em limiares (cortar skills, ajustar schemas, compactar antes, ativar cache de prompts, ativar spill-policy…).
39
39
  - **Amostragem assíncrona** — dobra O(1) por evento; a amostragem roda em um timer, nunca no caminho de append.
@@ -104,7 +104,7 @@ O `dsh-fast` consome apenas seams públicos: eventos `session/*` e `agent/*`, o
104
104
 
105
105
  - **Domínio de armazenamento, não eventos de sessão** — o `Session.append` do rc.2 não oferece marcador `ignorable` nem superfície de registro de eventos externa; um evento `fast/*` faria o coordenador de persistência recusar o log ao restaurar. As métricas vão ao domínio de armazenamento; os eventos brutos seguem como fonte reconstruível.
106
106
  - **A detecção de spill é heurística** — lê o aviso persistente (`Full … stored at:`); não há evento de sessão dedicado.
107
- - **O system prompt é um único balde** — AGENTS.md, skills e persona formam o system prompt montado; não há contagem por seção.
107
+ - **O system prompt é um único balde** — AGENTS.md, skills e persona formam o system prompt montado; desde `0.1.5-alpha.1` é o nó 0 da superfície (um `system/message`) e não traz contagem por seção, então são reportados juntos.
108
108
  - **O tempo de carga começa na publicação** — a leitura de disco de uma restauração ocorre antes de `session/created`; a duração reportada é publicação→primeira requisição.
109
109
 
110
110
  ## Development
package/README.zh.md CHANGED
@@ -11,6 +11,7 @@
11
11
 
12
12
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
13
13
  [![DSH plugin](https://img.shields.io/badge/dsh--plugin-✅-green)](https://github.com/topics/dsh-plugin)
14
+ [![dsh-doctor](https://raw.githubusercontent.com/PerryLink/dsh-plugin-doctor/main/badges/PerryLink__dsh-fast.svg)](https://github.com/PerryLink/dsh-plugin-doctor#verified-徽章)
14
15
  [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
15
16
  [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-fast/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-fast/actions)
16
17
  [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-fast?label=version)](https://github.com/PerryLink/dsh-fast/releases)
@@ -25,17 +26,16 @@
25
26
 
26
27
  ## Compatibility
27
28
 
28
- - DeepSeek Harness `dsh-v0.1.3-alpha.1`(peer 钉在 `0.1.2-rc.1`)。
29
- 0.1.2-rc.1(2026-09-02 已适配):会话信封保留 ignorable 字段但仅用于存量日志读取兼容——Session.append 仍无法盖章,门控行为不变。已于 2026-09-06 对照 dsh-v0.1.3-alpha.1 master checkout 核验(全门控链 + profile 安装冒烟)。
29
+ - DeepSeek Harness `dsh-v0.1.5-rc.1`(2026-09-09 已适配;公开 tag commit `183f08e9c6`):系统提示词改为 surface 节点 0(`system/message`)而不再放在请求信封里,因此报告从会话表面读取它,并把 token meter 的 surface 计价扣除系统提示词后再上报。已于 2026-09-10 用已发布的 `0.1.5-rc.1` peers 核验(本地全门控链);每月的 compat workflow 用同一钉号重跑 profile 安装冒烟。
30
30
  - Node `^22.19.0 || >=24.0.0`,纯 ESM(`"type": "module"`)。
31
- - peer 依赖:`@deepseek-ai/cordis ^4.0.2`、`@deepseek-ai/schemastery ^3.18.2`,以及 `@deepseek-ai/dsh-session`、`@deepseek-ai/dsh-tools`、`@deepseek-ai/dsh-commands`、`@deepseek-ai/dsh-compaction`、`@deepseek-ai/dsh-storage-domain`(`>=0.1.2-rc.1 <0.2.0`)。
31
+ - peer 依赖:`@deepseek-ai/cordis ^4.0.2`、`@deepseek-ai/schemastery ^3.18.2`,以及 `@deepseek-ai/dsh-session`、`@deepseek-ai/dsh-tools`、`@deepseek-ai/dsh-commands`、`@deepseek-ai/dsh-compaction`、`@deepseek-ai/dsh-storage-domain`(`>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0`;devDependencies 钉 `0.1.5-rc.1`);`0.1.2-rc.1` 旧线仍通过结构式回退读取 pre-0.1.5 的 `header.system` 在运行时受支持。
32
32
 
33
33
  ## What you get
34
34
 
35
35
  - **会话加载耗时** —— 发布到首次请求的延迟,按 `open`(全新)/`restore`(带 seed/恢复)分类,并给出恢复时的 seed 事件数。
36
36
  - **spill 命中统计** —— 有多少工具结果被溢出到会话级工件(从持久化的 spill 提示标记检测)。
37
37
  - **compaction 次数与触发原因** —— 总次数,按 `manual`(斜杠命令)/`automatic`(压力)区分,以及总 shadow token 数。
38
- - **上下文注入体量** —— 系统提示词(AGENTS.md + 技能 + 人设)、工具 schema、会话表面的 token 数及其占比。
38
+ - **上下文注入体量** —— 系统提示词(AGENTS.md + 技能 + 人设)、工具 schema、会话表面的 token 数及其占比;其中“会话表面”只含对话历史(`0.1.5-alpha.1` 的 meter surface 含系统节点,dsh-fast 已扣除)。
39
39
  - **LLM 缓存命中率** —— 由 provider usage 聚合的 input / cache-read / cache-write / output token 与命中率。
40
40
  - **优化建议** —— 阈值驱动的建议(精简技能、收紧工具 schema、更早压缩、启用提示词缓存、启用 spill-policy 等)。
41
41
  - **异步采样** —— 每个事件 O(1) 折叠,定时器采样,绝不在追加路径上执行。
@@ -106,7 +106,7 @@ dsh plugin --profile demo remove dsh-fast # 卸载
106
106
 
107
107
  - **用存储域而非会话事件** —— rc.2 的 `Session.append` 没有 `ignorable` 标记能力,也没有外部事件注册面,写自定义 `fast/*` 会话事件会让持久化协调器在恢复时拒绝日志。因此度量改为持久化到存储域;原始事件仍是可重建的事实来源。
108
108
  - **spill 检测是启发式** —— 读取持久化的 spill 提示(`Full … stored at:`);没有专门的会话事件。
109
- - **系统提示词是单个桶** —— AGENTS.md、技能目录与人设都属于组装后的系统提示词;header 不携带分段 token 统计,因此合并上报。
109
+ - **系统提示词是单个桶** —— AGENTS.md、技能目录与人设都属于组装后的系统提示词;自 `0.1.5-alpha.1` 起它是 surface 节点 0(`system/message`),本身不携带分段 token 统计,因此合并上报。
110
110
  - **加载耗时从发布时刻起算** —— 恢复时的磁盘读取发生在 `session/created` 之前(由 `sessionPersistence` 负责),本插件允许的事件观察不到;上报的时长是发布到首次请求的延迟。
111
111
 
112
112
  ## Development
@@ -12,9 +12,9 @@ published tarball except where noted; these are install-time dependencies:
12
12
  | [tsdown](https://github.com/rolldown/tsdown) | `^0.22.14` | MIT | Build-time bundling of `lib/` (a regular dependency so the git-install channel's `prepare` script can build) |
13
13
  | [typescript](https://github.com/microsoft/TypeScript) | `^5.9.0` | Apache-2.0 | Build-time declaration emission (`lib/types/`) |
14
14
  | [zod](https://github.com/colinhacks/zod) | `^4.4.3` | MIT | Runtime value schema for the `dsh_fast` storage-domain table (bundled into `lib/`) |
15
- | [@deepseek-ai/cordis](https://www.npmjs.com/package/@deepseek-ai/cordis) | `^4.0.1` (peer) | See package | The plugin runtime |
16
- | [@deepseek-ai/schemastery](https://www.npmjs.com/package/@deepseek-ai/schemastery) | `^3.18.0` (peer) | See package | Configuration schema |
17
- | `@deepseek-ai/dsh-*` peers | `0.1.1-rc.2` (peer) | See packages | Official harness seams (`dsh-session`, `dsh-tools`, `dsh-commands`, `dsh-compaction`, `dsh-storage-domain`) |
15
+ | [@deepseek-ai/cordis](https://www.npmjs.com/package/@deepseek-ai/cordis) | `^4.0.2` (peer) | See package | The plugin runtime |
16
+ | [@deepseek-ai/schemastery](https://www.npmjs.com/package/@deepseek-ai/schemastery) | `^3.18.2` (peer) | See package | Configuration schema |
17
+ | `@deepseek-ai/dsh-*` peers | `>=0.1.2-rc.1 <0.2.0 \|\| >=0.1.5-alpha.1 <0.2.0` (peer; devDependencies pin `0.1.5-alpha.1`) | See packages | Official harness seams (`dsh-session`, `dsh-tools`, `dsh-commands`, `dsh-compaction`, `dsh-storage-domain`) |
18
18
 
19
19
  At runtime the plugin only talks to the harness services listed as
20
20
  peerDependencies; it performs no network requests and stores no credentials.
package/cordis.patch.yml CHANGED
@@ -34,7 +34,8 @@
34
34
  systemPromptTokens: 20000
35
35
  # Warn when the tool schema exceeds this many tokens.
36
36
  toolSchemaTokens: 8000
37
- # Warn when the conversation surface exceeds this many tokens.
37
+ # Warn when the conversation surface (message history, excluding the
38
+ # system prompt and tool schema) exceeds this many tokens.
38
39
  surfaceTokens: 60000
39
40
  # Warn when the LLM cache hit rate falls below this (0..1).
40
41
  cacheHitRateFloor: 0.1
package/lib/index.js CHANGED
@@ -160,13 +160,29 @@ function classifySystemSections(sections) {
160
160
  }
161
161
  /**
162
162
  * Price the assembled system prompt (harness identity + persona + tool
163
- * guidance + plugin sections).
164
- * @param header - canonical request envelope, or undefined before any request.
163
+ * guidance + plugin sections). 0.1.5-alpha.1 represents it as surface node 0
164
+ * (a `system/message`) instead of the request envelope's `system` field, so
165
+ * this mirrors `estimateSystemMessage` in `@deepseek-ai/dsh-token-meter`:
166
+ * empty content prices as 0 ("no system prompt").
167
+ * @param message - the effective system message, or undefined when none is active.
168
+ * @returns heuristic system-prompt tokens; 0 when absent or empty.
169
+ */
170
+ function estimateSystemTokens(message) {
171
+ if (message === void 0 || message.content.length === 0) return 0;
172
+ let characters = 0;
173
+ for (const block of message.content) characters += block.type === "text" ? block.text.length : JSON.stringify(block).length;
174
+ return Math.ceil(characters / CHARS_PER_TOKEN) + ROLE_OVERHEAD;
175
+ }
176
+ /**
177
+ * Price the legacy (<= 0.1.3-alpha.1) `EpochHeader.system` string. Kept as the
178
+ * runtime fallback for the old peer line, where the prompt never reached the
179
+ * surface and lived in the request envelope.
180
+ * @param system - the legacy rendered prompt text, or undefined before any request.
165
181
  * @returns heuristic system-prompt tokens; 0 when absent.
166
182
  */
167
- function estimateSystemTokens(header) {
168
- if (header?.system === void 0) return 0;
169
- return Math.ceil(header.system.length / CHARS_PER_TOKEN) + ROLE_OVERHEAD;
183
+ function estimateLegacySystemTokens(system) {
184
+ if (system === void 0) return 0;
185
+ return Math.ceil(system.length / CHARS_PER_TOKEN) + ROLE_OVERHEAD;
170
186
  }
171
187
  /**
172
188
  * Price the tool-schema part of the request envelope.
@@ -181,6 +197,42 @@ function estimateToolsTokens(header) {
181
197
  //#region src/collector.ts
182
198
  /** The durable marker every spill notice carries (`... Full ... stored at: <locator> ...`). */
183
199
  const SPILL_NOTICE_MARKERS = ["Full", "stored at:"];
200
+ /**
201
+ * The effective system prompt: the last non-empty `system/message` node in
202
+ * surface order. 0.1.5-alpha.1 derives the prompt from surface node 0; an empty
203
+ * node is dormant and never restores older text. Mirrors
204
+ * `SystemPromptProjection` in the host agent loop.
205
+ * @param session - the session to read.
206
+ * @returns the effective system message, or undefined when none is active.
207
+ */
208
+ function effectiveSystemMessage(session) {
209
+ let effective;
210
+ for (const seq of session.surface.nodes) {
211
+ const event = session.eventAt(seq);
212
+ if (event?.type !== "system/message") continue;
213
+ const message = event.data.message;
214
+ if (message.content.length === 0) continue;
215
+ effective = message;
216
+ }
217
+ return effective;
218
+ }
219
+ /** The display/durable text of a system message (text blocks plus structural JSON). */
220
+ function systemTextOf(message) {
221
+ let text = "";
222
+ for (const block of message.content) text += block.type === "text" ? block.text : JSON.stringify(block);
223
+ return text;
224
+ }
225
+ /**
226
+ * Structural read of the pre-0.1.5 `EpochHeader.system` string, removed from
227
+ * the public type when the prompt moved to surface node 0. This keeps the
228
+ * runtime fallback for the `0.1.2-rc.1` peer line.
229
+ * @param header - canonical request envelope, or undefined before any request.
230
+ * @returns the legacy prompt text, or undefined when absent.
231
+ */
232
+ function legacySystemText(header) {
233
+ const system = header?.system;
234
+ return typeof system === "string" ? system : void 0;
235
+ }
184
236
  /** Flatten a tool result's model-facing text blocks to one string. */
185
237
  function flattenToolResultText(message) {
186
238
  const block = message.content[0];
@@ -304,15 +356,19 @@ var FastCollector = class {
304
356
  const state = this.live.get(session);
305
357
  if (state === void 0) return emptySnapshot();
306
358
  const measurement = measure === void 0 ? void 0 : measure(session);
307
- const systemTokens = estimateSystemTokens(state.lastHeader);
359
+ const systemMessage = effectiveSystemMessage(session);
360
+ const legacySystem = systemMessage === void 0 ? legacySystemText(state.lastHeader) : void 0;
361
+ const systemTokens = systemMessage === void 0 ? estimateLegacySystemTokens(legacySystem) : estimateSystemTokens(systemMessage);
308
362
  const toolSchemaTokens = estimateToolsTokens(state.lastHeader);
309
- const surfaceTokens = measurement?.surfaceTokens ?? 0;
363
+ const measuredSurfaceTokens = measurement?.surfaceTokens ?? 0;
364
+ const surfaceTokens = systemMessage === void 0 ? measuredSurfaceTokens : Math.max(0, measuredSurfaceTokens - systemTokens);
310
365
  const totalTokens = measurement?.totalTokens ?? systemTokens + toolSchemaTokens + surfaceTokens;
311
- const systemChars = state.lastHeader?.system?.length ?? 0;
312
- const systemBreakdown = classifySystemSections(sections ?? (systemChars > 0 ? [{
366
+ const systemText = systemMessage === void 0 ? legacySystem : systemTextOf(systemMessage);
367
+ const syntheticSections = systemText === void 0 || systemText.length === 0 ? [] : [{
313
368
  name: "other",
314
- text: state.lastHeader.system
315
- }] : []));
369
+ text: systemText
370
+ }];
371
+ const systemBreakdown = classifySystemSections(sections ?? syntheticSections);
316
372
  return {
317
373
  load: {
318
374
  kind: state.kind,
@@ -691,7 +747,7 @@ function appendSample(history, sample, maxSamples) {
691
747
  //#endregion
692
748
  //#region src/version.ts
693
749
  /** Single-source plugin version, bumped by `scripts/release.mjs`. @module dsh-fast/version */
694
- const VERSION = "0.2.9";
750
+ const VERSION = "0.2.11";
695
751
  //#endregion
696
752
  //#region src/index.ts
697
753
  const name = "fast";
@@ -7,7 +7,7 @@
7
7
  * `Map` keyed by the live Session so the timer can iterate it.
8
8
  * @module dsh-fast/collector
9
9
  */
10
- import type { Session, SessionEvent, ToolResultMessage } from '@deepseek-ai/dsh-session';
10
+ import type { Session, SessionEvent, SystemMessage, ToolResultMessage } from '@deepseek-ai/dsh-session';
11
11
  import type { FastSnapshot, ContextStats } from './model.js';
12
12
  import type { ResolvedConfig } from './config.js';
13
13
  import { type SystemSection } from './estimate.js';
@@ -15,7 +15,9 @@ import { type SystemSection } from './estimate.js';
15
15
  * The structural surface of the optional `ctx.tokenMeter` service. Only the
16
16
  * fields dsh-fast reads are declared; the service is optional, so a host
17
17
  * without it still reports system/tool-schema volumes (surface/total fall back
18
- * to the header heuristic).
18
+ * to the heuristic header+surface sum). On 0.1.5-alpha.1 `surfaceTokens`
19
+ * includes the `system/message` surface node, which {@link FastCollector.snapshot}
20
+ * subtracts so the surface bucket stays conversation history.
19
21
  */
20
22
  export interface TokenMeasurement {
21
23
  readonly totalTokens: number;
@@ -23,6 +25,15 @@ export interface TokenMeasurement {
23
25
  }
24
26
  /** Lazy lookup of the optional token meter. */
25
27
  export type MeasureFn = (session: Session) => TokenMeasurement | undefined;
28
+ /**
29
+ * The effective system prompt: the last non-empty `system/message` node in
30
+ * surface order. 0.1.5-alpha.1 derives the prompt from surface node 0; an empty
31
+ * node is dormant and never restores older text. Mirrors
32
+ * `SystemPromptProjection` in the host agent loop.
33
+ * @param session - the session to read.
34
+ * @returns the effective system message, or undefined when none is active.
35
+ */
36
+ export declare function effectiveSystemMessage(session: Session): SystemMessage | undefined;
26
37
  /** Flatten a tool result's model-facing text blocks to one string. */
27
38
  export declare function flattenToolResultText(message: ToolResultMessage): string;
28
39
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../src/collector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAGxF,OAAO,KAAK,EAAE,YAAY,EAAc,YAAY,EAAE,MAAM,YAAY,CAAA;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAqE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAA;AAErH;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAC/B;AAED,+CAA+C;AAC/C,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,gBAAgB,GAAG,SAAS,CAAA;AAK1E,sEAAsE;AACtE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAQxE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAGvE;AAED,0EAA0E;AAC1E,wBAAgB,QAAQ,CACtB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GACd,IAAI,CAAC,YAAY,EAAE,aAAa,GAAG,YAAY,GAAG,cAAc,CAAC,CAOnE;AAED,+EAA+E;AAC/E,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIzE;AAsBD;;;;GAIG;AACH,qBAAa,aAAa;IAIZ,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgC;IAErD,kDAAkD;gBACrB,MAAM,EAAE,cAAc;IAEnD,oDAAoD;IACpD,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI5C,wCAAwC;IACxC,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI7C;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI;IAmCxD,qDAAqD;IACrD,YAAY,IAAI,gBAAgB,CAAC,OAAO,CAAC;IAIzC,kEAAkE;IAClE,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAI9B,kDAAkD;IAClD,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAIlC,yDAAyD;IACzD,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKjC;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,SAAS,aAAa,EAAE,GAAG,YAAY;IAqClG,sDAAsD;IACtD,OAAO,CAAC,UAAU;IAUlB,sCAAsC;IACtC,OAAO,CAAC,SAAS;IAYjB,iEAAiE;IACjE,OAAO,CAAC,KAAK;CAwBd"}
1
+ {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../src/collector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAe,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAGpH,OAAO,KAAK,EAAE,YAAY,EAAc,YAAY,EAAE,MAAM,YAAY,CAAA;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAKL,KAAK,aAAa,EACnB,MAAM,eAAe,CAAA;AAEtB;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAC/B;AAED,+CAA+C;AAC/C,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,gBAAgB,GAAG,SAAS,CAAA;AAK1E;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,GAAG,SAAS,CAUlF;AAqBD,sEAAsE;AACtE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAQxE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAGvE;AAED,0EAA0E;AAC1E,wBAAgB,QAAQ,CACtB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GACd,IAAI,CAAC,YAAY,EAAE,aAAa,GAAG,YAAY,GAAG,cAAc,CAAC,CAOnE;AAED,+EAA+E;AAC/E,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIzE;AAsBD;;;;GAIG;AACH,qBAAa,aAAa;IAIZ,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgC;IAErD,kDAAkD;gBACrB,MAAM,EAAE,cAAc;IAEnD,oDAAoD;IACpD,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI5C,wCAAwC;IACxC,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI7C;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI;IAmCxD,qDAAqD;IACrD,YAAY,IAAI,gBAAgB,CAAC,OAAO,CAAC;IAIzC,kEAAkE;IAClE,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAI9B,kDAAkD;IAClD,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAIlC,yDAAyD;IACzD,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKjC;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,SAAS,aAAa,EAAE,GAAG,YAAY;IAgDlG,sDAAsD;IACtD,OAAO,CAAC,UAAU;IAUlB,sCAAsC;IACtC,OAAO,CAAC,SAAS;IAYjB,iEAAiE;IACjE,OAAO,CAAC,KAAK;CAwBd"}
@@ -7,9 +7,48 @@
7
7
  * `Map` keyed by the live Session so the timer can iterate it.
8
8
  * @module dsh-fast/collector
9
9
  */
10
- import { classifySystemSections, estimateSystemTokens, estimateToolsTokens } from "./estimate.js";
10
+ import { classifySystemSections, estimateLegacySystemTokens, estimateSystemTokens, estimateToolsTokens, } from "./estimate.js";
11
11
  /** The durable marker every spill notice carries (`... Full ... stored at: <locator> ...`). */
12
12
  const SPILL_NOTICE_MARKERS = ['Full', 'stored at:'];
13
+ /**
14
+ * The effective system prompt: the last non-empty `system/message` node in
15
+ * surface order. 0.1.5-alpha.1 derives the prompt from surface node 0; an empty
16
+ * node is dormant and never restores older text. Mirrors
17
+ * `SystemPromptProjection` in the host agent loop.
18
+ * @param session - the session to read.
19
+ * @returns the effective system message, or undefined when none is active.
20
+ */
21
+ export function effectiveSystemMessage(session) {
22
+ let effective;
23
+ for (const seq of session.surface.nodes) {
24
+ const event = session.eventAt(seq);
25
+ if (event?.type !== 'system/message')
26
+ continue;
27
+ const message = event.data.message;
28
+ if (message.content.length === 0)
29
+ continue;
30
+ effective = message;
31
+ }
32
+ return effective;
33
+ }
34
+ /** The display/durable text of a system message (text blocks plus structural JSON). */
35
+ function systemTextOf(message) {
36
+ let text = '';
37
+ for (const block of message.content)
38
+ text += block.type === 'text' ? block.text : JSON.stringify(block);
39
+ return text;
40
+ }
41
+ /**
42
+ * Structural read of the pre-0.1.5 `EpochHeader.system` string, removed from
43
+ * the public type when the prompt moved to surface node 0. This keeps the
44
+ * runtime fallback for the `0.1.2-rc.1` peer line.
45
+ * @param header - canonical request envelope, or undefined before any request.
46
+ * @returns the legacy prompt text, or undefined when absent.
47
+ */
48
+ function legacySystemText(header) {
49
+ const system = header?.system;
50
+ return typeof system === 'string' ? system : undefined;
51
+ }
13
52
  /** Flatten a tool result's model-facing text blocks to one string. */
14
53
  export function flattenToolResultText(message) {
15
54
  const block = message.content[0];
@@ -144,12 +183,25 @@ export class FastCollector {
144
183
  if (state === undefined)
145
184
  return emptySnapshot();
146
185
  const measurement = measure === undefined ? undefined : measure(session);
147
- const systemTokens = estimateSystemTokens(state.lastHeader);
186
+ const systemMessage = effectiveSystemMessage(session);
187
+ const legacySystem = systemMessage === undefined ? legacySystemText(state.lastHeader) : undefined;
188
+ const systemTokens = systemMessage === undefined
189
+ ? estimateLegacySystemTokens(legacySystem)
190
+ : estimateSystemTokens(systemMessage);
148
191
  const toolSchemaTokens = estimateToolsTokens(state.lastHeader);
149
- const surfaceTokens = measurement?.surfaceTokens ?? 0;
192
+ const measuredSurfaceTokens = measurement?.surfaceTokens ?? 0;
193
+ // 0.1.5-alpha.1 prices the system prompt into the meter's surface (surface
194
+ // node 0), so subtract it and keep the surface bucket conversation history.
195
+ // The legacy line kept `header.system` out of the meter surface entirely.
196
+ const surfaceTokens = systemMessage === undefined
197
+ ? measuredSurfaceTokens
198
+ : Math.max(0, measuredSurfaceTokens - systemTokens);
150
199
  const totalTokens = measurement?.totalTokens ?? (systemTokens + toolSchemaTokens + surfaceTokens);
151
- const systemChars = state.lastHeader?.system?.length ?? 0;
152
- const systemBreakdown = classifySystemSections(sections ?? (systemChars > 0 ? [{ name: 'other', text: state.lastHeader.system }] : []));
200
+ const systemText = systemMessage === undefined ? legacySystem : systemTextOf(systemMessage);
201
+ const syntheticSections = systemText === undefined || systemText.length === 0
202
+ ? []
203
+ : [{ name: 'other', text: systemText }];
204
+ const systemBreakdown = classifySystemSections(sections ?? syntheticSections);
153
205
  return {
154
206
  load: {
155
207
  kind: state.kind,
@@ -1 +1 @@
1
- {"version":3,"file":"collector.js","sourceRoot":"","sources":["../../src/collector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"collector.js","sourceRoot":"","sources":["../../src/collector.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@
7
7
  * meter they mirror.
8
8
  * @module dsh-fast/estimate
9
9
  */
10
- import type { EpochHeader } from '@deepseek-ai/dsh-session';
10
+ import type { EpochHeader, SystemMessage } from '@deepseek-ai/dsh-session';
11
11
  import type { SystemPromptBreakdown } from './model.js';
12
12
  /** One named system-prompt section (name + resolved text). */
13
13
  export interface SystemSection {
@@ -27,11 +27,22 @@ export interface SystemSection {
27
27
  export declare function classifySystemSections(sections: readonly SystemSection[]): SystemPromptBreakdown;
28
28
  /**
29
29
  * Price the assembled system prompt (harness identity + persona + tool
30
- * guidance + plugin sections).
31
- * @param header - canonical request envelope, or undefined before any request.
30
+ * guidance + plugin sections). 0.1.5-alpha.1 represents it as surface node 0
31
+ * (a `system/message`) instead of the request envelope's `system` field, so
32
+ * this mirrors `estimateSystemMessage` in `@deepseek-ai/dsh-token-meter`:
33
+ * empty content prices as 0 ("no system prompt").
34
+ * @param message - the effective system message, or undefined when none is active.
35
+ * @returns heuristic system-prompt tokens; 0 when absent or empty.
36
+ */
37
+ export declare function estimateSystemTokens(message: SystemMessage | undefined): number;
38
+ /**
39
+ * Price the legacy (<= 0.1.3-alpha.1) `EpochHeader.system` string. Kept as the
40
+ * runtime fallback for the old peer line, where the prompt never reached the
41
+ * surface and lived in the request envelope.
42
+ * @param system - the legacy rendered prompt text, or undefined before any request.
32
43
  * @returns heuristic system-prompt tokens; 0 when absent.
33
44
  */
34
- export declare function estimateSystemTokens(header: EpochHeader | undefined): number;
45
+ export declare function estimateLegacySystemTokens(system: string | undefined): number;
35
46
  /**
36
47
  * Price the tool-schema part of the request envelope.
37
48
  * @param header - canonical request envelope, or undefined before any request.
@@ -1 +1 @@
1
- {"version":3,"file":"estimate.d.ts","sourceRoot":"","sources":["../../src/estimate.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAWvD,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAoBD;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,qBAAqB,CAehG;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,MAAM,CAG5E;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,MAAM,CAG3E"}
1
+ {"version":3,"file":"estimate.d.ts","sourceRoot":"","sources":["../../src/estimate.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC1E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAWvD,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAoBD;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,qBAAqB,CAehG;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,GAAG,MAAM,CAO/E;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAG7E;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,MAAM,CAG3E"}
@@ -62,14 +62,33 @@ export function classifySystemSections(sections) {
62
62
  }
63
63
  /**
64
64
  * Price the assembled system prompt (harness identity + persona + tool
65
- * guidance + plugin sections).
66
- * @param header - canonical request envelope, or undefined before any request.
65
+ * guidance + plugin sections). 0.1.5-alpha.1 represents it as surface node 0
66
+ * (a `system/message`) instead of the request envelope's `system` field, so
67
+ * this mirrors `estimateSystemMessage` in `@deepseek-ai/dsh-token-meter`:
68
+ * empty content prices as 0 ("no system prompt").
69
+ * @param message - the effective system message, or undefined when none is active.
70
+ * @returns heuristic system-prompt tokens; 0 when absent or empty.
71
+ */
72
+ export function estimateSystemTokens(message) {
73
+ if (message === undefined || message.content.length === 0)
74
+ return 0;
75
+ let characters = 0;
76
+ for (const block of message.content) {
77
+ characters += block.type === 'text' ? block.text.length : JSON.stringify(block).length;
78
+ }
79
+ return Math.ceil(characters / CHARS_PER_TOKEN) + ROLE_OVERHEAD;
80
+ }
81
+ /**
82
+ * Price the legacy (<= 0.1.3-alpha.1) `EpochHeader.system` string. Kept as the
83
+ * runtime fallback for the old peer line, where the prompt never reached the
84
+ * surface and lived in the request envelope.
85
+ * @param system - the legacy rendered prompt text, or undefined before any request.
67
86
  * @returns heuristic system-prompt tokens; 0 when absent.
68
87
  */
69
- export function estimateSystemTokens(header) {
70
- if (header?.system === undefined)
88
+ export function estimateLegacySystemTokens(system) {
89
+ if (system === undefined)
71
90
  return 0;
72
- return Math.ceil(header.system.length / CHARS_PER_TOKEN) + ROLE_OVERHEAD;
91
+ return Math.ceil(system.length / CHARS_PER_TOKEN) + ROLE_OVERHEAD;
73
92
  }
74
93
  /**
75
94
  * Price the tool-schema part of the request envelope.
@@ -1 +1 @@
1
- {"version":3,"file":"estimate.js","sourceRoot":"","sources":["../../src/estimate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"estimate.js","sourceRoot":"","sources":["../../src/estimate.ts"],"names":[],"mappings":"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"}
@@ -67,7 +67,7 @@ export interface ContextStats {
67
67
  systemTokens: number;
68
68
  /** Tool-schema tokens. */
69
69
  toolSchemaTokens: number;
70
- /** Conversation-surface tokens (message history). */
70
+ /** Conversation-surface tokens (message history; the system prompt is priced separately). */
71
71
  surfaceTokens: number;
72
72
  /** `systemTokens / totalTokens` (0 when the total is 0). */
73
73
  systemShare: number;
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/model.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,yEAAyE;AACzE,MAAM,WAAW,SAAS;IACxB,sEAAsE;IACtE,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;IACxB,oFAAoF;IACpF,UAAU,EAAE,MAAM,CAAA;IAClB,6FAA6F;IAC7F,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;CACpC;AAED,iFAAiF;AACjF,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,YAAY,CAAA;CACvB;AAED,kEAAkE;AAClE,MAAM,WAAW,UAAU;IACzB,6FAA6F;IAC7F,sBAAsB,EAAE,MAAM,CAAA;IAC9B,2FAA2F;IAC3F,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,qEAAqE;AACrE,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAA;IACb,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAA;IACd,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAA;IACjB,8DAA8D;IAC9D,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,sDAAsD;AACtD,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAA;IACd,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAA;IACb,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAA;CACd;AAED,wFAAwF;AACxF,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,QAAQ,EAAE,YAAY,CAAA;IACtB,yCAAyC;IACzC,MAAM,EAAE,YAAY,CAAA;IACpB,wCAAwC;IACxC,OAAO,EAAE,YAAY,CAAA;IACrB,sEAAsE;IACtE,KAAK,EAAE,YAAY,CAAA;CACpB;AAED,yEAAyE;AACzE,MAAM,WAAW,YAAY;IAC3B,2FAA2F;IAC3F,WAAW,EAAE,MAAM,CAAA;IACnB,sGAAsG;IACtG,YAAY,EAAE,MAAM,CAAA;IACpB,0BAA0B;IAC1B,gBAAgB,EAAE,MAAM,CAAA;IACxB,qDAAqD;IACrD,aAAa,EAAE,MAAM,CAAA;IACrB,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAA;IACnB,gEAAgE;IAChE,UAAU,EAAE,MAAM,CAAA;IAClB,6DAA6D;IAC7D,YAAY,EAAE,MAAM,CAAA;IACpB,kFAAkF;IAClF,eAAe,EAAE,qBAAqB,CAAA;CACvC;AAED,sEAAsE;AACtE,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAA;IACnB,eAAe,EAAE,MAAM,CAAA;IACvB,gBAAgB,EAAE,MAAM,CAAA;IACxB,YAAY,EAAE,MAAM,CAAA;IACpB,4FAA4F;IAC5F,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB;AAED,oEAAoE;AACpE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,CAAA;IACf,KAAK,EAAE,UAAU,CAAA;IACjB,UAAU,EAAE,eAAe,CAAA;IAC3B,OAAO,EAAE,YAAY,CAAA;IACrB,KAAK,EAAE,UAAU,CAAA;CAClB;AAED,+EAA+E;AAC/E,MAAM,WAAW,UAAW,SAAQ,YAAY;IAC9C,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAA;IACjB,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAA;IACnB,oEAAoE;IACpE,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,8FAA8F;IAC9F,GAAG,CAAC,EAAE,MAAM,CAAA;CACb"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/model.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,yEAAyE;AACzE,MAAM,WAAW,SAAS;IACxB,sEAAsE;IACtE,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;IACxB,oFAAoF;IACpF,UAAU,EAAE,MAAM,CAAA;IAClB,6FAA6F;IAC7F,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;CACpC;AAED,iFAAiF;AACjF,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,YAAY,CAAA;CACvB;AAED,kEAAkE;AAClE,MAAM,WAAW,UAAU;IACzB,6FAA6F;IAC7F,sBAAsB,EAAE,MAAM,CAAA;IAC9B,2FAA2F;IAC3F,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,qEAAqE;AACrE,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAA;IACb,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAA;IACd,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAA;IACjB,8DAA8D;IAC9D,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,sDAAsD;AACtD,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAA;IACd,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAA;IACb,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAA;CACd;AAED,wFAAwF;AACxF,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,QAAQ,EAAE,YAAY,CAAA;IACtB,yCAAyC;IACzC,MAAM,EAAE,YAAY,CAAA;IACpB,wCAAwC;IACxC,OAAO,EAAE,YAAY,CAAA;IACrB,sEAAsE;IACtE,KAAK,EAAE,YAAY,CAAA;CACpB;AAED,yEAAyE;AACzE,MAAM,WAAW,YAAY;IAC3B,2FAA2F;IAC3F,WAAW,EAAE,MAAM,CAAA;IACnB,sGAAsG;IACtG,YAAY,EAAE,MAAM,CAAA;IACpB,0BAA0B;IAC1B,gBAAgB,EAAE,MAAM,CAAA;IACxB,6FAA6F;IAC7F,aAAa,EAAE,MAAM,CAAA;IACrB,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAA;IACnB,gEAAgE;IAChE,UAAU,EAAE,MAAM,CAAA;IAClB,6DAA6D;IAC7D,YAAY,EAAE,MAAM,CAAA;IACpB,kFAAkF;IAClF,eAAe,EAAE,qBAAqB,CAAA;CACvC;AAED,sEAAsE;AACtE,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAA;IACnB,eAAe,EAAE,MAAM,CAAA;IACvB,gBAAgB,EAAE,MAAM,CAAA;IACxB,YAAY,EAAE,MAAM,CAAA;IACpB,4FAA4F;IAC5F,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB;AAED,oEAAoE;AACpE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,CAAA;IACf,KAAK,EAAE,UAAU,CAAA;IACjB,UAAU,EAAE,eAAe,CAAA;IAC3B,OAAO,EAAE,YAAY,CAAA;IACrB,KAAK,EAAE,UAAU,CAAA;CAClB;AAED,+EAA+E;AAC/E,MAAM,WAAW,UAAW,SAAQ,YAAY;IAC9C,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAA;IACjB,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAA;IACnB,oEAAoE;IACpE,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,8FAA8F;IAC9F,GAAG,CAAC,EAAE,MAAM,CAAA;CACb"}
@@ -1,3 +1,3 @@
1
1
  /** Single-source plugin version, bumped by `scripts/release.mjs`. @module dsh-fast/version */
2
- export declare const VERSION = "0.2.9";
2
+ export declare const VERSION = "0.2.11";
3
3
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,eAAO,MAAM,OAAO,UAAU,CAAA"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,eAAO,MAAM,OAAO,WAAW,CAAA"}
@@ -1,3 +1,3 @@
1
1
  /** Single-source plugin version, bumped by `scripts/release.mjs`. @module dsh-fast/version */
2
- export const VERSION = '0.2.9';
2
+ export const VERSION = '0.2.11';
3
3
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAA"}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-fast",
3
- "version": "0.2.9",
3
+ "version": "0.2.11",
4
4
  "description": "Read-only performance diagnostics for DeepSeek Harness: session load (open/restore) timing, spill-hit counts, compaction count and trigger, context-injection volume (AGENTS.md/skills/tool-schema token share), and LLM cache hit rate — surfaced via the /fast command and the fast_report tool, persisted as reconstructable fast/* session events with async sampling off the model path.",
5
5
  "author": "dsh-fast contributors",
6
6
  "repository": {
@@ -65,7 +65,8 @@
65
65
  ],
66
66
  "compatibility": {
67
67
  "dshVersions": [
68
- "0.1.2-rc.1"
68
+ "0.1.2-rc.1",
69
+ "0.1.5-rc.1"
69
70
  ]
70
71
  },
71
72
  "capability": {
@@ -99,13 +100,13 @@
99
100
  "packageManager": "pnpm@11.7.0",
100
101
  "peerDependencies": {
101
102
  "@deepseek-ai/cordis": "^4.0.2",
102
- "@deepseek-ai/dsh-commands": ">=0.1.2-rc.1 <0.2.0",
103
- "@deepseek-ai/dsh-compaction": ">=0.1.2-rc.1 <0.2.0",
104
- "@deepseek-ai/dsh-session": ">=0.1.2-rc.1 <0.2.0",
105
- "@deepseek-ai/dsh-storage": ">=0.1.2-rc.1 <0.2.0",
106
- "@deepseek-ai/dsh-storage-domain": ">=0.1.2-rc.1 <0.2.0",
107
- "@deepseek-ai/dsh-storage-json": ">=0.1.2-rc.1 <0.2.0",
108
- "@deepseek-ai/dsh-tools": ">=0.1.2-rc.1 <0.2.0",
103
+ "@deepseek-ai/dsh-commands": ">=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0",
104
+ "@deepseek-ai/dsh-compaction": ">=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0",
105
+ "@deepseek-ai/dsh-session": ">=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0",
106
+ "@deepseek-ai/dsh-storage": ">=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0",
107
+ "@deepseek-ai/dsh-storage-domain": ">=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0",
108
+ "@deepseek-ai/dsh-storage-json": ">=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0",
109
+ "@deepseek-ai/dsh-tools": ">=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0",
109
110
  "@deepseek-ai/schemastery": "^3.18.2"
110
111
  },
111
112
  "dependencies": {
@@ -114,21 +115,22 @@
114
115
  "zod": "^4.4.3"
115
116
  },
116
117
  "devDependencies": {
117
- "@deepseek-ai/dsh-attachment": "0.1.2-rc.1",
118
+ "@deepseek-ai/dsh-attachment": "0.1.5-rc.1",
118
119
  "@deepseek-ai/cordis": "^4.0.2",
119
120
  "@deepseek-ai/cordis-plugin-include": "^1.0.7",
120
121
  "@deepseek-ai/cordis-plugin-loader": "^1.0.3",
121
- "@deepseek-ai/dsh-agent": "0.1.2-rc.1",
122
- "@deepseek-ai/dsh-commands": "0.1.2-rc.1",
123
- "@deepseek-ai/dsh-compaction": "0.1.2-rc.1",
124
- "@deepseek-ai/dsh-llm": "0.1.2-rc.1",
125
- "@deepseek-ai/dsh-session": "0.1.2-rc.1",
126
- "@deepseek-ai/dsh-storage": "0.1.2-rc.1",
127
- "@deepseek-ai/dsh-storage-domain": "0.1.2-rc.1",
128
- "@deepseek-ai/dsh-storage-json": "0.1.2-rc.1",
129
- "@deepseek-ai/dsh-system-prompt": "0.1.2-rc.1",
130
- "@deepseek-ai/dsh-token-meter": "0.1.2-rc.1",
131
- "@deepseek-ai/dsh-tools": "0.1.2-rc.1",
122
+ "@deepseek-ai/dsh-agent": "0.1.5-rc.1",
123
+ "@deepseek-ai/dsh-commands": "0.1.5-rc.1",
124
+ "@deepseek-ai/dsh-compaction": "0.1.5-rc.1",
125
+ "@deepseek-ai/dsh-llm": "0.1.5-rc.1",
126
+ "@deepseek-ai/dsh-session": "0.1.5-rc.1",
127
+ "@deepseek-ai/dsh-session-projection": "0.1.5-rc.1",
128
+ "@deepseek-ai/dsh-storage": "0.1.5-rc.1",
129
+ "@deepseek-ai/dsh-storage-domain": "0.1.5-rc.1",
130
+ "@deepseek-ai/dsh-storage-json": "0.1.5-rc.1",
131
+ "@deepseek-ai/dsh-system-prompt": "0.1.5-rc.1",
132
+ "@deepseek-ai/dsh-token-meter": "0.1.5-rc.1",
133
+ "@deepseek-ai/dsh-tools": "0.1.5-rc.1",
132
134
  "@deepseek-ai/schemastery": "^3.18.2",
133
135
  "@types/node": "^22.19.0",
134
136
  "@vitest/coverage-v8": "^3.2.0",
package/src/collector.ts CHANGED
@@ -8,18 +8,26 @@
8
8
  * @module dsh-fast/collector
9
9
  */
10
10
 
11
- import type { Session, SessionEvent, ToolResultMessage } from '@deepseek-ai/dsh-session'
11
+ import type { EpochHeader, Session, SessionEvent, SystemMessage, ToolResultMessage } from '@deepseek-ai/dsh-session'
12
12
  // Type-only: registers the `compaction/*` SessionEventMap merge this collector folds.
13
13
  import type {} from '@deepseek-ai/dsh-compaction'
14
14
  import type { FastSnapshot, CacheStats, ContextStats } from './model.ts'
15
15
  import type { ResolvedConfig } from './config.ts'
16
- import { classifySystemSections, estimateSystemTokens, estimateToolsTokens, type SystemSection } from './estimate.ts'
16
+ import {
17
+ classifySystemSections,
18
+ estimateLegacySystemTokens,
19
+ estimateSystemTokens,
20
+ estimateToolsTokens,
21
+ type SystemSection,
22
+ } from './estimate.ts'
17
23
 
18
24
  /**
19
25
  * The structural surface of the optional `ctx.tokenMeter` service. Only the
20
26
  * fields dsh-fast reads are declared; the service is optional, so a host
21
27
  * without it still reports system/tool-schema volumes (surface/total fall back
22
- * to the header heuristic).
28
+ * to the heuristic header+surface sum). On 0.1.5-alpha.1 `surfaceTokens`
29
+ * includes the `system/message` surface node, which {@link FastCollector.snapshot}
30
+ * subtracts so the surface bucket stays conversation history.
23
31
  */
24
32
  export interface TokenMeasurement {
25
33
  readonly totalTokens: number
@@ -32,6 +40,45 @@ export type MeasureFn = (session: Session) => TokenMeasurement | undefined
32
40
  /** The durable marker every spill notice carries (`... Full ... stored at: <locator> ...`). */
33
41
  const SPILL_NOTICE_MARKERS = ['Full', 'stored at:'] as const
34
42
 
43
+ /**
44
+ * The effective system prompt: the last non-empty `system/message` node in
45
+ * surface order. 0.1.5-alpha.1 derives the prompt from surface node 0; an empty
46
+ * node is dormant and never restores older text. Mirrors
47
+ * `SystemPromptProjection` in the host agent loop.
48
+ * @param session - the session to read.
49
+ * @returns the effective system message, or undefined when none is active.
50
+ */
51
+ export function effectiveSystemMessage(session: Session): SystemMessage | undefined {
52
+ let effective: SystemMessage | undefined
53
+ for (const seq of session.surface.nodes) {
54
+ const event = session.eventAt(seq)
55
+ if (event?.type !== 'system/message') continue
56
+ const message = event.data.message
57
+ if (message.content.length === 0) continue
58
+ effective = message
59
+ }
60
+ return effective
61
+ }
62
+
63
+ /** The display/durable text of a system message (text blocks plus structural JSON). */
64
+ function systemTextOf(message: SystemMessage): string {
65
+ let text = ''
66
+ for (const block of message.content) text += block.type === 'text' ? block.text : JSON.stringify(block)
67
+ return text
68
+ }
69
+
70
+ /**
71
+ * Structural read of the pre-0.1.5 `EpochHeader.system` string, removed from
72
+ * the public type when the prompt moved to surface node 0. This keeps the
73
+ * runtime fallback for the `0.1.2-rc.1` peer line.
74
+ * @param header - canonical request envelope, or undefined before any request.
75
+ * @returns the legacy prompt text, or undefined when absent.
76
+ */
77
+ function legacySystemText(header: EpochHeader | undefined): string | undefined {
78
+ const system = (header as { system?: unknown } | undefined)?.system
79
+ return typeof system === 'string' ? system : undefined
80
+ }
81
+
35
82
  /** Flatten a tool result's model-facing text blocks to one string. */
36
83
  export function flattenToolResultText(message: ToolResultMessage): string {
37
84
  const block = message.content[0]
@@ -93,7 +140,7 @@ interface FastState {
93
140
  cacheReadTokens: number
94
141
  cacheWriteTokens: number
95
142
  outputTokens: number
96
- lastHeader: import('@deepseek-ai/dsh-session').EpochHeader | undefined
143
+ lastHeader: EpochHeader | undefined
97
144
  dirty: boolean
98
145
  }
99
146
 
@@ -193,14 +240,25 @@ export class FastCollector {
193
240
  const state = this.live.get(session)
194
241
  if (state === undefined) return emptySnapshot()
195
242
  const measurement = measure === undefined ? undefined : measure(session)
196
- const systemTokens = estimateSystemTokens(state.lastHeader)
243
+ const systemMessage = effectiveSystemMessage(session)
244
+ const legacySystem = systemMessage === undefined ? legacySystemText(state.lastHeader) : undefined
245
+ const systemTokens = systemMessage === undefined
246
+ ? estimateLegacySystemTokens(legacySystem)
247
+ : estimateSystemTokens(systemMessage)
197
248
  const toolSchemaTokens = estimateToolsTokens(state.lastHeader)
198
- const surfaceTokens = measurement?.surfaceTokens ?? 0
249
+ const measuredSurfaceTokens = measurement?.surfaceTokens ?? 0
250
+ // 0.1.5-alpha.1 prices the system prompt into the meter's surface (surface
251
+ // node 0), so subtract it and keep the surface bucket conversation history.
252
+ // The legacy line kept `header.system` out of the meter surface entirely.
253
+ const surfaceTokens = systemMessage === undefined
254
+ ? measuredSurfaceTokens
255
+ : Math.max(0, measuredSurfaceTokens - systemTokens)
199
256
  const totalTokens = measurement?.totalTokens ?? (systemTokens + toolSchemaTokens + surfaceTokens)
200
- const systemChars = state.lastHeader?.system?.length ?? 0
201
- const systemBreakdown = classifySystemSections(
202
- sections ?? (systemChars > 0 ? [{ name: 'other', text: state.lastHeader!.system! }] : []),
203
- )
257
+ const systemText = systemMessage === undefined ? legacySystem : systemTextOf(systemMessage)
258
+ const syntheticSections: readonly SystemSection[] = systemText === undefined || systemText.length === 0
259
+ ? []
260
+ : [{ name: 'other', text: systemText }]
261
+ const systemBreakdown = classifySystemSections(sections ?? syntheticSections)
204
262
  return {
205
263
  load: {
206
264
  kind: state.kind,
package/src/estimate.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  * @module dsh-fast/estimate
9
9
  */
10
10
 
11
- import type { EpochHeader } from '@deepseek-ai/dsh-session'
11
+ import type { EpochHeader, SystemMessage } from '@deepseek-ai/dsh-session'
12
12
  import type { SystemPromptBreakdown } from './model.ts'
13
13
 
14
14
  /** Fixed text-density estimate (chars per token). */
@@ -73,13 +73,32 @@ export function classifySystemSections(sections: readonly SystemSection[]): Syst
73
73
 
74
74
  /**
75
75
  * Price the assembled system prompt (harness identity + persona + tool
76
- * guidance + plugin sections).
77
- * @param header - canonical request envelope, or undefined before any request.
76
+ * guidance + plugin sections). 0.1.5-alpha.1 represents it as surface node 0
77
+ * (a `system/message`) instead of the request envelope's `system` field, so
78
+ * this mirrors `estimateSystemMessage` in `@deepseek-ai/dsh-token-meter`:
79
+ * empty content prices as 0 ("no system prompt").
80
+ * @param message - the effective system message, or undefined when none is active.
81
+ * @returns heuristic system-prompt tokens; 0 when absent or empty.
82
+ */
83
+ export function estimateSystemTokens(message: SystemMessage | undefined): number {
84
+ if (message === undefined || message.content.length === 0) return 0
85
+ let characters = 0
86
+ for (const block of message.content) {
87
+ characters += block.type === 'text' ? block.text.length : JSON.stringify(block).length
88
+ }
89
+ return Math.ceil(characters / CHARS_PER_TOKEN) + ROLE_OVERHEAD
90
+ }
91
+
92
+ /**
93
+ * Price the legacy (<= 0.1.3-alpha.1) `EpochHeader.system` string. Kept as the
94
+ * runtime fallback for the old peer line, where the prompt never reached the
95
+ * surface and lived in the request envelope.
96
+ * @param system - the legacy rendered prompt text, or undefined before any request.
78
97
  * @returns heuristic system-prompt tokens; 0 when absent.
79
98
  */
80
- export function estimateSystemTokens(header: EpochHeader | undefined): number {
81
- if (header?.system === undefined) return 0
82
- return Math.ceil(header.system.length / CHARS_PER_TOKEN) + ROLE_OVERHEAD
99
+ export function estimateLegacySystemTokens(system: string | undefined): number {
100
+ if (system === undefined) return 0
101
+ return Math.ceil(system.length / CHARS_PER_TOKEN) + ROLE_OVERHEAD
83
102
  }
84
103
 
85
104
  /**
package/src/model.ts CHANGED
@@ -74,7 +74,7 @@ export interface ContextStats {
74
74
  systemTokens: number
75
75
  /** Tool-schema tokens. */
76
76
  toolSchemaTokens: number
77
- /** Conversation-surface tokens (message history). */
77
+ /** Conversation-surface tokens (message history; the system prompt is priced separately). */
78
78
  surfaceTokens: number
79
79
  /** `systemTokens / totalTokens` (0 when the total is 0). */
80
80
  systemShare: number
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** Single-source plugin version, bumped by `scripts/release.mjs`. @module dsh-fast/version */
2
- export const VERSION = '0.2.9'
2
+ export const VERSION = '0.2.11'