From 963aaf27f6449d4bcd39f9f3340b5d5a68ae49e8 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 24 Nov 2025 18:52:47 +0000
Subject: [PATCH 1/8] feat: Mason/agent auth api
---
.stats.yml | 8 +-
api.md | 29 +++
src/client.ts | 5 +
src/resources/agents.ts | 3 +
src/resources/agents/agents.ts | 31 +++
src/resources/agents/auth.ts | 3 +
src/resources/agents/auth/auth.ts | 245 +++++++++++++++++++
src/resources/agents/auth/index.ts | 18 ++
src/resources/agents/auth/runs.ts | 125 ++++++++++
src/resources/agents/index.ts | 12 +
src/resources/index.ts | 1 +
tests/api-resources/agents/auth/auth.test.ts | 35 +++
tests/api-resources/agents/auth/runs.test.ts | 80 ++++++
13 files changed, 591 insertions(+), 4 deletions(-)
create mode 100644 src/resources/agents.ts
create mode 100644 src/resources/agents/agents.ts
create mode 100644 src/resources/agents/auth.ts
create mode 100644 src/resources/agents/auth/auth.ts
create mode 100644 src/resources/agents/auth/index.ts
create mode 100644 src/resources/agents/auth/runs.ts
create mode 100644 src/resources/agents/index.ts
create mode 100644 tests/api-resources/agents/auth/auth.test.ts
create mode 100644 tests/api-resources/agents/auth/runs.test.ts
diff --git a/.stats.yml b/.stats.yml
index 11b820d..bdbede3 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 66
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-2af1b468584cb44aa9babbbfb82bff4055614fbb5c815084a6b7dacc1cf1a822.yml
-openapi_spec_hash: 891affa2849341ea01d62011125f7edc
-config_hash: 9421eb86b7f3f4b274f123279da3858e
+configured_endpoints: 71
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-bb3f37e55117a56e7a4208bd646d3a68adeb651ced8531e13fbfc1fc9dcb05a4.yml
+openapi_spec_hash: 7303ce8ce3130e16a6a5c2bb49e43e9b
+config_hash: be146470fb2d4583b6533859f0fa48f5
diff --git a/api.md b/api.md
index 982d841..b16b435 100644
--- a/api.md
+++ b/api.md
@@ -220,3 +220,32 @@ Methods:
- client.extensions.download(idOrName) -> Response
- client.extensions.downloadFromChromeStore({ ...params }) -> Response
- client.extensions.upload({ ...params }) -> ExtensionUploadResponse
+
+# Agents
+
+## Auth
+
+Types:
+
+- AgentAuthDiscoverResponse
+- AgentAuthRunResponse
+- AgentAuthStartResponse
+- AgentAuthSubmitResponse
+- DiscoveredField
+
+Methods:
+
+- client.agents.auth.start({ ...params }) -> AgentAuthStartResponse
+
+### Runs
+
+Types:
+
+- RunExchangeResponse
+
+Methods:
+
+- client.agents.auth.runs.retrieve(runID) -> AgentAuthRunResponse
+- client.agents.auth.runs.discover(runID) -> AgentAuthDiscoverResponse
+- client.agents.auth.runs.exchange(runID, { ...params }) -> RunExchangeResponse
+- client.agents.auth.runs.submit(runID, { ...params }) -> AgentAuthSubmitResponse
diff --git a/src/client.ts b/src/client.ts
index a419c27..9d3ad81 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -61,6 +61,7 @@ import {
ProxyListResponse,
ProxyRetrieveResponse,
} from './resources/proxies';
+import { Agents } from './resources/agents/agents';
import {
BrowserCreateParams,
BrowserCreateResponse,
@@ -843,6 +844,7 @@ export class Kernel {
profiles: API.Profiles = new API.Profiles(this);
proxies: API.Proxies = new API.Proxies(this);
extensions: API.Extensions = new API.Extensions(this);
+ agents: API.Agents = new API.Agents(this);
}
Kernel.Deployments = Deployments;
@@ -852,6 +854,7 @@ Kernel.Browsers = Browsers;
Kernel.Profiles = Profiles;
Kernel.Proxies = Proxies;
Kernel.Extensions = Extensions;
+Kernel.Agents = Agents;
export declare namespace Kernel {
export type RequestOptions = Opts.RequestOptions;
@@ -933,6 +936,8 @@ export declare namespace Kernel {
type ExtensionUploadParams as ExtensionUploadParams,
};
+ export { Agents as Agents };
+
export type AppAction = API.AppAction;
export type ErrorDetail = API.ErrorDetail;
export type ErrorEvent = API.ErrorEvent;
diff --git a/src/resources/agents.ts b/src/resources/agents.ts
new file mode 100644
index 0000000..0c43db0
--- /dev/null
+++ b/src/resources/agents.ts
@@ -0,0 +1,3 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export * from './agents/index';
diff --git a/src/resources/agents/agents.ts b/src/resources/agents/agents.ts
new file mode 100644
index 0000000..67fd75b
--- /dev/null
+++ b/src/resources/agents/agents.ts
@@ -0,0 +1,31 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../core/resource';
+import * as AuthAPI from './auth/auth';
+import {
+ AgentAuthDiscoverResponse,
+ AgentAuthRunResponse,
+ AgentAuthStartResponse,
+ AgentAuthSubmitResponse,
+ Auth,
+ AuthStartParams,
+ DiscoveredField,
+} from './auth/auth';
+
+export class Agents extends APIResource {
+ auth: AuthAPI.Auth = new AuthAPI.Auth(this._client);
+}
+
+Agents.Auth = Auth;
+
+export declare namespace Agents {
+ export {
+ Auth as Auth,
+ type AgentAuthDiscoverResponse as AgentAuthDiscoverResponse,
+ type AgentAuthRunResponse as AgentAuthRunResponse,
+ type AgentAuthStartResponse as AgentAuthStartResponse,
+ type AgentAuthSubmitResponse as AgentAuthSubmitResponse,
+ type DiscoveredField as DiscoveredField,
+ type AuthStartParams as AuthStartParams,
+ };
+}
diff --git a/src/resources/agents/auth.ts b/src/resources/agents/auth.ts
new file mode 100644
index 0000000..b64faa1
--- /dev/null
+++ b/src/resources/agents/auth.ts
@@ -0,0 +1,3 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export * from './auth/index';
diff --git a/src/resources/agents/auth/auth.ts b/src/resources/agents/auth/auth.ts
new file mode 100644
index 0000000..a97ee3b
--- /dev/null
+++ b/src/resources/agents/auth/auth.ts
@@ -0,0 +1,245 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../../core/resource';
+import * as RunsAPI from './runs';
+import { RunDiscoverParams, RunExchangeParams, RunExchangeResponse, RunSubmitParams, Runs } from './runs';
+import { APIPromise } from '../../../core/api-promise';
+import { RequestOptions } from '../../../internal/request-options';
+
+export class Auth extends APIResource {
+ runs: RunsAPI.Runs = new RunsAPI.Runs(this._client);
+
+ /**
+ * Creates a browser session and returns a handoff code for the hosted flow. Uses
+ * standard API key or JWT authentication (not the JWT returned by the exchange
+ * endpoint).
+ *
+ * @example
+ * ```ts
+ * const agentAuthStartResponse =
+ * await client.agents.auth.start({
+ * profile_name: 'auth-abc123',
+ * target_domain: 'doordash.com',
+ * });
+ * ```
+ */
+ start(body: AuthStartParams, options?: RequestOptions): APIPromise {
+ return this._client.post('/agents/auth/start', { body, ...options });
+ }
+}
+
+/**
+ * Response from discover endpoint matching AuthBlueprint schema
+ */
+export interface AgentAuthDiscoverResponse {
+ /**
+ * Whether discovery succeeded
+ */
+ success: boolean;
+
+ /**
+ * Error message if discovery failed
+ */
+ error_message?: string;
+
+ /**
+ * Discovered form fields (present when success is true)
+ */
+ fields?: Array;
+
+ /**
+ * Whether user is already logged in
+ */
+ logged_in?: boolean;
+
+ /**
+ * URL of the discovered login page
+ */
+ login_url?: string;
+
+ /**
+ * Title of the login page
+ */
+ page_title?: string;
+}
+
+/**
+ * Response from get run endpoint
+ */
+export interface AgentAuthRunResponse {
+ /**
+ * App name (org name at time of run creation)
+ */
+ app_name: string;
+
+ /**
+ * When the handoff code expires
+ */
+ expires_at: string;
+
+ /**
+ * Run status
+ */
+ status: 'ACTIVE' | 'ENDED' | 'EXPIRED' | 'CANCELED';
+
+ /**
+ * Target domain for authentication
+ */
+ target_domain: string;
+}
+
+/**
+ * Response from starting an agent authentication run
+ */
+export interface AgentAuthStartResponse {
+ /**
+ * When the handoff code expires
+ */
+ expires_at: string;
+
+ /**
+ * One-time code for handoff
+ */
+ handoff_code: string;
+
+ /**
+ * URL to redirect user to
+ */
+ hosted_url: string;
+
+ /**
+ * Unique identifier for the run
+ */
+ run_id: string;
+}
+
+/**
+ * Response from submit endpoint matching SubmitResult schema
+ */
+export interface AgentAuthSubmitResponse {
+ /**
+ * Whether submission succeeded
+ */
+ success: boolean;
+
+ /**
+ * Additional fields needed (e.g., OTP) - present when needs_additional_auth is
+ * true
+ */
+ additional_fields?: Array;
+
+ /**
+ * App name (only present when logged_in is true)
+ */
+ app_name?: string;
+
+ /**
+ * Error message if submission failed
+ */
+ error_message?: string;
+
+ /**
+ * Whether user is now logged in
+ */
+ logged_in?: boolean;
+
+ /**
+ * Whether additional authentication fields are needed
+ */
+ needs_additional_auth?: boolean;
+
+ /**
+ * Target domain (only present when logged_in is true)
+ */
+ target_domain?: string;
+}
+
+/**
+ * A discovered form field
+ */
+export interface DiscoveredField {
+ /**
+ * Field label
+ */
+ label: string;
+
+ /**
+ * Field name
+ */
+ name: string;
+
+ /**
+ * CSS selector for the field
+ */
+ selector: string;
+
+ /**
+ * Field type
+ */
+ type: 'text' | 'email' | 'password' | 'tel' | 'number' | 'url' | 'code' | 'checkbox';
+
+ /**
+ * Field placeholder
+ */
+ placeholder?: string;
+
+ /**
+ * Whether field is required
+ */
+ required?: boolean;
+}
+
+export interface AuthStartParams {
+ /**
+ * Name of the profile to use for this flow
+ */
+ profile_name: string;
+
+ /**
+ * Target domain for authentication
+ */
+ target_domain: string;
+
+ /**
+ * Optional logo URL for the application
+ */
+ app_logo_url?: string;
+
+ /**
+ * Optional proxy configuration
+ */
+ proxy?: AuthStartParams.Proxy;
+}
+
+export namespace AuthStartParams {
+ /**
+ * Optional proxy configuration
+ */
+ export interface Proxy {
+ /**
+ * ID of the proxy to use
+ */
+ proxy_id?: string;
+ }
+}
+
+Auth.Runs = Runs;
+
+export declare namespace Auth {
+ export {
+ type AgentAuthDiscoverResponse as AgentAuthDiscoverResponse,
+ type AgentAuthRunResponse as AgentAuthRunResponse,
+ type AgentAuthStartResponse as AgentAuthStartResponse,
+ type AgentAuthSubmitResponse as AgentAuthSubmitResponse,
+ type DiscoveredField as DiscoveredField,
+ type AuthStartParams as AuthStartParams,
+ };
+
+ export {
+ Runs as Runs,
+ type RunExchangeResponse as RunExchangeResponse,
+ type RunDiscoverParams as RunDiscoverParams,
+ type RunExchangeParams as RunExchangeParams,
+ type RunSubmitParams as RunSubmitParams,
+ };
+}
diff --git a/src/resources/agents/auth/index.ts b/src/resources/agents/auth/index.ts
new file mode 100644
index 0000000..904c0ce
--- /dev/null
+++ b/src/resources/agents/auth/index.ts
@@ -0,0 +1,18 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export {
+ Auth,
+ type AgentAuthDiscoverResponse,
+ type AgentAuthRunResponse,
+ type AgentAuthStartResponse,
+ type AgentAuthSubmitResponse,
+ type DiscoveredField,
+ type AuthStartParams,
+} from './auth';
+export {
+ Runs,
+ type RunExchangeResponse,
+ type RunDiscoverParams,
+ type RunExchangeParams,
+ type RunSubmitParams,
+} from './runs';
diff --git a/src/resources/agents/auth/runs.ts b/src/resources/agents/auth/runs.ts
new file mode 100644
index 0000000..7b9e2e4
--- /dev/null
+++ b/src/resources/agents/auth/runs.ts
@@ -0,0 +1,125 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../../core/resource';
+import * as AuthAPI from './auth';
+import { APIPromise } from '../../../core/api-promise';
+import { RequestOptions } from '../../../internal/request-options';
+import { path } from '../../../internal/utils/path';
+
+export class Runs extends APIResource {
+ /**
+ * Returns run details including app_name and target_domain. Uses the JWT returned
+ * by the exchange endpoint, or standard API key or JWT authentication.
+ *
+ * @example
+ * ```ts
+ * const agentAuthRunResponse =
+ * await client.agents.auth.runs.retrieve('run_id');
+ * ```
+ */
+ retrieve(runID: string, options?: RequestOptions): APIPromise {
+ return this._client.get(path`/agents/auth/runs/${runID}`, options);
+ }
+
+ /**
+ * Inspects the target site to detect logged-in state or discover required fields.
+ * Returns 200 with success: true when fields are found, or 4xx/5xx for failures.
+ * Requires the JWT returned by the exchange endpoint.
+ *
+ * @example
+ * ```ts
+ * const agentAuthDiscoverResponse =
+ * await client.agents.auth.runs.discover('run_id');
+ * ```
+ */
+ discover(
+ runID: string,
+ body?: RunDiscoverParams | null | undefined,
+ options?: RequestOptions,
+ ): APIPromise {
+ return this._client.post(path`/agents/auth/runs/${runID}/discover`, { body, ...options });
+ }
+
+ /**
+ * Validates the handoff code and returns a JWT token for subsequent requests. No
+ * authentication required (the handoff code serves as the credential).
+ *
+ * @example
+ * ```ts
+ * const response = await client.agents.auth.runs.exchange(
+ * 'run_id',
+ * { code: 'otp_abc123xyz' },
+ * );
+ * ```
+ */
+ exchange(
+ runID: string,
+ body: RunExchangeParams,
+ options?: RequestOptions,
+ ): APIPromise {
+ return this._client.post(path`/agents/auth/runs/${runID}/exchange`, { body, ...options });
+ }
+
+ /**
+ * Submits field values for the discovered login form and may return additional
+ * auth fields or success. Requires the JWT returned by the exchange endpoint.
+ *
+ * @example
+ * ```ts
+ * const agentAuthSubmitResponse =
+ * await client.agents.auth.runs.submit('run_id', {
+ * field_values: {
+ * email: 'user@example.com',
+ * password: '********',
+ * },
+ * });
+ * ```
+ */
+ submit(
+ runID: string,
+ body: RunSubmitParams,
+ options?: RequestOptions,
+ ): APIPromise {
+ return this._client.post(path`/agents/auth/runs/${runID}/submit`, { body, ...options });
+ }
+}
+
+/**
+ * Response from exchange endpoint
+ */
+export interface RunExchangeResponse {
+ /**
+ * JWT token with run_id claim (30 minute TTL)
+ */
+ jwt: string;
+
+ /**
+ * Run ID
+ */
+ run_id: string;
+}
+
+export interface RunDiscoverParams {}
+
+export interface RunExchangeParams {
+ /**
+ * Handoff code from start endpoint
+ */
+ code: string;
+}
+
+export interface RunSubmitParams {
+ /**
+ * Values for the discovered login fields
+ */
+ field_values: { [key: string]: string };
+}
+
+export declare namespace Runs {
+ export {
+ type RunExchangeResponse as RunExchangeResponse,
+ type RunDiscoverParams as RunDiscoverParams,
+ type RunExchangeParams as RunExchangeParams,
+ type RunSubmitParams as RunSubmitParams,
+ };
+}
diff --git a/src/resources/agents/index.ts b/src/resources/agents/index.ts
new file mode 100644
index 0000000..c5647b7
--- /dev/null
+++ b/src/resources/agents/index.ts
@@ -0,0 +1,12 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export { Agents } from './agents';
+export {
+ Auth,
+ type AgentAuthDiscoverResponse,
+ type AgentAuthRunResponse,
+ type AgentAuthStartResponse,
+ type AgentAuthSubmitResponse,
+ type DiscoveredField,
+ type AuthStartParams,
+} from './auth/index';
diff --git a/src/resources/index.ts b/src/resources/index.ts
index 69c693d..3e3fce4 100644
--- a/src/resources/index.ts
+++ b/src/resources/index.ts
@@ -1,6 +1,7 @@
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
export * from './shared';
+export { Agents } from './agents/agents';
export {
Apps,
type AppListResponse,
diff --git a/tests/api-resources/agents/auth/auth.test.ts b/tests/api-resources/agents/auth/auth.test.ts
new file mode 100644
index 0000000..8d0224c
--- /dev/null
+++ b/tests/api-resources/agents/auth/auth.test.ts
@@ -0,0 +1,35 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import Kernel from '@onkernel/sdk';
+
+const client = new Kernel({
+ apiKey: 'My API Key',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('resource auth', () => {
+ // Prism tests are disabled
+ test.skip('start: only required params', async () => {
+ const responsePromise = client.agents.auth.start({
+ profile_name: 'auth-abc123',
+ target_domain: 'doordash.com',
+ });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ // Prism tests are disabled
+ test.skip('start: required and optional params', async () => {
+ const response = await client.agents.auth.start({
+ profile_name: 'auth-abc123',
+ target_domain: 'doordash.com',
+ app_logo_url: 'https://example.com/logo.png',
+ proxy: { proxy_id: 'proxy_id' },
+ });
+ });
+});
diff --git a/tests/api-resources/agents/auth/runs.test.ts b/tests/api-resources/agents/auth/runs.test.ts
new file mode 100644
index 0000000..c3e8b4b
--- /dev/null
+++ b/tests/api-resources/agents/auth/runs.test.ts
@@ -0,0 +1,80 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import Kernel from '@onkernel/sdk';
+
+const client = new Kernel({
+ apiKey: 'My API Key',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('resource runs', () => {
+ // Prism tests are disabled
+ test.skip('retrieve', async () => {
+ const responsePromise = client.agents.auth.runs.retrieve('run_id');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ // Prism tests are disabled
+ test.skip('discover', async () => {
+ const responsePromise = client.agents.auth.runs.discover('run_id');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ // Prism tests are disabled
+ test.skip('discover: request options and params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(
+ client.agents.auth.runs.discover('run_id', {}, { path: '/_stainless_unknown_path' }),
+ ).rejects.toThrow(Kernel.NotFoundError);
+ });
+
+ // Prism tests are disabled
+ test.skip('exchange: only required params', async () => {
+ const responsePromise = client.agents.auth.runs.exchange('run_id', { code: 'otp_abc123xyz' });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ // Prism tests are disabled
+ test.skip('exchange: required and optional params', async () => {
+ const response = await client.agents.auth.runs.exchange('run_id', { code: 'otp_abc123xyz' });
+ });
+
+ // Prism tests are disabled
+ test.skip('submit: only required params', async () => {
+ const responsePromise = client.agents.auth.runs.submit('run_id', {
+ field_values: { email: 'user@example.com', password: '********' },
+ });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ // Prism tests are disabled
+ test.skip('submit: required and optional params', async () => {
+ const response = await client.agents.auth.runs.submit('run_id', {
+ field_values: { email: 'user@example.com', password: '********' },
+ });
+ });
+});
From 6a38db078fe5d6a8818ea5bab18431bde011ad38 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 25 Nov 2025 18:13:27 +0000
Subject: [PATCH 2/8] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index bdbede3..fa4f900 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 71
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-bb3f37e55117a56e7a4208bd646d3a68adeb651ced8531e13fbfc1fc9dcb05a4.yml
-openapi_spec_hash: 7303ce8ce3130e16a6a5c2bb49e43e9b
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-ae9ed0d949aa701dd3873e49080fe923404a8869ffcb69b7c912a3f244d0236d.yml
+openapi_spec_hash: 654d6e13a8bfe2103b373c668f43b33d
config_hash: be146470fb2d4583b6533859f0fa48f5
From dc0e1941590ab7cd83489db42c28e08fdbf19172 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 26 Nov 2025 00:27:30 +0000
Subject: [PATCH 3/8] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index fa4f900..541095f 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 71
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-ae9ed0d949aa701dd3873e49080fe923404a8869ffcb69b7c912a3f244d0236d.yml
-openapi_spec_hash: 654d6e13a8bfe2103b373c668f43b33d
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-2a63841293bec1bb651c5a24a95b2e9b5c07851dec1164de1aa2f87dafc51046.yml
+openapi_spec_hash: d0bb3ca22c10b79758d503f717dd8e2f
config_hash: be146470fb2d4583b6533859f0fa48f5
From fe57be149a65b2f44e52d7b2a2ecfd8989694247 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 2 Dec 2025 01:22:14 +0000
Subject: [PATCH 4/8] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 541095f..a6b35ee 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 71
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-2a63841293bec1bb651c5a24a95b2e9b5c07851dec1164de1aa2f87dafc51046.yml
-openapi_spec_hash: d0bb3ca22c10b79758d503f717dd8e2f
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-92b20a9e4650f645d3bb23b64f4ae72287bb41d3922ff1371426a91879186362.yml
+openapi_spec_hash: a3c5f41d36734c980bc5313ee60b97cf
config_hash: be146470fb2d4583b6533859f0fa48f5
From 426b7b4d79357fcae88807aad49718c26eb02044 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 2 Dec 2025 04:13:44 +0000
Subject: [PATCH 5/8] chore(client): fix logger property type
---
src/client.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/client.ts b/src/client.ts
index 9d3ad81..81e9b73 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -187,7 +187,7 @@ export class Kernel {
baseURL: string;
maxRetries: number;
timeout: number;
- logger: Logger | undefined;
+ logger: Logger;
logLevel: LogLevel | undefined;
fetchOptions: MergedRequestInit | undefined;
From 0fca0c8145e7a9938a9ebe20eeac19eb9d3e4e82 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 2 Dec 2025 20:24:35 +0000
Subject: [PATCH 6/8] feat: Browser pools sdk release
---
.stats.yml | 8 +-
api.md | 41 +-
src/client.ts | 39 +-
src/resources/agents.ts | 3 -
src/resources/agents/agents.ts | 31 -
src/resources/agents/auth.ts | 3 -
src/resources/agents/auth/auth.ts | 245 --------
src/resources/agents/auth/index.ts | 18 -
src/resources/agents/auth/runs.ts | 125 -----
src/resources/agents/index.ts | 12 -
src/resources/browser-pools.ts | 560 +++++++++++++++++++
src/resources/browsers/browsers.ts | 174 +-----
src/resources/index.ts | 16 +-
src/resources/shared.ts | 69 +++
tests/api-resources/agents/auth/auth.test.ts | 35 --
tests/api-resources/agents/auth/runs.test.ts | 80 ---
tests/api-resources/browser-pools.test.ts | 159 ++++++
17 files changed, 868 insertions(+), 750 deletions(-)
delete mode 100644 src/resources/agents.ts
delete mode 100644 src/resources/agents/agents.ts
delete mode 100644 src/resources/agents/auth.ts
delete mode 100644 src/resources/agents/auth/auth.ts
delete mode 100644 src/resources/agents/auth/index.ts
delete mode 100644 src/resources/agents/auth/runs.ts
delete mode 100644 src/resources/agents/index.ts
create mode 100644 src/resources/browser-pools.ts
delete mode 100644 tests/api-resources/agents/auth/auth.test.ts
delete mode 100644 tests/api-resources/agents/auth/runs.test.ts
create mode 100644 tests/api-resources/browser-pools.test.ts
diff --git a/.stats.yml b/.stats.yml
index a6b35ee..c32f96d 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 71
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-92b20a9e4650f645d3bb23b64f4ae72287bb41d3922ff1371426a91879186362.yml
-openapi_spec_hash: a3c5f41d36734c980bc5313ee60b97cf
-config_hash: be146470fb2d4583b6533859f0fa48f5
+configured_endpoints: 74
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-340c8f009b71922347d4c238c8715cd752c8965abfa12cbb1ffabe35edc338a8.yml
+openapi_spec_hash: efc13ab03ef89cc07333db8ab5345f31
+config_hash: a4124701ae0a474e580d7416adbcfb00
diff --git a/api.md b/api.md
index b16b435..c3c1b6e 100644
--- a/api.md
+++ b/api.md
@@ -3,6 +3,9 @@
Types:
- AppAction
+- BrowserExtension
+- BrowserProfile
+- BrowserViewport
- ErrorDetail
- ErrorEvent
- ErrorModel
@@ -221,31 +224,25 @@ Methods:
- client.extensions.downloadFromChromeStore({ ...params }) -> Response
- client.extensions.upload({ ...params }) -> ExtensionUploadResponse
-# Agents
-
-## Auth
-
-Types:
-
-- AgentAuthDiscoverResponse
-- AgentAuthRunResponse
-- AgentAuthStartResponse
-- AgentAuthSubmitResponse
-- DiscoveredField
-
-Methods:
-
-- client.agents.auth.start({ ...params }) -> AgentAuthStartResponse
-
-### Runs
+# BrowserPools
Types:
-- RunExchangeResponse
+- BrowserPool
+- BrowserPoolAcquireRequest
+- BrowserPoolReleaseRequest
+- BrowserPoolRequest
+- BrowserPoolUpdateRequest
+- BrowserPoolListResponse
+- BrowserPoolAcquireResponse
Methods:
-- client.agents.auth.runs.retrieve(runID) -> AgentAuthRunResponse
-- client.agents.auth.runs.discover(runID) -> AgentAuthDiscoverResponse
-- client.agents.auth.runs.exchange(runID, { ...params }) -> RunExchangeResponse
-- client.agents.auth.runs.submit(runID, { ...params }) -> AgentAuthSubmitResponse
+- client.browserPools.create({ ...params }) -> BrowserPool
+- client.browserPools.retrieve(idOrName) -> BrowserPool
+- client.browserPools.update(idOrName, { ...params }) -> BrowserPool
+- client.browserPools.list() -> BrowserPoolListResponse
+- client.browserPools.delete(idOrName, { ...params }) -> void
+- client.browserPools.acquire(idOrName, { ...params }) -> BrowserPoolAcquireResponse
+- client.browserPools.flush(idOrName) -> void
+- client.browserPools.release(idOrName, { ...params }) -> void
diff --git a/src/client.ts b/src/client.ts
index 81e9b73..a0dffa0 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -19,6 +19,21 @@ import * as Uploads from './core/uploads';
import * as API from './resources/index';
import { APIPromise } from './core/api-promise';
import { AppListParams, AppListResponse, AppListResponsesOffsetPagination, Apps } from './resources/apps';
+import {
+ BrowserPool,
+ BrowserPoolAcquireParams,
+ BrowserPoolAcquireRequest,
+ BrowserPoolAcquireResponse,
+ BrowserPoolCreateParams,
+ BrowserPoolDeleteParams,
+ BrowserPoolListResponse,
+ BrowserPoolReleaseParams,
+ BrowserPoolReleaseRequest,
+ BrowserPoolRequest,
+ BrowserPoolUpdateParams,
+ BrowserPoolUpdateRequest,
+ BrowserPools,
+} from './resources/browser-pools';
import {
DeploymentCreateParams,
DeploymentCreateResponse,
@@ -61,7 +76,6 @@ import {
ProxyListResponse,
ProxyRetrieveResponse,
} from './resources/proxies';
-import { Agents } from './resources/agents/agents';
import {
BrowserCreateParams,
BrowserCreateResponse,
@@ -844,7 +858,7 @@ export class Kernel {
profiles: API.Profiles = new API.Profiles(this);
proxies: API.Proxies = new API.Proxies(this);
extensions: API.Extensions = new API.Extensions(this);
- agents: API.Agents = new API.Agents(this);
+ browserPools: API.BrowserPools = new API.BrowserPools(this);
}
Kernel.Deployments = Deployments;
@@ -854,7 +868,7 @@ Kernel.Browsers = Browsers;
Kernel.Profiles = Profiles;
Kernel.Proxies = Proxies;
Kernel.Extensions = Extensions;
-Kernel.Agents = Agents;
+Kernel.BrowserPools = BrowserPools;
export declare namespace Kernel {
export type RequestOptions = Opts.RequestOptions;
@@ -936,9 +950,26 @@ export declare namespace Kernel {
type ExtensionUploadParams as ExtensionUploadParams,
};
- export { Agents as Agents };
+ export {
+ BrowserPools as BrowserPools,
+ type BrowserPool as BrowserPool,
+ type BrowserPoolAcquireRequest as BrowserPoolAcquireRequest,
+ type BrowserPoolReleaseRequest as BrowserPoolReleaseRequest,
+ type BrowserPoolRequest as BrowserPoolRequest,
+ type BrowserPoolUpdateRequest as BrowserPoolUpdateRequest,
+ type BrowserPoolListResponse as BrowserPoolListResponse,
+ type BrowserPoolAcquireResponse as BrowserPoolAcquireResponse,
+ type BrowserPoolCreateParams as BrowserPoolCreateParams,
+ type BrowserPoolUpdateParams as BrowserPoolUpdateParams,
+ type BrowserPoolDeleteParams as BrowserPoolDeleteParams,
+ type BrowserPoolAcquireParams as BrowserPoolAcquireParams,
+ type BrowserPoolReleaseParams as BrowserPoolReleaseParams,
+ };
export type AppAction = API.AppAction;
+ export type BrowserExtension = API.BrowserExtension;
+ export type BrowserProfile = API.BrowserProfile;
+ export type BrowserViewport = API.BrowserViewport;
export type ErrorDetail = API.ErrorDetail;
export type ErrorEvent = API.ErrorEvent;
export type ErrorModel = API.ErrorModel;
diff --git a/src/resources/agents.ts b/src/resources/agents.ts
deleted file mode 100644
index 0c43db0..0000000
--- a/src/resources/agents.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-export * from './agents/index';
diff --git a/src/resources/agents/agents.ts b/src/resources/agents/agents.ts
deleted file mode 100644
index 67fd75b..0000000
--- a/src/resources/agents/agents.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { APIResource } from '../../core/resource';
-import * as AuthAPI from './auth/auth';
-import {
- AgentAuthDiscoverResponse,
- AgentAuthRunResponse,
- AgentAuthStartResponse,
- AgentAuthSubmitResponse,
- Auth,
- AuthStartParams,
- DiscoveredField,
-} from './auth/auth';
-
-export class Agents extends APIResource {
- auth: AuthAPI.Auth = new AuthAPI.Auth(this._client);
-}
-
-Agents.Auth = Auth;
-
-export declare namespace Agents {
- export {
- Auth as Auth,
- type AgentAuthDiscoverResponse as AgentAuthDiscoverResponse,
- type AgentAuthRunResponse as AgentAuthRunResponse,
- type AgentAuthStartResponse as AgentAuthStartResponse,
- type AgentAuthSubmitResponse as AgentAuthSubmitResponse,
- type DiscoveredField as DiscoveredField,
- type AuthStartParams as AuthStartParams,
- };
-}
diff --git a/src/resources/agents/auth.ts b/src/resources/agents/auth.ts
deleted file mode 100644
index b64faa1..0000000
--- a/src/resources/agents/auth.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-export * from './auth/index';
diff --git a/src/resources/agents/auth/auth.ts b/src/resources/agents/auth/auth.ts
deleted file mode 100644
index a97ee3b..0000000
--- a/src/resources/agents/auth/auth.ts
+++ /dev/null
@@ -1,245 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { APIResource } from '../../../core/resource';
-import * as RunsAPI from './runs';
-import { RunDiscoverParams, RunExchangeParams, RunExchangeResponse, RunSubmitParams, Runs } from './runs';
-import { APIPromise } from '../../../core/api-promise';
-import { RequestOptions } from '../../../internal/request-options';
-
-export class Auth extends APIResource {
- runs: RunsAPI.Runs = new RunsAPI.Runs(this._client);
-
- /**
- * Creates a browser session and returns a handoff code for the hosted flow. Uses
- * standard API key or JWT authentication (not the JWT returned by the exchange
- * endpoint).
- *
- * @example
- * ```ts
- * const agentAuthStartResponse =
- * await client.agents.auth.start({
- * profile_name: 'auth-abc123',
- * target_domain: 'doordash.com',
- * });
- * ```
- */
- start(body: AuthStartParams, options?: RequestOptions): APIPromise {
- return this._client.post('/agents/auth/start', { body, ...options });
- }
-}
-
-/**
- * Response from discover endpoint matching AuthBlueprint schema
- */
-export interface AgentAuthDiscoverResponse {
- /**
- * Whether discovery succeeded
- */
- success: boolean;
-
- /**
- * Error message if discovery failed
- */
- error_message?: string;
-
- /**
- * Discovered form fields (present when success is true)
- */
- fields?: Array;
-
- /**
- * Whether user is already logged in
- */
- logged_in?: boolean;
-
- /**
- * URL of the discovered login page
- */
- login_url?: string;
-
- /**
- * Title of the login page
- */
- page_title?: string;
-}
-
-/**
- * Response from get run endpoint
- */
-export interface AgentAuthRunResponse {
- /**
- * App name (org name at time of run creation)
- */
- app_name: string;
-
- /**
- * When the handoff code expires
- */
- expires_at: string;
-
- /**
- * Run status
- */
- status: 'ACTIVE' | 'ENDED' | 'EXPIRED' | 'CANCELED';
-
- /**
- * Target domain for authentication
- */
- target_domain: string;
-}
-
-/**
- * Response from starting an agent authentication run
- */
-export interface AgentAuthStartResponse {
- /**
- * When the handoff code expires
- */
- expires_at: string;
-
- /**
- * One-time code for handoff
- */
- handoff_code: string;
-
- /**
- * URL to redirect user to
- */
- hosted_url: string;
-
- /**
- * Unique identifier for the run
- */
- run_id: string;
-}
-
-/**
- * Response from submit endpoint matching SubmitResult schema
- */
-export interface AgentAuthSubmitResponse {
- /**
- * Whether submission succeeded
- */
- success: boolean;
-
- /**
- * Additional fields needed (e.g., OTP) - present when needs_additional_auth is
- * true
- */
- additional_fields?: Array;
-
- /**
- * App name (only present when logged_in is true)
- */
- app_name?: string;
-
- /**
- * Error message if submission failed
- */
- error_message?: string;
-
- /**
- * Whether user is now logged in
- */
- logged_in?: boolean;
-
- /**
- * Whether additional authentication fields are needed
- */
- needs_additional_auth?: boolean;
-
- /**
- * Target domain (only present when logged_in is true)
- */
- target_domain?: string;
-}
-
-/**
- * A discovered form field
- */
-export interface DiscoveredField {
- /**
- * Field label
- */
- label: string;
-
- /**
- * Field name
- */
- name: string;
-
- /**
- * CSS selector for the field
- */
- selector: string;
-
- /**
- * Field type
- */
- type: 'text' | 'email' | 'password' | 'tel' | 'number' | 'url' | 'code' | 'checkbox';
-
- /**
- * Field placeholder
- */
- placeholder?: string;
-
- /**
- * Whether field is required
- */
- required?: boolean;
-}
-
-export interface AuthStartParams {
- /**
- * Name of the profile to use for this flow
- */
- profile_name: string;
-
- /**
- * Target domain for authentication
- */
- target_domain: string;
-
- /**
- * Optional logo URL for the application
- */
- app_logo_url?: string;
-
- /**
- * Optional proxy configuration
- */
- proxy?: AuthStartParams.Proxy;
-}
-
-export namespace AuthStartParams {
- /**
- * Optional proxy configuration
- */
- export interface Proxy {
- /**
- * ID of the proxy to use
- */
- proxy_id?: string;
- }
-}
-
-Auth.Runs = Runs;
-
-export declare namespace Auth {
- export {
- type AgentAuthDiscoverResponse as AgentAuthDiscoverResponse,
- type AgentAuthRunResponse as AgentAuthRunResponse,
- type AgentAuthStartResponse as AgentAuthStartResponse,
- type AgentAuthSubmitResponse as AgentAuthSubmitResponse,
- type DiscoveredField as DiscoveredField,
- type AuthStartParams as AuthStartParams,
- };
-
- export {
- Runs as Runs,
- type RunExchangeResponse as RunExchangeResponse,
- type RunDiscoverParams as RunDiscoverParams,
- type RunExchangeParams as RunExchangeParams,
- type RunSubmitParams as RunSubmitParams,
- };
-}
diff --git a/src/resources/agents/auth/index.ts b/src/resources/agents/auth/index.ts
deleted file mode 100644
index 904c0ce..0000000
--- a/src/resources/agents/auth/index.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-export {
- Auth,
- type AgentAuthDiscoverResponse,
- type AgentAuthRunResponse,
- type AgentAuthStartResponse,
- type AgentAuthSubmitResponse,
- type DiscoveredField,
- type AuthStartParams,
-} from './auth';
-export {
- Runs,
- type RunExchangeResponse,
- type RunDiscoverParams,
- type RunExchangeParams,
- type RunSubmitParams,
-} from './runs';
diff --git a/src/resources/agents/auth/runs.ts b/src/resources/agents/auth/runs.ts
deleted file mode 100644
index 7b9e2e4..0000000
--- a/src/resources/agents/auth/runs.ts
+++ /dev/null
@@ -1,125 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { APIResource } from '../../../core/resource';
-import * as AuthAPI from './auth';
-import { APIPromise } from '../../../core/api-promise';
-import { RequestOptions } from '../../../internal/request-options';
-import { path } from '../../../internal/utils/path';
-
-export class Runs extends APIResource {
- /**
- * Returns run details including app_name and target_domain. Uses the JWT returned
- * by the exchange endpoint, or standard API key or JWT authentication.
- *
- * @example
- * ```ts
- * const agentAuthRunResponse =
- * await client.agents.auth.runs.retrieve('run_id');
- * ```
- */
- retrieve(runID: string, options?: RequestOptions): APIPromise {
- return this._client.get(path`/agents/auth/runs/${runID}`, options);
- }
-
- /**
- * Inspects the target site to detect logged-in state or discover required fields.
- * Returns 200 with success: true when fields are found, or 4xx/5xx for failures.
- * Requires the JWT returned by the exchange endpoint.
- *
- * @example
- * ```ts
- * const agentAuthDiscoverResponse =
- * await client.agents.auth.runs.discover('run_id');
- * ```
- */
- discover(
- runID: string,
- body?: RunDiscoverParams | null | undefined,
- options?: RequestOptions,
- ): APIPromise {
- return this._client.post(path`/agents/auth/runs/${runID}/discover`, { body, ...options });
- }
-
- /**
- * Validates the handoff code and returns a JWT token for subsequent requests. No
- * authentication required (the handoff code serves as the credential).
- *
- * @example
- * ```ts
- * const response = await client.agents.auth.runs.exchange(
- * 'run_id',
- * { code: 'otp_abc123xyz' },
- * );
- * ```
- */
- exchange(
- runID: string,
- body: RunExchangeParams,
- options?: RequestOptions,
- ): APIPromise {
- return this._client.post(path`/agents/auth/runs/${runID}/exchange`, { body, ...options });
- }
-
- /**
- * Submits field values for the discovered login form and may return additional
- * auth fields or success. Requires the JWT returned by the exchange endpoint.
- *
- * @example
- * ```ts
- * const agentAuthSubmitResponse =
- * await client.agents.auth.runs.submit('run_id', {
- * field_values: {
- * email: 'user@example.com',
- * password: '********',
- * },
- * });
- * ```
- */
- submit(
- runID: string,
- body: RunSubmitParams,
- options?: RequestOptions,
- ): APIPromise {
- return this._client.post(path`/agents/auth/runs/${runID}/submit`, { body, ...options });
- }
-}
-
-/**
- * Response from exchange endpoint
- */
-export interface RunExchangeResponse {
- /**
- * JWT token with run_id claim (30 minute TTL)
- */
- jwt: string;
-
- /**
- * Run ID
- */
- run_id: string;
-}
-
-export interface RunDiscoverParams {}
-
-export interface RunExchangeParams {
- /**
- * Handoff code from start endpoint
- */
- code: string;
-}
-
-export interface RunSubmitParams {
- /**
- * Values for the discovered login fields
- */
- field_values: { [key: string]: string };
-}
-
-export declare namespace Runs {
- export {
- type RunExchangeResponse as RunExchangeResponse,
- type RunDiscoverParams as RunDiscoverParams,
- type RunExchangeParams as RunExchangeParams,
- type RunSubmitParams as RunSubmitParams,
- };
-}
diff --git a/src/resources/agents/index.ts b/src/resources/agents/index.ts
deleted file mode 100644
index c5647b7..0000000
--- a/src/resources/agents/index.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-export { Agents } from './agents';
-export {
- Auth,
- type AgentAuthDiscoverResponse,
- type AgentAuthRunResponse,
- type AgentAuthStartResponse,
- type AgentAuthSubmitResponse,
- type DiscoveredField,
- type AuthStartParams,
-} from './auth/index';
diff --git a/src/resources/browser-pools.ts b/src/resources/browser-pools.ts
new file mode 100644
index 0000000..be28ad0
--- /dev/null
+++ b/src/resources/browser-pools.ts
@@ -0,0 +1,560 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../core/resource';
+import * as Shared from './shared';
+import * as BrowsersAPI from './browsers/browsers';
+import { APIPromise } from '../core/api-promise';
+import { buildHeaders } from '../internal/headers';
+import { RequestOptions } from '../internal/request-options';
+import { path } from '../internal/utils/path';
+
+export class BrowserPools extends APIResource {
+ /**
+ * Create a new browser pool with the specified configuration and size.
+ *
+ * @example
+ * ```ts
+ * const browserPool = await client.browserPools.create({
+ * size: 10,
+ * });
+ * ```
+ */
+ create(body: BrowserPoolCreateParams, options?: RequestOptions): APIPromise {
+ return this._client.post('/browser_pools', { body, ...options });
+ }
+
+ /**
+ * Retrieve details for a single browser pool by its ID or name.
+ *
+ * @example
+ * ```ts
+ * const browserPool = await client.browserPools.retrieve(
+ * 'id_or_name',
+ * );
+ * ```
+ */
+ retrieve(idOrName: string, options?: RequestOptions): APIPromise {
+ return this._client.get(path`/browser_pools/${idOrName}`, options);
+ }
+
+ /**
+ * Updates the configuration used to create browsers in the pool.
+ *
+ * @example
+ * ```ts
+ * const browserPool = await client.browserPools.update(
+ * 'id_or_name',
+ * { size: 10 },
+ * );
+ * ```
+ */
+ update(idOrName: string, body: BrowserPoolUpdateParams, options?: RequestOptions): APIPromise {
+ return this._client.patch(path`/browser_pools/${idOrName}`, { body, ...options });
+ }
+
+ /**
+ * List browser pools owned by the caller's organization.
+ *
+ * @example
+ * ```ts
+ * const browserPools = await client.browserPools.list();
+ * ```
+ */
+ list(options?: RequestOptions): APIPromise {
+ return this._client.get('/browser_pools', options);
+ }
+
+ /**
+ * Delete a browser pool and all browsers in it. By default, deletion is blocked if
+ * browsers are currently leased. Use force=true to terminate leased browsers.
+ *
+ * @example
+ * ```ts
+ * await client.browserPools.delete('id_or_name');
+ * ```
+ */
+ delete(
+ idOrName: string,
+ body: BrowserPoolDeleteParams | null | undefined = {},
+ options?: RequestOptions,
+ ): APIPromise {
+ return this._client.delete(path`/browser_pools/${idOrName}`, {
+ body,
+ ...options,
+ headers: buildHeaders([{ Accept: '*/*' }, options?.headers]),
+ });
+ }
+
+ /**
+ * Long-polling endpoint to acquire a browser from the pool. Returns immediately
+ * when a browser is available, or returns 204 No Content when the poll times out.
+ * The client should retry the request to continue waiting for a browser. The
+ * acquired browser will use the pool's timeout_seconds for its idle timeout.
+ *
+ * @example
+ * ```ts
+ * const response = await client.browserPools.acquire(
+ * 'id_or_name',
+ * );
+ * ```
+ */
+ acquire(
+ idOrName: string,
+ body: BrowserPoolAcquireParams,
+ options?: RequestOptions,
+ ): APIPromise {
+ return this._client.post(path`/browser_pools/${idOrName}/acquire`, { body, ...options });
+ }
+
+ /**
+ * Destroys all idle browsers in the pool; leased browsers are not affected.
+ *
+ * @example
+ * ```ts
+ * await client.browserPools.flush('id_or_name');
+ * ```
+ */
+ flush(idOrName: string, options?: RequestOptions): APIPromise {
+ return this._client.post(path`/browser_pools/${idOrName}/flush`, {
+ ...options,
+ headers: buildHeaders([{ Accept: '*/*' }, options?.headers]),
+ });
+ }
+
+ /**
+ * Release a browser back to the pool, optionally recreating the browser instance.
+ *
+ * @example
+ * ```ts
+ * await client.browserPools.release('id_or_name', {
+ * session_id: 'ts8iy3sg25ibheguyni2lg9t',
+ * });
+ * ```
+ */
+ release(idOrName: string, body: BrowserPoolReleaseParams, options?: RequestOptions): APIPromise {
+ return this._client.post(path`/browser_pools/${idOrName}/release`, {
+ body,
+ ...options,
+ headers: buildHeaders([{ Accept: '*/*' }, options?.headers]),
+ });
+ }
+}
+
+/**
+ * A browser pool containing multiple identically configured browsers.
+ */
+export interface BrowserPool {
+ /**
+ * Unique identifier for the browser pool
+ */
+ id: string;
+
+ /**
+ * Number of browsers currently acquired from the pool
+ */
+ acquired_count: number;
+
+ /**
+ * Number of browsers currently available in the pool
+ */
+ available_count: number;
+
+ /**
+ * Configuration used to create all browsers in this pool
+ */
+ browser_pool_config: BrowserPoolRequest;
+
+ /**
+ * Timestamp when the browser pool was created
+ */
+ created_at: string;
+
+ /**
+ * Browser pool name, if set
+ */
+ name?: string;
+}
+
+/**
+ * Request body for acquiring a browser from the pool.
+ */
+export interface BrowserPoolAcquireRequest {
+ /**
+ * Maximum number of seconds to wait for a browser to be available. Defaults to the
+ * calculated time it would take to fill the pool at the currently configured fill
+ * rate.
+ */
+ acquire_timeout_seconds?: number;
+}
+
+/**
+ * Request body for releasing a browser back to the pool.
+ */
+export interface BrowserPoolReleaseRequest {
+ /**
+ * Browser session ID to release back to the pool
+ */
+ session_id: string;
+
+ /**
+ * Whether to reuse the browser instance or destroy it and create a new one.
+ * Defaults to true.
+ */
+ reuse?: boolean;
+}
+
+/**
+ * Parameters for creating a browser pool. All browsers in the pool will be created
+ * with the same configuration.
+ */
+export interface BrowserPoolRequest {
+ /**
+ * Number of browsers to create in the pool
+ */
+ size: number;
+
+ /**
+ * List of browser extensions to load into the session. Provide each by id or name.
+ */
+ extensions?: Array;
+
+ /**
+ * Percentage of the pool to fill per minute. Defaults to 10%.
+ */
+ fill_rate_per_minute?: number;
+
+ /**
+ * If true, launches the browser using a headless image. Defaults to false.
+ */
+ headless?: boolean;
+
+ /**
+ * If true, launches the browser in kiosk mode to hide address bar and tabs in live
+ * view.
+ */
+ kiosk_mode?: boolean;
+
+ /**
+ * Optional name for the browser pool. Must be unique within the organization.
+ */
+ name?: string;
+
+ /**
+ * Profile selection for the browser session. Provide either id or name. If
+ * specified, the matching profile will be loaded into the browser session.
+ * Profiles must be created beforehand.
+ */
+ profile?: Shared.BrowserProfile;
+
+ /**
+ * Optional proxy to associate to the browser session. Must reference a proxy
+ * belonging to the caller's org.
+ */
+ proxy_id?: string;
+
+ /**
+ * If true, launches the browser in stealth mode to reduce detection by anti-bot
+ * mechanisms.
+ */
+ stealth?: boolean;
+
+ /**
+ * Default idle timeout in seconds for browsers acquired from this pool before they
+ * are destroyed. Defaults to 600 seconds if not specified
+ */
+ timeout_seconds?: number;
+
+ /**
+ * Initial browser window size in pixels with optional refresh rate. If omitted,
+ * image defaults apply (commonly 1024x768@60). Only specific viewport
+ * configurations are supported. The server will reject unsupported combinations.
+ * Supported resolutions are: 2560x1440@10, 1920x1080@25, 1920x1200@25,
+ * 1440x900@25, 1024x768@60, 1200x800@60 If refresh_rate is not provided, it will
+ * be automatically determined from the width and height if they match a supported
+ * configuration exactly. Note: Higher resolutions may affect the responsiveness of
+ * live view browser
+ */
+ viewport?: Shared.BrowserViewport;
+}
+
+/**
+ * Parameters for updating a browser pool. All browsers in the pool will be created
+ * with the same configuration.
+ */
+export interface BrowserPoolUpdateRequest extends BrowserPoolRequest {
+ /**
+ * Whether to discard all idle browsers and rebuild the pool immediately. Defaults
+ * to true.
+ */
+ discard_all_idle?: boolean;
+}
+
+export type BrowserPoolListResponse = Array;
+
+export interface BrowserPoolAcquireResponse {
+ /**
+ * Websocket URL for Chrome DevTools Protocol connections to the browser session
+ */
+ cdp_ws_url: string;
+
+ /**
+ * When the browser session was created.
+ */
+ created_at: string;
+
+ /**
+ * Whether the browser session is running in headless mode.
+ */
+ headless: boolean;
+
+ /**
+ * Unique identifier for the browser session
+ */
+ session_id: string;
+
+ /**
+ * Whether the browser session is running in stealth mode.
+ */
+ stealth: boolean;
+
+ /**
+ * The number of seconds of inactivity before the browser session is terminated.
+ */
+ timeout_seconds: number;
+
+ /**
+ * Remote URL for live viewing the browser session. Only available for non-headless
+ * browsers.
+ */
+ browser_live_view_url?: string;
+
+ /**
+ * When the browser session was soft-deleted. Only present for deleted sessions.
+ */
+ deleted_at?: string;
+
+ /**
+ * Whether the browser session is running in kiosk mode.
+ */
+ kiosk_mode?: boolean;
+
+ /**
+ * Optional persistence configuration for the browser session.
+ */
+ persistence?: BrowsersAPI.BrowserPersistence;
+
+ /**
+ * Browser profile metadata.
+ */
+ profile?: BrowsersAPI.Profile;
+
+ /**
+ * ID of the proxy associated with this browser session, if any.
+ */
+ proxy_id?: string;
+
+ /**
+ * Initial browser window size in pixels with optional refresh rate. If omitted,
+ * image defaults apply (commonly 1024x768@60). Only specific viewport
+ * configurations are supported. The server will reject unsupported combinations.
+ * Supported resolutions are: 2560x1440@10, 1920x1080@25, 1920x1200@25,
+ * 1440x900@25, 1024x768@60, 1200x800@60 If refresh_rate is not provided, it will
+ * be automatically determined from the width and height if they match a supported
+ * configuration exactly. Note: Higher resolutions may affect the responsiveness of
+ * live view browser
+ */
+ viewport?: Shared.BrowserViewport;
+}
+
+export interface BrowserPoolCreateParams {
+ /**
+ * Number of browsers to create in the pool
+ */
+ size: number;
+
+ /**
+ * List of browser extensions to load into the session. Provide each by id or name.
+ */
+ extensions?: Array;
+
+ /**
+ * Percentage of the pool to fill per minute. Defaults to 10%.
+ */
+ fill_rate_per_minute?: number;
+
+ /**
+ * If true, launches the browser using a headless image. Defaults to false.
+ */
+ headless?: boolean;
+
+ /**
+ * If true, launches the browser in kiosk mode to hide address bar and tabs in live
+ * view.
+ */
+ kiosk_mode?: boolean;
+
+ /**
+ * Optional name for the browser pool. Must be unique within the organization.
+ */
+ name?: string;
+
+ /**
+ * Profile selection for the browser session. Provide either id or name. If
+ * specified, the matching profile will be loaded into the browser session.
+ * Profiles must be created beforehand.
+ */
+ profile?: Shared.BrowserProfile;
+
+ /**
+ * Optional proxy to associate to the browser session. Must reference a proxy
+ * belonging to the caller's org.
+ */
+ proxy_id?: string;
+
+ /**
+ * If true, launches the browser in stealth mode to reduce detection by anti-bot
+ * mechanisms.
+ */
+ stealth?: boolean;
+
+ /**
+ * Default idle timeout in seconds for browsers acquired from this pool before they
+ * are destroyed. Defaults to 600 seconds if not specified
+ */
+ timeout_seconds?: number;
+
+ /**
+ * Initial browser window size in pixels with optional refresh rate. If omitted,
+ * image defaults apply (commonly 1024x768@60). Only specific viewport
+ * configurations are supported. The server will reject unsupported combinations.
+ * Supported resolutions are: 2560x1440@10, 1920x1080@25, 1920x1200@25,
+ * 1440x900@25, 1024x768@60, 1200x800@60 If refresh_rate is not provided, it will
+ * be automatically determined from the width and height if they match a supported
+ * configuration exactly. Note: Higher resolutions may affect the responsiveness of
+ * live view browser
+ */
+ viewport?: Shared.BrowserViewport;
+}
+
+export interface BrowserPoolUpdateParams {
+ /**
+ * Number of browsers to create in the pool
+ */
+ size: number;
+
+ /**
+ * Whether to discard all idle browsers and rebuild the pool immediately. Defaults
+ * to true.
+ */
+ discard_all_idle?: boolean;
+
+ /**
+ * List of browser extensions to load into the session. Provide each by id or name.
+ */
+ extensions?: Array;
+
+ /**
+ * Percentage of the pool to fill per minute. Defaults to 10%.
+ */
+ fill_rate_per_minute?: number;
+
+ /**
+ * If true, launches the browser using a headless image. Defaults to false.
+ */
+ headless?: boolean;
+
+ /**
+ * If true, launches the browser in kiosk mode to hide address bar and tabs in live
+ * view.
+ */
+ kiosk_mode?: boolean;
+
+ /**
+ * Optional name for the browser pool. Must be unique within the organization.
+ */
+ name?: string;
+
+ /**
+ * Profile selection for the browser session. Provide either id or name. If
+ * specified, the matching profile will be loaded into the browser session.
+ * Profiles must be created beforehand.
+ */
+ profile?: Shared.BrowserProfile;
+
+ /**
+ * Optional proxy to associate to the browser session. Must reference a proxy
+ * belonging to the caller's org.
+ */
+ proxy_id?: string;
+
+ /**
+ * If true, launches the browser in stealth mode to reduce detection by anti-bot
+ * mechanisms.
+ */
+ stealth?: boolean;
+
+ /**
+ * Default idle timeout in seconds for browsers acquired from this pool before they
+ * are destroyed. Defaults to 600 seconds if not specified
+ */
+ timeout_seconds?: number;
+
+ /**
+ * Initial browser window size in pixels with optional refresh rate. If omitted,
+ * image defaults apply (commonly 1024x768@60). Only specific viewport
+ * configurations are supported. The server will reject unsupported combinations.
+ * Supported resolutions are: 2560x1440@10, 1920x1080@25, 1920x1200@25,
+ * 1440x900@25, 1024x768@60, 1200x800@60 If refresh_rate is not provided, it will
+ * be automatically determined from the width and height if they match a supported
+ * configuration exactly. Note: Higher resolutions may affect the responsiveness of
+ * live view browser
+ */
+ viewport?: Shared.BrowserViewport;
+}
+
+export interface BrowserPoolDeleteParams {
+ /**
+ * If true, force delete even if browsers are currently leased. Leased browsers
+ * will be terminated.
+ */
+ force?: boolean;
+}
+
+export interface BrowserPoolAcquireParams {
+ /**
+ * Maximum number of seconds to wait for a browser to be available. Defaults to the
+ * calculated time it would take to fill the pool at the currently configured fill
+ * rate.
+ */
+ acquire_timeout_seconds?: number;
+}
+
+export interface BrowserPoolReleaseParams {
+ /**
+ * Browser session ID to release back to the pool
+ */
+ session_id: string;
+
+ /**
+ * Whether to reuse the browser instance or destroy it and create a new one.
+ * Defaults to true.
+ */
+ reuse?: boolean;
+}
+
+export declare namespace BrowserPools {
+ export {
+ type BrowserPool as BrowserPool,
+ type BrowserPoolAcquireRequest as BrowserPoolAcquireRequest,
+ type BrowserPoolReleaseRequest as BrowserPoolReleaseRequest,
+ type BrowserPoolRequest as BrowserPoolRequest,
+ type BrowserPoolUpdateRequest as BrowserPoolUpdateRequest,
+ type BrowserPoolListResponse as BrowserPoolListResponse,
+ type BrowserPoolAcquireResponse as BrowserPoolAcquireResponse,
+ type BrowserPoolCreateParams as BrowserPoolCreateParams,
+ type BrowserPoolUpdateParams as BrowserPoolUpdateParams,
+ type BrowserPoolDeleteParams as BrowserPoolDeleteParams,
+ type BrowserPoolAcquireParams as BrowserPoolAcquireParams,
+ type BrowserPoolReleaseParams as BrowserPoolReleaseParams,
+ };
+}
diff --git a/src/resources/browsers/browsers.ts b/src/resources/browsers/browsers.ts
index 1c0f9bc..d3f8b3d 100644
--- a/src/resources/browsers/browsers.ts
+++ b/src/resources/browsers/browsers.ts
@@ -1,6 +1,7 @@
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
import { APIResource } from '../../core/resource';
+import * as Shared from '../shared';
import * as ComputerAPI from './computer';
import {
Computer,
@@ -302,37 +303,7 @@ export interface BrowserCreateResponse {
* configuration exactly. Note: Higher resolutions may affect the responsiveness of
* live view browser
*/
- viewport?: BrowserCreateResponse.Viewport;
-}
-
-export namespace BrowserCreateResponse {
- /**
- * Initial browser window size in pixels with optional refresh rate. If omitted,
- * image defaults apply (commonly 1024x768@60). Only specific viewport
- * configurations are supported. The server will reject unsupported combinations.
- * Supported resolutions are: 2560x1440@10, 1920x1080@25, 1920x1200@25,
- * 1440x900@25, 1024x768@60, 1200x800@60 If refresh_rate is not provided, it will
- * be automatically determined from the width and height if they match a supported
- * configuration exactly. Note: Higher resolutions may affect the responsiveness of
- * live view browser
- */
- export interface Viewport {
- /**
- * Browser window height in pixels.
- */
- height: number;
-
- /**
- * Browser window width in pixels.
- */
- width: number;
-
- /**
- * Display refresh rate in Hz. If omitted, automatically determined from width and
- * height.
- */
- refresh_rate?: number;
- }
+ viewport?: Shared.BrowserViewport;
}
export interface BrowserRetrieveResponse {
@@ -407,37 +378,7 @@ export interface BrowserRetrieveResponse {
* configuration exactly. Note: Higher resolutions may affect the responsiveness of
* live view browser
*/
- viewport?: BrowserRetrieveResponse.Viewport;
-}
-
-export namespace BrowserRetrieveResponse {
- /**
- * Initial browser window size in pixels with optional refresh rate. If omitted,
- * image defaults apply (commonly 1024x768@60). Only specific viewport
- * configurations are supported. The server will reject unsupported combinations.
- * Supported resolutions are: 2560x1440@10, 1920x1080@25, 1920x1200@25,
- * 1440x900@25, 1024x768@60, 1200x800@60 If refresh_rate is not provided, it will
- * be automatically determined from the width and height if they match a supported
- * configuration exactly. Note: Higher resolutions may affect the responsiveness of
- * live view browser
- */
- export interface Viewport {
- /**
- * Browser window height in pixels.
- */
- height: number;
-
- /**
- * Browser window width in pixels.
- */
- width: number;
-
- /**
- * Display refresh rate in Hz. If omitted, automatically determined from width and
- * height.
- */
- refresh_rate?: number;
- }
+ viewport?: Shared.BrowserViewport;
}
export interface BrowserListResponse {
@@ -512,44 +453,14 @@ export interface BrowserListResponse {
* configuration exactly. Note: Higher resolutions may affect the responsiveness of
* live view browser
*/
- viewport?: BrowserListResponse.Viewport;
-}
-
-export namespace BrowserListResponse {
- /**
- * Initial browser window size in pixels with optional refresh rate. If omitted,
- * image defaults apply (commonly 1024x768@60). Only specific viewport
- * configurations are supported. The server will reject unsupported combinations.
- * Supported resolutions are: 2560x1440@10, 1920x1080@25, 1920x1200@25,
- * 1440x900@25, 1024x768@60, 1200x800@60 If refresh_rate is not provided, it will
- * be automatically determined from the width and height if they match a supported
- * configuration exactly. Note: Higher resolutions may affect the responsiveness of
- * live view browser
- */
- export interface Viewport {
- /**
- * Browser window height in pixels.
- */
- height: number;
-
- /**
- * Browser window width in pixels.
- */
- width: number;
-
- /**
- * Display refresh rate in Hz. If omitted, automatically determined from width and
- * height.
- */
- refresh_rate?: number;
- }
+ viewport?: Shared.BrowserViewport;
}
export interface BrowserCreateParams {
/**
* List of browser extensions to load into the session. Provide each by id or name.
*/
- extensions?: Array;
+ extensions?: Array;
/**
* If true, launches the browser using a headless image (no VNC/GUI). Defaults to
@@ -578,7 +489,7 @@ export interface BrowserCreateParams {
* specified, the matching profile will be loaded into the browser session.
* Profiles must be created beforehand.
*/
- profile?: BrowserCreateParams.Profile;
+ profile?: Shared.BrowserProfile;
/**
* Optional proxy to associate to the browser session. Must reference a proxy
@@ -612,78 +523,7 @@ export interface BrowserCreateParams {
* configuration exactly. Note: Higher resolutions may affect the responsiveness of
* live view browser
*/
- viewport?: BrowserCreateParams.Viewport;
-}
-
-export namespace BrowserCreateParams {
- /**
- * Extension selection for the browser session. Provide either id or name of an
- * extension uploaded to Kernel.
- */
- export interface Extension {
- /**
- * Extension ID to load for this browser session
- */
- id?: string;
-
- /**
- * Extension name to load for this browser session (instead of id). Must be 1-255
- * characters, using letters, numbers, dots, underscores, or hyphens.
- */
- name?: string;
- }
-
- /**
- * Profile selection for the browser session. Provide either id or name. If
- * specified, the matching profile will be loaded into the browser session.
- * Profiles must be created beforehand.
- */
- export interface Profile {
- /**
- * Profile ID to load for this browser session
- */
- id?: string;
-
- /**
- * Profile name to load for this browser session (instead of id). Must be 1-255
- * characters, using letters, numbers, dots, underscores, or hyphens.
- */
- name?: string;
-
- /**
- * If true, save changes made during the session back to the profile when the
- * session ends.
- */
- save_changes?: boolean;
- }
-
- /**
- * Initial browser window size in pixels with optional refresh rate. If omitted,
- * image defaults apply (commonly 1024x768@60). Only specific viewport
- * configurations are supported. The server will reject unsupported combinations.
- * Supported resolutions are: 2560x1440@10, 1920x1080@25, 1920x1200@25,
- * 1440x900@25, 1024x768@60, 1200x800@60 If refresh_rate is not provided, it will
- * be automatically determined from the width and height if they match a supported
- * configuration exactly. Note: Higher resolutions may affect the responsiveness of
- * live view browser
- */
- export interface Viewport {
- /**
- * Browser window height in pixels.
- */
- height: number;
-
- /**
- * Browser window width in pixels.
- */
- width: number;
-
- /**
- * Display refresh rate in Hz. If omitted, automatically determined from width and
- * height.
- */
- refresh_rate?: number;
- }
+ viewport?: Shared.BrowserViewport;
}
export interface BrowserListParams extends OffsetPaginationParams {
diff --git a/src/resources/index.ts b/src/resources/index.ts
index 3e3fce4..420e5e2 100644
--- a/src/resources/index.ts
+++ b/src/resources/index.ts
@@ -1,13 +1,27 @@
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
export * from './shared';
-export { Agents } from './agents/agents';
export {
Apps,
type AppListResponse,
type AppListParams,
type AppListResponsesOffsetPagination,
} from './apps';
+export {
+ BrowserPools,
+ type BrowserPool,
+ type BrowserPoolAcquireRequest,
+ type BrowserPoolReleaseRequest,
+ type BrowserPoolRequest,
+ type BrowserPoolUpdateRequest,
+ type BrowserPoolListResponse,
+ type BrowserPoolAcquireResponse,
+ type BrowserPoolCreateParams,
+ type BrowserPoolUpdateParams,
+ type BrowserPoolDeleteParams,
+ type BrowserPoolAcquireParams,
+ type BrowserPoolReleaseParams,
+} from './browser-pools';
export {
Browsers,
type BrowserPersistence,
diff --git a/src/resources/shared.ts b/src/resources/shared.ts
index c44734e..13cbc0b 100644
--- a/src/resources/shared.ts
+++ b/src/resources/shared.ts
@@ -10,6 +10,75 @@ export interface AppAction {
name: string;
}
+/**
+ * Extension selection for the browser session. Provide either id or name of an
+ * extension uploaded to Kernel.
+ */
+export interface BrowserExtension {
+ /**
+ * Extension ID to load for this browser session
+ */
+ id?: string;
+
+ /**
+ * Extension name to load for this browser session (instead of id). Must be 1-255
+ * characters, using letters, numbers, dots, underscores, or hyphens.
+ */
+ name?: string;
+}
+
+/**
+ * Profile selection for the browser session. Provide either id or name. If
+ * specified, the matching profile will be loaded into the browser session.
+ * Profiles must be created beforehand.
+ */
+export interface BrowserProfile {
+ /**
+ * Profile ID to load for this browser session
+ */
+ id?: string;
+
+ /**
+ * Profile name to load for this browser session (instead of id). Must be 1-255
+ * characters, using letters, numbers, dots, underscores, or hyphens.
+ */
+ name?: string;
+
+ /**
+ * If true, save changes made during the session back to the profile when the
+ * session ends.
+ */
+ save_changes?: boolean;
+}
+
+/**
+ * Initial browser window size in pixels with optional refresh rate. If omitted,
+ * image defaults apply (commonly 1024x768@60). Only specific viewport
+ * configurations are supported. The server will reject unsupported combinations.
+ * Supported resolutions are: 2560x1440@10, 1920x1080@25, 1920x1200@25,
+ * 1440x900@25, 1024x768@60, 1200x800@60 If refresh_rate is not provided, it will
+ * be automatically determined from the width and height if they match a supported
+ * configuration exactly. Note: Higher resolutions may affect the responsiveness of
+ * live view browser
+ */
+export interface BrowserViewport {
+ /**
+ * Browser window height in pixels.
+ */
+ height: number;
+
+ /**
+ * Browser window width in pixels.
+ */
+ width: number;
+
+ /**
+ * Display refresh rate in Hz. If omitted, automatically determined from width and
+ * height.
+ */
+ refresh_rate?: number;
+}
+
export interface ErrorDetail {
/**
* Lower-level error code providing more specific detail
diff --git a/tests/api-resources/agents/auth/auth.test.ts b/tests/api-resources/agents/auth/auth.test.ts
deleted file mode 100644
index 8d0224c..0000000
--- a/tests/api-resources/agents/auth/auth.test.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import Kernel from '@onkernel/sdk';
-
-const client = new Kernel({
- apiKey: 'My API Key',
- baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
-});
-
-describe('resource auth', () => {
- // Prism tests are disabled
- test.skip('start: only required params', async () => {
- const responsePromise = client.agents.auth.start({
- profile_name: 'auth-abc123',
- target_domain: 'doordash.com',
- });
- const rawResponse = await responsePromise.asResponse();
- expect(rawResponse).toBeInstanceOf(Response);
- const response = await responsePromise;
- expect(response).not.toBeInstanceOf(Response);
- const dataAndResponse = await responsePromise.withResponse();
- expect(dataAndResponse.data).toBe(response);
- expect(dataAndResponse.response).toBe(rawResponse);
- });
-
- // Prism tests are disabled
- test.skip('start: required and optional params', async () => {
- const response = await client.agents.auth.start({
- profile_name: 'auth-abc123',
- target_domain: 'doordash.com',
- app_logo_url: 'https://example.com/logo.png',
- proxy: { proxy_id: 'proxy_id' },
- });
- });
-});
diff --git a/tests/api-resources/agents/auth/runs.test.ts b/tests/api-resources/agents/auth/runs.test.ts
deleted file mode 100644
index c3e8b4b..0000000
--- a/tests/api-resources/agents/auth/runs.test.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import Kernel from '@onkernel/sdk';
-
-const client = new Kernel({
- apiKey: 'My API Key',
- baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
-});
-
-describe('resource runs', () => {
- // Prism tests are disabled
- test.skip('retrieve', async () => {
- const responsePromise = client.agents.auth.runs.retrieve('run_id');
- const rawResponse = await responsePromise.asResponse();
- expect(rawResponse).toBeInstanceOf(Response);
- const response = await responsePromise;
- expect(response).not.toBeInstanceOf(Response);
- const dataAndResponse = await responsePromise.withResponse();
- expect(dataAndResponse.data).toBe(response);
- expect(dataAndResponse.response).toBe(rawResponse);
- });
-
- // Prism tests are disabled
- test.skip('discover', async () => {
- const responsePromise = client.agents.auth.runs.discover('run_id');
- const rawResponse = await responsePromise.asResponse();
- expect(rawResponse).toBeInstanceOf(Response);
- const response = await responsePromise;
- expect(response).not.toBeInstanceOf(Response);
- const dataAndResponse = await responsePromise.withResponse();
- expect(dataAndResponse.data).toBe(response);
- expect(dataAndResponse.response).toBe(rawResponse);
- });
-
- // Prism tests are disabled
- test.skip('discover: request options and params are passed correctly', async () => {
- // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
- await expect(
- client.agents.auth.runs.discover('run_id', {}, { path: '/_stainless_unknown_path' }),
- ).rejects.toThrow(Kernel.NotFoundError);
- });
-
- // Prism tests are disabled
- test.skip('exchange: only required params', async () => {
- const responsePromise = client.agents.auth.runs.exchange('run_id', { code: 'otp_abc123xyz' });
- const rawResponse = await responsePromise.asResponse();
- expect(rawResponse).toBeInstanceOf(Response);
- const response = await responsePromise;
- expect(response).not.toBeInstanceOf(Response);
- const dataAndResponse = await responsePromise.withResponse();
- expect(dataAndResponse.data).toBe(response);
- expect(dataAndResponse.response).toBe(rawResponse);
- });
-
- // Prism tests are disabled
- test.skip('exchange: required and optional params', async () => {
- const response = await client.agents.auth.runs.exchange('run_id', { code: 'otp_abc123xyz' });
- });
-
- // Prism tests are disabled
- test.skip('submit: only required params', async () => {
- const responsePromise = client.agents.auth.runs.submit('run_id', {
- field_values: { email: 'user@example.com', password: '********' },
- });
- const rawResponse = await responsePromise.asResponse();
- expect(rawResponse).toBeInstanceOf(Response);
- const response = await responsePromise;
- expect(response).not.toBeInstanceOf(Response);
- const dataAndResponse = await responsePromise.withResponse();
- expect(dataAndResponse.data).toBe(response);
- expect(dataAndResponse.response).toBe(rawResponse);
- });
-
- // Prism tests are disabled
- test.skip('submit: required and optional params', async () => {
- const response = await client.agents.auth.runs.submit('run_id', {
- field_values: { email: 'user@example.com', password: '********' },
- });
- });
-});
diff --git a/tests/api-resources/browser-pools.test.ts b/tests/api-resources/browser-pools.test.ts
new file mode 100644
index 0000000..2fdc93e
--- /dev/null
+++ b/tests/api-resources/browser-pools.test.ts
@@ -0,0 +1,159 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import Kernel from '@onkernel/sdk';
+
+const client = new Kernel({
+ apiKey: 'My API Key',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('resource browserPools', () => {
+ // Prism tests are disabled
+ test.skip('create: only required params', async () => {
+ const responsePromise = client.browserPools.create({ size: 10 });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ // Prism tests are disabled
+ test.skip('create: required and optional params', async () => {
+ const response = await client.browserPools.create({
+ size: 10,
+ extensions: [{ id: 'id', name: 'name' }],
+ fill_rate_per_minute: 0,
+ headless: false,
+ kiosk_mode: true,
+ name: 'my-pool',
+ profile: { id: 'id', name: 'name', save_changes: true },
+ proxy_id: 'proxy_id',
+ stealth: true,
+ timeout_seconds: 60,
+ viewport: { height: 800, width: 1280, refresh_rate: 60 },
+ });
+ });
+
+ // Prism tests are disabled
+ test.skip('retrieve', async () => {
+ const responsePromise = client.browserPools.retrieve('id_or_name');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ // Prism tests are disabled
+ test.skip('update: only required params', async () => {
+ const responsePromise = client.browserPools.update('id_or_name', { size: 10 });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ // Prism tests are disabled
+ test.skip('update: required and optional params', async () => {
+ const response = await client.browserPools.update('id_or_name', {
+ size: 10,
+ discard_all_idle: false,
+ extensions: [{ id: 'id', name: 'name' }],
+ fill_rate_per_minute: 0,
+ headless: false,
+ kiosk_mode: true,
+ name: 'my-pool',
+ profile: { id: 'id', name: 'name', save_changes: true },
+ proxy_id: 'proxy_id',
+ stealth: true,
+ timeout_seconds: 60,
+ viewport: { height: 800, width: 1280, refresh_rate: 60 },
+ });
+ });
+
+ // Prism tests are disabled
+ test.skip('list', async () => {
+ const responsePromise = client.browserPools.list();
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ // Prism tests are disabled
+ test.skip('delete', async () => {
+ const responsePromise = client.browserPools.delete('id_or_name');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ // Prism tests are disabled
+ test.skip('delete: request options and params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(
+ client.browserPools.delete('id_or_name', { force: true }, { path: '/_stainless_unknown_path' }),
+ ).rejects.toThrow(Kernel.NotFoundError);
+ });
+
+ // Prism tests are disabled
+ test.skip('acquire', async () => {
+ const responsePromise = client.browserPools.acquire('id_or_name', {});
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ // Prism tests are disabled
+ test.skip('flush', async () => {
+ const responsePromise = client.browserPools.flush('id_or_name');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ // Prism tests are disabled
+ test.skip('release: only required params', async () => {
+ const responsePromise = client.browserPools.release('id_or_name', {
+ session_id: 'ts8iy3sg25ibheguyni2lg9t',
+ });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ // Prism tests are disabled
+ test.skip('release: required and optional params', async () => {
+ const response = await client.browserPools.release('id_or_name', {
+ session_id: 'ts8iy3sg25ibheguyni2lg9t',
+ reuse: false,
+ });
+ });
+});
From 1402989d9bb9850a05c4e926c1077ca60cc58387 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 2 Dec 2025 22:14:15 +0000
Subject: [PATCH 7/8] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index c32f96d..25e77f1 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 74
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-340c8f009b71922347d4c238c8715cd752c8965abfa12cbb1ffabe35edc338a8.yml
-openapi_spec_hash: efc13ab03ef89cc07333db8ab5345f31
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-3db06d1628149b5ea8303f1c72250664dfd7cb4a14ceb6102f1ae6e85c92c038.yml
+openapi_spec_hash: e5b3da2da328eb26d2a70e2521744c62
config_hash: a4124701ae0a474e580d7416adbcfb00
From 79cfbbb71b528d9adba7e352d4790e4ad3119c02 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 2 Dec 2025 22:14:34 +0000
Subject: [PATCH 8/8] release: 0.21.0
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 14 ++++++++++++++
package.json | 2 +-
src/version.ts | 2 +-
4 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 71e95ba..d353515 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.20.0"
+ ".": "0.21.0"
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e8d68b2..6a6c41b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,19 @@
# Changelog
+## 0.21.0 (2025-12-02)
+
+Full Changelog: [v0.20.0...v0.21.0](https://github.com/onkernel/kernel-node-sdk/compare/v0.20.0...v0.21.0)
+
+### Features
+
+* Browser pools sdk release ([0fca0c8](https://github.com/onkernel/kernel-node-sdk/commit/0fca0c8145e7a9938a9ebe20eeac19eb9d3e4e82))
+* Mason/agent auth api ([963aaf2](https://github.com/onkernel/kernel-node-sdk/commit/963aaf27f6449d4bcd39f9f3340b5d5a68ae49e8))
+
+
+### Chores
+
+* **client:** fix logger property type ([426b7b4](https://github.com/onkernel/kernel-node-sdk/commit/426b7b4d79357fcae88807aad49718c26eb02044))
+
## 0.20.0 (2025-11-19)
Full Changelog: [v0.19.2...v0.20.0](https://github.com/onkernel/kernel-node-sdk/compare/v0.19.2...v0.20.0)
diff --git a/package.json b/package.json
index 6fa7c73..9ff823b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@onkernel/sdk",
- "version": "0.20.0",
+ "version": "0.21.0",
"description": "The official TypeScript library for the Kernel API",
"author": "Kernel <>",
"types": "dist/index.d.ts",
diff --git a/src/version.ts b/src/version.ts
index b4e51da..bc95435 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const VERSION = '0.20.0'; // x-release-please-version
+export const VERSION = '0.21.0'; // x-release-please-version