@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
@@ -1,43 +1,173 @@
1
- import { m as KodaXMessage } from './types.d-B1uGoVTE.js';
2
- import { a as AgentMessage, V as SpanData, U as Span, W as SpanError, A as Agent, J as RunnerLlmReturn, o as Guardrail, N as RunnerToolObserver, h as CompactionDetails, n as FileOperations } from './types.d-CKJtjo-6.js';
3
- import { o as KodaXSessionLineage, f as KodaXJsonValue, a as KodaXCompactMemorySeed, l as KodaXSessionEntry, v as KodaXSessionTreeNode, n as KodaXSessionLabelEntry, r as KodaXSessionNavigationOptions, h as KodaXSessionArtifactLedgerEntry } from './types.d-mM8vqvhT.js';
1
+ import { X as KodaXToolDefinition, m as KodaXMessage, D as KodaXReasoningMode, Z as KodaXToolResultContentItem, T as KodaXThinkingBlock, G as KodaXRedactedThinkingBlock } from './types.d-B1uGoVTE.js';
2
+ import { a as KodaXCompactMemorySeed, k as KodaXSessionArtifactLedgerEntry } from './types.d-HBbWT-iA.js';
4
3
 
5
4
  /**
6
- * @kodax-ai/agent Constants
5
+ * Layer A Primitive: Agent / Handoff / Guardrail / AgentReasoningProfile
7
6
  *
8
- * 通用 Agent 常量配置
7
+ * FEATURE_080 (v0.7.23): Agent-as-data types. Declarative dataclass shape.
8
+ * The runtime counterpart is `Runner` in `./runner.ts`.
9
+ *
10
+ * History: extracted to `@kodax-ai/core` in FEATURE_082 (v0.7.24); merged back
11
+ * into `@kodax-ai/agent` in v0.7.35.1 FEATURE_142 (single-consumer rule —
12
+ * @kodax-ai/core had only @kodax-ai/coding as consumer). `@kodax-ai/coding` retains
13
+ * a barrel re-export for batteries-included consumers.
14
+ *
15
+ * Status: @experimental — API shape may be refined during v0.7.x. Used by
16
+ * the task-engine rewrite in FEATURE_084 (v0.7.26).
17
+ *
18
+ * Guardrail and AgentReasoningProfile are declared here but their runtime
19
+ * behavior is deferred:
20
+ * - Guardrail runtime → FEATURE_085 (v0.7.26)
21
+ * - AgentReasoningProfile behavior → FEATURE_078 (v0.7.29)
9
22
  */
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
23
 
21
24
  /**
22
- * @kodax-ai/agent Tokenizer
25
+ * Reasoning depth / mode selector. Alias for `KodaXReasoningMode` to keep the
26
+ * Layer A surface independent of the `KodaX*` brand; unified during the prefix
27
+ * cleanup in FEATURE_086 (v0.7.27).
28
+ */
29
+ type ReasoningDepth = KodaXReasoningMode;
30
+ /**
31
+ * Tool binding accepted by an `Agent`. Layer A treats tools as opaque
32
+ * definitions; the executor lives in `@kodax-ai/coding` and is wired up by the
33
+ * Runner when it dispatches through `runKodaX`.
34
+ */
35
+ type AgentTool = KodaXToolDefinition;
36
+ /**
37
+ * Transport-level message reused from the AI layer. Kept as an alias so
38
+ * consumers of the Layer A primitives do not need to import from `@kodax-ai/llm`
39
+ * directly.
40
+ */
41
+ type AgentMessage = KodaXMessage;
42
+ /**
43
+ * Declarative reasoning profile attached to an Agent.
23
44
  *
24
- * Token 估算 - 使用 tiktoken 进行精确计算
45
+ * In v0.7.23 this is a placeholder shape — only the `default` depth is read
46
+ * when the Runner dispatches to `runKodaX`. Escalation on revise/replan and
47
+ * max clamping are implemented in FEATURE_078 (v0.7.29).
25
48
  */
26
-
49
+ interface AgentReasoningProfile {
50
+ readonly default: ReasoningDepth;
51
+ readonly max?: ReasoningDepth;
52
+ readonly escalateOnRevise?: boolean;
53
+ }
54
+ /**
55
+ * Declarative middleware reference attached to an Agent.
56
+ *
57
+ * FEATURE_100 (v0.7.29) introduces this field so the coding preset
58
+ * can declare the four substrate middlewares (auto-reroute,
59
+ * mutation-reflection, pre-answer-judge, post-tool-judge) on the
60
+ * Agent declaration itself. Today these middlewares fire inside
61
+ * the substrate body; the declaration field serves as the
62
+ * machine-readable contract that the substrate honours, and lets
63
+ * SDK consumers introspect / override middleware policy without
64
+ * touching `runKodaX` internals.
65
+ *
66
+ * `enabled` is the only knob today; future versions add config
67
+ * payload as additional fields (kept declarative — no fn callbacks).
68
+ */
69
+ interface AgentMiddlewareDeclaration {
70
+ readonly name: string;
71
+ readonly enabled: boolean;
72
+ }
27
73
  /**
28
- * 估算消息的 token 数量
74
+ * Guardrail placeholder. Layer A declares the slot; the actual
75
+ * input/output/tool-call gating runtime lives in FEATURE_085 (v0.7.26).
29
76
  *
30
- * 精确计算包括:
31
- * - 消息结构开销(每条约 4 tokens)
32
- * - 角色标识
33
- * - 内容文本
34
- * - 工具调用和结果
77
+ * A guardrail targets one of three hook points:
78
+ * - `input`: inspect / veto prompts before they enter the agent loop.
79
+ * - `output`: inspect / rewrite assistant messages before they leave.
80
+ * - `tool`: inspect / veto tool invocations during the loop.
35
81
  */
36
- declare function estimateTokens(messages: KodaXMessage[]): number;
82
+ interface Guardrail {
83
+ readonly kind: 'input' | 'output' | 'tool';
84
+ readonly name: string;
85
+ }
37
86
  /**
38
- * 计算单个文本的 token 数量(便捷函数)
87
+ * Handoff between Agents.
88
+ *
89
+ * - `continuation`: ownership of the conversation transfers to `target` and
90
+ * the caller exits. Mirrors the Scout → Generator upgrade path.
91
+ * - `as-tool`: `target` is invoked like a tool from within the caller loop;
92
+ * only the generated input is passed, and control returns on completion.
93
+ * Mirrors FEATURE_067 `dispatch_child_task`.
94
+ *
95
+ * `inputFilter` is applied to the visible history before the target runs;
96
+ * default is no filtering.
97
+ */
98
+ interface Handoff<TTo = unknown> {
99
+ readonly target: Agent<TTo>;
100
+ readonly kind: 'continuation' | 'as-tool';
101
+ readonly description?: string;
102
+ readonly inputFilter?: (history: readonly AgentMessage[]) => readonly AgentMessage[];
103
+ }
104
+ /**
105
+ * Agent-as-data. A declarative specification of "who is running, with which
106
+ * instructions, tools, handoffs, and reasoning profile."
107
+ *
108
+ * Runtime note: in v0.7.23 the only Agent that is fully executed is the
109
+ * built-in coding preset (`createDefaultCodingAgent()`), which dispatches
110
+ * through `runKodaX`. Custom Agents defined by SDK consumers run through a
111
+ * generic Runner loop with limited capabilities (LLM call + Agent-declared
112
+ * tools only — no extensions, no managed-task harness). The full runtime
113
+ * arrives with FEATURE_084 (v0.7.26).
39
114
  */
40
- declare function countTokens(text: string): number;
115
+ interface Agent<TContext = unknown> {
116
+ readonly name: string;
117
+ readonly instructions: string | ((ctx: TContext) => string);
118
+ readonly tools?: readonly AgentTool[];
119
+ readonly handoffs?: readonly Handoff[];
120
+ readonly reasoning?: AgentReasoningProfile;
121
+ readonly guardrails?: readonly Guardrail[];
122
+ /**
123
+ * FEATURE_191 — one-sentence human-readable summary surfaced to
124
+ * other agents that may dispatch this one (e.g., via the
125
+ * `dispatch_child_task(subagent_type=<name>)` Worker SP block). The
126
+ * field propagates from `AgentContent.description` when the agent is
127
+ * built via the construction substrate; built-in / SDK-created
128
+ * agents may set it directly. Optional for backward compatibility
129
+ * with the FEATURE_089 minimal-agent shape and pre-FEATURE_191
130
+ * built-ins.
131
+ */
132
+ readonly description?: string;
133
+ /** Reserved for structured-output agents; not consumed in v0.7.23. */
134
+ readonly outputSchema?: unknown;
135
+ readonly model?: string;
136
+ readonly provider?: string;
137
+ /**
138
+ * FEATURE_100 (v0.7.29) substrate executor: when set, `Runner.run`
139
+ * delegates execution to this function instead of consulting the
140
+ * preset-dispatcher registry or running the generic LLM loop. The
141
+ * coding preset attaches `runKodaX`'s full execution pipeline here so
142
+ * the SDK surface `Runner.run(createDefaultCodingAgent(), prompt, opts)`
143
+ * directly drives substrate without a `registerPresetDispatcher`
144
+ * indirection (the v0.7.23 "Option Y" facade).
145
+ *
146
+ * Type is intentionally `unknown` to avoid a `core/agent.ts` ↔
147
+ * `core/runner.ts` module cycle. `Runner.run` casts to the
148
+ * `PresetDispatcher` shape declared in `runner.ts` at the call site.
149
+ */
150
+ readonly substrateExecutor?: unknown;
151
+ /**
152
+ * FEATURE_100 (v0.7.29) declarative middleware list. The coding
153
+ * preset declares the four substrate middlewares it ships with
154
+ * (auto-reroute, mutation-reflection, pre-answer-judge,
155
+ * post-tool-judge). Substrate consults this list on entry and
156
+ * skips the corresponding step when `enabled === false`. SDK
157
+ * consumers can introspect or override declared middleware
158
+ * without touching the substrate body.
159
+ */
160
+ readonly middleware?: readonly AgentMiddlewareDeclaration[];
161
+ }
162
+ /**
163
+ * Ergonomic factory. Equivalent to a plain object literal but freezes the
164
+ * shape so tests cannot mutate a shared Agent by accident.
165
+ */
166
+ declare function createAgent<TContext = unknown>(spec: Agent<TContext>): Agent<TContext>;
167
+ /**
168
+ * Ergonomic factory for Handoff.
169
+ */
170
+ declare function createHandoff<TTo = unknown>(spec: Handoff<TTo>): Handoff<TTo>;
41
171
 
42
172
  /**
43
173
  * Layer A Primitive: Session / SessionEntry / MessageEntry / SessionExtension
@@ -147,129 +277,200 @@ interface InMemorySessionOptions {
147
277
  declare function createInMemorySession(opts?: InMemorySessionOptions): Session;
148
278
 
149
279
  /**
150
- * Layer A Primitive: CompactionPolicy + DefaultSummaryCompaction
151
- *
152
- * FEATURE_081 (v0.7.23): Pluggable compaction for generic agent loops.
153
- *
154
- * Two layers:
155
- * - Layer A (here): `CompactionPolicy` interface + `DefaultSummaryCompaction`
156
- * a minimal "token threshold LLM summary of old messages" policy that
157
- * any external Agent can pick up with zero KodaX runtime dependency.
158
- * - Layer B (`../session-lineage/index.js/src/lineage.ts`): `LineageCompaction`
159
- * wraps the full FEATURE_072 lineage-native compaction for the coding
160
- * preset.
161
- *
162
- * The `compaction` entry shape written by `DefaultSummaryCompaction` is the
163
- * same type used by `LineageExtension`, so the two layers interoperate on
164
- * the same Session log.
165
- *
166
- * History: extracted to `@kodax-ai/core` in FEATURE_082 (v0.7.24); merged back
167
- * into `@kodax-ai/agent` in v0.7.35.1 FEATURE_142.
168
- */
169
-
170
- /**
171
- * Runtime context for a compaction pass. Abstracts the LLM/tokenizer
172
- * dependencies so policies stay independent of any specific provider.
173
- */
174
- interface CompactionContext {
280
+ * SpanData variants payload shapes carried by each `Span`.
281
+ *
282
+ * FEATURE_083 (v0.7.24): the Agent-era tracing model uses a discriminated
283
+ * union so consumers (OpenTelemetry adapter, Langfuse adapter, KodaX
284
+ * built-in file processor) can render each span kind with type safety.
285
+ *
286
+ * Variants mirror the semantic events KodaX emits today:
287
+ * - AgentSpanData : one `Runner.run(agent, ...)` round
288
+ * - GenerationSpanData: one provider LLM call
289
+ * - ToolCallSpanData : one tool invocation (including MCP tool)
290
+ * - HandoffSpanData : continuation or as-tool handoff between agents
291
+ * - CompactionSpanData: one compaction pass (token-threshold or lineage)
292
+ * - GuardrailSpanData : one guardrail check at input/output/tool
293
+ * - EvidenceSpanData : repo-intelligence / evidence acquisition
294
+ * - FanoutSpanData : parallel fanout bracket (winner-cancel capable)
295
+ *
296
+ * API surface is `@experimental` until v0.8.0 shape may be refined as
297
+ * FEATURE_084 (v0.7.26) starts emitting these.
298
+ */
299
+ interface AgentSpanData {
300
+ readonly kind: 'agent';
301
+ readonly agentName: string;
302
+ readonly model?: string;
303
+ readonly provider?: string;
304
+ readonly tools?: readonly string[];
305
+ readonly handoffs?: readonly string[];
306
+ readonly outputMessages?: number;
307
+ readonly error?: string;
308
+ }
309
+ interface GenerationSpanData {
310
+ readonly kind: 'generation';
311
+ readonly agentName: string;
312
+ readonly provider: string;
313
+ readonly model: string;
314
+ readonly inputMessages?: number;
315
+ readonly outputTokens?: number;
316
+ readonly inputTokens?: number;
317
+ readonly reasoningTokens?: number;
318
+ readonly cachedTokens?: number;
319
+ readonly usage?: {
320
+ readonly inputTokens?: number;
321
+ readonly outputTokens?: number;
322
+ readonly totalTokens?: number;
323
+ readonly reasoningTokens?: number;
324
+ readonly cachedTokens?: number;
325
+ readonly costUsd?: number;
326
+ };
327
+ readonly finishReason?: string;
328
+ readonly error?: string;
329
+ }
330
+ interface ToolCallSpanData {
331
+ readonly kind: 'tool_call';
332
+ readonly toolName: string;
333
+ readonly providerId?: string;
334
+ readonly capabilityId?: string;
335
+ readonly inputPreview?: string;
336
+ readonly outputPreview?: string;
337
+ readonly status: 'ok' | 'error';
338
+ readonly error?: string;
339
+ }
340
+ interface HandoffSpanData {
341
+ readonly kind: 'handoff';
342
+ readonly fromAgent: string;
343
+ readonly toAgent: string;
344
+ readonly handoffKind: 'continuation' | 'as-tool';
345
+ readonly description?: string;
346
+ }
347
+ interface CompactionSpanData {
348
+ readonly kind: 'compaction';
349
+ readonly policyName: string;
175
350
  readonly tokensUsed: number;
176
351
  readonly budget: number;
177
- /**
178
- * Summarizer implementation. Callers inject a function that maps a list of
179
- * messages to a short summary string. In coding-preset mode this is wired
180
- * to `runKodaX` internally; for external consumers it can call any LLM.
181
- */
182
- readonly summarize: (messages: readonly AgentMessage[]) => Promise<string>;
352
+ readonly replacedMessageCount: number;
353
+ readonly summaryLength: number;
354
+ readonly error?: string;
355
+ }
356
+ interface GuardrailSpanData {
357
+ readonly kind: 'guardrail';
358
+ readonly guardrailName: string;
359
+ readonly hookPoint: 'input' | 'output' | 'tool';
360
+ readonly decision: 'pass' | 'veto' | 'rewrite' | 'error';
361
+ readonly reason?: string;
362
+ readonly error?: string;
363
+ }
364
+ interface EvidenceSpanData {
365
+ readonly kind: 'evidence';
366
+ readonly source: string;
367
+ readonly queryPreview?: string;
368
+ readonly resultCount?: number;
369
+ readonly cacheHit?: boolean;
370
+ readonly error?: string;
371
+ }
372
+ interface FanoutSpanData {
373
+ readonly kind: 'fanout';
374
+ readonly agentName: string;
375
+ readonly childCount: number;
376
+ readonly winnerChildId?: string;
377
+ readonly cancelledChildIds?: readonly string[];
183
378
  }
184
379
  /**
185
- * Payload written to the `compaction` entry appended by `compact()`.
380
+ * FEATURE_184 (v0.7.45) Stop hook observability.
381
+ *
382
+ * Emitted when the Runner's `RunOptions.stopHook` is invoked or fails.
383
+ * `outcome` records what the hook returned (or `'error'` for thrown
384
+ * exceptions — fail-open path), `reanimateCount` is the running count
385
+ * after this invocation. `reason` carries the abort/reanimate text
386
+ * when relevant, truncated by consumers as needed.
186
387
  */
187
- interface CompactionEntryPayload {
188
- readonly summary: string;
189
- readonly replacedMessageEntryIds: readonly string[];
388
+ interface StopHookSpanData {
389
+ readonly kind: 'stop-hook';
390
+ readonly outcome: 'accept' | 'reanimate' | 'abort' | 'budget-exhausted' | 'error';
391
+ readonly reanimateCount: number;
392
+ readonly reanimateBudget: number;
393
+ readonly reason?: string;
394
+ readonly error?: string;
190
395
  }
191
396
  /**
192
- * Typed compaction entry. `type` is `'compaction'`; extensions (LineageExtension)
193
- * may claim this same type.
397
+ * Discriminated union of all span payload shapes. Additional variants may
398
+ * be added in future features — consumers should check `kind` before
399
+ * reading specific fields.
194
400
  */
195
- interface CompactionEntry extends SessionEntry {
196
- readonly type: 'compaction';
197
- readonly payload: CompactionEntryPayload;
198
- }
401
+ type SpanData = AgentSpanData | GenerationSpanData | ToolCallSpanData | HandoffSpanData | CompactionSpanData | GuardrailSpanData | EvidenceSpanData | FanoutSpanData | StopHookSpanData;
402
+
199
403
  /**
200
- * Outcome of a single CompactionPolicy.compact() pass. Renamed from
201
- * `CompactionResult` to `PolicyCompactionResult` in v0.7.35.1 FEATURE_142
202
- * because the Layer A primitive collided with @kodax-ai/agent's pre-existing
203
- * `CompactionResult` (compaction/types.ts) used by the coding orchestration
204
- * post-compact pipeline. The two types model different things:
205
- * - `PolicyCompactionResult` (here): "summary + replaced entry ids", the
206
- * payload of one CompactionPolicy step.
207
- * - `CompactionResult` (compaction/types.ts): the rich result of the
208
- * coding-side multi-pass compaction (artifactLedger / memorySeed /
209
- * tokensBefore / tokensAfter / etc).
404
+ * Span a single timed unit of work inside a Trace.
405
+ *
406
+ * FEATURE_083 (v0.7.24): minimal Span implementation modeled after the
407
+ * openai-agents-python Trace/Span pattern.
408
+ *
409
+ * Design constraints:
410
+ * - Span creation must be cheap (no await, no serialisation). Processors
411
+ * do their own batching / flushing.
412
+ * - `addChild()` is synchronous and immediately visible in the Trace tree.
413
+ * - `end()` is idempotent; calling it twice is a no-op.
414
+ * - `error` is an optional field that sets a flag on the span without
415
+ * throwing. The consumer decides how to surface errors.
210
416
  */
211
- interface PolicyCompactionResult {
212
- readonly summary: string;
213
- readonly replacedMessageEntryIds: readonly string[];
417
+
418
+ interface SpanError {
419
+ readonly message: string;
420
+ readonly stack?: string;
421
+ readonly data?: unknown;
214
422
  }
215
423
  /**
216
- * Pluggable compaction policy. Any multi-turn Agent loop can check
217
- * `shouldCompact()` at round boundaries and call `compact()` when it returns
218
- * true.
424
+ * Public Span interface. Concrete implementation is `SpanImpl`.
219
425
  */
220
- interface CompactionPolicy {
426
+ interface Span {
427
+ readonly id: string;
428
+ readonly traceId: string;
429
+ readonly parentId?: string;
221
430
  readonly name: string;
222
- shouldCompact(session: Session, tokensUsed: number, budget: number): boolean;
223
- compact(session: Session, ctx: CompactionContext): Promise<PolicyCompactionResult>;
224
- /** Optional: rehydrate compacted content when a restore hint is available. */
225
- restore?(session: Session, hint: unknown): Promise<void>;
431
+ readonly data: SpanData;
432
+ readonly startedAt: number;
433
+ readonly endedAt?: number;
434
+ readonly error?: SpanError;
435
+ readonly children: readonly Span[];
436
+ addChild(name: string, data: SpanData): Span;
437
+ setError(err: SpanError | Error): void;
438
+ end(): void;
226
439
  }
227
- /**
228
- * Configuration for `DefaultSummaryCompaction`.
229
- */
230
- interface DefaultSummaryCompactionOptions {
231
- /**
232
- * Fraction of `budget` at which compaction triggers. Default 0.8 (i.e.
233
- * 80% of the token budget). Must be in (0, 1].
234
- */
235
- readonly thresholdRatio?: number;
236
- /**
237
- * Number of most-recent message entries to preserve verbatim. Default 10.
238
- * Must be non-negative.
239
- */
240
- readonly keepRecent?: number;
241
- /**
242
- * Optional clock override (ms epoch). Useful for deterministic tests.
243
- */
440
+ interface SpanImplOptions {
441
+ readonly id: string;
442
+ readonly traceId: string;
443
+ readonly parentId?: string;
444
+ readonly name: string;
445
+ readonly data: SpanData;
446
+ readonly startedAt?: number;
244
447
  readonly now?: () => number;
245
- /**
246
- * Optional random-string override. Useful for deterministic tests.
247
- */
248
- readonly randomSuffix?: () => string;
448
+ readonly nextSpanId?: () => string;
449
+ readonly onChildCreated?: (span: Span) => void;
450
+ readonly onSpanEnd?: (span: Span) => void;
249
451
  }
250
- /**
251
- * Minimal "token threshold + LLM summary" compaction policy. Works on any
252
- * Session that stores `message` entries.
253
- *
254
- * Behavior:
255
- * - `shouldCompact` returns true when `tokensUsed >= budget *
256
- * thresholdRatio`.
257
- * - `compact` reads all `message` entries, keeps the last `keepRecent`
258
- * untouched, summarizes the rest via `ctx.summarize`, and appends a
259
- * single `compaction` entry to the session.
260
- *
261
- * Caller is responsible for invoking `shouldCompact` and for interpreting the
262
- * appended entry when building the next turn's prompt.
263
- */
264
- declare class DefaultSummaryCompaction implements CompactionPolicy {
265
- readonly name = "default-summary";
266
- private readonly thresholdRatio;
267
- private readonly keepRecent;
452
+ declare class SpanImpl implements Span {
453
+ readonly id: string;
454
+ readonly traceId: string;
455
+ readonly parentId?: string;
456
+ readonly name: string;
457
+ readonly data: SpanData;
458
+ readonly startedAt: number;
459
+ private _endedAt?;
460
+ private _error?;
461
+ private readonly _children;
268
462
  private readonly now;
269
- private readonly randomSuffix;
270
- constructor(opts?: DefaultSummaryCompactionOptions);
271
- shouldCompact(_session: Session, tokensUsed: number, budget: number): boolean;
272
- compact(session: Session, ctx: CompactionContext): Promise<PolicyCompactionResult>;
463
+ private readonly nextSpanId;
464
+ private readonly onChildCreated?;
465
+ private readonly onSpanEnd?;
466
+ private _ended;
467
+ constructor(opts: SpanImplOptions);
468
+ get endedAt(): number | undefined;
469
+ get error(): SpanError | undefined;
470
+ get children(): readonly Span[];
471
+ addChild(name: string, data: SpanData): Span;
472
+ setError(err: SpanError | Error): void;
473
+ end(): void;
273
474
  }
274
475
 
275
476
  /**
@@ -894,6 +1095,155 @@ declare class InvariantSession {
894
1095
  */
895
1096
  declare function createInvariantSessionForAgent(agent: Agent): InvariantSession | undefined;
896
1097
 
1098
+ /**
1099
+ * Runner Tool Loop — FEATURE_084 Shard 1 (v0.7.26).
1100
+ *
1101
+ * Extends the Layer A Runner generic-dispatch path with tool-call support.
1102
+ * Before Shard 1 the Runner could only do a single `system+user → assistant`
1103
+ * turn. Now the injected LLM callback may return a structured result that
1104
+ * declares tool calls; the Runner executes them, appends tool_use +
1105
+ * tool_result content blocks, and loops until the LLM stops emitting tool
1106
+ * calls (or MAX_TOOL_LOOP_ITERATIONS is reached).
1107
+ *
1108
+ * This Shard only lands the capability. No built-in Agent consumes it yet —
1109
+ * the coding preset (SA path) continues to dispatch through
1110
+ * `registerPresetDispatcher` unchanged.
1111
+ *
1112
+ * @experimental Shape may be refined during the v0.7.26 shard rollout.
1113
+ */
1114
+
1115
+ /**
1116
+ * Hard ceiling on tool-loop iterations. A single run may invoke at most this
1117
+ * many LLM turns (counting the initial turn); if the model keeps returning
1118
+ * tool calls past this limit we abort to prevent runaway behaviour.
1119
+ */
1120
+ declare const MAX_TOOL_LOOP_ITERATIONS = 20;
1121
+ /**
1122
+ * One tool invocation requested by the LLM.
1123
+ */
1124
+ interface RunnerToolCall {
1125
+ readonly id: string;
1126
+ readonly name: string;
1127
+ readonly input: Record<string, unknown>;
1128
+ }
1129
+ /**
1130
+ * Structured LLM result. Returning this instead of a plain string lets the
1131
+ * Runner drive a tool loop. If `toolCalls` is empty or omitted the loop
1132
+ * terminates and `text` becomes the final output.
1133
+ */
1134
+ interface RunnerLlmResult {
1135
+ readonly text: string;
1136
+ readonly toolCalls?: readonly RunnerToolCall[];
1137
+ readonly stopReason?: string;
1138
+ /**
1139
+ * v0.7.26 parity: extended-thinking blocks from the provider stream.
1140
+ * Must be preserved on the assistant message so (a) session resume can
1141
+ * re-render them and (b) Anthropic's extended-thinking API contract is
1142
+ * honoured — provider rejects the next turn with a 400 when a tool_use
1143
+ * turn's `thinking` block is missing from prior assistant history.
1144
+ */
1145
+ readonly thinkingBlocks?: readonly (KodaXThinkingBlock | KodaXRedactedThinkingBlock)[];
1146
+ }
1147
+ /**
1148
+ * LLM callback return type. `string` preserves the v0.7.23 single-turn
1149
+ * behaviour; `RunnerLlmResult` opts into the tool loop.
1150
+ */
1151
+ type RunnerLlmReturn = string | RunnerLlmResult;
1152
+ /**
1153
+ * Observer callbacks fired around every tool invocation. Preset
1154
+ * dispatchers (e.g. the coding Runner-driven path) pass these through
1155
+ * `RunOptions.toolObserver` so REPL / CLI consumers see live
1156
+ * `onToolCall` / `onToolResult` events, matching the legacy task-engine
1157
+ * event surface (v0.7.22 agent.ts fired `events.onToolResult` at three
1158
+ * sites per invocation).
1159
+ */
1160
+ interface RunnerToolObserver {
1161
+ /**
1162
+ * Permission / policy gate fired BEFORE each tool invocation. Return
1163
+ * `true` (or `undefined`) to allow, `false` to block with a generic
1164
+ * message, or a `string` to block with that message as the tool result.
1165
+ * Used to hook plan-mode / accept-edits / extension `tool:before`
1166
+ * policies onto the Runner-driven path (v0.7.22 parity — legacy
1167
+ * `events.beforeToolExecute` surface).
1168
+ */
1169
+ readonly beforeTool?: (call: RunnerToolCall) => Promise<boolean | string | undefined>;
1170
+ readonly onToolCall?: (call: RunnerToolCall) => void;
1171
+ readonly onToolResult?: (call: RunnerToolCall, result: RunnerToolResult) => void;
1172
+ }
1173
+ /**
1174
+ * Context passed to a RunnableTool's `execute` function.
1175
+ */
1176
+ interface RunnerToolContext {
1177
+ readonly agent: Agent;
1178
+ readonly abortSignal?: AbortSignal;
1179
+ /** The agent's Span, so tool implementations can nest custom spans if needed. */
1180
+ readonly agentSpan?: Span | null;
1181
+ /**
1182
+ * Current tool_use call id. Passed through so tool wrappers can correlate
1183
+ * progress events (`onToolProgress`) and other per-call side-effects with
1184
+ * the REPL's tool-block in the transcript. Populated by `executeRunnerToolCall`.
1185
+ */
1186
+ readonly toolCallId?: string;
1187
+ }
1188
+ /**
1189
+ * Value returned by `RunnableTool.execute`. The `content` is what the LLM
1190
+ * sees in the next turn as `tool_result`:
1191
+ *
1192
+ * - `string` — plain text (the default for most tools).
1193
+ * - `readonly KodaXToolResultContentItem[]` — an array of typed items
1194
+ * (text + image), used by multimodal tools like `read` on an image
1195
+ * path. Provider serializers lower each item to the wire format
1196
+ * (Anthropic accepts inline; OpenAI-compat downgrades image to text
1197
+ * placeholder).
1198
+ */
1199
+ interface RunnerToolResult {
1200
+ readonly content: string | readonly KodaXToolResultContentItem[];
1201
+ readonly isError?: boolean;
1202
+ readonly metadata?: Record<string, unknown>;
1203
+ }
1204
+ /**
1205
+ * A tool bundled with its executor. Extends `AgentTool` (the wire-format
1206
+ * `KodaXToolDefinition`) so it can be passed through to the provider
1207
+ * unchanged while also carrying a function the Runner can invoke.
1208
+ */
1209
+ interface RunnableTool extends AgentTool {
1210
+ readonly execute: (input: Record<string, unknown>, ctx: RunnerToolContext) => Promise<RunnerToolResult>;
1211
+ }
1212
+ /**
1213
+ * Narrowing helper — distinguishes a `RunnableTool` from a plain
1214
+ * `AgentTool`. An agent may declare both: the Runner only executes the
1215
+ * tools that carry an `execute` function.
1216
+ */
1217
+ declare function isRunnableTool(tool: AgentTool): tool is RunnableTool;
1218
+ /**
1219
+ * Narrowing helper for the LLM callback return shape.
1220
+ */
1221
+ declare function isRunnerLlmResult(value: unknown): value is RunnerLlmResult;
1222
+ /**
1223
+ * Execute one tool call against the agent's declared tools. Emits a
1224
+ * ToolCallSpan under `ctx.agentSpan` when tracing is active. Returns a
1225
+ * `RunnerToolResult` — tool errors do not throw, they are surfaced with
1226
+ * `isError: true` so the LLM can see them in the next turn and react.
1227
+ */
1228
+ declare function executeRunnerToolCall(call: RunnerToolCall, agent: Agent, ctx: RunnerToolContext): Promise<RunnerToolResult>;
1229
+ /**
1230
+ * Build the assistant message that captures one LLM turn. Preserves
1231
+ * thinking blocks (extended-thinking contract), text blocks, and tool_use
1232
+ * blocks in the order Anthropic's wire format expects: thinking → text →
1233
+ * tool_use. This mirrors v0.7.22 `agent.ts:2230`
1234
+ * (`[...thinkingBlocks, ...textBlocks, ...visibleToolBlocks]`) which the
1235
+ * Runner-driven path must preserve — without it Anthropic returns 400 on
1236
+ * the next turn when extended thinking is active, and session resume
1237
+ * loses the reasoning trace.
1238
+ */
1239
+ declare function buildAssistantMessageFromLlmResult(result: RunnerLlmResult): AgentMessage;
1240
+ /**
1241
+ * Build the user message that carries tool_result blocks back to the LLM.
1242
+ * Provider serializers (Anthropic, OpenAI) both accept tool_result on the
1243
+ * user turn.
1244
+ */
1245
+ declare function buildToolResultMessage(calls: readonly RunnerToolCall[], results: readonly RunnerToolResult[]): AgentMessage;
1246
+
897
1247
  /**
898
1248
  * Layer A Primitive: Runner
899
1249
  *
@@ -1316,468 +1666,612 @@ declare class Runner {
1316
1666
  declare function extractAssistantTextFromMessage(message: AgentMessage): string;
1317
1667
 
1318
1668
  /**
1319
- * v0.7.35.1 FEATURE_145Agent config home, 3-tier resolution.
1320
- *
1321
- * Centralizes the user-config directory used to be hardcoded across
1322
- * ~30 sites in 6 packages as `path.join(os.homedir(), '.kodax', ...)`.
1323
- * That pattern had two problems:
1324
- *
1325
- * 1. **Drift**: each new caller in a future feature was a fresh
1326
- * hardcode site; nothing stopped a caller from using the wrong
1327
- * string (`'kodax'` instead of `'.kodax'`, etc.).
1328
- * 2. **Substrate consumer coupling**: when `@kodax-ai/agent` is reused
1329
- * by a downstream agent (e.g. `@kodax-ai/ops-agent`,
1330
- * `@kodax-ai/data-analysis-agent`), there was no way to redirect the
1331
- * runtime config dir — every derivative agent was forced to
1332
- * share the `~/.kodax/` namespace.
1333
- *
1334
- * The helper exposes a 3-tier priority chain:
1335
- *
1336
- * 1. **Programmatic override** via {@link setAgentConfigHome} —
1337
- * highest priority. Substrate consumers call this once at boot,
1338
- * before any subsystem reads the path.
1339
- * 2. **`KODAX_HOME` env var** — middle priority. Used by shell / CI /
1340
- * test isolation / multi-tenant shared machines. (Already honored
1341
- * historically by `@kodax-ai/llm/src/reasoning-overrides.ts`; this
1342
- * helper makes it the canonical path for all packages.)
1343
- * 3. **`~/.kodax/`** — lowest priority. Default for the standalone
1344
- * kodax CLI. With DI not set + env not set, the resolver returns
1345
- * the same byte sequence as the prior hardcoded
1346
- * `path.join(os.homedir(), '.kodax')` calls — so the migration
1347
- * from hardcoded sites to this helper is byte-equivalent for the
1348
- * existing user base.
1349
- *
1350
- * Why a process-level singleton (and not per-call DI):
1351
- * the ~30 fs callsites are buried in library helpers (construction /
1352
- * mcp catalog / oauth tokens / paste-cache etc.). Threading a
1353
- * `configHome` parameter through every helper would change ~50
1354
- * function signatures, and every caller would have to remember to
1355
- * thread it — a single forgotten thread silently falls back to
1356
- * default. Singleton matches the `process.env.NODE_ENV` pattern: a
1357
- * process really has a single config home (no legitimate use case
1358
- * for a process to interleave reads/writes against `~/.kodax/` AND
1359
- * `~/.opsagent/` simultaneously).
1360
- *
1361
- * NOT migrated:
1362
- * - `@kodax-ai/llm/src/reasoning-overrides.ts:49` keeps its inline
1363
- * `process.env.KODAX_HOME ?? path.join(os.homedir(), '.kodax')`
1364
- * fallback because moving it to this helper would create an
1365
- * `@kodax-ai/llm → @kodax-ai/agent` dependency cycle (agent already
1366
- * imports ai). The two implementations have identical observable
1367
- * behavior at the env / default tiers; the programmatic override
1368
- * tier doesn't apply to ai-layer code.
1369
- * - **Project-relative** `.kodax/` paths (e.g. `path.join(projectRoot,
1370
- * '.kodax', 'AGENTS.md')`) are NOT migrated — those name a
1371
- * different concept (per-project config) and use a different root.
1372
- * - **CWD-relative** subpath constants like `path.join('.kodax',
1373
- * 'constructed', '_audit.jsonl')` (joined with a project root by
1374
- * the caller) are likewise project-scoped and stay as-is.
1375
- */
1376
- /**
1377
- * Set the agent config home programmatically. Highest priority in
1378
- * {@link getAgentConfigHome}'s 3-tier chain.
1379
- *
1380
- * Substrate consumers (e.g. an agent built on top of `@kodax-ai/agent`)
1381
- * should call this once at process boot, before any subsystem reads
1382
- * the path. Pass `undefined` to reset (used in tests).
1383
- */
1384
- declare function setAgentConfigHome(path: string | undefined): void;
1385
- /**
1386
- * Resolve the agent runtime config home directory.
1387
- *
1388
- * Priority (high → low):
1389
- * 1. Programmatic override via {@link setAgentConfigHome}
1390
- * 2. `KODAX_HOME` env var
1391
- * 3. `~/.kodax` (hardcoded default)
1392
- */
1393
- declare function getAgentConfigHome(): string;
1394
- /**
1395
- * Resolve a sub-path under the agent config home.
1396
- *
1397
- * Equivalent to `path.join(getAgentConfigHome(), ...segments)` but
1398
- * shorter at every callsite (which is the entire point of the helper —
1399
- * 30 callsites of `path.join(os.homedir(), '.kodax', x, y)` collapse to
1400
- * 30 callsites of `getAgentConfigPath(x, y)`).
1401
- */
1402
- declare function getAgentConfigPath(...segments: string[]): string;
1403
- /**
1404
- * v0.7.42 — Namespaced data directory for third-party apps embedding the
1405
- * KodaX SDK (e.g. `KodaX Space` desktop client, IDE extensions).
1406
- *
1407
- * Returns `${getAgentConfigHome()}/apps/<appId>/` and creates the directory
1408
- * if missing. Provides a coordination point so multiple SDK consumers can
1409
- * share `~/.kodax/` without colliding on path conventions.
1410
- *
1411
- * Constraints:
1412
- * - `appId` must match `^[a-z][a-z0-9-]{1,31}$` (lowercase kebab, 2–32 chars,
1413
- * no dots, no slashes, no underscores) — keeps the directory name safe
1414
- * across all filesystems and prevents `../` traversal.
1415
- * - Reserved prefixes (`kodax`, `kodax-*`) are rejected to leave room
1416
- * for first-party feature directories that may collide later.
1417
- *
1418
- * The convention is intentionally light — no central registry, no manifest.
1419
- * Apps owning their data dir means SDK upgrades cannot trample on third-party
1420
- * state. Apps are responsible for migration/cleanup within their own subtree.
1421
- */
1422
- declare function getAppDataDir(appId: string): string;
1423
-
1424
- /**
1425
- * History cleanup middleware — CAP-002
1669
+ * Guardrail RuntimeFEATURE_085 (v0.7.26).
1426
1670
  *
1427
- * Capability inventory: docs/features/v0.7.29-capability-inventory.md#cap-002
1671
+ * Three-tier runtime for Agent guardrails:
1428
1672
  *
1429
- * Two pure functions that maintain the assistant↔user `tool_use`/`tool_result`
1430
- * pairing invariant the provider expects. Both functions take a message array
1431
- * and return a new array (immutable — never mutate the input).
1673
+ * - `InputGuardrail`: runs once before the first LLM turn, inspects the
1674
+ * full input transcript, may allow / rewrite / block / escalate.
1675
+ * - `OutputGuardrail`: runs once before returning, inspects the final
1676
+ * assistant message, may allow / rewrite / block / escalate.
1677
+ * - `ToolGuardrail`: runs before and/or after each tool invocation,
1678
+ * inspects the call / result, may allow / rewrite / block / escalate.
1432
1679
  *
1433
- * - `cleanupIncompleteToolCalls`: when a stream is interrupted mid-flight,
1434
- * the last assistant message may carry orphan `tool_use` blocks with no
1435
- * matching `tool_result`. The next provider call would 400 with
1436
- * "tool_call_id not found". This function strips those orphans before
1437
- * the next request.
1680
+ * The four verdict actions:
1438
1681
  *
1439
- * - `validateAndFixToolHistory`: deeper pass that walks the full message
1440
- * history and fixes mis-pairings on both sides — orphan `tool_use` in
1441
- * assistant messages, orphan `tool_result` in user messages, and ensures
1442
- * no message becomes empty after stripping (Kimi specifically rejects
1443
- * empty assistant messages with 400, so we inject a `'...'` placeholder
1444
- * when stripping would empty an assistant message).
1682
+ * - `allow`: continue with the current value.
1683
+ * - `rewrite`: replace the current value with `payload`.
1684
+ * - `block`: throw `GuardrailBlockedError` (for input/output) or surface
1685
+ * an error tool_result (for tool-before); the LLM / caller sees a
1686
+ * rejection and must adapt.
1687
+ * - `escalate`: throw `GuardrailEscalateError`; the SDK consumer catches
1688
+ * and decides whether to prompt the user, retry under different
1689
+ * constraints, etc.
1445
1690
  *
1446
- * Migration history: extracted from `agent.ts` (originally lines 517–758)
1447
- * during FEATURE_100 P2. Both `agent.ts` and `task-engine/runner-driven.ts`
1448
- * already consume these via the package re-export (`@kodax-ai/coding`).
1691
+ * Every guardrail invocation emits a `GuardrailSpan` under the agent's
1692
+ * span when tracing is active.
1449
1693
  *
1450
- * Type guards are inlined here rather than imported from agent.ts because
1451
- * the migration's whole point is to remove dependencies on agent.ts. If
1452
- * additional agent-runtime modules need the same guards in the future,
1453
- * extract them to `agent-runtime/content-blocks.ts`.
1694
+ * @experimental API shape may adjust during v0.7.x rollout.
1454
1695
  */
1455
1696
 
1456
1697
  /**
1457
- * Walk the message history and remove mis-paired `tool_use` / `tool_result`
1458
- * blocks. Preserves message order and structure; never mutates input.
1698
+ * Shared execution context passed to every guardrail.
1459
1699
  *
1460
- * Rules enforced:
1461
- * - assistant `tool_use` with no matching `tool_result` in the next user
1462
- * message removed
1463
- * - assistant `tool_use` with empty / missing id removed
1464
- * - user `tool_result` with no matching assistant `tool_use` in the previous
1465
- * message removed
1466
- * - user `tool_result` with empty / missing tool_use_id → removed
1467
- * - assistant message that becomes content-empty after stripping → inject
1468
- * a `'...'` placeholder text block (preserves message-alternation invariant
1469
- * downstream providers like Kimi require)
1470
- */
1471
- declare function validateAndFixToolHistory(messages: KodaXMessage[]): KodaXMessage[];
1472
- /**
1473
- * Strip orphan `tool_use` blocks from the LAST assistant message only.
1700
+ * `messages` is the live conversation transcript at the moment this
1701
+ * guardrail fires. For tool-side guardrails this is the transcript at
1702
+ * call-site time — it does NOT yet include the assistant turn that
1703
+ * emitted the current tool_use, since that turn is appended only after
1704
+ * the full tool batch settles. Optional so existing guardrails that
1705
+ * don't read context still type-check; populated by the Runner for all
1706
+ * production hook points.
1474
1707
  *
1475
- * Used as a quick pre-stream guard when a previous turn was interrupted
1476
- * (Issue 072): the last assistant message has unanswered tool_use blocks,
1477
- * and the next provider request would 400 with "tool_call_id not found".
1478
- *
1479
- * Cheaper than `validateAndFixToolHistory` because it only touches the tail.
1708
+ * Added in FEATURE_092 (v0.7.33) so the auto-mode classifier guardrail
1709
+ * can extract intent context (user prompt + prior tool_use / tool_result
1710
+ * blocks) without reaching into Runner internals.
1480
1711
  */
1481
- declare function cleanupIncompleteToolCalls(messages: KodaXMessage[]): KodaXMessage[];
1482
-
1712
+ interface GuardrailContext {
1713
+ readonly agent: Agent;
1714
+ readonly abortSignal?: AbortSignal;
1715
+ readonly messages?: readonly AgentMessage[];
1716
+ }
1483
1717
  /**
1484
- * LineageExtension SessionExtension façade over lineage semantics.
1485
- *
1486
- * FEATURE_081 (v0.7.23): expresses today's `KodaXSessionLineage` operations
1487
- * (label, rewind, compaction ledger, branch summary) as a
1488
- * `SessionExtension` over the base `Session` primitive.
1489
- *
1490
- * FEATURE_082 (v0.7.24): moved from `@kodax-ai/coding/src/extensions/lineage.ts`
1491
- * to this package. Depends on `../index.js` for `Session` / `SessionEntry` /
1492
- * `SessionExtension` (Layer A primitives — extracted to `@kodax-ai/core` in
1493
- * FEATURE_082, merged back into `../index.js` in v0.7.35.1 FEATURE_142).
1494
- * `@kodax-ai/coding` keeps a barrel re-export.
1495
- *
1496
- * Scope:
1497
- * - Declare the extension object.
1498
- * - Implement `label` and `attachArtifact` operators that append standard
1499
- * entries to a Session.
1500
- * - Implement a `buildLineageTree` reducer that projects an entry stream
1501
- * back to a navigable tree.
1502
- * - NOT re-implemented here: `branch`, `rewind`, full compaction. Those
1503
- * stay in `../index.js/session-lineage.ts` for coding-preset use; the
1504
- * `LineageCompaction` policy in this package is the thin wrapper that
1505
- * adapts them to the Layer A `CompactionPolicy` contract.
1718
+ * Outcome of a single guardrail check. `payload` shape depends on the hook
1719
+ * point — see the specific guardrail interface for the expected type.
1506
1720
  */
1507
-
1721
+ type GuardrailVerdict = {
1722
+ readonly action: 'allow';
1723
+ } | {
1724
+ readonly action: 'rewrite';
1725
+ readonly payload: unknown;
1726
+ readonly reason?: string;
1727
+ } | {
1728
+ readonly action: 'block';
1729
+ readonly reason: string;
1730
+ } | {
1731
+ readonly action: 'escalate';
1732
+ readonly reason: string;
1733
+ };
1508
1734
  /**
1509
- * Entry types claimed by `LineageExtension`. Mirrors the legacy
1510
- * `KodaXSessionEntry` tagged union plus a `rewind_marker` placeholder (the
1511
- * legacy lineage records rewinds via `activeEntryId` mutation; Session is
1512
- * linear, so a marker entry is the equivalent).
1735
+ * Input-side guardrail. Expected `rewrite` payload shape:
1736
+ * `readonly AgentMessage[]` the replacement transcript.
1513
1737
  */
1514
- declare const LINEAGE_ENTRY_TYPES: readonly ["message", "label", "compaction", "branch_summary", "archive_marker", "rewind_marker", "artifact_ledger"];
1515
- type LineageEntryType = (typeof LINEAGE_ENTRY_TYPES)[number];
1738
+ interface InputGuardrail extends Guardrail {
1739
+ readonly kind: 'input';
1740
+ check(input: readonly AgentMessage[], ctx: GuardrailContext): Promise<GuardrailVerdict>;
1741
+ }
1516
1742
  /**
1517
- * Payload shape for a `label` entry. Mirrors
1518
- * `KodaXSessionLabelEntry.targetId`/`label` fields on the legacy lineage.
1743
+ * Output-side guardrail. Expected `rewrite` payload shape:
1744
+ * `AgentMessage` the replacement final assistant message.
1519
1745
  */
1520
- interface LineageLabelPayload {
1521
- readonly targetId: string;
1522
- readonly label?: string;
1746
+ interface OutputGuardrail extends Guardrail {
1747
+ readonly kind: 'output';
1748
+ check(output: AgentMessage, ctx: GuardrailContext): Promise<GuardrailVerdict>;
1523
1749
  }
1524
1750
  /**
1525
- * Payload shape for an `artifact_ledger` entry. Mirrors a minimal subset of
1526
- * `KodaXSessionArtifactLedgerEntry`; full semantic fidelity is kept on the
1527
- * legacy side for now and normalised in FEATURE_082.
1751
+ * Tool-side guardrail. `beforeTool` rewrite payload shape: `RunnerToolCall`
1752
+ * (replacement call). `afterTool` rewrite payload shape: `RunnerToolResult`
1753
+ * (replacement result). Either hook is optional.
1528
1754
  */
1529
- interface LineageArtifactLedgerPayload {
1530
- readonly ref: string;
1531
- readonly kind?: string;
1532
- readonly summary?: string;
1755
+ interface ToolGuardrail extends Guardrail {
1756
+ readonly kind: 'tool';
1757
+ beforeTool?(call: RunnerToolCall, ctx: GuardrailContext): Promise<GuardrailVerdict>;
1758
+ afterTool?(call: RunnerToolCall, result: RunnerToolResult, ctx: GuardrailContext): Promise<GuardrailVerdict>;
1533
1759
  }
1534
1760
  /**
1535
- * Projected tree node. Mirrors the navigation shape of
1536
- * `KodaXSessionTreeNode` from `../index.js/types.ts`, restricted to the
1537
- * fields the base Session can supply.
1761
+ * Thrown when any guardrail returns `{ action: 'block' }`. The Runner
1762
+ * propagates this up to the caller — the run is aborted at that point.
1538
1763
  */
1539
- interface LineageTreeNode {
1540
- readonly entry: SessionEntry;
1541
- readonly children: LineageTreeNode[];
1542
- readonly label?: string;
1764
+ declare class GuardrailBlockedError extends Error {
1765
+ readonly guardrailName: string;
1766
+ readonly hookPoint: 'input' | 'output' | 'tool';
1767
+ constructor(guardrailName: string, hookPoint: 'input' | 'output' | 'tool', reason: string);
1543
1768
  }
1544
1769
  /**
1545
- * The exported extension. Operators write standard-shaped entries; the
1546
- * reducer projects an entry stream back to a navigable tree.
1547
- *
1548
- * Immutability: top-level object, `operators`, and `reducers` are all
1549
- * frozen. Freezes are shallow — the functions stored inside `operators`
1550
- * and `reducers` are immutable by nature (closures reference only
1551
- * module-private state). External code must not mutate the extension;
1552
- * doing so is a programmer error that the type-level `readonly` already
1553
- * disallows without a cast.
1770
+ * Thrown when any guardrail returns `{ action: 'escalate' }`. Callers can
1771
+ * catch and prompt the user or apply a stricter policy before retrying.
1554
1772
  */
1555
- declare const LineageExtension: SessionExtension;
1556
-
1773
+ declare class GuardrailEscalateError extends Error {
1774
+ readonly guardrailName: string;
1775
+ readonly hookPoint: 'input' | 'output' | 'tool';
1776
+ constructor(guardrailName: string, hookPoint: 'input' | 'output' | 'tool', reason: string);
1777
+ }
1778
+ /** Filter a guardrail list by hook-point. */
1779
+ declare function collectGuardrails(guardrails: readonly Guardrail[] | undefined): {
1780
+ input: readonly InputGuardrail[];
1781
+ output: readonly OutputGuardrail[];
1782
+ tool: readonly ToolGuardrail[];
1783
+ };
1557
1784
  /**
1558
- * LineageCompaction `CompactionPolicy` adapter for the coding preset's
1559
- * FEATURE_072 lineage-native compaction runtime.
1560
- *
1561
- * FEATURE_082 (v0.7.24): introduced alongside the lineage extraction so the
1562
- * coding preset can implement `CompactionPolicy` without re-implementing the
1563
- * compaction loop. The actual compaction runtime (microcompaction, post-
1564
- * compact reconstruction, summary generation) stays in
1565
- * `../index.js/src/compaction/` until FEATURE_084 (v0.7.26) consolidates it.
1566
- *
1567
- * Usage (inside @kodax-ai/coding):
1568
- *
1569
- * const policy = new LineageCompaction({
1570
- * shouldCompact: (session, used, budget) => runFeature072Heuristic(used, budget),
1571
- * compact: async (session, ctx) => runFeature072Compaction(session, ctx),
1572
- * });
1573
- *
1574
- * The injected delegates keep this package free of coding-specific imports,
1575
- * preserving the dependency direction
1576
- * `@kodax-ai/coding -> @kodax-ai/session-lineage -> ../index.js`.
1785
+ * Run all input guardrails in declaration order. Returns the (possibly
1786
+ * rewritten) transcript. Throws on block / escalate.
1577
1787
  */
1578
-
1788
+ declare function runInputGuardrails(transcript: readonly AgentMessage[], guardrails: readonly InputGuardrail[], ctx: GuardrailContext, agentSpan: Span | null): Promise<readonly AgentMessage[]>;
1579
1789
  /**
1580
- * Delegates required to implement `LineageCompaction`. The coding preset
1581
- * supplies implementations that bridge to the existing FEATURE_072 code
1582
- * paths.
1790
+ * Run all output guardrails in declaration order. Returns the (possibly
1791
+ * rewritten) final assistant message. Throws on block / escalate.
1583
1792
  */
1584
- interface LineageCompactionDelegates {
1585
- readonly shouldCompact: (session: Session, tokensUsed: number, budget: number) => boolean;
1586
- readonly compact: (session: Session, ctx: CompactionContext) => Promise<PolicyCompactionResult>;
1587
- readonly restore?: (session: Session, hint: unknown) => Promise<void>;
1588
- }
1793
+ declare function runOutputGuardrails(output: AgentMessage, guardrails: readonly OutputGuardrail[], ctx: GuardrailContext, agentSpan: Span | null): Promise<AgentMessage>;
1589
1794
  /**
1590
- * `CompactionPolicy` implementation that preserves FEATURE_072 lineage-native
1591
- * compaction semantics by delegating to injected coding-preset functions.
1795
+ * Outcome of the before-tool guardrail stage.
1796
+ * - `{ kind: 'allow', call }`: continue to executeRunnerToolCall with `call`
1797
+ * - `{ kind: 'block', result }`: skip execution; return `result` as the
1798
+ * tool_result to the LLM (so it sees the rejection and can adapt)
1592
1799
  */
1593
- declare class LineageCompaction implements CompactionPolicy {
1594
- readonly name = "lineage-compaction";
1595
- private readonly delegates;
1596
- constructor(delegates: LineageCompactionDelegates);
1597
- shouldCompact(session: Session, tokensUsed: number, budget: number): boolean;
1598
- compact(session: Session, ctx: CompactionContext): Promise<PolicyCompactionResult>;
1599
- restore(session: Session, hint: unknown): Promise<void>;
1600
- }
1601
-
1800
+ type ToolBeforeOutcome = {
1801
+ readonly kind: 'allow';
1802
+ readonly call: RunnerToolCall;
1803
+ } | {
1804
+ readonly kind: 'block';
1805
+ readonly result: RunnerToolResult;
1806
+ };
1602
1807
  /**
1603
- * ../index.js Session
1604
- *
1605
- * 会话管理 - Session ID 生成和消息处理
1808
+ * Run before-tool guardrails in declaration order. Rewrite replaces the
1809
+ * tool call. Block surfaces an error tool_result to the LLM instead of
1810
+ * throwing the LLM sees the rejection and adapts. Escalate still throws.
1606
1811
  */
1607
-
1812
+ declare function runToolBeforeGuardrails(call: RunnerToolCall, guardrails: readonly ToolGuardrail[], ctx: GuardrailContext, agentSpan: Span | null): Promise<ToolBeforeOutcome>;
1608
1813
  /**
1609
- * 生成会话 ID
1610
- * 格式: YYYYMMDD_HHMMSS
1814
+ * Run after-tool guardrails in declaration order. Rewrite replaces the
1815
+ * result content. Block replaces with an error result. Escalate throws.
1611
1816
  */
1612
- declare function generateSessionId(): Promise<string>;
1817
+ declare function runToolAfterGuardrails(call: RunnerToolCall, result: RunnerToolResult, guardrails: readonly ToolGuardrail[], ctx: GuardrailContext, agentSpan: Span | null): Promise<RunnerToolResult>;
1818
+
1613
1819
  /**
1614
- * 从消息中提取标题
1615
- * 取第一条用户消息的前50个字符
1616
- */
1617
- declare function extractTitleFromMessages(messages: KodaXMessage[]): string;
1820
+ * Child task registry primitive — generic fan-out tracking.
1821
+ *
1822
+ * FEATURE_120 v0.7.39 Step 0 (package-attribution migration, ADR-021).
1823
+ * Lifted from `@kodax-ai/coding`'s `KodaXToolExecutionContext.childTaskRegistry`
1824
+ * field + inline cleanup chain in `tools/dispatch-child-tasks.ts`. The
1825
+ * coding side now consumes this primitive specialized to its
1826
+ * `KodaXChildExecutionResult` type; any other agent-flavor downstream
1827
+ * can specialize on its own child-result type without re-implementing
1828
+ * the cleanup contract.
1829
+ *
1830
+ * The shape is intentionally minimal: a Map plus a `register` helper
1831
+ * that bundles the v0.7.38 FEATURE_155 Bug A hotfix (`c1bdaf4e`)
1832
+ * cleanup chain into a single call site. The helper exists because
1833
+ * the cleanup is **not optional** — without it, every settled promise
1834
+ * stays in the registry forever, gets re-wrapped by the next
1835
+ * idle-yield `waitForWakeEvent` call, and fires spurious
1836
+ * `child-completed` wakes (production symptom: Evaluator gets
1837
+ * bombarded by duplicate `<task-completed>` notifications, consuming
1838
+ * an LLM turn each up to `IDLE_YIELD_MAX_ITERATIONS=64`).
1839
+ */
1840
+ /**
1841
+ * Map of `task_id` → in-flight child-execution promise. Generic over
1842
+ * the child-result type so the agent layer doesn't depend on any
1843
+ * specific agent flavor's result shape.
1844
+ *
1845
+ * Mutation contract:
1846
+ * - Owned by the runner's per-turn execution context. The dispatch
1847
+ * tool writes via `registerChildTask`; the idle-yield outer loop
1848
+ * reads via `Map.prototype.entries()` / `.size`.
1849
+ * - **Never delete entries manually** — call `registerChildTask`
1850
+ * and the cleanup chain it installs will run on settle.
1851
+ */
1852
+ type ChildTaskRegistry<T> = Map<string, Promise<T>>;
1853
+ /**
1854
+ * Register an in-flight child-execution promise in the registry and
1855
+ * install the cleanup chain that removes the entry once the promise
1856
+ * settles (success or failure).
1857
+ *
1858
+ * The cleanup chain is two stages:
1859
+ * 1. `.finally(() => registry.delete(childId))` — runs on settle
1860
+ * regardless of outcome, removing the entry before the next
1861
+ * idle-yield outer-loop iteration observes the registry.
1862
+ * 2. `.catch(() => {})` — swallows the rejection on the cleanup
1863
+ * chain so a child that crashes before any consumer awaits it
1864
+ * doesn't surface as `unhandledRejection` on Node. Must come
1865
+ * AFTER `.finally` because `.finally` returns a NEW promise
1866
+ * that rejects with the same reason.
1867
+ *
1868
+ * The original `promise` argument is **not** returned — the helper's
1869
+ * value-add is the cleanup side-effect, not promise transformation.
1870
+ * Callers that need to await the result read from `registry.get(id)`
1871
+ * or hold their own reference.
1872
+ *
1873
+ * @throws Error when `childId` already exists in the registry. Caller
1874
+ * should report this to the LLM as a tool-error (duplicate task_id);
1875
+ * the helper does NOT swallow the conflict because that would
1876
+ * silently overwrite an in-flight child's tracking entry.
1877
+ */
1878
+ declare function registerChildTask<T>(registry: ChildTaskRegistry<T>, childId: string, promise: Promise<T>): void;
1618
1879
 
1619
- type NavigableSessionEntry = Exclude<KodaXSessionEntry, KodaXSessionLabelEntry>;
1620
1880
  /**
1621
- * Reconcile a linear message list against an existing lineage tree.
1622
- *
1623
- * Existing matching entries are reused when possible, and only the missing
1624
- * tail is appended as new message entries.
1625
- */
1626
- declare function createSessionLineage(messages: KodaXMessage[], previous?: KodaXSessionLineage): KodaXSessionLineage;
1881
+ * Generic per-task abort primitive `requestTaskStop`.
1882
+ *
1883
+ * FEATURE_120 v0.7.39 Phase 3a (ADR-021). Coordinator-style agents need
1884
+ * to request that a specific in-flight child task exit gracefully. The
1885
+ * @kodax-ai/agent layer owns the abort-controller registry shape and
1886
+ * the abort-dispatch decision; agent-flavor wrappers (e.g. the coding
1887
+ * `task_stop` tool, Phase 3b) layer in domain framing such as the
1888
+ * `<coordinator-stop-request>` message tag.
1889
+ *
1890
+ * What this primitive owns:
1891
+ * - A `TaskAbortRegistry` type alias = `Map<string, AbortController>`.
1892
+ * The map is owned + mutated by the caller; the primitive only
1893
+ * reads it. Callers use `registry.set(id, controller)` /
1894
+ * `registry.delete(id)` directly — the standard `Map` mutators
1895
+ * are simple enough that wrapping them adds no value.
1896
+ * - `requestTaskStop({taskId, registry, reason?})` — looks up the
1897
+ * controller, decides whether to abort, calls `controller.abort`,
1898
+ * returns a structured outcome.
1899
+ *
1900
+ * Abort semantics (matches the existing FEATURE_115 soft-pause
1901
+ * principle): aborting fires the signal but does NOT interrupt any
1902
+ * synchronous tool that's already executing. The child's next abort
1903
+ * check (`signal.throwIfAborted()` or an `signal.aborted` poll)
1904
+ * surfaces the abort. This matches Node's AbortController contract.
1905
+ *
1906
+ * What this primitive does NOT do (deliberate):
1907
+ * - Enqueue a coordinator-stop-request message — that's a
1908
+ * coding-flavor convenience and uses the existing
1909
+ * `routeMessage` primitive at the tool layer.
1910
+ * - Track abort lifecycle / auto-cleanup the registry — the
1911
+ * controller's lifetime is tied to its owning task's Promise;
1912
+ * the caller removes the registry entry when the task settles
1913
+ * (typically in a `.finally` chain alongside the child-task
1914
+ * registry cleanup).
1915
+ * - Time-out enforcement / retry — orthogonal concerns owned at
1916
+ * higher layers if needed.
1917
+ */
1918
+ /**
1919
+ * Registry mapping task ids to their owning AbortController.
1920
+ * Lifetime: created per parent-run, populated at child dispatch,
1921
+ * cleared when the child Promise settles.
1922
+ */
1923
+ type TaskAbortRegistry = Map<string, AbortController>;
1924
+ interface RequestTaskStopOptions {
1925
+ /** Target task id. Must exist as a key in `registry`. */
1926
+ readonly taskId: string;
1927
+ /** Registry of in-flight task abort controllers. */
1928
+ readonly registry: ReadonlyMap<string, AbortController>;
1929
+ /**
1930
+ * Optional cause forwarded to `AbortController.abort(reason)`.
1931
+ * - Error → passed through verbatim (preserves stack / custom
1932
+ * subclasses).
1933
+ * - string → wrapped in `new Error(reason)`.
1934
+ * - undefined → a default Error mentioning the taskId is
1935
+ * fabricated so the child receives a non-empty signal.reason.
1936
+ */
1937
+ readonly reason?: string | Error;
1938
+ }
1939
+ type RequestTaskStopResult = {
1940
+ readonly ok: true;
1941
+ readonly taskId: string;
1942
+ } | {
1943
+ readonly ok: false;
1944
+ readonly reason: 'unknown-target';
1945
+ readonly taskId: string;
1946
+ } | {
1947
+ readonly ok: false;
1948
+ readonly reason: 'already-aborted';
1949
+ readonly taskId: string;
1950
+ };
1627
1951
  /**
1628
- * Walk the lineage from a target entry back to the root.
1952
+ * Look up `taskId` in `registry`. If found and not yet aborted, abort
1953
+ * the controller with the supplied reason. Returns a discriminated
1954
+ * outcome so callers can render success / error UX without string
1955
+ * matching.
1629
1956
  *
1630
- * Traversal stops safely if malformed data introduces a parent cycle.
1631
- */
1632
- declare function getSessionLineagePath(lineage: KodaXSessionLineage, targetId?: string | null): NavigableSessionEntry[];
1633
- /**
1634
- * Build the effective LLM-visible message context for the active lineage path.
1957
+ * `already-aborted` is reported separately from success because the
1958
+ * first-abort `signal.reason` is preserved verbatim — debugging
1959
+ * chains depend on the original cause not being overwritten by
1960
+ * subsequent stop requests.
1635
1961
  *
1636
- * FEATURE_072: for non-rewind compaction entries that carry
1637
- * `postCompactAttachments`, the slicer inlines attachments immediately after
1638
- * the summary. `getContextMessagesForEntry` stays 1-to-1 — attachments are a
1639
- * slicer-layer concern, which preserves the contract
1640
- * `entryMatchesContextMessage` and FEATURE_073's future firstKeptEntryId-based
1641
- * slicing both depend on.
1962
+ * Synchronous: `AbortController.abort` is synchronous; no async work
1963
+ * is performed by this primitive.
1642
1964
  */
1643
- declare function getSessionMessagesFromLineage(lineage: KodaXSessionLineage, targetId?: string | null): KodaXMessage[];
1644
- /**
1645
- * Resolve an entry selector using either a direct entry id or the latest label.
1646
- */
1647
- declare function resolveSessionLineageTarget(lineage: KodaXSessionLineage, selector: string): NavigableSessionEntry | undefined;
1648
- /**
1649
- * Move the active leaf to a selected target, optionally appending a
1650
- * branch-summary node that captures the abandoned path.
1651
- */
1652
- declare function setSessionLineageActiveEntry(lineage: KodaXSessionLineage, selector: string, options?: KodaXSessionNavigationOptions): KodaXSessionLineage | null;
1653
- /**
1654
- * Append a label change entry that bookmarks a lineage node.
1655
- */
1656
- declare function appendSessionLineageLabel(lineage: KodaXSessionLineage, selector: string, label?: string): KodaXSessionLineage | null;
1965
+ declare function requestTaskStop(opts: RequestTaskStopOptions): RequestTaskStopResult;
1966
+
1657
1967
  /**
1658
- * Apply a compaction event to the lineage.
1659
- *
1660
- * FEATURE_072 signature change: `keptMessages` (the post-summary tail that
1661
- * will become lineage entries) and `postCompactAttachments` (ledger +
1662
- * file-content messages that live on the CompactionEntry itself) are now
1663
- * separate parameters. The kept tail MUST NOT include attachments — otherwise
1664
- * they would be double-stored (once as message entries in lineage, once on
1665
- * the compaction entry). Phase A keeps `postCompactAttachments` optional so
1666
- * current callers that pass `[]` (or omit it) behave identically to today.
1667
- * Phase B migrates callers to supply real attachments.
1668
- */
1669
- declare function applySessionCompaction(lineage: KodaXSessionLineage | undefined, compactedMessages: KodaXMessage[], anchor: {
1670
- summary: string;
1671
- tokensBefore?: number;
1672
- tokensAfter?: number;
1673
- artifactLedgerId?: string;
1674
- reason?: string;
1675
- details?: KodaXJsonValue | CompactionDetails;
1676
- memorySeed?: KodaXCompactMemorySeed;
1677
- }, postCompactAttachments?: readonly KodaXMessage[]): KodaXSessionLineage;
1968
+ * FEATURE_125 (v0.7.41) Team Mode Layer 1: per-instance state broadcast.
1969
+ *
1970
+ * Each running KodaX session registers a directory under
1971
+ * `<agentConfigHome>/instances/<pid>/` containing three files:
1972
+ *
1973
+ * meta.json — written once at registration; cwd / startedAt /
1974
+ * optional git branch + remote. Static for the session.
1975
+ * state.json — re-written whenever the session's `currentIntent`,
1976
+ * `agentPhase`, or active/recently-modified file set
1977
+ * changes. Read by sibling sessions for context.
1978
+ * heartbeat — empty file whose mtime is touched on every refresh.
1979
+ * Sibling sessions use the mtime to declare an instance
1980
+ * stale (default 30s of no heartbeat → cleanup).
1981
+ *
1982
+ * Atomic write strategy:
1983
+ * - state.json is written via `<path>.tmp` + `rename()`. On POSIX the
1984
+ * rename is atomic; on Windows it is atomic when source + target sit
1985
+ * on the same filesystem (always true for `<agentConfigHome>/...`).
1986
+ * - heartbeat is touched via `utimesSync()`. Cheap, no rename needed.
1987
+ *
1988
+ * Lifecycle:
1989
+ * - `createStateWriter` writes meta.json + state.json + heartbeat once,
1990
+ * then starts an interval timer (default 1000ms) that refreshes
1991
+ * state.json and touches heartbeat.
1992
+ * - `update(patch)` shallow-merges the patch into the in-memory state
1993
+ * and flushes immediately so peer sessions see the change at the
1994
+ * next tool boundary, not at the next heartbeat tick.
1995
+ * - `shutdown()` clears the timer, removes the instance directory,
1996
+ * and resolves. Idempotent — safe to call multiple times.
1997
+ *
1998
+ * Crash recovery:
1999
+ * - If a process is killed mid-run, the directory is left on disk.
2000
+ * The next session's discovery scan (S2, `instance-discovery.ts`)
2001
+ * detects the stale heartbeat and removes the directory.
2002
+ *
2003
+ * DI-clean: every fs / clock dependency is injectable for hermetic tests.
2004
+ */
2005
+ /**
2006
+ * Live session state surfaced to sibling KodaX sessions. Mirrors the
2007
+ * shape documented in `docs/features/v0.7.41.md#feature_125-step-1`.
2008
+ */
2009
+ interface SessionStateSnapshot {
2010
+ readonly agentPhase: 'idle' | 'awaiting_llm' | 'running_tool';
2011
+ /** Single-line description of what the agent is currently doing. */
2012
+ readonly currentIntent?: string;
2013
+ /** Files the session is actively editing right now. */
2014
+ readonly activeFiles?: readonly string[];
2015
+ /** Files modified in the recent past (sibling sessions read this to detect "their content may be stale"). */
2016
+ readonly recentlyModifiedFiles?: readonly RecentlyModifiedFile[];
2017
+ /**
2018
+ * FEATURE_170 (v0.7.41) — optional one-line summary of the active
2019
+ * todo list. Lets sibling sessions display "they're currently
2020
+ * working on: <X>" without owning the todo store.
2021
+ */
2022
+ readonly currentTodoSummary?: CurrentTodoSummary;
2023
+ /**
2024
+ * v0.7.43 (FEATURE_173 Part B follow-up) — REPL session id
2025
+ * (e.g. `YYYYMMDD_HHMMSS`). Lets `listRunningSessions()` correlate
2026
+ * a sibling instance with its `.jsonl` file. Mutable: starts
2027
+ * undefined during bootstrap, set after `createInteractiveContext`,
2028
+ * re-published on `/new`. Older writers omit this; readers MUST
2029
+ * treat as optional.
2030
+ */
2031
+ readonly sessionId?: string;
2032
+ }
2033
+ interface RecentlyModifiedFile {
2034
+ readonly path: string;
2035
+ readonly modifiedAt: number;
2036
+ }
2037
+ interface CurrentTodoSummary {
2038
+ readonly inProgress?: string;
2039
+ readonly pendingCount: number;
2040
+ readonly completedCount: number;
2041
+ }
2042
+ interface SessionMeta {
2043
+ readonly cwd: string;
2044
+ readonly startedAt: number;
2045
+ readonly gitBranch?: string;
2046
+ readonly gitRemote?: string;
2047
+ }
1678
2048
  /**
1679
- * FEATURE_072 §7a: reconcile lineage after graceful-degradation trimming.
1680
- *
1681
- * Unlike `applySessionCompaction` (which creates a new island with a summary
1682
- * CompactionEntry), graceful degradation is atomic-block trimming — no LLM
1683
- * summary, no ledger re-injection. Routing it through `applySessionCompaction`
1684
- * would produce a degenerate CompactionEntry with `summary: ''` that pollutes
1685
- * the lineage view and session-tree UI.
1686
- *
1687
- * Instead, `applyLineageTruncation` reconciles the lineage against the trimmed
1688
- * flat messages via `createSessionLineage`, which will:
1689
- * - Match surviving messages to existing entries (reference or fingerprint)
1690
- * - Drop unmatched entries from the active path
1691
- * Fingerprint lookup handles the "trimmed tool_result content changed" case:
1692
- * the trimmed message gets a new entry id under the same parent chain.
1693
- *
1694
- * This is distinct from `applySessionCompaction`: no new CompactionEntry is
1695
- * appended, no summary is written, no island root is created. The lineage
1696
- * stays on the same island; only the tail shape changes.
2049
+ * Stored shape of `state.json` on disk — additive over SessionStateSnapshot.
1697
2050
  *
1698
- * Reserved for a future caller (v0.7.20 Phase C / v0.7.25 FEATURE_073). Phase B
1699
- * defines the helper; no production caller yet.
1700
- */
1701
- declare function applyLineageTruncation(lineage: KodaXSessionLineage | undefined, trimmedMessages: KodaXMessage[]): KodaXSessionLineage;
1702
- /**
1703
- * Rewind the current session lineage to a target entry, truncating all entries after it.
1704
- * Records a rewind event in the lineage for auditability.
1705
- * Returns null if targetEntryId is not found.
2051
+ * Reader contract (S2 `instance-discovery.ts`): parse the JSON, verify
2052
+ * `version === '1'` before reading any other field. On an unknown
2053
+ * version, log + skip the instance — this lets a newer writer coexist
2054
+ * with an older reader during an in-place upgrade.
1706
2055
  *
1707
- * @param lineage - The session lineage to rewind
1708
- * @param targetEntryId - The entry ID to rewind to (inclusive)
1709
- * @returns A new lineage with entries truncated after the target, or null if target not found
2056
+ * Fields are camelCase + a nested `meta` object (cwd / startedAt /
2057
+ * gitBranch / gitRemote). Do NOT assume the snake_case / flat shape
2058
+ * shown in early design-doc drafts the typed interface here is the
2059
+ * ground truth; the doc has been updated to match.
1710
2060
  */
2061
+ interface PersistedSessionState extends SessionStateSnapshot {
2062
+ readonly version: '1';
2063
+ readonly pid: number;
2064
+ readonly updatedAt: number;
2065
+ readonly meta: SessionMeta;
2066
+ }
2067
+ /** Minimal injectable fs surface — lets tests drive the writer without disk I/O. */
2068
+ interface StateWriterFs {
2069
+ mkdirSync(dirPath: string, options: {
2070
+ recursive: true;
2071
+ }): void;
2072
+ writeFileSync(filePath: string, data: string): void;
2073
+ /** Atomic write helper: writes to `${filePath}.tmp` then renames. */
2074
+ atomicWriteSync(filePath: string, data: string): void;
2075
+ utimesSync(filePath: string, atime: number, mtime: number): void;
2076
+ rmSync(dirPath: string, options: {
2077
+ recursive: true;
2078
+ force: true;
2079
+ }): void;
2080
+ existsSync(targetPath: string): boolean;
2081
+ }
2082
+ interface StateWriterOptions {
2083
+ /** Defaults to `process.pid`. Tests / multi-instance fixtures override. */
2084
+ readonly pid?: number;
2085
+ readonly meta: SessionMeta;
2086
+ readonly initialState: SessionStateSnapshot;
2087
+ /** Defaults to 1000ms. Tests pass a faster tick. */
2088
+ readonly heartbeatIntervalMs?: number;
2089
+ /** Defaults to `Date.now`. Tests inject a controllable clock. */
2090
+ readonly clock?: () => number;
2091
+ /** Defaults to {@link REAL_FS}. Tests inject an in-memory fs. */
2092
+ readonly fs?: StateWriterFs;
2093
+ /**
2094
+ * Root directory under which `<pid>/` is created. Defaults to
2095
+ * `getAgentConfigPath('instances')`. Tests can point at a temp dir.
2096
+ */
2097
+ readonly instancesRoot?: string;
2098
+ }
2099
+ interface StateWriter {
2100
+ readonly pid: number;
2101
+ readonly instanceDir: string;
2102
+ /** Apply a partial update to the in-memory state and flush to disk. */
2103
+ update(patch: Partial<SessionStateSnapshot>): void;
2104
+ /** Touch the heartbeat and re-write state.json without changing state. */
2105
+ refresh(): void;
2106
+ /** Stop the interval, remove the instance directory, resolve when done. */
2107
+ shutdown(): Promise<void>;
2108
+ /** Read-only snapshot of the current state. Useful for tests. */
2109
+ getState(): SessionStateSnapshot;
2110
+ }
1711
2111
  /**
1712
- * Find the entry ID of the second-to-last user message in the lineage.
1713
- * Used by `/rewind` (no argument) to go back one conversational turn.
1714
- * Returns null if fewer than 2 user messages exist.
1715
- */
1716
- declare function findPreviousUserEntryId(lineage: KodaXSessionLineage): string | null;
1717
- declare function rewindSessionLineage(lineage: KodaXSessionLineage, targetEntryId: string): KodaXSessionLineage | null;
1718
- declare function forkSessionLineage(lineage: KodaXSessionLineage, selector?: string): KodaXSessionLineage | null;
1719
- /**
1720
- * Convert a lineage into a nested tree structure for UI presentation.
1721
- */
1722
- declare function buildSessionTree(lineage: KodaXSessionLineage): KodaXSessionTreeNode[];
1723
- /**
1724
- * Count the effective context messages on the active lineage path.
2112
+ * Construct a writer, register the instance directory, and start the
2113
+ * heartbeat interval. Returns synchronously so the caller can rely on
2114
+ * `instanceDir` being live the moment the function returns.
1725
2115
  */
1726
- declare function countActiveLineageMessages(lineage: KodaXSessionLineage): number;
2116
+ declare function createStateWriter(options: StateWriterOptions): StateWriter;
2117
+
1727
2118
  /**
1728
- * Archive message entries from old "islands" (disconnected subtrees).
2119
+ * FEATURE_125 (v0.7.41) Team Mode Layer 2a: sibling instance discovery.
1729
2120
  *
1730
- * Each compaction entry has parentId: null, creating an independent island.
1731
- * The active leaf lives in one island (the "current" island). All other
1732
- * islands are considered "old" and eligible for archival.
2121
+ * Scans `<agentConfigHome>/instances/`, filters out the caller's own
2122
+ * pid, drops any directory whose `heartbeat` file is stale (>30s of no
2123
+ * touch), parses `state.json`, validates `version === '1'`, and returns
2124
+ * a typed list of live sibling instances. Stale directories are
2125
+ * optionally reaped (`reapStale: true`) — the next session entering
2126
+ * Team Mode does the cleanup so crashed processes don't accumulate
2127
+ * forever.
1733
2128
  *
1734
- * A "preserve closure" is computed first:
1735
- * - All entries in the current island (active path + recent branches)
1736
- * - Label targets and their ancestor chains
1737
- * - Non-message entries and their ancestor chains (prevents tree drift)
2129
+ * Per-instance failures (corrupt JSON, vanished file mid-read, permission
2130
+ * error) are isolated: the bad directory is logged + skipped, the rest
2131
+ * of the scan completes. Discovery NEVER throws to its caller — a
2132
+ * Team-Mode-disabled return is `[]`, not an exception. This keeps the
2133
+ * worker LLM call path resilient to one peer session's bad state.
1738
2134
  *
1739
- * Only entries outside the preserve closure are archived.
2135
+ * DI-clean: every fs / clock / logger dependency is injectable so
2136
+ * hermetic tests can simulate stale / corrupt / mid-scan-deletion
2137
+ * scenarios without real disk.
1740
2138
  */
1741
- declare function archiveOldIslands(lineage: KodaXSessionLineage): {
1742
- slimmedLineage: KodaXSessionLineage;
1743
- archivedEntries: KodaXSessionEntry[];
1744
- archivedCount: number;
1745
- archiveBatchId: string;
1746
- };
1747
2139
 
2140
+ /** A sibling KodaX session that passed stale + version-guard checks. */
2141
+ interface DiscoveredInstance {
2142
+ readonly pid: number;
2143
+ readonly state: PersistedSessionState;
2144
+ /** Heartbeat mtime in ms (epoch). Useful for ordering "freshest first". */
2145
+ readonly heartbeatMtimeMs: number;
2146
+ }
2147
+ /** Minimal injectable fs surface used by `discoverInstances`. */
2148
+ interface InstanceDiscoveryFs {
2149
+ existsSync(targetPath: string): boolean;
2150
+ readdirSync(dirPath: string): string[];
2151
+ /** Returns the mtime of the path in ms, or `null` if missing / unreadable. */
2152
+ statMtimeMs(filePath: string): number | null;
2153
+ readFileSync(filePath: string, encoding: 'utf8'): string;
2154
+ rmSync(dirPath: string, options: {
2155
+ recursive: true;
2156
+ force: true;
2157
+ }): void;
2158
+ }
2159
+ interface DiscoveryOptions {
2160
+ /**
2161
+ * pid to exclude from the result. Defaults to `process.pid` — the
2162
+ * caller's own state.json should not appear in its own sibling list.
2163
+ */
2164
+ readonly excludePid?: number;
2165
+ /**
2166
+ * Heartbeat mtime older than `now - staleThresholdMs` → directory is
2167
+ * stale. Default 30_000 (matches v0.7.41 spec).
2168
+ */
2169
+ readonly staleThresholdMs?: number;
2170
+ /**
2171
+ * When true, stale directories are removed during the scan (best-
2172
+ * effort `rmSync(force:true)`; failure is swallowed). When false,
2173
+ * stale directories are skipped but left on disk. Defaults to false
2174
+ * — wire from the session-startup path with `true` so crashed-process
2175
+ * dirs don't accumulate.
2176
+ */
2177
+ readonly reapStale?: boolean;
2178
+ readonly clock?: () => number;
2179
+ readonly fs?: InstanceDiscoveryFs;
2180
+ readonly instancesRoot?: string;
2181
+ /** Per-instance failure log; defaults to a no-op. Pass `console.warn` in dev. */
2182
+ readonly logger?: (message: string) => void;
2183
+ }
1748
2184
  /**
1749
- * ../../index.js File Tracking artifactLedger extraction.
1750
- *
1751
- * FEATURE_185 (v0.7.42) extends the previous input-only extractor to also
1752
- * read each tool_use's matching tool_result, enriching `metadata` with parsed
1753
- * hits / matchedPaths / exitCode / tail. Pipeline:
1754
- *
1755
- * Round end (REPL: repl.ts:1279/1371)
1756
- * → extractArtifactLedger(result.messages)
1757
- * → tool_result still raw (top-of-loop microcompact hasn't run on these)
1758
- * → buildArtifactEntry parses result content into metadata
1759
- * → mergeArtifactLedger commits enrichment to context.artifactLedger
1760
- * → storage.save persists the enriched ledger
1761
- *
1762
- * Top-of-loop microcompact (run-substrate.ts:621, iteration N+1)
1763
- * → clears tool_result.content older than maxAge to `[Cleared: ...]`
2185
+ * Synchronous discovery scan. Returns a freshness-sorted array
2186
+ * (newest heartbeat first) so callers that want only the N most-recent
2187
+ * siblings can slice without re-sorting.
1764
2188
  *
1765
- * Compaction time (compaction.ts:257)
1766
- * extractArtifactLedger(toProcess) re-runs on cleared messages
1767
- * buildArtifactEntry's parsers refuse `[Cleared: ...]` no fresh hits
1768
- * → mergeArtifactLedger preserves the round-end enrichment via
1769
- * per-key non-empty preference (see `mergeLedgerMetadata`).
1770
- *
1771
- * The metadata-aware merge is the keystone — without it, every compaction
1772
- * would silently downgrade ledger entries to input-only. End-to-end
1773
- * preservation is exercised by the "end-to-end enrichment survives
1774
- * microcompact" tests in file-tracker.test.ts.
2189
+ * Never throws. A missing `<instancesRoot>` directory means the user
2190
+ * is the first session ever on this machine → `[]`. A scan failure on
2191
+ * one entry is logged + skipped, not propagated.
2192
+ */
2193
+ declare function discoverInstances(options?: DiscoveryOptions): DiscoveredInstance[];
2194
+
2195
+ /**
2196
+ * ../../index.js Compaction Types
1775
2197
  */
1776
2198
 
1777
- declare function extractFileOps(messages: KodaXMessage[]): FileOperations;
1778
- declare function mergeFileOps(ops1: FileOperations, ops2: FileOperations): FileOperations;
1779
- declare function extractArtifactLedger(messages: KodaXMessage[]): KodaXSessionArtifactLedgerEntry[];
1780
- declare function mergeArtifactLedger(existing: KodaXSessionArtifactLedgerEntry[], next: KodaXSessionArtifactLedgerEntry[]): KodaXSessionArtifactLedgerEntry[];
2199
+ interface CompactionConfig {
2200
+ /** Whether automatic compaction is enabled. */
2201
+ enabled: boolean;
2202
+ /** Trigger compaction when context usage exceeds this percentage of the window. */
2203
+ triggerPercent: number;
2204
+ /**
2205
+ * @deprecated V2 compaction no longer uses this option.
2206
+ *
2207
+ * The system now combines protected recent context, lightweight pruning, and
2208
+ * rolling summaries automatically.
2209
+ */
2210
+ keepRecentPercent?: number;
2211
+ /** Percentage of the most recent context that is never compacted or pruned. Defaults to 20. */
2212
+ protectionPercent?: number;
2213
+ /**
2214
+ * Percentage of the context window used as the chunk size for each rolling
2215
+ * summary pass. Defaults to 10.
2216
+ */
2217
+ rollingSummaryPercent?: number;
2218
+ /** Prune oversized tool results when they exceed roughly this many tokens. Defaults to 500. */
2219
+ pruningThresholdTokens?: number;
2220
+ /**
2221
+ * Gap ratio for prune fast-return. After pruning, if remaining tokens still exceed
2222
+ * triggerTokens * pruningGapRatio, the system continues to the summarization path
2223
+ * instead of returning early. Defaults to 0.8.
2224
+ */
2225
+ pruningGapRatio?: number;
2226
+ /** Optional override for the provider context window. */
2227
+ contextWindow?: number;
2228
+ }
2229
+ interface CompactionDetails {
2230
+ readFiles: string[];
2231
+ modifiedFiles: string[];
2232
+ }
2233
+ interface CompactionAnchor {
2234
+ summary: string;
2235
+ tokensBefore: number;
2236
+ tokensAfter: number;
2237
+ entriesRemoved: number;
2238
+ reason: string;
2239
+ artifactLedgerId?: string;
2240
+ details?: CompactionDetails;
2241
+ memorySeed?: KodaXCompactMemorySeed;
2242
+ }
2243
+ interface CompactionUpdate {
2244
+ anchor?: CompactionAnchor;
2245
+ artifactLedger?: KodaXSessionArtifactLedgerEntry[];
2246
+ memorySeed?: KodaXCompactMemorySeed;
2247
+ /**
2248
+ * FEATURE_072: ledger-summary + file-content messages produced by
2249
+ * `buildPostCompactAttachments` + `buildFileContentMessages`. Agent.ts
2250
+ * passes these separately from the kept-tail messages so REPL-side
2251
+ * `applySessionCompaction` can store them natively on the CompactionEntry
2252
+ * rather than inlining them as loose `[Post-compact: ...]` system messages
2253
+ * in lineage. Agent.ts keeps inlining them into its local flat `messages`
2254
+ * via `injectPostCompactAttachments` (P4 belt-and-suspenders); the lineage
2255
+ * is the persistence source of truth.
2256
+ */
2257
+ postCompactAttachments?: readonly KodaXMessage[];
2258
+ }
2259
+ interface CompactionResult {
2260
+ compacted: boolean;
2261
+ messages: KodaXMessage[];
2262
+ summary?: string;
2263
+ tokensBefore: number;
2264
+ tokensAfter: number;
2265
+ entriesRemoved: number;
2266
+ details?: CompactionDetails;
2267
+ artifactLedger?: KodaXSessionArtifactLedgerEntry[];
2268
+ anchor?: CompactionAnchor;
2269
+ memorySeed?: KodaXCompactMemorySeed;
2270
+ }
2271
+ interface FileOperations {
2272
+ readFiles: string[];
2273
+ modifiedFiles: string[];
2274
+ }
1781
2275
 
1782
- export { DEFAULT_SYSTEM_CAP as D, KODAX_API_MIN_INTERVAL as K, LINEAGE_ENTRY_TYPES as L, PROMISE_PATTERN as P, Runner as V, generateSessionId as aA, getAdmittedAgentBindings as aB, getAgentConfigHome as aC, getAgentConfigPath as aD, getAppDataDir as aE, getSessionLineagePath as aF, getSessionMessagesFromLineage as aG, mergeArtifactLedger as aH, mergeFileOps as aI, registerPresetDispatcher as aJ, resolveSessionLineageTarget as aK, rewindSessionLineage as aL, runAdmissionAudit as aM, setAdmittedAgentBindings as aN, setAgentConfigHome as aO, setSessionLineageActiveEntry as aP, validateAndFixToolHistory as aQ, Tracer as aa, _resetAdmittedAgentBindings as ac, _resetPresetDispatchers as ad, appendSessionLineageLabel as ae, applyLineageTruncation as af, applySessionCompaction as ag, archiveOldIslands as ah, buildSessionTree as ai, buildSystemPrompt as aj, cleanupIncompleteToolCalls as ak, countActiveLineageMessages as al, countTokens as am, createInMemorySession as an, createInvariantSessionForAgent as ao, createSessionLineage as ap, createTrace as aq, defaultTracer as ar, detectInstructionsInjection as as, estimateTokens as at, extractArtifactLedger as au, extractAssistantTextFromMessage as av, extractFileOps as aw, extractTitleFromMessages as ax, findPreviousUserEntryId as ay, forkSessionLineage as az, DefaultSummaryCompaction as h, InvariantSession as m, KODAX_DEFAULT_TIMEOUT as n, KODAX_HARD_TIMEOUT as o, KODAX_MAX_INCOMPLETE_RETRIES as p, KODAX_MAX_MAXTOKENS_RETRIES as q, KODAX_MAX_RETRIES as r, KODAX_MAX_TOKENS as s, KODAX_RETRY_BASE_DELAY as t, KODAX_STAGGER_DELAY as u, LineageCompaction as w, LineageExtension as z };
1783
- export type { SessionForkOptions as $, AdmissionAuditOptions as A, LineageLabelPayload as B, CompactionContext as C, LineageTreeNode as E, MessageEntry as F, PolicyCompactionResult as G, PresetDispatcher as H, InMemorySessionOptions as I, PresetTracingContext as J, ManifestPatch as M, ReadonlyRecorder as N, ObserveCtx as O, QualityInvariant as Q, ReadonlyMutationTracker as R, RunEvent as S, RunOptions as T, RunResult as U, RunnerEvent as W, Session as X, SessionDispatchResult as Y, SessionEntry as Z, SessionExtension as _, AdmissionCtx as a, StartTraceOptions as a0, StopHookContext as a1, StopHookFn as a2, StopHookResult as a3, SystemCap as a4, TerminalCtx as a5, ToolCapability as a6, ToolPermission as a7, Trace as a8, TraceOptions as a9, TracerOptions as ab, AdmissionVerdict as b, AdmittedHandle as c, AgentManifest as d, CompactionEntry as e, CompactionEntryPayload as f, CompactionPolicy as g, DefaultSummaryCompactionOptions as i, Deliverable as j, InvariantId as k, InvariantResult as l, LineageArtifactLedgerPayload as v, LineageCompactionDelegates as x, LineageEntryType as y };
2276
+ export { DEFAULT_SYSTEM_CAP as D, InvariantSession as O, MAX_TOOL_LOOP_ITERATIONS as P, getAdmittedAgentBindings as a$, Runner as a6, Tracer as aI, _resetAdmittedAgentBindings as aK, _resetPresetDispatchers as aL, buildAssistantMessageFromLlmResult as aM, buildSystemPrompt as aN, buildToolResultMessage as aO, collectGuardrails as aP, createAgent as aQ, createHandoff as aR, createInMemorySession as aS, createInvariantSessionForAgent as aT, createStateWriter as aU, createTrace as aV, defaultTracer as aW, detectInstructionsInjection as aX, discoverInstances as aY, executeRunnerToolCall as aZ, extractAssistantTextFromMessage as a_, SpanImpl as ao, isRunnableTool as b0, isRunnerLlmResult as b1, registerChildTask as b2, registerPresetDispatcher as b3, requestTaskStop as b4, runAdmissionAudit as b5, runInputGuardrails as b6, runOutputGuardrails as b7, runToolAfterGuardrails as b8, runToolBeforeGuardrails as b9, setAdmittedAgentBindings as ba, GuardrailBlockedError as w, GuardrailEscalateError as y };
2277
+ export type { RecentlyModifiedFile as $, AdmissionAuditOptions as A, GuardrailVerdict as B, ChildTaskRegistry as C, EvidenceSpanData as E, FanoutSpanData as F, GenerationSpanData as G, Handoff as H, HandoffSpanData as I, InMemorySessionOptions as J, InputGuardrail as K, InstanceDiscoveryFs as L, InvariantId as M, InvariantResult as N, ManifestPatch as Q, MessageEntry as R, ObserveCtx as S, OutputGuardrail as T, PersistedSessionState as U, PresetDispatcher as V, PresetTracingContext as W, QualityInvariant as X, ReadonlyMutationTracker as Y, ReadonlyRecorder as Z, ReasoningDepth as _, AdmissionCtx as a, RequestTaskStopOptions as a0, RequestTaskStopResult as a1, RunEvent as a2, RunOptions as a3, RunResult as a4, RunnableTool as a5, RunnerEvent as a7, RunnerLlmResult as a8, RunnerLlmReturn as a9, TerminalCtx as aA, ToolBeforeOutcome as aB, ToolCallSpanData as aC, ToolCapability as aD, ToolGuardrail as aE, ToolPermission as aF, Trace as aG, TraceOptions as aH, TracerOptions as aJ, RunnerToolCall as aa, RunnerToolContext as ab, RunnerToolObserver as ac, RunnerToolResult as ad, Session as ae, SessionDispatchResult as af, SessionEntry as ag, SessionExtension as ah, SessionForkOptions as ai, SessionMeta as aj, SessionStateSnapshot as ak, Span as al, SpanData as am, SpanError as an, SpanImplOptions as ap, StartTraceOptions as aq, StateWriter as ar, StateWriterFs as as, StateWriterOptions as at, StopHookContext as au, StopHookFn as av, StopHookResult as aw, StopHookSpanData as ax, SystemCap as ay, TaskAbortRegistry as az, AdmissionVerdict as b, AdmittedHandle as c, Agent as d, AgentManifest as e, AgentMessage as f, AgentMiddlewareDeclaration as g, AgentReasoningProfile as h, AgentSpanData as i, AgentTool as j, CompactionAnchor as k, CompactionConfig as l, CompactionDetails as m, CompactionResult as n, CompactionSpanData as o, CompactionUpdate as p, CurrentTodoSummary as q, Deliverable as r, DiscoveredInstance as s, DiscoveryOptions as t, FileOperations as u, Guardrail as v, GuardrailContext as x, GuardrailSpanData as z };