From 987711ba473eceff308a6e1cd1ee4653e38b7254 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 16 May 2026 02:13:51 +0000 Subject: [PATCH 1/7] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 6b78eac..e7238e0 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 112 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-b7a19ff1fbd93322c8cffcd0b397ce2536ca8bff91594e0081bd030d4bec879f.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-85604d59d55171797ed7e5e60f46532e7825ccfcaf6ee1319284d513f582a9cf.yml openapi_spec_hash: 9dd204b37a357b19032aea9eb4496645 config_hash: 08d55086449943a8fec212b870061a3f From e251459afc038f2e15eef5ab77b91b398a75eae1 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 18 May 2026 13:14:49 +0000 Subject: [PATCH 2/7] feat: Expose POST /projects in public API --- .stats.yml | 4 ++-- src/resources/projects/projects.ts | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.stats.yml b/.stats.yml index e7238e0..e0a033e 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 112 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-85604d59d55171797ed7e5e60f46532e7825ccfcaf6ee1319284d513f582a9cf.yml -openapi_spec_hash: 9dd204b37a357b19032aea9eb4496645 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-982efd191c23737c9e1cdbcbf9237fa2231b9f74e0a25db2870293bdf9951c21.yml +openapi_spec_hash: eeb27952a4cc939316c24fc0ce2c9e3a config_hash: 08d55086449943a8fec212b870061a3f diff --git a/src/resources/projects/projects.ts b/src/resources/projects/projects.ts index fb1827f..dba1228 100644 --- a/src/resources/projects/projects.ts +++ b/src/resources/projects/projects.ts @@ -16,8 +16,7 @@ export class Projects extends APIResource { limits: LimitsAPI.Limits = new LimitsAPI.Limits(this._client); /** - * Create a new project within the authenticated organization. Requires the - * projects feature flag. + * Create a new project within the authenticated organization. * * @example * ```ts From e3b32bb8178e98e4ea15fb358a3e370dd96d0315 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 00:02:36 +0000 Subject: [PATCH 3/7] feat: browsers: accept chrome_policy on POST /browsers (KERNEL-1216) --- .stats.yml | 4 +- src/resources/browser-pools.ts | 7 ++++ src/resources/browsers/browsers.ts | 37 +++++++++++++++++++ src/resources/invocations.ts | 7 ++++ tests/api-resources/browsers/browsers.test.ts | 1 + 5 files changed, 54 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index e0a033e..542eaa0 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 112 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-982efd191c23737c9e1cdbcbf9237fa2231b9f74e0a25db2870293bdf9951c21.yml -openapi_spec_hash: eeb27952a4cc939316c24fc0ce2c9e3a +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-e564e74a7aae1744d4aa070a63c387f456c4719a48747dc6229b58a986255b65.yml +openapi_spec_hash: 62beb1f20708652aaee31bbffb6cfbe9 config_hash: 08d55086449943a8fec212b870061a3f diff --git a/src/resources/browser-pools.ts b/src/resources/browser-pools.ts index f7e1890..173abb0 100644 --- a/src/resources/browser-pools.ts +++ b/src/resources/browser-pools.ts @@ -323,6 +323,13 @@ export interface BrowserPoolAcquireResponse { */ browser_live_view_url?: string; + /** + * Custom Chrome enterprise policy overrides that were applied to this browser + * session, if any. Echoed back for verification. Keys are Chrome enterprise policy + * names. + */ + chrome_policy?: { [key: string]: unknown }; + /** * When the browser session was soft-deleted. Only present for deleted sessions. */ diff --git a/src/resources/browsers/browsers.ts b/src/resources/browsers/browsers.ts index 3766080..fc8aef2 100644 --- a/src/resources/browsers/browsers.ts +++ b/src/resources/browsers/browsers.ts @@ -355,6 +355,13 @@ export interface BrowserCreateResponse { */ browser_live_view_url?: string; + /** + * Custom Chrome enterprise policy overrides that were applied to this browser + * session, if any. Echoed back for verification. Keys are Chrome enterprise policy + * names. + */ + chrome_policy?: { [key: string]: unknown }; + /** * When the browser session was soft-deleted. Only present for deleted sessions. */ @@ -466,6 +473,13 @@ export interface BrowserRetrieveResponse { */ browser_live_view_url?: string; + /** + * Custom Chrome enterprise policy overrides that were applied to this browser + * session, if any. Echoed back for verification. Keys are Chrome enterprise policy + * names. + */ + chrome_policy?: { [key: string]: unknown }; + /** * When the browser session was soft-deleted. Only present for deleted sessions. */ @@ -577,6 +591,13 @@ export interface BrowserUpdateResponse { */ browser_live_view_url?: string; + /** + * Custom Chrome enterprise policy overrides that were applied to this browser + * session, if any. Echoed back for verification. Keys are Chrome enterprise policy + * names. + */ + chrome_policy?: { [key: string]: unknown }; + /** * When the browser session was soft-deleted. Only present for deleted sessions. */ @@ -688,6 +709,13 @@ export interface BrowserListResponse { */ browser_live_view_url?: string; + /** + * Custom Chrome enterprise policy overrides that were applied to this browser + * session, if any. Echoed back for verification. Keys are Chrome enterprise policy + * names. + */ + chrome_policy?: { [key: string]: unknown }; + /** * When the browser session was soft-deleted. Only present for deleted sessions. */ @@ -778,6 +806,15 @@ export interface BrowserCurlResponse { } export interface BrowserCreateParams { + /** + * Custom Chrome enterprise policy overrides applied to this browser session. Keys + * are Chrome enterprise policy names; values must match their expected types. + * Blocked: kernel-managed policies (extensions, proxy, CDP/automation). Ignored + * when reusing an existing persistent session. See + * https://chromeenterprise.google/policies/ + */ + chrome_policy?: { [key: string]: unknown }; + /** * List of browser extensions to load into the session. Provide each by id or name. */ diff --git a/src/resources/invocations.ts b/src/resources/invocations.ts index c26f6ec..d51c8ca 100644 --- a/src/resources/invocations.ts +++ b/src/resources/invocations.ts @@ -464,6 +464,13 @@ export namespace InvocationListBrowsersResponse { */ browser_live_view_url?: string; + /** + * Custom Chrome enterprise policy overrides that were applied to this browser + * session, if any. Echoed back for verification. Keys are Chrome enterprise policy + * names. + */ + chrome_policy?: { [key: string]: unknown }; + /** * When the browser session was soft-deleted. Only present for deleted sessions. */ diff --git a/tests/api-resources/browsers/browsers.test.ts b/tests/api-resources/browsers/browsers.test.ts index 471a51c..5ea987e 100644 --- a/tests/api-resources/browsers/browsers.test.ts +++ b/tests/api-resources/browsers/browsers.test.ts @@ -26,6 +26,7 @@ describe('resource browsers', () => { await expect( client.browsers.create( { + chrome_policy: { foo: 'bar' }, extensions: [{ id: 'id', name: 'name' }], gpu: false, headless: false, From 1677dc13811672b22ec12102bda30755fa4d1f6f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 02:37:18 +0000 Subject: [PATCH 4/7] chore(tests): remove redundant File import --- tests/uploads.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts index ba84b0c..981451d 100644 --- a/tests/uploads.test.ts +++ b/tests/uploads.test.ts @@ -1,7 +1,6 @@ import fs from 'fs'; import type { ResponseLike } from '@onkernel/sdk/internal/to-file'; import { toFile } from '@onkernel/sdk/core/uploads'; -import { File } from 'node:buffer'; class MyClass { name: string = 'foo'; From 46e3fb57502dcf44dd4c972fc42fb09c30eab6eb Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 02:37:52 +0000 Subject: [PATCH 5/7] fix(typescript): upgrade tsc-multi so that it works with Node 26 --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index c11d590..b78194a 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "publint": "^0.2.12", "ts-jest": "^29.1.0", "ts-node": "^10.5.0", - "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz", + "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.11/tsc-multi.tgz", "tsconfig-paths": "^4.0.0", "tslib": "^2.8.1", "typescript": "5.8.3", diff --git a/yarn.lock b/yarn.lock index 18e7cbd..00842e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3192,9 +3192,9 @@ ts-node@^10.5.0: v8-compile-cache-lib "^3.0.0" yn "3.1.1" -"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz": - version "1.1.9" - resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz#777f6f5d9e26bf0e94e5170990dd3a841d6707cd" +"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.11/tsc-multi.tgz": + version "1.1.11" + resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.11/tsc-multi.tgz#010247051be13b55abdc98f787c017285149f4f2" dependencies: debug "^4.3.7" fast-glob "^3.3.2" From 958614b4a683675d7e00d901fee039515f94df6a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 21 May 2026 18:53:03 +0000 Subject: [PATCH 6/7] feat: [kernel-1116] browser events api integration --- .stats.yml | 8 +- api.md | 40 + src/resources/browser-pools.ts | 36 +- src/resources/browsers/browsers.ts | 133 +- src/resources/browsers/index.ts | 35 + src/resources/browsers/telemetry.ts | 1521 +++++++++++++++++ src/resources/invocations.ts | 12 +- src/resources/proxies.ts | 4 +- tests/api-resources/browsers/browsers.test.ts | 8 + .../api-resources/browsers/telemetry.test.ts | 34 + 10 files changed, 1811 insertions(+), 20 deletions(-) create mode 100644 src/resources/browsers/telemetry.ts create mode 100644 tests/api-resources/browsers/telemetry.test.ts diff --git a/.stats.yml b/.stats.yml index 542eaa0..3dfe6c6 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 112 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-e564e74a7aae1744d4aa070a63c387f456c4719a48747dc6229b58a986255b65.yml -openapi_spec_hash: 62beb1f20708652aaee31bbffb6cfbe9 -config_hash: 08d55086449943a8fec212b870061a3f +configured_endpoints: 113 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-a9c7e806132001dbfbd4e8ae6c7d0935e503f457d63385fc800c862e3d064375.yml +openapi_spec_hash: b048dcb0c5401bc0a301c3d30cb8ecba +config_hash: 37661d89120558d34b6cc184292632f2 diff --git a/api.md b/api.md index ba877c9..3e2a18d 100644 --- a/api.md +++ b/api.md @@ -87,6 +87,46 @@ Methods: - client.browsers.deleteByID(id) -> void - client.browsers.loadExtensions(id, { ...params }) -> void +## Telemetry + +Types: + +- BrowserCallStack +- BrowserConsoleErrorEvent +- BrowserConsoleLogEvent +- BrowserEventContext +- BrowserEventSource +- BrowserHTTPHeaders +- BrowserInteractionClickEvent +- BrowserInteractionKeyEvent +- BrowserInteractionScrollSettledEvent +- BrowserMonitorDisconnectedEvent +- BrowserMonitorInitFailedEvent +- BrowserMonitorReconnectFailedEvent +- BrowserMonitorReconnectedEvent +- BrowserMonitorScreenshotEvent +- BrowserNetworkIdleEvent +- BrowserNetworkLoadingFailedEvent +- BrowserNetworkRequestEvent +- BrowserNetworkResponseEvent +- BrowserPageDomContentLoadedEvent +- BrowserPageLayoutSettledEvent +- BrowserPageLayoutShiftEvent +- BrowserPageLcpEvent +- BrowserPageLoadEvent +- BrowserPageNavigationEvent +- BrowserPageNavigationSettledEvent +- BrowserPageTabOpenedEvent +- BrowserTelemetryCategoriesConfig +- BrowserTelemetryCategoryConfig +- BrowserTelemetryConfig +- BrowserTelemetryEvent +- TelemetryStreamResponse + +Methods: + +- client.browsers.telemetry.stream(id, { ...params }) -> TelemetryStreamResponse + ## Replays Types: diff --git a/src/resources/browser-pools.ts b/src/resources/browser-pools.ts index 173abb0..a20c888 100644 --- a/src/resources/browser-pools.ts +++ b/src/resources/browser-pools.ts @@ -3,6 +3,7 @@ import { APIResource } from '../core/resource'; import * as Shared from './shared'; import * as BrowsersAPI from './browsers/browsers'; +import * as TelemetryAPI from './browsers/telemetry'; import { APIPromise } from '../core/api-promise'; import { buildHeaders } from '../internal/headers'; import { RequestOptions } from '../internal/request-options'; @@ -238,9 +239,11 @@ export namespace BrowserPool { proxy_id?: string; /** - * Optional URL to open when a browser is created for the pool. Navigation is - * best-effort, so navigation failures do not prevent the pool from filling. Reused - * browsers keep the page left by the previous lease. + * Optional URL to navigate to when a new browser is warmed into the pool. + * Best-effort: failures to navigate do not fail pool fill. Only applied to + * newly-warmed browsers; browsers reused via release/acquire keep whatever URL the + * previous lease left them on. Accepts any URL Chromium can resolve, including + * chrome:// pages. */ start_url?: string; @@ -368,10 +371,19 @@ export interface BrowserPoolAcquireResponse { proxy_id?: string; /** - * Start URL requested for the session, if provided. + * URL the session was asked to navigate to on creation, if any. Recorded for + * debugging. Navigation is fire-and-forget — the URL is dispatched to the browser + * without waiting for it to load, and any errors (DNS failure, bad status, + * timeout) are silently dropped. Captures what was requested, not what the browser + * actually loaded. */ start_url?: string; + /** + * Active telemetry configuration for the session, if any. + */ + telemetry?: TelemetryAPI.BrowserTelemetryConfig | null; + /** * Session usage metrics. */ @@ -450,9 +462,11 @@ export interface BrowserPoolCreateParams { proxy_id?: string; /** - * Optional URL to open when a browser is created for the pool. Navigation is - * best-effort, so navigation failures do not prevent the pool from filling. Reused - * browsers keep the page left by the previous lease. + * Optional URL to navigate to when a new browser is warmed into the pool. + * Best-effort: failures to navigate do not fail pool fill. Only applied to + * newly-warmed browsers; browsers reused via release/acquire keep whatever URL the + * previous lease left them on. Accepts any URL Chromium can resolve, including + * chrome:// pages. */ start_url?: string; @@ -547,9 +561,11 @@ export interface BrowserPoolUpdateParams { proxy_id?: string; /** - * Optional URL to open when a browser is created for the pool. Navigation is - * best-effort, so navigation failures do not prevent the pool from filling. Reused - * browsers keep the page left by the previous lease. + * Optional URL to navigate to when a new browser is warmed into the pool. + * Best-effort: failures to navigate do not fail pool fill. Only applied to + * newly-warmed browsers; browsers reused via release/acquire keep whatever URL the + * previous lease left them on. Accepts any URL Chromium can resolve, including + * chrome:// pages. */ start_url?: string; diff --git a/src/resources/browsers/browsers.ts b/src/resources/browsers/browsers.ts index fc8aef2..8b4b677 100644 --- a/src/resources/browsers/browsers.ts +++ b/src/resources/browsers/browsers.ts @@ -51,6 +51,42 @@ import { ReplayStopParams, Replays, } from './replays'; +import * as TelemetryAPI from './telemetry'; +import { + BrowserCallStack, + BrowserConsoleErrorEvent, + BrowserConsoleLogEvent, + BrowserEventContext, + BrowserEventSource, + BrowserHTTPHeaders, + BrowserInteractionClickEvent, + BrowserInteractionKeyEvent, + BrowserInteractionScrollSettledEvent, + BrowserMonitorDisconnectedEvent, + BrowserMonitorInitFailedEvent, + BrowserMonitorReconnectFailedEvent, + BrowserMonitorReconnectedEvent, + BrowserMonitorScreenshotEvent, + BrowserNetworkIdleEvent, + BrowserNetworkLoadingFailedEvent, + BrowserNetworkRequestEvent, + BrowserNetworkResponseEvent, + BrowserPageDomContentLoadedEvent, + BrowserPageLayoutSettledEvent, + BrowserPageLayoutShiftEvent, + BrowserPageLcpEvent, + BrowserPageLoadEvent, + BrowserPageNavigationEvent, + BrowserPageNavigationSettledEvent, + BrowserPageTabOpenedEvent, + BrowserTelemetryCategoriesConfig, + BrowserTelemetryCategoryConfig, + BrowserTelemetryConfig, + BrowserTelemetryEvent, + Telemetry, + TelemetryStreamParams, + TelemetryStreamResponse, +} from './telemetry'; import * as FsAPI from './fs/fs'; import { FCreateDirectoryParams, @@ -82,6 +118,7 @@ import { browserFetch, type BrowserFetchInit } from '../../lib/browser-fetch'; * Create and manage browser sessions. */ export class Browsers extends APIResource { + telemetry: TelemetryAPI.Telemetry = new TelemetryAPI.Telemetry(this._client); replays: ReplaysAPI.Replays = new ReplaysAPI.Replays(this._client); fs: FsAPI.Fs = new FsAPI.Fs(this._client); process: ProcessAPI.Process = new ProcessAPI.Process(this._client); @@ -400,10 +437,19 @@ export interface BrowserCreateResponse { proxy_id?: string; /** - * Start URL requested for the session, if provided. + * URL the session was asked to navigate to on creation, if any. Recorded for + * debugging. Navigation is fire-and-forget — the URL is dispatched to the browser + * without waiting for it to load, and any errors (DNS failure, bad status, + * timeout) are silently dropped. Captures what was requested, not what the browser + * actually loaded. */ start_url?: string; + /** + * Active telemetry configuration for the session, if any. + */ + telemetry?: TelemetryAPI.BrowserTelemetryConfig | null; + /** * Session usage metrics. */ @@ -518,10 +564,19 @@ export interface BrowserRetrieveResponse { proxy_id?: string; /** - * Start URL requested for the session, if provided. + * URL the session was asked to navigate to on creation, if any. Recorded for + * debugging. Navigation is fire-and-forget — the URL is dispatched to the browser + * without waiting for it to load, and any errors (DNS failure, bad status, + * timeout) are silently dropped. Captures what was requested, not what the browser + * actually loaded. */ start_url?: string; + /** + * Active telemetry configuration for the session, if any. + */ + telemetry?: TelemetryAPI.BrowserTelemetryConfig | null; + /** * Session usage metrics. */ @@ -636,10 +691,19 @@ export interface BrowserUpdateResponse { proxy_id?: string; /** - * Start URL requested for the session, if provided. + * URL the session was asked to navigate to on creation, if any. Recorded for + * debugging. Navigation is fire-and-forget — the URL is dispatched to the browser + * without waiting for it to load, and any errors (DNS failure, bad status, + * timeout) are silently dropped. Captures what was requested, not what the browser + * actually loaded. */ start_url?: string; + /** + * Active telemetry configuration for the session, if any. + */ + telemetry?: TelemetryAPI.BrowserTelemetryConfig | null; + /** * Session usage metrics. */ @@ -754,10 +818,19 @@ export interface BrowserListResponse { proxy_id?: string; /** - * Start URL requested for the session, if provided. + * URL the session was asked to navigate to on creation, if any. Recorded for + * debugging. Navigation is fire-and-forget — the URL is dispatched to the browser + * without waiting for it to load, and any errors (DNS failure, bad status, + * timeout) are silently dropped. Captures what was requested, not what the browser + * actually loaded. */ start_url?: string; + /** + * Active telemetry configuration for the session, if any. + */ + telemetry?: TelemetryAPI.BrowserTelemetryConfig | null; + /** * Session usage metrics. */ @@ -875,6 +948,13 @@ export interface BrowserCreateParams { */ stealth?: boolean; + /** + * Telemetry configuration for the browser session. If provided, telemetry capture + * starts with the specified category filter when the session is created. If + * omitted, no telemetry capture is started. + */ + telemetry?: TelemetryAPI.BrowserTelemetryConfig | null; + /** * The number of seconds of inactivity before the browser session is terminated. * Activity includes CDP connections and live view connections. Defaults to 60 @@ -927,6 +1007,14 @@ export interface BrowserUpdateParams { */ proxy_id?: string | null; + /** + * Telemetry configuration. Omit, set to null, or set to an empty object ({}) to + * leave the existing configuration unchanged (no-op). To enable capture for all + * categories using VM defaults, set browser to an empty object ({"browser": {}}). + * To stop capture, set every category's enabled to false. + */ + telemetry?: TelemetryAPI.BrowserTelemetryConfig | null; + /** * Viewport configuration to apply to the browser session. */ @@ -1028,6 +1116,7 @@ export namespace BrowserLoadExtensionsParams { } } +Browsers.Telemetry = Telemetry; Browsers.Replays = Replays; Browsers.Fs = Fs; Browsers.Process = Process; @@ -1056,6 +1145,42 @@ export declare namespace Browsers { type BrowserLoadExtensionsParams as BrowserLoadExtensionsParams, }; + export { + Telemetry as Telemetry, + type BrowserCallStack as BrowserCallStack, + type BrowserConsoleErrorEvent as BrowserConsoleErrorEvent, + type BrowserConsoleLogEvent as BrowserConsoleLogEvent, + type BrowserEventContext as BrowserEventContext, + type BrowserEventSource as BrowserEventSource, + type BrowserHTTPHeaders as BrowserHTTPHeaders, + type BrowserInteractionClickEvent as BrowserInteractionClickEvent, + type BrowserInteractionKeyEvent as BrowserInteractionKeyEvent, + type BrowserInteractionScrollSettledEvent as BrowserInteractionScrollSettledEvent, + type BrowserMonitorDisconnectedEvent as BrowserMonitorDisconnectedEvent, + type BrowserMonitorInitFailedEvent as BrowserMonitorInitFailedEvent, + type BrowserMonitorReconnectFailedEvent as BrowserMonitorReconnectFailedEvent, + type BrowserMonitorReconnectedEvent as BrowserMonitorReconnectedEvent, + type BrowserMonitorScreenshotEvent as BrowserMonitorScreenshotEvent, + type BrowserNetworkIdleEvent as BrowserNetworkIdleEvent, + type BrowserNetworkLoadingFailedEvent as BrowserNetworkLoadingFailedEvent, + type BrowserNetworkRequestEvent as BrowserNetworkRequestEvent, + type BrowserNetworkResponseEvent as BrowserNetworkResponseEvent, + type BrowserPageDomContentLoadedEvent as BrowserPageDomContentLoadedEvent, + type BrowserPageLayoutSettledEvent as BrowserPageLayoutSettledEvent, + type BrowserPageLayoutShiftEvent as BrowserPageLayoutShiftEvent, + type BrowserPageLcpEvent as BrowserPageLcpEvent, + type BrowserPageLoadEvent as BrowserPageLoadEvent, + type BrowserPageNavigationEvent as BrowserPageNavigationEvent, + type BrowserPageNavigationSettledEvent as BrowserPageNavigationSettledEvent, + type BrowserPageTabOpenedEvent as BrowserPageTabOpenedEvent, + type BrowserTelemetryCategoriesConfig as BrowserTelemetryCategoriesConfig, + type BrowserTelemetryCategoryConfig as BrowserTelemetryCategoryConfig, + type BrowserTelemetryConfig as BrowserTelemetryConfig, + type BrowserTelemetryEvent as BrowserTelemetryEvent, + type TelemetryStreamResponse as TelemetryStreamResponse, + type TelemetryStreamParams as TelemetryStreamParams, + }; + export { Replays as Replays, type ReplayListResponse as ReplayListResponse, diff --git a/src/resources/browsers/index.ts b/src/resources/browsers/index.ts index e38f073..90f686a 100644 --- a/src/resources/browsers/index.ts +++ b/src/resources/browsers/index.ts @@ -81,3 +81,38 @@ export { type ReplayStartParams, type ReplayStopParams, } from './replays'; +export { + Telemetry, + type BrowserCallStack, + type BrowserConsoleErrorEvent, + type BrowserConsoleLogEvent, + type BrowserEventContext, + type BrowserEventSource, + type BrowserHTTPHeaders, + type BrowserInteractionClickEvent, + type BrowserInteractionKeyEvent, + type BrowserInteractionScrollSettledEvent, + type BrowserMonitorDisconnectedEvent, + type BrowserMonitorInitFailedEvent, + type BrowserMonitorReconnectFailedEvent, + type BrowserMonitorReconnectedEvent, + type BrowserMonitorScreenshotEvent, + type BrowserNetworkIdleEvent, + type BrowserNetworkLoadingFailedEvent, + type BrowserNetworkRequestEvent, + type BrowserNetworkResponseEvent, + type BrowserPageDomContentLoadedEvent, + type BrowserPageLayoutSettledEvent, + type BrowserPageLayoutShiftEvent, + type BrowserPageLcpEvent, + type BrowserPageLoadEvent, + type BrowserPageNavigationEvent, + type BrowserPageNavigationSettledEvent, + type BrowserPageTabOpenedEvent, + type BrowserTelemetryCategoriesConfig, + type BrowserTelemetryCategoryConfig, + type BrowserTelemetryConfig, + type BrowserTelemetryEvent, + type TelemetryStreamResponse, + type TelemetryStreamParams, +} from './telemetry'; diff --git a/src/resources/browsers/telemetry.ts b/src/resources/browsers/telemetry.ts new file mode 100644 index 0000000..4c3adf5 --- /dev/null +++ b/src/resources/browsers/telemetry.ts @@ -0,0 +1,1521 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { APIResource } from '../../core/resource'; +import * as TelemetryAPI from './telemetry'; +import { APIPromise } from '../../core/api-promise'; +import { Stream } from '../../core/streaming'; +import { buildHeaders } from '../../internal/headers'; +import { RequestOptions } from '../../internal/request-options'; +import { path } from '../../internal/utils/path'; + +/** + * Stream live telemetry events from a browser session. + */ +export class Telemetry extends APIResource { + /** + * Streams browser telemetry events as a server-sent events (SSE) stream. The + * stream closes when the browser session terminates. Each event frame includes an + * id: field containing a monotonically increasing sequence number; pass it as + * Last-Event-ID on reconnect to resume without gaps. The event: field is never + * set; all frames carry JSON in the data: field. A keepalive comment frame is sent + * every 15 seconds when no events arrive. Returns 404 if the browser session does + * not exist. If telemetry was not enabled on the session, the stream opens but no + * events are delivered. + * + * @example + * ```ts + * const response = await client.browsers.telemetry.stream( + * 'id', + * ); + * ``` + */ + stream( + id: string, + params: TelemetryStreamParams | undefined = {}, + options?: RequestOptions, + ): APIPromise> { + const { 'Last-Event-ID': lastEventID } = params ?? {}; + return this._client.get(path`/browsers/${id}/telemetry`, { + ...options, + headers: buildHeaders([ + { + Accept: 'text/event-stream', + ...(lastEventID != null ? { 'Last-Event-ID': lastEventID } : undefined), + }, + options?.headers, + ]), + stream: true, + }) as APIPromise>; + } +} + +/** + * CDP Runtime.StackTrace representing the JavaScript call stack at the time of an + * event. Fields use CDP naming conventions rather than snake_case to match the + * Chrome DevTools Protocol wire format. + */ +export interface BrowserCallStack { + /** + * Ordered list of call frames, outermost first. + */ + callFrames: Array; + + /** + * Optional label for the stack trace (e.g. async cause). + */ + description?: string; + + /** + * Parent stack trace for async stacks. + */ + parent?: BrowserCallStack; +} + +export namespace BrowserCallStack { + export interface CallFrame { + /** + * Zero-based column number within the line. + */ + columnNumber: number; + + /** + * JavaScript function name, or empty string for anonymous functions. + */ + functionName: string; + + /** + * Zero-based line number within the script. + */ + lineNumber: number; + + /** + * CDP script identifier. + */ + scriptId: string; + + /** + * URL or name of the script file. + */ + url: string; + } +} + +/** + * A browser console error or uncaught JavaScript exception event. Emitted from two + * distinct CDP sources with different data shapes. Runtime.consoleAPICalled + * (console.error calls) produces level, text, args, and stack_trace. + * Runtime.exceptionThrown (uncaught exceptions) produces text, line, column, + * source_url, and stack_trace. Fields not applicable to the source are absent. + */ +export interface BrowserConsoleErrorEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'console_error'; + + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + data?: BrowserConsoleErrorEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserConsoleErrorEvent { + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + export interface Data extends TelemetryAPI.BrowserEventContext { + /** + * Error message text. Present in both source paths. + */ + text: string; + + /** + * All console arguments coerced to strings. Present only when sourced from + * Runtime.consoleAPICalled. + */ + args?: Array; + + /** + * Column number in the script where the exception was thrown. Present only when + * sourced from Runtime.exceptionThrown. + */ + column?: number; + + /** + * CDP console type value, always "error". Present only when sourced from + * Runtime.consoleAPICalled. + */ + level?: string; + + /** + * Line number in the script where the exception was thrown. Present only when + * sourced from Runtime.exceptionThrown. + */ + line?: number; + + /** + * URL of the script file that threw the exception. Present only when sourced from + * Runtime.exceptionThrown. + */ + source_url?: string; + + /** + * CDP Runtime.StackTrace representing the JavaScript call stack at the time of an + * event. Fields use CDP naming conventions rather than snake_case to match the + * Chrome DevTools Protocol wire format. + */ + stack_trace?: TelemetryAPI.BrowserCallStack; + } +} + +/** + * A browser console log event (console.log, console.info, console.warn, etc.). + */ +export interface BrowserConsoleLogEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'console_log'; + + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + data?: BrowserConsoleLogEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserConsoleLogEvent { + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + export interface Data extends TelemetryAPI.BrowserEventContext { + /** + * All console arguments coerced to strings. + */ + args?: Array; + + /** + * CDP Runtime.consoleAPICalled type, passed through unfiltered from Chrome. error + * is routed to console_error events instead; all other CDP console types appear + * here. See CDP spec for the full enum. + */ + level?: string; + + /** + * CDP Runtime.StackTrace representing the JavaScript call stack at the time of an + * event. Fields use CDP naming conventions rather than snake_case to match the + * Chrome DevTools Protocol wire format. + */ + stack_trace?: TelemetryAPI.BrowserCallStack; + + /** + * First console argument coerced to string. + */ + text?: string; + } +} + +/** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ +export interface BrowserEventContext { + /** + * CDP frame identifier within the target. + */ + frame_id?: string; + + /** + * CDP document loader identifier, reset on each navigation. + */ + loader_id?: string; + + /** + * Monotonically increasing navigation sequence number, incremented on each + * top-level navigation within the target. + */ + nav_seq?: number; + + /** + * CDP session identifier for the target connection. + */ + session_id?: string; + + /** + * Browser target identifier (stable across navigations within a tab). + */ + target_id?: string; + + /** + * CDP target type of the page that produced the event. + */ + target_type?: 'page' | 'background_page' | 'service_worker' | 'shared_worker' | 'other'; + + /** + * URL relevant to this event — page URL for navigation and page events, request + * URL for network events. + */ + url?: string; +} + +/** + * Provenance metadata identifying which producer emitted the event. + */ +export interface BrowserEventSource { + /** + * Event producer. cdp: Chrome DevTools Protocol events from the browser. + * kernel_api: Kernel API server. extension: injected Chrome extension. + * local_process: system process running alongside the browser. + */ + kind: 'cdp' | 'kernel_api' | 'extension' | 'local_process'; + + /** + * Producer-specific event name (e.g. Runtime.consoleAPICalled for CDP-sourced + * console events, Runtime.exceptionThrown for uncaught exceptions). + */ + event?: string; + + /** + * Producer-specific context (e.g. CDP target/session/frame IDs). + */ + metadata?: { [key: string]: string }; +} + +/** + * HTTP headers map forwarded as-is from CDP without normalization. Values are + * typically strings but may be any JSON type. + */ +export type BrowserHTTPHeaders = { [key: string]: unknown }; + +/** + * A browser user click event captured via injected page script. + */ +export interface BrowserInteractionClickEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'interaction_click'; + + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + data?: BrowserInteractionClickEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserInteractionClickEvent { + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + export interface Data extends TelemetryAPI.BrowserEventContext { + /** + * CSS selector path to the clicked element. + */ + selector?: string; + + /** + * HTML tag name of the clicked element in uppercase (e.g. BUTTON, A, DIV). + */ + tag?: string; + + /** + * Visible text content of the clicked element, trimmed. + */ + text?: string; + + /** + * Viewport x-coordinate of the click in CSS pixels. + */ + x?: number; + + /** + * Viewport y-coordinate of the click in CSS pixels. + */ + y?: number; + } +} + +/** + * A browser keyboard event captured via injected page script. + */ +export interface BrowserInteractionKeyEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'interaction_key'; + + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + data?: BrowserInteractionKeyEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserInteractionKeyEvent { + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + export interface Data extends TelemetryAPI.BrowserEventContext { + /** + * Key value from the KeyboardEvent (e.g. Enter, Backspace, a). + */ + key?: string; + + /** + * CSS selector path to the element that had focus when the key was pressed. + */ + selector?: string; + + /** + * HTML tag name of the focused element in uppercase (e.g. INPUT, TEXTAREA, DIV). + */ + tag?: string; + } +} + +/** + * A browser scroll settled event emitted after scroll position stops changing, + * captured via injected page script. + */ +export interface BrowserInteractionScrollSettledEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'interaction_scroll_settled'; + + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + data?: BrowserInteractionScrollSettledEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserInteractionScrollSettledEvent { + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + export interface Data extends TelemetryAPI.BrowserEventContext { + /** + * Scroll x-position at the start of the scroll gesture in CSS pixels. + */ + from_x?: number; + + /** + * Scroll y-position at the start of the scroll gesture in CSS pixels. + */ + from_y?: number; + + /** + * CSS selector path to the scrolled element. + */ + target_selector?: string; + + /** + * Final scroll x-position after the gesture settled in CSS pixels. + */ + to_x?: number; + + /** + * Final scroll y-position after the gesture settled in CSS pixels. + */ + to_y?: number; + } +} + +/** + * The CDP connection to Chrome was lost. Telemetry events may be dropped until + * monitor_reconnected arrives. Treat any in-progress computed state (network_idle, + * page_layout_settled) as unreliable until then. + */ +export interface BrowserMonitorDisconnectedEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'monitor_disconnected'; + + data?: BrowserMonitorDisconnectedEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserMonitorDisconnectedEvent { + export interface Data { + /** + * Reason for the disconnection. chrome_restarted: Chrome process restarted. + */ + reason?: 'chrome_restarted'; + } +} + +/** + * The CDP session could not be initialized. + */ +export interface BrowserMonitorInitFailedEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'monitor_init_failed'; + + data?: BrowserMonitorInitFailedEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserMonitorInitFailedEvent { + export interface Data { + /** + * The CDP method or initialization step that failed (e.g. Target.setAutoAttach). + */ + step?: string; + } +} + +/** + * The CDP connection to Chrome could not be re-established after exhausting all + * reconnection attempts. No further telemetry events will arrive on this session. + */ +export interface BrowserMonitorReconnectFailedEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'monitor_reconnect_failed'; + + data?: BrowserMonitorReconnectFailedEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserMonitorReconnectFailedEvent { + export interface Data { + /** + * Reason for the reconnection failure. reconnect_exhausted: all retry attempts + * were used up without successfully restoring the CDP connection. + */ + reason?: 'reconnect_exhausted'; + } +} + +/** + * The CDP connection to Chrome was successfully re-established after a + * disconnection. Events emitted during the gap are lost. Computed state is reset, + * so navigation and network tracking restart fresh from this point. + */ +export interface BrowserMonitorReconnectedEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'monitor_reconnected'; + + data?: BrowserMonitorReconnectedEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserMonitorReconnectedEvent { + export interface Data { + /** + * Wall-clock time in milliseconds taken to reconnect after the disconnection. + */ + reconnect_duration_ms?: number; + } +} + +/** + * A periodic screenshot of the browser viewport. + */ +export interface BrowserMonitorScreenshotEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'monitor_screenshot'; + + data?: BrowserMonitorScreenshotEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserMonitorScreenshotEvent { + export interface Data { + /** + * Base64-encoded PNG screenshot of the browser viewport. + */ + png?: string; + } +} + +/** + * A browser network idle event emitted after a 500ms quiet period with no + * in-flight HTTP requests. + */ +export interface BrowserNetworkIdleEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'network_idle'; + + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + data?: BrowserEventContext; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +/** + * A browser network loading failed event. If the request was already in flight + * when CDP attached (no prior network_request was emitted for it), url, frame_id, + * loader_id, and resource_type are absent; BrowserEventContext is partially + * populated in that case. + */ +export interface BrowserNetworkLoadingFailedEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'network_loading_failed'; + + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + data?: BrowserNetworkLoadingFailedEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserNetworkLoadingFailedEvent { + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + export interface Data extends TelemetryAPI.BrowserEventContext { + /** + * True if the request was canceled by the browser or page script. + */ + canceled?: boolean; + + /** + * Network error description (e.g. net::ERR_CONNECTION_REFUSED). + */ + error_text?: string; + + /** + * CDP request identifier matching the originating network_request event. + */ + request_id?: string; + + /** + * CDP Network.ResourceType for the request, passed through as-is from Chrome. + * Known values include Document, Fetch, XHR, Script, Stylesheet, Image, Media, + * Font, TextTrack, EventSource, WebSocket, Manifest, Prefetch, Other, and more. + */ + resource_type?: string; + } +} + +/** + * A browser network request sent event. + */ +export interface BrowserNetworkRequestEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'network_request'; + + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + data?: BrowserNetworkRequestEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserNetworkRequestEvent { + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + export interface Data extends TelemetryAPI.BrowserEventContext { + /** + * URL of the document that initiated the request. + */ + document_url?: string; + + /** + * Request headers. + */ + headers?: TelemetryAPI.BrowserHTTPHeaders; + + /** + * CDP Initiator.type indicating what caused the request, passed through as-is from + * Chrome. Known values include script, parser, preload, and other. + */ + initiator_type?: string; + + /** + * True if this request is the result of a redirect. + */ + is_redirect?: boolean; + + /** + * HTTP method as sent on the wire (e.g. GET, POST). + */ + method?: string; + + /** + * Request body for POST/PUT requests, if available. + */ + post_data?: string; + + /** + * Original URL before the redirect, present when is_redirect is true. + */ + redirect_url?: string; + + /** + * CDP request identifier, unique within the session. + */ + request_id?: string; + + /** + * CDP Network.ResourceType for the request, passed through as-is from Chrome. + * Known values include Document, Fetch, XHR, Script, Stylesheet, Image, Media, + * Font, TextTrack, EventSource, WebSocket, Manifest, Prefetch, Other, and more. + */ + resource_type?: string; + } +} + +/** + * A browser network response received event. Fired after the response body is + * fully received, not when headers arrive. + */ +export interface BrowserNetworkResponseEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'network_response'; + + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + data?: BrowserNetworkResponseEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserNetworkResponseEvent { + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + export interface Data extends TelemetryAPI.BrowserEventContext { + /** + * Truncated response body, present only for text MIME types. + */ + body?: string; + + /** + * Response headers. + */ + headers?: TelemetryAPI.BrowserHTTPHeaders; + + /** + * HTTP method of the original request. + */ + method?: string; + + /** + * MIME type of the response (e.g. text/html, application/json). + */ + mime_type?: string; + + /** + * CDP request identifier matching the originating network_request event. + */ + request_id?: string; + + /** + * CDP Network.ResourceType for the request, passed through as-is from Chrome. + * Known values include Document, Fetch, XHR, Script, Stylesheet, Image, Media, + * Font, TextTrack, EventSource, WebSocket, Manifest, Prefetch, Other, and more. + */ + resource_type?: string; + + /** + * HTTP response status code. + */ + status?: number; + + /** + * HTTP response status text (e.g. OK, Not Found). + */ + status_text?: string; + } +} + +/** + * A browser DOMContentLoaded event (CDP Page.domContentEventFired). + */ +export interface BrowserPageDomContentLoadedEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'page_dom_content_loaded'; + + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + data?: BrowserPageDomContentLoadedEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserPageDomContentLoadedEvent { + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + export interface Data extends TelemetryAPI.BrowserEventContext { + /** + * Chrome monotonic clock value in seconds at which DOMContentLoaded fired, + * relative to browser process start (not Unix epoch). Use ts for wall-clock time. + */ + cdp_timestamp?: number; + } +} + +/** + * A browser layout settled event emitted 1 second after page load with no + * intervening layout shifts, indicating visual stability. Each layout shift resets + * the 1-second timer. + */ +export interface BrowserPageLayoutSettledEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'page_layout_settled'; + + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + data?: BrowserEventContext; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +/** + * A browser cumulative layout shift (CLS) event from the Performance Timeline API. + */ +export interface BrowserPageLayoutShiftEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'page_layout_shift'; + + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + data?: BrowserPageLayoutShiftEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserPageLayoutShiftEvent { + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + export interface Data extends TelemetryAPI.BrowserEventContext { + /** + * Duration of the layout shift entry in milliseconds (always 0 for layout shifts + * per spec). + */ + duration?: number; + + /** + * PerformanceLayoutShift attributes from the Performance Timeline entry. + */ + layout_shift_details?: Data.LayoutShiftDetails; + + /** + * CDP frame identifier of the frame where the layout shift occurred. + */ + source_frame_id?: string; + + /** + * Performance Timeline timestamp of the layout shift in milliseconds. + */ + time?: number; + } + + export namespace Data { + /** + * PerformanceLayoutShift attributes from the Performance Timeline entry. + */ + export interface LayoutShiftDetails { + /** + * True if the layout shift was preceded by user input within 500ms, excluding it + * from CLS. + */ + had_recent_input?: boolean; + + /** + * Layout shift score for this entry (contribution to CLS). + */ + value?: number; + } + } +} + +/** + * A browser Largest Contentful Paint (LCP) event from the Performance Timeline + * API. + */ +export interface BrowserPageLcpEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'page_lcp'; + + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + data?: BrowserPageLcpEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserPageLcpEvent { + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + export interface Data extends TelemetryAPI.BrowserEventContext { + /** + * LargestContentfulPaint attributes from the Performance Timeline entry. + */ + lcp_details?: Data.LcpDetails; + + /** + * CDP frame identifier of the frame where the LCP element was rendered. + */ + source_frame_id?: string; + + /** + * Performance Timeline timestamp of the LCP entry in milliseconds. + */ + time?: number; + } + + export namespace Data { + /** + * LargestContentfulPaint attributes from the Performance Timeline entry. + */ + export interface LcpDetails { + /** + * id attribute of the LCP element, if present. + */ + element_id?: string; + + /** + * Load time of the LCP element in milliseconds. + */ + load_time?: number; + + /** + * CDP DOM node identifier of the LCP element. + */ + node_id?: number; + + /** + * Render time of the LCP element in milliseconds; 0 for cross-origin images + * without Timing-Allow-Origin. + */ + render_time?: number; + + /** + * Visible area of the LCP element in pixels squared. + */ + size?: number; + + /** + * URL of the LCP element for image or video elements. + */ + url?: string; + } + } +} + +/** + * A browser page load event (CDP Page.loadEventFired). + */ +export interface BrowserPageLoadEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'page_load'; + + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + data?: BrowserPageLoadEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserPageLoadEvent { + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + export interface Data extends TelemetryAPI.BrowserEventContext { + /** + * Chrome monotonic clock value in seconds at which the load event fired, relative + * to browser process start (not Unix epoch). Use ts for wall-clock time. + */ + cdp_timestamp?: number; + } +} + +/** + * A browser page navigation started event (CDP Page.frameNavigated). Carries nav + * context fields inline but not nav_seq, as this event resets the navigation + * epoch. + */ +export interface BrowserPageNavigationEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'page_navigation'; + + data?: BrowserPageNavigationEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserPageNavigationEvent { + export interface Data { + /** + * CDP frame identifier of the navigated frame. + */ + frame_id?: string; + + /** + * New CDP document loader identifier assigned for this navigation. + */ + loader_id?: string; + + /** + * Parent frame identifier for subframe navigations; absent for top-level + * navigations. + */ + parent_frame_id?: string; + + /** + * CDP session identifier. + */ + session_id?: string; + + /** + * Browser target identifier. + */ + target_id?: string; + + /** + * CDP target type of the page that produced the event. + */ + target_type?: 'page' | 'background_page' | 'service_worker' | 'shared_worker' | 'other'; + + /** + * URL navigated to. + */ + url?: string; + } +} + +/** + * Emitted when page_dom_content_loaded and page_layout_settled have both fired for + * the same navigation, indicating the page is loaded and visually stable. + * Independent of network_idle; a single pending request does not block it. + */ +export interface BrowserPageNavigationSettledEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'page_navigation_settled'; + + /** + * Browser event context stamped by the browser monitor onto all CDP-sourced + * events. Identifies the target, frame, and navigation epoch in which the event + * occurred. + */ + data?: BrowserEventContext; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +/** + * A new browser tab or target was opened (CDP Target.attachedToTarget for page + * targets). Fires before a CDP session is attached to the new target, so + * session_id, frame_id, loader_id, and nav_seq are absent; this event does not + * compose BrowserEventContext. Consumers reading context fields generically should + * treat it as a special case. + */ +export interface BrowserPageTabOpenedEvent { + /** + * Provenance metadata identifying which producer emitted the event. + */ + source: BrowserEventSource; + + /** + * Event timestamp in Unix microseconds. + */ + ts: number; + + type: 'page_tab_opened'; + + data?: BrowserPageTabOpenedEvent.Data; + + /** + * True if the data field was truncated due to size limits. + */ + truncated?: boolean; +} + +export namespace BrowserPageTabOpenedEvent { + export interface Data { + /** + * Target identifier of the tab that opened this one, if any. + */ + opener_id?: string; + + /** + * CDP target identifier for the newly opened tab. + */ + target_id?: string; + + /** + * CDP target type of the page that produced the event. + */ + target_type?: 'page' | 'background_page' | 'service_worker' | 'shared_worker' | 'other'; + + /** + * Initial page title of the new tab. + */ + title?: string; + + /** + * Initial URL of the new tab. + */ + url?: string; + } +} + +/** + * Per-category telemetry capture settings. + */ +export interface BrowserTelemetryCategoriesConfig { + /** + * Console output (log, warn, error) and uncaught exceptions. + */ + console?: BrowserTelemetryCategoryConfig; + + /** + * User interaction events including clicks, keydowns, and scroll-settled events. + */ + interaction?: BrowserTelemetryCategoryConfig; + + /** + * HTTP request and response metadata including URL, method, status code, and + * timing. Request post data is forwarded as-is from CDP. Text response bodies are + * truncated at 8 KB for structured types (JSON, XML, form data) and 4 KB for other + * text types. Binary responses (images, fonts, media) are excluded. + */ + network?: BrowserTelemetryCategoryConfig; + + /** + * Page lifecycle events including navigation, DOMContentLoaded, load, layout + * shifts, and LCP. + */ + page?: BrowserTelemetryCategoryConfig; +} + +/** + * Per-category telemetry configuration. + */ +export interface BrowserTelemetryCategoryConfig { + /** + * Whether this category is captured. Defaults to true if omitted. + */ + enabled?: boolean; +} + +/** + * Telemetry configuration for a browser session. + */ +export interface BrowserTelemetryConfig { + /** + * Per-category enable/disable flags. If omitted, all categories are captured. + */ + browser?: BrowserTelemetryCategoriesConfig; +} + +/** + * Union type representing any browser telemetry event. Discriminated on `type`. + * Events with a `monitor_` prefix (monitor_screenshot, monitor_disconnected, + * monitor_reconnected, monitor_reconnect_failed, monitor_init_failed) are always + * emitted regardless of the category configuration in BrowserTelemetryConfig. All + * other event types are controlled by the per-category enable/disable flags. + */ +export type BrowserTelemetryEvent = + | BrowserConsoleLogEvent + | BrowserConsoleErrorEvent + | BrowserNetworkRequestEvent + | BrowserNetworkResponseEvent + | BrowserNetworkLoadingFailedEvent + | BrowserNetworkIdleEvent + | BrowserPageNavigationEvent + | BrowserPageDomContentLoadedEvent + | BrowserPageLoadEvent + | BrowserPageTabOpenedEvent + | BrowserPageLayoutShiftEvent + | BrowserPageLcpEvent + | BrowserPageLayoutSettledEvent + | BrowserPageNavigationSettledEvent + | BrowserInteractionClickEvent + | BrowserInteractionKeyEvent + | BrowserInteractionScrollSettledEvent + | BrowserMonitorScreenshotEvent + | BrowserMonitorDisconnectedEvent + | BrowserMonitorReconnectedEvent + | BrowserMonitorReconnectFailedEvent + | BrowserMonitorInitFailedEvent; + +/** + * Envelope wrapping a browser telemetry event with its monotonic sequence number. + * Each SSE data: frame carries one envelope as JSON. The seq value is also emitted + * as the SSE id: field so clients can pass it as Last-Event-ID on reconnect. + */ +export interface TelemetryStreamResponse { + /** + * Union type representing any browser telemetry event. Discriminated on `type`. + * Events with a `monitor_` prefix (monitor_screenshot, monitor_disconnected, + * monitor_reconnected, monitor_reconnect_failed, monitor_init_failed) are always + * emitted regardless of the category configuration in BrowserTelemetryConfig. All + * other event types are controlled by the per-category enable/disable flags. + */ + event: BrowserTelemetryEvent; + + /** + * Process-monotonic sequence number assigned by the browser VM. Pass as + * Last-Event-ID on reconnect to resume without gaps. Gaps in received seq values + * indicate dropped events. + */ + seq: number; +} + +export interface TelemetryStreamParams { + /** + * Last event sequence number for SSE reconnection (sent by SSE clients on + * reconnect) + */ + 'Last-Event-ID'?: string; +} + +export declare namespace Telemetry { + export { + type BrowserCallStack as BrowserCallStack, + type BrowserConsoleErrorEvent as BrowserConsoleErrorEvent, + type BrowserConsoleLogEvent as BrowserConsoleLogEvent, + type BrowserEventContext as BrowserEventContext, + type BrowserEventSource as BrowserEventSource, + type BrowserHTTPHeaders as BrowserHTTPHeaders, + type BrowserInteractionClickEvent as BrowserInteractionClickEvent, + type BrowserInteractionKeyEvent as BrowserInteractionKeyEvent, + type BrowserInteractionScrollSettledEvent as BrowserInteractionScrollSettledEvent, + type BrowserMonitorDisconnectedEvent as BrowserMonitorDisconnectedEvent, + type BrowserMonitorInitFailedEvent as BrowserMonitorInitFailedEvent, + type BrowserMonitorReconnectFailedEvent as BrowserMonitorReconnectFailedEvent, + type BrowserMonitorReconnectedEvent as BrowserMonitorReconnectedEvent, + type BrowserMonitorScreenshotEvent as BrowserMonitorScreenshotEvent, + type BrowserNetworkIdleEvent as BrowserNetworkIdleEvent, + type BrowserNetworkLoadingFailedEvent as BrowserNetworkLoadingFailedEvent, + type BrowserNetworkRequestEvent as BrowserNetworkRequestEvent, + type BrowserNetworkResponseEvent as BrowserNetworkResponseEvent, + type BrowserPageDomContentLoadedEvent as BrowserPageDomContentLoadedEvent, + type BrowserPageLayoutSettledEvent as BrowserPageLayoutSettledEvent, + type BrowserPageLayoutShiftEvent as BrowserPageLayoutShiftEvent, + type BrowserPageLcpEvent as BrowserPageLcpEvent, + type BrowserPageLoadEvent as BrowserPageLoadEvent, + type BrowserPageNavigationEvent as BrowserPageNavigationEvent, + type BrowserPageNavigationSettledEvent as BrowserPageNavigationSettledEvent, + type BrowserPageTabOpenedEvent as BrowserPageTabOpenedEvent, + type BrowserTelemetryCategoriesConfig as BrowserTelemetryCategoriesConfig, + type BrowserTelemetryCategoryConfig as BrowserTelemetryCategoryConfig, + type BrowserTelemetryConfig as BrowserTelemetryConfig, + type BrowserTelemetryEvent as BrowserTelemetryEvent, + type TelemetryStreamResponse as TelemetryStreamResponse, + type TelemetryStreamParams as TelemetryStreamParams, + }; +} diff --git a/src/resources/invocations.ts b/src/resources/invocations.ts index d51c8ca..50dafd9 100644 --- a/src/resources/invocations.ts +++ b/src/resources/invocations.ts @@ -3,6 +3,7 @@ import { APIResource } from '../core/resource'; import * as Shared from './shared'; import * as BrowsersAPI from './browsers/browsers'; +import * as TelemetryAPI from './browsers/telemetry'; import { APIPromise } from '../core/api-promise'; import { OffsetPagination, type OffsetPaginationParams, PagePromise } from '../core/pagination'; import { Stream } from '../core/streaming'; @@ -509,10 +510,19 @@ export namespace InvocationListBrowsersResponse { proxy_id?: string; /** - * Start URL requested for the session, if provided. + * URL the session was asked to navigate to on creation, if any. Recorded for + * debugging. Navigation is fire-and-forget — the URL is dispatched to the browser + * without waiting for it to load, and any errors (DNS failure, bad status, + * timeout) are silently dropped. Captures what was requested, not what the browser + * actually loaded. */ start_url?: string; + /** + * Active telemetry configuration for the session, if any. + */ + telemetry?: TelemetryAPI.BrowserTelemetryConfig | null; + /** * Session usage metrics. */ diff --git a/src/resources/proxies.ts b/src/resources/proxies.ts index fdf7b92..b2eb567 100644 --- a/src/resources/proxies.ts +++ b/src/resources/proxies.ts @@ -1203,7 +1203,9 @@ export interface ProxyCheckParams { * between requests, so a successful check validates proxy configuration but does * not guarantee that a subsequent browser session will use the same exit IP or * reach the same site — it is useful for verifying credentials and connectivity, - * not for predicting site-specific behavior. + * not for predicting site-specific behavior. When provided, the check result does + * not update the proxy's health status, since a failure may indicate a problem + * with the target site rather than the proxy itself. */ url?: string; } diff --git a/tests/api-resources/browsers/browsers.test.ts b/tests/api-resources/browsers/browsers.test.ts index 5ea987e..6329136 100644 --- a/tests/api-resources/browsers/browsers.test.ts +++ b/tests/api-resources/browsers/browsers.test.ts @@ -41,6 +41,14 @@ describe('resource browsers', () => { proxy_id: 'proxy_id', start_url: 'https://example.com', stealth: true, + telemetry: { + browser: { + console: { enabled: true }, + interaction: { enabled: true }, + network: { enabled: true }, + page: { enabled: true }, + }, + }, timeout_seconds: 10, viewport: { height: 800, diff --git a/tests/api-resources/browsers/telemetry.test.ts b/tests/api-resources/browsers/telemetry.test.ts new file mode 100644 index 0000000..e198656 --- /dev/null +++ b/tests/api-resources/browsers/telemetry.test.ts @@ -0,0 +1,34 @@ +// 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 telemetry', () => { + // Mock server tests are disabled + test.skip('stream', async () => { + const responsePromise = client.browsers.telemetry.stream('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); + }); + + // Mock server tests are disabled + test.skip('stream: 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.browsers.telemetry.stream( + 'id', + { 'Last-Event-ID': 'Last-Event-ID' }, + { path: '/_stainless_unknown_path' }, + ), + ).rejects.toThrow(Kernel.NotFoundError); + }); +}); From 1c2bd3932940f897f304b1bfb3ac083dd3f6e0a8 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 21 May 2026 18:53:37 +0000 Subject: [PATCH 7/7] release: 0.56.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 20 ++++++++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- src/version.ts | 2 +- 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index b2ddd21..13093da 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.55.0" + ".": "0.56.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c34e4c..fc8733a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## 0.56.0 (2026-05-21) + +Full Changelog: [v0.55.0...v0.56.0](https://github.com/kernel/kernel-node-sdk/compare/v0.55.0...v0.56.0) + +### Features + +* [kernel-1116] browser events api integration ([958614b](https://github.com/kernel/kernel-node-sdk/commit/958614b4a683675d7e00d901fee039515f94df6a)) +* browsers: accept chrome_policy on POST /browsers (KERNEL-1216) ([e3b32bb](https://github.com/kernel/kernel-node-sdk/commit/e3b32bb8178e98e4ea15fb358a3e370dd96d0315)) +* Expose POST /projects in public API ([e251459](https://github.com/kernel/kernel-node-sdk/commit/e251459afc038f2e15eef5ab77b91b398a75eae1)) + + +### Bug Fixes + +* **typescript:** upgrade tsc-multi so that it works with Node 26 ([46e3fb5](https://github.com/kernel/kernel-node-sdk/commit/46e3fb57502dcf44dd4c972fc42fb09c30eab6eb)) + + +### Chores + +* **tests:** remove redundant File import ([1677dc1](https://github.com/kernel/kernel-node-sdk/commit/1677dc13811672b22ec12102bda30755fa4d1f6f)) + ## 0.55.0 (2026-05-15) Full Changelog: [v0.54.0...v0.55.0](https://github.com/kernel/kernel-node-sdk/compare/v0.54.0...v0.55.0) diff --git a/package-lock.json b/package-lock.json index c085d96..c951133 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@onkernel/sdk", - "version": "0.55.0", + "version": "0.56.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@onkernel/sdk", - "version": "0.55.0", + "version": "0.56.0", "license": "Apache-2.0", "devDependencies": { "@arethetypeswrong/cli": "^0.17.0", diff --git a/package.json b/package.json index b78194a..2b6179c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@onkernel/sdk", - "version": "0.55.0", + "version": "0.56.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 7c47df5..2d175e1 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '0.55.0'; // x-release-please-version +export const VERSION = '0.56.0'; // x-release-please-version