@bctrl/sdk 1.0.5 → 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 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.
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,97 @@
1
+ import type { JsonObject, V1PageQuery } from './types.js';
2
+ export type V1AiCredentialProvider = 'openai' | 'anthropic' | 'google' | 'azure' | 'groq' | 'deepseek' | 'mistral' | 'cerebras' | 'openrouter' | 'xai' | 'perplexity' | 'togetherai' | 'vercel-ai-gateway' | 'custom';
3
+ export type V1AiModelStatus = 'recommended' | 'supported' | 'experimental';
4
+ export type V1AiModelEngine = 'stagehand' | 'browserUse';
5
+ export interface V1AiModel {
6
+ id: string;
7
+ provider: V1AiCredentialProvider;
8
+ displayName: string;
9
+ managed: boolean;
10
+ status: V1AiModelStatus;
11
+ engines: V1AiModelEngine[];
12
+ supportsTools: boolean;
13
+ supportsVision: boolean;
14
+ supportsStructuredOutput: boolean;
15
+ supportsReasoningEffort: boolean;
16
+ supportsThinkingBudget: boolean;
17
+ }
18
+ export interface V1AiModelListQuery {
19
+ provider?: V1AiCredentialProvider;
20
+ status?: V1AiModelStatus;
21
+ managed?: boolean;
22
+ engine?: V1AiModelEngine;
23
+ }
24
+ export interface V1AiModelListResponse {
25
+ data: V1AiModel[];
26
+ }
27
+ export type V1AiCredentialStatus = 'enabled' | 'disabled';
28
+ export interface V1AiCredential {
29
+ id: string;
30
+ name: string;
31
+ provider: V1AiCredentialProvider;
32
+ status: V1AiCredentialStatus;
33
+ subaccountId?: string;
34
+ defaultModel?: string;
35
+ baseUrl?: string;
36
+ hasApiKey: boolean;
37
+ createdAt: string;
38
+ updatedAt: string;
39
+ }
40
+ export interface V1AiCredentialListQuery extends V1PageQuery {
41
+ provider?: V1AiCredentialProvider;
42
+ name?: string;
43
+ status?: V1AiCredentialStatus;
44
+ }
45
+ export interface V1AiCredentialCreateRequest {
46
+ provider: V1AiCredentialProvider;
47
+ name?: string;
48
+ apiKey?: string;
49
+ defaultModel?: string;
50
+ baseUrl?: string;
51
+ status?: V1AiCredentialStatus;
52
+ subaccountId?: string | null;
53
+ test?: boolean;
54
+ }
55
+ export interface V1AiCredentialUpdateRequest {
56
+ name?: string;
57
+ apiKey?: string | null;
58
+ defaultModel?: string | null;
59
+ baseUrl?: string | null;
60
+ status?: V1AiCredentialStatus;
61
+ }
62
+ export interface V1AiCredentialDeleteResponse {
63
+ id: string;
64
+ deleted: true;
65
+ }
66
+ export interface V1AiCredentialTestResponse {
67
+ ok: boolean;
68
+ checkedAt: string;
69
+ latencyMs?: number;
70
+ error?: string;
71
+ }
72
+ export type V1AiModelSelectionAuth = 'managed' | {
73
+ credential: string;
74
+ } | {
75
+ apiKey: string;
76
+ };
77
+ export interface V1AiModelSelectionObject {
78
+ model: string;
79
+ auth?: V1AiModelSelectionAuth;
80
+ provider?: V1AiCredentialProvider;
81
+ baseUrl?: string;
82
+ temperature?: number;
83
+ maxTokens?: number;
84
+ topP?: number;
85
+ reasoningEffort?: 'none' | 'low' | 'medium' | 'high' | 'xhigh';
86
+ thinkingBudgetTokens?: number;
87
+ responseFormat?: 'text' | 'json';
88
+ responseSchema?: JsonObject;
89
+ providerOptions?: JsonObject;
90
+ }
91
+ export type V1AiModelSelection = string | V1AiModelSelectionObject;
92
+ export type V1AiStoredModelSelectionAuth = 'managed' | {
93
+ credential: string;
94
+ };
95
+ export type V1AiStoredModelSelection = string | (Omit<V1AiModelSelectionObject, 'auth' | 'baseUrl'> & {
96
+ auth?: V1AiStoredModelSelectionAuth;
97
+ });
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);
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>;
package/dist/index.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  export { Bctrl, BctrlV1, type BctrlV1Options } from './bctrl.js';
2
2
  export { V1AccountClient, V1ApiKeysClient, V1AuthClient, V1SubaccountsClient, V1SubaccountUsageClient, V1UsageClient, } from './account.js';
3
- export { V1AiProvidersClient } from './aiProviders.js';
3
+ export { V1AiClient, V1AiCredentialsClient, V1AiModelsClient } from './ai.js';
4
4
  export { V1BrowserExtensionsClient } from './browserExtensions.js';
5
5
  export { BctrlError, BctrlApiError, BctrlAuthenticationError, BctrlConflictError, BctrlNetworkError, BctrlNotFoundError, BctrlNotReadyError, BctrlPermissionError, BctrlRateLimitError, BctrlUnsupportedError, BctrlValidationError, isControllerBusy, } from './errors.js';
6
6
  export { V1FilesClient } from './files.js';
7
7
  export { V1HelpClient } from './help.js';
8
8
  export { V1RuntimeBrowserUseInvocationsNamespaceClient, V1RuntimeInvocationsNamespaceClient, V1RuntimeStagehandInvocationsNamespaceClient, } from './invocations.js';
9
9
  export type { BrowserUseAgentOptions, V1InvocationCreateAndWaitOptions, V1InvocationWaitOptions, V1RuntimeInvocationCreateInput, StagehandActOptions, StagehandAgentOptions, StagehandExtractOptions, StagehandObserveOptions, StagehandVariablePrimitive, StagehandVariableValue, StagehandVariables, } from './invocations.js';
10
- export { V1RuntimeFilesNamespaceClient, V1RuntimeRunsNamespaceClient, V1RuntimesClient, } from './runtimes.js';
10
+ export { V1RuntimeFilesNamespaceClient, V1RuntimeRunsNamespaceClient, V1RuntimeTargetsNamespaceClient, V1RuntimesClient, } from './runtimes.js';
11
11
  export { V1ProxiesClient, V1ProxyPoolsClient } from './proxies.js';
12
12
  export { V1RunActivityNamespaceClient, V1RunEventsNamespaceClient, V1RunFilesNamespaceClient, V1RunInvocationsNamespaceClient, V1RunsClient, } from './runs.js';
13
13
  export { toOutputSchema, type JsonSchemaLike, type JsonSchemaObject } from './schemas.js';
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  export { Bctrl, BctrlV1 } from './bctrl.js';
2
2
  export { V1AccountClient, V1ApiKeysClient, V1AuthClient, V1SubaccountsClient, V1SubaccountUsageClient, V1UsageClient, } from './account.js';
3
- export { V1AiProvidersClient } from './aiProviders.js';
3
+ export { V1AiClient, V1AiCredentialsClient, V1AiModelsClient } from './ai.js';
4
4
  export { V1BrowserExtensionsClient } from './browserExtensions.js';
5
5
  export { BctrlError, BctrlApiError, BctrlAuthenticationError, BctrlConflictError, BctrlNetworkError, BctrlNotFoundError, BctrlNotReadyError, BctrlPermissionError, BctrlRateLimitError, BctrlUnsupportedError, BctrlValidationError, isControllerBusy, } from './errors.js';
6
6
  export { V1FilesClient } from './files.js';
7
7
  export { V1HelpClient } from './help.js';
8
8
  export { V1RuntimeBrowserUseInvocationsNamespaceClient, V1RuntimeInvocationsNamespaceClient, V1RuntimeStagehandInvocationsNamespaceClient, } from './invocations.js';
9
- export { V1RuntimeFilesNamespaceClient, V1RuntimeRunsNamespaceClient, V1RuntimesClient, } from './runtimes.js';
9
+ export { V1RuntimeFilesNamespaceClient, V1RuntimeRunsNamespaceClient, V1RuntimeTargetsNamespaceClient, V1RuntimesClient, } from './runtimes.js';
10
10
  export { V1ProxiesClient, V1ProxyPoolsClient } from './proxies.js';
11
11
  export { V1RunActivityNamespaceClient, V1RunEventsNamespaceClient, V1RunFilesNamespaceClient, V1RunInvocationsNamespaceClient, V1RunsClient, } from './runs.js';
12
12
  export { toOutputSchema } from './schemas.js';
@@ -1,6 +1,6 @@
1
1
  import { type V1HttpClient, type V1IdempotencyOptions } from './http.js';
2
2
  import { type JsonSchemaLike } from './schemas.js';
3
- import type { JsonObject, V1Invocation, V1InvocationPage, V1RuntimeInvocationCreateRequest, V1RuntimeInvocationFileInput, V1InvocationWaitRequest, V1InvocationWaitResponse } from './types.js';
3
+ import type { JsonObject, V1Invocation, V1RuntimeInvocationCreateRequest, V1RuntimeInvocationFileInput, V1RuntimeTargetSelector, V1InvocationWaitRequest, V1InvocationWaitResponse, V1AiModelSelection } from './types.js';
4
4
  export type StagehandVariablePrimitive = string | number | boolean;
5
5
  export type StagehandVariableValue = StagehandVariablePrimitive | {
6
6
  value: StagehandVariablePrimitive;
@@ -8,7 +8,7 @@ export type StagehandVariableValue = StagehandVariablePrimitive | {
8
8
  };
9
9
  export type StagehandVariables = Record<string, StagehandVariableValue>;
10
10
  interface RuntimeInvocationCommonOptions {
11
- page?: V1InvocationPage;
11
+ target?: V1RuntimeTargetSelector;
12
12
  metadata?: JsonObject;
13
13
  }
14
14
  interface RuntimeAgentCommonOptions extends RuntimeInvocationCommonOptions {
@@ -16,12 +16,10 @@ interface RuntimeAgentCommonOptions extends RuntimeInvocationCommonOptions {
16
16
  toolIds?: string[];
17
17
  files?: V1RuntimeInvocationFileInput[];
18
18
  schema?: JsonSchemaLike;
19
- outputSchema?: JsonObject;
20
19
  timeoutMs?: number;
21
20
  }
22
21
  interface AiSelectionOptions {
23
- aiProviderId?: string;
24
- model?: string;
22
+ model?: V1AiModelSelection;
25
23
  temperature?: number;
26
24
  }
27
25
  export interface StagehandActOptions extends RuntimeInvocationCommonOptions, AiSelectionOptions {
@@ -44,15 +42,15 @@ export interface StagehandAgentOptions extends RuntimeAgentCommonOptions, AiSele
44
42
  instruction: string;
45
43
  maxSteps?: number;
46
44
  variables?: StagehandVariables;
47
- executionAiProviderId?: string;
45
+ executionModel?: V1AiModelSelection;
48
46
  systemPrompt?: string;
49
47
  highlightCursor?: boolean;
50
48
  }
51
49
  export interface BrowserUseAgentOptions extends RuntimeAgentCommonOptions, AiSelectionOptions {
52
50
  instruction: string;
53
51
  maxSteps?: number;
54
- extractionAiProviderId?: string;
55
- fallbackAiProviderId?: string;
52
+ extractionModel?: V1AiModelSelection;
53
+ fallbackModel?: V1AiModelSelection;
56
54
  useVision?: boolean | 'auto';
57
55
  visionDetailLevel?: 'low' | 'high' | 'auto';
58
56
  flashMode?: boolean;
@@ -70,7 +68,6 @@ export interface BrowserUseAgentOptions extends RuntimeAgentCommonOptions, AiSel
70
68
  }
71
69
  type InvocationCreateWithSchema<T extends V1RuntimeInvocationCreateRequest> = Omit<T, 'outputSchema'> & {
72
70
  schema?: JsonSchemaLike;
73
- outputSchema?: JsonObject;
74
71
  };
75
72
  type ExtractInvocationCreateRequest = Extract<V1RuntimeInvocationCreateRequest, {
76
73
  action: 'extract';
@@ -162,9 +162,6 @@ function prepareInvocationCreateRequest(request) {
162
162
  if (!hasInvocationSchema(request)) {
163
163
  return request;
164
164
  }
165
- if ('outputSchema' in request && request.outputSchema !== undefined) {
166
- throw new TypeError('Pass either schema or outputSchema, not both');
167
- }
168
165
  const { schema, ...body } = request;
169
166
  return {
170
167
  ...body,
@@ -1,4 +1,5 @@
1
1
  export type V1ProxyProtocol = 'http' | 'socks5';
2
+ export type V1ProxyDnsResolution = 'local' | 'proxy';
2
3
  export type V1ProxyType = 'custom' | 'managed-rotating' | 'managed-static';
3
4
  export type V1ManagedRotatingPreference = 'balanced' | 'speed' | 'quality' | 'coverage';
4
5
  export type V1ManagedRotatingRotation = 'sticky' | 'rotating';
@@ -12,6 +13,7 @@ export interface V1ProxyBase {
12
13
  }
13
14
  export interface V1ManagedRotatingProxyConfig {
14
15
  protocol?: V1ProxyProtocol;
16
+ dnsResolution?: V1ProxyDnsResolution;
15
17
  ipFamily?: 'dual-stack' | 'ipv4-only';
16
18
  preference?: V1ManagedRotatingPreference;
17
19
  rotation?: V1ManagedRotatingRotation;
@@ -28,6 +30,7 @@ export interface V1ManagedRotatingProxyConfig {
28
30
  export type V1Proxy = (V1ProxyBase & {
29
31
  type: 'custom';
30
32
  protocol: V1ProxyProtocol;
33
+ dnsResolution?: V1ProxyDnsResolution;
31
34
  host: string;
32
35
  port: number;
33
36
  username?: string | null;
@@ -56,6 +59,7 @@ export type V1ProxyCreateRequest = {
56
59
  name?: string;
57
60
  url?: string;
58
61
  protocol?: V1ProxyProtocol;
62
+ dnsResolution?: V1ProxyDnsResolution;
59
63
  host?: string;
60
64
  port?: number;
61
65
  username?: string;
@@ -73,6 +77,7 @@ export interface V1ProxyUpdateRequest extends Partial<V1ManagedRotatingProxyConf
73
77
  name?: string;
74
78
  url?: string;
75
79
  protocol?: V1ProxyProtocol;
80
+ dnsResolution?: V1ProxyDnsResolution;
76
81
  host?: string;
77
82
  port?: number;
78
83
  username?: string | null;
@@ -1,17 +1,22 @@
1
1
  import { type V1HttpClient, type V1IdempotencyOptions } from './http.js';
2
2
  import { V1RuntimeInvocationsNamespaceClient } from './invocations.js';
3
- import type { V1ListEnvelope, V1File, V1Runtime, V1RuntimeCreateRequest, V1RuntimeFileCollectRequest, V1RuntimeFilesListQuery, V1RuntimeFileStageRequest, V1RuntimeFileUploadRequest, V1RuntimeStagedFile, V1RuntimeListQuery, V1RuntimeRunListQuery, V1RuntimeStartResponse, V1RuntimeStopResponse, V1RunSummary, V1SpaceRuntimeCreateRequest } from './types.js';
3
+ import type { V1ListEnvelope, V1File, V1Runtime, V1RuntimeCreateRequest, V1RuntimeDeleteResponse, V1RuntimeFileCollectRequest, V1RuntimeFilesListQuery, V1RuntimeFileStageRequest, V1RuntimeFileUploadRequest, V1RuntimeStagedFile, V1RuntimeListQuery, V1RuntimeRunListQuery, V1RuntimeStartResponse, V1RuntimeStopResponse, V1RuntimeTarget, V1RuntimeTargetCreateRequest, V1RuntimeUpdateRequest, V1RunSummary, V1SpaceRuntimeCreateRequest } from './types.js';
4
4
  export type V1RuntimeStartResult = V1RuntimeStartResponse;
5
5
  export declare class V1RuntimesClient {
6
6
  private readonly http;
7
7
  readonly files: V1RuntimeFilesNamespaceClient;
8
8
  readonly runs: V1RuntimeRunsNamespaceClient;
9
9
  readonly invocations: V1RuntimeInvocationsNamespaceClient;
10
+ readonly targets: V1RuntimeTargetsNamespaceClient;
10
11
  constructor(http: V1HttpClient);
11
12
  list(query?: V1RuntimeListQuery): Promise<V1ListEnvelope<V1Runtime>>;
12
13
  iter(query?: V1RuntimeListQuery): AsyncGenerator<V1Runtime, void, undefined>;
13
14
  create(request: V1RuntimeCreateRequest): Promise<V1Runtime>;
14
15
  createInSpace(spaceId: string, request: V1SpaceRuntimeCreateRequest): Promise<V1Runtime>;
16
+ update(id: string, request: V1RuntimeUpdateRequest): Promise<V1Runtime>;
17
+ delete(id: string, options?: {
18
+ force?: boolean;
19
+ }): Promise<V1RuntimeDeleteResponse>;
15
20
  get(id: string): Promise<V1Runtime>;
16
21
  stop(id: string): Promise<V1RuntimeStopResponse>;
17
22
  start(id: string, options?: V1IdempotencyOptions): Promise<V1RuntimeStartResult>;
@@ -31,3 +36,15 @@ export declare class V1RuntimeFilesNamespaceClient {
31
36
  stage(runtimeId: string, request: V1RuntimeFileStageRequest): Promise<V1RuntimeStagedFile>;
32
37
  collect(runtimeId: string, request: V1RuntimeFileCollectRequest): Promise<V1File>;
33
38
  }
39
+ export declare class V1RuntimeTargetsNamespaceClient {
40
+ private readonly http;
41
+ constructor(http: V1HttpClient);
42
+ list(runtimeId: string): Promise<V1ListEnvelope<V1RuntimeTarget>>;
43
+ create(runtimeId: string, request?: V1RuntimeTargetCreateRequest): Promise<V1RuntimeTarget>;
44
+ get(runtimeId: string, targetId: string): Promise<V1RuntimeTarget>;
45
+ activate(runtimeId: string, targetId: string): Promise<V1RuntimeTarget>;
46
+ delete(runtimeId: string, targetId: string): Promise<{
47
+ id: string;
48
+ deleted: boolean;
49
+ }>;
50
+ }
package/dist/runtimes.js CHANGED
@@ -62,16 +62,39 @@ class V1RuntimeFilesClient {
62
62
  });
63
63
  }
64
64
  }
65
+ class V1RuntimeTargetsClient {
66
+ http;
67
+ runtimeId;
68
+ constructor(http, runtimeId) {
69
+ this.http = http;
70
+ this.runtimeId = runtimeId;
71
+ }
72
+ list() {
73
+ return this.http.request(`/runtimes/${encodeURIComponent(this.runtimeId)}/targets`);
74
+ }
75
+ create(request = {}) {
76
+ return this.http.request(`/runtimes/${encodeURIComponent(this.runtimeId)}/targets`, {
77
+ method: 'POST',
78
+ body: request,
79
+ });
80
+ }
81
+ get(targetId) {
82
+ return this.http.request(`/runtimes/${encodeURIComponent(this.runtimeId)}/targets/${encodeURIComponent(targetId)}`);
83
+ }
84
+ activate(targetId) {
85
+ return this.http.request(`/runtimes/${encodeURIComponent(this.runtimeId)}/targets/${encodeURIComponent(targetId)}/activate`, { method: 'POST' });
86
+ }
87
+ delete(targetId) {
88
+ return this.http.request(`/runtimes/${encodeURIComponent(this.runtimeId)}/targets/${encodeURIComponent(targetId)}`, { method: 'DELETE' });
89
+ }
90
+ }
65
91
  function validateRuntimeCreateRequest(request) {
66
92
  const profileBacked = request.config?.profile === true;
67
93
  if (!profileBacked)
68
94
  return;
69
- if (!request.name?.trim()) {
70
- throw new BctrlValidationError('name is required when config.profile is true', 'runtime.profile_name_required');
71
- }
72
- const unsupported = ['stealth', 'proxy', 'fingerprint', 'extensionIds'].filter((key) => request.config?.[key] !== undefined);
95
+ const unsupported = ['stealth', 'fingerprint', 'extensionIds'].filter((key) => request.config?.[key] !== undefined);
73
96
  if (unsupported.length > 0) {
74
- throw new BctrlValidationError('Only config.profile, config.idleTimeoutMinutes, config.webRtcProxyOnly, config.forceOpenShadowRoots, and config.networkTraffic are supported for profile-backed browser runtimes', 'runtime.profile_config_unsupported', { unsupported });
97
+ throw new BctrlValidationError('Only config.profile, config.proxy, config.autoUpgrade, config.idleTimeoutMinutes, config.webRtcProxyOnly, config.forceOpenShadowRoots, and config.networkTraffic are supported for profile-backed browser runtimes', 'runtime.profile_config_unsupported', { unsupported });
75
98
  }
76
99
  }
77
100
  export class V1RuntimesClient {
@@ -79,11 +102,13 @@ export class V1RuntimesClient {
79
102
  files;
80
103
  runs;
81
104
  invocations;
105
+ targets;
82
106
  constructor(http) {
83
107
  this.http = http;
84
108
  this.files = new V1RuntimeFilesNamespaceClient(http);
85
109
  this.runs = new V1RuntimeRunsNamespaceClient(http);
86
110
  this.invocations = new V1RuntimeInvocationsNamespaceClient(http);
111
+ this.targets = new V1RuntimeTargetsNamespaceClient(http);
87
112
  }
88
113
  list(query = {}) {
89
114
  return this.http.request('/runtimes', { query });
@@ -105,6 +130,15 @@ export class V1RuntimesClient {
105
130
  body: { ...request, spaceId },
106
131
  });
107
132
  }
133
+ update(id, request) {
134
+ return this.http.request(`/runtimes/${encodeURIComponent(id)}`, {
135
+ method: 'PATCH',
136
+ body: request,
137
+ });
138
+ }
139
+ delete(id, options = {}) {
140
+ return this.http.request(`/runtimes/${encodeURIComponent(id)}${options.force ? '?force=true' : ''}`, { method: 'DELETE' });
141
+ }
108
142
  get(id) {
109
143
  return this.http.request(`/runtimes/${encodeURIComponent(id)}`);
110
144
  }
@@ -153,3 +187,24 @@ export class V1RuntimeFilesNamespaceClient {
153
187
  return new V1RuntimeFilesClient(this.http, runtimeId).collect(request);
154
188
  }
155
189
  }
190
+ export class V1RuntimeTargetsNamespaceClient {
191
+ http;
192
+ constructor(http) {
193
+ this.http = http;
194
+ }
195
+ list(runtimeId) {
196
+ return new V1RuntimeTargetsClient(this.http, runtimeId).list();
197
+ }
198
+ create(runtimeId, request = {}) {
199
+ return new V1RuntimeTargetsClient(this.http, runtimeId).create(request);
200
+ }
201
+ get(runtimeId, targetId) {
202
+ return new V1RuntimeTargetsClient(this.http, runtimeId).get(targetId);
203
+ }
204
+ activate(runtimeId, targetId) {
205
+ return new V1RuntimeTargetsClient(this.http, runtimeId).activate(targetId);
206
+ }
207
+ delete(runtimeId, targetId) {
208
+ return new V1RuntimeTargetsClient(this.http, runtimeId).delete(targetId);
209
+ }
210
+ }
package/dist/types.d.ts CHANGED
@@ -3,8 +3,10 @@ export type JsonValue = JsonPrimitive | JsonObject | JsonValue[];
3
3
  export type JsonObject = {
4
4
  [key: string]: JsonValue;
5
5
  };
6
+ import type { V1ManagedRotatingProxyConfig, V1ProxyDnsResolution, V1ProxyProtocol } from './proxyTypes.js';
7
+ import type { V1AiModelSelection, V1AiStoredModelSelection } from './aiTypes.js';
6
8
  export type { V1AccountUsage, V1ApiKey, V1ApiKeyCreateRequest, V1ApiKeyCreateResponse, V1ApiKeyDeleteResponse, V1ApiKeyListQuery, V1AuthScope, V1AuthWhoamiResponse, V1Plan, V1Subaccount, V1SubaccountArchiveResponse, V1SubaccountCreateRequest, V1SubaccountGetQuery, V1SubaccountLimits, V1SubaccountListQuery, V1SubaccountUpdateRequest, V1SubaccountUsage, V1SubaccountUsageListQuery, V1SubaccountUsageListResponse, } from './accountTypes.js';
7
- export type { V1AiProvider, V1AiProviderCreateRequest, V1AiProviderDeleteResponse, V1AiProviderGetQuery, V1AiProviderListQuery, V1AiProviderModel, V1AiProviderProvider, V1AiProviderStatus, V1AiProviderTestResponse, V1AiProviderUpdateRequest, } from './aiProviderTypes.js';
9
+ export type { V1AiCredential, V1AiCredentialCreateRequest, V1AiCredentialDeleteResponse, V1AiCredentialListQuery, V1AiCredentialProvider, V1AiCredentialStatus, V1AiCredentialTestResponse, V1AiCredentialUpdateRequest, V1AiModel, V1AiModelEngine, V1AiModelListQuery, V1AiModelListResponse, V1AiModelSelection, V1AiModelSelectionAuth, V1AiModelSelectionObject, V1AiModelStatus, V1AiStoredModelSelection, V1AiStoredModelSelectionAuth, } from './aiTypes.js';
8
10
  export type { V1BrowserExtension, V1BrowserExtensionDeleteResponse, V1BrowserExtensionFormat, V1BrowserExtensionImportRequest, V1BrowserExtensionListQuery, V1BrowserExtensionSource, V1BrowserExtensionUpdateRequest, V1BrowserExtensionUploadRequest, } from './browserExtensionTypes.js';
9
11
  export type { V1ToolCall, V1ToolCallActor, V1ToolCallListQuery, V1ToolCallStatus, V1ToolCallTool, } from './toolCallTypes.js';
10
12
  export type { V1Toolset, V1ToolsetBuiltinName, V1ToolsetCreateRequest, V1ToolsetDeleteResponse, V1ToolsetListQuery, V1ToolsetUpdateRequest, } from './toolsetTypes.js';
@@ -134,10 +136,10 @@ export interface V1SpaceVaultMount {
134
136
  allowRawReads?: boolean;
135
137
  }
136
138
  export interface V1SpaceAiMount {
137
- aiProviderIds?: string[];
139
+ credentialIds?: string[];
138
140
  defaults?: {
139
- stagehand?: string;
140
- browserUse?: string;
141
+ stagehand?: V1AiStoredModelSelection;
142
+ browserUse?: V1AiStoredModelSelection;
141
143
  };
142
144
  }
143
145
  export interface V1SpaceEnvironment {
@@ -146,10 +148,10 @@ export interface V1SpaceEnvironment {
146
148
  ai?: V1SpaceAiMount;
147
149
  }
148
150
  export interface V1SpaceAiMountUpdate {
149
- aiProviderIds?: string[] | null;
151
+ credentialIds?: string[] | null;
150
152
  defaults?: {
151
- stagehand?: string | null;
152
- browserUse?: string | null;
153
+ stagehand?: V1AiStoredModelSelection | null;
154
+ browserUse?: V1AiStoredModelSelection | null;
153
155
  } | null;
154
156
  }
155
157
  export interface V1SpaceEnvironmentUpdateRequest {
@@ -160,21 +162,34 @@ export interface V1SpaceEnvironmentUpdateRequest {
160
162
  export type V1RuntimeType = 'browser';
161
163
  export type V1RuntimeStatus = 'active' | 'stopped' | 'failed';
162
164
  export type V1BrowserStealth = 'medium' | 'high' | 'ultra';
163
- export type V1ProxyInput = {
164
- mode: 'custom';
165
- protocol: string;
165
+ export type V1ProxyInput = string | ({
166
+ id: string;
167
+ } & V1ManagedRotatingProxyConfig) | {
168
+ type?: 'custom';
169
+ url: string;
170
+ dnsResolution?: V1ProxyDnsResolution;
171
+ username?: string;
172
+ password?: string;
173
+ } | {
174
+ type?: 'custom';
175
+ protocol: V1ProxyProtocol;
176
+ dnsResolution?: V1ProxyDnsResolution;
166
177
  host: string;
167
178
  port: number;
168
179
  username?: string;
169
180
  password?: string;
170
- } | {
171
- mode: 'saved';
172
- id: string;
173
- overrides?: JsonObject;
174
- };
181
+ } | ({
182
+ type: 'managed-rotating';
183
+ } & V1ManagedRotatingProxyConfig);
175
184
  export interface V1RuntimeFingerprintCreateConfig {
176
- browser?: string;
177
- locale?: string;
185
+ /** Defaults to 'desktop' when omitted. */
186
+ device?: 'desktop' | 'mobile';
187
+ /** Defaults to 'windows' when omitted. */
188
+ os?: 'windows' | 'macos' | 'android' | 'ios';
189
+ /** Randomly selected from chrome, edge, and safari when omitted. */
190
+ browser?: 'chrome' | 'edge' | 'safari';
191
+ browserVersion?: string;
192
+ locale?: string | string[];
178
193
  }
179
194
  export type V1BrowserNetworkTrafficSaver = 'none' | 'light' | 'medium' | 'high';
180
195
  export type V1BrowserNetworkTrafficResourceType = 'media' | 'texttrack' | 'font' | 'image' | 'ping' | 'prefetch' | 'beacon';
@@ -188,6 +203,10 @@ export interface V1BrowserNetworkTrafficConfig {
188
203
  }
189
204
  export interface V1BrowserRuntimeCreateConfig {
190
205
  profile?: boolean;
206
+ /** Upgrade the browser to the latest available version on each start. The
207
+ * fingerprint keeps its identity; only the browser version advances.
208
+ * Defaults to true; set false to pin the current version. */
209
+ autoUpgrade?: boolean;
191
210
  stealth?: V1BrowserStealth;
192
211
  proxy?: V1ProxyInput | null;
193
212
  fingerprint?: V1RuntimeFingerprintCreateConfig;
@@ -206,6 +225,17 @@ export interface V1RuntimeCreateRequest {
206
225
  config?: V1BrowserRuntimeCreateConfig;
207
226
  }
208
227
  export type V1SpaceRuntimeCreateRequest = Omit<V1RuntimeCreateRequest, 'spaceId'>;
228
+ /** PATCH /v1/runtimes/{runtimeId} — name and idleTimeoutMinutes are editable
229
+ * any time; `config` only while the runtime is stopped. */
230
+ export interface V1RuntimeUpdateRequest {
231
+ name?: string;
232
+ idleTimeoutMinutes?: number;
233
+ config?: V1BrowserRuntimeCreateConfig;
234
+ }
235
+ export interface V1RuntimeDeleteResponse {
236
+ id: string;
237
+ deleted: boolean;
238
+ }
209
239
  export interface V1RuntimeListQuery {
210
240
  spaceId?: string;
211
241
  status?: V1RuntimeStatus | V1RuntimeStatus[];
@@ -229,16 +259,30 @@ export interface V1RuntimeProxyRef {
229
259
  type: 'custom' | 'managed-rotating' | 'managed-static';
230
260
  name: string;
231
261
  }
262
+ export type V1RuntimeInlineProxyConfig = {
263
+ type: 'custom';
264
+ protocol: V1ProxyProtocol;
265
+ dnsResolution?: V1ProxyDnsResolution;
266
+ host: string;
267
+ port: number;
268
+ username?: string | null;
269
+ hasPassword: boolean;
270
+ } | ({
271
+ type: 'managed-rotating';
272
+ } & V1ManagedRotatingProxyConfig);
232
273
  /** Resolved fingerprint reported on a runtime's config (response side). */
233
274
  export interface V1RuntimeFingerprint {
275
+ device?: 'desktop' | 'mobile';
276
+ os?: 'windows' | 'macos' | 'android' | 'ios';
277
+ browser?: string;
278
+ browserVersion?: string;
234
279
  userAgent?: string;
235
- locale?: string;
280
+ locale?: string | string[];
236
281
  timezone?: string;
237
282
  viewport?: {
238
283
  width: number;
239
284
  height: number;
240
285
  };
241
- browser?: string;
242
286
  }
243
287
  /**
244
288
  * Type-specific browser runtime config returned on the runtime resource. No open
@@ -246,8 +290,9 @@ export interface V1RuntimeFingerprint {
246
290
  */
247
291
  export interface V1BrowserRuntimeConfig {
248
292
  profile: boolean;
293
+ autoUpgrade?: boolean;
249
294
  stealth?: V1BrowserStealth;
250
- proxy?: V1RuntimeProxyRef | null;
295
+ proxy?: V1RuntimeProxyRef | V1RuntimeInlineProxyConfig | null;
251
296
  fingerprint?: V1RuntimeFingerprint;
252
297
  extensionIds?: string[];
253
298
  idleTimeoutMinutes?: number;
@@ -394,21 +439,37 @@ export interface V1RunLiveRequest {
394
439
  expiresInSeconds?: number;
395
440
  }
396
441
  export interface V1RunLiveResponse {
397
- iframeUrl: string;
442
+ url: string;
398
443
  expiresAt: string;
399
444
  }
400
445
  export interface V1RunRecordingRequest {
401
446
  expiresInSeconds?: number;
402
447
  }
403
448
  export interface V1RunRecordingResponse {
404
- iframeUrl: string;
449
+ url: string;
405
450
  status: string;
406
451
  durationMs?: number;
407
452
  expiresAt: string;
408
453
  }
409
454
  export type V1InvocationAction = 'act' | 'observe' | 'extract' | 'browserUse' | 'stagehandAgent' | 'solveCaptcha';
410
- export type V1InvocationPage = 'active' | 'new';
411
- export type V1InvocationErrorCode = 'invocation.failed' | 'invocation.cancelled' | 'invocation.timed_out' | 'invocation.dispatch_preparation_failed' | 'invocation.dispatch_unavailable' | 'invocation.target_create_failed' | 'invocation.captcha_solve_failed' | 'invocation.output_validation_failed' | 'invocation.stagehand_failed' | 'invocation.stagehand_incomplete' | 'invocation.browser_use_failed' | 'invocation.browser_use_interrupted' | 'invocation.browser_use_incomplete';
455
+ export type V1RuntimeTargetSelector = 'active' | 'new' | {
456
+ id: string;
457
+ };
458
+ export interface V1RuntimeTarget {
459
+ id: string;
460
+ runtimeId: string;
461
+ type: 'browser_page';
462
+ label: string;
463
+ uri?: string;
464
+ active: boolean;
465
+ metadata?: JsonObject;
466
+ }
467
+ export interface V1RuntimeTargetCreateRequest {
468
+ type?: 'browser_page';
469
+ uri?: string;
470
+ activate?: boolean;
471
+ }
472
+ export type V1InvocationErrorCode = 'invocation.failed' | 'invocation.cancelled' | 'invocation.timed_out' | 'invocation.dispatch_preparation_failed' | 'invocation.dispatch_unavailable' | 'invocation.captcha_not_found' | 'invocation.captcha_solve_failed' | 'invocation.output_validation_failed' | 'invocation.stagehand_failed' | 'invocation.stagehand_incomplete' | 'invocation.browser_use_failed' | 'invocation.browser_use_interrupted' | 'invocation.browser_use_incomplete';
412
473
  export interface V1InvocationError {
413
474
  code: V1InvocationErrorCode;
414
475
  message: string;
@@ -458,7 +519,7 @@ export interface V1RuntimeInvocationFileInput {
458
519
  name?: string;
459
520
  }
460
521
  interface V1RuntimeInvocationAgentFields {
461
- page?: V1InvocationPage;
522
+ target?: V1RuntimeTargetSelector;
462
523
  outputSchema?: JsonObject;
463
524
  toolsetId?: string;
464
525
  toolIds?: string[];
@@ -467,49 +528,44 @@ interface V1RuntimeInvocationAgentFields {
467
528
  timeoutMs?: number;
468
529
  }
469
530
  interface V1RuntimeInvocationAiSelectionFields {
470
- aiProviderId?: string;
471
- model?: string;
531
+ model?: V1AiModelSelection;
472
532
  temperature?: number;
473
533
  }
474
534
  export type V1RuntimeInvocationCreateRequest = {
475
535
  action: 'act';
476
- page?: V1InvocationPage;
536
+ target?: V1RuntimeTargetSelector;
477
537
  instruction: string;
478
538
  stagehandAction?: JsonObject;
479
539
  timeoutMs?: number;
480
- aiProviderId?: string;
481
- model?: string;
540
+ model?: V1AiModelSelection;
482
541
  temperature?: number;
483
542
  metadata?: JsonObject;
484
543
  } | {
485
544
  action: 'act';
486
- page?: V1InvocationPage;
545
+ target?: V1RuntimeTargetSelector;
487
546
  stagehandAction: JsonObject;
488
547
  instruction?: string;
489
548
  timeoutMs?: number;
490
- aiProviderId?: string;
491
- model?: string;
549
+ model?: V1AiModelSelection;
492
550
  temperature?: number;
493
551
  metadata?: JsonObject;
494
552
  } | {
495
553
  action: 'observe';
496
- page?: V1InvocationPage;
554
+ target?: V1RuntimeTargetSelector;
497
555
  instruction: string;
498
556
  selector?: string;
499
557
  timeoutMs?: number;
500
- aiProviderId?: string;
501
- model?: string;
558
+ model?: V1AiModelSelection;
502
559
  temperature?: number;
503
560
  metadata?: JsonObject;
504
561
  } | {
505
562
  action: 'extract';
506
- page?: V1InvocationPage;
563
+ target?: V1RuntimeTargetSelector;
507
564
  instruction?: string;
508
565
  selector?: string;
509
566
  outputSchema?: JsonObject;
510
567
  timeoutMs?: number;
511
- aiProviderId?: string;
512
- model?: string;
568
+ model?: V1AiModelSelection;
513
569
  temperature?: number;
514
570
  metadata?: JsonObject;
515
571
  } | (V1RuntimeInvocationAgentFields & V1RuntimeInvocationAiSelectionFields & {
@@ -517,15 +573,15 @@ export type V1RuntimeInvocationCreateRequest = {
517
573
  instruction: string;
518
574
  maxSteps?: number;
519
575
  variables?: JsonObject;
520
- executionAiProviderId?: string;
576
+ executionModel?: V1AiModelSelection;
521
577
  systemPrompt?: string;
522
578
  highlightCursor?: boolean;
523
579
  }) | (V1RuntimeInvocationAgentFields & V1RuntimeInvocationAiSelectionFields & {
524
580
  action: 'browserUse';
525
581
  instruction: string;
526
582
  maxSteps?: number;
527
- extractionAiProviderId?: string;
528
- fallbackAiProviderId?: string;
583
+ extractionModel?: V1AiModelSelection;
584
+ fallbackModel?: V1AiModelSelection;
529
585
  useVision?: boolean | 'auto';
530
586
  visionDetailLevel?: 'low' | 'high' | 'auto';
531
587
  flashMode?: boolean;
@@ -542,7 +598,9 @@ export type V1RuntimeInvocationCreateRequest = {
542
598
  sensitiveData?: Record<string, string | Record<string, string>>;
543
599
  }) | {
544
600
  action: 'solveCaptcha';
545
- page?: 'active';
601
+ target?: 'active' | {
602
+ id: string;
603
+ };
546
604
  timeoutMs?: number;
547
605
  metadata?: JsonObject;
548
606
  };
@@ -571,7 +629,24 @@ export interface V1FilesListQuery extends V1PageQuery {
571
629
  path?: string;
572
630
  prefix?: string;
573
631
  q?: string;
632
+ /** Only files created after this ISO timestamp. */
633
+ createdAfter?: string;
634
+ /** S3-delimiter-style directory view: `data` holds only files directly
635
+ * under `prefix`, and the response gains a `folders` array of immediate
636
+ * subfolder rollups. */
637
+ include?: 'folders';
638
+ }
639
+ /** Immediate-subfolder rollup returned by files.list with `include: 'folders'`. */
640
+ export interface V1FileFolder {
641
+ name: string;
642
+ path: string;
643
+ fileCount: number;
644
+ totalBytes: number;
645
+ lastCreatedAt: string | null;
574
646
  }
647
+ export type V1FilesListResponse = V1ListEnvelope<V1File> & {
648
+ folders?: V1FileFolder[];
649
+ };
575
650
  export interface V1FileUpdateRequest {
576
651
  name?: string;
577
652
  metadata?: JsonObject | null;
@@ -626,7 +701,7 @@ export interface V1RuntimeFileCollectRequest {
626
701
  type?: string;
627
702
  metadata?: JsonObject;
628
703
  }
629
- export type { V1ManagedRotatingDevice, V1ManagedRotatingPreference, V1ManagedRotatingProxyConfig, V1ManagedRotatingRotation, V1Proxy, V1ProxyBase, V1ProxyCreateRequest, V1ProxyDeleteResponse, V1ProxyListQuery, V1ProxyPool, V1ProxyPoolListQuery, V1ProxyProtocol, V1ProxyTestResponse, V1ProxyType, V1ProxyUpdateRequest, } from './proxyTypes.js';
704
+ export type { V1ManagedRotatingDevice, V1ManagedRotatingPreference, V1ManagedRotatingProxyConfig, V1ManagedRotatingRotation, V1Proxy, V1ProxyBase, V1ProxyCreateRequest, V1ProxyDeleteResponse, V1ProxyDnsResolution, V1ProxyListQuery, V1ProxyPool, V1ProxyPoolListQuery, V1ProxyProtocol, V1ProxyTestResponse, V1ProxyType, V1ProxyUpdateRequest, } from './proxyTypes.js';
630
705
  export type { V1VaultSecret, V1VaultSecretDeleteResponse, V1VaultSecretListQuery, V1VaultSecretPatchRequest, V1VaultSecretType, V1VaultSecretUpsertRequest, V1VaultSecretValue, V1VaultTotpResponse, } from './vaultTypes.js';
631
706
  export type V1ToolExecutionType = 'webhook' | 'mcp_tool' | 'hosted_function' | 'hosted_workflow' | 'bctrl_builtin';
632
707
  export type V1ToolExecution = {
package/package.json CHANGED
@@ -1,46 +1,46 @@
1
- {
2
- "name": "@bctrl/sdk",
3
- "version": "1.0.5",
4
- "description": "BCTRL SDK - Remote browser automation",
5
- "main": "./dist/index.js",
6
- "types": "./dist/index.d.ts",
7
- "type": "module",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js"
12
- },
13
- "./node": {
14
- "types": "./dist/node.d.ts",
15
- "import": "./dist/node.js"
16
- }
17
- },
18
- "scripts": {
19
- "clean": "rm -rf dist",
20
- "build": "pnpm run clean && tsc -p tsconfig.json",
21
- "prepack": "pnpm run build",
22
- "dev": "tsc --watch",
23
- "test": "tsx --test tests/v1/*.test.ts tests/v1/e2e/*.test.ts",
24
- "test:v1": "tsx --test tests/v1/*.test.ts tests/v1/e2e/*.test.ts",
25
- "test:v1:e2e": "BCTRL_E2E=1 tsx --test tests/v1/e2e/**/*.test.ts",
26
- "typecheck": "tsc --noEmit"
27
- },
28
- "keywords": [],
29
- "author": "",
30
- "license": "ISC",
31
- "dependencies": {
32
- "zod": "^4.3.6"
33
- },
34
- "packageManager": "pnpm@10.12.4",
35
- "devDependencies": {
36
- "@types/node": "^25.0.3",
37
- "@typescript-eslint/eslint-plugin": "^8.56.0",
38
- "@typescript-eslint/parser": "^8.56.0",
39
- "eslint": "^10.0.0",
40
- "tsx": "^4.21.0",
41
- "typescript": "^5.9.3"
42
- },
43
- "files": [
44
- "dist"
45
- ]
46
- }
1
+ {
2
+ "name": "@bctrl/sdk",
3
+ "version": "1.0.6",
4
+ "description": "BCTRL SDK - Remote browser automation",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "type": "module",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./node": {
14
+ "types": "./dist/node.d.ts",
15
+ "import": "./dist/node.js"
16
+ }
17
+ },
18
+ "scripts": {
19
+ "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
20
+ "build": "pnpm run clean && tsc -p tsconfig.json",
21
+ "prepack": "pnpm run build",
22
+ "dev": "tsc --watch",
23
+ "test": "tsx --test tests/v1/*.test.ts tests/v1/e2e/*.test.ts",
24
+ "test:v1": "tsx --test tests/v1/*.test.ts tests/v1/e2e/*.test.ts",
25
+ "test:v1:e2e": "BCTRL_E2E=1 tsx --test tests/v1/e2e/**/*.test.ts",
26
+ "typecheck": "tsc --noEmit"
27
+ },
28
+ "keywords": [],
29
+ "author": "",
30
+ "license": "ISC",
31
+ "dependencies": {
32
+ "zod": "^4.4.3"
33
+ },
34
+ "packageManager": "pnpm@10.12.4",
35
+ "devDependencies": {
36
+ "@types/node": "^25.0.3",
37
+ "@typescript-eslint/eslint-plugin": "^8.56.0",
38
+ "@typescript-eslint/parser": "^8.56.0",
39
+ "eslint": "^10.0.0",
40
+ "tsx": "^4.21.0",
41
+ "typescript": "^5.9.3"
42
+ },
43
+ "files": [
44
+ "dist"
45
+ ]
46
+ }
@@ -1,58 +0,0 @@
1
- import type { V1PageQuery } from './types.js';
2
- export type V1AiProviderProvider = 'openai' | 'anthropic' | 'google' | 'groq' | 'deepseek' | 'mistral' | 'cerebras' | 'openrouter' | 'xai' | 'perplexity' | 'togetherai' | 'vercel-ai-gateway' | 'custom';
3
- export type V1AiProviderStatus = 'enabled' | 'disabled';
4
- export interface V1AiProviderModel {
5
- id: string;
6
- name?: string;
7
- inputModalities?: string[];
8
- outputModalities?: string[];
9
- }
10
- export interface V1AiProvider {
11
- id: string;
12
- name?: string;
13
- provider: V1AiProviderProvider;
14
- status: V1AiProviderStatus;
15
- subaccountId?: string;
16
- defaultModel?: string;
17
- baseUrl?: string;
18
- hasApiKey: boolean;
19
- models?: V1AiProviderModel[];
20
- createdAt: string;
21
- updatedAt: string;
22
- }
23
- export interface V1AiProviderListQuery extends V1PageQuery {
24
- provider?: V1AiProviderProvider;
25
- status?: V1AiProviderStatus;
26
- include?: 'models' | 'models'[];
27
- subaccountId?: string;
28
- }
29
- export interface V1AiProviderGetQuery {
30
- include?: 'models' | 'models'[];
31
- }
32
- export interface V1AiProviderCreateRequest {
33
- provider: V1AiProviderProvider;
34
- name?: string;
35
- apiKey?: string;
36
- defaultModel?: string;
37
- baseUrl?: string;
38
- status?: V1AiProviderStatus;
39
- subaccountId?: string | null;
40
- test?: boolean;
41
- }
42
- export interface V1AiProviderUpdateRequest {
43
- name?: string;
44
- apiKey?: string | null;
45
- defaultModel?: string | null;
46
- baseUrl?: string | null;
47
- status?: V1AiProviderStatus;
48
- }
49
- export interface V1AiProviderDeleteResponse {
50
- id: string;
51
- deleted: true;
52
- }
53
- export interface V1AiProviderTestResponse {
54
- ok: boolean;
55
- checkedAt: string;
56
- latencyMs?: number;
57
- error?: string;
58
- }
@@ -1,13 +0,0 @@
1
- import type { V1HttpClient } from './http.js';
2
- import type { V1AiProvider, V1AiProviderCreateRequest, V1AiProviderDeleteResponse, V1AiProviderGetQuery, V1AiProviderListQuery, V1AiProviderTestResponse, V1AiProviderUpdateRequest, V1ListEnvelope } from './types.js';
3
- export declare class V1AiProvidersClient {
4
- private readonly http;
5
- constructor(http: V1HttpClient);
6
- list(query?: V1AiProviderListQuery): Promise<V1ListEnvelope<V1AiProvider>>;
7
- iter(query?: V1AiProviderListQuery): AsyncGenerator<V1AiProvider, void, undefined>;
8
- create(request: V1AiProviderCreateRequest): Promise<V1AiProvider>;
9
- get(aiProviderId: string, query?: V1AiProviderGetQuery): Promise<V1AiProvider>;
10
- update(aiProviderId: string, request: V1AiProviderUpdateRequest): Promise<V1AiProvider>;
11
- delete(aiProviderId: string): Promise<V1AiProviderDeleteResponse>;
12
- test(aiProviderId: string): Promise<V1AiProviderTestResponse>;
13
- }
@@ -1,36 +0,0 @@
1
- import { iterateV1Pages } from './pagination.js';
2
- export class V1AiProvidersClient {
3
- http;
4
- constructor(http) {
5
- this.http = http;
6
- }
7
- list(query = {}) {
8
- return this.http.request('/ai-providers', { query });
9
- }
10
- iter(query = {}) {
11
- return iterateV1Pages(query, (pageQuery) => this.list(pageQuery));
12
- }
13
- create(request) {
14
- return this.http.request('/ai-providers', {
15
- method: 'POST',
16
- body: request,
17
- });
18
- }
19
- get(aiProviderId, query = {}) {
20
- return this.http.request(`/ai-providers/${encodeURIComponent(aiProviderId)}`, {
21
- query,
22
- });
23
- }
24
- update(aiProviderId, request) {
25
- return this.http.request(`/ai-providers/${encodeURIComponent(aiProviderId)}`, {
26
- method: 'PATCH',
27
- body: request,
28
- });
29
- }
30
- delete(aiProviderId) {
31
- return this.http.request(`/ai-providers/${encodeURIComponent(aiProviderId)}`, { method: 'DELETE' });
32
- }
33
- test(aiProviderId) {
34
- return this.http.request(`/ai-providers/${encodeURIComponent(aiProviderId)}/test`, { method: 'POST' });
35
- }
36
- }
File without changes