@bctrl/sdk 1.0.5 → 1.0.7

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 CHANGED
@@ -1,71 +1,72 @@
1
- # @bctrl/sdk
2
-
3
- TypeScript SDK for BCTRL v1 spaces, browser runtimes, invocations, runs, and files.
4
-
5
- ## Install
6
-
7
- ```bash
8
- npm install @bctrl/sdk
9
- ```
10
-
11
- Node 18+ is required.
12
-
13
- ## Quick start
14
-
15
- ```ts
16
- import { Bctrl } from '@bctrl/sdk';
17
-
18
- const bctrl = new Bctrl({
19
- apiKey: process.env.BCTRL_API_KEY!,
20
- });
21
-
22
- const space = await bctrl.spaces.create({
23
- name: 'my-task',
24
- });
25
-
26
- const createdRuntime = await space.runtimes.create({
27
- type: 'browser',
28
- name: 'browser-task',
29
- config: {
30
- profile: false,
31
- },
32
- });
33
- const started = await createdRuntime.start();
34
- console.log(started.run.id, started.browser.cdpUrl);
35
-
36
- const invocation = await started.runtime.invocations.create({
37
- provider: 'stagehand',
38
- method: 'act',
39
- input: { instruction: 'Open https://example.com' },
40
- });
41
-
42
- const result = await invocation.wait({ timeoutMs: 60_000 });
43
- console.log(result.data.status);
44
- ```
45
-
46
- The public SDK targets `https://api.bctrl.ai/v1`. For local development, pass a
47
- local origin or v1 base URL:
48
-
49
- ```ts
50
- const bctrl = new Bctrl({
51
- apiKey: process.env.BCTRL_API_KEY!,
52
- baseUrl: 'http://localhost:8787',
53
- });
54
- ```
55
-
56
- `baseUrl` may include or omit `/v1`; the client normalizes either form.
57
-
58
- ## Entry points
59
-
60
- - `@bctrl/sdk`: v1 client, resources, errors, and public types
61
-
62
- ## Documentation
63
-
64
- - SDK reference: https://platform.bctrl.ai/api-reference/sdk/overview
65
- - Product site: https://bctrl.ai
66
-
67
- ## Telemetry
68
-
69
- The published SDK does not include vendor-owned telemetry or usage analytics.
70
-
71
- If you want observability around SDK calls, instrument your application directly with your own logging or error tracking.
1
+ # @bctrl/sdk
2
+
3
+ TypeScript SDK for BCTRL v1 spaces, browser runtimes, invocations, runs, and files.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @bctrl/sdk
9
+ ```
10
+
11
+ Node 18+ is required.
12
+
13
+ ## Quick start
14
+
15
+ ```ts
16
+ import { Bctrl } from '@bctrl/sdk';
17
+ import { z } from 'zod';
18
+
19
+ const bctrl = new Bctrl({
20
+ apiKey: process.env.BCTRL_API_KEY!,
21
+ });
22
+
23
+ const runtime = await bctrl.runtimes.create({
24
+ type: 'browser',
25
+ name: 'browser-task',
26
+ });
27
+ const started = await bctrl.runtimes.start(runtime.id);
28
+ console.log(started.runId, started.connectUrl);
29
+
30
+ const invocation = await bctrl.runtimes.invocations.createAndWait(
31
+ started.runtimeId,
32
+ {
33
+ action: 'extract',
34
+ instruction: 'Extract the page title.',
35
+ schema: z.object({
36
+ title: z.string(),
37
+ }),
38
+ },
39
+ { timeoutMs: 60_000 }
40
+ );
41
+
42
+ console.log(invocation.status, invocation.output);
43
+
44
+ await bctrl.runtimes.stop(started.runtimeId);
45
+ ```
46
+
47
+ The public SDK targets `https://api.bctrl.ai/v1`. For local development, pass a
48
+ local origin or v1 base URL:
49
+
50
+ ```ts
51
+ const bctrl = new Bctrl({
52
+ apiKey: process.env.BCTRL_API_KEY!,
53
+ baseUrl: 'http://localhost:8787',
54
+ });
55
+ ```
56
+
57
+ `baseUrl` may include or omit `/v1`; the client normalizes either form.
58
+
59
+ ## Entry points
60
+
61
+ - `@bctrl/sdk`: v1 client, resources, errors, and public types
62
+
63
+ ## Documentation
64
+
65
+ - SDK reference: https://platform.bctrl.ai/api-reference/sdk/overview
66
+ - Product site: https://bctrl.ai
67
+
68
+ ## Telemetry
69
+
70
+ The published SDK does not include vendor-owned telemetry or usage analytics.
71
+
72
+ If you want observability around SDK calls, instrument your application directly with your own logging or error tracking.
@@ -1,126 +1,20 @@
1
- import type { JsonObject, V1ListEnvelope, V1PageQuery } from './types.js';
2
- export type V1AuthScope = 'organization' | 'subaccount';
3
- export type V1Plan = 'free' | 'developer' | 'business' | 'enterprise';
4
- export interface V1AuthWhoamiResponse {
5
- email: string | null;
6
- scope: V1AuthScope;
7
- organizationId: string;
8
- subaccountId: string | null;
9
- defaultSpaceId: string;
10
- plan: V1Plan;
11
- keyId: string;
12
- }
13
- export interface V1ApiKey {
14
- id: string;
15
- keyKind: 'organization' | 'subaccount';
16
- subaccountId: string | null;
17
- name: string | null;
18
- keyPrefix: string;
19
- scopes: '*'[];
20
- expiresAt: string | null;
21
- createdAt: string;
22
- updatedAt: string;
23
- lastUsedAt: string | null;
24
- usageCount: number;
25
- }
26
- export interface V1ApiKeyListQuery extends V1PageQuery {
27
- subaccountId?: string;
28
- keyKind?: V1ApiKey['keyKind'];
29
- }
30
- export interface V1ApiKeyCreateRequest {
31
- name?: string;
32
- subaccountId?: string;
33
- scopes?: '*'[];
34
- expiresAt?: string | null;
35
- }
36
- export interface V1ApiKeyCreateResponse {
37
- data: V1ApiKey;
38
- secret: string;
39
- }
40
- export interface V1ApiKeyDeleteResponse {
41
- id: string;
42
- deleted: true;
43
- }
44
- export interface V1AccountUsage {
45
- organizationId: string;
46
- isBlocked: boolean;
47
- blockedReasons: string[];
48
- cycle: {
49
- startedAt: string | null;
50
- endsAt: string | null;
51
- };
52
- credits: {
53
- monthlyLimit: number;
54
- monthlyUsed: number;
55
- monthlyRemaining: number;
56
- purchasedRemaining: number;
57
- available: number;
58
- outstandingDebt: number;
59
- effectiveBalance: number;
60
- breakdown: JsonObject;
61
- };
62
- computedAt: string;
63
- }
64
- export interface V1SubaccountLimits {
65
- monthlyCredits?: number | null;
66
- maxConcurrentRuntimes?: number | null;
67
- maxRuntimeMinutes?: number | null;
68
- }
69
- export interface V1Subaccount {
70
- id: string;
71
- name: string;
72
- status: 'active' | 'archived';
73
- externalId?: string | null;
74
- metadata?: JsonObject | null;
75
- archivedAt?: string | null;
76
- defaultSpaceId: string;
77
- limits: V1SubaccountLimits;
78
- usage?: V1SubaccountUsage;
79
- createdAt: string;
80
- updatedAt: string;
81
- }
82
- export interface V1SubaccountListQuery extends V1PageQuery {
83
- status?: V1Subaccount['status'];
84
- externalId?: string;
85
- }
86
- export interface V1SubaccountCreateRequest {
87
- name: string;
88
- externalId?: string;
89
- metadata?: JsonObject;
90
- limits?: V1SubaccountLimits;
91
- }
92
- export interface V1SubaccountUpdateRequest {
93
- name?: string;
94
- externalId?: string | null;
95
- metadata?: JsonObject | null;
96
- limits?: V1SubaccountLimits;
97
- }
98
- export interface V1SubaccountGetQuery {
99
- include?: 'usage' | 'usage'[];
100
- }
101
- export interface V1SubaccountArchiveResponse {
102
- id: string;
103
- archived: true;
104
- }
105
- export interface V1SubaccountUsage {
106
- subaccountId: string;
107
- isBlocked: boolean;
108
- blockedReasons: string[];
109
- cycle: {
110
- startedAt: string | null;
111
- endsAt: string | null;
112
- };
113
- credits: {
114
- monthlyLimit: number;
115
- monthlyUsed: number;
116
- monthlyRemaining: number;
117
- purchasedRemaining: number;
118
- available: number;
119
- breakdown: JsonObject;
120
- };
121
- computedAt: string;
122
- }
123
- export type V1SubaccountUsageListQuery = V1PageQuery & {
124
- subaccountId?: string;
125
- };
126
- export type V1SubaccountUsageListResponse = V1ListEnvelope<V1SubaccountUsage>;
1
+ import type { OpenApiQuery, OpenApiSchemas } from './openapi.js';
2
+ export type V1AuthScope = OpenApiSchemas['AuthWhoamiResponse']['scope'];
3
+ export type V1Plan = OpenApiSchemas['AuthWhoamiResponse']['plan'];
4
+ export type V1AuthWhoamiResponse = OpenApiSchemas['AuthWhoamiResponse'];
5
+ export type V1ApiKey = OpenApiSchemas['ApiKey'];
6
+ export type V1ApiKeyListQuery = OpenApiQuery<'api-keys.list'>;
7
+ export type V1ApiKeyCreateRequest = OpenApiSchemas['ApiKeyCreateRequest'];
8
+ export type V1ApiKeyCreateResponse = OpenApiSchemas['ApiKeyCreateResponse'];
9
+ export type V1ApiKeyDeleteResponse = OpenApiSchemas['ApiKeyDeleteResponse'];
10
+ export type V1AccountUsage = OpenApiSchemas['AccountUsage'];
11
+ export type V1SubaccountLimits = OpenApiSchemas['SubaccountLimits'];
12
+ export type V1Subaccount = OpenApiSchemas['Subaccount'];
13
+ export type V1SubaccountListQuery = OpenApiQuery<'subaccounts.list'>;
14
+ export type V1SubaccountCreateRequest = OpenApiSchemas['SubaccountCreateRequest'];
15
+ export type V1SubaccountUpdateRequest = OpenApiSchemas['SubaccountUpdateRequest'];
16
+ export type V1SubaccountGetQuery = OpenApiQuery<'subaccounts.get'>;
17
+ export type V1SubaccountArchiveResponse = OpenApiSchemas['SubaccountArchiveResponse'];
18
+ export type V1SubaccountUsage = OpenApiSchemas['SubaccountUsage'];
19
+ export type V1SubaccountUsageListQuery = OpenApiQuery<'subaccounts.usage.list'>;
20
+ export type V1SubaccountUsageListResponse = OpenApiSchemas['SubaccountUsageListResponse'];
package/dist/ai.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ import type { V1HttpClient } from './http.js';
2
+ import type { V1AiCredential, V1AiCredentialCreateRequest, V1AiCredentialDeleteResponse, V1AiCredentialListQuery, V1AiCredentialTestResponse, V1AiCredentialUpdateRequest, V1AiModelListQuery, V1AiModelListResponse, V1ListEnvelope } from './types.js';
3
+ export declare class V1AiModelsClient {
4
+ private readonly http;
5
+ constructor(http: V1HttpClient);
6
+ list(query?: V1AiModelListQuery): Promise<V1AiModelListResponse>;
7
+ }
8
+ export declare class V1AiCredentialsClient {
9
+ private readonly http;
10
+ constructor(http: V1HttpClient);
11
+ list(query?: V1AiCredentialListQuery): Promise<V1ListEnvelope<V1AiCredential>>;
12
+ iter(query?: V1AiCredentialListQuery): AsyncGenerator<V1AiCredential, void, undefined>;
13
+ create(request: V1AiCredentialCreateRequest): Promise<V1AiCredential>;
14
+ get(credentialId: string): Promise<V1AiCredential>;
15
+ update(credentialId: string, request: V1AiCredentialUpdateRequest): Promise<V1AiCredential>;
16
+ delete(credentialId: string): Promise<V1AiCredentialDeleteResponse>;
17
+ test(credentialId: string): Promise<V1AiCredentialTestResponse>;
18
+ }
19
+ export declare class V1AiClient {
20
+ readonly models: V1AiModelsClient;
21
+ readonly credentials: V1AiCredentialsClient;
22
+ constructor(http: V1HttpClient);
23
+ }
package/dist/ai.js ADDED
@@ -0,0 +1,51 @@
1
+ import { iterateV1Pages } from './pagination.js';
2
+ export class V1AiModelsClient {
3
+ http;
4
+ constructor(http) {
5
+ this.http = http;
6
+ }
7
+ list(query = {}) {
8
+ return this.http.request('/ai/models', { query });
9
+ }
10
+ }
11
+ export class V1AiCredentialsClient {
12
+ http;
13
+ constructor(http) {
14
+ this.http = http;
15
+ }
16
+ list(query = {}) {
17
+ return this.http.request('/ai/credentials', { query });
18
+ }
19
+ iter(query = {}) {
20
+ return iterateV1Pages(query, (pageQuery) => this.list(pageQuery));
21
+ }
22
+ create(request) {
23
+ return this.http.request('/ai/credentials', {
24
+ method: 'POST',
25
+ body: request,
26
+ });
27
+ }
28
+ get(credentialId) {
29
+ return this.http.request(`/ai/credentials/${encodeURIComponent(credentialId)}`);
30
+ }
31
+ update(credentialId, request) {
32
+ return this.http.request(`/ai/credentials/${encodeURIComponent(credentialId)}`, {
33
+ method: 'PATCH',
34
+ body: request,
35
+ });
36
+ }
37
+ delete(credentialId) {
38
+ return this.http.request(`/ai/credentials/${encodeURIComponent(credentialId)}`, { method: 'DELETE' });
39
+ }
40
+ test(credentialId) {
41
+ return this.http.request(`/ai/credentials/${encodeURIComponent(credentialId)}/test`, { method: 'POST' });
42
+ }
43
+ }
44
+ export class V1AiClient {
45
+ models;
46
+ credentials;
47
+ constructor(http) {
48
+ this.models = new V1AiModelsClient(http);
49
+ this.credentials = new V1AiCredentialsClient(http);
50
+ }
51
+ }
@@ -0,0 +1,19 @@
1
+ import type { OpenApiQuery, OpenApiSchemas } from './openapi.js';
2
+ export type V1AiCredentialProvider = OpenApiSchemas['AiCredential']['provider'];
3
+ export type V1AiModelStatus = OpenApiSchemas['AiModel']['status'];
4
+ export type V1AiModelEngine = OpenApiSchemas['AiModel']['engines'][number];
5
+ export type V1AiModel = OpenApiSchemas['AiModel'];
6
+ export type V1AiModelListQuery = OpenApiQuery<'ai.models.list'>;
7
+ export type V1AiModelListResponse = OpenApiSchemas['AiModelListResponse'];
8
+ export type V1AiCredentialStatus = OpenApiSchemas['AiCredential']['status'];
9
+ export type V1AiCredential = OpenApiSchemas['AiCredential'];
10
+ export type V1AiCredentialListQuery = OpenApiQuery<'ai.credentials.list'>;
11
+ export type V1AiCredentialCreateRequest = OpenApiSchemas['AiCredentialCreateRequest'];
12
+ export type V1AiCredentialUpdateRequest = OpenApiSchemas['AiCredentialUpdateRequest'];
13
+ export type V1AiCredentialDeleteResponse = OpenApiSchemas['AiCredentialDeleteResponse'];
14
+ export type V1AiCredentialTestResponse = OpenApiSchemas['AiCredentialTestResponse'];
15
+ export type V1AiModelSelectionAuth = OpenApiSchemas['AiModelSelectionAuth'];
16
+ export type V1AiModelSelectionObject = OpenApiSchemas['AiModelSelection'];
17
+ export type V1AiModelSelection = string | V1AiModelSelectionObject;
18
+ export type V1AiStoredModelSelectionAuth = OpenApiSchemas['AiStoredModelSelectionAuth'];
19
+ export type V1AiStoredModelSelection = string | OpenApiSchemas['AiStoredModelSelection'];
package/dist/bctrl.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { V1AccountClient, V1ApiKeysClient, V1AuthClient, V1SubaccountsClient, V1UsageClient } from './account.js';
2
- import { V1AiProvidersClient } from './aiProviders.js';
2
+ import { V1AiClient } from './ai.js';
3
3
  import { V1BrowserExtensionsClient } from './browserExtensions.js';
4
4
  import { V1FilesClient } from './files.js';
5
5
  import { V1HelpClient } from './help.js';
@@ -26,7 +26,7 @@ export declare class BctrlV1 {
26
26
  private _vault;
27
27
  private _proxies;
28
28
  private _browserExtensions;
29
- private _aiProviders;
29
+ private _ai;
30
30
  private _account;
31
31
  private _apiKeys;
32
32
  private _auth;
@@ -45,7 +45,7 @@ export declare class BctrlV1 {
45
45
  get vault(): V1VaultClient;
46
46
  get proxies(): V1ProxiesClient;
47
47
  get browserExtensions(): V1BrowserExtensionsClient;
48
- get aiProviders(): V1AiProvidersClient;
48
+ get ai(): V1AiClient;
49
49
  get account(): V1AccountClient;
50
50
  get apiKeys(): V1ApiKeysClient;
51
51
  get auth(): V1AuthClient;
package/dist/bctrl.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { V1AccountClient, V1ApiKeysClient, V1AuthClient, V1SubaccountsClient, V1UsageClient, } from './account.js';
2
- import { V1AiProvidersClient } from './aiProviders.js';
2
+ import { V1AiClient } from './ai.js';
3
3
  import { V1BrowserExtensionsClient } from './browserExtensions.js';
4
4
  import { isControllerBusy } from './errors.js';
5
5
  import { V1FilesClient } from './files.js';
@@ -26,7 +26,7 @@ export class BctrlV1 {
26
26
  _vault = null;
27
27
  _proxies = null;
28
28
  _browserExtensions = null;
29
- _aiProviders = null;
29
+ _ai = null;
30
30
  _account = null;
31
31
  _apiKeys = null;
32
32
  _auth = null;
@@ -82,9 +82,9 @@ export class BctrlV1 {
82
82
  this._browserExtensions ??= new V1BrowserExtensionsClient(this.http);
83
83
  return this._browserExtensions;
84
84
  }
85
- get aiProviders() {
86
- this._aiProviders ??= new V1AiProvidersClient(this.http);
87
- return this._aiProviders;
85
+ get ai() {
86
+ this._ai ??= new V1AiClient(this.http);
87
+ return this._ai;
88
88
  }
89
89
  get account() {
90
90
  this._account ??= new V1AccountClient(this.http);
@@ -1,25 +1,8 @@
1
- import type { V1PageQuery } from './types.js';
2
- export type V1BrowserExtensionFormat = 'crx';
1
+ import type { OpenApiQuery, OpenApiSchemas } from './openapi.js';
2
+ export type V1BrowserExtensionFormat = OpenApiSchemas['BrowserExtension']['format'];
3
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
- }
4
+ export type V1BrowserExtension = OpenApiSchemas['BrowserExtension'];
5
+ export type V1BrowserExtensionListQuery = OpenApiQuery<'browser-extensions.list'>;
23
6
  export interface V1BrowserExtensionUploadRequest {
24
7
  /** Packed Chromium extension package. Only .crx is supported today. */
25
8
  file: Blob;
@@ -28,18 +11,6 @@ export interface V1BrowserExtensionUploadRequest {
28
11
  /** Parent/org keys may create inside a child subaccount. */
29
12
  subaccountId?: string;
30
13
  }
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
- }
14
+ export type V1BrowserExtensionImportRequest = OpenApiSchemas['BrowserExtensionImportRequest'];
15
+ export type V1BrowserExtensionUpdateRequest = OpenApiSchemas['BrowserExtensionUpdateRequest'];
16
+ export type V1BrowserExtensionDeleteResponse = OpenApiSchemas['BrowserExtensionDeleteResponse'];
package/dist/files.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import type { V1HttpClient } from './http.js';
2
- import type { V1File, V1FileDeleteResponse, V1FilesListQuery, V1FileUpdateRequest, V1FileUploadRequest, V1ListEnvelope } from './types.js';
2
+ import type { V1File, V1FileDeleteResponse, V1FilesListQuery, V1FilesListResponse, V1FileUpdateRequest, V1FileUploadRequest } from './types.js';
3
3
  export declare class V1FilesClient {
4
4
  private readonly http;
5
5
  constructor(http: V1HttpClient);
6
- list(query?: V1FilesListQuery): Promise<V1ListEnvelope<V1File>>;
6
+ list(query?: V1FilesListQuery): Promise<V1FilesListResponse>;
7
7
  iter(query?: V1FilesListQuery): AsyncGenerator<V1File, void, undefined>;
8
8
  get(id: string): Promise<V1File>;
9
9
  update(id: string, request: V1FileUpdateRequest): Promise<V1File>;