1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
/**
* Tool contract — what a tool conforms to and what the kernel calls.
*
* The kernel never finds or names a concrete tool; it receives them via
* `runTurn` and dispatches by shape. A tool's `parameters` uses a structural
* JSON-Schema-like type so the kernel stays dependency-light (no zod).
* Extensions may use zod internally and convert to this shape.
*/
import type { Logger } from "./logging.js";
/**
* Structural JSON Schema subset for tool parameter declarations.
* The kernel does not validate against this — the provider serializes it for
* the model, and the tool implementation validates its own input.
* Using a structural type (not a library) keeps the kernel dependency-free.
*/
export interface ToolParameterSchema {
readonly type: "object";
readonly properties?: Readonly<Record<string, JsonSchemaProperty>>;
readonly required?: readonly string[];
readonly additionalProperties?: boolean;
readonly description?: string;
}
/** A single property within a tool's parameter schema. */
export interface JsonSchemaProperty {
readonly type?: string;
readonly description?: string;
readonly enum?: readonly string[];
readonly items?: JsonSchemaProperty;
readonly properties?: Readonly<Record<string, JsonSchemaProperty>>;
readonly required?: readonly string[];
readonly default?: unknown;
}
/**
* Context passed to a tool's `execute` method. The kernel constructs this per
* call, attributing streaming output to the specific tool-call id so
* concurrent tool output is never interleaved ambiguously.
*/
export interface ToolExecuteContext {
/** Unique id of the tool-call this execution serves. */
readonly toolCallId: string;
/**
* Stream output from the tool. The kernel attributes every call to the
* tool-call id, so concurrent shell output from different tools is
* correctly separated.
*/
readonly onOutput: (data: string, stream: "stdout" | "stderr") => void;
/**
* Cancellation signal. An aborted turn sets this so in-flight tool work
* can clean up rather than leak.
*/
readonly signal: AbortSignal;
/**
* Pre-bound Logger scoped to this tool-call span. Tools log correlated
* without a global (P3). The kernel stamps extensionId, conversationId,
* turnId, and spanId automatically.
*/
readonly log: Logger;
/**
* Working directory for this turn, forwarded verbatim from `RunTurnInput.cwd`.
* Tools that touch the filesystem resolve and contain paths against it.
* Optional: when omitted, a tool falls back to its own configured/default
* workdir. The kernel never interprets it.
*/
readonly cwd?: string;
}
/**
* The value a tool returns from execution. Content is a string for
* provider-agnostic transport; `isError` flags failure so the model can
* react without the kernel interpreting the content.
*/
export interface ToolResult {
readonly content: string;
readonly isError?: boolean;
}
/**
* A tool-call as emitted by the provider and dispatched by the kernel.
* The kernel matches `name` against registered tools and passes `input`
* to the matched tool's `execute`.
*/
export interface ToolCall {
readonly id: string;
readonly name: string;
readonly input: unknown;
}
/**
* What a tool extension registers with the kernel via `host.defineTool`.
* The kernel calls `execute` blindly by shape — it never knows which
* concrete tools exist.
*/
export interface ToolContract {
/** Unique name the model uses to invoke this tool. */
readonly name: string;
/** Human-readable description shown to the model. */
readonly description: string;
/** JSON-Schema-ish parameter declaration (structural, no library dep). */
readonly parameters: ToolParameterSchema;
/**
* Execute the tool with parsed input. The kernel provides a per-call
* context (cancellation, output streaming, attribution).
*/
readonly execute: (args: unknown, ctx: ToolExecuteContext) => Promise<ToolResult>;
/**
* Whether this tool is safe to run concurrently with other tools.
* When `false`, the kernel serializes this tool's calls even when the
* dispatch policy allows parallelism. Defaults to `true` if omitted.
* This overrides the global setting downward only (never widens parallelism).
*/
readonly concurrencySafe?: boolean;
}
|