@bctrl/sdk 1.0.4 → 1.0.6
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 +72 -72
- package/dist/account.d.ts +43 -0
- package/dist/account.js +100 -0
- package/dist/accountTypes.d.ts +126 -0
- package/dist/accountTypes.js +1 -0
- package/dist/ai.d.ts +23 -0
- package/dist/ai.js +51 -0
- package/dist/aiTypes.d.ts +97 -0
- package/dist/aiTypes.js +1 -0
- package/dist/bctrl.d.ts +35 -3
- package/dist/bctrl.js +74 -6
- package/dist/browserExtensionTypes.d.ts +45 -0
- package/dist/browserExtensionTypes.js +1 -0
- package/dist/browserExtensions.d.ts +14 -0
- package/dist/browserExtensions.js +53 -0
- package/dist/files.d.ts +6 -24
- package/dist/files.js +9 -56
- package/dist/help.d.ts +7 -0
- package/dist/help.js +9 -0
- package/dist/http.d.ts +12 -1
- package/dist/http.js +73 -10
- package/dist/index.d.ts +17 -6
- package/dist/index.js +15 -5
- package/dist/invocations.d.ts +83 -48
- package/dist/invocations.js +141 -102
- package/dist/node.d.ts +12 -0
- package/dist/node.js +11 -0
- package/dist/proxies.d.ts +21 -0
- package/dist/proxies.js +55 -0
- package/dist/proxyTypes.d.ts +119 -0
- package/dist/proxyTypes.js +1 -0
- package/dist/runs.d.ts +35 -31
- package/dist/runs.js +95 -38
- package/dist/runtimes.d.ts +41 -40
- package/dist/runtimes.js +115 -61
- package/dist/schemas.d.ts +7 -0
- package/dist/schemas.js +36 -0
- package/dist/spaces.d.ts +20 -32
- package/dist/spaces.js +48 -36
- package/dist/toolCallTypes.d.ts +41 -0
- package/dist/toolCallTypes.js +1 -0
- package/dist/toolCalls.d.ts +9 -0
- package/dist/toolCalls.js +16 -0
- package/dist/tools.d.ts +23 -0
- package/dist/tools.js +49 -0
- package/dist/toolsetTypes.d.ts +32 -0
- package/dist/toolsetTypes.js +1 -0
- package/dist/toolsets.d.ts +12 -0
- package/dist/toolsets.js +31 -0
- package/dist/types.d.ts +586 -167
- package/dist/utils.d.ts +2 -1
- package/dist/utils.js +28 -3
- package/dist/vault.d.ts +14 -0
- package/dist/vault.js +37 -0
- package/dist/vaultTypes.d.ts +73 -0
- package/dist/vaultTypes.js +1 -0
- package/package.json +46 -37
package/dist/bctrl.js
CHANGED
|
@@ -1,17 +1,37 @@
|
|
|
1
|
+
import { V1AccountClient, V1ApiKeysClient, V1AuthClient, V1SubaccountsClient, V1UsageClient, } from './account.js';
|
|
2
|
+
import { V1AiClient } from './ai.js';
|
|
3
|
+
import { V1BrowserExtensionsClient } from './browserExtensions.js';
|
|
1
4
|
import { isControllerBusy } from './errors.js';
|
|
2
5
|
import { V1FilesClient } from './files.js';
|
|
6
|
+
import { V1HelpClient } from './help.js';
|
|
3
7
|
import { V1HttpClient } from './http.js';
|
|
4
|
-
import {
|
|
8
|
+
import { V1ProxiesClient } from './proxies.js';
|
|
5
9
|
import { V1RunsClient } from './runs.js';
|
|
6
10
|
import { V1RuntimesClient } from './runtimes.js';
|
|
7
11
|
import { V1SpacesClient } from './spaces.js';
|
|
12
|
+
import { V1ToolCallsClient } from './toolCalls.js';
|
|
13
|
+
import { V1ToolsClient } from './tools.js';
|
|
14
|
+
import { V1ToolsetsClient } from './toolsets.js';
|
|
15
|
+
import { V1VaultClient } from './vault.js';
|
|
8
16
|
export class BctrlV1 {
|
|
9
17
|
http;
|
|
10
18
|
_spaces = null;
|
|
11
19
|
_runtimes = null;
|
|
12
20
|
_runs = null;
|
|
13
|
-
_invocations = null;
|
|
14
21
|
_files = null;
|
|
22
|
+
_help = null;
|
|
23
|
+
_tools = null;
|
|
24
|
+
_toolsets = null;
|
|
25
|
+
_toolCalls = null;
|
|
26
|
+
_vault = null;
|
|
27
|
+
_proxies = null;
|
|
28
|
+
_browserExtensions = null;
|
|
29
|
+
_ai = null;
|
|
30
|
+
_account = null;
|
|
31
|
+
_apiKeys = null;
|
|
32
|
+
_auth = null;
|
|
33
|
+
_subaccounts = null;
|
|
34
|
+
_usage = null;
|
|
15
35
|
static isControllerBusy(error) {
|
|
16
36
|
return isControllerBusy(error);
|
|
17
37
|
}
|
|
@@ -30,13 +50,61 @@ export class BctrlV1 {
|
|
|
30
50
|
this._runs ??= new V1RunsClient(this.http);
|
|
31
51
|
return this._runs;
|
|
32
52
|
}
|
|
33
|
-
get invocations() {
|
|
34
|
-
this._invocations ??= new V1InvocationsClient(this.http);
|
|
35
|
-
return this._invocations;
|
|
36
|
-
}
|
|
37
53
|
get files() {
|
|
38
54
|
this._files ??= new V1FilesClient(this.http);
|
|
39
55
|
return this._files;
|
|
40
56
|
}
|
|
57
|
+
get help() {
|
|
58
|
+
this._help ??= new V1HelpClient(this.http);
|
|
59
|
+
return this._help;
|
|
60
|
+
}
|
|
61
|
+
get tools() {
|
|
62
|
+
this._tools ??= new V1ToolsClient(this.http);
|
|
63
|
+
return this._tools;
|
|
64
|
+
}
|
|
65
|
+
get toolsets() {
|
|
66
|
+
this._toolsets ??= new V1ToolsetsClient(this.http);
|
|
67
|
+
return this._toolsets;
|
|
68
|
+
}
|
|
69
|
+
get toolCalls() {
|
|
70
|
+
this._toolCalls ??= new V1ToolCallsClient(this.http);
|
|
71
|
+
return this._toolCalls;
|
|
72
|
+
}
|
|
73
|
+
get vault() {
|
|
74
|
+
this._vault ??= new V1VaultClient(this.http);
|
|
75
|
+
return this._vault;
|
|
76
|
+
}
|
|
77
|
+
get proxies() {
|
|
78
|
+
this._proxies ??= new V1ProxiesClient(this.http);
|
|
79
|
+
return this._proxies;
|
|
80
|
+
}
|
|
81
|
+
get browserExtensions() {
|
|
82
|
+
this._browserExtensions ??= new V1BrowserExtensionsClient(this.http);
|
|
83
|
+
return this._browserExtensions;
|
|
84
|
+
}
|
|
85
|
+
get ai() {
|
|
86
|
+
this._ai ??= new V1AiClient(this.http);
|
|
87
|
+
return this._ai;
|
|
88
|
+
}
|
|
89
|
+
get account() {
|
|
90
|
+
this._account ??= new V1AccountClient(this.http);
|
|
91
|
+
return this._account;
|
|
92
|
+
}
|
|
93
|
+
get apiKeys() {
|
|
94
|
+
this._apiKeys ??= new V1ApiKeysClient(this.http);
|
|
95
|
+
return this._apiKeys;
|
|
96
|
+
}
|
|
97
|
+
get auth() {
|
|
98
|
+
this._auth ??= new V1AuthClient(this.http);
|
|
99
|
+
return this._auth;
|
|
100
|
+
}
|
|
101
|
+
get subaccounts() {
|
|
102
|
+
this._subaccounts ??= new V1SubaccountsClient(this.http);
|
|
103
|
+
return this._subaccounts;
|
|
104
|
+
}
|
|
105
|
+
get usage() {
|
|
106
|
+
this._usage ??= new V1UsageClient(this.http);
|
|
107
|
+
return this._usage;
|
|
108
|
+
}
|
|
41
109
|
}
|
|
42
110
|
export { BctrlV1 as Bctrl };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { V1PageQuery } from './types.js';
|
|
2
|
+
export type V1BrowserExtensionFormat = 'crx';
|
|
3
|
+
export type V1BrowserExtensionSource = 'upload' | 'url';
|
|
4
|
+
export interface V1BrowserExtension {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
version: string;
|
|
8
|
+
format: V1BrowserExtensionFormat;
|
|
9
|
+
subaccountId?: string;
|
|
10
|
+
sourceUrl?: string;
|
|
11
|
+
sizeBytes?: number;
|
|
12
|
+
contentHash?: string;
|
|
13
|
+
profileCount: number;
|
|
14
|
+
createdAt: string;
|
|
15
|
+
updatedAt: string;
|
|
16
|
+
}
|
|
17
|
+
export interface V1BrowserExtensionListQuery extends V1PageQuery {
|
|
18
|
+
subaccountId?: string;
|
|
19
|
+
q?: string;
|
|
20
|
+
format?: V1BrowserExtensionFormat;
|
|
21
|
+
source?: V1BrowserExtensionSource;
|
|
22
|
+
}
|
|
23
|
+
export interface V1BrowserExtensionUploadRequest {
|
|
24
|
+
/** Packed Chromium extension package. Only .crx is supported today. */
|
|
25
|
+
file: Blob;
|
|
26
|
+
/** Optional display name. Defaults to manifest.name. */
|
|
27
|
+
name?: string;
|
|
28
|
+
/** Parent/org keys may create inside a child subaccount. */
|
|
29
|
+
subaccountId?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface V1BrowserExtensionImportRequest {
|
|
32
|
+
/** Chrome Web Store detail URL. */
|
|
33
|
+
url: string;
|
|
34
|
+
/** Optional display name. Defaults to manifest.name. */
|
|
35
|
+
name?: string;
|
|
36
|
+
/** Parent/org keys may create inside a child subaccount. */
|
|
37
|
+
subaccountId?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface V1BrowserExtensionUpdateRequest {
|
|
40
|
+
name: string;
|
|
41
|
+
}
|
|
42
|
+
export interface V1BrowserExtensionDeleteResponse {
|
|
43
|
+
id: string;
|
|
44
|
+
deleted: true;
|
|
45
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { V1HttpClient } from './http.js';
|
|
2
|
+
import type { V1BrowserExtension, V1BrowserExtensionDeleteResponse, V1BrowserExtensionImportRequest, V1BrowserExtensionListQuery, V1BrowserExtensionUpdateRequest, V1BrowserExtensionUploadRequest } from './browserExtensionTypes.js';
|
|
3
|
+
import type { V1ListEnvelope } from './types.js';
|
|
4
|
+
export declare class V1BrowserExtensionsClient {
|
|
5
|
+
private readonly http;
|
|
6
|
+
constructor(http: V1HttpClient);
|
|
7
|
+
list(query?: V1BrowserExtensionListQuery): Promise<V1ListEnvelope<V1BrowserExtension>>;
|
|
8
|
+
iter(query?: V1BrowserExtensionListQuery): AsyncGenerator<V1BrowserExtension, void, undefined>;
|
|
9
|
+
get(extensionId: string): Promise<V1BrowserExtension>;
|
|
10
|
+
upload(request: V1BrowserExtensionUploadRequest): Promise<V1BrowserExtension>;
|
|
11
|
+
import(request: V1BrowserExtensionImportRequest): Promise<V1BrowserExtension>;
|
|
12
|
+
update(extensionId: string, request: V1BrowserExtensionUpdateRequest): Promise<V1BrowserExtension>;
|
|
13
|
+
delete(extensionId: string): Promise<V1BrowserExtensionDeleteResponse>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { iterateV1Pages } from './pagination.js';
|
|
2
|
+
function browserExtensionFileName(file) {
|
|
3
|
+
const name = file.name;
|
|
4
|
+
return typeof name === 'string' && name.trim() ? name : 'extension.crx';
|
|
5
|
+
}
|
|
6
|
+
export class V1BrowserExtensionsClient {
|
|
7
|
+
http;
|
|
8
|
+
constructor(http) {
|
|
9
|
+
this.http = http;
|
|
10
|
+
}
|
|
11
|
+
list(query = {}) {
|
|
12
|
+
return this.http.request('/browser-extensions', {
|
|
13
|
+
query,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
iter(query = {}) {
|
|
17
|
+
return iterateV1Pages(query, (pageQuery) => this.list(pageQuery));
|
|
18
|
+
}
|
|
19
|
+
get(extensionId) {
|
|
20
|
+
return this.http.request(`/browser-extensions/${encodeURIComponent(extensionId)}`);
|
|
21
|
+
}
|
|
22
|
+
upload(request) {
|
|
23
|
+
const form = new FormData();
|
|
24
|
+
form.set('file', request.file, browserExtensionFileName(request.file));
|
|
25
|
+
if (request.name) {
|
|
26
|
+
form.set('name', request.name);
|
|
27
|
+
}
|
|
28
|
+
if (request.subaccountId) {
|
|
29
|
+
form.set('subaccountId', request.subaccountId);
|
|
30
|
+
}
|
|
31
|
+
return this.http.request('/browser-extensions/upload', {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
body: form,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
import(request) {
|
|
37
|
+
return this.http.request('/browser-extensions/import', {
|
|
38
|
+
method: 'POST',
|
|
39
|
+
body: request,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
update(extensionId, request) {
|
|
43
|
+
return this.http.request(`/browser-extensions/${encodeURIComponent(extensionId)}`, {
|
|
44
|
+
method: 'PATCH',
|
|
45
|
+
body: request,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
delete(extensionId) {
|
|
49
|
+
return this.http.request(`/browser-extensions/${encodeURIComponent(extensionId)}`, {
|
|
50
|
+
method: 'DELETE',
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
package/dist/files.d.ts
CHANGED
|
@@ -1,31 +1,13 @@
|
|
|
1
1
|
import type { V1HttpClient } from './http.js';
|
|
2
|
-
import type { V1File, V1FileDeleteResponse, V1FilesListQuery, V1FileUpdateRequest, V1FileUploadRequest
|
|
3
|
-
export declare class V1FileResource {
|
|
4
|
-
private readonly http;
|
|
5
|
-
readonly data: V1File;
|
|
6
|
-
constructor(http: V1HttpClient, data: V1File);
|
|
7
|
-
get id(): string;
|
|
8
|
-
refresh(): Promise<V1FileResource>;
|
|
9
|
-
content(): Promise<Response>;
|
|
10
|
-
update(request: V1FileUpdateRequest): Promise<V1FileResource>;
|
|
11
|
-
delete(): Promise<V1FileDeleteResponse>;
|
|
12
|
-
}
|
|
2
|
+
import type { V1File, V1FileDeleteResponse, V1FilesListQuery, V1FilesListResponse, V1FileUpdateRequest, V1FileUploadRequest } from './types.js';
|
|
13
3
|
export declare class V1FilesClient {
|
|
14
4
|
private readonly http;
|
|
15
5
|
constructor(http: V1HttpClient);
|
|
16
|
-
list(query
|
|
17
|
-
iter(query
|
|
18
|
-
get(id: string): Promise<
|
|
19
|
-
update(id: string, request: V1FileUpdateRequest): Promise<
|
|
6
|
+
list(query?: V1FilesListQuery): Promise<V1FilesListResponse>;
|
|
7
|
+
iter(query?: V1FilesListQuery): AsyncGenerator<V1File, void, undefined>;
|
|
8
|
+
get(id: string): Promise<V1File>;
|
|
9
|
+
update(id: string, request: V1FileUpdateRequest): Promise<V1File>;
|
|
20
10
|
content(id: string): Promise<Response>;
|
|
21
11
|
delete(id: string): Promise<V1FileDeleteResponse>;
|
|
22
|
-
upload(request: V1FileUploadRequest): Promise<
|
|
23
|
-
}
|
|
24
|
-
export declare class V1RunFilesClient {
|
|
25
|
-
private readonly http;
|
|
26
|
-
private readonly runId;
|
|
27
|
-
constructor(http: V1HttpClient, runId: string);
|
|
28
|
-
list(query?: V1RunFilesListQuery): Promise<V1ListEnvelope<V1File>>;
|
|
29
|
-
iter(query?: V1RunFilesListQuery): AsyncGenerator<V1File, void, undefined>;
|
|
30
|
-
export(request: V1RunFilesExportRequest): Promise<V1FileResource>;
|
|
12
|
+
upload(request: V1FileUploadRequest): Promise<V1File>;
|
|
31
13
|
}
|
package/dist/files.js
CHANGED
|
@@ -1,48 +1,23 @@
|
|
|
1
1
|
import { iterateV1Pages } from './pagination.js';
|
|
2
|
-
export class V1FileResource {
|
|
3
|
-
http;
|
|
4
|
-
data;
|
|
5
|
-
constructor(http, data) {
|
|
6
|
-
this.http = http;
|
|
7
|
-
this.data = data;
|
|
8
|
-
}
|
|
9
|
-
get id() {
|
|
10
|
-
return this.data.id;
|
|
11
|
-
}
|
|
12
|
-
refresh() {
|
|
13
|
-
return new V1FilesClient(this.http).get(this.id);
|
|
14
|
-
}
|
|
15
|
-
async content() {
|
|
16
|
-
return new V1FilesClient(this.http).content(this.id);
|
|
17
|
-
}
|
|
18
|
-
async update(request) {
|
|
19
|
-
return new V1FilesClient(this.http).update(this.id, request);
|
|
20
|
-
}
|
|
21
|
-
delete() {
|
|
22
|
-
return new V1FilesClient(this.http).delete(this.id);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
2
|
export class V1FilesClient {
|
|
26
3
|
http;
|
|
27
4
|
constructor(http) {
|
|
28
5
|
this.http = http;
|
|
29
6
|
}
|
|
30
|
-
list(query) {
|
|
7
|
+
list(query = {}) {
|
|
31
8
|
return this.http.request('/files', { query });
|
|
32
9
|
}
|
|
33
|
-
iter(query) {
|
|
10
|
+
iter(query = {}) {
|
|
34
11
|
return iterateV1Pages(query, (pageQuery) => this.list(pageQuery));
|
|
35
12
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return new V1FileResource(this.http, file);
|
|
13
|
+
get(id) {
|
|
14
|
+
return this.http.request(`/files/${encodeURIComponent(id)}`);
|
|
39
15
|
}
|
|
40
|
-
|
|
41
|
-
|
|
16
|
+
update(id, request) {
|
|
17
|
+
return this.http.request(`/files/${encodeURIComponent(id)}`, {
|
|
42
18
|
method: 'PATCH',
|
|
43
19
|
body: request,
|
|
44
20
|
});
|
|
45
|
-
return new V1FileResource(this.http, file);
|
|
46
21
|
}
|
|
47
22
|
content(id) {
|
|
48
23
|
return this.http.raw(`/files/${encodeURIComponent(id)}/content`);
|
|
@@ -52,7 +27,7 @@ export class V1FilesClient {
|
|
|
52
27
|
method: 'DELETE',
|
|
53
28
|
});
|
|
54
29
|
}
|
|
55
|
-
|
|
30
|
+
upload(request) {
|
|
56
31
|
const form = new FormData();
|
|
57
32
|
if (request.name) {
|
|
58
33
|
form.set('file', request.file, request.name);
|
|
@@ -66,32 +41,10 @@ export class V1FilesClient {
|
|
|
66
41
|
form.set('path', request.path);
|
|
67
42
|
if (request.metadata)
|
|
68
43
|
form.set('metadata', JSON.stringify(request.metadata));
|
|
69
|
-
|
|
44
|
+
return this.http.request('/files', {
|
|
70
45
|
method: 'POST',
|
|
71
|
-
query: { spaceId: request.spaceId },
|
|
46
|
+
query: request.spaceId ? { spaceId: request.spaceId } : undefined,
|
|
72
47
|
body: form,
|
|
73
48
|
});
|
|
74
|
-
return new V1FileResource(this.http, file);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
export class V1RunFilesClient {
|
|
78
|
-
http;
|
|
79
|
-
runId;
|
|
80
|
-
constructor(http, runId) {
|
|
81
|
-
this.http = http;
|
|
82
|
-
this.runId = runId;
|
|
83
|
-
}
|
|
84
|
-
list(query = {}) {
|
|
85
|
-
return this.http.request(`/runs/${encodeURIComponent(this.runId)}/files`, { query });
|
|
86
|
-
}
|
|
87
|
-
iter(query = {}) {
|
|
88
|
-
return iterateV1Pages(query, (pageQuery) => this.list(pageQuery));
|
|
89
|
-
}
|
|
90
|
-
async export(request) {
|
|
91
|
-
const file = await this.http.request(`/runs/${encodeURIComponent(this.runId)}/files/export`, {
|
|
92
|
-
method: 'POST',
|
|
93
|
-
body: request,
|
|
94
|
-
});
|
|
95
|
-
return new V1FileResource(this.http, file);
|
|
96
49
|
}
|
|
97
50
|
}
|
package/dist/help.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { V1HttpClient } from './http.js';
|
|
2
|
+
import type { V1HelpRequest, V1HelpResponse } from './types.js';
|
|
3
|
+
export declare class V1HelpClient {
|
|
4
|
+
private readonly http;
|
|
5
|
+
constructor(http: V1HttpClient);
|
|
6
|
+
get(request?: V1HelpRequest): Promise<V1HelpResponse>;
|
|
7
|
+
}
|
package/dist/help.js
ADDED
package/dist/http.d.ts
CHANGED
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
export interface V1ClientOptions {
|
|
2
2
|
apiKey?: string;
|
|
3
3
|
baseUrl?: string;
|
|
4
|
+
timeoutMs?: number;
|
|
5
|
+
maxRetries?: number;
|
|
6
|
+
fetch?: typeof fetch;
|
|
4
7
|
}
|
|
5
8
|
export interface V1RequestOptions {
|
|
6
|
-
method?: 'GET' | 'POST' | 'PATCH' | 'DELETE';
|
|
9
|
+
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
7
10
|
query?: object;
|
|
8
11
|
body?: unknown;
|
|
9
12
|
headers?: Record<string, string>;
|
|
10
13
|
timeoutMs?: number;
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
}
|
|
16
|
+
export interface V1IdempotencyOptions {
|
|
17
|
+
idempotencyKey?: string;
|
|
11
18
|
}
|
|
12
19
|
export declare class V1HttpClient {
|
|
13
20
|
readonly baseUrl: string;
|
|
14
21
|
readonly apiKey: string;
|
|
22
|
+
private readonly timeoutMs?;
|
|
23
|
+
private readonly maxRetries;
|
|
24
|
+
private readonly fetchImpl;
|
|
15
25
|
constructor(options: V1ClientOptions);
|
|
16
26
|
request<T>(path: string, options?: V1RequestOptions): Promise<T>;
|
|
17
27
|
raw(path: string, options?: V1RequestOptions): Promise<Response>;
|
|
18
28
|
}
|
|
29
|
+
export declare function v1IdempotencyHeaders(options?: V1IdempotencyOptions): Record<string, string> | undefined;
|
package/dist/http.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BctrlNetworkError, createV1HttpError } from './errors.js';
|
|
2
|
-
import { BCTRL_PRODUCTION_ORIGIN, fetchWithTimeout, resolveApiKey, stripTrailingSlash, } from './utils.js';
|
|
2
|
+
import { BCTRL_PRODUCTION_ORIGIN, abortableSleep, fetchWithTimeout, resolveApiKey, stripTrailingSlash, } from './utils.js';
|
|
3
3
|
import { SDK_VERSION } from './version.js';
|
|
4
4
|
const API_PREFIX = '/v1';
|
|
5
5
|
function resolveV1ApiBaseUrl(baseUrl) {
|
|
@@ -43,9 +43,7 @@ function parseResponseBody(text) {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
function responseRequestId(response) {
|
|
46
|
-
return (response.headers.get('x-request-id') ??
|
|
47
|
-
response.headers.get('x-bctrl-request-id') ??
|
|
48
|
-
undefined);
|
|
46
|
+
return (response.headers.get('x-request-id') ?? response.headers.get('x-bctrl-request-id') ?? undefined);
|
|
49
47
|
}
|
|
50
48
|
function isRecord(value) {
|
|
51
49
|
return Boolean(value && typeof value === 'object' && !Array.isArray(value));
|
|
@@ -73,9 +71,15 @@ function isBodyInit(value) {
|
|
|
73
71
|
export class V1HttpClient {
|
|
74
72
|
baseUrl;
|
|
75
73
|
apiKey;
|
|
74
|
+
timeoutMs;
|
|
75
|
+
maxRetries;
|
|
76
|
+
fetchImpl;
|
|
76
77
|
constructor(options) {
|
|
77
78
|
this.baseUrl = resolveV1ApiBaseUrl(options.baseUrl);
|
|
78
79
|
this.apiKey = resolveV1ApiKey(options.apiKey);
|
|
80
|
+
this.timeoutMs = options.timeoutMs;
|
|
81
|
+
this.maxRetries = options.maxRetries ?? 2;
|
|
82
|
+
this.fetchImpl = options.fetch ?? fetch;
|
|
79
83
|
}
|
|
80
84
|
async request(path, options = {}) {
|
|
81
85
|
const response = await this.raw(path, options);
|
|
@@ -95,8 +99,9 @@ export class V1HttpClient {
|
|
|
95
99
|
'User-Agent': `@bctrl/sdk/${SDK_VERSION} v1`,
|
|
96
100
|
...options.headers,
|
|
97
101
|
};
|
|
102
|
+
const method = options.method ?? 'GET';
|
|
98
103
|
const init = {
|
|
99
|
-
method
|
|
104
|
+
method,
|
|
100
105
|
headers,
|
|
101
106
|
};
|
|
102
107
|
if (options.body !== undefined) {
|
|
@@ -109,12 +114,32 @@ export class V1HttpClient {
|
|
|
109
114
|
}
|
|
110
115
|
}
|
|
111
116
|
let response;
|
|
112
|
-
|
|
113
|
-
|
|
117
|
+
let lastNetworkError;
|
|
118
|
+
const maxAttempts = canRetryRequest(method, headers) ? Math.max(1, this.maxRetries + 1) : 1;
|
|
119
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
120
|
+
try {
|
|
121
|
+
response = await fetchWithTimeout(url.toString(), { ...init, signal: options.signal }, options.timeoutMs ?? this.timeoutMs, this.fetchImpl);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
lastNetworkError = error;
|
|
125
|
+
if (attempt < maxAttempts && isRetryableNetworkError(error)) {
|
|
126
|
+
await abortableSleep(retryDelayMs(attempt), options.signal);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (error instanceof Error) {
|
|
130
|
+
throw new BctrlNetworkError(error.message, { cause: error });
|
|
131
|
+
}
|
|
132
|
+
throw new BctrlNetworkError('Network request failed');
|
|
133
|
+
}
|
|
134
|
+
if (response.ok || !isRetryableStatus(response.status) || attempt >= maxAttempts) {
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
await response.body?.cancel().catch(() => undefined);
|
|
138
|
+
await abortableSleep(retryAfterMs(response) ?? retryDelayMs(attempt), options.signal);
|
|
114
139
|
}
|
|
115
|
-
|
|
116
|
-
if (
|
|
117
|
-
throw new BctrlNetworkError(
|
|
140
|
+
if (!response) {
|
|
141
|
+
if (lastNetworkError instanceof Error) {
|
|
142
|
+
throw new BctrlNetworkError(lastNetworkError.message, { cause: lastNetworkError });
|
|
118
143
|
}
|
|
119
144
|
throw new BctrlNetworkError('Network request failed');
|
|
120
145
|
}
|
|
@@ -133,3 +158,41 @@ export class V1HttpClient {
|
|
|
133
158
|
return response;
|
|
134
159
|
}
|
|
135
160
|
}
|
|
161
|
+
function isRetryableStatus(status) {
|
|
162
|
+
return status === 408 || status === 429 || status >= 500;
|
|
163
|
+
}
|
|
164
|
+
function canRetryRequest(method, headers) {
|
|
165
|
+
const normalized = method.toUpperCase();
|
|
166
|
+
if (normalized === 'GET' || normalized === 'HEAD' || normalized === 'OPTIONS') {
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
return hasHeader(headers, 'Idempotency-Key');
|
|
170
|
+
}
|
|
171
|
+
function hasHeader(headers, name) {
|
|
172
|
+
const expected = name.toLowerCase();
|
|
173
|
+
return Object.entries(headers).some(([key, value]) => key.toLowerCase() === expected && value.trim().length > 0);
|
|
174
|
+
}
|
|
175
|
+
function isRetryableNetworkError(error) {
|
|
176
|
+
if (!(error instanceof Error))
|
|
177
|
+
return false;
|
|
178
|
+
return error.name === 'AbortError' || error.name === 'TimeoutError';
|
|
179
|
+
}
|
|
180
|
+
function retryAfterMs(response) {
|
|
181
|
+
const raw = response.headers.get('retry-after');
|
|
182
|
+
if (!raw)
|
|
183
|
+
return undefined;
|
|
184
|
+
const seconds = Number(raw);
|
|
185
|
+
if (Number.isFinite(seconds))
|
|
186
|
+
return Math.max(0, seconds * 1000);
|
|
187
|
+
const date = Date.parse(raw);
|
|
188
|
+
if (Number.isFinite(date))
|
|
189
|
+
return Math.max(0, date - Date.now());
|
|
190
|
+
return undefined;
|
|
191
|
+
}
|
|
192
|
+
function retryDelayMs(attempt) {
|
|
193
|
+
return Math.min(2000, 250 * 2 ** Math.max(0, attempt - 1));
|
|
194
|
+
}
|
|
195
|
+
export function v1IdempotencyHeaders(options) {
|
|
196
|
+
const key = options?.idempotencyKey?.trim();
|
|
197
|
+
return key ? { 'Idempotency-Key': key } : undefined;
|
|
198
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
export { Bctrl, BctrlV1, type BctrlV1Options } from './bctrl.js';
|
|
2
|
+
export { V1AccountClient, V1ApiKeysClient, V1AuthClient, V1SubaccountsClient, V1SubaccountUsageClient, V1UsageClient, } from './account.js';
|
|
3
|
+
export { V1AiClient, V1AiCredentialsClient, V1AiModelsClient } from './ai.js';
|
|
4
|
+
export { V1BrowserExtensionsClient } from './browserExtensions.js';
|
|
2
5
|
export { BctrlError, BctrlApiError, BctrlAuthenticationError, BctrlConflictError, BctrlNetworkError, BctrlNotFoundError, BctrlNotReadyError, BctrlPermissionError, BctrlRateLimitError, BctrlUnsupportedError, BctrlValidationError, isControllerBusy, } from './errors.js';
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
8
|
-
export {
|
|
6
|
+
export { V1FilesClient } from './files.js';
|
|
7
|
+
export { V1HelpClient } from './help.js';
|
|
8
|
+
export { V1RuntimeBrowserUseInvocationsNamespaceClient, V1RuntimeInvocationsNamespaceClient, V1RuntimeStagehandInvocationsNamespaceClient, } from './invocations.js';
|
|
9
|
+
export type { BrowserUseAgentOptions, V1InvocationCreateAndWaitOptions, V1InvocationWaitOptions, V1RuntimeInvocationCreateInput, StagehandActOptions, StagehandAgentOptions, StagehandExtractOptions, StagehandObserveOptions, StagehandVariablePrimitive, StagehandVariableValue, StagehandVariables, } from './invocations.js';
|
|
10
|
+
export { V1RuntimeFilesNamespaceClient, V1RuntimeRunsNamespaceClient, V1RuntimeTargetsNamespaceClient, V1RuntimesClient, } from './runtimes.js';
|
|
11
|
+
export { V1ProxiesClient, V1ProxyPoolsClient } from './proxies.js';
|
|
12
|
+
export { V1RunActivityNamespaceClient, V1RunEventsNamespaceClient, V1RunFilesNamespaceClient, V1RunInvocationsNamespaceClient, V1RunsClient, } from './runs.js';
|
|
13
|
+
export { toOutputSchema, type JsonSchemaLike, type JsonSchemaObject } from './schemas.js';
|
|
14
|
+
export { V1SpaceEnvironmentNamespaceClient, V1SpaceRuntimesNamespaceClient, V1SpacesClient, } from './spaces.js';
|
|
15
|
+
export { V1ToolCallsClient } from './toolCalls.js';
|
|
16
|
+
export { passthroughJsonSchema, V1ToolsClient } from './tools.js';
|
|
17
|
+
export { V1ToolsetsClient } from './toolsets.js';
|
|
18
|
+
export { V1VaultClient } from './vault.js';
|
|
9
19
|
export type * from './types.js';
|
|
20
|
+
export type * from './browserExtensionTypes.js';
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
export { Bctrl, BctrlV1 } from './bctrl.js';
|
|
2
|
+
export { V1AccountClient, V1ApiKeysClient, V1AuthClient, V1SubaccountsClient, V1SubaccountUsageClient, V1UsageClient, } from './account.js';
|
|
3
|
+
export { V1AiClient, V1AiCredentialsClient, V1AiModelsClient } from './ai.js';
|
|
4
|
+
export { V1BrowserExtensionsClient } from './browserExtensions.js';
|
|
2
5
|
export { BctrlError, BctrlApiError, BctrlAuthenticationError, BctrlConflictError, BctrlNetworkError, BctrlNotFoundError, BctrlNotReadyError, BctrlPermissionError, BctrlRateLimitError, BctrlUnsupportedError, BctrlValidationError, isControllerBusy, } from './errors.js';
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
6
|
+
export { V1FilesClient } from './files.js';
|
|
7
|
+
export { V1HelpClient } from './help.js';
|
|
8
|
+
export { V1RuntimeBrowserUseInvocationsNamespaceClient, V1RuntimeInvocationsNamespaceClient, V1RuntimeStagehandInvocationsNamespaceClient, } from './invocations.js';
|
|
9
|
+
export { V1RuntimeFilesNamespaceClient, V1RuntimeRunsNamespaceClient, V1RuntimeTargetsNamespaceClient, V1RuntimesClient, } from './runtimes.js';
|
|
10
|
+
export { V1ProxiesClient, V1ProxyPoolsClient } from './proxies.js';
|
|
11
|
+
export { V1RunActivityNamespaceClient, V1RunEventsNamespaceClient, V1RunFilesNamespaceClient, V1RunInvocationsNamespaceClient, V1RunsClient, } from './runs.js';
|
|
12
|
+
export { toOutputSchema } from './schemas.js';
|
|
13
|
+
export { V1SpaceEnvironmentNamespaceClient, V1SpaceRuntimesNamespaceClient, V1SpacesClient, } from './spaces.js';
|
|
14
|
+
export { V1ToolCallsClient } from './toolCalls.js';
|
|
15
|
+
export { passthroughJsonSchema, V1ToolsClient } from './tools.js';
|
|
16
|
+
export { V1ToolsetsClient } from './toolsets.js';
|
|
17
|
+
export { V1VaultClient } from './vault.js';
|