summaryrefslogtreecommitdiffhomepage
path: root/packages/kernel/src/contracts/tool.ts
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-04 22:26:46 +0900
committerAdam Malczewski <[email protected]>2026-06-04 22:26:46 +0900
commitfd855ffb335e72a94b6f992ede5a859237460a8b (patch)
tree3833674b0957ddec1ed3b3e6140c89360e675037 /packages/kernel/src/contracts/tool.ts
parenta6119e0434597399c773da6f0b31363003f6aa09 (diff)
downloaddispatch-fd855ffb335e72a94b6f992ede5a859237460a8b.tar.gz
dispatch-fd855ffb335e72a94b6f992ede5a859237460a8b.zip
feat(kernel): define the ABI contracts (conversation, tool, provider, auth, dispatch, hooks, extension/HostAPI, runtime, events)
Diffstat (limited to 'packages/kernel/src/contracts/tool.ts')
-rw-r--r--packages/kernel/src/contracts/tool.ts107
1 files changed, 107 insertions, 0 deletions
diff --git a/packages/kernel/src/contracts/tool.ts b/packages/kernel/src/contracts/tool.ts
new file mode 100644
index 0000000..f74ce77
--- /dev/null
+++ b/packages/kernel/src/contracts/tool.ts
@@ -0,0 +1,107 @@
+/**
+ * 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.
+ */
+
+/**
+ * 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;
+}
+
+/**
+ * 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;
+}