diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index e7ca613..13708fa 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.7.0"
+ ".": "0.7.1"
}
diff --git a/.stats.yml b/.stats.yml
index 401ed65..aa1aff7 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 17
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-3ec96d0022acb32aa2676c2e7ae20152b899a776ccd499380c334c955b9ba071.yml
-openapi_spec_hash: b64c095d82185c1cd0355abea88b606f
-config_hash: 00ec9df250b9dc077f8d3b93a442d252
+configured_endpoints: 18
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-d173129101e26f450c200e84430d993479c034700cf826917425d513b88912e6.yml
+openapi_spec_hash: 150b86da7588979d7619b1a894e4720c
+config_hash: eaeed470b1070b34df69c49d68e67355
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 54a37d1..71387ef 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,23 @@
# Changelog
+## 0.7.1 (2025-07-08)
+
+Full Changelog: [v0.7.0...v0.7.1](https://github.com/onkernel/kernel-node-sdk/compare/v0.7.0...v0.7.1)
+
+### Features
+
+* **api:** manual updates ([a018f17](https://github.com/onkernel/kernel-node-sdk/commit/a018f171c8161b3595fd66c9b2c8ca458e50deec))
+
+
+### Bug Fixes
+
+* avoid console usage ([f37b356](https://github.com/onkernel/kernel-node-sdk/commit/f37b3560b92abc5a85416b9b69f03a70b3ff71cf))
+
+
+### Chores
+
+* add docs to RequestOptions type ([fcb82ff](https://github.com/onkernel/kernel-node-sdk/commit/fcb82ff3d5c14af006bba0e441d57baf318a19cf))
+
## 0.7.0 (2025-07-02)
Full Changelog: [v0.6.5...v0.7.0](https://github.com/onkernel/kernel-node-sdk/compare/v0.6.5...v0.7.0)
diff --git a/api.md b/api.md
index 736d6e7..eeda41d 100644
--- a/api.md
+++ b/api.md
@@ -82,3 +82,4 @@ Methods:
- client.browsers.list() -> BrowserListResponse
- client.browsers.delete({ ...params }) -> void
- client.browsers.deleteByID(id) -> void
+- client.browsers.retrieveReplay(id) -> Response
diff --git a/package.json b/package.json
index dce29ff..9abb848 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@onkernel/sdk",
- "version": "0.7.0",
+ "version": "0.7.1",
"description": "The official TypeScript library for the Kernel API",
"author": "Kernel <>",
"types": "dist/index.d.ts",
diff --git a/src/client.ts b/src/client.ts
index 3b75d5b..b8f3925 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -95,6 +95,8 @@ export interface ClientOptions {
*
* Note that request timeouts are retried by default, so in a worst-case scenario you may wait
* much longer than this timeout before the promise succeeds or fails.
+ *
+ * @unit milliseconds
*/
timeout?: number | undefined;
/**
diff --git a/src/core/streaming.ts b/src/core/streaming.ts
index 7191ee4..a24bcfe 100644
--- a/src/core/streaming.ts
+++ b/src/core/streaming.ts
@@ -5,6 +5,8 @@ import { findDoubleNewlineIndex, LineDecoder } from '../internal/decoders/line';
import { ReadableStreamToAsyncIterable } from '../internal/shims';
import { isAbortError } from '../internal/errors';
import { encodeUTF8 } from '../internal/utils/bytes';
+import { loggerFor } from '../internal/utils/log';
+import type { Kernel } from '../client';
type Bytes = string | ArrayBuffer | Uint8Array | null | undefined;
@@ -16,16 +18,24 @@ export type ServerSentEvent = {
export class Stream- implements AsyncIterable
- {
controller: AbortController;
+ #client: Kernel | undefined;
constructor(
private iterator: () => AsyncIterator
- ,
controller: AbortController,
+ client?: Kernel,
) {
this.controller = controller;
+ this.#client = client;
}
- static fromSSEResponse
- (response: Response, controller: AbortController): Stream
- {
+ static fromSSEResponse
- (
+ response: Response,
+ controller: AbortController,
+ client?: Kernel,
+ ): Stream
- {
let consumed = false;
+ const logger = client ? loggerFor(client) : console;
async function* iterator(): AsyncIterator
- {
if (consumed) {
@@ -38,8 +48,8 @@ export class Stream
- implements AsyncIterable
- {
try {
yield JSON.parse(sse.data);
} catch (e) {
- console.error(`Could not parse message into JSON:`, sse.data);
- console.error(`From chunk:`, sse.raw);
+ logger.error(`Could not parse message into JSON:`, sse.data);
+ logger.error(`From chunk:`, sse.raw);
throw e;
}
}
@@ -54,14 +64,18 @@ export class Stream
- implements AsyncIterable
- {
}
}
- return new Stream(iterator, controller);
+ return new Stream(iterator, controller, client);
}
/**
* Generates a Stream from a newline-separated ReadableStream
* where each item is a JSON value.
*/
- static fromReadableStream
- (readableStream: ReadableStream, controller: AbortController): Stream
- {
+ static fromReadableStream
- (
+ readableStream: ReadableStream,
+ controller: AbortController,
+ client?: Kernel,
+ ): Stream
- {
let consumed = false;
async function* iterLines(): AsyncGenerator {
@@ -101,7 +115,7 @@ export class Stream
- implements AsyncIterable
- {
}
}
- return new Stream(iterator, controller);
+ return new Stream(iterator, controller, client);
}
[Symbol.asyncIterator](): AsyncIterator
- {
@@ -131,8 +145,8 @@ export class Stream
- implements AsyncIterable
- {
};
return [
- new Stream(() => teeIterator(left), this.controller),
- new Stream(() => teeIterator(right), this.controller),
+ new Stream(() => teeIterator(left), this.controller, this.#client),
+ new Stream(() => teeIterator(right), this.controller, this.#client),
];
}
diff --git a/src/internal/parse.ts b/src/internal/parse.ts
index 18d0b41..7fe9be4 100644
--- a/src/internal/parse.ts
+++ b/src/internal/parse.ts
@@ -24,10 +24,10 @@ export async function defaultParseResponse(client: Kernel, props: APIResponse
// that if you set `stream: true` the response type must also be `Stream`
if (props.options.__streamClass) {
- return props.options.__streamClass.fromSSEResponse(response, props.controller) as any;
+ return props.options.__streamClass.fromSSEResponse(response, props.controller, client) as any;
}
- return Stream.fromSSEResponse(response, props.controller) as any;
+ return Stream.fromSSEResponse(response, props.controller, client) as any;
}
// fetch refuses to read the body when the status code is 204.
diff --git a/src/internal/request-options.ts b/src/internal/request-options.ts
index ffe01ae..56765e5 100644
--- a/src/internal/request-options.ts
+++ b/src/internal/request-options.ts
@@ -10,17 +10,70 @@ import { type HeadersLike } from './headers';
export type FinalRequestOptions = RequestOptions & { method: HTTPMethod; path: string };
export type RequestOptions = {
+ /**
+ * The HTTP method for the request (e.g., 'get', 'post', 'put', 'delete').
+ */
method?: HTTPMethod;
+
+ /**
+ * The URL path for the request.
+ *
+ * @example "/v1/foo"
+ */
path?: string;
+
+ /**
+ * Query parameters to include in the request URL.
+ */
query?: object | undefined | null;
+
+ /**
+ * The request body. Can be a string, JSON object, FormData, or other supported types.
+ */
body?: unknown;
+
+ /**
+ * HTTP headers to include with the request. Can be a Headers object, plain object, or array of tuples.
+ */
headers?: HeadersLike;
+
+ /**
+ * The maximum number of times that the client will retry a request in case of a
+ * temporary failure, like a network error or a 5XX error from the server.
+ *
+ * @default 2
+ */
maxRetries?: number;
+
stream?: boolean | undefined;
+
+ /**
+ * The maximum amount of time (in milliseconds) that the client should wait for a response
+ * from the server before timing out a single request.
+ *
+ * @unit milliseconds
+ */
timeout?: number;
+
+ /**
+ * Additional `RequestInit` options to be passed to the underlying `fetch` call.
+ * These options will be merged with the client's default fetch options.
+ */
fetchOptions?: MergedRequestInit;
+
+ /**
+ * An AbortSignal that can be used to cancel the request.
+ */
signal?: AbortSignal | undefined | null;
+
+ /**
+ * A unique key for this request to enable idempotency.
+ */
idempotencyKey?: string;
+
+ /**
+ * Override the default base URL for this specific request.
+ */
defaultBaseURL?: string | undefined;
__binaryResponse?: boolean | undefined;
diff --git a/src/resources/browsers.ts b/src/resources/browsers.ts
index 8afcb8c..14398d4 100644
--- a/src/resources/browsers.ts
+++ b/src/resources/browsers.ts
@@ -84,6 +84,27 @@ export class Browsers extends APIResource {
headers: buildHeaders([{ Accept: '*/*' }, options?.headers]),
});
}
+
+ /**
+ * Get browser session replay.
+ *
+ * @example
+ * ```ts
+ * const response = await client.browsers.retrieveReplay(
+ * 'htzv5orfit78e1m2biiifpbv',
+ * );
+ *
+ * const content = await response.blob();
+ * console.log(content);
+ * ```
+ */
+ retrieveReplay(id: string, options?: RequestOptions): APIPromise {
+ return this._client.get(path`/browsers/${id}/replay`, {
+ ...options,
+ headers: buildHeaders([{ Accept: 'video/mp4' }, options?.headers]),
+ __binaryResponse: true,
+ });
+ }
}
/**
@@ -117,6 +138,11 @@ export interface BrowserCreateResponse {
* Optional persistence configuration for the browser session.
*/
persistence?: BrowserPersistence;
+
+ /**
+ * Remote URL for viewing the browser session replay if enabled
+ */
+ replay_view_url?: string;
}
export interface BrowserRetrieveResponse {
@@ -140,6 +166,11 @@ export interface BrowserRetrieveResponse {
* Optional persistence configuration for the browser session.
*/
persistence?: BrowserPersistence;
+
+ /**
+ * Remote URL for viewing the browser session replay if enabled
+ */
+ replay_view_url?: string;
}
export type BrowserListResponse = Array;
@@ -166,6 +197,11 @@ export namespace BrowserListResponse {
* Optional persistence configuration for the browser session.
*/
persistence?: BrowsersAPI.BrowserPersistence;
+
+ /**
+ * Remote URL for viewing the browser session replay if enabled
+ */
+ replay_view_url?: string;
}
}
@@ -186,6 +222,11 @@ export interface BrowserCreateParams {
*/
persistence?: BrowserPersistence;
+ /**
+ * If true, enables replay recording of the browser session. Defaults to false.
+ */
+ replay?: boolean;
+
/**
* If true, launches the browser in stealth mode to reduce detection by anti-bot
* mechanisms.
diff --git a/src/version.ts b/src/version.ts
index d9da9f7..5e85c4b 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const VERSION = '0.7.0'; // x-release-please-version
+export const VERSION = '0.7.1'; // x-release-please-version
diff --git a/tests/api-resources/browsers.test.ts b/tests/api-resources/browsers.test.ts
index d28bd02..b066fa2 100644
--- a/tests/api-resources/browsers.test.ts
+++ b/tests/api-resources/browsers.test.ts
@@ -29,6 +29,7 @@ describe('resource browsers', () => {
headless: false,
invocation_id: 'rr33xuugxj9h0bkf1rdt2bet',
persistence: { id: 'my-awesome-browser-for-user-1234' },
+ replay: true,
stealth: true,
},
{ path: '/_stainless_unknown_path' },