@kodax-ai/kodax 0.7.39 → 0.7.41

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 (61) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/README.md +58 -0
  3. package/README_CN.md +31 -0
  4. package/dist/chunks/{chunk-SF7WD7E5.js → chunk-5TFLMGER.js} +1 -1
  5. package/dist/chunks/{chunk-HUAU4KB3.js → chunk-6OB4AJOM.js} +1 -1
  6. package/dist/chunks/chunk-6QO6HWGU.js +30 -0
  7. package/dist/chunks/{chunk-SONW6AC7.js → chunk-EQ5DGS2W.js} +1 -1
  8. package/dist/chunks/chunk-EVIDQWMF.js +5 -0
  9. package/dist/chunks/chunk-HYWVRTFA.js +1233 -0
  10. package/dist/chunks/chunk-SX2IS5JP.js +16 -0
  11. package/dist/chunks/chunk-V4WSBIXB.js +2 -0
  12. package/dist/chunks/chunk-ZPJPNLBK.js +462 -0
  13. package/dist/chunks/compaction-config-LT5PEXPT.js +2 -0
  14. package/dist/chunks/{construction-bootstrap-XSE7ZABG.js → construction-bootstrap-HBCWJFHC.js} +1 -1
  15. package/dist/chunks/{devtools-MOFU7YQF.js → devtools-EYGFOXEU.js} +1 -1
  16. package/dist/chunks/{dist-WKW4CBG6.js → dist-M57GIWR4.js} +1 -1
  17. package/dist/chunks/dist-V3BS2NKB.js +2 -0
  18. package/dist/chunks/paste-5DSTHQGK.js +2 -0
  19. package/dist/chunks/{utils-3HW4KOGE.js → utils-FAFUQJ2A.js} +1 -1
  20. package/dist/index.d.ts +232 -7
  21. package/dist/index.js +2 -2
  22. package/dist/kodax_cli.js +945 -923
  23. package/dist/sdk-agent.d.ts +1459 -10
  24. package/dist/sdk-agent.js +1 -1
  25. package/dist/sdk-coding.d.ts +4543 -14
  26. package/dist/sdk-coding.js +1 -1
  27. package/dist/sdk-llm.d.ts +209 -10
  28. package/dist/sdk-llm.js +1 -1
  29. package/dist/sdk-repl.d.ts +2694 -13
  30. package/dist/sdk-repl.js +1 -1
  31. package/dist/sdk-skills.d.ts +487 -11
  32. package/dist/sdk-skills.js +1 -1
  33. package/dist/types-chunks/bash-prefix-extractor.d-B2iliwdi.d.ts +2432 -0
  34. package/dist/types-chunks/capability.d-BxNgd1-c.d.ts +368 -0
  35. package/dist/types-chunks/cost-tracker.d-C4dMlQuV.d.ts +342 -0
  36. package/dist/types-chunks/history-cleanup.d-q1vAvCss.d.ts +1266 -0
  37. package/dist/types-chunks/instance-discovery.d-DZhp77vb.d.ts +1217 -0
  38. package/dist/types-chunks/resolver.d-BwD6TKz7.d.ts +262 -0
  39. package/dist/types-chunks/storage.d-Bv9T99Qu.d.ts +584 -0
  40. package/dist/types-chunks/types.d-C5mHR87z.d.ts +119 -0
  41. package/package.json +8 -2
  42. package/dist/acp_events.d.ts +0 -109
  43. package/dist/acp_logger.d.ts +0 -20
  44. package/dist/acp_server.d.ts +0 -92
  45. package/dist/chunks/chunk-4E76FLZ3.js +0 -2
  46. package/dist/chunks/chunk-7LQ2NCHF.js +0 -1221
  47. package/dist/chunks/chunk-N2VZ2MJF.js +0 -11
  48. package/dist/chunks/chunk-WEEQZYZS.js +0 -460
  49. package/dist/chunks/chunk-XI75LZIO.js +0 -30
  50. package/dist/chunks/compaction-config-YL4SWWII.js +0 -2
  51. package/dist/chunks/dist-AMUYI7R5.js +0 -2
  52. package/dist/cli_commands.d.ts +0 -17
  53. package/dist/cli_option_helpers.d.ts +0 -49
  54. package/dist/cli_option_helpers.test.d.ts +0 -1
  55. package/dist/constructed_cli.d.ts +0 -82
  56. package/dist/constructed_cli.test.d.ts +0 -1
  57. package/dist/kodax_cli.d.ts +0 -7
  58. package/dist/self_modify_cli.d.ts +0 -81
  59. package/dist/self_modify_cli.test.d.ts +0 -9
  60. package/dist/skill_cli.d.ts +0 -15
  61. package/dist/skill_cli.test.d.ts +0 -1
@@ -0,0 +1,1266 @@
1
+ import { o as KodaXMessage } from './capability.d-BxNgd1-c.js';
2
+ import { a as AgentMessage, a7 as SpanData, a6 as Span, a8 as SpanError, A as Agent, _ as RunnerLlmReturn, G as Guardrail, a1 as RunnerToolObserver } from './instance-discovery.d-DZhp77vb.js';
3
+
4
+ /**
5
+ * @kodax-ai/agent Constants
6
+ *
7
+ * 通用 Agent 常量配置
8
+ */
9
+ declare const KODAX_MAX_TOKENS = 32768;
10
+ declare const KODAX_DEFAULT_TIMEOUT = 60;
11
+ declare const KODAX_HARD_TIMEOUT = 300;
12
+ declare const KODAX_MAX_RETRIES = 3;
13
+ declare const KODAX_RETRY_BASE_DELAY = 2;
14
+ declare const KODAX_MAX_INCOMPLETE_RETRIES = 2;
15
+ declare const KODAX_MAX_MAXTOKENS_RETRIES = 3;
16
+ declare const KODAX_STAGGER_DELAY = 1;
17
+ declare const KODAX_API_MIN_INTERVAL = 0.5;
18
+ declare const PROMISE_PATTERN: RegExp;
19
+
20
+ /**
21
+ * @kodax-ai/agent Tokenizer
22
+ *
23
+ * Token 估算 - 使用 tiktoken 进行精确计算
24
+ */
25
+
26
+ /**
27
+ * 估算消息的 token 数量
28
+ *
29
+ * 精确计算包括:
30
+ * - 消息结构开销(每条约 4 tokens)
31
+ * - 角色标识
32
+ * - 内容文本
33
+ * - 工具调用和结果
34
+ */
35
+ declare function estimateTokens(messages: KodaXMessage[]): number;
36
+ /**
37
+ * 计算单个文本的 token 数量(便捷函数)
38
+ */
39
+ declare function countTokens(text: string): number;
40
+
41
+ /**
42
+ * Layer A Primitive: Session / SessionEntry / MessageEntry / SessionExtension
43
+ *
44
+ * FEATURE_081 (v0.7.23): Base Session shape. The thick
45
+ * `KodaXSessionLineage` lives in `@kodax-ai/session-lineage` and is re-expressed
46
+ * as a `LineageExtension` over this base.
47
+ *
48
+ * History: extracted to `@kodax-ai/core` in FEATURE_082 (v0.7.24); merged back
49
+ * into `@kodax-ai/agent` in v0.7.35.1 FEATURE_142. `@kodax-ai/coding` retains a
50
+ * barrel re-export for batteries-included consumers.
51
+ *
52
+ * Status: @experimental — API shape may be refined during v0.7.x.
53
+ *
54
+ * Design intent:
55
+ * - Base Session is a minimal, linearly-appendable log of typed entries.
56
+ * - Extensions (lineage, artifacts, labels, compaction) layer on top by
57
+ * claiming additional `entry.type` values and contributing operators /
58
+ * reducers that read the entry stream.
59
+ * - coding preset composes LineageExtension + CompactionExtension +
60
+ * ArtifactExtension to reproduce today's `KodaXSessionLineage` behavior.
61
+ */
62
+
63
+ /**
64
+ * A single immutable entry in a Session log. `type` is the dispatch key used
65
+ * by extensions to claim ownership of an entry kind.
66
+ */
67
+ interface SessionEntry {
68
+ readonly id: string;
69
+ readonly ts: number;
70
+ readonly type: string;
71
+ readonly payload: unknown;
72
+ }
73
+ /**
74
+ * Canonical message entry type. All Layer A consumers can rely on
75
+ * `type: 'message'` entries existing; extensions add more types.
76
+ */
77
+ interface MessageEntry extends SessionEntry {
78
+ readonly type: 'message';
79
+ readonly payload: {
80
+ readonly role: AgentMessage['role'];
81
+ readonly content: AgentMessage['content'];
82
+ readonly synthetic?: boolean;
83
+ };
84
+ }
85
+ /**
86
+ * Options for forking a session.
87
+ *
88
+ * v0.7.23 exposes only `name` (label for the new fork); structural options
89
+ * (branch-at-entry, shallow copy, etc.) are reserved for later versions.
90
+ */
91
+ interface SessionForkOptions {
92
+ readonly name?: string;
93
+ }
94
+ /**
95
+ * Minimal Session interface.
96
+ *
97
+ * Implementations must guarantee:
98
+ * - `append()` is atomic: either the entry is visible on next `entries()`
99
+ * iteration or it throws.
100
+ * - `entries()` yields entries in append order.
101
+ * - `metadata` is a readonly snapshot; mutations are made via extensions.
102
+ * - `fork()` returns a new Session with a snapshot of current entries; the
103
+ * two sessions diverge thereafter.
104
+ */
105
+ interface Session {
106
+ readonly id: string;
107
+ append(entry: SessionEntry): Promise<void>;
108
+ entries(): AsyncIterable<SessionEntry>;
109
+ fork(opts?: SessionForkOptions): Promise<Session>;
110
+ readonly metadata: ReadonlyMap<string, unknown>;
111
+ }
112
+ /**
113
+ * Extension contract for teaching a Session new entry types + operators +
114
+ * reducers.
115
+ *
116
+ * - `entryTypes`: which `entry.type` values this extension owns. Two
117
+ * extensions composed into one Session must not claim overlapping types.
118
+ * - `operators`: high-level imperative verbs exposed to callers (e.g.
119
+ * `branch`, `rewind`, `attachArtifact`).
120
+ * - `reducers`: pure projections over the entry stream (e.g. "build lineage
121
+ * tree").
122
+ *
123
+ * The exact dispatch mechanics (`ExtendedSession<T>` typing, operator
124
+ * registration) land with the coding preset integration; v0.7.23 pins the
125
+ * shape only.
126
+ */
127
+ interface SessionExtension {
128
+ readonly name: string;
129
+ readonly entryTypes: readonly string[];
130
+ readonly operators?: Readonly<Record<string, (session: Session, ...args: readonly unknown[]) => Promise<unknown>>>;
131
+ readonly reducers?: Readonly<Record<string, (entries: readonly SessionEntry[]) => unknown>>;
132
+ }
133
+ /**
134
+ * Options for `createInMemorySession`.
135
+ */
136
+ interface InMemorySessionOptions {
137
+ readonly id?: string;
138
+ readonly metadata?: ReadonlyMap<string, unknown>;
139
+ readonly initialEntries?: readonly SessionEntry[];
140
+ }
141
+ /**
142
+ * In-memory Session suitable for tests, examples, and embedded SDK use. Not
143
+ * durable across process restarts — persistence is provided by coding-specific
144
+ * adapters in `@kodax-ai/session-lineage` and `@kodax-ai/agent`.
145
+ */
146
+ declare function createInMemorySession(opts?: InMemorySessionOptions): Session;
147
+
148
+ /**
149
+ * Layer A Primitive: CompactionPolicy + DefaultSummaryCompaction
150
+ *
151
+ * FEATURE_081 (v0.7.23): Pluggable compaction for generic agent loops.
152
+ *
153
+ * Two layers:
154
+ * - Layer A (here): `CompactionPolicy` interface + `DefaultSummaryCompaction`
155
+ * — a minimal "token threshold → LLM summary of old messages" policy that
156
+ * any external Agent can pick up with zero KodaX runtime dependency.
157
+ * - Layer B (`@kodax-ai/session-lineage/src/lineage.ts`): `LineageCompaction`
158
+ * wraps the full FEATURE_072 lineage-native compaction for the coding
159
+ * preset.
160
+ *
161
+ * The `compaction` entry shape written by `DefaultSummaryCompaction` is the
162
+ * same type used by `LineageExtension`, so the two layers interoperate on
163
+ * the same Session log.
164
+ *
165
+ * History: extracted to `@kodax-ai/core` in FEATURE_082 (v0.7.24); merged back
166
+ * into `@kodax-ai/agent` in v0.7.35.1 FEATURE_142.
167
+ */
168
+
169
+ /**
170
+ * Runtime context for a compaction pass. Abstracts the LLM/tokenizer
171
+ * dependencies so policies stay independent of any specific provider.
172
+ */
173
+ interface CompactionContext {
174
+ readonly tokensUsed: number;
175
+ readonly budget: number;
176
+ /**
177
+ * Summarizer implementation. Callers inject a function that maps a list of
178
+ * messages to a short summary string. In coding-preset mode this is wired
179
+ * to `runKodaX` internally; for external consumers it can call any LLM.
180
+ */
181
+ readonly summarize: (messages: readonly AgentMessage[]) => Promise<string>;
182
+ }
183
+ /**
184
+ * Payload written to the `compaction` entry appended by `compact()`.
185
+ */
186
+ interface CompactionEntryPayload {
187
+ readonly summary: string;
188
+ readonly replacedMessageEntryIds: readonly string[];
189
+ }
190
+ /**
191
+ * Typed compaction entry. `type` is `'compaction'`; extensions (LineageExtension)
192
+ * may claim this same type.
193
+ */
194
+ interface CompactionEntry extends SessionEntry {
195
+ readonly type: 'compaction';
196
+ readonly payload: CompactionEntryPayload;
197
+ }
198
+ /**
199
+ * Outcome of a single CompactionPolicy.compact() pass. Renamed from
200
+ * `CompactionResult` to `PolicyCompactionResult` in v0.7.35.1 FEATURE_142
201
+ * because the Layer A primitive collided with @kodax-ai/agent's pre-existing
202
+ * `CompactionResult` (compaction/types.ts) used by the coding orchestration
203
+ * post-compact pipeline. The two types model different things:
204
+ * - `PolicyCompactionResult` (here): "summary + replaced entry ids", the
205
+ * payload of one CompactionPolicy step.
206
+ * - `CompactionResult` (compaction/types.ts): the rich result of the
207
+ * coding-side multi-pass compaction (artifactLedger / memorySeed /
208
+ * tokensBefore / tokensAfter / etc).
209
+ */
210
+ interface PolicyCompactionResult {
211
+ readonly summary: string;
212
+ readonly replacedMessageEntryIds: readonly string[];
213
+ }
214
+ /**
215
+ * Pluggable compaction policy. Any multi-turn Agent loop can check
216
+ * `shouldCompact()` at round boundaries and call `compact()` when it returns
217
+ * true.
218
+ */
219
+ interface CompactionPolicy {
220
+ readonly name: string;
221
+ shouldCompact(session: Session, tokensUsed: number, budget: number): boolean;
222
+ compact(session: Session, ctx: CompactionContext): Promise<PolicyCompactionResult>;
223
+ /** Optional: rehydrate compacted content when a restore hint is available. */
224
+ restore?(session: Session, hint: unknown): Promise<void>;
225
+ }
226
+ /**
227
+ * Configuration for `DefaultSummaryCompaction`.
228
+ */
229
+ interface DefaultSummaryCompactionOptions {
230
+ /**
231
+ * Fraction of `budget` at which compaction triggers. Default 0.8 (i.e.
232
+ * 80% of the token budget). Must be in (0, 1].
233
+ */
234
+ readonly thresholdRatio?: number;
235
+ /**
236
+ * Number of most-recent message entries to preserve verbatim. Default 10.
237
+ * Must be non-negative.
238
+ */
239
+ readonly keepRecent?: number;
240
+ /**
241
+ * Optional clock override (ms epoch). Useful for deterministic tests.
242
+ */
243
+ readonly now?: () => number;
244
+ /**
245
+ * Optional random-string override. Useful for deterministic tests.
246
+ */
247
+ readonly randomSuffix?: () => string;
248
+ }
249
+ /**
250
+ * Minimal "token threshold + LLM summary" compaction policy. Works on any
251
+ * Session that stores `message` entries.
252
+ *
253
+ * Behavior:
254
+ * - `shouldCompact` returns true when `tokensUsed >= budget *
255
+ * thresholdRatio`.
256
+ * - `compact` reads all `message` entries, keeps the last `keepRecent`
257
+ * untouched, summarizes the rest via `ctx.summarize`, and appends a
258
+ * single `compaction` entry to the session.
259
+ *
260
+ * Caller is responsible for invoking `shouldCompact` and for interpreting the
261
+ * appended entry when building the next turn's prompt.
262
+ */
263
+ declare class DefaultSummaryCompaction implements CompactionPolicy {
264
+ readonly name = "default-summary";
265
+ private readonly thresholdRatio;
266
+ private readonly keepRecent;
267
+ private readonly now;
268
+ private readonly randomSuffix;
269
+ constructor(opts?: DefaultSummaryCompactionOptions);
270
+ shouldCompact(_session: Session, tokensUsed: number, budget: number): boolean;
271
+ compact(session: Session, ctx: CompactionContext): Promise<PolicyCompactionResult>;
272
+ }
273
+
274
+ /**
275
+ * Trace — the root container for a single user-visible workflow.
276
+ *
277
+ * FEATURE_083 (v0.7.24): a Trace wraps a root span and all its descendants.
278
+ * The Runner.run(agent, ...) entry creates a trace per run by default;
279
+ * consumers can nest runs under an existing trace via `Runner.run(agent, input, { trace })`.
280
+ */
281
+
282
+ interface Trace {
283
+ readonly id: string;
284
+ readonly startedAt: number;
285
+ readonly rootSpan: Span;
286
+ readonly metadata: ReadonlyMap<string, unknown>;
287
+ end(): void;
288
+ readonly endedAt?: number;
289
+ readonly error?: SpanError;
290
+ }
291
+ interface TraceOptions {
292
+ readonly id?: string;
293
+ readonly name?: string;
294
+ readonly rootSpanData?: SpanData;
295
+ readonly metadata?: ReadonlyMap<string, unknown>;
296
+ readonly now?: () => number;
297
+ readonly nextSpanId?: () => string;
298
+ readonly nextTraceId?: () => string;
299
+ readonly onSpanStart?: (span: Span) => void;
300
+ readonly onSpanEnd?: (span: Span) => void;
301
+ readonly onTraceEnd?: (trace: Trace) => void;
302
+ }
303
+
304
+ /**
305
+ * Tracer — convenience façade that creates Traces wired to the registered
306
+ * processors and default id generators.
307
+ *
308
+ * FEATURE_083 (v0.7.24): callers typically use the default tracer:
309
+ *
310
+ * const trace = defaultTracer.startTrace({ name: 'coding-run' });
311
+ * const child = trace.rootSpan.addChild('generation', { kind: 'generation', ... });
312
+ * // ... do work ...
313
+ * child.end();
314
+ * trace.end();
315
+ *
316
+ * Advanced callers can inject a custom clock / id generator for
317
+ * deterministic tests.
318
+ */
319
+
320
+ interface StartTraceOptions {
321
+ readonly id?: string;
322
+ readonly name?: string;
323
+ readonly rootSpanData?: TraceOptions['rootSpanData'];
324
+ readonly metadata?: ReadonlyMap<string, unknown>;
325
+ }
326
+ interface TracerOptions {
327
+ readonly now?: () => number;
328
+ readonly nextSpanId?: () => string;
329
+ readonly nextTraceId?: () => string;
330
+ }
331
+ declare class Tracer {
332
+ private readonly options;
333
+ constructor(options?: TracerOptions);
334
+ startTrace(opts?: StartTraceOptions): Trace;
335
+ }
336
+
337
+ /**
338
+ * Layer A Primitive: Quality Invariant + Admission Contract types.
339
+ *
340
+ * FEATURE_101 (v0.7.31) — types-only module. Runner.admit() runtime lives
341
+ * in `./runner.ts`; the seven (+1 external) invariant implementations live
342
+ * in `@kodax-ai/coding/src/agent-runtime/invariants/`.
343
+ *
344
+ * Why types-only here: the admission contract is a Layer A primitive that
345
+ * @kodax-ai/coding consumes — putting it in @kodax-ai/core keeps SDK consumers
346
+ * from pulling in coding-specific imports just to reference admission
347
+ * types. The actual invariant implementations need access to mutation
348
+ * trackers, budget controllers, and ToolGuardrail capability tiers — all
349
+ * of which live in @kodax-ai/coding — so they belong there.
350
+ *
351
+ * Status: @experimental. v0.7.31 ships these types alongside the FEATURE_089
352
+ * agent-generation consumer; once dispatch eval baseline (FEATURE_101
353
+ * Phase 3) stabilizes the schema we promote to ADR-021.
354
+ *
355
+ * See:
356
+ * - docs/features/v0.7.31.md#feature_101-constructed-agent-admission-contract
357
+ * - docs/features/v0.7.31.md#feature_106-ama-harness-selection-calibration
358
+ * (FEATURE_106 registers the 8th invariant 'harnessSelectionTiming' —
359
+ * external to admission v1 closed set but uses the same runtime)
360
+ */
361
+
362
+ /**
363
+ * Untrusted Agent declaration submitted by an LLM-driven generator
364
+ * (FEATURE_089) or any other consumer that wants the manifest verified
365
+ * by the admission contract before activation.
366
+ *
367
+ * Structurally `Agent` plus three manifest-only optional fields the LLM
368
+ * may declare to express intent (per FEATURE_101 §Manifest schema):
369
+ *
370
+ * - `requestedToolCapabilities`: "I plan to use bash:test, not bash:network"
371
+ * Admission intersects with the resolved capability set from `tools`.
372
+ * - `maxBudget`: "Cap my total turn budget at N" — admission clamps to
373
+ * `system_cap.maxBudget`; runtime further clamps to parent.remaining.
374
+ * - `declaredInvariants`: extra invariants the LLM voluntarily binds.
375
+ * The required set (resolved from role / toolScope / harnessTier) is
376
+ * ALWAYS a floor — declaredInvariants can only ADD.
377
+ *
378
+ * `Runner.admit(manifest)` reads as "this manifest has not been admitted
379
+ * yet" while `Runner.run(agent, ...)` reads as "this Agent is trusted
380
+ * to execute".
381
+ */
382
+ type AgentManifest = Agent & {
383
+ readonly requestedToolCapabilities?: readonly ToolPermission[];
384
+ readonly maxBudget?: number;
385
+ /**
386
+ * Tool-loop iteration ceiling the manifest commits to. Admission
387
+ * clamps to `system_cap.maxIterations` via `clampMaxIterations` patch;
388
+ * Runner.run reads the post-clamp value through `getAdmittedAgentBindings`
389
+ * and takes min-wins against `RunOptions.maxToolLoopIterations`. Symmetric
390
+ * with `maxBudget` — both are activation caps, both flow through the
391
+ * patch reducer, both consulted at runtime via the WeakMap binding.
392
+ */
393
+ readonly maxIterations?: number;
394
+ readonly declaredInvariants?: readonly InvariantId[];
395
+ };
396
+ /**
397
+ * Coarse-grained capability classes that group concrete tools by their
398
+ * observable side effects. Replaces the v0.7.30 `ToolName[]` allow-list
399
+ * with semantic categories so admission can reason about "this manifest
400
+ * wants bash:network capability" without enumerating every concrete tool.
401
+ *
402
+ * Aligned with FEATURE_092 (Auto Mode Classifier, v0.7.33) and FEATURE_094
403
+ * (anti-escape, v0.7.36) which both classify tools along these axes.
404
+ */
405
+ type ToolCapability = 'read' | 'edit' | 'bash:test' | 'bash:read-only' | 'bash:mutating' | 'bash:network' | 'subagent';
406
+ /**
407
+ * Per-tool capability declaration. Used in `AgentManifest.requestedToolCapabilities`
408
+ * (an optional field manifests can declare to express intent — admission
409
+ * intersects with the resolved capability set).
410
+ */
411
+ interface ToolPermission {
412
+ readonly tool: string;
413
+ readonly capabilities: readonly ToolCapability[];
414
+ }
415
+ /**
416
+ * Quality invariant identifier.
417
+ *
418
+ * **Admission contract v1 closed set (7 ids)** — FEATURE_101 itself enforces
419
+ * exactly these on every untrusted manifest:
420
+ *
421
+ * - 'finalOwner' Manifest must designate a final owner role
422
+ * - 'handoffLegality' Handoff graph (manifest + activated agents) is acyclic
423
+ * - 'budgetCeiling' manifest.maxBudget ≤ system_cap; runtime clamp to parent
424
+ * - 'toolPermission' Resolved capabilities ⊆ system_cap; runtime clamp to parent
425
+ * - 'evidenceTrail' Mutations must leave evidence; terminal verifies completeness
426
+ * - 'boundedRevise' maxIterations ≤ system; runtime tracks revise count
427
+ * - 'independentReview' Verifier role bound; verifier can't read generator reasoning
428
+ *
429
+ * **External consumers (open-ended) — registered to invariant runtime but
430
+ * NOT in admission v1 closed set**:
431
+ *
432
+ * - 'harnessSelectionTiming' FEATURE_106 (v0.7.31) — multi-file mutations
433
+ * must be preceded by an emitted harness verdict
434
+ *
435
+ * The runtime is open: future features may register additional invariants.
436
+ * The closed-set guarantee (7) applies to admission v1 only — see
437
+ * docs/features/v0.7.31.md FEATURE_101 §第一版 Invariant 清单 注脚.
438
+ */
439
+ type InvariantId = 'finalOwner' | 'handoffLegality' | 'budgetCeiling' | 'toolPermission' | 'evidenceTrail' | 'boundedRevise' | 'independentReview' | 'harnessSelectionTiming' | 'planBeforeMutate';
440
+ /**
441
+ * Patch the admission layer applies when an invariant returns severity='clamp'.
442
+ * Pure data — Runner applies it via a single deterministic reducer (see
443
+ * `applyManifestPatch` in `./admission-patch.ts`).
444
+ *
445
+ * Empty / undefined fields mean "no change". Multiple patches compose by
446
+ * union (removeTools concatenates, clamp* picks min, addInvariants unions).
447
+ */
448
+ interface ManifestPatch {
449
+ readonly removeTools?: readonly string[];
450
+ readonly clampMaxBudget?: number;
451
+ readonly clampMaxIterations?: number;
452
+ readonly addInvariants?: readonly InvariantId[];
453
+ readonly notes?: readonly string[];
454
+ }
455
+ /**
456
+ * Three-severity result returned by every invariant hook (admit / observe /
457
+ * assertTerminal):
458
+ *
459
+ * - `ok: true` No violation. Runner continues.
460
+ * - `severity: 'reject'` Hard violation. Admission fails (admit-time)
461
+ * or runtime escalates (observe/terminal-time).
462
+ * - `severity: 'clamp'` Manifest is over-broad. Admission applies the
463
+ * attached `patch` and admits with a warning.
464
+ * clamp severity ONLY makes sense at admit-time;
465
+ * observe/terminal hooks should use 'warn' or
466
+ * 'reject'.
467
+ * - `severity: 'warn'` Log-only signal. Runner records to trace +
468
+ * dispatch-eval metric, no action taken.
469
+ *
470
+ * The discriminated union pattern lets TypeScript narrow `patch` to only
471
+ * be present on clamp results — callers can't forget to check.
472
+ */
473
+ type InvariantResult = {
474
+ readonly ok: true;
475
+ } | {
476
+ readonly ok: false;
477
+ readonly severity: 'reject';
478
+ readonly reason: string;
479
+ } | {
480
+ readonly ok: false;
481
+ readonly severity: 'clamp';
482
+ readonly reason: string;
483
+ readonly patch: ManifestPatch;
484
+ } | {
485
+ readonly ok: false;
486
+ readonly severity: 'warn';
487
+ readonly reason: string;
488
+ };
489
+ /**
490
+ * System-wide caps the admission layer enforces against. The Runner
491
+ * resolves these from configuration once at startup (or per-call when
492
+ * the SDK consumer overrides via Runner.admit options).
493
+ *
494
+ * `maxBudget` / `maxIterations` are activation caps — runtime clamps to
495
+ * parent.remaining via the budget controller (separate concern).
496
+ * `allowedToolCapabilities` is the union of capabilities the system
497
+ * permits ANY constructed agent to request (intersected with
498
+ * manifest.requestedToolCapabilities at admission time).
499
+ */
500
+ interface SystemCap {
501
+ readonly maxBudget: number;
502
+ readonly maxIterations: number;
503
+ readonly allowedToolCapabilities: readonly ToolCapability[];
504
+ }
505
+ /**
506
+ * Context passed to invariant.admit() hooks at admission time.
507
+ *
508
+ * `activatedAgents` is the global set of already-admitted constructed
509
+ * agents — used by `handoffLegality` for transitive cycle detection
510
+ * (handoffs reference these by name).
511
+ *
512
+ * `stagedAgents` is the set of manifests that have been staged in the
513
+ * current generation batch but are not yet activated. FEATURE_101
514
+ * v0.7.31.1 patch: `handoffLegality` consults both maps so a same-batch
515
+ * cycle (A→B + B→A staged together, neither yet activated) is rejected
516
+ * at admission time instead of slipping through. The map is
517
+ * intentionally separate from `activatedAgents` so invariants that
518
+ * only care about already-running agents (future work) can still
519
+ * distinguish.
520
+ *
521
+ * Frozen at admission entry; invariants must not mutate.
522
+ */
523
+ interface AdmissionCtx {
524
+ readonly manifest: AgentManifest;
525
+ readonly activatedAgents: ReadonlyMap<string, Agent>;
526
+ readonly stagedAgents: ReadonlyMap<string, Agent>;
527
+ readonly systemCap: SystemCap;
528
+ }
529
+ /**
530
+ * Runtime event fed to invariant.observe() during agent execution.
531
+ * Discriminated by `kind` so each invariant only narrows on what it
532
+ * cares about (e.g. `harnessSelectionTiming` only inspects
533
+ * `mutation_recorded` events).
534
+ */
535
+ type RunnerEvent = {
536
+ readonly kind: 'tool_call';
537
+ readonly toolName: string;
538
+ readonly capability?: ToolCapability;
539
+ } | {
540
+ readonly kind: 'mutation_recorded';
541
+ readonly file: string;
542
+ readonly fileCount: number;
543
+ } | {
544
+ readonly kind: 'handoff_taken';
545
+ readonly target: string;
546
+ } | {
547
+ readonly kind: 'revise_count';
548
+ readonly harness: string;
549
+ readonly count: number;
550
+ } | {
551
+ readonly kind: 'evidence_added';
552
+ readonly artifactPath: string;
553
+ };
554
+ /**
555
+ * Read-only view of the per-run mutation tracker. Invariant observe hooks
556
+ * may inspect but never mutate. (The full @kodax-ai/coding mutation tracker
557
+ * has additional fields like per-file line deltas — those are the coding
558
+ * package's concern, not the Layer A primitive.)
559
+ */
560
+ interface ReadonlyMutationTracker {
561
+ readonly files: ReadonlySet<string>;
562
+ readonly totalOps: number;
563
+ }
564
+ /**
565
+ * Recorder slice exposed to observe hooks for cross-event correlation.
566
+ * Kept minimal — invariants that need richer state should manage their
567
+ * own per-instance counters and use the recorder only for shared
568
+ * "did Scout commit a harness verdict yet?" signal.
569
+ */
570
+ interface ReadonlyRecorder {
571
+ readonly scout?: {
572
+ readonly payload?: {
573
+ readonly scout?: {
574
+ readonly confirmedHarness?: string;
575
+ };
576
+ };
577
+ };
578
+ }
579
+ interface ObserveCtx {
580
+ readonly manifest: AgentManifest;
581
+ readonly mutationTracker: ReadonlyMutationTracker;
582
+ readonly recorder: ReadonlyRecorder;
583
+ }
584
+ /**
585
+ * Terminal-time deliverable inspected by invariant.assertTerminal hooks.
586
+ *
587
+ * `verdict` is set when an Evaluator role emitted a verdict; undefined
588
+ * for H0 runs that bypass evaluation. `evidenceArtifacts` enumerates the
589
+ * artifact files produced during the run (per-mutation evidence,
590
+ * verification reports, etc.).
591
+ */
592
+ interface Deliverable {
593
+ readonly evidenceArtifacts: readonly string[];
594
+ readonly verdict?: 'accept' | 'revise' | 'blocked';
595
+ readonly mutationCount: number;
596
+ }
597
+ interface TerminalCtx {
598
+ readonly manifest: AgentManifest;
599
+ readonly deliverable: Deliverable;
600
+ }
601
+ /**
602
+ * Quality Invariant declaration. An invariant declares which of the three
603
+ * hook points it implements (admit / observe / assertTerminal) — at least
604
+ * one of the three must be present.
605
+ *
606
+ * Invariants are registered to the runtime via `registerInvariant()` (in
607
+ * `./admission.ts` once Runner.admit lands). The runtime maintains a
608
+ * static registry indexed by `InvariantId`; `Runner.admit` resolves the
609
+ * required set per (role, toolScope, harnessTier) tuple and applies all
610
+ * relevant admit hooks.
611
+ *
612
+ * Invariants must be pure functions of their inputs. Side effects
613
+ * (writing trace, sending events) happen in the Runner shell, not inside
614
+ * the invariant body.
615
+ */
616
+ interface QualityInvariant {
617
+ readonly id: InvariantId;
618
+ readonly description: string;
619
+ admit?(manifest: AgentManifest, ctx: AdmissionCtx): InvariantResult;
620
+ observe?(event: RunnerEvent, ctx: ObserveCtx): InvariantResult;
621
+ assertTerminal?(deliverable: Deliverable, ctx: TerminalCtx): InvariantResult;
622
+ }
623
+ /**
624
+ * Opaque handle produced by `Runner.admit()` on success. Required input
625
+ * to `ConstructionRuntime.activate()` — prevents activate from being
626
+ * called on a manifest that hasn't gone through admission.
627
+ *
628
+ * `appliedPatches` records every clamp the admission applied; consumers
629
+ * can inspect to surface "what was modified vs the manifest you submitted".
630
+ * `invariantBindings` lists the invariants registered against this
631
+ * admitted agent (effective set = required ∪ declared).
632
+ */
633
+ interface AdmittedHandle {
634
+ readonly manifest: AgentManifest;
635
+ readonly admittedAt: string;
636
+ readonly appliedPatches: readonly ManifestPatch[];
637
+ readonly invariantBindings: readonly InvariantId[];
638
+ }
639
+ /**
640
+ * Admission verdict — discriminated union so TypeScript can narrow
641
+ * `handle` (only present on success) vs `reason` (only on failure).
642
+ *
643
+ * `retryable` on failure indicates whether the generator should be asked
644
+ * to fix and retry (schema invalid / DAG cycle) vs hard reject (system
645
+ * cap violated past clamp tolerance).
646
+ */
647
+ type AdmissionVerdict = {
648
+ readonly ok: true;
649
+ readonly handle: AdmittedHandle;
650
+ readonly clampNotes: readonly string[];
651
+ } | {
652
+ readonly ok: false;
653
+ readonly reason: string;
654
+ readonly retryable: boolean;
655
+ };
656
+
657
+ /**
658
+ * FEATURE_101 admission audit — the 5-step process `Runner.admit` runs
659
+ * against an untrusted manifest.
660
+ *
661
+ * Pure orchestration of the building blocks declared elsewhere in
662
+ * @kodax-ai/core:
663
+ *
664
+ * 1. **Schema validation** — manifest has well-formed name, instructions,
665
+ * tools, declaredInvariants, requestedToolCapabilities. Fail-fast on
666
+ * shape errors (no clamps).
667
+ * 2. **Resolve effective invariants** — required (system policy) ∪
668
+ * declared (manifest voluntary). Required is computed from
669
+ * role / toolScope / harnessTier; declared can only ADD.
670
+ * 3. **Run admit hooks** — for each effective invariant that has an
671
+ * admit hook registered, call it with the (manifest, ctx) tuple.
672
+ * Collect reject / clamp / warn results.
673
+ * 4. **Compose patches** — clamp-severity results carry patches; we
674
+ * compose them with `composePatches` (min-wins for clamps, union
675
+ * for collections).
676
+ * 5. **Apply patches** — `applyManifestPatch` produces the final
677
+ * admitted manifest. Reject results short-circuit before this step.
678
+ *
679
+ * Returns an `AdmissionVerdict` discriminated union — `ok: true` carries
680
+ * the `AdmittedHandle` plus `clampNotes`; `ok: false` carries `reason`
681
+ * and the `retryable` flag.
682
+ *
683
+ * Pure function (no I/O, no logging). The Runner shell is responsible
684
+ * for tracing / observability around this call.
685
+ */
686
+
687
+ /**
688
+ * Default system cap — high ceilings so admission only clamps when
689
+ * deployments have explicitly declared tighter limits. The numbers
690
+ * mirror the legacy `runManagedTask` budget defaults so this is a
691
+ * compatibility-preserving baseline, not a policy tightening.
692
+ */
693
+ declare const DEFAULT_SYSTEM_CAP: SystemCap;
694
+ /**
695
+ * Options accepted by `runAdmissionAudit` (and surfaced by `Runner.admit`).
696
+ * All fields are optional — the audit substitutes safe defaults so the
697
+ * SDK call surface stays a single positional argument: the manifest.
698
+ */
699
+ interface AdmissionAuditOptions {
700
+ readonly systemCap?: SystemCap;
701
+ readonly activatedAgents?: ReadonlyMap<string, Agent>;
702
+ /**
703
+ * FEATURE_101 v0.7.31.1 — same-batch staged agents. Manifests that
704
+ * have been staged but not yet activated still need to participate
705
+ * in `handoffLegality` cycle detection: a generator that writes A
706
+ * (handoff to B) and B (handoff to A) in the same batch sees neither
707
+ * activated when admission runs on each individually. With
708
+ * `stagedAgents` populated, the second admission detects the back
709
+ * edge to the first and rejects.
710
+ *
711
+ * Sourced from `ConstructionRuntime` which builds a Map of
712
+ * staged-status manifests at the call site.
713
+ */
714
+ readonly stagedAgents?: ReadonlyMap<string, Agent>;
715
+ /**
716
+ * Agent role identifier — opaque string from the agent layer's perspective.
717
+ * Concrete agent presets (e.g. coding's AMA harness with 'scout' / 'planner' /
718
+ * 'generator' / 'evaluator' / 'direct') brand this themselves; the admission
719
+ * framework only plumbs it through to `resolveRequiredInvariants`.
720
+ * v0.7.35.1 FEATURE_142: widened from coding-AMA literal union per ADR-021
721
+ * (agent layer must not enumerate coding-specific role names).
722
+ */
723
+ readonly role?: string;
724
+ readonly toolScope?: readonly string[];
725
+ /**
726
+ * Harness tier identifier — opaque string. Concrete agent presets brand it
727
+ * (e.g. coding's 'H0_DIRECT' / 'H1_EXECUTE_EVAL' / 'H2_PLAN_EXECUTE_EVAL').
728
+ * v0.7.35.1 FEATURE_142: widened from coding-AMA literal union per ADR-021.
729
+ */
730
+ readonly harnessTier?: string;
731
+ /**
732
+ * ISO timestamp recorded on the AdmittedHandle. Defaults to
733
+ * `new Date().toISOString()` — overridable so tests can pin a value.
734
+ */
735
+ readonly nowIso?: string;
736
+ }
737
+ /**
738
+ * Scan an instructions string for known prompt-injection patterns.
739
+ * Returns the first matching pattern id or undefined when clean.
740
+ */
741
+ declare function detectInstructionsInjection(text: string): string | undefined;
742
+ /**
743
+ * Run the admission audit against an untrusted manifest. Returns an
744
+ * `AdmissionVerdict` — never throws (errors are encoded in the verdict).
745
+ *
746
+ * Pure function: same inputs always return equivalent outputs (modulo
747
+ * the `nowIso` timestamp, which can be pinned via options).
748
+ */
749
+ declare function runAdmissionAudit(manifest: AgentManifest, options?: AdmissionAuditOptions): AdmissionVerdict;
750
+
751
+ /**
752
+ * FEATURE_101 (v0.7.31.1) — admission session: runtime dispatch of
753
+ * `observe` and `assertTerminal` invariant hooks.
754
+ *
755
+ * The v0.7.31 release shipped only the `admit` hook wired into
756
+ * `Runner.admit`. The three-segment hook model (admit / observe /
757
+ * assertTerminal) declared in FEATURE_101 §三段 hook 模型 had its
758
+ * other two thirds defined as types but never invoked at runtime —
759
+ * meaning every invariant that depended on observe / terminal
760
+ * (`evidenceTrail`, `independentReview`, `boundedRevise`,
761
+ * `harnessSelectionTiming`) was effectively dormant after admission.
762
+ *
763
+ * This module fills that gap with two pieces:
764
+ *
765
+ * 1. A WeakMap-backed binding registry (`setAdmittedAgentBindings` /
766
+ * `getAdmittedAgentBindings`) so `Runner.run` can recover the
767
+ * InvariantId set associated with an admitted agent without a
768
+ * compile-time dependency from `agent.ts` onto `admission.ts`
769
+ * (which would re-introduce the import cycle the original split
770
+ * avoided).
771
+ * 2. `InvariantSession`: a per-run event router. The Runner creates
772
+ * one when an agent has bindings, and threads `record*` calls
773
+ * through it during the run. The session dispatches observe to
774
+ * bound invariants and accumulates violations; assertTerminal
775
+ * runs once at end.
776
+ *
777
+ * Pure runtime — no I/O. The session does not log or trace; the Runner
778
+ * shell decides what to do with returned violation results
779
+ * (typically: trace span for `warn`, throw for `reject`, accumulate
780
+ * patches for `clamp` though clamp is admit-time only).
781
+ */
782
+
783
+ /**
784
+ * Associate an admitted manifest's invariant bindings with the runtime
785
+ * Agent the consumer uses. Set by `ConstructionRuntime.activate` after
786
+ * `Runner.admit` succeeds; SDK consumers calling `Runner.run` directly
787
+ * on hand-authored Agents leave this unset and skip runtime invariant
788
+ * dispatch entirely.
789
+ */
790
+ declare function setAdmittedAgentBindings(agent: Agent, manifest: AgentManifest, bindings: readonly InvariantId[]): void;
791
+ /**
792
+ * Look up bindings for an agent. Returns undefined when the agent was
793
+ * never admitted (trusted SDK / preset path).
794
+ */
795
+ declare function getAdmittedAgentBindings(agent: Agent): {
796
+ readonly bindings: readonly InvariantId[];
797
+ readonly manifest: AgentManifest;
798
+ } | undefined;
799
+ /**
800
+ * Test-only — clears the registry. Production code should never call
801
+ * this; the WeakMap entries are reclaimed naturally when agents fall
802
+ * out of scope.
803
+ */
804
+ declare function _resetAdmittedAgentBindings(agent: Agent): void;
805
+ /**
806
+ * Severity surface returned by `recordX` calls. A `reject` from
807
+ * observe means the run must abort; the Runner shell raises an error.
808
+ * A `warn` is informational — the Runner records it but continues.
809
+ * `ok` is the no-op success case.
810
+ */
811
+ interface SessionDispatchResult {
812
+ readonly results: readonly {
813
+ readonly id: InvariantId;
814
+ readonly result: InvariantResult;
815
+ }[];
816
+ }
817
+ /**
818
+ * Per-run state machine + event router. Constructed once at the start
819
+ * of a run (inside `Runner.run`) when the start agent has bindings.
820
+ * The Runner threads tool / handoff / mutation events through the
821
+ * `record*` API; the session fans them out to bound invariants.
822
+ *
823
+ * Threading rules (so the data stays valid):
824
+ * - `recordX` calls return synchronously; observe hooks are pure
825
+ * functions of the immutable event payload + read-only context.
826
+ * - `assertTerminal` must be called exactly once at run end. The
827
+ * Runner is responsible for honoring this.
828
+ * - The session is single-run; spawning a sub-run (handoff /
829
+ * dispatch_child_task) creates a fresh session for the target.
830
+ *
831
+ * The session is never exposed across module boundaries — it lives in
832
+ * the Runner closure and dies when the run ends. WeakMap is overkill
833
+ * for state that is by-construction scoped; plain fields suffice.
834
+ */
835
+ declare class InvariantSession {
836
+ private readonly bindings;
837
+ private readonly manifest;
838
+ private readonly mutations;
839
+ private readonly recorder;
840
+ private verdict;
841
+ private readonly evidenceArtifacts;
842
+ private readonly violations;
843
+ private terminalRan;
844
+ constructor(bindings: readonly InvariantId[], manifest: AgentManifest);
845
+ recordToolCall(toolName: string, capability?: ToolCapability): SessionDispatchResult;
846
+ recordHandoff(target: string): SessionDispatchResult;
847
+ /**
848
+ * Record a file mutation. `fileCount` is the cumulative distinct-file
849
+ * total (mirrors `harnessSelectionTiming` ObserveCtx contract). The
850
+ * session computes it from its internal MutableMutationTracker so
851
+ * callers don't need to track it.
852
+ */
853
+ recordMutation(file: string): SessionDispatchResult;
854
+ recordEvidence(artifactPath: string): SessionDispatchResult;
855
+ recordRevise(harness: string, count: number): SessionDispatchResult;
856
+ /**
857
+ * Record the Scout's confirmed-harness signal — drives
858
+ * `harnessSelectionTiming.observe`'s "did Scout commit a harness
859
+ * verdict yet?" check. Coding-side surface invokes this after the
860
+ * scout role emits its verdict.
861
+ */
862
+ setConfirmedHarness(harness: string): void;
863
+ setVerdict(verdict: 'accept' | 'revise' | 'blocked'): void;
864
+ /** @internal Test inspection + Runner trace surface. */
865
+ getViolations(): readonly {
866
+ readonly id: InvariantId;
867
+ readonly result: InvariantResult;
868
+ }[];
869
+ getMutationCount(): number;
870
+ getEvidenceArtifacts(): readonly string[];
871
+ /**
872
+ * Run all bound invariants' `assertTerminal` hooks. Caller must
873
+ * invoke exactly once; subsequent calls are no-ops (returns the
874
+ * accumulated violations from the first call). Returns the
875
+ * union of violations gathered during observe + this terminal pass.
876
+ */
877
+ assertTerminal(): SessionDispatchResult;
878
+ private dispatchObserve;
879
+ }
880
+ /**
881
+ * Construct a session for an agent if it has admission bindings, or
882
+ * return undefined for trusted (un-admitted) agents — the Runner
883
+ * checks the return value and skips invariant dispatch entirely when
884
+ * undefined, keeping the trusted-path zero-overhead.
885
+ */
886
+ declare function createInvariantSessionForAgent(agent: Agent): InvariantSession | undefined;
887
+
888
+ /**
889
+ * Layer A Primitive: Runner
890
+ *
891
+ * FEATURE_080 (v0.7.23): minimal execution entry for an `Agent`.
892
+ *
893
+ * Two dispatch paths:
894
+ * 1. **Preset dispatch** (the "default coding agent" registers via
895
+ * `registerPresetDispatcher`): delegates to the existing `runKodaX`
896
+ * implementation so SA users see zero behavior change. This is the
897
+ * "Option Y" dog-food wiring negotiated during FEATURE_080+081 design.
898
+ * 2. **Generic dispatch**: for user-defined agents. Performs a single
899
+ * system+user → assistant turn using an injected LLM callback. No tool
900
+ * loop, no extensions, no managed-task harness — those arrive with
901
+ * FEATURE_084 (v0.7.26).
902
+ *
903
+ * Status: @experimental. History: extracted to `@kodax-ai/core` in FEATURE_082
904
+ * (v0.7.24); merged back into `@kodax-ai/agent` in v0.7.35.1 FEATURE_142.
905
+ * `@kodax-ai/coding` retains a barrel re-export for batteries-included consumers.
906
+ */
907
+
908
+ /**
909
+ * Options accepted by `Runner.run` and `Runner.runStream`.
910
+ */
911
+ interface RunOptions {
912
+ /**
913
+ * Opaque payload forwarded to the preset dispatcher when one matches.
914
+ * For the built-in coding preset this carries `KodaXOptions`.
915
+ */
916
+ readonly presetOptions?: unknown;
917
+ /**
918
+ * LLM callback used by the generic dispatch path. Receives the assembled
919
+ * message transcript and the current Agent.
920
+ *
921
+ * Return a plain `string` to preserve the v0.7.23 single-turn behaviour
922
+ * (no tool loop). Return a `RunnerLlmResult` with `toolCalls` to opt into
923
+ * the FEATURE_084 tool loop — the Runner will execute each call against
924
+ * the agent's `RunnableTool`s, append tool_use + tool_result blocks to
925
+ * the transcript, and invoke this callback again until no tool calls are
926
+ * returned (or `MAX_TOOL_LOOP_ITERATIONS` is reached).
927
+ */
928
+ readonly llm?: (messages: readonly AgentMessage[], agent: Agent) => Promise<RunnerLlmReturn>;
929
+ /**
930
+ * Optional Session to persist the generic-path transcript into. When
931
+ * supplied, each generated message is appended as a `message` entry.
932
+ */
933
+ readonly session?: Session;
934
+ /**
935
+ * Abort signal forwarded to preset dispatchers that honor it.
936
+ */
937
+ readonly abortSignal?: AbortSignal;
938
+ /**
939
+ * FEATURE_083 (v0.7.24): tracer used to record AgentSpan / GenerationSpan /
940
+ * ToolCallSpan / HandoffSpan for this run. Defaults to `defaultTracer` when
941
+ * omitted. Pass `null` to disable tracing for this call.
942
+ */
943
+ readonly tracer?: Tracer | null;
944
+ /**
945
+ * When supplied, the run attaches its AgentSpan as a child of this trace's
946
+ * root span instead of starting a new trace. Useful when an outer Agent
947
+ * is orchestrating sub-runs and wants one trace per user request.
948
+ */
949
+ readonly trace?: Trace;
950
+ /**
951
+ * FEATURE_085 (v0.7.26): run-scoped guardrails. Merged with
952
+ * `agent.guardrails` — declaration order is agent-first, then opts.
953
+ * Input / output / tool-before / tool-after hooks all dispatch from
954
+ * this union. See `@kodax-ai/agent/primitives/guardrail.ts` for shape.
955
+ */
956
+ readonly guardrails?: readonly Guardrail[];
957
+ /**
958
+ * Per-run override for the tool-loop iteration cap. When omitted, the
959
+ * loop uses `MAX_TOOL_LOOP_ITERATIONS` (20) — a safe ceiling for
960
+ * stand-alone agent runs. Managed-task orchestration (multi-role
961
+ * handoff chain: Scout → Planner → Generator → Evaluator) needs a much
962
+ * higher cap because the iteration counter is shared across every
963
+ * role in the chain. Legacy `runManagedTask` gave each role its own
964
+ * `DEFAULT_MANAGED_WORK_BUDGET` (200) — the Runner-driven path passes
965
+ * that value here so long investigations don't trip the safety valve
966
+ * after ~20 tool calls.
967
+ */
968
+ readonly maxToolLoopIterations?: number;
969
+ /**
970
+ * v0.7.26 parity: observer callbacks fired around every tool
971
+ * invocation. Legacy `runManagedTask` emitted `events.onToolResult`
972
+ * at three sites per invocation so the REPL worker ledger could
973
+ * render live tool-call progress — without this plumbing, the
974
+ * Runner-driven path's UI shows only the final output. Preset
975
+ * dispatchers can attach this observer to surface `onToolCall` /
976
+ * `onToolResult` through the usual `KodaXEvents` bus.
977
+ */
978
+ readonly toolObserver?: RunnerToolObserver;
979
+ /**
980
+ * v0.7.26 parity: compaction hook. Called AFTER each iteration's
981
+ * tool_result has been appended to the transcript (or after the
982
+ * assistant message when there are no tool calls), before the next
983
+ * LLM turn. Return the replacement transcript to trigger compaction;
984
+ * return the same array (or undefined) to skip. Legacy agent.ts ran
985
+ * `intelligentCompact` on the same boundary, so Runner-driven parity
986
+ * requires this hook point. The Runner owns the transcript mutably,
987
+ * so this is the only point consumers can insert a compacted view.
988
+ */
989
+ readonly compactionHook?: (transcript: readonly AgentMessage[]) => Promise<readonly AgentMessage[] | undefined>;
990
+ /**
991
+ * FEATURE_101 (v0.7.31.1): callback fired once when the Runner has
992
+ * resolved invariant bindings on the start agent and created an
993
+ * `InvariantSession` for the run. Coding-side consumers (mutation
994
+ * tracker, verdict recorder, evidence trail) bind to the session
995
+ * here so per-tool event recording and verdict propagation flow
996
+ * into observe / assertTerminal hooks.
997
+ *
998
+ * Trusted (un-admitted) agents skip session creation entirely —
999
+ * this callback is never fired for them. The "auto-created
1000
+ * session" path keeps SDK consumers from having to instantiate
1001
+ * sessions themselves while still letting them observe.
1002
+ */
1003
+ readonly onInvariantSessionStarted?: (session: InvariantSession) => void;
1004
+ /**
1005
+ * FEATURE_101 (v0.7.31.1): pluggable tool capability classifier.
1006
+ * Runner calls this on every tool invocation (after Guardrail
1007
+ * before-hooks but before the actual execution); when present, the
1008
+ * returned `ToolCapability` is attached to the `tool_call` event
1009
+ * dispatched to `invariant.observe` hooks. Without a classifier
1010
+ * the event omits the capability field — invariants that key on
1011
+ * capability gracefully fall back to "unknown capability" semantics.
1012
+ *
1013
+ * The coding package wires `resolveToolCapability` from
1014
+ * `agent-runtime/invariants/tool-permission.ts` here.
1015
+ */
1016
+ readonly capabilityClassifier?: (toolName: string) => ToolCapability | undefined;
1017
+ /**
1018
+ * FEATURE_101 (v0.7.31.1): runtime tool capability re-clamp.
1019
+ *
1020
+ * Admission's `toolPermission` invariant clamps an admitted manifest's
1021
+ * tools to `system_cap.allowedToolCapabilities` at activation time.
1022
+ * That covers "agent declared a tool the system never allows", but
1023
+ * NOT the runtime case where a parent run is itself capped lower
1024
+ * than system_cap and dispatches a sub-agent. The design's two-stage
1025
+ * clamp model wants the parent's narrower set to apply to every
1026
+ * tool call inside the sub-run.
1027
+ *
1028
+ * When this option is set AND the start agent has admission bindings,
1029
+ * Runner.run filters every tool invocation through `capabilityClassifier`
1030
+ * and rejects calls whose capability tier is not in the parent set.
1031
+ * Rejection materializes as an error tool_result so the LLM can
1032
+ * observe the clamp and recover. Trusted (un-admitted) agents are
1033
+ * NOT clamped — the parent passes them as-is by design (admission
1034
+ * trust = runtime trust).
1035
+ */
1036
+ readonly parentToolCapabilities?: readonly ToolCapability[];
1037
+ /**
1038
+ * FEATURE_164 (v0.7.41) — mid-turn message injection hook.
1039
+ *
1040
+ * Called AFTER tool execution + compaction + handoff handling have
1041
+ * completed for the current iteration, but BEFORE the next iteration's
1042
+ * `runGenerationTurn` starts. The hook returns an array of additional
1043
+ * messages (typically user-role prompts the caller wants to splice in)
1044
+ * which the Runner pushes to the transcript and Session before the
1045
+ * next LLM call.
1046
+ *
1047
+ * Designed to support claudecode-style "chat-while-waiting": when the
1048
+ * user types a new query while the agent is mid-task, the caller's
1049
+ * hook can drain the input queue and inject it as a user message at
1050
+ * the tool-result boundary — Worker continues its loop, the LLM
1051
+ * sees the new user message in its next call, and no empty turn is
1052
+ * emitted. Replaces the legacy "return `{text: '', toolCalls: []}`"
1053
+ * pattern that polluted the transcript with an empty assistant turn.
1054
+ *
1055
+ * The hook fires only when the current iteration ran tool calls (the
1056
+ * terminal-no-tool branch returns before reaching here). Empty return
1057
+ * value is the no-op fast path. Returning a transcript-replacement
1058
+ * is intentionally NOT supported — callers wanting that semantic
1059
+ * should use `compactionHook` instead.
1060
+ */
1061
+ readonly beforeNextTurn?: (ctx: {
1062
+ readonly agent: Agent;
1063
+ readonly transcript: readonly AgentMessage[];
1064
+ readonly iteration: number;
1065
+ }) => Promise<readonly AgentMessage[]>;
1066
+ /**
1067
+ * FEATURE_166 (v0.7.41 follow-up) — agent-switch hook.
1068
+ *
1069
+ * Fires AFTER `currentAgent` has been swapped to the handoff target
1070
+ * (`handoffSignal.to`) AND after the transcript inputFilter +
1071
+ * system-message replacement have run, but BEFORE the next
1072
+ * iteration's `runGenerationTurn`. Lets callers react to a role
1073
+ * transition between
1074
+ * turns — most notably the coding observer, which uses this signal to
1075
+ * flip the REPL's `activeWorkerTitle` ahead of the new agent's first
1076
+ * streaming output (without this hook, the label only flips when the
1077
+ * new agent's first slot-tool succeeds, so the label LAGS through
1078
+ * Evaluator's thinking / pre-verdict text and any verification
1079
+ * tool calls; production session 20260515_185354 trace confirms).
1080
+ *
1081
+ * Awaitable so callers can perform async side effects (e.g. flushing
1082
+ * a status emit through an event bus). Errors propagate verbatim —
1083
+ * the hook is caller-controlled, matching `beforeNextTurn` semantics.
1084
+ *
1085
+ * Fires at most once per iteration (only the first matching handoff
1086
+ * in a tool-result batch transitions ownership; see line ~782).
1087
+ */
1088
+ readonly onAgentSwitched?: (ctx: {
1089
+ readonly from: Agent;
1090
+ readonly to: Agent;
1091
+ readonly iteration: number;
1092
+ }) => void | Promise<void>;
1093
+ }
1094
+ /**
1095
+ * Result returned by `Runner.run`.
1096
+ */
1097
+ interface RunResult<TData = unknown> {
1098
+ readonly output: string;
1099
+ readonly messages: readonly AgentMessage[];
1100
+ readonly sessionId?: string;
1101
+ readonly data?: TData;
1102
+ }
1103
+ /**
1104
+ * Stream events emitted by `Runner.runStream`. The event surface is
1105
+ * intentionally small in v0.7.23; FEATURE_084 expands it to mirror the
1106
+ * task-engine's event set.
1107
+ */
1108
+ type RunEvent<TData = unknown> = {
1109
+ readonly kind: 'message';
1110
+ readonly message: AgentMessage;
1111
+ } | {
1112
+ readonly kind: 'complete';
1113
+ readonly result: RunResult<TData>;
1114
+ } | {
1115
+ readonly kind: 'error';
1116
+ readonly error: Error;
1117
+ };
1118
+ /**
1119
+ * Tracing context handed to preset dispatchers so they can attach richer
1120
+ * spans (e.g. GenerationSpan, ToolCallSpan) under the Runner's AgentSpan.
1121
+ *
1122
+ * FEATURE_083 (v0.7.24): added in Slice 8 to let the coding preset emit
1123
+ * the AgentSpan lifecycle under the same trace as the Runner entry point.
1124
+ */
1125
+ interface PresetTracingContext {
1126
+ readonly tracer: Tracer;
1127
+ readonly trace: Trace;
1128
+ readonly agentSpan: Span;
1129
+ }
1130
+ /**
1131
+ * Preset dispatcher signature. Registered via `registerPresetDispatcher` and
1132
+ * keyed on `Agent.name`. The optional fourth argument carries tracing
1133
+ * context created by the Runner; dispatchers may emit child spans under
1134
+ * `tracingContext.agentSpan`.
1135
+ */
1136
+ type PresetDispatcher = (agent: Agent, input: string | readonly AgentMessage[], opts: RunOptions | undefined, tracingContext?: PresetTracingContext) => Promise<RunResult>;
1137
+ /**
1138
+ * Register a preset dispatcher for a given Agent name. The coding package
1139
+ * registers the `runKodaX` dispatcher for the default coding agent on
1140
+ * import of `createDefaultCodingAgent`.
1141
+ *
1142
+ * Returns an unregister function.
1143
+ */
1144
+ declare function registerPresetDispatcher(agentName: string, dispatcher: PresetDispatcher): () => void;
1145
+ /** @internal Testing helper. Do not rely on this from application code. */
1146
+ declare function _resetPresetDispatchers(): void;
1147
+ /**
1148
+ * Wrap a role-spec string in the trusted/untrusted boundary admission
1149
+ * applies to admitted (constructed) agents. Exported so the FEATURE_104
1150
+ * benchmark dataset (`benchmark/datasets/admission-wrap-baseline/`) can
1151
+ * use the production wrap text verbatim — preventing drift between the
1152
+ * Q6 non-degradation eval and the actual Runner behavior.
1153
+ *
1154
+ * `agent` selects the path: agents with admission bindings get the
1155
+ * full wrap; trusted agents pass through unchanged. Callers wanting the
1156
+ * wrap unconditionally (e.g. for test harnessing) should pass an agent
1157
+ * whose bindings are populated via `setAdmittedAgentBindings`.
1158
+ */
1159
+ declare function buildSystemPrompt(agent: Agent, instructions: string): string;
1160
+ /**
1161
+ * Minimal execution entry for an `Agent`.
1162
+ */
1163
+ declare class Runner {
1164
+ /**
1165
+ * Run an agent to completion. Resolves with the final output plus the
1166
+ * full transcript.
1167
+ *
1168
+ * FEATURE_083 (v0.7.24): emits an AgentSpan around every run and a
1169
+ * GenerationSpan around the underlying LLM call in the generic path.
1170
+ * Preset dispatchers receive a `PresetTracingContext` so they can attach
1171
+ * richer spans under the AgentSpan. Pass `opts.tracer = null` to skip
1172
+ * tracing entirely for performance-sensitive calls.
1173
+ */
1174
+ static run<TData = unknown>(agent: Agent, input: string | readonly AgentMessage[], opts?: RunOptions): Promise<RunResult<TData>>;
1175
+ /**
1176
+ * FEATURE_101 (v0.7.31): admit an untrusted `AgentManifest` against the
1177
+ * admission contract. Returns an `AdmissionVerdict` — `{ ok: true,
1178
+ * handle, clampNotes }` on admission, `{ ok: false, reason, retryable }`
1179
+ * on schema/invariant rejection.
1180
+ *
1181
+ * `Runner.admit` is the single gate between an LLM-emitted manifest and
1182
+ * an executable Agent. The caller MUST receive an admitted handle
1183
+ * before invoking `Runner.run` on any LLM-constructed agent (FEATURE_089
1184
+ * agent-generation enforces this via the activate handle plumbing in
1185
+ * v0.7.31; SDK consumers calling `Runner.run` on hand-authored Agents
1186
+ * are trusted by definition and skip admission).
1187
+ *
1188
+ * Pure delegation to `runAdmissionAudit` — invariants are resolved from
1189
+ * the shared module-scope registry (registered via
1190
+ * `registerCoreInvariants()` and the @kodax-ai/coding capability-coupled
1191
+ * invariants). The runtime stays sync (no I/O); `async` is reserved
1192
+ * for future versions that may need to consult external policy stores.
1193
+ *
1194
+ * @experimental
1195
+ */
1196
+ static admit(manifest: AgentManifest, options?: AdmissionAuditOptions): Promise<AdmissionVerdict>;
1197
+ /**
1198
+ * Streaming variant. v0.7.23 emits a single `complete` event after
1199
+ * delegating to `run`; richer intermediate events land with FEATURE_084.
1200
+ */
1201
+ static runStream<TData = unknown>(agent: Agent, input: string | readonly AgentMessage[], opts?: RunOptions): AsyncIterable<RunEvent<TData>>;
1202
+ }
1203
+ /** @internal Exposed so preset dispatchers can extract the assistant text from a KodaXResult. */
1204
+ declare function extractAssistantTextFromMessage(message: AgentMessage): string;
1205
+
1206
+ /**
1207
+ * History cleanup middleware — CAP-002
1208
+ *
1209
+ * Capability inventory: docs/features/v0.7.29-capability-inventory.md#cap-002
1210
+ *
1211
+ * Two pure functions that maintain the assistant↔user `tool_use`/`tool_result`
1212
+ * pairing invariant the provider expects. Both functions take a message array
1213
+ * and return a new array (immutable — never mutate the input).
1214
+ *
1215
+ * - `cleanupIncompleteToolCalls`: when a stream is interrupted mid-flight,
1216
+ * the last assistant message may carry orphan `tool_use` blocks with no
1217
+ * matching `tool_result`. The next provider call would 400 with
1218
+ * "tool_call_id not found". This function strips those orphans before
1219
+ * the next request.
1220
+ *
1221
+ * - `validateAndFixToolHistory`: deeper pass that walks the full message
1222
+ * history and fixes mis-pairings on both sides — orphan `tool_use` in
1223
+ * assistant messages, orphan `tool_result` in user messages, and ensures
1224
+ * no message becomes empty after stripping (Kimi specifically rejects
1225
+ * empty assistant messages with 400, so we inject a `'...'` placeholder
1226
+ * when stripping would empty an assistant message).
1227
+ *
1228
+ * Migration history: extracted from `agent.ts` (originally lines 517–758)
1229
+ * during FEATURE_100 P2. Both `agent.ts` and `task-engine/runner-driven.ts`
1230
+ * already consume these via the package re-export (`@kodax-ai/coding`).
1231
+ *
1232
+ * Type guards are inlined here rather than imported from agent.ts because
1233
+ * the migration's whole point is to remove dependencies on agent.ts. If
1234
+ * additional agent-runtime modules need the same guards in the future,
1235
+ * extract them to `agent-runtime/content-blocks.ts`.
1236
+ */
1237
+
1238
+ /**
1239
+ * Walk the message history and remove mis-paired `tool_use` / `tool_result`
1240
+ * blocks. Preserves message order and structure; never mutates input.
1241
+ *
1242
+ * Rules enforced:
1243
+ * - assistant `tool_use` with no matching `tool_result` in the next user
1244
+ * message → removed
1245
+ * - assistant `tool_use` with empty / missing id → removed
1246
+ * - user `tool_result` with no matching assistant `tool_use` in the previous
1247
+ * message → removed
1248
+ * - user `tool_result` with empty / missing tool_use_id → removed
1249
+ * - assistant message that becomes content-empty after stripping → inject
1250
+ * a `'...'` placeholder text block (preserves message-alternation invariant
1251
+ * downstream providers like Kimi require)
1252
+ */
1253
+ declare function validateAndFixToolHistory(messages: KodaXMessage[]): KodaXMessage[];
1254
+ /**
1255
+ * Strip orphan `tool_use` blocks from the LAST assistant message only.
1256
+ *
1257
+ * Used as a quick pre-stream guard when a previous turn was interrupted
1258
+ * (Issue 072): the last assistant message has unanswered tool_use blocks,
1259
+ * and the next provider request would 400 with "tool_call_id not found".
1260
+ *
1261
+ * Cheaper than `validateAndFixToolHistory` because it only touches the tail.
1262
+ */
1263
+ declare function cleanupIncompleteToolCalls(messages: KodaXMessage[]): KodaXMessage[];
1264
+
1265
+ export { cleanupIncompleteToolCalls as $, DEFAULT_SYSTEM_CAP as D, Runner as G, KODAX_API_MIN_INTERVAL as K, PROMISE_PATTERN as P, _resetPresetDispatchers as Y, buildSystemPrompt as Z, _resetAdmittedAgentBindings as _, countTokens as a0, createInMemorySession as a1, createInvariantSessionForAgent as a2, detectInstructionsInjection as a3, estimateTokens as a4, extractAssistantTextFromMessage as a5, getAdmittedAgentBindings as a6, registerPresetDispatcher as a7, runAdmissionAudit as a8, setAdmittedAgentBindings as a9, validateAndFixToolHistory as aa, 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 };
1266
+ export type { AdmissionAuditOptions as A, RunEvent as B, CompactionContext as C, RunOptions as E, RunResult as F, RunnerEvent as H, InMemorySessionOptions as I, SessionDispatchResult as J, SessionEntry as L, ManifestPatch as M, SessionExtension as N, ObserveCtx as O, QualityInvariant as Q, ReadonlyMutationTracker as R, Session as S, SessionForkOptions as T, SystemCap as U, TerminalCtx as V, ToolCapability as W, ToolPermission as X, AdmissionCtx as a, 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, MessageEntry as v, PolicyCompactionResult as w, PresetDispatcher as x, PresetTracingContext as y, ReadonlyRecorder as z };