Skip to content

Start typing to search the documentation.

Agent API

Last updated View as Markdown

The agent API is exported from @bapX/runtime.

import {
  BapxError,
  ResultUnavailableError,
  ToolInputValidationError,
  ToolLegacyDefinitionError,
  ToolOutputSerializationError,
  ToolOutputValidationError,
  bash,
  connectMcpServer,
  defineAgent,
  defineAgentProfile,
  defineTool,
  dispatch,
  type AgentInitializerContext,
  type AgentDispatchRequest,
  type AgentProfile,
  type AgentRuntimeConfig,
  type BashFactory,
  type CallHandle,
  type CompactionConfig,
  type AgentDefinition,
  type DeliveredAttachment,
  type DeliveredMessage,
  type DispatchReceipt,
  type FileStat,
  type BapxFs,
  type BapxHarness,
  type BapxLogger,
  type BapxSession,
  type BapxSessions,
  type McpServerConnection,
  type McpServerOptions,
  type NamedAgentDispatchRequest,
  type PromptImage,
  type PromptModel,
  type PromptOptions,
  type PromptResponse,
  type PromptResultResponse,
  type PromptUsage,
  type SandboxFactory,
  type ShellOptions,
  type ShellResult,
  type Skill,
  type SkillOptions,
  type SkillReference,
  type TaskOptions,
  type ThinkingLevel,
  type ToolContext,
  type ToolDefinition,
  type ToolInput,
  type ToolInputSchema,
  type ToolOutput,
  type ToolOutputSchema,
  type ToolValidationIssue,
} from '@bapX/runtime';

defineAgentProfile(...)

function defineAgentProfile(profile: AgentProfile): AgentProfile;

Validates and returns a reusable agent profile. Use profiles as the baseline for an agent definition or as named subagents available to session.task().

Throws when the profile contains unknown fields, invalid capabilities, duplicate capability names, or circular subagents.

AgentProfile

Field Type Description
name string Profile name. Required when selecting this profile with session.task().
description string Human-readable profile description.
model string Default model specifier.
instructions string Instructions prepended to discovered workspace context.
skills Skill[] Registered skills available to initialized sessions.
tools ToolDefinition[] Custom model-callable tools available to initialized sessions.
actions ActionDefinition[] Reusable Actions exposed to the model as framework-managed tools.
subagents AgentProfile[] Named profiles available for delegated session.task() operations.
thinkingLevel ThinkingLevel Default reasoning effort. Individual operations may override this value.
compaction false | CompactionConfig Automatic conversation-compaction configuration. false disables threshold compaction; overflow recovery and explicit session.compact() calls still compact when needed.
durability DurabilityConfig Durability configuration for durable agent submissions. Controls recovery attempt limits and submission timeouts. Rejected on subagent profiles.

When a profile is selected as a subagent with session.task(), it is self-contained: instructions, tools, skills, and subagents apply only as declared on the profile (omitted means none), while model, thinkingLevel, and compaction inherit from the parent as defaults. See Subagents.

DurabilityConfig

Field Type Default Description
maxAttempts number 10 Maximum total attempts before the submission is terminalized as failed. The initial run counts as the first attempt; each interruption that requires a new attempt consumes another.
timeoutMs number 3600000 Maximum wall-clock milliseconds for a single submission. Submissions exceeding this limit are aborted and settled as failed. Set higher for long-running agents (e.g. 21_600_000 for a 6-hour agent). The timeout is checked cooperatively at turn boundaries, not preemptively during provider calls.

CompactionConfig

Field Type Default Description
reserveTokens number model-aware; capped at 20000 Token headroom reserved before automatic compaction. Smaller model output limits and small context windows reduce this default.
keepRecentTokens number 8000 Recent tokens preserved unsummarized after compaction.
model string session model Model specifier override used for compaction summaries.

Skill

type Skill =
  | SkillReference
  | {
      name: string;
      description: string;
    };

Skill metadata registered with an agent, harness, or profile. Imported SkillReference values bundle application-owned skill content. Inline metadata adds only a named catalog entry; it does not package or inject an instruction body. Initialization rejects a registered skill whose name collides with a workspace-discovered skill. See Skills.

defineTool(...)

function defineTool<
  TInput extends ToolInputSchema | undefined = undefined,
  TOutput extends ToolOutputSchema | undefined = undefined,
>(options: {
  name: string;
  description: string;
  input?: TInput;
  output?: TOutput;
  run: ToolDefinition<TInput, TOutput>['run'];
}): ToolDefinition<TInput, TOutput>;

Validates a custom model-callable tool and returns a frozen definition. Tool names are checked for collisions with other active tools when a session assembles its tool list.

input and output are optional Valibot schemas. input must be a top-level object schema. Model-supplied input is validated and parsed before run receives it; validation failures become tool errors so the model can retry. When present, output validates and parses the returned value. Structured output is snapshotted as JSON-compatible data and JSON-stringified for the model. Without an output schema, returning undefined sends null to the model.

ToolDefinition

Field Type Description
name string Tool name. Must be unique across active built-in and custom tools.
description string Tells the model when and how to use this tool.
input ToolInputSchema Optional top-level Valibot object schema.
output ToolOutputSchema Optional Valibot schema for typed, validated output.
run ({ input, signal }) => value | Promise Receives parsed input when declared and an optional AbortSignal. Returns JSON-compatible structured data.
import { defineTool } from '@bapX/runtime';
import * as v from 'valibot';

const lookupPolicy = defineTool({
  name: 'lookup_policy',
  description: 'Read one approved policy by topic.',
  input: v.object({ topic: v.string() }),
  output: v.object({ title: v.string(), body: v.string() }),
  async run({ input, signal }) {
    return readPolicy(input.topic, { signal });
  },
});

Breaking migration

The old parameters and execute markers now throw when a tool is defined. Rename parameters to input, rename execute(args, signal) to run({ input, signal }), and return structured JSON-compatible data directly instead of calling JSON.stringify(...). Add output when the returned shape should be typed and validated.

connectMcpServer(...)

function connectMcpServer(name: string, options: McpServerOptions): Promise<McpServerConnection>;

Connects to a remote MCP server and returns its listed tools as Bapx tool definitions ready to pass directly in tools arrays.

Adapted tool names use mcp__<server>__<tool>. Unsupported characters are replaced with underscores, and duplicate adapted names are rejected. Do not wrap these tools with defineTool(). Close the returned connection when its tools are no longer needed.

McpServerOptions

Field Type Default Description
url string | URL MCP server endpoint.
transport 'streamable-http' | 'sse' 'streamable-http' Remote MCP transport. Use 'sse' for legacy servers.
headers HeadersInit Headers merged into MCP transport requests.
requestInit RequestInit Additional MCP transport request configuration.
fetch typeof fetch Custom fetch implementation used by the MCP transport.
timeoutMs number 60000 Per-request timeout in milliseconds for MCP requests.
resetTimeoutOnProgress boolean false Reset the per-request timeout whenever the server sends a progress notification.

McpServerConnection

interface McpServerConnection {
  name: string;
  tools: ToolDefinition[];
  close(): Promise<void>;
}
Field Description
name Server name supplied to connectMcpServer().
tools MCP tools ready to pass directly in tools arrays.
close() Close the underlying MCP client connection.

defineAgent(...)

function defineAgent<TEnv = Record<string, any>>(
  initialize: (
    context: AgentInitializerContext<TEnv>,
  ) => AgentRuntimeConfig | Promise<AgentRuntimeConfig>,
): AgentDefinition<TEnv>;

Defines an agent initializer. Default-export the returned value from an agents/<name>.ts module to define an addressable agent, or bind it to a Workflow Definition.

The initializer runs whenever a runner initializes a root harness from the agent definition. Do not treat it as a one-time constructor for a persistent agent instance id. Return a runtime config object with model: '<provider>/<model>' or a profile with its own model field.

AgentInitializerContext

Field Type Description
id string Agent instance ID or workflow run ID.
env TEnv Platform environment bindings supplied by the runtime.

AgentRuntimeConfig

Field Type Description
description string Optional organizational metadata describing what this agent does. Overrides the profile description when set. Per-initialization metadata only — for a static description that surfaces in the deployment manifest and listAgents(), use the module-level description export instead.
profile AgentProfile Reusable baseline profile. Agent-definition fields replace or extend profile values.
model string Default model specifier.
instructions string Instructions prepended to discovered workspace context.
skills Skill[] Additional registered skills available to initialized sessions.
tools ToolDefinition[] Additional custom model-callable tools available to initialized sessions.
actions ActionDefinition[] Additional reusable Actions exposed as framework-managed model tools.
subagents AgentProfile[] Additional named profiles available for delegated session.task() operations.
thinkingLevel ThinkingLevel Default reasoning effort. Individual operations may override this value.
compaction false | CompactionConfig Automatic conversation-compaction configuration. false disables threshold compaction; overflow recovery and explicit session.compact() calls still compact when needed.
durability DurabilityConfig Durability configuration for durable agent submissions. Controls recovery attempt limits and submission timeouts.
cwd string Working directory inside the initialized sandbox.
sandbox SandboxFactory Sandbox factory used to construct the initialized environment. Omit for the default in-memory sandbox; use bash(...) to wrap a custom just-bash factory (BashFactory). See Sandboxes.

AgentDefinition

AgentDefinition is the opaque initializer value returned by defineAgent().

dispatch(...)

function dispatch(agent: AgentDefinition, request: AgentDispatchRequest): Promise<DispatchReceipt>;

function dispatch(request: NamedAgentDispatchRequest): Promise<DispatchReceipt>;

interface AgentDispatchRequest {
  id: string;
  message: DeliveredMessage;
}

interface NamedAgentDispatchRequest extends AgentDispatchRequest {
  agent: string;
}

interface DispatchReceipt {
  dispatchId: string;
  acceptedAt: string;
}

Delivers a message for asynchronous processing by a continuing agent instance. The agent-definition overload requires a value default-exported by one discovered agents/<name>.ts module. The named overload selects a discovered agent module by name.

Field Description
agent Discovered agent module name for the named overload.
id Target agent instance id.
message The message delivered to the session. Bapx snapshots it when accepted.
dispatchId Generated delivery identifier returned in the receipt. This is not a workflow runId.
acceptedAt ISO timestamp assigned when dispatch admission begins.

await dispatch(...) resolves when the current runtime accepts and queues the message. It does not wait for model processing, tool calls, or an agent reply. Dispatched activity belongs to the continuing agent instance: it does not create workflow-run history and does not appear in SDK client.runs or raw /runs APIs.

DeliveredMessage

type DeliveredMessage =
  | { kind: 'user'; body: string; attachments?: DeliveredAttachment[] }
  | {
      kind: 'signal';
      type: string;
      body: string;
      attributes?: Record<string, string>;
      tagName?: string;
    };

The single unified message shape delivered into an agent’s session, whether it arrives through dispatch(...) or a direct HTTP prompt.

kind: 'user' is a real, user-attributed chat turn. It produces a canonical user_message record and projects into the model conversation like any other user message. Use it when one person is talking directly to the assistant — a direct 1:1 chat surface such as an SDK-driven chat UI — optionally carrying image attachments.

kind: 'signal' is a structured, non-conversational event — a webhook payload, a scheduled trigger, an internal system notification. It produces a canonical signal record and renders into the model conversation as an XML-tagged block rather than a chat turn. This is the right shape for more advanced scenarios, including most channels: a Slack thread or GitHub issue is a multi-user conversation the agent participates in as one member, and signals model each participant’s activity — with sender identity in attributes — where a user message would confuse other participants with the assistant’s own user.

Field Applies to Description
body both The message content. Always a string today; JSON-stringify structured payloads yourself.
attachments user Images attached to the message. See DeliveredAttachment.
type signal Caller-defined event/signal type, e.g. 'slack.message'.
attributes signal Flat, scalar-valued metadata for correlation — analogous to HTTP headers. Rendered alongside the body.
tagName signal Overrides the XML tag name used when rendering the signal into the model prompt. Defaults to signal.

DeliveredAttachment

type DeliveredAttachment = {
  type: 'image';
  data: string;
  mimeType: string;
  filename?: string;
};

One image attachment on a kind: 'user' DeliveredMessage. Today the only supported attachment is an image; the selected model must support image input.

Delivery durability depends on the generated target. Node uses a process-lifetime in-memory queue by default; with a durable db.ts adapter, dispatches survive restarts and are reconciled on the replacement process. Cloudflare durably admits delivery to the target agent Durable Object, orders it with direct prompts, and reconciles interruptions conservatively. Both targets retry only when replay safety is provable; external effects still require application-level idempotency. See Durable Agents for recovery details, and Deploy Agents on Node.js and Deploy Agents on Cloudflare for target-specific setup.

Agent

An agent definition is the opaque value returned by defineAgent(). Default-export it from agents/<name>.ts to make persistent instances addressable, or bind it to a workflow as execution policy. Workflow runners initialize their harness automatically.

Harness

A harness is an initialized agent environment supplied by the active runner. Actions receive it as context.harness; application code does not name or initialize workflow harnesses.

BapxHarness

Initialized agent environment for sessions and workspace operations.

interface BapxHarness {
  readonly name: string;
  session(name?: string): Promise<BapxSession>;
  readonly sessions: BapxSessions;
  shell(command: string, options?: ShellOptions): CallHandle<ShellResult>;
  readonly fs: BapxFs;
}

harness.session(...)

session(name?: string): Promise<BapxSession>;

Gets or creates a session in this harness. Defaults to the 'default' session. Names beginning with task: are reserved for framework-owned detached task sessions.

harness.sessions.get(...)

get(name?: string): Promise<BapxSession>;

Loads an existing session. Defaults to 'default'. Rejects with SessionNotFoundError if it does not exist.

harness.sessions.create(...)

create(name?: string): Promise<BapxSession>;

Creates a new session. Defaults to 'default'. Rejects with SessionAlreadyExistsError if it already exists.

harness.shell(...)

shell(command: string, options?: ShellOptions): CallHandle<ShellResult>;

Runs a shell command in the harness sandbox without recording it in a conversation.

harness.fs

  • Type: BapxFs

Reads and writes files in the harness sandbox without recording them in a conversation.

Session

A session is named conversation state inside a harness. A session runs one active prompt, skill, task, shell, or compact operation at a time. Use separate named sessions for parallel conversation branches.

BapxSession

Named conversation state inside a harness.

interface BapxSession {
  readonly name: string;
  prompt(text: string, options?: PromptOptions): CallHandle<PromptResponse>;
  skill(skill: SkillReference | string, options?: SkillOptions): CallHandle<PromptResponse>;
  task(text: string, options?: TaskOptions): CallHandle<PromptResponse>;
  shell(command: string, options?: ShellOptions): CallHandle<ShellResult>;
  readonly fs: BapxFs;
  compact(): Promise<void>;
}

The prompt(), skill(), and task() signatures above omit structured-result overloads. Pass a Valibot schema as options.result to resolve with validated response.data.

session.prompt(...)

prompt(text: string, options?: PromptOptions): CallHandle<PromptResponse>;

Runs a model operation with a text instruction.

PromptOptions

Field Type Description
result Valibot schema Require validated structured data and resolve with response.data.
tools ToolDefinition[] Additional custom model-callable tools for this operation.
model string Model specifier override for this operation.
thinkingLevel ThinkingLevel Reasoning-effort override for this operation.
signal AbortSignal Cancel this operation.
images PromptImage[] Images attached to the user message. Requires a vision-capable model.

PromptImage

type PromptImage = {
  type: 'image';
  data: string;
  mimeType: string;
};

The selected model must support image input.

PromptResponse

interface PromptResponse {
  text: string;
  usage: PromptUsage;
  model: PromptModel;
}

PromptUsage

Aggregated token and cost usage for model work performed by one operation. Tool use, result retries, and automatic compaction may cause one operation to include multiple model turns.

PromptModel

interface PromptModel {
  provider: string;
  id: string;
}

Model selected for the operation’s primary turn.

PromptResultResponse

interface PromptResultResponse<T> {
  data: T;
  usage: PromptUsage;
  model: PromptModel;
}

A structured-result operation throws ResultUnavailableError when the agent cannot produce validated data.

session.skill(...)

skill(skill: SkillReference | string, options?: SkillOptions): CallHandle<PromptResponse>;

Runs a registered skill. Pass options.result to require validated structured data instead of freeform text.

SkillReference

interface SkillReference {
  readonly __bapXSkillReference: true;
  readonly id: string;
  readonly name: string;
  readonly description: string;
}

Opaque imported packaged-skill reference accepted by session.skill(). Import a SKILL.md value rather than constructing one manually.

SkillOptions

Field Type Description
args Record<string, unknown> Arguments included with the skill instruction.
result Valibot schema Require validated structured data and resolve with response.data.
tools ToolDefinition[] Additional custom model-callable tools for this operation.
model string Model specifier override for this operation.
thinkingLevel ThinkingLevel Reasoning-effort override for this operation.
signal AbortSignal Cancel this operation.
images PromptImage[] Images attached to the skill’s user message. Requires a vision-capable model.

session.task(...)

task(text: string, options?: TaskOptions): CallHandle<PromptResponse>;

Delegates work to a detached child session. Pass options.agent to select a named subagent profile and options.result to require validated data.

TaskOptions

Field Type Description
agent string Named subagent profile selected for this delegated task.
result Valibot schema Require validated structured data and resolve with response.data.
tools ToolDefinition[] Additional custom model-callable tools for this operation.
model string Model specifier override for this operation.
thinkingLevel ThinkingLevel Reasoning-effort override for this operation.
cwd string Working directory for the detached task session. Defaults to the parent session cwd.
signal AbortSignal Cancel this task.
images PromptImage[] Images attached to the task’s initial user message. Requires a vision-capable model.

session.shell(...)

shell(command: string, options?: ShellOptions): CallHandle<ShellResult>;

Runs a shell command and records its command exchange in conversation state.

ShellOptions

Field Type Description
env Record<string, string> Environment variables supplied to the command.
cwd string Working directory supplied to the command.
timeoutMs number Wall-clock deadline in milliseconds, forwarded to the sandbox adapter’s native timeout.
signal AbortSignal Cancel this operation.

ShellResult

interface ShellResult {
  stdout: string;
  stderr: string;
  exitCode: number;
}

session.fs

  • Type: BapxFs

Reads and writes files in the session sandbox without recording them in the conversation transcript.

session.compact()

compact(): Promise<void>;

Triggers conversation compaction immediately. Resolves without work when there is nothing to compact. Rejects when summarization fails or is aborted. Rejects with SessionBusyError if another operation is active on the session.

CallHandle<T>

interface CallHandle<T> extends Promise<T> {
  readonly signal: AbortSignal;
  abort(reason?: unknown): void;
}

prompt(), skill(), task(), and shell() return awaitable call handles. Retain the handle when application code needs to cancel in-flight work. Aborting rejects the awaited operation with an AbortError (DOMException). Pass options.signal to merge an external abort signal with the handle’s signal.

Other session failures reject with typed BapxError subclasses such as SessionBusyError, SkillNotRegisteredError, and SubagentNotDeclaredError, all importable from @bapX/runtime. See the Errors Reference for the full vocabulary.

BapxFs

interface BapxFs {
  readFile(path: string): Promise<string>;
  readFileBuffer(path: string): Promise<Uint8Array>;
  writeFile(path: string, content: string | Uint8Array): Promise<void>;
  stat(path: string): Promise<FileStat>;
  readdir(path: string): Promise<string[]>;
  exists(path: string): Promise<boolean>;
  mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;
  rm(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>;
}

Paths may be absolute or relative. Relative paths use the configured cwd, or the sandbox adapter’s default when cwd is omitted; use absolute paths for portability across sandbox adapters. These operations are out-of-band and do not appear in conversation history.

writeFile() creates missing parent directories automatically, in every sandbox mode — no prior mkdir() is needed before writing to a nested path.

FileStat

interface FileStat {
  isFile: boolean;
  isDirectory: boolean;
  isSymbolicLink?: boolean;
  size?: number;
  mtime?: Date;
}

isSymbolicLink, size, and mtime are omitted when the sandbox adapter’s provider does not expose them.