summaryrefslogtreecommitdiffhomepage
path: root/packages/kernel/src/contracts/provider.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/provider.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/provider.ts')
-rw-r--r--packages/kernel/src/contracts/provider.ts116
1 files changed, 116 insertions, 0 deletions
diff --git a/packages/kernel/src/contracts/provider.ts b/packages/kernel/src/contracts/provider.ts
new file mode 100644
index 0000000..1d0fd75
--- /dev/null
+++ b/packages/kernel/src/contracts/provider.ts
@@ -0,0 +1,116 @@
+/**
+ * Provider contract — how an LLM backend plugs into the kernel.
+ *
+ * The kernel is provider-agnostic: it knows only this streaming interface and
+ * the event taxonomy. A provider extension wraps a concrete LLM API and
+ * translates its responses into `ProviderEvent`s.
+ */
+
+import type { ChatMessage } from "./conversation.js";
+import type { ToolContract } from "./tool.js";
+
+/**
+ * Token usage counters for a single step. All fields are counts of tokens.
+ * Cache fields are optional because not all providers expose cache metrics.
+ */
+export interface Usage {
+ readonly inputTokens: number;
+ readonly outputTokens: number;
+ readonly cacheReadTokens?: number;
+ readonly cacheWriteTokens?: number;
+}
+
+/**
+ * Events a provider yields during a single `stream` call. The kernel consumes
+ * these to drive tool dispatch, build chunks, and emit outward `AgentEvent`s.
+ * Discriminated by `type`.
+ */
+export type ProviderEvent =
+ | TextDeltaEvent
+ | ReasoningDeltaEvent
+ | ProviderToolCallEvent
+ | UsageEvent
+ | FinishEvent
+ | ProviderErrorEvent;
+
+/** Incremental text content from the model. */
+export interface TextDeltaEvent {
+ readonly type: "text-delta";
+ readonly delta: string;
+}
+
+/** Incremental reasoning / thinking content from the model. */
+export interface ReasoningDeltaEvent {
+ readonly type: "reasoning-delta";
+ readonly delta: string;
+}
+
+/**
+ * A complete tool-call parsed by the provider. The kernel uses `name` to
+ * dispatch to the matching `ToolContract`.
+ */
+export interface ProviderToolCallEvent {
+ readonly type: "tool-call";
+ readonly toolCallId: string;
+ readonly toolName: string;
+ readonly input: unknown;
+}
+
+/** Token usage report, typically emitted at step end. */
+export interface UsageEvent {
+ readonly type: "usage";
+ readonly usage: Usage;
+}
+
+/**
+ * Signals the end of a step. `reason` indicates why the model stopped
+ * generating (e.g. "stop", "tool-calls", "length", "content-filter").
+ */
+export interface FinishEvent {
+ readonly type: "finish";
+ readonly reason: string;
+}
+
+/** An error from the provider (network, rate-limit, model error, etc.). */
+export interface ProviderErrorEvent {
+ readonly type: "error";
+ readonly message: string;
+ readonly code?: string;
+ readonly retryable?: boolean;
+}
+
+/**
+ * Options passed to a provider's `stream` method beyond messages and tools.
+ * Kept minimal — providers may ignore fields they don't support.
+ */
+export interface ProviderStreamOptions {
+ /** Model identifier to use. */
+ readonly model?: string;
+ /** Sampling temperature override. */
+ readonly temperature?: number;
+ /** Maximum output tokens override. */
+ readonly maxTokens?: number;
+ /** System prompt to prepend. */
+ readonly systemPrompt?: string;
+}
+
+/**
+ * What a provider extension registers with the kernel. The kernel calls
+ * `stream` and consumes the async iterable of events — it never knows which
+ * concrete LLM API is behind it.
+ */
+export interface ProviderContract {
+ /** Unique identifier for this provider (e.g. "anthropic", "openai-compat"). */
+ readonly id: string;
+
+ /**
+ * Stream a response for the given messages and available tools.
+ * The provider yields `ProviderEvent`s incrementally; the kernel drives
+ * tool dispatch and chunk assembly from them.
+ */
+ readonly stream: (
+ messages: readonly ChatMessage[],
+ tools: readonly ToolContract[],
+ opts?: ProviderStreamOptions,
+ ) => AsyncIterable<ProviderEvent>;
+}