billion-context-dsh 0.2.25 → 0.2.26

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.
@@ -12,6 +12,16 @@
12
12
  */
13
13
  import type { CoreMessage } from 'acp-kernel';
14
14
  import type { Session, SessionEvent } from '@deepseek-ai/dsh-session';
15
+ declare module '@deepseek-ai/dsh-llm/message' {
16
+ interface MessageSourceMap {
17
+ acpNudge: {
18
+ kind: 'plugin:acp-nudge';
19
+ };
20
+ acpPrune: {
21
+ kind: 'plugin:billion-context-dsh';
22
+ };
23
+ }
24
+ }
15
25
  /**
16
26
  * Extract plain text from a DSH content block array or string.
17
27
  *
@@ -89,6 +99,21 @@ export declare function buildToolCallIndex(events: readonly SessionEvent[]): Rea
89
99
  */
90
100
  export declare const SUMMARY_FRAME_PREFIX = "[Model-written summary \u2014 not user words; re-verify any obligations before relying on them]";
91
101
  export declare function withSummaryFramePrefix(text: string): string;
102
+ /**
103
+ * The lead-in of a summary the ENGINE writes itself — today only the
104
+ * context-overflow emergency marker (src/index.ts `compactForOverflow`).
105
+ * Recognition is by content, not by caller: the writer and both framing sites
106
+ * share this ONE literal.
107
+ */
108
+ export declare const ENGINE_SUMMARY_LEAD = "[engine-written summary \u2014 context-overflow emergency compaction";
109
+ export declare function isEngineWrittenSummary(text: string): boolean;
110
+ /**
111
+ * The block summary the automatic overflow recovery writes. It is the engine's
112
+ * own note — not model-written text, not user words — saying which range was
113
+ * hidden to get the request under the window and where the originals still
114
+ * live (the append-only log: search_context/decompress rebuild from it).
115
+ */
116
+ export declare function overflowMarkerSummary(hiddenCount: number): string;
92
117
  export declare function projectEvent(event: SessionEvent, toolNames?: ReadonlyMap<string, string>): CoreMessage[];
93
118
  /** Project a session's message events into CoreMessage[] in log order. */
94
119
  export declare function eventsToCoreMessages(events: readonly SessionEvent[], toolNames?: ReadonlyMap<string, string>): CoreMessage[];
@@ -131,40 +156,85 @@ export declare function mediaBlocksOfEvent(event: SessionEvent): readonly unknow
131
156
  * Whether a surface user message is a compaction checkpoint node (already
132
157
  * compressed). Defined here (not in region.ts) so the classifier below and
133
158
  * region.ts share ONE implementation.
159
+ *
160
+ * Recognizes BOTH host shapes (issue #168): the ≤0.1.6 wrapper
161
+ * `{ kind: 'plugin', plugin: 'compact', compactionId }` and the 0.1.7+
162
+ * producer-owned kind `{ kind: 'compact-checkpoint', compactionId }` written
163
+ * by dsh-compaction's `compactCheckpointSource()` (verified against the
164
+ * published 0.1.7-alpha.1 artifact: the marker object is exactly
165
+ * `{ kind: 'compact-checkpoint' }` plus `compactionId` and an optional
166
+ * `sourceCommandId`). The 0.1.7 V3→V4 migration rewrites pre-0.1.7 sessions
167
+ * to the new shape, so both shapes coexist on one surface and both must be
168
+ * recognized — a row that misses this predicate classifies as `real`, which
169
+ * double-counts its summary text in acp_status, can steal the protected-tail
170
+ * window, and hides it from every distillation entry point below.
134
171
  */
135
172
  export declare function isCheckpointNode(event: SessionEvent): boolean;
173
+ /**
174
+ * The durable compaction id stamped on a checkpoint summary node, reading BOTH
175
+ * host shapes (see {@link isCheckpointNode}). Returns null when the event is
176
+ * not a checkpoint node or carries no id — a malformed row still CLASSIFIES
177
+ * as a checkpoint (it must never read as real content) but has no block to
178
+ * link to. Single shared extractor for the ledger index (`summarySeqIndex`),
179
+ * the distill-edge resolver (`blockRefForSummarySeq`) and the decompress
180
+ * recursion (`checkpointBlockIdOf`) — those sites must not re-derive the shape
181
+ * check themselves (issue #168).
182
+ */
183
+ export declare function checkpointCompactionIdOf(event: SessionEvent): string | null;
136
184
  /**
137
185
  * Injection/authoring classification of one surface event — the ONE shared
138
186
  * classifier for range scanning and the protected-tail scan (never ad-hoc
139
187
  * predicates that drift apart).
140
188
  *
141
189
  * - `real` — genuine conversation content (user turns without an injected
142
- * source, assistant prose/tool-calls, tool results, sub-agent relay rows).
143
- * This is the only class that may win "last real user message" protection
144
- * (minus relay rows, see `isRealUserTurn`).
190
+ * source, assistant prose/tool-calls, tool results, sub-agent relay rows,
191
+ * and host content channels in BOTH spellings: legacy plugin names and the
192
+ * DSH >= 0.1.7 direct-kind renames, issue #169). This is the only class
193
+ * that may win "last real user message" protection (minus all non-user
194
+ * rows, see `isRealUserTurn`).
145
195
  * - `metadata` — the engine's own ephemeral rows: nudge echoes and
146
196
  * compress-pair replacement stubs. Their content is derived from
147
197
  * already-visible messages, so folding them into an adjacent real segment
148
198
  * is zero-loss — this preserves main's behavior for engine-authored rows.
149
- * - `checkpoint` — compaction summary nodes (`plugin: 'compact'`).
199
+ * - `checkpoint` — compaction summary nodes (both host shapes, see
200
+ * `isCheckpointNode`: legacy `plugin: 'compact'` and 0.1.7+
201
+ * `kind: 'compact-checkpoint'`, issue #168).
150
202
  * Distillation is an explicit act; never folded into any segment.
151
203
  * - `instruction` — host-authored policy/instructions: AGENTS.md injections
152
- * (both host shapes), skill catalogs, and ANY unknown `kind:'plugin'` row.
153
- * Folding these is unsafe (the model would lose live policy text, and the
154
- * host re-injects the current AGENTS.md copy when it disappears — the
155
- * compress → re-inject loop this PR fixes). Unknown plugin names fall here
156
- * deliberately: a future host injection must never silently become
157
- * compressible content.
204
+ * (both host shapes), skill catalogs, host compaction summary rows
205
+ * (`compact-basic`, issue #169), and ANY unknown `kind:'plugin'` row or
206
+ * unaudited direct kind. Folding these is unsafe (the model would lose
207
+ * live policy text, and the host re-injects the current AGENTS.md copy
208
+ * when it disappears — the compress → re-inject loop this PR fixes).
209
+ * Unknown channel names fall here deliberately in BOTH namespaces: a
210
+ * future host injection must never silently become compressible content.
158
211
  */
159
212
  export type SurfaceEventClass = 'real' | 'metadata' | 'checkpoint' | 'instruction';
160
213
  /** Plugin names the engine itself authors — safe to fold into real segments. */
161
214
  export declare const METADATA_PLUGINS: ReadonlySet<string>;
162
215
  /**
163
- * True for AGENTS.md instruction rows in BOTH host shapes: the hook shape
164
- * (`kind:'agent-instructions'`, form 'instructions') and the baseline shape
165
- * (`kind:'plugin'` + plugin 'agent-instructions'). Shared by the newest-row
166
- * scan and the range scanner so protection and folding always agree on what
167
- * counts as an AGENTS.md row.
216
+ * Resolve the owning plugin name from either durable source shape: the legacy
217
+ * V3 wrapper `{ kind: 'plugin', plugin: '<name>' }` or the V4 producer kind
218
+ * `'plugin:<name>'`. DSH 0.1.7's V3→V4 migration rewrites every unregistered
219
+ * plugin row into the latter on file open, so both shapes coexist on a live
220
+ * surface until a session has been fully rewritten (issue #163). Returns
221
+ * undefined when neither shape is present, or when the name is missing,
222
+ * non-string, or empty — callers then keep their conservative fallback.
223
+ */
224
+ export declare function sourcePluginOf(source: {
225
+ kind?: unknown;
226
+ plugin?: unknown;
227
+ } | undefined): string | undefined;
228
+ /**
229
+ * True for AGENTS.md instruction rows in ALL host shapes: the hook shape
230
+ * (`kind:'agent-instructions'`, form 'instructions'), the legacy V3 wrapper
231
+ * (`kind:'plugin'` + plugin 'agent-instructions'), and the V4 producer kind
232
+ * (`kind:'plugin:agent-instructions'`) that DSH 0.1.7's migration rewrites
233
+ * legacy rows into on file open (issue #163) — a migrated session must keep
234
+ * its newest-row pin, or the current copy becomes foldable and the
235
+ * compress → re-inject loop returns. Shared by the newest-row scan and the
236
+ * range scanner so protection and folding always agree on what counts as an
237
+ * AGENTS.md row.
168
238
  */
169
239
  export declare function isAgentInstructionsRow(event: SessionEvent): boolean;
170
240
  export declare function classifySurfaceEvent(event: SessionEvent): SurfaceEventClass;
package/dist/nudge.d.ts CHANGED
@@ -38,6 +38,14 @@ export interface NudgeOutcome {
38
38
  * minimal hosts that lack the token-meter service.
39
39
  */
40
40
  export declare function resolveTokenCount(agent: Agent, coreMessages: CoreMessage[]): number;
41
+ /**
42
+ * Lazy per-seq media price. The FIRST lookup triggers one meter measurement, so
43
+ * the range walk only asks about seqs that really carry an attachment — a
44
+ * media-free session never pays for the measurement (issue #117, issue #110).
45
+ * Exported for the context-overflow recovery path, which ranks ranges with the
46
+ * same vocabulary as the nudge table.
47
+ */
48
+ export declare function meterMediaPriceResolver(agent: Agent, session: import('@deepseek-ai/dsh-session').Session): MediaPriceOf;
41
49
  /**
42
50
  * Render the compressible-range table as seq refs for the model.
43
51
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "billion-context-dsh",
3
- "version": "0.2.25",
3
+ "version": "0.2.26",
4
4
  "description": "Active Context Pruning (ACP) for the DeepSeek Harness — model-driven context management as a CompactionEngine backend.",
5
5
  "keywords": [
6
6
  "deepseek",