Mount a git repository the model may read for the rest of this agent's life.
Takes the same spec B.git.repo.open takes, or a repo already opened with it — the opened form is
the only one available for a repository constructed from live content, since building one needs a
live folder the script has to supply.
The model is given an alias and nothing else: never a url, a host, an organization, a repository
name, or a credential. A repo without an alias is refused here rather than given an invented one —
name it in the spec, or open it with alias. Each mount is pinned to a commit when the call begins,
so a concurrent publish cannot shift the ground mid-conversation, and the pinned shas come back on
every result as mounts.
const agent = B.ai.agent()
.addRepo({ alias: "scripts", purpose: "script", repo: "100001___200002", ref: "master" });
A mount spec, or a repo from B.git.repo.
Add a tool to the agent's tool registry. Every subsequent
sendMessage(...) exposes the accumulated tools to the model.
Inline literals get their executor's args parameter typed via
FromSchema<S> — the same inference trick B.ai.call and
B.ai.tool.custom() use. Tools produced by B.ai.tool.custom() /
forNewEntry / forExistingEntry pass through as AiTool. Returns
this agent for chaining.
Tool to add to the registry.
Deprecated: with resume(results) the reviewed results go back into
the conversation itself, so the model sees what was applied; this
runs the executors outside it.
Applies the user-reviewed (and possibly modified) tool calls
produced by a stub-mode sendMessage(message, false). Each
entry's name is looked up in this agent's tool registry and
its executor is invoked with the entry's arguments. Returns
an array mirroring the toolCalls shape: {name, arguments, result, isError}[]. Tools the agent doesn't know about produce
an isError: true entry rather than throwing.
The transcript is NOT mutated. sendMessage(message, false)
and applicator(...) are both transparent to the agent's
conversation: the user message that triggered the stub, the
assistant's tool_use turn, and the real tool results are all
left out, because the model never saw the results and a
transcript holds only what the model saw. To carry what was
applied forward on this path, say so in the next
sendMessage(...) text. To carry it forward losslessly, defer
through onToolCall and resume instead.
Tool calls to dispatch. Typically the (possibly modified) toolCalls array returned by sendMessage(message, false).
The conversation as plain text turns: the hand-written seed until the first executed call, and after that the user messages and assistant answers of the transcript — tool cycles left out, as this shape cannot carry them. getTranscript() is the lossless view. Mutating the returned array does not affect the agent.
The conversation as the model last saw it: every message of every executed sendMessage(...) so far, tool calls and results included. Empty until the first executed call returns, and after a reset. Store getTranscript().toJson() to continue in a later execution with setTranscript(json).
Unmount the repository holding alias, so later sendMessage(...) calls no longer offer it to the model. Returns this agent for chaining; unmounting an alias that is not mounted is not an error.
The alias the repo was mounted under.
Remove a tool from the agent's tool registry by name. No-op when no tool with that name is registered. Returns this agent for chaining.
Name of the tool to remove.
Answer the tool calls an onToolCall hook deferred, and continue the
conversation from there. Takes one entry per open call — the ids from
AiCallResult.deferred — each with the result the tool is taken to
have returned (a string, a number, an object; rendered as a tool's own
return value would be) and an optional isError. Every open call must be
answered and every entry must name an open call; anything else is refused
naming the id, before the model is asked. The results go onto the
transcript as tool results, the model is asked again with no new user
message, and the loop runs on under the same tools, knobs and hooks.
Works across executions: run A defers and stores
getTranscript().toJson() and result.deferred; a reviewer edits or
approves; run B builds an agent with the same tools,
setTranscript(json), and calls resume(results).
const agent = B.ai.agent({tools: [createEntry], onToolCall: () => ({action: "defer"})});
const proposed = agent.sendMessage("File the intake for the new resident.");
// ... later, after review ...
const done = agent.resume(proposed.deferred.map(c => ({id: c.id, result: apply(c)})));
One answer per deferred call.
Send a user message through the configured agent. Builds a fresh
AiCallOptions from the agent's current state (provider, model,
flag, systemPrompt, tools, the conversation so far, onTurn,
the hooks) plus the supplied message, dispatches through the same
usage-gated B.ai.call pipeline, and returns the resulting
AiCallResult. The agent then keeps result.transcript — every
message the model saw, tool cycles included — so subsequent
sendMessage(...) calls continue the conversation from exactly
there. Denied calls (result.denialCode set) leave the agent's
transcript untouched, since the model never saw that message.
When the onToolCall hook defers a call, the kept transcript ends on
that open call and the next step is resume(results), not another
message: a sendMessage(...) on such a transcript is refused naming
the open calls.
User message to send.
Deprecated: the review-and-apply pair is now onToolCall returning
{action: "defer"} plus resume(results), which threads the reviewed
results back into the same conversation losslessly — in this execution
or, with getTranscript().toJson() stored in between, in a later one.
When executeTools is true, identical to the 1-arg sendMessage(message).
When false, the call runs with a hook that defers every tool call the
model requests: the model's first round of tool calls ends the call with
outcome: "STOPPED_BY_HOOK", stopReason: "deferred", deferred listing
them, and toolCalls listing them in the old shape ({name, arguments, result: "action queued", isError: false}) for applicator(...). No
executor runs. The agent's transcript is not mutated — the result's
transcript holds the exchange with the calls open, and a script that
wants to resume it seeds the agent with setTranscript(result.transcript)
first, since this overload leaves the agent as it was.
This differs from the stub mode it replaces, which fed the model a fake
"action queued" result and asked again until it answered in prose: the
result reported outcome: "END_TURN" with that closing prose as text,
and toolCalls covered every round the model chained. Here the model
makes one round of calls, outcome is "STOPPED_BY_HOOK", stopReason
is "deferred", and text is whatever the tool-use turn itself wrote,
usually nothing. A script that branched on outcome === "END_TURN"
must branch on "STOPPED_BY_HOOK" here. Real chaining is what resume
provides.
User message to send.
When false, every tool call is deferred, listed as "action queued", and the agent's transcript is left untouched. When true, identical to the 1-arg overload.
Shorten the conversation automatically as it fills the model's context window. See AiClientOptions.autoCompact. Null clears it, which is the default. Returns this agent for chaining.
When to compact and how much to keep, or null to let the conversation grow.
Replace the conversation with a hand-written seed. Pass [] (or null)
to reset. Any transcript the agent held is discarded: the seed is what
the next sendMessage(...) sends, and the transcript that call returns
then carries the conversation from there. To continue a conversation a
previous call produced, prefer setTranscript(...), which keeps the
tool cycles this shape cannot. Returns this agent for chaining.
Replacement chat history. Each entry is {role: "user"|"assistant"|"tool", content: string}.
Set a wall-clock budget for each sendMessage(...), in milliseconds. See AiClientOptions.deadlineMillis. Null clears it. Returns this agent for chaining.
A positive whole number of milliseconds, or null for no deadline.
Set how much reasoning the model spends before answering. See AiClientOptions.effort. Null clears it. Returns this agent for chaining.
The level, or null for the provider's default.
Set the usage gate tracking flag (e.g. "marketingModule"). Returns this agent for chaining.
Custom tracking flag reported to the usage gate.
Set the most model round-trips one sendMessage(...) may make. See AiClientOptions.maxIterations. Null clears it. Returns this agent for chaining.
A positive whole number, or null for the gate's and the harness's caps alone.
Set the most output tokens the model may generate on one iteration, for every sendMessage(...). See AiClientOptions.maxTokens. Null clears it. Returns this agent for chaining.
A positive whole number, or null for the provider's default.
Set the AI model identifier. Falls back to the provider's configured default when unset. Returns this agent for chaining.
Model identifier.
Set the hook called with each piece of assistant text as it streams. See AiClientOptions.onDelta. Pass null to clear. Returns this agent for chaining.
The hook, or null to clear.
Set the hook called after each model round-trip, which may stop the loop. See AiClientOptions.onIteration. Pass null to clear. Returns this agent for chaining.
The hook, or null to clear.
Set the hook called before each model request with the message list about to be sent. See AiClientOptions.onRequest. Pass null to clear. Returns this agent for chaining.
The hook, or null to clear.
Set the hook called for each tool call before it runs, which may run it (with other arguments), deny it, or defer it for resume(results). See AiClientOptions.onToolCall. Pass null to clear. Returns this agent for chaining.
The hook, or null to clear.
Set the hook called with what each tool returned before the model sees it. See AiClientOptions.onToolResult. Pass null to clear. Returns this agent for chaining.
The hook, or null to clear.
Set the per-turn continuation callback used by every sendMessage(...)
on this agent. Pass null to clear. After each completed assistant
turn (no outstanding tool calls), the callback is invoked with the
response; return an AiTurnDecision with a message to continue, or
{done: true} / null to stop. Returns this agent for chaining.
Continuation callback, or null to clear.
Set whether one answer may request several tool calls at once. See AiClientOptions.parallelToolCalls. Null clears it. Returns this agent for chaining.
The switch, or null for the provider's default.
Set the AI provider name (e.g. "anthropic"). Falls back to the configured tenant default when unset. Returns this agent for chaining.
Provider name.
Set a JSON schema the final answer must conform to; result.parsed is then the answer parsed. See AiClientOptions.responseSchema. Null clears it. Returns this agent for chaining.
The schema, or null for free text.
Set the strings the model stops generating at. See AiClientOptions.stopSequences. Null or an empty array clears them. Returns this agent for chaining.
The sequences, or null for none.
Set the system prompt sent on every sendMessage(...). When provided, replaces the configured tenant default; per-call agent directives are still appended. Returns this agent for chaining.
System prompt text.
Set whether the model thinks before it answers. See AiClientOptions.thinking. Null clears it. Returns this agent for chaining.
The mode, or null for the provider's default.
Set whether the model must call a tool on each iteration. See AiClientOptions.toolChoice. Null clears it. Returns this agent for chaining.
The choice, or null for the provider's default.
Record what each model round-trip costs, in the trace of every result this agent returns. See AiClientOptions.trace. Null clears it, which is the default. Returns this agent for chaining.
True to trace, or null/false not to.
Replace the conversation with a transcript a previous call produced —
an AiTranscript (result.transcript, or getTranscript() from another
agent) or the string its toJson() returned, which is how a conversation
is carried between executions. Pass null to reset. Any hand-written
chatHistory seed is discarded. A string that does not decode, or whose
tool results do not pair with tool calls, throws with a message naming
the entry. Returns this agent for chaining.
The conversation to continue, or null to start over.
Reusable AI agent. Holds connection settings, an accumulated tool registry, an onTurn callback, the per-iteration hooks (
onRequest,onToolCall,onToolResult,onIteration,onDelta), and the running conversation as anAiTranscript; eachsendMessage(...)dispatches through the same usage-gated pipeline asB.ai.call. After each executed call the agent keeps the returned transcript — every message the model saw, tool calls and results included — and seeds the next call from it; calls the usage gate denied leave it untouched. WhenonToolCalldefers a call the transcript is kept with that call open andresume(results)continues it, in this execution or a later one. Carry a conversation across executions withgetTranscript().toJson()andsetTranscript(json). Returned byB.ai.agent().Example: ```javascript
const agent = B.ai.agent({ systemPrompt: "You summarize intake notes." }) .setModel("claude-opus-5") .addTool(lookupResident);
agent.sendMessage("Summarize the note on file."); const result = agent.sendMessage("Now list every medication you saw.");
// The second call already knew about the first; park it for the next execution. B.ai.state(curEntry.fields.agentState).save(agent);