@beeos-ai/bma-sdk 1.0.1 → 2.0.0

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.
Files changed (79) hide show
  1. package/README.md +65 -132
  2. package/dist/beta.d.ts +55 -0
  3. package/dist/beta.js +69 -0
  4. package/dist/beta.js.map +1 -0
  5. package/dist/client.d.ts +32 -0
  6. package/dist/client.js +50 -0
  7. package/dist/client.js.map +1 -0
  8. package/dist/errors.d.ts +6 -75
  9. package/dist/errors.js +11 -105
  10. package/dist/errors.js.map +1 -1
  11. package/dist/extensions.d.ts +80 -0
  12. package/dist/extensions.js +24 -0
  13. package/dist/extensions.js.map +1 -0
  14. package/dist/generated/extensions-resources.d.ts +271 -0
  15. package/dist/generated/extensions-resources.js +255 -0
  16. package/dist/generated/extensions-resources.js.map +1 -0
  17. package/dist/generated/extensions.d.ts +3727 -0
  18. package/dist/generated/{rest.js → extensions.js} +1 -1
  19. package/dist/generated/extensions.js.map +1 -0
  20. package/dist/idempotency.d.ts +4 -0
  21. package/dist/idempotency.js +7 -0
  22. package/dist/idempotency.js.map +1 -0
  23. package/dist/index.d.ts +9 -55
  24. package/dist/index.js +9 -57
  25. package/dist/index.js.map +1 -1
  26. package/dist/internal.d.ts +9 -0
  27. package/dist/internal.js +32 -0
  28. package/dist/internal.js.map +1 -0
  29. package/dist/resume.d.ts +22 -0
  30. package/dist/resume.js +122 -0
  31. package/dist/resume.js.map +1 -0
  32. package/dist/version.d.ts +1 -1
  33. package/dist/version.js +3 -3
  34. package/dist/version.js.map +1 -1
  35. package/package.json +6 -12
  36. package/dist/core.d.ts +0 -105
  37. package/dist/core.js +0 -406
  38. package/dist/core.js.map +0 -1
  39. package/dist/facade-extensions.d.ts +0 -27
  40. package/dist/facade-extensions.js +0 -47
  41. package/dist/facade-extensions.js.map +0 -1
  42. package/dist/generated/facade-extensions-operations.d.ts +0 -133
  43. package/dist/generated/facade-extensions-operations.js +0 -11
  44. package/dist/generated/facade-extensions-operations.js.map +0 -1
  45. package/dist/generated/facade-extensions-resources.d.ts +0 -34
  46. package/dist/generated/facade-extensions-resources.js +0 -47
  47. package/dist/generated/facade-extensions-resources.js.map +0 -1
  48. package/dist/generated/facade-extensions-types.d.ts +0 -14
  49. package/dist/generated/facade-extensions-types.js +0 -2
  50. package/dist/generated/facade-extensions-types.js.map +0 -1
  51. package/dist/generated/facade-extensions.d.ts +0 -507
  52. package/dist/generated/facade-extensions.js +0 -6
  53. package/dist/generated/facade-extensions.js.map +0 -1
  54. package/dist/generated/rest-operations.d.ts +0 -4079
  55. package/dist/generated/rest-operations.js +0 -234
  56. package/dist/generated/rest-operations.js.map +0 -1
  57. package/dist/generated/rest-resources.d.ts +0 -666
  58. package/dist/generated/rest-resources.js +0 -1124
  59. package/dist/generated/rest-resources.js.map +0 -1
  60. package/dist/generated/rest-types.d.ts +0 -572
  61. package/dist/generated/rest-types.js +0 -2
  62. package/dist/generated/rest-types.js.map +0 -1
  63. package/dist/generated/rest.d.ts +0 -18519
  64. package/dist/generated/rest.js.map +0 -1
  65. package/dist/lib/artifacts.d.ts +0 -14
  66. package/dist/lib/artifacts.js +0 -56
  67. package/dist/lib/artifacts.js.map +0 -1
  68. package/dist/lib/tool-runner.d.ts +0 -99
  69. package/dist/lib/tool-runner.js +0 -140
  70. package/dist/lib/tool-runner.js.map +0 -1
  71. package/dist/pagination.d.ts +0 -31
  72. package/dist/pagination.js +0 -66
  73. package/dist/pagination.js.map +0 -1
  74. package/dist/resource.d.ts +0 -8
  75. package/dist/resource.js +0 -9
  76. package/dist/resource.js.map +0 -1
  77. package/dist/streaming.d.ts +0 -27
  78. package/dist/streaming.js +0 -89
  79. package/dist/streaming.js.map +0 -1
package/README.md CHANGED
@@ -2,151 +2,84 @@
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/@beeos-ai/bma-sdk.svg)](https://www.npmjs.com/package/@beeos-ai/bma-sdk)
4
4
 
5
- TypeScript client for the BMA REST API, generated from
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.
5
+ TypeScript client for BMA, version 2.0 (ADR 0025): **the official
6
+ [`@anthropic-ai/sdk`](https://www.npmjs.com/package/@anthropic-ai/sdk) 1.6.0
7
+ plus the BMA extensions**. `BmaClient` extends the official `Anthropic` client,
8
+ so every Claude Managed Agents resource under `client.beta` (agents,
9
+ environments, sessions, events, files, skills, vaults, memory stores, …) is the
10
+ official one with its signatures; the BMA extensions (`machines`,
11
+ `machinePools` and `.grants`, `desktopSessions` and `.tickets`,
12
+ `terminalSessions` and `.tickets`, `organization.projects`) are generated from
13
+ [`contracts/bma/v2/extensions.openapi.yaml`](../contracts/bma/v2/extensions.openapi.yaml)
14
+ and use the same client: base URL, authentication, retries, timeouts, `fetch`,
15
+ middleware and error classes. Server side only: the API key is a tenant
16
+ credential (hand end users a ticket, never the key).
9
17
 
10
18
  | | |
11
19
  | --- | --- |
12
- | Version | 1.0.0 (tag `v1.0.0`), see [CHANGELOG](../CHANGELOG.md); upgrading from 0.4: [MIGRATION](../MIGRATION.md) |
13
- | Contract | BMA REST snapshot recorded in [`contracts/bma/lock.json`](../contracts/bma/lock.json) |
20
+ | Version | 2.0.0, see [CHANGELOG](../CHANGELOG.md); from 1.x: [MIGRATION](../MIGRATION.md#typescript-1x--20) |
21
+ | Official core | `@anthropic-ai/sdk` 1.6.0 (exact pin) |
14
22
  | Node.js | 20 or newer; ESM |
15
23
 
16
24
  ```ts
17
- import { BmaClient } from "@beeos-ai/bma-sdk";
25
+ import { BmaClient, errorCode, sessionExtensions } from "@beeos-ai/bma-sdk";
18
26
 
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
- });
27
+ // apiKey: BMA_API_KEY, baseURL: BMA_BASE_URL (default https://api.bma.beeos.ai),
28
+ // project: BMA_PROJECT_ID. ANTHROPIC_* is never read.
29
+ const client = new BmaClient({ apiKey: process.env.BMA_API_KEY, baseURL: process.env.BMA_BASE_URL });
25
30
 
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" },
31
- );
31
+ const session = await client.beta.sessions.create({
32
+ agent: agentId,
33
+ environment_id: environmentId,
34
+ bma_model_override: { model: "deepseek-flash" }, // typed BMA field
35
+ });
36
+ console.log(sessionExtensions(session).modelOverride);
32
37
 
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
- }
38
+ // Open the stream first, then send. A dropped stream resumes with Last-Event-ID
39
+ // and returns every event once.
40
+ const stream = await client.beta.sessions.events.stream(session.id);
41
+ await client.beta.sessions.events.send(session.id, {
42
+ events: [{ type: "user.message", content: [{ type: "text", text: "Start the task." }] }],
43
+ });
44
+ for await (const event of stream) {
45
+ if (event.type === "session.status_idle") break;
39
46
  }
40
- ```
41
-
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
47
 
104
- ## Custom tools
48
+ // Extensions
49
+ for await (const machine of client.beta.machines.list({ limit: 20 })) console.log(machine.id);
50
+ const term = await client.beta.terminalSessions.create({ machine_id: machineId }); // sends an Idempotency-Key
51
+ const ticket = await client.beta.terminalSessions.tickets.create(term.id, {}); // single use; give it to the end user
105
52
 
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();
53
+ try {
54
+ await client.beta.machines.retrieve("mch_x");
55
+ } catch (err) {
56
+ console.log(errorCode(err)); // BMA's error.code, e.g. "machine_not_found"
57
+ }
129
58
  ```
130
59
 
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.
136
-
137
- ## BMA extensions to the Anthropic facade
138
-
139
- Use the official Anthropic SDK for `/v1/agents`, `/v1/environments`,
140
- `/v1/sessions` and events. The routes BMA adds live in a separate entry point:
141
-
142
- ```ts
143
- import { FacadeExtensionsClient, bmaSequence } from "@beeos-ai/bma-sdk/facade-extensions";
144
-
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 });
60
+ - **Extension fields.** `sessionExtensions`, `agentExtensions`,
61
+ `environmentExtensions` and `eventExtensions` read `bma_*` response fields as
62
+ typed values; `sessions.create/update`, `agents.create/update` and
63
+ `environments.create/update` accept `bma_model_override`, `bma_harness` and
64
+ `bma_desktop` as typed params (`bma_model_override: null` revokes).
65
+ - **Project.** `new BmaClient({ project })` sets `x-bma-project-id`;
66
+ `client.withOptions({ project })` copies the client into another project.
67
+ - **Idempotency.** Extension creates send a random `Idempotency-Key` once per
68
+ call, so automatic retries resend it; pass `{ headers: { "Idempotency-Key": key } }`
69
+ to choose it. CMA creates get none unless you pass one.
70
+ - **Types.** The extension request and response types are exported by name
71
+ (`Machine`, `MachineCreateParams`, …); the whole schema set is
72
+ `components["schemas"]`.
73
+ - Credential features of the official client (profiles, `authToken`,
74
+ federation) are disabled: authentication is the BMA API key.
75
+
76
+ ## Development
77
+
78
+ ```bash
79
+ npm ci
80
+ npm run build # tsc
81
+ npm test # unit tests against a local server; BMA_INTEGRATION=1 adds the staging test
149
82
  ```
150
83
 
151
- The executor protocol (executor, harness and agent ends) is the separate
152
- package [`@beeos-ai/bma-executor-sdk`](https://github.com/beeos-ai/bma-executor-sdk/tree/main/typescript).
84
+ `src/generated/` is written by `tools/generate.sh` (openapi-typescript for the
85
+ types, `tools/sdkgen/ts2gen.py` for the services); never edit it by hand.
package/dist/beta.d.ts ADDED
@@ -0,0 +1,55 @@
1
+ import { APIPromise } from '@anthropic-ai/sdk/core/api-promise';
2
+ import { type RequestOptions } from './internal.js';
3
+ import { Stream } from '@anthropic-ai/sdk/core/streaming';
4
+ import { Beta } from '@anthropic-ai/sdk/resources/beta/beta';
5
+ import { Agents, type AgentCreateParams, type AgentUpdateParams } from '@anthropic-ai/sdk/resources/beta/agents/agents';
6
+ import { Environments, type EnvironmentCreateParams, type EnvironmentUpdateParams } from '@anthropic-ai/sdk/resources/beta/environments/environments';
7
+ import { Events, type EventStreamParams } from '@anthropic-ai/sdk/resources/beta/sessions/events';
8
+ import { Sessions, type SessionCreateParams, type SessionUpdateParams } from '@anthropic-ai/sdk/resources/beta/sessions/sessions';
9
+ import { Organization } from '@anthropic-ai/sdk/resources/beta/organization/organization';
10
+ import type { AgentExtParams, EnvironmentExtParams, SessionCreateExt, SessionUpdateExt } from './extensions.js';
11
+ import { OrganizationProjects, type ExtensionServices } from './generated/extensions-resources.js';
12
+ type StreamEvent = Awaited<ReturnType<Events['stream']>> extends Stream<infer T> ? T : never;
13
+ /** client.beta.sessions.events: the official resource whose `stream` resumes a dropped connection. */
14
+ export declare class BmaEvents extends Events {
15
+ /**
16
+ * Stream Events. Same signature and frames as the official method. When the
17
+ * connection drops or the server ends the stream, it reconnects with
18
+ * `Last-Event-ID` set to the `bma_sequence` before the one of the last frame
19
+ * and returns every event once. The official, non-resuming stream is
20
+ * `Events.prototype.stream.call(client.beta.sessions.events, ...)`.
21
+ */
22
+ stream(sessionID: string, params?: EventStreamParams | undefined, options?: RequestOptions): APIPromise<Stream<StreamEvent>>;
23
+ }
24
+ /** client.beta.sessions: the official resource with the typed bma_* request fields and the resuming events stream. */
25
+ export declare class BmaSessions extends Sessions {
26
+ events: BmaEvents;
27
+ create(params: SessionCreateParams & SessionCreateExt, options?: RequestOptions): APIPromise<Beta.Sessions.BetaManagedAgentsSession>;
28
+ update(sessionID: string, params: SessionUpdateParams & SessionUpdateExt, options?: RequestOptions): APIPromise<Beta.Sessions.BetaManagedAgentsSession>;
29
+ }
30
+ /** client.beta.agents: the official resource with the typed bma_harness request field. */
31
+ export declare class BmaAgents extends Agents {
32
+ create(params: AgentCreateParams & AgentExtParams, options?: RequestOptions): APIPromise<Beta.Agents.BetaManagedAgentsAgent>;
33
+ update(agentID: string, params: AgentUpdateParams & AgentExtParams, options?: RequestOptions): APIPromise<Beta.Agents.BetaManagedAgentsAgent>;
34
+ }
35
+ /** client.beta.environments: the official resource with the typed bma_desktop request field. */
36
+ export declare class BmaEnvironments extends Environments {
37
+ create(params: EnvironmentCreateParams & EnvironmentExtParams, options?: RequestOptions): APIPromise<Beta.Environments.BetaEnvironment>;
38
+ update(environmentID: string, params: EnvironmentUpdateParams & EnvironmentExtParams, options?: RequestOptions): APIPromise<Beta.Environments.BetaEnvironment>;
39
+ }
40
+ /** client.beta.organization: the official resource plus `projects`. */
41
+ export declare class BmaOrganization extends Organization {
42
+ projects: OrganizationProjects;
43
+ }
44
+ /** client.beta: the official Beta resources plus the BMA extensions. */
45
+ export declare class BmaBeta extends Beta implements ExtensionServices {
46
+ agents: BmaAgents;
47
+ environments: BmaEnvironments;
48
+ sessions: BmaSessions;
49
+ organization: BmaOrganization;
50
+ machines: import("./generated/extensions-resources.js").Machines;
51
+ machinePools: import("./generated/extensions-resources.js").MachinePools;
52
+ desktopSessions: import("./generated/extensions-resources.js").DesktopSessions;
53
+ terminalSessions: import("./generated/extensions-resources.js").TerminalSessions;
54
+ }
55
+ export {};
package/dist/beta.js ADDED
@@ -0,0 +1,69 @@
1
+ import { mergeHeaders } from './internal.js';
2
+ import { Beta } from '@anthropic-ai/sdk/resources/beta/beta';
3
+ import { Agents } from '@anthropic-ai/sdk/resources/beta/agents/agents';
4
+ import { Environments, } from '@anthropic-ai/sdk/resources/beta/environments/environments';
5
+ import { Events } from '@anthropic-ai/sdk/resources/beta/sessions/events';
6
+ import { Sessions, } from '@anthropic-ai/sdk/resources/beta/sessions/sessions';
7
+ import { Organization } from '@anthropic-ai/sdk/resources/beta/organization/organization';
8
+ import { OrganizationProjects, newExtensionServices } from './generated/extensions-resources.js';
9
+ import { resumable } from './resume.js';
10
+ /** client.beta.sessions.events: the official resource whose `stream` resumes a dropped connection. */
11
+ export class BmaEvents extends Events {
12
+ /**
13
+ * Stream Events. Same signature and frames as the official method. When the
14
+ * connection drops or the server ends the stream, it reconnects with
15
+ * `Last-Event-ID` set to the `bma_sequence` before the one of the last frame
16
+ * and returns every event once. The official, non-resuming stream is
17
+ * `Events.prototype.stream.call(client.beta.sessions.events, ...)`.
18
+ */
19
+ stream(sessionID, params = {}, options) {
20
+ const open = (lastEventID) => super.stream(sessionID, params, lastEventID ?
21
+ { ...options, headers: mergeHeaders([options?.headers, { 'Last-Event-ID': lastEventID }]) }
22
+ : options);
23
+ return super.stream(sessionID, params, options)._thenUnwrap((first) => resumable(first, open, this._client, options?.signal));
24
+ }
25
+ }
26
+ /** client.beta.sessions: the official resource with the typed bma_* request fields and the resuming events stream. */
27
+ export class BmaSessions extends Sessions {
28
+ events = new BmaEvents(this._client);
29
+ create(params, options) {
30
+ return super.create(params, options);
31
+ }
32
+ update(sessionID, params, options) {
33
+ return super.update(sessionID, params, options);
34
+ }
35
+ }
36
+ /** client.beta.agents: the official resource with the typed bma_harness request field. */
37
+ export class BmaAgents extends Agents {
38
+ create(params, options) {
39
+ return super.create(params, options);
40
+ }
41
+ update(agentID, params, options) {
42
+ return super.update(agentID, params, options);
43
+ }
44
+ }
45
+ /** client.beta.environments: the official resource with the typed bma_desktop request field. */
46
+ export class BmaEnvironments extends Environments {
47
+ create(params, options) {
48
+ return super.create(params, options);
49
+ }
50
+ update(environmentID, params, options) {
51
+ return super.update(environmentID, params, options);
52
+ }
53
+ }
54
+ /** client.beta.organization: the official resource plus `projects`. */
55
+ export class BmaOrganization extends Organization {
56
+ projects = new OrganizationProjects(this._client);
57
+ }
58
+ /** client.beta: the official Beta resources plus the BMA extensions. */
59
+ export class BmaBeta extends Beta {
60
+ agents = new BmaAgents(this._client);
61
+ environments = new BmaEnvironments(this._client);
62
+ sessions = new BmaSessions(this._client);
63
+ organization = new BmaOrganization(this._client);
64
+ machines = newExtensionServices(this._client).machines;
65
+ machinePools = newExtensionServices(this._client).machinePools;
66
+ desktopSessions = newExtensionServices(this._client).desktopSessions;
67
+ terminalSessions = newExtensionServices(this._client).terminalSessions;
68
+ }
69
+ //# sourceMappingURL=beta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"beta.js","sourceRoot":"","sources":["../src/beta.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import { Anthropic, type ClientOptions } from '@anthropic-ai/sdk';
2
+ import { BmaBeta } from './beta.js';
3
+ /** The hosted BMA origin (the paths carry /v1). */
4
+ export declare const DEFAULT_BASE_URL = "https://api.bma.beeos.ai";
5
+ export interface BmaClientOptions extends Omit<ClientOptions, 'apiKey' | 'authToken' | 'credentials' | 'config' | 'profile' | 'baseURL' | 'webhookKey'> {
6
+ /** The BMA API key (a tenant credential, server side only). Defaults to process.env.BMA_API_KEY. */
7
+ apiKey?: string | null | undefined;
8
+ /** The deployment origin, e.g. https://api.staging.bma.beeos.ai. Defaults to process.env.BMA_BASE_URL, else DEFAULT_BASE_URL. */
9
+ baseURL?: string | null | undefined;
10
+ /** The project scope, sent as x-bma-project-id; required when the key can see more than one project. Defaults to process.env.BMA_PROJECT_ID. */
11
+ project?: string | null | undefined;
12
+ }
13
+ /**
14
+ * The BMA client: the official Anthropic client with the BMA defaults, whose
15
+ * `beta` adds the BMA extensions. It never reads the ANTHROPIC_API_KEY,
16
+ * ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL or credential-profile configuration
17
+ * of the official client: the key defaults to BMA_API_KEY, the origin to
18
+ * BMA_BASE_URL and the project to BMA_PROJECT_ID.
19
+ *
20
+ * Only use it on a server: the API key is a tenant credential. End-user
21
+ * clients get single-use tickets instead.
22
+ */
23
+ export declare class BmaClient extends Anthropic {
24
+ beta: BmaBeta;
25
+ constructor({ apiKey, baseURL, project, defaultHeaders, ...rest }?: BmaClientOptions);
26
+ /** A copy with other options; `project` replaces the project scope. */
27
+ withOptions(options: Partial<ClientOptions> & {
28
+ project?: string | null;
29
+ }): this;
30
+ /** Never resolve the official credential chain (profiles, federation, files). */
31
+ protected _shouldResolveDefaultCredentials(): boolean;
32
+ }
package/dist/client.js ADDED
@@ -0,0 +1,50 @@
1
+ import { Anthropic } from '@anthropic-ai/sdk';
2
+ import { BmaBeta } from './beta.js';
3
+ import { SDK_VERSION } from './version.js';
4
+ /** The hosted BMA origin (the paths carry /v1). */
5
+ export const DEFAULT_BASE_URL = 'https://api.bma.beeos.ai';
6
+ function env(name) {
7
+ const value = typeof process !== 'undefined' ? process.env?.[name]?.trim() : undefined;
8
+ return value || undefined;
9
+ }
10
+ /**
11
+ * The BMA client: the official Anthropic client with the BMA defaults, whose
12
+ * `beta` adds the BMA extensions. It never reads the ANTHROPIC_API_KEY,
13
+ * ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL or credential-profile configuration
14
+ * of the official client: the key defaults to BMA_API_KEY, the origin to
15
+ * BMA_BASE_URL and the project to BMA_PROJECT_ID.
16
+ *
17
+ * Only use it on a server: the API key is a tenant credential. End-user
18
+ * clients get single-use tickets instead.
19
+ */
20
+ export class BmaClient extends Anthropic {
21
+ beta = new BmaBeta(this);
22
+ constructor({ apiKey, baseURL, project, defaultHeaders, ...rest } = {}) {
23
+ const key = apiKey || env('BMA_API_KEY');
24
+ if (!key) {
25
+ throw new TypeError('BmaClient: set the apiKey option or the BMA_API_KEY environment variable');
26
+ }
27
+ const scope = project || undefined;
28
+ super({
29
+ ...rest,
30
+ apiKey: key,
31
+ authToken: null,
32
+ baseURL: baseURL || env('BMA_BASE_URL') || DEFAULT_BASE_URL,
33
+ defaultHeaders: {
34
+ 'X-BMA-SDK': `bma-sdk-ts/${SDK_VERSION}`,
35
+ ...(env('BMA_PROJECT_ID') ? { 'x-bma-project-id': env('BMA_PROJECT_ID') } : {}),
36
+ ...defaultHeaders,
37
+ ...(scope ? { 'x-bma-project-id': scope } : {}),
38
+ },
39
+ });
40
+ }
41
+ /** A copy with other options; `project` replaces the project scope. */
42
+ withOptions(options) {
43
+ return super.withOptions(options);
44
+ }
45
+ /** Never resolve the official credential chain (profiles, federation, files). */
46
+ _shouldResolveDefaultCredentials() {
47
+ return false;
48
+ }
49
+ }
50
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAsB,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,mDAAmD;AACnD,MAAM,CAAC,MAAM,gBAAgB,GAAG,0BAA0B,CAAC;AAY3D,SAAS,GAAG,CAAC,IAAY;IACvB,MAAM,KAAK,GAAG,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACvF,OAAO,KAAK,IAAI,SAAS,CAAC;AAC5B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,OAAO,SAAU,SAAQ,SAAS;IAC7B,IAAI,GAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3C,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI,KAAuB,EAAE;QACtF,MAAM,GAAG,GAAG,MAAM,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;QACzC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,SAAS,CAAC,0EAA0E,CAAC,CAAC;QAClG,CAAC;QACD,MAAM,KAAK,GAAG,OAAO,IAAI,SAAS,CAAC;QACnC,KAAK,CAAC;YACJ,GAAG,IAAI;YACP,MAAM,EAAE,GAAG;YACX,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,OAAO,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,gBAAgB;YAC3D,cAAc,EAAE;gBACd,WAAW,EAAE,cAAc,WAAW,EAAE;gBACxC,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,GAAG,CAAC,gBAAgB,CAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChF,GAAG,cAAc;gBACjB,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAChD;SACF,CAAC,CAAC;IACL,CAAC;IAED,uEAAuE;IAC9D,WAAW,CAAC,OAA6D;QAChF,OAAO,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,iFAAiF;IAC9D,gCAAgC;QACjD,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
package/dist/errors.d.ts CHANGED
@@ -1,77 +1,8 @@
1
- import type { components } from "./generated/rest.js";
2
- /** Contract error codes; unknown future codes still type-check as strings. */
3
- export type ErrorCode = components["schemas"]["ErrorCode"] | (string & {});
4
- type AgentConfigErrorIssue = components["schemas"]["AgentConfigErrorIssue"];
5
- /** Base class of every error thrown by the SDK. */
6
- export declare class BmaError extends Error {
7
- constructor(message: string, options?: {
8
- cause?: unknown;
9
- });
10
- }
11
- /** An error response from the API, or a request that never got one. */
12
- export declare class BmaApiError<TStatus extends number | undefined = number | undefined> extends BmaError {
13
- /** HTTP status; undefined for connection errors and stream error frames. */
14
- readonly status: TStatus;
15
- readonly headers: Headers | undefined;
16
- /** Stable error code from the response body. */
17
- readonly code: ErrorCode | undefined;
18
- /** Parsed response body, if any. */
19
- readonly error: unknown;
20
- /** Field-level problems for agent config validation errors. */
21
- readonly issues: AgentConfigErrorIssue[] | undefined;
22
- /** Current file digest for file_content_conflict / expected_digest_required. */
23
- readonly currentDigest: string | undefined;
24
- /** Facade extensions only: the Anthropic-style `error.type`. */
25
- readonly type: string | undefined;
26
- constructor(status: TStatus, body: unknown, message: string | undefined, headers: Headers | undefined, options?: {
27
- cause?: unknown;
28
- });
29
- /** @internal */
30
- static generate(status: number, body: unknown, headers: Headers): BmaApiError;
31
- }
32
- export declare class APIConnectionError extends BmaApiError<undefined> {
33
- constructor({ message, cause }?: {
34
- message?: string;
35
- cause?: unknown;
36
- });
37
- }
38
- export declare class APIConnectionTimeoutError extends APIConnectionError {
39
- constructor({ message }?: {
40
- message?: string;
41
- });
42
- }
43
- export declare class APIUserAbortError extends BmaApiError<undefined> {
44
- constructor({ message }?: {
45
- message?: string;
46
- });
47
- }
48
1
  /**
49
- * An `error` frame on an event stream. The stream ends after it; frames with
50
- * code `service_unavailable` are retried by the SDK before this is thrown.
2
+ * BMA's reason for an API error (`error.code` of the Anthropic error envelope,
3
+ * e.g. "idempotency_key_reused"), or undefined when `error` is not an API
4
+ * error or has no code. Branch on it rather than on the message. (The
5
+ * official `errorCode` property is `error.details.error_code`, which BMA does
6
+ * not set.)
51
7
  */
52
- export declare class EventStreamError extends BmaApiError<undefined> {
53
- constructor(body: unknown);
54
- }
55
- export declare class BadRequestError extends BmaApiError<400> {
56
- }
57
- export declare class AuthenticationError extends BmaApiError<401> {
58
- }
59
- export declare class PermissionDeniedError extends BmaApiError<403> {
60
- }
61
- export declare class NotFoundError extends BmaApiError<404> {
62
- }
63
- export declare class RequestTimeoutError extends BmaApiError<408> {
64
- }
65
- export declare class ConflictError extends BmaApiError<409> {
66
- }
67
- export declare class ContentTooLargeError extends BmaApiError<413> {
68
- }
69
- export declare class UnprocessableEntityError extends BmaApiError<422> {
70
- }
71
- export declare class RateLimitError extends BmaApiError<429> {
72
- }
73
- export declare class InternalServerError extends BmaApiError<number> {
74
- }
75
- export declare class ServiceUnavailableError extends InternalServerError {
76
- }
77
- export {};
8
+ export declare function errorCode(error: unknown): string | undefined;
package/dist/errors.js CHANGED
@@ -1,109 +1,15 @@
1
- /** Base class of every error thrown by the SDK. */
2
- export class BmaError extends Error {
3
- constructor(message, options) {
4
- super(message, options);
5
- this.name = new.target.name;
6
- }
7
- }
8
- /** An error response from the API, or a request that never got one. */
9
- export class BmaApiError extends BmaError {
10
- /** HTTP status; undefined for connection errors and stream error frames. */
11
- status;
12
- headers;
13
- /** Stable error code from the response body. */
14
- code;
15
- /** Parsed response body, if any. */
16
- error;
17
- /** Field-level problems for agent config validation errors. */
18
- issues;
19
- /** Current file digest for file_content_conflict / expected_digest_required. */
20
- currentDigest;
21
- /** Facade extensions only: the Anthropic-style `error.type`. */
22
- type;
23
- constructor(status, body, message, headers, options) {
24
- const wire = (typeof body === "object" && body !== null ? body : {});
25
- // Native API: {error: string, code}. Facade: {type: "error", error: {type, message, code}}.
26
- const nested = typeof wire.error === "object" && wire.error !== null ? wire.error : undefined;
27
- const code = str(nested ? nested.code : wire.code);
28
- const type = nested ? str(nested.type) : undefined;
29
- const detail = str(nested ? nested.message : wire.error) ?? message;
30
- super(status === undefined
31
- ? (message ?? detail ?? "bma: request failed")
32
- : `bma: ${status} ${code ?? type ?? "unknown"}: ${detail ?? `HTTP ${status}`}`, options);
33
- this.status = status;
34
- this.headers = headers;
35
- this.code = code;
36
- this.type = type;
37
- this.error = body;
38
- this.issues = Array.isArray(wire.issues) ? wire.issues : undefined;
39
- this.currentDigest = str(wire.current_digest);
40
- }
41
- /** @internal */
42
- static generate(status, body, headers) {
43
- const cls = STATUS_CLASSES.get(status) ?? (status >= 500 ? InternalServerError : BmaApiError);
44
- return new cls(status, body, undefined, headers);
45
- }
46
- }
47
- function str(value) {
48
- return typeof value === "string" && value !== "" ? value : undefined;
49
- }
50
- export class APIConnectionError extends BmaApiError {
51
- constructor({ message, cause } = {}) {
52
- super(undefined, undefined, message ?? "bma: connection error", undefined, { cause });
53
- }
54
- }
55
- export class APIConnectionTimeoutError extends APIConnectionError {
56
- constructor({ message } = {}) {
57
- super({ message: message ?? "bma: request timed out" });
58
- }
59
- }
60
- export class APIUserAbortError extends BmaApiError {
61
- constructor({ message } = {}) {
62
- super(undefined, undefined, message ?? "bma: request was aborted", undefined);
63
- }
64
- }
1
+ import { APIError } from '@anthropic-ai/sdk';
65
2
  /**
66
- * An `error` frame on an event stream. The stream ends after it; frames with
67
- * code `service_unavailable` are retried by the SDK before this is thrown.
3
+ * BMA's reason for an API error (`error.code` of the Anthropic error envelope,
4
+ * e.g. "idempotency_key_reused"), or undefined when `error` is not an API
5
+ * error or has no code. Branch on it rather than on the message. (The
6
+ * official `errorCode` property is `error.details.error_code`, which BMA does
7
+ * not set.)
68
8
  */
69
- export class EventStreamError extends BmaApiError {
70
- constructor(body) {
71
- const wire = (body ?? {});
72
- super(undefined, body, `bma: event stream error ${String(wire.code ?? "unknown")}: ${String(wire.error ?? "")}`, undefined);
73
- }
74
- }
75
- export class BadRequestError extends BmaApiError {
76
- }
77
- export class AuthenticationError extends BmaApiError {
78
- }
79
- export class PermissionDeniedError extends BmaApiError {
80
- }
81
- export class NotFoundError extends BmaApiError {
82
- }
83
- export class RequestTimeoutError extends BmaApiError {
84
- }
85
- export class ConflictError extends BmaApiError {
86
- }
87
- export class ContentTooLargeError extends BmaApiError {
88
- }
89
- export class UnprocessableEntityError extends BmaApiError {
90
- }
91
- export class RateLimitError extends BmaApiError {
92
- }
93
- export class InternalServerError extends BmaApiError {
94
- }
95
- export class ServiceUnavailableError extends InternalServerError {
9
+ export function errorCode(error) {
10
+ if (!(error instanceof APIError))
11
+ return undefined;
12
+ const code = error.error?.error?.code;
13
+ return typeof code === 'string' ? code : undefined;
96
14
  }
97
- const STATUS_CLASSES = new Map([
98
- [400, BadRequestError],
99
- [401, AuthenticationError],
100
- [403, PermissionDeniedError],
101
- [404, NotFoundError],
102
- [408, RequestTimeoutError],
103
- [409, ConflictError],
104
- [413, ContentTooLargeError],
105
- [422, UnprocessableEntityError],
106
- [429, RateLimitError],
107
- [503, ServiceUnavailableError],
108
- ]);
109
15
  //# sourceMappingURL=errors.js.map