@beeos-ai/bma-sdk 0.0.0-stage → 0.4.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.
- package/README.md +51 -2
- package/dist/facade-extensions.d.ts +71 -0
- package/dist/facade-extensions.js +134 -0
- package/dist/facade-extensions.js.map +1 -0
- package/dist/generated/facade-extensions.d.ts +507 -0
- package/dist/generated/facade-extensions.js +6 -0
- package/dist/generated/facade-extensions.js.map +1 -0
- package/dist/generated/rest.d.ts +18099 -0
- package/dist/generated/rest.js +6 -0
- package/dist/generated/rest.js.map +1 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.js +248 -0
- package/dist/index.js.map +1 -0
- package/package.json +40 -4
package/README.md
CHANGED
|
@@ -1,3 +1,52 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @beeos-ai/bma-sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
TypeScript client for the BMA REST API, generated from
|
|
4
|
+
[`contracts/bma/rest.openapi.yaml`](../contracts/bma/rest.openapi.yaml), plus
|
|
5
|
+
the BMA extensions to the Anthropic Managed Agents API.
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { BmaClient, unwrap } from "@beeos-ai/bma-sdk";
|
|
9
|
+
|
|
10
|
+
const bma = new BmaClient({ baseUrl: "https://host/api/v1", token: process.env.BMA_TOKEN! });
|
|
11
|
+
const path = { orgID: "org_...", projectID: "proj_...", agentID: "agt_..." };
|
|
12
|
+
|
|
13
|
+
const { session } = unwrap(
|
|
14
|
+
await bma.rest.POST("/orgs/{orgID}/projects/{projectID}/agents/{agentID}/sessions", {
|
|
15
|
+
params: { path },
|
|
16
|
+
body: { idempotency_key: "task-1", model_override: { model: "deepseek-flash", expires_with_session: true /* ... */ } },
|
|
17
|
+
}),
|
|
18
|
+
);
|
|
19
|
+
await bma.rest.POST("/orgs/{orgID}/projects/{projectID}/agents/{agentID}/inputs", {
|
|
20
|
+
params: { path, query: { session_id: session.id } },
|
|
21
|
+
body: { content_blocks: [{ type: "text", text: "Start." }] },
|
|
22
|
+
});
|
|
23
|
+
for await (const frame of bma.streamEvents({ ...path, sessionId: session.id })) {
|
|
24
|
+
console.log(frame.event, frame.sequence);
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`bma.rest` is a fully typed [openapi-fetch](https://openapi-ts.dev/openapi-fetch/)
|
|
29
|
+
client for every contract operation. `streamEvents` parses the SSE stream and
|
|
30
|
+
`downloadArtifact` verifies the artifact size and sha256 digest.
|
|
31
|
+
|
|
32
|
+
## BMA extensions to the Anthropic facade
|
|
33
|
+
|
|
34
|
+
Use the official Anthropic SDK for `/v1/agents`, `/v1/environments`,
|
|
35
|
+
`/v1/sessions` and events. The routes BMA adds live in a separate entry point:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { FacadeExtensionsClient, bmaSequence } from "@beeos-ai/bma-sdk/facade-extensions";
|
|
39
|
+
|
|
40
|
+
const ext = new FacadeExtensionsClient({ baseUrl: "https://host", apiKey: key, projectId: "proj_..." });
|
|
41
|
+
const ticket = await ext.getSessionDesktopStream(sessionId, { desktopSessionId, origin: location.origin });
|
|
42
|
+
await ext.uploadSessionFile(sessionId, new Blob([bytes]), "report.pdf");
|
|
43
|
+
const page = await ext.listSessionFiles(sessionId, { limit: 100 });
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
It also exports the extension field types `ModelConfigOverride`
|
|
47
|
+
(`agent.model.api_url/api_key/api_format`), `MCPServerBMAAuth`
|
|
48
|
+
(`mcp_servers[].bma_auth`), `IDEMPOTENCY_KEY_HEADER`, and `bmaSequence(event)`
|
|
49
|
+
for `bma_sequence` resume cursors.
|
|
50
|
+
|
|
51
|
+
The executor protocol (executor, harness and agent ends) is the separate
|
|
52
|
+
package [`@beeos-ai/bma-executor-sdk`](../executor/typescript).
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { type Client } from "openapi-fetch";
|
|
2
|
+
import type { components, paths } from "./generated/facade-extensions.js";
|
|
3
|
+
export type { paths as FacadeExtensionPaths };
|
|
4
|
+
export type DesktopStream = components["schemas"]["DesktopStream"];
|
|
5
|
+
export type SessionFile = components["schemas"]["SessionFile"];
|
|
6
|
+
export type SessionFilePage = components["schemas"]["SessionFilePage"];
|
|
7
|
+
/** BMA extension: a project file mounted into a session. */
|
|
8
|
+
export type FileResource = components["schemas"]["FileResource"];
|
|
9
|
+
export type FileResourcePage = components["schemas"]["FileResourcePage"];
|
|
10
|
+
export type DeletedSessionResource = components["schemas"]["DeletedSessionResource"];
|
|
11
|
+
/** BMA extension: one downloaded session file with its response metadata. */
|
|
12
|
+
export interface SessionFileContent {
|
|
13
|
+
content: Uint8Array;
|
|
14
|
+
contentType: string | null;
|
|
15
|
+
filename: string | null;
|
|
16
|
+
digest: string | null;
|
|
17
|
+
}
|
|
18
|
+
/** BMA extension: session `agent.model` object with a write-only credential override. */
|
|
19
|
+
export type ModelConfigOverride = components["schemas"]["ModelConfigOverride"];
|
|
20
|
+
/** BMA extension: `mcp_servers[].bma_auth`. */
|
|
21
|
+
export type MCPServerBMAAuth = components["schemas"]["MCPServerBMAAuth"];
|
|
22
|
+
/** BMA extension header forwarded on session create and send-events. */
|
|
23
|
+
export declare const IDEMPOTENCY_KEY_HEADER = "Idempotency-Key";
|
|
24
|
+
/**
|
|
25
|
+
* Returns the BMA extension `bma_sequence` of a facade session event, or
|
|
26
|
+
* undefined for preview and synthetic events. Send it as `Last-Event-ID` to
|
|
27
|
+
* resume `GET /v1/sessions/{id}/events/stream`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function bmaSequence(event: unknown): number | undefined;
|
|
30
|
+
export interface FacadeExtensionsOptions {
|
|
31
|
+
/** BMA organization API key (sent as x-api-key). */
|
|
32
|
+
apiKey: string;
|
|
33
|
+
/** Facade origin, without /v1 (for example https://api.bma.beeos.ai). */
|
|
34
|
+
baseUrl: string;
|
|
35
|
+
/** Project to operate in (x-bma-project-id); required for multi-project keys. */
|
|
36
|
+
projectId?: string;
|
|
37
|
+
fetch?: typeof globalThis.fetch;
|
|
38
|
+
}
|
|
39
|
+
/** An Anthropic-style error envelope returned by a facade extension route. */
|
|
40
|
+
export declare class FacadeApiError extends Error {
|
|
41
|
+
readonly status: number;
|
|
42
|
+
readonly type: string;
|
|
43
|
+
readonly code?: string;
|
|
44
|
+
constructor(status: number, body: unknown);
|
|
45
|
+
}
|
|
46
|
+
/** Client for the BMA extension routes of the Anthropic-compatible facade. */
|
|
47
|
+
export declare class FacadeExtensionsClient {
|
|
48
|
+
readonly raw: Client<paths>;
|
|
49
|
+
constructor(options: FacadeExtensionsOptions);
|
|
50
|
+
/** BMA extension: GET /v1/sessions/{session_id}/desktop/stream. */
|
|
51
|
+
getSessionDesktopStream(sessionId: string, options: {
|
|
52
|
+
desktopSessionId: string;
|
|
53
|
+
ttlSeconds?: number;
|
|
54
|
+
origin?: string;
|
|
55
|
+
}): Promise<DesktopStream>;
|
|
56
|
+
/** BMA extension: POST /v1/sessions/{session_id}/files (multipart, at most 8 MiB). */
|
|
57
|
+
uploadSessionFile(sessionId: string, file: Blob, filename: string): Promise<SessionFile>;
|
|
58
|
+
/** BMA extension: GET /v1/sessions/{session_id}/files. */
|
|
59
|
+
listSessionFiles(sessionId: string, options?: {
|
|
60
|
+
limit?: number;
|
|
61
|
+
page?: string;
|
|
62
|
+
}): Promise<SessionFilePage>;
|
|
63
|
+
/** BMA extension: GET /v1/sessions/{session_id}/files/{file_id}/content. */
|
|
64
|
+
downloadSessionFile(sessionId: string, fileId: string): Promise<SessionFileContent>;
|
|
65
|
+
/** BMA extension: POST /v1/sessions/{session_id}/resources. */
|
|
66
|
+
addSessionResource(sessionId: string, fileId: string, mountPath?: string): Promise<FileResource>;
|
|
67
|
+
/** BMA extension: GET /v1/sessions/{session_id}/resources. */
|
|
68
|
+
listSessionResources(sessionId: string): Promise<FileResourcePage>;
|
|
69
|
+
/** BMA extension: DELETE /v1/sessions/{session_id}/resources/{resource_id}. */
|
|
70
|
+
deleteSessionResource(sessionId: string, resourceId: string): Promise<DeletedSessionResource>;
|
|
71
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// BMA extensions to the Anthropic Managed Agents API.
|
|
2
|
+
//
|
|
3
|
+
// The standard facade routes (/v1/agents, /v1/environments, /v1/sessions,
|
|
4
|
+
// events, events/stream, /v1/files, /v1/memory_stores) are served by the
|
|
5
|
+
// official Anthropic SDKs pointed at a BMA deployment. Everything in this module is a
|
|
6
|
+
// BMA extension that is NOT part of the Anthropic contract. Types come from
|
|
7
|
+
// src/generated/facade-extensions.ts, generated from
|
|
8
|
+
// contracts/bma/facade-extensions.openapi.yaml.
|
|
9
|
+
import createClient from "openapi-fetch";
|
|
10
|
+
function dispositionFilename(value) {
|
|
11
|
+
if (!value)
|
|
12
|
+
return null;
|
|
13
|
+
const match = /filename\*?=(?:UTF-8'')?"?([^";]+)"?/i.exec(value);
|
|
14
|
+
return match?.[1] ? decodeURIComponent(match[1]) : null;
|
|
15
|
+
}
|
|
16
|
+
/** BMA extension header forwarded on session create and send-events. */
|
|
17
|
+
export const IDEMPOTENCY_KEY_HEADER = "Idempotency-Key";
|
|
18
|
+
/**
|
|
19
|
+
* Returns the BMA extension `bma_sequence` of a facade session event, or
|
|
20
|
+
* undefined for preview and synthetic events. Send it as `Last-Event-ID` to
|
|
21
|
+
* resume `GET /v1/sessions/{id}/events/stream`.
|
|
22
|
+
*/
|
|
23
|
+
export function bmaSequence(event) {
|
|
24
|
+
const value = event?.bma_sequence;
|
|
25
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : undefined;
|
|
26
|
+
}
|
|
27
|
+
/** An Anthropic-style error envelope returned by a facade extension route. */
|
|
28
|
+
export class FacadeApiError extends Error {
|
|
29
|
+
status;
|
|
30
|
+
type;
|
|
31
|
+
code;
|
|
32
|
+
constructor(status, body) {
|
|
33
|
+
const error = (body?.error ?? {});
|
|
34
|
+
const type = typeof error.type === "string" ? error.type : "api_error";
|
|
35
|
+
const message = typeof error.message === "string" && error.message !== "" ? error.message : `HTTP ${status}`;
|
|
36
|
+
super(`bma facade: HTTP ${status} ${type}: ${message}`);
|
|
37
|
+
this.name = "FacadeApiError";
|
|
38
|
+
this.status = status;
|
|
39
|
+
this.type = type;
|
|
40
|
+
this.code = typeof error.code === "string" ? error.code : undefined;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function check(result) {
|
|
44
|
+
if (result.response.ok)
|
|
45
|
+
return result.data;
|
|
46
|
+
throw new FacadeApiError(result.response.status, result.error);
|
|
47
|
+
}
|
|
48
|
+
/** Client for the BMA extension routes of the Anthropic-compatible facade. */
|
|
49
|
+
export class FacadeExtensionsClient {
|
|
50
|
+
raw;
|
|
51
|
+
constructor(options) {
|
|
52
|
+
const apiKey = options.apiKey?.trim();
|
|
53
|
+
if (!apiKey)
|
|
54
|
+
throw new Error("bma facade: apiKey is required");
|
|
55
|
+
const baseUrl = options.baseUrl?.trim().replace(/\/+$/, "");
|
|
56
|
+
if (!baseUrl)
|
|
57
|
+
throw new Error("bma facade: baseUrl is required");
|
|
58
|
+
if (baseUrl.endsWith("/v1"))
|
|
59
|
+
throw new Error("bma facade: baseUrl must be the origin without /v1");
|
|
60
|
+
const headers = { "x-api-key": apiKey };
|
|
61
|
+
if (options.projectId)
|
|
62
|
+
headers["x-bma-project-id"] = options.projectId;
|
|
63
|
+
this.raw = createClient({ baseUrl, headers, fetch: options.fetch ?? globalThis.fetch });
|
|
64
|
+
}
|
|
65
|
+
/** BMA extension: GET /v1/sessions/{session_id}/desktop/stream. */
|
|
66
|
+
async getSessionDesktopStream(sessionId, options) {
|
|
67
|
+
return check(await this.raw.GET("/v1/sessions/{session_id}/desktop/stream", {
|
|
68
|
+
params: {
|
|
69
|
+
path: { session_id: sessionId },
|
|
70
|
+
query: {
|
|
71
|
+
desktop_session_id: options.desktopSessionId,
|
|
72
|
+
ttl_seconds: options.ttlSeconds,
|
|
73
|
+
origin: options.origin,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
/** BMA extension: POST /v1/sessions/{session_id}/files (multipart, at most 8 MiB). */
|
|
79
|
+
async uploadSessionFile(sessionId, file, filename) {
|
|
80
|
+
const form = new FormData();
|
|
81
|
+
form.append("file", file, filename);
|
|
82
|
+
return check(await this.raw.POST("/v1/sessions/{session_id}/files", {
|
|
83
|
+
params: { path: { session_id: sessionId } },
|
|
84
|
+
// The generated body type is the schema object; the wire body is FormData.
|
|
85
|
+
body: form,
|
|
86
|
+
bodySerializer: (body) => body,
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
/** BMA extension: GET /v1/sessions/{session_id}/files. */
|
|
90
|
+
async listSessionFiles(sessionId, options = {}) {
|
|
91
|
+
return check(await this.raw.GET("/v1/sessions/{session_id}/files", {
|
|
92
|
+
params: { path: { session_id: sessionId }, query: { limit: options.limit, page: options.page } },
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
/** BMA extension: GET /v1/sessions/{session_id}/files/{file_id}/content. */
|
|
96
|
+
async downloadSessionFile(sessionId, fileId) {
|
|
97
|
+
const result = await this.raw.GET("/v1/sessions/{session_id}/files/{file_id}/content", {
|
|
98
|
+
params: { path: { session_id: sessionId, file_id: fileId } },
|
|
99
|
+
parseAs: "arrayBuffer",
|
|
100
|
+
});
|
|
101
|
+
if (!result.response.ok)
|
|
102
|
+
throw new FacadeApiError(result.response.status, result.error);
|
|
103
|
+
return {
|
|
104
|
+
content: new Uint8Array(result.data),
|
|
105
|
+
contentType: result.response.headers.get("content-type"),
|
|
106
|
+
filename: dispositionFilename(result.response.headers.get("content-disposition")),
|
|
107
|
+
digest: result.response.headers.get("x-bma-file-digest"),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/** BMA extension: POST /v1/sessions/{session_id}/resources. */
|
|
111
|
+
async addSessionResource(sessionId, fileId, mountPath) {
|
|
112
|
+
return check(await this.raw.POST("/v1/sessions/{session_id}/resources", {
|
|
113
|
+
params: { path: { session_id: sessionId } },
|
|
114
|
+
body: {
|
|
115
|
+
type: "file",
|
|
116
|
+
file_id: fileId,
|
|
117
|
+
...(mountPath === undefined ? {} : { mount_path: mountPath }),
|
|
118
|
+
},
|
|
119
|
+
}));
|
|
120
|
+
}
|
|
121
|
+
/** BMA extension: GET /v1/sessions/{session_id}/resources. */
|
|
122
|
+
async listSessionResources(sessionId) {
|
|
123
|
+
return check(await this.raw.GET("/v1/sessions/{session_id}/resources", {
|
|
124
|
+
params: { path: { session_id: sessionId } },
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
/** BMA extension: DELETE /v1/sessions/{session_id}/resources/{resource_id}. */
|
|
128
|
+
async deleteSessionResource(sessionId, resourceId) {
|
|
129
|
+
return check(await this.raw.DELETE("/v1/sessions/{session_id}/resources/{resource_id}", {
|
|
130
|
+
params: { path: { session_id: sessionId, resource_id: resourceId } },
|
|
131
|
+
}));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=facade-extensions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facade-extensions.js","sourceRoot":"","sources":["../src/facade-extensions.ts"],"names":[],"mappings":"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"}
|