Skip to content

zidane/types

Type-only access to the public agent, session, context, decision and hook types, plus the typed error classes.

import { … } from 'zidane/types'src/types-export.ts

Use zidane/types when you only need to name a type, for example in a shared package that never creates an agent. Import with import type and the entry adds nothing to your bundle. The page lists agent options and hooks, session turns and usage, execution contexts, decisions and MCP connections.

TypeScript
import type { Agent, AgentOptions, SessionTurn } from 'zidane/types'
import { createAgent } from 'zidane'
import { basic } from 'zidane/presets'
import { anthropic } from 'zidane/providers/anthropic'

const options: AgentOptions = { ...basic, provider: anthropic() }
const agent: Agent = createAgent(options)

function lastTurn(turns: SessionTurn[]): SessionTurn | undefined {
  return turns[turns.length - 1]
}

console.log(lastTurn([]), agent.hooks !== undefined)

Functions#

flattenTurnsFunction#

Depth-first walk over the stats tree, returning every TurnUsage entry — parent loop first, then each child subtree in completion order.

AgentStats.totalIn and the other total* fields already sum the whole tree. Anything that needs per-turn data across the tree, such as a per-model rollup, walks through this.

statsByModelFunction#

Group cumulative usage by TurnUsage.modelId. Each entry sums the input, output, cache, cost, and turn-count across every turn the tree attributed to that model — naturally handling cross-model runs (vision-fallback, model-shifted subagents, mixed-provider workflows).

Turns missing modelId (mock providers, providers that don't echo a model id) are bucketed under the literal string '(unknown)'.

toolOutputBudgetByteLengthFunction#

Approximate text-budget size of a tool output, in bytes.

Structured attachment blocks count as the short markers produced by toolResultToText, not as raw base64 payload bytes. The per-turn toolOutputBudget is a readability/context-loading steering guard; a vision/PDF-capable provider can receive attachment bytes without needing the model to summarize them as if they were text output.

toolOutputByteLengthFunction#

Approximate wire payload size of a tool output, in bytes.

  • Plain text: UTF-8 byte length.
  • Structured content: text blocks contribute their UTF-8 byte length; image blocks contribute their base64 character length — a proxy for the serialized request-body footprint, NOT for tokens. Vision encoders tokenize decoded pixels (geometry-dependent; e.g. Anthropic ≈ w·h/750, OpenAI ≈ 85 + 170/tile), which has no meaningful relationship to base64 length.

Used by the agent loop to populate outputBytes on tool:after, tool:transform, mcp:tool:after, and mcp:tool:transform hooks so consumers can size-budget tool output without re-counting bytes themselves. Suitable for wire-size telemetry; the per-turn toolOutputBudget uses toolOutputBudgetByteLength so attachments do not trigger text-output summarization nudges by themselves. NOT a substitute for provider-side context-window accounting — defer to server-side context management (e.g. Anthropic's context-management-* beta) when token accuracy matters.

toolResultToTextFunction#

Lossy flattener — converts ToolResultContent[] (or a plain string) to a single string. Non-text blocks are replaced with markers such as [image: <media>, <n> b64 bytes] (a ref block shows ref <ref> in place of the size).

Use at UI boundaries where a string is required; providers that understand structured content should route the array through without flattening.

Constants#

DEFAULT_AGENT_CLOCKConstant#

Native clock backing the default (Date.now + crypto.randomUUID).

Interfaces#

AgentBehaviorInterface#

Run behavior settings: limits, guards, caching, compaction and recovery policies. Set agent-wide on AgentOptions.behavior and override per run.

AgentClockInterface#

Time + UUID source. Defaults to Date.now() and crypto.randomUUID().

Scoped to journaled metadata — every callsite that lands in SessionTurn.id, SessionTurn.createdAt, runId, turnId, or hook payloads consumers may persist. Live-only measurements (TTFT deltas, elapsed counters) keep Date.now() directly so they reflect real wall-clock progress.

now() may return a Promise<number>: the loop awaits it at every callsite. randomUUID() stays synchronous so a clock can provide replay-stable identifiers without async metadata plumbing.

Precedence: AgentRunOptions.clock > AgentOptions.clock > DEFAULT_AGENT_CLOCK. A run on a replay-mode durable runtime (AgentOptions.durable) takes its time and ids from the runtime instead, so a replay regenerates byte-identical session metadata.

AgentDecideInterface#

agent.decide / ctx.decide. Never throws by default: failures come back as { ok: false, reason }. Pass { throw: true } to get a DecisionError instead.

AgentDecisionsOptionsInterface#

Agent-level configuration for decisions (AgentOptions.decisions).

AgentRunOptionsInterface#

Options for one Agent.run call.

AgentStatsInterface#

Token, cost and timing totals returned by Agent.run.

ChildRunStatsInterface#

Stats of one spawned subagent run, passed to spawn:complete and listed in AgentStats.children.

DecideHookContextInterface#

Present on every hook context except decision:* (see AgentHookHandlers).

DecisionEndHookContextInterface#

Context passed to the decision:end hook.

DecisionFailureInterface#

A decision that produced no answers. See DecisionFailureReason.

DecisionRequestInterface#

Input to agent.decide and ctx.decide: the evidence and the questions to answer about it.

DecisionStartHookContextInterface#

Context passed to the decision:start hook.

DecisionSuccessInterface#

A decision that produced answers.

DecisionUsageInterface#

Token usage of one decision call.

McpServerConfigInterface#

Configuration of one MCP server the agent connects to and exposes as tools.

McpToolHookContextInterface#

Base context for MCP tool hooks.

tool is the native tool name on the MCP server. server is the configured server name. The canonical zidane-namespaced identity is mcp_{server}_{tool}.

displayName equals the canonical namespaced name unless the agent has aliased this MCP tool via AgentOptions.toolAliases; in which case displayName is the alias that the LLM sees.

ModelUsageInterface#

Per-model usage rollup produced by statsByModel.

turns counts the number of TurnUsage entries attributed to the model across the whole tree (parent loop + every recursively-spawned child). Cache and cost numbers are summed from the same set of turns.

MutationValidationBatchInterface#

Successful mutations from one tool-results round, passed to validate.

MutationValidationFailureInterface#

Details of a failed validation, passed to onFailure.

MutationValidationHooksOptionsInterface#

Options for createMutationValidationHooks.

MutationValidationMutationInterface#

One successful file mutation (created, updated or edited) made by a tool call.

OAuthRefreshHookContextInterface#

Context for OAuth refresh hooks

PromptAudioPartInterface#

Audio attachment in a multimodal prompt.

PromptDocumentPartInterface#

Document attachment in a multimodal prompt.

PromptImagePartInterface#

Image attachment in a multimodal prompt.

PromptTextPartInterface#

Text part of a multimodal prompt.

PromptVideoPartInterface#

Video attachment in a multimodal prompt.

QueuedUserMessageInterface#

A user message that waits in a run's steering or follow-up queue (Agent.steer, Agent.followUp). The loop adds it as a user turn.

RepeatGuardConfigInterface#

Configuration for the consecutive-identical-call repeat guard. See AgentBehavior.repeatGuard for the full contract.

ResolveContentRefBlockInterface#

Block passed to a ResolveContentRef callback.

RetryConfigInterface#

Configuration for the loop's retry-with-backoff policy around provider.stream(). See AgentBehavior.retry.

SessionHookContextInterface#

Base context for session hooks

SessionMessageInterface#

One message of a session conversation, as sent to the provider.

SessionTurnInterface#

One persisted turn of a session: a user prompt, an assistant response, or a system or command entry.

SpawnHookContextInterface#

Base context for spawn hooks

StagedToolStateInterface#

Staging handle behind a ToolStateView: the seam a durable run uses to move a call's mutations through its step record. Not part of the tool-facing surface; resolve it with stagedToolState.

StreamHookContextInterface#

Context for stream hooks

ToolHookContextInterface#

Base context for tool execution hooks: the tool call a tool:* hook fires for, with ids, names, input and the run it belongs to.

name is the canonical tool identity — the spec name registered on the agent (or the mcp_{server}_{tool} name for MCP tools). Hooks should policy-match against name.

displayName is the outward-facing name — the alias surfaced to the LLM when AgentOptions.toolAliases maps the canonical name; otherwise equal to name. UI/telemetry adapters should emit displayName.

Canonical vs. alias matters on session resume: session.turns persists canonical names only, so renaming an alias cannot desync history.

ToolResultAudioContentInterface#

Audio tool-result block with inline base64 data.

ToolResultDocumentContentInterface#

Document tool-result block with inline data.

ToolResultDocumentRefContentInterface#

Document tool-result block that carries a content reference instead of inline data.

ToolResultImageContentInterface#

Image tool-result block with inline base64 data.

ToolResultImageRefContentInterface#

Image tool-result block that carries a content reference instead of inline data.

ToolResultTextContentInterface#

Text tool-result block.

ToolResultVideoContentInterface#

Video tool-result block with inline base64 data.

ToolStateControllerInterface#

Per-agent owner of the snapshot + per-call staging.

One controller per agent instance: the snapshot is shared across runs (so state written in run 1 is visible in run 2 without a reload), while each tool call gets its own view so its mutations can be journaled and committed independently.

ToolStateStoreInterface#

Durable backing for tool state. NOT runtime-specific — implement it against whatever the host already trusts with durable writes.

load runs once per agent instance, before any tool dispatch. commit receives the ops staged by one tool call, in the order the tool made them.

Two requirements on commit:

  • Idempotent. A durable adapter may hand the same ops twice if the invocation is retried before the commit is recorded.
  • Non-throwing, ideally. A rejection does not fail the tool call — the body already ran and its side effects already happened, so the dispatch path reports the failure (the tool-state:commit-failed hook, else a stderr line) and drops the write rather than killing the run. Retry inside your implementation if the write matters more than the latency.

ToolStateViewInterface#

Tool-facing view. Reads hit the hydrated snapshot merged with this call's own staged writes; writes stage an op (see the module docstring for why they aren't written through).

TurnUsageInterface#

Token usage and timing for one turn.

Types#

AgentHookBusType#

agent.hooks: the agent's hookable, with registration typed through AgentHookHandlers (so handlers see ctx.decide) while callHook keeps the raw AgentHooks context shapes.

AgentHookHandlersType#

Handler signatures as consumers see them: identical to AgentHooks except object contexts also carry DecideHookContext.decide. The agent attaches it (non-enumerable) right before handlers run, so code that fires hooks builds contexts without it.

AgentToolStateType#

Read-only window over an agent's durable tool state — the read half of the ToolStateView a tool sees through ToolContext.state, minus the write path. Backed by ToolStateController.committed, so a host reads exactly what the tools have committed so far; a call's staged writes stay invisible until it settles.

Reads are lazy: they resolve against the live state at call time, so a read inside a turn:after / agent:done hook sees every commit from the turn that just settled. The state hydrates from the configured AgentOptions.toolState store at run start (memoized on success, retried on a failed load) — before the first run, reads report only what this process has committed, which for a fresh agent is nothing. Read after a run, not before.

There is no set: a host-level write has no tool result to be journaled with, so it would not survive a durable replay — exposing it would reintroduce exactly the class of bug the staging design exists to prevent. Mutate state from inside a tool.

Scope is this agent instance only. Tool state is NOT inherited by subagents (spawn starts a fresh controller), so this view never reflects a child's writes.

DecisionAnswerType#

Answer to one question: a predicate, choice or score answer, or a refusal.

DecisionAnswersType#

Answers keyed by question name, each typed from its question.

DecisionFailureReasonType#

Why a decision produced no answers:

  • unavailable: decisions disabled, no capable provider, missing credentials, or unknown model
  • auth: the provider rejected the credential (401/403)
  • unsupported: the input can't be expressed on this provider's wire (e.g. images)
  • timeout / aborted: wall-clock cap hit / caller or run cancelled
  • rate_limited / quota: 429 or 529 / 402
  • invalid: the request failed validation, or the response was malformed
  • error: anything else (5xx, network)

DecisionInputType#

The evidence the questions are evaluated against:

  • a string,
  • a JSON object of related context,
  • multimodal prompt parts (text + images; support varies per provider).

DecisionOutcomeType#

Result of a decision: a DecisionSuccess or a DecisionFailure. Narrow on ok.

DecisionQuestionType#

One question: a predicate, a choice or a score.

DecisionQuestionsType#

Questions keyed by name. The name keys the matching answer.

MutationValidationResultType#

Result of a validation: { ok: true }, or { ok: false } with an optional message and error list.

ProgressNudgeKindType#

Stall pattern that can trigger a progress nudge. See AgentBehavior.progressNudges.

ProgressNudgeMessageType#

Message a progress nudge steers the model with: a fixed string, or a function of the nudge kind and its trigger count.

PromptPartType#

One block of a multimodal user prompt.

agent.run({ prompt }) accepts either a plain string (treated as a single text part) or an array of these parts for multimodal inputs.

document parts are routed per provider: PDF-style mime types are sent as native document blocks when the provider supports them; text documents are inlined as text with an attachment header. Providers that cannot handle an image or document throw early.

QueuedMessageOptionsType#

What Agent.steer and Agent.followUp take besides the prompt.

RepeatGuardToolMatcherType#

Per-tool predicate selecting which tools the RepeatGuardConfig watches. A bare string matches that exact canonical name; a function receives the canonical name and returns true to track it.

ResolveContentRefType#

Host callback that resolves a content reference to its payload. Called at provider wire time with the block that holds the ref.

RunHookMapType#

Per-run hook registrations. Each entry can be a single handler or an array of handlers. Keys are AgentHooks event names (loose-typed here to avoid a circular import; agent-run.ts validates the event names at run time, and AgentHookMap is the strongly-typed form).

SessionContentBlockType#

Content block of a session message: text, media, a tool call, a tool result, or thinking.

text, tool_call and thinking blocks can carry a signature: opaque state the producing API wants back with that block (a Gemini thought signature, an Anthropic thinking HMAC, OpenAI encrypted reasoning), tagged with its SignatureProducer. Only that provider's wire builder reads it; the others map blocks field by field and never send it.

SessionEndStatusType#

How a run ended: 'completed', 'aborted' or 'error'.

SuccessfulMutationOutcomeType#

Tool outcomes that count as a successful mutation.

ThinkingLevelType#

One of the THINKING_LEVELS strings: how much the model reasons before it answers.

ToolOutcomeType#

Structured side-effect outcome for mutating tools (write_file, edit, multi_edit, and custom tools that opt in via ToolContext.reportOutcome).

Surfaced on tool:after.outcome so hosts can build no-op-resistant loop guards ("did this edit actually change bytes?") WITHOUT string-matching the result prose (Created /Updated /No change needed …), which is fragile across versions. Absent on tool:after for read-only tools and any tool that never calls reportOutcome.

  • created — a new file/resource was written.
  • updated — an existing file/resource changed (full overwrite differed).
  • edited — a surgical in-place change applied at least one replacement.
  • noop — the call succeeded but changed zero bytes (idempotent write, replacement that produced identical content).
  • failed — the mutation was attempted but did not take effect (error, stale-read rejection, no-match). Pairs with isError on the wire result; reported explicitly so guards don't have to infer.

ToolResultContentType#

A single block of structured tool-result content.

MCP servers can return a mix of text, image, audio, video, and resource blocks. Tools return string for the common text-only case or ToolResultContent[] when they need to preserve non-text content (e.g. screenshots from a browser MCP).

Providers that support native multi-part tool results (Anthropic, OpenAI Codex via pi-ai) route image blocks into their wire format verbatim; OpenAI-compat providers route them via a companion-user-message fallback when the underlying model/endpoint does not accept images inside tool-role messages.

ToolResultMetadataType#

Provider/model-invisible metadata associated with a tool result. Hooks use this to persist telemetry about transforms (compression, redaction, etc.) without adding model-visible text to the result body. Hooks can read it; the model never sees it.

ToolStateOpType#

One staged mutation. JSON-shaped on purpose: durable adapters journal these verbatim, so a tagged union with an explicit delete flag beats value: undefined (which JSON drops).

TurnFinishReasonType#

Reason the provider gave for stopping the turn.

  • 'stop' — natural turn end (end_turn / stop_sequence).
  • 'tool-calls' — model emitted tool_use blocks.
  • 'length' — max_tokens reached, or (Anthropic 4.6+) the response bumped against the model's context window mid-stream (model_context_window_exceeded). The partial response is preserved; the loop emits this reason so consumers can prune/retry.
  • 'content-filter' — model refused.
  • 'pause' — Anthropic pause_turn: a server-side mid-turn pause for very long thinking. The loop continues with a synthetic "Please continue." user message rather than terminating; consumers see the pause via this finish reason on the prior assistant turn.
  • 'error' — provider classified the turn as failed.
  • 'other' — unknown / unmapped.

Re-exports#

These names are documented on the entry point that owns them.