@b4run/sdk

Use this whenCopy link to section: Use this when

Start here when you build a B4.run application. @b4run/sdk owns the route-authoring types and helpers most application code uses. Use /pure only when an integration needs dependency-free path or hash utilities, and /testing when you write route scenarios for b4 test.

Install and importCopy link to section: Install and import

bash
npm install @b4run/sdk
ts
import { agent, defineMiddleware, defineMemory } from "@b4run/sdk"
import { pureJoin } from "@b4run/sdk/pure"
import { scenarios } from "@b4run/sdk/testing"

Compatibility and audienceCopy link to section: Compatibility and audience

SurfaceRuntimePurityAudienceStability
@b4run/sdkedge-safenot-claimedapplicationsupported
@b4run/sdk/pureedge-safedependency-freeintegrationsupported
@b4run/sdk/testingnode-onlynot-claimedtestingsupported
@b4run/sdk/tool-step.schema.jsonpackage metadatan/aintegrationsupported
@b4run/sdk/answer.schema.jsonpackage metadatan/aintegrationsupported

@b4run/sdk/testing is the route-scoped scenario API used by b4 test. It's not the @b4run/testing package, which provides a programmatic agent harness.

Public exportsCopy link to section: Public exports

@b4run/sdkCopy link to section: @b4run/sdk

ExportResponsibility
AgentConfigConfigure an agent route.
ConstraintContextDescribe the live context passed to a tool constraint.
ConstraintPredicateValidate one tool call before execution.
ConstraintVerdictExpress a constraint decision.
B4AgentRepresent an authored agent route.
DelegationConfigConfigure subagent delegation policy.
DelegationConstraintPredicateValidate a delegated request.
DelegationContextDescribe a delegated request's live context.
DelegationRequestDescribe a delegated input.
DelegationRuleExpress one named delegation policy.
DelegationRulesMap subagent names to delegation policy.
DelegationVerdictExpress a delegation constraint decision.
ReasoningConfigConfigure model reasoning per provider.
OpenAIReasoningConfigConfigure OpenAI reasoning effort and streamed summary.
AnthropicReasoningConfigConfigure Anthropic extended thinking.
RetryConfigConfigure model-call retry attempts and delay.
SubagentMapMap local subagent names to agents.
ToolScopeSelect and gate route tools.
ApproveEntryName one tools.approve tool, or { tool, allowAlways: false } to approve every call.
NormalizedApproveEntryDescribe a tools.approve entry as { tool, allowAlways }.
normalizeApproveEntriesNormalize tools.approve entries to { tool, allowAlways }.
agentDeclare an agent route.
isB4AgentTest whether a value is an authored B4.run agent.
BackendAdapterDefine a route backend adapter contract.
B4ErrorCodeName a registered B4.run error.
B4ErrorDescriptorDescribe a registered B4.run error.
B4_ERRORSRead the error descriptor registry.
describeErrorLook up an error descriptor.
errorDocsUrlBuild the documentation URL for an error code.
AnthropicModelIdName a curated Anthropic model.
GoogleModelIdName a curated Google model.
KnownModelIdOffer curated model autocomplete while accepting custom string IDs.
OpenAiModelIdName a curated OpenAI model.
XaiModelIdName a curated xAI model.
ANTHROPIC_MODEL_IDSList curated Anthropic model IDs.
CURATED_MODEL_IDSMap curated providers to model IDs.
GOOGLE_MODEL_IDSList curated Google model IDs.
OPENAI_MODEL_IDSList curated OpenAI model IDs.
XAI_MODEL_IDSList curated xAI model IDs.
DefinedMemoryRepresent a typed memory declaration.
MemoryScopeDimensionDefine one typed memory namespace dimension.
defineMemoryDeclare a typed long-term memory schema.
ContinueResultContinue middleware execution with optional context.
B4MiddlewareDefine the middleware export contract: a handler or a lifecycle definition.
MiddlewareDefinitionDefine middleware with setup, dispose, handle, and after.
MiddlewareAfterHookValidate or replace the final assistant message of an AG-UI run.
MiddlewareAfterRunDescribe what after receives: the final message and the allowed context.
MiddlewareAfterResultExpress an after decision: keep, replace, or reject.
MiddlewareAfterMessageDescribe one message of the conversation an after run was started with.
ReplaceFinalMessageResultReplace the final assistant message from after.
MiddlewareHandlerDefine the per-request middleware function.
MiddlewareRequestDescribe a middleware request.
MiddlewareSetupContextDescribe what setup receives.
MiddlewareResultExpress a middleware decision.
RejectResultStop middleware execution with a response.
allowContinue middleware execution.
defineMiddlewarePreserve types for a middleware function or lifecycle definition.
rejectStop middleware execution.
AuthDefinitionDeclare the app's authentication: authenticate, plus optional setup, dispose and canReviewMemory.
AuthRequestDescribe the request authenticate resolves: headers, method and url.
AuthResultExpress what authenticate returns: a principal, undefined for anonymous, or a rejection.
AuthSetupContextDescribe what an auth setup hook receives.
B4PrincipalName the app's principal type, as b4 typegen declares it from src/auth.ts.
B4PrincipalShapeDescribe the smallest principal: an object with a string id.
B4RegisterDeclare app types the SDK reads; b4 typegen adds principal.
defineAuthDeclare and brand the app's authentication for src/auth.ts.
isAuthDefinitionTell a defineAuth value from any other object.
B4ThreadAccessDefine one thread-access action handler.
ThreadAccessAllowExpress an allow decision, optionally stamping a thread on create.
ThreadAccessDenyExpress a deny decision with an optional status and body.
ThreadAccessPolicyDeclare per-action thread authorization handlers.
ThreadAccessRequestDescribe the thread request being authorized.
ThreadAccessRequestedWorkspaceDescribe the workspace an upload stages or a create chooses: the source digest, and on a create its links, baseline and uploadedBy, the stamps its uploads were allowed with.
ThreadAccessResultExpress a thread authorization decision.
ThreadActionName the coarse thread action being authorized.
ThreadOperationName the specific endpoint operation being authorized.
ThreadSubjectDescribe the thread a decision is made about.
THREAD_ACCESS_METADATA_KEYName the reserved metadata key holding the server-issued access stamp.
defineThreadAccessPreserve types for a thread access policy.
ownedThreadsBuild the common thread policy as a value: each caller reaches only the threads it created, and adminsRead principals may also read the rest.
OwnedThreadsOptionsConfigure ownedThreads: owner (the id a thread is stamped with; default principal.id) and adminsRead.
ownedThreadsOptionsRead back the options an ownedThreads policy was built from, or undefined for any other policy.
denyRefuse a thread request.
permitAllow a thread request, optionally stamping it on create.
ApprovalGrantModeName the approval-grant strictness: off, optional, or required.
ApprovalGrantMinterMint one single-use approval grant for one parked interrupt.
InterruptGrantRecordDescribe a stored grant row, which holds the hash and never the grant.
InterruptGrantStoreDefine the durable record of which parked approvals have been answered.
InterruptGrantConsumptionExpress the outcome of a conditional consume.
APPROVAL_GRANT_MODESList every approval-grant mode.
APPROVAL_GRANT_MINTER_KEYName the run-config key the per-run minter travels under.
APPROVAL_GRANT_PREFIXExpose the b4ag_ prefix that makes a grant recognizable.
APPROVAL_GRANT_BYTESExpose the randomness, in bytes, behind one grant.
isApprovalGrantModeValidate an approval-grant mode.
isApprovalGrantShapeCheck a grant arriving on the wire before it is hashed.
createApprovalGrantMint one grant and return its plaintext and hash.
hashApprovalGrantHash a grant for storage and comparison.
timingSafeHexEqualCompare two hex digests in constant time.
createMemoryInterruptGrantStoreCreate the in-process grant store used by tests and storeless runtimes.
ClientToolCallRecordDescribe one row of the tool-call record: a client-provided call the server issued and is waiting on, or a server tool call recorded for identity — with the route that issued it and, inside a subagent, the launching task call.
ToolCallOriginSay where a server tool call was issued from when inside a subagent: the child route's key and the launching task call id.
ClientToolCallStoreDefine the durable record of tool calls on AG-UI runs: which client calls are outstanding, answered, or voided, and which server calls were issued and settled.
ToolCallRecordKindTell a client tool call row from a server tool call row.
ClientToolCallSettleExpress the outcome of settling a server tool call row.
ClientToolCallAnswerExpress the outcome of answering a client tool call.
ClientToolRecorderRecord a tool call before it runs or its turn parks, and settle a server call afterward.
CLIENT_TOOL_RECORDER_KEYName the run-config key the per-run client tool recorder travels under.
createMemoryClientToolCallStoreCreate the in-process client tool call store used by tests and embedders.
encodeClientToolResultEncode a client tool result for a store's text column: text as itself, a part list as a self-describing JSON envelope.
decodeClientToolResultDecode a stored client tool result: an envelope back to its parts, anything else as the text it is.
B4ContentPartDescribe one AG-UI 1.0 content part: a B4TextPart or a B4MediaPart.
B4TextPartDescribe a text content part.
B4MediaPartDescribe an image, audio, video or document part and its source.
B4MediaPartTypeName the four media part types.
B4PartSourceDescribe where a media part's bytes come from: inline data, a URL, or a provider file handle.
B4DataSourceDescribe inline base64 bytes with their mimeType.
B4UrlSourceDescribe a URL the provider fetches; B4.run never fetches it.
B4FileSourceDescribe a file handle issued by a model provider, optionally naming that provider.
B4MessageContentDescribe what a user or tool message carries: a string or an ordered list of content parts.
isContentPartCheck that an unvalidated value is a structurally valid content part.
isContentPartArrayCheck that an unvalidated value is an array of valid content parts.
contentPartsTextRead a message's text: a string as is, or a part list's text parts in order.
BuiltInModelProviderIdName a built-in model provider.
ModelProviderIdName a built-in or custom model provider.
inferProviderInfer a provider from a model ID.
SUPPORTED_AGENT_PROVIDERSList providers built into agent materialization.
RouteConfigDescribe route metadata.
RouteKindName a supported route kind.
RouteStateMapExpose an open compatibility interface for route state.
RouteToolMapExpose an open compatibility interface for route tools.
RuntimeContextProvide request-scoped runtime data.
RuntimeToolDescribe a runtime tool callable.
ToolRegistryMap runtime tool names to callables.
PrettifyFlatten an object type for editor display.
ModelIdValidationRepresent advisory model-ID validation.
validateModelIdCheck a model ID against curated suggestions.
B4ToolContextProvide context to a B4.run tool.
WorkspaceFsDefine the workspace filesystem contract exposed to tools.
WorkspaceContextSupply trusted managed workspace identity, provenance, and permission-bound initial reads.
ToolDisplayDescribe how a tool call reads to a person (icon, running/done/failed labels, sources).
ToolDisplayIconName one of the fixed step icons.
ToolDisplaySourceDescribe a file, URL or record a call drew on.
TOOL_DISPLAY_ICONSList the fixed step icon names.
TOOL_DISPLAY_LABEL_MAXCap a step label's length.
describeToolDisplayProblemName what is wrong with a display export, or nothing.
isToolDisplayIconNarrow a string to a step icon name.
ToolDenialDescribe a denied tool call's result: the reason the model receives, branded.
TOOL_DENIALName the symbol key that brands a denied tool call's result.
toolDenialBrand a denial reason as a tool result; the model still reads the reason as plain text.
isToolDenialTell a denied tool call's result from a successful one.
B4ToolStepThe versioned b4.step contract for one tool call: v: 1, kind, status, label, icon, queries, sources, start and settle times, error and gate decision.
B4ToolStepStatusName a step status: running, completed, failed, denied or cancelled.
B4ToolStepReadA step read from the wire, whose status is absent when the producer sent one this reader does not know.
B4ToolStepUpdateA partial step for mergeToolStep; status and kind may be absent.
B4StepSourceA file, URL, document or record a step or answer drew on, with a stable id.
B4AnswerAnnotationsThe b4.answer annotations on a final answer: citations, uncited sources, attribution.
B4_STEP_METADATA_KEYThe message-metadata key a tool call's step travels under (b4.step).
B4_ANSWER_METADATA_KEYThe message-metadata key a final answer's annotations travel under (b4.answer).
B4_STEP_EVENT_NAMEThe AG-UI CUSTOM event name a live step travels as (b4.step).
B4_STEP_VERSIONThe contract's major version (1). Additive changes never bump it.
B4_TOOL_STEP_STATUSESList every step status.
B4_BUILTIN_TOOLSList the recommended builtin values for provider tools; the field stays an open string.
B4_TOOL_STEP_JSON_SCHEMAThe JSON Schema for a b4.step value.
B4_ANSWER_JSON_SCHEMAThe JSON Schema for b4.answer annotations.
readToolStepNormalize a b4.step value (legacy shapes included) to a step; an unknown status is dropped, and an unusable value returns undefined.
readToolStepUpdateLike readToolStep, but kind stays absent when the source did not state it, so a merge keeps the stored kind.
readAnswerAnnotationsNormalize b4.answer annotations.
mergeToolStepMerge a step from a call or a message into the stored step by the contract's rules.
settleOpenStepsSettle running steps at a run's end: failed after an error, cancelled after a cancel or interrupt, sparing the interrupt's open calls.
B4_STEP_KEYThe additional_kwargs key under which every ToolMessage persists its v1 B4ToolStep (b4_step); read old and new values with readToolStep.
B4_SUBAGENT_KEYThe additional_kwargs key under which a task ToolMessage persists the subagent it launched (b4_subagent).
B4_TURN_METADATA_KEYThe checkpoint-metadata key under which the runtime stamps how a turn ended (b4:turn).
GateDecisionHow a permission gate was answered: once, always or deny.
PersistedStepDeprecated: use B4ToolStep. The step a ToolMessage persists: status (completed, failed or denied), icon, label, sources, start and settle times, and the gate decision.
PersistedSubagentThe subagent a task call launched: name, route, description, depth, child checkpoint namespace, outcome and error.
PersistedTurnEndHow and when a turn ended, stamped on the head checkpoint's metadata.
readPersistedStepDeprecated: use readToolStep. Validate a b4_step value; invalid optional fields are dropped, a missing identity returns undefined.
readPersistedSubagentValidate a b4_subagent value.
readPersistedTurnEndValidate a b4:turn value.

@b4run/sdk/pureCopy link to section: @b4run/sdk/pure

ExportResponsibility
POSIX_SEPExpose the portable path separator.
pureBasenameRead the last path component.
pureDirnameRead the parent path.
pureJoinJoin path segments without Node dependencies.
pureRelativeCompute one portable relative path.
pureResolveResolve portable path segments.
sha1HexCompute a SHA-1 hexadecimal digest.
sha256HexCompute a SHA-256 hexadecimal digest.

@b4run/sdk/testingCopy link to section: @b4run/sdk/testing

ExportResponsibility
TOOL_STEP_FIXTURESList the b4.step fixture corpus: named event sequences with the steps and answers they must fold to.
ToolStepFixtureDescribe one fixture: its name, events and expected result.
ToolStepFixtureEventDescribe one AG-UI event in a fixture.
ToolStepFoldedDescribe the steps and answers a fold produces.
foldToolStepEventsFold fixture events into steps and answers; a reference implementation for a client's own reducer.
RouteScenarioMapReceive generated route-to-tool augmentation.
RuntimeErrorExpectationDescribe an expected scenario error.
RuntimeExecutionBaseResultShare fields across scenario execution results.
RuntimeExecutionErrorDescribe a failed execution error.
RuntimeExecutionErrorKindName a runtime failure kind.
RuntimeExecutionFailureResultRepresent a failed execution.
RuntimeExecutionModeName the materialized route mode.
RuntimeExecutionResultRepresent either execution outcome.
RuntimeExecutionSuccessResultRepresent a successful execution.
RuntimeExecutionTimingDescribe execution timing.
RuntimeMetaExpectationDescribe expected runtime metadata.
ScenarioDescriptorRepresent one authored scenario.
ScenarioSuiteBuilderBuild route-scoped scenarios fluently.
ScenarioSuiteDescriptorRepresent a completed scenario suite.
ScenarioToolCallExpectationDescriptorDescribe an expected tool call.
ScenarioToolCallRecordRecord an observed tool call.
ScenarioToolMockDescriptorDescribe a mocked tool response.
expectErrorAssert a failed runtime result.
expectMetaAssert selected runtime metadata.
expectOutputAssert a successful runtime output.
isScenarioSuiteTest whether a value is a scenario suite.
readScenarioSuiteRead a scenario suite descriptor.
scenariosStart a typed scenario suite for a route.

@b4run/sdk/tool-step.schema.jsonCopy link to section: @b4run/sdk/tool-step.schema.json

The JSON Schema of a b4.step value, as data for tooling and for producers in other languages. It is the same schema as B4_TOOL_STEP_JSON_SCHEMA. It has no TypeScript exports, runtime classification, or purity claim. Don't execute it as application code.

@b4run/sdk/answer.schema.jsonCopy link to section: @b4run/sdk/answer.schema.json

The JSON Schema of b4.answer annotations, as data for tooling and for producers in other languages. It is the same schema as B4_ANSWER_JSON_SCHEMA. It has no TypeScript exports, runtime classification, or purity claim. Don't execute it as application code.

Key contractsCopy link to section: Key contracts

agent() and AgentConfigCopy link to section: agent() and AgentConfig

Use agent() as a route module's default export. model and systemPrompt are required. Optional policy, retry, reasoning, subagent, and tool fields are preserved on the branded descriptor.

ts
export declare function agent<const Subagents extends SubagentMap = {}>(
  config: AgentConfig<Subagents>,
): B4Agent<Subagents>
ts
export interface AgentConfig<Subagents extends SubagentMap = {}> {
  readonly delegation?: DelegationConfig<NoInfer<Extract<keyof Subagents, string>>>
  readonly description?: string
  readonly model: KnownModelId
  readonly provider?: ModelProviderId
  readonly reasoning?: ReasoningConfig
  readonly retry?: RetryConfig
  readonly recursionLimit?: number
  readonly subagents?: Subagents
  readonly tools?: ToolScope
  readonly systemPrompt: string
}

Fields: @b4run/sdk#.:AgentConfig

FieldTypeRequiredDescription
readonly delegationDelegationConfig<NoInfer<Extract<keyof Subagents, string>>>noControl dispatch to named subagents.
readonly descriptionstringnoDescribe the agent for selection.
readonly modelKnownModelIdyesSelect the model.
readonly providerModelProviderIdnoOverride provider inference.
readonly reasoningReasoningConfignoTune reasoning per provider.
readonly retryRetryConfignoTune transient retry behavior.
readonly recursionLimitnumbernoCap LangGraph super-steps.
readonly subagentsSubagentsnoRegister child agents by name.
readonly toolsToolScopenoScope and gate tools.
readonly systemPromptstringyesSet the agent's system instruction.

Behavior contract sdk.agent.descriptor-shape

agent() returns a branded descriptor and includes optional tool scope only when supplied.

Agent configuration signatures

ts
export interface ReasoningConfig {
  readonly openai?: OpenAIReasoningConfig
  readonly anthropic?: AnthropicReasoningConfig
}

Fields: @b4run/sdk#.:ReasoningConfig

FieldTypeRequiredDescription
readonly openaiOpenAIReasoningConfignoApply when the route resolves to OpenAI.
readonly anthropicAnthropicReasoningConfignoApply when the route resolves to Anthropic.
ts
export interface OpenAIReasoningConfig {
  readonly effort?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh"
  readonly summary?: "auto" | "concise" | "detailed"
}

Fields: @b4run/sdk#.:OpenAIReasoningConfig

FieldTypeRequiredDescription
readonly effort"none" | "minimal" | "low" | "medium" | "high" | "xhigh"noSet the request's reasoning effort.
readonly summary"auto" | "concise" | "detailed"noStream a reasoning summary on the Responses API.
ts
export interface AnthropicReasoningConfig {
  readonly budgetTokens: number
}

Fields: @b4run/sdk#.:AnthropicReasoningConfig

FieldTypeRequiredDescription
readonly budgetTokensnumberyesEnable extended thinking with this token budget (at least 1024).
ts
export interface RetryConfig {
  readonly maxAttempts?: number
  readonly baseDelay?: number
}

Fields: @b4run/sdk#.:RetryConfig

FieldTypeRequiredDescription
readonly maxAttemptsnumbernoSet attempts per model call; defaults to 3.
readonly baseDelaynumbernoSet the first capacity rate-limit backoff; defaults to 1000.
ts
export declare function isB4Agent(value: unknown): value is B4Agent

allow() and reject()Copy link to section: allow() and reject()

Middleware returns an explicit continue or reject result. Use allow(context?) to continue and reject(status, body?) to stop the request.

defineMiddleware accepts either the handler function or a lifecycle definition with optional setup(ctx) and dispose() hooks around handle. setup runs once, lazily, before the first gated request and is retried on the next request if it rejects. dispose runs from the Node runtimes' shutdown path. See Lifecycle hooks. The definition may also carry after(run), which receives an AG-UI run's final assistant message with the allowed context and may keep, replace, or reject(...) it before the client sees it. See Validating the final assistant message.

ts
export declare function defineMiddleware<T extends B4Middleware>(middleware: T): T
ts
export declare function allow(context?: Record<string, unknown>): ContinueResult
ts
export declare function reject(status: number, body?: unknown): RejectResult

Behavior contract sdk.middleware.result-shapes

allow() and reject() return discriminated result objects; omitted context and body properties are absent.

defineAuth()Copy link to section: defineAuth()

src/auth.ts must default-export the result. authenticate runs once per request, before middleware and the thread-access policy, and its principal reaches middleware and the policy as req.principal and every tool as ctx.principal. See Authentication.

ts
export declare function defineAuth<P extends B4PrincipalShape>(definition: AuthDefinition<P>): AuthDefinition<P>
export declare function isAuthDefinition(value: unknown): value is AuthDefinition

validateModelId()Copy link to section: validateModelId()

Flags likely model-ID typos. It does not restrict custom model IDs.

ts
export declare function validateModelId(opts: {
  readonly model: string
  readonly provider?: string
}): ModelIdValidation

Behavior contract sdk.validate-model-id.advisory

Model validation is advisory: curated near-misses return provider-specific suggestions, while an uncurated or unresolved provider returns ok: true.

Application guidance

Treat ok: false as a warning for application feedback, not a runtime gate.

RouteConfigCopy link to section: RouteConfig

runtime, streaming, and tags are reserved metadata and don't change execution. Select deployment runtime with build.targets, select streaming through the endpoint or transport, and do not rely on tags for behavior.

ts
export interface RouteConfig {
  readonly runtime?: "node" | "edge"
  readonly streaming?: boolean
  readonly tags?: readonly string[]
}

Fields: @b4run/sdk#.:RouteConfig

FieldTypeRequiredDescription
readonly runtime"node" | "edge"noReserved; has no effect.
readonly streamingbooleannoReserved; has no effect.
readonly tagsreadonly string[]noReserved; has no effect.

defineMemory()Copy link to section: defineMemory()

Declare the typed schema, kind, and namespace dimensions for a route's memory.ts module. identity is optional. Semantic memory defaults its reconciliation identity elsewhere.

ts
export declare function defineMemory<S extends z.ZodTypeAny>(def: {
  kind: DefinedMemory["kind"]
  scope: readonly MemoryScopeDimension[]
  schema: S
  identity?: readonly string[]
}): DefinedMemory<S>

Choosing a surfaceCopy link to section: Choosing a surface

Application routes normally import the root. Use /pure for infrastructure that must avoid runtime dependencies. Use /testing in *.scenario.ts files, and @b4run/testing when a test needs a programmatic harness.

Trusted initial sourceCopy link to section: Trusted initial source

An authored tool's optional ctx.workspace is present only for an admitted managed workspace. It exposes id, sourceDigest, the pinned environment, an optional baselineCommit, and readInitialFile(path): Promise<Uint8Array>. Initial reads use the same read permission policy as ordinary file reads and return independently owned bytes. The context has no provider handle or lifecycle methods and cannot select another thread's source.

Use ctx.fs for current files. ctx.fs.stat(path) inspects entry kind, size, executable mode, and a symlink's target without following the leaf link; custom backends must supply lstat to support it.

ts
import { agent } from "@b4run/sdk"
 
export default agent({
  model: "gpt-5-mini",
  systemPrompt: "Answer concisely.",
})

Continue with Agents, Middleware, Long-term Memory, Scenario Testing, and Agent Test Harness.