Agent SDK

kraken-ai is the open-source, fully typed agent framework. Define an agent, give it Zod-typed tools, point it at a model, and run it — with structured output, multi-agent teams, and human-in-the-loop built in.

#Installation

The kraken-ai package is already a dependency of every scaffolded Kraken project — you do not normally install it by hand. To add it to an existing project, install it from npm:

$ pnpm add kraken-ai

The SDK has a single runtime peer dependency, zod (v4+), which you use to type tool parameters and structured output. The Google provider additionally needs @google/genai, declared as an optional peer dependency and loaded lazily only when you use it.

ts
import {
  Agent,
  tool,
  google,
  configure,
  formatEvent,
} from "kraken-ai";
import { z } from "zod";

#Agent

An Agent is constructed from an AgentConfig object. The model is resolved at construction time; tools, teams, and structured output are wired in lazily per run.

ts
const agent = new Agent({
  name: "pricing-analyst",
  model: "google/gemini-3-flash-preview",
  instructions: "You are a pricing analyst. Use tools to look up product data.",
});

AgentConfig fields:

namestringRequired

Human-readable name. Also used as the delegation tool name when this agent is a team member.

modelModel | ModelStringRequired

The model powering the agent. Either a provider-qualified string such as "google/gemini-3-flash-preview" or a Model instance from a provider factory like google().

instructionsstringRequired

System instructions defining the agent's behavior.

descriptionstringOptional

Capabilities description shown to orchestrator agents when this agent is delegated to.

toolsTool[]Optional

Tools available to the agent, created with the tool() factory.

temperaturenumberOptional

Sampling temperature.

allowTemperatureOverridebooleanOptional

When false, a parent agent cannot override this agent's temperature. Defaults to true.

maxOutputTokensnumberOptional

Maximum number of output tokens per model call.

thinkingLevel"low" | "medium" | "high"Optional

Default reasoning depth for all LLM calls. Providers map this to their native thinking configuration.

teamAgentLike[]Optional

Team members this agent can delegate to. Each becomes a delegation tool the model can choose to call.

outputSchemaz.ZodTypeOptional

Zod schema for structured JSON output. When set, the model is constrained to the schema and the result's output is validated and typed as z.infer<TOutput>.

kernelKernelOptional

Custom kernel for full manual control of the execution loop. See Advanced.

logLevel"silent" | "debug" | "info" | "warn" | "error"Optional

Log verbosity override for this agent.

#agent.run()

agent.run(messages: Message[], options?: RunOptions) executes the agent against a non-empty array of conversation messages and resolves to a RunResult.

A Message has a role of "user" or "assistant" and a string content; assistant turns may also carry toolCalls and toolResults for multi-turn histories.

RunResult is a discriminated union on status. Narrow on status before accessing the other fields — each one exists on only one branch of the union.

PropertyTypeBranchDescription
status"complete" | "interrupted"AlwaysThe discriminant. "complete" when the agent finished; "interrupted" when a tool requiring approval paused execution.
outputTOutputcompleteThe agent output. unknown by default, or z.infer<TOutput> when outputSchema is configured.
messagesMessage[]completeThe full conversation history including tool calls and results.
usage{ inputTokens: number; outputTokens: number }completeAggregated token usage.
transitionsTransitionRecord[]completeThe recorded state transitions for the run.
interruptInterruptinterruptedThe pending tool call awaiting a human decision (toolName, args, toolCallId).
resume(decision: HumanDecision) => Promise<RunResult>interruptedResume the run with "approve", "reject", or { feedback: string }.

RunOptions accepts an onEvent callback for real-time event streaming, an AbortSignal via signal, a middleware chain, an explicit runId, per-run temperature / thinkingLevel / maxOutputTokens overrides, and dryRun (tool calls logged but not executed).

ts
const result = await agent.run([
  { role: "user", content: "What is the price of SKU-4821?" },
]);

if (result.status === "complete") {
  console.log(result.output);
} else {
  // A tool required approval — decide, then resume.
  const next = await result.resume("approve");
}

#tool()

tool() creates a Zod-typed tool. The parameters schema is converted to JSON Schema for the model and used at runtime to validate arguments before execute is called. Invalid arguments throw a ToolInputValidationError with the expected schema and per-field errors.

namestringRequired

Tool name presented to the model.

descriptionstringRequired

What the tool does — the model uses this to decide when to call it.

parametersz.ZodTypeRequired

Zod schema for the tool arguments. The execute callback receives z.infer<typeof parameters>.

execute(args) => Promise<TReturn>Required

The handler. Receives validated, typed arguments and returns the tool result.

requiresApprovalboolean | ((args) => boolean)Optional

Require a human decision before execution. A boolean, or a per-invocation predicate over the arguments. When it gates a call, run() returns an interrupted result.

ts
const lookupPrice = tool({
  name: "lookup_price",
  description: "Look up the current price of a product by SKU",
  parameters: z.object({ sku: z.string() }),
  execute: async ({ sku }) => {
    const price = await db.products.getPrice(sku);
    return { sku, price };
  },
});

#Models & providers

A model is either a provider-qualified string or a Model instance from a provider factory. String format is "provider/model-id" — for example "google/gemini-3.1-pro-preview" or "google/gemini-3-flash-preview". String models are resolved lazily on first use.

google(modelId, config?) returns a Google Gemini model. config accepts an optional apiKey and retry overrides. When no key is passed, the provider reads GEMINI_API_KEY, then GOOGLE_API_KEY, from the environment.

ts
import { google, mock } from "kraken-ai";

const model = google("gemini-3-flash-preview");

// Deterministic model for tests — no network, with call tracking.
const testModel = mock({
  response: { text: "ok", usage: { inputTokens: 1, outputTokens: 1 } },
});

mock() creates a deterministic model for testing: it records every call and replies from a fixed response or pattern-matched handlers.

Important

openai() is exported and accepts the OpenAI model-id type, but the provider is not yet implemented — calling it throws a ProviderError. Use the Google provider, a mock() model, or a custom Model implementation.

#Events

Pass onEvent in RunOptions to receive a typed AgentEvent for each step of a run. AgentEvent is a discriminated union on type, covering configuration, transcript init, lifecycle transitions, LLM calls, model thoughts, tool calls, delegation, interrupts, kills, errors, notifications, and structured-output completion. Every event carries the agent name, a runId, a timestamp, and a monotonic sequence number.

formatEvent(event) renders any event as a human-readable one-line string, useful for development logging.

ts
import { formatEvent } from "kraken-ai";

await agent.run(messages, {
  onEvent: (event) => {
    process.stdout.write(formatEvent(event) + "\n");
  },
});

#Errors

Every SDK error extends KrakenError and carries a stable code string for narrowing.

KrakenErrorcode: "KRAKEN_ERROR"Optional

Base class for all kraken-ai errors.

ValidationErrorcode: "VALIDATION_ERROR"Optional

Invalid configuration or input — for example an unparseable model string or unknown provider.

ProviderErrorcode: "PROVIDER_ERROR"Optional

A failure from an LLM provider (missing API key, rate limit, API error). Also thrown by the not-yet-implemented OpenAI provider.

ToolErrorcode: "TOOL_ERROR"Optional

An error during tool execution. Carries the toolName.

ToolInputValidationErrorcode: "TOOL_INPUT_VALIDATION_ERROR"Optional

The model supplied tool arguments that fail the parameter schema. Carries toolName, the expected JSON Schema, and the received arguments.

OutputValidationErrorcode: "OUTPUT_VALIDATION_ERROR"Optional

Structured output failed the agent's outputSchema after retries. Carries the rawOutput and retry context.

#Advanced

defineKernel() defines a custom kernel — an async generator that takes full manual control of the execution loop, yielding signals such as spawn, await, interrupt, and complete. Pass the result as kernel in AgentConfig.

defineSkillTool() and skillDiscoveryMessage() implement the progressive-disclosure skills pattern without framework lock-in:

  • defineSkillTool({ skillId, load }) builds a load_skill_* tool that defers fetching the skill body to a caller-provided load function.
  • skillDiscoveryMessage(entries) builds an <available_skills> catalog string to drop into the system prompt so the model can discover what is loadable.

On the Kraken platform you author skills declaratively instead — see Skills.

Putting it together — an agent with a tool and a Google model:

ts
import { Agent, tool, google } from "kraken-ai";
import { z } from "zod";

const lookupPrice = tool({
  name: "lookup_price",
  description: "Look up the current price of a product by SKU",
  parameters: z.object({ sku: z.string() }),
  execute: async ({ sku }) => ({ sku, price: 42.0 }),
});

const agent = new Agent({
  name: "pricing-analyst",
  model: google("gemini-3-flash-preview"),
  instructions: "You are a pricing analyst. Use tools to look up product data.",
  tools: [lookupPrice],
});

const result = await agent.run([
  { role: "user", content: "What is the price of SKU-4821?" },
]);

if (result.status === "complete") {
  console.log(result.output);
}

Note

kraken-ai runs the agent loop in-process. The Kraken platform runs the same agents inside governed, sandboxed runtimes with policy enforcement, audit, and observability — see the Platform SDK.

#Next steps

  • Platform SDK — Promote agents to the governed platform: connectors, actions, skills, and the PlatformClient.
  • Agents — How agents, runs, teams, and structured output work on the Kraken platform.
  • CLI — Scaffold projects, generate types, and manage credentials with the kraken CLI.