manifest
Manifest barrel — agent config conversion and tool schema handling.
Used by aai-cli (bundler) and aai-server (rpc-schemas). Generated bundle
entries call toAgentConfig, which is why this subpath is published.
Functions
Section titled “Functions”agentToolsToSchemas()
Section titled “agentToolsToSchemas()”agentToolsToSchemas(
tools):ToolSchema[]
Parameters
Section titled “Parameters”Readonly<Record<string, ToolDef>>
Returns
Section titled “Returns”normalizeToolMessages()
Section titled “normalizeToolMessages()”normalizeToolMessages(
input):ToolMessages|undefined
Author input → the wire shape, dropping every kind the tool did not declare.
Answers undefined for a tool with nothing to say, so a schema for an
ordinary tool is byte-identical to what it was before this field existed —
which is what keeps messages off every deployed agent’s tool declarations
and out of every snapshot that did not opt in.
Parameters
Section titled “Parameters”ToolMessagesInput | undefined
Returns
Section titled “Returns”ToolMessages | undefined
toAgentConfig()
Section titled “toAgentConfig()”toAgentConfig(
source):object
Convert an agent definition into its serializable AgentConfig,
injecting the default providers, deriving the session mode, and running
the cross-field validation rules. Called from generated bundle entries and
the runtime.
Parameters
Section titled “Parameters”source
Section titled “source”Returns
Section titled “Returns”object
builtinTools?
Section titled “builtinTools?”
optionalbuiltinTools?: readonlystring[]
deadAirCoverMs?
Section titled “deadAirCoverMs?”
optionaldeadAirCoverMs?:number
description?
Section titled “description?”
optionaldescription?:string
errorPhrase?
Section titled “errorPhrase?”
optionalerrorPhrase?:string
greeting
Section titled “greeting”greeting:
string
idleTimeoutMs?
Section titled “idleTimeoutMs?”
optionalidleTimeoutMs?:number
interruptionBackoffMs?
Section titled “interruptionBackoffMs?”
optionalinterruptionBackoffMs?:number
interruptionMinDurationMs?
Section titled “interruptionMinDurationMs?”
optionalinterruptionMinDurationMs?:number
{
kind:string;options:z.ZodRecord<z.ZodString,z.ZodUnknown>; }
maxOutputTokens?
Section titled “maxOutputTokens?”
optionalmaxOutputTokens?:number
maxRetries?
Section titled “maxRetries?”
optionalmaxRetries?:number
maxSteps?
Section titled “maxSteps?”
optionalmaxSteps?:number
mcpServers?
Section titled “mcpServers?”
optionalmcpServers?:Record<string, {pinnedTools?:Record<string,string>;tokenEnv?:string;url:string; }>
minBargeInWords?
Section titled “minBargeInWords?”
optionalminBargeInWords?:number
optionalmode?:"s2s"|"text"|"pipeline"
name:
string
optionalpage?:"voice"|"static"
preemptiveGeneration?
Section titled “preemptiveGeneration?”
optionalpreemptiveGeneration?:boolean
requiredEnv?
Section titled “requiredEnv?”
optionalrequiredEnv?: readonlystring[]
resetToolChoice?
Section titled “resetToolChoice?”
optionalresetToolChoice?:boolean
resumeFalseInterruption?
Section titled “resumeFalseInterruption?”
optionalresumeFalseInterruption?:boolean
{
kind:string;options:z.ZodRecord<z.ZodString,z.ZodUnknown>; }
silencePrompt?
Section titled “silencePrompt?”
optionalsilencePrompt?:string
silenceTimeoutMs?
Section titled “silenceTimeoutMs?”
optionalsilenceTimeoutMs?:number
startFailurePhrase?
Section titled “startFailurePhrase?”
optionalstartFailurePhrase?:string
startSpeakingFloorMs?
Section titled “startSpeakingFloorMs?”
optionalstartSpeakingFloorMs?:number
{
kind:string;options:z.ZodRecord<z.ZodString,z.ZodUnknown>; }
sttPrompt?
Section titled “sttPrompt?”
optionalsttPrompt?:string
systemPrompt
Section titled “systemPrompt”systemPrompt:
string
telephony?
Section titled “telephony?”
optionaltelephony?:boolean| readonlystring[]
temperature?
Section titled “temperature?”
optionaltemperature?:number
optionaltext?:true
toolChoice?
Section titled “toolChoice?”
optionaltoolChoice?:"auto"|"required"|"none"| {toolName:string;type:"tool"; }
{
kind:string;options:z.ZodRecord<z.ZodString,z.ZodUnknown>; }
turnDetection?
Section titled “turnDetection?”
optionalturnDetection?:string
usageLimits?
Section titled “usageLimits?”{
totalTokens?:number; }
userTurnLimit?
Section titled “userTurnLimit?”{
maxDurationMs?:number;maxWords?:number; }
voicePresets?
Section titled “voicePresets?”
optionalvoicePresets?: readonlystring[]
toolRegistry()
Section titled “toolRegistry()”toolRegistry(
modules):ToolRegistry
Build a checked registry from already-loaded modules.
Synchronous, because the caller that matters most — the generated worker
entry — has the modules statically imported already, and a Promise there
would put top-level await in a bundle the guest loads.
Parameters
Section titled “Parameters”modules
Section titled “modules”Returns
Section titled “Returns”withTools()
Section titled “withTools()”withTools<
D>(def,registry):D
Attach a registry to an agent definition, returning the def the runtime runs.
A NEW object rather than a mutation: the def a module default-exports is shared (a spec imports the same one the entry does), and a loader quietly rewriting it makes the order of two imports decide what an agent can do.
It is also the seam every registry NOT assembled by a bundler goes on
through. Two do. withToolsDir (@alexkroman1/aai-runtime) scans a real
directory for a self-hosted process and comes back here. And the studio’s own
coding agent resolves its tool families from a session
(aai-guest/studio-agent.ts), which is what makes that honest rather than an
exception: a registry resolved from a session instead of from a directory,
attached the same way.
Closing over a directory is NOT what puts a registry here — this said so,
and templates/coding-agent/ disproves it: nine tools that all close over one
directory, shipped as FILES, each re-exporting an entry from a registry
shared.ts builds once. What the studio has that a template does not is a
directory chosen per SESSION and re-materialized under a running process,
where a file’s default export is evaluated once at import. The distinction is
LIFETIME, not closure, and it matters because the closure reading would tell
an author their tools cannot be files when they can.
A name the def ALREADY holds is an error. Through agent() that is now
unreachable — it returns an empty table and refuses a tools argument — so
what this catches is a hand-written export default { … tools: {…} } that
skipped agent(), and a second withTools over a def that already has one.
A name the def declared as a BUILTIN is an error too, and that one an
author can reach. builtinTools: ["calculate"] beside tools/calculate.ts
is one file name away at all times, filenames being the only thing here a
user picks freely — and it built clean: the runtime’s merge drops the
colliding builtin (mergeBuiltinSurface), so the entry the author wrote did
nothing and the only trace was one info line in a session log, minted at the
first call rather than at the build. That is the same silence discovery was
introduced to kill (“forgetting one line was silent”), reached by the other
route, and it is the one collision where BOTH halves were declared on purpose
— so it is a contradiction to report rather than a precedence to apply.
Structural rather than AgentDef, and it hands back what it was given: a
caller keeps whatever else its def carries, and nothing this returns is
described by a type the caller did not already name. builtinTools joins the
constraint as optional and widened to readonly string[], so a def that
carries none still passes and this module still names no builtin catalog.
Type Parameters
Section titled “Type Parameters”D extends object
Parameters
Section titled “Parameters”D
registry
Section titled “registry”Returns
Section titled “Returns”D
Type Aliases
Section titled “Type Aliases”AgentConfig
Section titled “AgentConfig”AgentConfig =
z.infer<typeofAgentConfigSchema>
JSON-safe subset of the agent definition — the canonical serializable config that flows CLI → server → runtime unchanged.
AgentConfigSource
Section titled “AgentConfigSource”AgentConfigSource =
Omit<AgentConfig,"mode"|"systemPrompt"> &object&{ [K in HostOnlyAgentField]?: unknown }
What toAgentConfig accepts: every serializable AgentConfig
field (mode excepted — it is derived, never supplied) plus the host-only
fields the deny-list strips. AgentDef is assignable to this by
construction; the explicit | undefined on the host-only members keeps
spread call sites ({...agent, stt: maybeUndefined}) legal under
exactOptionalPropertyTypes.
Type Declaration
Section titled “Type Declaration”systemPrompt?
Section titled “systemPrompt?”
optionalsystemPrompt?:AgentSystemPrompt
Wider than the config’s own string, because AgentDef.systemPrompt
may be a RESOLVER — a function this layer cannot serialize and must not
hand onward. Widened here rather than on AgentConfig so AgentDef
stays assignable to this by construction, which is what every
toAgentConfig(agent) call site relies on. toAgentConfig drops it (see
staticSystemPrompt); the runtime holds the agent’s own module and asks
the function per request.
HostOnlyAgentField
Section titled “HostOnlyAgentField”HostOnlyAgentField = typeof
HOST_ONLY_AGENT_FIELDS[number]
A host-only AgentDef field name stripped by toAgentConfig (tools, events, …).
SessionMode
Section titled “SessionMode”SessionMode =
"s2s"|"pipeline"|"text"
Session mode derived from which provider fields are set.
toAgentConfig, createRuntime, and the server’s IsolateConfigSchema
all use assertProviderTriple so there’s one source of truth for the
validation.
"text" is the one mode with no audio path at all: the agent is an LLM,
a system prompt and its tools, driven by createTextAgent
(@alexkroman1/aai-runtime) over a message list rather than by a
transport over a socket.
ToolModules
Section titled “ToolModules”ToolModules =
Readonly<Record<string,unknown>>
path → module namespace, which is what both sources produce: Vite’s
import.meta.glob (eager) and the static import list the CLI generates.
ToolRegistry
Section titled “ToolRegistry”ToolRegistry =
Readonly<Record<string,ToolDef<ToolInputSchema>>>
A checked set of tools, keyed by the name the model calls.
ToolSchema
Section titled “ToolSchema”ToolSchema =
object
A tool declaration in wire form: name, description, and JSON Schema
parameters — the serializable counterpart of ToolDef.
Properties
Section titled “Properties”description
Section titled “description”description:
string
messages?
Section titled “messages?”
optionalmessages?:ToolMessages
The tool’s spoken messages, NORMALIZED — see ToolMessages.
It rides on the wire declaration rather than beside it because that is what
makes the feature mean the same thing in every mode: the deployed guest
builds this from the agent’s own ToolDefs, and a host-mode client that
supplies its own tool declarations gets the behaviour by declaring the
field. Nothing here reaches the model — toVercelTools passes name,
description and parameters to the provider and reads this itself.
Absent for every tool that declares none, which is what keeps an ordinary tool’s wire declaration byte-identical to what it was before the field existed.
name:
string
parameters
Section titled “parameters”parameters:
JSONSchema7
type:
"function"
Variables
Section titled “Variables”HOST_ONLY_AGENT_FIELDS
Section titled “HOST_ONLY_AGENT_FIELDS”
constHOST_ONLY_AGENT_FIELDS: readonly ["tools","syncState","workflows","subagents","personas","dialogs","events","inputGuardrails","outputGuardrails"]
AgentDef fields that must never cross the serialization boundary — the
single deny-list toAgentConfig strips. Everything else on the agent
definition flows into AgentConfig by default, so a new serializable
field works CLI → server → runtime without touching a mapper. A field added
to AgentDef must appear either in AgentConfigSchema or here — the
type-level guard in the internal-types test enforces that subtraction.
It cannot catch a SUPERFLUOUS entry, which is the other direction and the one
that went stale: state sat here after AgentDef.state was deleted with the
ctx.state bag, denying a key nothing produces and telling every reader the
bag still exists. An entry here is a claim that AgentDef has that field.
References
Section titled “References”ToolCompletionMessage
Section titled “ToolCompletionMessage”Re-exports ToolCompletionMessage
ToolDelayedMessage
Section titled “ToolDelayedMessage”Re-exports ToolDelayedMessage
ToolMessageCondition
Section titled “ToolMessageCondition”Re-exports ToolMessageCondition
ToolMessages
Section titled “ToolMessages”Re-exports ToolMessages
ToolMessagesInput
Section titled “ToolMessagesInput”Re-exports ToolMessagesInput
ToolStartMessage
Section titled “ToolStartMessage”Re-exports ToolStartMessage