@kodax-ai/kodax 0.7.62 → 0.7.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2300 -2145
- package/README.md +81 -9
- package/README_CN.md +54 -5
- package/dist/chunks/{agent-4ZMCIEGD.js → agent-KER4WDNO.js} +1 -1
- package/dist/chunks/argument-completer-HK3MHA3K.js +2 -0
- package/dist/chunks/{chunk-ARUWXX25.js → chunk-35P7QL2Q.js} +1 -1
- package/dist/chunks/chunk-3HKBBY74.js +339 -0
- package/dist/chunks/chunk-AKBH2EEE.js +8 -0
- package/dist/chunks/{chunk-OGRJQGKO.js → chunk-ALS32RNZ.js} +1 -1
- package/dist/chunks/chunk-MHRN2LQV.js +328 -0
- package/dist/chunks/{chunk-JILSZHCQ.js → chunk-NBQW7PNZ.js} +2 -2
- package/dist/chunks/{chunk-S4GVQO3W.js → chunk-O7N22GJ3.js} +1 -1
- package/dist/chunks/chunk-ONUPGMER.js +2 -0
- package/dist/chunks/{chunk-ZL5CEANW.js → chunk-PZTG2C33.js} +1 -1
- package/dist/chunks/{chunk-AY3BLB4Q.js → chunk-QAQ2HNXD.js} +112 -112
- package/dist/chunks/{chunk-6OZ5KWG3.js → chunk-QJJKMNZF.js} +1 -1
- package/dist/chunks/chunk-QJVZZSEO.js +56 -0
- package/dist/chunks/chunk-TLJGOKBT.js +729 -0
- package/dist/chunks/{chunk-6HTR3GHZ.js → chunk-VS4CDDEF.js} +245 -245
- package/dist/chunks/chunk-WBBEJIAY.js +306 -0
- package/dist/chunks/{chunk-HO6P6CPU.js → chunk-WMIZCY2J.js} +1 -1
- package/dist/chunks/{chunk-UA744TZM.js → chunk-YRBNXFHY.js} +1 -1
- package/dist/chunks/compaction-config-7GMUFNPB.js +2 -0
- package/dist/chunks/{construction-bootstrap-4ZNFZFX2.js → construction-bootstrap-3XDS2D5K.js} +1 -1
- package/dist/chunks/{devtools-4CRULTR2.js → devtools-CD6KSIHE.js} +1 -1
- package/dist/chunks/{devtools-YINBSZC7.js → devtools-XR5F2C6T.js} +1 -1
- package/dist/chunks/{dist-73L4OYPD.js → dist-4PXB7U22.js} +1 -1
- package/dist/chunks/dist-4YAYT2TO.js +2 -0
- package/dist/chunks/host-KG3456QP.js +2 -0
- package/dist/chunks/{paste-FDYM7SZX.js → paste-C33GZQV5.js} +1 -1
- package/dist/chunks/run-manager-6CAH3KTA.js +2 -0
- package/dist/chunks/utils-OT5ENFUL.js +2 -0
- package/dist/constructed-handler-worker.js +2 -0
- package/dist/index.d.ts +22 -11
- package/dist/index.js +6 -6
- package/dist/kodax_cli.js +1117 -1090
- package/dist/runtime-worker.js +2843 -0
- package/dist/sdk-agent.d.ts +29 -10
- package/dist/sdk-agent.js +1 -1
- package/dist/sdk-coding.d.ts +108 -1091
- package/dist/sdk-coding.js +1 -1
- package/dist/sdk-llm.js +1 -1
- package/dist/sdk-mcp.d.ts +2 -1
- package/dist/sdk-mcp.js +1 -1
- package/dist/sdk-media.js +1 -1
- package/dist/sdk-repl.d.ts +198 -184
- package/dist/sdk-repl.js +2 -2
- package/dist/sdk-runtime.d.ts +982 -0
- package/dist/sdk-runtime.js +2 -0
- package/dist/sdk-session.d.ts +4 -4
- package/dist/sdk-session.js +1 -1
- package/dist/sdk-skills.js +1 -1
- package/dist/semantic-worker.js +191 -10
- package/dist/types-chunks/{bash-prefix-extractor.d-Do_TCAmA.d.ts → bash-prefix-extractor.d-BjkITAva.d.ts} +266 -4
- package/dist/types-chunks/{run-manager.d-CYY3pZeJ.d.ts → capsule.d-hVhPNkHd.d.ts} +9 -107
- package/dist/types-chunks/commands.d-C3B1TdGM.d.ts +213 -0
- package/dist/types-chunks/{types.d-DFf4Sfys.d.ts → guardrail.d-C_Siraua.d.ts} +3 -128
- package/dist/types-chunks/{guardrail.d-DRp0Lqvx.d.ts → guardrail.d-wk-s0psS.d.ts} +3 -3
- package/dist/types-chunks/{manager.d-DBD7SOTT.d.ts → manager.d-Zum9cGHU.d.ts} +3 -173
- package/dist/types-chunks/oauth-login.d-Bgb4rdLN.d.ts +174 -0
- package/dist/types-chunks/{process.d-DXkRD7hj.d.ts → process.d-CY2g03Mb.d.ts} +11 -4
- package/dist/types-chunks/public-api.d-jtREVfEq.d.ts +596 -0
- package/dist/types-chunks/run-manager.d-CFknOfo1.d.ts +91 -0
- package/dist/types-chunks/{sdk-session-BGGOC0cT.d.ts → sdk-session-CLqyfAmf.d.ts} +8 -304
- package/dist/types-chunks/types.d-BMLxKV69.d.ts +128 -0
- package/dist/types-chunks/types.d-CUN_bZU7.d.ts +975 -0
- package/dist/types-chunks/{utils.d-ChOEH3NF.d.ts → utils.d-C1rpoeDh.d.ts} +84 -72
- package/package.json +7 -1
- package/dist/chunks/argument-completer-5PWSKFKI.js +0 -2
- package/dist/chunks/chunk-2F4R7WM7.js +0 -52
- package/dist/chunks/chunk-3KD26NCI.js +0 -310
- package/dist/chunks/chunk-E2Q4RIOD.js +0 -731
- package/dist/chunks/chunk-S4ISEA6F.js +0 -341
- package/dist/chunks/chunk-V4WSBIXB.js +0 -2
- package/dist/chunks/chunk-WFE6FBQ2.js +0 -326
- package/dist/chunks/compaction-config-SP3REMFR.js +0 -2
- package/dist/chunks/dist-IKWRJW6J.js +0 -2
- package/dist/chunks/host-XL5CH7QP.js +0 -2
- package/dist/chunks/run-manager-UXIPDVVF.js +0 -2
- package/dist/chunks/utils-XKWEVPE3.js +0 -2
- package/dist/types-chunks/storage.d-C3umBC4g.d.ts +0 -280
|
@@ -0,0 +1,975 @@
|
|
|
1
|
+
import { a8 as KodaXWireReasoningEffort, a0 as KodaXToolDefinition, a2 as KodaXToolResultContentItem, j as KodaXMessage } from './types.d-Bp4Lm1jv.js';
|
|
2
|
+
import { K as KodaXBaseProvider } from './base.d-DalIRhbb.js';
|
|
3
|
+
import { C as CapabilityKind, a as CapabilityProvider } from './capability.d-3C62G8Eq.js';
|
|
4
|
+
import { a4 as KodaXJsonValue, U as KodaXExtensionSessionRecord, W as KodaXExtensionStore } from './process.d-CY2g03Mb.js';
|
|
5
|
+
import { aw as KodaXToolExecutionContext, bd as ToolSideEffect } from './bash-prefix-extractor.d-BjkITAva.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* KodaX Constructed-World types (FEATURE_087, v0.7.28).
|
|
9
|
+
*
|
|
10
|
+
* Runtime-generated capabilities (tools / agents / skills / ...) live in
|
|
11
|
+
* `.kodax/constructed/` and are loaded into the same registries as builtin
|
|
12
|
+
* primitives. v0.7.28 only ships tool generation (FEATURE_088); other kinds
|
|
13
|
+
* land in FEATURE_089 / FEATURE_090.
|
|
14
|
+
*
|
|
15
|
+
* Cross-references:
|
|
16
|
+
* - DD §14 — lifecycle, security model, registry merge semantics.
|
|
17
|
+
* - docs/features/v0.7.28.md — capability schema, generation flow.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Handler script source. v0.7.28 limits language to `'javascript'` so that
|
|
22
|
+
* `loadHandler()` can `await import()` the file directly without an
|
|
23
|
+
* intermediate TS → JS compile step (no esbuild / tsx dependency).
|
|
24
|
+
*
|
|
25
|
+
* TypeScript handlers are explicitly out of scope; Coding Agent generates
|
|
26
|
+
* JS strings on the wire.
|
|
27
|
+
*/
|
|
28
|
+
interface ScriptSource {
|
|
29
|
+
readonly kind: 'script';
|
|
30
|
+
readonly language: 'javascript';
|
|
31
|
+
readonly code: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Capability declaration.
|
|
35
|
+
*
|
|
36
|
+
* v0.7.28 ships the single-dimension form: a whitelist of builtin tool
|
|
37
|
+
* names that the handler may invoke through `ctx.tools.<name>(...)`.
|
|
38
|
+
* All I/O — fs / net / env — must flow through builtin tools (`read` /
|
|
39
|
+
* `write` / `bash` / etc.); handlers do not receive direct `ctx.fs` /
|
|
40
|
+
* `ctx.net` / `ctx.env` entry points.
|
|
41
|
+
*
|
|
42
|
+
* Forward-compatible evolution: if the future demands path/domain-level
|
|
43
|
+
* constraints, this can grow to `(string | { name; constraints })[]`
|
|
44
|
+
* without breaking existing manifests.
|
|
45
|
+
*/
|
|
46
|
+
interface Capabilities {
|
|
47
|
+
readonly tools: readonly string[];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Tool-kind artifact body (the `content` of `ConstructionArtifact` when
|
|
51
|
+
* `kind === 'tool'`).
|
|
52
|
+
*/
|
|
53
|
+
interface ToolContent {
|
|
54
|
+
readonly description: string;
|
|
55
|
+
readonly inputSchema: Record<string, unknown>;
|
|
56
|
+
readonly capabilities: Capabilities;
|
|
57
|
+
readonly handler: ScriptSource;
|
|
58
|
+
/**
|
|
59
|
+
* Per-tool timeout override. Defaults to {@link DEFAULT_HANDLER_TIMEOUT_MS}
|
|
60
|
+
* when omitted. Bounded by AbortController in `loadHandler()`.
|
|
61
|
+
*/
|
|
62
|
+
readonly timeoutMs?: number;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Default handler timeout. Picked to match the historical ceiling on
|
|
66
|
+
* builtin streaming tools (30s); revisit if a constructed tool demands
|
|
67
|
+
* longer-running computation.
|
|
68
|
+
*/
|
|
69
|
+
declare const DEFAULT_HANDLER_TIMEOUT_MS = 30000;
|
|
70
|
+
/**
|
|
71
|
+
* Lifecycle state on disk. Drives both the startup glob filter and the
|
|
72
|
+
* `revoke()` semantics. See DD §14.1 — file system is the single source
|
|
73
|
+
* of truth; no separate `_manifest.json` index file (C4 decision).
|
|
74
|
+
*/
|
|
75
|
+
type ArtifactStatus = 'staged' | 'active' | 'revoked';
|
|
76
|
+
/**
|
|
77
|
+
* Reference to a tool by stable id. v0.7.31 (FEATURE_089) introduces
|
|
78
|
+
* Agent manifests that bundle tool refs rather than inline tool bodies;
|
|
79
|
+
* the resolver expands these refs to concrete `KodaXToolDefinition`
|
|
80
|
+
* instances at activate time.
|
|
81
|
+
*
|
|
82
|
+
* `ref` shape:
|
|
83
|
+
* - `builtin:<name>` — a tool from the static registry
|
|
84
|
+
* (e.g. `builtin:read`, `builtin:bash`)
|
|
85
|
+
* - `constructed:<name>@<ver>` — a previously-activated constructed tool
|
|
86
|
+
*/
|
|
87
|
+
interface ToolRef {
|
|
88
|
+
readonly ref: string;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Reference to a Guardrail by stable id. The Layer A `Guardrail`
|
|
92
|
+
* declaration is name-only (no runtime hooks); resolvers map known
|
|
93
|
+
* names to constructed `ToolGuardrail` / `InputGuardrail` /
|
|
94
|
+
* `OutputGuardrail` instances at activation time.
|
|
95
|
+
*/
|
|
96
|
+
interface GuardrailRef {
|
|
97
|
+
readonly kind: 'input' | 'output' | 'tool';
|
|
98
|
+
readonly ref: string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Reference to a handoff target by stable id (another constructed agent
|
|
102
|
+
* or a builtin role). The resolver expands `target.ref` to the actual
|
|
103
|
+
* `Agent` declaration at admission time so the handoff DAG check
|
|
104
|
+
* (`handoffLegality` invariant) sees the full graph.
|
|
105
|
+
*/
|
|
106
|
+
interface AgentHandoffRef {
|
|
107
|
+
readonly target: {
|
|
108
|
+
readonly ref: string;
|
|
109
|
+
};
|
|
110
|
+
readonly kind: 'continuation' | 'as-tool';
|
|
111
|
+
readonly description?: string;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Reasoning profile declaration mirroring the Layer A
|
|
115
|
+
* `AgentReasoningProfile`. Kept structurally identical so the resolver
|
|
116
|
+
* passes the value through without re-shaping.
|
|
117
|
+
*/
|
|
118
|
+
interface AgentReasoningRef {
|
|
119
|
+
readonly default: 'quick' | 'balanced' | 'deep';
|
|
120
|
+
readonly max?: 'quick' | 'balanced' | 'deep';
|
|
121
|
+
readonly escalateOnRevise?: boolean;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Sandbox test case. Used by `sandbox_test_agent` to verify a
|
|
125
|
+
* constructed agent before it can activate. Each case feeds `input`
|
|
126
|
+
* to a sandbox Runner instance and grades the agent's final output:
|
|
127
|
+
*
|
|
128
|
+
* - `expectMatch` — final text must match this regex (string form)
|
|
129
|
+
* - `expectNotMatch` — final text must NOT match this regex
|
|
130
|
+
* - `expectFinalText` — exact substring match (case-sensitive)
|
|
131
|
+
*
|
|
132
|
+
* At least one of the three expect-fields must be present; the cases
|
|
133
|
+
* are graded by `runSandboxAgentTest()` (FEATURE_089 Phase 3.5).
|
|
134
|
+
*/
|
|
135
|
+
interface AgentTestCase {
|
|
136
|
+
readonly id: string;
|
|
137
|
+
readonly input: string;
|
|
138
|
+
readonly expectMatch?: string;
|
|
139
|
+
readonly expectNotMatch?: string;
|
|
140
|
+
readonly expectFinalText?: string;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Agent-kind artifact body (the `content` of `ConstructionArtifact`
|
|
144
|
+
* when `kind === 'agent'`).
|
|
145
|
+
*
|
|
146
|
+
* FEATURE_089 (v0.7.31): all fields except `instructions` are optional;
|
|
147
|
+
* a minimal "echo agent" can be expressed as `{ instructions: '...' }`.
|
|
148
|
+
* Tool / handoff / guardrail refs are resolved at admission time
|
|
149
|
+
* (Runner.admit's 5-step audit expands them and feeds the resolved
|
|
150
|
+
* Agent through the invariant chain).
|
|
151
|
+
*/
|
|
152
|
+
interface AgentContent {
|
|
153
|
+
readonly instructions: string;
|
|
154
|
+
readonly tools?: readonly ToolRef[];
|
|
155
|
+
readonly handoffs?: readonly AgentHandoffRef[];
|
|
156
|
+
readonly reasoning?: AgentReasoningRef;
|
|
157
|
+
readonly guardrails?: readonly GuardrailRef[];
|
|
158
|
+
readonly model?: string;
|
|
159
|
+
readonly provider?: string;
|
|
160
|
+
readonly effort?: KodaXWireReasoningEffort;
|
|
161
|
+
/**
|
|
162
|
+
* FEATURE_191 — one-sentence human-readable summary surfaced in the
|
|
163
|
+
* Worker system prompt's `=== Available specialist agents ===`
|
|
164
|
+
* block (FEATURE_191 A.3) and in `/agents list` UIs. Frontmatter
|
|
165
|
+
* `description` field of `~/.kodax/agents/<name>.md` and the
|
|
166
|
+
* `name`-paired argument of `KodaXExtensionAPI.registerAgent`
|
|
167
|
+
* funnel into this field. Optional for backward compatibility with
|
|
168
|
+
* FEATURE_089 minimal-agent shape (`{ instructions: '...' }`);
|
|
169
|
+
* the SP block renders `(no description)` when absent.
|
|
170
|
+
*/
|
|
171
|
+
readonly description?: string;
|
|
172
|
+
/**
|
|
173
|
+
* Optional structured-output schema mirroring `Agent.outputSchema`.
|
|
174
|
+
* Pure pass-through to the runtime — admission does not validate
|
|
175
|
+
* shape semantics here, only well-formed JSON.
|
|
176
|
+
*/
|
|
177
|
+
readonly outputSchema?: Record<string, unknown>;
|
|
178
|
+
/**
|
|
179
|
+
* Optional sandbox test cases. When present, `sandbox_test_agent`
|
|
180
|
+
* runs them; when absent, the test step performs only the static
|
|
181
|
+
* checks (manifest schema + admission audit).
|
|
182
|
+
*/
|
|
183
|
+
readonly testCases?: readonly AgentTestCase[];
|
|
184
|
+
/**
|
|
185
|
+
* Maximum total budget (iteration count) the agent may consume.
|
|
186
|
+
* Plumbed onto the resolved `AgentManifest.maxBudget` and clamped by
|
|
187
|
+
* `budgetCeiling` invariant during admission.
|
|
188
|
+
*/
|
|
189
|
+
readonly maxBudget?: number;
|
|
190
|
+
/**
|
|
191
|
+
* Voluntary additional invariants the LLM declares this agent
|
|
192
|
+
* commits to. Plumbed onto `AgentManifest.declaredInvariants`;
|
|
193
|
+
* unioned on top of the required set during admission.
|
|
194
|
+
*/
|
|
195
|
+
readonly declaredInvariants?: readonly string[];
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Persisted artifact shape (one JSON file per name/version under
|
|
199
|
+
* `.kodax/constructed/<kind>s/<name>/<version>.json`).
|
|
200
|
+
*
|
|
201
|
+
* Discriminated union over `kind`:
|
|
202
|
+
* - `kind: 'tool'` — v0.7.28 (FEATURE_088) tool generation
|
|
203
|
+
* - `kind: 'agent'` — v0.7.31 (FEATURE_089) agent generation; passes
|
|
204
|
+
* through `Runner.admit()` at activation time
|
|
205
|
+
*
|
|
206
|
+
* Lifecycle fields (status / timestamps / contentHash / sourceAgent /
|
|
207
|
+
* signedBy) are common to all kinds.
|
|
208
|
+
*/
|
|
209
|
+
type ConstructionArtifact = ToolArtifact | AgentArtifact;
|
|
210
|
+
interface ConstructionArtifactBase {
|
|
211
|
+
readonly name: string;
|
|
212
|
+
readonly version: string;
|
|
213
|
+
status: ArtifactStatus;
|
|
214
|
+
readonly signedBy?: string;
|
|
215
|
+
readonly createdAt: number;
|
|
216
|
+
readonly sourceAgent?: string;
|
|
217
|
+
testedAt?: number;
|
|
218
|
+
activatedAt?: number;
|
|
219
|
+
revokedAt?: number;
|
|
220
|
+
/**
|
|
221
|
+
* SHA-256 of `JSON.stringify(content)` captured at activate time.
|
|
222
|
+
* `rehydrateActiveArtifacts()` recomputes and compares — a mismatch
|
|
223
|
+
* indicates the manifest was edited between activation and the next
|
|
224
|
+
* boot (naive cross-session tampering, e.g. an LLM rewriting the .json
|
|
225
|
+
* via the Write tool without recomputing the hash). Mismatched
|
|
226
|
+
* artifacts are skipped at rehydrate with a stderr warning. This is
|
|
227
|
+
* NOT a defense against a coordinated attacker who recomputes the
|
|
228
|
+
* hash; the threat model is single-user CLI integrity, not multi-user
|
|
229
|
+
* supply chain.
|
|
230
|
+
*/
|
|
231
|
+
contentHash?: string;
|
|
232
|
+
}
|
|
233
|
+
interface ToolArtifact extends ConstructionArtifactBase {
|
|
234
|
+
readonly kind: 'tool';
|
|
235
|
+
readonly content: ToolContent;
|
|
236
|
+
}
|
|
237
|
+
interface AgentArtifact extends ConstructionArtifactBase {
|
|
238
|
+
readonly kind: 'agent';
|
|
239
|
+
readonly content: AgentContent;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Returned by {@link ConstructionRuntime.stage}; opaque handle that
|
|
243
|
+
* downstream `test()` / `activate()` calls bind to.
|
|
244
|
+
*/
|
|
245
|
+
interface StagedHandle {
|
|
246
|
+
readonly artifact: ConstructionArtifact;
|
|
247
|
+
readonly stagedAt: number;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Outcome of {@link ConstructionRuntime.test}. `ok=false` blocks
|
|
251
|
+
* activation; `warnings` surface but do not block.
|
|
252
|
+
*/
|
|
253
|
+
interface TestResult {
|
|
254
|
+
readonly ok: boolean;
|
|
255
|
+
readonly errors?: readonly string[];
|
|
256
|
+
readonly warnings?: readonly string[];
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Policy gate — invoked once per `activate()` before the artifact is
|
|
260
|
+
* registered. Default rejects implicit auto-approval; the REPL surface
|
|
261
|
+
* binds a dialog-based policy in `packages/repl/src/common/construction-
|
|
262
|
+
* bootstrap.ts` so user approval flows through the live askUser channel.
|
|
263
|
+
*
|
|
264
|
+
* Modeled as a function type rather than an interface (D3 decision):
|
|
265
|
+
* keeps the contract surface tiny, no class boilerplate.
|
|
266
|
+
*
|
|
267
|
+
* No declarative `kodax.config.ts` override hatch is provided — see the
|
|
268
|
+
* "Deferred Design Decisions" section in `features/v0.7.28.md` for why
|
|
269
|
+
* a `risk_mode` enum (when truly needed) is preferred over user-authored
|
|
270
|
+
* policy functions.
|
|
271
|
+
*/
|
|
272
|
+
type ConstructionPolicy = (artifact: ConstructionArtifact) => Promise<ConstructionPolicyVerdict>;
|
|
273
|
+
type ConstructionPolicyVerdict = 'approve' | 'reject' | 'ask-user';
|
|
274
|
+
/** Default policy: always ask the user; no implicit approvals. */
|
|
275
|
+
declare const defaultPolicy: ConstructionPolicy;
|
|
276
|
+
/**
|
|
277
|
+
* Thrown by `CtxProxy` when handler attempts to access a tool not declared
|
|
278
|
+
* in `capabilities.tools`. Caught in tracer; surfaces as a tool error.
|
|
279
|
+
*/
|
|
280
|
+
declare class CapabilityDeniedError extends Error {
|
|
281
|
+
readonly toolName: string;
|
|
282
|
+
readonly declaredTools: readonly string[];
|
|
283
|
+
constructor(toolName: string, declaredTools: readonly string[]);
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Thrown when a manifest cannot be parsed / is missing required fields.
|
|
287
|
+
* Surfaces during stage() / startup glob; tracer records details.
|
|
288
|
+
*/
|
|
289
|
+
declare class ConstructionManifestError extends Error {
|
|
290
|
+
readonly path?: string;
|
|
291
|
+
constructor(message: string, path?: string);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* KodaX Tool Types
|
|
296
|
+
*/
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Progress yield from a streaming (async generator) tool.
|
|
300
|
+
* Each yield appears as a real-time status update in the REPL transcript.
|
|
301
|
+
*/
|
|
302
|
+
interface ToolProgress {
|
|
303
|
+
readonly stage: string;
|
|
304
|
+
readonly message: string;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Final result a tool may return. Either a plain string (the default for
|
|
308
|
+
* text-only tools) OR a typed-array form for multimodal returns (e.g.
|
|
309
|
+
* `read` on an image path returns `[{type:'text',...}, {type:'image',...}]`).
|
|
310
|
+
* Providers serialize each shape to their wire format; OpenAI-compat
|
|
311
|
+
* gateways downgrade image items to a placeholder rather than rejecting.
|
|
312
|
+
*
|
|
313
|
+
* The array form mirrors claudecode's FileReadTool image return — Claude
|
|
314
|
+
* Code packs image data into `tool_result` content so the model can
|
|
315
|
+
* re-fetch images via the tool path. See
|
|
316
|
+
* `c:/Works/claudecode/src/tools/FileReadTool/FileReadTool.ts:866-891`.
|
|
317
|
+
*/
|
|
318
|
+
type ToolResult = string | readonly KodaXToolResultContentItem[];
|
|
319
|
+
/** Standard tool handler — returns a final result (text or multimodal). */
|
|
320
|
+
type ToolHandlerSync = (input: Record<string, unknown>, context: KodaXToolExecutionContext) => Promise<ToolResult>;
|
|
321
|
+
/** Streaming tool handler — yields progress updates, returns final result. */
|
|
322
|
+
type ToolHandlerStreaming = (input: Record<string, unknown>, context: KodaXToolExecutionContext) => AsyncGenerator<ToolProgress, ToolResult, void>;
|
|
323
|
+
/** Union of both handler types. Existing tools use ToolHandlerSync; new long-running tools may use ToolHandlerStreaming. */
|
|
324
|
+
type ToolHandler = ToolHandlerSync | ToolHandlerStreaming;
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* FEATURE_149 (v0.7.38) — interrupt-on-submit policy for in-flight tools.
|
|
328
|
+
*
|
|
329
|
+
* Controls whether submitting a new prompt while THIS tool is mid-execution
|
|
330
|
+
* triggers a fast-abort of the current agent round (so the new prompt starts
|
|
331
|
+
* immediately) or queues the prompt to run after the tool resolves.
|
|
332
|
+
*
|
|
333
|
+
* - `'cancel'` — long-running tools whose work the user is likely to want
|
|
334
|
+
* to abandon when they redirect (e.g., `bash` running a 30s script,
|
|
335
|
+
* `dispatch_child_task` synchronously awaiting a child, sleep-style
|
|
336
|
+
* tools). InkREPL submit handler aborts the round immediately.
|
|
337
|
+
*
|
|
338
|
+
* - `'wait'` (default) — atomic / fast tools (read, grep, glob, write,
|
|
339
|
+
* edit, …) where waiting for completion is cheaper than aborting and
|
|
340
|
+
* redoing.
|
|
341
|
+
*
|
|
342
|
+
* Mirrors Claude Code `interruptBehavior` (`utils/handlePromptSubmit.ts`).
|
|
343
|
+
*/
|
|
344
|
+
type ToolInterruptBehavior = 'cancel' | 'wait';
|
|
345
|
+
interface LocalToolDefinition extends KodaXToolDefinition {
|
|
346
|
+
handler: ToolHandler;
|
|
347
|
+
/**
|
|
348
|
+
* v0.7.42 — Required declarative side-effect class. See
|
|
349
|
+
* {@link ToolSideEffect} for category definitions and rationale. Plan
|
|
350
|
+
* mode and SDK embedders' permission brokers consume this; failure to
|
|
351
|
+
* declare is a TypeScript error (by design — `sideEffect` is required,
|
|
352
|
+
* not optional, to prevent silent drift when new tools are added).
|
|
353
|
+
*/
|
|
354
|
+
sideEffect: ToolSideEffect;
|
|
355
|
+
/**
|
|
356
|
+
* v0.7.42 — Optional plan-mode override.
|
|
357
|
+
*
|
|
358
|
+
* - `undefined` (default): plan-mode permits only `sideEffect ===
|
|
359
|
+
* 'readonly'` tools.
|
|
360
|
+
* - `true`: explicitly permitted in plan mode even when sideEffect is
|
|
361
|
+
* not `'readonly'`. Reserve for tools whose effect is itself part of
|
|
362
|
+
* the planning loop (`exit_plan_mode`, `task_stop`, `todo_update`,
|
|
363
|
+
* `todo_create`, `ask_user_question`).
|
|
364
|
+
* - `false`: explicitly blocked in plan mode even when sideEffect is
|
|
365
|
+
* `'readonly'`. Rare — useful for read-only tools whose output would
|
|
366
|
+
* leak content the planner should not see.
|
|
367
|
+
*/
|
|
368
|
+
planModeAllowed?: boolean;
|
|
369
|
+
/**
|
|
370
|
+
* FEATURE_149 (v0.7.38) — submit-time interrupt policy. See
|
|
371
|
+
* {@link ToolInterruptBehavior}. Default `'wait'` when undefined.
|
|
372
|
+
*/
|
|
373
|
+
interruptBehavior?: ToolInterruptBehavior;
|
|
374
|
+
/**
|
|
375
|
+
* Progressive disclosure — when `true`, the tool's full description is
|
|
376
|
+
* replaced with `searchHint` (a one-line summary) in the LLM-visible
|
|
377
|
+
* tool schema until the per-session unlock Set marks the tool name as
|
|
378
|
+
* unlocked. Unlocking happens via the `tool_search` tool: the LLM
|
|
379
|
+
* invokes `tool_search` with a query that selects this tool, and the
|
|
380
|
+
* full description + JSON schema are returned in the tool_result text.
|
|
381
|
+
* The next `getActiveToolDefinitions` call for the same session sees
|
|
382
|
+
* the unlock and emits the full description.
|
|
383
|
+
*
|
|
384
|
+
* Use for tools with rich descriptions (>500 bytes) whose teaching
|
|
385
|
+
* content the model only needs to consume when it actually plans to
|
|
386
|
+
* call the tool. Saves turn-1 context without dropping the tool.
|
|
387
|
+
*
|
|
388
|
+
* Mirrors claudecode `Tool.shouldDefer` — see
|
|
389
|
+
* `c:/Works/claudecode/src/tools/Tool.ts` for the parent design and
|
|
390
|
+
* `c:/Works/claudecode/src/tools/ToolSearchTool/` for the bootstrap.
|
|
391
|
+
*/
|
|
392
|
+
shouldDefer?: boolean;
|
|
393
|
+
/**
|
|
394
|
+
* One-line hint shown in place of the full description when this tool
|
|
395
|
+
* is deferred and not yet unlocked. Required when `shouldDefer: true`.
|
|
396
|
+
* Should answer "when would I want to look this up" in ≤ 100 chars
|
|
397
|
+
* so the LLM can decide whether to invoke `tool_search` for the full
|
|
398
|
+
* schema. Example: `'Fetch a specific remote URL — use tool_search to load full schema.'`
|
|
399
|
+
*/
|
|
400
|
+
searchHint?: string;
|
|
401
|
+
/**
|
|
402
|
+
* Classifier projection — REQUIRED (FEATURE_092 v0.7.33).
|
|
403
|
+
*
|
|
404
|
+
* Returns a one-line string that the auto-mode classifier sees as the
|
|
405
|
+
* `<action>` to evaluate. The classifier asks: "Given the user's
|
|
406
|
+
* intent + rules, should the agent be allowed to run this?"
|
|
407
|
+
*
|
|
408
|
+
* THREE-TIER STRATEGY (pick by tool's risk profile):
|
|
409
|
+
*
|
|
410
|
+
* 1. ZERO RISK (read-only, structural):
|
|
411
|
+
* → return '' (Tier 1 — classifier is skipped entirely, zero token cost)
|
|
412
|
+
* Examples: read, grep, glob, ask_user_question, exit_plan_mode
|
|
413
|
+
*
|
|
414
|
+
* 2. HIGH RISK (mutates state, network, exec, spawn):
|
|
415
|
+
* → write a CUSTOM projection that surfaces the risk-bearing fields
|
|
416
|
+
* Examples: bash (`Bash: ${i.command}`), web_fetch (`WebFetch ${i.url}`)
|
|
417
|
+
* See `classifier-projection.ts` for examples by category.
|
|
418
|
+
*
|
|
419
|
+
* 3. LOW RISK (structured input, side-effect-capable):
|
|
420
|
+
* → return defaultToClassifierInput(name, input) (one-line helper)
|
|
421
|
+
* Examples: semantic_lookup (refresh: true rebuilds index)
|
|
422
|
+
*
|
|
423
|
+
* KEEP IT SHORT: ≤ 100 chars typical. Variable-length user-provided fields
|
|
424
|
+
* (bash command, URL, dispatch_child_task objective) may legitimately
|
|
425
|
+
* exceed this — the projection's job is to make the risk visible, not to
|
|
426
|
+
* fit a fixed budget at the cost of hiding it.
|
|
427
|
+
*
|
|
428
|
+
* NEVER include: raw file contents, secrets, API keys, full LLM-emitted
|
|
429
|
+
* reasoning, or untrusted text passed through verbatim. Use byte/line
|
|
430
|
+
* counts as proxies (`Write ${path} (${content.length} bytes)`).
|
|
431
|
+
*
|
|
432
|
+
* See `docs/features/v0.7.33.md` "Tool 接口扩展" for design rationale.
|
|
433
|
+
*/
|
|
434
|
+
toClassifierInput: (input: unknown) => string;
|
|
435
|
+
}
|
|
436
|
+
interface ToolDefinitionSource {
|
|
437
|
+
/**
|
|
438
|
+
* Origin of the registered tool. `'constructed'` (FEATURE_087, v0.7.28)
|
|
439
|
+
* marks tools materialized at runtime by `ConstructionRuntime` from
|
|
440
|
+
* `.kodax/constructed/tools/<name>/<version>.json` artifacts.
|
|
441
|
+
*/
|
|
442
|
+
kind: 'builtin' | 'extension' | 'constructed';
|
|
443
|
+
id?: string;
|
|
444
|
+
label?: string;
|
|
445
|
+
/**
|
|
446
|
+
* Constructed-only: semver of the activated artifact. Used by
|
|
447
|
+
* `findByVersion()` and by `revoke()` to locate a specific stack entry.
|
|
448
|
+
*/
|
|
449
|
+
version?: string;
|
|
450
|
+
/**
|
|
451
|
+
* Constructed-only: absolute path to the artifact JSON on disk.
|
|
452
|
+
* Lets revoke / inspect operations round-trip back to the source of
|
|
453
|
+
* truth without re-globbing.
|
|
454
|
+
*/
|
|
455
|
+
manifestPath?: string;
|
|
456
|
+
}
|
|
457
|
+
interface RegisteredToolDefinition extends LocalToolDefinition {
|
|
458
|
+
registrationId: string;
|
|
459
|
+
requiredParams: string[];
|
|
460
|
+
source: ToolDefinitionSource;
|
|
461
|
+
}
|
|
462
|
+
interface ToolRegistrationOptions {
|
|
463
|
+
source?: ToolDefinitionSource;
|
|
464
|
+
}
|
|
465
|
+
type ToolRegistry = Map<string, RegisteredToolDefinition[]>;
|
|
466
|
+
type KodaXRetrievalToolName = 'web_search' | 'web_fetch' | 'code_search' | 'semantic_lookup' | 'mcp_search' | 'mcp_describe' | 'mcp_call' | 'mcp_read_resource' | 'mcp_get_prompt';
|
|
467
|
+
type KodaXRetrievalScope = 'workspace' | 'remote';
|
|
468
|
+
type KodaXRetrievalTrust = 'workspace' | 'provider' | 'open-world';
|
|
469
|
+
type KodaXRetrievalFreshness = 'fresh' | 'snapshot' | 'unknown';
|
|
470
|
+
interface KodaXRetrievalArtifact {
|
|
471
|
+
kind: 'url' | 'path' | 'symbol' | 'module' | 'process' | 'provider';
|
|
472
|
+
label: string;
|
|
473
|
+
value: string;
|
|
474
|
+
}
|
|
475
|
+
interface KodaXRetrievalItem {
|
|
476
|
+
title: string;
|
|
477
|
+
locator?: string;
|
|
478
|
+
snippet?: string;
|
|
479
|
+
score?: number;
|
|
480
|
+
metadata?: Record<string, unknown>;
|
|
481
|
+
}
|
|
482
|
+
interface KodaXRetrievalResult {
|
|
483
|
+
tool: KodaXRetrievalToolName;
|
|
484
|
+
query?: string;
|
|
485
|
+
scope: KodaXRetrievalScope;
|
|
486
|
+
trust: KodaXRetrievalTrust;
|
|
487
|
+
freshness: KodaXRetrievalFreshness;
|
|
488
|
+
provider?: string;
|
|
489
|
+
summary: string;
|
|
490
|
+
content?: string;
|
|
491
|
+
items: KodaXRetrievalItem[];
|
|
492
|
+
artifacts?: KodaXRetrievalArtifact[];
|
|
493
|
+
metadata?: Record<string, unknown>;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
interface ExecOptions {
|
|
497
|
+
/** Extra environment variables to inject (merged with safe base env). */
|
|
498
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
499
|
+
/** Working directory. Defaults to process.cwd(). */
|
|
500
|
+
readonly cwd?: string;
|
|
501
|
+
/** Timeout in milliseconds. Defaults to 30000. */
|
|
502
|
+
readonly timeout?: number;
|
|
503
|
+
/** Shell to use. Defaults to 'bash' on Unix, 'powershell' on Windows. */
|
|
504
|
+
readonly shell?: 'bash' | 'powershell';
|
|
505
|
+
}
|
|
506
|
+
interface ExecResult {
|
|
507
|
+
readonly exitCode: number;
|
|
508
|
+
readonly stdout: string;
|
|
509
|
+
readonly stderr: string;
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Run a shell command with a sandboxed environment.
|
|
513
|
+
*
|
|
514
|
+
* SECURITY: Only a whitelist of safe environment variables is passed to the
|
|
515
|
+
* subprocess. API keys and tokens from the parent environment are NOT inherited.
|
|
516
|
+
*/
|
|
517
|
+
declare function exec(command: string, options?: ExecOptions): Promise<ExecResult>;
|
|
518
|
+
interface WebhookOptions {
|
|
519
|
+
/** HTTP method. Defaults to 'POST'. */
|
|
520
|
+
readonly method?: 'POST' | 'PUT';
|
|
521
|
+
/** Extra HTTP headers. */
|
|
522
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
523
|
+
/** Timeout in milliseconds. Defaults to 10000. */
|
|
524
|
+
readonly timeout?: number;
|
|
525
|
+
}
|
|
526
|
+
interface WebhookResult {
|
|
527
|
+
readonly ok: boolean;
|
|
528
|
+
readonly status: number;
|
|
529
|
+
readonly body?: string;
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Send an HTTP webhook with timeout support.
|
|
533
|
+
* Returns a result object instead of throwing on errors.
|
|
534
|
+
*/
|
|
535
|
+
declare function webhook(url: string, payload: unknown, options?: WebhookOptions): Promise<WebhookResult>;
|
|
536
|
+
|
|
537
|
+
interface ModelProviderRegistration {
|
|
538
|
+
name: string;
|
|
539
|
+
factory: () => KodaXBaseProvider;
|
|
540
|
+
}
|
|
541
|
+
interface ExtensionCommandDefinition {
|
|
542
|
+
name: string;
|
|
543
|
+
aliases?: string[];
|
|
544
|
+
description: string;
|
|
545
|
+
usage?: string;
|
|
546
|
+
metadata?: Record<string, unknown>;
|
|
547
|
+
handler: (args: string[], context: ExtensionCommandContext) => Promise<ExtensionCommandResult | void> | ExtensionCommandResult | void;
|
|
548
|
+
}
|
|
549
|
+
interface ExtensionModelSelection {
|
|
550
|
+
provider?: string;
|
|
551
|
+
model?: string;
|
|
552
|
+
}
|
|
553
|
+
interface ExtensionLogger {
|
|
554
|
+
debug: (...args: unknown[]) => void;
|
|
555
|
+
info: (...args: unknown[]) => void;
|
|
556
|
+
warn: (...args: unknown[]) => void;
|
|
557
|
+
error: (...args: unknown[]) => void;
|
|
558
|
+
}
|
|
559
|
+
interface ExtensionFileContributionSource {
|
|
560
|
+
kind: 'extension';
|
|
561
|
+
id: string;
|
|
562
|
+
label: string;
|
|
563
|
+
path: string;
|
|
564
|
+
}
|
|
565
|
+
interface RuntimeContributionSource {
|
|
566
|
+
kind: 'runtime';
|
|
567
|
+
id: string;
|
|
568
|
+
label: string;
|
|
569
|
+
path?: string;
|
|
570
|
+
}
|
|
571
|
+
type ExtensionContributionSource = ExtensionFileContributionSource | RuntimeContributionSource;
|
|
572
|
+
type ExtensionLoadSource = 'api' | 'cli' | 'config' | 'discovery';
|
|
573
|
+
interface LoadedExtensionDiagnostic {
|
|
574
|
+
path: string;
|
|
575
|
+
label: string;
|
|
576
|
+
loadSource: ExtensionLoadSource;
|
|
577
|
+
sessionStateKeys?: string[];
|
|
578
|
+
sessionRecordCounts?: Record<string, number>;
|
|
579
|
+
}
|
|
580
|
+
interface RegisteredCapabilityProviderDiagnostic {
|
|
581
|
+
id: string;
|
|
582
|
+
kinds: CapabilityKind[];
|
|
583
|
+
source: ExtensionContributionSource;
|
|
584
|
+
metadata?: Record<string, unknown>;
|
|
585
|
+
}
|
|
586
|
+
interface RegisteredCommandDiagnostic {
|
|
587
|
+
name: string;
|
|
588
|
+
aliases?: string[];
|
|
589
|
+
description: string;
|
|
590
|
+
usage?: string;
|
|
591
|
+
metadata?: Record<string, unknown>;
|
|
592
|
+
source: ExtensionContributionSource;
|
|
593
|
+
}
|
|
594
|
+
interface RegisteredToolDiagnostic {
|
|
595
|
+
name: string;
|
|
596
|
+
description: string;
|
|
597
|
+
requiredParams: string[];
|
|
598
|
+
source: RegisteredToolDefinition['source'];
|
|
599
|
+
shadowedSources: RegisteredToolDefinition['source'][];
|
|
600
|
+
}
|
|
601
|
+
interface RegisteredHookDiagnostic {
|
|
602
|
+
hook: keyof ExtensionHookMap;
|
|
603
|
+
order: number;
|
|
604
|
+
source: ExtensionContributionSource;
|
|
605
|
+
}
|
|
606
|
+
type ExtensionFailureStage = 'load' | 'reload' | 'event' | 'hook' | 'persistence';
|
|
607
|
+
interface ExtensionFailureDiagnostic {
|
|
608
|
+
stage: ExtensionFailureStage;
|
|
609
|
+
target: string;
|
|
610
|
+
message: string;
|
|
611
|
+
occurredAt: string;
|
|
612
|
+
source: ExtensionContributionSource;
|
|
613
|
+
}
|
|
614
|
+
interface ExtensionRuntimeDiagnostics {
|
|
615
|
+
loadedExtensions: LoadedExtensionDiagnostic[];
|
|
616
|
+
capabilityProviders: RegisteredCapabilityProviderDiagnostic[];
|
|
617
|
+
commands: RegisteredCommandDiagnostic[];
|
|
618
|
+
tools: RegisteredToolDiagnostic[];
|
|
619
|
+
hooks: RegisteredHookDiagnostic[];
|
|
620
|
+
failures: ExtensionFailureDiagnostic[];
|
|
621
|
+
defaults: {
|
|
622
|
+
activeTools?: string[];
|
|
623
|
+
modelSelection: ExtensionModelSelection;
|
|
624
|
+
thinkingLevel?: KodaXWireReasoningEffort;
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
interface ExtensionCommandInvocation {
|
|
628
|
+
prompt: string;
|
|
629
|
+
displayName?: string;
|
|
630
|
+
disableModelInvocation?: boolean;
|
|
631
|
+
allowedTools?: string;
|
|
632
|
+
context?: 'fork';
|
|
633
|
+
model?: string;
|
|
634
|
+
}
|
|
635
|
+
interface ExtensionCommandResult {
|
|
636
|
+
success?: boolean;
|
|
637
|
+
message?: string;
|
|
638
|
+
data?: unknown;
|
|
639
|
+
invocation?: ExtensionCommandInvocation;
|
|
640
|
+
}
|
|
641
|
+
interface ExtensionCommandContext {
|
|
642
|
+
sessionId?: string;
|
|
643
|
+
gitRoot?: string;
|
|
644
|
+
workingDirectory: string;
|
|
645
|
+
reloadExtensions: () => Promise<void>;
|
|
646
|
+
getDiagnostics: () => ExtensionRuntimeDiagnostics;
|
|
647
|
+
logger: ExtensionLogger;
|
|
648
|
+
}
|
|
649
|
+
interface ExtensionToolBeforeHookContext {
|
|
650
|
+
name: string;
|
|
651
|
+
input: Record<string, unknown>;
|
|
652
|
+
toolId?: string;
|
|
653
|
+
executionCwd?: string;
|
|
654
|
+
gitRoot?: string;
|
|
655
|
+
}
|
|
656
|
+
interface ExtensionProviderBeforeHookContext {
|
|
657
|
+
provider: string;
|
|
658
|
+
model?: string;
|
|
659
|
+
reasoningMode?: KodaXWireReasoningEffort;
|
|
660
|
+
systemPrompt: string;
|
|
661
|
+
block: (reason: string) => void;
|
|
662
|
+
replaceProvider: (provider: string) => void;
|
|
663
|
+
replaceModel: (model?: string) => void;
|
|
664
|
+
replaceSystemPrompt: (systemPrompt: string) => void;
|
|
665
|
+
setThinkingLevel: (level: KodaXWireReasoningEffort) => void;
|
|
666
|
+
}
|
|
667
|
+
interface ExtensionTurnSettleHookContext {
|
|
668
|
+
sessionId: string;
|
|
669
|
+
lastText: string;
|
|
670
|
+
hadToolCalls: boolean;
|
|
671
|
+
success: boolean;
|
|
672
|
+
signal?: 'COMPLETE' | 'BLOCKED' | 'DECIDE';
|
|
673
|
+
queueUserMessage: (message: string | KodaXMessage) => void;
|
|
674
|
+
setModelSelection: (next: ExtensionModelSelection) => void;
|
|
675
|
+
setThinkingLevel: (level: KodaXWireReasoningEffort) => void;
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* FEATURE_184 (v0.7.45) — Stop Hook bridge context for extensions.
|
|
679
|
+
*
|
|
680
|
+
* Fires ONLY when the model terminates a turn text-only (no tool_use)
|
|
681
|
+
* — a strict subset of `turn:settle`, which fires on every turn end
|
|
682
|
+
* including mid-task tool turns. Use this hook for verification or
|
|
683
|
+
* "is the task actually done?" checks. The three-state return surface
|
|
684
|
+
* mirrors `RunOptions.stopHook` at the agent layer; the bridge passes
|
|
685
|
+
* the extension's return through unchanged.
|
|
686
|
+
*
|
|
687
|
+
* Coding-layer first-party consumers (Sidecar Verifier, FEATURE_184
|
|
688
|
+
* Phase D) wire directly to the agent `stopHook`. Third-party
|
|
689
|
+
* extensions write `api.hook('turn:complete', handler)` and the bridge
|
|
690
|
+
* dispatches to them inside the agent's `stopHook` callback. Handlers
|
|
691
|
+
* fire in registration order, first non-`void` return short-circuits
|
|
692
|
+
* the chain (matches `tool:before` semantics).
|
|
693
|
+
*
|
|
694
|
+
* Scope note: this hook fires on the AMA `runner-driven` path only
|
|
695
|
+
* (main loop, B1 retry, V2 worker). SA-path child agents dispatched
|
|
696
|
+
* via `dispatch_child_task` go through `runKodaX` and do NOT trigger
|
|
697
|
+
* this hook — observe their lifecycle via `turn:settle` on the SA
|
|
698
|
+
* path. Extensions wanting "every agent termination" semantics must
|
|
699
|
+
* register both hooks.
|
|
700
|
+
*/
|
|
701
|
+
interface ExtensionTurnCompleteHookContext {
|
|
702
|
+
sessionId: string;
|
|
703
|
+
lastAssistantText: string;
|
|
704
|
+
signal: 'natural-end';
|
|
705
|
+
reanimateCount: number;
|
|
706
|
+
reanimateBudget: number;
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* FEATURE_184 (v0.7.45) — Extension `turn:complete` return surface.
|
|
710
|
+
*
|
|
711
|
+
* - `void` / `undefined` → accept the termination, defer to next
|
|
712
|
+
* handler (or fall through to agent terminal path if none).
|
|
713
|
+
* - `string` → reanimate: synthesize a user message, run another
|
|
714
|
+
* turn. Bounded by Runner's `stopHookReanimateBudget`.
|
|
715
|
+
* - `{ abort: true, reason }` → halt the run, surface reason to
|
|
716
|
+
* caller via `RunResult.output` + `stoppedByHook = true`.
|
|
717
|
+
*/
|
|
718
|
+
type ExtensionTurnCompleteHookResult = void | string | {
|
|
719
|
+
readonly abort: true;
|
|
720
|
+
readonly reason: string;
|
|
721
|
+
};
|
|
722
|
+
interface ExtensionSessionHydrateHookContext {
|
|
723
|
+
sessionId: string;
|
|
724
|
+
getState: <T = KodaXJsonValue>(key: string) => T | undefined;
|
|
725
|
+
setState: (key: string, value: KodaXJsonValue | undefined) => void;
|
|
726
|
+
listRecords: (type?: string) => KodaXExtensionSessionRecord[];
|
|
727
|
+
appendRecord: (type: string, data?: KodaXJsonValue, options?: {
|
|
728
|
+
dedupeKey?: string;
|
|
729
|
+
}) => KodaXExtensionSessionRecord | undefined;
|
|
730
|
+
clearRecords: (type?: string) => number;
|
|
731
|
+
}
|
|
732
|
+
interface ExtensionEventMap {
|
|
733
|
+
'session:start': {
|
|
734
|
+
provider: string;
|
|
735
|
+
sessionId: string;
|
|
736
|
+
};
|
|
737
|
+
'turn:start': {
|
|
738
|
+
sessionId: string;
|
|
739
|
+
iteration: number;
|
|
740
|
+
maxIter: number;
|
|
741
|
+
};
|
|
742
|
+
'text:delta': {
|
|
743
|
+
text: string;
|
|
744
|
+
};
|
|
745
|
+
'thinking:delta': {
|
|
746
|
+
text: string;
|
|
747
|
+
};
|
|
748
|
+
'thinking:end': {
|
|
749
|
+
thinking: string;
|
|
750
|
+
};
|
|
751
|
+
'tool:start': {
|
|
752
|
+
name: string;
|
|
753
|
+
id: string;
|
|
754
|
+
input?: Record<string, unknown>;
|
|
755
|
+
};
|
|
756
|
+
'tool:result': {
|
|
757
|
+
id: string;
|
|
758
|
+
name: string;
|
|
759
|
+
content: string;
|
|
760
|
+
};
|
|
761
|
+
'provider:selected': {
|
|
762
|
+
provider: string;
|
|
763
|
+
model?: string;
|
|
764
|
+
};
|
|
765
|
+
'provider:rate-limit': {
|
|
766
|
+
provider: string;
|
|
767
|
+
attempt: number;
|
|
768
|
+
maxRetries: number;
|
|
769
|
+
delayMs: number;
|
|
770
|
+
};
|
|
771
|
+
'capability:search': {
|
|
772
|
+
providerId: string;
|
|
773
|
+
query: string;
|
|
774
|
+
kind?: CapabilityKind;
|
|
775
|
+
limit?: number;
|
|
776
|
+
};
|
|
777
|
+
'capability:describe': {
|
|
778
|
+
providerId: string;
|
|
779
|
+
capabilityId: string;
|
|
780
|
+
};
|
|
781
|
+
'capability:invoke': {
|
|
782
|
+
providerId: string;
|
|
783
|
+
capabilityId: string;
|
|
784
|
+
kind: CapabilityKind;
|
|
785
|
+
};
|
|
786
|
+
'capability:refresh': {
|
|
787
|
+
providerId: string;
|
|
788
|
+
};
|
|
789
|
+
'stream:end': undefined;
|
|
790
|
+
'turn:end': {
|
|
791
|
+
sessionId: string;
|
|
792
|
+
iteration: number;
|
|
793
|
+
lastText: string;
|
|
794
|
+
hadToolCalls: boolean;
|
|
795
|
+
signal?: 'COMPLETE' | 'BLOCKED' | 'DECIDE';
|
|
796
|
+
};
|
|
797
|
+
'complete': {
|
|
798
|
+
success: boolean;
|
|
799
|
+
signal?: 'COMPLETE' | 'BLOCKED' | 'DECIDE';
|
|
800
|
+
};
|
|
801
|
+
'error': {
|
|
802
|
+
error: Error;
|
|
803
|
+
};
|
|
804
|
+
'todo:created': {
|
|
805
|
+
id: string;
|
|
806
|
+
item: KodaXTodoItem;
|
|
807
|
+
source: TodoMutationSource;
|
|
808
|
+
};
|
|
809
|
+
'todo:updated': {
|
|
810
|
+
id: string;
|
|
811
|
+
before: KodaXTodoItem;
|
|
812
|
+
after: KodaXTodoItem;
|
|
813
|
+
changedFields: readonly (keyof KodaXTodoItem)[];
|
|
814
|
+
source: TodoMutationSource;
|
|
815
|
+
};
|
|
816
|
+
'todo:deleted': {
|
|
817
|
+
id: string;
|
|
818
|
+
item: KodaXTodoItem;
|
|
819
|
+
source: TodoMutationSource;
|
|
820
|
+
};
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* FEATURE_170 v0.7.41 — provenance tag for todo:* events / hooks. Lets
|
|
824
|
+
* extension authors distinguish LLM-driven mutations (`tool`) from
|
|
825
|
+
* runner-side automation (`internal`) — e.g. an extension that audits
|
|
826
|
+
* todo churn should ignore `internal` flips to avoid false positives.
|
|
827
|
+
*/
|
|
828
|
+
type TodoMutationSource = 'tool' | 'internal';
|
|
829
|
+
/**
|
|
830
|
+
* FEATURE_170 v0.7.41 — seed shape passed to `'todo:before-create'`.
|
|
831
|
+
* Mirrors `TodoAddSeed` from todo-store.ts (kept structurally compatible
|
|
832
|
+
* to avoid coupling extension authors to the internal task-engine type).
|
|
833
|
+
*
|
|
834
|
+
* v0.7.42 — `content` renamed to `subject` + optional `description` to
|
|
835
|
+
* match claudecode V2 `TaskCreateTool` schema. See `TodoItem` JSDoc in
|
|
836
|
+
* packages/coding/src/types.ts.
|
|
837
|
+
*/
|
|
838
|
+
interface ExtensionTodoCreateSeed {
|
|
839
|
+
readonly subject: string;
|
|
840
|
+
readonly description?: string;
|
|
841
|
+
readonly activeForm?: string;
|
|
842
|
+
readonly evaluator?: 'build' | 'test' | 'lint';
|
|
843
|
+
readonly owner?: string;
|
|
844
|
+
readonly sourceObligationIndex?: number;
|
|
845
|
+
readonly metadata?: Record<string, unknown>;
|
|
846
|
+
}
|
|
847
|
+
/**
|
|
848
|
+
* FEATURE_170 v0.7.41 — minimal todo item shape exposed to extensions
|
|
849
|
+
* via the todo:* events. Kept structurally identical to the engine's
|
|
850
|
+
* `TodoItem` so the runtime can pass values straight through without
|
|
851
|
+
* conversion, but redeclared here so extension consumers don't import
|
|
852
|
+
* from `packages/coding/src/types.ts` (which is task-engine internal).
|
|
853
|
+
*
|
|
854
|
+
* Drift guard: a compile-time assignability assertion at the bottom of
|
|
855
|
+
* this file fires if `TodoItem` (engine) gains a field that this
|
|
856
|
+
* extension-facing shape does NOT mirror — see `__todoItemParity` below.
|
|
857
|
+
*/
|
|
858
|
+
interface KodaXTodoItem {
|
|
859
|
+
readonly id: string;
|
|
860
|
+
/** v0.7.42 — see TodoItem.subject JSDoc in packages/coding/src/types.ts. */
|
|
861
|
+
readonly subject: string;
|
|
862
|
+
readonly description?: string;
|
|
863
|
+
readonly status: 'pending' | 'in_progress' | 'completed' | 'failed' | 'skipped' | 'cancelled';
|
|
864
|
+
readonly owner?: string;
|
|
865
|
+
readonly sourceObligationIndex?: number;
|
|
866
|
+
readonly note?: string;
|
|
867
|
+
readonly evaluator?: 'build' | 'test' | 'lint';
|
|
868
|
+
readonly activeForm?: string;
|
|
869
|
+
readonly metadata?: Record<string, unknown>;
|
|
870
|
+
}
|
|
871
|
+
interface ExtensionHookMap {
|
|
872
|
+
'tool:before': (context: ExtensionToolBeforeHookContext) => Promise<void | string | false> | void | string | false;
|
|
873
|
+
'provider:before': (context: ExtensionProviderBeforeHookContext) => Promise<void> | void;
|
|
874
|
+
'turn:settle': (context: ExtensionTurnSettleHookContext) => Promise<void> | void;
|
|
875
|
+
'turn:complete': (context: ExtensionTurnCompleteHookContext) => Promise<ExtensionTurnCompleteHookResult> | ExtensionTurnCompleteHookResult;
|
|
876
|
+
'session:hydrate': (context: ExtensionSessionHydrateHookContext) => Promise<void> | void;
|
|
877
|
+
'todo:before-create': (context: {
|
|
878
|
+
seed: ExtensionTodoCreateSeed;
|
|
879
|
+
}) => Promise<void | string | false> | void | string | false;
|
|
880
|
+
'todo:before-complete': (context: {
|
|
881
|
+
id: string;
|
|
882
|
+
item: KodaXTodoItem;
|
|
883
|
+
}) => Promise<void | string | false> | void | string | false;
|
|
884
|
+
}
|
|
885
|
+
interface ExtensionRuntimeController {
|
|
886
|
+
queueUserMessage(message: string | KodaXMessage): void;
|
|
887
|
+
getSessionState<T = KodaXJsonValue>(key: string): T | undefined;
|
|
888
|
+
setSessionState(key: string, value: KodaXJsonValue | undefined): void;
|
|
889
|
+
appendSessionRecord(type: string, data?: KodaXJsonValue, options?: {
|
|
890
|
+
dedupeKey?: string;
|
|
891
|
+
}): KodaXExtensionSessionRecord | undefined;
|
|
892
|
+
listSessionRecords(type?: string): KodaXExtensionSessionRecord[];
|
|
893
|
+
clearSessionRecords(type?: string): number;
|
|
894
|
+
getActiveTools(): string[];
|
|
895
|
+
setActiveTools(toolNames: string[]): void;
|
|
896
|
+
getModelSelection(): ExtensionModelSelection;
|
|
897
|
+
setModelSelection(next: ExtensionModelSelection): void;
|
|
898
|
+
getThinkingLevel(): KodaXWireReasoningEffort | undefined;
|
|
899
|
+
setThinkingLevel(level: KodaXWireReasoningEffort): void;
|
|
900
|
+
}
|
|
901
|
+
interface KodaXExtensionAPI {
|
|
902
|
+
registerTool: (definition: LocalToolDefinition) => () => void;
|
|
903
|
+
getTool: (name: string) => RegisteredToolDefinition | undefined;
|
|
904
|
+
getBuiltinTool: (name: string) => RegisteredToolDefinition | undefined;
|
|
905
|
+
registerModelProvider: (registration: ModelProviderRegistration) => () => void;
|
|
906
|
+
registerCapabilityProvider: (provider: CapabilityProvider) => () => void;
|
|
907
|
+
registerCommand: (command: ExtensionCommandDefinition) => () => void;
|
|
908
|
+
registerSkillPath: (skillPath: string) => () => void;
|
|
909
|
+
/**
|
|
910
|
+
* FEATURE_191 (v0.7.43) — register a constructed agent at extension
|
|
911
|
+
* activate time. The extension supplies the agent name and an
|
|
912
|
+
* `AgentContent` body (instructions + optional tools/handoffs/
|
|
913
|
+
* reasoning/model/description); the runtime threads it through
|
|
914
|
+
* `buildAdmissionManifest` + `Runner.admit` and registers the
|
|
915
|
+
* activated Agent via `registerConstructedAgent({ source:
|
|
916
|
+
* 'extension' })`. The returned dispose fn (also auto-pushed onto
|
|
917
|
+
* the extension's disposables list) unregisters the agent on
|
|
918
|
+
* extension deactivate.
|
|
919
|
+
*
|
|
920
|
+
* Returns `Promise<() => void>` — **you MUST `await` the call**
|
|
921
|
+
* before invoking the dispose function. Unlike sibling
|
|
922
|
+
* `registerTool` (sync), this is async because `Runner.admit` is
|
|
923
|
+
* declared async (FEATURE_101 admission contract — admission may
|
|
924
|
+
* consult disk for handoff-target staged-agent resolution).
|
|
925
|
+
*
|
|
926
|
+
* @example
|
|
927
|
+
* ```ts
|
|
928
|
+
* // CORRECT — await unwraps the Promise to a sync dispose
|
|
929
|
+
* export default async function activate(api: KodaXExtensionAPI) {
|
|
930
|
+
* const dispose = await api.registerAgent('db-reviewer', {
|
|
931
|
+
* instructions: 'You review DB migrations.',
|
|
932
|
+
* description: 'DB migration reviewer',
|
|
933
|
+
* });
|
|
934
|
+
* // dispose() is now callable on demand; the runtime also auto-
|
|
935
|
+
* // disposes via the extension's disposables list at deactivate.
|
|
936
|
+
* }
|
|
937
|
+
* ```
|
|
938
|
+
*
|
|
939
|
+
* @example
|
|
940
|
+
* ```ts
|
|
941
|
+
* // WRONG — TypeScript catches this; .js / @ts-ignore consumers
|
|
942
|
+
* // hit a runtime TypeError because Promise is not a function.
|
|
943
|
+
* export default function activate(api: KodaXExtensionAPI) {
|
|
944
|
+
* const dispose = api.registerAgent('x', { instructions: '...' });
|
|
945
|
+
* dispose(); // TypeError: dispose is not a function
|
|
946
|
+
* }
|
|
947
|
+
* ```
|
|
948
|
+
*
|
|
949
|
+
* Throws on admission rejection (with the verdict reason) so the
|
|
950
|
+
* extension author sees the failure at activate time rather than
|
|
951
|
+
* having a silently-dropped registration. The throw also halts
|
|
952
|
+
* extension loading — the extension's other registrations roll back
|
|
953
|
+
* via `LoadedExtensionRecord.disposables` reverse-iterate.
|
|
954
|
+
*/
|
|
955
|
+
registerAgent: (name: string, content: AgentContent) => Promise<() => void>;
|
|
956
|
+
on: <TEvent extends keyof ExtensionEventMap>(event: TEvent, handler: (payload: ExtensionEventMap[TEvent]) => Promise<void> | void) => () => void;
|
|
957
|
+
hook: <THook extends keyof ExtensionHookMap>(hook: THook, handler: ExtensionHookMap[THook]) => () => void;
|
|
958
|
+
logger: ExtensionLogger;
|
|
959
|
+
config: Readonly<Record<string, unknown>>;
|
|
960
|
+
runtime: ExtensionRuntimeController;
|
|
961
|
+
/** Extension-scoped key-value store that persists across sessions. */
|
|
962
|
+
persistence: KodaXExtensionStore;
|
|
963
|
+
/** Run a shell command with sandboxed environment (no API key leakage). */
|
|
964
|
+
exec: (command: string, options?: ExecOptions) => Promise<ExecResult>;
|
|
965
|
+
/** Send an HTTP webhook with timeout support. */
|
|
966
|
+
webhook: (url: string, payload: unknown, options?: WebhookOptions) => Promise<WebhookResult>;
|
|
967
|
+
}
|
|
968
|
+
type KodaXExtensionActivationResult = void | (() => void | Promise<void>) | Promise<void | (() => void | Promise<void>)>;
|
|
969
|
+
interface KodaXExtensionModule {
|
|
970
|
+
default?: (api: KodaXExtensionAPI) => KodaXExtensionActivationResult;
|
|
971
|
+
activate?: (api: KodaXExtensionAPI) => KodaXExtensionActivationResult;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
export { DEFAULT_HANDLER_TIMEOUT_MS as D, defaultPolicy as a1, exec as a2, webhook as a3, CapabilityDeniedError as c, ConstructionManifestError as e };
|
|
975
|
+
export type { WebhookOptions as $, AgentArtifact as A, KodaXRetrievalItem as B, Capabilities as C, ExecOptions as E, KodaXRetrievalResult as F, KodaXRetrievalScope as G, KodaXRetrievalToolName as H, KodaXRetrievalTrust as I, LocalToolDefinition as J, KodaXExtensionAPI as K, LoadedExtensionDiagnostic as L, ModelProviderRegistration as M, RegisteredCommandDiagnostic as N, RegisteredHookDiagnostic as O, RegisteredToolDefinition as P, RegisteredToolDiagnostic as Q, RegisteredCapabilityProviderDiagnostic as R, ScriptSource as S, StagedHandle as T, TestResult as U, ToolContent as V, ToolDefinitionSource as W, ToolHandler as X, ToolHandlerSync as Y, ToolRegistrationOptions as Z, ToolRegistry as _, AgentContent as a, WebhookResult as a0, ArtifactStatus as b, ConstructionArtifact as d, ConstructionPolicy as f, ConstructionPolicyVerdict as g, ExecResult as h, ExtensionCommandContext as i, ExtensionCommandDefinition as j, ExtensionCommandInvocation as k, ExtensionCommandResult as l, ExtensionContributionSource as m, ExtensionEventMap as n, ExtensionFailureDiagnostic as o, ExtensionFailureStage as p, ExtensionHookMap as q, ExtensionLoadSource as r, ExtensionLogger as s, ExtensionRuntimeController as t, ExtensionRuntimeDiagnostics as u, ExtensionToolBeforeHookContext as v, KodaXExtensionActivationResult as w, KodaXExtensionModule as x, KodaXRetrievalArtifact as y, KodaXRetrievalFreshness as z };
|