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.
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.