Bluestep JS Documentation
    Preparing search index...

    Interface AiCallOptions<Schemas>

    Options for B.ai.call(). Extends AiClientOptions with a single-call message. At least one of message, chatHistory or transcript must be provided. The type parameter Schemas carries the literal types of each tool's input_schema so inline tool literals get a typed executor args parameter without an explicit cast — see B.ai.call.

    interface AiCallOptions<
        Schemas extends readonly JSONSchema[] = readonly JSONSchema[],
    > {
        autoCompact?: AiAutoCompactOptions;
        chatHistory?: AiChatHistoryEntry[];
        deadlineMillis?: number;
        effort?: "low" | "medium" | "high" | "xhigh" | "max";
        flag?: string;
        maxIterations?: number;
        maxTokens?: number;
        message?: string | AiContentBlock[];
        model?: string;
        onDelta?: (text: string) => void;
        onIteration?: (state: AiIterationState) => void | AiIterationDecision;
        onRequest?: (transcript: AiTranscript) => void;
        onToolCall?: (call: AiToolCallEvent) => void | AiToolCallDecision;
        onToolResult?: (
            call: AiToolCallEvent,
            result: AiToolResultEvent,
        ) => void | AiToolResultOverride;
        onTurn?: (response: AiCallResult) => AiTurnDecision;
        parallelToolCalls?: boolean;
        provider?: string;
        repos?: (GitRepo | GitMountSpec)[];
        responseSchema?: JSONSchema;
        stopSequences?: string[];
        systemPrompt?: string;
        thinking?: "adaptive" | "disabled";
        toolChoice?: "auto" | "none" | "any" | { tool: string };
        tools?: { [K in string | number | symbol]: AiToolLiteral<Schemas[K]> };
        trace?: boolean;
        transcript?: string | AiTranscript;
    }

    Type Parameters

    Hierarchy (View Summary)

    Index
    autoCompact?: AiAutoCompactOptions

    Shorten the conversation automatically as it approaches the model's context window, instead of letting it grow until the provider refuses it. Omit to leave it alone, which is the default.

    Where the model compacts server-side — the provider is asked whether this one does, not assumed from its name — the provider does the work and the transcript comes back carrying its summary. Where it does not, the harness folds the middle of the conversation into one message before sending, keeping the first turn and the last keepLastTurns, and cutting only at turn boundaries so tool pairs are never split.

    Either way this rewrites history the script can still read afterwards, which is why it happens only when asked for.

    chatHistory?: AiChatHistoryEntry[]

    Conversation history to seed the model with, hand-written. Each entry is {role: "user"|"assistant"|"tool", content: string}. To continue a conversation a previous call produced, pass its transcript instead — it carries the tool cycles this shape cannot. Supplying both throws.

    deadlineMillis?: number

    A wall-clock budget for the whole call — on an agent, for each sendMessage — in milliseconds, measured on the same clock as result.durationMillis. Checked between iterations, never mid-request: a tool that ran has had its effect, so the loop stops before the next model request rather than during one. When it stops the loop, outcome is DEADLINE and the transcript ends on the last tool result. A retry that would end after the deadline is not taken.

    effort?: "low" | "medium" | "high" | "xhigh" | "max"

    How much reasoning the model spends before answering. Anthropic output_config.effort, all five levels; OpenAI reasoning_effort, with xhigh and max sent as high. Each provider declares which knobs it takes, and a call naming one the provider does not is refused before anything is sent. Omit for the provider's default.

    flag?: string

    Custom tracking flag (e.g. "marketingModule"). Reported to the usage gate so superusers can scope limits and reporting by flag.

    maxIterations?: number

    Most model round-trips this call may make. The usage gate may issue a cap of its own; the smaller of the two applies, and the harness's hard cap sits above both. When it stops the loop, outcome is ITERATION_LIMIT and the pending tool calls are not executed.

    maxTokens?: number

    Most output tokens the model may generate on one iteration. Overrides the configured default (Anthropic max_tokens, OpenAI-compatible max_completion_tokens). Must be a positive whole number.

    message?: string | AiContentBlock[]

    User message to send to the model: a string, or an array of content blocks for an image, a PDF, or a file read straight out of a mounted repo. Appended after the seed (chatHistory or transcript) when one is provided. Omitted with a seed that ends on an assistant turn, the list goes to the model unchanged, which treats it as a prefill of its own answer: it continues that turn rather than answering anything new.

    model?: string

    AI model identifier to use. Falls back to the provider's configured default when omitted.

    onDelta?: (text: string) => void

    Called with each piece of assistant text as the provider streams it, in order, on the script thread. A provider that cannot stream delivers each answer's whole text as one delta once it has arrived. A request that fails after text was delivered is not retried, so a delta is never shown twice; the failure reaches the script as an AiCallException. A hook that throws ends the call with outcome: "ERROR" where it threw: the rest of the answer is abandoned unread, no tool of that turn runs, and the exception is the script's own.

    onIteration?: (state: AiIterationState) => void | AiIterationDecision

    Called after each model round-trip, once its usage is counted and before any tool it requested runs, with the call's running totals and what the round-trip produced. Return {stop: true, reason?} to end the loop there: the tool calls are not executed, outcome is STOPPED_BY_HOOK, hookReason is the reason, and onTurn is not consulted. A stop outranks the caps: a round-trip the output cap also truncated ends as STOPPED_BY_HOOK, and state.stopReason is where the hook sees the cap. Return nothing to continue. Runs on the script thread; a hook that throws ends the call with outcome: "ERROR" — the exception is the script's own, no result or transcript comes back, and what earlier iterations' tools did is not undone.

    onRequest?: (transcript: AiTranscript) => void

    Called before each model request with the message list about to be sent, an AiTranscript, for inspection. What it does to the object does not reach the request. Runs on the script thread; a hook that throws ends the call with outcome: "ERROR".

    onToolCall?: (call: AiToolCallEvent) => void | AiToolCallDecision

    Called for each tool call the model requests, before it runs. Return {action: "run"} (with arguments to run it with different arguments), {action: "deny", reason} to refuse it — the model is shown the reason as an error result and continues — or {action: "defer"} to leave it unanswered: the call then ends with outcome: "STOPPED_BY_HOOK" and deferred lists it for AiAgent.resume(results), in this execution or a later one. Return nothing to run the call as requested. Every call of one model turn is put to the hook; those it runs or denies are answered, those it defers stay open. call.annotations carries whatever the tool's author declared (readOnly, destructive, idempotent), so one policy can cover every tool without naming them. Runs on the script thread; a hook that throws ends the call with outcome: "ERROR" — the exception is the script's own, no result or transcript comes back, and what earlier calls of the turn already did stands.

    onToolResult?: (
        call: AiToolCallEvent,
        result: AiToolResultEvent,
    ) => void | AiToolResultOverride

    Called with what a tool returned, whole, before the model sees it. Return {content} to replace the text the model is shown — the usual clip then applies to the replacement — or nothing to leave it. The toolCalls summary keeps what the tool returned either way. Runs on the script thread; a hook that throws ends the call with outcome: "ERROR" — the exception is the script's own, no result or transcript comes back, and what the tool did is not undone.

    onTurn?: (response: AiCallResult) => AiTurnDecision

    Continuation callback for script-driven multi-turn conversations. After each 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.

    parallelToolCalls?: boolean

    Whether one answer may request several tool calls at once. The providers default to yes; false limits the model to one call per iteration. Anthropic and OpenAI; a call naming it on a provider that does not take it is refused before anything is sent.

    provider?: string

    AI provider name (e.g. "anthropic"). Falls back to the configured tenant default when omitted.

    repos?: (GitRepo | GitMountSpec)[]

    Git repositories the model may read, as mount specs or as repos already opened with B.git.repo. Each mount is pinned to one commit when the call begins, and the model is given an alias and nothing else — never a url, a host, an organization, a repository name, or a credential. A repo with no history (one constructed from live content) is simply not offered the history tools rather than being offered tools that always fail.

    responseSchema?: JSONSchema

    A JSON schema the final answer must conform to. The model's text is then that document, and result.parsed is it parsed. Every object in the schema must set additionalProperties: false; recursive schemas and numeric or length constraints are not accepted by the providers. Anthropic output_config.format, OpenAI response_format; a call naming it on a provider that does not take it is refused before anything is sent.

    stopSequences?: string[]

    Strings the model stops generating at. The text returned excludes the sequence; Anthropic reports the stop as stopReason: "stop_sequence", which outcome reads as END_TURN.

    systemPrompt?: string

    System prompt. When provided, replaces the configured tenant default; per-call agent directives are still appended.

    thinking?: "adaptive" | "disabled"

    Whether the model thinks before it answers: adaptive (it decides how much) or disabled. Anthropic only; a model that always thinks refuses disabled with a 400, which reaches the script as an AiCallException. There is no fixed thinking budget: the current models reject one.

    toolChoice?: "auto" | "none" | "any" | { tool: string }

    Whether the model must call a tool on each iteration: "auto" (it decides; the default), "none" (it may not), "any" (it must call at least one), or {tool: "<name>"} (it must call that one). Ignored on an iteration that offers no tools. A named tool must be one this call offers. Claude Fable 5.1 and Claude Mythos 5.1 refuse a forced choice, so on those models any and {tool} are sent as auto with the requirement stated in the system prompt instead; the substitution is logged.

    tools?: { [K in string | number | symbol]: AiToolLiteral<Schemas[K]> }

    Tool definitions exposed to the model. Each tool combines a JSON schema with a JS executor invoked when the model emits a tool_use block. Inline literals get their executor's args type derived from their own input_schema; tools produced by B.ai.tool.custom()/forNewEntry/forExistingEntry pass through as AiTool.

    trace?: boolean

    Whether to record what each model round-trip cost, in result.trace. Off by default, and absent means off — there is no third state. The trace is built from what the provider already reported, so turning it on costs one small record per iteration and no extra request; it is opt-in so that a result is not carrying a list every caller ignores. Read it to find which iteration spent the tokens, whether the prompt cache is being read or rewritten, and whether the provider sent the call as it was written — see AiTraceEntry.

    transcript?: string | AiTranscript

    The conversation to continue: an AiTranscript from a previous call's result.transcript, or the string its toJson() returned. The model sees every message it held, tool calls and results included, followed by message; with no message the list goes unchanged, and a transcript ending on an assistant turn is then a prefill the model continues rather than a question it answers. A string that does not decode, or whose tool results do not pair with tool calls, throws with a message naming the entry. Mutually exclusive with chatHistory.