Agent Development Kit · Reference

Glossary

One definition per word, and a link to the chapter that shows it running. Nothing here is new — every entry is the vocabulary the other chapters already use, written down once so a sentence four pages away still parses. The last section is the honest part: the words the package spends twice.

Reads · in any order, at any time Needs · nothing (no cells on this page) Package · @animahealth/adk (MIT)

Vocabulary

What you build

Nine words cover everything you hand the runner. Five of them are the closed set of runnable kinds; the rest are what those kinds are made of.

Term What it means here
runnable Anything the runner executes. A union of five kinds — agent, step, sequence, parallel, loop — each a plain object carrying a kind and a name. There is no sixth case and no escape hatch. The five kinds.
agent The only runnable kind that talks to a provider. It carries model, context and tools, and calls the model in a loop until the model stops asking for tools. The five kinds.
step Your TypeScript as a runnable, in the same session. No model, no prompt. Returning a runnable from its execute delegates to that runnable, which is how routing is written. (The runner also counts model calls in something it calls steps — see One word, two jobs.) A step is your code.
sequence Runs its runnables in order on one session, stopping early on error or yield. A sequence of two agents.
parallel Runs its branches concurrently on cloned sessions, then merges each branch's new events back into the parent ledger. Loop and parallel.
loop Repeats one runnable while a while predicate holds, capped by a required maxIterations. Loop and parallel.
app What adk(config) returns. It holds the state schema, the store, the registered adapters, app-level hooks and error handlers, and the factories that build everything else: app.agent, app.tool, app.context, app.step, app.run. An agent with a tool.
tool A name, a description, a Zod schema and a function. The name and description are prompt — they are the only reason a model reaches for this tool rather than another. The whole config.
yielding tool A tool that declares a yieldSchema. Instead of computing an answer it suspends the run until one is supplied from outside; with no execute, the supplied input becomes the result. A tool that yields.

Vocabulary

One run, and how it ends

Four nested units of work: a turn contains a run, a run contains invocations, an invocation contains model calls. They are easy to conflate, and the caps are set on different ones.

Term What it means here
run One call of app.run(runnable, input): the runnable executes against a session until it completes, yields, or fails. The quickstart.
run result What a run hands back: output, usage, status, iterations, stepEvents, session, state and runnable, plus per-status extras. There is no run.events. What the run left behind.
invocation One execution of one runnable, opened by invocation_start and closed by invocation_end. Nested runnables nest invocations, and every event carries the invocationId that produced it. One ledger, interleaved.
model call One request to a provider, bracketed by a model_start and a model_end. A tool-using turn makes two: one to decide the call, one to answer with its result. The ledger.
iteration One model call plus the tools it asked for — the unit run.iterations counts, maxSteps caps at 25, and model_start.stepIndex numbers. Timeouts and caps.
turn One input applied to a session, run to a stopping point, then committed. app.handler.turn is that unit — and the only place the afterTurn hook fires. One hook.
yield A run stopping to wait for something from outside rather than finishing. The invocation stays open — an invocation_yield with no matching invocation_end — which is precisely what a sleeping agent is. What a sleeping agent is.
run status How the run ended: completed, yielded_tool, yielded_message, error, max_steps, max_turns, aborted, transferred and the rest. Yielding for a message.
session status A different axis, describing the session rather than the run over it: active, awaiting_input, completed or error. The run that stops.
output run.output: the text of the reply, the parsed value when an output schema is set, items (every assistant event) and media. A schema on output.
usage Tokens, model calls and an estimated cost, summed from the run's model_end events. A scripted run has none — there were no tokens. What it cost.
handoff Giving work to another agent from inside a tool or step. ctx.run awaits it, ctx.spawn backgrounds it with a handle, ctx.dispatch fires and forgets, and returning a runnable transfers to it outright. What ctx carries.

Vocabulary

The ledger, and what is derived from it

One append-only list is the whole storage model. State, status, the invocation tree and a fork of the past are all computed from it rather than kept beside it.

Term What it means here
session An append-only list of events plus everything derived from it. One per program, not one per agent, so every runnable reads the same history. One ledger, interleaved.
ledger That event list read as a record: run.session.events. run.stepEvents is this run's slice of it, and the test kit's TestResult.events is an alias for the whole thing. One ledger, interleaved.
event One durable row. Every event carries id, type, createdAt, invocationId and agentName, and the package exports a type guard per type, so narrowing the union is a filter. One ledger, interleaved.
stream event What a subscriber sees while a run is in flight: the same events, minus what the session already held, plus the assistant_delta and thought_delta chunks the ledger never keeps. What the run left behind.
prompt event The six message-shaped types a provider serializes: system, user, assistant, thought, tool_call, tool_result. Everything else in the ledger is bookkeeping, and messageCount counts exactly these. Rendered every turn.
annotation An annotation event written by ctx.note(message, opts) — a phase marker, a log line, a checkpoint. It is not a prompt event, so no model sees it unless a renderer puts it there. A step is your code.
state The values an agent holds, replayed from state_change events on every read. Nothing is saved to a state table; replay is the storage. Run it, then read state.
state scope Which bucket a state key lives in: session, the shared scopes user, patient, practice, org and team, and temp. Declare only the ones you use. A schema, and its scopes.
shared scope A scope keyed by an id the session carries, so several sessions address the same values. Its values can move between reads, which is why a read is recorded as an observation state change. The audit trail.
temp The one scope never written to the ledger: scratch space for a single invocation, held in memory. Reading it outside an invocation throws. Writing state from a tool.
state schema The Zod types declared per scope on adk({ schema }). It is a compile-time contract over every read and write, and a defaults table for seeding. A schema, and its scopes.
fork session.forkAt(index) — a new session carrying the events up to that point, so an alternate history runs without disturbing this one. stateAt(index) is the read-only version of the same replay. Snapshots and time travel.
store Where the events live between runs. adk({ store }) takes one, and Postgres, SQLite, DynamoDB and the default in-memory store all implement the same SessionStore contract — so which one is a deployment decision, not an agent one. What a sleeping agent is.
commit Writing buffered events to the store. The turn, rest and agui handlers commit after every turn; driving app.run yourself, you call sessions.commit yourself. What a sleeping agent is.

Vocabulary

What the model sees

The ledger is history; the prompt is a projection of it, rebuilt before every model call. These are the words for that projection.

Term What it means here
context An agent's context: array. Not a string — a list of renderers applied in order before every model call. A context is a pipeline.
renderer A function from a RenderContext to a RenderContext. The chain starts with an empty event list, so nothing reaches the model unless a renderer puts it there. A context is a pipeline.
tap A renderer that returns its input unchanged so it can record the finished render. The only way to see the exact text a call was built from — model_start stores the shape, not the words. A context is a pipeline.
history scope history({ scope }): which invocations are visible to this render — direct, all, invocation, ancestors or agent. Unrelated to a state scope. Scopes and filters.
tool choice Which of an agent's tools the model may pick on this call. limitTools(names) narrows the choice and toolChoice sets the mode; neither removes a tool from the definitions the provider is sent. Which tools it may pick.
prompt caching Reusing a stable prompt prefix at the provider. Opt in per descriptor, and mark where the reusable prefix ends with app.context.cacheableUser(text). Prompt caching.
output schema The Zod schema on an agent's output. A renderer can read it as ctx.outputSchema, already rendered as prompt text, and every model_start records which one its call used. Native, prompt, and a real model.
output mode Where that schema is enforced. native (the default) sends it to the provider as a response format; prompt withholds it and leaves the job to your own prompt. Native, prompt, and a real model.
correction A receipt from the output parser: the path it touched, what it found, what it produced, and why. Their totalScore is what the repair cost, so a high score is a signal about your prompt. The parser under it.

Vocabulary

The model seam

Naming a model and calling one are different jobs held by different objects. That separation is what lets the same agent run against a provider or against a script.

Term What it means here
descriptor An agent's model: — a plain data object holding provider, name and options, which never talks to anyone. openai('gpt-5.6-luna') returns one; you can also write one by hand. A model is a value.
adapter The object that speaks a provider's wire protocol. Resolved per model call, in a fixed order: an adapter registered on the app wins, then the factory the descriptor carries, then a dynamic import. Descriptor, adapter, runner.
provider openai, gemini or claude — named on the descriptor, and the key an adapter is registered under. Descriptor, adapter, runner.
test kit @animahealth/adk/testing: runTest, the user/model/input/result step builders, mockAgent, MockAdapter, the assertion helpers and the vitest matchers. A scripted turn.
scripted model A MockAdapter standing in for a provider, so a run needs no key and no network. It replaces exactly one thing — the model's turns. Tools, context, state and the ledger are the real ones. The mock replaces the model.

Vocabulary

Guardrails and recovery

Two layers, deliberately separate: hooks decide what is allowed to happen, error handlers decide what a failure means.

Term What it means here
hook One object with optional lifecycle methods: onEvent, onStep, beforeAgent/afterAgent, beforeModel/afterModel, beforeTool/afterTool, and afterTurn. Attach it at the app, the agent, or one call. One hook.
interception A hook method returning a value instead of undefined. A beforeTool that returns a tool_result means the tool never executes and the model reads that result instead. A hook that says no.
error handler { canHandle?, handle }, where handle returns one of six verdicts — throw, skip, abort, retry, fallback, pass — and the first that is not pass wins. Six recovery actions.
phase Where a failure happened: model, tool, callback or render. With no handler the defaults are asymmetric — a tool error is skipped, a model error is thrown. What a throw actually does.
retry config { maxAttempts, initialDelayMs, maxDelayMs, backoffMultiplier, retryableErrors? }, set on a tool or on a descriptor. Retries are internal: the ledger records one result per call, not one per attempt. Timeouts, retries, failure.
maxSteps · maxTurns An agent's two caps: 25 iterations inside one invocation, and 100 yield-and-resume cycles. Both end the run with a status of their own name rather than an error. Timeouts and caps.

Vocabulary

Words this site uses

These are about the documentation rather than the package. They matter because a chapter tells you which of its code blocks you can press Run on, and why the others you cannot.

Term What it means here
cell A code block on these pages you can edit and press Run. It executes the shipped package in your browser, and all the cells on one page share a scope in document order. Paste a key, run everything.
mock cell A cell whose model is scripted by the test kit. It needs no key and no network, and its tools really execute. Most cells on this site are mock cells. A scripted turn.
live cell A cell that calls OpenAI with the key you paste into the box on that page. The key lives in your browser's localStorage and the request goes straight to api.openai.com. Paste a key, run everything.
static block A code block with no Run button, for code the substrate cannot serve — another provider's SDK, vitest, a server route. It is checked by hand against the same types the cells compile against. In your repo.
substrate What a page's cells are allowed to import: @animahealth/adk, @animahealth/adk/testing, @animahealth/adk/openai, and zod. Anything beyond that is a static block. In your repo.
tier The stability promise on an entry point. Core is the main entry and the subpaths beside it; Experimental/workflow, /agents/coding, /executors — may change or vanish in any release, and is reachable only through its own subpath, never the main entry.

Read this one twice

One word, two jobs

Twelve words in this package name more than one thing. The ambiguity is in the API itself, not only in the prose about it, so the fix is to read the surrounding member rather than the word. Each row is a real collision you will meet.

Word One job The other
step A runnable kind — app.step({ execute }), your code in the graph. One model call and its tools — run.iterations, maxSteps, model_start.stepIndex, run.stepEvents, the hook onStep. Nothing to do with app.step.
turn One input, run, and commit — app.handler.turn, the hook afterTurn, and maxTurns counting yield-and-resume cycles. Loosely, one model call: a scripted model(...) step is one of those, and a tool-using exchange with the user is two.
scope A state scope — session, user, temp and the rest of the buckets state lives in. A history scope — history({ scope: 'direct' }), choosing which invocations a render can see.
schema A tool's argument schema (and its yieldSchema) — the border a model's JSON has to cross. The app's state schema (adk({ schema })) and an agent's output schema (output: { schema }). Three different Zod objects, three different jobs.
status A run status — completed, yielded_tool, max_steps: how one run ended. A session status — active, awaiting_input: what the session is now. A yielded run leaves a session awaiting_input.
output The agent's output: config — the schema or state key its reply is parsed into. run.output, the value a run produced; and ctx.output(value), the signal that ends an invocation with one.
context An agent's context: renderers — the list that builds the prompt. The ctx a tool, step or hook receives — args, session, state, signal. Also RenderContext, ErrorContext, TurnContext.
agent A runnable kind — app.agent({ model, tools }), the thing the runner executes. Five primitives. A coding agent — a CodingAgent handle on a harness like Claude Code. It is a tool and a runner of its own, not one of the five kinds. Coding agents.
model The model: descriptor on an agent — a value naming a provider and a model, resolved to an adapter at run time. A model is a value. model(…), the test-kit script step standing in for one reply (the step vocabulary) — and, in prose, the LLM itself.
store A SessionStore — where the ledger and scoped state are committed. Stores: the sleeping agent. Never the vector side: qdrant, pgvector, sqliteVec and inMemoryIndex are indexes on this site, and they hold no session. Vector backends.
tool · tools app.tool({ … }) builds one function tool, and an agent's tools: array is what it may call. Tools. app.tools.* is a different thing entirely: the namespace holding the built-in web-tool factories. Web tools.
result What a run produced — run.output, and the test kit's TestResult.result, which is the whole RunResult the kit ran. What the run left behind. result({ toolName: value }), the script step supplying a yielded call's result (the step vocabulary); and tool_result, the ledger event a tool's return becomes (the ledger).

The rule that resolves most of them. Ask whether the word is naming something you built or something the runner counted. app.step is yours; stepIndex is the runner's. output: is yours; run.output is the runner's. The two never appear in the same expression.