SDK
Generated TypeScript SDK reference.
SDK
Generated from packages/sdk/src/index.ts with TypeDoc.
Classes
Aex
Unified user-facing client for the aex platform. The same class
powers the published @aexhq/sdk SDK and (under the hood) every host-side
subcommand of the in-container aex CLI. All operations talk to
the dashboard BFF and operate on durable run records.
The SDK never asks the caller for a workspace id — workspace identity
is derived server-side from the API key on every request. Use
client.whoami() if you want to introspect which workspace the
token resolves to.
Members:
constructor(Constructor)agentsMd(Property)files(Property)outputs(Property)secrets(Property)sessions(Property)skills(Property)batch(Method)billing(Method)billingCheckout(Method)billingLedger(Method)billingPortal(Method)deleteWorkspaceAsset(Method)openSession(Method)run(Method)submit(Method)webhookSigningSecret(Method)whoami(Method)
AexApiError
Thrown by SDK and CLI operations when the dashboard BFF returns a non-2xx
response. Carries the HTTP status, the redacted parsed body, the server's
STABLE AexApiErrorCode (when present), and a requestId for support.
Construct via import("./error-factory.js").apiErrorFromResponse — the
single wire→exception mapping — which dispatches to a typed subclass
(AexAuthError / AexIdempotencyConflictError /
AexNotFoundError / AexRateLimitError).
Members:
constructor(Constructor)apiCode(Property)body(Property)requestId(Property)status(Property)
AexAuthError
401/403 auth failure (token invalid/revoked/expired, forbidden, insufficient scope).
Members:
constructor(Constructor)requiredScope(Property)
AexError
Members:
constructor(Constructor)code(Property)details(Property)
AexIdempotencyConflictError
409 — the idempotency key was reused with a different request body.
Members:
constructor(Constructor)
AexNetworkError
Thrown when a BFF-bound request fails BEFORE any HTTP response exists — DNS
failure, connection refused, TLS error, socket reset. Wraps the raw fetch
rejection (whose undici form is a bare TypeError: fetch failed with the
useful code hidden on cause.code) into a message that names the request
and the transport failure, e.g.
POST api.aex.dev/assets/presign failed: ECONNREFUSED (connect ECONNREFUSED 127.0.0.1:443).
The original rejection is preserved on cause.
Members:
constructor(Constructor)attempts(Property)causeCode(Property)elapsedMs(Property)host(Property)method(Property)path(Property)
AexNotFoundError
404 — the requested resource was not found.
Members:
constructor(Constructor)
AexRateLimitError
Structured throttle error. Extends the contracts AexRateLimitErrorBase
(the SINGLE rate-limit class the wire→exception factory also throws, so
isRateLimited recognises BOTH — no split-brain) and enriches it with the
retry-layer detail: attempts, source, and an upstream providerFault.
retryAfterMs is inherited. The message is a fixed, non-leaky summary — it
never echoes the raw error body (which is still available, redacted, on .body).
Members:
constructor(Constructor)attempts(Property)providerFault(Property)source(Property)
AgentsMd
AgentsMd — a single markdown file delivered to the agent as the first user turn of the session (matches Claude Code's CLAUDE.md behaviour).
const rules = await AgentsMd.fromContent("# Be helpful", { name: "rules" }); await client.run({ agentsMd: [rules], message: "..." });
client.run / openSession materializes the bytes to the hosted asset store
before the run lands. Asset deduplication handles repeated uploads automatically.
Members:
constructor(Constructor)isDraft(Accessor)ref(Accessor)toJSON(Method)fromContent(Method)fromPath(Method)
AgentsMdClient
Workspace AgentsMd admin operations exposed under client.agentsMd.
New sessions usually use AgentsMd.fromContent(...) or
AgentsMd.fromPath(...) directly on openSession / run; the SDK
materializes those bytes to the hosted asset store before the session starts. This namespace is
the read/delete surface for persisted AgentsMd records.
Members:
constructor(Constructor)delete(Method)get(Method)list(Method)
ChildRunHandle
A first-class, lineage-discoverable SUBAGENT CHILD run — handed out by
session.children() / run.children(), backed by the RUN facade
(getRun/events/outputs), NOT openSession. Every child the platform hands you
is resolvable through this handle; its lineage (parentRunId/depth) and
terminal outcome (status) are first-class.
Members:
constructor(Constructor)depth(Accessor)id(Accessor)parentRunId(Accessor)ref(Accessor)status(Accessor)cancel(Method)children(Method)events(Method)get(Method)outputs(Method)
CleanupError
Members:
constructor(Constructor)
CredentialValidationError
Members:
constructor(Constructor)
File
File — arbitrary bytes (single file or zipped folder) delivered to
the agent as a mounted runtime resource. The managed runtime UNZIPS the
snapshotted bytes into the mountPath DIRECTORY during workspace
materialization, preserving the real filename + extension.
const settings = await File.fromPath("./settings.json"); const dataset = await File.fromPath("./data/"); await client.run({ files: [settings, dataset], message: "..." });
mountPath is the absolute container directory the file unzips into; it
defaults to /workspace (the agent's default working directory), so a file
handed with no mountPath lands directly in the agent's cwd — a single file
subtitles.srt becomes /workspace/subtitles.srt, a folder lands its entries
under /workspace/. The resolved path is surfaced back on the Run record.
FIDELITY: a directory walk captures executable bits and symlinks into a
.aexmeta.json sidecar (emitted only when such metadata exists, so a
pure-content bundle stays byte-identical → dedup continuity), and honors
.aexignore (gitignore-compatible) plus always-on defaults (.git/,
node_modules/). SCALE: a large input (total raw size over the streaming
threshold, File.fromPath only) is uploaded via a streaming two-pass
multipart flow that holds only one entry + one part in memory, lifting the
old ~2 GiB in-memory ceiling.
client.run / openSession materializes the bytes to the hosted asset store
before the run lands; the wire ref becomes kind:"asset". Repeat uploads of the
same bytes are deduped.
Members:
constructor(Constructor)isDraft(Accessor)ref(Accessor)toJSON(Method)fromBytes(Method)fromPath(Method)
FilesClient
Workspace File admin operations exposed under client.files.
New sessions usually use File.fromPath(...) or
File.fromBytes(...) directly on openSession / run; the SDK materializes
those bytes to the hosted asset store before the session starts. This namespace is the read/delete
surface for persisted file records.
Members:
constructor(Constructor)delete(Method)get(Method)list(Method)
McpServer
Inline MCP server reference OR a workspace-persistent ref via
McpServer.fromId("mcp_...").
For inline refs, headers (typically Authorization) are vaulted
server-side under secrets.mcpServers and excluded from the
idempotency hash; the non-secret {name, url} part is hashed.
The SDK splits the header bag from the public ref BEFORE the wire
payload is built, so a single inline McpServer instance becomes:
- a
submission.mcpServersentry of{ name, url }, and - (when
headersis present) asecrets.mcpServersentry of{ name, headers }.
For workspace refs (McpServer.fromId(id)), the submission entry
is {kind:"workspace", id}; the BFF resolves it to inline when
the session is created. The user still supplies auth separately via
secrets.mcpServers[<workspace-name>] keyed by the workspace
MCP's persisted name.
Members:
constructor(Constructor)headers(Property)id(Property)kind(Property)name(Property)transport(Property)url(Property)toSecretEntry(Method)toSubmissionEntry(Method)fromId(Method)remote(Method)
OutputsClient
Cross-run output search (aex.outputs). Composed client-side (per-run
listSessionOutputs + the contracts output filter): scope a corpus with
query.runIds, or omit it to scan every run in the workspace. Metadata-only
(reference hits, no bytes); a content-shaped query throws a typed
"content search unsupported".
Members:
constructor(Constructor)search(Method)
ProviderError
Members:
constructor(Constructor)status(Property)
RunConfigValidationError
Members:
constructor(Constructor)
RunStateError
Members:
constructor(Constructor)apiCode(Property)requestId(Property)status(Property)
Secret
A secret with the SAME lifecycle semantic as File / AgentsMd:
EPHEMERAL per-run by default, PROMOTABLE to a persisted, name-searchable
workspace secret you can reference and reuse.
Secret.value(v)— EPHEMERAL per-run: the value is vaulted when the session is created and excluded from the idempotency hash; only a{ ephemeral: true }placeholder rides the (hashed) submission. Deleted when the run finishes. Clean, no workspace dependency. ≙File.fromBytes(...)(a draft).secret.upload(client, { name })— PROMOTE that value into the workspace secret store undername; resolves to aSecret.ref.Secret.ref(handle)— WORKSPACE: only the handle rides the submission; the value is resolved server-side from the workspace secret store. No value ever travels.
The SDK splits each Secret BEFORE the wire payload is built (exactly how
McpServer splits headers into secrets.mcpServers): the env-var name keys
submission.secretEnv[name] = toSubmissionEntry(), and for ephemeral values
secrets.envSecrets[name] = toSecretValue().
Members:
constructor(Constructor)handle(Property)kind(Property)isConsumed(Accessor)toJSON(Method)toSecretValue(Method)toString(Method)toSubmissionEntry(Method)upload(Method)ref(Method)value(Method)
SecretsClient
Workspace secret management exposed under client.secrets, mirroring
client.agentsMd / client.files.
Lifecycle parity with assets: a Secret.value(...) is per-run and
gone at terminal; set (or promoting an ephemeral via secret.upload)
persists a named, searchable workspace secret you can get (metadata),
rotate, list, and delete. The identity is the name; the value rotates
under that stable name.
Values are write-only through the public SDK: set/rotate send the value in
the request BODY (never the URL); get/list return metadata only.
Members:
constructor(Constructor)delete(Method)get(Method)list(Method)rotate(Method)set(Method)
SecretString
Members:
constructor(Constructor)toJSON(Method)toString(Method)unwrap(Method)
SessionClient
Public surface of the aex SDK.
Aex is the single SDK client. Composition primitives are Tool, Skill,
McpServer, AgentsMd, File, and Secret. Everything else is types,
errors, and event type guards re-exported from @aexhq/contracts.
Members:
constructor(Constructor)create(Method)delete(Method)get(Method)list(Method)open(Method)outputs(Method)run(Method)
SessionHandle
Public surface of the aex SDK.
Aex is the single SDK client. Composition primitives are Tool, Skill,
McpServer, AgentsMd, File, and Secret. Everything else is types,
errors, and event type guards re-exported from @aexhq/contracts.
Members:
constructor(Constructor)id(Accessor)messages(Accessor)record(Accessor)approve(Method)cancel(Method)children(Method)delete(Method)deny(Method)download(Method)downloadMetadata(Method)events(Method)outputs(Method)refresh(Method)replayLast(Method)requestApproval(Method)resume(Method)send(Method)suspend(Method)unit(Method)wait(Method)webhooks(Method)
SessionTurnStream
Public surface of the aex SDK.
Aex is the single SDK client. Composition primitives are Tool, Skill,
McpServer, AgentsMd, File, and Secret. Everything else is types,
errors, and event type guards re-exported from @aexhq/contracts.
Members:
constructor(Constructor)[asyncIterator](Method)done(Method)
Skill
A Skill is a FIRST-CLASS, workspace-scoped, by-name bundle of instructional /
executable content (SKILL.md at the bundle root plus any supporting files).
It is DISTINCT from a Tool: skills are passed on the session's separate
skills: input, not tools:, and a run gets a single skills meta-tool
(list/load) rather than one load-tool per skill.
Lifecycle mirrors Secret promotion, but keyed to a workspace name:
- The
Skill.from*factories read a bundle, liftname+descriptionfrom theSKILL.mdYAML frontmatter (an explicit{ name }overrides), and canonically zip + hash the bytes → a DRAFT skill. skill.upload(client)UPSERTS the workspace skill by name: it stages the bytes to the content-addressed asset store (presign/finalize) and PUTs the registry entry. Identical bytes are a no-op. Returns an uploadedSkillwhose wire ref is{ kind:"skill", name }(BY NAME — no assetId, no hash).- Passing a DRAFT skill in
skills:auto-upserts it on submit (same ergonomic as a draftTool/File).
Binding is by name and mutable: a re-upload under the same name changes what every future run referencing that name sees.
Members:
description(Accessor)isDraft(Accessor)name(Accessor)ref(Accessor)toJSON(Method)upload(Method)fromBytes(Method)fromContent(Method)fromDir(Method)fromFiles(Method)fromUrl(Method)
SkillBundleValidationError
Members:
constructor(Constructor)
SkillsClient
Workspace skill registry operations exposed under client.skills.
Session creation normally passes Skill.from*(...) instances directly in the
skills option (auto-upserted by name). This namespace is the metadata
read/delete surface for the named workspace skill registry.
Members:
constructor(Constructor)delete(Method)get(Method)list(Method)
Tool
Members:
isDraft(Accessor)ref(Accessor)toJSON(Method)upload(Method)fromAsset(Method)fromFiles(Method)fromPath(Method)
Interfaces
AexEventView
A coordinator AexEvent with the standardized-event-type guards carried
as METHODS (event.isTextMessage(), event.isToolCallStart(), …). Extends
AexEvent by declaration merging, so it exposes every envelope field
unchanged. Construct one with asAexEventView.
Members:
channel(Property)data(Property)emittedAt(Property)id(Property)level(Property)message(Property)receivedAt(Property)sequence(Property)source(Property)sourceSeq(Property)specversion(Property)subject(Property)time(Property)type(Property)isAwaitingApproval(Method)isCustom(Method)isEventChannel(Method)isFromSource(Method)isLog(Method)isResultDecoded(Method)isResultRefused(Method)isRunError(Method)isRunFinished(Method)isRunSettled(Method)isRunStarted(Method)isRunTerminal(Method)isTextMessage(Method)isToolCallResult(Method)isToolCallStart(Method)toolCallId(Method)
AexOptions
Members:
apiKey(Property)baseUrl(Property)debug(Property)fetch(Property)retry(Property)
AgentsMdRecordWire
Wire-level record for a workspace AgentsMd file as returned by the BFF.
Mirrors PublicWorkspaceFile from the dashboard service layer.
Members:
createdAt(Property)fileCount(Property)finalizedAt(Property)hash(Property)id(Property)kind(Property)manifest(Property)name(Property)sizeBytes(Property)state(Property)updatedAt(Property)
ApprovalGate
Declarative HITL write-gate: park awaiting_approval before any listed tool.
Members:
tools(Property)
AssetRef
Storage-neutral uploaded asset reference. Runtime materialization resolves
assetId privately; public callers never name object-store paths.
Members:
assetId(Property)kind(Property)mountPath(Property)name(Property)
BatchItemResult
One item's settled result inside a BatchResult.
Members:
outcome(Property)runId(Property)
BatchOptions
Options for Aex.batch.
Members:
concurrency(Property)rollup(Property)
BatchResult
The result of aex.batch(items, …): every item's settled result PLUS a real
rollup. The rollup is honest because run() awaits settle, so every item's
costUsd/usage is populated — a missing cost is a typed absent, not a
silent $0.
Members:
failed(Property)okCount(Property)results(Property)totalCostUsd(Property)totalUsage(Property)
BillingCheckoutRequest
Members:
cancelUrl(Property)idempotencyKey(Property)planKey(Property)successUrl(Property)
BillingHostedSession
Hosted checkout/portal session. The client should open url.
Members:
url(Property)
BillingLedgerEntry
One row of the workspace credit ledger as returned by
GET /api/billing/ledger (newest first). amountUsd is signed: top-ups are
positive, run charges negative. Tolerant of additive server fields.
Members:
amountUsd(Property)createdAt(Property)createdBy(Property)currency(Property)description(Property)entryType(Property)id(Property)runId(Property)
BillingLedgerPage
One page of recent ledger rows (newest first). Not cursor-paged — limit bounds the read.
Members:
entries(Property)
BillingLedgerQuery
Query for the billing ledger read. limit is clamped server-side to [1, 100] (default 25).
Members:
limit(Property)
BillingPortalRequest
Members:
returnUrl(Property)
BillingSummary
Customer-facing billing summary — GET /api/billing (scope billing:read).
All money fields are USD numbers. The index signature keeps the shape tolerant
of ADDITIVE server fields (e.g. a deployment newer than this SDK reporting
extra plan attributes) — unknown keys are preserved, never rejected.
Members:
balanceUsd(Property)monthSpendUsd(Property)paymentMethodStatus(Property)planKey(Property)spendCapUsd(Property)subscriptionStatus(Property)
BundledSkill
In-memory skill bundle: a flat path -> bytes map and the deterministically-zipped representation.
The SDK runs only the cheap, safety-critical checks here
(validateSkillBundleEntry: no .., no absolute paths, no Windows
backslashes, depth/length limits). The BFF re-canonicalises and
recomputes the canonical hash on receipt — SDK-side hashing is NOT
part of any contract, so we don't expose one for workspace uploads.
For workspace skills the SDK computes an advisory sha256 of the
canonicalised zip via hashSkillBundle() before upserting the skill by name.
The platform verifies the hash against the uploaded bytes and uses it for
deduplication.
Members:
compressedSize(Property)fileCount(Property)zip(Property)
BundledTool
Members:
compressedSize(Property)fileCount(Property)zip(Property)
BundleMeta
Fidelity metadata captured from a local directory walk: exec are the
bundle-relative paths that restore executable (0o755); symlinks are captured
links. When non-empty it is serialized into the RESERVED_META_ENTRY
sidecar, appended LAST so a pure-content bundle stays byte-identical to the
pre-fidelity output (dedup continuity).
Members:
exec(Property)symlinks(Property)
ChildRunRef
A subagent CHILD run, enumerated under its parent via GET /runs/:id/children.
A first-class, lineage-discoverable run reference: it ResolvableRunRef
(its id resolves through the run facade — events/outputs/getRun), carries the
lineage (parentRunId/depth) and the terminal outcome/cost, so a child is
observable exactly like a top-level run.
Members:
costUsd(Property)createdAt(Property)depth(Property)lastTurnOutcome(Property)parentRunId(Property)status(Property)terminalAt(Property)
FileRecordWire
Wire-level record for a workspace File as returned by the BFF.
Mirrors PublicWorkspaceFile from the dashboard service layer
with kind='file' and f_* ids.
Members:
createdAt(Property)fileCount(Property)finalizedAt(Property)hash(Property)id(Property)kind(Property)manifest(Property)name(Property)sizeBytes(Property)state(Property)updatedAt(Property)
InlineSecrets
Per-run inline secrets bundle. apiKeys holds the BYOK provider keys, keyed
by RunProvider. A run REQUIRES a key for its own provider; it MAY
carry keys for additional providers so a subagent spawned with a
different-family model inherits them server-side from the vault (the keys
never transit the container). mcpServers credentials are cross-provider
(an MCP credential is the same secret whichever model is driving the MCP
client).
Members:
apiKeys(Property)envSecrets(Property)mcpServers(Property)
McpServerRef
The non-secret half of an MCP server declaration. This is what enters
the hashed submission, the run snapshot, and any audit log. name
keys into secrets.mcpServers for the per-request headers.
transport is optional on the wire — when omitted, the runtime is
free to pick the default remote transport (http). When present, it
MUST be one of REMOTE_MCP_TRANSPORTS; stdio is rejected at
parse time.
Members:
name(Property)transport(Property)url(Property)
McpServerSecret
Members:
headers(Property)name(Property)url(Property)
Output
One captured output file as the dashboard reports it. Use
outputLink / createOutputLink to get a temporary direct URL for download.
Members:
contentType(Property)createdAt(Property)filename(Property)id(Property)sizeBytes(Property)
OutputDownloadOptions
Members:
timeoutMs(Property)to(Property)
OutputFilePathSelector
Members:
match(Property)path(Property)
OutputLink
Members:
expiresAt(Property)expiresInSeconds(Property)output(Property)url(Property)
OutputLinkOptions
Members:
expiresIn(Property)
OutputQuery
Members:
contentType(Property)dir(Property)extension(Property)filename(Property)path(Property)recursive(Property)type(Property)
OutputSearchHit
One output-search hit — a reference only (no bytes); read with readOutputText.
Members:
contentType(Property)filename(Property)outputId(Property)runId(Property)sizeBytes(Property)
OutputSearchPage
A page of output-search hits.
Members:
hits(Property)
OutputSearchQuery
Cross-run output search query (Aex.sessions.searchOutputs). Restrict to a
corpus with runIds; filter by filename substring / extension / content type.
The MVP composes this client-side (per-run listOutputs + filter) — a future
server-side GET /api/outputs/search can back the same contract with a real
cross-run index, body-only swap.
Members:
contentType(Property)extension(Property)filename(Property)limit(Property)runIds(Property)
OutputText
A byte-capped, decoded text read of one output file, as returned by
Aex.sessions.outputs(id).read. Built for feeding run deliverables to an LLM
without loading the whole (possibly very large) file into memory or context:
the read streams and stops at maxBytes, so text is at most that many bytes
decoded as UTF-8. Check truncated before treating text as complete.
Members:
output(Property)text(Property)totalBytes(Property)truncated(Property)
ParsedApiKey
Members:
plane(Property)region(Property)regionCode(Property)workspaceId(Property)
PlatformRunSubmissionRequest
Members:
idempotencyKey(Property)limits(Property)machine(Property)provider(Property)runtimeSize(Property)secrets(Property)submission(Property)timeoutMs(Property)webhook(Property)workspaceId(Property)
ProviderEvent
Provider-emitted event payload. Provider-specific fields are passed through structurally so historical events and managed-runner events can be displayed and downloaded without each client needing provider-specific schemas.
Members:
created_at(Property)id(Property)type(Property)
ProviderFault
A structured, redaction-safe description of an UPSTREAM provider fault the aex runtime surfaces on a failed turn (a rate limit, an overloaded provider, a quota exhaustion, or a generic provider error). It is a sibling of the API-plane throttle: the container/runtime emits this shape on the terminal error and the SDK re-exposes it on AexRateLimitError.providerFault so callers get one place to read "the model provider throttled us".
Members:
kind(Property)message(Property)provider(Property)retryAfterMs(Property)status(Property)
ReadOutputTextOptions
Options for Aex.sessions.outputs(id).read / import("./operations.js").readOutputText.
Members:
grep(Property)maxBytes(Property)timeoutMs(Property)
ResolvableRunRef
The minimal capability a value must carry to be RESOLVABLE through the run
facade — getRun / listRunEvents / listOutputs all key on this id.
Encodes the "handed ⇒ resolvable" invariant at the type level: anything the
platform hands you as a run reference exposes a resolvable id, so a run can
never be surfaced as a bare unresolvable string.
Members:
id(Property)
RetryOptions
Tunes the built-in retry loop. All fields are optional; omit the whole
retry option (or pass retry: false on the client) to accept the defaults
or turn the loop off entirely.
Members:
initialDelayMs(Property)maxAttempts(Property)maxDelayMs(Property)maxElapsedMs(Property)
Run
Loose record describing a run as the dashboard BFF returns it. Concrete dashboard-managed fields appear in the index signature; the SDK and CLI may surface them without strong typing per-field.
runtimeManifest is derived from the validated submission + the chosen
provider on every read — see runtime-manifest.ts. It is undefined
on responses from BFFs that predate Phase 2 of the runtime-environment
rollout; SDK consumers MUST treat it as best-effort and not panic on
its absence.
Members:
costTelemetry(Property)createdAt(Property)errorMessage(Property)failureClass(Property)id(Property)lastTurnOutcome(Property)runtimeManifest(Property)startedAt(Property)status(Property)terminalAt(Property)updatedAt(Property)usage(Property)workspaceId(Property)
RunCollectOptions
Options for Aex.run.
Members:
await(Property)idleTimeoutMs(Property)pingIntervalMs(Property)throwOnFailure(Property)timeoutMs(Property)webSocketFactory(Property)
RunEnvironment
Networking + runtime-package snapshot carried inside a flat submission
so the hosted API can deep-clone and mutate it per run (e.g. injecting the
proxy hostname into allowed_hosts) without sharing state across
concurrent runs.
envVars is the customer-controlled key/value bag delivered into the
managed container process and mirrored in the mounted RUNTIME.env /
RUNTIME.json files. The same keys become __KEY__ substitution targets
in agent-facing markdown inside skill / agentsmd / file bundles. Aex-set
runtime keys use the reserved AEX_* prefix; customer keys MUST NOT
collide with that prefix.
Members:
envVars(Property)networking(Property)packages(Property)
RunEvents
A run-facade events accessor (list + polling stream) keyed on a run id.
Members:
list(Method)stream(Method)
RunLimits
Per-run override of the lineage limits. Both fields are optional; an absent
field means "use the platform default". The parser (parseRunLimits)
only validates positivity/shape — clamping to the workspace + platform
ceilings is the resolver's job (see resolveRunLimits in @aexhq/shared).
Members:
maxConcurrentChildRuns(Property)maxSpendUsd(Property)maxSubagentDepth(Property)maxTurns(Property)
RunOutputs
A run-facade outputs accessor (a subset of SessionOutputs) keyed on a run id.
Members:
download(Method)find(Method)findOne(Method)link(Method)list(Method)read(Method)
RunRecordArchiveFileV1
Members:
contentType(Property)filename(Property)id(Property)namespace(Property)path(Property)recordCount(Property)role(Property)sizeBytes(Property)status(Property)
RunRecordCostV1
Members:
status(Property)telemetry(Property)
RunRecordDownloadErrorV1
Members:
filename(Property)id(Property)message(Property)namespace(Property)
RunRecordManifestV1
Members:
errors(Property)files(Property)namespaces(Property)outputs(Property)runId(Property)runRecordSchemaVersion(Property)schemaVersion(Property)
RunRecordMetadataV1
Members:
cost(Property)custody(Property)run(Property)submission(Property)
RunRecordNamespaceV1
Members:
description(Property)name(Property)prefix(Property)status(Property)
RunRecordSubmissionSnapshotV1
Members:
submission(Property)
RunRecordV1
Members:
events(Property)manifest(Property)metadata(Property)outputs(Property)runId(Property)schemaVersion(Property)
RunResult
The unified SETTLED result of Aex.run. Extends the contracts
SettledResult (the ONE settled shape run() and done() share), so
the terminal status (a SessionTerminalOutcome), ok, costUsd
(number, >= 0), and usage are ALWAYS present — run() awaits the settle
commit by default. Adds the one-shot conveniences: the run-compatible record,
events, decoded trace, assistant text, and captured outputs.
T is the responseFormat decode type: when the run was submitted with a
json_schema responseFormat, outcome carries the typed decoded
value or a typed refusal.
Members:
events(Property)messages(Property)outcome(Property)outputs(Property)run(Property)runId(Property)session(Property)sessionId(Property)text(Property)trace(Property)turn(Property)
RuntimeManifest
The in-container paths the agent and skill code reference at
runtime. All fields are absolute, all reflect Anthropic Managed
Agents' session-mount rebase rule (every mount_path lands under
/mnt/session/uploads/ regardless of the leading slash).
skillsRoot is the location of Skills API-registered bundles, which
the runtime auto-discovers under /workspace/skills/<name>/ —
empirically a separate root from the session-resource mounts, NOT
under /mnt/session/uploads/.
Members:
aexCli(Property)assetsRoot(Property)envVars(Property)filesRoot(Property)indexJson(Property)mountedFiles(Property)provider(Property)readme(Property)runtimeEnv(Property)runtimeJson(Property)skillsRoot(Property)
RuntimeResources
Managed runtime sizing presets.
The public contract exposes product-level runtime size tokens, not host implementation details. The closed token set keeps invalid resource pairings out of the wire contract while leaving the concrete host mapping private.
Members:
cpus(Property)memoryMb(Property)
RunWebhookDelivery
One row of a run's webhook delivery ledger, as returned by
GET /api/runs/:id/webhook-deliveries. id is the stable webhook-id
header the consumer dedupes on across retries; the optional fields are
populated only once a delivery attempt has been made.
Members:
attemptCount(Property)createdAt(Property)eventType(Property)id(Property)lastError(Property)lastStatusCode(Property)nextAttemptAt(Property)status(Property)
RunWebhookSpec
Per-run webhook callback. v1: terminal-only; the URL must be https.
Members:
url(Property)
SecretRecord
Wire-level record for a workspace secret as returned by the BFF.
Workspace secrets share the lifecycle SEMANTIC of skills/files: a
Secret.value(...) is per-run and gone at terminal; PROMOTING it (or
aex.secrets.set) persists a named, searchable workspace secret. The
identity is the name (the handle a Secret.ref points at); the value
rotates under that stable name, bumping version.
This record is METADATA ONLY — it never carries the secret value. The value is write-only on create/rotate and readable solely via the audited SecretReveal path.
Members:
createdAt(Property)deletedAt(Property)id(Property)name(Property)state(Property)updatedAt(Property)version(Property)
Session
Members:
activeDurationMs(Property)costUsd(Property)createdAt(Property)errorMessage(Property)failureClass(Property)id(Property)idleAt(Property)idleTtl(Property)idleTtlMs(Property)lastTurnDurationMs(Property)lastTurnOutcome(Property)retainedStorageBytes(Property)sessionId(Property)status(Property)suspendedAt(Property)turnSeq(Property)turnStatus(Property)updatedAt(Property)usage(Property)
SessionCreateOptions
Options for opening a session (the low-level API) or a one-shot run.
Everything the agent needs is spelled out at the call site:
model/system— the agent's brief.tools— customToolbundles and builtin tool-name references; local custom-tool instances are materialized to the hosted asset store before the session lands.skills— workspace skill bundles fromSkill.fromDir/Skill.fromUrl/Skill.fromFiles/ …; the SDK upserts them by name before the session lands, and the wire submission references only those names.agentsMd/files— local composition instances (AgentsMd.fromContent/File.fromBytes, …), materialized to the hosted asset store before the session lands.mcpServers— instances whose secrets are split into the vaulted secrets channel server-side; the public submission carries only the declarations.apiKeys— the BYOK provider key(s), keyed by provider. A key for the selected provider is REQUIRED. The platform never holds a long-lived provider key on your behalf.
Members:
agentsMd(Property)apiKeys(Property)approvalGate(Property)environment(Property)files(Property)idempotencyKey(Property)includeBuiltinTools(Property)mcpServers(Property)metadata(Property)model(Property)outputMode(Property)outputs(Property)overrides(Property)provider(Property)responseFormat(Property)runtime(Property)skills(Property)system(Property)tools(Property)webhook(Property)
SessionEnvironmentOptions
Members:
secrets(Property)variables(Property)
SessionEvents
Accessor over the session's event stream (session.events()). EVERY surface
yields the one canonical AexEventView (guard-bearing, non-optional
populated sequence): the buffered snapshot list(), the polling stream()
iterator, the live coordinator streamEnvelopes() iterator, and the
events-namespace archive.
Members:
archiveLink(Method)download(Method)first(Method)last(Method)list(Method)stream(Method)streamEnvelopes(Method)
SessionListPage
Members:
nextCursor(Property)sessions(Property)
SessionListQuery
Members:
cursor(Property)limit(Property)since(Property)status(Property)
SessionMessages
Accessor over the session's assistant messages. session.messages returns
this synchronously; each method fetches on call.
Members:
all(Method)first(Method)last(Method)list(Method)
SessionOutputs
Accessor over the session's captured output files (session.outputs()):
enumerate, read one as capped text, locate/resolve, and download.
Members:
download(Method)fetch(Method)find(Method)findOne(Method)first(Method)last(Method)link(Method)list(Method)read(Method)search(Method)
SessionOverrides
Members:
idleTtl(Property)maxSpendUsd(Property)maxTurns(Property)timeout(Property)
SessionRetentionPolicy
Members:
idleTtl(Property)
SessionRunOptions
Options for opening a session (the low-level API) or a one-shot run.
Everything the agent needs is spelled out at the call site:
model/system— the agent's brief.tools— customToolbundles and builtin tool-name references; local custom-tool instances are materialized to the hosted asset store before the session lands.skills— workspace skill bundles fromSkill.fromDir/Skill.fromUrl/Skill.fromFiles/ …; the SDK upserts them by name before the session lands, and the wire submission references only those names.agentsMd/files— local composition instances (AgentsMd.fromContent/File.fromBytes, …), materialized to the hosted asset store before the session lands.mcpServers— instances whose secrets are split into the vaulted secrets channel server-side; the public submission carries only the declarations.apiKeys— the BYOK provider key(s), keyed by provider. A key for the selected provider is REQUIRED. The platform never holds a long-lived provider key on your behalf.
Members:
deleteAfter(Property)message(Property)messageIdempotencyKey(Property)stream(Property)
SessionRunResult
The unified SETTLED result of one turn (session.send(...).done()). Extends
the contracts SettledResult, so done() returns the SAME shape as
run(): the terminal status (a SessionTerminalOutcome), ok,
costUsd, and usage are always present (the turn awaits settle by default).
SessionSendOptions
Members:
await(Property)from(Property)idempotencyKey(Property)idleTimeoutMs(Property)pingIntervalMs(Property)webSocketFactory(Property)
SessionSummary
Members:
activeDurationMs(Property)costUsd(Property)createdAt(Property)id(Property)idleAt(Property)idleTtl(Property)idleTtlMs(Property)retainedStorageBytes(Property)sessionId(Property)status(Property)suspendedAt(Property)turnSeq(Property)updatedAt(Property)
SessionTurn
Members:
endedAt(Property)eventCursor(Property)sessionId(Property)startedAt(Property)status(Property)turnId(Property)turnSeq(Property)
SessionTurnResult
The unified SETTLED result of one turn (session.send(...).done()). Extends
the contracts SettledResult, so done() returns the SAME shape as
run(): the terminal status (a SessionTerminalOutcome), ok,
costUsd, and usage are always present (the turn awaits settle by default).
Members:
events(Property)messages(Property)outcome(Property)outputs(Property)session(Property)sessionId(Property)text(Property)turn(Property)
SessionWebhooks
Accessor over the session's webhook delivery ledger (session.webhooks()).
Members:
list(Method)redeliver(Method)
SettledResult
The unified SETTLED-RESULT contract shared by run() and done(). Because
both await the settle commit by default, these fields are ALWAYS present at a
terminal read — they are NON-optional, so a code path that forgets to
populate costUsd/usage/the terminal status fails to typecheck. The SDK
RunResult/SessionTurnResult extend this one shape so done() == run().
costUsd is the AEX showback estimate in USD (>= 0) and EXCLUDES the
customer's BYOK provider spend — price BYOK from usage tokens.
Members:
costUsd(Property)error(Property)ok(Property)status(Property)usage(Property)
SkillBundleEntry
Manifest entry persisted in skill_bundles.manifest and in run-owned
snapshots. path is forward-slash, relative, normalised. mode is the
stored POSIX mode (sanitised, NOT the user's filesystem mode) — see
SKILL_BUNDLE_LIMITS.defaultFileMode.
Members:
mode(Property)path(Property)size(Property)
SkillBundleManifest
Members:
entries(Property)fileCount(Property)totalSize(Property)
SkillRecordWire
Wire-level metadata record for a workspace skill as returned by the BFF.
Workspace skills are named, mutable, by-name-bound bundles: skill.upload()
upserts one under a stable name; a run references it by that name and the
platform resolves it to the CURRENT bytes at submit time. This record is
METADATA ONLY — the bytes live in the content-addressed asset store keyed by
contentHash. version bumps each time the bytes change under the name.
Members:
contentHash(Property)createdAt(Property)deletedAt(Property)description(Property)id(Property)kind(Property)name(Property)sizeBytes(Property)updatedAt(Property)version(Property)
SkillRef
The PUBLIC wire reference to a workspace skill — by NAME, no bytes, no hash.
This is what the SDK sends in submission.skills and what the idempotency
hash covers. The run resolves the name to the workspace skill's CURRENT bytes
at submit time (a re-upload under the same name changes what later runs see).
Members:
kind(Property)name(Property)
StreamEventsOptions
Members:
intervalMs(Property)signal(Property)
SubmitResult
The result of Aex.submit: the run id + a resumable session handle.
Members:
runId(Property)session(Property)
TextMessageEventView
A TEXT_MESSAGE_CONTENT event with its assistant-text payload narrowed.
delta discriminates a per-token STREAMING delta (delta: true, emitted on
outputMode:'stream') from the final coalesced block (delta absent/false).
Both narrow via isTextMessage().
Members:
data(Property)type(Property)
ToolBundleManifest
Members:
description(Property)entry(Property)input_schema(Property)name(Property)
ToolCallResultEventView
A TOOL_CALL_RESULT event with the correlating id + result narrowed.
Members:
data(Property)type(Property)toolCallId(Method)
ToolCallStartEventView
A TOOL_CALL_START event with the tool-call id/name/args narrowed.
Members:
data(Property)type(Property)toolCallId(Method)
ToolRef
User-supplied executable tool bundle. The bytes are addressed by the same content-addressed asset ref used by Skills/Files, while the provider-visible manifest rides as value-free metadata on the submission.
Members:
description(Property)entry(Property)input_schema(Property)
UsageSummary
Members:
cacheCreationInputTokens(Property)cacheReadInputTokens(Property)inputTokens(Property)outputTokens(Property)totalTokens(Property)
VerifyAexWebhookInput
Customer-side verification for aex run webhooks (Standard Webhooks scheme).
aex signs every delivery HMAC-SHA256 over ${webhook-id}.${webhook-timestamp}.${rawBody}
and sends three headers:
webhook-id: stable across retries (dedupe key)webhook-timestamp: unix seconds at send timewebhook-signature: space-delimited list ofv1,<base64(hmac)>entries (a list during secret rotation — accept ANY match)
The secret is the workspace signing secret surfaced once as whsec_<base64>;
the HMAC key is the raw bytes after the whsec_ prefix. Verification accepts
the secret with or without the prefix.
Pure Web Crypto — identical under Bun and Node; this mirrors the
standardwebhooks library so a customer can verify with either.
Members:
headers(Property)rawBody(Property)secret(Property)toleranceSeconds(Property)
WaitForRunOptions
Members:
intervalMs(Property)signal(Property)timeoutMs(Property)
WebhookSigningSecret
The workspace webhook signing secret reveal — POST /api/webhook/signing-secret.
whsec is the Standard-Webhooks style whsec_<base64> string that
verifyAexWebhook accepts as secret. The endpoint reveals the current
secret, CREATING one on first use; it does not rotate (a repeat call returns
the same value). POST (not GET) so every reveal is a logged action.
Members:
whsec(Property)
WhoAmI
Members:
caps(Property)limits(Property)principalType(Property)scopes(Property)tokenId(Property)tokenName(Property)workspaceId(Property)
Functions
apiErrorFromResponse
apiErrorFromResponse(input)
bundleSkillFiles
bundleSkillFiles(files, meta)
hashSkillBundle
Compute sha256:<hex> of the given canonicalised zip bytes. Used by the
Skill.from* / File / AgentsMd factories to populate the draft's
contentHash field. The hash is advisory — the BFF verifies
it against the uploaded zip; a mismatch is rejected. Web-Crypto-only so the
SDK works in Bun, Node, edge runtimes, and browsers without polyfills.
hashSkillBundle(zipBytes)
isAexApiErrorCode
Narrow an arbitrary value to a known AexApiErrorCode.
isAexApiErrorCode(value)
isAuthError
True for a 401/403 authentication/authorization failure.
isAuthError(err)
isIdempotencyConflict
True for a 409 idempotency-key reuse conflict.
isIdempotencyConflict(err)
isInsufficientScope
True for a 403 whose cause is a missing scope (insufficient_scope).
isInsufficientScope(err)
isNotFound
True for a 404 not-found error.
isNotFound(err)
isRateLimited
True for a 429 rate/concurrency-limit error.
isRateLimited(err)
isRunModel
isRunModel(input)
isStreamableProvider
True when a provider has a streaming producer wired (a STREAMABLE_SHAPES shape).
isStreamableProvider(provider)
isTerminalSessionStatus
True when a session status is terminal (an outcome, or deleted/expired).
isTerminalSessionStatus(status)
isThrottleFault
True when a ProviderFault represents a "back off and retry" signal.
isThrottleFault(fault)
normaliseSkillBundlePath
Reject input paths that try to escape the bundle root or smuggle
platform-specific syntax. Returns the canonical forward-slash
relative path; never returns paths starting or ending with /.
Rejects:
- empty strings and pure whitespace
- absolute paths (
/foo,C:\foo,\\server\share) - backslash separators (Windows)
..segments anywhere in the path.segments anywhere except a leading bare.- paths whose length exceeds
SKILL_BUNDLE_LIMITS.maxPathLength - paths whose depth exceeds
SKILL_BUNDLE_LIMITS.maxDepth - NUL bytes
normaliseSkillBundlePath(input)
parseApiKey
Parse a self-describing API key, or null for any legacy/opaque/tampered
value. Validates the aex_ prefix, the 6-part shape, a known plane and
region code, and the CRC over the first 5 parts.
parseApiKey(token)
parseApprovalGate
Parse the optional submission.approvalGate. Absent / empty tool list ⇒
undefined (no gate). Tool names are deduped; the strict allow-list mirrors the
sibling parsers.
parseApprovalGate(input)
parseProviderFault
Best-effort parse of an unknown value into a ProviderFault. Tolerant of two shapes so the SDK consumes the runtime fault the moment it starts emitting one, without a contracts change:
- The canonical
{ provider?, kind, status?, retryAfterMs?, message? }(optionally nested under aproviderFaultkey), OR - A raw upstream error
{ type: "rate_limit_error" | "overloaded_error" | ..., message?, retry_after? | retryAfter? }—typemaps tokindandretry_after(seconds) maps toretryAfterMs.
Returns undefined when the value carries no recognizable fault.
parseProviderFault(value)
parseResponseFormat
Parse the optional submission.responseFormat. Mirrors parseOutputMode
/ OUTPUT_MODES: absent ⇒ undefined; a bad kind or unknown subfield is
rejected (fail-fast). json_schema requires a JSON-object schema.
parseResponseFormat(input)
parseRunModel
parseRunModel(input, field)
providerForModel
The default upstream provider for a model id — the first provider declared
for it in MODEL_PROVIDER_IDS. Returns undefined when the input is
not a known RunModel (so the SDK can fall back to the default and let
the server reject the model).
providerForModel(model)
providersForModel
All upstream providers that can serve a model id, in declaration order.
Returns [] for an unknown model.
providersForModel(model)
redactSecrets
redactSecrets(value)
resolveBuiltinToolNames
Resolve the set of builtin tool NAMES a submission injects, deduplicated and in BUILTIN_TOOL_NAMES order.
includeBuiltinTools !== false⇒ start from DEFAULT_BUILTIN_TOOLS (the standard set);false⇒ start from none (pure-MCP / pure-custom).- union in every builtin-name string the caller listed in
tools(used to cherry-pick a narrow subset whenincludeBuiltinToolsis false).
Every toolRefs string MUST be a member of BUILTIN_TOOL_NAMES; the
union is validated ⊆ the closed set so an invalid name can never leak through.
resolveBuiltinToolNames(includeBuiltinTools, toolRefs)
resolveModelProvider
The single model→provider resolver shared by the SDK and the CLI, wrapping providersForModel with the forward-compat unknown-model allowance:
providergiven: it is honored. Ifmodelis a KNOWN id, the provider must serve it (else throw). Ifmodelis UNKNOWN, it is allowed through so a slightly-old client can still run a newly-launched model (the server arbitrates).provideromitted: a known model resolves to its DEFAULT provider (first declared). An UNKNOWN model with no provider throws adid you mean?hint — you must name a provider to run a model this client doesn't know.
Returns the resolved RunProvider.
resolveModelProvider(model, provider)
resolveProviderModelId
Translate a canonical model id + provider into the provider-native model
string the upstream API expects (e.g. ("gpt-4o-mini", "openrouter") →
"openai/gpt-4o-mini"). Throws when the provider does not serve the model.
resolveProviderModelId(model, provider)
suggest
The closest candidate to input by a unique case-insensitive prefix match,
else by Levenshtein distance (≤ 2), else undefined. Ties break by
declaration order. Used on an invalid --model / --provider /
--runtime-size (and the SDK's unknown-model throw) to turn a flat rejection
into a fix hint.
suggest(input, candidates)
usageFromProviderUsage
Project a UsageSummary from the settle-written
RunCostProviderUsage entries — the SINGLE server source of token
usage (Run.costTelemetry.providerUsage). Sums each field across all
provider entries; a field is present only when at least one entry carried it.
This retires the dead session.usage / aex.usage-event usage path: the SDK
derives usage from cost telemetry, never re-reads a dual-written top-level
usage. Pure.
usageFromProviderUsage(providerUsage)
validateSkillBundleEntry
Validate one manifest entry: normalises the path, bounds the size, and sanitises the mode to one of {defaultFileMode, defaultDirMode}. The bundle is files-only, so any non-regular-file entry is rejected upstream by the caller (zip parser must skip symlinks, device files, etc. before reaching this function).
validateSkillBundleEntry(input)
validateSkillBundleManifest
Validate a full skill bundle manifest. Enforces:
- entries is a non-empty array
SKILL.mdexists at the bundle root (this is what makes a bundle a skill rather than a plain workspace file)- file count <= maxFiles
- total uncompressed size <= maxDecompressedBytes
- per-entry validation (see
validateSkillBundleEntry) - no duplicate paths
In this public surface, skill means "Claude Skill" — bundles without
SKILL.md are not skills and must go
through the AgentsMd or File upload concepts instead.
Returns a canonical manifest with totals computed.
validateSkillBundleManifest(input)
verifyAexWebhook
Verify an aex webhook delivery. Returns true only when the timestamp is
within tolerance AND one of the v1,<base64> entries in webhook-signature
matches the HMAC over ${id}.${timestamp}.${rawBody}. Constant-time compare;
never throws on a bad signature (only on a malformed secret).
verifyAexWebhook(input)
Variables
AEX_API_ERROR_CODES
SSoT for the platform's STABLE API error codes.
The server (aex-platform api.ts) imports this table instead of keeping its
own private copy, so a route emitting a code absent from the union fails to
compile and adding a code without a message is caught. The SDK error factory
(import("./error-factory.js").apiErrorFromResponse) dispatches on the
code to a typed subclass; the CLI maps it to a human remedy.
The code is the stable, machine-branchable identity of a failure — distinct
from the human message. idempotency_conflict and insufficient_scope
(previously message-less bare 409/403 bodies) are first-class here.
AEX_API_ERROR_MESSAGES
Human message per stable code. A Record (not Partial) so a code added to
AEX_API_ERROR_CODES without a message is a COMPILE error. These are
the fallback messages the factory uses when the server sends a BARE code with
no message detail.
AEX_API_ERROR_REMEDIES
Optional per-code fix hint the CLI surfaces alongside the error message.
AEX_RUN_SETTLED_NAME
The data.name of the settle-consistency barrier event. The coordinator
broadcasts ONE such CUSTOM event as a run's LAST stream event, after the
Postgres mirror lands — so observing it ⇒ a subsequent getRun is terminal
and listOutputs is complete. It is intentionally a CUSTOM event (not a
typed RUN_* event): off-the-shelf AG-UI clients ignore it, while
streamEnvelopes(runId, { settleConsistent: true }) ends the iterator on it.
Unlike RUN_FINISHED (the AG-UI render-complete UX signal, emitted by the
runner BEFORE the platform learns the outcome), this is settle-gated. The
platform mirrors this constant in @aexhq/shared.
BUILTIN_TOOL_NAMES
The CLOSED set of builtin tool NAMES the managed runtime can inject — one per
machine tool the hands implement. This list is the single source of truth for
validating builtin tool references; the platform's HANDS_TOOLS (the execute
vocabulary) is pinned EQUAL to it at module load (platform-runtime-agent
assertNamesMatch), so a rename on either side fails loudly rather than
silently shipping a name the executors do not speak.
Order mirrors HANDS_TOOLS. A builtin tool reference (a bare string in
submission.tools) must be a member of this set.
BuiltinTools
Typo-safe accessors for the closed builtin tool set: each key maps to the
real tool NAME string. Reference a builtin in submission.tools via
BuiltinTools.web_search rather than the bare string so a rename is a
compile error, not a runtime 400.
Keys are the real tool names; a unit test asserts Object.values(BuiltinTools)
deep-equals BUILTIN_TOOL_NAMES so the two can never drift.
CUSTODY_MANIFEST_SCHEMA_VERSION
DEFAULT_BUILTIN_TOOLS
The default builtin tool set injected when includeBuiltinTools !== false.
It is the complete closed builtin set.
DEFAULT_RUN_PROVIDER
DEFAULT_RUNTIME_SIZE
Default when runtimeSize is omitted (the 1 GB tier).
MCP_SERVER_NAME_PATTERN
MODEL_PROVIDER_IDS
Source of truth for the closed model set: each canonical model id maps to the upstream providers that can serve it and the provider-native model string each one expects.
Models.* / RUN_MODELS are aex's own canonical, provider-neutral
identifiers — they are NOT the strings sent to a provider. The platform
translates a (canonical model, provider) pair to the native id via
resolveProviderModelId when it builds the run's session manifest. The
same canonical model can therefore be served by more than one provider (e.g.
gpt-4o-mini via openai or openrouter), with a different native string
per provider.
Ordering matters: the first provider listed for a model is its default
(see providerForModel) — list the native vendor before openrouter.
Additions belong here first so SDK types, CLI validation, docs examples, and
platform parsing all move together.
Models
Symbol-style accessors for the closed model set. Prefer these over raw
strings so an invalid token is a compile error, not a runtime 400 — e.g.
Models.CLAUDE_HAIKU_4_5. These are aex's canonical ids, not the native
strings sent upstream; the platform translates them per provider (see
MODEL_PROVIDER_IDS / resolveProviderModelId). When a model is
served by more than one provider, pair it with an explicit Providers
value; otherwise the single (default) provider is used.
PLANE_BASE_URLS
Plane → API base URL. When the SDK constructor is given no explicit baseUrl
it DERIVES the target from the API key's embedded plane (see
import("./api-key.js").parseApiKey) rather than blindly defaulting to
prod — so a dev key routes to dev-api.aex.dev and a prd key routes to
api.aex.dev.
The plane-mismatch guard still fires when a key is pointed at the wrong
canonical host (for example, a dev key with baseUrl=https://api.aex.dev).
Providers
Symbol-style accessors for the closed provider set. Prefer these over raw
strings so an invalid token is a compile error, not a runtime 400 — e.g.
Providers.DEEPSEEK. The same model id can route through different upstream
providers (official vs OpenRouter, etc.), so provider is a first-class
submission field; name it explicitly with one of these constants rather than
relying on the model alone to determine routing.
Every value mirrors RUN_PROVIDERS exactly; a unit test asserts
Object.values(Providers) deep-equals RUN_PROVIDERS so the two can never
drift.
RESPONSE_FORMAT_KINDS
Response-format kinds: free-form text (default) or provider-native json_schema.
RUN_MODELS
RUN_MODELS_BY_PROVIDER
Provider → canonical models that provider can serve. Derived from MODEL_PROVIDER_IDS; every provider currently serves at least one model, so all RunProvider keys are present.
RUN_PROVIDERS
Run-time provider selector. Aex exposes one customer interface for every provider. All new submissions execute through the managed runtime; provider selection only decides which upstream model route the managed provider-proxy uses.
RUN_RECORD_MANIFEST_SCHEMA_VERSION
RUN_RECORD_SCHEMA_VERSION
RUNTIME_SIZE_PRESETS
The single source of truth: every offered preset, keyed by its wire token.
Tokens intentionally remain stable product presets. The smallest
(shared-0.06x-256mb) tier is for light / IO-bound runs only.
RUNTIME_SIZES
All preset tokens, ordered as declared. Handy for CLI help + validation.
SESSION_STATUSES
The full closed set of session statuses: the resumable lifecycle half, the
terminal-outcome half (bound to RUN_TERMINAL_OUTCOMES), and the
first-class HITL write-gate awaiting_approval. Composed — never
hand-listed — so the outcome vocabulary can only be extended at the run SSoT.
SESSION_TERMINAL_OUTCOMES
The terminal OUTCOME half of a session's status — DERIVED from the run
outcome SSoT via satisfies readonly RunTerminalOutcome[], so a new run
outcome fails to compile until it is accounted for here (and therefore in
SESSION_STATUSES). This is the compile-time binding that stops the
session and run terminal vocabularies from drifting: the bare session
error is gone — a failed turn is failed, a wall-clock kill timed_out,
a cancel cancelled, a clean finish succeeded.
Sizes
Symbol-style accessors for TS callers: the SHARED_2X_8GB member resolves to
the wire token "shared-2x-8gb". Re-exported by the SDK as Sizes.
SKILL_BUNDLE_LIMITS
Hard caps applied at upload time. The SDK enforces these before computing the zip hash so a clearly-too-big bundle never wastes bytes-on-the-wire; the BFF re-enforces server-side because the SDK is untrusted. Numbers are deliberately conservative for the MVP and can be tuned later; keep this object as the single tuning point.
SKILL_NAME_PATTERN
Human-readable, workspace-scoped name. Lowercase, kebab-friendly,
1..128 chars. The DB enforces the length bound via
skill_bundles_name_len_chk; this regex tightens the SDK/CLI input
surface so callers fail at the boundary rather than in the BFF.
SKILL_RESERVED_NAMES
Names reserved by the skills subsystem and therefore usable as neither a
skill name nor a custom tool name. skills is the injected meta-tool (see
SKILLS_TOOL_NAME in submission.ts); skill is its singular. Both
the SDK factories and the BFF parseSkills / parseTools reject these.
STREAMABLE_SHAPES
The provider wire-SHAPES that have a real per-token streaming producer. This const is the contracts-side SSoT, pinned EQUAL to the platform's shape SSoT by a cross-repo parity test so streaming can never be promised for a shape nothing feeds.