Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.2.0"
".": "0.3.0"
}
6 changes: 3 additions & 3 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 7
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-705638ac8966569986bd9ebb7c9761bf0016909e9f2753e77ceabb12c8049511.yml
openapi_spec_hash: a8fbbcaa38e91c7f97313620b42d8d62
config_hash: a35b56eb05306a0f02e83c11d57f975f
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-f7d6b6489159f611a2bfdc267ce0a6fc0455bed1ffa0c310044baaa5d8381b9b.yml
openapi_spec_hash: cd88d8068abfde8382da0bed674e440c
config_hash: 5c69fb596588b8ace08203858518c149
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Changelog

## 0.3.0 (2025-12-18)

Full Changelog: [v0.2.0...v0.3.0](https://github.com/browserbase/stagehand-java/compare/v0.2.0...v0.3.0)

### Features

* **api:** manual updates ([b6bdf1a](https://github.com/browserbase/stagehand-java/commit/b6bdf1a26a45556dcfee59b088983cd7e7839f43))
* **api:** manual updates ([9b6860a](https://github.com/browserbase/stagehand-java/commit/9b6860a4f60d1a740fbb026eef291e40fb8e1845))
* **api:** manual updates ([28f7978](https://github.com/browserbase/stagehand-java/commit/28f7978e1f040169dbb20aa68efb8e5ceb9a34d2))
* **api:** manual updates ([07db616](https://github.com/browserbase/stagehand-java/commit/07db616b7209716efa346035d65f5d7bf616c992))
* **api:** manual updates ([3cf2073](https://github.com/browserbase/stagehand-java/commit/3cf20739785134610aa7bcbdbce3215c3c3a9970))
* **api:** manual updates ([adace53](https://github.com/browserbase/stagehand-java/commit/adace53fc3e4a0fb4b866172aec98519ec0f29d5))
* **api:** manual updates ([dd65420](https://github.com/browserbase/stagehand-java/commit/dd65420fecb521fba36cbf2a623ce675973a27a0))
* **api:** manual updates ([067c9e6](https://github.com/browserbase/stagehand-java/commit/067c9e644940fa3671665a902bc605b8e358473f))
* **api:** manual updates ([d7aabe3](https://github.com/browserbase/stagehand-java/commit/d7aabe36f42d8344477f2f468bd3ba15837c0516))
* **api:** manual updates ([13074f1](https://github.com/browserbase/stagehand-java/commit/13074f11bbc12057b60e89f37f850ca8f5bc7a83))

## 0.2.0 (2025-12-16)

Full Changelog: [v0.1.0...v0.2.0](https://github.com/browserbase/stagehand-java/compare/v0.1.0...v0.2.0)
Expand Down
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

<!-- x-release-please-start-version -->

[![Maven Central](https://img.shields.io/maven-central/v/com.browserbase.api/stagehand-java)](https://central.sonatype.com/artifact/com.browserbase.api/stagehand-java/0.2.0)
[![javadoc](https://javadoc.io/badge2/com.browserbase.api/stagehand-java/0.2.0/javadoc.svg)](https://javadoc.io/doc/com.browserbase.api/stagehand-java/0.2.0)
[![Maven Central](https://img.shields.io/maven-central/v/com.browserbase.api/stagehand-java)](https://central.sonatype.com/artifact/com.browserbase.api/stagehand-java/0.3.0)
[![javadoc](https://javadoc.io/badge2/com.browserbase.api/stagehand-java/0.3.0/javadoc.svg)](https://javadoc.io/doc/com.browserbase.api/stagehand-java/0.3.0)

<!-- x-release-please-end -->

Expand All @@ -13,7 +13,7 @@ It is generated with [Stainless](https://www.stainless.com/).

<!-- x-release-please-start-version -->

The REST API documentation can be found on [docs.stagehand.dev](https://docs.stagehand.dev). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.browserbase.api/stagehand-java/0.2.0).
The REST API documentation can be found on [docs.stagehand.dev](https://docs.stagehand.dev). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.browserbase.api/stagehand-java/0.3.0).

<!-- x-release-please-end -->

Expand All @@ -24,7 +24,7 @@ The REST API documentation can be found on [docs.stagehand.dev](https://docs.sta
### Gradle

```kotlin
implementation("com.browserbase.api:stagehand-java:0.2.0")
implementation("com.browserbase.api:stagehand-java:0.3.0")
```

### Maven
Expand All @@ -33,7 +33,7 @@ implementation("com.browserbase.api:stagehand-java:0.2.0")
<dependency>
<groupId>com.browserbase.api</groupId>
<artifactId>stagehand-java</artifactId>
<version>0.2.0</version>
<version>0.3.0</version>
</dependency>
```

Expand All @@ -56,7 +56,7 @@ import com.browserbase.api.models.sessions.SessionActResponse;
StagehandClient client = StagehandOkHttpClient.fromEnv();

SessionActParams params = SessionActParams.builder()
.sessionId("00000000-your-session-id-000000000000")
.id("00000000-your-session-id-000000000000")
.input("click the first link on the page")
.build();
SessionActResponse response = client.sessions().act(params);
Expand Down Expand Up @@ -162,7 +162,7 @@ import java.util.concurrent.CompletableFuture;
StagehandClient client = StagehandOkHttpClient.fromEnv();

SessionActParams params = SessionActParams.builder()
.sessionId("00000000-your-session-id-000000000000")
.id("00000000-your-session-id-000000000000")
.input("click the first link on the page")
.build();
CompletableFuture<SessionActResponse> response = client.async().sessions().act(params);
Expand All @@ -182,7 +182,7 @@ import java.util.concurrent.CompletableFuture;
StagehandClientAsync client = StagehandOkHttpClientAsync.fromEnv();

SessionActParams params = SessionActParams.builder()
.sessionId("00000000-your-session-id-000000000000")
.id("00000000-your-session-id-000000000000")
.input("click the first link on the page")
.build();
CompletableFuture<SessionActResponse> response = client.sessions().act(params);
Expand All @@ -203,8 +203,7 @@ import com.browserbase.api.models.sessions.SessionStartParams;
import com.browserbase.api.models.sessions.SessionStartResponse;

SessionStartParams params = SessionStartParams.builder()
.browserbaseApiKey("your Browserbase API key")
.browserbaseProjectId("your Browserbase Project ID")
.modelName("openai/gpt-5-nano")
.build();
HttpResponseFor<SessionStartResponse> response = client.sessions().withRawResponse().start(params);

Expand Down Expand Up @@ -237,6 +236,8 @@ The SDK throws custom unchecked exception types:
| 5xx | [`InternalServerException`](stagehand-java-core/src/main/kotlin/com/browserbase/api/errors/InternalServerException.kt) |
| others | [`UnexpectedStatusCodeException`](stagehand-java-core/src/main/kotlin/com/browserbase/api/errors/UnexpectedStatusCodeException.kt) |

[`SseException`](stagehand-java-core/src/main/kotlin/com/browserbase/api/errors/SseException.kt) is thrown for errors encountered during [SSE streaming](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) after a successful initial HTTP response.

- [`StagehandIoException`](stagehand-java-core/src/main/kotlin/com/browserbase/api/errors/StagehandIoException.kt): I/O networking errors.

- [`StagehandRetryableException`](stagehand-java-core/src/main/kotlin/com/browserbase/api/errors/StagehandRetryableException.kt): Generic error indicating a failure that could be retried by the client.
Expand Down Expand Up @@ -505,8 +506,8 @@ import com.browserbase.api.core.JsonMissing;
import com.browserbase.api.models.sessions.SessionActParams;

SessionActParams params = SessionActParams.builder()
.input("click the sign in button")
.sessionId(JsonMissing.of())
.input("Click the login button")
.id(JsonMissing.of())
.build();
```

Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ repositories {

allprojects {
group = "com.browserbase.api"
version = "0.2.0" // x-release-please-version
version = "0.3.0" // x-release-please-version
}

subprojects {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.browserbase.api.client.StagehandClientImpl
import com.browserbase.api.core.ClientOptions
import com.browserbase.api.core.Sleeper
import com.browserbase.api.core.Timeout
import com.browserbase.api.core.http.AsyncStreamResponse
import com.browserbase.api.core.http.Headers
import com.browserbase.api.core.http.HttpClient
import com.browserbase.api.core.http.QueryParams
Expand All @@ -16,6 +17,7 @@ import java.net.Proxy
import java.time.Clock
import java.time.Duration
import java.util.Optional
import java.util.concurrent.Executor
import javax.net.ssl.HostnameVerifier
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.X509TrustManager
Expand Down Expand Up @@ -121,6 +123,17 @@ class StagehandOkHttpClient private constructor() {
*/
fun jsonMapper(jsonMapper: JsonMapper) = apply { clientOptions.jsonMapper(jsonMapper) }

/**
* The executor to use for running [AsyncStreamResponse.Handler] callbacks.
*
* Defaults to a dedicated cached thread pool.
*
* This class takes ownership of the executor and shuts it down, if possible, when closed.
*/
fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply {
clientOptions.streamHandlerExecutor(streamHandlerExecutor)
}

/**
* The interface to use for delaying execution, like during retries.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.browserbase.api.client.StagehandClientAsyncImpl
import com.browserbase.api.core.ClientOptions
import com.browserbase.api.core.Sleeper
import com.browserbase.api.core.Timeout
import com.browserbase.api.core.http.AsyncStreamResponse
import com.browserbase.api.core.http.Headers
import com.browserbase.api.core.http.HttpClient
import com.browserbase.api.core.http.QueryParams
Expand All @@ -16,6 +17,7 @@ import java.net.Proxy
import java.time.Clock
import java.time.Duration
import java.util.Optional
import java.util.concurrent.Executor
import javax.net.ssl.HostnameVerifier
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.X509TrustManager
Expand Down Expand Up @@ -121,6 +123,17 @@ class StagehandOkHttpClientAsync private constructor() {
*/
fun jsonMapper(jsonMapper: JsonMapper) = apply { clientOptions.jsonMapper(jsonMapper) }

/**
* The executor to use for running [AsyncStreamResponse.Handler] callbacks.
*
* Defaults to a dedicated cached thread pool.
*
* This class takes ownership of the executor and shuts it down, if possible, when closed.
*/
fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply {
clientOptions.streamHandlerExecutor(streamHandlerExecutor)
}

/**
* The interface to use for delaying execution, like during retries.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

package com.browserbase.api.core

import com.browserbase.api.core.http.AsyncStreamResponse
import com.browserbase.api.core.http.Headers
import com.browserbase.api.core.http.HttpClient
import com.browserbase.api.core.http.PhantomReachableClosingHttpClient
Expand All @@ -11,6 +12,11 @@ import com.fasterxml.jackson.databind.json.JsonMapper
import java.time.Clock
import java.time.Duration
import java.util.Optional
import java.util.concurrent.Executor
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.ThreadFactory
import java.util.concurrent.atomic.AtomicLong
import kotlin.jvm.optionals.getOrNull

/** A class representing the SDK client configuration. */
Expand Down Expand Up @@ -40,6 +46,14 @@ private constructor(
* rarely needs to be overridden.
*/
@get:JvmName("jsonMapper") val jsonMapper: JsonMapper,
/**
* The executor to use for running [AsyncStreamResponse.Handler] callbacks.
*
* Defaults to a dedicated cached thread pool.
*
* This class takes ownership of the executor and shuts it down, if possible, when closed.
*/
@get:JvmName("streamHandlerExecutor") val streamHandlerExecutor: Executor,
/**
* The interface to use for delaying execution, like during retries.
*
Expand Down Expand Up @@ -147,6 +161,7 @@ private constructor(
private var httpClient: HttpClient? = null
private var checkJacksonVersionCompatibility: Boolean = true
private var jsonMapper: JsonMapper = jsonMapper()
private var streamHandlerExecutor: Executor? = null
private var sleeper: Sleeper? = null
private var clock: Clock = Clock.systemUTC()
private var baseUrl: String? = null
Expand All @@ -164,6 +179,7 @@ private constructor(
httpClient = clientOptions.originalHttpClient
checkJacksonVersionCompatibility = clientOptions.checkJacksonVersionCompatibility
jsonMapper = clientOptions.jsonMapper
streamHandlerExecutor = clientOptions.streamHandlerExecutor
sleeper = clientOptions.sleeper
clock = clientOptions.clock
baseUrl = clientOptions.baseUrl
Expand Down Expand Up @@ -207,6 +223,20 @@ private constructor(
*/
fun jsonMapper(jsonMapper: JsonMapper) = apply { this.jsonMapper = jsonMapper }

/**
* The executor to use for running [AsyncStreamResponse.Handler] callbacks.
*
* Defaults to a dedicated cached thread pool.
*
* This class takes ownership of the executor and shuts it down, if possible, when closed.
*/
fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply {
this.streamHandlerExecutor =
if (streamHandlerExecutor is ExecutorService)
PhantomReachableExecutorService(streamHandlerExecutor)
else streamHandlerExecutor
}

/**
* The interface to use for delaying execution, like during retries.
*
Expand Down Expand Up @@ -422,6 +452,24 @@ private constructor(
*/
fun build(): ClientOptions {
val httpClient = checkRequired("httpClient", httpClient)
val streamHandlerExecutor =
streamHandlerExecutor
?: PhantomReachableExecutorService(
Executors.newCachedThreadPool(
object : ThreadFactory {

private val threadFactory: ThreadFactory =
Executors.defaultThreadFactory()
private val count = AtomicLong(0)

override fun newThread(runnable: Runnable): Thread =
threadFactory.newThread(runnable).also {
it.name =
"stagehand-stream-handler-thread-${count.getAndIncrement()}"
}
}
)
)
val sleeper = sleeper ?: PhantomReachableSleeper(DefaultSleeper())
val browserbaseApiKey = checkRequired("browserbaseApiKey", browserbaseApiKey)
val browserbaseProjectId = checkRequired("browserbaseProjectId", browserbaseProjectId)
Expand Down Expand Up @@ -464,6 +512,7 @@ private constructor(
.build(),
checkJacksonVersionCompatibility,
jsonMapper,
streamHandlerExecutor,
sleeper,
clock,
baseUrl,
Expand Down Expand Up @@ -491,6 +540,7 @@ private constructor(
*/
fun close() {
httpClient.close()
(streamHandlerExecutor as? ExecutorService)?.shutdown()
sleeper.close()
}
}
Loading
Loading