@kodax-ai/kodax 0.7.43 → 0.7.44

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/chunks/{chunk-YMRZBS4G.js → chunk-35BDEEC5.js} +1 -1
  3. package/dist/chunks/{chunk-7G5PSL6C.js → chunk-4YPL2UVZ.js} +253 -235
  4. package/dist/chunks/chunk-DI2G3YWL.js +31 -0
  5. package/dist/chunks/chunk-HHQ7YTGM.js +425 -0
  6. package/dist/chunks/chunk-QHILHQBB.js +519 -0
  7. package/dist/chunks/{chunk-IYSK7LUK.js → chunk-RUDYNAK7.js} +1 -1
  8. package/dist/chunks/{compaction-config-3E57ABCT.js → compaction-config-NAPRF7XR.js} +1 -1
  9. package/dist/chunks/{construction-bootstrap-JR63KI5N.js → construction-bootstrap-PHTGBRNU.js} +1 -1
  10. package/dist/chunks/dist-CCYBJJZY.js +2 -0
  11. package/dist/chunks/{dist-XANXEVTU.js → dist-RHIHZAYX.js} +1 -1
  12. package/dist/chunks/{utils-HQ2QCKJA.js → utils-TV3UYCHQ.js} +1 -1
  13. package/dist/index.d.ts +8 -8
  14. package/dist/index.js +2 -2
  15. package/dist/kodax_cli.js +624 -589
  16. package/dist/provider-capabilities.json +167 -0
  17. package/dist/sdk-agent.d.ts +62 -7
  18. package/dist/sdk-agent.js +1 -1
  19. package/dist/sdk-coding.d.ts +367 -13
  20. package/dist/sdk-coding.js +1 -1
  21. package/dist/sdk-llm.d.ts +1 -1
  22. package/dist/sdk-llm.js +1 -1
  23. package/dist/sdk-mcp.js +1 -1
  24. package/dist/sdk-repl.d.ts +6 -6
  25. package/dist/sdk-repl.js +1 -1
  26. package/dist/sdk-session.d.ts +2 -2
  27. package/dist/sdk-session.js +1 -1
  28. package/dist/sdk-skills.js +1 -1
  29. package/dist/types-chunks/{bash-prefix-extractor.d-DMrGImMl.d.ts → bash-prefix-extractor.d-DdoSeghD.d.ts} +417 -5
  30. package/dist/types-chunks/file-tracker.d-DOfaoCbJ.d.ts +633 -0
  31. package/dist/types-chunks/{resolver.d-CA68_NeH.d.ts → resolver.d-B7ZnVuuf.d.ts} +16 -13
  32. package/dist/types-chunks/{storage.d-DPAEX7zS.d.ts → storage.d-DFD9ln5c.d.ts} +1 -1
  33. package/dist/types-chunks/{file-tracker.d-zaLZeNBK.d.ts → types.d-DM8zEJgF.d.ts} +1029 -535
  34. package/dist/types-chunks/{types.d-mM8vqvhT.d.ts → types.d-HBbWT-iA.d.ts} +41 -3
  35. package/dist/types-chunks/{utils.d-DkLZD_wa.d.ts → utils.d-C5fzCE9W.d.ts} +3 -3
  36. package/package.json +2 -2
  37. package/dist/chunks/chunk-K75O2CAE.js +0 -31
  38. package/dist/chunks/chunk-UG4262JI.js +0 -502
  39. package/dist/chunks/chunk-VHKAJDQD.js +0 -425
  40. package/dist/chunks/dist-KWHUKXEL.js +0 -2
  41. package/dist/types-chunks/types.d-CKJtjo-6.d.ts +0 -1127
@@ -0,0 +1,633 @@
1
+ import { m as KodaXMessage } from './types.d-B1uGoVTE.js';
2
+ import { f as AgentMessage, ag as SessionEntry, ae as Session, ah as SessionExtension, m as CompactionDetails, u as FileOperations } from './types.d-DM8zEJgF.js';
3
+ import { s as KodaXSessionLineage, i as KodaXJsonValue, a as KodaXCompactMemorySeed, o as KodaXSessionEntry, z as KodaXSessionTreeNode, r as KodaXSessionLabelEntry, q as KodaXSessionGoalEntry, v as KodaXSessionNavigationOptions, k as KodaXSessionArtifactLedgerEntry } from './types.d-HBbWT-iA.js';
4
+
5
+ /**
6
+ * @kodax-ai/agent Constants
7
+ *
8
+ * 通用 Agent 常量配置
9
+ */
10
+ declare const KODAX_MAX_TOKENS = 32768;
11
+ declare const KODAX_DEFAULT_TIMEOUT = 60;
12
+ declare const KODAX_HARD_TIMEOUT = 300;
13
+ declare const KODAX_MAX_RETRIES = 3;
14
+ declare const KODAX_RETRY_BASE_DELAY = 2;
15
+ declare const KODAX_MAX_INCOMPLETE_RETRIES = 2;
16
+ declare const KODAX_MAX_MAXTOKENS_RETRIES = 3;
17
+ declare const KODAX_STAGGER_DELAY = 1;
18
+ declare const KODAX_API_MIN_INTERVAL = 0.5;
19
+ declare const PROMISE_PATTERN: RegExp;
20
+
21
+ /**
22
+ * @kodax-ai/agent Tokenizer
23
+ *
24
+ * Token 估算 - 使用 tiktoken 进行精确计算
25
+ */
26
+
27
+ /**
28
+ * 估算消息的 token 数量
29
+ *
30
+ * 精确计算包括:
31
+ * - 消息结构开销(每条约 4 tokens)
32
+ * - 角色标识
33
+ * - 内容文本
34
+ * - 工具调用和结果
35
+ */
36
+ declare function estimateTokens(messages: KodaXMessage[]): number;
37
+ /**
38
+ * 计算单个文本的 token 数量(便捷函数)
39
+ */
40
+ declare function countTokens(text: string): number;
41
+
42
+ /**
43
+ * Layer A Primitive: CompactionPolicy + DefaultSummaryCompaction
44
+ *
45
+ * FEATURE_081 (v0.7.23): Pluggable compaction for generic agent loops.
46
+ *
47
+ * Two layers:
48
+ * - Layer A (here): `CompactionPolicy` interface + `DefaultSummaryCompaction`
49
+ * — a minimal "token threshold → LLM summary of old messages" policy that
50
+ * any external Agent can pick up with zero KodaX runtime dependency.
51
+ * - Layer B (`../session-lineage/index.js/src/lineage.ts`): `LineageCompaction`
52
+ * wraps the full FEATURE_072 lineage-native compaction for the coding
53
+ * preset.
54
+ *
55
+ * The `compaction` entry shape written by `DefaultSummaryCompaction` is the
56
+ * same type used by `LineageExtension`, so the two layers interoperate on
57
+ * the same Session log.
58
+ *
59
+ * History: extracted to `@kodax-ai/core` in FEATURE_082 (v0.7.24); merged back
60
+ * into `@kodax-ai/agent` in v0.7.35.1 FEATURE_142.
61
+ */
62
+
63
+ /**
64
+ * Runtime context for a compaction pass. Abstracts the LLM/tokenizer
65
+ * dependencies so policies stay independent of any specific provider.
66
+ */
67
+ interface CompactionContext {
68
+ readonly tokensUsed: number;
69
+ readonly budget: number;
70
+ /**
71
+ * Summarizer implementation. Callers inject a function that maps a list of
72
+ * messages to a short summary string. In coding-preset mode this is wired
73
+ * to `runKodaX` internally; for external consumers it can call any LLM.
74
+ */
75
+ readonly summarize: (messages: readonly AgentMessage[]) => Promise<string>;
76
+ }
77
+ /**
78
+ * Payload written to the `compaction` entry appended by `compact()`.
79
+ */
80
+ interface CompactionEntryPayload {
81
+ readonly summary: string;
82
+ readonly replacedMessageEntryIds: readonly string[];
83
+ }
84
+ /**
85
+ * Typed compaction entry. `type` is `'compaction'`; extensions (LineageExtension)
86
+ * may claim this same type.
87
+ */
88
+ interface CompactionEntry extends SessionEntry {
89
+ readonly type: 'compaction';
90
+ readonly payload: CompactionEntryPayload;
91
+ }
92
+ /**
93
+ * Outcome of a single CompactionPolicy.compact() pass. Renamed from
94
+ * `CompactionResult` to `PolicyCompactionResult` in v0.7.35.1 FEATURE_142
95
+ * because the Layer A primitive collided with @kodax-ai/agent's pre-existing
96
+ * `CompactionResult` (compaction/types.ts) used by the coding orchestration
97
+ * post-compact pipeline. The two types model different things:
98
+ * - `PolicyCompactionResult` (here): "summary + replaced entry ids", the
99
+ * payload of one CompactionPolicy step.
100
+ * - `CompactionResult` (compaction/types.ts): the rich result of the
101
+ * coding-side multi-pass compaction (artifactLedger / memorySeed /
102
+ * tokensBefore / tokensAfter / etc).
103
+ */
104
+ interface PolicyCompactionResult {
105
+ readonly summary: string;
106
+ readonly replacedMessageEntryIds: readonly string[];
107
+ }
108
+ /**
109
+ * Pluggable compaction policy. Any multi-turn Agent loop can check
110
+ * `shouldCompact()` at round boundaries and call `compact()` when it returns
111
+ * true.
112
+ */
113
+ interface CompactionPolicy {
114
+ readonly name: string;
115
+ shouldCompact(session: Session, tokensUsed: number, budget: number): boolean;
116
+ compact(session: Session, ctx: CompactionContext): Promise<PolicyCompactionResult>;
117
+ /** Optional: rehydrate compacted content when a restore hint is available. */
118
+ restore?(session: Session, hint: unknown): Promise<void>;
119
+ }
120
+ /**
121
+ * Configuration for `DefaultSummaryCompaction`.
122
+ */
123
+ interface DefaultSummaryCompactionOptions {
124
+ /**
125
+ * Fraction of `budget` at which compaction triggers. Default 0.8 (i.e.
126
+ * 80% of the token budget). Must be in (0, 1].
127
+ */
128
+ readonly thresholdRatio?: number;
129
+ /**
130
+ * Number of most-recent message entries to preserve verbatim. Default 10.
131
+ * Must be non-negative.
132
+ */
133
+ readonly keepRecent?: number;
134
+ /**
135
+ * Optional clock override (ms epoch). Useful for deterministic tests.
136
+ */
137
+ readonly now?: () => number;
138
+ /**
139
+ * Optional random-string override. Useful for deterministic tests.
140
+ */
141
+ readonly randomSuffix?: () => string;
142
+ }
143
+ /**
144
+ * Minimal "token threshold + LLM summary" compaction policy. Works on any
145
+ * Session that stores `message` entries.
146
+ *
147
+ * Behavior:
148
+ * - `shouldCompact` returns true when `tokensUsed >= budget *
149
+ * thresholdRatio`.
150
+ * - `compact` reads all `message` entries, keeps the last `keepRecent`
151
+ * untouched, summarizes the rest via `ctx.summarize`, and appends a
152
+ * single `compaction` entry to the session.
153
+ *
154
+ * Caller is responsible for invoking `shouldCompact` and for interpreting the
155
+ * appended entry when building the next turn's prompt.
156
+ */
157
+ declare class DefaultSummaryCompaction implements CompactionPolicy {
158
+ readonly name = "default-summary";
159
+ private readonly thresholdRatio;
160
+ private readonly keepRecent;
161
+ private readonly now;
162
+ private readonly randomSuffix;
163
+ constructor(opts?: DefaultSummaryCompactionOptions);
164
+ shouldCompact(_session: Session, tokensUsed: number, budget: number): boolean;
165
+ compact(session: Session, ctx: CompactionContext): Promise<PolicyCompactionResult>;
166
+ }
167
+
168
+ /**
169
+ * v0.7.35.1 FEATURE_145 — Agent config home, 3-tier resolution.
170
+ *
171
+ * Centralizes the user-config directory used to be hardcoded across
172
+ * ~30 sites in 6 packages as `path.join(os.homedir(), '.kodax', ...)`.
173
+ * That pattern had two problems:
174
+ *
175
+ * 1. **Drift**: each new caller in a future feature was a fresh
176
+ * hardcode site; nothing stopped a caller from using the wrong
177
+ * string (`'kodax'` instead of `'.kodax'`, etc.).
178
+ * 2. **Substrate consumer coupling**: when `@kodax-ai/agent` is reused
179
+ * by a downstream agent (e.g. `@kodax-ai/ops-agent`,
180
+ * `@kodax-ai/data-analysis-agent`), there was no way to redirect the
181
+ * runtime config dir — every derivative agent was forced to
182
+ * share the `~/.kodax/` namespace.
183
+ *
184
+ * The helper exposes a 3-tier priority chain:
185
+ *
186
+ * 1. **Programmatic override** via {@link setAgentConfigHome} —
187
+ * highest priority. Substrate consumers call this once at boot,
188
+ * before any subsystem reads the path.
189
+ * 2. **`KODAX_HOME` env var** — middle priority. Used by shell / CI /
190
+ * test isolation / multi-tenant shared machines. (Already honored
191
+ * historically by `@kodax-ai/llm/src/reasoning-overrides.ts`; this
192
+ * helper makes it the canonical path for all packages.)
193
+ * 3. **`~/.kodax/`** — lowest priority. Default for the standalone
194
+ * kodax CLI. With DI not set + env not set, the resolver returns
195
+ * the same byte sequence as the prior hardcoded
196
+ * `path.join(os.homedir(), '.kodax')` calls — so the migration
197
+ * from hardcoded sites to this helper is byte-equivalent for the
198
+ * existing user base.
199
+ *
200
+ * Why a process-level singleton (and not per-call DI):
201
+ * the ~30 fs callsites are buried in library helpers (construction /
202
+ * mcp catalog / oauth tokens / paste-cache etc.). Threading a
203
+ * `configHome` parameter through every helper would change ~50
204
+ * function signatures, and every caller would have to remember to
205
+ * thread it — a single forgotten thread silently falls back to
206
+ * default. Singleton matches the `process.env.NODE_ENV` pattern: a
207
+ * process really has a single config home (no legitimate use case
208
+ * for a process to interleave reads/writes against `~/.kodax/` AND
209
+ * `~/.opsagent/` simultaneously).
210
+ *
211
+ * NOT migrated:
212
+ * - `@kodax-ai/llm/src/reasoning-overrides.ts:49` keeps its inline
213
+ * `process.env.KODAX_HOME ?? path.join(os.homedir(), '.kodax')`
214
+ * fallback because moving it to this helper would create an
215
+ * `@kodax-ai/llm → @kodax-ai/agent` dependency cycle (agent already
216
+ * imports ai). The two implementations have identical observable
217
+ * behavior at the env / default tiers; the programmatic override
218
+ * tier doesn't apply to ai-layer code.
219
+ * - **Project-relative** `.kodax/` paths (e.g. `path.join(projectRoot,
220
+ * '.kodax', 'AGENTS.md')`) are NOT migrated — those name a
221
+ * different concept (per-project config) and use a different root.
222
+ * - **CWD-relative** subpath constants like `path.join('.kodax',
223
+ * 'constructed', '_audit.jsonl')` (joined with a project root by
224
+ * the caller) are likewise project-scoped and stay as-is.
225
+ */
226
+ /**
227
+ * Set the agent config home programmatically. Highest priority in
228
+ * {@link getAgentConfigHome}'s 3-tier chain.
229
+ *
230
+ * Substrate consumers (e.g. an agent built on top of `@kodax-ai/agent`)
231
+ * should call this once at process boot, before any subsystem reads
232
+ * the path. Pass `undefined` to reset (used in tests).
233
+ */
234
+ declare function setAgentConfigHome(path: string | undefined): void;
235
+ /**
236
+ * Resolve the agent runtime config home directory.
237
+ *
238
+ * Priority (high → low):
239
+ * 1. Programmatic override via {@link setAgentConfigHome}
240
+ * 2. `KODAX_HOME` env var
241
+ * 3. `~/.kodax` (hardcoded default)
242
+ */
243
+ declare function getAgentConfigHome(): string;
244
+ /**
245
+ * Resolve a sub-path under the agent config home.
246
+ *
247
+ * Equivalent to `path.join(getAgentConfigHome(), ...segments)` but
248
+ * shorter at every callsite (which is the entire point of the helper —
249
+ * 30 callsites of `path.join(os.homedir(), '.kodax', x, y)` collapse to
250
+ * 30 callsites of `getAgentConfigPath(x, y)`).
251
+ */
252
+ declare function getAgentConfigPath(...segments: string[]): string;
253
+ /**
254
+ * v0.7.42 — Namespaced data directory for third-party apps embedding the
255
+ * KodaX SDK (e.g. `KodaX Space` desktop client, IDE extensions).
256
+ *
257
+ * Returns `${getAgentConfigHome()}/apps/<appId>/` and creates the directory
258
+ * if missing. Provides a coordination point so multiple SDK consumers can
259
+ * share `~/.kodax/` without colliding on path conventions.
260
+ *
261
+ * Constraints:
262
+ * - `appId` must match `^[a-z][a-z0-9-]{1,31}$` (lowercase kebab, 2–32 chars,
263
+ * no dots, no slashes, no underscores) — keeps the directory name safe
264
+ * across all filesystems and prevents `../` traversal.
265
+ * - Reserved prefixes (`kodax`, `kodax-*`) are rejected to leave room
266
+ * for first-party feature directories that may collide later.
267
+ *
268
+ * The convention is intentionally light — no central registry, no manifest.
269
+ * Apps owning their data dir means SDK upgrades cannot trample on third-party
270
+ * state. Apps are responsible for migration/cleanup within their own subtree.
271
+ */
272
+ declare function getAppDataDir(appId: string): string;
273
+
274
+ /**
275
+ * History cleanup middleware — CAP-002
276
+ *
277
+ * Capability inventory: docs/features/v0.7.29-capability-inventory.md#cap-002
278
+ *
279
+ * Two pure functions that maintain the assistant↔user `tool_use`/`tool_result`
280
+ * pairing invariant the provider expects. Both functions take a message array
281
+ * and return a new array (immutable — never mutate the input).
282
+ *
283
+ * - `cleanupIncompleteToolCalls`: when a stream is interrupted mid-flight,
284
+ * the last assistant message may carry orphan `tool_use` blocks with no
285
+ * matching `tool_result`. The next provider call would 400 with
286
+ * "tool_call_id not found". This function strips those orphans before
287
+ * the next request.
288
+ *
289
+ * - `validateAndFixToolHistory`: deeper pass that walks the full message
290
+ * history and fixes mis-pairings on both sides — orphan `tool_use` in
291
+ * assistant messages, orphan `tool_result` in user messages, and ensures
292
+ * no message becomes empty after stripping (Kimi specifically rejects
293
+ * empty assistant messages with 400, so we inject a `'...'` placeholder
294
+ * when stripping would empty an assistant message).
295
+ *
296
+ * Migration history: extracted from `agent.ts` (originally lines 517–758)
297
+ * during FEATURE_100 P2. Both `agent.ts` and `task-engine/runner-driven.ts`
298
+ * already consume these via the package re-export (`@kodax-ai/coding`).
299
+ *
300
+ * Type guards are inlined here rather than imported from agent.ts because
301
+ * the migration's whole point is to remove dependencies on agent.ts. If
302
+ * additional agent-runtime modules need the same guards in the future,
303
+ * extract them to `agent-runtime/content-blocks.ts`.
304
+ */
305
+
306
+ /**
307
+ * Walk the message history and remove mis-paired `tool_use` / `tool_result`
308
+ * blocks. Preserves message order and structure; never mutates input.
309
+ *
310
+ * Rules enforced:
311
+ * - assistant `tool_use` with no matching `tool_result` in the next user
312
+ * message → removed
313
+ * - assistant `tool_use` with empty / missing id → removed
314
+ * - user `tool_result` with no matching assistant `tool_use` in the previous
315
+ * message → removed
316
+ * - user `tool_result` with empty / missing tool_use_id → removed
317
+ * - assistant message that becomes content-empty after stripping → inject
318
+ * a `'...'` placeholder text block (preserves message-alternation invariant
319
+ * downstream providers like Kimi require)
320
+ */
321
+ declare function validateAndFixToolHistory(messages: KodaXMessage[]): KodaXMessage[];
322
+ /**
323
+ * Strip orphan `tool_use` blocks from the LAST assistant message only.
324
+ *
325
+ * Used as a quick pre-stream guard when a previous turn was interrupted
326
+ * (Issue 072): the last assistant message has unanswered tool_use blocks,
327
+ * and the next provider request would 400 with "tool_call_id not found".
328
+ *
329
+ * Cheaper than `validateAndFixToolHistory` because it only touches the tail.
330
+ */
331
+ declare function cleanupIncompleteToolCalls(messages: KodaXMessage[]): KodaXMessage[];
332
+
333
+ /**
334
+ * LineageExtension — SessionExtension façade over lineage semantics.
335
+ *
336
+ * FEATURE_081 (v0.7.23): expresses today's `KodaXSessionLineage` operations
337
+ * (label, rewind, compaction ledger, branch summary) as a
338
+ * `SessionExtension` over the base `Session` primitive.
339
+ *
340
+ * FEATURE_082 (v0.7.24): moved from `@kodax-ai/coding/src/extensions/lineage.ts`
341
+ * to this package. Depends on `../index.js` for `Session` / `SessionEntry` /
342
+ * `SessionExtension` (Layer A primitives — extracted to `@kodax-ai/core` in
343
+ * FEATURE_082, merged back into `../index.js` in v0.7.35.1 FEATURE_142).
344
+ * `@kodax-ai/coding` keeps a barrel re-export.
345
+ *
346
+ * Scope:
347
+ * - Declare the extension object.
348
+ * - Implement `label` and `attachArtifact` operators that append standard
349
+ * entries to a Session.
350
+ * - Implement a `buildLineageTree` reducer that projects an entry stream
351
+ * back to a navigable tree.
352
+ * - NOT re-implemented here: `branch`, `rewind`, full compaction. Those
353
+ * stay in `../index.js/session-lineage.ts` for coding-preset use; the
354
+ * `LineageCompaction` policy in this package is the thin wrapper that
355
+ * adapts them to the Layer A `CompactionPolicy` contract.
356
+ */
357
+
358
+ /**
359
+ * Entry types claimed by `LineageExtension`. Mirrors the legacy
360
+ * `KodaXSessionEntry` tagged union plus a `rewind_marker` placeholder (the
361
+ * legacy lineage records rewinds via `activeEntryId` mutation; Session is
362
+ * linear, so a marker entry is the equivalent).
363
+ */
364
+ declare const LINEAGE_ENTRY_TYPES: readonly ["message", "label", "compaction", "branch_summary", "archive_marker", "rewind_marker", "artifact_ledger"];
365
+ type LineageEntryType = (typeof LINEAGE_ENTRY_TYPES)[number];
366
+ /**
367
+ * Payload shape for a `label` entry. Mirrors
368
+ * `KodaXSessionLabelEntry.targetId`/`label` fields on the legacy lineage.
369
+ */
370
+ interface LineageLabelPayload {
371
+ readonly targetId: string;
372
+ readonly label?: string;
373
+ }
374
+ /**
375
+ * Payload shape for an `artifact_ledger` entry. Mirrors a minimal subset of
376
+ * `KodaXSessionArtifactLedgerEntry`; full semantic fidelity is kept on the
377
+ * legacy side for now and normalised in FEATURE_082.
378
+ */
379
+ interface LineageArtifactLedgerPayload {
380
+ readonly ref: string;
381
+ readonly kind?: string;
382
+ readonly summary?: string;
383
+ }
384
+ /**
385
+ * Projected tree node. Mirrors the navigation shape of
386
+ * `KodaXSessionTreeNode` from `../index.js/types.ts`, restricted to the
387
+ * fields the base Session can supply.
388
+ */
389
+ interface LineageTreeNode {
390
+ readonly entry: SessionEntry;
391
+ readonly children: LineageTreeNode[];
392
+ readonly label?: string;
393
+ }
394
+ /**
395
+ * The exported extension. Operators write standard-shaped entries; the
396
+ * reducer projects an entry stream back to a navigable tree.
397
+ *
398
+ * Immutability: top-level object, `operators`, and `reducers` are all
399
+ * frozen. Freezes are shallow — the functions stored inside `operators`
400
+ * and `reducers` are immutable by nature (closures reference only
401
+ * module-private state). External code must not mutate the extension;
402
+ * doing so is a programmer error that the type-level `readonly` already
403
+ * disallows without a cast.
404
+ */
405
+ declare const LineageExtension: SessionExtension;
406
+
407
+ /**
408
+ * LineageCompaction — `CompactionPolicy` adapter for the coding preset's
409
+ * FEATURE_072 lineage-native compaction runtime.
410
+ *
411
+ * FEATURE_082 (v0.7.24): introduced alongside the lineage extraction so the
412
+ * coding preset can implement `CompactionPolicy` without re-implementing the
413
+ * compaction loop. The actual compaction runtime (microcompaction, post-
414
+ * compact reconstruction, summary generation) stays in
415
+ * `../index.js/src/compaction/` until FEATURE_084 (v0.7.26) consolidates it.
416
+ *
417
+ * Usage (inside @kodax-ai/coding):
418
+ *
419
+ * const policy = new LineageCompaction({
420
+ * shouldCompact: (session, used, budget) => runFeature072Heuristic(used, budget),
421
+ * compact: async (session, ctx) => runFeature072Compaction(session, ctx),
422
+ * });
423
+ *
424
+ * The injected delegates keep this package free of coding-specific imports,
425
+ * preserving the dependency direction
426
+ * `@kodax-ai/coding -> @kodax-ai/session-lineage -> ../index.js`.
427
+ */
428
+
429
+ /**
430
+ * Delegates required to implement `LineageCompaction`. The coding preset
431
+ * supplies implementations that bridge to the existing FEATURE_072 code
432
+ * paths.
433
+ */
434
+ interface LineageCompactionDelegates {
435
+ readonly shouldCompact: (session: Session, tokensUsed: number, budget: number) => boolean;
436
+ readonly compact: (session: Session, ctx: CompactionContext) => Promise<PolicyCompactionResult>;
437
+ readonly restore?: (session: Session, hint: unknown) => Promise<void>;
438
+ }
439
+ /**
440
+ * `CompactionPolicy` implementation that preserves FEATURE_072 lineage-native
441
+ * compaction semantics by delegating to injected coding-preset functions.
442
+ */
443
+ declare class LineageCompaction implements CompactionPolicy {
444
+ readonly name = "lineage-compaction";
445
+ private readonly delegates;
446
+ constructor(delegates: LineageCompactionDelegates);
447
+ shouldCompact(session: Session, tokensUsed: number, budget: number): boolean;
448
+ compact(session: Session, ctx: CompactionContext): Promise<PolicyCompactionResult>;
449
+ restore(session: Session, hint: unknown): Promise<void>;
450
+ }
451
+
452
+ /**
453
+ * ../index.js Session
454
+ *
455
+ * 会话管理 - Session ID 生成和消息处理
456
+ */
457
+
458
+ /**
459
+ * 生成会话 ID
460
+ * 格式: YYYYMMDD_HHMMSS
461
+ */
462
+ declare function generateSessionId(): Promise<string>;
463
+ /**
464
+ * 从消息中提取标题
465
+ * 取第一条用户消息的前50个字符
466
+ */
467
+ declare function extractTitleFromMessages(messages: KodaXMessage[]): string;
468
+
469
+ type NavigableSessionEntry = Exclude<KodaXSessionEntry, KodaXSessionLabelEntry | KodaXSessionGoalEntry>;
470
+ /**
471
+ * Reconcile a linear message list against an existing lineage tree.
472
+ *
473
+ * Existing matching entries are reused when possible, and only the missing
474
+ * tail is appended as new message entries.
475
+ */
476
+ declare function createSessionLineage(messages: KodaXMessage[], previous?: KodaXSessionLineage): KodaXSessionLineage;
477
+ /**
478
+ * Walk the lineage from a target entry back to the root.
479
+ *
480
+ * Traversal stops safely if malformed data introduces a parent cycle.
481
+ */
482
+ declare function getSessionLineagePath(lineage: KodaXSessionLineage, targetId?: string | null): NavigableSessionEntry[];
483
+ /**
484
+ * Build the effective LLM-visible message context for the active lineage path.
485
+ *
486
+ * FEATURE_072: for non-rewind compaction entries that carry
487
+ * `postCompactAttachments`, the slicer inlines attachments immediately after
488
+ * the summary. `getContextMessagesForEntry` stays 1-to-1 — attachments are a
489
+ * slicer-layer concern, which preserves the contract
490
+ * `entryMatchesContextMessage` and FEATURE_073's future firstKeptEntryId-based
491
+ * slicing both depend on.
492
+ */
493
+ declare function getSessionMessagesFromLineage(lineage: KodaXSessionLineage, targetId?: string | null): KodaXMessage[];
494
+ /**
495
+ * Resolve an entry selector using either a direct entry id or the latest label.
496
+ */
497
+ declare function resolveSessionLineageTarget(lineage: KodaXSessionLineage, selector: string): NavigableSessionEntry | undefined;
498
+ /**
499
+ * Move the active leaf to a selected target, optionally appending a
500
+ * branch-summary node that captures the abandoned path.
501
+ */
502
+ declare function setSessionLineageActiveEntry(lineage: KodaXSessionLineage, selector: string, options?: KodaXSessionNavigationOptions): KodaXSessionLineage | null;
503
+ /**
504
+ * Append a label change entry that bookmarks a lineage node.
505
+ */
506
+ declare function appendSessionLineageLabel(lineage: KodaXSessionLineage, selector: string, label?: string): KodaXSessionLineage | null;
507
+ /**
508
+ * Apply a compaction event to the lineage.
509
+ *
510
+ * FEATURE_072 signature change: `keptMessages` (the post-summary tail that
511
+ * will become lineage entries) and `postCompactAttachments` (ledger +
512
+ * file-content messages that live on the CompactionEntry itself) are now
513
+ * separate parameters. The kept tail MUST NOT include attachments — otherwise
514
+ * they would be double-stored (once as message entries in lineage, once on
515
+ * the compaction entry). Phase A keeps `postCompactAttachments` optional so
516
+ * current callers that pass `[]` (or omit it) behave identically to today.
517
+ * Phase B migrates callers to supply real attachments.
518
+ */
519
+ declare function applySessionCompaction(lineage: KodaXSessionLineage | undefined, compactedMessages: KodaXMessage[], anchor: {
520
+ summary: string;
521
+ tokensBefore?: number;
522
+ tokensAfter?: number;
523
+ artifactLedgerId?: string;
524
+ reason?: string;
525
+ details?: KodaXJsonValue | CompactionDetails;
526
+ memorySeed?: KodaXCompactMemorySeed;
527
+ }, postCompactAttachments?: readonly KodaXMessage[]): KodaXSessionLineage;
528
+ /**
529
+ * FEATURE_072 §7a: reconcile lineage after graceful-degradation trimming.
530
+ *
531
+ * Unlike `applySessionCompaction` (which creates a new island with a summary
532
+ * CompactionEntry), graceful degradation is atomic-block trimming — no LLM
533
+ * summary, no ledger re-injection. Routing it through `applySessionCompaction`
534
+ * would produce a degenerate CompactionEntry with `summary: ''` that pollutes
535
+ * the lineage view and session-tree UI.
536
+ *
537
+ * Instead, `applyLineageTruncation` reconciles the lineage against the trimmed
538
+ * flat messages via `createSessionLineage`, which will:
539
+ * - Match surviving messages to existing entries (reference or fingerprint)
540
+ * - Drop unmatched entries from the active path
541
+ * Fingerprint lookup handles the "trimmed tool_result content changed" case:
542
+ * the trimmed message gets a new entry id under the same parent chain.
543
+ *
544
+ * This is distinct from `applySessionCompaction`: no new CompactionEntry is
545
+ * appended, no summary is written, no island root is created. The lineage
546
+ * stays on the same island; only the tail shape changes.
547
+ *
548
+ * Reserved for a future caller (v0.7.20 Phase C / v0.7.25 FEATURE_073). Phase B
549
+ * defines the helper; no production caller yet.
550
+ */
551
+ declare function applyLineageTruncation(lineage: KodaXSessionLineage | undefined, trimmedMessages: KodaXMessage[]): KodaXSessionLineage;
552
+ /**
553
+ * Rewind the current session lineage to a target entry, truncating all entries after it.
554
+ * Records a rewind event in the lineage for auditability.
555
+ * Returns null if targetEntryId is not found.
556
+ *
557
+ * @param lineage - The session lineage to rewind
558
+ * @param targetEntryId - The entry ID to rewind to (inclusive)
559
+ * @returns A new lineage with entries truncated after the target, or null if target not found
560
+ */
561
+ /**
562
+ * Find the entry ID of the second-to-last user message in the lineage.
563
+ * Used by `/rewind` (no argument) to go back one conversational turn.
564
+ * Returns null if fewer than 2 user messages exist.
565
+ */
566
+ declare function findPreviousUserEntryId(lineage: KodaXSessionLineage): string | null;
567
+ declare function rewindSessionLineage(lineage: KodaXSessionLineage, targetEntryId: string): KodaXSessionLineage | null;
568
+ declare function forkSessionLineage(lineage: KodaXSessionLineage, selector?: string): KodaXSessionLineage | null;
569
+ /**
570
+ * Convert a lineage into a nested tree structure for UI presentation.
571
+ */
572
+ declare function buildSessionTree(lineage: KodaXSessionLineage): KodaXSessionTreeNode[];
573
+ /**
574
+ * Count the effective context messages on the active lineage path.
575
+ */
576
+ declare function countActiveLineageMessages(lineage: KodaXSessionLineage): number;
577
+ /**
578
+ * Archive message entries from old "islands" (disconnected subtrees).
579
+ *
580
+ * Each compaction entry has parentId: null, creating an independent island.
581
+ * The active leaf lives in one island (the "current" island). All other
582
+ * islands are considered "old" and eligible for archival.
583
+ *
584
+ * A "preserve closure" is computed first:
585
+ * - All entries in the current island (active path + recent branches)
586
+ * - Label targets and their ancestor chains
587
+ * - Non-message entries and their ancestor chains (prevents tree drift)
588
+ *
589
+ * Only entries outside the preserve closure are archived.
590
+ */
591
+ declare function archiveOldIslands(lineage: KodaXSessionLineage): {
592
+ slimmedLineage: KodaXSessionLineage;
593
+ archivedEntries: KodaXSessionEntry[];
594
+ archivedCount: number;
595
+ archiveBatchId: string;
596
+ };
597
+
598
+ /**
599
+ * ../../index.js File Tracking — artifactLedger extraction.
600
+ *
601
+ * FEATURE_185 (v0.7.42) extends the previous input-only extractor to also
602
+ * read each tool_use's matching tool_result, enriching `metadata` with parsed
603
+ * hits / matchedPaths / exitCode / tail. Pipeline:
604
+ *
605
+ * Round end (REPL: repl.ts:1279/1371)
606
+ * → extractArtifactLedger(result.messages)
607
+ * → tool_result still raw (top-of-loop microcompact hasn't run on these)
608
+ * → buildArtifactEntry parses result content into metadata
609
+ * → mergeArtifactLedger commits enrichment to context.artifactLedger
610
+ * → storage.save persists the enriched ledger
611
+ *
612
+ * Top-of-loop microcompact (run-substrate.ts:621, iteration N+1)
613
+ * → clears tool_result.content older than maxAge to `[Cleared: ...]`
614
+ *
615
+ * Compaction time (compaction.ts:257)
616
+ * → extractArtifactLedger(toProcess) re-runs on cleared messages
617
+ * → buildArtifactEntry's parsers refuse `[Cleared: ...]` → no fresh hits
618
+ * → mergeArtifactLedger preserves the round-end enrichment via
619
+ * per-key non-empty preference (see `mergeLedgerMetadata`).
620
+ *
621
+ * The metadata-aware merge is the keystone — without it, every compaction
622
+ * would silently downgrade ledger entries to input-only. End-to-end
623
+ * preservation is exercised by the "end-to-end enrichment survives
624
+ * microcompact" tests in file-tracker.test.ts.
625
+ */
626
+
627
+ declare function extractFileOps(messages: KodaXMessage[]): FileOperations;
628
+ declare function mergeFileOps(ops1: FileOperations, ops2: FileOperations): FileOperations;
629
+ declare function extractArtifactLedger(messages: KodaXMessage[]): KodaXSessionArtifactLedgerEntry[];
630
+ declare function mergeArtifactLedger(existing: KodaXSessionArtifactLedgerEntry[], next: KodaXSessionArtifactLedgerEntry[]): KodaXSessionArtifactLedgerEntry[];
631
+
632
+ export { countActiveLineageMessages as A, countTokens as B, DefaultSummaryCompaction as D, createSessionLineage as E, estimateTokens as F, extractArtifactLedger as G, extractFileOps as H, extractTitleFromMessages as I, findPreviousUserEntryId as J, KODAX_API_MIN_INTERVAL as K, LINEAGE_ENTRY_TYPES as L, forkSessionLineage as M, generateSessionId as N, getAgentConfigHome as O, PROMISE_PATTERN as P, getAgentConfigPath as Q, getAppDataDir as R, getSessionLineagePath as S, getSessionMessagesFromLineage as T, mergeArtifactLedger as U, mergeFileOps as V, resolveSessionLineageTarget as W, rewindSessionLineage as X, setAgentConfigHome as Y, setSessionLineageActiveEntry as Z, validateAndFixToolHistory as _, KODAX_DEFAULT_TIMEOUT as e, KODAX_HARD_TIMEOUT as f, KODAX_MAX_INCOMPLETE_RETRIES as g, KODAX_MAX_MAXTOKENS_RETRIES as h, KODAX_MAX_RETRIES as i, KODAX_MAX_TOKENS as j, KODAX_RETRY_BASE_DELAY as k, KODAX_STAGGER_DELAY as l, LineageCompaction as n, LineageExtension as q, appendSessionLineageLabel as u, applyLineageTruncation as v, applySessionCompaction as w, archiveOldIslands as x, buildSessionTree as y, cleanupIncompleteToolCalls as z };
633
+ export type { CompactionContext as C, CompactionEntry as a, CompactionEntryPayload as b, CompactionPolicy as c, DefaultSummaryCompactionOptions as d, LineageArtifactLedgerPayload as m, LineageCompactionDelegates as o, LineageEntryType as p, LineageLabelPayload as r, LineageTreeNode as s, PolicyCompactionResult as t };