@beeos-ai/bma-sdk 0.4.2 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +122 -34
- package/dist/core.d.ts +105 -0
- package/dist/core.js +406 -0
- package/dist/core.js.map +1 -0
- package/dist/errors.d.ts +77 -0
- package/dist/errors.js +109 -0
- package/dist/errors.js.map +1 -0
- package/dist/facade-extensions.d.ts +17 -61
- package/dist/facade-extensions.js +25 -112
- package/dist/facade-extensions.js.map +1 -1
- package/dist/generated/facade-extensions-operations.d.ts +133 -0
- package/dist/generated/facade-extensions-operations.js +11 -0
- package/dist/generated/facade-extensions-operations.js.map +1 -0
- package/dist/generated/facade-extensions-resources.d.ts +34 -0
- package/dist/generated/facade-extensions-resources.js +47 -0
- package/dist/generated/facade-extensions-resources.js.map +1 -0
- package/dist/generated/facade-extensions-types.d.ts +14 -0
- package/dist/generated/facade-extensions-types.js +2 -0
- package/dist/generated/facade-extensions-types.js.map +1 -0
- package/dist/generated/rest-operations.d.ts +4079 -0
- package/dist/generated/rest-operations.js +234 -0
- package/dist/generated/rest-operations.js.map +1 -0
- package/dist/generated/rest-resources.d.ts +666 -0
- package/dist/generated/rest-resources.js +1124 -0
- package/dist/generated/rest-resources.js.map +1 -0
- package/dist/generated/rest-types.d.ts +572 -0
- package/dist/generated/rest-types.js +2 -0
- package/dist/generated/rest-types.js.map +1 -0
- package/dist/generated/rest.d.ts +244 -21
- package/dist/index.d.ts +41 -76
- package/dist/index.js +49 -239
- package/dist/index.js.map +1 -1
- package/dist/lib/artifacts.d.ts +14 -0
- package/dist/lib/artifacts.js +56 -0
- package/dist/lib/artifacts.js.map +1 -0
- package/dist/lib/tool-runner.d.ts +99 -0
- package/dist/lib/tool-runner.js +140 -0
- package/dist/lib/tool-runner.js.map +1 -0
- package/dist/pagination.d.ts +31 -0
- package/dist/pagination.js +66 -0
- package/dist/pagination.js.map +1 -0
- package/dist/resource.d.ts +8 -0
- package/dist/resource.js +9 -0
- package/dist/resource.js.map +1 -0
- package/dist/streaming.d.ts +27 -0
- package/dist/streaming.js +89 -0
- package/dist/streaming.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +4 -0
- package/dist/version.js.map +1 -0
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -3,43 +3,136 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@beeos-ai/bma-sdk)
|
|
4
4
|
|
|
5
5
|
TypeScript client for the BMA REST API, generated from
|
|
6
|
-
[`contracts/bma/rest.openapi.yaml`](../contracts/bma/rest.openapi.yaml)
|
|
7
|
-
|
|
6
|
+
[`contracts/bma/rest.openapi.yaml`](../contracts/bma/rest.openapi.yaml) and the
|
|
7
|
+
resource map [`contracts/bma/sdk.resources.yaml`](../contracts/bma/sdk.resources.yaml),
|
|
8
|
+
plus the BMA extensions to the Anthropic Managed Agents API.
|
|
8
9
|
|
|
9
10
|
| | |
|
|
10
11
|
| --- | --- |
|
|
11
|
-
| Version | 0.
|
|
12
|
+
| Version | 1.0.0 (tag `v1.0.0`), see [CHANGELOG](../CHANGELOG.md); upgrading from 0.4: [MIGRATION](../MIGRATION.md) |
|
|
12
13
|
| Contract | BMA REST snapshot recorded in [`contracts/bma/lock.json`](../contracts/bma/lock.json) |
|
|
13
|
-
| Node.js | 20 or newer; ESM
|
|
14
|
-
|
|
15
|
-
```sh
|
|
16
|
-
npm install @beeos-ai/bma-sdk@0.4.2
|
|
17
|
-
```
|
|
14
|
+
| Node.js | 20 or newer; ESM |
|
|
18
15
|
|
|
19
16
|
```ts
|
|
20
|
-
import { BmaClient
|
|
17
|
+
import { BmaClient } from "@beeos-ai/bma-sdk";
|
|
21
18
|
|
|
22
|
-
const bma = new BmaClient({
|
|
23
|
-
|
|
19
|
+
const bma = new BmaClient({
|
|
20
|
+
token: process.env.BMA_TOKEN!,
|
|
21
|
+
baseUrl: process.env.BMA_BASE_URL!, // origin, e.g. https://api.staging.bma.beeos.ai
|
|
22
|
+
orgId: "org_...", // defaults: also read from BMA_ORG_ID / BMA_PROJECT_ID
|
|
23
|
+
projectId: "prj_...",
|
|
24
|
+
});
|
|
24
25
|
|
|
25
|
-
const { session } =
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
26
|
+
const { session } = await bma.agents.sessions.create(agentId, { idempotency_key: "task-1" });
|
|
27
|
+
await bma.agents.inputs.create(
|
|
28
|
+
agentId,
|
|
29
|
+
{ session_id: session.id, content_blocks: [{ type: "text", text: "Plan my week." }] },
|
|
30
|
+
{ idempotencyKey: "input-1" },
|
|
30
31
|
);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
|
|
33
|
+
for await (const ev of bma.agents.events.stream(agentId, { session_id: session.id, stream_deltas: true })) {
|
|
34
|
+
switch (ev.event) {
|
|
35
|
+
case "model_output": console.log(ev.sequence, ev.data.content_blocks); break;
|
|
36
|
+
case "tool_call_update": console.log(ev.data.tool_call_id, ev.data.state); break;
|
|
37
|
+
case "model_output_delta": console.log(ev.data); break;
|
|
38
|
+
}
|
|
37
39
|
}
|
|
38
40
|
```
|
|
39
41
|
|
|
40
|
-
`
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
Set `baseUrl` to the origin of your BMA deployment (for example
|
|
43
|
+
`https://api.staging.bma.beeos.ai`; the default `https://api.bma.beeos.ai` does
|
|
44
|
+
not resolve yet). The client adds `/api/v1`; a value already ending in
|
|
45
|
+
`/api/v1` is accepted. `token` and `baseUrl` default to
|
|
46
|
+
`BMA_TOKEN` and `BMA_BASE_URL`, `orgId` and `projectId` to `BMA_ORG_ID` and
|
|
47
|
+
`BMA_PROJECT_ID`.
|
|
48
|
+
|
|
49
|
+
## Methods
|
|
50
|
+
|
|
51
|
+
Every contract operation is a method on a resource: path IDs are positional
|
|
52
|
+
arguments, `params` is the operation's query, header and body fields in one
|
|
53
|
+
object (wire names, snake_case), and `options` is the per-request
|
|
54
|
+
`{ timeout, maxRetries, signal, idempotencyKey, headers }`. Params and results
|
|
55
|
+
are the contract types; every schema is exported by name (`AgentSession`,
|
|
56
|
+
`ToolCall`, ...).
|
|
57
|
+
|
|
58
|
+
- **Scope.** `orgId` / `projectId` fill the organization and project of every
|
|
59
|
+
method; pass `org_id` / `project_id` in params to override one call.
|
|
60
|
+
- **Lists.** Every list whose response is `{ data, next_<param> }` returns a
|
|
61
|
+
`PagePromise`: `await` gives the first page (`page.data`,
|
|
62
|
+
`page.hasNextPage()`, `page.getNextPage()`), and
|
|
63
|
+
`for await (const agent of bma.agents.list())` walks every item. Besides
|
|
64
|
+
`cursor` lists this covers `agents.events.list` (forward by
|
|
65
|
+
`after_sequence`, backward when you pass `before_sequence`),
|
|
66
|
+
`agents.sessions.list` (`before_id`), `agentSessions.list` (`after_id`),
|
|
67
|
+
`agents.turns.list`, `agents.turns.events.list` and `files.list` (`page`).
|
|
68
|
+
- **Event stream.** `agents.events.stream()` yields frames discriminated by
|
|
69
|
+
`event`; durable frames carry `id` and `sequence`. Like EventSource, it
|
|
70
|
+
reconnects with `Last-Event-ID` set to the last durable frame when the
|
|
71
|
+
connection drops, when the server ends the response (a deployment), or on
|
|
72
|
+
an `error` frame with code `service_unavailable`; a frame cut off at the end
|
|
73
|
+
is discarded. It never ends on its own: it throws once `maxRetries`
|
|
74
|
+
reconnects in a row received no data (a heartbeat counts as data), and any
|
|
75
|
+
other error frame throws `EventStreamError`.
|
|
76
|
+
- **Files.** Uploads take the bytes as `body` (`Blob`, `ArrayBuffer`, typed
|
|
77
|
+
array or string); downloads (`files.download`, `agents.artifacts.download`,
|
|
78
|
+
...) return the `Response`. `agents.artifacts.downloadVerified(artifact, { maxBytes })`
|
|
79
|
+
verifies the size and sha256 digest.
|
|
80
|
+
|
|
81
|
+
## Errors, retries, timeouts
|
|
82
|
+
|
|
83
|
+
Errors are `BmaApiError` subclasses named after the status, as in the
|
|
84
|
+
Anthropic SDK: `BadRequestError` (400), `AuthenticationError` (401),
|
|
85
|
+
`PermissionDeniedError` (403), `NotFoundError` (404), `ConflictError` (409),
|
|
86
|
+
`ContentTooLargeError` (413), `UnprocessableEntityError` (422),
|
|
87
|
+
`RateLimitError` (429), `InternalServerError` (5xx), `ServiceUnavailableError`
|
|
88
|
+
(503), plus `APIConnectionError`, `APIConnectionTimeoutError` and
|
|
89
|
+
`APIUserAbortError`. `error.code` is the contract's `ErrorCode`.
|
|
90
|
+
|
|
91
|
+
Each call retries twice by default (`maxRetries`) with exponential backoff,
|
|
92
|
+
honouring `retry-after-ms` / `retry-after`. Reads and operations that accept
|
|
93
|
+
an `Idempotency-Key` retry 408, 429, 5xx and connection errors; the SDK sends
|
|
94
|
+
a generated key (`bma-sdk-retry-<uuid>`) unless you pass `idempotencyKey`, and
|
|
95
|
+
reuses it across the retries. Other writes retry only 429, 503 and requests
|
|
96
|
+
that never reached the server. 409 is never retried. The timeout is 60 s per
|
|
97
|
+
attempt (`timeout`), measured until the response headers arrive; `0`
|
|
98
|
+
disables it. Uploads (binary and multipart bodies) get only a per-call
|
|
99
|
+
`timeout`, so a large file is never cut off by the client default (Node's
|
|
100
|
+
fetch still bounds connecting and waiting for headers). The `signal` also
|
|
101
|
+
aborts reading the response body. Every error the SDK throws is a
|
|
102
|
+
`BmaError`.
|
|
103
|
+
|
|
104
|
+
## Custom tools
|
|
105
|
+
|
|
106
|
+
A custom tool call waits in `ready` until a consumer submits its result.
|
|
107
|
+
`defineTool` takes any [Standard Schema](https://standardschema.dev) (zod 4.2+,
|
|
108
|
+
valibot, arktype) and `agents.toolCalls.runner` runs the matching calls of an
|
|
109
|
+
agent and its subagents:
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { z } from "zod";
|
|
113
|
+
import { ToolError, defineTool } from "@beeos-ai/bma-sdk";
|
|
114
|
+
|
|
115
|
+
const weather = defineTool({
|
|
116
|
+
name: "get_weather",
|
|
117
|
+
description: "Current weather",
|
|
118
|
+
inputSchema: z.object({ city: z.string() }),
|
|
119
|
+
run: async ({ city }) => {
|
|
120
|
+
if (!city) throw new ToolError("city is empty"); // submitted as a failed result
|
|
121
|
+
return `Sunny in ${city}`; // string or result content blocks
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
// weather.definition is the agent config entry for tools.get_weather.
|
|
125
|
+
|
|
126
|
+
const runner = bma.agents.toolCalls.runner(agentId, { session_id: session.id, tools: [weather] });
|
|
127
|
+
// ... later
|
|
128
|
+
await runner.stop();
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The runner reconnects its event stream without limit by default (backoff up
|
|
132
|
+
to 8 s; `max_reconnects` bounds it), lists ready calls again after each
|
|
133
|
+
reconnect, treats a 409 on submit (another consumer answered first) as
|
|
134
|
+
handled, and `done()` rejects with the error that stopped it; it never ends
|
|
135
|
+
silently.
|
|
43
136
|
|
|
44
137
|
## BMA extensions to the Anthropic facade
|
|
45
138
|
|
|
@@ -49,16 +142,11 @@ Use the official Anthropic SDK for `/v1/agents`, `/v1/environments`,
|
|
|
49
142
|
```ts
|
|
50
143
|
import { FacadeExtensionsClient, bmaSequence } from "@beeos-ai/bma-sdk/facade-extensions";
|
|
51
144
|
|
|
52
|
-
const ext = new FacadeExtensionsClient({ baseUrl: "https://host", apiKey: key, projectId: "
|
|
53
|
-
const ticket = await ext.
|
|
54
|
-
await ext.
|
|
55
|
-
const page = await ext.
|
|
145
|
+
const ext = new FacadeExtensionsClient({ baseUrl: "https://host", apiKey: key, projectId: "prj_..." });
|
|
146
|
+
const ticket = await ext.sessions.desktop.stream(sessionId, { desktop_session_id, origin: location.origin });
|
|
147
|
+
await ext.sessions.files.upload(sessionId, { file: new File([bytes], "report.pdf") });
|
|
148
|
+
const page = await ext.sessions.files.list(sessionId, { limit: 100 });
|
|
56
149
|
```
|
|
57
150
|
|
|
58
|
-
It also exports the extension field types `ModelConfigOverride`
|
|
59
|
-
(`agent.model.api_url/api_key/api_format`), `MCPServerBMAAuth`
|
|
60
|
-
(`mcp_servers[].bma_auth`), `IDEMPOTENCY_KEY_HEADER`, and `bmaSequence(event)`
|
|
61
|
-
for `bma_sequence` resume cursors.
|
|
62
|
-
|
|
63
151
|
The executor protocol (executor, harness and agent ends) is the separate
|
|
64
152
|
package [`@beeos-ai/bma-executor-sdk`](https://github.com/beeos-ai/bma-executor-sdk/tree/main/typescript).
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { PagePromise, type CursorPageBody } from "./pagination.js";
|
|
2
|
+
import { Stream } from "./streaming.js";
|
|
3
|
+
/**
|
|
4
|
+
* Default per-attempt timeout (D3), measured until the response headers
|
|
5
|
+
* arrive. Uploads (binary and multipart bodies) have no default timeout;
|
|
6
|
+
* event streams and downloads are bounded only until the headers arrive.
|
|
7
|
+
*/
|
|
8
|
+
export declare const DEFAULT_TIMEOUT_MS = 60000;
|
|
9
|
+
/** Default retries after the first attempt (D3; @anthropic-ai/sdk uses 2). */
|
|
10
|
+
export declare const DEFAULT_MAX_RETRIES = 2;
|
|
11
|
+
/** Generated description of one contract operation. */
|
|
12
|
+
export interface OperationDescriptor {
|
|
13
|
+
readonly id: string;
|
|
14
|
+
readonly method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
15
|
+
readonly path: string;
|
|
16
|
+
/** Path template name -> params key (scope params) or positional name. */
|
|
17
|
+
readonly pathParams?: Readonly<Record<string, string>>;
|
|
18
|
+
/** Query name -> serialization style. */
|
|
19
|
+
readonly query?: Readonly<Record<string, string>>;
|
|
20
|
+
/** Header name -> params key. */
|
|
21
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
22
|
+
readonly body?: "json" | "binary" | "multipart";
|
|
23
|
+
readonly bodyRequired?: boolean;
|
|
24
|
+
readonly multipartJSON?: readonly string[];
|
|
25
|
+
readonly response: "json" | "void" | "binary" | "sse";
|
|
26
|
+
/** The operation accepts an Idempotency-Key header. */
|
|
27
|
+
readonly idempotency?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Paginated list: [query parameter, response field] pairs, the default
|
|
30
|
+
* direction first, e.g. [["cursor", "next_cursor"]].
|
|
31
|
+
*/
|
|
32
|
+
readonly page?: readonly (readonly [string, string])[];
|
|
33
|
+
}
|
|
34
|
+
/** Per-request options; every resource method takes them last. */
|
|
35
|
+
export interface RequestOptions {
|
|
36
|
+
/**
|
|
37
|
+
* Per-attempt timeout in milliseconds, until the response headers arrive;
|
|
38
|
+
* 0 means none. Uploads use only this per-call value (no client default).
|
|
39
|
+
*/
|
|
40
|
+
timeout?: number;
|
|
41
|
+
/** Retries after the first attempt; for event streams, reconnects in a row without receiving data. */
|
|
42
|
+
maxRetries?: number;
|
|
43
|
+
signal?: AbortSignal;
|
|
44
|
+
/**
|
|
45
|
+
* Idempotency-Key for operations that declare it. When omitted the SDK
|
|
46
|
+
* generates one and reuses it across the retries of this call.
|
|
47
|
+
*/
|
|
48
|
+
idempotencyKey?: string;
|
|
49
|
+
headers?: Record<string, string>;
|
|
50
|
+
}
|
|
51
|
+
/** A raw request body: file contents or bytes. */
|
|
52
|
+
export type Uploadable = Blob | ArrayBuffer | ArrayBufferView | string;
|
|
53
|
+
/** @internal A body that may be omitted entirely. */
|
|
54
|
+
export type OptionalBody<B> = B | {
|
|
55
|
+
[K in keyof B]?: never;
|
|
56
|
+
};
|
|
57
|
+
/** @internal A multipart body whose binary fields take a Blob or File. */
|
|
58
|
+
export type MultipartBody<B, Files extends PropertyKey> = B extends unknown ? {
|
|
59
|
+
[K in keyof B]: K extends Files ? Blob : B[K];
|
|
60
|
+
} : never;
|
|
61
|
+
/** @internal */
|
|
62
|
+
export interface ClientCoreOptions {
|
|
63
|
+
baseUrl: string;
|
|
64
|
+
fetch?: typeof globalThis.fetch;
|
|
65
|
+
timeout?: number;
|
|
66
|
+
maxRetries?: number;
|
|
67
|
+
/** Authentication and other headers sent on every request. */
|
|
68
|
+
headers: Record<string, string>;
|
|
69
|
+
/** Scope defaults keyed by params name (org_id, project_id). */
|
|
70
|
+
scope: Record<string, string | undefined>;
|
|
71
|
+
/** Client option that sets each scope default, for error messages. */
|
|
72
|
+
scopeOption: Record<string, string>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The deployment origin of a BMA base URL (BMA_BASE_URL): trailing slashes and
|
|
76
|
+
* a trailing /api/v1 (the pre-1.0 API-root form) are removed, so the SDK adds
|
|
77
|
+
* each API prefix exactly once.
|
|
78
|
+
*/
|
|
79
|
+
export declare function bmaOrigin(baseUrl: string): string;
|
|
80
|
+
/** @internal The transport every resource calls. */
|
|
81
|
+
export declare class ClientCore {
|
|
82
|
+
#private;
|
|
83
|
+
readonly baseUrl: string;
|
|
84
|
+
constructor(options: ClientCoreOptions);
|
|
85
|
+
/** @internal */
|
|
86
|
+
_request<T>(op: OperationDescriptor, path: Record<string, string>, params: object, options?: RequestOptions): Promise<T>;
|
|
87
|
+
/**
|
|
88
|
+
* @internal A paginated list. The cursor parameter is the one of
|
|
89
|
+
* `op.page` the caller passed (e.g. before_sequence), else the default.
|
|
90
|
+
*/
|
|
91
|
+
_page<R extends CursorPageBody>(op: OperationDescriptor, path: Record<string, string>, params: object, options?: RequestOptions): PagePromise<R>;
|
|
92
|
+
/**
|
|
93
|
+
* @internal Event stream with EventSource reconnection: when the
|
|
94
|
+
* connection drops or the server ends the response (a rolling restart), or
|
|
95
|
+
* sends an `error` frame with code `service_unavailable`, the stream
|
|
96
|
+
* reconnects with Last-Event-ID set to the last durable frame. A frame not
|
|
97
|
+
* terminated before the end is discarded. Reconnects are bounded by
|
|
98
|
+
* `maxReconnects` (default `maxRetries`) attempts in a row that receive no
|
|
99
|
+
* data; any other error frame ends the stream with EventStreamError.
|
|
100
|
+
*/
|
|
101
|
+
_stream<T>(op: OperationDescriptor, path: Record<string, string>, params: object, options?: RequestOptions, hooks?: {
|
|
102
|
+
onOpen?: () => void;
|
|
103
|
+
maxReconnects?: number;
|
|
104
|
+
}): Stream<T>;
|
|
105
|
+
}
|