From 13074f11bbc12057b60e89f37f850ca8f5bc7a83 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 02:13:36 +0000 Subject: [PATCH 01/13] feat(api): manual updates --- .stats.yml | 6 +- README.md | 105 +- .../browserbase/api/models/sessions/Action.kt | 170 +- .../api/models/sessions/ModelConfig.kt | 579 +++--- .../api/models/sessions/SessionActParams.kt | 1233 ------------- .../api/models/sessions/SessionActResponse.kt | 269 --- .../api/models/sessions/SessionEndParams.kt | 229 --- .../api/models/sessions/SessionEndResponse.kt | 153 -- .../sessions/SessionExecuteAgentParams.kt | 1547 ----------------- .../sessions/SessionExecuteAgentResponse.kt | 158 -- .../models/sessions/SessionExtractParams.kt | 1064 ------------ .../models/sessions/SessionExtractResponse.kt | 457 ----- .../models/sessions/SessionNavigateParams.kt | 992 ----------- .../sessions/SessionNavigateResponse.kt | 216 --- .../models/sessions/SessionObserveParams.kt | 902 ---------- .../api/models/sessions/SessionStartParams.kt | 758 +------- .../models/sessions/SessionStartResponse.kt | 115 +- .../api/services/async/SessionServiceAsync.kt | 444 +---- .../services/async/SessionServiceAsyncImpl.kt | 261 --- .../api/services/blocking/SessionService.kt | 441 +---- .../services/blocking/SessionServiceImpl.kt | 237 --- .../api/models/sessions/ActionTest.kt | 28 +- .../api/models/sessions/ModelConfigTest.kt | 68 +- .../models/sessions/SessionActParamsTest.kt | 166 -- .../models/sessions/SessionActResponseTest.kt | 69 - .../models/sessions/SessionEndParamsTest.kt | 24 - .../models/sessions/SessionEndResponseTest.kt | 32 - .../sessions/SessionExecuteAgentParamsTest.kt | 170 -- .../SessionExecuteAgentResponseTest.kt | 34 - .../sessions/SessionExtractParamsTest.kt | 158 -- .../sessions/SessionExtractResponseTest.kt | 94 - .../sessions/SessionNavigateParamsTest.kt | 111 -- .../sessions/SessionNavigateResponseTest.kt | 36 - .../sessions/SessionObserveParamsTest.kt | 136 -- .../models/sessions/SessionStartParamsTest.kt | 66 +- .../sessions/SessionStartResponseTest.kt | 16 +- .../api/services/ErrorHandlingTest.kt | 204 +-- .../api/services/ServiceParamsTest.kt | 61 +- .../services/async/SessionServiceAsyncTest.kt | 238 +-- .../services/blocking/SessionServiceTest.kt | 232 +-- .../api/proguard/ProGuardCompatibilityTest.kt | 26 +- 41 files changed, 738 insertions(+), 11567 deletions(-) delete mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt delete mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActResponse.kt delete mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndParams.kt delete mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt delete mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParams.kt delete mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponse.kt delete mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractParams.kt delete mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractResponse.kt delete mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateParams.kt delete mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponse.kt delete mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveParams.kt delete mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt delete mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActResponseTest.kt delete mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndParamsTest.kt delete mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt delete mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParamsTest.kt delete mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponseTest.kt delete mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt delete mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractResponseTest.kt delete mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt delete mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponseTest.kt delete mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt diff --git a/.stats.yml b/.stats.yml index 36782ae..f5e93e0 100644 --- a/.stats.yml +++ b/.stats.yml @@ -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 +configured_endpoints: 1 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-516862e7e90968bc55ac44ce7ffe2d5c1f738c11757471c2b9e0e4cff9384f2c.yml +openapi_spec_hash: 19bbe52a6ae0eec7fc3f6698e831ee55 config_hash: a35b56eb05306a0f02e83c11d57f975f diff --git a/README.md b/README.md index c383ecb..ae4e26a 100644 --- a/README.md +++ b/README.md @@ -48,18 +48,14 @@ This library requires Java 8 or later. ```java import com.browserbase.api.client.StagehandClient; import com.browserbase.api.client.okhttp.StagehandOkHttpClient; -import com.browserbase.api.models.sessions.SessionActParams; -import com.browserbase.api.models.sessions.SessionActResponse; +import com.browserbase.api.models.sessions.SessionStartParams; +import com.browserbase.api.models.sessions.SessionStartResponse; // Configures using the `stagehand.browserbaseApiKey`, `stagehand.browserbaseProjectId`, `stagehand.modelApiKey` and `stagehand.baseUrl` system properties // Or configures using the `BROWSERBASE_API_KEY`, `BROWSERBASE_PROJECT_ID`, `MODEL_API_KEY` and `STAGEHAND_BASE_URL` environment variables StagehandClient client = StagehandOkHttpClient.fromEnv(); -SessionActParams params = SessionActParams.builder() - .sessionId("00000000-your-session-id-000000000000") - .input("click the first link on the page") - .build(); -SessionActResponse response = client.sessions().act(params); +SessionStartResponse response = client.sessions().start(); ``` ## Client configuration @@ -136,7 +132,7 @@ The `withOptions()` method does not affect the original client or service. To send a request to the Stagehand API, build an instance of some `Params` class and pass it to the corresponding client method. When the response is received, it will be deserialized into an instance of a Java class. -For example, `client.sessions().act(...)` should be called with an instance of `SessionActParams`, and it will return an instance of `SessionActResponse`. +For example, `client.sessions().start(...)` should be called with an instance of `SessionStartParams`, and it will return an instance of `SessionStartResponse`. ## Immutability @@ -153,19 +149,15 @@ The default client is synchronous. To switch to asynchronous execution, call the ```java import com.browserbase.api.client.StagehandClient; import com.browserbase.api.client.okhttp.StagehandOkHttpClient; -import com.browserbase.api.models.sessions.SessionActParams; -import com.browserbase.api.models.sessions.SessionActResponse; +import com.browserbase.api.models.sessions.SessionStartParams; +import com.browserbase.api.models.sessions.SessionStartResponse; import java.util.concurrent.CompletableFuture; // Configures using the `stagehand.browserbaseApiKey`, `stagehand.browserbaseProjectId`, `stagehand.modelApiKey` and `stagehand.baseUrl` system properties // Or configures using the `BROWSERBASE_API_KEY`, `BROWSERBASE_PROJECT_ID`, `MODEL_API_KEY` and `STAGEHAND_BASE_URL` environment variables StagehandClient client = StagehandOkHttpClient.fromEnv(); -SessionActParams params = SessionActParams.builder() - .sessionId("00000000-your-session-id-000000000000") - .input("click the first link on the page") - .build(); -CompletableFuture response = client.async().sessions().act(params); +CompletableFuture response = client.async().sessions().start(); ``` Or create an asynchronous client from the beginning: @@ -173,19 +165,15 @@ Or create an asynchronous client from the beginning: ```java import com.browserbase.api.client.StagehandClientAsync; import com.browserbase.api.client.okhttp.StagehandOkHttpClientAsync; -import com.browserbase.api.models.sessions.SessionActParams; -import com.browserbase.api.models.sessions.SessionActResponse; +import com.browserbase.api.models.sessions.SessionStartParams; +import com.browserbase.api.models.sessions.SessionStartResponse; import java.util.concurrent.CompletableFuture; // Configures using the `stagehand.browserbaseApiKey`, `stagehand.browserbaseProjectId`, `stagehand.modelApiKey` and `stagehand.baseUrl` system properties // Or configures using the `BROWSERBASE_API_KEY`, `BROWSERBASE_PROJECT_ID`, `MODEL_API_KEY` and `STAGEHAND_BASE_URL` environment variables StagehandClientAsync client = StagehandOkHttpClientAsync.fromEnv(); -SessionActParams params = SessionActParams.builder() - .sessionId("00000000-your-session-id-000000000000") - .input("click the first link on the page") - .build(); -CompletableFuture response = client.sessions().act(params); +CompletableFuture response = client.sessions().start(); ``` The asynchronous client supports the same options as the synchronous one, except most methods return `CompletableFuture`s. @@ -202,11 +190,7 @@ import com.browserbase.api.core.http.HttpResponseFor; 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") - .build(); -HttpResponseFor response = client.sessions().withRawResponse().start(params); +HttpResponseFor response = client.sessions().withRawResponse().start(); int statusCode = response.statusCode(); Headers headers = response.headers(); @@ -315,9 +299,7 @@ To set a custom timeout, configure the method call using the `timeout` method: ```java import com.browserbase.api.models.sessions.SessionStartResponse; -SessionStartResponse response = client.sessions().start( - params, RequestOptions.builder().timeout(Duration.ofSeconds(30)).build() -); +SessionStartResponse response = client.sessions().start(RequestOptions.builder().timeout(Duration.ofSeconds(30)).build()); ``` Or configure the default for all method calls at the client level: @@ -420,9 +402,9 @@ To set undocumented parameters, call the `putAdditionalHeader`, `putAdditionalQu ```java import com.browserbase.api.core.JsonValue; -import com.browserbase.api.models.sessions.SessionActParams; +import com.browserbase.api.models.sessions.SessionStartParams; -SessionActParams params = SessionActParams.builder() +SessionStartParams params = SessionStartParams.builder() .putAdditionalHeader("Secret-Header", "42") .putAdditionalQueryParam("secret_query_param", "42") .putAdditionalBodyProperty("secretProperty", JsonValue.from("42")) @@ -431,30 +413,12 @@ SessionActParams params = SessionActParams.builder() These can be accessed on the built object later using the `_additionalHeaders()`, `_additionalQueryParams()`, and `_additionalBodyProperties()` methods. -To set undocumented parameters on _nested_ headers, query params, or body classes, call the `putAdditionalProperty` method on the nested class: - -```java -import com.browserbase.api.core.JsonValue; -import com.browserbase.api.models.sessions.SessionActParams; - -SessionActParams params = SessionActParams.builder() - .options(SessionActParams.Options.builder() - .putAdditionalProperty("secretProperty", JsonValue.from("42")) - .build()) - .build(); -``` - -These properties can be accessed on the nested built object later using the `_additionalProperties()` method. - To set a documented parameter or property to an undocumented or not yet supported _value_, pass a [`JsonValue`](stagehand-java-core/src/main/kotlin/com/browserbase/api/core/Values.kt) object to its setter: ```java -import com.browserbase.api.core.JsonValue; -import com.browserbase.api.models.sessions.SessionActParams; +import com.browserbase.api.models.sessions.SessionStartParams; -SessionActParams params = SessionActParams.builder() - .input(JsonValue.from(42)) - .build(); +SessionStartParams params = SessionStartParams.builder().build(); ``` The most straightforward way to create a [`JsonValue`](stagehand-java-core/src/main/kotlin/com/browserbase/api/core/Values.kt) is using its `from(...)` method: @@ -496,20 +460,6 @@ JsonValue complexValue = JsonValue.from(Map.of( )); ``` -Normally a `Builder` class's `build` method will throw [`IllegalStateException`](https://docs.oracle.com/javase/8/docs/api/java/lang/IllegalStateException.html) if any required parameter or property is unset. - -To forcibly omit a required parameter or property, pass [`JsonMissing`](stagehand-java-core/src/main/kotlin/com/browserbase/api/core/Values.kt): - -```java -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()) - .build(); -``` - ### Response properties To access undocumented response properties, call the `_additionalProperties()` method: @@ -518,7 +468,7 @@ To access undocumented response properties, call the `_additionalProperties()` m import com.browserbase.api.core.JsonValue; import java.util.Map; -Map additionalProperties = client.sessions().act(params)._additionalProperties(); +Map additionalProperties = client.sessions().start(params)._additionalProperties(); JsonValue secretPropertyValue = additionalProperties.get("secretProperty"); String result = secretPropertyValue.accept(new JsonValue.Visitor<>() { @@ -546,22 +496,21 @@ To access a property's raw JSON value, which may be undocumented, call its `_` p ```java import com.browserbase.api.core.JsonField; -import com.browserbase.api.models.sessions.SessionActParams; import java.util.Optional; -JsonField input = client.sessions().act(params)._input(); +JsonField field = client.sessions().start(params)._field(); -if (input.isMissing()) { +if (field.isMissing()) { // The property is absent from the JSON response -} else if (input.isNull()) { +} else if (field.isNull()) { // The property was set to literal null } else { // Check if value was provided as a string // Other methods include `asNumber()`, `asBoolean()`, etc. - Optional jsonString = input.asString(); + Optional jsonString = field.asString(); // Try to deserialize into a custom type - MyClass myObject = input.asUnknown().orElseThrow().convert(MyClass.class); + MyClass myObject = field.asUnknown().orElseThrow().convert(MyClass.class); } ``` @@ -574,19 +523,17 @@ By default, the SDK will not throw an exception in this case. It will throw [`St If you would prefer to check that the response is completely well-typed upfront, then either call `validate()`: ```java -import com.browserbase.api.models.sessions.SessionActResponse; +import com.browserbase.api.models.sessions.SessionStartResponse; -SessionActResponse response = client.sessions().act(params).validate(); +SessionStartResponse response = client.sessions().start(params).validate(); ``` Or configure the method call to validate the response using the `responseValidation` method: ```java -import com.browserbase.api.models.sessions.SessionActResponse; +import com.browserbase.api.models.sessions.SessionStartResponse; -SessionActResponse response = client.sessions().act( - params, RequestOptions.builder().responseValidation(true).build() -); +SessionStartResponse response = client.sessions().start(RequestOptions.builder().responseValidation(true).build()); ``` Or configure the default for all method calls at the client level: diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/Action.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/Action.kt index d30a40b..e9ae4bc 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/Action.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/Action.kt @@ -19,39 +19,28 @@ import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull +/** Action object returned by observe and used by act */ class Action @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - private val arguments: JsonField>, private val description: JsonField, - private val method: JsonField, private val selector: JsonField, - private val backendNodeId: JsonField, + private val arguments: JsonField>, + private val method: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("arguments") - @ExcludeMissing - arguments: JsonField> = JsonMissing.of(), @JsonProperty("description") @ExcludeMissing description: JsonField = JsonMissing.of(), - @JsonProperty("method") @ExcludeMissing method: JsonField = JsonMissing.of(), @JsonProperty("selector") @ExcludeMissing selector: JsonField = JsonMissing.of(), - @JsonProperty("backendNodeId") + @JsonProperty("arguments") @ExcludeMissing - backendNodeId: JsonField = JsonMissing.of(), - ) : this(arguments, description, method, selector, backendNodeId, mutableMapOf()) - - /** - * Arguments for the method - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun arguments(): List = arguments.getRequired("arguments") + arguments: JsonField> = JsonMissing.of(), + @JsonProperty("method") @ExcludeMissing method: JsonField = JsonMissing.of(), + ) : this(description, selector, arguments, method, mutableMapOf()) /** * Human-readable description of the action @@ -62,15 +51,7 @@ private constructor( fun description(): String = description.getRequired("description") /** - * Method to execute (e.g., "click", "fill") - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun method(): String = method.getRequired("method") - - /** - * CSS or XPath selector for the element + * CSS selector or XPath for the element * * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). @@ -78,19 +59,20 @@ private constructor( fun selector(): String = selector.getRequired("selector") /** - * CDP backend node ID + * Arguments to pass to the method * * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ - fun backendNodeId(): Optional = backendNodeId.getOptional("backendNodeId") + fun arguments(): Optional> = arguments.getOptional("arguments") /** - * Returns the raw JSON value of [arguments]. + * The method to execute (click, fill, etc.) * - * Unlike [arguments], this method doesn't throw if the JSON field has an unexpected type. + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - @JsonProperty("arguments") @ExcludeMissing fun _arguments(): JsonField> = arguments + fun method(): Optional = method.getOptional("method") /** * Returns the raw JSON value of [description]. @@ -100,27 +82,25 @@ private constructor( @JsonProperty("description") @ExcludeMissing fun _description(): JsonField = description /** - * Returns the raw JSON value of [method]. + * Returns the raw JSON value of [selector]. * - * Unlike [method], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [selector], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("method") @ExcludeMissing fun _method(): JsonField = method + @JsonProperty("selector") @ExcludeMissing fun _selector(): JsonField = selector /** - * Returns the raw JSON value of [selector]. + * Returns the raw JSON value of [arguments]. * - * Unlike [selector], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [arguments], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("selector") @ExcludeMissing fun _selector(): JsonField = selector + @JsonProperty("arguments") @ExcludeMissing fun _arguments(): JsonField> = arguments /** - * Returns the raw JSON value of [backendNodeId]. + * Returns the raw JSON value of [method]. * - * Unlike [backendNodeId], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [method], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("backendNodeId") - @ExcludeMissing - fun _backendNodeId(): JsonField = backendNodeId + @JsonProperty("method") @ExcludeMissing fun _method(): JsonField = method @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -141,9 +121,7 @@ private constructor( * * The following fields are required: * ```java - * .arguments() * .description() - * .method() * .selector() * ``` */ @@ -153,24 +131,45 @@ private constructor( /** A builder for [Action]. */ class Builder internal constructor() { - private var arguments: JsonField>? = null private var description: JsonField? = null - private var method: JsonField? = null private var selector: JsonField? = null - private var backendNodeId: JsonField = JsonMissing.of() + private var arguments: JsonField>? = null + private var method: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(action: Action) = apply { - arguments = action.arguments.map { it.toMutableList() } description = action.description - method = action.method selector = action.selector - backendNodeId = action.backendNodeId + arguments = action.arguments.map { it.toMutableList() } + method = action.method additionalProperties = action.additionalProperties.toMutableMap() } - /** Arguments for the method */ + /** Human-readable description of the action */ + fun description(description: String) = description(JsonField.of(description)) + + /** + * Sets [Builder.description] to an arbitrary JSON value. + * + * You should usually call [Builder.description] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun description(description: JsonField) = apply { this.description = description } + + /** CSS selector or XPath for the element */ + fun selector(selector: String) = selector(JsonField.of(selector)) + + /** + * Sets [Builder.selector] to an arbitrary JSON value. + * + * You should usually call [Builder.selector] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun selector(selector: JsonField) = apply { this.selector = selector } + + /** Arguments to pass to the method */ fun arguments(arguments: List) = arguments(JsonField.of(arguments)) /** @@ -196,19 +195,7 @@ private constructor( } } - /** Human-readable description of the action */ - fun description(description: String) = description(JsonField.of(description)) - - /** - * Sets [Builder.description] to an arbitrary JSON value. - * - * You should usually call [Builder.description] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun description(description: JsonField) = apply { this.description = description } - - /** Method to execute (e.g., "click", "fill") */ + /** The method to execute (click, fill, etc.) */ fun method(method: String) = method(JsonField.of(method)) /** @@ -219,31 +206,6 @@ private constructor( */ fun method(method: JsonField) = apply { this.method = method } - /** CSS or XPath selector for the element */ - fun selector(selector: String) = selector(JsonField.of(selector)) - - /** - * Sets [Builder.selector] to an arbitrary JSON value. - * - * You should usually call [Builder.selector] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun selector(selector: JsonField) = apply { this.selector = selector } - - /** CDP backend node ID */ - fun backendNodeId(backendNodeId: Long) = backendNodeId(JsonField.of(backendNodeId)) - - /** - * Sets [Builder.backendNodeId] to an arbitrary JSON value. - * - * You should usually call [Builder.backendNodeId] with a well-typed [Long] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun backendNodeId(backendNodeId: JsonField) = apply { - this.backendNodeId = backendNodeId - } - fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -270,9 +232,7 @@ private constructor( * * The following fields are required: * ```java - * .arguments() * .description() - * .method() * .selector() * ``` * @@ -280,11 +240,10 @@ private constructor( */ fun build(): Action = Action( - checkRequired("arguments", arguments).map { it.toImmutable() }, checkRequired("description", description), - checkRequired("method", method), checkRequired("selector", selector), - backendNodeId, + (arguments ?: JsonMissing.of()).map { it.toImmutable() }, + method, additionalProperties.toMutableMap(), ) } @@ -296,11 +255,10 @@ private constructor( return@apply } - arguments() description() - method() selector() - backendNodeId() + arguments() + method() validated = true } @@ -319,11 +277,10 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (arguments.asKnown().getOrNull()?.size ?: 0) + - (if (description.asKnown().isPresent) 1 else 0) + - (if (method.asKnown().isPresent) 1 else 0) + + (if (description.asKnown().isPresent) 1 else 0) + (if (selector.asKnown().isPresent) 1 else 0) + - (if (backendNodeId.asKnown().isPresent) 1 else 0) + (arguments.asKnown().getOrNull()?.size ?: 0) + + (if (method.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { if (this === other) { @@ -331,20 +288,19 @@ private constructor( } return other is Action && - arguments == other.arguments && description == other.description && - method == other.method && selector == other.selector && - backendNodeId == other.backendNodeId && + arguments == other.arguments && + method == other.method && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash(arguments, description, method, selector, backendNodeId, additionalProperties) + Objects.hash(description, selector, arguments, method, additionalProperties) } override fun hashCode(): Int = hashCode override fun toString() = - "Action{arguments=$arguments, description=$description, method=$method, selector=$selector, backendNodeId=$backendNodeId, additionalProperties=$additionalProperties}" + "Action{description=$description, selector=$selector, arguments=$arguments, method=$method, additionalProperties=$additionalProperties}" } diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/ModelConfig.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/ModelConfig.kt index e08ebfa..0d210b0 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/ModelConfig.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/ModelConfig.kt @@ -2,205 +2,61 @@ package com.browserbase.api.models.sessions -import com.browserbase.api.core.Enum +import com.browserbase.api.core.BaseDeserializer +import com.browserbase.api.core.BaseSerializer import com.browserbase.api.core.ExcludeMissing import com.browserbase.api.core.JsonField import com.browserbase.api.core.JsonMissing import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.allMaxBy +import com.browserbase.api.core.checkRequired +import com.browserbase.api.core.getOrThrow import com.browserbase.api.errors.StagehandInvalidDataException import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter import com.fasterxml.jackson.annotation.JsonCreator import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Collections import java.util.Objects import java.util.Optional -import kotlin.jvm.optionals.getOrNull +@JsonDeserialize(using = ModelConfig.Deserializer::class) +@JsonSerialize(using = ModelConfig.Serializer::class) class ModelConfig -@JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - private val apiKey: JsonField, - private val baseUrl: JsonField, - private val model: JsonField, - private val provider: JsonField, - private val additionalProperties: MutableMap, + private val string: String? = null, + private val unionMember1: UnionMember1? = null, + private val _json: JsonValue? = null, ) { - @JsonCreator - private constructor( - @JsonProperty("apiKey") @ExcludeMissing apiKey: JsonField = JsonMissing.of(), - @JsonProperty("baseURL") @ExcludeMissing baseUrl: JsonField = JsonMissing.of(), - @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), - @JsonProperty("provider") @ExcludeMissing provider: JsonField = JsonMissing.of(), - ) : this(apiKey, baseUrl, model, provider, mutableMapOf()) + fun string(): Optional = Optional.ofNullable(string) - /** - * API key for the model provider - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun apiKey(): Optional = apiKey.getOptional("apiKey") + fun unionMember1(): Optional = Optional.ofNullable(unionMember1) - /** - * Custom base URL for API - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun baseUrl(): Optional = baseUrl.getOptional("baseURL") + fun isString(): Boolean = string != null - /** - * Model name - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun model(): Optional = model.getOptional("model") + fun isUnionMember1(): Boolean = unionMember1 != null - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun provider(): Optional = provider.getOptional("provider") + fun asString(): String = string.getOrThrow("string") - /** - * Returns the raw JSON value of [apiKey]. - * - * Unlike [apiKey], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("apiKey") @ExcludeMissing fun _apiKey(): JsonField = apiKey + fun asUnionMember1(): UnionMember1 = unionMember1.getOrThrow("unionMember1") - /** - * Returns the raw JSON value of [baseUrl]. - * - * Unlike [baseUrl], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("baseURL") @ExcludeMissing fun _baseUrl(): JsonField = baseUrl + fun _json(): Optional = Optional.ofNullable(_json) - /** - * Returns the raw JSON value of [model]. - * - * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model - - /** - * Returns the raw JSON value of [provider]. - * - * Unlike [provider], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("provider") @ExcludeMissing fun _provider(): JsonField = provider - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [ModelConfig]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [ModelConfig]. */ - class Builder internal constructor() { - - private var apiKey: JsonField = JsonMissing.of() - private var baseUrl: JsonField = JsonMissing.of() - private var model: JsonField = JsonMissing.of() - private var provider: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(modelConfig: ModelConfig) = apply { - apiKey = modelConfig.apiKey - baseUrl = modelConfig.baseUrl - model = modelConfig.model - provider = modelConfig.provider - additionalProperties = modelConfig.additionalProperties.toMutableMap() + fun accept(visitor: Visitor): T = + when { + string != null -> visitor.visitString(string) + unionMember1 != null -> visitor.visitUnionMember1(unionMember1) + else -> visitor.unknown(_json) } - /** API key for the model provider */ - fun apiKey(apiKey: String) = apiKey(JsonField.of(apiKey)) - - /** - * Sets [Builder.apiKey] to an arbitrary JSON value. - * - * You should usually call [Builder.apiKey] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun apiKey(apiKey: JsonField) = apply { this.apiKey = apiKey } - - /** Custom base URL for API */ - fun baseUrl(baseUrl: String) = baseUrl(JsonField.of(baseUrl)) - - /** - * Sets [Builder.baseUrl] to an arbitrary JSON value. - * - * You should usually call [Builder.baseUrl] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun baseUrl(baseUrl: JsonField) = apply { this.baseUrl = baseUrl } - - /** Model name */ - fun model(model: String) = model(JsonField.of(model)) - - /** - * Sets [Builder.model] to an arbitrary JSON value. - * - * You should usually call [Builder.model] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun model(model: JsonField) = apply { this.model = model } - - fun provider(provider: Provider) = provider(JsonField.of(provider)) - - /** - * Sets [Builder.provider] to an arbitrary JSON value. - * - * You should usually call [Builder.provider] with a well-typed [Provider] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun provider(provider: JsonField) = apply { this.provider = provider } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [ModelConfig]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): ModelConfig = - ModelConfig(apiKey, baseUrl, model, provider, additionalProperties.toMutableMap()) - } - private var validated: Boolean = false fun validate(): ModelConfig = apply { @@ -208,10 +64,15 @@ private constructor( return@apply } - apiKey() - baseUrl() - model() - provider().ifPresent { it.validate() } + accept( + object : Visitor { + override fun visitString(string: String) {} + + override fun visitUnionMember1(unionMember1: UnionMember1) { + unionMember1.validate() + } + } + ) validated = true } @@ -230,112 +91,291 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (if (apiKey.asKnown().isPresent) 1 else 0) + - (if (baseUrl.asKnown().isPresent) 1 else 0) + - (if (model.asKnown().isPresent) 1 else 0) + - (provider.asKnown().getOrNull()?.validity() ?: 0) + accept( + object : Visitor { + override fun visitString(string: String) = 1 - class Provider @JsonCreator private constructor(private val value: JsonField) : Enum { + override fun visitUnionMember1(unionMember1: UnionMember1) = unionMember1.validity() - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { + override fun unknown(json: JsonValue?) = 0 + } + ) - @JvmField val OPENAI = of("openai") + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @JvmField val ANTHROPIC = of("anthropic") + return other is ModelConfig && string == other.string && unionMember1 == other.unionMember1 + } - @JvmField val GOOGLE = of("google") + override fun hashCode(): Int = Objects.hash(string, unionMember1) - @JvmStatic fun of(value: String) = Provider(JsonField.of(value)) + override fun toString(): String = + when { + string != null -> "ModelConfig{string=$string}" + unionMember1 != null -> "ModelConfig{unionMember1=$unionMember1}" + _json != null -> "ModelConfig{_unknown=$_json}" + else -> throw IllegalStateException("Invalid ModelConfig") } - /** An enum containing [Provider]'s known values. */ - enum class Known { - OPENAI, - ANTHROPIC, - GOOGLE, - } + companion object { + + @JvmStatic fun ofString(string: String) = ModelConfig(string = string) + + @JvmStatic + fun ofUnionMember1(unionMember1: UnionMember1) = ModelConfig(unionMember1 = unionMember1) + } + + /** + * An interface that defines how to map each variant of [ModelConfig] to a value of type [T]. + */ + interface Visitor { + + fun visitString(string: String): T + + fun visitUnionMember1(unionMember1: UnionMember1): T /** - * An enum containing [Provider]'s known values, as well as an [_UNKNOWN] member. + * Maps an unknown variant of [ModelConfig] to a value of type [T]. + * + * An instance of [ModelConfig] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. * - * An instance of [Provider] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. + * @throws StagehandInvalidDataException in the default implementation. */ - enum class Value { - OPENAI, - ANTHROPIC, - GOOGLE, - /** An enum member indicating that [Provider] was instantiated with an unknown value. */ - _UNKNOWN, + fun unknown(json: JsonValue?): T { + throw StagehandInvalidDataException("Unknown ModelConfig: $json") } + } + + internal class Deserializer : BaseDeserializer(ModelConfig::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): ModelConfig { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + ModelConfig(unionMember1 = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + ModelConfig(string = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with all + // the possible variants (e.g. deserializing from array). + 0 -> ModelConfig(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(ModelConfig::class) { + + override fun serialize( + value: ModelConfig, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.string != null -> generator.writeObject(value.string) + value.unionMember1 != null -> generator.writeObject(value.unionMember1) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid ModelConfig") + } + } + } + + class UnionMember1 + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val modelName: JsonField, + private val apiKey: JsonField, + private val baseUrl: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("modelName") + @ExcludeMissing + modelName: JsonField = JsonMissing.of(), + @JsonProperty("apiKey") @ExcludeMissing apiKey: JsonField = JsonMissing.of(), + @JsonProperty("baseURL") @ExcludeMissing baseUrl: JsonField = JsonMissing.of(), + ) : this(modelName, apiKey, baseUrl, mutableMapOf()) /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ - fun value(): Value = - when (this) { - OPENAI -> Value.OPENAI - ANTHROPIC -> Value.ANTHROPIC - GOOGLE -> Value.GOOGLE - else -> Value._UNKNOWN - } + fun modelName(): String = modelName.getRequired("modelName") /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun apiKey(): Optional = apiKey.getOptional("apiKey") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun baseUrl(): Optional = baseUrl.getOptional("baseURL") + + /** + * Returns the raw JSON value of [modelName]. * - * @throws StagehandInvalidDataException if this class instance's value is a not a known - * member. + * Unlike [modelName], this method doesn't throw if the JSON field has an unexpected type. */ - fun known(): Known = - when (this) { - OPENAI -> Known.OPENAI - ANTHROPIC -> Known.ANTHROPIC - GOOGLE -> Known.GOOGLE - else -> throw StagehandInvalidDataException("Unknown Provider: $value") - } + @JsonProperty("modelName") @ExcludeMissing fun _modelName(): JsonField = modelName /** - * Returns this class instance's primitive wire representation. + * Returns the raw JSON value of [apiKey]. * - * This differs from the [toString] method because that method is primarily for debugging - * and generally doesn't throw. + * Unlike [apiKey], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("apiKey") @ExcludeMissing fun _apiKey(): JsonField = apiKey + + /** + * Returns the raw JSON value of [baseUrl]. * - * @throws StagehandInvalidDataException if this class instance's value does not have the - * expected primitive type. + * Unlike [baseUrl], this method doesn't throw if the JSON field has an unexpected type. */ - fun asString(): String = - _value().asString().orElseThrow { - StagehandInvalidDataException("Value is not a String") + @JsonProperty("baseURL") @ExcludeMissing fun _baseUrl(): JsonField = baseUrl + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [UnionMember1]. + * + * The following fields are required: + * ```java + * .modelName() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [UnionMember1]. */ + class Builder internal constructor() { + + private var modelName: JsonField? = null + private var apiKey: JsonField = JsonMissing.of() + private var baseUrl: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(unionMember1: UnionMember1) = apply { + modelName = unionMember1.modelName + apiKey = unionMember1.apiKey + baseUrl = unionMember1.baseUrl + additionalProperties = unionMember1.additionalProperties.toMutableMap() + } + + fun modelName(modelName: String) = modelName(JsonField.of(modelName)) + + /** + * Sets [Builder.modelName] to an arbitrary JSON value. + * + * You should usually call [Builder.modelName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun modelName(modelName: JsonField) = apply { this.modelName = modelName } + + fun apiKey(apiKey: String) = apiKey(JsonField.of(apiKey)) + + /** + * Sets [Builder.apiKey] to an arbitrary JSON value. + * + * You should usually call [Builder.apiKey] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun apiKey(apiKey: JsonField) = apply { this.apiKey = apiKey } + + fun baseUrl(baseUrl: String) = baseUrl(JsonField.of(baseUrl)) + + /** + * Sets [Builder.baseUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.baseUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun baseUrl(baseUrl: JsonField) = apply { this.baseUrl = baseUrl } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) } + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [UnionMember1]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .modelName() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): UnionMember1 = + UnionMember1( + checkRequired("modelName", modelName), + apiKey, + baseUrl, + additionalProperties.toMutableMap(), + ) + } + private var validated: Boolean = false - fun validate(): Provider = apply { + fun validate(): UnionMember1 = apply { if (validated) { return@apply } - known() + modelName() + apiKey() + baseUrl() validated = true } @@ -353,40 +393,31 @@ private constructor( * * Used for best match union deserialization. */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + @JvmSynthetic + internal fun validity(): Int = + (if (modelName.asKnown().isPresent) 1 else 0) + + (if (apiKey.asKnown().isPresent) 1 else 0) + + (if (baseUrl.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Provider && value == other.value + return other is UnionMember1 && + modelName == other.modelName && + apiKey == other.apiKey && + baseUrl == other.baseUrl && + additionalProperties == other.additionalProperties } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + private val hashCode: Int by lazy { + Objects.hash(modelName, apiKey, baseUrl, additionalProperties) } - return other is ModelConfig && - apiKey == other.apiKey && - baseUrl == other.baseUrl && - model == other.model && - provider == other.provider && - additionalProperties == other.additionalProperties - } + override fun hashCode(): Int = hashCode - private val hashCode: Int by lazy { - Objects.hash(apiKey, baseUrl, model, provider, additionalProperties) + override fun toString() = + "UnionMember1{modelName=$modelName, apiKey=$apiKey, baseUrl=$baseUrl, additionalProperties=$additionalProperties}" } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "ModelConfig{apiKey=$apiKey, baseUrl=$baseUrl, model=$model, provider=$provider, additionalProperties=$additionalProperties}" } diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt deleted file mode 100644 index 34cae33..0000000 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt +++ /dev/null @@ -1,1233 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.BaseDeserializer -import com.browserbase.api.core.BaseSerializer -import com.browserbase.api.core.Enum -import com.browserbase.api.core.ExcludeMissing -import com.browserbase.api.core.JsonField -import com.browserbase.api.core.JsonMissing -import com.browserbase.api.core.JsonValue -import com.browserbase.api.core.Params -import com.browserbase.api.core.allMaxBy -import com.browserbase.api.core.checkRequired -import com.browserbase.api.core.getOrThrow -import com.browserbase.api.core.http.Headers -import com.browserbase.api.core.http.QueryParams -import com.browserbase.api.core.toImmutable -import com.browserbase.api.errors.StagehandInvalidDataException -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonCreator -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.ObjectCodec -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.SerializerProvider -import com.fasterxml.jackson.databind.annotation.JsonDeserialize -import com.fasterxml.jackson.databind.annotation.JsonSerialize -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import java.util.Collections -import java.util.Objects -import java.util.Optional -import kotlin.jvm.optionals.getOrNull - -/** - * Performs a browser action based on natural language instruction or a specific action object - * returned by observe(). - */ -class SessionActParams -private constructor( - private val sessionId: String?, - private val xStreamResponse: XStreamResponse?, - private val body: Body, - private val additionalHeaders: Headers, - private val additionalQueryParams: QueryParams, -) : Params { - - fun sessionId(): Optional = Optional.ofNullable(sessionId) - - fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) - - /** - * Natural language instruction - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun input(): Input = body.input() - - /** - * Frame ID to act on (optional) - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun frameId(): Optional = body.frameId() - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun options(): Optional = body.options() - - /** - * Returns the raw JSON value of [input]. - * - * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _input(): JsonField = body._input() - - /** - * Returns the raw JSON value of [frameId]. - * - * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _frameId(): JsonField = body._frameId() - - /** - * Returns the raw JSON value of [options]. - * - * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _options(): JsonField = body._options() - - fun _additionalBodyProperties(): Map = body._additionalProperties() - - /** Additional headers to send with the request. */ - fun _additionalHeaders(): Headers = additionalHeaders - - /** Additional query param to send with the request. */ - fun _additionalQueryParams(): QueryParams = additionalQueryParams - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [SessionActParams]. - * - * The following fields are required: - * ```java - * .input() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [SessionActParams]. */ - class Builder internal constructor() { - - private var sessionId: String? = null - private var xStreamResponse: XStreamResponse? = null - private var body: Body.Builder = Body.builder() - private var additionalHeaders: Headers.Builder = Headers.builder() - private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() - - @JvmSynthetic - internal fun from(sessionActParams: SessionActParams) = apply { - sessionId = sessionActParams.sessionId - xStreamResponse = sessionActParams.xStreamResponse - body = sessionActParams.body.toBuilder() - additionalHeaders = sessionActParams.additionalHeaders.toBuilder() - additionalQueryParams = sessionActParams.additionalQueryParams.toBuilder() - } - - fun sessionId(sessionId: String?) = apply { this.sessionId = sessionId } - - /** Alias for calling [Builder.sessionId] with `sessionId.orElse(null)`. */ - fun sessionId(sessionId: Optional) = sessionId(sessionId.getOrNull()) - - fun xStreamResponse(xStreamResponse: XStreamResponse?) = apply { - this.xStreamResponse = xStreamResponse - } - - /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ - fun xStreamResponse(xStreamResponse: Optional) = - xStreamResponse(xStreamResponse.getOrNull()) - - /** - * Sets the entire request body. - * - * This is generally only useful if you are already constructing the body separately. - * Otherwise, it's more convenient to use the top-level setters instead: - * - [input] - * - [frameId] - * - [options] - */ - fun body(body: Body) = apply { this.body = body.toBuilder() } - - /** Natural language instruction */ - fun input(input: Input) = apply { body.input(input) } - - /** - * Sets [Builder.input] to an arbitrary JSON value. - * - * You should usually call [Builder.input] with a well-typed [Input] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun input(input: JsonField) = apply { body.input(input) } - - /** Alias for calling [input] with `Input.ofString(string)`. */ - fun input(string: String) = apply { body.input(string) } - - /** Alias for calling [input] with `Input.ofAction(action)`. */ - fun input(action: Action) = apply { body.input(action) } - - /** Frame ID to act on (optional) */ - fun frameId(frameId: String) = apply { body.frameId(frameId) } - - /** - * Sets [Builder.frameId] to an arbitrary JSON value. - * - * You should usually call [Builder.frameId] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun frameId(frameId: JsonField) = apply { body.frameId(frameId) } - - fun options(options: Options) = apply { body.options(options) } - - /** - * Sets [Builder.options] to an arbitrary JSON value. - * - * You should usually call [Builder.options] with a well-typed [Options] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun options(options: JsonField) = apply { body.options(options) } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - body.additionalProperties(additionalBodyProperties) - } - - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - body.putAdditionalProperty(key, value) - } - - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - body.putAllAdditionalProperties(additionalBodyProperties) - } - - fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - - fun removeAllAdditionalBodyProperties(keys: Set) = apply { - body.removeAllAdditionalProperties(keys) - } - - fun additionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.clear() - putAllAdditionalHeaders(additionalHeaders) - } - - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllAdditionalHeaders(additionalHeaders) - } - - fun putAdditionalHeader(name: String, value: String) = apply { - additionalHeaders.put(name, value) - } - - fun putAdditionalHeaders(name: String, values: Iterable) = apply { - additionalHeaders.put(name, values) - } - - fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.putAll(additionalHeaders) - } - - fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.putAll(additionalHeaders) - } - - fun replaceAdditionalHeaders(name: String, value: String) = apply { - additionalHeaders.replace(name, value) - } - - fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { - additionalHeaders.replace(name, values) - } - - fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.replaceAll(additionalHeaders) - } - - fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.replaceAll(additionalHeaders) - } - - fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - - fun removeAllAdditionalHeaders(names: Set) = apply { - additionalHeaders.removeAll(names) - } - - fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.clear() - putAllAdditionalQueryParams(additionalQueryParams) - } - - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllAdditionalQueryParams(additionalQueryParams) - } - - fun putAdditionalQueryParam(key: String, value: String) = apply { - additionalQueryParams.put(key, value) - } - - fun putAdditionalQueryParams(key: String, values: Iterable) = apply { - additionalQueryParams.put(key, values) - } - - fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.putAll(additionalQueryParams) - } - - fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = - apply { - this.additionalQueryParams.putAll(additionalQueryParams) - } - - fun replaceAdditionalQueryParams(key: String, value: String) = apply { - additionalQueryParams.replace(key, value) - } - - fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { - additionalQueryParams.replace(key, values) - } - - fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.replaceAll(additionalQueryParams) - } - - fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = - apply { - this.additionalQueryParams.replaceAll(additionalQueryParams) - } - - fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } - - fun removeAllAdditionalQueryParams(keys: Set) = apply { - additionalQueryParams.removeAll(keys) - } - - /** - * Returns an immutable instance of [SessionActParams]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .input() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): SessionActParams = - SessionActParams( - sessionId, - xStreamResponse, - body.build(), - additionalHeaders.build(), - additionalQueryParams.build(), - ) - } - - fun _body(): Body = body - - fun _pathParam(index: Int): String = - when (index) { - 0 -> sessionId ?: "" - else -> "" - } - - override fun _headers(): Headers = - Headers.builder() - .apply { - xStreamResponse?.let { put("x-stream-response", it.toString()) } - putAll(additionalHeaders) - } - .build() - - override fun _queryParams(): QueryParams = additionalQueryParams - - class Body - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val input: JsonField, - private val frameId: JsonField, - private val options: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("input") @ExcludeMissing input: JsonField = JsonMissing.of(), - @JsonProperty("frameId") @ExcludeMissing frameId: JsonField = JsonMissing.of(), - @JsonProperty("options") @ExcludeMissing options: JsonField = JsonMissing.of(), - ) : this(input, frameId, options, mutableMapOf()) - - /** - * Natural language instruction - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun input(): Input = input.getRequired("input") - - /** - * Frame ID to act on (optional) - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun frameId(): Optional = frameId.getOptional("frameId") - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun options(): Optional = options.getOptional("options") - - /** - * Returns the raw JSON value of [input]. - * - * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("input") @ExcludeMissing fun _input(): JsonField = input - - /** - * Returns the raw JSON value of [frameId]. - * - * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("frameId") @ExcludeMissing fun _frameId(): JsonField = frameId - - /** - * Returns the raw JSON value of [options]. - * - * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("options") @ExcludeMissing fun _options(): JsonField = options - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [Body]. - * - * The following fields are required: - * ```java - * .input() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Body]. */ - class Builder internal constructor() { - - private var input: JsonField? = null - private var frameId: JsonField = JsonMissing.of() - private var options: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(body: Body) = apply { - input = body.input - frameId = body.frameId - options = body.options - additionalProperties = body.additionalProperties.toMutableMap() - } - - /** Natural language instruction */ - fun input(input: Input) = input(JsonField.of(input)) - - /** - * Sets [Builder.input] to an arbitrary JSON value. - * - * You should usually call [Builder.input] with a well-typed [Input] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun input(input: JsonField) = apply { this.input = input } - - /** Alias for calling [input] with `Input.ofString(string)`. */ - fun input(string: String) = input(Input.ofString(string)) - - /** Alias for calling [input] with `Input.ofAction(action)`. */ - fun input(action: Action) = input(Input.ofAction(action)) - - /** Frame ID to act on (optional) */ - fun frameId(frameId: String) = frameId(JsonField.of(frameId)) - - /** - * Sets [Builder.frameId] to an arbitrary JSON value. - * - * You should usually call [Builder.frameId] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun frameId(frameId: JsonField) = apply { this.frameId = frameId } - - fun options(options: Options) = options(JsonField.of(options)) - - /** - * Sets [Builder.options] to an arbitrary JSON value. - * - * You should usually call [Builder.options] with a well-typed [Options] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun options(options: JsonField) = apply { this.options = options } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Body]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .input() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): Body = - Body( - checkRequired("input", input), - frameId, - options, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Body = apply { - if (validated) { - return@apply - } - - input().validate() - frameId() - options().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (input.asKnown().getOrNull()?.validity() ?: 0) + - (if (frameId.asKnown().isPresent) 1 else 0) + - (options.asKnown().getOrNull()?.validity() ?: 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Body && - input == other.input && - frameId == other.frameId && - options == other.options && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(input, frameId, options, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Body{input=$input, frameId=$frameId, options=$options, additionalProperties=$additionalProperties}" - } - - /** Natural language instruction */ - @JsonDeserialize(using = Input.Deserializer::class) - @JsonSerialize(using = Input.Serializer::class) - class Input - private constructor( - private val string: String? = null, - private val action: Action? = null, - private val _json: JsonValue? = null, - ) { - - /** Natural language instruction */ - fun string(): Optional = Optional.ofNullable(string) - - fun action(): Optional = Optional.ofNullable(action) - - fun isString(): Boolean = string != null - - fun isAction(): Boolean = action != null - - /** Natural language instruction */ - fun asString(): String = string.getOrThrow("string") - - fun asAction(): Action = action.getOrThrow("action") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - string != null -> visitor.visitString(string) - action != null -> visitor.visitAction(action) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): Input = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitString(string: String) {} - - override fun visitAction(action: Action) { - action.validate() - } - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitString(string: String) = 1 - - override fun visitAction(action: Action) = action.validity() - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Input && string == other.string && action == other.action - } - - override fun hashCode(): Int = Objects.hash(string, action) - - override fun toString(): String = - when { - string != null -> "Input{string=$string}" - action != null -> "Input{action=$action}" - _json != null -> "Input{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Input") - } - - companion object { - - /** Natural language instruction */ - @JvmStatic fun ofString(string: String) = Input(string = string) - - @JvmStatic fun ofAction(action: Action) = Input(action = action) - } - - /** An interface that defines how to map each variant of [Input] to a value of type [T]. */ - interface Visitor { - - /** Natural language instruction */ - fun visitString(string: String): T - - fun visitAction(action: Action): T - - /** - * Maps an unknown variant of [Input] to a value of type [T]. - * - * An instance of [Input] can contain an unknown variant if it was deserialized from - * data that doesn't match any known variant. For example, if the SDK is on an older - * version than the API, then the API may respond with new variants that the SDK is - * unaware of. - * - * @throws StagehandInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw StagehandInvalidDataException("Unknown Input: $json") - } - } - - internal class Deserializer : BaseDeserializer(Input::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): Input { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef())?.let { - Input(action = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - Input(string = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely incompatible with - // all the possible variants (e.g. deserializing from array). - 0 -> Input(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then use the first - // completely valid match, or simply the first match if none are completely - // valid. - else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : BaseSerializer(Input::class) { - - override fun serialize( - value: Input, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.string != null -> generator.writeObject(value.string) - value.action != null -> generator.writeObject(value.action) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid Input") - } - } - } - } - - class Options - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val model: JsonField, - private val timeout: JsonField, - private val variables: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), - @JsonProperty("timeout") @ExcludeMissing timeout: JsonField = JsonMissing.of(), - @JsonProperty("variables") - @ExcludeMissing - variables: JsonField = JsonMissing.of(), - ) : this(model, timeout, variables, mutableMapOf()) - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun model(): Optional = model.getOptional("model") - - /** - * Timeout in milliseconds - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun timeout(): Optional = timeout.getOptional("timeout") - - /** - * Template variables for instruction - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun variables(): Optional = variables.getOptional("variables") - - /** - * Returns the raw JSON value of [model]. - * - * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model - - /** - * Returns the raw JSON value of [timeout]. - * - * Unlike [timeout], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("timeout") @ExcludeMissing fun _timeout(): JsonField = timeout - - /** - * Returns the raw JSON value of [variables]. - * - * Unlike [variables], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("variables") - @ExcludeMissing - fun _variables(): JsonField = variables - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [Options]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Options]. */ - class Builder internal constructor() { - - private var model: JsonField = JsonMissing.of() - private var timeout: JsonField = JsonMissing.of() - private var variables: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(options: Options) = apply { - model = options.model - timeout = options.timeout - variables = options.variables - additionalProperties = options.additionalProperties.toMutableMap() - } - - fun model(model: ModelConfig) = model(JsonField.of(model)) - - /** - * Sets [Builder.model] to an arbitrary JSON value. - * - * You should usually call [Builder.model] with a well-typed [ModelConfig] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun model(model: JsonField) = apply { this.model = model } - - /** Timeout in milliseconds */ - fun timeout(timeout: Long) = timeout(JsonField.of(timeout)) - - /** - * Sets [Builder.timeout] to an arbitrary JSON value. - * - * You should usually call [Builder.timeout] with a well-typed [Long] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun timeout(timeout: JsonField) = apply { this.timeout = timeout } - - /** Template variables for instruction */ - fun variables(variables: Variables) = variables(JsonField.of(variables)) - - /** - * Sets [Builder.variables] to an arbitrary JSON value. - * - * You should usually call [Builder.variables] with a well-typed [Variables] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun variables(variables: JsonField) = apply { this.variables = variables } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Options]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Options = - Options(model, timeout, variables, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): Options = apply { - if (validated) { - return@apply - } - - model().ifPresent { it.validate() } - timeout() - variables().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (model.asKnown().getOrNull()?.validity() ?: 0) + - (if (timeout.asKnown().isPresent) 1 else 0) + - (variables.asKnown().getOrNull()?.validity() ?: 0) - - /** Template variables for instruction */ - class Variables - @JsonCreator - private constructor( - @com.fasterxml.jackson.annotation.JsonValue - private val additionalProperties: Map - ) { - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [Variables]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Variables]. */ - class Builder internal constructor() { - - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(variables: Variables) = apply { - additionalProperties = variables.additionalProperties.toMutableMap() - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Variables]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Variables = Variables(additionalProperties.toImmutable()) - } - - private var validated: Boolean = false - - fun validate(): Variables = apply { - if (validated) { - return@apply - } - - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - additionalProperties.count { (_, value) -> !value.isNull() && !value.isMissing() } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Variables && additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = "Variables{additionalProperties=$additionalProperties}" - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Options && - model == other.model && - timeout == other.timeout && - variables == other.variables && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(model, timeout, variables, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Options{model=$model, timeout=$timeout, variables=$variables, additionalProperties=$additionalProperties}" - } - - class XStreamResponse @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val TRUE = of("true") - - @JvmField val FALSE = of("false") - - @JvmStatic fun of(value: String) = XStreamResponse(JsonField.of(value)) - } - - /** An enum containing [XStreamResponse]'s known values. */ - enum class Known { - TRUE, - FALSE, - } - - /** - * An enum containing [XStreamResponse]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [XStreamResponse] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - TRUE, - FALSE, - /** - * An enum member indicating that [XStreamResponse] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - TRUE -> Value.TRUE - FALSE -> Value.FALSE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws StagehandInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - TRUE -> Known.TRUE - FALSE -> Known.FALSE - else -> throw StagehandInvalidDataException("Unknown XStreamResponse: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for debugging - * and generally doesn't throw. - * - * @throws StagehandInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - StagehandInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): XStreamResponse = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is XStreamResponse && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is SessionActParams && - sessionId == other.sessionId && - xStreamResponse == other.xStreamResponse && - body == other.body && - additionalHeaders == other.additionalHeaders && - additionalQueryParams == other.additionalQueryParams - } - - override fun hashCode(): Int = - Objects.hash(sessionId, xStreamResponse, body, additionalHeaders, additionalQueryParams) - - override fun toString() = - "SessionActParams{sessionId=$sessionId, xStreamResponse=$xStreamResponse, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" -} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActResponse.kt deleted file mode 100644 index 69dfcab..0000000 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActResponse.kt +++ /dev/null @@ -1,269 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.ExcludeMissing -import com.browserbase.api.core.JsonField -import com.browserbase.api.core.JsonMissing -import com.browserbase.api.core.JsonValue -import com.browserbase.api.core.checkKnown -import com.browserbase.api.core.checkRequired -import com.browserbase.api.core.toImmutable -import com.browserbase.api.errors.StagehandInvalidDataException -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonCreator -import com.fasterxml.jackson.annotation.JsonProperty -import java.util.Collections -import java.util.Objects -import kotlin.jvm.optionals.getOrNull - -class SessionActResponse -@JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor( - private val actions: JsonField>, - private val message: JsonField, - private val success: JsonField, - private val additionalProperties: MutableMap, -) { - - @JsonCreator - private constructor( - @JsonProperty("actions") - @ExcludeMissing - actions: JsonField> = JsonMissing.of(), - @JsonProperty("message") @ExcludeMissing message: JsonField = JsonMissing.of(), - @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), - ) : this(actions, message, success, mutableMapOf()) - - /** - * Actions that were executed - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun actions(): List = actions.getRequired("actions") - - /** - * Result message - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun message(): String = message.getRequired("message") - - /** - * Whether the action succeeded - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun success(): Boolean = success.getRequired("success") - - /** - * Returns the raw JSON value of [actions]. - * - * Unlike [actions], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("actions") @ExcludeMissing fun _actions(): JsonField> = actions - - /** - * Returns the raw JSON value of [message]. - * - * Unlike [message], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("message") @ExcludeMissing fun _message(): JsonField = message - - /** - * Returns the raw JSON value of [success]. - * - * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [SessionActResponse]. - * - * The following fields are required: - * ```java - * .actions() - * .message() - * .success() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [SessionActResponse]. */ - class Builder internal constructor() { - - private var actions: JsonField>? = null - private var message: JsonField? = null - private var success: JsonField? = null - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(sessionActResponse: SessionActResponse) = apply { - actions = sessionActResponse.actions.map { it.toMutableList() } - message = sessionActResponse.message - success = sessionActResponse.success - additionalProperties = sessionActResponse.additionalProperties.toMutableMap() - } - - /** Actions that were executed */ - fun actions(actions: List) = actions(JsonField.of(actions)) - - /** - * Sets [Builder.actions] to an arbitrary JSON value. - * - * You should usually call [Builder.actions] with a well-typed `List` value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun actions(actions: JsonField>) = apply { - this.actions = actions.map { it.toMutableList() } - } - - /** - * Adds a single [Action] to [actions]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addAction(action: Action) = apply { - actions = - (actions ?: JsonField.of(mutableListOf())).also { - checkKnown("actions", it).add(action) - } - } - - /** Result message */ - fun message(message: String) = message(JsonField.of(message)) - - /** - * Sets [Builder.message] to an arbitrary JSON value. - * - * You should usually call [Builder.message] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun message(message: JsonField) = apply { this.message = message } - - /** Whether the action succeeded */ - fun success(success: Boolean) = success(JsonField.of(success)) - - /** - * Sets [Builder.success] to an arbitrary JSON value. - * - * You should usually call [Builder.success] with a well-typed [Boolean] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun success(success: JsonField) = apply { this.success = success } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [SessionActResponse]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .actions() - * .message() - * .success() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): SessionActResponse = - SessionActResponse( - checkRequired("actions", actions).map { it.toImmutable() }, - checkRequired("message", message), - checkRequired("success", success), - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): SessionActResponse = apply { - if (validated) { - return@apply - } - - actions().forEach { it.validate() } - message() - success() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (actions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + - (if (message.asKnown().isPresent) 1 else 0) + - (if (success.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is SessionActResponse && - actions == other.actions && - message == other.message && - success == other.success && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(actions, message, success, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "SessionActResponse{actions=$actions, message=$message, success=$success, additionalProperties=$additionalProperties}" -} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndParams.kt deleted file mode 100644 index a3bb3fe..0000000 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndParams.kt +++ /dev/null @@ -1,229 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.JsonValue -import com.browserbase.api.core.Params -import com.browserbase.api.core.http.Headers -import com.browserbase.api.core.http.QueryParams -import com.browserbase.api.core.toImmutable -import java.util.Objects -import java.util.Optional -import kotlin.jvm.optionals.getOrNull - -/** Closes the browser and cleans up all resources associated with the session. */ -class SessionEndParams -private constructor( - private val sessionId: String?, - private val additionalHeaders: Headers, - private val additionalQueryParams: QueryParams, - private val additionalBodyProperties: Map, -) : Params { - - fun sessionId(): Optional = Optional.ofNullable(sessionId) - - /** Additional body properties to send with the request. */ - fun _additionalBodyProperties(): Map = additionalBodyProperties - - /** Additional headers to send with the request. */ - fun _additionalHeaders(): Headers = additionalHeaders - - /** Additional query param to send with the request. */ - fun _additionalQueryParams(): QueryParams = additionalQueryParams - - fun toBuilder() = Builder().from(this) - - companion object { - - @JvmStatic fun none(): SessionEndParams = builder().build() - - /** Returns a mutable builder for constructing an instance of [SessionEndParams]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [SessionEndParams]. */ - class Builder internal constructor() { - - private var sessionId: String? = null - private var additionalHeaders: Headers.Builder = Headers.builder() - private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() - private var additionalBodyProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(sessionEndParams: SessionEndParams) = apply { - sessionId = sessionEndParams.sessionId - additionalHeaders = sessionEndParams.additionalHeaders.toBuilder() - additionalQueryParams = sessionEndParams.additionalQueryParams.toBuilder() - additionalBodyProperties = sessionEndParams.additionalBodyProperties.toMutableMap() - } - - fun sessionId(sessionId: String?) = apply { this.sessionId = sessionId } - - /** Alias for calling [Builder.sessionId] with `sessionId.orElse(null)`. */ - fun sessionId(sessionId: Optional) = sessionId(sessionId.getOrNull()) - - fun additionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.clear() - putAllAdditionalHeaders(additionalHeaders) - } - - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllAdditionalHeaders(additionalHeaders) - } - - fun putAdditionalHeader(name: String, value: String) = apply { - additionalHeaders.put(name, value) - } - - fun putAdditionalHeaders(name: String, values: Iterable) = apply { - additionalHeaders.put(name, values) - } - - fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.putAll(additionalHeaders) - } - - fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.putAll(additionalHeaders) - } - - fun replaceAdditionalHeaders(name: String, value: String) = apply { - additionalHeaders.replace(name, value) - } - - fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { - additionalHeaders.replace(name, values) - } - - fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.replaceAll(additionalHeaders) - } - - fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.replaceAll(additionalHeaders) - } - - fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - - fun removeAllAdditionalHeaders(names: Set) = apply { - additionalHeaders.removeAll(names) - } - - fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.clear() - putAllAdditionalQueryParams(additionalQueryParams) - } - - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllAdditionalQueryParams(additionalQueryParams) - } - - fun putAdditionalQueryParam(key: String, value: String) = apply { - additionalQueryParams.put(key, value) - } - - fun putAdditionalQueryParams(key: String, values: Iterable) = apply { - additionalQueryParams.put(key, values) - } - - fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.putAll(additionalQueryParams) - } - - fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = - apply { - this.additionalQueryParams.putAll(additionalQueryParams) - } - - fun replaceAdditionalQueryParams(key: String, value: String) = apply { - additionalQueryParams.replace(key, value) - } - - fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { - additionalQueryParams.replace(key, values) - } - - fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.replaceAll(additionalQueryParams) - } - - fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = - apply { - this.additionalQueryParams.replaceAll(additionalQueryParams) - } - - fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } - - fun removeAllAdditionalQueryParams(keys: Set) = apply { - additionalQueryParams.removeAll(keys) - } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - putAllAdditionalBodyProperties(additionalBodyProperties) - } - - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - additionalBodyProperties.put(key, value) - } - - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - this.additionalBodyProperties.putAll(additionalBodyProperties) - } - - fun removeAdditionalBodyProperty(key: String) = apply { - additionalBodyProperties.remove(key) - } - - fun removeAllAdditionalBodyProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalBodyProperty) - } - - /** - * Returns an immutable instance of [SessionEndParams]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): SessionEndParams = - SessionEndParams( - sessionId, - additionalHeaders.build(), - additionalQueryParams.build(), - additionalBodyProperties.toImmutable(), - ) - } - - fun _body(): Optional> = - Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - - fun _pathParam(index: Int): String = - when (index) { - 0 -> sessionId ?: "" - else -> "" - } - - override fun _headers(): Headers = additionalHeaders - - override fun _queryParams(): QueryParams = additionalQueryParams - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is SessionEndParams && - sessionId == other.sessionId && - additionalHeaders == other.additionalHeaders && - additionalQueryParams == other.additionalQueryParams && - additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int = - Objects.hash(sessionId, additionalHeaders, additionalQueryParams, additionalBodyProperties) - - override fun toString() = - "SessionEndParams{sessionId=$sessionId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" -} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt deleted file mode 100644 index feba7d7..0000000 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt +++ /dev/null @@ -1,153 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.ExcludeMissing -import com.browserbase.api.core.JsonField -import com.browserbase.api.core.JsonMissing -import com.browserbase.api.core.JsonValue -import com.browserbase.api.errors.StagehandInvalidDataException -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonCreator -import com.fasterxml.jackson.annotation.JsonProperty -import java.util.Collections -import java.util.Objects -import java.util.Optional - -class SessionEndResponse -@JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor( - private val success: JsonField, - private val additionalProperties: MutableMap, -) { - - @JsonCreator - private constructor( - @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of() - ) : this(success, mutableMapOf()) - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun success(): Optional = success.getOptional("success") - - /** - * Returns the raw JSON value of [success]. - * - * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [SessionEndResponse]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [SessionEndResponse]. */ - class Builder internal constructor() { - - private var success: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(sessionEndResponse: SessionEndResponse) = apply { - success = sessionEndResponse.success - additionalProperties = sessionEndResponse.additionalProperties.toMutableMap() - } - - fun success(success: Boolean) = success(JsonField.of(success)) - - /** - * Sets [Builder.success] to an arbitrary JSON value. - * - * You should usually call [Builder.success] with a well-typed [Boolean] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun success(success: JsonField) = apply { this.success = success } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [SessionEndResponse]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): SessionEndResponse = - SessionEndResponse(success, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): SessionEndResponse = apply { - if (validated) { - return@apply - } - - success() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = (if (success.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is SessionEndResponse && - success == other.success && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(success, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "SessionEndResponse{success=$success, additionalProperties=$additionalProperties}" -} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParams.kt deleted file mode 100644 index d2c5c47..0000000 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParams.kt +++ /dev/null @@ -1,1547 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.BaseDeserializer -import com.browserbase.api.core.BaseSerializer -import com.browserbase.api.core.Enum -import com.browserbase.api.core.ExcludeMissing -import com.browserbase.api.core.JsonField -import com.browserbase.api.core.JsonMissing -import com.browserbase.api.core.JsonValue -import com.browserbase.api.core.Params -import com.browserbase.api.core.allMaxBy -import com.browserbase.api.core.checkRequired -import com.browserbase.api.core.getOrThrow -import com.browserbase.api.core.http.Headers -import com.browserbase.api.core.http.QueryParams -import com.browserbase.api.errors.StagehandInvalidDataException -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonCreator -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.ObjectCodec -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.SerializerProvider -import com.fasterxml.jackson.databind.annotation.JsonDeserialize -import com.fasterxml.jackson.databind.annotation.JsonSerialize -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import java.util.Collections -import java.util.Objects -import java.util.Optional -import kotlin.jvm.optionals.getOrNull - -/** Runs an autonomous agent that can perform multiple actions to complete a complex task. */ -class SessionExecuteAgentParams -private constructor( - private val sessionId: String?, - private val xStreamResponse: XStreamResponse?, - private val body: Body, - private val additionalHeaders: Headers, - private val additionalQueryParams: QueryParams, -) : Params { - - fun sessionId(): Optional = Optional.ofNullable(sessionId) - - fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun agentConfig(): AgentConfig = body.agentConfig() - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun executeOptions(): ExecuteOptions = body.executeOptions() - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun frameId(): Optional = body.frameId() - - /** - * Returns the raw JSON value of [agentConfig]. - * - * Unlike [agentConfig], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _agentConfig(): JsonField = body._agentConfig() - - /** - * Returns the raw JSON value of [executeOptions]. - * - * Unlike [executeOptions], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _executeOptions(): JsonField = body._executeOptions() - - /** - * Returns the raw JSON value of [frameId]. - * - * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _frameId(): JsonField = body._frameId() - - fun _additionalBodyProperties(): Map = body._additionalProperties() - - /** Additional headers to send with the request. */ - fun _additionalHeaders(): Headers = additionalHeaders - - /** Additional query param to send with the request. */ - fun _additionalQueryParams(): QueryParams = additionalQueryParams - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [SessionExecuteAgentParams]. - * - * The following fields are required: - * ```java - * .agentConfig() - * .executeOptions() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [SessionExecuteAgentParams]. */ - class Builder internal constructor() { - - private var sessionId: String? = null - private var xStreamResponse: XStreamResponse? = null - private var body: Body.Builder = Body.builder() - private var additionalHeaders: Headers.Builder = Headers.builder() - private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() - - @JvmSynthetic - internal fun from(sessionExecuteAgentParams: SessionExecuteAgentParams) = apply { - sessionId = sessionExecuteAgentParams.sessionId - xStreamResponse = sessionExecuteAgentParams.xStreamResponse - body = sessionExecuteAgentParams.body.toBuilder() - additionalHeaders = sessionExecuteAgentParams.additionalHeaders.toBuilder() - additionalQueryParams = sessionExecuteAgentParams.additionalQueryParams.toBuilder() - } - - fun sessionId(sessionId: String?) = apply { this.sessionId = sessionId } - - /** Alias for calling [Builder.sessionId] with `sessionId.orElse(null)`. */ - fun sessionId(sessionId: Optional) = sessionId(sessionId.getOrNull()) - - fun xStreamResponse(xStreamResponse: XStreamResponse?) = apply { - this.xStreamResponse = xStreamResponse - } - - /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ - fun xStreamResponse(xStreamResponse: Optional) = - xStreamResponse(xStreamResponse.getOrNull()) - - /** - * Sets the entire request body. - * - * This is generally only useful if you are already constructing the body separately. - * Otherwise, it's more convenient to use the top-level setters instead: - * - [agentConfig] - * - [executeOptions] - * - [frameId] - */ - fun body(body: Body) = apply { this.body = body.toBuilder() } - - fun agentConfig(agentConfig: AgentConfig) = apply { body.agentConfig(agentConfig) } - - /** - * Sets [Builder.agentConfig] to an arbitrary JSON value. - * - * You should usually call [Builder.agentConfig] with a well-typed [AgentConfig] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun agentConfig(agentConfig: JsonField) = apply { - body.agentConfig(agentConfig) - } - - fun executeOptions(executeOptions: ExecuteOptions) = apply { - body.executeOptions(executeOptions) - } - - /** - * Sets [Builder.executeOptions] to an arbitrary JSON value. - * - * You should usually call [Builder.executeOptions] with a well-typed [ExecuteOptions] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun executeOptions(executeOptions: JsonField) = apply { - body.executeOptions(executeOptions) - } - - fun frameId(frameId: String) = apply { body.frameId(frameId) } - - /** - * Sets [Builder.frameId] to an arbitrary JSON value. - * - * You should usually call [Builder.frameId] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun frameId(frameId: JsonField) = apply { body.frameId(frameId) } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - body.additionalProperties(additionalBodyProperties) - } - - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - body.putAdditionalProperty(key, value) - } - - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - body.putAllAdditionalProperties(additionalBodyProperties) - } - - fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - - fun removeAllAdditionalBodyProperties(keys: Set) = apply { - body.removeAllAdditionalProperties(keys) - } - - fun additionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.clear() - putAllAdditionalHeaders(additionalHeaders) - } - - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllAdditionalHeaders(additionalHeaders) - } - - fun putAdditionalHeader(name: String, value: String) = apply { - additionalHeaders.put(name, value) - } - - fun putAdditionalHeaders(name: String, values: Iterable) = apply { - additionalHeaders.put(name, values) - } - - fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.putAll(additionalHeaders) - } - - fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.putAll(additionalHeaders) - } - - fun replaceAdditionalHeaders(name: String, value: String) = apply { - additionalHeaders.replace(name, value) - } - - fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { - additionalHeaders.replace(name, values) - } - - fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.replaceAll(additionalHeaders) - } - - fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.replaceAll(additionalHeaders) - } - - fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - - fun removeAllAdditionalHeaders(names: Set) = apply { - additionalHeaders.removeAll(names) - } - - fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.clear() - putAllAdditionalQueryParams(additionalQueryParams) - } - - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllAdditionalQueryParams(additionalQueryParams) - } - - fun putAdditionalQueryParam(key: String, value: String) = apply { - additionalQueryParams.put(key, value) - } - - fun putAdditionalQueryParams(key: String, values: Iterable) = apply { - additionalQueryParams.put(key, values) - } - - fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.putAll(additionalQueryParams) - } - - fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = - apply { - this.additionalQueryParams.putAll(additionalQueryParams) - } - - fun replaceAdditionalQueryParams(key: String, value: String) = apply { - additionalQueryParams.replace(key, value) - } - - fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { - additionalQueryParams.replace(key, values) - } - - fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.replaceAll(additionalQueryParams) - } - - fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = - apply { - this.additionalQueryParams.replaceAll(additionalQueryParams) - } - - fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } - - fun removeAllAdditionalQueryParams(keys: Set) = apply { - additionalQueryParams.removeAll(keys) - } - - /** - * Returns an immutable instance of [SessionExecuteAgentParams]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .agentConfig() - * .executeOptions() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): SessionExecuteAgentParams = - SessionExecuteAgentParams( - sessionId, - xStreamResponse, - body.build(), - additionalHeaders.build(), - additionalQueryParams.build(), - ) - } - - fun _body(): Body = body - - fun _pathParam(index: Int): String = - when (index) { - 0 -> sessionId ?: "" - else -> "" - } - - override fun _headers(): Headers = - Headers.builder() - .apply { - xStreamResponse?.let { put("x-stream-response", it.toString()) } - putAll(additionalHeaders) - } - .build() - - override fun _queryParams(): QueryParams = additionalQueryParams - - class Body - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val agentConfig: JsonField, - private val executeOptions: JsonField, - private val frameId: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("agentConfig") - @ExcludeMissing - agentConfig: JsonField = JsonMissing.of(), - @JsonProperty("executeOptions") - @ExcludeMissing - executeOptions: JsonField = JsonMissing.of(), - @JsonProperty("frameId") @ExcludeMissing frameId: JsonField = JsonMissing.of(), - ) : this(agentConfig, executeOptions, frameId, mutableMapOf()) - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun agentConfig(): AgentConfig = agentConfig.getRequired("agentConfig") - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun executeOptions(): ExecuteOptions = executeOptions.getRequired("executeOptions") - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun frameId(): Optional = frameId.getOptional("frameId") - - /** - * Returns the raw JSON value of [agentConfig]. - * - * Unlike [agentConfig], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("agentConfig") - @ExcludeMissing - fun _agentConfig(): JsonField = agentConfig - - /** - * Returns the raw JSON value of [executeOptions]. - * - * Unlike [executeOptions], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("executeOptions") - @ExcludeMissing - fun _executeOptions(): JsonField = executeOptions - - /** - * Returns the raw JSON value of [frameId]. - * - * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("frameId") @ExcludeMissing fun _frameId(): JsonField = frameId - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [Body]. - * - * The following fields are required: - * ```java - * .agentConfig() - * .executeOptions() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Body]. */ - class Builder internal constructor() { - - private var agentConfig: JsonField? = null - private var executeOptions: JsonField? = null - private var frameId: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(body: Body) = apply { - agentConfig = body.agentConfig - executeOptions = body.executeOptions - frameId = body.frameId - additionalProperties = body.additionalProperties.toMutableMap() - } - - fun agentConfig(agentConfig: AgentConfig) = agentConfig(JsonField.of(agentConfig)) - - /** - * Sets [Builder.agentConfig] to an arbitrary JSON value. - * - * You should usually call [Builder.agentConfig] with a well-typed [AgentConfig] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun agentConfig(agentConfig: JsonField) = apply { - this.agentConfig = agentConfig - } - - fun executeOptions(executeOptions: ExecuteOptions) = - executeOptions(JsonField.of(executeOptions)) - - /** - * Sets [Builder.executeOptions] to an arbitrary JSON value. - * - * You should usually call [Builder.executeOptions] with a well-typed [ExecuteOptions] - * value instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun executeOptions(executeOptions: JsonField) = apply { - this.executeOptions = executeOptions - } - - fun frameId(frameId: String) = frameId(JsonField.of(frameId)) - - /** - * Sets [Builder.frameId] to an arbitrary JSON value. - * - * You should usually call [Builder.frameId] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun frameId(frameId: JsonField) = apply { this.frameId = frameId } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Body]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .agentConfig() - * .executeOptions() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): Body = - Body( - checkRequired("agentConfig", agentConfig), - checkRequired("executeOptions", executeOptions), - frameId, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Body = apply { - if (validated) { - return@apply - } - - agentConfig().validate() - executeOptions().validate() - frameId() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (agentConfig.asKnown().getOrNull()?.validity() ?: 0) + - (executeOptions.asKnown().getOrNull()?.validity() ?: 0) + - (if (frameId.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Body && - agentConfig == other.agentConfig && - executeOptions == other.executeOptions && - frameId == other.frameId && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(agentConfig, executeOptions, frameId, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Body{agentConfig=$agentConfig, executeOptions=$executeOptions, frameId=$frameId, additionalProperties=$additionalProperties}" - } - - class AgentConfig - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val cua: JsonField, - private val model: JsonField, - private val provider: JsonField, - private val systemPrompt: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("cua") @ExcludeMissing cua: JsonField = JsonMissing.of(), - @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), - @JsonProperty("provider") - @ExcludeMissing - provider: JsonField = JsonMissing.of(), - @JsonProperty("systemPrompt") - @ExcludeMissing - systemPrompt: JsonField = JsonMissing.of(), - ) : this(cua, model, provider, systemPrompt, mutableMapOf()) - - /** - * Enable Computer Use Agent mode - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun cua(): Optional = cua.getOptional("cua") - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun model(): Optional = model.getOptional("model") - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun provider(): Optional = provider.getOptional("provider") - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun systemPrompt(): Optional = systemPrompt.getOptional("systemPrompt") - - /** - * Returns the raw JSON value of [cua]. - * - * Unlike [cua], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("cua") @ExcludeMissing fun _cua(): JsonField = cua - - /** - * Returns the raw JSON value of [model]. - * - * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model - - /** - * Returns the raw JSON value of [provider]. - * - * Unlike [provider], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("provider") @ExcludeMissing fun _provider(): JsonField = provider - - /** - * Returns the raw JSON value of [systemPrompt]. - * - * Unlike [systemPrompt], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("systemPrompt") - @ExcludeMissing - fun _systemPrompt(): JsonField = systemPrompt - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [AgentConfig]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [AgentConfig]. */ - class Builder internal constructor() { - - private var cua: JsonField = JsonMissing.of() - private var model: JsonField = JsonMissing.of() - private var provider: JsonField = JsonMissing.of() - private var systemPrompt: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(agentConfig: AgentConfig) = apply { - cua = agentConfig.cua - model = agentConfig.model - provider = agentConfig.provider - systemPrompt = agentConfig.systemPrompt - additionalProperties = agentConfig.additionalProperties.toMutableMap() - } - - /** Enable Computer Use Agent mode */ - fun cua(cua: Boolean) = cua(JsonField.of(cua)) - - /** - * Sets [Builder.cua] to an arbitrary JSON value. - * - * You should usually call [Builder.cua] with a well-typed [Boolean] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun cua(cua: JsonField) = apply { this.cua = cua } - - fun model(model: Model) = model(JsonField.of(model)) - - /** - * Sets [Builder.model] to an arbitrary JSON value. - * - * You should usually call [Builder.model] with a well-typed [Model] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun model(model: JsonField) = apply { this.model = model } - - /** Alias for calling [model] with `Model.ofString(string)`. */ - fun model(string: String) = model(Model.ofString(string)) - - /** Alias for calling [model] with `Model.ofConfig(config)`. */ - fun model(config: ModelConfig) = model(Model.ofConfig(config)) - - fun provider(provider: Provider) = provider(JsonField.of(provider)) - - /** - * Sets [Builder.provider] to an arbitrary JSON value. - * - * You should usually call [Builder.provider] with a well-typed [Provider] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun provider(provider: JsonField) = apply { this.provider = provider } - - fun systemPrompt(systemPrompt: String) = systemPrompt(JsonField.of(systemPrompt)) - - /** - * Sets [Builder.systemPrompt] to an arbitrary JSON value. - * - * You should usually call [Builder.systemPrompt] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun systemPrompt(systemPrompt: JsonField) = apply { - this.systemPrompt = systemPrompt - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [AgentConfig]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): AgentConfig = - AgentConfig(cua, model, provider, systemPrompt, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): AgentConfig = apply { - if (validated) { - return@apply - } - - cua() - model().ifPresent { it.validate() } - provider().ifPresent { it.validate() } - systemPrompt() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (if (cua.asKnown().isPresent) 1 else 0) + - (model.asKnown().getOrNull()?.validity() ?: 0) + - (provider.asKnown().getOrNull()?.validity() ?: 0) + - (if (systemPrompt.asKnown().isPresent) 1 else 0) - - @JsonDeserialize(using = Model.Deserializer::class) - @JsonSerialize(using = Model.Serializer::class) - class Model - private constructor( - private val string: String? = null, - private val config: ModelConfig? = null, - private val _json: JsonValue? = null, - ) { - - fun string(): Optional = Optional.ofNullable(string) - - fun config(): Optional = Optional.ofNullable(config) - - fun isString(): Boolean = string != null - - fun isConfig(): Boolean = config != null - - fun asString(): String = string.getOrThrow("string") - - fun asConfig(): ModelConfig = config.getOrThrow("config") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - string != null -> visitor.visitString(string) - config != null -> visitor.visitConfig(config) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): Model = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitString(string: String) {} - - override fun visitConfig(config: ModelConfig) { - config.validate() - } - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitString(string: String) = 1 - - override fun visitConfig(config: ModelConfig) = config.validity() - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Model && string == other.string && config == other.config - } - - override fun hashCode(): Int = Objects.hash(string, config) - - override fun toString(): String = - when { - string != null -> "Model{string=$string}" - config != null -> "Model{config=$config}" - _json != null -> "Model{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Model") - } - - companion object { - - @JvmStatic fun ofString(string: String) = Model(string = string) - - @JvmStatic fun ofConfig(config: ModelConfig) = Model(config = config) - } - - /** - * An interface that defines how to map each variant of [Model] to a value of type [T]. - */ - interface Visitor { - - fun visitString(string: String): T - - fun visitConfig(config: ModelConfig): T - - /** - * Maps an unknown variant of [Model] to a value of type [T]. - * - * An instance of [Model] can contain an unknown variant if it was deserialized from - * data that doesn't match any known variant. For example, if the SDK is on an older - * version than the API, then the API may respond with new variants that the SDK is - * unaware of. - * - * @throws StagehandInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw StagehandInvalidDataException("Unknown Model: $json") - } - } - - internal class Deserializer : BaseDeserializer(Model::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): Model { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef())?.let { - Model(config = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - Model(string = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely incompatible - // with all the possible variants (e.g. deserializing from array). - 0 -> Model(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then use the - // first completely valid match, or simply the first match if none are - // completely valid. - else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : BaseSerializer(Model::class) { - - override fun serialize( - value: Model, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.string != null -> generator.writeObject(value.string) - value.config != null -> generator.writeObject(value.config) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid Model") - } - } - } - } - - class Provider @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is - * on an older version than the API, then the API may respond with new members that the - * SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val OPENAI = of("openai") - - @JvmField val ANTHROPIC = of("anthropic") - - @JvmField val GOOGLE = of("google") - - @JvmStatic fun of(value: String) = Provider(JsonField.of(value)) - } - - /** An enum containing [Provider]'s known values. */ - enum class Known { - OPENAI, - ANTHROPIC, - GOOGLE, - } - - /** - * An enum containing [Provider]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Provider] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if - * the SDK is on an older version than the API, then the API may respond with new - * members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - OPENAI, - ANTHROPIC, - GOOGLE, - /** - * An enum member indicating that [Provider] was instantiated with an unknown value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you - * want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - OPENAI -> Value.OPENAI - ANTHROPIC -> Value.ANTHROPIC - GOOGLE -> Value.GOOGLE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and - * don't want to throw for the unknown case. - * - * @throws StagehandInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - OPENAI -> Known.OPENAI - ANTHROPIC -> Known.ANTHROPIC - GOOGLE -> Known.GOOGLE - else -> throw StagehandInvalidDataException("Unknown Provider: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws StagehandInvalidDataException if this class instance's value does not have - * the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - StagehandInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Provider = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Provider && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AgentConfig && - cua == other.cua && - model == other.model && - provider == other.provider && - systemPrompt == other.systemPrompt && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(cua, model, provider, systemPrompt, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "AgentConfig{cua=$cua, model=$model, provider=$provider, systemPrompt=$systemPrompt, additionalProperties=$additionalProperties}" - } - - class ExecuteOptions - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val instruction: JsonField, - private val highlightCursor: JsonField, - private val maxSteps: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("instruction") - @ExcludeMissing - instruction: JsonField = JsonMissing.of(), - @JsonProperty("highlightCursor") - @ExcludeMissing - highlightCursor: JsonField = JsonMissing.of(), - @JsonProperty("maxSteps") @ExcludeMissing maxSteps: JsonField = JsonMissing.of(), - ) : this(instruction, highlightCursor, maxSteps, mutableMapOf()) - - /** - * Task for the agent to complete - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun instruction(): String = instruction.getRequired("instruction") - - /** - * Visually highlight the cursor during actions - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun highlightCursor(): Optional = highlightCursor.getOptional("highlightCursor") - - /** - * Maximum number of steps the agent can take - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun maxSteps(): Optional = maxSteps.getOptional("maxSteps") - - /** - * Returns the raw JSON value of [instruction]. - * - * Unlike [instruction], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("instruction") - @ExcludeMissing - fun _instruction(): JsonField = instruction - - /** - * Returns the raw JSON value of [highlightCursor]. - * - * Unlike [highlightCursor], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("highlightCursor") - @ExcludeMissing - fun _highlightCursor(): JsonField = highlightCursor - - /** - * Returns the raw JSON value of [maxSteps]. - * - * Unlike [maxSteps], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("maxSteps") @ExcludeMissing fun _maxSteps(): JsonField = maxSteps - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [ExecuteOptions]. - * - * The following fields are required: - * ```java - * .instruction() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [ExecuteOptions]. */ - class Builder internal constructor() { - - private var instruction: JsonField? = null - private var highlightCursor: JsonField = JsonMissing.of() - private var maxSteps: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(executeOptions: ExecuteOptions) = apply { - instruction = executeOptions.instruction - highlightCursor = executeOptions.highlightCursor - maxSteps = executeOptions.maxSteps - additionalProperties = executeOptions.additionalProperties.toMutableMap() - } - - /** Task for the agent to complete */ - fun instruction(instruction: String) = instruction(JsonField.of(instruction)) - - /** - * Sets [Builder.instruction] to an arbitrary JSON value. - * - * You should usually call [Builder.instruction] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun instruction(instruction: JsonField) = apply { - this.instruction = instruction - } - - /** Visually highlight the cursor during actions */ - fun highlightCursor(highlightCursor: Boolean) = - highlightCursor(JsonField.of(highlightCursor)) - - /** - * Sets [Builder.highlightCursor] to an arbitrary JSON value. - * - * You should usually call [Builder.highlightCursor] with a well-typed [Boolean] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun highlightCursor(highlightCursor: JsonField) = apply { - this.highlightCursor = highlightCursor - } - - /** Maximum number of steps the agent can take */ - fun maxSteps(maxSteps: Long) = maxSteps(JsonField.of(maxSteps)) - - /** - * Sets [Builder.maxSteps] to an arbitrary JSON value. - * - * You should usually call [Builder.maxSteps] with a well-typed [Long] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun maxSteps(maxSteps: JsonField) = apply { this.maxSteps = maxSteps } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [ExecuteOptions]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .instruction() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): ExecuteOptions = - ExecuteOptions( - checkRequired("instruction", instruction), - highlightCursor, - maxSteps, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): ExecuteOptions = apply { - if (validated) { - return@apply - } - - instruction() - highlightCursor() - maxSteps() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (if (instruction.asKnown().isPresent) 1 else 0) + - (if (highlightCursor.asKnown().isPresent) 1 else 0) + - (if (maxSteps.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ExecuteOptions && - instruction == other.instruction && - highlightCursor == other.highlightCursor && - maxSteps == other.maxSteps && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(instruction, highlightCursor, maxSteps, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "ExecuteOptions{instruction=$instruction, highlightCursor=$highlightCursor, maxSteps=$maxSteps, additionalProperties=$additionalProperties}" - } - - class XStreamResponse @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val TRUE = of("true") - - @JvmField val FALSE = of("false") - - @JvmStatic fun of(value: String) = XStreamResponse(JsonField.of(value)) - } - - /** An enum containing [XStreamResponse]'s known values. */ - enum class Known { - TRUE, - FALSE, - } - - /** - * An enum containing [XStreamResponse]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [XStreamResponse] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - TRUE, - FALSE, - /** - * An enum member indicating that [XStreamResponse] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - TRUE -> Value.TRUE - FALSE -> Value.FALSE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws StagehandInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - TRUE -> Known.TRUE - FALSE -> Known.FALSE - else -> throw StagehandInvalidDataException("Unknown XStreamResponse: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for debugging - * and generally doesn't throw. - * - * @throws StagehandInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - StagehandInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): XStreamResponse = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is XStreamResponse && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is SessionExecuteAgentParams && - sessionId == other.sessionId && - xStreamResponse == other.xStreamResponse && - body == other.body && - additionalHeaders == other.additionalHeaders && - additionalQueryParams == other.additionalQueryParams - } - - override fun hashCode(): Int = - Objects.hash(sessionId, xStreamResponse, body, additionalHeaders, additionalQueryParams) - - override fun toString() = - "SessionExecuteAgentParams{sessionId=$sessionId, xStreamResponse=$xStreamResponse, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" -} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponse.kt deleted file mode 100644 index 3c3af1d..0000000 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponse.kt +++ /dev/null @@ -1,158 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.ExcludeMissing -import com.browserbase.api.core.JsonField -import com.browserbase.api.core.JsonMissing -import com.browserbase.api.core.JsonValue -import com.browserbase.api.errors.StagehandInvalidDataException -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonCreator -import com.fasterxml.jackson.annotation.JsonProperty -import java.util.Collections -import java.util.Objects -import java.util.Optional - -class SessionExecuteAgentResponse -@JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor( - private val message: JsonField, - private val additionalProperties: MutableMap, -) { - - @JsonCreator - private constructor( - @JsonProperty("message") @ExcludeMissing message: JsonField = JsonMissing.of() - ) : this(message, mutableMapOf()) - - /** - * Final message from the agent - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun message(): Optional = message.getOptional("message") - - /** - * Returns the raw JSON value of [message]. - * - * Unlike [message], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("message") @ExcludeMissing fun _message(): JsonField = message - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [SessionExecuteAgentResponse]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [SessionExecuteAgentResponse]. */ - class Builder internal constructor() { - - private var message: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(sessionExecuteAgentResponse: SessionExecuteAgentResponse) = apply { - message = sessionExecuteAgentResponse.message - additionalProperties = sessionExecuteAgentResponse.additionalProperties.toMutableMap() - } - - /** Final message from the agent */ - fun message(message: String) = message(JsonField.of(message)) - - /** - * Sets [Builder.message] to an arbitrary JSON value. - * - * You should usually call [Builder.message] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun message(message: JsonField) = apply { this.message = message } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [SessionExecuteAgentResponse]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): SessionExecuteAgentResponse = - SessionExecuteAgentResponse(message, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): SessionExecuteAgentResponse = apply { - if (validated) { - return@apply - } - - message() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = (if (message.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is SessionExecuteAgentResponse && - message == other.message && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(message, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "SessionExecuteAgentResponse{message=$message, additionalProperties=$additionalProperties}" -} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractParams.kt deleted file mode 100644 index 3833673..0000000 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractParams.kt +++ /dev/null @@ -1,1064 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.Enum -import com.browserbase.api.core.ExcludeMissing -import com.browserbase.api.core.JsonField -import com.browserbase.api.core.JsonMissing -import com.browserbase.api.core.JsonValue -import com.browserbase.api.core.Params -import com.browserbase.api.core.http.Headers -import com.browserbase.api.core.http.QueryParams -import com.browserbase.api.core.toImmutable -import com.browserbase.api.errors.StagehandInvalidDataException -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonCreator -import com.fasterxml.jackson.annotation.JsonProperty -import java.util.Collections -import java.util.Objects -import java.util.Optional -import kotlin.jvm.optionals.getOrNull - -/** - * Extracts data from the current page using natural language instructions and optional JSON schema - * for structured output. - */ -class SessionExtractParams -private constructor( - private val sessionId: String?, - private val xStreamResponse: XStreamResponse?, - private val body: Body, - private val additionalHeaders: Headers, - private val additionalQueryParams: QueryParams, -) : Params { - - fun sessionId(): Optional = Optional.ofNullable(sessionId) - - fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) - - /** - * Frame ID to extract from - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun frameId(): Optional = body.frameId() - - /** - * Natural language instruction for extraction - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun instruction(): Optional = body.instruction() - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun options(): Optional = body.options() - - /** - * JSON Schema for structured output - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun schema(): Optional = body.schema() - - /** - * Returns the raw JSON value of [frameId]. - * - * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _frameId(): JsonField = body._frameId() - - /** - * Returns the raw JSON value of [instruction]. - * - * Unlike [instruction], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _instruction(): JsonField = body._instruction() - - /** - * Returns the raw JSON value of [options]. - * - * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _options(): JsonField = body._options() - - /** - * Returns the raw JSON value of [schema]. - * - * Unlike [schema], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _schema(): JsonField = body._schema() - - fun _additionalBodyProperties(): Map = body._additionalProperties() - - /** Additional headers to send with the request. */ - fun _additionalHeaders(): Headers = additionalHeaders - - /** Additional query param to send with the request. */ - fun _additionalQueryParams(): QueryParams = additionalQueryParams - - fun toBuilder() = Builder().from(this) - - companion object { - - @JvmStatic fun none(): SessionExtractParams = builder().build() - - /** Returns a mutable builder for constructing an instance of [SessionExtractParams]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [SessionExtractParams]. */ - class Builder internal constructor() { - - private var sessionId: String? = null - private var xStreamResponse: XStreamResponse? = null - private var body: Body.Builder = Body.builder() - private var additionalHeaders: Headers.Builder = Headers.builder() - private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() - - @JvmSynthetic - internal fun from(sessionExtractParams: SessionExtractParams) = apply { - sessionId = sessionExtractParams.sessionId - xStreamResponse = sessionExtractParams.xStreamResponse - body = sessionExtractParams.body.toBuilder() - additionalHeaders = sessionExtractParams.additionalHeaders.toBuilder() - additionalQueryParams = sessionExtractParams.additionalQueryParams.toBuilder() - } - - fun sessionId(sessionId: String?) = apply { this.sessionId = sessionId } - - /** Alias for calling [Builder.sessionId] with `sessionId.orElse(null)`. */ - fun sessionId(sessionId: Optional) = sessionId(sessionId.getOrNull()) - - fun xStreamResponse(xStreamResponse: XStreamResponse?) = apply { - this.xStreamResponse = xStreamResponse - } - - /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ - fun xStreamResponse(xStreamResponse: Optional) = - xStreamResponse(xStreamResponse.getOrNull()) - - /** - * Sets the entire request body. - * - * This is generally only useful if you are already constructing the body separately. - * Otherwise, it's more convenient to use the top-level setters instead: - * - [frameId] - * - [instruction] - * - [options] - * - [schema] - */ - fun body(body: Body) = apply { this.body = body.toBuilder() } - - /** Frame ID to extract from */ - fun frameId(frameId: String) = apply { body.frameId(frameId) } - - /** - * Sets [Builder.frameId] to an arbitrary JSON value. - * - * You should usually call [Builder.frameId] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun frameId(frameId: JsonField) = apply { body.frameId(frameId) } - - /** Natural language instruction for extraction */ - fun instruction(instruction: String) = apply { body.instruction(instruction) } - - /** - * Sets [Builder.instruction] to an arbitrary JSON value. - * - * You should usually call [Builder.instruction] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun instruction(instruction: JsonField) = apply { body.instruction(instruction) } - - fun options(options: Options) = apply { body.options(options) } - - /** - * Sets [Builder.options] to an arbitrary JSON value. - * - * You should usually call [Builder.options] with a well-typed [Options] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun options(options: JsonField) = apply { body.options(options) } - - /** JSON Schema for structured output */ - fun schema(schema: Schema) = apply { body.schema(schema) } - - /** - * Sets [Builder.schema] to an arbitrary JSON value. - * - * You should usually call [Builder.schema] with a well-typed [Schema] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun schema(schema: JsonField) = apply { body.schema(schema) } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - body.additionalProperties(additionalBodyProperties) - } - - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - body.putAdditionalProperty(key, value) - } - - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - body.putAllAdditionalProperties(additionalBodyProperties) - } - - fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - - fun removeAllAdditionalBodyProperties(keys: Set) = apply { - body.removeAllAdditionalProperties(keys) - } - - fun additionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.clear() - putAllAdditionalHeaders(additionalHeaders) - } - - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllAdditionalHeaders(additionalHeaders) - } - - fun putAdditionalHeader(name: String, value: String) = apply { - additionalHeaders.put(name, value) - } - - fun putAdditionalHeaders(name: String, values: Iterable) = apply { - additionalHeaders.put(name, values) - } - - fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.putAll(additionalHeaders) - } - - fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.putAll(additionalHeaders) - } - - fun replaceAdditionalHeaders(name: String, value: String) = apply { - additionalHeaders.replace(name, value) - } - - fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { - additionalHeaders.replace(name, values) - } - - fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.replaceAll(additionalHeaders) - } - - fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.replaceAll(additionalHeaders) - } - - fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - - fun removeAllAdditionalHeaders(names: Set) = apply { - additionalHeaders.removeAll(names) - } - - fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.clear() - putAllAdditionalQueryParams(additionalQueryParams) - } - - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllAdditionalQueryParams(additionalQueryParams) - } - - fun putAdditionalQueryParam(key: String, value: String) = apply { - additionalQueryParams.put(key, value) - } - - fun putAdditionalQueryParams(key: String, values: Iterable) = apply { - additionalQueryParams.put(key, values) - } - - fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.putAll(additionalQueryParams) - } - - fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = - apply { - this.additionalQueryParams.putAll(additionalQueryParams) - } - - fun replaceAdditionalQueryParams(key: String, value: String) = apply { - additionalQueryParams.replace(key, value) - } - - fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { - additionalQueryParams.replace(key, values) - } - - fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.replaceAll(additionalQueryParams) - } - - fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = - apply { - this.additionalQueryParams.replaceAll(additionalQueryParams) - } - - fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } - - fun removeAllAdditionalQueryParams(keys: Set) = apply { - additionalQueryParams.removeAll(keys) - } - - /** - * Returns an immutable instance of [SessionExtractParams]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): SessionExtractParams = - SessionExtractParams( - sessionId, - xStreamResponse, - body.build(), - additionalHeaders.build(), - additionalQueryParams.build(), - ) - } - - fun _body(): Body = body - - fun _pathParam(index: Int): String = - when (index) { - 0 -> sessionId ?: "" - else -> "" - } - - override fun _headers(): Headers = - Headers.builder() - .apply { - xStreamResponse?.let { put("x-stream-response", it.toString()) } - putAll(additionalHeaders) - } - .build() - - override fun _queryParams(): QueryParams = additionalQueryParams - - class Body - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val frameId: JsonField, - private val instruction: JsonField, - private val options: JsonField, - private val schema: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("frameId") @ExcludeMissing frameId: JsonField = JsonMissing.of(), - @JsonProperty("instruction") - @ExcludeMissing - instruction: JsonField = JsonMissing.of(), - @JsonProperty("options") @ExcludeMissing options: JsonField = JsonMissing.of(), - @JsonProperty("schema") @ExcludeMissing schema: JsonField = JsonMissing.of(), - ) : this(frameId, instruction, options, schema, mutableMapOf()) - - /** - * Frame ID to extract from - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun frameId(): Optional = frameId.getOptional("frameId") - - /** - * Natural language instruction for extraction - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun instruction(): Optional = instruction.getOptional("instruction") - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun options(): Optional = options.getOptional("options") - - /** - * JSON Schema for structured output - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun schema(): Optional = schema.getOptional("schema") - - /** - * Returns the raw JSON value of [frameId]. - * - * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("frameId") @ExcludeMissing fun _frameId(): JsonField = frameId - - /** - * Returns the raw JSON value of [instruction]. - * - * Unlike [instruction], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("instruction") - @ExcludeMissing - fun _instruction(): JsonField = instruction - - /** - * Returns the raw JSON value of [options]. - * - * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("options") @ExcludeMissing fun _options(): JsonField = options - - /** - * Returns the raw JSON value of [schema]. - * - * Unlike [schema], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("schema") @ExcludeMissing fun _schema(): JsonField = schema - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [Body]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Body]. */ - class Builder internal constructor() { - - private var frameId: JsonField = JsonMissing.of() - private var instruction: JsonField = JsonMissing.of() - private var options: JsonField = JsonMissing.of() - private var schema: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(body: Body) = apply { - frameId = body.frameId - instruction = body.instruction - options = body.options - schema = body.schema - additionalProperties = body.additionalProperties.toMutableMap() - } - - /** Frame ID to extract from */ - fun frameId(frameId: String) = frameId(JsonField.of(frameId)) - - /** - * Sets [Builder.frameId] to an arbitrary JSON value. - * - * You should usually call [Builder.frameId] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun frameId(frameId: JsonField) = apply { this.frameId = frameId } - - /** Natural language instruction for extraction */ - fun instruction(instruction: String) = instruction(JsonField.of(instruction)) - - /** - * Sets [Builder.instruction] to an arbitrary JSON value. - * - * You should usually call [Builder.instruction] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun instruction(instruction: JsonField) = apply { - this.instruction = instruction - } - - fun options(options: Options) = options(JsonField.of(options)) - - /** - * Sets [Builder.options] to an arbitrary JSON value. - * - * You should usually call [Builder.options] with a well-typed [Options] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun options(options: JsonField) = apply { this.options = options } - - /** JSON Schema for structured output */ - fun schema(schema: Schema) = schema(JsonField.of(schema)) - - /** - * Sets [Builder.schema] to an arbitrary JSON value. - * - * You should usually call [Builder.schema] with a well-typed [Schema] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun schema(schema: JsonField) = apply { this.schema = schema } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Body]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Body = - Body(frameId, instruction, options, schema, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): Body = apply { - if (validated) { - return@apply - } - - frameId() - instruction() - options().ifPresent { it.validate() } - schema().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (if (frameId.asKnown().isPresent) 1 else 0) + - (if (instruction.asKnown().isPresent) 1 else 0) + - (options.asKnown().getOrNull()?.validity() ?: 0) + - (schema.asKnown().getOrNull()?.validity() ?: 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Body && - frameId == other.frameId && - instruction == other.instruction && - options == other.options && - schema == other.schema && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(frameId, instruction, options, schema, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Body{frameId=$frameId, instruction=$instruction, options=$options, schema=$schema, additionalProperties=$additionalProperties}" - } - - class Options - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val model: JsonField, - private val selector: JsonField, - private val timeout: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), - @JsonProperty("selector") - @ExcludeMissing - selector: JsonField = JsonMissing.of(), - @JsonProperty("timeout") @ExcludeMissing timeout: JsonField = JsonMissing.of(), - ) : this(model, selector, timeout, mutableMapOf()) - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun model(): Optional = model.getOptional("model") - - /** - * Extract only from elements matching this selector - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun selector(): Optional = selector.getOptional("selector") - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun timeout(): Optional = timeout.getOptional("timeout") - - /** - * Returns the raw JSON value of [model]. - * - * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model - - /** - * Returns the raw JSON value of [selector]. - * - * Unlike [selector], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("selector") @ExcludeMissing fun _selector(): JsonField = selector - - /** - * Returns the raw JSON value of [timeout]. - * - * Unlike [timeout], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("timeout") @ExcludeMissing fun _timeout(): JsonField = timeout - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [Options]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Options]. */ - class Builder internal constructor() { - - private var model: JsonField = JsonMissing.of() - private var selector: JsonField = JsonMissing.of() - private var timeout: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(options: Options) = apply { - model = options.model - selector = options.selector - timeout = options.timeout - additionalProperties = options.additionalProperties.toMutableMap() - } - - fun model(model: ModelConfig) = model(JsonField.of(model)) - - /** - * Sets [Builder.model] to an arbitrary JSON value. - * - * You should usually call [Builder.model] with a well-typed [ModelConfig] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun model(model: JsonField) = apply { this.model = model } - - /** Extract only from elements matching this selector */ - fun selector(selector: String) = selector(JsonField.of(selector)) - - /** - * Sets [Builder.selector] to an arbitrary JSON value. - * - * You should usually call [Builder.selector] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun selector(selector: JsonField) = apply { this.selector = selector } - - fun timeout(timeout: Long) = timeout(JsonField.of(timeout)) - - /** - * Sets [Builder.timeout] to an arbitrary JSON value. - * - * You should usually call [Builder.timeout] with a well-typed [Long] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun timeout(timeout: JsonField) = apply { this.timeout = timeout } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Options]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Options = - Options(model, selector, timeout, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): Options = apply { - if (validated) { - return@apply - } - - model().ifPresent { it.validate() } - selector() - timeout() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (model.asKnown().getOrNull()?.validity() ?: 0) + - (if (selector.asKnown().isPresent) 1 else 0) + - (if (timeout.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Options && - model == other.model && - selector == other.selector && - timeout == other.timeout && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(model, selector, timeout, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Options{model=$model, selector=$selector, timeout=$timeout, additionalProperties=$additionalProperties}" - } - - /** JSON Schema for structured output */ - class Schema - @JsonCreator - private constructor( - @com.fasterxml.jackson.annotation.JsonValue - private val additionalProperties: Map - ) { - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [Schema]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Schema]. */ - class Builder internal constructor() { - - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(schema: Schema) = apply { - additionalProperties = schema.additionalProperties.toMutableMap() - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Schema]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Schema = Schema(additionalProperties.toImmutable()) - } - - private var validated: Boolean = false - - fun validate(): Schema = apply { - if (validated) { - return@apply - } - - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - additionalProperties.count { (_, value) -> !value.isNull() && !value.isMissing() } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Schema && additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = "Schema{additionalProperties=$additionalProperties}" - } - - class XStreamResponse @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val TRUE = of("true") - - @JvmField val FALSE = of("false") - - @JvmStatic fun of(value: String) = XStreamResponse(JsonField.of(value)) - } - - /** An enum containing [XStreamResponse]'s known values. */ - enum class Known { - TRUE, - FALSE, - } - - /** - * An enum containing [XStreamResponse]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [XStreamResponse] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - TRUE, - FALSE, - /** - * An enum member indicating that [XStreamResponse] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - TRUE -> Value.TRUE - FALSE -> Value.FALSE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws StagehandInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - TRUE -> Known.TRUE - FALSE -> Known.FALSE - else -> throw StagehandInvalidDataException("Unknown XStreamResponse: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for debugging - * and generally doesn't throw. - * - * @throws StagehandInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - StagehandInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): XStreamResponse = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is XStreamResponse && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is SessionExtractParams && - sessionId == other.sessionId && - xStreamResponse == other.xStreamResponse && - body == other.body && - additionalHeaders == other.additionalHeaders && - additionalQueryParams == other.additionalQueryParams - } - - override fun hashCode(): Int = - Objects.hash(sessionId, xStreamResponse, body, additionalHeaders, additionalQueryParams) - - override fun toString() = - "SessionExtractParams{sessionId=$sessionId, xStreamResponse=$xStreamResponse, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" -} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractResponse.kt deleted file mode 100644 index 6816259..0000000 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractResponse.kt +++ /dev/null @@ -1,457 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.BaseDeserializer -import com.browserbase.api.core.BaseSerializer -import com.browserbase.api.core.ExcludeMissing -import com.browserbase.api.core.JsonField -import com.browserbase.api.core.JsonMissing -import com.browserbase.api.core.JsonValue -import com.browserbase.api.core.allMaxBy -import com.browserbase.api.core.getOrThrow -import com.browserbase.api.core.toImmutable -import com.browserbase.api.errors.StagehandInvalidDataException -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonCreator -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.ObjectCodec -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.SerializerProvider -import com.fasterxml.jackson.databind.annotation.JsonDeserialize -import com.fasterxml.jackson.databind.annotation.JsonSerialize -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import java.util.Collections -import java.util.Objects -import java.util.Optional - -/** Default extraction result */ -@JsonDeserialize(using = SessionExtractResponse.Deserializer::class) -@JsonSerialize(using = SessionExtractResponse.Serializer::class) -class SessionExtractResponse -private constructor( - private val extraction: Extraction? = null, - private val custom: Custom? = null, - private val _json: JsonValue? = null, -) { - - /** Default extraction result */ - fun extraction(): Optional = Optional.ofNullable(extraction) - - /** Structured data matching provided schema */ - fun custom(): Optional = Optional.ofNullable(custom) - - fun isExtraction(): Boolean = extraction != null - - fun isCustom(): Boolean = custom != null - - /** Default extraction result */ - fun asExtraction(): Extraction = extraction.getOrThrow("extraction") - - /** Structured data matching provided schema */ - fun asCustom(): Custom = custom.getOrThrow("custom") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T = - when { - extraction != null -> visitor.visitExtraction(extraction) - custom != null -> visitor.visitCustom(custom) - else -> visitor.unknown(_json) - } - - private var validated: Boolean = false - - fun validate(): SessionExtractResponse = apply { - if (validated) { - return@apply - } - - accept( - object : Visitor { - override fun visitExtraction(extraction: Extraction) { - extraction.validate() - } - - override fun visitCustom(custom: Custom) { - custom.validate() - } - } - ) - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitExtraction(extraction: Extraction) = extraction.validity() - - override fun visitCustom(custom: Custom) = custom.validity() - - override fun unknown(json: JsonValue?) = 0 - } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is SessionExtractResponse && - extraction == other.extraction && - custom == other.custom - } - - override fun hashCode(): Int = Objects.hash(extraction, custom) - - override fun toString(): String = - when { - extraction != null -> "SessionExtractResponse{extraction=$extraction}" - custom != null -> "SessionExtractResponse{custom=$custom}" - _json != null -> "SessionExtractResponse{_unknown=$_json}" - else -> throw IllegalStateException("Invalid SessionExtractResponse") - } - - companion object { - - /** Default extraction result */ - @JvmStatic - fun ofExtraction(extraction: Extraction) = SessionExtractResponse(extraction = extraction) - - /** Structured data matching provided schema */ - @JvmStatic fun ofCustom(custom: Custom) = SessionExtractResponse(custom = custom) - } - - /** - * An interface that defines how to map each variant of [SessionExtractResponse] to a value of - * type [T]. - */ - interface Visitor { - - /** Default extraction result */ - fun visitExtraction(extraction: Extraction): T - - /** Structured data matching provided schema */ - fun visitCustom(custom: Custom): T - - /** - * Maps an unknown variant of [SessionExtractResponse] to a value of type [T]. - * - * An instance of [SessionExtractResponse] can contain an unknown variant if it was - * deserialized from data that doesn't match any known variant. For example, if the SDK is - * on an older version than the API, then the API may respond with new variants that the SDK - * is unaware of. - * - * @throws StagehandInvalidDataException in the default implementation. - */ - fun unknown(json: JsonValue?): T { - throw StagehandInvalidDataException("Unknown SessionExtractResponse: $json") - } - } - - internal class Deserializer : - BaseDeserializer(SessionExtractResponse::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): SessionExtractResponse { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef())?.let { - SessionExtractResponse(extraction = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - SessionExtractResponse(custom = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely incompatible with all - // the possible variants (e.g. deserializing from boolean). - 0 -> SessionExtractResponse(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then use the first - // completely valid match, or simply the first match if none are completely valid. - else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } - - internal class Serializer : - BaseSerializer(SessionExtractResponse::class) { - - override fun serialize( - value: SessionExtractResponse, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.extraction != null -> generator.writeObject(value.extraction) - value.custom != null -> generator.writeObject(value.custom) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid SessionExtractResponse") - } - } - } - - /** Default extraction result */ - class Extraction - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val extraction: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("extraction") - @ExcludeMissing - extraction: JsonField = JsonMissing.of() - ) : this(extraction, mutableMapOf()) - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun extraction(): Optional = extraction.getOptional("extraction") - - /** - * Returns the raw JSON value of [extraction]. - * - * Unlike [extraction], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("extraction") - @ExcludeMissing - fun _extraction(): JsonField = extraction - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [Extraction]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Extraction]. */ - class Builder internal constructor() { - - private var extraction: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(extraction: Extraction) = apply { - this.extraction = extraction.extraction - additionalProperties = extraction.additionalProperties.toMutableMap() - } - - fun extraction(extraction: String) = extraction(JsonField.of(extraction)) - - /** - * Sets [Builder.extraction] to an arbitrary JSON value. - * - * You should usually call [Builder.extraction] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun extraction(extraction: JsonField) = apply { this.extraction = extraction } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Extraction]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Extraction = Extraction(extraction, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): Extraction = apply { - if (validated) { - return@apply - } - - extraction() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = (if (extraction.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Extraction && - extraction == other.extraction && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(extraction, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Extraction{extraction=$extraction, additionalProperties=$additionalProperties}" - } - - /** Structured data matching provided schema */ - class Custom - @JsonCreator - private constructor( - @com.fasterxml.jackson.annotation.JsonValue - private val additionalProperties: Map - ) { - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [Custom]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Custom]. */ - class Builder internal constructor() { - - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(custom: Custom) = apply { - additionalProperties = custom.additionalProperties.toMutableMap() - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Custom]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Custom = Custom(additionalProperties.toImmutable()) - } - - private var validated: Boolean = false - - fun validate(): Custom = apply { - if (validated) { - return@apply - } - - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - additionalProperties.count { (_, value) -> !value.isNull() && !value.isMissing() } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Custom && additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = "Custom{additionalProperties=$additionalProperties}" - } -} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateParams.kt deleted file mode 100644 index e57efd3..0000000 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateParams.kt +++ /dev/null @@ -1,992 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.Enum -import com.browserbase.api.core.ExcludeMissing -import com.browserbase.api.core.JsonField -import com.browserbase.api.core.JsonMissing -import com.browserbase.api.core.JsonValue -import com.browserbase.api.core.Params -import com.browserbase.api.core.checkRequired -import com.browserbase.api.core.http.Headers -import com.browserbase.api.core.http.QueryParams -import com.browserbase.api.errors.StagehandInvalidDataException -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonCreator -import com.fasterxml.jackson.annotation.JsonProperty -import java.util.Collections -import java.util.Objects -import java.util.Optional -import kotlin.jvm.optionals.getOrNull - -/** Navigates the browser to the specified URL and waits for page load. */ -class SessionNavigateParams -private constructor( - private val sessionId: String?, - private val xStreamResponse: XStreamResponse?, - private val body: Body, - private val additionalHeaders: Headers, - private val additionalQueryParams: QueryParams, -) : Params { - - fun sessionId(): Optional = Optional.ofNullable(sessionId) - - fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) - - /** - * URL to navigate to - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun url(): String = body.url() - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun frameId(): Optional = body.frameId() - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun options(): Optional = body.options() - - /** - * Returns the raw JSON value of [url]. - * - * Unlike [url], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _url(): JsonField = body._url() - - /** - * Returns the raw JSON value of [frameId]. - * - * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _frameId(): JsonField = body._frameId() - - /** - * Returns the raw JSON value of [options]. - * - * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _options(): JsonField = body._options() - - fun _additionalBodyProperties(): Map = body._additionalProperties() - - /** Additional headers to send with the request. */ - fun _additionalHeaders(): Headers = additionalHeaders - - /** Additional query param to send with the request. */ - fun _additionalQueryParams(): QueryParams = additionalQueryParams - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [SessionNavigateParams]. - * - * The following fields are required: - * ```java - * .url() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [SessionNavigateParams]. */ - class Builder internal constructor() { - - private var sessionId: String? = null - private var xStreamResponse: XStreamResponse? = null - private var body: Body.Builder = Body.builder() - private var additionalHeaders: Headers.Builder = Headers.builder() - private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() - - @JvmSynthetic - internal fun from(sessionNavigateParams: SessionNavigateParams) = apply { - sessionId = sessionNavigateParams.sessionId - xStreamResponse = sessionNavigateParams.xStreamResponse - body = sessionNavigateParams.body.toBuilder() - additionalHeaders = sessionNavigateParams.additionalHeaders.toBuilder() - additionalQueryParams = sessionNavigateParams.additionalQueryParams.toBuilder() - } - - fun sessionId(sessionId: String?) = apply { this.sessionId = sessionId } - - /** Alias for calling [Builder.sessionId] with `sessionId.orElse(null)`. */ - fun sessionId(sessionId: Optional) = sessionId(sessionId.getOrNull()) - - fun xStreamResponse(xStreamResponse: XStreamResponse?) = apply { - this.xStreamResponse = xStreamResponse - } - - /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ - fun xStreamResponse(xStreamResponse: Optional) = - xStreamResponse(xStreamResponse.getOrNull()) - - /** - * Sets the entire request body. - * - * This is generally only useful if you are already constructing the body separately. - * Otherwise, it's more convenient to use the top-level setters instead: - * - [url] - * - [frameId] - * - [options] - */ - fun body(body: Body) = apply { this.body = body.toBuilder() } - - /** URL to navigate to */ - fun url(url: String) = apply { body.url(url) } - - /** - * Sets [Builder.url] to an arbitrary JSON value. - * - * You should usually call [Builder.url] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun url(url: JsonField) = apply { body.url(url) } - - fun frameId(frameId: String) = apply { body.frameId(frameId) } - - /** - * Sets [Builder.frameId] to an arbitrary JSON value. - * - * You should usually call [Builder.frameId] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun frameId(frameId: JsonField) = apply { body.frameId(frameId) } - - fun options(options: Options) = apply { body.options(options) } - - /** - * Sets [Builder.options] to an arbitrary JSON value. - * - * You should usually call [Builder.options] with a well-typed [Options] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun options(options: JsonField) = apply { body.options(options) } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - body.additionalProperties(additionalBodyProperties) - } - - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - body.putAdditionalProperty(key, value) - } - - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - body.putAllAdditionalProperties(additionalBodyProperties) - } - - fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - - fun removeAllAdditionalBodyProperties(keys: Set) = apply { - body.removeAllAdditionalProperties(keys) - } - - fun additionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.clear() - putAllAdditionalHeaders(additionalHeaders) - } - - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllAdditionalHeaders(additionalHeaders) - } - - fun putAdditionalHeader(name: String, value: String) = apply { - additionalHeaders.put(name, value) - } - - fun putAdditionalHeaders(name: String, values: Iterable) = apply { - additionalHeaders.put(name, values) - } - - fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.putAll(additionalHeaders) - } - - fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.putAll(additionalHeaders) - } - - fun replaceAdditionalHeaders(name: String, value: String) = apply { - additionalHeaders.replace(name, value) - } - - fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { - additionalHeaders.replace(name, values) - } - - fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.replaceAll(additionalHeaders) - } - - fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.replaceAll(additionalHeaders) - } - - fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - - fun removeAllAdditionalHeaders(names: Set) = apply { - additionalHeaders.removeAll(names) - } - - fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.clear() - putAllAdditionalQueryParams(additionalQueryParams) - } - - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllAdditionalQueryParams(additionalQueryParams) - } - - fun putAdditionalQueryParam(key: String, value: String) = apply { - additionalQueryParams.put(key, value) - } - - fun putAdditionalQueryParams(key: String, values: Iterable) = apply { - additionalQueryParams.put(key, values) - } - - fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.putAll(additionalQueryParams) - } - - fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = - apply { - this.additionalQueryParams.putAll(additionalQueryParams) - } - - fun replaceAdditionalQueryParams(key: String, value: String) = apply { - additionalQueryParams.replace(key, value) - } - - fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { - additionalQueryParams.replace(key, values) - } - - fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.replaceAll(additionalQueryParams) - } - - fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = - apply { - this.additionalQueryParams.replaceAll(additionalQueryParams) - } - - fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } - - fun removeAllAdditionalQueryParams(keys: Set) = apply { - additionalQueryParams.removeAll(keys) - } - - /** - * Returns an immutable instance of [SessionNavigateParams]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .url() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): SessionNavigateParams = - SessionNavigateParams( - sessionId, - xStreamResponse, - body.build(), - additionalHeaders.build(), - additionalQueryParams.build(), - ) - } - - fun _body(): Body = body - - fun _pathParam(index: Int): String = - when (index) { - 0 -> sessionId ?: "" - else -> "" - } - - override fun _headers(): Headers = - Headers.builder() - .apply { - xStreamResponse?.let { put("x-stream-response", it.toString()) } - putAll(additionalHeaders) - } - .build() - - override fun _queryParams(): QueryParams = additionalQueryParams - - class Body - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val url: JsonField, - private val frameId: JsonField, - private val options: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("url") @ExcludeMissing url: JsonField = JsonMissing.of(), - @JsonProperty("frameId") @ExcludeMissing frameId: JsonField = JsonMissing.of(), - @JsonProperty("options") @ExcludeMissing options: JsonField = JsonMissing.of(), - ) : this(url, frameId, options, mutableMapOf()) - - /** - * URL to navigate to - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun url(): String = url.getRequired("url") - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun frameId(): Optional = frameId.getOptional("frameId") - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun options(): Optional = options.getOptional("options") - - /** - * Returns the raw JSON value of [url]. - * - * Unlike [url], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("url") @ExcludeMissing fun _url(): JsonField = url - - /** - * Returns the raw JSON value of [frameId]. - * - * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("frameId") @ExcludeMissing fun _frameId(): JsonField = frameId - - /** - * Returns the raw JSON value of [options]. - * - * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("options") @ExcludeMissing fun _options(): JsonField = options - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [Body]. - * - * The following fields are required: - * ```java - * .url() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Body]. */ - class Builder internal constructor() { - - private var url: JsonField? = null - private var frameId: JsonField = JsonMissing.of() - private var options: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(body: Body) = apply { - url = body.url - frameId = body.frameId - options = body.options - additionalProperties = body.additionalProperties.toMutableMap() - } - - /** URL to navigate to */ - fun url(url: String) = url(JsonField.of(url)) - - /** - * Sets [Builder.url] to an arbitrary JSON value. - * - * You should usually call [Builder.url] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun url(url: JsonField) = apply { this.url = url } - - fun frameId(frameId: String) = frameId(JsonField.of(frameId)) - - /** - * Sets [Builder.frameId] to an arbitrary JSON value. - * - * You should usually call [Builder.frameId] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun frameId(frameId: JsonField) = apply { this.frameId = frameId } - - fun options(options: Options) = options(JsonField.of(options)) - - /** - * Sets [Builder.options] to an arbitrary JSON value. - * - * You should usually call [Builder.options] with a well-typed [Options] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun options(options: JsonField) = apply { this.options = options } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Body]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .url() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): Body = - Body( - checkRequired("url", url), - frameId, - options, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Body = apply { - if (validated) { - return@apply - } - - url() - frameId() - options().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (if (url.asKnown().isPresent) 1 else 0) + - (if (frameId.asKnown().isPresent) 1 else 0) + - (options.asKnown().getOrNull()?.validity() ?: 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Body && - url == other.url && - frameId == other.frameId && - options == other.options && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(url, frameId, options, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Body{url=$url, frameId=$frameId, options=$options, additionalProperties=$additionalProperties}" - } - - class Options - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val waitUntil: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("waitUntil") - @ExcludeMissing - waitUntil: JsonField = JsonMissing.of() - ) : this(waitUntil, mutableMapOf()) - - /** - * When to consider navigation complete - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun waitUntil(): Optional = waitUntil.getOptional("waitUntil") - - /** - * Returns the raw JSON value of [waitUntil]. - * - * Unlike [waitUntil], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("waitUntil") - @ExcludeMissing - fun _waitUntil(): JsonField = waitUntil - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [Options]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Options]. */ - class Builder internal constructor() { - - private var waitUntil: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(options: Options) = apply { - waitUntil = options.waitUntil - additionalProperties = options.additionalProperties.toMutableMap() - } - - /** When to consider navigation complete */ - fun waitUntil(waitUntil: WaitUntil) = waitUntil(JsonField.of(waitUntil)) - - /** - * Sets [Builder.waitUntil] to an arbitrary JSON value. - * - * You should usually call [Builder.waitUntil] with a well-typed [WaitUntil] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun waitUntil(waitUntil: JsonField) = apply { this.waitUntil = waitUntil } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Options]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Options = Options(waitUntil, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): Options = apply { - if (validated) { - return@apply - } - - waitUntil().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = (waitUntil.asKnown().getOrNull()?.validity() ?: 0) - - /** When to consider navigation complete */ - class WaitUntil @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is - * on an older version than the API, then the API may respond with new members that the - * SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val LOAD = of("load") - - @JvmField val DOMCONTENTLOADED = of("domcontentloaded") - - @JvmField val NETWORKIDLE = of("networkidle") - - @JvmStatic fun of(value: String) = WaitUntil(JsonField.of(value)) - } - - /** An enum containing [WaitUntil]'s known values. */ - enum class Known { - LOAD, - DOMCONTENTLOADED, - NETWORKIDLE, - } - - /** - * An enum containing [WaitUntil]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [WaitUntil] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if - * the SDK is on an older version than the API, then the API may respond with new - * members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - LOAD, - DOMCONTENTLOADED, - NETWORKIDLE, - /** - * An enum member indicating that [WaitUntil] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you - * want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - LOAD -> Value.LOAD - DOMCONTENTLOADED -> Value.DOMCONTENTLOADED - NETWORKIDLE -> Value.NETWORKIDLE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and - * don't want to throw for the unknown case. - * - * @throws StagehandInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - LOAD -> Known.LOAD - DOMCONTENTLOADED -> Known.DOMCONTENTLOADED - NETWORKIDLE -> Known.NETWORKIDLE - else -> throw StagehandInvalidDataException("Unknown WaitUntil: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws StagehandInvalidDataException if this class instance's value does not have - * the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - StagehandInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): WaitUntil = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is WaitUntil && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Options && - waitUntil == other.waitUntil && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(waitUntil, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Options{waitUntil=$waitUntil, additionalProperties=$additionalProperties}" - } - - class XStreamResponse @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val TRUE = of("true") - - @JvmField val FALSE = of("false") - - @JvmStatic fun of(value: String) = XStreamResponse(JsonField.of(value)) - } - - /** An enum containing [XStreamResponse]'s known values. */ - enum class Known { - TRUE, - FALSE, - } - - /** - * An enum containing [XStreamResponse]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [XStreamResponse] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - TRUE, - FALSE, - /** - * An enum member indicating that [XStreamResponse] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - TRUE -> Value.TRUE - FALSE -> Value.FALSE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws StagehandInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - TRUE -> Known.TRUE - FALSE -> Known.FALSE - else -> throw StagehandInvalidDataException("Unknown XStreamResponse: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for debugging - * and generally doesn't throw. - * - * @throws StagehandInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - StagehandInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): XStreamResponse = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is XStreamResponse && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is SessionNavigateParams && - sessionId == other.sessionId && - xStreamResponse == other.xStreamResponse && - body == other.body && - additionalHeaders == other.additionalHeaders && - additionalQueryParams == other.additionalQueryParams - } - - override fun hashCode(): Int = - Objects.hash(sessionId, xStreamResponse, body, additionalHeaders, additionalQueryParams) - - override fun toString() = - "SessionNavigateParams{sessionId=$sessionId, xStreamResponse=$xStreamResponse, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" -} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponse.kt deleted file mode 100644 index 50422bd..0000000 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponse.kt +++ /dev/null @@ -1,216 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.ExcludeMissing -import com.browserbase.api.core.JsonField -import com.browserbase.api.core.JsonMissing -import com.browserbase.api.core.JsonValue -import com.browserbase.api.errors.StagehandInvalidDataException -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonCreator -import com.fasterxml.jackson.annotation.JsonProperty -import java.util.Collections -import java.util.Objects -import java.util.Optional - -/** Navigation response (may be null) */ -class SessionNavigateResponse -@JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor( - private val ok: JsonField, - private val status: JsonField, - private val url: JsonField, - private val additionalProperties: MutableMap, -) { - - @JsonCreator - private constructor( - @JsonProperty("ok") @ExcludeMissing ok: JsonField = JsonMissing.of(), - @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), - @JsonProperty("url") @ExcludeMissing url: JsonField = JsonMissing.of(), - ) : this(ok, status, url, mutableMapOf()) - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun ok(): Optional = ok.getOptional("ok") - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun status(): Optional = status.getOptional("status") - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun url(): Optional = url.getOptional("url") - - /** - * Returns the raw JSON value of [ok]. - * - * Unlike [ok], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("ok") @ExcludeMissing fun _ok(): JsonField = ok - - /** - * Returns the raw JSON value of [status]. - * - * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status - - /** - * Returns the raw JSON value of [url]. - * - * Unlike [url], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("url") @ExcludeMissing fun _url(): JsonField = url - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [SessionNavigateResponse]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [SessionNavigateResponse]. */ - class Builder internal constructor() { - - private var ok: JsonField = JsonMissing.of() - private var status: JsonField = JsonMissing.of() - private var url: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(sessionNavigateResponse: SessionNavigateResponse) = apply { - ok = sessionNavigateResponse.ok - status = sessionNavigateResponse.status - url = sessionNavigateResponse.url - additionalProperties = sessionNavigateResponse.additionalProperties.toMutableMap() - } - - fun ok(ok: Boolean) = ok(JsonField.of(ok)) - - /** - * Sets [Builder.ok] to an arbitrary JSON value. - * - * You should usually call [Builder.ok] with a well-typed [Boolean] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun ok(ok: JsonField) = apply { this.ok = ok } - - fun status(status: Long) = status(JsonField.of(status)) - - /** - * Sets [Builder.status] to an arbitrary JSON value. - * - * You should usually call [Builder.status] with a well-typed [Long] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun status(status: JsonField) = apply { this.status = status } - - fun url(url: String) = url(JsonField.of(url)) - - /** - * Sets [Builder.url] to an arbitrary JSON value. - * - * You should usually call [Builder.url] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun url(url: JsonField) = apply { this.url = url } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [SessionNavigateResponse]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): SessionNavigateResponse = - SessionNavigateResponse(ok, status, url, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): SessionNavigateResponse = apply { - if (validated) { - return@apply - } - - ok() - status() - url() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (if (ok.asKnown().isPresent) 1 else 0) + - (if (status.asKnown().isPresent) 1 else 0) + - (if (url.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is SessionNavigateResponse && - ok == other.ok && - status == other.status && - url == other.url && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(ok, status, url, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "SessionNavigateResponse{ok=$ok, status=$status, url=$url, additionalProperties=$additionalProperties}" -} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveParams.kt deleted file mode 100644 index 0d67973..0000000 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveParams.kt +++ /dev/null @@ -1,902 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.Enum -import com.browserbase.api.core.ExcludeMissing -import com.browserbase.api.core.JsonField -import com.browserbase.api.core.JsonMissing -import com.browserbase.api.core.JsonValue -import com.browserbase.api.core.Params -import com.browserbase.api.core.http.Headers -import com.browserbase.api.core.http.QueryParams -import com.browserbase.api.errors.StagehandInvalidDataException -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonCreator -import com.fasterxml.jackson.annotation.JsonProperty -import java.util.Collections -import java.util.Objects -import java.util.Optional -import kotlin.jvm.optionals.getOrNull - -/** - * Returns a list of candidate actions that can be performed on the page, optionally filtered by - * natural language instruction. - */ -class SessionObserveParams -private constructor( - private val sessionId: String?, - private val xStreamResponse: XStreamResponse?, - private val body: Body, - private val additionalHeaders: Headers, - private val additionalQueryParams: QueryParams, -) : Params { - - fun sessionId(): Optional = Optional.ofNullable(sessionId) - - fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) - - /** - * Frame ID to observe - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun frameId(): Optional = body.frameId() - - /** - * Natural language instruction to filter actions - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun instruction(): Optional = body.instruction() - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun options(): Optional = body.options() - - /** - * Returns the raw JSON value of [frameId]. - * - * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _frameId(): JsonField = body._frameId() - - /** - * Returns the raw JSON value of [instruction]. - * - * Unlike [instruction], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _instruction(): JsonField = body._instruction() - - /** - * Returns the raw JSON value of [options]. - * - * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _options(): JsonField = body._options() - - fun _additionalBodyProperties(): Map = body._additionalProperties() - - /** Additional headers to send with the request. */ - fun _additionalHeaders(): Headers = additionalHeaders - - /** Additional query param to send with the request. */ - fun _additionalQueryParams(): QueryParams = additionalQueryParams - - fun toBuilder() = Builder().from(this) - - companion object { - - @JvmStatic fun none(): SessionObserveParams = builder().build() - - /** Returns a mutable builder for constructing an instance of [SessionObserveParams]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [SessionObserveParams]. */ - class Builder internal constructor() { - - private var sessionId: String? = null - private var xStreamResponse: XStreamResponse? = null - private var body: Body.Builder = Body.builder() - private var additionalHeaders: Headers.Builder = Headers.builder() - private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() - - @JvmSynthetic - internal fun from(sessionObserveParams: SessionObserveParams) = apply { - sessionId = sessionObserveParams.sessionId - xStreamResponse = sessionObserveParams.xStreamResponse - body = sessionObserveParams.body.toBuilder() - additionalHeaders = sessionObserveParams.additionalHeaders.toBuilder() - additionalQueryParams = sessionObserveParams.additionalQueryParams.toBuilder() - } - - fun sessionId(sessionId: String?) = apply { this.sessionId = sessionId } - - /** Alias for calling [Builder.sessionId] with `sessionId.orElse(null)`. */ - fun sessionId(sessionId: Optional) = sessionId(sessionId.getOrNull()) - - fun xStreamResponse(xStreamResponse: XStreamResponse?) = apply { - this.xStreamResponse = xStreamResponse - } - - /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ - fun xStreamResponse(xStreamResponse: Optional) = - xStreamResponse(xStreamResponse.getOrNull()) - - /** - * Sets the entire request body. - * - * This is generally only useful if you are already constructing the body separately. - * Otherwise, it's more convenient to use the top-level setters instead: - * - [frameId] - * - [instruction] - * - [options] - */ - fun body(body: Body) = apply { this.body = body.toBuilder() } - - /** Frame ID to observe */ - fun frameId(frameId: String) = apply { body.frameId(frameId) } - - /** - * Sets [Builder.frameId] to an arbitrary JSON value. - * - * You should usually call [Builder.frameId] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun frameId(frameId: JsonField) = apply { body.frameId(frameId) } - - /** Natural language instruction to filter actions */ - fun instruction(instruction: String) = apply { body.instruction(instruction) } - - /** - * Sets [Builder.instruction] to an arbitrary JSON value. - * - * You should usually call [Builder.instruction] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun instruction(instruction: JsonField) = apply { body.instruction(instruction) } - - fun options(options: Options) = apply { body.options(options) } - - /** - * Sets [Builder.options] to an arbitrary JSON value. - * - * You should usually call [Builder.options] with a well-typed [Options] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun options(options: JsonField) = apply { body.options(options) } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - body.additionalProperties(additionalBodyProperties) - } - - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - body.putAdditionalProperty(key, value) - } - - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - body.putAllAdditionalProperties(additionalBodyProperties) - } - - fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - - fun removeAllAdditionalBodyProperties(keys: Set) = apply { - body.removeAllAdditionalProperties(keys) - } - - fun additionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.clear() - putAllAdditionalHeaders(additionalHeaders) - } - - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllAdditionalHeaders(additionalHeaders) - } - - fun putAdditionalHeader(name: String, value: String) = apply { - additionalHeaders.put(name, value) - } - - fun putAdditionalHeaders(name: String, values: Iterable) = apply { - additionalHeaders.put(name, values) - } - - fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.putAll(additionalHeaders) - } - - fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.putAll(additionalHeaders) - } - - fun replaceAdditionalHeaders(name: String, value: String) = apply { - additionalHeaders.replace(name, value) - } - - fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { - additionalHeaders.replace(name, values) - } - - fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.replaceAll(additionalHeaders) - } - - fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.replaceAll(additionalHeaders) - } - - fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - - fun removeAllAdditionalHeaders(names: Set) = apply { - additionalHeaders.removeAll(names) - } - - fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.clear() - putAllAdditionalQueryParams(additionalQueryParams) - } - - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllAdditionalQueryParams(additionalQueryParams) - } - - fun putAdditionalQueryParam(key: String, value: String) = apply { - additionalQueryParams.put(key, value) - } - - fun putAdditionalQueryParams(key: String, values: Iterable) = apply { - additionalQueryParams.put(key, values) - } - - fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.putAll(additionalQueryParams) - } - - fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = - apply { - this.additionalQueryParams.putAll(additionalQueryParams) - } - - fun replaceAdditionalQueryParams(key: String, value: String) = apply { - additionalQueryParams.replace(key, value) - } - - fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { - additionalQueryParams.replace(key, values) - } - - fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.replaceAll(additionalQueryParams) - } - - fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = - apply { - this.additionalQueryParams.replaceAll(additionalQueryParams) - } - - fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } - - fun removeAllAdditionalQueryParams(keys: Set) = apply { - additionalQueryParams.removeAll(keys) - } - - /** - * Returns an immutable instance of [SessionObserveParams]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): SessionObserveParams = - SessionObserveParams( - sessionId, - xStreamResponse, - body.build(), - additionalHeaders.build(), - additionalQueryParams.build(), - ) - } - - fun _body(): Body = body - - fun _pathParam(index: Int): String = - when (index) { - 0 -> sessionId ?: "" - else -> "" - } - - override fun _headers(): Headers = - Headers.builder() - .apply { - xStreamResponse?.let { put("x-stream-response", it.toString()) } - putAll(additionalHeaders) - } - .build() - - override fun _queryParams(): QueryParams = additionalQueryParams - - class Body - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val frameId: JsonField, - private val instruction: JsonField, - private val options: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("frameId") @ExcludeMissing frameId: JsonField = JsonMissing.of(), - @JsonProperty("instruction") - @ExcludeMissing - instruction: JsonField = JsonMissing.of(), - @JsonProperty("options") @ExcludeMissing options: JsonField = JsonMissing.of(), - ) : this(frameId, instruction, options, mutableMapOf()) - - /** - * Frame ID to observe - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun frameId(): Optional = frameId.getOptional("frameId") - - /** - * Natural language instruction to filter actions - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun instruction(): Optional = instruction.getOptional("instruction") - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun options(): Optional = options.getOptional("options") - - /** - * Returns the raw JSON value of [frameId]. - * - * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("frameId") @ExcludeMissing fun _frameId(): JsonField = frameId - - /** - * Returns the raw JSON value of [instruction]. - * - * Unlike [instruction], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("instruction") - @ExcludeMissing - fun _instruction(): JsonField = instruction - - /** - * Returns the raw JSON value of [options]. - * - * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("options") @ExcludeMissing fun _options(): JsonField = options - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [Body]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Body]. */ - class Builder internal constructor() { - - private var frameId: JsonField = JsonMissing.of() - private var instruction: JsonField = JsonMissing.of() - private var options: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(body: Body) = apply { - frameId = body.frameId - instruction = body.instruction - options = body.options - additionalProperties = body.additionalProperties.toMutableMap() - } - - /** Frame ID to observe */ - fun frameId(frameId: String) = frameId(JsonField.of(frameId)) - - /** - * Sets [Builder.frameId] to an arbitrary JSON value. - * - * You should usually call [Builder.frameId] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun frameId(frameId: JsonField) = apply { this.frameId = frameId } - - /** Natural language instruction to filter actions */ - fun instruction(instruction: String) = instruction(JsonField.of(instruction)) - - /** - * Sets [Builder.instruction] to an arbitrary JSON value. - * - * You should usually call [Builder.instruction] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun instruction(instruction: JsonField) = apply { - this.instruction = instruction - } - - fun options(options: Options) = options(JsonField.of(options)) - - /** - * Sets [Builder.options] to an arbitrary JSON value. - * - * You should usually call [Builder.options] with a well-typed [Options] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun options(options: JsonField) = apply { this.options = options } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Body]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Body = - Body(frameId, instruction, options, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): Body = apply { - if (validated) { - return@apply - } - - frameId() - instruction() - options().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (if (frameId.asKnown().isPresent) 1 else 0) + - (if (instruction.asKnown().isPresent) 1 else 0) + - (options.asKnown().getOrNull()?.validity() ?: 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Body && - frameId == other.frameId && - instruction == other.instruction && - options == other.options && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(frameId, instruction, options, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Body{frameId=$frameId, instruction=$instruction, options=$options, additionalProperties=$additionalProperties}" - } - - class Options - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val model: JsonField, - private val selector: JsonField, - private val timeout: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), - @JsonProperty("selector") - @ExcludeMissing - selector: JsonField = JsonMissing.of(), - @JsonProperty("timeout") @ExcludeMissing timeout: JsonField = JsonMissing.of(), - ) : this(model, selector, timeout, mutableMapOf()) - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun model(): Optional = model.getOptional("model") - - /** - * Observe only elements matching this selector - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun selector(): Optional = selector.getOptional("selector") - - /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun timeout(): Optional = timeout.getOptional("timeout") - - /** - * Returns the raw JSON value of [model]. - * - * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model - - /** - * Returns the raw JSON value of [selector]. - * - * Unlike [selector], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("selector") @ExcludeMissing fun _selector(): JsonField = selector - - /** - * Returns the raw JSON value of [timeout]. - * - * Unlike [timeout], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("timeout") @ExcludeMissing fun _timeout(): JsonField = timeout - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [Options]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Options]. */ - class Builder internal constructor() { - - private var model: JsonField = JsonMissing.of() - private var selector: JsonField = JsonMissing.of() - private var timeout: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(options: Options) = apply { - model = options.model - selector = options.selector - timeout = options.timeout - additionalProperties = options.additionalProperties.toMutableMap() - } - - fun model(model: ModelConfig) = model(JsonField.of(model)) - - /** - * Sets [Builder.model] to an arbitrary JSON value. - * - * You should usually call [Builder.model] with a well-typed [ModelConfig] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun model(model: JsonField) = apply { this.model = model } - - /** Observe only elements matching this selector */ - fun selector(selector: String) = selector(JsonField.of(selector)) - - /** - * Sets [Builder.selector] to an arbitrary JSON value. - * - * You should usually call [Builder.selector] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun selector(selector: JsonField) = apply { this.selector = selector } - - fun timeout(timeout: Long) = timeout(JsonField.of(timeout)) - - /** - * Sets [Builder.timeout] to an arbitrary JSON value. - * - * You should usually call [Builder.timeout] with a well-typed [Long] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun timeout(timeout: JsonField) = apply { this.timeout = timeout } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Options]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): Options = - Options(model, selector, timeout, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): Options = apply { - if (validated) { - return@apply - } - - model().ifPresent { it.validate() } - selector() - timeout() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (model.asKnown().getOrNull()?.validity() ?: 0) + - (if (selector.asKnown().isPresent) 1 else 0) + - (if (timeout.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Options && - model == other.model && - selector == other.selector && - timeout == other.timeout && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(model, selector, timeout, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Options{model=$model, selector=$selector, timeout=$timeout, additionalProperties=$additionalProperties}" - } - - class XStreamResponse @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val TRUE = of("true") - - @JvmField val FALSE = of("false") - - @JvmStatic fun of(value: String) = XStreamResponse(JsonField.of(value)) - } - - /** An enum containing [XStreamResponse]'s known values. */ - enum class Known { - TRUE, - FALSE, - } - - /** - * An enum containing [XStreamResponse]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [XStreamResponse] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - TRUE, - FALSE, - /** - * An enum member indicating that [XStreamResponse] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - TRUE -> Value.TRUE - FALSE -> Value.FALSE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws StagehandInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - TRUE -> Known.TRUE - FALSE -> Known.FALSE - else -> throw StagehandInvalidDataException("Unknown XStreamResponse: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for debugging - * and generally doesn't throw. - * - * @throws StagehandInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - StagehandInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): XStreamResponse = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is XStreamResponse && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is SessionObserveParams && - sessionId == other.sessionId && - xStreamResponse == other.xStreamResponse && - body == other.body && - additionalHeaders == other.additionalHeaders && - additionalQueryParams == other.additionalQueryParams - } - - override fun hashCode(): Int = - Objects.hash(sessionId, xStreamResponse, body, additionalHeaders, additionalQueryParams) - - override fun toString() = - "SessionObserveParams{sessionId=$sessionId, xStreamResponse=$xStreamResponse, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" -} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt index cda3e99..e0c55aa 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt @@ -2,143 +2,39 @@ package com.browserbase.api.models.sessions -import com.browserbase.api.core.ExcludeMissing -import com.browserbase.api.core.JsonField import com.browserbase.api.core.JsonMissing import com.browserbase.api.core.JsonValue import com.browserbase.api.core.Params -import com.browserbase.api.core.checkRequired import com.browserbase.api.core.http.Headers import com.browserbase.api.core.http.QueryParams -import com.browserbase.api.errors.StagehandInvalidDataException -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonCreator -import com.fasterxml.jackson.annotation.JsonProperty -import java.util.Collections import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** - * Initializes a new Stagehand session with a browser instance. Returns a session ID that must be - * used for all subsequent requests. + * Creates a new browser session with the specified configuration. Returns a session ID used for all + * subsequent operations. */ class SessionStartParams private constructor( - private val body: Body, + private val xLanguage: JsonValue?, + private val xSdkVersion: JsonValue?, + private val xSentAt: JsonValue?, + private val xStreamResponse: JsonValue?, + private val body: JsonValue, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - /** - * API key for Browserbase Cloud - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun browserbaseApiKey(): String = body.browserbaseApiKey() - - /** - * Project ID for Browserbase - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun browserbaseProjectId(): String = body.browserbaseProjectId() - - /** - * Timeout in ms to wait for DOM to settle - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun domSettleTimeout(): Optional = body.domSettleTimeout() - - /** - * AI model to use for actions (must be prefixed with provider/) - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun model(): Optional = body.model() - - /** - * Enable self-healing for failed actions - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun selfHeal(): Optional = body.selfHeal() - - /** - * Custom system prompt for AI actions - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun systemPrompt(): Optional = body.systemPrompt() - - /** - * Logging verbosity level - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun verbose(): Optional = body.verbose() - - /** - * Returns the raw JSON value of [browserbaseApiKey]. - * - * Unlike [browserbaseApiKey], this method doesn't throw if the JSON field has an unexpected - * type. - */ - fun _browserbaseApiKey(): JsonField = body._browserbaseApiKey() - - /** - * Returns the raw JSON value of [browserbaseProjectId]. - * - * Unlike [browserbaseProjectId], this method doesn't throw if the JSON field has an unexpected - * type. - */ - fun _browserbaseProjectId(): JsonField = body._browserbaseProjectId() - - /** - * Returns the raw JSON value of [domSettleTimeout]. - * - * Unlike [domSettleTimeout], this method doesn't throw if the JSON field has an unexpected - * type. - */ - fun _domSettleTimeout(): JsonField = body._domSettleTimeout() - - /** - * Returns the raw JSON value of [model]. - * - * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _model(): JsonField = body._model() - - /** - * Returns the raw JSON value of [selfHeal]. - * - * Unlike [selfHeal], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _selfHeal(): JsonField = body._selfHeal() - - /** - * Returns the raw JSON value of [systemPrompt]. - * - * Unlike [systemPrompt], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _systemPrompt(): JsonField = body._systemPrompt() - - /** - * Returns the raw JSON value of [verbose]. - * - * Unlike [verbose], this method doesn't throw if the JSON field has an unexpected type. - */ - fun _verbose(): JsonField = body._verbose() - - fun _additionalBodyProperties(): Map = body._additionalProperties() + fun xLanguage(): Optional = Optional.ofNullable(xLanguage) + + fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) + + fun xSentAt(): Optional = Optional.ofNullable(xSentAt) + + fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) + + fun body(): JsonValue = body /** Additional headers to send with the request. */ fun _additionalHeaders(): Headers = additionalHeaders @@ -150,160 +46,58 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [SessionStartParams]. - * - * The following fields are required: - * ```java - * .browserbaseApiKey() - * .browserbaseProjectId() - * ``` - */ + @JvmStatic fun none(): SessionStartParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [SessionStartParams]. */ @JvmStatic fun builder() = Builder() } /** A builder for [SessionStartParams]. */ class Builder internal constructor() { - private var body: Body.Builder = Body.builder() + private var xLanguage: JsonValue? = null + private var xSdkVersion: JsonValue? = null + private var xSentAt: JsonValue? = null + private var xStreamResponse: JsonValue? = null + private var body: JsonValue = JsonMissing.of() private var additionalHeaders: Headers.Builder = Headers.builder() private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(sessionStartParams: SessionStartParams) = apply { - body = sessionStartParams.body.toBuilder() + xLanguage = sessionStartParams.xLanguage + xSdkVersion = sessionStartParams.xSdkVersion + xSentAt = sessionStartParams.xSentAt + xStreamResponse = sessionStartParams.xStreamResponse + body = sessionStartParams.body additionalHeaders = sessionStartParams.additionalHeaders.toBuilder() additionalQueryParams = sessionStartParams.additionalQueryParams.toBuilder() } - /** - * Sets the entire request body. - * - * This is generally only useful if you are already constructing the body separately. - * Otherwise, it's more convenient to use the top-level setters instead: - * - [browserbaseApiKey] - * - [browserbaseProjectId] - * - [domSettleTimeout] - * - [model] - * - [selfHeal] - * - etc. - */ - fun body(body: Body) = apply { this.body = body.toBuilder() } + fun xLanguage(xLanguage: JsonValue?) = apply { this.xLanguage = xLanguage } - /** API key for Browserbase Cloud */ - fun browserbaseApiKey(browserbaseApiKey: String) = apply { - body.browserbaseApiKey(browserbaseApiKey) - } + /** Alias for calling [Builder.xLanguage] with `xLanguage.orElse(null)`. */ + fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) - /** - * Sets [Builder.browserbaseApiKey] to an arbitrary JSON value. - * - * You should usually call [Builder.browserbaseApiKey] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun browserbaseApiKey(browserbaseApiKey: JsonField) = apply { - body.browserbaseApiKey(browserbaseApiKey) - } + fun xSdkVersion(xSdkVersion: JsonValue?) = apply { this.xSdkVersion = xSdkVersion } - /** Project ID for Browserbase */ - fun browserbaseProjectId(browserbaseProjectId: String) = apply { - body.browserbaseProjectId(browserbaseProjectId) - } + /** Alias for calling [Builder.xSdkVersion] with `xSdkVersion.orElse(null)`. */ + fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) - /** - * Sets [Builder.browserbaseProjectId] to an arbitrary JSON value. - * - * You should usually call [Builder.browserbaseProjectId] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun browserbaseProjectId(browserbaseProjectId: JsonField) = apply { - body.browserbaseProjectId(browserbaseProjectId) - } + fun xSentAt(xSentAt: JsonValue?) = apply { this.xSentAt = xSentAt } - /** Timeout in ms to wait for DOM to settle */ - fun domSettleTimeout(domSettleTimeout: Long) = apply { - body.domSettleTimeout(domSettleTimeout) - } + /** Alias for calling [Builder.xSentAt] with `xSentAt.orElse(null)`. */ + fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) - /** - * Sets [Builder.domSettleTimeout] to an arbitrary JSON value. - * - * You should usually call [Builder.domSettleTimeout] with a well-typed [Long] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun domSettleTimeout(domSettleTimeout: JsonField) = apply { - body.domSettleTimeout(domSettleTimeout) + fun xStreamResponse(xStreamResponse: JsonValue?) = apply { + this.xStreamResponse = xStreamResponse } - /** AI model to use for actions (must be prefixed with provider/) */ - fun model(model: String) = apply { body.model(model) } - - /** - * Sets [Builder.model] to an arbitrary JSON value. - * - * You should usually call [Builder.model] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun model(model: JsonField) = apply { body.model(model) } - - /** Enable self-healing for failed actions */ - fun selfHeal(selfHeal: Boolean) = apply { body.selfHeal(selfHeal) } - - /** - * Sets [Builder.selfHeal] to an arbitrary JSON value. - * - * You should usually call [Builder.selfHeal] with a well-typed [Boolean] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun selfHeal(selfHeal: JsonField) = apply { body.selfHeal(selfHeal) } - - /** Custom system prompt for AI actions */ - fun systemPrompt(systemPrompt: String) = apply { body.systemPrompt(systemPrompt) } - - /** - * Sets [Builder.systemPrompt] to an arbitrary JSON value. - * - * You should usually call [Builder.systemPrompt] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun systemPrompt(systemPrompt: JsonField) = apply { - body.systemPrompt(systemPrompt) - } + /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ + fun xStreamResponse(xStreamResponse: Optional) = + xStreamResponse(xStreamResponse.getOrNull()) - /** Logging verbosity level */ - fun verbose(verbose: Long) = apply { body.verbose(verbose) } - - /** - * Sets [Builder.verbose] to an arbitrary JSON value. - * - * You should usually call [Builder.verbose] with a well-typed [Long] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. - */ - fun verbose(verbose: JsonField) = apply { body.verbose(verbose) } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - body.additionalProperties(additionalBodyProperties) - } - - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - body.putAdditionalProperty(key, value) - } - - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - body.putAllAdditionalProperties(additionalBodyProperties) - } - - fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - - fun removeAllAdditionalBodyProperties(keys: Set) = apply { - body.removeAllAdditionalProperties(keys) - } + fun body(body: JsonValue) = apply { this.body = body } fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -407,469 +201,51 @@ private constructor( * Returns an immutable instance of [SessionStartParams]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .browserbaseApiKey() - * .browserbaseProjectId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): SessionStartParams = SessionStartParams( - body.build(), + xLanguage, + xSdkVersion, + xSentAt, + xStreamResponse, + body, additionalHeaders.build(), additionalQueryParams.build(), ) } - fun _body(): Body = body + fun _body(): JsonValue = body - override fun _headers(): Headers = additionalHeaders + override fun _headers(): Headers = Headers.builder().apply { putAll(additionalHeaders) }.build() override fun _queryParams(): QueryParams = additionalQueryParams - class Body - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val browserbaseApiKey: JsonField, - private val browserbaseProjectId: JsonField, - private val domSettleTimeout: JsonField, - private val model: JsonField, - private val selfHeal: JsonField, - private val systemPrompt: JsonField, - private val verbose: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("BROWSERBASE_API_KEY") - @ExcludeMissing - browserbaseApiKey: JsonField = JsonMissing.of(), - @JsonProperty("BROWSERBASE_PROJECT_ID") - @ExcludeMissing - browserbaseProjectId: JsonField = JsonMissing.of(), - @JsonProperty("domSettleTimeout") - @ExcludeMissing - domSettleTimeout: JsonField = JsonMissing.of(), - @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), - @JsonProperty("selfHeal") - @ExcludeMissing - selfHeal: JsonField = JsonMissing.of(), - @JsonProperty("systemPrompt") - @ExcludeMissing - systemPrompt: JsonField = JsonMissing.of(), - @JsonProperty("verbose") @ExcludeMissing verbose: JsonField = JsonMissing.of(), - ) : this( - browserbaseApiKey, - browserbaseProjectId, - domSettleTimeout, - model, - selfHeal, - systemPrompt, - verbose, - mutableMapOf(), - ) - - /** - * API key for Browserbase Cloud - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun browserbaseApiKey(): String = browserbaseApiKey.getRequired("BROWSERBASE_API_KEY") - - /** - * Project ID for Browserbase - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun browserbaseProjectId(): String = - browserbaseProjectId.getRequired("BROWSERBASE_PROJECT_ID") - - /** - * Timeout in ms to wait for DOM to settle - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun domSettleTimeout(): Optional = domSettleTimeout.getOptional("domSettleTimeout") - - /** - * AI model to use for actions (must be prefixed with provider/) - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun model(): Optional = model.getOptional("model") - - /** - * Enable self-healing for failed actions - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun selfHeal(): Optional = selfHeal.getOptional("selfHeal") - - /** - * Custom system prompt for AI actions - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun systemPrompt(): Optional = systemPrompt.getOptional("systemPrompt") - - /** - * Logging verbosity level - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun verbose(): Optional = verbose.getOptional("verbose") - - /** - * Returns the raw JSON value of [browserbaseApiKey]. - * - * Unlike [browserbaseApiKey], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("BROWSERBASE_API_KEY") - @ExcludeMissing - fun _browserbaseApiKey(): JsonField = browserbaseApiKey - - /** - * Returns the raw JSON value of [browserbaseProjectId]. - * - * Unlike [browserbaseProjectId], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("BROWSERBASE_PROJECT_ID") - @ExcludeMissing - fun _browserbaseProjectId(): JsonField = browserbaseProjectId - - /** - * Returns the raw JSON value of [domSettleTimeout]. - * - * Unlike [domSettleTimeout], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("domSettleTimeout") - @ExcludeMissing - fun _domSettleTimeout(): JsonField = domSettleTimeout - - /** - * Returns the raw JSON value of [model]. - * - * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model - - /** - * Returns the raw JSON value of [selfHeal]. - * - * Unlike [selfHeal], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("selfHeal") @ExcludeMissing fun _selfHeal(): JsonField = selfHeal - - /** - * Returns the raw JSON value of [systemPrompt]. - * - * Unlike [systemPrompt], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("systemPrompt") - @ExcludeMissing - fun _systemPrompt(): JsonField = systemPrompt - - /** - * Returns the raw JSON value of [verbose]. - * - * Unlike [verbose], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("verbose") @ExcludeMissing fun _verbose(): JsonField = verbose - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [Body]. - * - * The following fields are required: - * ```java - * .browserbaseApiKey() - * .browserbaseProjectId() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Body]. */ - class Builder internal constructor() { - - private var browserbaseApiKey: JsonField? = null - private var browserbaseProjectId: JsonField? = null - private var domSettleTimeout: JsonField = JsonMissing.of() - private var model: JsonField = JsonMissing.of() - private var selfHeal: JsonField = JsonMissing.of() - private var systemPrompt: JsonField = JsonMissing.of() - private var verbose: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(body: Body) = apply { - browserbaseApiKey = body.browserbaseApiKey - browserbaseProjectId = body.browserbaseProjectId - domSettleTimeout = body.domSettleTimeout - model = body.model - selfHeal = body.selfHeal - systemPrompt = body.systemPrompt - verbose = body.verbose - additionalProperties = body.additionalProperties.toMutableMap() - } - - /** API key for Browserbase Cloud */ - fun browserbaseApiKey(browserbaseApiKey: String) = - browserbaseApiKey(JsonField.of(browserbaseApiKey)) - - /** - * Sets [Builder.browserbaseApiKey] to an arbitrary JSON value. - * - * You should usually call [Builder.browserbaseApiKey] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun browserbaseApiKey(browserbaseApiKey: JsonField) = apply { - this.browserbaseApiKey = browserbaseApiKey - } - - /** Project ID for Browserbase */ - fun browserbaseProjectId(browserbaseProjectId: String) = - browserbaseProjectId(JsonField.of(browserbaseProjectId)) - - /** - * Sets [Builder.browserbaseProjectId] to an arbitrary JSON value. - * - * You should usually call [Builder.browserbaseProjectId] with a well-typed [String] - * value instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun browserbaseProjectId(browserbaseProjectId: JsonField) = apply { - this.browserbaseProjectId = browserbaseProjectId - } - - /** Timeout in ms to wait for DOM to settle */ - fun domSettleTimeout(domSettleTimeout: Long) = - domSettleTimeout(JsonField.of(domSettleTimeout)) - - /** - * Sets [Builder.domSettleTimeout] to an arbitrary JSON value. - * - * You should usually call [Builder.domSettleTimeout] with a well-typed [Long] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun domSettleTimeout(domSettleTimeout: JsonField) = apply { - this.domSettleTimeout = domSettleTimeout - } - - /** AI model to use for actions (must be prefixed with provider/) */ - fun model(model: String) = model(JsonField.of(model)) - - /** - * Sets [Builder.model] to an arbitrary JSON value. - * - * You should usually call [Builder.model] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun model(model: JsonField) = apply { this.model = model } - - /** Enable self-healing for failed actions */ - fun selfHeal(selfHeal: Boolean) = selfHeal(JsonField.of(selfHeal)) - - /** - * Sets [Builder.selfHeal] to an arbitrary JSON value. - * - * You should usually call [Builder.selfHeal] with a well-typed [Boolean] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun selfHeal(selfHeal: JsonField) = apply { this.selfHeal = selfHeal } - - /** Custom system prompt for AI actions */ - fun systemPrompt(systemPrompt: String) = systemPrompt(JsonField.of(systemPrompt)) - - /** - * Sets [Builder.systemPrompt] to an arbitrary JSON value. - * - * You should usually call [Builder.systemPrompt] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun systemPrompt(systemPrompt: JsonField) = apply { - this.systemPrompt = systemPrompt - } - - /** Logging verbosity level */ - fun verbose(verbose: Long) = verbose(JsonField.of(verbose)) - - /** - * Sets [Builder.verbose] to an arbitrary JSON value. - * - * You should usually call [Builder.verbose] with a well-typed [Long] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun verbose(verbose: JsonField) = apply { this.verbose = verbose } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Body]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .browserbaseApiKey() - * .browserbaseProjectId() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): Body = - Body( - checkRequired("browserbaseApiKey", browserbaseApiKey), - checkRequired("browserbaseProjectId", browserbaseProjectId), - domSettleTimeout, - model, - selfHeal, - systemPrompt, - verbose, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): Body = apply { - if (validated) { - return@apply - } - - browserbaseApiKey() - browserbaseProjectId() - domSettleTimeout() - model() - selfHeal() - systemPrompt() - verbose() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (if (browserbaseApiKey.asKnown().isPresent) 1 else 0) + - (if (browserbaseProjectId.asKnown().isPresent) 1 else 0) + - (if (domSettleTimeout.asKnown().isPresent) 1 else 0) + - (if (model.asKnown().isPresent) 1 else 0) + - (if (selfHeal.asKnown().isPresent) 1 else 0) + - (if (systemPrompt.asKnown().isPresent) 1 else 0) + - (if (verbose.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Body && - browserbaseApiKey == other.browserbaseApiKey && - browserbaseProjectId == other.browserbaseProjectId && - domSettleTimeout == other.domSettleTimeout && - model == other.model && - selfHeal == other.selfHeal && - systemPrompt == other.systemPrompt && - verbose == other.verbose && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash( - browserbaseApiKey, - browserbaseProjectId, - domSettleTimeout, - model, - selfHeal, - systemPrompt, - verbose, - additionalProperties, - ) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Body{browserbaseApiKey=$browserbaseApiKey, browserbaseProjectId=$browserbaseProjectId, domSettleTimeout=$domSettleTimeout, model=$model, selfHeal=$selfHeal, systemPrompt=$systemPrompt, verbose=$verbose, additionalProperties=$additionalProperties}" - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } return other is SessionStartParams && + xLanguage == other.xLanguage && + xSdkVersion == other.xSdkVersion && + xSentAt == other.xSentAt && + xStreamResponse == other.xStreamResponse && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams } - override fun hashCode(): Int = Objects.hash(body, additionalHeaders, additionalQueryParams) + override fun hashCode(): Int = + Objects.hash( + xLanguage, + xSdkVersion, + xSentAt, + xStreamResponse, + body, + additionalHeaders, + additionalQueryParams, + ) override fun toString() = - "SessionStartParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" + "SessionStartParams{xLanguage=$xLanguage, xSdkVersion=$xSdkVersion, xSentAt=$xSentAt, xStreamResponse=$xStreamResponse, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartResponse.kt index 2e71372..b63f41e 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartResponse.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartResponse.kt @@ -3,61 +3,19 @@ package com.browserbase.api.models.sessions import com.browserbase.api.core.ExcludeMissing -import com.browserbase.api.core.JsonField -import com.browserbase.api.core.JsonMissing import com.browserbase.api.core.JsonValue -import com.browserbase.api.core.checkRequired import com.browserbase.api.errors.StagehandInvalidDataException import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter import com.fasterxml.jackson.annotation.JsonCreator -import com.fasterxml.jackson.annotation.JsonProperty import java.util.Collections import java.util.Objects class SessionStartResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor( - private val available: JsonField, - private val sessionId: JsonField, - private val additionalProperties: MutableMap, -) { - - @JsonCreator - private constructor( - @JsonProperty("available") @ExcludeMissing available: JsonField = JsonMissing.of(), - @JsonProperty("sessionId") @ExcludeMissing sessionId: JsonField = JsonMissing.of(), - ) : this(available, sessionId, mutableMapOf()) +private constructor(private val additionalProperties: MutableMap) { - /** - * Whether the session is ready to use - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun available(): Boolean = available.getRequired("available") - - /** - * Unique identifier for the session - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun sessionId(): String = sessionId.getRequired("sessionId") - - /** - * Returns the raw JSON value of [available]. - * - * Unlike [available], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("available") @ExcludeMissing fun _available(): JsonField = available - - /** - * Returns the raw JSON value of [sessionId]. - * - * Unlike [sessionId], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("sessionId") @ExcludeMissing fun _sessionId(): JsonField = sessionId + @JsonCreator private constructor() : this(mutableMapOf()) @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -73,56 +31,20 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [SessionStartResponse]. - * - * The following fields are required: - * ```java - * .available() - * .sessionId() - * ``` - */ + /** Returns a mutable builder for constructing an instance of [SessionStartResponse]. */ @JvmStatic fun builder() = Builder() } /** A builder for [SessionStartResponse]. */ class Builder internal constructor() { - private var available: JsonField? = null - private var sessionId: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(sessionStartResponse: SessionStartResponse) = apply { - available = sessionStartResponse.available - sessionId = sessionStartResponse.sessionId additionalProperties = sessionStartResponse.additionalProperties.toMutableMap() } - /** Whether the session is ready to use */ - fun available(available: Boolean) = available(JsonField.of(available)) - - /** - * Sets [Builder.available] to an arbitrary JSON value. - * - * You should usually call [Builder.available] with a well-typed [Boolean] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun available(available: JsonField) = apply { this.available = available } - - /** Unique identifier for the session */ - fun sessionId(sessionId: String) = sessionId(JsonField.of(sessionId)) - - /** - * Sets [Builder.sessionId] to an arbitrary JSON value. - * - * You should usually call [Builder.sessionId] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun sessionId(sessionId: JsonField) = apply { this.sessionId = sessionId } - fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -146,21 +68,9 @@ private constructor( * Returns an immutable instance of [SessionStartResponse]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .available() - * .sessionId() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): SessionStartResponse = - SessionStartResponse( - checkRequired("available", available), - checkRequired("sessionId", sessionId), - additionalProperties.toMutableMap(), - ) + SessionStartResponse(additionalProperties.toMutableMap()) } private var validated: Boolean = false @@ -170,8 +80,6 @@ private constructor( return@apply } - available() - sessionId() validated = true } @@ -188,26 +96,19 @@ private constructor( * * Used for best match union deserialization. */ - @JvmSynthetic - internal fun validity(): Int = - (if (available.asKnown().isPresent) 1 else 0) + - (if (sessionId.asKnown().isPresent) 1 else 0) + @JvmSynthetic internal fun validity(): Int = 0 override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is SessionStartResponse && - available == other.available && - sessionId == other.sessionId && - additionalProperties == other.additionalProperties + return other is SessionStartResponse && additionalProperties == other.additionalProperties } - private val hashCode: Int by lazy { Objects.hash(available, sessionId, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } override fun hashCode(): Int = hashCode - override fun toString() = - "SessionStartResponse{available=$available, sessionId=$sessionId, additionalProperties=$additionalProperties}" + override fun toString() = "SessionStartResponse{additionalProperties=$additionalProperties}" } diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsync.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsync.kt index 5c78924..d481fec 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsync.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsync.kt @@ -5,21 +5,8 @@ package com.browserbase.api.services.async import com.browserbase.api.core.ClientOptions import com.browserbase.api.core.RequestOptions import com.browserbase.api.core.http.HttpResponseFor -import com.browserbase.api.models.sessions.Action -import com.browserbase.api.models.sessions.SessionActParams -import com.browserbase.api.models.sessions.SessionActResponse -import com.browserbase.api.models.sessions.SessionEndParams -import com.browserbase.api.models.sessions.SessionEndResponse -import com.browserbase.api.models.sessions.SessionExecuteAgentParams -import com.browserbase.api.models.sessions.SessionExecuteAgentResponse -import com.browserbase.api.models.sessions.SessionExtractParams -import com.browserbase.api.models.sessions.SessionExtractResponse -import com.browserbase.api.models.sessions.SessionNavigateParams -import com.browserbase.api.models.sessions.SessionNavigateResponse -import com.browserbase.api.models.sessions.SessionObserveParams import com.browserbase.api.models.sessions.SessionStartParams import com.browserbase.api.models.sessions.SessionStartResponse -import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.function.Consumer @@ -38,207 +25,26 @@ interface SessionServiceAsync { fun withOptions(modifier: Consumer): SessionServiceAsync /** - * Performs a browser action based on natural language instruction or a specific action object - * returned by observe(). + * Creates a new browser session with the specified configuration. Returns a session ID used for + * all subsequent operations. */ - fun act(sessionId: String, params: SessionActParams): CompletableFuture = - act(sessionId, params, RequestOptions.none()) - - /** @see act */ - fun act( - sessionId: String, - params: SessionActParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture = - act(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see act */ - fun act(params: SessionActParams): CompletableFuture = - act(params, RequestOptions.none()) - - /** @see act */ - fun act( - params: SessionActParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture - - /** Closes the browser and cleans up all resources associated with the session. */ - fun end(sessionId: String): CompletableFuture = - end(sessionId, SessionEndParams.none()) - - /** @see end */ - fun end( - sessionId: String, - params: SessionEndParams = SessionEndParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture = - end(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see end */ - fun end( - sessionId: String, - params: SessionEndParams = SessionEndParams.none(), - ): CompletableFuture = end(sessionId, params, RequestOptions.none()) - - /** @see end */ - fun end( - params: SessionEndParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture - - /** @see end */ - fun end(params: SessionEndParams): CompletableFuture = - end(params, RequestOptions.none()) - - /** @see end */ - fun end( - sessionId: String, - requestOptions: RequestOptions, - ): CompletableFuture = - end(sessionId, SessionEndParams.none(), requestOptions) - - /** Runs an autonomous agent that can perform multiple actions to complete a complex task. */ - fun executeAgent( - sessionId: String, - params: SessionExecuteAgentParams, - ): CompletableFuture = - executeAgent(sessionId, params, RequestOptions.none()) - - /** @see executeAgent */ - fun executeAgent( - sessionId: String, - params: SessionExecuteAgentParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture = - executeAgent(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see executeAgent */ - fun executeAgent( - params: SessionExecuteAgentParams - ): CompletableFuture = executeAgent(params, RequestOptions.none()) - - /** @see executeAgent */ - fun executeAgent( - params: SessionExecuteAgentParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture - - /** - * Extracts data from the current page using natural language instructions and optional JSON - * schema for structured output. - */ - fun extract(sessionId: String): CompletableFuture = - extract(sessionId, SessionExtractParams.none()) - - /** @see extract */ - fun extract( - sessionId: String, - params: SessionExtractParams = SessionExtractParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture = - extract(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see extract */ - fun extract( - sessionId: String, - params: SessionExtractParams = SessionExtractParams.none(), - ): CompletableFuture = extract(sessionId, params, RequestOptions.none()) - - /** @see extract */ - fun extract( - params: SessionExtractParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture - - /** @see extract */ - fun extract(params: SessionExtractParams): CompletableFuture = - extract(params, RequestOptions.none()) - - /** @see extract */ - fun extract( - sessionId: String, - requestOptions: RequestOptions, - ): CompletableFuture = - extract(sessionId, SessionExtractParams.none(), requestOptions) - - /** Navigates the browser to the specified URL and waits for page load. */ - fun navigate( - sessionId: String, - params: SessionNavigateParams, - ): CompletableFuture> = - navigate(sessionId, params, RequestOptions.none()) - - /** @see navigate */ - fun navigate( - sessionId: String, - params: SessionNavigateParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> = - navigate(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see navigate */ - fun navigate( - params: SessionNavigateParams - ): CompletableFuture> = - navigate(params, RequestOptions.none()) - - /** @see navigate */ - fun navigate( - params: SessionNavigateParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> - - /** - * Returns a list of candidate actions that can be performed on the page, optionally filtered by - * natural language instruction. - */ - fun observe(sessionId: String): CompletableFuture> = - observe(sessionId, SessionObserveParams.none()) - - /** @see observe */ - fun observe( - sessionId: String, - params: SessionObserveParams = SessionObserveParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> = - observe(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see observe */ - fun observe( - sessionId: String, - params: SessionObserveParams = SessionObserveParams.none(), - ): CompletableFuture> = observe(sessionId, params, RequestOptions.none()) - - /** @see observe */ - fun observe( - params: SessionObserveParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> - - /** @see observe */ - fun observe(params: SessionObserveParams): CompletableFuture> = - observe(params, RequestOptions.none()) - - /** @see observe */ - fun observe( - sessionId: String, - requestOptions: RequestOptions, - ): CompletableFuture> = - observe(sessionId, SessionObserveParams.none(), requestOptions) - - /** - * Initializes a new Stagehand session with a browser instance. Returns a session ID that must - * be used for all subsequent requests. - */ - fun start(params: SessionStartParams): CompletableFuture = - start(params, RequestOptions.none()) + fun start(): CompletableFuture = start(SessionStartParams.none()) /** @see start */ fun start( - params: SessionStartParams, + params: SessionStartParams = SessionStartParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see start */ + fun start( + params: SessionStartParams = SessionStartParams.none() + ): CompletableFuture = start(params, RequestOptions.none()) + + /** @see start */ + fun start(requestOptions: RequestOptions): CompletableFuture = + start(SessionStartParams.none(), requestOptions) + /** * A view of [SessionServiceAsync] that provides access to raw HTTP responses for each method. */ @@ -254,226 +60,28 @@ interface SessionServiceAsync { ): SessionServiceAsync.WithRawResponse /** - * Returns a raw HTTP response for `post /sessions/{sessionId}/act`, but is otherwise the - * same as [SessionServiceAsync.act]. - */ - fun act( - sessionId: String, - params: SessionActParams, - ): CompletableFuture> = - act(sessionId, params, RequestOptions.none()) - - /** @see act */ - fun act( - sessionId: String, - params: SessionActParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> = - act(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see act */ - fun act(params: SessionActParams): CompletableFuture> = - act(params, RequestOptions.none()) - - /** @see act */ - fun act( - params: SessionActParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> - - /** - * Returns a raw HTTP response for `post /sessions/{sessionId}/end`, but is otherwise the - * same as [SessionServiceAsync.end]. - */ - fun end(sessionId: String): CompletableFuture> = - end(sessionId, SessionEndParams.none()) - - /** @see end */ - fun end( - sessionId: String, - params: SessionEndParams = SessionEndParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> = - end(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see end */ - fun end( - sessionId: String, - params: SessionEndParams = SessionEndParams.none(), - ): CompletableFuture> = - end(sessionId, params, RequestOptions.none()) - - /** @see end */ - fun end( - params: SessionEndParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> - - /** @see end */ - fun end(params: SessionEndParams): CompletableFuture> = - end(params, RequestOptions.none()) - - /** @see end */ - fun end( - sessionId: String, - requestOptions: RequestOptions, - ): CompletableFuture> = - end(sessionId, SessionEndParams.none(), requestOptions) - - /** - * Returns a raw HTTP response for `post /sessions/{sessionId}/agentExecute`, but is - * otherwise the same as [SessionServiceAsync.executeAgent]. - */ - fun executeAgent( - sessionId: String, - params: SessionExecuteAgentParams, - ): CompletableFuture> = - executeAgent(sessionId, params, RequestOptions.none()) - - /** @see executeAgent */ - fun executeAgent( - sessionId: String, - params: SessionExecuteAgentParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> = - executeAgent(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see executeAgent */ - fun executeAgent( - params: SessionExecuteAgentParams - ): CompletableFuture> = - executeAgent(params, RequestOptions.none()) - - /** @see executeAgent */ - fun executeAgent( - params: SessionExecuteAgentParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> - - /** - * Returns a raw HTTP response for `post /sessions/{sessionId}/extract`, but is otherwise - * the same as [SessionServiceAsync.extract]. - */ - fun extract(sessionId: String): CompletableFuture> = - extract(sessionId, SessionExtractParams.none()) - - /** @see extract */ - fun extract( - sessionId: String, - params: SessionExtractParams = SessionExtractParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> = - extract(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see extract */ - fun extract( - sessionId: String, - params: SessionExtractParams = SessionExtractParams.none(), - ): CompletableFuture> = - extract(sessionId, params, RequestOptions.none()) - - /** @see extract */ - fun extract( - params: SessionExtractParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> - - /** @see extract */ - fun extract( - params: SessionExtractParams - ): CompletableFuture> = - extract(params, RequestOptions.none()) - - /** @see extract */ - fun extract( - sessionId: String, - requestOptions: RequestOptions, - ): CompletableFuture> = - extract(sessionId, SessionExtractParams.none(), requestOptions) - - /** - * Returns a raw HTTP response for `post /sessions/{sessionId}/navigate`, but is otherwise - * the same as [SessionServiceAsync.navigate]. - */ - fun navigate( - sessionId: String, - params: SessionNavigateParams, - ): CompletableFuture>> = - navigate(sessionId, params, RequestOptions.none()) - - /** @see navigate */ - fun navigate( - sessionId: String, - params: SessionNavigateParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture>> = - navigate(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see navigate */ - fun navigate( - params: SessionNavigateParams - ): CompletableFuture>> = - navigate(params, RequestOptions.none()) - - /** @see navigate */ - fun navigate( - params: SessionNavigateParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture>> - - /** - * Returns a raw HTTP response for `post /sessions/{sessionId}/observe`, but is otherwise - * the same as [SessionServiceAsync.observe]. + * Returns a raw HTTP response for `post /sessions/start`, but is otherwise the same as + * [SessionServiceAsync.start]. */ - fun observe(sessionId: String): CompletableFuture>> = - observe(sessionId, SessionObserveParams.none()) - - /** @see observe */ - fun observe( - sessionId: String, - params: SessionObserveParams = SessionObserveParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture>> = - observe(params.toBuilder().sessionId(sessionId).build(), requestOptions) + fun start(): CompletableFuture> = + start(SessionStartParams.none()) - /** @see observe */ - fun observe( - sessionId: String, - params: SessionObserveParams = SessionObserveParams.none(), - ): CompletableFuture>> = - observe(sessionId, params, RequestOptions.none()) - - /** @see observe */ - fun observe( - params: SessionObserveParams, + /** @see start */ + fun start( + params: SessionStartParams = SessionStartParams.none(), requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture>> - - /** @see observe */ - fun observe( - params: SessionObserveParams - ): CompletableFuture>> = observe(params, RequestOptions.none()) - - /** @see observe */ - fun observe( - sessionId: String, - requestOptions: RequestOptions, - ): CompletableFuture>> = - observe(sessionId, SessionObserveParams.none(), requestOptions) + ): CompletableFuture> - /** - * Returns a raw HTTP response for `post /sessions/start`, but is otherwise the same as - * [SessionServiceAsync.start]. - */ + /** @see start */ fun start( - params: SessionStartParams + params: SessionStartParams = SessionStartParams.none() ): CompletableFuture> = start(params, RequestOptions.none()) /** @see start */ fun start( - params: SessionStartParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> + requestOptions: RequestOptions + ): CompletableFuture> = + start(SessionStartParams.none(), requestOptions) } } diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsyncImpl.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsyncImpl.kt index baa7114..056c59c 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsyncImpl.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsyncImpl.kt @@ -4,7 +4,6 @@ package com.browserbase.api.services.async import com.browserbase.api.core.ClientOptions import com.browserbase.api.core.RequestOptions -import com.browserbase.api.core.checkRequired import com.browserbase.api.core.handlers.errorBodyHandler import com.browserbase.api.core.handlers.errorHandler import com.browserbase.api.core.handlers.jsonHandler @@ -16,24 +15,10 @@ import com.browserbase.api.core.http.HttpResponseFor import com.browserbase.api.core.http.json import com.browserbase.api.core.http.parseable import com.browserbase.api.core.prepareAsync -import com.browserbase.api.models.sessions.Action -import com.browserbase.api.models.sessions.SessionActParams -import com.browserbase.api.models.sessions.SessionActResponse -import com.browserbase.api.models.sessions.SessionEndParams -import com.browserbase.api.models.sessions.SessionEndResponse -import com.browserbase.api.models.sessions.SessionExecuteAgentParams -import com.browserbase.api.models.sessions.SessionExecuteAgentResponse -import com.browserbase.api.models.sessions.SessionExtractParams -import com.browserbase.api.models.sessions.SessionExtractResponse -import com.browserbase.api.models.sessions.SessionNavigateParams -import com.browserbase.api.models.sessions.SessionNavigateResponse -import com.browserbase.api.models.sessions.SessionObserveParams import com.browserbase.api.models.sessions.SessionStartParams import com.browserbase.api.models.sessions.SessionStartResponse -import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.function.Consumer -import kotlin.jvm.optionals.getOrNull class SessionServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : SessionServiceAsync { @@ -47,48 +32,6 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl override fun withOptions(modifier: Consumer): SessionServiceAsync = SessionServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) - override fun act( - params: SessionActParams, - requestOptions: RequestOptions, - ): CompletableFuture = - // post /sessions/{sessionId}/act - withRawResponse().act(params, requestOptions).thenApply { it.parse() } - - override fun end( - params: SessionEndParams, - requestOptions: RequestOptions, - ): CompletableFuture = - // post /sessions/{sessionId}/end - withRawResponse().end(params, requestOptions).thenApply { it.parse() } - - override fun executeAgent( - params: SessionExecuteAgentParams, - requestOptions: RequestOptions, - ): CompletableFuture = - // post /sessions/{sessionId}/agentExecute - withRawResponse().executeAgent(params, requestOptions).thenApply { it.parse() } - - override fun extract( - params: SessionExtractParams, - requestOptions: RequestOptions, - ): CompletableFuture = - // post /sessions/{sessionId}/extract - withRawResponse().extract(params, requestOptions).thenApply { it.parse() } - - override fun navigate( - params: SessionNavigateParams, - requestOptions: RequestOptions, - ): CompletableFuture> = - // post /sessions/{sessionId}/navigate - withRawResponse().navigate(params, requestOptions).thenApply { it.parse() } - - override fun observe( - params: SessionObserveParams, - requestOptions: RequestOptions, - ): CompletableFuture> = - // post /sessions/{sessionId}/observe - withRawResponse().observe(params, requestOptions).thenApply { it.parse() } - override fun start( params: SessionStartParams, requestOptions: RequestOptions, @@ -109,210 +52,6 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl clientOptions.toBuilder().apply(modifier::accept).build() ) - private val actHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun act( - params: SessionActParams, - requestOptions: RequestOptions, - ): CompletableFuture> { - // We check here instead of in the params builder because this can be specified - // positionally or in the params class. - checkRequired("sessionId", params.sessionId().getOrNull()) - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "act") - .body(json(clientOptions.jsonMapper, params._body())) - .build() - .prepareAsync(clientOptions, params) - val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) - return request - .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } - .thenApply { response -> - errorHandler.handle(response).parseable { - response - .use { actHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } - } - - private val endHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun end( - params: SessionEndParams, - requestOptions: RequestOptions, - ): CompletableFuture> { - // We check here instead of in the params builder because this can be specified - // positionally or in the params class. - checkRequired("sessionId", params.sessionId().getOrNull()) - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "end") - .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - .prepareAsync(clientOptions, params) - val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) - return request - .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } - .thenApply { response -> - errorHandler.handle(response).parseable { - response - .use { endHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } - } - - private val executeAgentHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun executeAgent( - params: SessionExecuteAgentParams, - requestOptions: RequestOptions, - ): CompletableFuture> { - // We check here instead of in the params builder because this can be specified - // positionally or in the params class. - checkRequired("sessionId", params.sessionId().getOrNull()) - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "agentExecute") - .body(json(clientOptions.jsonMapper, params._body())) - .build() - .prepareAsync(clientOptions, params) - val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) - return request - .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } - .thenApply { response -> - errorHandler.handle(response).parseable { - response - .use { executeAgentHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } - } - - private val extractHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun extract( - params: SessionExtractParams, - requestOptions: RequestOptions, - ): CompletableFuture> { - // We check here instead of in the params builder because this can be specified - // positionally or in the params class. - checkRequired("sessionId", params.sessionId().getOrNull()) - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "extract") - .body(json(clientOptions.jsonMapper, params._body())) - .build() - .prepareAsync(clientOptions, params) - val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) - return request - .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } - .thenApply { response -> - errorHandler.handle(response).parseable { - response - .use { extractHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } - } - - private val navigateHandler: Handler> = - jsonHandler>(clientOptions.jsonMapper) - - override fun navigate( - params: SessionNavigateParams, - requestOptions: RequestOptions, - ): CompletableFuture>> { - // We check here instead of in the params builder because this can be specified - // positionally or in the params class. - checkRequired("sessionId", params.sessionId().getOrNull()) - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "navigate") - .body(json(clientOptions.jsonMapper, params._body())) - .build() - .prepareAsync(clientOptions, params) - val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) - return request - .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } - .thenApply { response -> - errorHandler.handle(response).parseable { - response - .use { navigateHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.ifPresent { it.validate() } - } - } - } - } - } - - private val observeHandler: Handler> = - jsonHandler>(clientOptions.jsonMapper) - - override fun observe( - params: SessionObserveParams, - requestOptions: RequestOptions, - ): CompletableFuture>> { - // We check here instead of in the params builder because this can be specified - // positionally or in the params class. - checkRequired("sessionId", params.sessionId().getOrNull()) - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "observe") - .body(json(clientOptions.jsonMapper, params._body())) - .build() - .prepareAsync(clientOptions, params) - val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) - return request - .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } - .thenApply { response -> - errorHandler.handle(response).parseable { - response - .use { observeHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.forEach { it.validate() } - } - } - } - } - } - private val startHandler: Handler = jsonHandler(clientOptions.jsonMapper) diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionService.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionService.kt index aac24dc..ddd7ad3 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionService.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionService.kt @@ -5,22 +5,9 @@ package com.browserbase.api.services.blocking import com.browserbase.api.core.ClientOptions import com.browserbase.api.core.RequestOptions import com.browserbase.api.core.http.HttpResponseFor -import com.browserbase.api.models.sessions.Action -import com.browserbase.api.models.sessions.SessionActParams -import com.browserbase.api.models.sessions.SessionActResponse -import com.browserbase.api.models.sessions.SessionEndParams -import com.browserbase.api.models.sessions.SessionEndResponse -import com.browserbase.api.models.sessions.SessionExecuteAgentParams -import com.browserbase.api.models.sessions.SessionExecuteAgentResponse -import com.browserbase.api.models.sessions.SessionExtractParams -import com.browserbase.api.models.sessions.SessionExtractResponse -import com.browserbase.api.models.sessions.SessionNavigateParams -import com.browserbase.api.models.sessions.SessionNavigateResponse -import com.browserbase.api.models.sessions.SessionObserveParams import com.browserbase.api.models.sessions.SessionStartParams import com.browserbase.api.models.sessions.SessionStartResponse import com.google.errorprone.annotations.MustBeClosed -import java.util.Optional import java.util.function.Consumer interface SessionService { @@ -38,184 +25,24 @@ interface SessionService { fun withOptions(modifier: Consumer): SessionService /** - * Performs a browser action based on natural language instruction or a specific action object - * returned by observe(). + * Creates a new browser session with the specified configuration. Returns a session ID used for + * all subsequent operations. */ - fun act(sessionId: String, params: SessionActParams): SessionActResponse = - act(sessionId, params, RequestOptions.none()) + fun start(): SessionStartResponse = start(SessionStartParams.none()) - /** @see act */ - fun act( - sessionId: String, - params: SessionActParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): SessionActResponse = act(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see act */ - fun act(params: SessionActParams): SessionActResponse = act(params, RequestOptions.none()) - - /** @see act */ - fun act( - params: SessionActParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): SessionActResponse - - /** Closes the browser and cleans up all resources associated with the session. */ - fun end(sessionId: String): SessionEndResponse = end(sessionId, SessionEndParams.none()) - - /** @see end */ - fun end( - sessionId: String, - params: SessionEndParams = SessionEndParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): SessionEndResponse = end(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see end */ - fun end( - sessionId: String, - params: SessionEndParams = SessionEndParams.none(), - ): SessionEndResponse = end(sessionId, params, RequestOptions.none()) - - /** @see end */ - fun end( - params: SessionEndParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): SessionEndResponse - - /** @see end */ - fun end(params: SessionEndParams): SessionEndResponse = end(params, RequestOptions.none()) - - /** @see end */ - fun end(sessionId: String, requestOptions: RequestOptions): SessionEndResponse = - end(sessionId, SessionEndParams.none(), requestOptions) - - /** Runs an autonomous agent that can perform multiple actions to complete a complex task. */ - fun executeAgent( - sessionId: String, - params: SessionExecuteAgentParams, - ): SessionExecuteAgentResponse = executeAgent(sessionId, params, RequestOptions.none()) - - /** @see executeAgent */ - fun executeAgent( - sessionId: String, - params: SessionExecuteAgentParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): SessionExecuteAgentResponse = - executeAgent(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see executeAgent */ - fun executeAgent(params: SessionExecuteAgentParams): SessionExecuteAgentResponse = - executeAgent(params, RequestOptions.none()) - - /** @see executeAgent */ - fun executeAgent( - params: SessionExecuteAgentParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): SessionExecuteAgentResponse - - /** - * Extracts data from the current page using natural language instructions and optional JSON - * schema for structured output. - */ - fun extract(sessionId: String): SessionExtractResponse = - extract(sessionId, SessionExtractParams.none()) - - /** @see extract */ - fun extract( - sessionId: String, - params: SessionExtractParams = SessionExtractParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): SessionExtractResponse = - extract(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see extract */ - fun extract( - sessionId: String, - params: SessionExtractParams = SessionExtractParams.none(), - ): SessionExtractResponse = extract(sessionId, params, RequestOptions.none()) - - /** @see extract */ - fun extract( - params: SessionExtractParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): SessionExtractResponse - - /** @see extract */ - fun extract(params: SessionExtractParams): SessionExtractResponse = - extract(params, RequestOptions.none()) - - /** @see extract */ - fun extract(sessionId: String, requestOptions: RequestOptions): SessionExtractResponse = - extract(sessionId, SessionExtractParams.none(), requestOptions) - - /** Navigates the browser to the specified URL and waits for page load. */ - fun navigate( - sessionId: String, - params: SessionNavigateParams, - ): Optional = navigate(sessionId, params, RequestOptions.none()) - - /** @see navigate */ - fun navigate( - sessionId: String, - params: SessionNavigateParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): Optional = - navigate(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see navigate */ - fun navigate(params: SessionNavigateParams): Optional = - navigate(params, RequestOptions.none()) - - /** @see navigate */ - fun navigate( - params: SessionNavigateParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): Optional - - /** - * Returns a list of candidate actions that can be performed on the page, optionally filtered by - * natural language instruction. - */ - fun observe(sessionId: String): List = observe(sessionId, SessionObserveParams.none()) - - /** @see observe */ - fun observe( - sessionId: String, - params: SessionObserveParams = SessionObserveParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): List = observe(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see observe */ - fun observe( - sessionId: String, - params: SessionObserveParams = SessionObserveParams.none(), - ): List = observe(sessionId, params, RequestOptions.none()) - - /** @see observe */ - fun observe( - params: SessionObserveParams, + /** @see start */ + fun start( + params: SessionStartParams = SessionStartParams.none(), requestOptions: RequestOptions = RequestOptions.none(), - ): List - - /** @see observe */ - fun observe(params: SessionObserveParams): List = observe(params, RequestOptions.none()) - - /** @see observe */ - fun observe(sessionId: String, requestOptions: RequestOptions): List = - observe(sessionId, SessionObserveParams.none(), requestOptions) + ): SessionStartResponse - /** - * Initializes a new Stagehand session with a browser instance. Returns a session ID that must - * be used for all subsequent requests. - */ - fun start(params: SessionStartParams): SessionStartResponse = + /** @see start */ + fun start(params: SessionStartParams = SessionStartParams.none()): SessionStartResponse = start(params, RequestOptions.none()) /** @see start */ - fun start( - params: SessionStartParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): SessionStartResponse + fun start(requestOptions: RequestOptions): SessionStartResponse = + start(SessionStartParams.none(), requestOptions) /** A view of [SessionService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -227,249 +54,29 @@ interface SessionService { */ fun withOptions(modifier: Consumer): SessionService.WithRawResponse - /** - * Returns a raw HTTP response for `post /sessions/{sessionId}/act`, but is otherwise the - * same as [SessionService.act]. - */ - @MustBeClosed - fun act(sessionId: String, params: SessionActParams): HttpResponseFor = - act(sessionId, params, RequestOptions.none()) - - /** @see act */ - @MustBeClosed - fun act( - sessionId: String, - params: SessionActParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor = - act(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see act */ - @MustBeClosed - fun act(params: SessionActParams): HttpResponseFor = - act(params, RequestOptions.none()) - - /** @see act */ - @MustBeClosed - fun act( - params: SessionActParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor - - /** - * Returns a raw HTTP response for `post /sessions/{sessionId}/end`, but is otherwise the - * same as [SessionService.end]. - */ - @MustBeClosed - fun end(sessionId: String): HttpResponseFor = - end(sessionId, SessionEndParams.none()) - - /** @see end */ - @MustBeClosed - fun end( - sessionId: String, - params: SessionEndParams = SessionEndParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor = - end(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see end */ - @MustBeClosed - fun end( - sessionId: String, - params: SessionEndParams = SessionEndParams.none(), - ): HttpResponseFor = end(sessionId, params, RequestOptions.none()) - - /** @see end */ - @MustBeClosed - fun end( - params: SessionEndParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor - - /** @see end */ - @MustBeClosed - fun end(params: SessionEndParams): HttpResponseFor = - end(params, RequestOptions.none()) - - /** @see end */ - @MustBeClosed - fun end( - sessionId: String, - requestOptions: RequestOptions, - ): HttpResponseFor = - end(sessionId, SessionEndParams.none(), requestOptions) - - /** - * Returns a raw HTTP response for `post /sessions/{sessionId}/agentExecute`, but is - * otherwise the same as [SessionService.executeAgent]. - */ - @MustBeClosed - fun executeAgent( - sessionId: String, - params: SessionExecuteAgentParams, - ): HttpResponseFor = - executeAgent(sessionId, params, RequestOptions.none()) - - /** @see executeAgent */ - @MustBeClosed - fun executeAgent( - sessionId: String, - params: SessionExecuteAgentParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor = - executeAgent(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see executeAgent */ - @MustBeClosed - fun executeAgent( - params: SessionExecuteAgentParams - ): HttpResponseFor = - executeAgent(params, RequestOptions.none()) - - /** @see executeAgent */ - @MustBeClosed - fun executeAgent( - params: SessionExecuteAgentParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor - - /** - * Returns a raw HTTP response for `post /sessions/{sessionId}/extract`, but is otherwise - * the same as [SessionService.extract]. - */ - @MustBeClosed - fun extract(sessionId: String): HttpResponseFor = - extract(sessionId, SessionExtractParams.none()) - - /** @see extract */ - @MustBeClosed - fun extract( - sessionId: String, - params: SessionExtractParams = SessionExtractParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor = - extract(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see extract */ - @MustBeClosed - fun extract( - sessionId: String, - params: SessionExtractParams = SessionExtractParams.none(), - ): HttpResponseFor = - extract(sessionId, params, RequestOptions.none()) - - /** @see extract */ - @MustBeClosed - fun extract( - params: SessionExtractParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor - - /** @see extract */ - @MustBeClosed - fun extract(params: SessionExtractParams): HttpResponseFor = - extract(params, RequestOptions.none()) - - /** @see extract */ - @MustBeClosed - fun extract( - sessionId: String, - requestOptions: RequestOptions, - ): HttpResponseFor = - extract(sessionId, SessionExtractParams.none(), requestOptions) - - /** - * Returns a raw HTTP response for `post /sessions/{sessionId}/navigate`, but is otherwise - * the same as [SessionService.navigate]. - */ - @MustBeClosed - fun navigate( - sessionId: String, - params: SessionNavigateParams, - ): HttpResponseFor> = - navigate(sessionId, params, RequestOptions.none()) - - /** @see navigate */ - @MustBeClosed - fun navigate( - sessionId: String, - params: SessionNavigateParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor> = - navigate(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see navigate */ - @MustBeClosed - fun navigate( - params: SessionNavigateParams - ): HttpResponseFor> = - navigate(params, RequestOptions.none()) - - /** @see navigate */ - @MustBeClosed - fun navigate( - params: SessionNavigateParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor> - - /** - * Returns a raw HTTP response for `post /sessions/{sessionId}/observe`, but is otherwise - * the same as [SessionService.observe]. - */ - @MustBeClosed - fun observe(sessionId: String): HttpResponseFor> = - observe(sessionId, SessionObserveParams.none()) - - /** @see observe */ - @MustBeClosed - fun observe( - sessionId: String, - params: SessionObserveParams = SessionObserveParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor> = - observe(params.toBuilder().sessionId(sessionId).build(), requestOptions) - - /** @see observe */ - @MustBeClosed - fun observe( - sessionId: String, - params: SessionObserveParams = SessionObserveParams.none(), - ): HttpResponseFor> = observe(sessionId, params, RequestOptions.none()) - - /** @see observe */ - @MustBeClosed - fun observe( - params: SessionObserveParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor> - - /** @see observe */ - @MustBeClosed - fun observe(params: SessionObserveParams): HttpResponseFor> = - observe(params, RequestOptions.none()) - - /** @see observe */ - @MustBeClosed - fun observe( - sessionId: String, - requestOptions: RequestOptions, - ): HttpResponseFor> = - observe(sessionId, SessionObserveParams.none(), requestOptions) - /** * Returns a raw HTTP response for `post /sessions/start`, but is otherwise the same as * [SessionService.start]. */ @MustBeClosed - fun start(params: SessionStartParams): HttpResponseFor = - start(params, RequestOptions.none()) + fun start(): HttpResponseFor = start(SessionStartParams.none()) /** @see start */ @MustBeClosed fun start( - params: SessionStartParams, + params: SessionStartParams = SessionStartParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + + /** @see start */ + @MustBeClosed + fun start( + params: SessionStartParams = SessionStartParams.none() + ): HttpResponseFor = start(params, RequestOptions.none()) + + /** @see start */ + @MustBeClosed + fun start(requestOptions: RequestOptions): HttpResponseFor = + start(SessionStartParams.none(), requestOptions) } } diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionServiceImpl.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionServiceImpl.kt index 6c09595..2a983bb 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionServiceImpl.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionServiceImpl.kt @@ -4,7 +4,6 @@ package com.browserbase.api.services.blocking import com.browserbase.api.core.ClientOptions import com.browserbase.api.core.RequestOptions -import com.browserbase.api.core.checkRequired import com.browserbase.api.core.handlers.errorBodyHandler import com.browserbase.api.core.handlers.errorHandler import com.browserbase.api.core.handlers.jsonHandler @@ -16,23 +15,9 @@ import com.browserbase.api.core.http.HttpResponseFor import com.browserbase.api.core.http.json import com.browserbase.api.core.http.parseable import com.browserbase.api.core.prepare -import com.browserbase.api.models.sessions.Action -import com.browserbase.api.models.sessions.SessionActParams -import com.browserbase.api.models.sessions.SessionActResponse -import com.browserbase.api.models.sessions.SessionEndParams -import com.browserbase.api.models.sessions.SessionEndResponse -import com.browserbase.api.models.sessions.SessionExecuteAgentParams -import com.browserbase.api.models.sessions.SessionExecuteAgentResponse -import com.browserbase.api.models.sessions.SessionExtractParams -import com.browserbase.api.models.sessions.SessionExtractResponse -import com.browserbase.api.models.sessions.SessionNavigateParams -import com.browserbase.api.models.sessions.SessionNavigateResponse -import com.browserbase.api.models.sessions.SessionObserveParams import com.browserbase.api.models.sessions.SessionStartParams import com.browserbase.api.models.sessions.SessionStartResponse -import java.util.Optional import java.util.function.Consumer -import kotlin.jvm.optionals.getOrNull class SessionServiceImpl internal constructor(private val clientOptions: ClientOptions) : SessionService { @@ -46,42 +31,6 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO override fun withOptions(modifier: Consumer): SessionService = SessionServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) - override fun act(params: SessionActParams, requestOptions: RequestOptions): SessionActResponse = - // post /sessions/{sessionId}/act - withRawResponse().act(params, requestOptions).parse() - - override fun end(params: SessionEndParams, requestOptions: RequestOptions): SessionEndResponse = - // post /sessions/{sessionId}/end - withRawResponse().end(params, requestOptions).parse() - - override fun executeAgent( - params: SessionExecuteAgentParams, - requestOptions: RequestOptions, - ): SessionExecuteAgentResponse = - // post /sessions/{sessionId}/agentExecute - withRawResponse().executeAgent(params, requestOptions).parse() - - override fun extract( - params: SessionExtractParams, - requestOptions: RequestOptions, - ): SessionExtractResponse = - // post /sessions/{sessionId}/extract - withRawResponse().extract(params, requestOptions).parse() - - override fun navigate( - params: SessionNavigateParams, - requestOptions: RequestOptions, - ): Optional = - // post /sessions/{sessionId}/navigate - withRawResponse().navigate(params, requestOptions).parse() - - override fun observe( - params: SessionObserveParams, - requestOptions: RequestOptions, - ): List = - // post /sessions/{sessionId}/observe - withRawResponse().observe(params, requestOptions).parse() - override fun start( params: SessionStartParams, requestOptions: RequestOptions, @@ -102,192 +51,6 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO clientOptions.toBuilder().apply(modifier::accept).build() ) - private val actHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun act( - params: SessionActParams, - requestOptions: RequestOptions, - ): HttpResponseFor { - // We check here instead of in the params builder because this can be specified - // positionally or in the params class. - checkRequired("sessionId", params.sessionId().getOrNull()) - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "act") - .body(json(clientOptions.jsonMapper, params._body())) - .build() - .prepare(clientOptions, params) - val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) - val response = clientOptions.httpClient.execute(request, requestOptions) - return errorHandler.handle(response).parseable { - response - .use { actHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } - - private val endHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun end( - params: SessionEndParams, - requestOptions: RequestOptions, - ): HttpResponseFor { - // We check here instead of in the params builder because this can be specified - // positionally or in the params class. - checkRequired("sessionId", params.sessionId().getOrNull()) - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "end") - .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - .prepare(clientOptions, params) - val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) - val response = clientOptions.httpClient.execute(request, requestOptions) - return errorHandler.handle(response).parseable { - response - .use { endHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } - - private val executeAgentHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun executeAgent( - params: SessionExecuteAgentParams, - requestOptions: RequestOptions, - ): HttpResponseFor { - // We check here instead of in the params builder because this can be specified - // positionally or in the params class. - checkRequired("sessionId", params.sessionId().getOrNull()) - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "agentExecute") - .body(json(clientOptions.jsonMapper, params._body())) - .build() - .prepare(clientOptions, params) - val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) - val response = clientOptions.httpClient.execute(request, requestOptions) - return errorHandler.handle(response).parseable { - response - .use { executeAgentHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } - - private val extractHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - - override fun extract( - params: SessionExtractParams, - requestOptions: RequestOptions, - ): HttpResponseFor { - // We check here instead of in the params builder because this can be specified - // positionally or in the params class. - checkRequired("sessionId", params.sessionId().getOrNull()) - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "extract") - .body(json(clientOptions.jsonMapper, params._body())) - .build() - .prepare(clientOptions, params) - val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) - val response = clientOptions.httpClient.execute(request, requestOptions) - return errorHandler.handle(response).parseable { - response - .use { extractHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.validate() - } - } - } - } - - private val navigateHandler: Handler> = - jsonHandler>(clientOptions.jsonMapper) - - override fun navigate( - params: SessionNavigateParams, - requestOptions: RequestOptions, - ): HttpResponseFor> { - // We check here instead of in the params builder because this can be specified - // positionally or in the params class. - checkRequired("sessionId", params.sessionId().getOrNull()) - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "navigate") - .body(json(clientOptions.jsonMapper, params._body())) - .build() - .prepare(clientOptions, params) - val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) - val response = clientOptions.httpClient.execute(request, requestOptions) - return errorHandler.handle(response).parseable { - response - .use { navigateHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.ifPresent { it.validate() } - } - } - } - } - - private val observeHandler: Handler> = - jsonHandler>(clientOptions.jsonMapper) - - override fun observe( - params: SessionObserveParams, - requestOptions: RequestOptions, - ): HttpResponseFor> { - // We check here instead of in the params builder because this can be specified - // positionally or in the params class. - checkRequired("sessionId", params.sessionId().getOrNull()) - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "observe") - .body(json(clientOptions.jsonMapper, params._body())) - .build() - .prepare(clientOptions, params) - val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) - val response = clientOptions.httpClient.execute(request, requestOptions) - return errorHandler.handle(response).parseable { - response - .use { observeHandler.handle(it) } - .also { - if (requestOptions.responseValidation!!) { - it.forEach { it.validate() } - } - } - } - } - private val startHandler: Handler = jsonHandler(clientOptions.jsonMapper) diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/ActionTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/ActionTest.kt index fcd120c..4464f91 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/ActionTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/ActionTest.kt @@ -4,6 +4,7 @@ package com.browserbase.api.models.sessions import com.browserbase.api.core.jsonMapper import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import kotlin.jvm.optionals.getOrNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -13,18 +14,16 @@ internal class ActionTest { fun create() { val action = Action.builder() - .addArgument("string") - .description("description") - .method("method") - .selector("selector") - .backendNodeId(0L) + .description("Click the submit button") + .selector("[data-testid='submit-button']") + .addArgument("Hello World") + .method("click") .build() - assertThat(action.arguments()).containsExactly("string") - assertThat(action.description()).isEqualTo("description") - assertThat(action.method()).isEqualTo("method") - assertThat(action.selector()).isEqualTo("selector") - assertThat(action.backendNodeId()).contains(0L) + assertThat(action.description()).isEqualTo("Click the submit button") + assertThat(action.selector()).isEqualTo("[data-testid='submit-button']") + assertThat(action.arguments().getOrNull()).containsExactly("Hello World") + assertThat(action.method()).contains("click") } @Test @@ -32,11 +31,10 @@ internal class ActionTest { val jsonMapper = jsonMapper() val action = Action.builder() - .addArgument("string") - .description("description") - .method("method") - .selector("selector") - .backendNodeId(0L) + .description("Click the submit button") + .selector("[data-testid='submit-button']") + .addArgument("Hello World") + .method("click") .build() val roundtrippedAction = diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/ModelConfigTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/ModelConfigTest.kt index 0430aec..b45bc3f 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/ModelConfigTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/ModelConfigTest.kt @@ -2,39 +2,66 @@ package com.browserbase.api.models.sessions +import com.browserbase.api.core.JsonValue import com.browserbase.api.core.jsonMapper +import com.browserbase.api.errors.StagehandInvalidDataException import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows internal class ModelConfigTest { @Test - fun create() { - val modelConfig = - ModelConfig.builder() + fun ofString() { + val string = "string" + + val modelConfig = ModelConfig.ofString(string) + + assertThat(modelConfig.string()).contains(string) + assertThat(modelConfig.unionMember1()).isEmpty + } + + @Test + fun ofStringRoundtrip() { + val jsonMapper = jsonMapper() + val modelConfig = ModelConfig.ofString("string") + + val roundtrippedModelConfig = + jsonMapper.readValue( + jsonMapper.writeValueAsString(modelConfig), + jacksonTypeRef(), + ) + + assertThat(roundtrippedModelConfig).isEqualTo(modelConfig) + } + + @Test + fun ofUnionMember1() { + val unionMember1 = + ModelConfig.UnionMember1.builder() + .modelName("modelName") .apiKey("apiKey") .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) .build() - assertThat(modelConfig.apiKey()).contains("apiKey") - assertThat(modelConfig.baseUrl()).contains("https://example.com") - assertThat(modelConfig.model()).contains("model") - assertThat(modelConfig.provider()).contains(ModelConfig.Provider.OPENAI) + val modelConfig = ModelConfig.ofUnionMember1(unionMember1) + + assertThat(modelConfig.string()).isEmpty + assertThat(modelConfig.unionMember1()).contains(unionMember1) } @Test - fun roundtrip() { + fun ofUnionMember1Roundtrip() { val jsonMapper = jsonMapper() val modelConfig = - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() + ModelConfig.ofUnionMember1( + ModelConfig.UnionMember1.builder() + .modelName("modelName") + .apiKey("apiKey") + .baseUrl("https://example.com") + .build() + ) val roundtrippedModelConfig = jsonMapper.readValue( @@ -44,4 +71,13 @@ internal class ModelConfigTest { assertThat(roundtrippedModelConfig).isEqualTo(modelConfig) } + + @Test + fun incompatibleJsonShapeDeserializesToUnknown() { + val value = JsonValue.from(listOf("invalid", "array")) + val modelConfig = jsonMapper().convertValue(value, jacksonTypeRef()) + + val e = assertThrows { modelConfig.validate() } + assertThat(e).hasMessageStartingWith("Unknown ") + } } diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt deleted file mode 100644 index fbcca00..0000000 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt +++ /dev/null @@ -1,166 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.JsonValue -import com.browserbase.api.core.http.Headers -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class SessionActParamsTest { - - @Test - fun create() { - SessionActParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("click the sign in button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .timeout(0L) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty("foo", JsonValue.from("string")) - .build() - ) - .build() - ) - .build() - } - - @Test - fun pathParams() { - val params = - SessionActParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .input("click the sign in button") - .build() - - assertThat(params._pathParam(0)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - // out-of-bound path param - assertThat(params._pathParam(1)).isEqualTo("") - } - - @Test - fun headers() { - val params = - SessionActParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("click the sign in button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .timeout(0L) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty("foo", JsonValue.from("string")) - .build() - ) - .build() - ) - .build() - - val headers = params._headers() - - assertThat(headers).isEqualTo(Headers.builder().put("x-stream-response", "true").build()) - } - - @Test - fun headersWithoutOptionalFields() { - val params = - SessionActParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .input("click the sign in button") - .build() - - val headers = params._headers() - - assertThat(headers).isEqualTo(Headers.builder().build()) - } - - @Test - fun body() { - val params = - SessionActParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("click the sign in button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .timeout(0L) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty("foo", JsonValue.from("string")) - .build() - ) - .build() - ) - .build() - - val body = params._body() - - assertThat(body.input()) - .isEqualTo(SessionActParams.Input.ofString("click the sign in button")) - assertThat(body.frameId()).contains("frameId") - assertThat(body.options()) - .contains( - SessionActParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .timeout(0L) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty("foo", JsonValue.from("string")) - .build() - ) - .build() - ) - } - - @Test - fun bodyWithoutOptionalFields() { - val params = - SessionActParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .input("click the sign in button") - .build() - - val body = params._body() - - assertThat(body.input()) - .isEqualTo(SessionActParams.Input.ofString("click the sign in button")) - } -} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActResponseTest.kt deleted file mode 100644 index 7f4d8c8..0000000 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActResponseTest.kt +++ /dev/null @@ -1,69 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.jsonMapper -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class SessionActResponseTest { - - @Test - fun create() { - val sessionActResponse = - SessionActResponse.builder() - .addAction( - Action.builder() - .addArgument("string") - .description("description") - .method("method") - .selector("selector") - .backendNodeId(0L) - .build() - ) - .message("message") - .success(true) - .build() - - assertThat(sessionActResponse.actions()) - .containsExactly( - Action.builder() - .addArgument("string") - .description("description") - .method("method") - .selector("selector") - .backendNodeId(0L) - .build() - ) - assertThat(sessionActResponse.message()).isEqualTo("message") - assertThat(sessionActResponse.success()).isEqualTo(true) - } - - @Test - fun roundtrip() { - val jsonMapper = jsonMapper() - val sessionActResponse = - SessionActResponse.builder() - .addAction( - Action.builder() - .addArgument("string") - .description("description") - .method("method") - .selector("selector") - .backendNodeId(0L) - .build() - ) - .message("message") - .success(true) - .build() - - val roundtrippedSessionActResponse = - jsonMapper.readValue( - jsonMapper.writeValueAsString(sessionActResponse), - jacksonTypeRef(), - ) - - assertThat(roundtrippedSessionActResponse).isEqualTo(sessionActResponse) - } -} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndParamsTest.kt deleted file mode 100644 index ab839e5..0000000 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndParamsTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class SessionEndParamsTest { - - @Test - fun create() { - SessionEndParams.builder().sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() - } - - @Test - fun pathParams() { - val params = - SessionEndParams.builder().sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() - - assertThat(params._pathParam(0)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - // out-of-bound path param - assertThat(params._pathParam(1)).isEqualTo("") - } -} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt deleted file mode 100644 index b52414c..0000000 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt +++ /dev/null @@ -1,32 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.jsonMapper -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class SessionEndResponseTest { - - @Test - fun create() { - val sessionEndResponse = SessionEndResponse.builder().success(true).build() - - assertThat(sessionEndResponse.success()).contains(true) - } - - @Test - fun roundtrip() { - val jsonMapper = jsonMapper() - val sessionEndResponse = SessionEndResponse.builder().success(true).build() - - val roundtrippedSessionEndResponse = - jsonMapper.readValue( - jsonMapper.writeValueAsString(sessionEndResponse), - jacksonTypeRef(), - ) - - assertThat(roundtrippedSessionEndResponse).isEqualTo(sessionEndResponse) - } -} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParamsTest.kt deleted file mode 100644 index 6d0d59b..0000000 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParamsTest.kt +++ /dev/null @@ -1,170 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.http.Headers -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class SessionExecuteAgentParamsTest { - - @Test - fun create() { - SessionExecuteAgentParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionExecuteAgentParams.XStreamResponse.TRUE) - .agentConfig( - SessionExecuteAgentParams.AgentConfig.builder() - .cua(true) - .model("openai/gpt-4o") - .provider(SessionExecuteAgentParams.AgentConfig.Provider.OPENAI) - .systemPrompt("systemPrompt") - .build() - ) - .executeOptions( - SessionExecuteAgentParams.ExecuteOptions.builder() - .instruction("Find and click the first product") - .highlightCursor(true) - .maxSteps(10L) - .build() - ) - .frameId("frameId") - .build() - } - - @Test - fun pathParams() { - val params = - SessionExecuteAgentParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .agentConfig(SessionExecuteAgentParams.AgentConfig.builder().build()) - .executeOptions( - SessionExecuteAgentParams.ExecuteOptions.builder() - .instruction("Find and click the first product") - .build() - ) - .build() - - assertThat(params._pathParam(0)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - // out-of-bound path param - assertThat(params._pathParam(1)).isEqualTo("") - } - - @Test - fun headers() { - val params = - SessionExecuteAgentParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionExecuteAgentParams.XStreamResponse.TRUE) - .agentConfig( - SessionExecuteAgentParams.AgentConfig.builder() - .cua(true) - .model("openai/gpt-4o") - .provider(SessionExecuteAgentParams.AgentConfig.Provider.OPENAI) - .systemPrompt("systemPrompt") - .build() - ) - .executeOptions( - SessionExecuteAgentParams.ExecuteOptions.builder() - .instruction("Find and click the first product") - .highlightCursor(true) - .maxSteps(10L) - .build() - ) - .frameId("frameId") - .build() - - val headers = params._headers() - - assertThat(headers).isEqualTo(Headers.builder().put("x-stream-response", "true").build()) - } - - @Test - fun headersWithoutOptionalFields() { - val params = - SessionExecuteAgentParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .agentConfig(SessionExecuteAgentParams.AgentConfig.builder().build()) - .executeOptions( - SessionExecuteAgentParams.ExecuteOptions.builder() - .instruction("Find and click the first product") - .build() - ) - .build() - - val headers = params._headers() - - assertThat(headers).isEqualTo(Headers.builder().build()) - } - - @Test - fun body() { - val params = - SessionExecuteAgentParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionExecuteAgentParams.XStreamResponse.TRUE) - .agentConfig( - SessionExecuteAgentParams.AgentConfig.builder() - .cua(true) - .model("openai/gpt-4o") - .provider(SessionExecuteAgentParams.AgentConfig.Provider.OPENAI) - .systemPrompt("systemPrompt") - .build() - ) - .executeOptions( - SessionExecuteAgentParams.ExecuteOptions.builder() - .instruction("Find and click the first product") - .highlightCursor(true) - .maxSteps(10L) - .build() - ) - .frameId("frameId") - .build() - - val body = params._body() - - assertThat(body.agentConfig()) - .isEqualTo( - SessionExecuteAgentParams.AgentConfig.builder() - .cua(true) - .model("openai/gpt-4o") - .provider(SessionExecuteAgentParams.AgentConfig.Provider.OPENAI) - .systemPrompt("systemPrompt") - .build() - ) - assertThat(body.executeOptions()) - .isEqualTo( - SessionExecuteAgentParams.ExecuteOptions.builder() - .instruction("Find and click the first product") - .highlightCursor(true) - .maxSteps(10L) - .build() - ) - assertThat(body.frameId()).contains("frameId") - } - - @Test - fun bodyWithoutOptionalFields() { - val params = - SessionExecuteAgentParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .agentConfig(SessionExecuteAgentParams.AgentConfig.builder().build()) - .executeOptions( - SessionExecuteAgentParams.ExecuteOptions.builder() - .instruction("Find and click the first product") - .build() - ) - .build() - - val body = params._body() - - assertThat(body.agentConfig()) - .isEqualTo(SessionExecuteAgentParams.AgentConfig.builder().build()) - assertThat(body.executeOptions()) - .isEqualTo( - SessionExecuteAgentParams.ExecuteOptions.builder() - .instruction("Find and click the first product") - .build() - ) - } -} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponseTest.kt deleted file mode 100644 index 4737af6..0000000 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponseTest.kt +++ /dev/null @@ -1,34 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.jsonMapper -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class SessionExecuteAgentResponseTest { - - @Test - fun create() { - val sessionExecuteAgentResponse = - SessionExecuteAgentResponse.builder().message("message").build() - - assertThat(sessionExecuteAgentResponse.message()).contains("message") - } - - @Test - fun roundtrip() { - val jsonMapper = jsonMapper() - val sessionExecuteAgentResponse = - SessionExecuteAgentResponse.builder().message("message").build() - - val roundtrippedSessionExecuteAgentResponse = - jsonMapper.readValue( - jsonMapper.writeValueAsString(sessionExecuteAgentResponse), - jacksonTypeRef(), - ) - - assertThat(roundtrippedSessionExecuteAgentResponse).isEqualTo(sessionExecuteAgentResponse) - } -} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt deleted file mode 100644 index 7df72a7..0000000 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt +++ /dev/null @@ -1,158 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.JsonValue -import com.browserbase.api.core.http.Headers -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class SessionExtractParamsTest { - - @Test - fun create() { - SessionExtractParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionExtractParams.XStreamResponse.TRUE) - .frameId("frameId") - .instruction("extract the page title") - .options( - SessionExtractParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .selector("selector") - .timeout(0L) - .build() - ) - .schema( - SessionExtractParams.Schema.builder() - .putAdditionalProperty("foo", JsonValue.from("bar")) - .build() - ) - .build() - } - - @Test - fun pathParams() { - val params = - SessionExtractParams.builder().sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() - - assertThat(params._pathParam(0)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - // out-of-bound path param - assertThat(params._pathParam(1)).isEqualTo("") - } - - @Test - fun headers() { - val params = - SessionExtractParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionExtractParams.XStreamResponse.TRUE) - .frameId("frameId") - .instruction("extract the page title") - .options( - SessionExtractParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .selector("selector") - .timeout(0L) - .build() - ) - .schema( - SessionExtractParams.Schema.builder() - .putAdditionalProperty("foo", JsonValue.from("bar")) - .build() - ) - .build() - - val headers = params._headers() - - assertThat(headers).isEqualTo(Headers.builder().put("x-stream-response", "true").build()) - } - - @Test - fun headersWithoutOptionalFields() { - val params = - SessionExtractParams.builder().sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() - - val headers = params._headers() - - assertThat(headers).isEqualTo(Headers.builder().build()) - } - - @Test - fun body() { - val params = - SessionExtractParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionExtractParams.XStreamResponse.TRUE) - .frameId("frameId") - .instruction("extract the page title") - .options( - SessionExtractParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .selector("selector") - .timeout(0L) - .build() - ) - .schema( - SessionExtractParams.Schema.builder() - .putAdditionalProperty("foo", JsonValue.from("bar")) - .build() - ) - .build() - - val body = params._body() - - assertThat(body.frameId()).contains("frameId") - assertThat(body.instruction()).contains("extract the page title") - assertThat(body.options()) - .contains( - SessionExtractParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .selector("selector") - .timeout(0L) - .build() - ) - assertThat(body.schema()) - .contains( - SessionExtractParams.Schema.builder() - .putAdditionalProperty("foo", JsonValue.from("bar")) - .build() - ) - } - - @Test - fun bodyWithoutOptionalFields() { - val params = - SessionExtractParams.builder().sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() - - val body = params._body() - } -} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractResponseTest.kt deleted file mode 100644 index 42022d5..0000000 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractResponseTest.kt +++ /dev/null @@ -1,94 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.JsonValue -import com.browserbase.api.core.jsonMapper -import com.browserbase.api.errors.StagehandInvalidDataException -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertThrows -import org.junit.jupiter.params.ParameterizedTest -import org.junit.jupiter.params.provider.EnumSource - -internal class SessionExtractResponseTest { - - @Test - fun ofExtraction() { - val extraction = - SessionExtractResponse.Extraction.builder().extraction("extraction").build() - - val sessionExtractResponse = SessionExtractResponse.ofExtraction(extraction) - - assertThat(sessionExtractResponse.extraction()).contains(extraction) - assertThat(sessionExtractResponse.custom()).isEmpty - } - - @Test - fun ofExtractionRoundtrip() { - val jsonMapper = jsonMapper() - val sessionExtractResponse = - SessionExtractResponse.ofExtraction( - SessionExtractResponse.Extraction.builder().extraction("extraction").build() - ) - - val roundtrippedSessionExtractResponse = - jsonMapper.readValue( - jsonMapper.writeValueAsString(sessionExtractResponse), - jacksonTypeRef(), - ) - - assertThat(roundtrippedSessionExtractResponse).isEqualTo(sessionExtractResponse) - } - - @Test - fun ofCustom() { - val custom = - SessionExtractResponse.Custom.builder() - .putAdditionalProperty("foo", JsonValue.from("bar")) - .build() - - val sessionExtractResponse = SessionExtractResponse.ofCustom(custom) - - assertThat(sessionExtractResponse.extraction()).isEmpty - assertThat(sessionExtractResponse.custom()).contains(custom) - } - - @Test - fun ofCustomRoundtrip() { - val jsonMapper = jsonMapper() - val sessionExtractResponse = - SessionExtractResponse.ofCustom( - SessionExtractResponse.Custom.builder() - .putAdditionalProperty("foo", JsonValue.from("bar")) - .build() - ) - - val roundtrippedSessionExtractResponse = - jsonMapper.readValue( - jsonMapper.writeValueAsString(sessionExtractResponse), - jacksonTypeRef(), - ) - - assertThat(roundtrippedSessionExtractResponse).isEqualTo(sessionExtractResponse) - } - - enum class IncompatibleJsonShapeTestCase(val value: JsonValue) { - BOOLEAN(JsonValue.from(false)), - STRING(JsonValue.from("invalid")), - INTEGER(JsonValue.from(-1)), - FLOAT(JsonValue.from(3.14)), - ARRAY(JsonValue.from(listOf("invalid", "array"))), - } - - @ParameterizedTest - @EnumSource - fun incompatibleJsonShapeDeserializesToUnknown(testCase: IncompatibleJsonShapeTestCase) { - val sessionExtractResponse = - jsonMapper().convertValue(testCase.value, jacksonTypeRef()) - - val e = assertThrows { sessionExtractResponse.validate() } - assertThat(e).hasMessageStartingWith("Unknown ") - } -} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt deleted file mode 100644 index fe762db..0000000 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt +++ /dev/null @@ -1,111 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.http.Headers -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class SessionNavigateParamsTest { - - @Test - fun create() { - SessionNavigateParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionNavigateParams.XStreamResponse.TRUE) - .url("https://example.com") - .frameId("frameId") - .options( - SessionNavigateParams.Options.builder() - .waitUntil(SessionNavigateParams.Options.WaitUntil.LOAD) - .build() - ) - .build() - } - - @Test - fun pathParams() { - val params = - SessionNavigateParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .url("https://example.com") - .build() - - assertThat(params._pathParam(0)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - // out-of-bound path param - assertThat(params._pathParam(1)).isEqualTo("") - } - - @Test - fun headers() { - val params = - SessionNavigateParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionNavigateParams.XStreamResponse.TRUE) - .url("https://example.com") - .frameId("frameId") - .options( - SessionNavigateParams.Options.builder() - .waitUntil(SessionNavigateParams.Options.WaitUntil.LOAD) - .build() - ) - .build() - - val headers = params._headers() - - assertThat(headers).isEqualTo(Headers.builder().put("x-stream-response", "true").build()) - } - - @Test - fun headersWithoutOptionalFields() { - val params = - SessionNavigateParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .url("https://example.com") - .build() - - val headers = params._headers() - - assertThat(headers).isEqualTo(Headers.builder().build()) - } - - @Test - fun body() { - val params = - SessionNavigateParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionNavigateParams.XStreamResponse.TRUE) - .url("https://example.com") - .frameId("frameId") - .options( - SessionNavigateParams.Options.builder() - .waitUntil(SessionNavigateParams.Options.WaitUntil.LOAD) - .build() - ) - .build() - - val body = params._body() - - assertThat(body.url()).isEqualTo("https://example.com") - assertThat(body.frameId()).contains("frameId") - assertThat(body.options()) - .contains( - SessionNavigateParams.Options.builder() - .waitUntil(SessionNavigateParams.Options.WaitUntil.LOAD) - .build() - ) - } - - @Test - fun bodyWithoutOptionalFields() { - val params = - SessionNavigateParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .url("https://example.com") - .build() - - val body = params._body() - - assertThat(body.url()).isEqualTo("https://example.com") - } -} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponseTest.kt deleted file mode 100644 index 1385964..0000000 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponseTest.kt +++ /dev/null @@ -1,36 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.jsonMapper -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class SessionNavigateResponseTest { - - @Test - fun create() { - val sessionNavigateResponse = - SessionNavigateResponse.builder().ok(true).status(0L).url("url").build() - - assertThat(sessionNavigateResponse.ok()).contains(true) - assertThat(sessionNavigateResponse.status()).contains(0L) - assertThat(sessionNavigateResponse.url()).contains("url") - } - - @Test - fun roundtrip() { - val jsonMapper = jsonMapper() - val sessionNavigateResponse = - SessionNavigateResponse.builder().ok(true).status(0L).url("url").build() - - val roundtrippedSessionNavigateResponse = - jsonMapper.readValue( - jsonMapper.writeValueAsString(sessionNavigateResponse), - jacksonTypeRef(), - ) - - assertThat(roundtrippedSessionNavigateResponse).isEqualTo(sessionNavigateResponse) - } -} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt deleted file mode 100644 index a8ab677..0000000 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt +++ /dev/null @@ -1,136 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.http.Headers -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class SessionObserveParamsTest { - - @Test - fun create() { - SessionObserveParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionObserveParams.XStreamResponse.TRUE) - .frameId("frameId") - .instruction("instruction") - .options( - SessionObserveParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .selector("selector") - .timeout(0L) - .build() - ) - .build() - } - - @Test - fun pathParams() { - val params = - SessionObserveParams.builder().sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() - - assertThat(params._pathParam(0)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - // out-of-bound path param - assertThat(params._pathParam(1)).isEqualTo("") - } - - @Test - fun headers() { - val params = - SessionObserveParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionObserveParams.XStreamResponse.TRUE) - .frameId("frameId") - .instruction("instruction") - .options( - SessionObserveParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .selector("selector") - .timeout(0L) - .build() - ) - .build() - - val headers = params._headers() - - assertThat(headers).isEqualTo(Headers.builder().put("x-stream-response", "true").build()) - } - - @Test - fun headersWithoutOptionalFields() { - val params = - SessionObserveParams.builder().sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() - - val headers = params._headers() - - assertThat(headers).isEqualTo(Headers.builder().build()) - } - - @Test - fun body() { - val params = - SessionObserveParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionObserveParams.XStreamResponse.TRUE) - .frameId("frameId") - .instruction("instruction") - .options( - SessionObserveParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .selector("selector") - .timeout(0L) - .build() - ) - .build() - - val body = params._body() - - assertThat(body.frameId()).contains("frameId") - assertThat(body.instruction()).contains("instruction") - assertThat(body.options()) - .contains( - SessionObserveParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .selector("selector") - .timeout(0L) - .build() - ) - } - - @Test - fun bodyWithoutOptionalFields() { - val params = - SessionObserveParams.builder().sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() - - val body = params._body() - } -} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt index 9454bf3..627f9ae 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt @@ -2,6 +2,8 @@ package com.browserbase.api.models.sessions +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.http.Headers import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -10,51 +12,59 @@ internal class SessionStartParamsTest { @Test fun create() { SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() } @Test - fun body() { + fun headers() { val params = SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() - val body = params._body() + val headers = params._headers() - assertThat(body.browserbaseApiKey()).isEqualTo("BROWSERBASE_API_KEY") - assertThat(body.browserbaseProjectId()).isEqualTo("BROWSERBASE_PROJECT_ID") - assertThat(body.domSettleTimeout()).contains(0L) - assertThat(body.model()).contains("openai/gpt-4o") - assertThat(body.selfHeal()).contains(true) - assertThat(body.systemPrompt()).contains("systemPrompt") - assertThat(body.verbose()).contains(1L) + assertThat(headers).isEqualTo(Headers.builder().build()) } @Test - fun bodyWithoutOptionalFields() { + fun headersWithoutOptionalFields() { + val params = SessionStartParams.builder().build() + + val headers = params._headers() + + assertThat(headers).isEqualTo(Headers.builder().build()) + } + + @Test + fun body() { val params = SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() val body = params._body() - assertThat(body.browserbaseApiKey()).isEqualTo("BROWSERBASE_API_KEY") - assertThat(body.browserbaseProjectId()).isEqualTo("BROWSERBASE_PROJECT_ID") + assertThat(body).isEqualTo(JsonValue.from(mapOf())) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = SessionStartParams.builder().build() + + val body = params._body() } } diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartResponseTest.kt index 714c73d..51616d7 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartResponseTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartResponseTest.kt @@ -11,25 +11,13 @@ internal class SessionStartResponseTest { @Test fun create() { - val sessionStartResponse = - SessionStartResponse.builder() - .available(true) - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .build() - - assertThat(sessionStartResponse.available()).isEqualTo(true) - assertThat(sessionStartResponse.sessionId()) - .isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + val sessionStartResponse = SessionStartResponse.builder().build() } @Test fun roundtrip() { val jsonMapper = jsonMapper() - val sessionStartResponse = - SessionStartResponse.builder() - .available(true) - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .build() + val sessionStartResponse = SessionStartResponse.builder().build() val roundtrippedSessionStartResponse = jsonMapper.readValue( diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt index 509b889..ccf1223 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt @@ -74,13 +74,11 @@ internal class ErrorHandlingTest { assertThrows { sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) } @@ -104,13 +102,11 @@ internal class ErrorHandlingTest { assertThrows { sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) } @@ -134,13 +130,11 @@ internal class ErrorHandlingTest { assertThrows { sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) } @@ -164,13 +158,11 @@ internal class ErrorHandlingTest { assertThrows { sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) } @@ -194,13 +186,11 @@ internal class ErrorHandlingTest { assertThrows { sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) } @@ -224,13 +214,11 @@ internal class ErrorHandlingTest { assertThrows { sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) } @@ -254,13 +242,11 @@ internal class ErrorHandlingTest { assertThrows { sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) } @@ -284,13 +270,11 @@ internal class ErrorHandlingTest { assertThrows { sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) } @@ -314,13 +298,11 @@ internal class ErrorHandlingTest { assertThrows { sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) } @@ -344,13 +326,11 @@ internal class ErrorHandlingTest { assertThrows { sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) } @@ -374,13 +354,11 @@ internal class ErrorHandlingTest { assertThrows { sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) } @@ -404,13 +382,11 @@ internal class ErrorHandlingTest { assertThrows { sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) } @@ -434,13 +410,11 @@ internal class ErrorHandlingTest { assertThrows { sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) } @@ -464,13 +438,11 @@ internal class ErrorHandlingTest { assertThrows { sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) } @@ -494,13 +466,11 @@ internal class ErrorHandlingTest { assertThrows { sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) } @@ -524,13 +494,11 @@ internal class ErrorHandlingTest { assertThrows { sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) } @@ -552,13 +520,11 @@ internal class ErrorHandlingTest { assertThrows { sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) } diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt index aa39440..8af7ae3 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt @@ -5,12 +5,9 @@ package com.browserbase.api.services import com.browserbase.api.client.StagehandClient import com.browserbase.api.client.okhttp.StagehandOkHttpClient import com.browserbase.api.core.JsonValue -import com.browserbase.api.models.sessions.ModelConfig -import com.browserbase.api.models.sessions.SessionActParams import com.browserbase.api.models.sessions.SessionStartParams import com.github.tomakehurst.wiremock.client.WireMock.anyUrl import com.github.tomakehurst.wiremock.client.WireMock.equalTo -import com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath import com.github.tomakehurst.wiremock.client.WireMock.ok import com.github.tomakehurst.wiremock.client.WireMock.post import com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor @@ -48,16 +45,13 @@ internal class ServiceParamsTest { sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .putAdditionalHeader("Secret-Header", "42") .putAdditionalQueryParam("secret_query_param", "42") - .putAdditionalBodyProperty("secretProperty", JsonValue.from("42")) .build() ) @@ -65,51 +59,6 @@ internal class ServiceParamsTest { postRequestedFor(anyUrl()) .withHeader("Secret-Header", equalTo("42")) .withQueryParam("secret_query_param", equalTo("42")) - .withRequestBody(matchingJsonPath("$.secretProperty", equalTo("42"))) - ) - } - - @Disabled("Prism tests are disabled") - @Test - fun act() { - val sessionService = client.sessions() - stubFor(post(anyUrl()).willReturn(ok("{}"))) - - sessionService.act( - SessionActParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("click the sign in button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .timeout(0L) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty("foo", JsonValue.from("string")) - .build() - ) - .build() - ) - .putAdditionalHeader("Secret-Header", "42") - .putAdditionalQueryParam("secret_query_param", "42") - .putAdditionalBodyProperty("secretProperty", JsonValue.from("42")) - .build() - ) - - verify( - postRequestedFor(anyUrl()) - .withHeader("Secret-Header", equalTo("42")) - .withQueryParam("secret_query_param", equalTo("42")) - .withRequestBody(matchingJsonPath("$.secretProperty", equalTo("42"))) ) } } diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt index d041842..57ff039 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt @@ -5,14 +5,7 @@ package com.browserbase.api.services.async import com.browserbase.api.TestServerExtension import com.browserbase.api.client.okhttp.StagehandOkHttpClientAsync import com.browserbase.api.core.JsonValue -import com.browserbase.api.models.sessions.ModelConfig -import com.browserbase.api.models.sessions.SessionActParams -import com.browserbase.api.models.sessions.SessionExecuteAgentParams -import com.browserbase.api.models.sessions.SessionExtractParams -import com.browserbase.api.models.sessions.SessionNavigateParams -import com.browserbase.api.models.sessions.SessionObserveParams import com.browserbase.api.models.sessions.SessionStartParams -import kotlin.jvm.optionals.getOrNull import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -20,225 +13,6 @@ import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) internal class SessionServiceAsyncTest { - @Disabled("Prism tests are disabled") - @Test - fun act() { - val client = - StagehandOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .browserbaseApiKey("My Browserbase API Key") - .browserbaseProjectId("My Browserbase Project ID") - .modelApiKey("My Model API Key") - .build() - val sessionServiceAsync = client.sessions() - - val responseFuture = - sessionServiceAsync.act( - SessionActParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("click the sign in button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .timeout(0L) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty("foo", JsonValue.from("string")) - .build() - ) - .build() - ) - .build() - ) - - val response = responseFuture.get() - response.validate() - } - - @Disabled("Prism tests are disabled") - @Test - fun end() { - val client = - StagehandOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .browserbaseApiKey("My Browserbase API Key") - .browserbaseProjectId("My Browserbase Project ID") - .modelApiKey("My Model API Key") - .build() - val sessionServiceAsync = client.sessions() - - val responseFuture = sessionServiceAsync.end("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - - val response = responseFuture.get() - response.validate() - } - - @Disabled("Prism tests are disabled") - @Test - fun executeAgent() { - val client = - StagehandOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .browserbaseApiKey("My Browserbase API Key") - .browserbaseProjectId("My Browserbase Project ID") - .modelApiKey("My Model API Key") - .build() - val sessionServiceAsync = client.sessions() - - val responseFuture = - sessionServiceAsync.executeAgent( - SessionExecuteAgentParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionExecuteAgentParams.XStreamResponse.TRUE) - .agentConfig( - SessionExecuteAgentParams.AgentConfig.builder() - .cua(true) - .model("openai/gpt-4o") - .provider(SessionExecuteAgentParams.AgentConfig.Provider.OPENAI) - .systemPrompt("systemPrompt") - .build() - ) - .executeOptions( - SessionExecuteAgentParams.ExecuteOptions.builder() - .instruction("Find and click the first product") - .highlightCursor(true) - .maxSteps(10L) - .build() - ) - .frameId("frameId") - .build() - ) - - val response = responseFuture.get() - response.validate() - } - - @Disabled("Prism tests are disabled") - @Test - fun extract() { - val client = - StagehandOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .browserbaseApiKey("My Browserbase API Key") - .browserbaseProjectId("My Browserbase Project ID") - .modelApiKey("My Model API Key") - .build() - val sessionServiceAsync = client.sessions() - - val responseFuture = - sessionServiceAsync.extract( - SessionExtractParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionExtractParams.XStreamResponse.TRUE) - .frameId("frameId") - .instruction("extract the page title") - .options( - SessionExtractParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .selector("selector") - .timeout(0L) - .build() - ) - .schema( - SessionExtractParams.Schema.builder() - .putAdditionalProperty("foo", JsonValue.from("bar")) - .build() - ) - .build() - ) - - val response = responseFuture.get() - response.validate() - } - - @Disabled("Prism tests are disabled") - @Test - fun navigate() { - val client = - StagehandOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .browserbaseApiKey("My Browserbase API Key") - .browserbaseProjectId("My Browserbase Project ID") - .modelApiKey("My Model API Key") - .build() - val sessionServiceAsync = client.sessions() - - val responseFuture = - sessionServiceAsync.navigate( - SessionNavigateParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionNavigateParams.XStreamResponse.TRUE) - .url("https://example.com") - .frameId("frameId") - .options( - SessionNavigateParams.Options.builder() - .waitUntil(SessionNavigateParams.Options.WaitUntil.LOAD) - .build() - ) - .build() - ) - - val response = responseFuture.get() - val unwrappedResponse = response.getOrNull() - unwrappedResponse?.validate() - } - - @Disabled("Prism tests are disabled") - @Test - fun observe() { - val client = - StagehandOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .browserbaseApiKey("My Browserbase API Key") - .browserbaseProjectId("My Browserbase Project ID") - .modelApiKey("My Model API Key") - .build() - val sessionServiceAsync = client.sessions() - - val actionsFuture = - sessionServiceAsync.observe( - SessionObserveParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionObserveParams.XStreamResponse.TRUE) - .frameId("frameId") - .instruction("instruction") - .options( - SessionObserveParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .selector("selector") - .timeout(0L) - .build() - ) - .build() - ) - - val actions = actionsFuture.get() - actions.forEach { it.validate() } - } - @Disabled("Prism tests are disabled") @Test fun start() { @@ -254,13 +28,11 @@ internal class SessionServiceAsyncTest { val responseFuture = sessionServiceAsync.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt index 10177a3..c782cd2 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt @@ -5,14 +5,7 @@ package com.browserbase.api.services.blocking import com.browserbase.api.TestServerExtension import com.browserbase.api.client.okhttp.StagehandOkHttpClient import com.browserbase.api.core.JsonValue -import com.browserbase.api.models.sessions.ModelConfig -import com.browserbase.api.models.sessions.SessionActParams -import com.browserbase.api.models.sessions.SessionExecuteAgentParams -import com.browserbase.api.models.sessions.SessionExtractParams -import com.browserbase.api.models.sessions.SessionNavigateParams -import com.browserbase.api.models.sessions.SessionObserveParams import com.browserbase.api.models.sessions.SessionStartParams -import kotlin.jvm.optionals.getOrNull import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -20,219 +13,6 @@ import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) internal class SessionServiceTest { - @Disabled("Prism tests are disabled") - @Test - fun act() { - val client = - StagehandOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .browserbaseApiKey("My Browserbase API Key") - .browserbaseProjectId("My Browserbase Project ID") - .modelApiKey("My Model API Key") - .build() - val sessionService = client.sessions() - - val response = - sessionService.act( - SessionActParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("click the sign in button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .timeout(0L) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty("foo", JsonValue.from("string")) - .build() - ) - .build() - ) - .build() - ) - - response.validate() - } - - @Disabled("Prism tests are disabled") - @Test - fun end() { - val client = - StagehandOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .browserbaseApiKey("My Browserbase API Key") - .browserbaseProjectId("My Browserbase Project ID") - .modelApiKey("My Model API Key") - .build() - val sessionService = client.sessions() - - val response = sessionService.end("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - - response.validate() - } - - @Disabled("Prism tests are disabled") - @Test - fun executeAgent() { - val client = - StagehandOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .browserbaseApiKey("My Browserbase API Key") - .browserbaseProjectId("My Browserbase Project ID") - .modelApiKey("My Model API Key") - .build() - val sessionService = client.sessions() - - val response = - sessionService.executeAgent( - SessionExecuteAgentParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionExecuteAgentParams.XStreamResponse.TRUE) - .agentConfig( - SessionExecuteAgentParams.AgentConfig.builder() - .cua(true) - .model("openai/gpt-4o") - .provider(SessionExecuteAgentParams.AgentConfig.Provider.OPENAI) - .systemPrompt("systemPrompt") - .build() - ) - .executeOptions( - SessionExecuteAgentParams.ExecuteOptions.builder() - .instruction("Find and click the first product") - .highlightCursor(true) - .maxSteps(10L) - .build() - ) - .frameId("frameId") - .build() - ) - - response.validate() - } - - @Disabled("Prism tests are disabled") - @Test - fun extract() { - val client = - StagehandOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .browserbaseApiKey("My Browserbase API Key") - .browserbaseProjectId("My Browserbase Project ID") - .modelApiKey("My Model API Key") - .build() - val sessionService = client.sessions() - - val response = - sessionService.extract( - SessionExtractParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionExtractParams.XStreamResponse.TRUE) - .frameId("frameId") - .instruction("extract the page title") - .options( - SessionExtractParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .selector("selector") - .timeout(0L) - .build() - ) - .schema( - SessionExtractParams.Schema.builder() - .putAdditionalProperty("foo", JsonValue.from("bar")) - .build() - ) - .build() - ) - - response.validate() - } - - @Disabled("Prism tests are disabled") - @Test - fun navigate() { - val client = - StagehandOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .browserbaseApiKey("My Browserbase API Key") - .browserbaseProjectId("My Browserbase Project ID") - .modelApiKey("My Model API Key") - .build() - val sessionService = client.sessions() - - val response = - sessionService.navigate( - SessionNavigateParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionNavigateParams.XStreamResponse.TRUE) - .url("https://example.com") - .frameId("frameId") - .options( - SessionNavigateParams.Options.builder() - .waitUntil(SessionNavigateParams.Options.WaitUntil.LOAD) - .build() - ) - .build() - ) - - val unwrappedResponse = response.getOrNull() - unwrappedResponse?.validate() - } - - @Disabled("Prism tests are disabled") - @Test - fun observe() { - val client = - StagehandOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .browserbaseApiKey("My Browserbase API Key") - .browserbaseProjectId("My Browserbase Project ID") - .modelApiKey("My Model API Key") - .build() - val sessionService = client.sessions() - - val actions = - sessionService.observe( - SessionObserveParams.builder() - .sessionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .xStreamResponse(SessionObserveParams.XStreamResponse.TRUE) - .frameId("frameId") - .instruction("instruction") - .options( - SessionObserveParams.Options.builder() - .model( - ModelConfig.builder() - .apiKey("apiKey") - .baseUrl("https://example.com") - .model("model") - .provider(ModelConfig.Provider.OPENAI) - .build() - ) - .selector("selector") - .timeout(0L) - .build() - ) - .build() - ) - - actions.forEach { it.validate() } - } - @Disabled("Prism tests are disabled") @Test fun start() { @@ -248,13 +28,11 @@ internal class SessionServiceTest { val response = sessionService.start( SessionStartParams.builder() - .browserbaseApiKey("BROWSERBASE_API_KEY") - .browserbaseProjectId("BROWSERBASE_PROJECT_ID") - .domSettleTimeout(0L) - .model("openai/gpt-4o") - .selfHeal(true) - .systemPrompt("systemPrompt") - .verbose(1L) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) .build() ) diff --git a/stagehand-java-proguard-test/src/test/kotlin/com/browserbase/api/proguard/ProGuardCompatibilityTest.kt b/stagehand-java-proguard-test/src/test/kotlin/com/browserbase/api/proguard/ProGuardCompatibilityTest.kt index 3960aa2..63da21d 100644 --- a/stagehand-java-proguard-test/src/test/kotlin/com/browserbase/api/proguard/ProGuardCompatibilityTest.kt +++ b/stagehand-java-proguard-test/src/test/kotlin/com/browserbase/api/proguard/ProGuardCompatibilityTest.kt @@ -5,7 +5,7 @@ package com.browserbase.api.proguard import com.browserbase.api.client.okhttp.StagehandOkHttpClient import com.browserbase.api.core.jsonMapper import com.browserbase.api.models.sessions.Action -import com.browserbase.api.models.sessions.SessionExtractResponse +import com.browserbase.api.models.sessions.ModelConfig import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import kotlin.reflect.full.memberFunctions import kotlin.reflect.jvm.javaMethod @@ -61,11 +61,10 @@ internal class ProGuardCompatibilityTest { val jsonMapper = jsonMapper() val action = Action.builder() - .addArgument("string") - .description("description") - .method("method") - .selector("selector") - .backendNodeId(0L) + .description("Click the submit button") + .selector("[data-testid='submit-button']") + .addArgument("Hello World") + .method("click") .build() val roundtrippedAction = @@ -75,19 +74,16 @@ internal class ProGuardCompatibilityTest { } @Test - fun sessionExtractResponseRoundtrip() { + fun modelConfigRoundtrip() { val jsonMapper = jsonMapper() - val sessionExtractResponse = - SessionExtractResponse.ofExtraction( - SessionExtractResponse.Extraction.builder().extraction("extraction").build() - ) + val modelConfig = ModelConfig.ofString("string") - val roundtrippedSessionExtractResponse = + val roundtrippedModelConfig = jsonMapper.readValue( - jsonMapper.writeValueAsString(sessionExtractResponse), - jacksonTypeRef(), + jsonMapper.writeValueAsString(modelConfig), + jacksonTypeRef(), ) - assertThat(roundtrippedSessionExtractResponse).isEqualTo(sessionExtractResponse) + assertThat(roundtrippedModelConfig).isEqualTo(modelConfig) } } From 653676a2e7ca92be91a6931bd293a4be2617e79d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 02:15:15 +0000 Subject: [PATCH 02/13] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index f5e93e0..855c5aa 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 1 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-516862e7e90968bc55ac44ce7ffe2d5c1f738c11757471c2b9e0e4cff9384f2c.yml -openapi_spec_hash: 19bbe52a6ae0eec7fc3f6698e831ee55 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-24dc965121b5ad70c846fd8b96ce4638d13bac7e86ba0f50a8d13a5664ac4929.yml +openapi_spec_hash: 5a8e70d2a5358bfd6917f907b4a4d1f3 config_hash: a35b56eb05306a0f02e83c11d57f975f From d7aabe36f42d8344477f2f468bd3ba15837c0516 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 02:40:24 +0000 Subject: [PATCH 03/13] feat(api): manual updates --- .stats.yml | 8 +- README.md | 14 + .../api/models/sessions/SessionActParams.kt | 267 ++++++++++ .../api/models/sessions/SessionActResponse.kt | 113 +++++ .../api/models/sessions/SessionEndParams.kt | 289 +++++++++++ .../api/models/sessions/SessionEndResponse.kt | 113 +++++ .../sessions/SessionExecuteAgentParams.kt | 269 ++++++++++ .../sessions/SessionExecuteAgentResponse.kt | 118 +++++ .../models/sessions/SessionExtractParams.kt | 267 ++++++++++ .../models/sessions/SessionExtractResponse.kt | 114 +++++ .../models/sessions/SessionNavigateParams.kt | 267 ++++++++++ .../sessions/SessionNavigateResponse.kt | 115 +++++ .../models/sessions/SessionObserveParams.kt | 269 ++++++++++ .../models/sessions/SessionObserveResponse.kt | 114 +++++ .../api/services/async/SessionServiceAsync.kt | 466 ++++++++++++++++++ .../services/async/SessionServiceAsyncImpl.kt | 240 +++++++++ .../api/services/blocking/SessionService.kt | 459 +++++++++++++++++ .../services/blocking/SessionServiceImpl.kt | 216 ++++++++ .../models/sessions/SessionActParamsTest.kt | 82 +++ .../models/sessions/SessionActResponseTest.kt | 30 ++ .../models/sessions/SessionEndParamsTest.kt | 56 +++ .../models/sessions/SessionEndResponseTest.kt | 30 ++ .../sessions/SessionExecuteAgentParamsTest.kt | 85 ++++ .../SessionExecuteAgentResponseTest.kt | 30 ++ .../sessions/SessionExtractParamsTest.kt | 82 +++ .../sessions/SessionExtractResponseTest.kt | 30 ++ .../sessions/SessionNavigateParamsTest.kt | 85 ++++ .../sessions/SessionNavigateResponseTest.kt | 30 ++ .../sessions/SessionObserveParamsTest.kt | 82 +++ .../sessions/SessionObserveResponseTest.kt | 30 ++ .../services/async/SessionServiceAsyncTest.kt | 173 +++++++ .../services/blocking/SessionServiceTest.kt | 167 +++++++ 32 files changed, 4706 insertions(+), 4 deletions(-) create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActResponse.kt create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndParams.kt create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParams.kt create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponse.kt create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractParams.kt create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractResponse.kt create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateParams.kt create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponse.kt create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveParams.kt create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveResponse.kt create mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt create mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActResponseTest.kt create mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndParamsTest.kt create mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt create mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParamsTest.kt create mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponseTest.kt create mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt create mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractResponseTest.kt create mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt create mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponseTest.kt create mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt create mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveResponseTest.kt diff --git a/.stats.yml b/.stats.yml index 855c5aa..c436ede 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 1 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-24dc965121b5ad70c846fd8b96ce4638d13bac7e86ba0f50a8d13a5664ac4929.yml -openapi_spec_hash: 5a8e70d2a5358bfd6917f907b4a4d1f3 -config_hash: a35b56eb05306a0f02e83c11d57f975f +configured_endpoints: 7 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-c1a6f03afe5d6823c198e5ac476fb688dacc783dae1fefdf6bf142084e298e16.yml +openapi_spec_hash: d20e8f697ce8d5bb80295fc1e8ce02e8 +config_hash: e457d704d820df5d25acfd379169f132 diff --git a/README.md b/README.md index ae4e26a..1bab387 100644 --- a/README.md +++ b/README.md @@ -460,6 +460,20 @@ JsonValue complexValue = JsonValue.from(Map.of( )); ``` +Normally a `Builder` class's `build` method will throw [`IllegalStateException`](https://docs.oracle.com/javase/8/docs/api/java/lang/IllegalStateException.html) if any required parameter or property is unset. + +To forcibly omit a required parameter or property, pass [`JsonMissing`](stagehand-java-core/src/main/kotlin/com/browserbase/api/core/Values.kt): + +```java +import com.browserbase.api.core.JsonMissing; +import com.browserbase.api.models.sessions.SessionActParams; +import com.browserbase.api.models.sessions.SessionStartParams; + +SessionStartParams params = SessionActParams.builder() + .id(JsonMissing.of()) + .build(); +``` + ### Response properties To access undocumented response properties, call the `_additionalProperties()` method: diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt new file mode 100644 index 0000000..9992e1f --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt @@ -0,0 +1,267 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.JsonMissing +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.Params +import com.browserbase.api.core.http.Headers +import com.browserbase.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Executes a browser action using natural language instructions or a predefined Action object. */ +class SessionActParams +private constructor( + private val id: JsonValue?, + private val xLanguage: JsonValue?, + private val xSdkVersion: JsonValue?, + private val xSentAt: JsonValue?, + private val xStreamResponse: JsonValue?, + private val body: JsonValue, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun id(): Optional = Optional.ofNullable(id) + + fun xLanguage(): Optional = Optional.ofNullable(xLanguage) + + fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) + + fun xSentAt(): Optional = Optional.ofNullable(xSentAt) + + fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) + + fun body(): JsonValue = body + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + @JvmStatic fun none(): SessionActParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [SessionActParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SessionActParams]. */ + class Builder internal constructor() { + + private var id: JsonValue? = null + private var xLanguage: JsonValue? = null + private var xSdkVersion: JsonValue? = null + private var xSentAt: JsonValue? = null + private var xStreamResponse: JsonValue? = null + private var body: JsonValue = JsonMissing.of() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(sessionActParams: SessionActParams) = apply { + id = sessionActParams.id + xLanguage = sessionActParams.xLanguage + xSdkVersion = sessionActParams.xSdkVersion + xSentAt = sessionActParams.xSentAt + xStreamResponse = sessionActParams.xStreamResponse + body = sessionActParams.body + additionalHeaders = sessionActParams.additionalHeaders.toBuilder() + additionalQueryParams = sessionActParams.additionalQueryParams.toBuilder() + } + + fun id(id: JsonValue?) = apply { this.id = id } + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + fun xLanguage(xLanguage: JsonValue?) = apply { this.xLanguage = xLanguage } + + /** Alias for calling [Builder.xLanguage] with `xLanguage.orElse(null)`. */ + fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) + + fun xSdkVersion(xSdkVersion: JsonValue?) = apply { this.xSdkVersion = xSdkVersion } + + /** Alias for calling [Builder.xSdkVersion] with `xSdkVersion.orElse(null)`. */ + fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) + + fun xSentAt(xSentAt: JsonValue?) = apply { this.xSentAt = xSentAt } + + /** Alias for calling [Builder.xSentAt] with `xSentAt.orElse(null)`. */ + fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) + + fun xStreamResponse(xStreamResponse: JsonValue?) = apply { + this.xStreamResponse = xStreamResponse + } + + /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ + fun xStreamResponse(xStreamResponse: Optional) = + xStreamResponse(xStreamResponse.getOrNull()) + + fun body(body: JsonValue) = apply { this.body = body } + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [SessionActParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): SessionActParams = + SessionActParams( + id, + xLanguage, + xSdkVersion, + xSentAt, + xStreamResponse, + body, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): JsonValue = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> id?.toString() ?: "" + else -> "" + } + + override fun _headers(): Headers = Headers.builder().apply { putAll(additionalHeaders) }.build() + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SessionActParams && + id == other.id && + xLanguage == other.xLanguage && + xSdkVersion == other.xSdkVersion && + xSentAt == other.xSentAt && + xStreamResponse == other.xStreamResponse && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash( + id, + xLanguage, + xSdkVersion, + xSentAt, + xStreamResponse, + body, + additionalHeaders, + additionalQueryParams, + ) + + override fun toString() = + "SessionActParams{id=$id, xLanguage=$xLanguage, xSdkVersion=$xSdkVersion, xSentAt=$xSentAt, xStreamResponse=$xStreamResponse, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActResponse.kt new file mode 100644 index 0000000..57b8827 --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActResponse.kt @@ -0,0 +1,113 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonValue +import com.browserbase.api.errors.StagehandInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import java.util.Collections +import java.util.Objects + +class SessionActResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor(private val additionalProperties: MutableMap) { + + @JsonCreator private constructor() : this(mutableMapOf()) + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [SessionActResponse]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SessionActResponse]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(sessionActResponse: SessionActResponse) = apply { + additionalProperties = sessionActResponse.additionalProperties.toMutableMap() + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [SessionActResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): SessionActResponse = SessionActResponse(additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): SessionActResponse = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = 0 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SessionActResponse && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "SessionActResponse{additionalProperties=$additionalProperties}" +} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndParams.kt new file mode 100644 index 0000000..02f9cb0 --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndParams.kt @@ -0,0 +1,289 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.Params +import com.browserbase.api.core.http.Headers +import com.browserbase.api.core.http.QueryParams +import com.browserbase.api.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Terminates the browser session and releases all associated resources. */ +class SessionEndParams +private constructor( + private val id: JsonValue?, + private val xLanguage: JsonValue?, + private val xSdkVersion: JsonValue?, + private val xSentAt: JsonValue?, + private val xStreamResponse: JsonValue?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun id(): Optional = Optional.ofNullable(id) + + fun xLanguage(): Optional = Optional.ofNullable(xLanguage) + + fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) + + fun xSentAt(): Optional = Optional.ofNullable(xSentAt) + + fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) + + /** Additional body properties to send with the request. */ + fun _additionalBodyProperties(): Map = additionalBodyProperties + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + @JvmStatic fun none(): SessionEndParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [SessionEndParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SessionEndParams]. */ + class Builder internal constructor() { + + private var id: JsonValue? = null + private var xLanguage: JsonValue? = null + private var xSdkVersion: JsonValue? = null + private var xSentAt: JsonValue? = null + private var xStreamResponse: JsonValue? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + private var additionalBodyProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(sessionEndParams: SessionEndParams) = apply { + id = sessionEndParams.id + xLanguage = sessionEndParams.xLanguage + xSdkVersion = sessionEndParams.xSdkVersion + xSentAt = sessionEndParams.xSentAt + xStreamResponse = sessionEndParams.xStreamResponse + additionalHeaders = sessionEndParams.additionalHeaders.toBuilder() + additionalQueryParams = sessionEndParams.additionalQueryParams.toBuilder() + additionalBodyProperties = sessionEndParams.additionalBodyProperties.toMutableMap() + } + + fun id(id: JsonValue?) = apply { this.id = id } + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + fun xLanguage(xLanguage: JsonValue?) = apply { this.xLanguage = xLanguage } + + /** Alias for calling [Builder.xLanguage] with `xLanguage.orElse(null)`. */ + fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) + + fun xSdkVersion(xSdkVersion: JsonValue?) = apply { this.xSdkVersion = xSdkVersion } + + /** Alias for calling [Builder.xSdkVersion] with `xSdkVersion.orElse(null)`. */ + fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) + + fun xSentAt(xSentAt: JsonValue?) = apply { this.xSentAt = xSentAt } + + /** Alias for calling [Builder.xSentAt] with `xSentAt.orElse(null)`. */ + fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) + + fun xStreamResponse(xStreamResponse: JsonValue?) = apply { + this.xStreamResponse = xStreamResponse + } + + /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ + fun xStreamResponse(xStreamResponse: Optional) = + xStreamResponse(xStreamResponse.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + this.additionalBodyProperties.clear() + putAllAdditionalBodyProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + additionalBodyProperties.put(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + this.additionalBodyProperties.putAll(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [SessionEndParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): SessionEndParams = + SessionEndParams( + id, + xLanguage, + xSdkVersion, + xSentAt, + xStreamResponse, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> id?.toString() ?: "" + else -> "" + } + + override fun _headers(): Headers = Headers.builder().apply { putAll(additionalHeaders) }.build() + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SessionEndParams && + id == other.id && + xLanguage == other.xLanguage && + xSdkVersion == other.xSdkVersion && + xSentAt == other.xSentAt && + xStreamResponse == other.xStreamResponse && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash( + id, + xLanguage, + xSdkVersion, + xSentAt, + xStreamResponse, + additionalHeaders, + additionalQueryParams, + additionalBodyProperties, + ) + + override fun toString() = + "SessionEndParams{id=$id, xLanguage=$xLanguage, xSdkVersion=$xSdkVersion, xSentAt=$xSentAt, xStreamResponse=$xStreamResponse, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt new file mode 100644 index 0000000..970e0fd --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt @@ -0,0 +1,113 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonValue +import com.browserbase.api.errors.StagehandInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import java.util.Collections +import java.util.Objects + +class SessionEndResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor(private val additionalProperties: MutableMap) { + + @JsonCreator private constructor() : this(mutableMapOf()) + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [SessionEndResponse]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SessionEndResponse]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(sessionEndResponse: SessionEndResponse) = apply { + additionalProperties = sessionEndResponse.additionalProperties.toMutableMap() + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [SessionEndResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): SessionEndResponse = SessionEndResponse(additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): SessionEndResponse = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = 0 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SessionEndResponse && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "SessionEndResponse{additionalProperties=$additionalProperties}" +} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParams.kt new file mode 100644 index 0000000..eca9552 --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParams.kt @@ -0,0 +1,269 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.JsonMissing +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.Params +import com.browserbase.api.core.http.Headers +import com.browserbase.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Runs an autonomous AI agent that can perform complex multi-step browser tasks. */ +class SessionExecuteAgentParams +private constructor( + private val id: JsonValue?, + private val xLanguage: JsonValue?, + private val xSdkVersion: JsonValue?, + private val xSentAt: JsonValue?, + private val xStreamResponse: JsonValue?, + private val body: JsonValue, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun id(): Optional = Optional.ofNullable(id) + + fun xLanguage(): Optional = Optional.ofNullable(xLanguage) + + fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) + + fun xSentAt(): Optional = Optional.ofNullable(xSentAt) + + fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) + + fun body(): JsonValue = body + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + @JvmStatic fun none(): SessionExecuteAgentParams = builder().build() + + /** + * Returns a mutable builder for constructing an instance of [SessionExecuteAgentParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SessionExecuteAgentParams]. */ + class Builder internal constructor() { + + private var id: JsonValue? = null + private var xLanguage: JsonValue? = null + private var xSdkVersion: JsonValue? = null + private var xSentAt: JsonValue? = null + private var xStreamResponse: JsonValue? = null + private var body: JsonValue = JsonMissing.of() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(sessionExecuteAgentParams: SessionExecuteAgentParams) = apply { + id = sessionExecuteAgentParams.id + xLanguage = sessionExecuteAgentParams.xLanguage + xSdkVersion = sessionExecuteAgentParams.xSdkVersion + xSentAt = sessionExecuteAgentParams.xSentAt + xStreamResponse = sessionExecuteAgentParams.xStreamResponse + body = sessionExecuteAgentParams.body + additionalHeaders = sessionExecuteAgentParams.additionalHeaders.toBuilder() + additionalQueryParams = sessionExecuteAgentParams.additionalQueryParams.toBuilder() + } + + fun id(id: JsonValue?) = apply { this.id = id } + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + fun xLanguage(xLanguage: JsonValue?) = apply { this.xLanguage = xLanguage } + + /** Alias for calling [Builder.xLanguage] with `xLanguage.orElse(null)`. */ + fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) + + fun xSdkVersion(xSdkVersion: JsonValue?) = apply { this.xSdkVersion = xSdkVersion } + + /** Alias for calling [Builder.xSdkVersion] with `xSdkVersion.orElse(null)`. */ + fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) + + fun xSentAt(xSentAt: JsonValue?) = apply { this.xSentAt = xSentAt } + + /** Alias for calling [Builder.xSentAt] with `xSentAt.orElse(null)`. */ + fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) + + fun xStreamResponse(xStreamResponse: JsonValue?) = apply { + this.xStreamResponse = xStreamResponse + } + + /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ + fun xStreamResponse(xStreamResponse: Optional) = + xStreamResponse(xStreamResponse.getOrNull()) + + fun body(body: JsonValue) = apply { this.body = body } + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [SessionExecuteAgentParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): SessionExecuteAgentParams = + SessionExecuteAgentParams( + id, + xLanguage, + xSdkVersion, + xSentAt, + xStreamResponse, + body, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): JsonValue = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> id?.toString() ?: "" + else -> "" + } + + override fun _headers(): Headers = Headers.builder().apply { putAll(additionalHeaders) }.build() + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SessionExecuteAgentParams && + id == other.id && + xLanguage == other.xLanguage && + xSdkVersion == other.xSdkVersion && + xSentAt == other.xSentAt && + xStreamResponse == other.xStreamResponse && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash( + id, + xLanguage, + xSdkVersion, + xSentAt, + xStreamResponse, + body, + additionalHeaders, + additionalQueryParams, + ) + + override fun toString() = + "SessionExecuteAgentParams{id=$id, xLanguage=$xLanguage, xSdkVersion=$xSdkVersion, xSentAt=$xSentAt, xStreamResponse=$xStreamResponse, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponse.kt new file mode 100644 index 0000000..700a7ba --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponse.kt @@ -0,0 +1,118 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonValue +import com.browserbase.api.errors.StagehandInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import java.util.Collections +import java.util.Objects + +class SessionExecuteAgentResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor(private val additionalProperties: MutableMap) { + + @JsonCreator private constructor() : this(mutableMapOf()) + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [SessionExecuteAgentResponse]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SessionExecuteAgentResponse]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(sessionExecuteAgentResponse: SessionExecuteAgentResponse) = apply { + additionalProperties = sessionExecuteAgentResponse.additionalProperties.toMutableMap() + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [SessionExecuteAgentResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): SessionExecuteAgentResponse = + SessionExecuteAgentResponse(additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): SessionExecuteAgentResponse = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = 0 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SessionExecuteAgentResponse && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "SessionExecuteAgentResponse{additionalProperties=$additionalProperties}" +} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractParams.kt new file mode 100644 index 0000000..18414ff --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractParams.kt @@ -0,0 +1,267 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.JsonMissing +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.Params +import com.browserbase.api.core.http.Headers +import com.browserbase.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Extracts structured data from the current page using AI-powered analysis. */ +class SessionExtractParams +private constructor( + private val id: JsonValue?, + private val xLanguage: JsonValue?, + private val xSdkVersion: JsonValue?, + private val xSentAt: JsonValue?, + private val xStreamResponse: JsonValue?, + private val body: JsonValue, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun id(): Optional = Optional.ofNullable(id) + + fun xLanguage(): Optional = Optional.ofNullable(xLanguage) + + fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) + + fun xSentAt(): Optional = Optional.ofNullable(xSentAt) + + fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) + + fun body(): JsonValue = body + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + @JvmStatic fun none(): SessionExtractParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [SessionExtractParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SessionExtractParams]. */ + class Builder internal constructor() { + + private var id: JsonValue? = null + private var xLanguage: JsonValue? = null + private var xSdkVersion: JsonValue? = null + private var xSentAt: JsonValue? = null + private var xStreamResponse: JsonValue? = null + private var body: JsonValue = JsonMissing.of() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(sessionExtractParams: SessionExtractParams) = apply { + id = sessionExtractParams.id + xLanguage = sessionExtractParams.xLanguage + xSdkVersion = sessionExtractParams.xSdkVersion + xSentAt = sessionExtractParams.xSentAt + xStreamResponse = sessionExtractParams.xStreamResponse + body = sessionExtractParams.body + additionalHeaders = sessionExtractParams.additionalHeaders.toBuilder() + additionalQueryParams = sessionExtractParams.additionalQueryParams.toBuilder() + } + + fun id(id: JsonValue?) = apply { this.id = id } + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + fun xLanguage(xLanguage: JsonValue?) = apply { this.xLanguage = xLanguage } + + /** Alias for calling [Builder.xLanguage] with `xLanguage.orElse(null)`. */ + fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) + + fun xSdkVersion(xSdkVersion: JsonValue?) = apply { this.xSdkVersion = xSdkVersion } + + /** Alias for calling [Builder.xSdkVersion] with `xSdkVersion.orElse(null)`. */ + fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) + + fun xSentAt(xSentAt: JsonValue?) = apply { this.xSentAt = xSentAt } + + /** Alias for calling [Builder.xSentAt] with `xSentAt.orElse(null)`. */ + fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) + + fun xStreamResponse(xStreamResponse: JsonValue?) = apply { + this.xStreamResponse = xStreamResponse + } + + /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ + fun xStreamResponse(xStreamResponse: Optional) = + xStreamResponse(xStreamResponse.getOrNull()) + + fun body(body: JsonValue) = apply { this.body = body } + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [SessionExtractParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): SessionExtractParams = + SessionExtractParams( + id, + xLanguage, + xSdkVersion, + xSentAt, + xStreamResponse, + body, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): JsonValue = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> id?.toString() ?: "" + else -> "" + } + + override fun _headers(): Headers = Headers.builder().apply { putAll(additionalHeaders) }.build() + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SessionExtractParams && + id == other.id && + xLanguage == other.xLanguage && + xSdkVersion == other.xSdkVersion && + xSentAt == other.xSentAt && + xStreamResponse == other.xStreamResponse && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash( + id, + xLanguage, + xSdkVersion, + xSentAt, + xStreamResponse, + body, + additionalHeaders, + additionalQueryParams, + ) + + override fun toString() = + "SessionExtractParams{id=$id, xLanguage=$xLanguage, xSdkVersion=$xSdkVersion, xSentAt=$xSentAt, xStreamResponse=$xStreamResponse, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractResponse.kt new file mode 100644 index 0000000..1e08b0f --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractResponse.kt @@ -0,0 +1,114 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonValue +import com.browserbase.api.errors.StagehandInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import java.util.Collections +import java.util.Objects + +class SessionExtractResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor(private val additionalProperties: MutableMap) { + + @JsonCreator private constructor() : this(mutableMapOf()) + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [SessionExtractResponse]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SessionExtractResponse]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(sessionExtractResponse: SessionExtractResponse) = apply { + additionalProperties = sessionExtractResponse.additionalProperties.toMutableMap() + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [SessionExtractResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): SessionExtractResponse = + SessionExtractResponse(additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): SessionExtractResponse = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = 0 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SessionExtractResponse && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "SessionExtractResponse{additionalProperties=$additionalProperties}" +} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateParams.kt new file mode 100644 index 0000000..9f282ab --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateParams.kt @@ -0,0 +1,267 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.JsonMissing +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.Params +import com.browserbase.api.core.http.Headers +import com.browserbase.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Navigates the browser to the specified URL. */ +class SessionNavigateParams +private constructor( + private val id: JsonValue?, + private val xLanguage: JsonValue?, + private val xSdkVersion: JsonValue?, + private val xSentAt: JsonValue?, + private val xStreamResponse: JsonValue?, + private val body: JsonValue, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun id(): Optional = Optional.ofNullable(id) + + fun xLanguage(): Optional = Optional.ofNullable(xLanguage) + + fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) + + fun xSentAt(): Optional = Optional.ofNullable(xSentAt) + + fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) + + fun body(): JsonValue = body + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + @JvmStatic fun none(): SessionNavigateParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [SessionNavigateParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SessionNavigateParams]. */ + class Builder internal constructor() { + + private var id: JsonValue? = null + private var xLanguage: JsonValue? = null + private var xSdkVersion: JsonValue? = null + private var xSentAt: JsonValue? = null + private var xStreamResponse: JsonValue? = null + private var body: JsonValue = JsonMissing.of() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(sessionNavigateParams: SessionNavigateParams) = apply { + id = sessionNavigateParams.id + xLanguage = sessionNavigateParams.xLanguage + xSdkVersion = sessionNavigateParams.xSdkVersion + xSentAt = sessionNavigateParams.xSentAt + xStreamResponse = sessionNavigateParams.xStreamResponse + body = sessionNavigateParams.body + additionalHeaders = sessionNavigateParams.additionalHeaders.toBuilder() + additionalQueryParams = sessionNavigateParams.additionalQueryParams.toBuilder() + } + + fun id(id: JsonValue?) = apply { this.id = id } + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + fun xLanguage(xLanguage: JsonValue?) = apply { this.xLanguage = xLanguage } + + /** Alias for calling [Builder.xLanguage] with `xLanguage.orElse(null)`. */ + fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) + + fun xSdkVersion(xSdkVersion: JsonValue?) = apply { this.xSdkVersion = xSdkVersion } + + /** Alias for calling [Builder.xSdkVersion] with `xSdkVersion.orElse(null)`. */ + fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) + + fun xSentAt(xSentAt: JsonValue?) = apply { this.xSentAt = xSentAt } + + /** Alias for calling [Builder.xSentAt] with `xSentAt.orElse(null)`. */ + fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) + + fun xStreamResponse(xStreamResponse: JsonValue?) = apply { + this.xStreamResponse = xStreamResponse + } + + /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ + fun xStreamResponse(xStreamResponse: Optional) = + xStreamResponse(xStreamResponse.getOrNull()) + + fun body(body: JsonValue) = apply { this.body = body } + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [SessionNavigateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): SessionNavigateParams = + SessionNavigateParams( + id, + xLanguage, + xSdkVersion, + xSentAt, + xStreamResponse, + body, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): JsonValue = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> id?.toString() ?: "" + else -> "" + } + + override fun _headers(): Headers = Headers.builder().apply { putAll(additionalHeaders) }.build() + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SessionNavigateParams && + id == other.id && + xLanguage == other.xLanguage && + xSdkVersion == other.xSdkVersion && + xSentAt == other.xSentAt && + xStreamResponse == other.xStreamResponse && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash( + id, + xLanguage, + xSdkVersion, + xSentAt, + xStreamResponse, + body, + additionalHeaders, + additionalQueryParams, + ) + + override fun toString() = + "SessionNavigateParams{id=$id, xLanguage=$xLanguage, xSdkVersion=$xSdkVersion, xSentAt=$xSentAt, xStreamResponse=$xStreamResponse, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponse.kt new file mode 100644 index 0000000..916d1a2 --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponse.kt @@ -0,0 +1,115 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonValue +import com.browserbase.api.errors.StagehandInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import java.util.Collections +import java.util.Objects + +class SessionNavigateResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor(private val additionalProperties: MutableMap) { + + @JsonCreator private constructor() : this(mutableMapOf()) + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [SessionNavigateResponse]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SessionNavigateResponse]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(sessionNavigateResponse: SessionNavigateResponse) = apply { + additionalProperties = sessionNavigateResponse.additionalProperties.toMutableMap() + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [SessionNavigateResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): SessionNavigateResponse = + SessionNavigateResponse(additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): SessionNavigateResponse = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = 0 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SessionNavigateResponse && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "SessionNavigateResponse{additionalProperties=$additionalProperties}" +} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveParams.kt new file mode 100644 index 0000000..3f4fb2b --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveParams.kt @@ -0,0 +1,269 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.JsonMissing +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.Params +import com.browserbase.api.core.http.Headers +import com.browserbase.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Identifies and returns available actions on the current page that match the given instruction. + */ +class SessionObserveParams +private constructor( + private val id: JsonValue?, + private val xLanguage: JsonValue?, + private val xSdkVersion: JsonValue?, + private val xSentAt: JsonValue?, + private val xStreamResponse: JsonValue?, + private val body: JsonValue, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun id(): Optional = Optional.ofNullable(id) + + fun xLanguage(): Optional = Optional.ofNullable(xLanguage) + + fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) + + fun xSentAt(): Optional = Optional.ofNullable(xSentAt) + + fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) + + fun body(): JsonValue = body + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + @JvmStatic fun none(): SessionObserveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [SessionObserveParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SessionObserveParams]. */ + class Builder internal constructor() { + + private var id: JsonValue? = null + private var xLanguage: JsonValue? = null + private var xSdkVersion: JsonValue? = null + private var xSentAt: JsonValue? = null + private var xStreamResponse: JsonValue? = null + private var body: JsonValue = JsonMissing.of() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(sessionObserveParams: SessionObserveParams) = apply { + id = sessionObserveParams.id + xLanguage = sessionObserveParams.xLanguage + xSdkVersion = sessionObserveParams.xSdkVersion + xSentAt = sessionObserveParams.xSentAt + xStreamResponse = sessionObserveParams.xStreamResponse + body = sessionObserveParams.body + additionalHeaders = sessionObserveParams.additionalHeaders.toBuilder() + additionalQueryParams = sessionObserveParams.additionalQueryParams.toBuilder() + } + + fun id(id: JsonValue?) = apply { this.id = id } + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + fun xLanguage(xLanguage: JsonValue?) = apply { this.xLanguage = xLanguage } + + /** Alias for calling [Builder.xLanguage] with `xLanguage.orElse(null)`. */ + fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) + + fun xSdkVersion(xSdkVersion: JsonValue?) = apply { this.xSdkVersion = xSdkVersion } + + /** Alias for calling [Builder.xSdkVersion] with `xSdkVersion.orElse(null)`. */ + fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) + + fun xSentAt(xSentAt: JsonValue?) = apply { this.xSentAt = xSentAt } + + /** Alias for calling [Builder.xSentAt] with `xSentAt.orElse(null)`. */ + fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) + + fun xStreamResponse(xStreamResponse: JsonValue?) = apply { + this.xStreamResponse = xStreamResponse + } + + /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ + fun xStreamResponse(xStreamResponse: Optional) = + xStreamResponse(xStreamResponse.getOrNull()) + + fun body(body: JsonValue) = apply { this.body = body } + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [SessionObserveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): SessionObserveParams = + SessionObserveParams( + id, + xLanguage, + xSdkVersion, + xSentAt, + xStreamResponse, + body, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): JsonValue = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> id?.toString() ?: "" + else -> "" + } + + override fun _headers(): Headers = Headers.builder().apply { putAll(additionalHeaders) }.build() + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SessionObserveParams && + id == other.id && + xLanguage == other.xLanguage && + xSdkVersion == other.xSdkVersion && + xSentAt == other.xSentAt && + xStreamResponse == other.xStreamResponse && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash( + id, + xLanguage, + xSdkVersion, + xSentAt, + xStreamResponse, + body, + additionalHeaders, + additionalQueryParams, + ) + + override fun toString() = + "SessionObserveParams{id=$id, xLanguage=$xLanguage, xSdkVersion=$xSdkVersion, xSentAt=$xSentAt, xStreamResponse=$xStreamResponse, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveResponse.kt new file mode 100644 index 0000000..a27fc10 --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveResponse.kt @@ -0,0 +1,114 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonValue +import com.browserbase.api.errors.StagehandInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import java.util.Collections +import java.util.Objects + +class SessionObserveResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor(private val additionalProperties: MutableMap) { + + @JsonCreator private constructor() : this(mutableMapOf()) + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [SessionObserveResponse]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SessionObserveResponse]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(sessionObserveResponse: SessionObserveResponse) = apply { + additionalProperties = sessionObserveResponse.additionalProperties.toMutableMap() + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [SessionObserveResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): SessionObserveResponse = + SessionObserveResponse(additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): SessionObserveResponse = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = 0 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SessionObserveResponse && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "SessionObserveResponse{additionalProperties=$additionalProperties}" +} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsync.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsync.kt index d481fec..435bf27 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsync.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsync.kt @@ -3,8 +3,21 @@ package com.browserbase.api.services.async import com.browserbase.api.core.ClientOptions +import com.browserbase.api.core.JsonValue import com.browserbase.api.core.RequestOptions import com.browserbase.api.core.http.HttpResponseFor +import com.browserbase.api.models.sessions.SessionActParams +import com.browserbase.api.models.sessions.SessionActResponse +import com.browserbase.api.models.sessions.SessionEndParams +import com.browserbase.api.models.sessions.SessionEndResponse +import com.browserbase.api.models.sessions.SessionExecuteAgentParams +import com.browserbase.api.models.sessions.SessionExecuteAgentResponse +import com.browserbase.api.models.sessions.SessionExtractParams +import com.browserbase.api.models.sessions.SessionExtractResponse +import com.browserbase.api.models.sessions.SessionNavigateParams +import com.browserbase.api.models.sessions.SessionNavigateResponse +import com.browserbase.api.models.sessions.SessionObserveParams +import com.browserbase.api.models.sessions.SessionObserveResponse import com.browserbase.api.models.sessions.SessionStartParams import com.browserbase.api.models.sessions.SessionStartResponse import java.util.concurrent.CompletableFuture @@ -24,6 +37,215 @@ interface SessionServiceAsync { */ fun withOptions(modifier: Consumer): SessionServiceAsync + /** + * Executes a browser action using natural language instructions or a predefined Action object. + */ + fun act(id: JsonValue): CompletableFuture = act(id, SessionActParams.none()) + + /** @see act */ + fun act( + id: JsonValue, + params: SessionActParams = SessionActParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + act(params.toBuilder().id(id).build(), requestOptions) + + /** @see act */ + fun act( + id: JsonValue, + params: SessionActParams = SessionActParams.none(), + ): CompletableFuture = act(id, params, RequestOptions.none()) + + /** @see act */ + fun act( + params: SessionActParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see act */ + fun act(params: SessionActParams): CompletableFuture = + act(params, RequestOptions.none()) + + /** @see act */ + fun act(id: JsonValue, requestOptions: RequestOptions): CompletableFuture = + act(id, SessionActParams.none(), requestOptions) + + /** Terminates the browser session and releases all associated resources. */ + fun end(id: JsonValue): CompletableFuture = end(id, SessionEndParams.none()) + + /** @see end */ + fun end( + id: JsonValue, + params: SessionEndParams = SessionEndParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + end(params.toBuilder().id(id).build(), requestOptions) + + /** @see end */ + fun end( + id: JsonValue, + params: SessionEndParams = SessionEndParams.none(), + ): CompletableFuture = end(id, params, RequestOptions.none()) + + /** @see end */ + fun end( + params: SessionEndParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see end */ + fun end(params: SessionEndParams): CompletableFuture = + end(params, RequestOptions.none()) + + /** @see end */ + fun end(id: JsonValue, requestOptions: RequestOptions): CompletableFuture = + end(id, SessionEndParams.none(), requestOptions) + + /** Runs an autonomous AI agent that can perform complex multi-step browser tasks. */ + fun executeAgent(id: JsonValue): CompletableFuture = + executeAgent(id, SessionExecuteAgentParams.none()) + + /** @see executeAgent */ + fun executeAgent( + id: JsonValue, + params: SessionExecuteAgentParams = SessionExecuteAgentParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + executeAgent(params.toBuilder().id(id).build(), requestOptions) + + /** @see executeAgent */ + fun executeAgent( + id: JsonValue, + params: SessionExecuteAgentParams = SessionExecuteAgentParams.none(), + ): CompletableFuture = + executeAgent(id, params, RequestOptions.none()) + + /** @see executeAgent */ + fun executeAgent( + params: SessionExecuteAgentParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see executeAgent */ + fun executeAgent( + params: SessionExecuteAgentParams + ): CompletableFuture = executeAgent(params, RequestOptions.none()) + + /** @see executeAgent */ + fun executeAgent( + id: JsonValue, + requestOptions: RequestOptions, + ): CompletableFuture = + executeAgent(id, SessionExecuteAgentParams.none(), requestOptions) + + /** Extracts structured data from the current page using AI-powered analysis. */ + fun extract(id: JsonValue): CompletableFuture = + extract(id, SessionExtractParams.none()) + + /** @see extract */ + fun extract( + id: JsonValue, + params: SessionExtractParams = SessionExtractParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + extract(params.toBuilder().id(id).build(), requestOptions) + + /** @see extract */ + fun extract( + id: JsonValue, + params: SessionExtractParams = SessionExtractParams.none(), + ): CompletableFuture = extract(id, params, RequestOptions.none()) + + /** @see extract */ + fun extract( + params: SessionExtractParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see extract */ + fun extract(params: SessionExtractParams): CompletableFuture = + extract(params, RequestOptions.none()) + + /** @see extract */ + fun extract( + id: JsonValue, + requestOptions: RequestOptions, + ): CompletableFuture = + extract(id, SessionExtractParams.none(), requestOptions) + + /** Navigates the browser to the specified URL. */ + fun navigate(id: JsonValue): CompletableFuture = + navigate(id, SessionNavigateParams.none()) + + /** @see navigate */ + fun navigate( + id: JsonValue, + params: SessionNavigateParams = SessionNavigateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + navigate(params.toBuilder().id(id).build(), requestOptions) + + /** @see navigate */ + fun navigate( + id: JsonValue, + params: SessionNavigateParams = SessionNavigateParams.none(), + ): CompletableFuture = navigate(id, params, RequestOptions.none()) + + /** @see navigate */ + fun navigate( + params: SessionNavigateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see navigate */ + fun navigate(params: SessionNavigateParams): CompletableFuture = + navigate(params, RequestOptions.none()) + + /** @see navigate */ + fun navigate( + id: JsonValue, + requestOptions: RequestOptions, + ): CompletableFuture = + navigate(id, SessionNavigateParams.none(), requestOptions) + + /** + * Identifies and returns available actions on the current page that match the given + * instruction. + */ + fun observe(id: JsonValue): CompletableFuture = + observe(id, SessionObserveParams.none()) + + /** @see observe */ + fun observe( + id: JsonValue, + params: SessionObserveParams = SessionObserveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + observe(params.toBuilder().id(id).build(), requestOptions) + + /** @see observe */ + fun observe( + id: JsonValue, + params: SessionObserveParams = SessionObserveParams.none(), + ): CompletableFuture = observe(id, params, RequestOptions.none()) + + /** @see observe */ + fun observe( + params: SessionObserveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see observe */ + fun observe(params: SessionObserveParams): CompletableFuture = + observe(params, RequestOptions.none()) + + /** @see observe */ + fun observe( + id: JsonValue, + requestOptions: RequestOptions, + ): CompletableFuture = + observe(id, SessionObserveParams.none(), requestOptions) + /** * Creates a new browser session with the specified configuration. Returns a session ID used for * all subsequent operations. @@ -59,6 +281,250 @@ interface SessionServiceAsync { modifier: Consumer ): SessionServiceAsync.WithRawResponse + /** + * Returns a raw HTTP response for `post /sessions/{id}/act`, but is otherwise the same as + * [SessionServiceAsync.act]. + */ + fun act(id: JsonValue): CompletableFuture> = + act(id, SessionActParams.none()) + + /** @see act */ + fun act( + id: JsonValue, + params: SessionActParams = SessionActParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + act(params.toBuilder().id(id).build(), requestOptions) + + /** @see act */ + fun act( + id: JsonValue, + params: SessionActParams = SessionActParams.none(), + ): CompletableFuture> = + act(id, params, RequestOptions.none()) + + /** @see act */ + fun act( + params: SessionActParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see act */ + fun act(params: SessionActParams): CompletableFuture> = + act(params, RequestOptions.none()) + + /** @see act */ + fun act( + id: JsonValue, + requestOptions: RequestOptions, + ): CompletableFuture> = + act(id, SessionActParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /sessions/{id}/end`, but is otherwise the same as + * [SessionServiceAsync.end]. + */ + fun end(id: JsonValue): CompletableFuture> = + end(id, SessionEndParams.none()) + + /** @see end */ + fun end( + id: JsonValue, + params: SessionEndParams = SessionEndParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + end(params.toBuilder().id(id).build(), requestOptions) + + /** @see end */ + fun end( + id: JsonValue, + params: SessionEndParams = SessionEndParams.none(), + ): CompletableFuture> = + end(id, params, RequestOptions.none()) + + /** @see end */ + fun end( + params: SessionEndParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see end */ + fun end(params: SessionEndParams): CompletableFuture> = + end(params, RequestOptions.none()) + + /** @see end */ + fun end( + id: JsonValue, + requestOptions: RequestOptions, + ): CompletableFuture> = + end(id, SessionEndParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /sessions/{id}/agentExecute`, but is otherwise the + * same as [SessionServiceAsync.executeAgent]. + */ + fun executeAgent( + id: JsonValue + ): CompletableFuture> = + executeAgent(id, SessionExecuteAgentParams.none()) + + /** @see executeAgent */ + fun executeAgent( + id: JsonValue, + params: SessionExecuteAgentParams = SessionExecuteAgentParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + executeAgent(params.toBuilder().id(id).build(), requestOptions) + + /** @see executeAgent */ + fun executeAgent( + id: JsonValue, + params: SessionExecuteAgentParams = SessionExecuteAgentParams.none(), + ): CompletableFuture> = + executeAgent(id, params, RequestOptions.none()) + + /** @see executeAgent */ + fun executeAgent( + params: SessionExecuteAgentParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see executeAgent */ + fun executeAgent( + params: SessionExecuteAgentParams + ): CompletableFuture> = + executeAgent(params, RequestOptions.none()) + + /** @see executeAgent */ + fun executeAgent( + id: JsonValue, + requestOptions: RequestOptions, + ): CompletableFuture> = + executeAgent(id, SessionExecuteAgentParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /sessions/{id}/extract`, but is otherwise the same + * as [SessionServiceAsync.extract]. + */ + fun extract(id: JsonValue): CompletableFuture> = + extract(id, SessionExtractParams.none()) + + /** @see extract */ + fun extract( + id: JsonValue, + params: SessionExtractParams = SessionExtractParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + extract(params.toBuilder().id(id).build(), requestOptions) + + /** @see extract */ + fun extract( + id: JsonValue, + params: SessionExtractParams = SessionExtractParams.none(), + ): CompletableFuture> = + extract(id, params, RequestOptions.none()) + + /** @see extract */ + fun extract( + params: SessionExtractParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see extract */ + fun extract( + params: SessionExtractParams + ): CompletableFuture> = + extract(params, RequestOptions.none()) + + /** @see extract */ + fun extract( + id: JsonValue, + requestOptions: RequestOptions, + ): CompletableFuture> = + extract(id, SessionExtractParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /sessions/{id}/navigate`, but is otherwise the same + * as [SessionServiceAsync.navigate]. + */ + fun navigate(id: JsonValue): CompletableFuture> = + navigate(id, SessionNavigateParams.none()) + + /** @see navigate */ + fun navigate( + id: JsonValue, + params: SessionNavigateParams = SessionNavigateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + navigate(params.toBuilder().id(id).build(), requestOptions) + + /** @see navigate */ + fun navigate( + id: JsonValue, + params: SessionNavigateParams = SessionNavigateParams.none(), + ): CompletableFuture> = + navigate(id, params, RequestOptions.none()) + + /** @see navigate */ + fun navigate( + params: SessionNavigateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see navigate */ + fun navigate( + params: SessionNavigateParams + ): CompletableFuture> = + navigate(params, RequestOptions.none()) + + /** @see navigate */ + fun navigate( + id: JsonValue, + requestOptions: RequestOptions, + ): CompletableFuture> = + navigate(id, SessionNavigateParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /sessions/{id}/observe`, but is otherwise the same + * as [SessionServiceAsync.observe]. + */ + fun observe(id: JsonValue): CompletableFuture> = + observe(id, SessionObserveParams.none()) + + /** @see observe */ + fun observe( + id: JsonValue, + params: SessionObserveParams = SessionObserveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + observe(params.toBuilder().id(id).build(), requestOptions) + + /** @see observe */ + fun observe( + id: JsonValue, + params: SessionObserveParams = SessionObserveParams.none(), + ): CompletableFuture> = + observe(id, params, RequestOptions.none()) + + /** @see observe */ + fun observe( + params: SessionObserveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see observe */ + fun observe( + params: SessionObserveParams + ): CompletableFuture> = + observe(params, RequestOptions.none()) + + /** @see observe */ + fun observe( + id: JsonValue, + requestOptions: RequestOptions, + ): CompletableFuture> = + observe(id, SessionObserveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /sessions/start`, but is otherwise the same as * [SessionServiceAsync.start]. diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsyncImpl.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsyncImpl.kt index 056c59c..7746896 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsyncImpl.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsyncImpl.kt @@ -15,6 +15,18 @@ import com.browserbase.api.core.http.HttpResponseFor import com.browserbase.api.core.http.json import com.browserbase.api.core.http.parseable import com.browserbase.api.core.prepareAsync +import com.browserbase.api.models.sessions.SessionActParams +import com.browserbase.api.models.sessions.SessionActResponse +import com.browserbase.api.models.sessions.SessionEndParams +import com.browserbase.api.models.sessions.SessionEndResponse +import com.browserbase.api.models.sessions.SessionExecuteAgentParams +import com.browserbase.api.models.sessions.SessionExecuteAgentResponse +import com.browserbase.api.models.sessions.SessionExtractParams +import com.browserbase.api.models.sessions.SessionExtractResponse +import com.browserbase.api.models.sessions.SessionNavigateParams +import com.browserbase.api.models.sessions.SessionNavigateResponse +import com.browserbase.api.models.sessions.SessionObserveParams +import com.browserbase.api.models.sessions.SessionObserveResponse import com.browserbase.api.models.sessions.SessionStartParams import com.browserbase.api.models.sessions.SessionStartResponse import java.util.concurrent.CompletableFuture @@ -32,6 +44,48 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl override fun withOptions(modifier: Consumer): SessionServiceAsync = SessionServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + override fun act( + params: SessionActParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /sessions/{id}/act + withRawResponse().act(params, requestOptions).thenApply { it.parse() } + + override fun end( + params: SessionEndParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /sessions/{id}/end + withRawResponse().end(params, requestOptions).thenApply { it.parse() } + + override fun executeAgent( + params: SessionExecuteAgentParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /sessions/{id}/agentExecute + withRawResponse().executeAgent(params, requestOptions).thenApply { it.parse() } + + override fun extract( + params: SessionExtractParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /sessions/{id}/extract + withRawResponse().extract(params, requestOptions).thenApply { it.parse() } + + override fun navigate( + params: SessionNavigateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /sessions/{id}/navigate + withRawResponse().navigate(params, requestOptions).thenApply { it.parse() } + + override fun observe( + params: SessionObserveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /sessions/{id}/observe + withRawResponse().observe(params, requestOptions).thenApply { it.parse() } + override fun start( params: SessionStartParams, requestOptions: RequestOptions, @@ -52,6 +106,192 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl clientOptions.toBuilder().apply(modifier::accept).build() ) + private val actHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun act( + params: SessionActParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("sessions", params._pathParam(0), "act") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { actHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val endHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun end( + params: SessionEndParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("sessions", params._pathParam(0), "end") + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { endHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val executeAgentHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun executeAgent( + params: SessionExecuteAgentParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("sessions", params._pathParam(0), "agentExecute") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { executeAgentHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val extractHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun extract( + params: SessionExtractParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("sessions", params._pathParam(0), "extract") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { extractHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val navigateHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun navigate( + params: SessionNavigateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("sessions", params._pathParam(0), "navigate") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { navigateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val observeHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun observe( + params: SessionObserveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("sessions", params._pathParam(0), "observe") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { observeHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + private val startHandler: Handler = jsonHandler(clientOptions.jsonMapper) diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionService.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionService.kt index ddd7ad3..f29cc14 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionService.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionService.kt @@ -3,8 +3,21 @@ package com.browserbase.api.services.blocking import com.browserbase.api.core.ClientOptions +import com.browserbase.api.core.JsonValue import com.browserbase.api.core.RequestOptions import com.browserbase.api.core.http.HttpResponseFor +import com.browserbase.api.models.sessions.SessionActParams +import com.browserbase.api.models.sessions.SessionActResponse +import com.browserbase.api.models.sessions.SessionEndParams +import com.browserbase.api.models.sessions.SessionEndResponse +import com.browserbase.api.models.sessions.SessionExecuteAgentParams +import com.browserbase.api.models.sessions.SessionExecuteAgentResponse +import com.browserbase.api.models.sessions.SessionExtractParams +import com.browserbase.api.models.sessions.SessionExtractResponse +import com.browserbase.api.models.sessions.SessionNavigateParams +import com.browserbase.api.models.sessions.SessionNavigateResponse +import com.browserbase.api.models.sessions.SessionObserveParams +import com.browserbase.api.models.sessions.SessionObserveResponse import com.browserbase.api.models.sessions.SessionStartParams import com.browserbase.api.models.sessions.SessionStartResponse import com.google.errorprone.annotations.MustBeClosed @@ -24,6 +37,187 @@ interface SessionService { */ fun withOptions(modifier: Consumer): SessionService + /** + * Executes a browser action using natural language instructions or a predefined Action object. + */ + fun act(id: JsonValue): SessionActResponse = act(id, SessionActParams.none()) + + /** @see act */ + fun act( + id: JsonValue, + params: SessionActParams = SessionActParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): SessionActResponse = act(params.toBuilder().id(id).build(), requestOptions) + + /** @see act */ + fun act(id: JsonValue, params: SessionActParams = SessionActParams.none()): SessionActResponse = + act(id, params, RequestOptions.none()) + + /** @see act */ + fun act( + params: SessionActParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): SessionActResponse + + /** @see act */ + fun act(params: SessionActParams): SessionActResponse = act(params, RequestOptions.none()) + + /** @see act */ + fun act(id: JsonValue, requestOptions: RequestOptions): SessionActResponse = + act(id, SessionActParams.none(), requestOptions) + + /** Terminates the browser session and releases all associated resources. */ + fun end(id: JsonValue): SessionEndResponse = end(id, SessionEndParams.none()) + + /** @see end */ + fun end( + id: JsonValue, + params: SessionEndParams = SessionEndParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): SessionEndResponse = end(params.toBuilder().id(id).build(), requestOptions) + + /** @see end */ + fun end(id: JsonValue, params: SessionEndParams = SessionEndParams.none()): SessionEndResponse = + end(id, params, RequestOptions.none()) + + /** @see end */ + fun end( + params: SessionEndParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): SessionEndResponse + + /** @see end */ + fun end(params: SessionEndParams): SessionEndResponse = end(params, RequestOptions.none()) + + /** @see end */ + fun end(id: JsonValue, requestOptions: RequestOptions): SessionEndResponse = + end(id, SessionEndParams.none(), requestOptions) + + /** Runs an autonomous AI agent that can perform complex multi-step browser tasks. */ + fun executeAgent(id: JsonValue): SessionExecuteAgentResponse = + executeAgent(id, SessionExecuteAgentParams.none()) + + /** @see executeAgent */ + fun executeAgent( + id: JsonValue, + params: SessionExecuteAgentParams = SessionExecuteAgentParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): SessionExecuteAgentResponse = executeAgent(params.toBuilder().id(id).build(), requestOptions) + + /** @see executeAgent */ + fun executeAgent( + id: JsonValue, + params: SessionExecuteAgentParams = SessionExecuteAgentParams.none(), + ): SessionExecuteAgentResponse = executeAgent(id, params, RequestOptions.none()) + + /** @see executeAgent */ + fun executeAgent( + params: SessionExecuteAgentParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): SessionExecuteAgentResponse + + /** @see executeAgent */ + fun executeAgent(params: SessionExecuteAgentParams): SessionExecuteAgentResponse = + executeAgent(params, RequestOptions.none()) + + /** @see executeAgent */ + fun executeAgent(id: JsonValue, requestOptions: RequestOptions): SessionExecuteAgentResponse = + executeAgent(id, SessionExecuteAgentParams.none(), requestOptions) + + /** Extracts structured data from the current page using AI-powered analysis. */ + fun extract(id: JsonValue): SessionExtractResponse = extract(id, SessionExtractParams.none()) + + /** @see extract */ + fun extract( + id: JsonValue, + params: SessionExtractParams = SessionExtractParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): SessionExtractResponse = extract(params.toBuilder().id(id).build(), requestOptions) + + /** @see extract */ + fun extract( + id: JsonValue, + params: SessionExtractParams = SessionExtractParams.none(), + ): SessionExtractResponse = extract(id, params, RequestOptions.none()) + + /** @see extract */ + fun extract( + params: SessionExtractParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): SessionExtractResponse + + /** @see extract */ + fun extract(params: SessionExtractParams): SessionExtractResponse = + extract(params, RequestOptions.none()) + + /** @see extract */ + fun extract(id: JsonValue, requestOptions: RequestOptions): SessionExtractResponse = + extract(id, SessionExtractParams.none(), requestOptions) + + /** Navigates the browser to the specified URL. */ + fun navigate(id: JsonValue): SessionNavigateResponse = + navigate(id, SessionNavigateParams.none()) + + /** @see navigate */ + fun navigate( + id: JsonValue, + params: SessionNavigateParams = SessionNavigateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): SessionNavigateResponse = navigate(params.toBuilder().id(id).build(), requestOptions) + + /** @see navigate */ + fun navigate( + id: JsonValue, + params: SessionNavigateParams = SessionNavigateParams.none(), + ): SessionNavigateResponse = navigate(id, params, RequestOptions.none()) + + /** @see navigate */ + fun navigate( + params: SessionNavigateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): SessionNavigateResponse + + /** @see navigate */ + fun navigate(params: SessionNavigateParams): SessionNavigateResponse = + navigate(params, RequestOptions.none()) + + /** @see navigate */ + fun navigate(id: JsonValue, requestOptions: RequestOptions): SessionNavigateResponse = + navigate(id, SessionNavigateParams.none(), requestOptions) + + /** + * Identifies and returns available actions on the current page that match the given + * instruction. + */ + fun observe(id: JsonValue): SessionObserveResponse = observe(id, SessionObserveParams.none()) + + /** @see observe */ + fun observe( + id: JsonValue, + params: SessionObserveParams = SessionObserveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): SessionObserveResponse = observe(params.toBuilder().id(id).build(), requestOptions) + + /** @see observe */ + fun observe( + id: JsonValue, + params: SessionObserveParams = SessionObserveParams.none(), + ): SessionObserveResponse = observe(id, params, RequestOptions.none()) + + /** @see observe */ + fun observe( + params: SessionObserveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): SessionObserveResponse + + /** @see observe */ + fun observe(params: SessionObserveParams): SessionObserveResponse = + observe(params, RequestOptions.none()) + + /** @see observe */ + fun observe(id: JsonValue, requestOptions: RequestOptions): SessionObserveResponse = + observe(id, SessionObserveParams.none(), requestOptions) + /** * Creates a new browser session with the specified configuration. Returns a session ID used for * all subsequent operations. @@ -54,6 +248,271 @@ interface SessionService { */ fun withOptions(modifier: Consumer): SessionService.WithRawResponse + /** + * Returns a raw HTTP response for `post /sessions/{id}/act`, but is otherwise the same as + * [SessionService.act]. + */ + @MustBeClosed + fun act(id: JsonValue): HttpResponseFor = + act(id, SessionActParams.none()) + + /** @see act */ + @MustBeClosed + fun act( + id: JsonValue, + params: SessionActParams = SessionActParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + act(params.toBuilder().id(id).build(), requestOptions) + + /** @see act */ + @MustBeClosed + fun act( + id: JsonValue, + params: SessionActParams = SessionActParams.none(), + ): HttpResponseFor = act(id, params, RequestOptions.none()) + + /** @see act */ + @MustBeClosed + fun act( + params: SessionActParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see act */ + @MustBeClosed + fun act(params: SessionActParams): HttpResponseFor = + act(params, RequestOptions.none()) + + /** @see act */ + @MustBeClosed + fun act( + id: JsonValue, + requestOptions: RequestOptions, + ): HttpResponseFor = act(id, SessionActParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /sessions/{id}/end`, but is otherwise the same as + * [SessionService.end]. + */ + @MustBeClosed + fun end(id: JsonValue): HttpResponseFor = + end(id, SessionEndParams.none()) + + /** @see end */ + @MustBeClosed + fun end( + id: JsonValue, + params: SessionEndParams = SessionEndParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + end(params.toBuilder().id(id).build(), requestOptions) + + /** @see end */ + @MustBeClosed + fun end( + id: JsonValue, + params: SessionEndParams = SessionEndParams.none(), + ): HttpResponseFor = end(id, params, RequestOptions.none()) + + /** @see end */ + @MustBeClosed + fun end( + params: SessionEndParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see end */ + @MustBeClosed + fun end(params: SessionEndParams): HttpResponseFor = + end(params, RequestOptions.none()) + + /** @see end */ + @MustBeClosed + fun end( + id: JsonValue, + requestOptions: RequestOptions, + ): HttpResponseFor = end(id, SessionEndParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /sessions/{id}/agentExecute`, but is otherwise the + * same as [SessionService.executeAgent]. + */ + @MustBeClosed + fun executeAgent(id: JsonValue): HttpResponseFor = + executeAgent(id, SessionExecuteAgentParams.none()) + + /** @see executeAgent */ + @MustBeClosed + fun executeAgent( + id: JsonValue, + params: SessionExecuteAgentParams = SessionExecuteAgentParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + executeAgent(params.toBuilder().id(id).build(), requestOptions) + + /** @see executeAgent */ + @MustBeClosed + fun executeAgent( + id: JsonValue, + params: SessionExecuteAgentParams = SessionExecuteAgentParams.none(), + ): HttpResponseFor = + executeAgent(id, params, RequestOptions.none()) + + /** @see executeAgent */ + @MustBeClosed + fun executeAgent( + params: SessionExecuteAgentParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see executeAgent */ + @MustBeClosed + fun executeAgent( + params: SessionExecuteAgentParams + ): HttpResponseFor = + executeAgent(params, RequestOptions.none()) + + /** @see executeAgent */ + @MustBeClosed + fun executeAgent( + id: JsonValue, + requestOptions: RequestOptions, + ): HttpResponseFor = + executeAgent(id, SessionExecuteAgentParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /sessions/{id}/extract`, but is otherwise the same + * as [SessionService.extract]. + */ + @MustBeClosed + fun extract(id: JsonValue): HttpResponseFor = + extract(id, SessionExtractParams.none()) + + /** @see extract */ + @MustBeClosed + fun extract( + id: JsonValue, + params: SessionExtractParams = SessionExtractParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + extract(params.toBuilder().id(id).build(), requestOptions) + + /** @see extract */ + @MustBeClosed + fun extract( + id: JsonValue, + params: SessionExtractParams = SessionExtractParams.none(), + ): HttpResponseFor = extract(id, params, RequestOptions.none()) + + /** @see extract */ + @MustBeClosed + fun extract( + params: SessionExtractParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see extract */ + @MustBeClosed + fun extract(params: SessionExtractParams): HttpResponseFor = + extract(params, RequestOptions.none()) + + /** @see extract */ + @MustBeClosed + fun extract( + id: JsonValue, + requestOptions: RequestOptions, + ): HttpResponseFor = + extract(id, SessionExtractParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /sessions/{id}/navigate`, but is otherwise the same + * as [SessionService.navigate]. + */ + @MustBeClosed + fun navigate(id: JsonValue): HttpResponseFor = + navigate(id, SessionNavigateParams.none()) + + /** @see navigate */ + @MustBeClosed + fun navigate( + id: JsonValue, + params: SessionNavigateParams = SessionNavigateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + navigate(params.toBuilder().id(id).build(), requestOptions) + + /** @see navigate */ + @MustBeClosed + fun navigate( + id: JsonValue, + params: SessionNavigateParams = SessionNavigateParams.none(), + ): HttpResponseFor = navigate(id, params, RequestOptions.none()) + + /** @see navigate */ + @MustBeClosed + fun navigate( + params: SessionNavigateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see navigate */ + @MustBeClosed + fun navigate(params: SessionNavigateParams): HttpResponseFor = + navigate(params, RequestOptions.none()) + + /** @see navigate */ + @MustBeClosed + fun navigate( + id: JsonValue, + requestOptions: RequestOptions, + ): HttpResponseFor = + navigate(id, SessionNavigateParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `post /sessions/{id}/observe`, but is otherwise the same + * as [SessionService.observe]. + */ + @MustBeClosed + fun observe(id: JsonValue): HttpResponseFor = + observe(id, SessionObserveParams.none()) + + /** @see observe */ + @MustBeClosed + fun observe( + id: JsonValue, + params: SessionObserveParams = SessionObserveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + observe(params.toBuilder().id(id).build(), requestOptions) + + /** @see observe */ + @MustBeClosed + fun observe( + id: JsonValue, + params: SessionObserveParams = SessionObserveParams.none(), + ): HttpResponseFor = observe(id, params, RequestOptions.none()) + + /** @see observe */ + @MustBeClosed + fun observe( + params: SessionObserveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see observe */ + @MustBeClosed + fun observe(params: SessionObserveParams): HttpResponseFor = + observe(params, RequestOptions.none()) + + /** @see observe */ + @MustBeClosed + fun observe( + id: JsonValue, + requestOptions: RequestOptions, + ): HttpResponseFor = + observe(id, SessionObserveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /sessions/start`, but is otherwise the same as * [SessionService.start]. diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionServiceImpl.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionServiceImpl.kt index 2a983bb..467e9db 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionServiceImpl.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionServiceImpl.kt @@ -15,6 +15,18 @@ import com.browserbase.api.core.http.HttpResponseFor import com.browserbase.api.core.http.json import com.browserbase.api.core.http.parseable import com.browserbase.api.core.prepare +import com.browserbase.api.models.sessions.SessionActParams +import com.browserbase.api.models.sessions.SessionActResponse +import com.browserbase.api.models.sessions.SessionEndParams +import com.browserbase.api.models.sessions.SessionEndResponse +import com.browserbase.api.models.sessions.SessionExecuteAgentParams +import com.browserbase.api.models.sessions.SessionExecuteAgentResponse +import com.browserbase.api.models.sessions.SessionExtractParams +import com.browserbase.api.models.sessions.SessionExtractResponse +import com.browserbase.api.models.sessions.SessionNavigateParams +import com.browserbase.api.models.sessions.SessionNavigateResponse +import com.browserbase.api.models.sessions.SessionObserveParams +import com.browserbase.api.models.sessions.SessionObserveResponse import com.browserbase.api.models.sessions.SessionStartParams import com.browserbase.api.models.sessions.SessionStartResponse import java.util.function.Consumer @@ -31,6 +43,42 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO override fun withOptions(modifier: Consumer): SessionService = SessionServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + override fun act(params: SessionActParams, requestOptions: RequestOptions): SessionActResponse = + // post /sessions/{id}/act + withRawResponse().act(params, requestOptions).parse() + + override fun end(params: SessionEndParams, requestOptions: RequestOptions): SessionEndResponse = + // post /sessions/{id}/end + withRawResponse().end(params, requestOptions).parse() + + override fun executeAgent( + params: SessionExecuteAgentParams, + requestOptions: RequestOptions, + ): SessionExecuteAgentResponse = + // post /sessions/{id}/agentExecute + withRawResponse().executeAgent(params, requestOptions).parse() + + override fun extract( + params: SessionExtractParams, + requestOptions: RequestOptions, + ): SessionExtractResponse = + // post /sessions/{id}/extract + withRawResponse().extract(params, requestOptions).parse() + + override fun navigate( + params: SessionNavigateParams, + requestOptions: RequestOptions, + ): SessionNavigateResponse = + // post /sessions/{id}/navigate + withRawResponse().navigate(params, requestOptions).parse() + + override fun observe( + params: SessionObserveParams, + requestOptions: RequestOptions, + ): SessionObserveResponse = + // post /sessions/{id}/observe + withRawResponse().observe(params, requestOptions).parse() + override fun start( params: SessionStartParams, requestOptions: RequestOptions, @@ -51,6 +99,174 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO clientOptions.toBuilder().apply(modifier::accept).build() ) + private val actHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun act( + params: SessionActParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("sessions", params._pathParam(0), "act") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { actHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val endHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun end( + params: SessionEndParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("sessions", params._pathParam(0), "end") + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { endHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val executeAgentHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun executeAgent( + params: SessionExecuteAgentParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("sessions", params._pathParam(0), "agentExecute") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { executeAgentHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val extractHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun extract( + params: SessionExtractParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("sessions", params._pathParam(0), "extract") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { extractHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val navigateHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun navigate( + params: SessionNavigateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("sessions", params._pathParam(0), "navigate") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { navigateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val observeHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun observe( + params: SessionObserveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("sessions", params._pathParam(0), "observe") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { observeHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + private val startHandler: Handler = jsonHandler(clientOptions.jsonMapper) diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt new file mode 100644 index 0000000..4b81e39 --- /dev/null +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt @@ -0,0 +1,82 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.http.Headers +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SessionActParamsTest { + + @Test + fun create() { + SessionActParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + } + + @Test + fun pathParams() { + val params = SessionActParams.builder().id(JsonValue.from(mapOf())).build() + + assertThat(params._pathParam(0)).isEqualTo("[object Object]") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun headers() { + val params = + SessionActParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + + val headers = params._headers() + + assertThat(headers).isEqualTo(Headers.builder().build()) + } + + @Test + fun headersWithoutOptionalFields() { + val params = SessionActParams.builder().id(JsonValue.from(mapOf())).build() + + val headers = params._headers() + + assertThat(headers).isEqualTo(Headers.builder().build()) + } + + @Test + fun body() { + val params = + SessionActParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + + val body = params._body() + + assertThat(body).isEqualTo(JsonValue.from(mapOf())) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = SessionActParams.builder().id(JsonValue.from(mapOf())).build() + + val body = params._body() + } +} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActResponseTest.kt new file mode 100644 index 0000000..83f3fa4 --- /dev/null +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActResponseTest.kt @@ -0,0 +1,30 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SessionActResponseTest { + + @Test + fun create() { + val sessionActResponse = SessionActResponse.builder().build() + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val sessionActResponse = SessionActResponse.builder().build() + + val roundtrippedSessionActResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(sessionActResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedSessionActResponse).isEqualTo(sessionActResponse) + } +} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndParamsTest.kt new file mode 100644 index 0000000..514fc5e --- /dev/null +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndParamsTest.kt @@ -0,0 +1,56 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.http.Headers +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SessionEndParamsTest { + + @Test + fun create() { + SessionEndParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .build() + } + + @Test + fun pathParams() { + val params = SessionEndParams.builder().id(JsonValue.from(mapOf())).build() + + assertThat(params._pathParam(0)).isEqualTo("[object Object]") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun headers() { + val params = + SessionEndParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .build() + + val headers = params._headers() + + assertThat(headers).isEqualTo(Headers.builder().build()) + } + + @Test + fun headersWithoutOptionalFields() { + val params = SessionEndParams.builder().id(JsonValue.from(mapOf())).build() + + val headers = params._headers() + + assertThat(headers).isEqualTo(Headers.builder().build()) + } +} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt new file mode 100644 index 0000000..30e45db --- /dev/null +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt @@ -0,0 +1,30 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SessionEndResponseTest { + + @Test + fun create() { + val sessionEndResponse = SessionEndResponse.builder().build() + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val sessionEndResponse = SessionEndResponse.builder().build() + + val roundtrippedSessionEndResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(sessionEndResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedSessionEndResponse).isEqualTo(sessionEndResponse) + } +} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParamsTest.kt new file mode 100644 index 0000000..90f1e1f --- /dev/null +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParamsTest.kt @@ -0,0 +1,85 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.http.Headers +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SessionExecuteAgentParamsTest { + + @Test + fun create() { + SessionExecuteAgentParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + } + + @Test + fun pathParams() { + val params = + SessionExecuteAgentParams.builder().id(JsonValue.from(mapOf())).build() + + assertThat(params._pathParam(0)).isEqualTo("[object Object]") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun headers() { + val params = + SessionExecuteAgentParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + + val headers = params._headers() + + assertThat(headers).isEqualTo(Headers.builder().build()) + } + + @Test + fun headersWithoutOptionalFields() { + val params = + SessionExecuteAgentParams.builder().id(JsonValue.from(mapOf())).build() + + val headers = params._headers() + + assertThat(headers).isEqualTo(Headers.builder().build()) + } + + @Test + fun body() { + val params = + SessionExecuteAgentParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + + val body = params._body() + + assertThat(body).isEqualTo(JsonValue.from(mapOf())) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + SessionExecuteAgentParams.builder().id(JsonValue.from(mapOf())).build() + + val body = params._body() + } +} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponseTest.kt new file mode 100644 index 0000000..0c28d46 --- /dev/null +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponseTest.kt @@ -0,0 +1,30 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SessionExecuteAgentResponseTest { + + @Test + fun create() { + val sessionExecuteAgentResponse = SessionExecuteAgentResponse.builder().build() + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val sessionExecuteAgentResponse = SessionExecuteAgentResponse.builder().build() + + val roundtrippedSessionExecuteAgentResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(sessionExecuteAgentResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedSessionExecuteAgentResponse).isEqualTo(sessionExecuteAgentResponse) + } +} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt new file mode 100644 index 0000000..e631276 --- /dev/null +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt @@ -0,0 +1,82 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.http.Headers +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SessionExtractParamsTest { + + @Test + fun create() { + SessionExtractParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + } + + @Test + fun pathParams() { + val params = SessionExtractParams.builder().id(JsonValue.from(mapOf())).build() + + assertThat(params._pathParam(0)).isEqualTo("[object Object]") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun headers() { + val params = + SessionExtractParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + + val headers = params._headers() + + assertThat(headers).isEqualTo(Headers.builder().build()) + } + + @Test + fun headersWithoutOptionalFields() { + val params = SessionExtractParams.builder().id(JsonValue.from(mapOf())).build() + + val headers = params._headers() + + assertThat(headers).isEqualTo(Headers.builder().build()) + } + + @Test + fun body() { + val params = + SessionExtractParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + + val body = params._body() + + assertThat(body).isEqualTo(JsonValue.from(mapOf())) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = SessionExtractParams.builder().id(JsonValue.from(mapOf())).build() + + val body = params._body() + } +} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractResponseTest.kt new file mode 100644 index 0000000..04bed64 --- /dev/null +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractResponseTest.kt @@ -0,0 +1,30 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SessionExtractResponseTest { + + @Test + fun create() { + val sessionExtractResponse = SessionExtractResponse.builder().build() + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val sessionExtractResponse = SessionExtractResponse.builder().build() + + val roundtrippedSessionExtractResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(sessionExtractResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedSessionExtractResponse).isEqualTo(sessionExtractResponse) + } +} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt new file mode 100644 index 0000000..6d8a60d --- /dev/null +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt @@ -0,0 +1,85 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.http.Headers +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SessionNavigateParamsTest { + + @Test + fun create() { + SessionNavigateParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + } + + @Test + fun pathParams() { + val params = + SessionNavigateParams.builder().id(JsonValue.from(mapOf())).build() + + assertThat(params._pathParam(0)).isEqualTo("[object Object]") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun headers() { + val params = + SessionNavigateParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + + val headers = params._headers() + + assertThat(headers).isEqualTo(Headers.builder().build()) + } + + @Test + fun headersWithoutOptionalFields() { + val params = + SessionNavigateParams.builder().id(JsonValue.from(mapOf())).build() + + val headers = params._headers() + + assertThat(headers).isEqualTo(Headers.builder().build()) + } + + @Test + fun body() { + val params = + SessionNavigateParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + + val body = params._body() + + assertThat(body).isEqualTo(JsonValue.from(mapOf())) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + SessionNavigateParams.builder().id(JsonValue.from(mapOf())).build() + + val body = params._body() + } +} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponseTest.kt new file mode 100644 index 0000000..6d62909 --- /dev/null +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponseTest.kt @@ -0,0 +1,30 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SessionNavigateResponseTest { + + @Test + fun create() { + val sessionNavigateResponse = SessionNavigateResponse.builder().build() + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val sessionNavigateResponse = SessionNavigateResponse.builder().build() + + val roundtrippedSessionNavigateResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(sessionNavigateResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedSessionNavigateResponse).isEqualTo(sessionNavigateResponse) + } +} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt new file mode 100644 index 0000000..8943f1d --- /dev/null +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt @@ -0,0 +1,82 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.http.Headers +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SessionObserveParamsTest { + + @Test + fun create() { + SessionObserveParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + } + + @Test + fun pathParams() { + val params = SessionObserveParams.builder().id(JsonValue.from(mapOf())).build() + + assertThat(params._pathParam(0)).isEqualTo("[object Object]") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun headers() { + val params = + SessionObserveParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + + val headers = params._headers() + + assertThat(headers).isEqualTo(Headers.builder().build()) + } + + @Test + fun headersWithoutOptionalFields() { + val params = SessionObserveParams.builder().id(JsonValue.from(mapOf())).build() + + val headers = params._headers() + + assertThat(headers).isEqualTo(Headers.builder().build()) + } + + @Test + fun body() { + val params = + SessionObserveParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + + val body = params._body() + + assertThat(body).isEqualTo(JsonValue.from(mapOf())) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = SessionObserveParams.builder().id(JsonValue.from(mapOf())).build() + + val body = params._body() + } +} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveResponseTest.kt new file mode 100644 index 0000000..b597689 --- /dev/null +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveResponseTest.kt @@ -0,0 +1,30 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SessionObserveResponseTest { + + @Test + fun create() { + val sessionObserveResponse = SessionObserveResponse.builder().build() + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val sessionObserveResponse = SessionObserveResponse.builder().build() + + val roundtrippedSessionObserveResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(sessionObserveResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedSessionObserveResponse).isEqualTo(sessionObserveResponse) + } +} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt index 57ff039..dba84aa 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt @@ -5,6 +5,12 @@ package com.browserbase.api.services.async import com.browserbase.api.TestServerExtension import com.browserbase.api.client.okhttp.StagehandOkHttpClientAsync import com.browserbase.api.core.JsonValue +import com.browserbase.api.models.sessions.SessionActParams +import com.browserbase.api.models.sessions.SessionEndParams +import com.browserbase.api.models.sessions.SessionExecuteAgentParams +import com.browserbase.api.models.sessions.SessionExtractParams +import com.browserbase.api.models.sessions.SessionNavigateParams +import com.browserbase.api.models.sessions.SessionObserveParams import com.browserbase.api.models.sessions.SessionStartParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test @@ -13,6 +19,173 @@ import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) internal class SessionServiceAsyncTest { + @Disabled("Prism tests are disabled") + @Test + fun act() { + val client = + StagehandOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionServiceAsync = client.sessions() + + val responseFuture = + sessionServiceAsync.act( + SessionActParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + ) + + val response = responseFuture.get() + response.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun end() { + val client = + StagehandOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionServiceAsync = client.sessions() + + val responseFuture = + sessionServiceAsync.end( + SessionEndParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .build() + ) + + val response = responseFuture.get() + response.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun executeAgent() { + val client = + StagehandOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionServiceAsync = client.sessions() + + val responseFuture = + sessionServiceAsync.executeAgent( + SessionExecuteAgentParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + ) + + val response = responseFuture.get() + response.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun extract() { + val client = + StagehandOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionServiceAsync = client.sessions() + + val responseFuture = + sessionServiceAsync.extract( + SessionExtractParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + ) + + val response = responseFuture.get() + response.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun navigate() { + val client = + StagehandOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionServiceAsync = client.sessions() + + val responseFuture = + sessionServiceAsync.navigate( + SessionNavigateParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + ) + + val response = responseFuture.get() + response.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun observe() { + val client = + StagehandOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionServiceAsync = client.sessions() + + val responseFuture = + sessionServiceAsync.observe( + SessionObserveParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + ) + + val response = responseFuture.get() + response.validate() + } + @Disabled("Prism tests are disabled") @Test fun start() { diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt index c782cd2..03853cd 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt @@ -5,6 +5,12 @@ package com.browserbase.api.services.blocking import com.browserbase.api.TestServerExtension import com.browserbase.api.client.okhttp.StagehandOkHttpClient import com.browserbase.api.core.JsonValue +import com.browserbase.api.models.sessions.SessionActParams +import com.browserbase.api.models.sessions.SessionEndParams +import com.browserbase.api.models.sessions.SessionExecuteAgentParams +import com.browserbase.api.models.sessions.SessionExtractParams +import com.browserbase.api.models.sessions.SessionNavigateParams +import com.browserbase.api.models.sessions.SessionObserveParams import com.browserbase.api.models.sessions.SessionStartParams import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test @@ -13,6 +19,167 @@ import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) internal class SessionServiceTest { + @Disabled("Prism tests are disabled") + @Test + fun act() { + val client = + StagehandOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionService = client.sessions() + + val response = + sessionService.act( + SessionActParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + ) + + response.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun end() { + val client = + StagehandOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionService = client.sessions() + + val response = + sessionService.end( + SessionEndParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .build() + ) + + response.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun executeAgent() { + val client = + StagehandOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionService = client.sessions() + + val response = + sessionService.executeAgent( + SessionExecuteAgentParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + ) + + response.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun extract() { + val client = + StagehandOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionService = client.sessions() + + val response = + sessionService.extract( + SessionExtractParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + ) + + response.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun navigate() { + val client = + StagehandOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionService = client.sessions() + + val response = + sessionService.navigate( + SessionNavigateParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + ) + + response.validate() + } + + @Disabled("Prism tests are disabled") + @Test + fun observe() { + val client = + StagehandOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionService = client.sessions() + + val response = + sessionService.observe( + SessionObserveParams.builder() + .id(JsonValue.from(mapOf())) + .xLanguage(JsonValue.from(mapOf())) + .xSdkVersion(JsonValue.from(mapOf())) + .xSentAt(JsonValue.from(mapOf())) + .xStreamResponse(JsonValue.from(mapOf())) + .body(JsonValue.from(mapOf())) + .build() + ) + + response.validate() + } + @Disabled("Prism tests are disabled") @Test fun start() { From 067c9e644940fa3671665a902bc605b8e358473f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 18:20:37 +0000 Subject: [PATCH 04/13] feat(api): manual updates --- .stats.yml | 6 +- README.md | 104 +- .../main/kotlin/stagehand.publish.gradle.kts | 2 +- .../api/models/sessions/SessionActParams.kt | 1547 +++- .../api/models/sessions/SessionActResponse.kt | 731 +- .../api/models/sessions/SessionEndParams.kt | 347 +- .../api/models/sessions/SessionEndResponse.kt | 193 +- .../sessions/SessionExecuteAgentParams.kt | 269 - .../sessions/SessionExecuteAgentResponse.kt | 118 - .../models/sessions/SessionExecuteParams.kt | 1403 +++ .../models/sessions/SessionExecuteResponse.kt | 1775 ++++ .../models/sessions/SessionExtractParams.kt | 1069 ++- .../models/sessions/SessionExtractResponse.kt | 395 +- .../models/sessions/SessionNavigateParams.kt | 1074 ++- .../sessions/SessionNavigateResponse.kt | 392 +- .../models/sessions/SessionObserveParams.kt | 907 +- .../models/sessions/SessionObserveResponse.kt | 439 +- .../api/models/sessions/SessionStartParams.kt | 7696 ++++++++++++++++- .../models/sessions/SessionStartResponse.kt | 428 +- .../api/services/async/SessionServiceAsync.kt | 323 +- .../services/async/SessionServiceAsyncImpl.kt | 72 +- .../api/services/blocking/SessionService.kt | 295 +- .../services/blocking/SessionServiceImpl.kt | 72 +- .../models/sessions/SessionActParamsTest.kt | 122 +- .../models/sessions/SessionActResponseTest.kt | 73 +- .../models/sessions/SessionEndParamsTest.kt | 38 +- .../models/sessions/SessionEndResponseTest.kt | 8 +- .../sessions/SessionExecuteAgentParamsTest.kt | 85 - .../SessionExecuteAgentResponseTest.kt | 30 - .../sessions/SessionExecuteParamsTest.kt | 199 + .../sessions/SessionExecuteResponseTest.kt | 151 + .../sessions/SessionExtractParamsTest.kt | 115 +- .../sessions/SessionExtractResponseTest.kt | 32 +- .../sessions/SessionNavigateParamsTest.kt | 102 +- .../sessions/SessionNavigateResponseTest.kt | 33 +- .../sessions/SessionObserveParamsTest.kt | 94 +- .../sessions/SessionObserveResponseTest.kt | 52 +- .../models/sessions/SessionStartParamsTest.kt | 607 +- .../sessions/SessionStartResponseTest.kt | 31 +- .../api/services/ErrorHandlingTest.kt | 547 +- .../api/services/ServiceParamsTest.kt | 35 +- .../services/async/SessionServiceAsyncTest.kt | 290 +- .../services/blocking/SessionServiceTest.kt | 290 +- 43 files changed, 20977 insertions(+), 1614 deletions(-) delete mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParams.kt delete mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponse.kt create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteParams.kt create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteResponse.kt delete mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParamsTest.kt delete mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponseTest.kt create mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteParamsTest.kt create mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteResponseTest.kt diff --git a/.stats.yml b/.stats.yml index c436ede..87bd24b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 7 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-c1a6f03afe5d6823c198e5ac476fb688dacc783dae1fefdf6bf142084e298e16.yml -openapi_spec_hash: d20e8f697ce8d5bb80295fc1e8ce02e8 -config_hash: e457d704d820df5d25acfd379169f132 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-349e1b0f6291eedd731c1660155a50adcb3424fb8cd9e17bbdc0939ff3bbffcd.yml +openapi_spec_hash: 456b593ea71d72bc31a6338a25363e9f +config_hash: 5f6b5ec6e84fb01932ba87c6a9623d9b diff --git a/README.md b/README.md index 1bab387..019da3c 100644 --- a/README.md +++ b/README.md @@ -48,14 +48,18 @@ This library requires Java 8 or later. ```java import com.browserbase.api.client.StagehandClient; import com.browserbase.api.client.okhttp.StagehandOkHttpClient; -import com.browserbase.api.models.sessions.SessionStartParams; -import com.browserbase.api.models.sessions.SessionStartResponse; +import com.browserbase.api.models.sessions.SessionActParams; +import com.browserbase.api.models.sessions.SessionActResponse; // Configures using the `stagehand.browserbaseApiKey`, `stagehand.browserbaseProjectId`, `stagehand.modelApiKey` and `stagehand.baseUrl` system properties // Or configures using the `BROWSERBASE_API_KEY`, `BROWSERBASE_PROJECT_ID`, `MODEL_API_KEY` and `STAGEHAND_BASE_URL` environment variables StagehandClient client = StagehandOkHttpClient.fromEnv(); -SessionStartResponse response = client.sessions().start(); +SessionActParams params = SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .input("Click the login button") + .build(); +SessionActResponse response = client.sessions().act(params); ``` ## Client configuration @@ -132,7 +136,7 @@ The `withOptions()` method does not affect the original client or service. To send a request to the Stagehand API, build an instance of some `Params` class and pass it to the corresponding client method. When the response is received, it will be deserialized into an instance of a Java class. -For example, `client.sessions().start(...)` should be called with an instance of `SessionStartParams`, and it will return an instance of `SessionStartResponse`. +For example, `client.sessions().act(...)` should be called with an instance of `SessionActParams`, and it will return an instance of `SessionActResponse`. ## Immutability @@ -149,15 +153,19 @@ The default client is synchronous. To switch to asynchronous execution, call the ```java import com.browserbase.api.client.StagehandClient; import com.browserbase.api.client.okhttp.StagehandOkHttpClient; -import com.browserbase.api.models.sessions.SessionStartParams; -import com.browserbase.api.models.sessions.SessionStartResponse; +import com.browserbase.api.models.sessions.SessionActParams; +import com.browserbase.api.models.sessions.SessionActResponse; import java.util.concurrent.CompletableFuture; // Configures using the `stagehand.browserbaseApiKey`, `stagehand.browserbaseProjectId`, `stagehand.modelApiKey` and `stagehand.baseUrl` system properties // Or configures using the `BROWSERBASE_API_KEY`, `BROWSERBASE_PROJECT_ID`, `MODEL_API_KEY` and `STAGEHAND_BASE_URL` environment variables StagehandClient client = StagehandOkHttpClient.fromEnv(); -CompletableFuture response = client.async().sessions().start(); +SessionActParams params = SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .input("Click the login button") + .build(); +CompletableFuture response = client.async().sessions().act(params); ``` Or create an asynchronous client from the beginning: @@ -165,15 +173,19 @@ Or create an asynchronous client from the beginning: ```java import com.browserbase.api.client.StagehandClientAsync; import com.browserbase.api.client.okhttp.StagehandOkHttpClientAsync; -import com.browserbase.api.models.sessions.SessionStartParams; -import com.browserbase.api.models.sessions.SessionStartResponse; +import com.browserbase.api.models.sessions.SessionActParams; +import com.browserbase.api.models.sessions.SessionActResponse; import java.util.concurrent.CompletableFuture; // Configures using the `stagehand.browserbaseApiKey`, `stagehand.browserbaseProjectId`, `stagehand.modelApiKey` and `stagehand.baseUrl` system properties // Or configures using the `BROWSERBASE_API_KEY`, `BROWSERBASE_PROJECT_ID`, `MODEL_API_KEY` and `STAGEHAND_BASE_URL` environment variables StagehandClientAsync client = StagehandOkHttpClientAsync.fromEnv(); -CompletableFuture response = client.sessions().start(); +SessionActParams params = SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .input("Click the login button") + .build(); +CompletableFuture response = client.sessions().act(params); ``` The asynchronous client supports the same options as the synchronous one, except most methods return `CompletableFuture`s. @@ -187,10 +199,14 @@ To access this data, prefix any HTTP method call on a client or service with `wi ```java import com.browserbase.api.core.http.Headers; import com.browserbase.api.core.http.HttpResponseFor; -import com.browserbase.api.models.sessions.SessionStartParams; -import com.browserbase.api.models.sessions.SessionStartResponse; +import com.browserbase.api.models.sessions.SessionActParams; +import com.browserbase.api.models.sessions.SessionActResponse; -HttpResponseFor response = client.sessions().withRawResponse().start(); +SessionActParams params = SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .input("Click the login button") + .build(); +HttpResponseFor response = client.sessions().withRawResponse().act(params); int statusCode = response.statusCode(); Headers headers = response.headers(); @@ -199,9 +215,9 @@ Headers headers = response.headers(); You can still deserialize the response into an instance of a Java class if needed: ```java -import com.browserbase.api.models.sessions.SessionStartResponse; +import com.browserbase.api.models.sessions.SessionActResponse; -SessionStartResponse parsedResponse = response.parse(); +SessionActResponse parsedResponse = response.parse(); ``` ## Error handling @@ -297,9 +313,11 @@ Requests time out after 1 minute by default. To set a custom timeout, configure the method call using the `timeout` method: ```java -import com.browserbase.api.models.sessions.SessionStartResponse; +import com.browserbase.api.models.sessions.SessionActResponse; -SessionStartResponse response = client.sessions().start(RequestOptions.builder().timeout(Duration.ofSeconds(30)).build()); +SessionActResponse response = client.sessions().act( + params, RequestOptions.builder().timeout(Duration.ofSeconds(30)).build() +); ``` Or configure the default for all method calls at the client level: @@ -402,9 +420,9 @@ To set undocumented parameters, call the `putAdditionalHeader`, `putAdditionalQu ```java import com.browserbase.api.core.JsonValue; -import com.browserbase.api.models.sessions.SessionStartParams; +import com.browserbase.api.models.sessions.SessionActParams; -SessionStartParams params = SessionStartParams.builder() +SessionActParams params = SessionActParams.builder() .putAdditionalHeader("Secret-Header", "42") .putAdditionalQueryParam("secret_query_param", "42") .putAdditionalBodyProperty("secretProperty", JsonValue.from("42")) @@ -413,12 +431,29 @@ SessionStartParams params = SessionStartParams.builder() These can be accessed on the built object later using the `_additionalHeaders()`, `_additionalQueryParams()`, and `_additionalBodyProperties()` methods. +To set undocumented parameters on _nested_ headers, query params, or body classes, call the `putAdditionalProperty` method on the nested class: + +```java +import com.browserbase.api.core.JsonValue; +import com.browserbase.api.models.sessions.SessionActParams; + +SessionActParams params = SessionActParams.builder() + .options(SessionActParams.Options.builder() + .putAdditionalProperty("secretProperty", JsonValue.from("42")) + .build()) + .build(); +``` + +These properties can be accessed on the nested built object later using the `_additionalProperties()` method. + To set a documented parameter or property to an undocumented or not yet supported _value_, pass a [`JsonValue`](stagehand-java-core/src/main/kotlin/com/browserbase/api/core/Values.kt) object to its setter: ```java -import com.browserbase.api.models.sessions.SessionStartParams; +import com.browserbase.api.models.sessions.SessionActParams; -SessionStartParams params = SessionStartParams.builder().build(); +SessionActParams params = SessionActParams.builder() + .input("Click the login button") + .build(); ``` The most straightforward way to create a [`JsonValue`](stagehand-java-core/src/main/kotlin/com/browserbase/api/core/Values.kt) is using its `from(...)` method: @@ -467,9 +502,9 @@ To forcibly omit a required parameter or property, pass [`JsonMissing`](stagehan ```java import com.browserbase.api.core.JsonMissing; import com.browserbase.api.models.sessions.SessionActParams; -import com.browserbase.api.models.sessions.SessionStartParams; -SessionStartParams params = SessionActParams.builder() +SessionActParams params = SessionActParams.builder() + .input("Click the login button") .id(JsonMissing.of()) .build(); ``` @@ -482,7 +517,7 @@ To access undocumented response properties, call the `_additionalProperties()` m import com.browserbase.api.core.JsonValue; import java.util.Map; -Map additionalProperties = client.sessions().start(params)._additionalProperties(); +Map additionalProperties = client.sessions().act(params)._additionalProperties(); JsonValue secretPropertyValue = additionalProperties.get("secretProperty"); String result = secretPropertyValue.accept(new JsonValue.Visitor<>() { @@ -510,21 +545,22 @@ To access a property's raw JSON value, which may be undocumented, call its `_` p ```java import com.browserbase.api.core.JsonField; +import com.browserbase.api.models.sessions.SessionActParams; import java.util.Optional; -JsonField field = client.sessions().start(params)._field(); +JsonField input = client.sessions().act(params)._input(); -if (field.isMissing()) { +if (input.isMissing()) { // The property is absent from the JSON response -} else if (field.isNull()) { +} else if (input.isNull()) { // The property was set to literal null } else { // Check if value was provided as a string // Other methods include `asNumber()`, `asBoolean()`, etc. - Optional jsonString = field.asString(); + Optional jsonString = input.asString(); // Try to deserialize into a custom type - MyClass myObject = field.asUnknown().orElseThrow().convert(MyClass.class); + MyClass myObject = input.asUnknown().orElseThrow().convert(MyClass.class); } ``` @@ -537,17 +573,19 @@ By default, the SDK will not throw an exception in this case. It will throw [`St If you would prefer to check that the response is completely well-typed upfront, then either call `validate()`: ```java -import com.browserbase.api.models.sessions.SessionStartResponse; +import com.browserbase.api.models.sessions.SessionActResponse; -SessionStartResponse response = client.sessions().start(params).validate(); +SessionActResponse response = client.sessions().act(params).validate(); ``` Or configure the method call to validate the response using the `responseValidation` method: ```java -import com.browserbase.api.models.sessions.SessionStartResponse; +import com.browserbase.api.models.sessions.SessionActResponse; -SessionStartResponse response = client.sessions().start(RequestOptions.builder().responseValidation(true).build()); +SessionActResponse response = client.sessions().act( + params, RequestOptions.builder().responseValidation(true).build() +); ``` Or configure the default for all method calls at the client level: diff --git a/buildSrc/src/main/kotlin/stagehand.publish.gradle.kts b/buildSrc/src/main/kotlin/stagehand.publish.gradle.kts index 7b0ce3f..796aad4 100644 --- a/buildSrc/src/main/kotlin/stagehand.publish.gradle.kts +++ b/buildSrc/src/main/kotlin/stagehand.publish.gradle.kts @@ -10,7 +10,7 @@ configure { pom { name.set("Stagehand API") - description.set("Stagehand SDK for AI browser automation [ALPHA]. This API allows clients to\nexecute browser automation tasks remotely on the Browserbase cloud.\n\nAll endpoints except /sessions/start require an active session ID. Responses are\nstreamed using Server-Sent Events (SSE) when the `x-stream-response: true`\nheader is provided.\n\nThis SDK is currently ALPHA software and is not production ready! Please try it\nand give us your feedback, stay tuned for upcoming release announcements!") + description.set("Stagehand SDK for AI browser automation [ALPHA].") url.set("https://docs.stagehand.dev") licenses { diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt index 9992e1f..7e98b5d 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt @@ -2,11 +2,36 @@ package com.browserbase.api.models.sessions +import com.browserbase.api.core.BaseDeserializer +import com.browserbase.api.core.BaseSerializer +import com.browserbase.api.core.Enum +import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonField import com.browserbase.api.core.JsonMissing import com.browserbase.api.core.JsonValue import com.browserbase.api.core.Params +import com.browserbase.api.core.allMaxBy +import com.browserbase.api.core.checkKnown +import com.browserbase.api.core.checkRequired +import com.browserbase.api.core.getOrThrow import com.browserbase.api.core.http.Headers import com.browserbase.api.core.http.QueryParams +import com.browserbase.api.core.toImmutable +import com.browserbase.api.errors.StagehandInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.time.OffsetDateTime +import java.time.format.DateTimeFormatter +import java.util.Collections import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull @@ -14,27 +39,75 @@ import kotlin.jvm.optionals.getOrNull /** Executes a browser action using natural language instructions or a predefined Action object. */ class SessionActParams private constructor( - private val id: JsonValue?, - private val xLanguage: JsonValue?, - private val xSdkVersion: JsonValue?, - private val xSentAt: JsonValue?, - private val xStreamResponse: JsonValue?, - private val body: JsonValue, + private val id: String?, + private val xLanguage: XLanguage?, + private val xSdkVersion: String?, + private val xSentAt: OffsetDateTime?, + private val xStreamResponse: XStreamResponse?, + private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun id(): Optional = Optional.ofNullable(id) + /** Unique session identifier */ + fun id(): Optional = Optional.ofNullable(id) - fun xLanguage(): Optional = Optional.ofNullable(xLanguage) + /** Client SDK language */ + fun xLanguage(): Optional = Optional.ofNullable(xLanguage) - fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) + /** Version of the Stagehand SDK */ + fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) - fun xSentAt(): Optional = Optional.ofNullable(xSentAt) + /** ISO timestamp when request was sent */ + fun xSentAt(): Optional = Optional.ofNullable(xSentAt) - fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) + /** Whether to stream the response via SSE */ + fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) - fun body(): JsonValue = body + /** + * Natural language instruction or Action object + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun input(): Input = body.input() + + /** + * Target frame ID for the action + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun frameId(): Optional = body.frameId() + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun options(): Optional = body.options() + + /** + * Returns the raw JSON value of [input]. + * + * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _input(): JsonField = body._input() + + /** + * Returns the raw JSON value of [frameId]. + * + * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _frameId(): JsonField = body._frameId() + + /** + * Returns the raw JSON value of [options]. + * + * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _options(): JsonField = body._options() + + fun _additionalBodyProperties(): Map = body._additionalProperties() /** Additional headers to send with the request. */ fun _additionalHeaders(): Headers = additionalHeaders @@ -46,21 +119,26 @@ private constructor( companion object { - @JvmStatic fun none(): SessionActParams = builder().build() - - /** Returns a mutable builder for constructing an instance of [SessionActParams]. */ + /** + * Returns a mutable builder for constructing an instance of [SessionActParams]. + * + * The following fields are required: + * ```java + * .input() + * ``` + */ @JvmStatic fun builder() = Builder() } /** A builder for [SessionActParams]. */ class Builder internal constructor() { - private var id: JsonValue? = null - private var xLanguage: JsonValue? = null - private var xSdkVersion: JsonValue? = null - private var xSentAt: JsonValue? = null - private var xStreamResponse: JsonValue? = null - private var body: JsonValue = JsonMissing.of() + private var id: String? = null + private var xLanguage: XLanguage? = null + private var xSdkVersion: String? = null + private var xSentAt: OffsetDateTime? = null + private var xStreamResponse: XStreamResponse? = null + private var body: Body.Builder = Body.builder() private var additionalHeaders: Headers.Builder = Headers.builder() private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @@ -71,40 +149,111 @@ private constructor( xSdkVersion = sessionActParams.xSdkVersion xSentAt = sessionActParams.xSentAt xStreamResponse = sessionActParams.xStreamResponse - body = sessionActParams.body + body = sessionActParams.body.toBuilder() additionalHeaders = sessionActParams.additionalHeaders.toBuilder() additionalQueryParams = sessionActParams.additionalQueryParams.toBuilder() } - fun id(id: JsonValue?) = apply { this.id = id } + /** Unique session identifier */ + fun id(id: String?) = apply { this.id = id } /** Alias for calling [Builder.id] with `id.orElse(null)`. */ - fun id(id: Optional) = id(id.getOrNull()) + fun id(id: Optional) = id(id.getOrNull()) - fun xLanguage(xLanguage: JsonValue?) = apply { this.xLanguage = xLanguage } + /** Client SDK language */ + fun xLanguage(xLanguage: XLanguage?) = apply { this.xLanguage = xLanguage } /** Alias for calling [Builder.xLanguage] with `xLanguage.orElse(null)`. */ - fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) + fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) - fun xSdkVersion(xSdkVersion: JsonValue?) = apply { this.xSdkVersion = xSdkVersion } + /** Version of the Stagehand SDK */ + fun xSdkVersion(xSdkVersion: String?) = apply { this.xSdkVersion = xSdkVersion } /** Alias for calling [Builder.xSdkVersion] with `xSdkVersion.orElse(null)`. */ - fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) + fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) - fun xSentAt(xSentAt: JsonValue?) = apply { this.xSentAt = xSentAt } + /** ISO timestamp when request was sent */ + fun xSentAt(xSentAt: OffsetDateTime?) = apply { this.xSentAt = xSentAt } /** Alias for calling [Builder.xSentAt] with `xSentAt.orElse(null)`. */ - fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) + fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) - fun xStreamResponse(xStreamResponse: JsonValue?) = apply { + /** Whether to stream the response via SSE */ + fun xStreamResponse(xStreamResponse: XStreamResponse?) = apply { this.xStreamResponse = xStreamResponse } /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ - fun xStreamResponse(xStreamResponse: Optional) = + fun xStreamResponse(xStreamResponse: Optional) = xStreamResponse(xStreamResponse.getOrNull()) - fun body(body: JsonValue) = apply { this.body = body } + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [input] + * - [frameId] + * - [options] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** Natural language instruction or Action object */ + fun input(input: Input) = apply { body.input(input) } + + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed [Input] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun input(input: JsonField) = apply { body.input(input) } + + /** Alias for calling [input] with `Input.ofString(string)`. */ + fun input(string: String) = apply { body.input(string) } + + /** Alias for calling [input] with `Input.ofAction(action)`. */ + fun input(action: Input.ActionInput) = apply { body.input(action) } + + /** Target frame ID for the action */ + fun frameId(frameId: String) = apply { body.frameId(frameId) } + + /** + * Sets [Builder.frameId] to an arbitrary JSON value. + * + * You should usually call [Builder.frameId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun frameId(frameId: JsonField) = apply { body.frameId(frameId) } + + fun options(options: Options) = apply { body.options(options) } + + /** + * Sets [Builder.options] to an arbitrary JSON value. + * + * You should usually call [Builder.options] with a well-typed [Options] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun options(options: JsonField) = apply { body.options(options) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -208,6 +357,13 @@ private constructor( * Returns an immutable instance of [SessionActParams]. * * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .input() + * ``` + * + * @throws IllegalStateException if any required field is unset. */ fun build(): SessionActParams = SessionActParams( @@ -216,24 +372,1341 @@ private constructor( xSdkVersion, xSentAt, xStreamResponse, - body, + body.build(), additionalHeaders.build(), additionalQueryParams.build(), ) } - fun _body(): JsonValue = body + fun _body(): Body = body fun _pathParam(index: Int): String = when (index) { - 0 -> id?.toString() ?: "" + 0 -> id ?: "" else -> "" } - override fun _headers(): Headers = Headers.builder().apply { putAll(additionalHeaders) }.build() + override fun _headers(): Headers = + Headers.builder() + .apply { + xLanguage?.let { put("x-language", it.toString()) } + xSdkVersion?.let { put("x-sdk-version", it) } + xSentAt?.let { put("x-sent-at", DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(it)) } + xStreamResponse?.let { put("x-stream-response", it.toString()) } + putAll(additionalHeaders) + } + .build() override fun _queryParams(): QueryParams = additionalQueryParams + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val input: JsonField, + private val frameId: JsonField, + private val options: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("input") @ExcludeMissing input: JsonField = JsonMissing.of(), + @JsonProperty("frameId") @ExcludeMissing frameId: JsonField = JsonMissing.of(), + @JsonProperty("options") @ExcludeMissing options: JsonField = JsonMissing.of(), + ) : this(input, frameId, options, mutableMapOf()) + + /** + * Natural language instruction or Action object + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun input(): Input = input.getRequired("input") + + /** + * Target frame ID for the action + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun frameId(): Optional = frameId.getOptional("frameId") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun options(): Optional = options.getOptional("options") + + /** + * Returns the raw JSON value of [input]. + * + * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("input") @ExcludeMissing fun _input(): JsonField = input + + /** + * Returns the raw JSON value of [frameId]. + * + * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("frameId") @ExcludeMissing fun _frameId(): JsonField = frameId + + /** + * Returns the raw JSON value of [options]. + * + * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("options") @ExcludeMissing fun _options(): JsonField = options + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .input() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var input: JsonField? = null + private var frameId: JsonField = JsonMissing.of() + private var options: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + input = body.input + frameId = body.frameId + options = body.options + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** Natural language instruction or Action object */ + fun input(input: Input) = input(JsonField.of(input)) + + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed [Input] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun input(input: JsonField) = apply { this.input = input } + + /** Alias for calling [input] with `Input.ofString(string)`. */ + fun input(string: String) = input(Input.ofString(string)) + + /** Alias for calling [input] with `Input.ofAction(action)`. */ + fun input(action: Input.ActionInput) = input(Input.ofAction(action)) + + /** Target frame ID for the action */ + fun frameId(frameId: String) = frameId(JsonField.of(frameId)) + + /** + * Sets [Builder.frameId] to an arbitrary JSON value. + * + * You should usually call [Builder.frameId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun frameId(frameId: JsonField) = apply { this.frameId = frameId } + + fun options(options: Options) = options(JsonField.of(options)) + + /** + * Sets [Builder.options] to an arbitrary JSON value. + * + * You should usually call [Builder.options] with a well-typed [Options] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun options(options: JsonField) = apply { this.options = options } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .input() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("input", input), + frameId, + options, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + input().validate() + frameId() + options().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (input.asKnown().getOrNull()?.validity() ?: 0) + + (if (frameId.asKnown().isPresent) 1 else 0) + + (options.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + input == other.input && + frameId == other.frameId && + options == other.options && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(input, frameId, options, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{input=$input, frameId=$frameId, options=$options, additionalProperties=$additionalProperties}" + } + + /** Natural language instruction or Action object */ + @JsonDeserialize(using = Input.Deserializer::class) + @JsonSerialize(using = Input.Serializer::class) + class Input + private constructor( + private val string: String? = null, + private val action: ActionInput? = null, + private val _json: JsonValue? = null, + ) { + + fun string(): Optional = Optional.ofNullable(string) + + /** Action object returned by observe and used by act */ + fun action(): Optional = Optional.ofNullable(action) + + fun isString(): Boolean = string != null + + fun isAction(): Boolean = action != null + + fun asString(): String = string.getOrThrow("string") + + /** Action object returned by observe and used by act */ + fun asAction(): ActionInput = action.getOrThrow("action") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + string != null -> visitor.visitString(string) + action != null -> visitor.visitAction(action) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): Input = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitString(string: String) {} + + override fun visitAction(action: ActionInput) { + action.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitString(string: String) = 1 + + override fun visitAction(action: ActionInput) = action.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Input && string == other.string && action == other.action + } + + override fun hashCode(): Int = Objects.hash(string, action) + + override fun toString(): String = + when { + string != null -> "Input{string=$string}" + action != null -> "Input{action=$action}" + _json != null -> "Input{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Input") + } + + companion object { + + @JvmStatic fun ofString(string: String) = Input(string = string) + + /** Action object returned by observe and used by act */ + @JvmStatic fun ofAction(action: ActionInput) = Input(action = action) + } + + /** An interface that defines how to map each variant of [Input] to a value of type [T]. */ + interface Visitor { + + fun visitString(string: String): T + + /** Action object returned by observe and used by act */ + fun visitAction(action: ActionInput): T + + /** + * Maps an unknown variant of [Input] to a value of type [T]. + * + * An instance of [Input] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws StagehandInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw StagehandInvalidDataException("Unknown Input: $json") + } + } + + internal class Deserializer : BaseDeserializer(Input::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Input { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + Input(action = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Input(string = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from array). + 0 -> Input(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Input::class) { + + override fun serialize( + value: Input, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.string != null -> generator.writeObject(value.string) + value.action != null -> generator.writeObject(value.action) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Input") + } + } + } + + /** Action object returned by observe and used by act */ + class ActionInput + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val description: JsonField, + private val selector: JsonField, + private val arguments: JsonField>, + private val method: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("description") + @ExcludeMissing + description: JsonField = JsonMissing.of(), + @JsonProperty("selector") + @ExcludeMissing + selector: JsonField = JsonMissing.of(), + @JsonProperty("arguments") + @ExcludeMissing + arguments: JsonField> = JsonMissing.of(), + @JsonProperty("method") @ExcludeMissing method: JsonField = JsonMissing.of(), + ) : this(description, selector, arguments, method, mutableMapOf()) + + /** + * Human-readable description of the action + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun description(): String = description.getRequired("description") + + /** + * CSS selector or XPath for the element + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun selector(): String = selector.getRequired("selector") + + /** + * Arguments to pass to the method + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun arguments(): Optional> = arguments.getOptional("arguments") + + /** + * The method to execute (click, fill, etc.) + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun method(): Optional = method.getOptional("method") + + /** + * Returns the raw JSON value of [description]. + * + * Unlike [description], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("description") + @ExcludeMissing + fun _description(): JsonField = description + + /** + * Returns the raw JSON value of [selector]. + * + * Unlike [selector], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("selector") @ExcludeMissing fun _selector(): JsonField = selector + + /** + * Returns the raw JSON value of [arguments]. + * + * Unlike [arguments], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("arguments") + @ExcludeMissing + fun _arguments(): JsonField> = arguments + + /** + * Returns the raw JSON value of [method]. + * + * Unlike [method], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("method") @ExcludeMissing fun _method(): JsonField = method + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ActionInput]. + * + * The following fields are required: + * ```java + * .description() + * .selector() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ActionInput]. */ + class Builder internal constructor() { + + private var description: JsonField? = null + private var selector: JsonField? = null + private var arguments: JsonField>? = null + private var method: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(actionInput: ActionInput) = apply { + description = actionInput.description + selector = actionInput.selector + arguments = actionInput.arguments.map { it.toMutableList() } + method = actionInput.method + additionalProperties = actionInput.additionalProperties.toMutableMap() + } + + /** Human-readable description of the action */ + fun description(description: String) = description(JsonField.of(description)) + + /** + * Sets [Builder.description] to an arbitrary JSON value. + * + * You should usually call [Builder.description] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun description(description: JsonField) = apply { + this.description = description + } + + /** CSS selector or XPath for the element */ + fun selector(selector: String) = selector(JsonField.of(selector)) + + /** + * Sets [Builder.selector] to an arbitrary JSON value. + * + * You should usually call [Builder.selector] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun selector(selector: JsonField) = apply { this.selector = selector } + + /** Arguments to pass to the method */ + fun arguments(arguments: List) = arguments(JsonField.of(arguments)) + + /** + * Sets [Builder.arguments] to an arbitrary JSON value. + * + * You should usually call [Builder.arguments] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun arguments(arguments: JsonField>) = apply { + this.arguments = arguments.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [arguments]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addArgument(argument: String) = apply { + arguments = + (arguments ?: JsonField.of(mutableListOf())).also { + checkKnown("arguments", it).add(argument) + } + } + + /** The method to execute (click, fill, etc.) */ + fun method(method: String) = method(JsonField.of(method)) + + /** + * Sets [Builder.method] to an arbitrary JSON value. + * + * You should usually call [Builder.method] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun method(method: JsonField) = apply { this.method = method } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ActionInput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .description() + * .selector() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ActionInput = + ActionInput( + checkRequired("description", description), + checkRequired("selector", selector), + (arguments ?: JsonMissing.of()).map { it.toImmutable() }, + method, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ActionInput = apply { + if (validated) { + return@apply + } + + description() + selector() + arguments() + method() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (description.asKnown().isPresent) 1 else 0) + + (if (selector.asKnown().isPresent) 1 else 0) + + (arguments.asKnown().getOrNull()?.size ?: 0) + + (if (method.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ActionInput && + description == other.description && + selector == other.selector && + arguments == other.arguments && + method == other.method && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(description, selector, arguments, method, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ActionInput{description=$description, selector=$selector, arguments=$arguments, method=$method, additionalProperties=$additionalProperties}" + } + } + + class Options + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val model: JsonField, + private val timeout: JsonField, + private val variables: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), + @JsonProperty("timeout") @ExcludeMissing timeout: JsonField = JsonMissing.of(), + @JsonProperty("variables") + @ExcludeMissing + variables: JsonField = JsonMissing.of(), + ) : this(model, timeout, variables, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun model(): Optional = model.getOptional("model") + + /** + * Timeout in ms for the action + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun timeout(): Optional = timeout.getOptional("timeout") + + /** + * Variables to substitute in the action instruction + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun variables(): Optional = variables.getOptional("variables") + + /** + * Returns the raw JSON value of [model]. + * + * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model + + /** + * Returns the raw JSON value of [timeout]. + * + * Unlike [timeout], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("timeout") @ExcludeMissing fun _timeout(): JsonField = timeout + + /** + * Returns the raw JSON value of [variables]. + * + * Unlike [variables], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("variables") + @ExcludeMissing + fun _variables(): JsonField = variables + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Options]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Options]. */ + class Builder internal constructor() { + + private var model: JsonField = JsonMissing.of() + private var timeout: JsonField = JsonMissing.of() + private var variables: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(options: Options) = apply { + model = options.model + timeout = options.timeout + variables = options.variables + additionalProperties = options.additionalProperties.toMutableMap() + } + + fun model(model: ModelConfig) = model(JsonField.of(model)) + + /** + * Sets [Builder.model] to an arbitrary JSON value. + * + * You should usually call [Builder.model] with a well-typed [ModelConfig] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun model(model: JsonField) = apply { this.model = model } + + /** Alias for calling [model] with `ModelConfig.ofString(string)`. */ + fun model(string: String) = model(ModelConfig.ofString(string)) + + /** Alias for calling [model] with `ModelConfig.ofUnionMember1(unionMember1)`. */ + fun model(unionMember1: ModelConfig.UnionMember1) = + model(ModelConfig.ofUnionMember1(unionMember1)) + + /** Timeout in ms for the action */ + fun timeout(timeout: Double) = timeout(JsonField.of(timeout)) + + /** + * Sets [Builder.timeout] to an arbitrary JSON value. + * + * You should usually call [Builder.timeout] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun timeout(timeout: JsonField) = apply { this.timeout = timeout } + + /** Variables to substitute in the action instruction */ + fun variables(variables: Variables) = variables(JsonField.of(variables)) + + /** + * Sets [Builder.variables] to an arbitrary JSON value. + * + * You should usually call [Builder.variables] with a well-typed [Variables] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun variables(variables: JsonField) = apply { this.variables = variables } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Options]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Options = + Options(model, timeout, variables, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Options = apply { + if (validated) { + return@apply + } + + model().ifPresent { it.validate() } + timeout() + variables().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (model.asKnown().getOrNull()?.validity() ?: 0) + + (if (timeout.asKnown().isPresent) 1 else 0) + + (variables.asKnown().getOrNull()?.validity() ?: 0) + + /** Variables to substitute in the action instruction */ + class Variables + @JsonCreator + private constructor( + @com.fasterxml.jackson.annotation.JsonValue + private val additionalProperties: Map + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Variables]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Variables]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(variables: Variables) = apply { + additionalProperties = variables.additionalProperties.toMutableMap() + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Variables]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Variables = Variables(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Variables = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + additionalProperties.count { (_, value) -> !value.isNull() && !value.isMissing() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Variables && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Variables{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Options && + model == other.model && + timeout == other.timeout && + variables == other.variables && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(model, timeout, variables, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Options{model=$model, timeout=$timeout, variables=$variables, additionalProperties=$additionalProperties}" + } + + /** Client SDK language */ + class XLanguage @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TYPESCRIPT = of("typescript") + + @JvmField val PYTHON = of("python") + + @JvmField val PLAYGROUND = of("playground") + + @JvmStatic fun of(value: String) = XLanguage(JsonField.of(value)) + } + + /** An enum containing [XLanguage]'s known values. */ + enum class Known { + TYPESCRIPT, + PYTHON, + PLAYGROUND, + } + + /** + * An enum containing [XLanguage]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [XLanguage] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TYPESCRIPT, + PYTHON, + PLAYGROUND, + /** + * An enum member indicating that [XLanguage] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TYPESCRIPT -> Value.TYPESCRIPT + PYTHON -> Value.PYTHON + PLAYGROUND -> Value.PLAYGROUND + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TYPESCRIPT -> Known.TYPESCRIPT + PYTHON -> Known.PYTHON + PLAYGROUND -> Known.PLAYGROUND + else -> throw StagehandInvalidDataException("Unknown XLanguage: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): XLanguage = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is XLanguage && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** Whether to stream the response via SSE */ + class XStreamResponse @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TRUE = of("true") + + @JvmField val FALSE = of("false") + + @JvmStatic fun of(value: String) = XStreamResponse(JsonField.of(value)) + } + + /** An enum containing [XStreamResponse]'s known values. */ + enum class Known { + TRUE, + FALSE, + } + + /** + * An enum containing [XStreamResponse]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [XStreamResponse] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TRUE, + FALSE, + /** + * An enum member indicating that [XStreamResponse] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TRUE -> Value.TRUE + FALSE -> Value.FALSE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRUE -> Known.TRUE + FALSE -> Known.FALSE + else -> throw StagehandInvalidDataException("Unknown XStreamResponse: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): XStreamResponse = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is XStreamResponse && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActResponse.kt index 57b8827..bfa1f65 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActResponse.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActResponse.kt @@ -2,20 +2,63 @@ package com.browserbase.api.models.sessions +import com.browserbase.api.core.Enum import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonField +import com.browserbase.api.core.JsonMissing import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.checkKnown +import com.browserbase.api.core.checkRequired +import com.browserbase.api.core.toImmutable import com.browserbase.api.errors.StagehandInvalidDataException import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty import java.util.Collections import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull class SessionActResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor(private val additionalProperties: MutableMap) { +private constructor( + private val data: JsonField, + private val success: JsonField, + private val additionalProperties: MutableMap, +) { - @JsonCreator private constructor() : this(mutableMapOf()) + @JsonCreator + private constructor( + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), + ) : this(data, success, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun data(): Data = data.getRequired("data") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun success(): Success = success.getRequired("success") + + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField = data + + /** + * Returns the raw JSON value of [success]. + * + * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -31,20 +74,52 @@ private constructor(private val additionalProperties: MutableMap? = null + private var success: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(sessionActResponse: SessionActResponse) = apply { + data = sessionActResponse.data + success = sessionActResponse.success additionalProperties = sessionActResponse.additionalProperties.toMutableMap() } + fun data(data: Data) = data(JsonField.of(data)) + + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed [Data] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun data(data: JsonField) = apply { this.data = data } + + fun success(success: Success) = success(JsonField.of(success)) + + /** + * Sets [Builder.success] to an arbitrary JSON value. + * + * You should usually call [Builder.success] with a well-typed [Success] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun success(success: JsonField) = apply { this.success = success } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -68,8 +143,21 @@ private constructor(private val additionalProperties: MutableMap, + private val actionId: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("result") @ExcludeMissing result: JsonField = JsonMissing.of(), + @JsonProperty("actionId") @ExcludeMissing actionId: JsonField = JsonMissing.of(), + ) : this(result, actionId, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun result(): Result = result.getRequired("result") + + /** + * Action ID for tracking + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun actionId(): Optional = actionId.getOptional("actionId") + + /** + * Returns the raw JSON value of [result]. + * + * Unlike [result], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("result") @ExcludeMissing fun _result(): JsonField = result + + /** + * Returns the raw JSON value of [actionId]. + * + * Unlike [actionId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("actionId") @ExcludeMissing fun _actionId(): JsonField = actionId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Data]. + * + * The following fields are required: + * ```java + * .result() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var result: JsonField? = null + private var actionId: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + result = data.result + actionId = data.actionId + additionalProperties = data.additionalProperties.toMutableMap() + } + + fun result(result: Result) = result(JsonField.of(result)) + + /** + * Sets [Builder.result] to an arbitrary JSON value. + * + * You should usually call [Builder.result] with a well-typed [Result] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun result(result: JsonField) = apply { this.result = result } + + /** Action ID for tracking */ + fun actionId(actionId: String) = actionId(JsonField.of(actionId)) + + /** + * Sets [Builder.actionId] to an arbitrary JSON value. + * + * You should usually call [Builder.actionId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun actionId(actionId: JsonField) = apply { this.actionId = actionId } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .result() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Data = + Data(checkRequired("result", result), actionId, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Data = apply { + if (validated) { + return@apply + } + + result().validate() + actionId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (result.asKnown().getOrNull()?.validity() ?: 0) + + (if (actionId.asKnown().isPresent) 1 else 0) + + class Result + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val actionDescription: JsonField, + private val actions: JsonField>, + private val message: JsonField, + private val success: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("actionDescription") + @ExcludeMissing + actionDescription: JsonField = JsonMissing.of(), + @JsonProperty("actions") + @ExcludeMissing + actions: JsonField> = JsonMissing.of(), + @JsonProperty("message") + @ExcludeMissing + message: JsonField = JsonMissing.of(), + @JsonProperty("success") + @ExcludeMissing + success: JsonField = JsonMissing.of(), + ) : this(actionDescription, actions, message, success, mutableMapOf()) + + /** + * Description of the action that was performed + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun actionDescription(): String = actionDescription.getRequired("actionDescription") + + /** + * List of actions that were executed + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun actions(): List = actions.getRequired("actions") + + /** + * Human-readable result message + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun message(): String = message.getRequired("message") + + /** + * Whether the action completed successfully + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun success(): Boolean = success.getRequired("success") + + /** + * Returns the raw JSON value of [actionDescription]. + * + * Unlike [actionDescription], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("actionDescription") + @ExcludeMissing + fun _actionDescription(): JsonField = actionDescription + + /** + * Returns the raw JSON value of [actions]. + * + * Unlike [actions], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("actions") + @ExcludeMissing + fun _actions(): JsonField> = actions + + /** + * Returns the raw JSON value of [message]. + * + * Unlike [message], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("message") @ExcludeMissing fun _message(): JsonField = message + + /** + * Returns the raw JSON value of [success]. + * + * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Result]. + * + * The following fields are required: + * ```java + * .actionDescription() + * .actions() + * .message() + * .success() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Result]. */ + class Builder internal constructor() { + + private var actionDescription: JsonField? = null + private var actions: JsonField>? = null + private var message: JsonField? = null + private var success: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(result: Result) = apply { + actionDescription = result.actionDescription + actions = result.actions.map { it.toMutableList() } + message = result.message + success = result.success + additionalProperties = result.additionalProperties.toMutableMap() + } + + /** Description of the action that was performed */ + fun actionDescription(actionDescription: String) = + actionDescription(JsonField.of(actionDescription)) + + /** + * Sets [Builder.actionDescription] to an arbitrary JSON value. + * + * You should usually call [Builder.actionDescription] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun actionDescription(actionDescription: JsonField) = apply { + this.actionDescription = actionDescription + } + + /** List of actions that were executed */ + fun actions(actions: List) = actions(JsonField.of(actions)) + + /** + * Sets [Builder.actions] to an arbitrary JSON value. + * + * You should usually call [Builder.actions] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun actions(actions: JsonField>) = apply { + this.actions = actions.map { it.toMutableList() } + } + + /** + * Adds a single [Action] to [actions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAction(action: Action) = apply { + actions = + (actions ?: JsonField.of(mutableListOf())).also { + checkKnown("actions", it).add(action) + } + } + + /** Human-readable result message */ + fun message(message: String) = message(JsonField.of(message)) + + /** + * Sets [Builder.message] to an arbitrary JSON value. + * + * You should usually call [Builder.message] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun message(message: JsonField) = apply { this.message = message } + + /** Whether the action completed successfully */ + fun success(success: Boolean) = success(JsonField.of(success)) + + /** + * Sets [Builder.success] to an arbitrary JSON value. + * + * You should usually call [Builder.success] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun success(success: JsonField) = apply { this.success = success } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Result]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .actionDescription() + * .actions() + * .message() + * .success() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Result = + Result( + checkRequired("actionDescription", actionDescription), + checkRequired("actions", actions).map { it.toImmutable() }, + checkRequired("message", message), + checkRequired("success", success), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Result = apply { + if (validated) { + return@apply + } + + actionDescription() + actions().forEach { it.validate() } + message() + success() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (actionDescription.asKnown().isPresent) 1 else 0) + + (actions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (message.asKnown().isPresent) 1 else 0) + + (if (success.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Result && + actionDescription == other.actionDescription && + actions == other.actions && + message == other.message && + success == other.success && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(actionDescription, actions, message, success, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Result{actionDescription=$actionDescription, actions=$actions, message=$message, success=$success, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Data && + result == other.result && + actionId == other.actionId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(result, actionId, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Data{result=$result, actionId=$actionId, additionalProperties=$additionalProperties}" + } + + class Success @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TRUE = of(true) + + @JvmStatic fun of(value: Boolean) = Success(JsonField.of(value)) + } + + /** An enum containing [Success]'s known values. */ + enum class Known { + TRUE + } + + /** + * An enum containing [Success]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Success] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TRUE, + /** An enum member indicating that [Success] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TRUE -> Value.TRUE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRUE -> Known.TRUE + else -> throw StagehandInvalidDataException("Unknown Success: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asBoolean(): Boolean = + _value().asBoolean().orElseThrow { + StagehandInvalidDataException("Value is not a Boolean") + } + + private var validated: Boolean = false + + fun validate(): Success = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Success && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is SessionActResponse && additionalProperties == other.additionalProperties + return other is SessionActResponse && + data == other.data && + success == other.success && + additionalProperties == other.additionalProperties } - private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(data, success, additionalProperties) } override fun hashCode(): Int = hashCode - override fun toString() = "SessionActResponse{additionalProperties=$additionalProperties}" + override fun toString() = + "SessionActResponse{data=$data, success=$success, additionalProperties=$additionalProperties}" } diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndParams.kt index 02f9cb0..90a656f 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndParams.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndParams.kt @@ -2,11 +2,17 @@ package com.browserbase.api.models.sessions +import com.browserbase.api.core.Enum +import com.browserbase.api.core.JsonField import com.browserbase.api.core.JsonValue import com.browserbase.api.core.Params import com.browserbase.api.core.http.Headers import com.browserbase.api.core.http.QueryParams import com.browserbase.api.core.toImmutable +import com.browserbase.api.errors.StagehandInvalidDataException +import com.fasterxml.jackson.annotation.JsonCreator +import java.time.OffsetDateTime +import java.time.format.DateTimeFormatter import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull @@ -14,25 +20,30 @@ import kotlin.jvm.optionals.getOrNull /** Terminates the browser session and releases all associated resources. */ class SessionEndParams private constructor( - private val id: JsonValue?, - private val xLanguage: JsonValue?, - private val xSdkVersion: JsonValue?, - private val xSentAt: JsonValue?, - private val xStreamResponse: JsonValue?, + private val id: String?, + private val xLanguage: XLanguage?, + private val xSdkVersion: String?, + private val xSentAt: OffsetDateTime?, + private val xStreamResponse: XStreamResponse?, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, ) : Params { - fun id(): Optional = Optional.ofNullable(id) + /** Unique session identifier */ + fun id(): Optional = Optional.ofNullable(id) - fun xLanguage(): Optional = Optional.ofNullable(xLanguage) + /** Client SDK language */ + fun xLanguage(): Optional = Optional.ofNullable(xLanguage) - fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) + /** Version of the Stagehand SDK */ + fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) - fun xSentAt(): Optional = Optional.ofNullable(xSentAt) + /** ISO timestamp when request was sent */ + fun xSentAt(): Optional = Optional.ofNullable(xSentAt) - fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) + /** Whether to stream the response via SSE */ + fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) /** Additional body properties to send with the request. */ fun _additionalBodyProperties(): Map = additionalBodyProperties @@ -56,11 +67,11 @@ private constructor( /** A builder for [SessionEndParams]. */ class Builder internal constructor() { - private var id: JsonValue? = null - private var xLanguage: JsonValue? = null - private var xSdkVersion: JsonValue? = null - private var xSentAt: JsonValue? = null - private var xStreamResponse: JsonValue? = null + private var id: String? = null + private var xLanguage: XLanguage? = null + private var xSdkVersion: String? = null + private var xSentAt: OffsetDateTime? = null + private var xStreamResponse: XStreamResponse? = null private var additionalHeaders: Headers.Builder = Headers.builder() private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() private var additionalBodyProperties: MutableMap = mutableMapOf() @@ -77,32 +88,37 @@ private constructor( additionalBodyProperties = sessionEndParams.additionalBodyProperties.toMutableMap() } - fun id(id: JsonValue?) = apply { this.id = id } + /** Unique session identifier */ + fun id(id: String?) = apply { this.id = id } /** Alias for calling [Builder.id] with `id.orElse(null)`. */ - fun id(id: Optional) = id(id.getOrNull()) + fun id(id: Optional) = id(id.getOrNull()) - fun xLanguage(xLanguage: JsonValue?) = apply { this.xLanguage = xLanguage } + /** Client SDK language */ + fun xLanguage(xLanguage: XLanguage?) = apply { this.xLanguage = xLanguage } /** Alias for calling [Builder.xLanguage] with `xLanguage.orElse(null)`. */ - fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) + fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) - fun xSdkVersion(xSdkVersion: JsonValue?) = apply { this.xSdkVersion = xSdkVersion } + /** Version of the Stagehand SDK */ + fun xSdkVersion(xSdkVersion: String?) = apply { this.xSdkVersion = xSdkVersion } /** Alias for calling [Builder.xSdkVersion] with `xSdkVersion.orElse(null)`. */ - fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) + fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) - fun xSentAt(xSentAt: JsonValue?) = apply { this.xSentAt = xSentAt } + /** ISO timestamp when request was sent */ + fun xSentAt(xSentAt: OffsetDateTime?) = apply { this.xSentAt = xSentAt } /** Alias for calling [Builder.xSentAt] with `xSentAt.orElse(null)`. */ - fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) + fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) - fun xStreamResponse(xStreamResponse: JsonValue?) = apply { + /** Whether to stream the response via SSE */ + fun xStreamResponse(xStreamResponse: XStreamResponse?) = apply { this.xStreamResponse = xStreamResponse } /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ - fun xStreamResponse(xStreamResponse: Optional) = + fun xStreamResponse(xStreamResponse: Optional) = xStreamResponse(xStreamResponse.getOrNull()) fun additionalHeaders(additionalHeaders: Headers) = apply { @@ -248,14 +264,291 @@ private constructor( fun _pathParam(index: Int): String = when (index) { - 0 -> id?.toString() ?: "" + 0 -> id ?: "" else -> "" } - override fun _headers(): Headers = Headers.builder().apply { putAll(additionalHeaders) }.build() + override fun _headers(): Headers = + Headers.builder() + .apply { + xLanguage?.let { put("x-language", it.toString()) } + xSdkVersion?.let { put("x-sdk-version", it) } + xSentAt?.let { put("x-sent-at", DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(it)) } + xStreamResponse?.let { put("x-stream-response", it.toString()) } + putAll(additionalHeaders) + } + .build() override fun _queryParams(): QueryParams = additionalQueryParams + /** Client SDK language */ + class XLanguage @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TYPESCRIPT = of("typescript") + + @JvmField val PYTHON = of("python") + + @JvmField val PLAYGROUND = of("playground") + + @JvmStatic fun of(value: String) = XLanguage(JsonField.of(value)) + } + + /** An enum containing [XLanguage]'s known values. */ + enum class Known { + TYPESCRIPT, + PYTHON, + PLAYGROUND, + } + + /** + * An enum containing [XLanguage]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [XLanguage] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TYPESCRIPT, + PYTHON, + PLAYGROUND, + /** + * An enum member indicating that [XLanguage] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TYPESCRIPT -> Value.TYPESCRIPT + PYTHON -> Value.PYTHON + PLAYGROUND -> Value.PLAYGROUND + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TYPESCRIPT -> Known.TYPESCRIPT + PYTHON -> Known.PYTHON + PLAYGROUND -> Known.PLAYGROUND + else -> throw StagehandInvalidDataException("Unknown XLanguage: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): XLanguage = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is XLanguage && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** Whether to stream the response via SSE */ + class XStreamResponse @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TRUE = of("true") + + @JvmField val FALSE = of("false") + + @JvmStatic fun of(value: String) = XStreamResponse(JsonField.of(value)) + } + + /** An enum containing [XStreamResponse]'s known values. */ + enum class Known { + TRUE, + FALSE, + } + + /** + * An enum containing [XStreamResponse]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [XStreamResponse] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TRUE, + FALSE, + /** + * An enum member indicating that [XStreamResponse] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TRUE -> Value.TRUE + FALSE -> Value.FALSE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRUE -> Known.TRUE + FALSE -> Known.FALSE + else -> throw StagehandInvalidDataException("Unknown XStreamResponse: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): XStreamResponse = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is XStreamResponse && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt index 970e0fd..3bed0ac 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt @@ -2,20 +2,45 @@ package com.browserbase.api.models.sessions +import com.browserbase.api.core.Enum import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonField +import com.browserbase.api.core.JsonMissing import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.checkRequired import com.browserbase.api.errors.StagehandInvalidDataException import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty import java.util.Collections import java.util.Objects +import kotlin.jvm.optionals.getOrNull class SessionEndResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor(private val additionalProperties: MutableMap) { +private constructor( + private val success: JsonField, + private val additionalProperties: MutableMap, +) { - @JsonCreator private constructor() : this(mutableMapOf()) + @JsonCreator + private constructor( + @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of() + ) : this(success, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun success(): Success = success.getRequired("success") + + /** + * Returns the raw JSON value of [success]. + * + * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -31,20 +56,39 @@ private constructor(private val additionalProperties: MutableMap? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(sessionEndResponse: SessionEndResponse) = apply { + success = sessionEndResponse.success additionalProperties = sessionEndResponse.additionalProperties.toMutableMap() } + fun success(success: Success) = success(JsonField.of(success)) + + /** + * Sets [Builder.success] to an arbitrary JSON value. + * + * You should usually call [Builder.success] with a well-typed [Success] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun success(success: JsonField) = apply { this.success = success } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -68,8 +112,19 @@ private constructor(private val additionalProperties: MutableMap) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TRUE = of(true) + + @JvmStatic fun of(value: Boolean) = Success(JsonField.of(value)) + } + + /** An enum containing [Success]'s known values. */ + enum class Known { + TRUE + } + + /** + * An enum containing [Success]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Success] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TRUE, + /** An enum member indicating that [Success] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TRUE -> Value.TRUE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRUE -> Known.TRUE + else -> throw StagehandInvalidDataException("Unknown Success: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asBoolean(): Boolean = + _value().asBoolean().orElseThrow { + StagehandInvalidDataException("Value is not a Boolean") + } + + private var validated: Boolean = false + + fun validate(): Success = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Success && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is SessionEndResponse && additionalProperties == other.additionalProperties + return other is SessionEndResponse && + success == other.success && + additionalProperties == other.additionalProperties } - private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(success, additionalProperties) } override fun hashCode(): Int = hashCode - override fun toString() = "SessionEndResponse{additionalProperties=$additionalProperties}" + override fun toString() = + "SessionEndResponse{success=$success, additionalProperties=$additionalProperties}" } diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParams.kt deleted file mode 100644 index eca9552..0000000 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParams.kt +++ /dev/null @@ -1,269 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.JsonMissing -import com.browserbase.api.core.JsonValue -import com.browserbase.api.core.Params -import com.browserbase.api.core.http.Headers -import com.browserbase.api.core.http.QueryParams -import java.util.Objects -import java.util.Optional -import kotlin.jvm.optionals.getOrNull - -/** Runs an autonomous AI agent that can perform complex multi-step browser tasks. */ -class SessionExecuteAgentParams -private constructor( - private val id: JsonValue?, - private val xLanguage: JsonValue?, - private val xSdkVersion: JsonValue?, - private val xSentAt: JsonValue?, - private val xStreamResponse: JsonValue?, - private val body: JsonValue, - private val additionalHeaders: Headers, - private val additionalQueryParams: QueryParams, -) : Params { - - fun id(): Optional = Optional.ofNullable(id) - - fun xLanguage(): Optional = Optional.ofNullable(xLanguage) - - fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) - - fun xSentAt(): Optional = Optional.ofNullable(xSentAt) - - fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) - - fun body(): JsonValue = body - - /** Additional headers to send with the request. */ - fun _additionalHeaders(): Headers = additionalHeaders - - /** Additional query param to send with the request. */ - fun _additionalQueryParams(): QueryParams = additionalQueryParams - - fun toBuilder() = Builder().from(this) - - companion object { - - @JvmStatic fun none(): SessionExecuteAgentParams = builder().build() - - /** - * Returns a mutable builder for constructing an instance of [SessionExecuteAgentParams]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [SessionExecuteAgentParams]. */ - class Builder internal constructor() { - - private var id: JsonValue? = null - private var xLanguage: JsonValue? = null - private var xSdkVersion: JsonValue? = null - private var xSentAt: JsonValue? = null - private var xStreamResponse: JsonValue? = null - private var body: JsonValue = JsonMissing.of() - private var additionalHeaders: Headers.Builder = Headers.builder() - private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() - - @JvmSynthetic - internal fun from(sessionExecuteAgentParams: SessionExecuteAgentParams) = apply { - id = sessionExecuteAgentParams.id - xLanguage = sessionExecuteAgentParams.xLanguage - xSdkVersion = sessionExecuteAgentParams.xSdkVersion - xSentAt = sessionExecuteAgentParams.xSentAt - xStreamResponse = sessionExecuteAgentParams.xStreamResponse - body = sessionExecuteAgentParams.body - additionalHeaders = sessionExecuteAgentParams.additionalHeaders.toBuilder() - additionalQueryParams = sessionExecuteAgentParams.additionalQueryParams.toBuilder() - } - - fun id(id: JsonValue?) = apply { this.id = id } - - /** Alias for calling [Builder.id] with `id.orElse(null)`. */ - fun id(id: Optional) = id(id.getOrNull()) - - fun xLanguage(xLanguage: JsonValue?) = apply { this.xLanguage = xLanguage } - - /** Alias for calling [Builder.xLanguage] with `xLanguage.orElse(null)`. */ - fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) - - fun xSdkVersion(xSdkVersion: JsonValue?) = apply { this.xSdkVersion = xSdkVersion } - - /** Alias for calling [Builder.xSdkVersion] with `xSdkVersion.orElse(null)`. */ - fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) - - fun xSentAt(xSentAt: JsonValue?) = apply { this.xSentAt = xSentAt } - - /** Alias for calling [Builder.xSentAt] with `xSentAt.orElse(null)`. */ - fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) - - fun xStreamResponse(xStreamResponse: JsonValue?) = apply { - this.xStreamResponse = xStreamResponse - } - - /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ - fun xStreamResponse(xStreamResponse: Optional) = - xStreamResponse(xStreamResponse.getOrNull()) - - fun body(body: JsonValue) = apply { this.body = body } - - fun additionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.clear() - putAllAdditionalHeaders(additionalHeaders) - } - - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllAdditionalHeaders(additionalHeaders) - } - - fun putAdditionalHeader(name: String, value: String) = apply { - additionalHeaders.put(name, value) - } - - fun putAdditionalHeaders(name: String, values: Iterable) = apply { - additionalHeaders.put(name, values) - } - - fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.putAll(additionalHeaders) - } - - fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.putAll(additionalHeaders) - } - - fun replaceAdditionalHeaders(name: String, value: String) = apply { - additionalHeaders.replace(name, value) - } - - fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { - additionalHeaders.replace(name, values) - } - - fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { - this.additionalHeaders.replaceAll(additionalHeaders) - } - - fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.replaceAll(additionalHeaders) - } - - fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - - fun removeAllAdditionalHeaders(names: Set) = apply { - additionalHeaders.removeAll(names) - } - - fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.clear() - putAllAdditionalQueryParams(additionalQueryParams) - } - - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllAdditionalQueryParams(additionalQueryParams) - } - - fun putAdditionalQueryParam(key: String, value: String) = apply { - additionalQueryParams.put(key, value) - } - - fun putAdditionalQueryParams(key: String, values: Iterable) = apply { - additionalQueryParams.put(key, values) - } - - fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.putAll(additionalQueryParams) - } - - fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = - apply { - this.additionalQueryParams.putAll(additionalQueryParams) - } - - fun replaceAdditionalQueryParams(key: String, value: String) = apply { - additionalQueryParams.replace(key, value) - } - - fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { - additionalQueryParams.replace(key, values) - } - - fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { - this.additionalQueryParams.replaceAll(additionalQueryParams) - } - - fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = - apply { - this.additionalQueryParams.replaceAll(additionalQueryParams) - } - - fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } - - fun removeAllAdditionalQueryParams(keys: Set) = apply { - additionalQueryParams.removeAll(keys) - } - - /** - * Returns an immutable instance of [SessionExecuteAgentParams]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): SessionExecuteAgentParams = - SessionExecuteAgentParams( - id, - xLanguage, - xSdkVersion, - xSentAt, - xStreamResponse, - body, - additionalHeaders.build(), - additionalQueryParams.build(), - ) - } - - fun _body(): JsonValue = body - - fun _pathParam(index: Int): String = - when (index) { - 0 -> id?.toString() ?: "" - else -> "" - } - - override fun _headers(): Headers = Headers.builder().apply { putAll(additionalHeaders) }.build() - - override fun _queryParams(): QueryParams = additionalQueryParams - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is SessionExecuteAgentParams && - id == other.id && - xLanguage == other.xLanguage && - xSdkVersion == other.xSdkVersion && - xSentAt == other.xSentAt && - xStreamResponse == other.xStreamResponse && - body == other.body && - additionalHeaders == other.additionalHeaders && - additionalQueryParams == other.additionalQueryParams - } - - override fun hashCode(): Int = - Objects.hash( - id, - xLanguage, - xSdkVersion, - xSentAt, - xStreamResponse, - body, - additionalHeaders, - additionalQueryParams, - ) - - override fun toString() = - "SessionExecuteAgentParams{id=$id, xLanguage=$xLanguage, xSdkVersion=$xSdkVersion, xSentAt=$xSentAt, xStreamResponse=$xStreamResponse, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" -} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponse.kt deleted file mode 100644 index 700a7ba..0000000 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponse.kt +++ /dev/null @@ -1,118 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.ExcludeMissing -import com.browserbase.api.core.JsonValue -import com.browserbase.api.errors.StagehandInvalidDataException -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonCreator -import java.util.Collections -import java.util.Objects - -class SessionExecuteAgentResponse -@JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor(private val additionalProperties: MutableMap) { - - @JsonCreator private constructor() : this(mutableMapOf()) - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [SessionExecuteAgentResponse]. - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [SessionExecuteAgentResponse]. */ - class Builder internal constructor() { - - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(sessionExecuteAgentResponse: SessionExecuteAgentResponse) = apply { - additionalProperties = sessionExecuteAgentResponse.additionalProperties.toMutableMap() - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [SessionExecuteAgentResponse]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): SessionExecuteAgentResponse = - SessionExecuteAgentResponse(additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false - - fun validate(): SessionExecuteAgentResponse = apply { - if (validated) { - return@apply - } - - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = 0 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is SessionExecuteAgentResponse && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "SessionExecuteAgentResponse{additionalProperties=$additionalProperties}" -} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteParams.kt new file mode 100644 index 0000000..4b615cf --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteParams.kt @@ -0,0 +1,1403 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.Enum +import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonField +import com.browserbase.api.core.JsonMissing +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.Params +import com.browserbase.api.core.checkRequired +import com.browserbase.api.core.http.Headers +import com.browserbase.api.core.http.QueryParams +import com.browserbase.api.errors.StagehandInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import java.time.OffsetDateTime +import java.time.format.DateTimeFormatter +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Runs an autonomous AI agent that can perform complex multi-step browser tasks. */ +class SessionExecuteParams +private constructor( + private val id: String?, + private val xLanguage: XLanguage?, + private val xSdkVersion: String?, + private val xSentAt: OffsetDateTime?, + private val xStreamResponse: XStreamResponse?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** Unique session identifier */ + fun id(): Optional = Optional.ofNullable(id) + + /** Client SDK language */ + fun xLanguage(): Optional = Optional.ofNullable(xLanguage) + + /** Version of the Stagehand SDK */ + fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) + + /** ISO timestamp when request was sent */ + fun xSentAt(): Optional = Optional.ofNullable(xSentAt) + + /** Whether to stream the response via SSE */ + fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun agentConfig(): AgentConfig = body.agentConfig() + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun executeOptions(): ExecuteOptions = body.executeOptions() + + /** + * Target frame ID for the agent + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun frameId(): Optional = body.frameId() + + /** + * Returns the raw JSON value of [agentConfig]. + * + * Unlike [agentConfig], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _agentConfig(): JsonField = body._agentConfig() + + /** + * Returns the raw JSON value of [executeOptions]. + * + * Unlike [executeOptions], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _executeOptions(): JsonField = body._executeOptions() + + /** + * Returns the raw JSON value of [frameId]. + * + * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _frameId(): JsonField = body._frameId() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [SessionExecuteParams]. + * + * The following fields are required: + * ```java + * .agentConfig() + * .executeOptions() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SessionExecuteParams]. */ + class Builder internal constructor() { + + private var id: String? = null + private var xLanguage: XLanguage? = null + private var xSdkVersion: String? = null + private var xSentAt: OffsetDateTime? = null + private var xStreamResponse: XStreamResponse? = null + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(sessionExecuteParams: SessionExecuteParams) = apply { + id = sessionExecuteParams.id + xLanguage = sessionExecuteParams.xLanguage + xSdkVersion = sessionExecuteParams.xSdkVersion + xSentAt = sessionExecuteParams.xSentAt + xStreamResponse = sessionExecuteParams.xStreamResponse + body = sessionExecuteParams.body.toBuilder() + additionalHeaders = sessionExecuteParams.additionalHeaders.toBuilder() + additionalQueryParams = sessionExecuteParams.additionalQueryParams.toBuilder() + } + + /** Unique session identifier */ + fun id(id: String?) = apply { this.id = id } + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + /** Client SDK language */ + fun xLanguage(xLanguage: XLanguage?) = apply { this.xLanguage = xLanguage } + + /** Alias for calling [Builder.xLanguage] with `xLanguage.orElse(null)`. */ + fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) + + /** Version of the Stagehand SDK */ + fun xSdkVersion(xSdkVersion: String?) = apply { this.xSdkVersion = xSdkVersion } + + /** Alias for calling [Builder.xSdkVersion] with `xSdkVersion.orElse(null)`. */ + fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) + + /** ISO timestamp when request was sent */ + fun xSentAt(xSentAt: OffsetDateTime?) = apply { this.xSentAt = xSentAt } + + /** Alias for calling [Builder.xSentAt] with `xSentAt.orElse(null)`. */ + fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) + + /** Whether to stream the response via SSE */ + fun xStreamResponse(xStreamResponse: XStreamResponse?) = apply { + this.xStreamResponse = xStreamResponse + } + + /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ + fun xStreamResponse(xStreamResponse: Optional) = + xStreamResponse(xStreamResponse.getOrNull()) + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [agentConfig] + * - [executeOptions] + * - [frameId] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + fun agentConfig(agentConfig: AgentConfig) = apply { body.agentConfig(agentConfig) } + + /** + * Sets [Builder.agentConfig] to an arbitrary JSON value. + * + * You should usually call [Builder.agentConfig] with a well-typed [AgentConfig] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun agentConfig(agentConfig: JsonField) = apply { + body.agentConfig(agentConfig) + } + + fun executeOptions(executeOptions: ExecuteOptions) = apply { + body.executeOptions(executeOptions) + } + + /** + * Sets [Builder.executeOptions] to an arbitrary JSON value. + * + * You should usually call [Builder.executeOptions] with a well-typed [ExecuteOptions] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun executeOptions(executeOptions: JsonField) = apply { + body.executeOptions(executeOptions) + } + + /** Target frame ID for the agent */ + fun frameId(frameId: String) = apply { body.frameId(frameId) } + + /** + * Sets [Builder.frameId] to an arbitrary JSON value. + * + * You should usually call [Builder.frameId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun frameId(frameId: JsonField) = apply { body.frameId(frameId) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [SessionExecuteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .agentConfig() + * .executeOptions() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SessionExecuteParams = + SessionExecuteParams( + id, + xLanguage, + xSdkVersion, + xSentAt, + xStreamResponse, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> id ?: "" + else -> "" + } + + override fun _headers(): Headers = + Headers.builder() + .apply { + xLanguage?.let { put("x-language", it.toString()) } + xSdkVersion?.let { put("x-sdk-version", it) } + xSentAt?.let { put("x-sent-at", DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(it)) } + xStreamResponse?.let { put("x-stream-response", it.toString()) } + putAll(additionalHeaders) + } + .build() + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val agentConfig: JsonField, + private val executeOptions: JsonField, + private val frameId: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("agentConfig") + @ExcludeMissing + agentConfig: JsonField = JsonMissing.of(), + @JsonProperty("executeOptions") + @ExcludeMissing + executeOptions: JsonField = JsonMissing.of(), + @JsonProperty("frameId") @ExcludeMissing frameId: JsonField = JsonMissing.of(), + ) : this(agentConfig, executeOptions, frameId, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun agentConfig(): AgentConfig = agentConfig.getRequired("agentConfig") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun executeOptions(): ExecuteOptions = executeOptions.getRequired("executeOptions") + + /** + * Target frame ID for the agent + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun frameId(): Optional = frameId.getOptional("frameId") + + /** + * Returns the raw JSON value of [agentConfig]. + * + * Unlike [agentConfig], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("agentConfig") + @ExcludeMissing + fun _agentConfig(): JsonField = agentConfig + + /** + * Returns the raw JSON value of [executeOptions]. + * + * Unlike [executeOptions], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("executeOptions") + @ExcludeMissing + fun _executeOptions(): JsonField = executeOptions + + /** + * Returns the raw JSON value of [frameId]. + * + * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("frameId") @ExcludeMissing fun _frameId(): JsonField = frameId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .agentConfig() + * .executeOptions() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var agentConfig: JsonField? = null + private var executeOptions: JsonField? = null + private var frameId: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + agentConfig = body.agentConfig + executeOptions = body.executeOptions + frameId = body.frameId + additionalProperties = body.additionalProperties.toMutableMap() + } + + fun agentConfig(agentConfig: AgentConfig) = agentConfig(JsonField.of(agentConfig)) + + /** + * Sets [Builder.agentConfig] to an arbitrary JSON value. + * + * You should usually call [Builder.agentConfig] with a well-typed [AgentConfig] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun agentConfig(agentConfig: JsonField) = apply { + this.agentConfig = agentConfig + } + + fun executeOptions(executeOptions: ExecuteOptions) = + executeOptions(JsonField.of(executeOptions)) + + /** + * Sets [Builder.executeOptions] to an arbitrary JSON value. + * + * You should usually call [Builder.executeOptions] with a well-typed [ExecuteOptions] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun executeOptions(executeOptions: JsonField) = apply { + this.executeOptions = executeOptions + } + + /** Target frame ID for the agent */ + fun frameId(frameId: String) = frameId(JsonField.of(frameId)) + + /** + * Sets [Builder.frameId] to an arbitrary JSON value. + * + * You should usually call [Builder.frameId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun frameId(frameId: JsonField) = apply { this.frameId = frameId } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .agentConfig() + * .executeOptions() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("agentConfig", agentConfig), + checkRequired("executeOptions", executeOptions), + frameId, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + agentConfig().validate() + executeOptions().validate() + frameId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (agentConfig.asKnown().getOrNull()?.validity() ?: 0) + + (executeOptions.asKnown().getOrNull()?.validity() ?: 0) + + (if (frameId.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + agentConfig == other.agentConfig && + executeOptions == other.executeOptions && + frameId == other.frameId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(agentConfig, executeOptions, frameId, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{agentConfig=$agentConfig, executeOptions=$executeOptions, frameId=$frameId, additionalProperties=$additionalProperties}" + } + + class AgentConfig + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val cua: JsonField, + private val model: JsonField, + private val systemPrompt: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("cua") @ExcludeMissing cua: JsonField = JsonMissing.of(), + @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), + @JsonProperty("systemPrompt") + @ExcludeMissing + systemPrompt: JsonField = JsonMissing.of(), + ) : this(cua, model, systemPrompt, mutableMapOf()) + + /** + * Enable Computer Use Agent mode + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun cua(): Optional = cua.getOptional("cua") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun model(): Optional = model.getOptional("model") + + /** + * Custom system prompt for the agent + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun systemPrompt(): Optional = systemPrompt.getOptional("systemPrompt") + + /** + * Returns the raw JSON value of [cua]. + * + * Unlike [cua], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cua") @ExcludeMissing fun _cua(): JsonField = cua + + /** + * Returns the raw JSON value of [model]. + * + * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model + + /** + * Returns the raw JSON value of [systemPrompt]. + * + * Unlike [systemPrompt], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("systemPrompt") + @ExcludeMissing + fun _systemPrompt(): JsonField = systemPrompt + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [AgentConfig]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AgentConfig]. */ + class Builder internal constructor() { + + private var cua: JsonField = JsonMissing.of() + private var model: JsonField = JsonMissing.of() + private var systemPrompt: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(agentConfig: AgentConfig) = apply { + cua = agentConfig.cua + model = agentConfig.model + systemPrompt = agentConfig.systemPrompt + additionalProperties = agentConfig.additionalProperties.toMutableMap() + } + + /** Enable Computer Use Agent mode */ + fun cua(cua: Boolean) = cua(JsonField.of(cua)) + + /** + * Sets [Builder.cua] to an arbitrary JSON value. + * + * You should usually call [Builder.cua] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun cua(cua: JsonField) = apply { this.cua = cua } + + fun model(model: ModelConfig) = model(JsonField.of(model)) + + /** + * Sets [Builder.model] to an arbitrary JSON value. + * + * You should usually call [Builder.model] with a well-typed [ModelConfig] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun model(model: JsonField) = apply { this.model = model } + + /** Alias for calling [model] with `ModelConfig.ofString(string)`. */ + fun model(string: String) = model(ModelConfig.ofString(string)) + + /** Alias for calling [model] with `ModelConfig.ofUnionMember1(unionMember1)`. */ + fun model(unionMember1: ModelConfig.UnionMember1) = + model(ModelConfig.ofUnionMember1(unionMember1)) + + /** Custom system prompt for the agent */ + fun systemPrompt(systemPrompt: String) = systemPrompt(JsonField.of(systemPrompt)) + + /** + * Sets [Builder.systemPrompt] to an arbitrary JSON value. + * + * You should usually call [Builder.systemPrompt] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun systemPrompt(systemPrompt: JsonField) = apply { + this.systemPrompt = systemPrompt + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [AgentConfig]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AgentConfig = + AgentConfig(cua, model, systemPrompt, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): AgentConfig = apply { + if (validated) { + return@apply + } + + cua() + model().ifPresent { it.validate() } + systemPrompt() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (cua.asKnown().isPresent) 1 else 0) + + (model.asKnown().getOrNull()?.validity() ?: 0) + + (if (systemPrompt.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AgentConfig && + cua == other.cua && + model == other.model && + systemPrompt == other.systemPrompt && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(cua, model, systemPrompt, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AgentConfig{cua=$cua, model=$model, systemPrompt=$systemPrompt, additionalProperties=$additionalProperties}" + } + + class ExecuteOptions + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val instruction: JsonField, + private val highlightCursor: JsonField, + private val maxSteps: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("instruction") + @ExcludeMissing + instruction: JsonField = JsonMissing.of(), + @JsonProperty("highlightCursor") + @ExcludeMissing + highlightCursor: JsonField = JsonMissing.of(), + @JsonProperty("maxSteps") @ExcludeMissing maxSteps: JsonField = JsonMissing.of(), + ) : this(instruction, highlightCursor, maxSteps, mutableMapOf()) + + /** + * Natural language instruction for the agent + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun instruction(): String = instruction.getRequired("instruction") + + /** + * Whether to visually highlight the cursor during execution + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun highlightCursor(): Optional = highlightCursor.getOptional("highlightCursor") + + /** + * Maximum number of steps the agent can take + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun maxSteps(): Optional = maxSteps.getOptional("maxSteps") + + /** + * Returns the raw JSON value of [instruction]. + * + * Unlike [instruction], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("instruction") + @ExcludeMissing + fun _instruction(): JsonField = instruction + + /** + * Returns the raw JSON value of [highlightCursor]. + * + * Unlike [highlightCursor], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("highlightCursor") + @ExcludeMissing + fun _highlightCursor(): JsonField = highlightCursor + + /** + * Returns the raw JSON value of [maxSteps]. + * + * Unlike [maxSteps], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("maxSteps") @ExcludeMissing fun _maxSteps(): JsonField = maxSteps + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ExecuteOptions]. + * + * The following fields are required: + * ```java + * .instruction() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ExecuteOptions]. */ + class Builder internal constructor() { + + private var instruction: JsonField? = null + private var highlightCursor: JsonField = JsonMissing.of() + private var maxSteps: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(executeOptions: ExecuteOptions) = apply { + instruction = executeOptions.instruction + highlightCursor = executeOptions.highlightCursor + maxSteps = executeOptions.maxSteps + additionalProperties = executeOptions.additionalProperties.toMutableMap() + } + + /** Natural language instruction for the agent */ + fun instruction(instruction: String) = instruction(JsonField.of(instruction)) + + /** + * Sets [Builder.instruction] to an arbitrary JSON value. + * + * You should usually call [Builder.instruction] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun instruction(instruction: JsonField) = apply { + this.instruction = instruction + } + + /** Whether to visually highlight the cursor during execution */ + fun highlightCursor(highlightCursor: Boolean) = + highlightCursor(JsonField.of(highlightCursor)) + + /** + * Sets [Builder.highlightCursor] to an arbitrary JSON value. + * + * You should usually call [Builder.highlightCursor] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun highlightCursor(highlightCursor: JsonField) = apply { + this.highlightCursor = highlightCursor + } + + /** Maximum number of steps the agent can take */ + fun maxSteps(maxSteps: Double) = maxSteps(JsonField.of(maxSteps)) + + /** + * Sets [Builder.maxSteps] to an arbitrary JSON value. + * + * You should usually call [Builder.maxSteps] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun maxSteps(maxSteps: JsonField) = apply { this.maxSteps = maxSteps } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ExecuteOptions]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .instruction() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ExecuteOptions = + ExecuteOptions( + checkRequired("instruction", instruction), + highlightCursor, + maxSteps, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ExecuteOptions = apply { + if (validated) { + return@apply + } + + instruction() + highlightCursor() + maxSteps() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (instruction.asKnown().isPresent) 1 else 0) + + (if (highlightCursor.asKnown().isPresent) 1 else 0) + + (if (maxSteps.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ExecuteOptions && + instruction == other.instruction && + highlightCursor == other.highlightCursor && + maxSteps == other.maxSteps && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(instruction, highlightCursor, maxSteps, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ExecuteOptions{instruction=$instruction, highlightCursor=$highlightCursor, maxSteps=$maxSteps, additionalProperties=$additionalProperties}" + } + + /** Client SDK language */ + class XLanguage @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TYPESCRIPT = of("typescript") + + @JvmField val PYTHON = of("python") + + @JvmField val PLAYGROUND = of("playground") + + @JvmStatic fun of(value: String) = XLanguage(JsonField.of(value)) + } + + /** An enum containing [XLanguage]'s known values. */ + enum class Known { + TYPESCRIPT, + PYTHON, + PLAYGROUND, + } + + /** + * An enum containing [XLanguage]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [XLanguage] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TYPESCRIPT, + PYTHON, + PLAYGROUND, + /** + * An enum member indicating that [XLanguage] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TYPESCRIPT -> Value.TYPESCRIPT + PYTHON -> Value.PYTHON + PLAYGROUND -> Value.PLAYGROUND + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TYPESCRIPT -> Known.TYPESCRIPT + PYTHON -> Known.PYTHON + PLAYGROUND -> Known.PLAYGROUND + else -> throw StagehandInvalidDataException("Unknown XLanguage: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): XLanguage = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is XLanguage && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** Whether to stream the response via SSE */ + class XStreamResponse @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TRUE = of("true") + + @JvmField val FALSE = of("false") + + @JvmStatic fun of(value: String) = XStreamResponse(JsonField.of(value)) + } + + /** An enum containing [XStreamResponse]'s known values. */ + enum class Known { + TRUE, + FALSE, + } + + /** + * An enum containing [XStreamResponse]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [XStreamResponse] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TRUE, + FALSE, + /** + * An enum member indicating that [XStreamResponse] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TRUE -> Value.TRUE + FALSE -> Value.FALSE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRUE -> Known.TRUE + FALSE -> Known.FALSE + else -> throw StagehandInvalidDataException("Unknown XStreamResponse: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): XStreamResponse = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is XStreamResponse && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SessionExecuteParams && + id == other.id && + xLanguage == other.xLanguage && + xSdkVersion == other.xSdkVersion && + xSentAt == other.xSentAt && + xStreamResponse == other.xStreamResponse && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash( + id, + xLanguage, + xSdkVersion, + xSentAt, + xStreamResponse, + body, + additionalHeaders, + additionalQueryParams, + ) + + override fun toString() = + "SessionExecuteParams{id=$id, xLanguage=$xLanguage, xSdkVersion=$xSdkVersion, xSentAt=$xSentAt, xStreamResponse=$xStreamResponse, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteResponse.kt new file mode 100644 index 0000000..2478f77 --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteResponse.kt @@ -0,0 +1,1775 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.Enum +import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonField +import com.browserbase.api.core.JsonMissing +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.checkKnown +import com.browserbase.api.core.checkRequired +import com.browserbase.api.core.toImmutable +import com.browserbase.api.errors.StagehandInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class SessionExecuteResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val data: JsonField, + private val success: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), + ) : this(data, success, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun data(): Data = data.getRequired("data") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun success(): Success = success.getRequired("success") + + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField = data + + /** + * Returns the raw JSON value of [success]. + * + * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [SessionExecuteResponse]. + * + * The following fields are required: + * ```java + * .data() + * .success() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SessionExecuteResponse]. */ + class Builder internal constructor() { + + private var data: JsonField? = null + private var success: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(sessionExecuteResponse: SessionExecuteResponse) = apply { + data = sessionExecuteResponse.data + success = sessionExecuteResponse.success + additionalProperties = sessionExecuteResponse.additionalProperties.toMutableMap() + } + + fun data(data: Data) = data(JsonField.of(data)) + + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed [Data] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun data(data: JsonField) = apply { this.data = data } + + fun success(success: Success) = success(JsonField.of(success)) + + /** + * Sets [Builder.success] to an arbitrary JSON value. + * + * You should usually call [Builder.success] with a well-typed [Success] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun success(success: JsonField) = apply { this.success = success } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [SessionExecuteResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .data() + * .success() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SessionExecuteResponse = + SessionExecuteResponse( + checkRequired("data", data), + checkRequired("success", success), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): SessionExecuteResponse = apply { + if (validated) { + return@apply + } + + data().validate() + success().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (data.asKnown().getOrNull()?.validity() ?: 0) + + (success.asKnown().getOrNull()?.validity() ?: 0) + + class Data + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val result: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("result") @ExcludeMissing result: JsonField = JsonMissing.of() + ) : this(result, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun result(): Result = result.getRequired("result") + + /** + * Returns the raw JSON value of [result]. + * + * Unlike [result], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("result") @ExcludeMissing fun _result(): JsonField = result + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Data]. + * + * The following fields are required: + * ```java + * .result() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var result: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + result = data.result + additionalProperties = data.additionalProperties.toMutableMap() + } + + fun result(result: Result) = result(JsonField.of(result)) + + /** + * Sets [Builder.result] to an arbitrary JSON value. + * + * You should usually call [Builder.result] with a well-typed [Result] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun result(result: JsonField) = apply { this.result = result } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .result() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Data = + Data(checkRequired("result", result), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Data = apply { + if (validated) { + return@apply + } + + result().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (result.asKnown().getOrNull()?.validity() ?: 0) + + class Result + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val actions: JsonField>, + private val completed: JsonField, + private val message: JsonField, + private val success: JsonField, + private val metadata: JsonField, + private val usage: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("actions") + @ExcludeMissing + actions: JsonField> = JsonMissing.of(), + @JsonProperty("completed") + @ExcludeMissing + completed: JsonField = JsonMissing.of(), + @JsonProperty("message") + @ExcludeMissing + message: JsonField = JsonMissing.of(), + @JsonProperty("success") + @ExcludeMissing + success: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + metadata: JsonField = JsonMissing.of(), + @JsonProperty("usage") @ExcludeMissing usage: JsonField = JsonMissing.of(), + ) : this(actions, completed, message, success, metadata, usage, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun actions(): List = actions.getRequired("actions") + + /** + * Whether the agent finished its task + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun completed(): Boolean = completed.getRequired("completed") + + /** + * Summary of what the agent accomplished + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun message(): String = message.getRequired("message") + + /** + * Whether the agent completed successfully + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun success(): Boolean = success.getRequired("success") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun metadata(): Optional = metadata.getOptional("metadata") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun usage(): Optional = usage.getOptional("usage") + + /** + * Returns the raw JSON value of [actions]. + * + * Unlike [actions], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("actions") + @ExcludeMissing + fun _actions(): JsonField> = actions + + /** + * Returns the raw JSON value of [completed]. + * + * Unlike [completed], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("completed") + @ExcludeMissing + fun _completed(): JsonField = completed + + /** + * Returns the raw JSON value of [message]. + * + * Unlike [message], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("message") @ExcludeMissing fun _message(): JsonField = message + + /** + * Returns the raw JSON value of [success]. + * + * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success + + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("metadata") + @ExcludeMissing + fun _metadata(): JsonField = metadata + + /** + * Returns the raw JSON value of [usage]. + * + * Unlike [usage], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("usage") @ExcludeMissing fun _usage(): JsonField = usage + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Result]. + * + * The following fields are required: + * ```java + * .actions() + * .completed() + * .message() + * .success() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Result]. */ + class Builder internal constructor() { + + private var actions: JsonField>? = null + private var completed: JsonField? = null + private var message: JsonField? = null + private var success: JsonField? = null + private var metadata: JsonField = JsonMissing.of() + private var usage: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(result: Result) = apply { + actions = result.actions.map { it.toMutableList() } + completed = result.completed + message = result.message + success = result.success + metadata = result.metadata + usage = result.usage + additionalProperties = result.additionalProperties.toMutableMap() + } + + fun actions(actions: List) = actions(JsonField.of(actions)) + + /** + * Sets [Builder.actions] to an arbitrary JSON value. + * + * You should usually call [Builder.actions] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun actions(actions: JsonField>) = apply { + this.actions = actions.map { it.toMutableList() } + } + + /** + * Adds a single [Action] to [actions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAction(action: Action) = apply { + actions = + (actions ?: JsonField.of(mutableListOf())).also { + checkKnown("actions", it).add(action) + } + } + + /** Whether the agent finished its task */ + fun completed(completed: Boolean) = completed(JsonField.of(completed)) + + /** + * Sets [Builder.completed] to an arbitrary JSON value. + * + * You should usually call [Builder.completed] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun completed(completed: JsonField) = apply { this.completed = completed } + + /** Summary of what the agent accomplished */ + fun message(message: String) = message(JsonField.of(message)) + + /** + * Sets [Builder.message] to an arbitrary JSON value. + * + * You should usually call [Builder.message] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun message(message: JsonField) = apply { this.message = message } + + /** Whether the agent completed successfully */ + fun success(success: Boolean) = success(JsonField.of(success)) + + /** + * Sets [Builder.success] to an arbitrary JSON value. + * + * You should usually call [Builder.success] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun success(success: JsonField) = apply { this.success = success } + + fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } + + fun usage(usage: Usage) = usage(JsonField.of(usage)) + + /** + * Sets [Builder.usage] to an arbitrary JSON value. + * + * You should usually call [Builder.usage] with a well-typed [Usage] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun usage(usage: JsonField) = apply { this.usage = usage } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Result]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .actions() + * .completed() + * .message() + * .success() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Result = + Result( + checkRequired("actions", actions).map { it.toImmutable() }, + checkRequired("completed", completed), + checkRequired("message", message), + checkRequired("success", success), + metadata, + usage, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Result = apply { + if (validated) { + return@apply + } + + actions().forEach { it.validate() } + completed() + message() + success() + metadata().ifPresent { it.validate() } + usage().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (actions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (completed.asKnown().isPresent) 1 else 0) + + (if (message.asKnown().isPresent) 1 else 0) + + (if (success.asKnown().isPresent) 1 else 0) + + (metadata.asKnown().getOrNull()?.validity() ?: 0) + + (usage.asKnown().getOrNull()?.validity() ?: 0) + + class Action + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val type: JsonField, + private val action: JsonField, + private val instruction: JsonField, + private val pageText: JsonField, + private val pageUrl: JsonField, + private val reasoning: JsonField, + private val taskCompleted: JsonField, + private val timeMs: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("type") + @ExcludeMissing + type: JsonField = JsonMissing.of(), + @JsonProperty("action") + @ExcludeMissing + action: JsonField = JsonMissing.of(), + @JsonProperty("instruction") + @ExcludeMissing + instruction: JsonField = JsonMissing.of(), + @JsonProperty("pageText") + @ExcludeMissing + pageText: JsonField = JsonMissing.of(), + @JsonProperty("pageUrl") + @ExcludeMissing + pageUrl: JsonField = JsonMissing.of(), + @JsonProperty("reasoning") + @ExcludeMissing + reasoning: JsonField = JsonMissing.of(), + @JsonProperty("taskCompleted") + @ExcludeMissing + taskCompleted: JsonField = JsonMissing.of(), + @JsonProperty("timeMs") + @ExcludeMissing + timeMs: JsonField = JsonMissing.of(), + ) : this( + type, + action, + instruction, + pageText, + pageUrl, + reasoning, + taskCompleted, + timeMs, + mutableMapOf(), + ) + + /** + * Type of action taken + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or + * is unexpectedly missing or null (e.g. if the server responded with an + * unexpected value). + */ + fun type(): String = type.getRequired("type") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun action(): Optional = action.getOptional("action") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun instruction(): Optional = instruction.getOptional("instruction") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun pageText(): Optional = pageText.getOptional("pageText") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun pageUrl(): Optional = pageUrl.getOptional("pageUrl") + + /** + * Agent's reasoning for taking this action + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun reasoning(): Optional = reasoning.getOptional("reasoning") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun taskCompleted(): Optional = taskCompleted.getOptional("taskCompleted") + + /** + * Time taken for this action in ms + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun timeMs(): Optional = timeMs.getOptional("timeMs") + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + /** + * Returns the raw JSON value of [action]. + * + * Unlike [action], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("action") @ExcludeMissing fun _action(): JsonField = action + + /** + * Returns the raw JSON value of [instruction]. + * + * Unlike [instruction], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("instruction") + @ExcludeMissing + fun _instruction(): JsonField = instruction + + /** + * Returns the raw JSON value of [pageText]. + * + * Unlike [pageText], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("pageText") + @ExcludeMissing + fun _pageText(): JsonField = pageText + + /** + * Returns the raw JSON value of [pageUrl]. + * + * Unlike [pageUrl], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("pageUrl") @ExcludeMissing fun _pageUrl(): JsonField = pageUrl + + /** + * Returns the raw JSON value of [reasoning]. + * + * Unlike [reasoning], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("reasoning") + @ExcludeMissing + fun _reasoning(): JsonField = reasoning + + /** + * Returns the raw JSON value of [taskCompleted]. + * + * Unlike [taskCompleted], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("taskCompleted") + @ExcludeMissing + fun _taskCompleted(): JsonField = taskCompleted + + /** + * Returns the raw JSON value of [timeMs]. + * + * Unlike [timeMs], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("timeMs") @ExcludeMissing fun _timeMs(): JsonField = timeMs + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Action]. + * + * The following fields are required: + * ```java + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Action]. */ + class Builder internal constructor() { + + private var type: JsonField? = null + private var action: JsonField = JsonMissing.of() + private var instruction: JsonField = JsonMissing.of() + private var pageText: JsonField = JsonMissing.of() + private var pageUrl: JsonField = JsonMissing.of() + private var reasoning: JsonField = JsonMissing.of() + private var taskCompleted: JsonField = JsonMissing.of() + private var timeMs: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(action: Action) = apply { + type = action.type + this.action = action.action + instruction = action.instruction + pageText = action.pageText + pageUrl = action.pageUrl + reasoning = action.reasoning + taskCompleted = action.taskCompleted + timeMs = action.timeMs + additionalProperties = action.additionalProperties.toMutableMap() + } + + /** Type of action taken */ + fun type(type: String) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + fun action(action: String) = action(JsonField.of(action)) + + /** + * Sets [Builder.action] to an arbitrary JSON value. + * + * You should usually call [Builder.action] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun action(action: JsonField) = apply { this.action = action } + + fun instruction(instruction: String) = instruction(JsonField.of(instruction)) + + /** + * Sets [Builder.instruction] to an arbitrary JSON value. + * + * You should usually call [Builder.instruction] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun instruction(instruction: JsonField) = apply { + this.instruction = instruction + } + + fun pageText(pageText: String) = pageText(JsonField.of(pageText)) + + /** + * Sets [Builder.pageText] to an arbitrary JSON value. + * + * You should usually call [Builder.pageText] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun pageText(pageText: JsonField) = apply { this.pageText = pageText } + + fun pageUrl(pageUrl: String) = pageUrl(JsonField.of(pageUrl)) + + /** + * Sets [Builder.pageUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.pageUrl] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun pageUrl(pageUrl: JsonField) = apply { this.pageUrl = pageUrl } + + /** Agent's reasoning for taking this action */ + fun reasoning(reasoning: String) = reasoning(JsonField.of(reasoning)) + + /** + * Sets [Builder.reasoning] to an arbitrary JSON value. + * + * You should usually call [Builder.reasoning] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun reasoning(reasoning: JsonField) = apply { + this.reasoning = reasoning + } + + fun taskCompleted(taskCompleted: Boolean) = + taskCompleted(JsonField.of(taskCompleted)) + + /** + * Sets [Builder.taskCompleted] to an arbitrary JSON value. + * + * You should usually call [Builder.taskCompleted] with a well-typed [Boolean] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun taskCompleted(taskCompleted: JsonField) = apply { + this.taskCompleted = taskCompleted + } + + /** Time taken for this action in ms */ + fun timeMs(timeMs: Double) = timeMs(JsonField.of(timeMs)) + + /** + * Sets [Builder.timeMs] to an arbitrary JSON value. + * + * You should usually call [Builder.timeMs] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun timeMs(timeMs: JsonField) = apply { this.timeMs = timeMs } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Action]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Action = + Action( + checkRequired("type", type), + action, + instruction, + pageText, + pageUrl, + reasoning, + taskCompleted, + timeMs, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Action = apply { + if (validated) { + return@apply + } + + type() + action() + instruction() + pageText() + pageUrl() + reasoning() + taskCompleted() + timeMs() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (type.asKnown().isPresent) 1 else 0) + + (if (action.asKnown().isPresent) 1 else 0) + + (if (instruction.asKnown().isPresent) 1 else 0) + + (if (pageText.asKnown().isPresent) 1 else 0) + + (if (pageUrl.asKnown().isPresent) 1 else 0) + + (if (reasoning.asKnown().isPresent) 1 else 0) + + (if (taskCompleted.asKnown().isPresent) 1 else 0) + + (if (timeMs.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Action && + type == other.type && + action == other.action && + instruction == other.instruction && + pageText == other.pageText && + pageUrl == other.pageUrl && + reasoning == other.reasoning && + taskCompleted == other.taskCompleted && + timeMs == other.timeMs && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + type, + action, + instruction, + pageText, + pageUrl, + reasoning, + taskCompleted, + timeMs, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Action{type=$type, action=$action, instruction=$instruction, pageText=$pageText, pageUrl=$pageUrl, reasoning=$reasoning, taskCompleted=$taskCompleted, timeMs=$timeMs, additionalProperties=$additionalProperties}" + } + + class Metadata + @JsonCreator + private constructor( + @com.fasterxml.jackson.annotation.JsonValue + private val additionalProperties: Map + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Metadata]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Metadata]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(metadata: Metadata) = apply { + additionalProperties = metadata.additionalProperties.toMutableMap() + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Metadata = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + additionalProperties.count { (_, value) -> + !value.isNull() && !value.isMissing() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Metadata && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + } + + class Usage + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val inferenceTimeMs: JsonField, + private val inputTokens: JsonField, + private val outputTokens: JsonField, + private val cachedInputTokens: JsonField, + private val reasoningTokens: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("inference_time_ms") + @ExcludeMissing + inferenceTimeMs: JsonField = JsonMissing.of(), + @JsonProperty("input_tokens") + @ExcludeMissing + inputTokens: JsonField = JsonMissing.of(), + @JsonProperty("output_tokens") + @ExcludeMissing + outputTokens: JsonField = JsonMissing.of(), + @JsonProperty("cached_input_tokens") + @ExcludeMissing + cachedInputTokens: JsonField = JsonMissing.of(), + @JsonProperty("reasoning_tokens") + @ExcludeMissing + reasoningTokens: JsonField = JsonMissing.of(), + ) : this( + inferenceTimeMs, + inputTokens, + outputTokens, + cachedInputTokens, + reasoningTokens, + mutableMapOf(), + ) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or + * is unexpectedly missing or null (e.g. if the server responded with an + * unexpected value). + */ + fun inferenceTimeMs(): Double = inferenceTimeMs.getRequired("inference_time_ms") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or + * is unexpectedly missing or null (e.g. if the server responded with an + * unexpected value). + */ + fun inputTokens(): Double = inputTokens.getRequired("input_tokens") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or + * is unexpectedly missing or null (e.g. if the server responded with an + * unexpected value). + */ + fun outputTokens(): Double = outputTokens.getRequired("output_tokens") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun cachedInputTokens(): Optional = + cachedInputTokens.getOptional("cached_input_tokens") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun reasoningTokens(): Optional = + reasoningTokens.getOptional("reasoning_tokens") + + /** + * Returns the raw JSON value of [inferenceTimeMs]. + * + * Unlike [inferenceTimeMs], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("inference_time_ms") + @ExcludeMissing + fun _inferenceTimeMs(): JsonField = inferenceTimeMs + + /** + * Returns the raw JSON value of [inputTokens]. + * + * Unlike [inputTokens], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("input_tokens") + @ExcludeMissing + fun _inputTokens(): JsonField = inputTokens + + /** + * Returns the raw JSON value of [outputTokens]. + * + * Unlike [outputTokens], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("output_tokens") + @ExcludeMissing + fun _outputTokens(): JsonField = outputTokens + + /** + * Returns the raw JSON value of [cachedInputTokens]. + * + * Unlike [cachedInputTokens], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("cached_input_tokens") + @ExcludeMissing + fun _cachedInputTokens(): JsonField = cachedInputTokens + + /** + * Returns the raw JSON value of [reasoningTokens]. + * + * Unlike [reasoningTokens], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("reasoning_tokens") + @ExcludeMissing + fun _reasoningTokens(): JsonField = reasoningTokens + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Usage]. + * + * The following fields are required: + * ```java + * .inferenceTimeMs() + * .inputTokens() + * .outputTokens() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Usage]. */ + class Builder internal constructor() { + + private var inferenceTimeMs: JsonField? = null + private var inputTokens: JsonField? = null + private var outputTokens: JsonField? = null + private var cachedInputTokens: JsonField = JsonMissing.of() + private var reasoningTokens: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(usage: Usage) = apply { + inferenceTimeMs = usage.inferenceTimeMs + inputTokens = usage.inputTokens + outputTokens = usage.outputTokens + cachedInputTokens = usage.cachedInputTokens + reasoningTokens = usage.reasoningTokens + additionalProperties = usage.additionalProperties.toMutableMap() + } + + fun inferenceTimeMs(inferenceTimeMs: Double) = + inferenceTimeMs(JsonField.of(inferenceTimeMs)) + + /** + * Sets [Builder.inferenceTimeMs] to an arbitrary JSON value. + * + * You should usually call [Builder.inferenceTimeMs] with a well-typed [Double] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun inferenceTimeMs(inferenceTimeMs: JsonField) = apply { + this.inferenceTimeMs = inferenceTimeMs + } + + fun inputTokens(inputTokens: Double) = inputTokens(JsonField.of(inputTokens)) + + /** + * Sets [Builder.inputTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.inputTokens] with a well-typed [Double] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun inputTokens(inputTokens: JsonField) = apply { + this.inputTokens = inputTokens + } + + fun outputTokens(outputTokens: Double) = + outputTokens(JsonField.of(outputTokens)) + + /** + * Sets [Builder.outputTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.outputTokens] with a well-typed [Double] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun outputTokens(outputTokens: JsonField) = apply { + this.outputTokens = outputTokens + } + + fun cachedInputTokens(cachedInputTokens: Double) = + cachedInputTokens(JsonField.of(cachedInputTokens)) + + /** + * Sets [Builder.cachedInputTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.cachedInputTokens] with a well-typed + * [Double] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun cachedInputTokens(cachedInputTokens: JsonField) = apply { + this.cachedInputTokens = cachedInputTokens + } + + fun reasoningTokens(reasoningTokens: Double) = + reasoningTokens(JsonField.of(reasoningTokens)) + + /** + * Sets [Builder.reasoningTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.reasoningTokens] with a well-typed [Double] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun reasoningTokens(reasoningTokens: JsonField) = apply { + this.reasoningTokens = reasoningTokens + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Usage]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .inferenceTimeMs() + * .inputTokens() + * .outputTokens() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Usage = + Usage( + checkRequired("inferenceTimeMs", inferenceTimeMs), + checkRequired("inputTokens", inputTokens), + checkRequired("outputTokens", outputTokens), + cachedInputTokens, + reasoningTokens, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Usage = apply { + if (validated) { + return@apply + } + + inferenceTimeMs() + inputTokens() + outputTokens() + cachedInputTokens() + reasoningTokens() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (inferenceTimeMs.asKnown().isPresent) 1 else 0) + + (if (inputTokens.asKnown().isPresent) 1 else 0) + + (if (outputTokens.asKnown().isPresent) 1 else 0) + + (if (cachedInputTokens.asKnown().isPresent) 1 else 0) + + (if (reasoningTokens.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Usage && + inferenceTimeMs == other.inferenceTimeMs && + inputTokens == other.inputTokens && + outputTokens == other.outputTokens && + cachedInputTokens == other.cachedInputTokens && + reasoningTokens == other.reasoningTokens && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + inferenceTimeMs, + inputTokens, + outputTokens, + cachedInputTokens, + reasoningTokens, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Usage{inferenceTimeMs=$inferenceTimeMs, inputTokens=$inputTokens, outputTokens=$outputTokens, cachedInputTokens=$cachedInputTokens, reasoningTokens=$reasoningTokens, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Result && + actions == other.actions && + completed == other.completed && + message == other.message && + success == other.success && + metadata == other.metadata && + usage == other.usage && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + actions, + completed, + message, + success, + metadata, + usage, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Result{actions=$actions, completed=$completed, message=$message, success=$success, metadata=$metadata, usage=$usage, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Data && + result == other.result && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(result, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Data{result=$result, additionalProperties=$additionalProperties}" + } + + class Success @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TRUE = of(true) + + @JvmStatic fun of(value: Boolean) = Success(JsonField.of(value)) + } + + /** An enum containing [Success]'s known values. */ + enum class Known { + TRUE + } + + /** + * An enum containing [Success]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Success] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TRUE, + /** An enum member indicating that [Success] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TRUE -> Value.TRUE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRUE -> Known.TRUE + else -> throw StagehandInvalidDataException("Unknown Success: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asBoolean(): Boolean = + _value().asBoolean().orElseThrow { + StagehandInvalidDataException("Value is not a Boolean") + } + + private var validated: Boolean = false + + fun validate(): Success = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Success && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SessionExecuteResponse && + data == other.data && + success == other.success && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(data, success, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "SessionExecuteResponse{data=$data, success=$success, additionalProperties=$additionalProperties}" +} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractParams.kt index 18414ff..b86cdc3 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractParams.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractParams.kt @@ -2,11 +2,23 @@ package com.browserbase.api.models.sessions +import com.browserbase.api.core.Enum +import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonField import com.browserbase.api.core.JsonMissing import com.browserbase.api.core.JsonValue import com.browserbase.api.core.Params import com.browserbase.api.core.http.Headers import com.browserbase.api.core.http.QueryParams +import com.browserbase.api.core.toImmutable +import com.browserbase.api.errors.StagehandInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import java.time.OffsetDateTime +import java.time.format.DateTimeFormatter +import java.util.Collections import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull @@ -14,27 +26,90 @@ import kotlin.jvm.optionals.getOrNull /** Extracts structured data from the current page using AI-powered analysis. */ class SessionExtractParams private constructor( - private val id: JsonValue?, - private val xLanguage: JsonValue?, - private val xSdkVersion: JsonValue?, - private val xSentAt: JsonValue?, - private val xStreamResponse: JsonValue?, - private val body: JsonValue, + private val id: String?, + private val xLanguage: XLanguage?, + private val xSdkVersion: String?, + private val xSentAt: OffsetDateTime?, + private val xStreamResponse: XStreamResponse?, + private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun id(): Optional = Optional.ofNullable(id) + /** Unique session identifier */ + fun id(): Optional = Optional.ofNullable(id) - fun xLanguage(): Optional = Optional.ofNullable(xLanguage) + /** Client SDK language */ + fun xLanguage(): Optional = Optional.ofNullable(xLanguage) - fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) + /** Version of the Stagehand SDK */ + fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) - fun xSentAt(): Optional = Optional.ofNullable(xSentAt) + /** ISO timestamp when request was sent */ + fun xSentAt(): Optional = Optional.ofNullable(xSentAt) - fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) + /** Whether to stream the response via SSE */ + fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) - fun body(): JsonValue = body + /** + * Target frame ID for the extraction + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun frameId(): Optional = body.frameId() + + /** + * Natural language instruction for what to extract + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun instruction(): Optional = body.instruction() + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun options(): Optional = body.options() + + /** + * JSON Schema defining the structure of data to extract + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun schema(): Optional = body.schema() + + /** + * Returns the raw JSON value of [frameId]. + * + * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _frameId(): JsonField = body._frameId() + + /** + * Returns the raw JSON value of [instruction]. + * + * Unlike [instruction], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _instruction(): JsonField = body._instruction() + + /** + * Returns the raw JSON value of [options]. + * + * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _options(): JsonField = body._options() + + /** + * Returns the raw JSON value of [schema]. + * + * Unlike [schema], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _schema(): JsonField = body._schema() + + fun _additionalBodyProperties(): Map = body._additionalProperties() /** Additional headers to send with the request. */ fun _additionalHeaders(): Headers = additionalHeaders @@ -55,12 +130,12 @@ private constructor( /** A builder for [SessionExtractParams]. */ class Builder internal constructor() { - private var id: JsonValue? = null - private var xLanguage: JsonValue? = null - private var xSdkVersion: JsonValue? = null - private var xSentAt: JsonValue? = null - private var xStreamResponse: JsonValue? = null - private var body: JsonValue = JsonMissing.of() + private var id: String? = null + private var xLanguage: XLanguage? = null + private var xSdkVersion: String? = null + private var xSentAt: OffsetDateTime? = null + private var xStreamResponse: XStreamResponse? = null + private var body: Body.Builder = Body.builder() private var additionalHeaders: Headers.Builder = Headers.builder() private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @@ -71,40 +146,118 @@ private constructor( xSdkVersion = sessionExtractParams.xSdkVersion xSentAt = sessionExtractParams.xSentAt xStreamResponse = sessionExtractParams.xStreamResponse - body = sessionExtractParams.body + body = sessionExtractParams.body.toBuilder() additionalHeaders = sessionExtractParams.additionalHeaders.toBuilder() additionalQueryParams = sessionExtractParams.additionalQueryParams.toBuilder() } - fun id(id: JsonValue?) = apply { this.id = id } + /** Unique session identifier */ + fun id(id: String?) = apply { this.id = id } /** Alias for calling [Builder.id] with `id.orElse(null)`. */ - fun id(id: Optional) = id(id.getOrNull()) + fun id(id: Optional) = id(id.getOrNull()) - fun xLanguage(xLanguage: JsonValue?) = apply { this.xLanguage = xLanguage } + /** Client SDK language */ + fun xLanguage(xLanguage: XLanguage?) = apply { this.xLanguage = xLanguage } /** Alias for calling [Builder.xLanguage] with `xLanguage.orElse(null)`. */ - fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) + fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) - fun xSdkVersion(xSdkVersion: JsonValue?) = apply { this.xSdkVersion = xSdkVersion } + /** Version of the Stagehand SDK */ + fun xSdkVersion(xSdkVersion: String?) = apply { this.xSdkVersion = xSdkVersion } /** Alias for calling [Builder.xSdkVersion] with `xSdkVersion.orElse(null)`. */ - fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) + fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) - fun xSentAt(xSentAt: JsonValue?) = apply { this.xSentAt = xSentAt } + /** ISO timestamp when request was sent */ + fun xSentAt(xSentAt: OffsetDateTime?) = apply { this.xSentAt = xSentAt } /** Alias for calling [Builder.xSentAt] with `xSentAt.orElse(null)`. */ - fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) + fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) - fun xStreamResponse(xStreamResponse: JsonValue?) = apply { + /** Whether to stream the response via SSE */ + fun xStreamResponse(xStreamResponse: XStreamResponse?) = apply { this.xStreamResponse = xStreamResponse } /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ - fun xStreamResponse(xStreamResponse: Optional) = + fun xStreamResponse(xStreamResponse: Optional) = xStreamResponse(xStreamResponse.getOrNull()) - fun body(body: JsonValue) = apply { this.body = body } + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [frameId] + * - [instruction] + * - [options] + * - [schema] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** Target frame ID for the extraction */ + fun frameId(frameId: String) = apply { body.frameId(frameId) } + + /** + * Sets [Builder.frameId] to an arbitrary JSON value. + * + * You should usually call [Builder.frameId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun frameId(frameId: JsonField) = apply { body.frameId(frameId) } + + /** Natural language instruction for what to extract */ + fun instruction(instruction: String) = apply { body.instruction(instruction) } + + /** + * Sets [Builder.instruction] to an arbitrary JSON value. + * + * You should usually call [Builder.instruction] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun instruction(instruction: JsonField) = apply { body.instruction(instruction) } + + fun options(options: Options) = apply { body.options(options) } + + /** + * Sets [Builder.options] to an arbitrary JSON value. + * + * You should usually call [Builder.options] with a well-typed [Options] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun options(options: JsonField) = apply { body.options(options) } + + /** JSON Schema defining the structure of data to extract */ + fun schema(schema: Schema) = apply { body.schema(schema) } + + /** + * Sets [Builder.schema] to an arbitrary JSON value. + * + * You should usually call [Builder.schema] with a well-typed [Schema] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun schema(schema: JsonField) = apply { body.schema(schema) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -216,24 +369,872 @@ private constructor( xSdkVersion, xSentAt, xStreamResponse, - body, + body.build(), additionalHeaders.build(), additionalQueryParams.build(), ) } - fun _body(): JsonValue = body + fun _body(): Body = body fun _pathParam(index: Int): String = when (index) { - 0 -> id?.toString() ?: "" + 0 -> id ?: "" else -> "" } - override fun _headers(): Headers = Headers.builder().apply { putAll(additionalHeaders) }.build() + override fun _headers(): Headers = + Headers.builder() + .apply { + xLanguage?.let { put("x-language", it.toString()) } + xSdkVersion?.let { put("x-sdk-version", it) } + xSentAt?.let { put("x-sent-at", DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(it)) } + xStreamResponse?.let { put("x-stream-response", it.toString()) } + putAll(additionalHeaders) + } + .build() override fun _queryParams(): QueryParams = additionalQueryParams + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val frameId: JsonField, + private val instruction: JsonField, + private val options: JsonField, + private val schema: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("frameId") @ExcludeMissing frameId: JsonField = JsonMissing.of(), + @JsonProperty("instruction") + @ExcludeMissing + instruction: JsonField = JsonMissing.of(), + @JsonProperty("options") @ExcludeMissing options: JsonField = JsonMissing.of(), + @JsonProperty("schema") @ExcludeMissing schema: JsonField = JsonMissing.of(), + ) : this(frameId, instruction, options, schema, mutableMapOf()) + + /** + * Target frame ID for the extraction + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun frameId(): Optional = frameId.getOptional("frameId") + + /** + * Natural language instruction for what to extract + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun instruction(): Optional = instruction.getOptional("instruction") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun options(): Optional = options.getOptional("options") + + /** + * JSON Schema defining the structure of data to extract + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun schema(): Optional = schema.getOptional("schema") + + /** + * Returns the raw JSON value of [frameId]. + * + * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("frameId") @ExcludeMissing fun _frameId(): JsonField = frameId + + /** + * Returns the raw JSON value of [instruction]. + * + * Unlike [instruction], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("instruction") + @ExcludeMissing + fun _instruction(): JsonField = instruction + + /** + * Returns the raw JSON value of [options]. + * + * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("options") @ExcludeMissing fun _options(): JsonField = options + + /** + * Returns the raw JSON value of [schema]. + * + * Unlike [schema], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("schema") @ExcludeMissing fun _schema(): JsonField = schema + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Body]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var frameId: JsonField = JsonMissing.of() + private var instruction: JsonField = JsonMissing.of() + private var options: JsonField = JsonMissing.of() + private var schema: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + frameId = body.frameId + instruction = body.instruction + options = body.options + schema = body.schema + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** Target frame ID for the extraction */ + fun frameId(frameId: String) = frameId(JsonField.of(frameId)) + + /** + * Sets [Builder.frameId] to an arbitrary JSON value. + * + * You should usually call [Builder.frameId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun frameId(frameId: JsonField) = apply { this.frameId = frameId } + + /** Natural language instruction for what to extract */ + fun instruction(instruction: String) = instruction(JsonField.of(instruction)) + + /** + * Sets [Builder.instruction] to an arbitrary JSON value. + * + * You should usually call [Builder.instruction] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun instruction(instruction: JsonField) = apply { + this.instruction = instruction + } + + fun options(options: Options) = options(JsonField.of(options)) + + /** + * Sets [Builder.options] to an arbitrary JSON value. + * + * You should usually call [Builder.options] with a well-typed [Options] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun options(options: JsonField) = apply { this.options = options } + + /** JSON Schema defining the structure of data to extract */ + fun schema(schema: Schema) = schema(JsonField.of(schema)) + + /** + * Sets [Builder.schema] to an arbitrary JSON value. + * + * You should usually call [Builder.schema] with a well-typed [Schema] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun schema(schema: JsonField) = apply { this.schema = schema } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = + Body(frameId, instruction, options, schema, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + frameId() + instruction() + options().ifPresent { it.validate() } + schema().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (frameId.asKnown().isPresent) 1 else 0) + + (if (instruction.asKnown().isPresent) 1 else 0) + + (options.asKnown().getOrNull()?.validity() ?: 0) + + (schema.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + frameId == other.frameId && + instruction == other.instruction && + options == other.options && + schema == other.schema && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(frameId, instruction, options, schema, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{frameId=$frameId, instruction=$instruction, options=$options, schema=$schema, additionalProperties=$additionalProperties}" + } + + class Options + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val model: JsonField, + private val selector: JsonField, + private val timeout: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), + @JsonProperty("selector") + @ExcludeMissing + selector: JsonField = JsonMissing.of(), + @JsonProperty("timeout") @ExcludeMissing timeout: JsonField = JsonMissing.of(), + ) : this(model, selector, timeout, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun model(): Optional = model.getOptional("model") + + /** + * CSS selector to scope extraction to a specific element + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun selector(): Optional = selector.getOptional("selector") + + /** + * Timeout in ms for the extraction + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun timeout(): Optional = timeout.getOptional("timeout") + + /** + * Returns the raw JSON value of [model]. + * + * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model + + /** + * Returns the raw JSON value of [selector]. + * + * Unlike [selector], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("selector") @ExcludeMissing fun _selector(): JsonField = selector + + /** + * Returns the raw JSON value of [timeout]. + * + * Unlike [timeout], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("timeout") @ExcludeMissing fun _timeout(): JsonField = timeout + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Options]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Options]. */ + class Builder internal constructor() { + + private var model: JsonField = JsonMissing.of() + private var selector: JsonField = JsonMissing.of() + private var timeout: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(options: Options) = apply { + model = options.model + selector = options.selector + timeout = options.timeout + additionalProperties = options.additionalProperties.toMutableMap() + } + + fun model(model: ModelConfig) = model(JsonField.of(model)) + + /** + * Sets [Builder.model] to an arbitrary JSON value. + * + * You should usually call [Builder.model] with a well-typed [ModelConfig] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun model(model: JsonField) = apply { this.model = model } + + /** Alias for calling [model] with `ModelConfig.ofString(string)`. */ + fun model(string: String) = model(ModelConfig.ofString(string)) + + /** Alias for calling [model] with `ModelConfig.ofUnionMember1(unionMember1)`. */ + fun model(unionMember1: ModelConfig.UnionMember1) = + model(ModelConfig.ofUnionMember1(unionMember1)) + + /** CSS selector to scope extraction to a specific element */ + fun selector(selector: String) = selector(JsonField.of(selector)) + + /** + * Sets [Builder.selector] to an arbitrary JSON value. + * + * You should usually call [Builder.selector] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun selector(selector: JsonField) = apply { this.selector = selector } + + /** Timeout in ms for the extraction */ + fun timeout(timeout: Double) = timeout(JsonField.of(timeout)) + + /** + * Sets [Builder.timeout] to an arbitrary JSON value. + * + * You should usually call [Builder.timeout] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun timeout(timeout: JsonField) = apply { this.timeout = timeout } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Options]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Options = + Options(model, selector, timeout, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Options = apply { + if (validated) { + return@apply + } + + model().ifPresent { it.validate() } + selector() + timeout() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (model.asKnown().getOrNull()?.validity() ?: 0) + + (if (selector.asKnown().isPresent) 1 else 0) + + (if (timeout.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Options && + model == other.model && + selector == other.selector && + timeout == other.timeout && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(model, selector, timeout, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Options{model=$model, selector=$selector, timeout=$timeout, additionalProperties=$additionalProperties}" + } + + /** JSON Schema defining the structure of data to extract */ + class Schema + @JsonCreator + private constructor( + @com.fasterxml.jackson.annotation.JsonValue + private val additionalProperties: Map + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Schema]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Schema]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(schema: Schema) = apply { + additionalProperties = schema.additionalProperties.toMutableMap() + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Schema]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Schema = Schema(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): Schema = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + additionalProperties.count { (_, value) -> !value.isNull() && !value.isMissing() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Schema && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Schema{additionalProperties=$additionalProperties}" + } + + /** Client SDK language */ + class XLanguage @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TYPESCRIPT = of("typescript") + + @JvmField val PYTHON = of("python") + + @JvmField val PLAYGROUND = of("playground") + + @JvmStatic fun of(value: String) = XLanguage(JsonField.of(value)) + } + + /** An enum containing [XLanguage]'s known values. */ + enum class Known { + TYPESCRIPT, + PYTHON, + PLAYGROUND, + } + + /** + * An enum containing [XLanguage]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [XLanguage] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TYPESCRIPT, + PYTHON, + PLAYGROUND, + /** + * An enum member indicating that [XLanguage] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TYPESCRIPT -> Value.TYPESCRIPT + PYTHON -> Value.PYTHON + PLAYGROUND -> Value.PLAYGROUND + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TYPESCRIPT -> Known.TYPESCRIPT + PYTHON -> Known.PYTHON + PLAYGROUND -> Known.PLAYGROUND + else -> throw StagehandInvalidDataException("Unknown XLanguage: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): XLanguage = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is XLanguage && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** Whether to stream the response via SSE */ + class XStreamResponse @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TRUE = of("true") + + @JvmField val FALSE = of("false") + + @JvmStatic fun of(value: String) = XStreamResponse(JsonField.of(value)) + } + + /** An enum containing [XStreamResponse]'s known values. */ + enum class Known { + TRUE, + FALSE, + } + + /** + * An enum containing [XStreamResponse]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [XStreamResponse] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TRUE, + FALSE, + /** + * An enum member indicating that [XStreamResponse] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TRUE -> Value.TRUE + FALSE -> Value.FALSE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRUE -> Known.TRUE + FALSE -> Known.FALSE + else -> throw StagehandInvalidDataException("Unknown XStreamResponse: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): XStreamResponse = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is XStreamResponse && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractResponse.kt index 1e08b0f..f48f24f 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractResponse.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractResponse.kt @@ -2,20 +2,61 @@ package com.browserbase.api.models.sessions +import com.browserbase.api.core.Enum import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonField +import com.browserbase.api.core.JsonMissing import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.checkRequired import com.browserbase.api.errors.StagehandInvalidDataException import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty import java.util.Collections import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull class SessionExtractResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor(private val additionalProperties: MutableMap) { +private constructor( + private val data: JsonField, + private val success: JsonField, + private val additionalProperties: MutableMap, +) { - @JsonCreator private constructor() : this(mutableMapOf()) + @JsonCreator + private constructor( + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), + ) : this(data, success, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun data(): Data = data.getRequired("data") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun success(): Success = success.getRequired("success") + + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField = data + + /** + * Returns the raw JSON value of [success]. + * + * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -31,20 +72,52 @@ private constructor(private val additionalProperties: MutableMap? = null + private var success: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(sessionExtractResponse: SessionExtractResponse) = apply { + data = sessionExtractResponse.data + success = sessionExtractResponse.success additionalProperties = sessionExtractResponse.additionalProperties.toMutableMap() } + fun data(data: Data) = data(JsonField.of(data)) + + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed [Data] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun data(data: JsonField) = apply { this.data = data } + + fun success(success: Success) = success(JsonField.of(success)) + + /** + * Sets [Builder.success] to an arbitrary JSON value. + * + * You should usually call [Builder.success] with a well-typed [Success] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun success(success: JsonField) = apply { this.success = success } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -68,9 +141,21 @@ private constructor(private val additionalProperties: MutableMap, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("result") @ExcludeMissing result: JsonValue = JsonMissing.of(), + @JsonProperty("actionId") @ExcludeMissing actionId: JsonField = JsonMissing.of(), + ) : this(result, actionId, mutableMapOf()) + + /** Extracted data matching the requested schema */ + @JsonProperty("result") @ExcludeMissing fun _result(): JsonValue = result + + /** + * Action ID for tracking + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun actionId(): Optional = actionId.getOptional("actionId") + + /** + * Returns the raw JSON value of [actionId]. + * + * Unlike [actionId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("actionId") @ExcludeMissing fun _actionId(): JsonField = actionId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Data]. + * + * The following fields are required: + * ```java + * .result() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var result: JsonValue? = null + private var actionId: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + result = data.result + actionId = data.actionId + additionalProperties = data.additionalProperties.toMutableMap() + } + + /** Extracted data matching the requested schema */ + fun result(result: JsonValue) = apply { this.result = result } + + /** Action ID for tracking */ + fun actionId(actionId: String) = actionId(JsonField.of(actionId)) + + /** + * Sets [Builder.actionId] to an arbitrary JSON value. + * + * You should usually call [Builder.actionId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun actionId(actionId: JsonField) = apply { this.actionId = actionId } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .result() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Data = + Data(checkRequired("result", result), actionId, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Data = apply { + if (validated) { + return@apply + } + + actionId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (if (actionId.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Data && + result == other.result && + actionId == other.actionId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(result, actionId, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Data{result=$result, actionId=$actionId, additionalProperties=$additionalProperties}" + } + + class Success @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TRUE = of(true) + + @JvmStatic fun of(value: Boolean) = Success(JsonField.of(value)) + } + + /** An enum containing [Success]'s known values. */ + enum class Known { + TRUE + } + + /** + * An enum containing [Success]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Success] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TRUE, + /** An enum member indicating that [Success] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TRUE -> Value.TRUE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRUE -> Known.TRUE + else -> throw StagehandInvalidDataException("Unknown Success: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asBoolean(): Boolean = + _value().asBoolean().orElseThrow { + StagehandInvalidDataException("Value is not a Boolean") + } + + private var validated: Boolean = false + + fun validate(): Success = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Success && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is SessionExtractResponse && additionalProperties == other.additionalProperties + return other is SessionExtractResponse && + data == other.data && + success == other.success && + additionalProperties == other.additionalProperties } - private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(data, success, additionalProperties) } override fun hashCode(): Int = hashCode - override fun toString() = "SessionExtractResponse{additionalProperties=$additionalProperties}" + override fun toString() = + "SessionExtractResponse{data=$data, success=$success, additionalProperties=$additionalProperties}" } diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateParams.kt index 9f282ab..b07cf2c 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateParams.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateParams.kt @@ -2,11 +2,23 @@ package com.browserbase.api.models.sessions +import com.browserbase.api.core.Enum +import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonField import com.browserbase.api.core.JsonMissing import com.browserbase.api.core.JsonValue import com.browserbase.api.core.Params +import com.browserbase.api.core.checkRequired import com.browserbase.api.core.http.Headers import com.browserbase.api.core.http.QueryParams +import com.browserbase.api.errors.StagehandInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import java.time.OffsetDateTime +import java.time.format.DateTimeFormatter +import java.util.Collections import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull @@ -14,27 +26,75 @@ import kotlin.jvm.optionals.getOrNull /** Navigates the browser to the specified URL. */ class SessionNavigateParams private constructor( - private val id: JsonValue?, - private val xLanguage: JsonValue?, - private val xSdkVersion: JsonValue?, - private val xSentAt: JsonValue?, - private val xStreamResponse: JsonValue?, - private val body: JsonValue, + private val id: String?, + private val xLanguage: XLanguage?, + private val xSdkVersion: String?, + private val xSentAt: OffsetDateTime?, + private val xStreamResponse: XStreamResponse?, + private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun id(): Optional = Optional.ofNullable(id) + /** Unique session identifier */ + fun id(): Optional = Optional.ofNullable(id) - fun xLanguage(): Optional = Optional.ofNullable(xLanguage) + /** Client SDK language */ + fun xLanguage(): Optional = Optional.ofNullable(xLanguage) - fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) + /** Version of the Stagehand SDK */ + fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) - fun xSentAt(): Optional = Optional.ofNullable(xSentAt) + /** ISO timestamp when request was sent */ + fun xSentAt(): Optional = Optional.ofNullable(xSentAt) - fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) + /** Whether to stream the response via SSE */ + fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) - fun body(): JsonValue = body + /** + * URL to navigate to + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun url(): String = body.url() + + /** + * Target frame ID for the navigation + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun frameId(): Optional = body.frameId() + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun options(): Optional = body.options() + + /** + * Returns the raw JSON value of [url]. + * + * Unlike [url], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _url(): JsonField = body._url() + + /** + * Returns the raw JSON value of [frameId]. + * + * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _frameId(): JsonField = body._frameId() + + /** + * Returns the raw JSON value of [options]. + * + * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _options(): JsonField = body._options() + + fun _additionalBodyProperties(): Map = body._additionalProperties() /** Additional headers to send with the request. */ fun _additionalHeaders(): Headers = additionalHeaders @@ -46,21 +106,26 @@ private constructor( companion object { - @JvmStatic fun none(): SessionNavigateParams = builder().build() - - /** Returns a mutable builder for constructing an instance of [SessionNavigateParams]. */ + /** + * Returns a mutable builder for constructing an instance of [SessionNavigateParams]. + * + * The following fields are required: + * ```java + * .url() + * ``` + */ @JvmStatic fun builder() = Builder() } /** A builder for [SessionNavigateParams]. */ class Builder internal constructor() { - private var id: JsonValue? = null - private var xLanguage: JsonValue? = null - private var xSdkVersion: JsonValue? = null - private var xSentAt: JsonValue? = null - private var xStreamResponse: JsonValue? = null - private var body: JsonValue = JsonMissing.of() + private var id: String? = null + private var xLanguage: XLanguage? = null + private var xSdkVersion: String? = null + private var xSentAt: OffsetDateTime? = null + private var xStreamResponse: XStreamResponse? = null + private var body: Body.Builder = Body.builder() private var additionalHeaders: Headers.Builder = Headers.builder() private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @@ -71,40 +136,105 @@ private constructor( xSdkVersion = sessionNavigateParams.xSdkVersion xSentAt = sessionNavigateParams.xSentAt xStreamResponse = sessionNavigateParams.xStreamResponse - body = sessionNavigateParams.body + body = sessionNavigateParams.body.toBuilder() additionalHeaders = sessionNavigateParams.additionalHeaders.toBuilder() additionalQueryParams = sessionNavigateParams.additionalQueryParams.toBuilder() } - fun id(id: JsonValue?) = apply { this.id = id } + /** Unique session identifier */ + fun id(id: String?) = apply { this.id = id } /** Alias for calling [Builder.id] with `id.orElse(null)`. */ - fun id(id: Optional) = id(id.getOrNull()) + fun id(id: Optional) = id(id.getOrNull()) - fun xLanguage(xLanguage: JsonValue?) = apply { this.xLanguage = xLanguage } + /** Client SDK language */ + fun xLanguage(xLanguage: XLanguage?) = apply { this.xLanguage = xLanguage } /** Alias for calling [Builder.xLanguage] with `xLanguage.orElse(null)`. */ - fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) + fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) - fun xSdkVersion(xSdkVersion: JsonValue?) = apply { this.xSdkVersion = xSdkVersion } + /** Version of the Stagehand SDK */ + fun xSdkVersion(xSdkVersion: String?) = apply { this.xSdkVersion = xSdkVersion } /** Alias for calling [Builder.xSdkVersion] with `xSdkVersion.orElse(null)`. */ - fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) + fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) - fun xSentAt(xSentAt: JsonValue?) = apply { this.xSentAt = xSentAt } + /** ISO timestamp when request was sent */ + fun xSentAt(xSentAt: OffsetDateTime?) = apply { this.xSentAt = xSentAt } /** Alias for calling [Builder.xSentAt] with `xSentAt.orElse(null)`. */ - fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) + fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) - fun xStreamResponse(xStreamResponse: JsonValue?) = apply { + /** Whether to stream the response via SSE */ + fun xStreamResponse(xStreamResponse: XStreamResponse?) = apply { this.xStreamResponse = xStreamResponse } /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ - fun xStreamResponse(xStreamResponse: Optional) = + fun xStreamResponse(xStreamResponse: Optional) = xStreamResponse(xStreamResponse.getOrNull()) - fun body(body: JsonValue) = apply { this.body = body } + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [url] + * - [frameId] + * - [options] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** URL to navigate to */ + fun url(url: String) = apply { body.url(url) } + + /** + * Sets [Builder.url] to an arbitrary JSON value. + * + * You should usually call [Builder.url] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun url(url: JsonField) = apply { body.url(url) } + + /** Target frame ID for the navigation */ + fun frameId(frameId: String) = apply { body.frameId(frameId) } + + /** + * Sets [Builder.frameId] to an arbitrary JSON value. + * + * You should usually call [Builder.frameId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun frameId(frameId: JsonField) = apply { body.frameId(frameId) } + + fun options(options: Options) = apply { body.options(options) } + + /** + * Sets [Builder.options] to an arbitrary JSON value. + * + * You should usually call [Builder.options] with a well-typed [Options] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun options(options: JsonField) = apply { body.options(options) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -208,6 +338,13 @@ private constructor( * Returns an immutable instance of [SessionNavigateParams]. * * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .url() + * ``` + * + * @throws IllegalStateException if any required field is unset. */ fun build(): SessionNavigateParams = SessionNavigateParams( @@ -216,24 +353,887 @@ private constructor( xSdkVersion, xSentAt, xStreamResponse, - body, + body.build(), additionalHeaders.build(), additionalQueryParams.build(), ) } - fun _body(): JsonValue = body + fun _body(): Body = body fun _pathParam(index: Int): String = when (index) { - 0 -> id?.toString() ?: "" + 0 -> id ?: "" else -> "" } - override fun _headers(): Headers = Headers.builder().apply { putAll(additionalHeaders) }.build() + override fun _headers(): Headers = + Headers.builder() + .apply { + xLanguage?.let { put("x-language", it.toString()) } + xSdkVersion?.let { put("x-sdk-version", it) } + xSentAt?.let { put("x-sent-at", DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(it)) } + xStreamResponse?.let { put("x-stream-response", it.toString()) } + putAll(additionalHeaders) + } + .build() override fun _queryParams(): QueryParams = additionalQueryParams + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val url: JsonField, + private val frameId: JsonField, + private val options: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("url") @ExcludeMissing url: JsonField = JsonMissing.of(), + @JsonProperty("frameId") @ExcludeMissing frameId: JsonField = JsonMissing.of(), + @JsonProperty("options") @ExcludeMissing options: JsonField = JsonMissing.of(), + ) : this(url, frameId, options, mutableMapOf()) + + /** + * URL to navigate to + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun url(): String = url.getRequired("url") + + /** + * Target frame ID for the navigation + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun frameId(): Optional = frameId.getOptional("frameId") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun options(): Optional = options.getOptional("options") + + /** + * Returns the raw JSON value of [url]. + * + * Unlike [url], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("url") @ExcludeMissing fun _url(): JsonField = url + + /** + * Returns the raw JSON value of [frameId]. + * + * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("frameId") @ExcludeMissing fun _frameId(): JsonField = frameId + + /** + * Returns the raw JSON value of [options]. + * + * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("options") @ExcludeMissing fun _options(): JsonField = options + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .url() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var url: JsonField? = null + private var frameId: JsonField = JsonMissing.of() + private var options: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + url = body.url + frameId = body.frameId + options = body.options + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** URL to navigate to */ + fun url(url: String) = url(JsonField.of(url)) + + /** + * Sets [Builder.url] to an arbitrary JSON value. + * + * You should usually call [Builder.url] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun url(url: JsonField) = apply { this.url = url } + + /** Target frame ID for the navigation */ + fun frameId(frameId: String) = frameId(JsonField.of(frameId)) + + /** + * Sets [Builder.frameId] to an arbitrary JSON value. + * + * You should usually call [Builder.frameId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun frameId(frameId: JsonField) = apply { this.frameId = frameId } + + fun options(options: Options) = options(JsonField.of(options)) + + /** + * Sets [Builder.options] to an arbitrary JSON value. + * + * You should usually call [Builder.options] with a well-typed [Options] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun options(options: JsonField) = apply { this.options = options } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .url() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("url", url), + frameId, + options, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + url() + frameId() + options().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (url.asKnown().isPresent) 1 else 0) + + (if (frameId.asKnown().isPresent) 1 else 0) + + (options.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + url == other.url && + frameId == other.frameId && + options == other.options && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(url, frameId, options, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{url=$url, frameId=$frameId, options=$options, additionalProperties=$additionalProperties}" + } + + class Options + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val referer: JsonField, + private val timeout: JsonField, + private val waitUntil: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("referer") @ExcludeMissing referer: JsonField = JsonMissing.of(), + @JsonProperty("timeout") @ExcludeMissing timeout: JsonField = JsonMissing.of(), + @JsonProperty("waitUntil") + @ExcludeMissing + waitUntil: JsonField = JsonMissing.of(), + ) : this(referer, timeout, waitUntil, mutableMapOf()) + + /** + * Referer header to send with the request + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun referer(): Optional = referer.getOptional("referer") + + /** + * Timeout in ms for the navigation + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun timeout(): Optional = timeout.getOptional("timeout") + + /** + * When to consider navigation complete + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun waitUntil(): Optional = waitUntil.getOptional("waitUntil") + + /** + * Returns the raw JSON value of [referer]. + * + * Unlike [referer], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("referer") @ExcludeMissing fun _referer(): JsonField = referer + + /** + * Returns the raw JSON value of [timeout]. + * + * Unlike [timeout], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("timeout") @ExcludeMissing fun _timeout(): JsonField = timeout + + /** + * Returns the raw JSON value of [waitUntil]. + * + * Unlike [waitUntil], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("waitUntil") + @ExcludeMissing + fun _waitUntil(): JsonField = waitUntil + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Options]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Options]. */ + class Builder internal constructor() { + + private var referer: JsonField = JsonMissing.of() + private var timeout: JsonField = JsonMissing.of() + private var waitUntil: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(options: Options) = apply { + referer = options.referer + timeout = options.timeout + waitUntil = options.waitUntil + additionalProperties = options.additionalProperties.toMutableMap() + } + + /** Referer header to send with the request */ + fun referer(referer: String) = referer(JsonField.of(referer)) + + /** + * Sets [Builder.referer] to an arbitrary JSON value. + * + * You should usually call [Builder.referer] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun referer(referer: JsonField) = apply { this.referer = referer } + + /** Timeout in ms for the navigation */ + fun timeout(timeout: Double) = timeout(JsonField.of(timeout)) + + /** + * Sets [Builder.timeout] to an arbitrary JSON value. + * + * You should usually call [Builder.timeout] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun timeout(timeout: JsonField) = apply { this.timeout = timeout } + + /** When to consider navigation complete */ + fun waitUntil(waitUntil: WaitUntil) = waitUntil(JsonField.of(waitUntil)) + + /** + * Sets [Builder.waitUntil] to an arbitrary JSON value. + * + * You should usually call [Builder.waitUntil] with a well-typed [WaitUntil] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun waitUntil(waitUntil: JsonField) = apply { this.waitUntil = waitUntil } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Options]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Options = + Options(referer, timeout, waitUntil, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Options = apply { + if (validated) { + return@apply + } + + referer() + timeout() + waitUntil().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (referer.asKnown().isPresent) 1 else 0) + + (if (timeout.asKnown().isPresent) 1 else 0) + + (waitUntil.asKnown().getOrNull()?.validity() ?: 0) + + /** When to consider navigation complete */ + class WaitUntil @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val LOAD = of("load") + + @JvmField val DOMCONTENTLOADED = of("domcontentloaded") + + @JvmField val NETWORKIDLE = of("networkidle") + + @JvmStatic fun of(value: String) = WaitUntil(JsonField.of(value)) + } + + /** An enum containing [WaitUntil]'s known values. */ + enum class Known { + LOAD, + DOMCONTENTLOADED, + NETWORKIDLE, + } + + /** + * An enum containing [WaitUntil]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [WaitUntil] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + LOAD, + DOMCONTENTLOADED, + NETWORKIDLE, + /** + * An enum member indicating that [WaitUntil] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + LOAD -> Value.LOAD + DOMCONTENTLOADED -> Value.DOMCONTENTLOADED + NETWORKIDLE -> Value.NETWORKIDLE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + LOAD -> Known.LOAD + DOMCONTENTLOADED -> Known.DOMCONTENTLOADED + NETWORKIDLE -> Known.NETWORKIDLE + else -> throw StagehandInvalidDataException("Unknown WaitUntil: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): WaitUntil = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is WaitUntil && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Options && + referer == other.referer && + timeout == other.timeout && + waitUntil == other.waitUntil && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(referer, timeout, waitUntil, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Options{referer=$referer, timeout=$timeout, waitUntil=$waitUntil, additionalProperties=$additionalProperties}" + } + + /** Client SDK language */ + class XLanguage @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TYPESCRIPT = of("typescript") + + @JvmField val PYTHON = of("python") + + @JvmField val PLAYGROUND = of("playground") + + @JvmStatic fun of(value: String) = XLanguage(JsonField.of(value)) + } + + /** An enum containing [XLanguage]'s known values. */ + enum class Known { + TYPESCRIPT, + PYTHON, + PLAYGROUND, + } + + /** + * An enum containing [XLanguage]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [XLanguage] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TYPESCRIPT, + PYTHON, + PLAYGROUND, + /** + * An enum member indicating that [XLanguage] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TYPESCRIPT -> Value.TYPESCRIPT + PYTHON -> Value.PYTHON + PLAYGROUND -> Value.PLAYGROUND + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TYPESCRIPT -> Known.TYPESCRIPT + PYTHON -> Known.PYTHON + PLAYGROUND -> Known.PLAYGROUND + else -> throw StagehandInvalidDataException("Unknown XLanguage: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): XLanguage = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is XLanguage && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** Whether to stream the response via SSE */ + class XStreamResponse @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TRUE = of("true") + + @JvmField val FALSE = of("false") + + @JvmStatic fun of(value: String) = XStreamResponse(JsonField.of(value)) + } + + /** An enum containing [XStreamResponse]'s known values. */ + enum class Known { + TRUE, + FALSE, + } + + /** + * An enum containing [XStreamResponse]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [XStreamResponse] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TRUE, + FALSE, + /** + * An enum member indicating that [XStreamResponse] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TRUE -> Value.TRUE + FALSE -> Value.FALSE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRUE -> Known.TRUE + FALSE -> Known.FALSE + else -> throw StagehandInvalidDataException("Unknown XStreamResponse: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): XStreamResponse = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is XStreamResponse && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponse.kt index 916d1a2..56a53a4 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponse.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponse.kt @@ -2,20 +2,61 @@ package com.browserbase.api.models.sessions +import com.browserbase.api.core.Enum import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonField +import com.browserbase.api.core.JsonMissing import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.checkRequired import com.browserbase.api.errors.StagehandInvalidDataException import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty import java.util.Collections import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull class SessionNavigateResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor(private val additionalProperties: MutableMap) { +private constructor( + private val data: JsonField, + private val success: JsonField, + private val additionalProperties: MutableMap, +) { - @JsonCreator private constructor() : this(mutableMapOf()) + @JsonCreator + private constructor( + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), + ) : this(data, success, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun data(): Data = data.getRequired("data") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun success(): Success = success.getRequired("success") + + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField = data + + /** + * Returns the raw JSON value of [success]. + * + * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -31,20 +72,52 @@ private constructor(private val additionalProperties: MutableMap? = null + private var success: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(sessionNavigateResponse: SessionNavigateResponse) = apply { + data = sessionNavigateResponse.data + success = sessionNavigateResponse.success additionalProperties = sessionNavigateResponse.additionalProperties.toMutableMap() } + fun data(data: Data) = data(JsonField.of(data)) + + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed [Data] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun data(data: JsonField) = apply { this.data = data } + + fun success(success: Success) = success(JsonField.of(success)) + + /** + * Sets [Builder.success] to an arbitrary JSON value. + * + * You should usually call [Builder.success] with a well-typed [Success] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun success(success: JsonField) = apply { this.success = success } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -68,9 +141,21 @@ private constructor(private val additionalProperties: MutableMap, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("result") @ExcludeMissing result: JsonValue = JsonMissing.of(), + @JsonProperty("actionId") @ExcludeMissing actionId: JsonField = JsonMissing.of(), + ) : this(result, actionId, mutableMapOf()) + + /** Navigation response (Playwright Response object or null) */ + @JsonProperty("result") @ExcludeMissing fun _result(): JsonValue = result + + /** + * Action ID for tracking + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun actionId(): Optional = actionId.getOptional("actionId") + + /** + * Returns the raw JSON value of [actionId]. + * + * Unlike [actionId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("actionId") @ExcludeMissing fun _actionId(): JsonField = actionId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Data]. + * + * The following fields are required: + * ```java + * .result() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var result: JsonValue? = null + private var actionId: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + result = data.result + actionId = data.actionId + additionalProperties = data.additionalProperties.toMutableMap() + } + + /** Navigation response (Playwright Response object or null) */ + fun result(result: JsonValue) = apply { this.result = result } + + /** Action ID for tracking */ + fun actionId(actionId: String) = actionId(JsonField.of(actionId)) + + /** + * Sets [Builder.actionId] to an arbitrary JSON value. + * + * You should usually call [Builder.actionId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun actionId(actionId: JsonField) = apply { this.actionId = actionId } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .result() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Data = + Data(checkRequired("result", result), actionId, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Data = apply { + if (validated) { + return@apply + } + + actionId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (if (actionId.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Data && + result == other.result && + actionId == other.actionId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(result, actionId, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Data{result=$result, actionId=$actionId, additionalProperties=$additionalProperties}" + } + + class Success @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TRUE = of(true) + + @JvmStatic fun of(value: Boolean) = Success(JsonField.of(value)) + } + + /** An enum containing [Success]'s known values. */ + enum class Known { + TRUE + } + + /** + * An enum containing [Success]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Success] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TRUE, + /** An enum member indicating that [Success] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TRUE -> Value.TRUE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRUE -> Known.TRUE + else -> throw StagehandInvalidDataException("Unknown Success: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asBoolean(): Boolean = + _value().asBoolean().orElseThrow { + StagehandInvalidDataException("Value is not a Boolean") + } + + private var validated: Boolean = false + + fun validate(): Success = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Success && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } override fun equals(other: Any?): Boolean { if (this === other) { @@ -104,12 +479,15 @@ private constructor(private val additionalProperties: MutableMap = Optional.ofNullable(id) + /** Unique session identifier */ + fun id(): Optional = Optional.ofNullable(id) - fun xLanguage(): Optional = Optional.ofNullable(xLanguage) + /** Client SDK language */ + fun xLanguage(): Optional = Optional.ofNullable(xLanguage) - fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) + /** Version of the Stagehand SDK */ + fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) - fun xSentAt(): Optional = Optional.ofNullable(xSentAt) + /** ISO timestamp when request was sent */ + fun xSentAt(): Optional = Optional.ofNullable(xSentAt) - fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) + /** Whether to stream the response via SSE */ + fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) - fun body(): JsonValue = body + /** + * Target frame ID for the observation + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun frameId(): Optional = body.frameId() + + /** + * Natural language instruction for what actions to find + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun instruction(): Optional = body.instruction() + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun options(): Optional = body.options() + + /** + * Returns the raw JSON value of [frameId]. + * + * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _frameId(): JsonField = body._frameId() + + /** + * Returns the raw JSON value of [instruction]. + * + * Unlike [instruction], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _instruction(): JsonField = body._instruction() + + /** + * Returns the raw JSON value of [options]. + * + * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _options(): JsonField = body._options() + + fun _additionalBodyProperties(): Map = body._additionalProperties() /** Additional headers to send with the request. */ fun _additionalHeaders(): Headers = additionalHeaders @@ -57,12 +116,12 @@ private constructor( /** A builder for [SessionObserveParams]. */ class Builder internal constructor() { - private var id: JsonValue? = null - private var xLanguage: JsonValue? = null - private var xSdkVersion: JsonValue? = null - private var xSentAt: JsonValue? = null - private var xStreamResponse: JsonValue? = null - private var body: JsonValue = JsonMissing.of() + private var id: String? = null + private var xLanguage: XLanguage? = null + private var xSdkVersion: String? = null + private var xSentAt: OffsetDateTime? = null + private var xStreamResponse: XStreamResponse? = null + private var body: Body.Builder = Body.builder() private var additionalHeaders: Headers.Builder = Headers.builder() private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @@ -73,40 +132,106 @@ private constructor( xSdkVersion = sessionObserveParams.xSdkVersion xSentAt = sessionObserveParams.xSentAt xStreamResponse = sessionObserveParams.xStreamResponse - body = sessionObserveParams.body + body = sessionObserveParams.body.toBuilder() additionalHeaders = sessionObserveParams.additionalHeaders.toBuilder() additionalQueryParams = sessionObserveParams.additionalQueryParams.toBuilder() } - fun id(id: JsonValue?) = apply { this.id = id } + /** Unique session identifier */ + fun id(id: String?) = apply { this.id = id } /** Alias for calling [Builder.id] with `id.orElse(null)`. */ - fun id(id: Optional) = id(id.getOrNull()) + fun id(id: Optional) = id(id.getOrNull()) - fun xLanguage(xLanguage: JsonValue?) = apply { this.xLanguage = xLanguage } + /** Client SDK language */ + fun xLanguage(xLanguage: XLanguage?) = apply { this.xLanguage = xLanguage } /** Alias for calling [Builder.xLanguage] with `xLanguage.orElse(null)`. */ - fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) + fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) - fun xSdkVersion(xSdkVersion: JsonValue?) = apply { this.xSdkVersion = xSdkVersion } + /** Version of the Stagehand SDK */ + fun xSdkVersion(xSdkVersion: String?) = apply { this.xSdkVersion = xSdkVersion } /** Alias for calling [Builder.xSdkVersion] with `xSdkVersion.orElse(null)`. */ - fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) + fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) - fun xSentAt(xSentAt: JsonValue?) = apply { this.xSentAt = xSentAt } + /** ISO timestamp when request was sent */ + fun xSentAt(xSentAt: OffsetDateTime?) = apply { this.xSentAt = xSentAt } /** Alias for calling [Builder.xSentAt] with `xSentAt.orElse(null)`. */ - fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) + fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) - fun xStreamResponse(xStreamResponse: JsonValue?) = apply { + /** Whether to stream the response via SSE */ + fun xStreamResponse(xStreamResponse: XStreamResponse?) = apply { this.xStreamResponse = xStreamResponse } /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ - fun xStreamResponse(xStreamResponse: Optional) = + fun xStreamResponse(xStreamResponse: Optional) = xStreamResponse(xStreamResponse.getOrNull()) - fun body(body: JsonValue) = apply { this.body = body } + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [frameId] + * - [instruction] + * - [options] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** Target frame ID for the observation */ + fun frameId(frameId: String) = apply { body.frameId(frameId) } + + /** + * Sets [Builder.frameId] to an arbitrary JSON value. + * + * You should usually call [Builder.frameId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun frameId(frameId: JsonField) = apply { body.frameId(frameId) } + + /** Natural language instruction for what actions to find */ + fun instruction(instruction: String) = apply { body.instruction(instruction) } + + /** + * Sets [Builder.instruction] to an arbitrary JSON value. + * + * You should usually call [Builder.instruction] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun instruction(instruction: JsonField) = apply { body.instruction(instruction) } + + fun options(options: Options) = apply { body.options(options) } + + /** + * Sets [Builder.options] to an arbitrary JSON value. + * + * You should usually call [Builder.options] with a well-typed [Options] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun options(options: JsonField) = apply { body.options(options) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -218,24 +343,738 @@ private constructor( xSdkVersion, xSentAt, xStreamResponse, - body, + body.build(), additionalHeaders.build(), additionalQueryParams.build(), ) } - fun _body(): JsonValue = body + fun _body(): Body = body fun _pathParam(index: Int): String = when (index) { - 0 -> id?.toString() ?: "" + 0 -> id ?: "" else -> "" } - override fun _headers(): Headers = Headers.builder().apply { putAll(additionalHeaders) }.build() + override fun _headers(): Headers = + Headers.builder() + .apply { + xLanguage?.let { put("x-language", it.toString()) } + xSdkVersion?.let { put("x-sdk-version", it) } + xSentAt?.let { put("x-sent-at", DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(it)) } + xStreamResponse?.let { put("x-stream-response", it.toString()) } + putAll(additionalHeaders) + } + .build() override fun _queryParams(): QueryParams = additionalQueryParams + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val frameId: JsonField, + private val instruction: JsonField, + private val options: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("frameId") @ExcludeMissing frameId: JsonField = JsonMissing.of(), + @JsonProperty("instruction") + @ExcludeMissing + instruction: JsonField = JsonMissing.of(), + @JsonProperty("options") @ExcludeMissing options: JsonField = JsonMissing.of(), + ) : this(frameId, instruction, options, mutableMapOf()) + + /** + * Target frame ID for the observation + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun frameId(): Optional = frameId.getOptional("frameId") + + /** + * Natural language instruction for what actions to find + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun instruction(): Optional = instruction.getOptional("instruction") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun options(): Optional = options.getOptional("options") + + /** + * Returns the raw JSON value of [frameId]. + * + * Unlike [frameId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("frameId") @ExcludeMissing fun _frameId(): JsonField = frameId + + /** + * Returns the raw JSON value of [instruction]. + * + * Unlike [instruction], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("instruction") + @ExcludeMissing + fun _instruction(): JsonField = instruction + + /** + * Returns the raw JSON value of [options]. + * + * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("options") @ExcludeMissing fun _options(): JsonField = options + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Body]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var frameId: JsonField = JsonMissing.of() + private var instruction: JsonField = JsonMissing.of() + private var options: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + frameId = body.frameId + instruction = body.instruction + options = body.options + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** Target frame ID for the observation */ + fun frameId(frameId: String) = frameId(JsonField.of(frameId)) + + /** + * Sets [Builder.frameId] to an arbitrary JSON value. + * + * You should usually call [Builder.frameId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun frameId(frameId: JsonField) = apply { this.frameId = frameId } + + /** Natural language instruction for what actions to find */ + fun instruction(instruction: String) = instruction(JsonField.of(instruction)) + + /** + * Sets [Builder.instruction] to an arbitrary JSON value. + * + * You should usually call [Builder.instruction] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun instruction(instruction: JsonField) = apply { + this.instruction = instruction + } + + fun options(options: Options) = options(JsonField.of(options)) + + /** + * Sets [Builder.options] to an arbitrary JSON value. + * + * You should usually call [Builder.options] with a well-typed [Options] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun options(options: JsonField) = apply { this.options = options } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = + Body(frameId, instruction, options, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + frameId() + instruction() + options().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (frameId.asKnown().isPresent) 1 else 0) + + (if (instruction.asKnown().isPresent) 1 else 0) + + (options.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + frameId == other.frameId && + instruction == other.instruction && + options == other.options && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(frameId, instruction, options, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{frameId=$frameId, instruction=$instruction, options=$options, additionalProperties=$additionalProperties}" + } + + class Options + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val model: JsonField, + private val selector: JsonField, + private val timeout: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), + @JsonProperty("selector") + @ExcludeMissing + selector: JsonField = JsonMissing.of(), + @JsonProperty("timeout") @ExcludeMissing timeout: JsonField = JsonMissing.of(), + ) : this(model, selector, timeout, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun model(): Optional = model.getOptional("model") + + /** + * CSS selector to scope observation to a specific element + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun selector(): Optional = selector.getOptional("selector") + + /** + * Timeout in ms for the observation + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun timeout(): Optional = timeout.getOptional("timeout") + + /** + * Returns the raw JSON value of [model]. + * + * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model + + /** + * Returns the raw JSON value of [selector]. + * + * Unlike [selector], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("selector") @ExcludeMissing fun _selector(): JsonField = selector + + /** + * Returns the raw JSON value of [timeout]. + * + * Unlike [timeout], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("timeout") @ExcludeMissing fun _timeout(): JsonField = timeout + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Options]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Options]. */ + class Builder internal constructor() { + + private var model: JsonField = JsonMissing.of() + private var selector: JsonField = JsonMissing.of() + private var timeout: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(options: Options) = apply { + model = options.model + selector = options.selector + timeout = options.timeout + additionalProperties = options.additionalProperties.toMutableMap() + } + + fun model(model: ModelConfig) = model(JsonField.of(model)) + + /** + * Sets [Builder.model] to an arbitrary JSON value. + * + * You should usually call [Builder.model] with a well-typed [ModelConfig] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun model(model: JsonField) = apply { this.model = model } + + /** Alias for calling [model] with `ModelConfig.ofString(string)`. */ + fun model(string: String) = model(ModelConfig.ofString(string)) + + /** Alias for calling [model] with `ModelConfig.ofUnionMember1(unionMember1)`. */ + fun model(unionMember1: ModelConfig.UnionMember1) = + model(ModelConfig.ofUnionMember1(unionMember1)) + + /** CSS selector to scope observation to a specific element */ + fun selector(selector: String) = selector(JsonField.of(selector)) + + /** + * Sets [Builder.selector] to an arbitrary JSON value. + * + * You should usually call [Builder.selector] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun selector(selector: JsonField) = apply { this.selector = selector } + + /** Timeout in ms for the observation */ + fun timeout(timeout: Double) = timeout(JsonField.of(timeout)) + + /** + * Sets [Builder.timeout] to an arbitrary JSON value. + * + * You should usually call [Builder.timeout] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun timeout(timeout: JsonField) = apply { this.timeout = timeout } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Options]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Options = + Options(model, selector, timeout, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Options = apply { + if (validated) { + return@apply + } + + model().ifPresent { it.validate() } + selector() + timeout() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (model.asKnown().getOrNull()?.validity() ?: 0) + + (if (selector.asKnown().isPresent) 1 else 0) + + (if (timeout.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Options && + model == other.model && + selector == other.selector && + timeout == other.timeout && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(model, selector, timeout, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Options{model=$model, selector=$selector, timeout=$timeout, additionalProperties=$additionalProperties}" + } + + /** Client SDK language */ + class XLanguage @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TYPESCRIPT = of("typescript") + + @JvmField val PYTHON = of("python") + + @JvmField val PLAYGROUND = of("playground") + + @JvmStatic fun of(value: String) = XLanguage(JsonField.of(value)) + } + + /** An enum containing [XLanguage]'s known values. */ + enum class Known { + TYPESCRIPT, + PYTHON, + PLAYGROUND, + } + + /** + * An enum containing [XLanguage]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [XLanguage] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TYPESCRIPT, + PYTHON, + PLAYGROUND, + /** + * An enum member indicating that [XLanguage] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TYPESCRIPT -> Value.TYPESCRIPT + PYTHON -> Value.PYTHON + PLAYGROUND -> Value.PLAYGROUND + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TYPESCRIPT -> Known.TYPESCRIPT + PYTHON -> Known.PYTHON + PLAYGROUND -> Known.PLAYGROUND + else -> throw StagehandInvalidDataException("Unknown XLanguage: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): XLanguage = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is XLanguage && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** Whether to stream the response via SSE */ + class XStreamResponse @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TRUE = of("true") + + @JvmField val FALSE = of("false") + + @JvmStatic fun of(value: String) = XStreamResponse(JsonField.of(value)) + } + + /** An enum containing [XStreamResponse]'s known values. */ + enum class Known { + TRUE, + FALSE, + } + + /** + * An enum containing [XStreamResponse]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [XStreamResponse] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TRUE, + FALSE, + /** + * An enum member indicating that [XStreamResponse] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TRUE -> Value.TRUE + FALSE -> Value.FALSE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRUE -> Known.TRUE + FALSE -> Known.FALSE + else -> throw StagehandInvalidDataException("Unknown XStreamResponse: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): XStreamResponse = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is XStreamResponse && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveResponse.kt index a27fc10..a06fd48 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveResponse.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveResponse.kt @@ -2,20 +2,63 @@ package com.browserbase.api.models.sessions +import com.browserbase.api.core.Enum import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonField +import com.browserbase.api.core.JsonMissing import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.checkKnown +import com.browserbase.api.core.checkRequired +import com.browserbase.api.core.toImmutable import com.browserbase.api.errors.StagehandInvalidDataException import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty import java.util.Collections import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull class SessionObserveResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor(private val additionalProperties: MutableMap) { +private constructor( + private val data: JsonField, + private val success: JsonField, + private val additionalProperties: MutableMap, +) { - @JsonCreator private constructor() : this(mutableMapOf()) + @JsonCreator + private constructor( + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), + ) : this(data, success, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun data(): Data = data.getRequired("data") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun success(): Success = success.getRequired("success") + + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField = data + + /** + * Returns the raw JSON value of [success]. + * + * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -31,20 +74,52 @@ private constructor(private val additionalProperties: MutableMap? = null + private var success: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(sessionObserveResponse: SessionObserveResponse) = apply { + data = sessionObserveResponse.data + success = sessionObserveResponse.success additionalProperties = sessionObserveResponse.additionalProperties.toMutableMap() } + fun data(data: Data) = data(JsonField.of(data)) + + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed [Data] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun data(data: JsonField) = apply { this.data = data } + + fun success(success: Success) = success(JsonField.of(success)) + + /** + * Sets [Builder.success] to an arbitrary JSON value. + * + * You should usually call [Builder.success] with a well-typed [Success] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun success(success: JsonField) = apply { this.success = success } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -68,9 +143,21 @@ private constructor(private val additionalProperties: MutableMap>, + private val actionId: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("result") + @ExcludeMissing + result: JsonField> = JsonMissing.of(), + @JsonProperty("actionId") @ExcludeMissing actionId: JsonField = JsonMissing.of(), + ) : this(result, actionId, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun result(): List = result.getRequired("result") + + /** + * Action ID for tracking + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun actionId(): Optional = actionId.getOptional("actionId") + + /** + * Returns the raw JSON value of [result]. + * + * Unlike [result], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("result") @ExcludeMissing fun _result(): JsonField> = result + + /** + * Returns the raw JSON value of [actionId]. + * + * Unlike [actionId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("actionId") @ExcludeMissing fun _actionId(): JsonField = actionId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Data]. + * + * The following fields are required: + * ```java + * .result() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var result: JsonField>? = null + private var actionId: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + result = data.result.map { it.toMutableList() } + actionId = data.actionId + additionalProperties = data.additionalProperties.toMutableMap() + } + + fun result(result: List) = result(JsonField.of(result)) + + /** + * Sets [Builder.result] to an arbitrary JSON value. + * + * You should usually call [Builder.result] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun result(result: JsonField>) = apply { + this.result = result.map { it.toMutableList() } + } + + /** + * Adds a single [Action] to [Builder.result]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addResult(result: Action) = apply { + this.result = + (this.result ?: JsonField.of(mutableListOf())).also { + checkKnown("result", it).add(result) + } + } + + /** Action ID for tracking */ + fun actionId(actionId: String) = actionId(JsonField.of(actionId)) + + /** + * Sets [Builder.actionId] to an arbitrary JSON value. + * + * You should usually call [Builder.actionId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun actionId(actionId: JsonField) = apply { this.actionId = actionId } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .result() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Data = + Data( + checkRequired("result", result).map { it.toImmutable() }, + actionId, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Data = apply { + if (validated) { + return@apply + } + + result().forEach { it.validate() } + actionId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (result.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (actionId.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Data && + result == other.result && + actionId == other.actionId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(result, actionId, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Data{result=$result, actionId=$actionId, additionalProperties=$additionalProperties}" + } + + class Success @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TRUE = of(true) + + @JvmStatic fun of(value: Boolean) = Success(JsonField.of(value)) + } + + /** An enum containing [Success]'s known values. */ + enum class Known { + TRUE + } + + /** + * An enum containing [Success]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Success] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TRUE, + /** An enum member indicating that [Success] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TRUE -> Value.TRUE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRUE -> Known.TRUE + else -> throw StagehandInvalidDataException("Unknown Success: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asBoolean(): Boolean = + _value().asBoolean().orElseThrow { + StagehandInvalidDataException("Value is not a Boolean") + } + + private var validated: Boolean = false + + fun validate(): Success = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Success && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is SessionObserveResponse && additionalProperties == other.additionalProperties + return other is SessionObserveResponse && + data == other.data && + success == other.success && + additionalProperties == other.additionalProperties } - private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(data, success, additionalProperties) } override fun hashCode(): Int = hashCode - override fun toString() = "SessionObserveResponse{additionalProperties=$additionalProperties}" + override fun toString() = + "SessionObserveResponse{data=$data, success=$success, additionalProperties=$additionalProperties}" } diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt index e0c55aa..20ba71d 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt @@ -2,11 +2,36 @@ package com.browserbase.api.models.sessions +import com.browserbase.api.core.BaseDeserializer +import com.browserbase.api.core.BaseSerializer +import com.browserbase.api.core.Enum +import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonField import com.browserbase.api.core.JsonMissing import com.browserbase.api.core.JsonValue import com.browserbase.api.core.Params +import com.browserbase.api.core.allMaxBy +import com.browserbase.api.core.checkKnown +import com.browserbase.api.core.checkRequired +import com.browserbase.api.core.getOrThrow import com.browserbase.api.core.http.Headers import com.browserbase.api.core.http.QueryParams +import com.browserbase.api.core.toImmutable +import com.browserbase.api.errors.StagehandInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.time.OffsetDateTime +import java.time.format.DateTimeFormatter +import java.util.Collections import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull @@ -17,24 +42,204 @@ import kotlin.jvm.optionals.getOrNull */ class SessionStartParams private constructor( - private val xLanguage: JsonValue?, - private val xSdkVersion: JsonValue?, - private val xSentAt: JsonValue?, - private val xStreamResponse: JsonValue?, - private val body: JsonValue, + private val xLanguage: XLanguage?, + private val xSdkVersion: String?, + private val xSentAt: OffsetDateTime?, + private val xStreamResponse: XStreamResponse?, + private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun xLanguage(): Optional = Optional.ofNullable(xLanguage) + /** Client SDK language */ + fun xLanguage(): Optional = Optional.ofNullable(xLanguage) - fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) + /** Version of the Stagehand SDK */ + fun xSdkVersion(): Optional = Optional.ofNullable(xSdkVersion) - fun xSentAt(): Optional = Optional.ofNullable(xSentAt) + /** ISO timestamp when request was sent */ + fun xSentAt(): Optional = Optional.ofNullable(xSentAt) - fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) + /** Whether to stream the response via SSE */ + fun xStreamResponse(): Optional = Optional.ofNullable(xStreamResponse) - fun body(): JsonValue = body + /** + * Model name to use for AI operations + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun modelName(): String = body.modelName() + + /** + * Timeout in ms for act operations + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun actTimeoutMs(): Optional = body.actTimeoutMs() + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun browser(): Optional = body.browser() + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun browserbaseSessionCreateParams(): Optional = + body.browserbaseSessionCreateParams() + + /** + * Existing Browserbase session ID to resume + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun browserbaseSessionId(): Optional = body.browserbaseSessionId() + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun debugDom(): Optional = body.debugDom() + + /** + * Timeout in ms to wait for DOM to settle + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun domSettleTimeoutMs(): Optional = body.domSettleTimeoutMs() + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun experimental(): Optional = body.experimental() + + /** + * Enable self-healing for failed actions + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun selfHeal(): Optional = body.selfHeal() + + /** + * Custom system prompt for AI operations + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun systemPrompt(): Optional = body.systemPrompt() + + /** + * Logging verbosity level (0=quiet, 1=normal, 2=debug) + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun verbose(): Optional = body.verbose() + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun waitForCaptchaSolves(): Optional = body.waitForCaptchaSolves() + + /** + * Returns the raw JSON value of [modelName]. + * + * Unlike [modelName], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _modelName(): JsonField = body._modelName() + + /** + * Returns the raw JSON value of [actTimeoutMs]. + * + * Unlike [actTimeoutMs], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _actTimeoutMs(): JsonField = body._actTimeoutMs() + + /** + * Returns the raw JSON value of [browser]. + * + * Unlike [browser], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _browser(): JsonField = body._browser() + + /** + * Returns the raw JSON value of [browserbaseSessionCreateParams]. + * + * Unlike [browserbaseSessionCreateParams], this method doesn't throw if the JSON field has an + * unexpected type. + */ + fun _browserbaseSessionCreateParams(): JsonField = + body._browserbaseSessionCreateParams() + + /** + * Returns the raw JSON value of [browserbaseSessionId]. + * + * Unlike [browserbaseSessionId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + fun _browserbaseSessionId(): JsonField = body._browserbaseSessionId() + + /** + * Returns the raw JSON value of [debugDom]. + * + * Unlike [debugDom], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _debugDom(): JsonField = body._debugDom() + + /** + * Returns the raw JSON value of [domSettleTimeoutMs]. + * + * Unlike [domSettleTimeoutMs], this method doesn't throw if the JSON field has an unexpected + * type. + */ + fun _domSettleTimeoutMs(): JsonField = body._domSettleTimeoutMs() + + /** + * Returns the raw JSON value of [experimental]. + * + * Unlike [experimental], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _experimental(): JsonField = body._experimental() + + /** + * Returns the raw JSON value of [selfHeal]. + * + * Unlike [selfHeal], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _selfHeal(): JsonField = body._selfHeal() + + /** + * Returns the raw JSON value of [systemPrompt]. + * + * Unlike [systemPrompt], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _systemPrompt(): JsonField = body._systemPrompt() + + /** + * Returns the raw JSON value of [verbose]. + * + * Unlike [verbose], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _verbose(): JsonField = body._verbose() + + /** + * Returns the raw JSON value of [waitForCaptchaSolves]. + * + * Unlike [waitForCaptchaSolves], this method doesn't throw if the JSON field has an unexpected + * type. + */ + fun _waitForCaptchaSolves(): JsonField = body._waitForCaptchaSolves() + + fun _additionalBodyProperties(): Map = body._additionalProperties() /** Additional headers to send with the request. */ fun _additionalHeaders(): Headers = additionalHeaders @@ -46,20 +251,25 @@ private constructor( companion object { - @JvmStatic fun none(): SessionStartParams = builder().build() - - /** Returns a mutable builder for constructing an instance of [SessionStartParams]. */ + /** + * Returns a mutable builder for constructing an instance of [SessionStartParams]. + * + * The following fields are required: + * ```java + * .modelName() + * ``` + */ @JvmStatic fun builder() = Builder() } /** A builder for [SessionStartParams]. */ class Builder internal constructor() { - private var xLanguage: JsonValue? = null - private var xSdkVersion: JsonValue? = null - private var xSentAt: JsonValue? = null - private var xStreamResponse: JsonValue? = null - private var body: JsonValue = JsonMissing.of() + private var xLanguage: XLanguage? = null + private var xSdkVersion: String? = null + private var xSentAt: OffsetDateTime? = null + private var xStreamResponse: XStreamResponse? = null + private var body: Body.Builder = Body.builder() private var additionalHeaders: Headers.Builder = Headers.builder() private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @@ -69,35 +279,229 @@ private constructor( xSdkVersion = sessionStartParams.xSdkVersion xSentAt = sessionStartParams.xSentAt xStreamResponse = sessionStartParams.xStreamResponse - body = sessionStartParams.body + body = sessionStartParams.body.toBuilder() additionalHeaders = sessionStartParams.additionalHeaders.toBuilder() additionalQueryParams = sessionStartParams.additionalQueryParams.toBuilder() } - fun xLanguage(xLanguage: JsonValue?) = apply { this.xLanguage = xLanguage } + /** Client SDK language */ + fun xLanguage(xLanguage: XLanguage?) = apply { this.xLanguage = xLanguage } /** Alias for calling [Builder.xLanguage] with `xLanguage.orElse(null)`. */ - fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) + fun xLanguage(xLanguage: Optional) = xLanguage(xLanguage.getOrNull()) - fun xSdkVersion(xSdkVersion: JsonValue?) = apply { this.xSdkVersion = xSdkVersion } + /** Version of the Stagehand SDK */ + fun xSdkVersion(xSdkVersion: String?) = apply { this.xSdkVersion = xSdkVersion } /** Alias for calling [Builder.xSdkVersion] with `xSdkVersion.orElse(null)`. */ - fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) + fun xSdkVersion(xSdkVersion: Optional) = xSdkVersion(xSdkVersion.getOrNull()) - fun xSentAt(xSentAt: JsonValue?) = apply { this.xSentAt = xSentAt } + /** ISO timestamp when request was sent */ + fun xSentAt(xSentAt: OffsetDateTime?) = apply { this.xSentAt = xSentAt } /** Alias for calling [Builder.xSentAt] with `xSentAt.orElse(null)`. */ - fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) + fun xSentAt(xSentAt: Optional) = xSentAt(xSentAt.getOrNull()) - fun xStreamResponse(xStreamResponse: JsonValue?) = apply { + /** Whether to stream the response via SSE */ + fun xStreamResponse(xStreamResponse: XStreamResponse?) = apply { this.xStreamResponse = xStreamResponse } /** Alias for calling [Builder.xStreamResponse] with `xStreamResponse.orElse(null)`. */ - fun xStreamResponse(xStreamResponse: Optional) = + fun xStreamResponse(xStreamResponse: Optional) = xStreamResponse(xStreamResponse.getOrNull()) - fun body(body: JsonValue) = apply { this.body = body } + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [modelName] + * - [actTimeoutMs] + * - [browser] + * - [browserbaseSessionCreateParams] + * - [browserbaseSessionId] + * - etc. + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** Model name to use for AI operations */ + fun modelName(modelName: String) = apply { body.modelName(modelName) } + + /** + * Sets [Builder.modelName] to an arbitrary JSON value. + * + * You should usually call [Builder.modelName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun modelName(modelName: JsonField) = apply { body.modelName(modelName) } + + /** Timeout in ms for act operations */ + fun actTimeoutMs(actTimeoutMs: Double) = apply { body.actTimeoutMs(actTimeoutMs) } + + /** + * Sets [Builder.actTimeoutMs] to an arbitrary JSON value. + * + * You should usually call [Builder.actTimeoutMs] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun actTimeoutMs(actTimeoutMs: JsonField) = apply { + body.actTimeoutMs(actTimeoutMs) + } + + fun browser(browser: Browser) = apply { body.browser(browser) } + + /** + * Sets [Builder.browser] to an arbitrary JSON value. + * + * You should usually call [Builder.browser] with a well-typed [Browser] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun browser(browser: JsonField) = apply { body.browser(browser) } + + fun browserbaseSessionCreateParams( + browserbaseSessionCreateParams: BrowserbaseSessionCreateParams + ) = apply { body.browserbaseSessionCreateParams(browserbaseSessionCreateParams) } + + /** + * Sets [Builder.browserbaseSessionCreateParams] to an arbitrary JSON value. + * + * You should usually call [Builder.browserbaseSessionCreateParams] with a well-typed + * [BrowserbaseSessionCreateParams] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun browserbaseSessionCreateParams( + browserbaseSessionCreateParams: JsonField + ) = apply { body.browserbaseSessionCreateParams(browserbaseSessionCreateParams) } + + /** Existing Browserbase session ID to resume */ + fun browserbaseSessionId(browserbaseSessionId: String) = apply { + body.browserbaseSessionId(browserbaseSessionId) + } + + /** + * Sets [Builder.browserbaseSessionId] to an arbitrary JSON value. + * + * You should usually call [Builder.browserbaseSessionId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun browserbaseSessionId(browserbaseSessionId: JsonField) = apply { + body.browserbaseSessionId(browserbaseSessionId) + } + + fun debugDom(debugDom: Boolean) = apply { body.debugDom(debugDom) } + + /** + * Sets [Builder.debugDom] to an arbitrary JSON value. + * + * You should usually call [Builder.debugDom] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun debugDom(debugDom: JsonField) = apply { body.debugDom(debugDom) } + + /** Timeout in ms to wait for DOM to settle */ + fun domSettleTimeoutMs(domSettleTimeoutMs: Double) = apply { + body.domSettleTimeoutMs(domSettleTimeoutMs) + } + + /** + * Sets [Builder.domSettleTimeoutMs] to an arbitrary JSON value. + * + * You should usually call [Builder.domSettleTimeoutMs] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun domSettleTimeoutMs(domSettleTimeoutMs: JsonField) = apply { + body.domSettleTimeoutMs(domSettleTimeoutMs) + } + + fun experimental(experimental: Boolean) = apply { body.experimental(experimental) } + + /** + * Sets [Builder.experimental] to an arbitrary JSON value. + * + * You should usually call [Builder.experimental] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun experimental(experimental: JsonField) = apply { + body.experimental(experimental) + } + + /** Enable self-healing for failed actions */ + fun selfHeal(selfHeal: Boolean) = apply { body.selfHeal(selfHeal) } + + /** + * Sets [Builder.selfHeal] to an arbitrary JSON value. + * + * You should usually call [Builder.selfHeal] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun selfHeal(selfHeal: JsonField) = apply { body.selfHeal(selfHeal) } + + /** Custom system prompt for AI operations */ + fun systemPrompt(systemPrompt: String) = apply { body.systemPrompt(systemPrompt) } + + /** + * Sets [Builder.systemPrompt] to an arbitrary JSON value. + * + * You should usually call [Builder.systemPrompt] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun systemPrompt(systemPrompt: JsonField) = apply { + body.systemPrompt(systemPrompt) + } + + /** Logging verbosity level (0=quiet, 1=normal, 2=debug) */ + fun verbose(verbose: Verbose) = apply { body.verbose(verbose) } + + /** + * Sets [Builder.verbose] to an arbitrary JSON value. + * + * You should usually call [Builder.verbose] with a well-typed [Verbose] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun verbose(verbose: JsonField) = apply { body.verbose(verbose) } + + fun waitForCaptchaSolves(waitForCaptchaSolves: Boolean) = apply { + body.waitForCaptchaSolves(waitForCaptchaSolves) + } + + /** + * Sets [Builder.waitForCaptchaSolves] to an arbitrary JSON value. + * + * You should usually call [Builder.waitForCaptchaSolves] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun waitForCaptchaSolves(waitForCaptchaSolves: JsonField) = apply { + body.waitForCaptchaSolves(waitForCaptchaSolves) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } fun additionalHeaders(additionalHeaders: Headers) = apply { this.additionalHeaders.clear() @@ -201,6 +605,13 @@ private constructor( * Returns an immutable instance of [SessionStartParams]. * * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .modelName() + * ``` + * + * @throws IllegalStateException if any required field is unset. */ fun build(): SessionStartParams = SessionStartParams( @@ -208,18 +619,7241 @@ private constructor( xSdkVersion, xSentAt, xStreamResponse, - body, + body.build(), additionalHeaders.build(), additionalQueryParams.build(), ) } - fun _body(): JsonValue = body + fun _body(): Body = body - override fun _headers(): Headers = Headers.builder().apply { putAll(additionalHeaders) }.build() + override fun _headers(): Headers = + Headers.builder() + .apply { + xLanguage?.let { put("x-language", it.toString()) } + xSdkVersion?.let { put("x-sdk-version", it) } + xSentAt?.let { put("x-sent-at", DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(it)) } + xStreamResponse?.let { put("x-stream-response", it.toString()) } + putAll(additionalHeaders) + } + .build() override fun _queryParams(): QueryParams = additionalQueryParams + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val modelName: JsonField, + private val actTimeoutMs: JsonField, + private val browser: JsonField, + private val browserbaseSessionCreateParams: JsonField, + private val browserbaseSessionId: JsonField, + private val debugDom: JsonField, + private val domSettleTimeoutMs: JsonField, + private val experimental: JsonField, + private val selfHeal: JsonField, + private val systemPrompt: JsonField, + private val verbose: JsonField, + private val waitForCaptchaSolves: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("modelName") + @ExcludeMissing + modelName: JsonField = JsonMissing.of(), + @JsonProperty("actTimeoutMs") + @ExcludeMissing + actTimeoutMs: JsonField = JsonMissing.of(), + @JsonProperty("browser") @ExcludeMissing browser: JsonField = JsonMissing.of(), + @JsonProperty("browserbaseSessionCreateParams") + @ExcludeMissing + browserbaseSessionCreateParams: JsonField = + JsonMissing.of(), + @JsonProperty("browserbaseSessionID") + @ExcludeMissing + browserbaseSessionId: JsonField = JsonMissing.of(), + @JsonProperty("debugDom") + @ExcludeMissing + debugDom: JsonField = JsonMissing.of(), + @JsonProperty("domSettleTimeoutMs") + @ExcludeMissing + domSettleTimeoutMs: JsonField = JsonMissing.of(), + @JsonProperty("experimental") + @ExcludeMissing + experimental: JsonField = JsonMissing.of(), + @JsonProperty("selfHeal") + @ExcludeMissing + selfHeal: JsonField = JsonMissing.of(), + @JsonProperty("systemPrompt") + @ExcludeMissing + systemPrompt: JsonField = JsonMissing.of(), + @JsonProperty("verbose") @ExcludeMissing verbose: JsonField = JsonMissing.of(), + @JsonProperty("waitForCaptchaSolves") + @ExcludeMissing + waitForCaptchaSolves: JsonField = JsonMissing.of(), + ) : this( + modelName, + actTimeoutMs, + browser, + browserbaseSessionCreateParams, + browserbaseSessionId, + debugDom, + domSettleTimeoutMs, + experimental, + selfHeal, + systemPrompt, + verbose, + waitForCaptchaSolves, + mutableMapOf(), + ) + + /** + * Model name to use for AI operations + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun modelName(): String = modelName.getRequired("modelName") + + /** + * Timeout in ms for act operations + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun actTimeoutMs(): Optional = actTimeoutMs.getOptional("actTimeoutMs") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun browser(): Optional = browser.getOptional("browser") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun browserbaseSessionCreateParams(): Optional = + browserbaseSessionCreateParams.getOptional("browserbaseSessionCreateParams") + + /** + * Existing Browserbase session ID to resume + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun browserbaseSessionId(): Optional = + browserbaseSessionId.getOptional("browserbaseSessionID") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun debugDom(): Optional = debugDom.getOptional("debugDom") + + /** + * Timeout in ms to wait for DOM to settle + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun domSettleTimeoutMs(): Optional = + domSettleTimeoutMs.getOptional("domSettleTimeoutMs") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun experimental(): Optional = experimental.getOptional("experimental") + + /** + * Enable self-healing for failed actions + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun selfHeal(): Optional = selfHeal.getOptional("selfHeal") + + /** + * Custom system prompt for AI operations + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun systemPrompt(): Optional = systemPrompt.getOptional("systemPrompt") + + /** + * Logging verbosity level (0=quiet, 1=normal, 2=debug) + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun verbose(): Optional = verbose.getOptional("verbose") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun waitForCaptchaSolves(): Optional = + waitForCaptchaSolves.getOptional("waitForCaptchaSolves") + + /** + * Returns the raw JSON value of [modelName]. + * + * Unlike [modelName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("modelName") @ExcludeMissing fun _modelName(): JsonField = modelName + + /** + * Returns the raw JSON value of [actTimeoutMs]. + * + * Unlike [actTimeoutMs], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("actTimeoutMs") + @ExcludeMissing + fun _actTimeoutMs(): JsonField = actTimeoutMs + + /** + * Returns the raw JSON value of [browser]. + * + * Unlike [browser], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("browser") @ExcludeMissing fun _browser(): JsonField = browser + + /** + * Returns the raw JSON value of [browserbaseSessionCreateParams]. + * + * Unlike [browserbaseSessionCreateParams], this method doesn't throw if the JSON field has + * an unexpected type. + */ + @JsonProperty("browserbaseSessionCreateParams") + @ExcludeMissing + fun _browserbaseSessionCreateParams(): JsonField = + browserbaseSessionCreateParams + + /** + * Returns the raw JSON value of [browserbaseSessionId]. + * + * Unlike [browserbaseSessionId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("browserbaseSessionID") + @ExcludeMissing + fun _browserbaseSessionId(): JsonField = browserbaseSessionId + + /** + * Returns the raw JSON value of [debugDom]. + * + * Unlike [debugDom], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("debugDom") @ExcludeMissing fun _debugDom(): JsonField = debugDom + + /** + * Returns the raw JSON value of [domSettleTimeoutMs]. + * + * Unlike [domSettleTimeoutMs], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("domSettleTimeoutMs") + @ExcludeMissing + fun _domSettleTimeoutMs(): JsonField = domSettleTimeoutMs + + /** + * Returns the raw JSON value of [experimental]. + * + * Unlike [experimental], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("experimental") + @ExcludeMissing + fun _experimental(): JsonField = experimental + + /** + * Returns the raw JSON value of [selfHeal]. + * + * Unlike [selfHeal], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("selfHeal") @ExcludeMissing fun _selfHeal(): JsonField = selfHeal + + /** + * Returns the raw JSON value of [systemPrompt]. + * + * Unlike [systemPrompt], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("systemPrompt") + @ExcludeMissing + fun _systemPrompt(): JsonField = systemPrompt + + /** + * Returns the raw JSON value of [verbose]. + * + * Unlike [verbose], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("verbose") @ExcludeMissing fun _verbose(): JsonField = verbose + + /** + * Returns the raw JSON value of [waitForCaptchaSolves]. + * + * Unlike [waitForCaptchaSolves], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("waitForCaptchaSolves") + @ExcludeMissing + fun _waitForCaptchaSolves(): JsonField = waitForCaptchaSolves + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .modelName() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var modelName: JsonField? = null + private var actTimeoutMs: JsonField = JsonMissing.of() + private var browser: JsonField = JsonMissing.of() + private var browserbaseSessionCreateParams: JsonField = + JsonMissing.of() + private var browserbaseSessionId: JsonField = JsonMissing.of() + private var debugDom: JsonField = JsonMissing.of() + private var domSettleTimeoutMs: JsonField = JsonMissing.of() + private var experimental: JsonField = JsonMissing.of() + private var selfHeal: JsonField = JsonMissing.of() + private var systemPrompt: JsonField = JsonMissing.of() + private var verbose: JsonField = JsonMissing.of() + private var waitForCaptchaSolves: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + modelName = body.modelName + actTimeoutMs = body.actTimeoutMs + browser = body.browser + browserbaseSessionCreateParams = body.browserbaseSessionCreateParams + browserbaseSessionId = body.browserbaseSessionId + debugDom = body.debugDom + domSettleTimeoutMs = body.domSettleTimeoutMs + experimental = body.experimental + selfHeal = body.selfHeal + systemPrompt = body.systemPrompt + verbose = body.verbose + waitForCaptchaSolves = body.waitForCaptchaSolves + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** Model name to use for AI operations */ + fun modelName(modelName: String) = modelName(JsonField.of(modelName)) + + /** + * Sets [Builder.modelName] to an arbitrary JSON value. + * + * You should usually call [Builder.modelName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun modelName(modelName: JsonField) = apply { this.modelName = modelName } + + /** Timeout in ms for act operations */ + fun actTimeoutMs(actTimeoutMs: Double) = actTimeoutMs(JsonField.of(actTimeoutMs)) + + /** + * Sets [Builder.actTimeoutMs] to an arbitrary JSON value. + * + * You should usually call [Builder.actTimeoutMs] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun actTimeoutMs(actTimeoutMs: JsonField) = apply { + this.actTimeoutMs = actTimeoutMs + } + + fun browser(browser: Browser) = browser(JsonField.of(browser)) + + /** + * Sets [Builder.browser] to an arbitrary JSON value. + * + * You should usually call [Builder.browser] with a well-typed [Browser] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun browser(browser: JsonField) = apply { this.browser = browser } + + fun browserbaseSessionCreateParams( + browserbaseSessionCreateParams: BrowserbaseSessionCreateParams + ) = browserbaseSessionCreateParams(JsonField.of(browserbaseSessionCreateParams)) + + /** + * Sets [Builder.browserbaseSessionCreateParams] to an arbitrary JSON value. + * + * You should usually call [Builder.browserbaseSessionCreateParams] with a well-typed + * [BrowserbaseSessionCreateParams] value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ + fun browserbaseSessionCreateParams( + browserbaseSessionCreateParams: JsonField + ) = apply { this.browserbaseSessionCreateParams = browserbaseSessionCreateParams } + + /** Existing Browserbase session ID to resume */ + fun browserbaseSessionId(browserbaseSessionId: String) = + browserbaseSessionId(JsonField.of(browserbaseSessionId)) + + /** + * Sets [Builder.browserbaseSessionId] to an arbitrary JSON value. + * + * You should usually call [Builder.browserbaseSessionId] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun browserbaseSessionId(browserbaseSessionId: JsonField) = apply { + this.browserbaseSessionId = browserbaseSessionId + } + + fun debugDom(debugDom: Boolean) = debugDom(JsonField.of(debugDom)) + + /** + * Sets [Builder.debugDom] to an arbitrary JSON value. + * + * You should usually call [Builder.debugDom] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun debugDom(debugDom: JsonField) = apply { this.debugDom = debugDom } + + /** Timeout in ms to wait for DOM to settle */ + fun domSettleTimeoutMs(domSettleTimeoutMs: Double) = + domSettleTimeoutMs(JsonField.of(domSettleTimeoutMs)) + + /** + * Sets [Builder.domSettleTimeoutMs] to an arbitrary JSON value. + * + * You should usually call [Builder.domSettleTimeoutMs] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun domSettleTimeoutMs(domSettleTimeoutMs: JsonField) = apply { + this.domSettleTimeoutMs = domSettleTimeoutMs + } + + fun experimental(experimental: Boolean) = experimental(JsonField.of(experimental)) + + /** + * Sets [Builder.experimental] to an arbitrary JSON value. + * + * You should usually call [Builder.experimental] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun experimental(experimental: JsonField) = apply { + this.experimental = experimental + } + + /** Enable self-healing for failed actions */ + fun selfHeal(selfHeal: Boolean) = selfHeal(JsonField.of(selfHeal)) + + /** + * Sets [Builder.selfHeal] to an arbitrary JSON value. + * + * You should usually call [Builder.selfHeal] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun selfHeal(selfHeal: JsonField) = apply { this.selfHeal = selfHeal } + + /** Custom system prompt for AI operations */ + fun systemPrompt(systemPrompt: String) = systemPrompt(JsonField.of(systemPrompt)) + + /** + * Sets [Builder.systemPrompt] to an arbitrary JSON value. + * + * You should usually call [Builder.systemPrompt] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun systemPrompt(systemPrompt: JsonField) = apply { + this.systemPrompt = systemPrompt + } + + /** Logging verbosity level (0=quiet, 1=normal, 2=debug) */ + fun verbose(verbose: Verbose) = verbose(JsonField.of(verbose)) + + /** + * Sets [Builder.verbose] to an arbitrary JSON value. + * + * You should usually call [Builder.verbose] with a well-typed [Verbose] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun verbose(verbose: JsonField) = apply { this.verbose = verbose } + + fun waitForCaptchaSolves(waitForCaptchaSolves: Boolean) = + waitForCaptchaSolves(JsonField.of(waitForCaptchaSolves)) + + /** + * Sets [Builder.waitForCaptchaSolves] to an arbitrary JSON value. + * + * You should usually call [Builder.waitForCaptchaSolves] with a well-typed [Boolean] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun waitForCaptchaSolves(waitForCaptchaSolves: JsonField) = apply { + this.waitForCaptchaSolves = waitForCaptchaSolves + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .modelName() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("modelName", modelName), + actTimeoutMs, + browser, + browserbaseSessionCreateParams, + browserbaseSessionId, + debugDom, + domSettleTimeoutMs, + experimental, + selfHeal, + systemPrompt, + verbose, + waitForCaptchaSolves, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + modelName() + actTimeoutMs() + browser().ifPresent { it.validate() } + browserbaseSessionCreateParams().ifPresent { it.validate() } + browserbaseSessionId() + debugDom() + domSettleTimeoutMs() + experimental() + selfHeal() + systemPrompt() + verbose().ifPresent { it.validate() } + waitForCaptchaSolves() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (modelName.asKnown().isPresent) 1 else 0) + + (if (actTimeoutMs.asKnown().isPresent) 1 else 0) + + (browser.asKnown().getOrNull()?.validity() ?: 0) + + (browserbaseSessionCreateParams.asKnown().getOrNull()?.validity() ?: 0) + + (if (browserbaseSessionId.asKnown().isPresent) 1 else 0) + + (if (debugDom.asKnown().isPresent) 1 else 0) + + (if (domSettleTimeoutMs.asKnown().isPresent) 1 else 0) + + (if (experimental.asKnown().isPresent) 1 else 0) + + (if (selfHeal.asKnown().isPresent) 1 else 0) + + (if (systemPrompt.asKnown().isPresent) 1 else 0) + + (verbose.asKnown().getOrNull()?.validity() ?: 0) + + (if (waitForCaptchaSolves.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + modelName == other.modelName && + actTimeoutMs == other.actTimeoutMs && + browser == other.browser && + browserbaseSessionCreateParams == other.browserbaseSessionCreateParams && + browserbaseSessionId == other.browserbaseSessionId && + debugDom == other.debugDom && + domSettleTimeoutMs == other.domSettleTimeoutMs && + experimental == other.experimental && + selfHeal == other.selfHeal && + systemPrompt == other.systemPrompt && + verbose == other.verbose && + waitForCaptchaSolves == other.waitForCaptchaSolves && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + modelName, + actTimeoutMs, + browser, + browserbaseSessionCreateParams, + browserbaseSessionId, + debugDom, + domSettleTimeoutMs, + experimental, + selfHeal, + systemPrompt, + verbose, + waitForCaptchaSolves, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{modelName=$modelName, actTimeoutMs=$actTimeoutMs, browser=$browser, browserbaseSessionCreateParams=$browserbaseSessionCreateParams, browserbaseSessionId=$browserbaseSessionId, debugDom=$debugDom, domSettleTimeoutMs=$domSettleTimeoutMs, experimental=$experimental, selfHeal=$selfHeal, systemPrompt=$systemPrompt, verbose=$verbose, waitForCaptchaSolves=$waitForCaptchaSolves, additionalProperties=$additionalProperties}" + } + + class Browser + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val cdpUrl: JsonField, + private val launchOptions: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("cdpUrl") @ExcludeMissing cdpUrl: JsonField = JsonMissing.of(), + @JsonProperty("launchOptions") + @ExcludeMissing + launchOptions: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this(cdpUrl, launchOptions, type, mutableMapOf()) + + /** + * Chrome DevTools Protocol URL for connecting to existing browser + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun cdpUrl(): Optional = cdpUrl.getOptional("cdpUrl") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun launchOptions(): Optional = launchOptions.getOptional("launchOptions") + + /** + * Browser type to use + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun type(): Optional = type.getOptional("type") + + /** + * Returns the raw JSON value of [cdpUrl]. + * + * Unlike [cdpUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cdpUrl") @ExcludeMissing fun _cdpUrl(): JsonField = cdpUrl + + /** + * Returns the raw JSON value of [launchOptions]. + * + * Unlike [launchOptions], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("launchOptions") + @ExcludeMissing + fun _launchOptions(): JsonField = launchOptions + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Browser]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Browser]. */ + class Builder internal constructor() { + + private var cdpUrl: JsonField = JsonMissing.of() + private var launchOptions: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(browser: Browser) = apply { + cdpUrl = browser.cdpUrl + launchOptions = browser.launchOptions + type = browser.type + additionalProperties = browser.additionalProperties.toMutableMap() + } + + /** Chrome DevTools Protocol URL for connecting to existing browser */ + fun cdpUrl(cdpUrl: String) = cdpUrl(JsonField.of(cdpUrl)) + + /** + * Sets [Builder.cdpUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.cdpUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun cdpUrl(cdpUrl: JsonField) = apply { this.cdpUrl = cdpUrl } + + fun launchOptions(launchOptions: LaunchOptions) = + launchOptions(JsonField.of(launchOptions)) + + /** + * Sets [Builder.launchOptions] to an arbitrary JSON value. + * + * You should usually call [Builder.launchOptions] with a well-typed [LaunchOptions] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun launchOptions(launchOptions: JsonField) = apply { + this.launchOptions = launchOptions + } + + /** Browser type to use */ + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonField) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Browser]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Browser = + Browser(cdpUrl, launchOptions, type, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Browser = apply { + if (validated) { + return@apply + } + + cdpUrl() + launchOptions().ifPresent { it.validate() } + type().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (cdpUrl.asKnown().isPresent) 1 else 0) + + (launchOptions.asKnown().getOrNull()?.validity() ?: 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + class LaunchOptions + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val acceptDownloads: JsonField, + private val args: JsonField>, + private val cdpUrl: JsonField, + private val chromiumSandbox: JsonField, + private val connectTimeoutMs: JsonField, + private val deviceScaleFactor: JsonField, + private val devtools: JsonField, + private val downloadsPath: JsonField, + private val executablePath: JsonField, + private val hasTouch: JsonField, + private val headless: JsonField, + private val ignoreDefaultArgs: JsonField, + private val ignoreHttpsErrors: JsonField, + private val locale: JsonField, + private val preserveUserDataDir: JsonField, + private val proxy: JsonField, + private val userDataDir: JsonField, + private val viewport: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("acceptDownloads") + @ExcludeMissing + acceptDownloads: JsonField = JsonMissing.of(), + @JsonProperty("args") + @ExcludeMissing + args: JsonField> = JsonMissing.of(), + @JsonProperty("cdpUrl") + @ExcludeMissing + cdpUrl: JsonField = JsonMissing.of(), + @JsonProperty("chromiumSandbox") + @ExcludeMissing + chromiumSandbox: JsonField = JsonMissing.of(), + @JsonProperty("connectTimeoutMs") + @ExcludeMissing + connectTimeoutMs: JsonField = JsonMissing.of(), + @JsonProperty("deviceScaleFactor") + @ExcludeMissing + deviceScaleFactor: JsonField = JsonMissing.of(), + @JsonProperty("devtools") + @ExcludeMissing + devtools: JsonField = JsonMissing.of(), + @JsonProperty("downloadsPath") + @ExcludeMissing + downloadsPath: JsonField = JsonMissing.of(), + @JsonProperty("executablePath") + @ExcludeMissing + executablePath: JsonField = JsonMissing.of(), + @JsonProperty("hasTouch") + @ExcludeMissing + hasTouch: JsonField = JsonMissing.of(), + @JsonProperty("headless") + @ExcludeMissing + headless: JsonField = JsonMissing.of(), + @JsonProperty("ignoreDefaultArgs") + @ExcludeMissing + ignoreDefaultArgs: JsonField = JsonMissing.of(), + @JsonProperty("ignoreHTTPSErrors") + @ExcludeMissing + ignoreHttpsErrors: JsonField = JsonMissing.of(), + @JsonProperty("locale") + @ExcludeMissing + locale: JsonField = JsonMissing.of(), + @JsonProperty("preserveUserDataDir") + @ExcludeMissing + preserveUserDataDir: JsonField = JsonMissing.of(), + @JsonProperty("proxy") @ExcludeMissing proxy: JsonField = JsonMissing.of(), + @JsonProperty("userDataDir") + @ExcludeMissing + userDataDir: JsonField = JsonMissing.of(), + @JsonProperty("viewport") + @ExcludeMissing + viewport: JsonField = JsonMissing.of(), + ) : this( + acceptDownloads, + args, + cdpUrl, + chromiumSandbox, + connectTimeoutMs, + deviceScaleFactor, + devtools, + downloadsPath, + executablePath, + hasTouch, + headless, + ignoreDefaultArgs, + ignoreHttpsErrors, + locale, + preserveUserDataDir, + proxy, + userDataDir, + viewport, + mutableMapOf(), + ) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun acceptDownloads(): Optional = + acceptDownloads.getOptional("acceptDownloads") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun args(): Optional> = args.getOptional("args") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun cdpUrl(): Optional = cdpUrl.getOptional("cdpUrl") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun chromiumSandbox(): Optional = + chromiumSandbox.getOptional("chromiumSandbox") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun connectTimeoutMs(): Optional = + connectTimeoutMs.getOptional("connectTimeoutMs") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun deviceScaleFactor(): Optional = + deviceScaleFactor.getOptional("deviceScaleFactor") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun devtools(): Optional = devtools.getOptional("devtools") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun downloadsPath(): Optional = downloadsPath.getOptional("downloadsPath") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun executablePath(): Optional = executablePath.getOptional("executablePath") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun hasTouch(): Optional = hasTouch.getOptional("hasTouch") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun headless(): Optional = headless.getOptional("headless") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun ignoreDefaultArgs(): Optional = + ignoreDefaultArgs.getOptional("ignoreDefaultArgs") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun ignoreHttpsErrors(): Optional = + ignoreHttpsErrors.getOptional("ignoreHTTPSErrors") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun locale(): Optional = locale.getOptional("locale") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun preserveUserDataDir(): Optional = + preserveUserDataDir.getOptional("preserveUserDataDir") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun proxy(): Optional = proxy.getOptional("proxy") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun userDataDir(): Optional = userDataDir.getOptional("userDataDir") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun viewport(): Optional = viewport.getOptional("viewport") + + /** + * Returns the raw JSON value of [acceptDownloads]. + * + * Unlike [acceptDownloads], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("acceptDownloads") + @ExcludeMissing + fun _acceptDownloads(): JsonField = acceptDownloads + + /** + * Returns the raw JSON value of [args]. + * + * Unlike [args], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("args") @ExcludeMissing fun _args(): JsonField> = args + + /** + * Returns the raw JSON value of [cdpUrl]. + * + * Unlike [cdpUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cdpUrl") @ExcludeMissing fun _cdpUrl(): JsonField = cdpUrl + + /** + * Returns the raw JSON value of [chromiumSandbox]. + * + * Unlike [chromiumSandbox], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("chromiumSandbox") + @ExcludeMissing + fun _chromiumSandbox(): JsonField = chromiumSandbox + + /** + * Returns the raw JSON value of [connectTimeoutMs]. + * + * Unlike [connectTimeoutMs], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("connectTimeoutMs") + @ExcludeMissing + fun _connectTimeoutMs(): JsonField = connectTimeoutMs + + /** + * Returns the raw JSON value of [deviceScaleFactor]. + * + * Unlike [deviceScaleFactor], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("deviceScaleFactor") + @ExcludeMissing + fun _deviceScaleFactor(): JsonField = deviceScaleFactor + + /** + * Returns the raw JSON value of [devtools]. + * + * Unlike [devtools], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("devtools") @ExcludeMissing fun _devtools(): JsonField = devtools + + /** + * Returns the raw JSON value of [downloadsPath]. + * + * Unlike [downloadsPath], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("downloadsPath") + @ExcludeMissing + fun _downloadsPath(): JsonField = downloadsPath + + /** + * Returns the raw JSON value of [executablePath]. + * + * Unlike [executablePath], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("executablePath") + @ExcludeMissing + fun _executablePath(): JsonField = executablePath + + /** + * Returns the raw JSON value of [hasTouch]. + * + * Unlike [hasTouch], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("hasTouch") @ExcludeMissing fun _hasTouch(): JsonField = hasTouch + + /** + * Returns the raw JSON value of [headless]. + * + * Unlike [headless], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("headless") @ExcludeMissing fun _headless(): JsonField = headless + + /** + * Returns the raw JSON value of [ignoreDefaultArgs]. + * + * Unlike [ignoreDefaultArgs], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("ignoreDefaultArgs") + @ExcludeMissing + fun _ignoreDefaultArgs(): JsonField = ignoreDefaultArgs + + /** + * Returns the raw JSON value of [ignoreHttpsErrors]. + * + * Unlike [ignoreHttpsErrors], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("ignoreHTTPSErrors") + @ExcludeMissing + fun _ignoreHttpsErrors(): JsonField = ignoreHttpsErrors + + /** + * Returns the raw JSON value of [locale]. + * + * Unlike [locale], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("locale") @ExcludeMissing fun _locale(): JsonField = locale + + /** + * Returns the raw JSON value of [preserveUserDataDir]. + * + * Unlike [preserveUserDataDir], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("preserveUserDataDir") + @ExcludeMissing + fun _preserveUserDataDir(): JsonField = preserveUserDataDir + + /** + * Returns the raw JSON value of [proxy]. + * + * Unlike [proxy], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("proxy") @ExcludeMissing fun _proxy(): JsonField = proxy + + /** + * Returns the raw JSON value of [userDataDir]. + * + * Unlike [userDataDir], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("userDataDir") + @ExcludeMissing + fun _userDataDir(): JsonField = userDataDir + + /** + * Returns the raw JSON value of [viewport]. + * + * Unlike [viewport], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("viewport") + @ExcludeMissing + fun _viewport(): JsonField = viewport + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [LaunchOptions]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LaunchOptions]. */ + class Builder internal constructor() { + + private var acceptDownloads: JsonField = JsonMissing.of() + private var args: JsonField>? = null + private var cdpUrl: JsonField = JsonMissing.of() + private var chromiumSandbox: JsonField = JsonMissing.of() + private var connectTimeoutMs: JsonField = JsonMissing.of() + private var deviceScaleFactor: JsonField = JsonMissing.of() + private var devtools: JsonField = JsonMissing.of() + private var downloadsPath: JsonField = JsonMissing.of() + private var executablePath: JsonField = JsonMissing.of() + private var hasTouch: JsonField = JsonMissing.of() + private var headless: JsonField = JsonMissing.of() + private var ignoreDefaultArgs: JsonField = JsonMissing.of() + private var ignoreHttpsErrors: JsonField = JsonMissing.of() + private var locale: JsonField = JsonMissing.of() + private var preserveUserDataDir: JsonField = JsonMissing.of() + private var proxy: JsonField = JsonMissing.of() + private var userDataDir: JsonField = JsonMissing.of() + private var viewport: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(launchOptions: LaunchOptions) = apply { + acceptDownloads = launchOptions.acceptDownloads + args = launchOptions.args.map { it.toMutableList() } + cdpUrl = launchOptions.cdpUrl + chromiumSandbox = launchOptions.chromiumSandbox + connectTimeoutMs = launchOptions.connectTimeoutMs + deviceScaleFactor = launchOptions.deviceScaleFactor + devtools = launchOptions.devtools + downloadsPath = launchOptions.downloadsPath + executablePath = launchOptions.executablePath + hasTouch = launchOptions.hasTouch + headless = launchOptions.headless + ignoreDefaultArgs = launchOptions.ignoreDefaultArgs + ignoreHttpsErrors = launchOptions.ignoreHttpsErrors + locale = launchOptions.locale + preserveUserDataDir = launchOptions.preserveUserDataDir + proxy = launchOptions.proxy + userDataDir = launchOptions.userDataDir + viewport = launchOptions.viewport + additionalProperties = launchOptions.additionalProperties.toMutableMap() + } + + fun acceptDownloads(acceptDownloads: Boolean) = + acceptDownloads(JsonField.of(acceptDownloads)) + + /** + * Sets [Builder.acceptDownloads] to an arbitrary JSON value. + * + * You should usually call [Builder.acceptDownloads] with a well-typed [Boolean] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun acceptDownloads(acceptDownloads: JsonField) = apply { + this.acceptDownloads = acceptDownloads + } + + fun args(args: List) = args(JsonField.of(args)) + + /** + * Sets [Builder.args] to an arbitrary JSON value. + * + * You should usually call [Builder.args] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun args(args: JsonField>) = apply { + this.args = args.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [args]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addArg(arg: String) = apply { + args = + (args ?: JsonField.of(mutableListOf())).also { + checkKnown("args", it).add(arg) + } + } + + fun cdpUrl(cdpUrl: String) = cdpUrl(JsonField.of(cdpUrl)) + + /** + * Sets [Builder.cdpUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.cdpUrl] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun cdpUrl(cdpUrl: JsonField) = apply { this.cdpUrl = cdpUrl } + + fun chromiumSandbox(chromiumSandbox: Boolean) = + chromiumSandbox(JsonField.of(chromiumSandbox)) + + /** + * Sets [Builder.chromiumSandbox] to an arbitrary JSON value. + * + * You should usually call [Builder.chromiumSandbox] with a well-typed [Boolean] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun chromiumSandbox(chromiumSandbox: JsonField) = apply { + this.chromiumSandbox = chromiumSandbox + } + + fun connectTimeoutMs(connectTimeoutMs: Double) = + connectTimeoutMs(JsonField.of(connectTimeoutMs)) + + /** + * Sets [Builder.connectTimeoutMs] to an arbitrary JSON value. + * + * You should usually call [Builder.connectTimeoutMs] with a well-typed [Double] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun connectTimeoutMs(connectTimeoutMs: JsonField) = apply { + this.connectTimeoutMs = connectTimeoutMs + } + + fun deviceScaleFactor(deviceScaleFactor: Double) = + deviceScaleFactor(JsonField.of(deviceScaleFactor)) + + /** + * Sets [Builder.deviceScaleFactor] to an arbitrary JSON value. + * + * You should usually call [Builder.deviceScaleFactor] with a well-typed [Double] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun deviceScaleFactor(deviceScaleFactor: JsonField) = apply { + this.deviceScaleFactor = deviceScaleFactor + } + + fun devtools(devtools: Boolean) = devtools(JsonField.of(devtools)) + + /** + * Sets [Builder.devtools] to an arbitrary JSON value. + * + * You should usually call [Builder.devtools] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun devtools(devtools: JsonField) = apply { this.devtools = devtools } + + fun downloadsPath(downloadsPath: String) = + downloadsPath(JsonField.of(downloadsPath)) + + /** + * Sets [Builder.downloadsPath] to an arbitrary JSON value. + * + * You should usually call [Builder.downloadsPath] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun downloadsPath(downloadsPath: JsonField) = apply { + this.downloadsPath = downloadsPath + } + + fun executablePath(executablePath: String) = + executablePath(JsonField.of(executablePath)) + + /** + * Sets [Builder.executablePath] to an arbitrary JSON value. + * + * You should usually call [Builder.executablePath] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun executablePath(executablePath: JsonField) = apply { + this.executablePath = executablePath + } + + fun hasTouch(hasTouch: Boolean) = hasTouch(JsonField.of(hasTouch)) + + /** + * Sets [Builder.hasTouch] to an arbitrary JSON value. + * + * You should usually call [Builder.hasTouch] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun hasTouch(hasTouch: JsonField) = apply { this.hasTouch = hasTouch } + + fun headless(headless: Boolean) = headless(JsonField.of(headless)) + + /** + * Sets [Builder.headless] to an arbitrary JSON value. + * + * You should usually call [Builder.headless] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun headless(headless: JsonField) = apply { this.headless = headless } + + fun ignoreDefaultArgs(ignoreDefaultArgs: IgnoreDefaultArgs) = + ignoreDefaultArgs(JsonField.of(ignoreDefaultArgs)) + + /** + * Sets [Builder.ignoreDefaultArgs] to an arbitrary JSON value. + * + * You should usually call [Builder.ignoreDefaultArgs] with a well-typed + * [IgnoreDefaultArgs] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun ignoreDefaultArgs(ignoreDefaultArgs: JsonField) = apply { + this.ignoreDefaultArgs = ignoreDefaultArgs + } + + /** Alias for calling [ignoreDefaultArgs] with `IgnoreDefaultArgs.ofBool(bool)`. */ + fun ignoreDefaultArgs(bool: Boolean) = + ignoreDefaultArgs(IgnoreDefaultArgs.ofBool(bool)) + + /** + * Alias for calling [ignoreDefaultArgs] with + * `IgnoreDefaultArgs.ofStrings(strings)`. + */ + fun ignoreDefaultArgsOfStrings(strings: List) = + ignoreDefaultArgs(IgnoreDefaultArgs.ofStrings(strings)) + + fun ignoreHttpsErrors(ignoreHttpsErrors: Boolean) = + ignoreHttpsErrors(JsonField.of(ignoreHttpsErrors)) + + /** + * Sets [Builder.ignoreHttpsErrors] to an arbitrary JSON value. + * + * You should usually call [Builder.ignoreHttpsErrors] with a well-typed [Boolean] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun ignoreHttpsErrors(ignoreHttpsErrors: JsonField) = apply { + this.ignoreHttpsErrors = ignoreHttpsErrors + } + + fun locale(locale: String) = locale(JsonField.of(locale)) + + /** + * Sets [Builder.locale] to an arbitrary JSON value. + * + * You should usually call [Builder.locale] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun locale(locale: JsonField) = apply { this.locale = locale } + + fun preserveUserDataDir(preserveUserDataDir: Boolean) = + preserveUserDataDir(JsonField.of(preserveUserDataDir)) + + /** + * Sets [Builder.preserveUserDataDir] to an arbitrary JSON value. + * + * You should usually call [Builder.preserveUserDataDir] with a well-typed [Boolean] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun preserveUserDataDir(preserveUserDataDir: JsonField) = apply { + this.preserveUserDataDir = preserveUserDataDir + } + + fun proxy(proxy: Proxy) = proxy(JsonField.of(proxy)) + + /** + * Sets [Builder.proxy] to an arbitrary JSON value. + * + * You should usually call [Builder.proxy] with a well-typed [Proxy] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun proxy(proxy: JsonField) = apply { this.proxy = proxy } + + fun userDataDir(userDataDir: String) = userDataDir(JsonField.of(userDataDir)) + + /** + * Sets [Builder.userDataDir] to an arbitrary JSON value. + * + * You should usually call [Builder.userDataDir] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun userDataDir(userDataDir: JsonField) = apply { + this.userDataDir = userDataDir + } + + fun viewport(viewport: Viewport) = viewport(JsonField.of(viewport)) + + /** + * Sets [Builder.viewport] to an arbitrary JSON value. + * + * You should usually call [Builder.viewport] with a well-typed [Viewport] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun viewport(viewport: JsonField) = apply { this.viewport = viewport } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [LaunchOptions]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): LaunchOptions = + LaunchOptions( + acceptDownloads, + (args ?: JsonMissing.of()).map { it.toImmutable() }, + cdpUrl, + chromiumSandbox, + connectTimeoutMs, + deviceScaleFactor, + devtools, + downloadsPath, + executablePath, + hasTouch, + headless, + ignoreDefaultArgs, + ignoreHttpsErrors, + locale, + preserveUserDataDir, + proxy, + userDataDir, + viewport, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): LaunchOptions = apply { + if (validated) { + return@apply + } + + acceptDownloads() + args() + cdpUrl() + chromiumSandbox() + connectTimeoutMs() + deviceScaleFactor() + devtools() + downloadsPath() + executablePath() + hasTouch() + headless() + ignoreDefaultArgs().ifPresent { it.validate() } + ignoreHttpsErrors() + locale() + preserveUserDataDir() + proxy().ifPresent { it.validate() } + userDataDir() + viewport().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (acceptDownloads.asKnown().isPresent) 1 else 0) + + (args.asKnown().getOrNull()?.size ?: 0) + + (if (cdpUrl.asKnown().isPresent) 1 else 0) + + (if (chromiumSandbox.asKnown().isPresent) 1 else 0) + + (if (connectTimeoutMs.asKnown().isPresent) 1 else 0) + + (if (deviceScaleFactor.asKnown().isPresent) 1 else 0) + + (if (devtools.asKnown().isPresent) 1 else 0) + + (if (downloadsPath.asKnown().isPresent) 1 else 0) + + (if (executablePath.asKnown().isPresent) 1 else 0) + + (if (hasTouch.asKnown().isPresent) 1 else 0) + + (if (headless.asKnown().isPresent) 1 else 0) + + (ignoreDefaultArgs.asKnown().getOrNull()?.validity() ?: 0) + + (if (ignoreHttpsErrors.asKnown().isPresent) 1 else 0) + + (if (locale.asKnown().isPresent) 1 else 0) + + (if (preserveUserDataDir.asKnown().isPresent) 1 else 0) + + (proxy.asKnown().getOrNull()?.validity() ?: 0) + + (if (userDataDir.asKnown().isPresent) 1 else 0) + + (viewport.asKnown().getOrNull()?.validity() ?: 0) + + @JsonDeserialize(using = IgnoreDefaultArgs.Deserializer::class) + @JsonSerialize(using = IgnoreDefaultArgs.Serializer::class) + class IgnoreDefaultArgs + private constructor( + private val bool: Boolean? = null, + private val strings: List? = null, + private val _json: JsonValue? = null, + ) { + + fun bool(): Optional = Optional.ofNullable(bool) + + fun strings(): Optional> = Optional.ofNullable(strings) + + fun isBool(): Boolean = bool != null + + fun isStrings(): Boolean = strings != null + + fun asBool(): Boolean = bool.getOrThrow("bool") + + fun asStrings(): List = strings.getOrThrow("strings") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + bool != null -> visitor.visitBool(bool) + strings != null -> visitor.visitStrings(strings) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): IgnoreDefaultArgs = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitBool(bool: Boolean) {} + + override fun visitStrings(strings: List) {} + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitBool(bool: Boolean) = 1 + + override fun visitStrings(strings: List) = strings.size + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is IgnoreDefaultArgs && + bool == other.bool && + strings == other.strings + } + + override fun hashCode(): Int = Objects.hash(bool, strings) + + override fun toString(): String = + when { + bool != null -> "IgnoreDefaultArgs{bool=$bool}" + strings != null -> "IgnoreDefaultArgs{strings=$strings}" + _json != null -> "IgnoreDefaultArgs{_unknown=$_json}" + else -> throw IllegalStateException("Invalid IgnoreDefaultArgs") + } + + companion object { + + @JvmStatic fun ofBool(bool: Boolean) = IgnoreDefaultArgs(bool = bool) + + @JvmStatic + fun ofStrings(strings: List) = + IgnoreDefaultArgs(strings = strings.toImmutable()) + } + + /** + * An interface that defines how to map each variant of [IgnoreDefaultArgs] to a + * value of type [T]. + */ + interface Visitor { + + fun visitBool(bool: Boolean): T + + fun visitStrings(strings: List): T + + /** + * Maps an unknown variant of [IgnoreDefaultArgs] to a value of type [T]. + * + * An instance of [IgnoreDefaultArgs] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if + * the SDK is on an older version than the API, then the API may respond with + * new variants that the SDK is unaware of. + * + * @throws StagehandInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw StagehandInvalidDataException("Unknown IgnoreDefaultArgs: $json") + } + } + + internal class Deserializer : + BaseDeserializer(IgnoreDefaultArgs::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): IgnoreDefaultArgs { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + IgnoreDefaultArgs(bool = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef>())?.let { + IgnoreDefaultArgs(strings = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely + // incompatible with all the possible variants (e.g. deserializing from + // string). + 0 -> IgnoreDefaultArgs(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use + // the first completely valid match, or simply the first match if none + // are completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : + BaseSerializer(IgnoreDefaultArgs::class) { + + override fun serialize( + value: IgnoreDefaultArgs, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.bool != null -> generator.writeObject(value.bool) + value.strings != null -> generator.writeObject(value.strings) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid IgnoreDefaultArgs") + } + } + } + } + + class Proxy + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val server: JsonField, + private val bypass: JsonField, + private val password: JsonField, + private val username: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("server") + @ExcludeMissing + server: JsonField = JsonMissing.of(), + @JsonProperty("bypass") + @ExcludeMissing + bypass: JsonField = JsonMissing.of(), + @JsonProperty("password") + @ExcludeMissing + password: JsonField = JsonMissing.of(), + @JsonProperty("username") + @ExcludeMissing + username: JsonField = JsonMissing.of(), + ) : this(server, bypass, password, username, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or + * is unexpectedly missing or null (e.g. if the server responded with an + * unexpected value). + */ + fun server(): String = server.getRequired("server") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun bypass(): Optional = bypass.getOptional("bypass") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun password(): Optional = password.getOptional("password") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun username(): Optional = username.getOptional("username") + + /** + * Returns the raw JSON value of [server]. + * + * Unlike [server], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("server") @ExcludeMissing fun _server(): JsonField = server + + /** + * Returns the raw JSON value of [bypass]. + * + * Unlike [bypass], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("bypass") @ExcludeMissing fun _bypass(): JsonField = bypass + + /** + * Returns the raw JSON value of [password]. + * + * Unlike [password], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("password") + @ExcludeMissing + fun _password(): JsonField = password + + /** + * Returns the raw JSON value of [username]. + * + * Unlike [username], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("username") + @ExcludeMissing + fun _username(): JsonField = username + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Proxy]. + * + * The following fields are required: + * ```java + * .server() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Proxy]. */ + class Builder internal constructor() { + + private var server: JsonField? = null + private var bypass: JsonField = JsonMissing.of() + private var password: JsonField = JsonMissing.of() + private var username: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(proxy: Proxy) = apply { + server = proxy.server + bypass = proxy.bypass + password = proxy.password + username = proxy.username + additionalProperties = proxy.additionalProperties.toMutableMap() + } + + fun server(server: String) = server(JsonField.of(server)) + + /** + * Sets [Builder.server] to an arbitrary JSON value. + * + * You should usually call [Builder.server] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun server(server: JsonField) = apply { this.server = server } + + fun bypass(bypass: String) = bypass(JsonField.of(bypass)) + + /** + * Sets [Builder.bypass] to an arbitrary JSON value. + * + * You should usually call [Builder.bypass] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun bypass(bypass: JsonField) = apply { this.bypass = bypass } + + fun password(password: String) = password(JsonField.of(password)) + + /** + * Sets [Builder.password] to an arbitrary JSON value. + * + * You should usually call [Builder.password] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun password(password: JsonField) = apply { this.password = password } + + fun username(username: String) = username(JsonField.of(username)) + + /** + * Sets [Builder.username] to an arbitrary JSON value. + * + * You should usually call [Builder.username] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun username(username: JsonField) = apply { this.username = username } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Proxy]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .server() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Proxy = + Proxy( + checkRequired("server", server), + bypass, + password, + username, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Proxy = apply { + if (validated) { + return@apply + } + + server() + bypass() + password() + username() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (server.asKnown().isPresent) 1 else 0) + + (if (bypass.asKnown().isPresent) 1 else 0) + + (if (password.asKnown().isPresent) 1 else 0) + + (if (username.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Proxy && + server == other.server && + bypass == other.bypass && + password == other.password && + username == other.username && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(server, bypass, password, username, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Proxy{server=$server, bypass=$bypass, password=$password, username=$username, additionalProperties=$additionalProperties}" + } + + class Viewport + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val height: JsonField, + private val width: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("height") + @ExcludeMissing + height: JsonField = JsonMissing.of(), + @JsonProperty("width") + @ExcludeMissing + width: JsonField = JsonMissing.of(), + ) : this(height, width, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or + * is unexpectedly missing or null (e.g. if the server responded with an + * unexpected value). + */ + fun height(): Double = height.getRequired("height") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or + * is unexpectedly missing or null (e.g. if the server responded with an + * unexpected value). + */ + fun width(): Double = width.getRequired("width") + + /** + * Returns the raw JSON value of [height]. + * + * Unlike [height], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("height") @ExcludeMissing fun _height(): JsonField = height + + /** + * Returns the raw JSON value of [width]. + * + * Unlike [width], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("width") @ExcludeMissing fun _width(): JsonField = width + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Viewport]. + * + * The following fields are required: + * ```java + * .height() + * .width() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Viewport]. */ + class Builder internal constructor() { + + private var height: JsonField? = null + private var width: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(viewport: Viewport) = apply { + height = viewport.height + width = viewport.width + additionalProperties = viewport.additionalProperties.toMutableMap() + } + + fun height(height: Double) = height(JsonField.of(height)) + + /** + * Sets [Builder.height] to an arbitrary JSON value. + * + * You should usually call [Builder.height] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun height(height: JsonField) = apply { this.height = height } + + fun width(width: Double) = width(JsonField.of(width)) + + /** + * Sets [Builder.width] to an arbitrary JSON value. + * + * You should usually call [Builder.width] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun width(width: JsonField) = apply { this.width = width } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Viewport]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .height() + * .width() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Viewport = + Viewport( + checkRequired("height", height), + checkRequired("width", width), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Viewport = apply { + if (validated) { + return@apply + } + + height() + width() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (height.asKnown().isPresent) 1 else 0) + + (if (width.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Viewport && + height == other.height && + width == other.width && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(height, width, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Viewport{height=$height, width=$width, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LaunchOptions && + acceptDownloads == other.acceptDownloads && + args == other.args && + cdpUrl == other.cdpUrl && + chromiumSandbox == other.chromiumSandbox && + connectTimeoutMs == other.connectTimeoutMs && + deviceScaleFactor == other.deviceScaleFactor && + devtools == other.devtools && + downloadsPath == other.downloadsPath && + executablePath == other.executablePath && + hasTouch == other.hasTouch && + headless == other.headless && + ignoreDefaultArgs == other.ignoreDefaultArgs && + ignoreHttpsErrors == other.ignoreHttpsErrors && + locale == other.locale && + preserveUserDataDir == other.preserveUserDataDir && + proxy == other.proxy && + userDataDir == other.userDataDir && + viewport == other.viewport && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + acceptDownloads, + args, + cdpUrl, + chromiumSandbox, + connectTimeoutMs, + deviceScaleFactor, + devtools, + downloadsPath, + executablePath, + hasTouch, + headless, + ignoreDefaultArgs, + ignoreHttpsErrors, + locale, + preserveUserDataDir, + proxy, + userDataDir, + viewport, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "LaunchOptions{acceptDownloads=$acceptDownloads, args=$args, cdpUrl=$cdpUrl, chromiumSandbox=$chromiumSandbox, connectTimeoutMs=$connectTimeoutMs, deviceScaleFactor=$deviceScaleFactor, devtools=$devtools, downloadsPath=$downloadsPath, executablePath=$executablePath, hasTouch=$hasTouch, headless=$headless, ignoreDefaultArgs=$ignoreDefaultArgs, ignoreHttpsErrors=$ignoreHttpsErrors, locale=$locale, preserveUserDataDir=$preserveUserDataDir, proxy=$proxy, userDataDir=$userDataDir, viewport=$viewport, additionalProperties=$additionalProperties}" + } + + /** Browser type to use */ + class Type @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val LOCAL = of("local") + + @JvmField val BROWSERBASE = of("browserbase") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + LOCAL, + BROWSERBASE, + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + LOCAL, + BROWSERBASE, + /** An enum member indicating that [Type] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + LOCAL -> Value.LOCAL + BROWSERBASE -> Value.BROWSERBASE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + LOCAL -> Known.LOCAL + BROWSERBASE -> Known.BROWSERBASE + else -> throw StagehandInvalidDataException("Unknown Type: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Type = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Type && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Browser && + cdpUrl == other.cdpUrl && + launchOptions == other.launchOptions && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(cdpUrl, launchOptions, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Browser{cdpUrl=$cdpUrl, launchOptions=$launchOptions, type=$type, additionalProperties=$additionalProperties}" + } + + class BrowserbaseSessionCreateParams + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val browserSettings: JsonField, + private val extensionId: JsonField, + private val keepAlive: JsonField, + private val projectId: JsonField, + private val proxies: JsonField, + private val region: JsonField, + private val timeout: JsonField, + private val userMetadata: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("browserSettings") + @ExcludeMissing + browserSettings: JsonField = JsonMissing.of(), + @JsonProperty("extensionId") + @ExcludeMissing + extensionId: JsonField = JsonMissing.of(), + @JsonProperty("keepAlive") + @ExcludeMissing + keepAlive: JsonField = JsonMissing.of(), + @JsonProperty("projectId") + @ExcludeMissing + projectId: JsonField = JsonMissing.of(), + @JsonProperty("proxies") @ExcludeMissing proxies: JsonField = JsonMissing.of(), + @JsonProperty("region") @ExcludeMissing region: JsonField = JsonMissing.of(), + @JsonProperty("timeout") @ExcludeMissing timeout: JsonField = JsonMissing.of(), + @JsonProperty("userMetadata") + @ExcludeMissing + userMetadata: JsonField = JsonMissing.of(), + ) : this( + browserSettings, + extensionId, + keepAlive, + projectId, + proxies, + region, + timeout, + userMetadata, + mutableMapOf(), + ) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun browserSettings(): Optional = + browserSettings.getOptional("browserSettings") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun extensionId(): Optional = extensionId.getOptional("extensionId") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun keepAlive(): Optional = keepAlive.getOptional("keepAlive") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun projectId(): Optional = projectId.getOptional("projectId") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun proxies(): Optional = proxies.getOptional("proxies") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun region(): Optional = region.getOptional("region") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun timeout(): Optional = timeout.getOptional("timeout") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun userMetadata(): Optional = userMetadata.getOptional("userMetadata") + + /** + * Returns the raw JSON value of [browserSettings]. + * + * Unlike [browserSettings], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("browserSettings") + @ExcludeMissing + fun _browserSettings(): JsonField = browserSettings + + /** + * Returns the raw JSON value of [extensionId]. + * + * Unlike [extensionId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("extensionId") + @ExcludeMissing + fun _extensionId(): JsonField = extensionId + + /** + * Returns the raw JSON value of [keepAlive]. + * + * Unlike [keepAlive], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("keepAlive") @ExcludeMissing fun _keepAlive(): JsonField = keepAlive + + /** + * Returns the raw JSON value of [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("projectId") @ExcludeMissing fun _projectId(): JsonField = projectId + + /** + * Returns the raw JSON value of [proxies]. + * + * Unlike [proxies], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("proxies") @ExcludeMissing fun _proxies(): JsonField = proxies + + /** + * Returns the raw JSON value of [region]. + * + * Unlike [region], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("region") @ExcludeMissing fun _region(): JsonField = region + + /** + * Returns the raw JSON value of [timeout]. + * + * Unlike [timeout], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("timeout") @ExcludeMissing fun _timeout(): JsonField = timeout + + /** + * Returns the raw JSON value of [userMetadata]. + * + * Unlike [userMetadata], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("userMetadata") + @ExcludeMissing + fun _userMetadata(): JsonField = userMetadata + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [BrowserbaseSessionCreateParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrowserbaseSessionCreateParams]. */ + class Builder internal constructor() { + + private var browserSettings: JsonField = JsonMissing.of() + private var extensionId: JsonField = JsonMissing.of() + private var keepAlive: JsonField = JsonMissing.of() + private var projectId: JsonField = JsonMissing.of() + private var proxies: JsonField = JsonMissing.of() + private var region: JsonField = JsonMissing.of() + private var timeout: JsonField = JsonMissing.of() + private var userMetadata: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(browserbaseSessionCreateParams: BrowserbaseSessionCreateParams) = + apply { + browserSettings = browserbaseSessionCreateParams.browserSettings + extensionId = browserbaseSessionCreateParams.extensionId + keepAlive = browserbaseSessionCreateParams.keepAlive + projectId = browserbaseSessionCreateParams.projectId + proxies = browserbaseSessionCreateParams.proxies + region = browserbaseSessionCreateParams.region + timeout = browserbaseSessionCreateParams.timeout + userMetadata = browserbaseSessionCreateParams.userMetadata + additionalProperties = + browserbaseSessionCreateParams.additionalProperties.toMutableMap() + } + + fun browserSettings(browserSettings: BrowserSettings) = + browserSettings(JsonField.of(browserSettings)) + + /** + * Sets [Builder.browserSettings] to an arbitrary JSON value. + * + * You should usually call [Builder.browserSettings] with a well-typed [BrowserSettings] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun browserSettings(browserSettings: JsonField) = apply { + this.browserSettings = browserSettings + } + + fun extensionId(extensionId: String) = extensionId(JsonField.of(extensionId)) + + /** + * Sets [Builder.extensionId] to an arbitrary JSON value. + * + * You should usually call [Builder.extensionId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun extensionId(extensionId: JsonField) = apply { + this.extensionId = extensionId + } + + fun keepAlive(keepAlive: Boolean) = keepAlive(JsonField.of(keepAlive)) + + /** + * Sets [Builder.keepAlive] to an arbitrary JSON value. + * + * You should usually call [Builder.keepAlive] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun keepAlive(keepAlive: JsonField) = apply { this.keepAlive = keepAlive } + + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } + + fun proxies(proxies: Proxies) = proxies(JsonField.of(proxies)) + + /** + * Sets [Builder.proxies] to an arbitrary JSON value. + * + * You should usually call [Builder.proxies] with a well-typed [Proxies] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun proxies(proxies: JsonField) = apply { this.proxies = proxies } + + /** Alias for calling [proxies] with `Proxies.ofBool(bool)`. */ + fun proxies(bool: Boolean) = proxies(Proxies.ofBool(bool)) + + /** + * Alias for calling [proxies] with + * `Proxies.ofUnnamedSchemaWithArrayParent0s(unnamedSchemaWithArrayParent0s)`. + */ + fun proxiesOfUnnamedSchemaWithArrayParent0s( + unnamedSchemaWithArrayParent0s: List + ) = proxies(Proxies.ofUnnamedSchemaWithArrayParent0s(unnamedSchemaWithArrayParent0s)) + + fun region(region: Region) = region(JsonField.of(region)) + + /** + * Sets [Builder.region] to an arbitrary JSON value. + * + * You should usually call [Builder.region] with a well-typed [Region] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun region(region: JsonField) = apply { this.region = region } + + fun timeout(timeout: Double) = timeout(JsonField.of(timeout)) + + /** + * Sets [Builder.timeout] to an arbitrary JSON value. + * + * You should usually call [Builder.timeout] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun timeout(timeout: JsonField) = apply { this.timeout = timeout } + + fun userMetadata(userMetadata: UserMetadata) = userMetadata(JsonField.of(userMetadata)) + + /** + * Sets [Builder.userMetadata] to an arbitrary JSON value. + * + * You should usually call [Builder.userMetadata] with a well-typed [UserMetadata] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun userMetadata(userMetadata: JsonField) = apply { + this.userMetadata = userMetadata + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [BrowserbaseSessionCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BrowserbaseSessionCreateParams = + BrowserbaseSessionCreateParams( + browserSettings, + extensionId, + keepAlive, + projectId, + proxies, + region, + timeout, + userMetadata, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): BrowserbaseSessionCreateParams = apply { + if (validated) { + return@apply + } + + browserSettings().ifPresent { it.validate() } + extensionId() + keepAlive() + projectId() + proxies().ifPresent { it.validate() } + region().ifPresent { it.validate() } + timeout() + userMetadata().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (browserSettings.asKnown().getOrNull()?.validity() ?: 0) + + (if (extensionId.asKnown().isPresent) 1 else 0) + + (if (keepAlive.asKnown().isPresent) 1 else 0) + + (if (projectId.asKnown().isPresent) 1 else 0) + + (proxies.asKnown().getOrNull()?.validity() ?: 0) + + (region.asKnown().getOrNull()?.validity() ?: 0) + + (if (timeout.asKnown().isPresent) 1 else 0) + + (userMetadata.asKnown().getOrNull()?.validity() ?: 0) + + class BrowserSettings + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val advancedStealth: JsonField, + private val blockAds: JsonField, + private val context: JsonField, + private val extensionId: JsonField, + private val fingerprint: JsonField, + private val logSession: JsonField, + private val recordSession: JsonField, + private val solveCaptchas: JsonField, + private val viewport: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("advancedStealth") + @ExcludeMissing + advancedStealth: JsonField = JsonMissing.of(), + @JsonProperty("blockAds") + @ExcludeMissing + blockAds: JsonField = JsonMissing.of(), + @JsonProperty("context") + @ExcludeMissing + context: JsonField = JsonMissing.of(), + @JsonProperty("extensionId") + @ExcludeMissing + extensionId: JsonField = JsonMissing.of(), + @JsonProperty("fingerprint") + @ExcludeMissing + fingerprint: JsonField = JsonMissing.of(), + @JsonProperty("logSession") + @ExcludeMissing + logSession: JsonField = JsonMissing.of(), + @JsonProperty("recordSession") + @ExcludeMissing + recordSession: JsonField = JsonMissing.of(), + @JsonProperty("solveCaptchas") + @ExcludeMissing + solveCaptchas: JsonField = JsonMissing.of(), + @JsonProperty("viewport") + @ExcludeMissing + viewport: JsonField = JsonMissing.of(), + ) : this( + advancedStealth, + blockAds, + context, + extensionId, + fingerprint, + logSession, + recordSession, + solveCaptchas, + viewport, + mutableMapOf(), + ) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun advancedStealth(): Optional = + advancedStealth.getOptional("advancedStealth") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun blockAds(): Optional = blockAds.getOptional("blockAds") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun context(): Optional = context.getOptional("context") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun extensionId(): Optional = extensionId.getOptional("extensionId") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun fingerprint(): Optional = fingerprint.getOptional("fingerprint") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun logSession(): Optional = logSession.getOptional("logSession") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun recordSession(): Optional = recordSession.getOptional("recordSession") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun solveCaptchas(): Optional = solveCaptchas.getOptional("solveCaptchas") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun viewport(): Optional = viewport.getOptional("viewport") + + /** + * Returns the raw JSON value of [advancedStealth]. + * + * Unlike [advancedStealth], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("advancedStealth") + @ExcludeMissing + fun _advancedStealth(): JsonField = advancedStealth + + /** + * Returns the raw JSON value of [blockAds]. + * + * Unlike [blockAds], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("blockAds") @ExcludeMissing fun _blockAds(): JsonField = blockAds + + /** + * Returns the raw JSON value of [context]. + * + * Unlike [context], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("context") @ExcludeMissing fun _context(): JsonField = context + + /** + * Returns the raw JSON value of [extensionId]. + * + * Unlike [extensionId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("extensionId") + @ExcludeMissing + fun _extensionId(): JsonField = extensionId + + /** + * Returns the raw JSON value of [fingerprint]. + * + * Unlike [fingerprint], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("fingerprint") + @ExcludeMissing + fun _fingerprint(): JsonField = fingerprint + + /** + * Returns the raw JSON value of [logSession]. + * + * Unlike [logSession], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("logSession") + @ExcludeMissing + fun _logSession(): JsonField = logSession + + /** + * Returns the raw JSON value of [recordSession]. + * + * Unlike [recordSession], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("recordSession") + @ExcludeMissing + fun _recordSession(): JsonField = recordSession + + /** + * Returns the raw JSON value of [solveCaptchas]. + * + * Unlike [solveCaptchas], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("solveCaptchas") + @ExcludeMissing + fun _solveCaptchas(): JsonField = solveCaptchas + + /** + * Returns the raw JSON value of [viewport]. + * + * Unlike [viewport], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("viewport") + @ExcludeMissing + fun _viewport(): JsonField = viewport + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [BrowserSettings]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrowserSettings]. */ + class Builder internal constructor() { + + private var advancedStealth: JsonField = JsonMissing.of() + private var blockAds: JsonField = JsonMissing.of() + private var context: JsonField = JsonMissing.of() + private var extensionId: JsonField = JsonMissing.of() + private var fingerprint: JsonField = JsonMissing.of() + private var logSession: JsonField = JsonMissing.of() + private var recordSession: JsonField = JsonMissing.of() + private var solveCaptchas: JsonField = JsonMissing.of() + private var viewport: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(browserSettings: BrowserSettings) = apply { + advancedStealth = browserSettings.advancedStealth + blockAds = browserSettings.blockAds + context = browserSettings.context + extensionId = browserSettings.extensionId + fingerprint = browserSettings.fingerprint + logSession = browserSettings.logSession + recordSession = browserSettings.recordSession + solveCaptchas = browserSettings.solveCaptchas + viewport = browserSettings.viewport + additionalProperties = browserSettings.additionalProperties.toMutableMap() + } + + fun advancedStealth(advancedStealth: Boolean) = + advancedStealth(JsonField.of(advancedStealth)) + + /** + * Sets [Builder.advancedStealth] to an arbitrary JSON value. + * + * You should usually call [Builder.advancedStealth] with a well-typed [Boolean] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun advancedStealth(advancedStealth: JsonField) = apply { + this.advancedStealth = advancedStealth + } + + fun blockAds(blockAds: Boolean) = blockAds(JsonField.of(blockAds)) + + /** + * Sets [Builder.blockAds] to an arbitrary JSON value. + * + * You should usually call [Builder.blockAds] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun blockAds(blockAds: JsonField) = apply { this.blockAds = blockAds } + + fun context(context: Context) = context(JsonField.of(context)) + + /** + * Sets [Builder.context] to an arbitrary JSON value. + * + * You should usually call [Builder.context] with a well-typed [Context] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun context(context: JsonField) = apply { this.context = context } + + fun extensionId(extensionId: String) = extensionId(JsonField.of(extensionId)) + + /** + * Sets [Builder.extensionId] to an arbitrary JSON value. + * + * You should usually call [Builder.extensionId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun extensionId(extensionId: JsonField) = apply { + this.extensionId = extensionId + } + + fun fingerprint(fingerprint: Fingerprint) = fingerprint(JsonField.of(fingerprint)) + + /** + * Sets [Builder.fingerprint] to an arbitrary JSON value. + * + * You should usually call [Builder.fingerprint] with a well-typed [Fingerprint] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun fingerprint(fingerprint: JsonField) = apply { + this.fingerprint = fingerprint + } + + fun logSession(logSession: Boolean) = logSession(JsonField.of(logSession)) + + /** + * Sets [Builder.logSession] to an arbitrary JSON value. + * + * You should usually call [Builder.logSession] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun logSession(logSession: JsonField) = apply { + this.logSession = logSession + } + + fun recordSession(recordSession: Boolean) = + recordSession(JsonField.of(recordSession)) + + /** + * Sets [Builder.recordSession] to an arbitrary JSON value. + * + * You should usually call [Builder.recordSession] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun recordSession(recordSession: JsonField) = apply { + this.recordSession = recordSession + } + + fun solveCaptchas(solveCaptchas: Boolean) = + solveCaptchas(JsonField.of(solveCaptchas)) + + /** + * Sets [Builder.solveCaptchas] to an arbitrary JSON value. + * + * You should usually call [Builder.solveCaptchas] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun solveCaptchas(solveCaptchas: JsonField) = apply { + this.solveCaptchas = solveCaptchas + } + + fun viewport(viewport: Viewport) = viewport(JsonField.of(viewport)) + + /** + * Sets [Builder.viewport] to an arbitrary JSON value. + * + * You should usually call [Builder.viewport] with a well-typed [Viewport] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun viewport(viewport: JsonField) = apply { this.viewport = viewport } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [BrowserSettings]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BrowserSettings = + BrowserSettings( + advancedStealth, + blockAds, + context, + extensionId, + fingerprint, + logSession, + recordSession, + solveCaptchas, + viewport, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): BrowserSettings = apply { + if (validated) { + return@apply + } + + advancedStealth() + blockAds() + context().ifPresent { it.validate() } + extensionId() + fingerprint().ifPresent { it.validate() } + logSession() + recordSession() + solveCaptchas() + viewport().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (advancedStealth.asKnown().isPresent) 1 else 0) + + (if (blockAds.asKnown().isPresent) 1 else 0) + + (context.asKnown().getOrNull()?.validity() ?: 0) + + (if (extensionId.asKnown().isPresent) 1 else 0) + + (fingerprint.asKnown().getOrNull()?.validity() ?: 0) + + (if (logSession.asKnown().isPresent) 1 else 0) + + (if (recordSession.asKnown().isPresent) 1 else 0) + + (if (solveCaptchas.asKnown().isPresent) 1 else 0) + + (viewport.asKnown().getOrNull()?.validity() ?: 0) + + class Context + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val persist: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("persist") + @ExcludeMissing + persist: JsonField = JsonMissing.of(), + ) : this(id, persist, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or + * is unexpectedly missing or null (e.g. if the server responded with an + * unexpected value). + */ + fun id(): String = id.getRequired("id") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun persist(): Optional = persist.getOptional("persist") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [persist]. + * + * Unlike [persist], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("persist") + @ExcludeMissing + fun _persist(): JsonField = persist + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Context]. + * + * The following fields are required: + * ```java + * .id() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Context]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var persist: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(context: Context) = apply { + id = context.id + persist = context.persist + additionalProperties = context.additionalProperties.toMutableMap() + } + + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + fun persist(persist: Boolean) = persist(JsonField.of(persist)) + + /** + * Sets [Builder.persist] to an arbitrary JSON value. + * + * You should usually call [Builder.persist] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun persist(persist: JsonField) = apply { this.persist = persist } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Context]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Context = + Context( + checkRequired("id", id), + persist, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Context = apply { + if (validated) { + return@apply + } + + id() + persist() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (id.asKnown().isPresent) 1 else 0) + + (if (persist.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Context && + id == other.id && + persist == other.persist && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, persist, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Context{id=$id, persist=$persist, additionalProperties=$additionalProperties}" + } + + class Fingerprint + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val browsers: JsonField>, + private val devices: JsonField>, + private val httpVersion: JsonField, + private val locales: JsonField>, + private val operatingSystems: JsonField>, + private val screen: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("browsers") + @ExcludeMissing + browsers: JsonField> = JsonMissing.of(), + @JsonProperty("devices") + @ExcludeMissing + devices: JsonField> = JsonMissing.of(), + @JsonProperty("httpVersion") + @ExcludeMissing + httpVersion: JsonField = JsonMissing.of(), + @JsonProperty("locales") + @ExcludeMissing + locales: JsonField> = JsonMissing.of(), + @JsonProperty("operatingSystems") + @ExcludeMissing + operatingSystems: JsonField> = JsonMissing.of(), + @JsonProperty("screen") + @ExcludeMissing + screen: JsonField = JsonMissing.of(), + ) : this( + browsers, + devices, + httpVersion, + locales, + operatingSystems, + screen, + mutableMapOf(), + ) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun browsers(): Optional> = browsers.getOptional("browsers") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun devices(): Optional> = devices.getOptional("devices") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun httpVersion(): Optional = httpVersion.getOptional("httpVersion") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun locales(): Optional> = locales.getOptional("locales") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun operatingSystems(): Optional> = + operatingSystems.getOptional("operatingSystems") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun screen(): Optional = screen.getOptional("screen") + + /** + * Returns the raw JSON value of [browsers]. + * + * Unlike [browsers], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("browsers") + @ExcludeMissing + fun _browsers(): JsonField> = browsers + + /** + * Returns the raw JSON value of [devices]. + * + * Unlike [devices], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("devices") + @ExcludeMissing + fun _devices(): JsonField> = devices + + /** + * Returns the raw JSON value of [httpVersion]. + * + * Unlike [httpVersion], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("httpVersion") + @ExcludeMissing + fun _httpVersion(): JsonField = httpVersion + + /** + * Returns the raw JSON value of [locales]. + * + * Unlike [locales], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("locales") + @ExcludeMissing + fun _locales(): JsonField> = locales + + /** + * Returns the raw JSON value of [operatingSystems]. + * + * Unlike [operatingSystems], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("operatingSystems") + @ExcludeMissing + fun _operatingSystems(): JsonField> = operatingSystems + + /** + * Returns the raw JSON value of [screen]. + * + * Unlike [screen], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("screen") @ExcludeMissing fun _screen(): JsonField = screen + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Fingerprint]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Fingerprint]. */ + class Builder internal constructor() { + + private var browsers: JsonField>? = null + private var devices: JsonField>? = null + private var httpVersion: JsonField = JsonMissing.of() + private var locales: JsonField>? = null + private var operatingSystems: JsonField>? = null + private var screen: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(fingerprint: Fingerprint) = apply { + browsers = fingerprint.browsers.map { it.toMutableList() } + devices = fingerprint.devices.map { it.toMutableList() } + httpVersion = fingerprint.httpVersion + locales = fingerprint.locales.map { it.toMutableList() } + operatingSystems = fingerprint.operatingSystems.map { it.toMutableList() } + screen = fingerprint.screen + additionalProperties = fingerprint.additionalProperties.toMutableMap() + } + + fun browsers(browsers: List) = browsers(JsonField.of(browsers)) + + /** + * Sets [Builder.browsers] to an arbitrary JSON value. + * + * You should usually call [Builder.browsers] with a well-typed `List` + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun browsers(browsers: JsonField>) = apply { + this.browsers = browsers.map { it.toMutableList() } + } + + /** + * Adds a single [Browser] to [browsers]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addBrowser(browser: Browser) = apply { + browsers = + (browsers ?: JsonField.of(mutableListOf())).also { + checkKnown("browsers", it).add(browser) + } + } + + fun devices(devices: List) = devices(JsonField.of(devices)) + + /** + * Sets [Builder.devices] to an arbitrary JSON value. + * + * You should usually call [Builder.devices] with a well-typed `List` + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun devices(devices: JsonField>) = apply { + this.devices = devices.map { it.toMutableList() } + } + + /** + * Adds a single [Device] to [devices]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addDevice(device: Device) = apply { + devices = + (devices ?: JsonField.of(mutableListOf())).also { + checkKnown("devices", it).add(device) + } + } + + fun httpVersion(httpVersion: HttpVersion) = + httpVersion(JsonField.of(httpVersion)) + + /** + * Sets [Builder.httpVersion] to an arbitrary JSON value. + * + * You should usually call [Builder.httpVersion] with a well-typed [HttpVersion] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun httpVersion(httpVersion: JsonField) = apply { + this.httpVersion = httpVersion + } + + fun locales(locales: List) = locales(JsonField.of(locales)) + + /** + * Sets [Builder.locales] to an arbitrary JSON value. + * + * You should usually call [Builder.locales] with a well-typed `List` + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun locales(locales: JsonField>) = apply { + this.locales = locales.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [locales]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addLocale(locale: String) = apply { + locales = + (locales ?: JsonField.of(mutableListOf())).also { + checkKnown("locales", it).add(locale) + } + } + + fun operatingSystems(operatingSystems: List) = + operatingSystems(JsonField.of(operatingSystems)) + + /** + * Sets [Builder.operatingSystems] to an arbitrary JSON value. + * + * You should usually call [Builder.operatingSystems] with a well-typed + * `List` value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ + fun operatingSystems(operatingSystems: JsonField>) = + apply { + this.operatingSystems = operatingSystems.map { it.toMutableList() } + } + + /** + * Adds a single [OperatingSystem] to [operatingSystems]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addOperatingSystem(operatingSystem: OperatingSystem) = apply { + operatingSystems = + (operatingSystems ?: JsonField.of(mutableListOf())).also { + checkKnown("operatingSystems", it).add(operatingSystem) + } + } + + fun screen(screen: Screen) = screen(JsonField.of(screen)) + + /** + * Sets [Builder.screen] to an arbitrary JSON value. + * + * You should usually call [Builder.screen] with a well-typed [Screen] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun screen(screen: JsonField) = apply { this.screen = screen } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Fingerprint]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Fingerprint = + Fingerprint( + (browsers ?: JsonMissing.of()).map { it.toImmutable() }, + (devices ?: JsonMissing.of()).map { it.toImmutable() }, + httpVersion, + (locales ?: JsonMissing.of()).map { it.toImmutable() }, + (operatingSystems ?: JsonMissing.of()).map { it.toImmutable() }, + screen, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Fingerprint = apply { + if (validated) { + return@apply + } + + browsers().ifPresent { it.forEach { it.validate() } } + devices().ifPresent { it.forEach { it.validate() } } + httpVersion().ifPresent { it.validate() } + locales() + operatingSystems().ifPresent { it.forEach { it.validate() } } + screen().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (browsers.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (devices.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (httpVersion.asKnown().getOrNull()?.validity() ?: 0) + + (locales.asKnown().getOrNull()?.size ?: 0) + + (operatingSystems.asKnown().getOrNull()?.sumOf { it.validity().toInt() } + ?: 0) + + (screen.asKnown().getOrNull()?.validity() ?: 0) + + class Browser + @JsonCreator + private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that + * doesn't match any known member, and you want to know that value. For example, + * if the SDK is on an older version than the API, then the API may respond with + * new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue + fun _value(): JsonField = value + + companion object { + + @JvmField val CHROME = of("chrome") + + @JvmField val EDGE = of("edge") + + @JvmField val FIREFOX = of("firefox") + + @JvmField val SAFARI = of("safari") + + @JvmStatic fun of(value: String) = Browser(JsonField.of(value)) + } + + /** An enum containing [Browser]'s known values. */ + enum class Known { + CHROME, + EDGE, + FIREFOX, + SAFARI, + } + + /** + * An enum containing [Browser]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Browser] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For + * example, if the SDK is on an older version than the API, then the API may + * respond with new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + CHROME, + EDGE, + FIREFOX, + SAFARI, + /** + * An enum member indicating that [Browser] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or + * if you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + CHROME -> Value.CHROME + EDGE -> Value.EDGE + FIREFOX -> Value.FIREFOX + SAFARI -> Value.SAFARI + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known + * and don't want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not + * a known member. + */ + fun known(): Known = + when (this) { + CHROME -> Known.CHROME + EDGE -> Known.EDGE + FIREFOX -> Known.FIREFOX + SAFARI -> Known.SAFARI + else -> throw StagehandInvalidDataException("Unknown Browser: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Browser = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Browser && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + class Device + @JsonCreator + private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that + * doesn't match any known member, and you want to know that value. For example, + * if the SDK is on an older version than the API, then the API may respond with + * new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue + fun _value(): JsonField = value + + companion object { + + @JvmField val DESKTOP = of("desktop") + + @JvmField val MOBILE = of("mobile") + + @JvmStatic fun of(value: String) = Device(JsonField.of(value)) + } + + /** An enum containing [Device]'s known values. */ + enum class Known { + DESKTOP, + MOBILE, + } + + /** + * An enum containing [Device]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Device] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For + * example, if the SDK is on an older version than the API, then the API may + * respond with new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + DESKTOP, + MOBILE, + /** + * An enum member indicating that [Device] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or + * if you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + DESKTOP -> Value.DESKTOP + MOBILE -> Value.MOBILE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known + * and don't want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not + * a known member. + */ + fun known(): Known = + when (this) { + DESKTOP -> Known.DESKTOP + MOBILE -> Known.MOBILE + else -> throw StagehandInvalidDataException("Unknown Device: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Device = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Device && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + class HttpVersion + @JsonCreator + private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that + * doesn't match any known member, and you want to know that value. For example, + * if the SDK is on an older version than the API, then the API may respond with + * new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue + fun _value(): JsonField = value + + companion object { + + @JvmField val _1 = of("1") + + @JvmField val _2 = of("2") + + @JvmStatic fun of(value: String) = HttpVersion(JsonField.of(value)) + } + + /** An enum containing [HttpVersion]'s known values. */ + enum class Known { + _1, + _2, + } + + /** + * An enum containing [HttpVersion]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [HttpVersion] can contain an unknown value in a couple of + * cases: + * - It was deserialized from data that doesn't match any known member. For + * example, if the SDK is on an older version than the API, then the API may + * respond with new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + _1, + _2, + /** + * An enum member indicating that [HttpVersion] was instantiated with an + * unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or + * if you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + _1 -> Value._1 + _2 -> Value._2 + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known + * and don't want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not + * a known member. + */ + fun known(): Known = + when (this) { + _1 -> Known._1 + _2 -> Known._2 + else -> + throw StagehandInvalidDataException("Unknown HttpVersion: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): HttpVersion = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is HttpVersion && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + class OperatingSystem + @JsonCreator + private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that + * doesn't match any known member, and you want to know that value. For example, + * if the SDK is on an older version than the API, then the API may respond with + * new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue + fun _value(): JsonField = value + + companion object { + + @JvmField val ANDROID = of("android") + + @JvmField val IOS = of("ios") + + @JvmField val LINUX = of("linux") + + @JvmField val MACOS = of("macos") + + @JvmField val WINDOWS = of("windows") + + @JvmStatic fun of(value: String) = OperatingSystem(JsonField.of(value)) + } + + /** An enum containing [OperatingSystem]'s known values. */ + enum class Known { + ANDROID, + IOS, + LINUX, + MACOS, + WINDOWS, + } + + /** + * An enum containing [OperatingSystem]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [OperatingSystem] can contain an unknown value in a couple of + * cases: + * - It was deserialized from data that doesn't match any known member. For + * example, if the SDK is on an older version than the API, then the API may + * respond with new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + ANDROID, + IOS, + LINUX, + MACOS, + WINDOWS, + /** + * An enum member indicating that [OperatingSystem] was instantiated with an + * unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or + * if you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + ANDROID -> Value.ANDROID + IOS -> Value.IOS + LINUX -> Value.LINUX + MACOS -> Value.MACOS + WINDOWS -> Value.WINDOWS + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known + * and don't want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not + * a known member. + */ + fun known(): Known = + when (this) { + ANDROID -> Known.ANDROID + IOS -> Known.IOS + LINUX -> Known.LINUX + MACOS -> Known.MACOS + WINDOWS -> Known.WINDOWS + else -> + throw StagehandInvalidDataException( + "Unknown OperatingSystem: $value" + ) + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): OperatingSystem = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is OperatingSystem && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + class Screen + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val maxHeight: JsonField, + private val maxWidth: JsonField, + private val minHeight: JsonField, + private val minWidth: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("maxHeight") + @ExcludeMissing + maxHeight: JsonField = JsonMissing.of(), + @JsonProperty("maxWidth") + @ExcludeMissing + maxWidth: JsonField = JsonMissing.of(), + @JsonProperty("minHeight") + @ExcludeMissing + minHeight: JsonField = JsonMissing.of(), + @JsonProperty("minWidth") + @ExcludeMissing + minWidth: JsonField = JsonMissing.of(), + ) : this(maxHeight, maxWidth, minHeight, minWidth, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun maxHeight(): Optional = maxHeight.getOptional("maxHeight") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun maxWidth(): Optional = maxWidth.getOptional("maxWidth") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun minHeight(): Optional = minHeight.getOptional("minHeight") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun minWidth(): Optional = minWidth.getOptional("minWidth") + + /** + * Returns the raw JSON value of [maxHeight]. + * + * Unlike [maxHeight], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("maxHeight") + @ExcludeMissing + fun _maxHeight(): JsonField = maxHeight + + /** + * Returns the raw JSON value of [maxWidth]. + * + * Unlike [maxWidth], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("maxWidth") + @ExcludeMissing + fun _maxWidth(): JsonField = maxWidth + + /** + * Returns the raw JSON value of [minHeight]. + * + * Unlike [minHeight], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("minHeight") + @ExcludeMissing + fun _minHeight(): JsonField = minHeight + + /** + * Returns the raw JSON value of [minWidth]. + * + * Unlike [minWidth], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("minWidth") + @ExcludeMissing + fun _minWidth(): JsonField = minWidth + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Screen]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Screen]. */ + class Builder internal constructor() { + + private var maxHeight: JsonField = JsonMissing.of() + private var maxWidth: JsonField = JsonMissing.of() + private var minHeight: JsonField = JsonMissing.of() + private var minWidth: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(screen: Screen) = apply { + maxHeight = screen.maxHeight + maxWidth = screen.maxWidth + minHeight = screen.minHeight + minWidth = screen.minWidth + additionalProperties = screen.additionalProperties.toMutableMap() + } + + fun maxHeight(maxHeight: Double) = maxHeight(JsonField.of(maxHeight)) + + /** + * Sets [Builder.maxHeight] to an arbitrary JSON value. + * + * You should usually call [Builder.maxHeight] with a well-typed [Double] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun maxHeight(maxHeight: JsonField) = apply { + this.maxHeight = maxHeight + } + + fun maxWidth(maxWidth: Double) = maxWidth(JsonField.of(maxWidth)) + + /** + * Sets [Builder.maxWidth] to an arbitrary JSON value. + * + * You should usually call [Builder.maxWidth] with a well-typed [Double] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun maxWidth(maxWidth: JsonField) = apply { + this.maxWidth = maxWidth + } + + fun minHeight(minHeight: Double) = minHeight(JsonField.of(minHeight)) + + /** + * Sets [Builder.minHeight] to an arbitrary JSON value. + * + * You should usually call [Builder.minHeight] with a well-typed [Double] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun minHeight(minHeight: JsonField) = apply { + this.minHeight = minHeight + } + + fun minWidth(minWidth: Double) = minWidth(JsonField.of(minWidth)) + + /** + * Sets [Builder.minWidth] to an arbitrary JSON value. + * + * You should usually call [Builder.minWidth] with a well-typed [Double] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun minWidth(minWidth: JsonField) = apply { + this.minWidth = minWidth + } + + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties( + additionalProperties: Map + ) = apply { this.additionalProperties.putAll(additionalProperties) } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Screen]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Screen = + Screen( + maxHeight, + maxWidth, + minHeight, + minWidth, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Screen = apply { + if (validated) { + return@apply + } + + maxHeight() + maxWidth() + minHeight() + minWidth() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (maxHeight.asKnown().isPresent) 1 else 0) + + (if (maxWidth.asKnown().isPresent) 1 else 0) + + (if (minHeight.asKnown().isPresent) 1 else 0) + + (if (minWidth.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Screen && + maxHeight == other.maxHeight && + maxWidth == other.maxWidth && + minHeight == other.minHeight && + minWidth == other.minWidth && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(maxHeight, maxWidth, minHeight, minWidth, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Screen{maxHeight=$maxHeight, maxWidth=$maxWidth, minHeight=$minHeight, minWidth=$minWidth, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Fingerprint && + browsers == other.browsers && + devices == other.devices && + httpVersion == other.httpVersion && + locales == other.locales && + operatingSystems == other.operatingSystems && + screen == other.screen && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + browsers, + devices, + httpVersion, + locales, + operatingSystems, + screen, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Fingerprint{browsers=$browsers, devices=$devices, httpVersion=$httpVersion, locales=$locales, operatingSystems=$operatingSystems, screen=$screen, additionalProperties=$additionalProperties}" + } + + class Viewport + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val height: JsonField, + private val width: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("height") + @ExcludeMissing + height: JsonField = JsonMissing.of(), + @JsonProperty("width") + @ExcludeMissing + width: JsonField = JsonMissing.of(), + ) : this(height, width, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun height(): Optional = height.getOptional("height") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun width(): Optional = width.getOptional("width") + + /** + * Returns the raw JSON value of [height]. + * + * Unlike [height], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("height") @ExcludeMissing fun _height(): JsonField = height + + /** + * Returns the raw JSON value of [width]. + * + * Unlike [width], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("width") @ExcludeMissing fun _width(): JsonField = width + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Viewport]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Viewport]. */ + class Builder internal constructor() { + + private var height: JsonField = JsonMissing.of() + private var width: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(viewport: Viewport) = apply { + height = viewport.height + width = viewport.width + additionalProperties = viewport.additionalProperties.toMutableMap() + } + + fun height(height: Double) = height(JsonField.of(height)) + + /** + * Sets [Builder.height] to an arbitrary JSON value. + * + * You should usually call [Builder.height] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun height(height: JsonField) = apply { this.height = height } + + fun width(width: Double) = width(JsonField.of(width)) + + /** + * Sets [Builder.width] to an arbitrary JSON value. + * + * You should usually call [Builder.width] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun width(width: JsonField) = apply { this.width = width } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Viewport]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Viewport = + Viewport(height, width, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Viewport = apply { + if (validated) { + return@apply + } + + height() + width() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (height.asKnown().isPresent) 1 else 0) + + (if (width.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Viewport && + height == other.height && + width == other.width && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(height, width, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Viewport{height=$height, width=$width, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BrowserSettings && + advancedStealth == other.advancedStealth && + blockAds == other.blockAds && + context == other.context && + extensionId == other.extensionId && + fingerprint == other.fingerprint && + logSession == other.logSession && + recordSession == other.recordSession && + solveCaptchas == other.solveCaptchas && + viewport == other.viewport && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + advancedStealth, + blockAds, + context, + extensionId, + fingerprint, + logSession, + recordSession, + solveCaptchas, + viewport, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BrowserSettings{advancedStealth=$advancedStealth, blockAds=$blockAds, context=$context, extensionId=$extensionId, fingerprint=$fingerprint, logSession=$logSession, recordSession=$recordSession, solveCaptchas=$solveCaptchas, viewport=$viewport, additionalProperties=$additionalProperties}" + } + + @JsonDeserialize(using = Proxies.Deserializer::class) + @JsonSerialize(using = Proxies.Serializer::class) + class Proxies + private constructor( + private val bool: Boolean? = null, + private val unnamedSchemaWithArrayParent0s: List? = null, + private val _json: JsonValue? = null, + ) { + + fun bool(): Optional = Optional.ofNullable(bool) + + fun unnamedSchemaWithArrayParent0s(): Optional> = + Optional.ofNullable(unnamedSchemaWithArrayParent0s) + + fun isBool(): Boolean = bool != null + + fun isUnnamedSchemaWithArrayParent0s(): Boolean = unnamedSchemaWithArrayParent0s != null + + fun asBool(): Boolean = bool.getOrThrow("bool") + + fun asUnnamedSchemaWithArrayParent0s(): List = + unnamedSchemaWithArrayParent0s.getOrThrow("unnamedSchemaWithArrayParent0s") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + bool != null -> visitor.visitBool(bool) + unnamedSchemaWithArrayParent0s != null -> + visitor.visitUnnamedSchemaWithArrayParent0s(unnamedSchemaWithArrayParent0s) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): Proxies = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitBool(bool: Boolean) {} + + override fun visitUnnamedSchemaWithArrayParent0s( + unnamedSchemaWithArrayParent0s: List + ) { + unnamedSchemaWithArrayParent0s.forEach { it.validate() } + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitBool(bool: Boolean) = 1 + + override fun visitUnnamedSchemaWithArrayParent0s( + unnamedSchemaWithArrayParent0s: List + ) = unnamedSchemaWithArrayParent0s.sumOf { it.validity().toInt() } + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Proxies && + bool == other.bool && + unnamedSchemaWithArrayParent0s == other.unnamedSchemaWithArrayParent0s + } + + override fun hashCode(): Int = Objects.hash(bool, unnamedSchemaWithArrayParent0s) + + override fun toString(): String = + when { + bool != null -> "Proxies{bool=$bool}" + unnamedSchemaWithArrayParent0s != null -> + "Proxies{unnamedSchemaWithArrayParent0s=$unnamedSchemaWithArrayParent0s}" + _json != null -> "Proxies{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Proxies") + } + + companion object { + + @JvmStatic fun ofBool(bool: Boolean) = Proxies(bool = bool) + + @JvmStatic + fun ofUnnamedSchemaWithArrayParent0s( + unnamedSchemaWithArrayParent0s: List + ) = + Proxies( + unnamedSchemaWithArrayParent0s = + unnamedSchemaWithArrayParent0s.toImmutable() + ) + } + + /** + * An interface that defines how to map each variant of [Proxies] to a value of type + * [T]. + */ + interface Visitor { + + fun visitBool(bool: Boolean): T + + fun visitUnnamedSchemaWithArrayParent0s( + unnamedSchemaWithArrayParent0s: List + ): T + + /** + * Maps an unknown variant of [Proxies] to a value of type [T]. + * + * An instance of [Proxies] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the + * SDK is unaware of. + * + * @throws StagehandInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw StagehandInvalidDataException("Unknown Proxies: $json") + } + } + + internal class Deserializer : BaseDeserializer(Proxies::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Proxies { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + Proxies(bool = it, _json = json) + }, + tryDeserialize( + node, + jacksonTypeRef>(), + ) + ?.let { + Proxies(unnamedSchemaWithArrayParent0s = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible + // with all the possible variants (e.g. deserializing from string). + 0 -> Proxies(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the + // first completely valid match, or simply the first match if none are + // completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Proxies::class) { + + override fun serialize( + value: Proxies, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.bool != null -> generator.writeObject(value.bool) + value.unnamedSchemaWithArrayParent0s != null -> + generator.writeObject(value.unnamedSchemaWithArrayParent0s) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Proxies") + } + } + } + + @JsonDeserialize(using = UnnamedSchemaWithArrayParent0.Deserializer::class) + @JsonSerialize(using = UnnamedSchemaWithArrayParent0.Serializer::class) + class UnnamedSchemaWithArrayParent0 + private constructor( + private val browserbaseProxyConfig: BrowserbaseProxyConfig? = null, + private val externalProxyConfig: ExternalProxyConfig? = null, + private val _json: JsonValue? = null, + ) { + + fun browserbaseProxyConfig(): Optional = + Optional.ofNullable(browserbaseProxyConfig) + + fun externalProxyConfig(): Optional = + Optional.ofNullable(externalProxyConfig) + + fun isBrowserbaseProxyConfig(): Boolean = browserbaseProxyConfig != null + + fun isExternalProxyConfig(): Boolean = externalProxyConfig != null + + fun asBrowserbaseProxyConfig(): BrowserbaseProxyConfig = + browserbaseProxyConfig.getOrThrow("browserbaseProxyConfig") + + fun asExternalProxyConfig(): ExternalProxyConfig = + externalProxyConfig.getOrThrow("externalProxyConfig") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + browserbaseProxyConfig != null -> + visitor.visitBrowserbaseProxyConfig(browserbaseProxyConfig) + externalProxyConfig != null -> + visitor.visitExternalProxyConfig(externalProxyConfig) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): UnnamedSchemaWithArrayParent0 = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitBrowserbaseProxyConfig( + browserbaseProxyConfig: BrowserbaseProxyConfig + ) { + browserbaseProxyConfig.validate() + } + + override fun visitExternalProxyConfig( + externalProxyConfig: ExternalProxyConfig + ) { + externalProxyConfig.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitBrowserbaseProxyConfig( + browserbaseProxyConfig: BrowserbaseProxyConfig + ) = browserbaseProxyConfig.validity() + + override fun visitExternalProxyConfig( + externalProxyConfig: ExternalProxyConfig + ) = externalProxyConfig.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is UnnamedSchemaWithArrayParent0 && + browserbaseProxyConfig == other.browserbaseProxyConfig && + externalProxyConfig == other.externalProxyConfig + } + + override fun hashCode(): Int = + Objects.hash(browserbaseProxyConfig, externalProxyConfig) + + override fun toString(): String = + when { + browserbaseProxyConfig != null -> + "UnnamedSchemaWithArrayParent0{browserbaseProxyConfig=$browserbaseProxyConfig}" + externalProxyConfig != null -> + "UnnamedSchemaWithArrayParent0{externalProxyConfig=$externalProxyConfig}" + _json != null -> "UnnamedSchemaWithArrayParent0{_unknown=$_json}" + else -> throw IllegalStateException("Invalid UnnamedSchemaWithArrayParent0") + } + + companion object { + + @JvmStatic + fun ofBrowserbaseProxyConfig(browserbaseProxyConfig: BrowserbaseProxyConfig) = + UnnamedSchemaWithArrayParent0( + browserbaseProxyConfig = browserbaseProxyConfig + ) + + @JvmStatic + fun ofExternalProxyConfig(externalProxyConfig: ExternalProxyConfig) = + UnnamedSchemaWithArrayParent0(externalProxyConfig = externalProxyConfig) + } + + /** + * An interface that defines how to map each variant of + * [UnnamedSchemaWithArrayParent0] to a value of type [T]. + */ + interface Visitor { + + fun visitBrowserbaseProxyConfig( + browserbaseProxyConfig: BrowserbaseProxyConfig + ): T + + fun visitExternalProxyConfig(externalProxyConfig: ExternalProxyConfig): T + + /** + * Maps an unknown variant of [UnnamedSchemaWithArrayParent0] to a value of type + * [T]. + * + * An instance of [UnnamedSchemaWithArrayParent0] can contain an unknown variant + * if it was deserialized from data that doesn't match any known variant. For + * example, if the SDK is on an older version than the API, then the API may + * respond with new variants that the SDK is unaware of. + * + * @throws StagehandInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw StagehandInvalidDataException( + "Unknown UnnamedSchemaWithArrayParent0: $json" + ) + } + } + + internal class Deserializer : + BaseDeserializer( + UnnamedSchemaWithArrayParent0::class + ) { + + override fun ObjectCodec.deserialize( + node: JsonNode + ): UnnamedSchemaWithArrayParent0 { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef()) + ?.let { + UnnamedSchemaWithArrayParent0( + browserbaseProxyConfig = it, + _json = json, + ) + }, + tryDeserialize(node, jacksonTypeRef()) + ?.let { + UnnamedSchemaWithArrayParent0( + externalProxyConfig = it, + _json = json, + ) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely + // incompatible with all the possible variants (e.g. deserializing from + // boolean). + 0 -> UnnamedSchemaWithArrayParent0(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use + // the first completely valid match, or simply the first match if none + // are completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : + BaseSerializer( + UnnamedSchemaWithArrayParent0::class + ) { + + override fun serialize( + value: UnnamedSchemaWithArrayParent0, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.browserbaseProxyConfig != null -> + generator.writeObject(value.browserbaseProxyConfig) + value.externalProxyConfig != null -> + generator.writeObject(value.externalProxyConfig) + value._json != null -> generator.writeObject(value._json) + else -> + throw IllegalStateException("Invalid UnnamedSchemaWithArrayParent0") + } + } + } + + class BrowserbaseProxyConfig + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val type: JsonField, + private val domainPattern: JsonField, + private val geolocation: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("type") + @ExcludeMissing + type: JsonField = JsonMissing.of(), + @JsonProperty("domainPattern") + @ExcludeMissing + domainPattern: JsonField = JsonMissing.of(), + @JsonProperty("geolocation") + @ExcludeMissing + geolocation: JsonField = JsonMissing.of(), + ) : this(type, domainPattern, geolocation, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected + * type or is unexpectedly missing or null (e.g. if the server responded with + * an unexpected value). + */ + fun type(): Type = type.getRequired("type") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun domainPattern(): Optional = + domainPattern.getOptional("domainPattern") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun geolocation(): Optional = + geolocation.getOptional("geolocation") + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + /** + * Returns the raw JSON value of [domainPattern]. + * + * Unlike [domainPattern], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("domainPattern") + @ExcludeMissing + fun _domainPattern(): JsonField = domainPattern + + /** + * Returns the raw JSON value of [geolocation]. + * + * Unlike [geolocation], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("geolocation") + @ExcludeMissing + fun _geolocation(): JsonField = geolocation + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [BrowserbaseProxyConfig]. + * + * The following fields are required: + * ```java + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BrowserbaseProxyConfig]. */ + class Builder internal constructor() { + + private var type: JsonField? = null + private var domainPattern: JsonField = JsonMissing.of() + private var geolocation: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(browserbaseProxyConfig: BrowserbaseProxyConfig) = apply { + type = browserbaseProxyConfig.type + domainPattern = browserbaseProxyConfig.domainPattern + geolocation = browserbaseProxyConfig.geolocation + additionalProperties = + browserbaseProxyConfig.additionalProperties.toMutableMap() + } + + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + fun domainPattern(domainPattern: String) = + domainPattern(JsonField.of(domainPattern)) + + /** + * Sets [Builder.domainPattern] to an arbitrary JSON value. + * + * You should usually call [Builder.domainPattern] with a well-typed + * [String] value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun domainPattern(domainPattern: JsonField) = apply { + this.domainPattern = domainPattern + } + + fun geolocation(geolocation: Geolocation) = + geolocation(JsonField.of(geolocation)) + + /** + * Sets [Builder.geolocation] to an arbitrary JSON value. + * + * You should usually call [Builder.geolocation] with a well-typed + * [Geolocation] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun geolocation(geolocation: JsonField) = apply { + this.geolocation = geolocation + } + + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties( + additionalProperties: Map + ) = apply { this.additionalProperties.putAll(additionalProperties) } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [BrowserbaseProxyConfig]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BrowserbaseProxyConfig = + BrowserbaseProxyConfig( + checkRequired("type", type), + domainPattern, + geolocation, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): BrowserbaseProxyConfig = apply { + if (validated) { + return@apply + } + + type().validate() + domainPattern() + geolocation().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (domainPattern.asKnown().isPresent) 1 else 0) + + (geolocation.asKnown().getOrNull()?.validity() ?: 0) + + class Type + @JsonCreator + private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data + * that doesn't match any known member, and you want to know that value. For + * example, if the SDK is on an older version than the API, then the API may + * respond with new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue + fun _value(): JsonField = value + + companion object { + + @JvmField val BROWSERBASE = of("browserbase") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + BROWSERBASE + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For + * example, if the SDK is on an older version than the API, then the API + * may respond with new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + BROWSERBASE, + /** + * An enum member indicating that [Type] was instantiated with an + * unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always + * known or if you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + BROWSERBASE -> Value.BROWSERBASE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always + * known and don't want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a + * not a known member. + */ + fun known(): Known = + when (this) { + BROWSERBASE -> Known.BROWSERBASE + else -> throw StagehandInvalidDataException("Unknown Type: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily + * for debugging and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does + * not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Type = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this + * object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Type && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + class Geolocation + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val country: JsonField, + private val city: JsonField, + private val state: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("country") + @ExcludeMissing + country: JsonField = JsonMissing.of(), + @JsonProperty("city") + @ExcludeMissing + city: JsonField = JsonMissing.of(), + @JsonProperty("state") + @ExcludeMissing + state: JsonField = JsonMissing.of(), + ) : this(country, city, state, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected + * type or is unexpectedly missing or null (e.g. if the server responded + * with an unexpected value). + */ + fun country(): String = country.getRequired("country") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun city(): Optional = city.getOptional("city") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun state(): Optional = state.getOptional("state") + + /** + * Returns the raw JSON value of [country]. + * + * Unlike [country], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("country") + @ExcludeMissing + fun _country(): JsonField = country + + /** + * Returns the raw JSON value of [city]. + * + * Unlike [city], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("city") @ExcludeMissing fun _city(): JsonField = city + + /** + * Returns the raw JSON value of [state]. + * + * Unlike [state], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("state") + @ExcludeMissing + fun _state(): JsonField = state + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [Geolocation]. + * + * The following fields are required: + * ```java + * .country() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Geolocation]. */ + class Builder internal constructor() { + + private var country: JsonField? = null + private var city: JsonField = JsonMissing.of() + private var state: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(geolocation: Geolocation) = apply { + country = geolocation.country + city = geolocation.city + state = geolocation.state + additionalProperties = + geolocation.additionalProperties.toMutableMap() + } + + fun country(country: String) = country(JsonField.of(country)) + + /** + * Sets [Builder.country] to an arbitrary JSON value. + * + * You should usually call [Builder.country] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun country(country: JsonField) = apply { + this.country = country + } + + fun city(city: String) = city(JsonField.of(city)) + + /** + * Sets [Builder.city] to an arbitrary JSON value. + * + * You should usually call [Builder.city] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun city(city: JsonField) = apply { this.city = city } + + fun state(state: String) = state(JsonField.of(state)) + + /** + * Sets [Builder.state] to an arbitrary JSON value. + * + * You should usually call [Builder.state] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun state(state: JsonField) = apply { this.state = state } + + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties( + additionalProperties: Map + ) = apply { this.additionalProperties.putAll(additionalProperties) } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Geolocation]. + * + * Further updates to this [Builder] will not mutate the returned + * instance. + * + * The following fields are required: + * ```java + * .country() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Geolocation = + Geolocation( + checkRequired("country", country), + city, + state, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Geolocation = apply { + if (validated) { + return@apply + } + + country() + city() + state() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this + * object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (country.asKnown().isPresent) 1 else 0) + + (if (city.asKnown().isPresent) 1 else 0) + + (if (state.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Geolocation && + country == other.country && + city == other.city && + state == other.state && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(country, city, state, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Geolocation{country=$country, city=$city, state=$state, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BrowserbaseProxyConfig && + type == other.type && + domainPattern == other.domainPattern && + geolocation == other.geolocation && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(type, domainPattern, geolocation, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BrowserbaseProxyConfig{type=$type, domainPattern=$domainPattern, geolocation=$geolocation, additionalProperties=$additionalProperties}" + } + + class ExternalProxyConfig + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val server: JsonField, + private val type: JsonField, + private val domainPattern: JsonField, + private val password: JsonField, + private val username: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("server") + @ExcludeMissing + server: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + type: JsonField = JsonMissing.of(), + @JsonProperty("domainPattern") + @ExcludeMissing + domainPattern: JsonField = JsonMissing.of(), + @JsonProperty("password") + @ExcludeMissing + password: JsonField = JsonMissing.of(), + @JsonProperty("username") + @ExcludeMissing + username: JsonField = JsonMissing.of(), + ) : this(server, type, domainPattern, password, username, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected + * type or is unexpectedly missing or null (e.g. if the server responded with + * an unexpected value). + */ + fun server(): String = server.getRequired("server") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected + * type or is unexpectedly missing or null (e.g. if the server responded with + * an unexpected value). + */ + fun type(): Type = type.getRequired("type") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun domainPattern(): Optional = + domainPattern.getOptional("domainPattern") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun password(): Optional = password.getOptional("password") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun username(): Optional = username.getOptional("username") + + /** + * Returns the raw JSON value of [server]. + * + * Unlike [server], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("server") + @ExcludeMissing + fun _server(): JsonField = server + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + /** + * Returns the raw JSON value of [domainPattern]. + * + * Unlike [domainPattern], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("domainPattern") + @ExcludeMissing + fun _domainPattern(): JsonField = domainPattern + + /** + * Returns the raw JSON value of [password]. + * + * Unlike [password], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("password") + @ExcludeMissing + fun _password(): JsonField = password + + /** + * Returns the raw JSON value of [username]. + * + * Unlike [username], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("username") + @ExcludeMissing + fun _username(): JsonField = username + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [ExternalProxyConfig]. + * + * The following fields are required: + * ```java + * .server() + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ExternalProxyConfig]. */ + class Builder internal constructor() { + + private var server: JsonField? = null + private var type: JsonField? = null + private var domainPattern: JsonField = JsonMissing.of() + private var password: JsonField = JsonMissing.of() + private var username: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(externalProxyConfig: ExternalProxyConfig) = apply { + server = externalProxyConfig.server + type = externalProxyConfig.type + domainPattern = externalProxyConfig.domainPattern + password = externalProxyConfig.password + username = externalProxyConfig.username + additionalProperties = + externalProxyConfig.additionalProperties.toMutableMap() + } + + fun server(server: String) = server(JsonField.of(server)) + + /** + * Sets [Builder.server] to an arbitrary JSON value. + * + * You should usually call [Builder.server] with a well-typed [String] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun server(server: JsonField) = apply { this.server = server } + + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + fun domainPattern(domainPattern: String) = + domainPattern(JsonField.of(domainPattern)) + + /** + * Sets [Builder.domainPattern] to an arbitrary JSON value. + * + * You should usually call [Builder.domainPattern] with a well-typed + * [String] value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun domainPattern(domainPattern: JsonField) = apply { + this.domainPattern = domainPattern + } + + fun password(password: String) = password(JsonField.of(password)) + + /** + * Sets [Builder.password] to an arbitrary JSON value. + * + * You should usually call [Builder.password] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun password(password: JsonField) = apply { + this.password = password + } + + fun username(username: String) = username(JsonField.of(username)) + + /** + * Sets [Builder.username] to an arbitrary JSON value. + * + * You should usually call [Builder.username] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun username(username: JsonField) = apply { + this.username = username + } + + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties( + additionalProperties: Map + ) = apply { this.additionalProperties.putAll(additionalProperties) } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ExternalProxyConfig]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .server() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ExternalProxyConfig = + ExternalProxyConfig( + checkRequired("server", server), + checkRequired("type", type), + domainPattern, + password, + username, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ExternalProxyConfig = apply { + if (validated) { + return@apply + } + + server() + type().validate() + domainPattern() + password() + username() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (server.asKnown().isPresent) 1 else 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (domainPattern.asKnown().isPresent) 1 else 0) + + (if (password.asKnown().isPresent) 1 else 0) + + (if (username.asKnown().isPresent) 1 else 0) + + class Type + @JsonCreator + private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data + * that doesn't match any known member, and you want to know that value. For + * example, if the SDK is on an older version than the API, then the API may + * respond with new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue + fun _value(): JsonField = value + + companion object { + + @JvmField val EXTERNAL = of("external") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + EXTERNAL + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For + * example, if the SDK is on an older version than the API, then the API + * may respond with new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + EXTERNAL, + /** + * An enum member indicating that [Type] was instantiated with an + * unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always + * known or if you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + EXTERNAL -> Value.EXTERNAL + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always + * known and don't want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a + * not a known member. + */ + fun known(): Known = + when (this) { + EXTERNAL -> Known.EXTERNAL + else -> throw StagehandInvalidDataException("Unknown Type: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily + * for debugging and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does + * not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Type = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this + * object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Type && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ExternalProxyConfig && + server == other.server && + type == other.type && + domainPattern == other.domainPattern && + password == other.password && + username == other.username && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + server, + type, + domainPattern, + password, + username, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ExternalProxyConfig{server=$server, type=$type, domainPattern=$domainPattern, password=$password, username=$username, additionalProperties=$additionalProperties}" + } + } + } + + class Region @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val US_WEST_2 = of("us-west-2") + + @JvmField val US_EAST_1 = of("us-east-1") + + @JvmField val EU_CENTRAL_1 = of("eu-central-1") + + @JvmField val AP_SOUTHEAST_1 = of("ap-southeast-1") + + @JvmStatic fun of(value: String) = Region(JsonField.of(value)) + } + + /** An enum containing [Region]'s known values. */ + enum class Known { + US_WEST_2, + US_EAST_1, + EU_CENTRAL_1, + AP_SOUTHEAST_1, + } + + /** + * An enum containing [Region]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Region] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + US_WEST_2, + US_EAST_1, + EU_CENTRAL_1, + AP_SOUTHEAST_1, + /** + * An enum member indicating that [Region] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + US_WEST_2 -> Value.US_WEST_2 + US_EAST_1 -> Value.US_EAST_1 + EU_CENTRAL_1 -> Value.EU_CENTRAL_1 + AP_SOUTHEAST_1 -> Value.AP_SOUTHEAST_1 + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + US_WEST_2 -> Known.US_WEST_2 + US_EAST_1 -> Known.US_EAST_1 + EU_CENTRAL_1 -> Known.EU_CENTRAL_1 + AP_SOUTHEAST_1 -> Known.AP_SOUTHEAST_1 + else -> throw StagehandInvalidDataException("Unknown Region: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Region = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Region && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + class UserMetadata + @JsonCreator + private constructor( + @com.fasterxml.jackson.annotation.JsonValue + private val additionalProperties: Map + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [UserMetadata]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [UserMetadata]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(userMetadata: UserMetadata) = apply { + additionalProperties = userMetadata.additionalProperties.toMutableMap() + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [UserMetadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): UserMetadata = UserMetadata(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + fun validate(): UserMetadata = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + additionalProperties.count { (_, value) -> !value.isNull() && !value.isMissing() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is UserMetadata && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "UserMetadata{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BrowserbaseSessionCreateParams && + browserSettings == other.browserSettings && + extensionId == other.extensionId && + keepAlive == other.keepAlive && + projectId == other.projectId && + proxies == other.proxies && + region == other.region && + timeout == other.timeout && + userMetadata == other.userMetadata && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + browserSettings, + extensionId, + keepAlive, + projectId, + proxies, + region, + timeout, + userMetadata, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BrowserbaseSessionCreateParams{browserSettings=$browserSettings, extensionId=$extensionId, keepAlive=$keepAlive, projectId=$projectId, proxies=$proxies, region=$region, timeout=$timeout, userMetadata=$userMetadata, additionalProperties=$additionalProperties}" + } + + /** Logging verbosity level (0=quiet, 1=normal, 2=debug) */ + class Verbose @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val _0 = of(0.0) + + @JvmField val _1 = of(1.0) + + @JvmField val _2 = of(2.0) + + @JvmStatic fun of(value: Double) = Verbose(JsonField.of(value)) + } + + /** An enum containing [Verbose]'s known values. */ + enum class Known { + _0, + _1, + _2, + } + + /** + * An enum containing [Verbose]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Verbose] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + _0, + _1, + _2, + /** An enum member indicating that [Verbose] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + _0 -> Value._0 + _1 -> Value._1 + _2 -> Value._2 + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + _0 -> Known._0 + _1 -> Known._1 + _2 -> Known._2 + else -> throw StagehandInvalidDataException("Unknown Verbose: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asDouble(): Double = + _value().asNumber().getOrNull()?.toDouble() + ?: throw StagehandInvalidDataException("Value is not a Double") + + private var validated: Boolean = false + + fun validate(): Verbose = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Verbose && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** Client SDK language */ + class XLanguage @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TYPESCRIPT = of("typescript") + + @JvmField val PYTHON = of("python") + + @JvmField val PLAYGROUND = of("playground") + + @JvmStatic fun of(value: String) = XLanguage(JsonField.of(value)) + } + + /** An enum containing [XLanguage]'s known values. */ + enum class Known { + TYPESCRIPT, + PYTHON, + PLAYGROUND, + } + + /** + * An enum containing [XLanguage]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [XLanguage] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TYPESCRIPT, + PYTHON, + PLAYGROUND, + /** + * An enum member indicating that [XLanguage] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TYPESCRIPT -> Value.TYPESCRIPT + PYTHON -> Value.PYTHON + PLAYGROUND -> Value.PLAYGROUND + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TYPESCRIPT -> Known.TYPESCRIPT + PYTHON -> Known.PYTHON + PLAYGROUND -> Known.PLAYGROUND + else -> throw StagehandInvalidDataException("Unknown XLanguage: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): XLanguage = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is XLanguage && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** Whether to stream the response via SSE */ + class XStreamResponse @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TRUE = of("true") + + @JvmField val FALSE = of("false") + + @JvmStatic fun of(value: String) = XStreamResponse(JsonField.of(value)) + } + + /** An enum containing [XStreamResponse]'s known values. */ + enum class Known { + TRUE, + FALSE, + } + + /** + * An enum containing [XStreamResponse]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [XStreamResponse] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TRUE, + FALSE, + /** + * An enum member indicating that [XStreamResponse] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TRUE -> Value.TRUE + FALSE -> Value.FALSE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRUE -> Known.TRUE + FALSE -> Known.FALSE + else -> throw StagehandInvalidDataException("Unknown XStreamResponse: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): XStreamResponse = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is XStreamResponse && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartResponse.kt index b63f41e..420925f 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartResponse.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartResponse.kt @@ -2,20 +2,60 @@ package com.browserbase.api.models.sessions +import com.browserbase.api.core.Enum import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonField +import com.browserbase.api.core.JsonMissing import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.checkRequired import com.browserbase.api.errors.StagehandInvalidDataException import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty import java.util.Collections import java.util.Objects +import kotlin.jvm.optionals.getOrNull class SessionStartResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor(private val additionalProperties: MutableMap) { +private constructor( + private val data: JsonField, + private val success: JsonField, + private val additionalProperties: MutableMap, +) { - @JsonCreator private constructor() : this(mutableMapOf()) + @JsonCreator + private constructor( + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), + ) : this(data, success, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun data(): Data = data.getRequired("data") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun success(): Success = success.getRequired("success") + + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField = data + + /** + * Returns the raw JSON value of [success]. + * + * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -31,20 +71,52 @@ private constructor(private val additionalProperties: MutableMap? = null + private var success: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(sessionStartResponse: SessionStartResponse) = apply { + data = sessionStartResponse.data + success = sessionStartResponse.success additionalProperties = sessionStartResponse.additionalProperties.toMutableMap() } + fun data(data: Data) = data(JsonField.of(data)) + + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed [Data] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun data(data: JsonField) = apply { this.data = data } + + fun success(success: Success) = success(JsonField.of(success)) + + /** + * Sets [Builder.success] to an arbitrary JSON value. + * + * You should usually call [Builder.success] with a well-typed [Success] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun success(success: JsonField) = apply { this.success = success } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -68,9 +140,21 @@ private constructor(private val additionalProperties: MutableMap, + private val sessionId: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("available") + @ExcludeMissing + available: JsonField = JsonMissing.of(), + @JsonProperty("sessionId") + @ExcludeMissing + sessionId: JsonField = JsonMissing.of(), + ) : this(available, sessionId, mutableMapOf()) + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun available(): Boolean = available.getRequired("available") + + /** + * Unique session identifier + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun sessionId(): String = sessionId.getRequired("sessionId") + + /** + * Returns the raw JSON value of [available]. + * + * Unlike [available], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("available") @ExcludeMissing fun _available(): JsonField = available + + /** + * Returns the raw JSON value of [sessionId]. + * + * Unlike [sessionId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("sessionId") @ExcludeMissing fun _sessionId(): JsonField = sessionId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Data]. + * + * The following fields are required: + * ```java + * .available() + * .sessionId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var available: JsonField? = null + private var sessionId: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + available = data.available + sessionId = data.sessionId + additionalProperties = data.additionalProperties.toMutableMap() + } + + fun available(available: Boolean) = available(JsonField.of(available)) + + /** + * Sets [Builder.available] to an arbitrary JSON value. + * + * You should usually call [Builder.available] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun available(available: JsonField) = apply { this.available = available } + + /** Unique session identifier */ + fun sessionId(sessionId: String) = sessionId(JsonField.of(sessionId)) + + /** + * Sets [Builder.sessionId] to an arbitrary JSON value. + * + * You should usually call [Builder.sessionId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun sessionId(sessionId: JsonField) = apply { this.sessionId = sessionId } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .available() + * .sessionId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Data = + Data( + checkRequired("available", available), + checkRequired("sessionId", sessionId), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Data = apply { + if (validated) { + return@apply + } + + available() + sessionId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (available.asKnown().isPresent) 1 else 0) + + (if (sessionId.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Data && + available == other.available && + sessionId == other.sessionId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(available, sessionId, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Data{available=$available, sessionId=$sessionId, additionalProperties=$additionalProperties}" + } + + class Success @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val TRUE = of(true) + + @JvmStatic fun of(value: Boolean) = Success(JsonField.of(value)) + } + + /** An enum containing [Success]'s known values. */ + enum class Known { + TRUE + } + + /** + * An enum containing [Success]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Success] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + TRUE, + /** An enum member indicating that [Success] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + TRUE -> Value.TRUE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + TRUE -> Known.TRUE + else -> throw StagehandInvalidDataException("Unknown Success: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asBoolean(): Boolean = + _value().asBoolean().orElseThrow { + StagehandInvalidDataException("Value is not a Boolean") + } + + private var validated: Boolean = false + + fun validate(): Success = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Success && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is SessionStartResponse && additionalProperties == other.additionalProperties + return other is SessionStartResponse && + data == other.data && + success == other.success && + additionalProperties == other.additionalProperties } - private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(data, success, additionalProperties) } override fun hashCode(): Int = hashCode - override fun toString() = "SessionStartResponse{additionalProperties=$additionalProperties}" + override fun toString() = + "SessionStartResponse{data=$data, success=$success, additionalProperties=$additionalProperties}" } diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsync.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsync.kt index 435bf27..423fd57 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsync.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsync.kt @@ -3,15 +3,14 @@ package com.browserbase.api.services.async import com.browserbase.api.core.ClientOptions -import com.browserbase.api.core.JsonValue import com.browserbase.api.core.RequestOptions import com.browserbase.api.core.http.HttpResponseFor import com.browserbase.api.models.sessions.SessionActParams import com.browserbase.api.models.sessions.SessionActResponse import com.browserbase.api.models.sessions.SessionEndParams import com.browserbase.api.models.sessions.SessionEndResponse -import com.browserbase.api.models.sessions.SessionExecuteAgentParams -import com.browserbase.api.models.sessions.SessionExecuteAgentResponse +import com.browserbase.api.models.sessions.SessionExecuteParams +import com.browserbase.api.models.sessions.SessionExecuteResponse import com.browserbase.api.models.sessions.SessionExtractParams import com.browserbase.api.models.sessions.SessionExtractResponse import com.browserbase.api.models.sessions.SessionNavigateParams @@ -40,21 +39,20 @@ interface SessionServiceAsync { /** * Executes a browser action using natural language instructions or a predefined Action object. */ - fun act(id: JsonValue): CompletableFuture = act(id, SessionActParams.none()) + fun act(id: String, params: SessionActParams): CompletableFuture = + act(id, params, RequestOptions.none()) /** @see act */ fun act( - id: JsonValue, - params: SessionActParams = SessionActParams.none(), + id: String, + params: SessionActParams, requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture = act(params.toBuilder().id(id).build(), requestOptions) /** @see act */ - fun act( - id: JsonValue, - params: SessionActParams = SessionActParams.none(), - ): CompletableFuture = act(id, params, RequestOptions.none()) + fun act(params: SessionActParams): CompletableFuture = + act(params, RequestOptions.none()) /** @see act */ fun act( @@ -62,20 +60,12 @@ interface SessionServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture - /** @see act */ - fun act(params: SessionActParams): CompletableFuture = - act(params, RequestOptions.none()) - - /** @see act */ - fun act(id: JsonValue, requestOptions: RequestOptions): CompletableFuture = - act(id, SessionActParams.none(), requestOptions) - /** Terminates the browser session and releases all associated resources. */ - fun end(id: JsonValue): CompletableFuture = end(id, SessionEndParams.none()) + fun end(id: String): CompletableFuture = end(id, SessionEndParams.none()) /** @see end */ fun end( - id: JsonValue, + id: String, params: SessionEndParams = SessionEndParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture = @@ -83,7 +73,7 @@ interface SessionServiceAsync { /** @see end */ fun end( - id: JsonValue, + id: String, params: SessionEndParams = SessionEndParams.none(), ): CompletableFuture = end(id, params, RequestOptions.none()) @@ -98,53 +88,40 @@ interface SessionServiceAsync { end(params, RequestOptions.none()) /** @see end */ - fun end(id: JsonValue, requestOptions: RequestOptions): CompletableFuture = + fun end(id: String, requestOptions: RequestOptions): CompletableFuture = end(id, SessionEndParams.none(), requestOptions) /** Runs an autonomous AI agent that can perform complex multi-step browser tasks. */ - fun executeAgent(id: JsonValue): CompletableFuture = - executeAgent(id, SessionExecuteAgentParams.none()) - - /** @see executeAgent */ - fun executeAgent( - id: JsonValue, - params: SessionExecuteAgentParams = SessionExecuteAgentParams.none(), + fun execute( + id: String, + params: SessionExecuteParams, + ): CompletableFuture = execute(id, params, RequestOptions.none()) + + /** @see execute */ + fun execute( + id: String, + params: SessionExecuteParams, requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture = - executeAgent(params.toBuilder().id(id).build(), requestOptions) - - /** @see executeAgent */ - fun executeAgent( - id: JsonValue, - params: SessionExecuteAgentParams = SessionExecuteAgentParams.none(), - ): CompletableFuture = - executeAgent(id, params, RequestOptions.none()) - - /** @see executeAgent */ - fun executeAgent( - params: SessionExecuteAgentParams, - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture + ): CompletableFuture = + execute(params.toBuilder().id(id).build(), requestOptions) - /** @see executeAgent */ - fun executeAgent( - params: SessionExecuteAgentParams - ): CompletableFuture = executeAgent(params, RequestOptions.none()) + /** @see execute */ + fun execute(params: SessionExecuteParams): CompletableFuture = + execute(params, RequestOptions.none()) - /** @see executeAgent */ - fun executeAgent( - id: JsonValue, - requestOptions: RequestOptions, - ): CompletableFuture = - executeAgent(id, SessionExecuteAgentParams.none(), requestOptions) + /** @see execute */ + fun execute( + params: SessionExecuteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture /** Extracts structured data from the current page using AI-powered analysis. */ - fun extract(id: JsonValue): CompletableFuture = + fun extract(id: String): CompletableFuture = extract(id, SessionExtractParams.none()) /** @see extract */ fun extract( - id: JsonValue, + id: String, params: SessionExtractParams = SessionExtractParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture = @@ -152,7 +129,7 @@ interface SessionServiceAsync { /** @see extract */ fun extract( - id: JsonValue, + id: String, params: SessionExtractParams = SessionExtractParams.none(), ): CompletableFuture = extract(id, params, RequestOptions.none()) @@ -168,34 +145,24 @@ interface SessionServiceAsync { /** @see extract */ fun extract( - id: JsonValue, + id: String, requestOptions: RequestOptions, ): CompletableFuture = extract(id, SessionExtractParams.none(), requestOptions) /** Navigates the browser to the specified URL. */ - fun navigate(id: JsonValue): CompletableFuture = - navigate(id, SessionNavigateParams.none()) - - /** @see navigate */ - fun navigate( - id: JsonValue, - params: SessionNavigateParams = SessionNavigateParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture = - navigate(params.toBuilder().id(id).build(), requestOptions) - - /** @see navigate */ fun navigate( - id: JsonValue, - params: SessionNavigateParams = SessionNavigateParams.none(), + id: String, + params: SessionNavigateParams, ): CompletableFuture = navigate(id, params, RequestOptions.none()) /** @see navigate */ fun navigate( + id: String, params: SessionNavigateParams, requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture + ): CompletableFuture = + navigate(params.toBuilder().id(id).build(), requestOptions) /** @see navigate */ fun navigate(params: SessionNavigateParams): CompletableFuture = @@ -203,21 +170,20 @@ interface SessionServiceAsync { /** @see navigate */ fun navigate( - id: JsonValue, - requestOptions: RequestOptions, - ): CompletableFuture = - navigate(id, SessionNavigateParams.none(), requestOptions) + params: SessionNavigateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture /** * Identifies and returns available actions on the current page that match the given * instruction. */ - fun observe(id: JsonValue): CompletableFuture = + fun observe(id: String): CompletableFuture = observe(id, SessionObserveParams.none()) /** @see observe */ fun observe( - id: JsonValue, + id: String, params: SessionObserveParams = SessionObserveParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture = @@ -225,7 +191,7 @@ interface SessionServiceAsync { /** @see observe */ fun observe( - id: JsonValue, + id: String, params: SessionObserveParams = SessionObserveParams.none(), ): CompletableFuture = observe(id, params, RequestOptions.none()) @@ -241,7 +207,7 @@ interface SessionServiceAsync { /** @see observe */ fun observe( - id: JsonValue, + id: String, requestOptions: RequestOptions, ): CompletableFuture = observe(id, SessionObserveParams.none(), requestOptions) @@ -250,23 +216,15 @@ interface SessionServiceAsync { * Creates a new browser session with the specified configuration. Returns a session ID used for * all subsequent operations. */ - fun start(): CompletableFuture = start(SessionStartParams.none()) + fun start(params: SessionStartParams): CompletableFuture = + start(params, RequestOptions.none()) /** @see start */ fun start( - params: SessionStartParams = SessionStartParams.none(), + params: SessionStartParams, requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture - /** @see start */ - fun start( - params: SessionStartParams = SessionStartParams.none() - ): CompletableFuture = start(params, RequestOptions.none()) - - /** @see start */ - fun start(requestOptions: RequestOptions): CompletableFuture = - start(SessionStartParams.none(), requestOptions) - /** * A view of [SessionServiceAsync] that provides access to raw HTTP responses for each method. */ @@ -282,32 +240,22 @@ interface SessionServiceAsync { ): SessionServiceAsync.WithRawResponse /** - * Returns a raw HTTP response for `post /sessions/{id}/act`, but is otherwise the same as - * [SessionServiceAsync.act]. + * Returns a raw HTTP response for `post /v1/sessions/{id}/act`, but is otherwise the same + * as [SessionServiceAsync.act]. */ - fun act(id: JsonValue): CompletableFuture> = - act(id, SessionActParams.none()) - - /** @see act */ fun act( - id: JsonValue, - params: SessionActParams = SessionActParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> = - act(params.toBuilder().id(id).build(), requestOptions) - - /** @see act */ - fun act( - id: JsonValue, - params: SessionActParams = SessionActParams.none(), + id: String, + params: SessionActParams, ): CompletableFuture> = act(id, params, RequestOptions.none()) /** @see act */ fun act( + id: String, params: SessionActParams, requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> + ): CompletableFuture> = + act(params.toBuilder().id(id).build(), requestOptions) /** @see act */ fun act(params: SessionActParams): CompletableFuture> = @@ -315,21 +263,20 @@ interface SessionServiceAsync { /** @see act */ fun act( - id: JsonValue, - requestOptions: RequestOptions, - ): CompletableFuture> = - act(id, SessionActParams.none(), requestOptions) + params: SessionActParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> /** - * Returns a raw HTTP response for `post /sessions/{id}/end`, but is otherwise the same as - * [SessionServiceAsync.end]. + * Returns a raw HTTP response for `post /v1/sessions/{id}/end`, but is otherwise the same + * as [SessionServiceAsync.end]. */ - fun end(id: JsonValue): CompletableFuture> = + fun end(id: String): CompletableFuture> = end(id, SessionEndParams.none()) /** @see end */ fun end( - id: JsonValue, + id: String, params: SessionEndParams = SessionEndParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> = @@ -337,7 +284,7 @@ interface SessionServiceAsync { /** @see end */ fun end( - id: JsonValue, + id: String, params: SessionEndParams = SessionEndParams.none(), ): CompletableFuture> = end(id, params, RequestOptions.none()) @@ -354,64 +301,51 @@ interface SessionServiceAsync { /** @see end */ fun end( - id: JsonValue, + id: String, requestOptions: RequestOptions, ): CompletableFuture> = end(id, SessionEndParams.none(), requestOptions) /** - * Returns a raw HTTP response for `post /sessions/{id}/agentExecute`, but is otherwise the - * same as [SessionServiceAsync.executeAgent]. + * Returns a raw HTTP response for `post /v1/sessions/{id}/agentExecute`, but is otherwise + * the same as [SessionServiceAsync.execute]. */ - fun executeAgent( - id: JsonValue - ): CompletableFuture> = - executeAgent(id, SessionExecuteAgentParams.none()) - - /** @see executeAgent */ - fun executeAgent( - id: JsonValue, - params: SessionExecuteAgentParams = SessionExecuteAgentParams.none(), + fun execute( + id: String, + params: SessionExecuteParams, + ): CompletableFuture> = + execute(id, params, RequestOptions.none()) + + /** @see execute */ + fun execute( + id: String, + params: SessionExecuteParams, requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> = - executeAgent(params.toBuilder().id(id).build(), requestOptions) - - /** @see executeAgent */ - fun executeAgent( - id: JsonValue, - params: SessionExecuteAgentParams = SessionExecuteAgentParams.none(), - ): CompletableFuture> = - executeAgent(id, params, RequestOptions.none()) - - /** @see executeAgent */ - fun executeAgent( - params: SessionExecuteAgentParams, + ): CompletableFuture> = + execute(params.toBuilder().id(id).build(), requestOptions) + + /** @see execute */ + fun execute( + params: SessionExecuteParams + ): CompletableFuture> = + execute(params, RequestOptions.none()) + + /** @see execute */ + fun execute( + params: SessionExecuteParams, requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> - - /** @see executeAgent */ - fun executeAgent( - params: SessionExecuteAgentParams - ): CompletableFuture> = - executeAgent(params, RequestOptions.none()) - - /** @see executeAgent */ - fun executeAgent( - id: JsonValue, - requestOptions: RequestOptions, - ): CompletableFuture> = - executeAgent(id, SessionExecuteAgentParams.none(), requestOptions) + ): CompletableFuture> /** - * Returns a raw HTTP response for `post /sessions/{id}/extract`, but is otherwise the same - * as [SessionServiceAsync.extract]. + * Returns a raw HTTP response for `post /v1/sessions/{id}/extract`, but is otherwise the + * same as [SessionServiceAsync.extract]. */ - fun extract(id: JsonValue): CompletableFuture> = + fun extract(id: String): CompletableFuture> = extract(id, SessionExtractParams.none()) /** @see extract */ fun extract( - id: JsonValue, + id: String, params: SessionExtractParams = SessionExtractParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> = @@ -419,7 +353,7 @@ interface SessionServiceAsync { /** @see extract */ fun extract( - id: JsonValue, + id: String, params: SessionExtractParams = SessionExtractParams.none(), ): CompletableFuture> = extract(id, params, RequestOptions.none()) @@ -438,38 +372,28 @@ interface SessionServiceAsync { /** @see extract */ fun extract( - id: JsonValue, + id: String, requestOptions: RequestOptions, ): CompletableFuture> = extract(id, SessionExtractParams.none(), requestOptions) /** - * Returns a raw HTTP response for `post /sessions/{id}/navigate`, but is otherwise the same - * as [SessionServiceAsync.navigate]. + * Returns a raw HTTP response for `post /v1/sessions/{id}/navigate`, but is otherwise the + * same as [SessionServiceAsync.navigate]. */ - fun navigate(id: JsonValue): CompletableFuture> = - navigate(id, SessionNavigateParams.none()) - - /** @see navigate */ fun navigate( - id: JsonValue, - params: SessionNavigateParams = SessionNavigateParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> = - navigate(params.toBuilder().id(id).build(), requestOptions) - - /** @see navigate */ - fun navigate( - id: JsonValue, - params: SessionNavigateParams = SessionNavigateParams.none(), + id: String, + params: SessionNavigateParams, ): CompletableFuture> = navigate(id, params, RequestOptions.none()) /** @see navigate */ fun navigate( + id: String, params: SessionNavigateParams, requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> + ): CompletableFuture> = + navigate(params.toBuilder().id(id).build(), requestOptions) /** @see navigate */ fun navigate( @@ -479,21 +403,20 @@ interface SessionServiceAsync { /** @see navigate */ fun navigate( - id: JsonValue, - requestOptions: RequestOptions, - ): CompletableFuture> = - navigate(id, SessionNavigateParams.none(), requestOptions) + params: SessionNavigateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> /** - * Returns a raw HTTP response for `post /sessions/{id}/observe`, but is otherwise the same - * as [SessionServiceAsync.observe]. + * Returns a raw HTTP response for `post /v1/sessions/{id}/observe`, but is otherwise the + * same as [SessionServiceAsync.observe]. */ - fun observe(id: JsonValue): CompletableFuture> = + fun observe(id: String): CompletableFuture> = observe(id, SessionObserveParams.none()) /** @see observe */ fun observe( - id: JsonValue, + id: String, params: SessionObserveParams = SessionObserveParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> = @@ -501,7 +424,7 @@ interface SessionServiceAsync { /** @see observe */ fun observe( - id: JsonValue, + id: String, params: SessionObserveParams = SessionObserveParams.none(), ): CompletableFuture> = observe(id, params, RequestOptions.none()) @@ -520,34 +443,24 @@ interface SessionServiceAsync { /** @see observe */ fun observe( - id: JsonValue, + id: String, requestOptions: RequestOptions, ): CompletableFuture> = observe(id, SessionObserveParams.none(), requestOptions) /** - * Returns a raw HTTP response for `post /sessions/start`, but is otherwise the same as + * Returns a raw HTTP response for `post /v1/sessions/start`, but is otherwise the same as * [SessionServiceAsync.start]. */ - fun start(): CompletableFuture> = - start(SessionStartParams.none()) - - /** @see start */ - fun start( - params: SessionStartParams = SessionStartParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> - - /** @see start */ fun start( - params: SessionStartParams = SessionStartParams.none() + params: SessionStartParams ): CompletableFuture> = start(params, RequestOptions.none()) /** @see start */ fun start( - requestOptions: RequestOptions - ): CompletableFuture> = - start(SessionStartParams.none(), requestOptions) + params: SessionStartParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> } } diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsyncImpl.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsyncImpl.kt index 7746896..99037bc 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsyncImpl.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsyncImpl.kt @@ -4,6 +4,7 @@ package com.browserbase.api.services.async import com.browserbase.api.core.ClientOptions import com.browserbase.api.core.RequestOptions +import com.browserbase.api.core.checkRequired import com.browserbase.api.core.handlers.errorBodyHandler import com.browserbase.api.core.handlers.errorHandler import com.browserbase.api.core.handlers.jsonHandler @@ -19,8 +20,8 @@ import com.browserbase.api.models.sessions.SessionActParams import com.browserbase.api.models.sessions.SessionActResponse import com.browserbase.api.models.sessions.SessionEndParams import com.browserbase.api.models.sessions.SessionEndResponse -import com.browserbase.api.models.sessions.SessionExecuteAgentParams -import com.browserbase.api.models.sessions.SessionExecuteAgentResponse +import com.browserbase.api.models.sessions.SessionExecuteParams +import com.browserbase.api.models.sessions.SessionExecuteResponse import com.browserbase.api.models.sessions.SessionExtractParams import com.browserbase.api.models.sessions.SessionExtractResponse import com.browserbase.api.models.sessions.SessionNavigateParams @@ -31,6 +32,7 @@ import com.browserbase.api.models.sessions.SessionStartParams import com.browserbase.api.models.sessions.SessionStartResponse import java.util.concurrent.CompletableFuture import java.util.function.Consumer +import kotlin.jvm.optionals.getOrNull class SessionServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : SessionServiceAsync { @@ -48,49 +50,49 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl params: SessionActParams, requestOptions: RequestOptions, ): CompletableFuture = - // post /sessions/{id}/act + // post /v1/sessions/{id}/act withRawResponse().act(params, requestOptions).thenApply { it.parse() } override fun end( params: SessionEndParams, requestOptions: RequestOptions, ): CompletableFuture = - // post /sessions/{id}/end + // post /v1/sessions/{id}/end withRawResponse().end(params, requestOptions).thenApply { it.parse() } - override fun executeAgent( - params: SessionExecuteAgentParams, + override fun execute( + params: SessionExecuteParams, requestOptions: RequestOptions, - ): CompletableFuture = - // post /sessions/{id}/agentExecute - withRawResponse().executeAgent(params, requestOptions).thenApply { it.parse() } + ): CompletableFuture = + // post /v1/sessions/{id}/agentExecute + withRawResponse().execute(params, requestOptions).thenApply { it.parse() } override fun extract( params: SessionExtractParams, requestOptions: RequestOptions, ): CompletableFuture = - // post /sessions/{id}/extract + // post /v1/sessions/{id}/extract withRawResponse().extract(params, requestOptions).thenApply { it.parse() } override fun navigate( params: SessionNavigateParams, requestOptions: RequestOptions, ): CompletableFuture = - // post /sessions/{id}/navigate + // post /v1/sessions/{id}/navigate withRawResponse().navigate(params, requestOptions).thenApply { it.parse() } override fun observe( params: SessionObserveParams, requestOptions: RequestOptions, ): CompletableFuture = - // post /sessions/{id}/observe + // post /v1/sessions/{id}/observe withRawResponse().observe(params, requestOptions).thenApply { it.parse() } override fun start( params: SessionStartParams, requestOptions: RequestOptions, ): CompletableFuture = - // post /sessions/start + // post /v1/sessions/start withRawResponse().start(params, requestOptions).thenApply { it.parse() } class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : @@ -113,11 +115,14 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl params: SessionActParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "act") + .addPathSegments("v1", "sessions", params._pathParam(0), "act") .body(json(clientOptions.jsonMapper, params._body())) .build() .prepareAsync(clientOptions, params) @@ -144,11 +149,14 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl params: SessionEndParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "end") + .addPathSegments("v1", "sessions", params._pathParam(0), "end") .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } .build() .prepareAsync(clientOptions, params) @@ -168,18 +176,21 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl } } - private val executeAgentHandler: Handler = - jsonHandler(clientOptions.jsonMapper) + private val executeHandler: Handler = + jsonHandler(clientOptions.jsonMapper) - override fun executeAgent( - params: SessionExecuteAgentParams, + override fun execute( + params: SessionExecuteParams, requestOptions: RequestOptions, - ): CompletableFuture> { + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "agentExecute") + .addPathSegments("v1", "sessions", params._pathParam(0), "agentExecute") .body(json(clientOptions.jsonMapper, params._body())) .build() .prepareAsync(clientOptions, params) @@ -189,7 +200,7 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl .thenApply { response -> errorHandler.handle(response).parseable { response - .use { executeAgentHandler.handle(it) } + .use { executeHandler.handle(it) } .also { if (requestOptions.responseValidation!!) { it.validate() @@ -206,11 +217,14 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl params: SessionExtractParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "extract") + .addPathSegments("v1", "sessions", params._pathParam(0), "extract") .body(json(clientOptions.jsonMapper, params._body())) .build() .prepareAsync(clientOptions, params) @@ -237,11 +251,14 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl params: SessionNavigateParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "navigate") + .addPathSegments("v1", "sessions", params._pathParam(0), "navigate") .body(json(clientOptions.jsonMapper, params._body())) .build() .prepareAsync(clientOptions, params) @@ -268,11 +285,14 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl params: SessionObserveParams, requestOptions: RequestOptions, ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "observe") + .addPathSegments("v1", "sessions", params._pathParam(0), "observe") .body(json(clientOptions.jsonMapper, params._body())) .build() .prepareAsync(clientOptions, params) @@ -303,7 +323,7 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", "start") + .addPathSegments("v1", "sessions", "start") .body(json(clientOptions.jsonMapper, params._body())) .build() .prepareAsync(clientOptions, params) diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionService.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionService.kt index f29cc14..df7bb72 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionService.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionService.kt @@ -3,15 +3,14 @@ package com.browserbase.api.services.blocking import com.browserbase.api.core.ClientOptions -import com.browserbase.api.core.JsonValue import com.browserbase.api.core.RequestOptions import com.browserbase.api.core.http.HttpResponseFor import com.browserbase.api.models.sessions.SessionActParams import com.browserbase.api.models.sessions.SessionActResponse import com.browserbase.api.models.sessions.SessionEndParams import com.browserbase.api.models.sessions.SessionEndResponse -import com.browserbase.api.models.sessions.SessionExecuteAgentParams -import com.browserbase.api.models.sessions.SessionExecuteAgentResponse +import com.browserbase.api.models.sessions.SessionExecuteParams +import com.browserbase.api.models.sessions.SessionExecuteResponse import com.browserbase.api.models.sessions.SessionExtractParams import com.browserbase.api.models.sessions.SessionExtractResponse import com.browserbase.api.models.sessions.SessionNavigateParams @@ -40,18 +39,18 @@ interface SessionService { /** * Executes a browser action using natural language instructions or a predefined Action object. */ - fun act(id: JsonValue): SessionActResponse = act(id, SessionActParams.none()) + fun act(id: String, params: SessionActParams): SessionActResponse = + act(id, params, RequestOptions.none()) /** @see act */ fun act( - id: JsonValue, - params: SessionActParams = SessionActParams.none(), + id: String, + params: SessionActParams, requestOptions: RequestOptions = RequestOptions.none(), ): SessionActResponse = act(params.toBuilder().id(id).build(), requestOptions) /** @see act */ - fun act(id: JsonValue, params: SessionActParams = SessionActParams.none()): SessionActResponse = - act(id, params, RequestOptions.none()) + fun act(params: SessionActParams): SessionActResponse = act(params, RequestOptions.none()) /** @see act */ fun act( @@ -59,25 +58,18 @@ interface SessionService { requestOptions: RequestOptions = RequestOptions.none(), ): SessionActResponse - /** @see act */ - fun act(params: SessionActParams): SessionActResponse = act(params, RequestOptions.none()) - - /** @see act */ - fun act(id: JsonValue, requestOptions: RequestOptions): SessionActResponse = - act(id, SessionActParams.none(), requestOptions) - /** Terminates the browser session and releases all associated resources. */ - fun end(id: JsonValue): SessionEndResponse = end(id, SessionEndParams.none()) + fun end(id: String): SessionEndResponse = end(id, SessionEndParams.none()) /** @see end */ fun end( - id: JsonValue, + id: String, params: SessionEndParams = SessionEndParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): SessionEndResponse = end(params.toBuilder().id(id).build(), requestOptions) /** @see end */ - fun end(id: JsonValue, params: SessionEndParams = SessionEndParams.none()): SessionEndResponse = + fun end(id: String, params: SessionEndParams = SessionEndParams.none()): SessionEndResponse = end(id, params, RequestOptions.none()) /** @see end */ @@ -90,53 +82,43 @@ interface SessionService { fun end(params: SessionEndParams): SessionEndResponse = end(params, RequestOptions.none()) /** @see end */ - fun end(id: JsonValue, requestOptions: RequestOptions): SessionEndResponse = + fun end(id: String, requestOptions: RequestOptions): SessionEndResponse = end(id, SessionEndParams.none(), requestOptions) /** Runs an autonomous AI agent that can perform complex multi-step browser tasks. */ - fun executeAgent(id: JsonValue): SessionExecuteAgentResponse = - executeAgent(id, SessionExecuteAgentParams.none()) + fun execute(id: String, params: SessionExecuteParams): SessionExecuteResponse = + execute(id, params, RequestOptions.none()) - /** @see executeAgent */ - fun executeAgent( - id: JsonValue, - params: SessionExecuteAgentParams = SessionExecuteAgentParams.none(), + /** @see execute */ + fun execute( + id: String, + params: SessionExecuteParams, requestOptions: RequestOptions = RequestOptions.none(), - ): SessionExecuteAgentResponse = executeAgent(params.toBuilder().id(id).build(), requestOptions) + ): SessionExecuteResponse = execute(params.toBuilder().id(id).build(), requestOptions) - /** @see executeAgent */ - fun executeAgent( - id: JsonValue, - params: SessionExecuteAgentParams = SessionExecuteAgentParams.none(), - ): SessionExecuteAgentResponse = executeAgent(id, params, RequestOptions.none()) + /** @see execute */ + fun execute(params: SessionExecuteParams): SessionExecuteResponse = + execute(params, RequestOptions.none()) - /** @see executeAgent */ - fun executeAgent( - params: SessionExecuteAgentParams, + /** @see execute */ + fun execute( + params: SessionExecuteParams, requestOptions: RequestOptions = RequestOptions.none(), - ): SessionExecuteAgentResponse - - /** @see executeAgent */ - fun executeAgent(params: SessionExecuteAgentParams): SessionExecuteAgentResponse = - executeAgent(params, RequestOptions.none()) - - /** @see executeAgent */ - fun executeAgent(id: JsonValue, requestOptions: RequestOptions): SessionExecuteAgentResponse = - executeAgent(id, SessionExecuteAgentParams.none(), requestOptions) + ): SessionExecuteResponse /** Extracts structured data from the current page using AI-powered analysis. */ - fun extract(id: JsonValue): SessionExtractResponse = extract(id, SessionExtractParams.none()) + fun extract(id: String): SessionExtractResponse = extract(id, SessionExtractParams.none()) /** @see extract */ fun extract( - id: JsonValue, + id: String, params: SessionExtractParams = SessionExtractParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): SessionExtractResponse = extract(params.toBuilder().id(id).build(), requestOptions) /** @see extract */ fun extract( - id: JsonValue, + id: String, params: SessionExtractParams = SessionExtractParams.none(), ): SessionExtractResponse = extract(id, params, RequestOptions.none()) @@ -151,25 +133,23 @@ interface SessionService { extract(params, RequestOptions.none()) /** @see extract */ - fun extract(id: JsonValue, requestOptions: RequestOptions): SessionExtractResponse = + fun extract(id: String, requestOptions: RequestOptions): SessionExtractResponse = extract(id, SessionExtractParams.none(), requestOptions) /** Navigates the browser to the specified URL. */ - fun navigate(id: JsonValue): SessionNavigateResponse = - navigate(id, SessionNavigateParams.none()) + fun navigate(id: String, params: SessionNavigateParams): SessionNavigateResponse = + navigate(id, params, RequestOptions.none()) /** @see navigate */ fun navigate( - id: JsonValue, - params: SessionNavigateParams = SessionNavigateParams.none(), + id: String, + params: SessionNavigateParams, requestOptions: RequestOptions = RequestOptions.none(), ): SessionNavigateResponse = navigate(params.toBuilder().id(id).build(), requestOptions) /** @see navigate */ - fun navigate( - id: JsonValue, - params: SessionNavigateParams = SessionNavigateParams.none(), - ): SessionNavigateResponse = navigate(id, params, RequestOptions.none()) + fun navigate(params: SessionNavigateParams): SessionNavigateResponse = + navigate(params, RequestOptions.none()) /** @see navigate */ fun navigate( @@ -177,30 +157,22 @@ interface SessionService { requestOptions: RequestOptions = RequestOptions.none(), ): SessionNavigateResponse - /** @see navigate */ - fun navigate(params: SessionNavigateParams): SessionNavigateResponse = - navigate(params, RequestOptions.none()) - - /** @see navigate */ - fun navigate(id: JsonValue, requestOptions: RequestOptions): SessionNavigateResponse = - navigate(id, SessionNavigateParams.none(), requestOptions) - /** * Identifies and returns available actions on the current page that match the given * instruction. */ - fun observe(id: JsonValue): SessionObserveResponse = observe(id, SessionObserveParams.none()) + fun observe(id: String): SessionObserveResponse = observe(id, SessionObserveParams.none()) /** @see observe */ fun observe( - id: JsonValue, + id: String, params: SessionObserveParams = SessionObserveParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): SessionObserveResponse = observe(params.toBuilder().id(id).build(), requestOptions) /** @see observe */ fun observe( - id: JsonValue, + id: String, params: SessionObserveParams = SessionObserveParams.none(), ): SessionObserveResponse = observe(id, params, RequestOptions.none()) @@ -215,29 +187,22 @@ interface SessionService { observe(params, RequestOptions.none()) /** @see observe */ - fun observe(id: JsonValue, requestOptions: RequestOptions): SessionObserveResponse = + fun observe(id: String, requestOptions: RequestOptions): SessionObserveResponse = observe(id, SessionObserveParams.none(), requestOptions) /** * Creates a new browser session with the specified configuration. Returns a session ID used for * all subsequent operations. */ - fun start(): SessionStartResponse = start(SessionStartParams.none()) + fun start(params: SessionStartParams): SessionStartResponse = + start(params, RequestOptions.none()) /** @see start */ fun start( - params: SessionStartParams = SessionStartParams.none(), + params: SessionStartParams, requestOptions: RequestOptions = RequestOptions.none(), ): SessionStartResponse - /** @see start */ - fun start(params: SessionStartParams = SessionStartParams.none()): SessionStartResponse = - start(params, RequestOptions.none()) - - /** @see start */ - fun start(requestOptions: RequestOptions): SessionStartResponse = - start(SessionStartParams.none(), requestOptions) - /** A view of [SessionService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { @@ -249,28 +214,26 @@ interface SessionService { fun withOptions(modifier: Consumer): SessionService.WithRawResponse /** - * Returns a raw HTTP response for `post /sessions/{id}/act`, but is otherwise the same as - * [SessionService.act]. + * Returns a raw HTTP response for `post /v1/sessions/{id}/act`, but is otherwise the same + * as [SessionService.act]. */ @MustBeClosed - fun act(id: JsonValue): HttpResponseFor = - act(id, SessionActParams.none()) + fun act(id: String, params: SessionActParams): HttpResponseFor = + act(id, params, RequestOptions.none()) /** @see act */ @MustBeClosed fun act( - id: JsonValue, - params: SessionActParams = SessionActParams.none(), + id: String, + params: SessionActParams, requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor = act(params.toBuilder().id(id).build(), requestOptions) /** @see act */ @MustBeClosed - fun act( - id: JsonValue, - params: SessionActParams = SessionActParams.none(), - ): HttpResponseFor = act(id, params, RequestOptions.none()) + fun act(params: SessionActParams): HttpResponseFor = + act(params, RequestOptions.none()) /** @see act */ @MustBeClosed @@ -279,30 +242,17 @@ interface SessionService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor - /** @see act */ - @MustBeClosed - fun act(params: SessionActParams): HttpResponseFor = - act(params, RequestOptions.none()) - - /** @see act */ - @MustBeClosed - fun act( - id: JsonValue, - requestOptions: RequestOptions, - ): HttpResponseFor = act(id, SessionActParams.none(), requestOptions) - /** - * Returns a raw HTTP response for `post /sessions/{id}/end`, but is otherwise the same as - * [SessionService.end]. + * Returns a raw HTTP response for `post /v1/sessions/{id}/end`, but is otherwise the same + * as [SessionService.end]. */ @MustBeClosed - fun end(id: JsonValue): HttpResponseFor = - end(id, SessionEndParams.none()) + fun end(id: String): HttpResponseFor = end(id, SessionEndParams.none()) /** @see end */ @MustBeClosed fun end( - id: JsonValue, + id: String, params: SessionEndParams = SessionEndParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor = @@ -311,7 +261,7 @@ interface SessionService { /** @see end */ @MustBeClosed fun end( - id: JsonValue, + id: String, params: SessionEndParams = SessionEndParams.none(), ): HttpResponseFor = end(id, params, RequestOptions.none()) @@ -329,70 +279,52 @@ interface SessionService { /** @see end */ @MustBeClosed - fun end( - id: JsonValue, - requestOptions: RequestOptions, - ): HttpResponseFor = end(id, SessionEndParams.none(), requestOptions) + fun end(id: String, requestOptions: RequestOptions): HttpResponseFor = + end(id, SessionEndParams.none(), requestOptions) /** - * Returns a raw HTTP response for `post /sessions/{id}/agentExecute`, but is otherwise the - * same as [SessionService.executeAgent]. + * Returns a raw HTTP response for `post /v1/sessions/{id}/agentExecute`, but is otherwise + * the same as [SessionService.execute]. */ @MustBeClosed - fun executeAgent(id: JsonValue): HttpResponseFor = - executeAgent(id, SessionExecuteAgentParams.none()) + fun execute( + id: String, + params: SessionExecuteParams, + ): HttpResponseFor = execute(id, params, RequestOptions.none()) - /** @see executeAgent */ + /** @see execute */ @MustBeClosed - fun executeAgent( - id: JsonValue, - params: SessionExecuteAgentParams = SessionExecuteAgentParams.none(), + fun execute( + id: String, + params: SessionExecuteParams, requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor = - executeAgent(params.toBuilder().id(id).build(), requestOptions) + ): HttpResponseFor = + execute(params.toBuilder().id(id).build(), requestOptions) - /** @see executeAgent */ + /** @see execute */ @MustBeClosed - fun executeAgent( - id: JsonValue, - params: SessionExecuteAgentParams = SessionExecuteAgentParams.none(), - ): HttpResponseFor = - executeAgent(id, params, RequestOptions.none()) + fun execute(params: SessionExecuteParams): HttpResponseFor = + execute(params, RequestOptions.none()) - /** @see executeAgent */ + /** @see execute */ @MustBeClosed - fun executeAgent( - params: SessionExecuteAgentParams, + fun execute( + params: SessionExecuteParams, requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor - - /** @see executeAgent */ - @MustBeClosed - fun executeAgent( - params: SessionExecuteAgentParams - ): HttpResponseFor = - executeAgent(params, RequestOptions.none()) - - /** @see executeAgent */ - @MustBeClosed - fun executeAgent( - id: JsonValue, - requestOptions: RequestOptions, - ): HttpResponseFor = - executeAgent(id, SessionExecuteAgentParams.none(), requestOptions) + ): HttpResponseFor /** - * Returns a raw HTTP response for `post /sessions/{id}/extract`, but is otherwise the same - * as [SessionService.extract]. + * Returns a raw HTTP response for `post /v1/sessions/{id}/extract`, but is otherwise the + * same as [SessionService.extract]. */ @MustBeClosed - fun extract(id: JsonValue): HttpResponseFor = + fun extract(id: String): HttpResponseFor = extract(id, SessionExtractParams.none()) /** @see extract */ @MustBeClosed fun extract( - id: JsonValue, + id: String, params: SessionExtractParams = SessionExtractParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor = @@ -401,7 +333,7 @@ interface SessionService { /** @see extract */ @MustBeClosed fun extract( - id: JsonValue, + id: String, params: SessionExtractParams = SessionExtractParams.none(), ): HttpResponseFor = extract(id, params, RequestOptions.none()) @@ -420,41 +352,29 @@ interface SessionService { /** @see extract */ @MustBeClosed fun extract( - id: JsonValue, + id: String, requestOptions: RequestOptions, ): HttpResponseFor = extract(id, SessionExtractParams.none(), requestOptions) /** - * Returns a raw HTTP response for `post /sessions/{id}/navigate`, but is otherwise the same - * as [SessionService.navigate]. + * Returns a raw HTTP response for `post /v1/sessions/{id}/navigate`, but is otherwise the + * same as [SessionService.navigate]. */ @MustBeClosed - fun navigate(id: JsonValue): HttpResponseFor = - navigate(id, SessionNavigateParams.none()) - - /** @see navigate */ - @MustBeClosed fun navigate( - id: JsonValue, - params: SessionNavigateParams = SessionNavigateParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor = - navigate(params.toBuilder().id(id).build(), requestOptions) - - /** @see navigate */ - @MustBeClosed - fun navigate( - id: JsonValue, - params: SessionNavigateParams = SessionNavigateParams.none(), + id: String, + params: SessionNavigateParams, ): HttpResponseFor = navigate(id, params, RequestOptions.none()) /** @see navigate */ @MustBeClosed fun navigate( + id: String, params: SessionNavigateParams, requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor + ): HttpResponseFor = + navigate(params.toBuilder().id(id).build(), requestOptions) /** @see navigate */ @MustBeClosed @@ -464,23 +384,22 @@ interface SessionService { /** @see navigate */ @MustBeClosed fun navigate( - id: JsonValue, - requestOptions: RequestOptions, - ): HttpResponseFor = - navigate(id, SessionNavigateParams.none(), requestOptions) + params: SessionNavigateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor /** - * Returns a raw HTTP response for `post /sessions/{id}/observe`, but is otherwise the same - * as [SessionService.observe]. + * Returns a raw HTTP response for `post /v1/sessions/{id}/observe`, but is otherwise the + * same as [SessionService.observe]. */ @MustBeClosed - fun observe(id: JsonValue): HttpResponseFor = + fun observe(id: String): HttpResponseFor = observe(id, SessionObserveParams.none()) /** @see observe */ @MustBeClosed fun observe( - id: JsonValue, + id: String, params: SessionObserveParams = SessionObserveParams.none(), requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor = @@ -489,7 +408,7 @@ interface SessionService { /** @see observe */ @MustBeClosed fun observe( - id: JsonValue, + id: String, params: SessionObserveParams = SessionObserveParams.none(), ): HttpResponseFor = observe(id, params, RequestOptions.none()) @@ -508,34 +427,24 @@ interface SessionService { /** @see observe */ @MustBeClosed fun observe( - id: JsonValue, + id: String, requestOptions: RequestOptions, ): HttpResponseFor = observe(id, SessionObserveParams.none(), requestOptions) /** - * Returns a raw HTTP response for `post /sessions/start`, but is otherwise the same as + * Returns a raw HTTP response for `post /v1/sessions/start`, but is otherwise the same as * [SessionService.start]. */ @MustBeClosed - fun start(): HttpResponseFor = start(SessionStartParams.none()) + fun start(params: SessionStartParams): HttpResponseFor = + start(params, RequestOptions.none()) /** @see start */ @MustBeClosed fun start( - params: SessionStartParams = SessionStartParams.none(), + params: SessionStartParams, requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor - - /** @see start */ - @MustBeClosed - fun start( - params: SessionStartParams = SessionStartParams.none() - ): HttpResponseFor = start(params, RequestOptions.none()) - - /** @see start */ - @MustBeClosed - fun start(requestOptions: RequestOptions): HttpResponseFor = - start(SessionStartParams.none(), requestOptions) } } diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionServiceImpl.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionServiceImpl.kt index 467e9db..aac8272 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionServiceImpl.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionServiceImpl.kt @@ -4,6 +4,7 @@ package com.browserbase.api.services.blocking import com.browserbase.api.core.ClientOptions import com.browserbase.api.core.RequestOptions +import com.browserbase.api.core.checkRequired import com.browserbase.api.core.handlers.errorBodyHandler import com.browserbase.api.core.handlers.errorHandler import com.browserbase.api.core.handlers.jsonHandler @@ -19,8 +20,8 @@ import com.browserbase.api.models.sessions.SessionActParams import com.browserbase.api.models.sessions.SessionActResponse import com.browserbase.api.models.sessions.SessionEndParams import com.browserbase.api.models.sessions.SessionEndResponse -import com.browserbase.api.models.sessions.SessionExecuteAgentParams -import com.browserbase.api.models.sessions.SessionExecuteAgentResponse +import com.browserbase.api.models.sessions.SessionExecuteParams +import com.browserbase.api.models.sessions.SessionExecuteResponse import com.browserbase.api.models.sessions.SessionExtractParams import com.browserbase.api.models.sessions.SessionExtractResponse import com.browserbase.api.models.sessions.SessionNavigateParams @@ -30,6 +31,7 @@ import com.browserbase.api.models.sessions.SessionObserveResponse import com.browserbase.api.models.sessions.SessionStartParams import com.browserbase.api.models.sessions.SessionStartResponse import java.util.function.Consumer +import kotlin.jvm.optionals.getOrNull class SessionServiceImpl internal constructor(private val clientOptions: ClientOptions) : SessionService { @@ -44,46 +46,46 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO SessionServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) override fun act(params: SessionActParams, requestOptions: RequestOptions): SessionActResponse = - // post /sessions/{id}/act + // post /v1/sessions/{id}/act withRawResponse().act(params, requestOptions).parse() override fun end(params: SessionEndParams, requestOptions: RequestOptions): SessionEndResponse = - // post /sessions/{id}/end + // post /v1/sessions/{id}/end withRawResponse().end(params, requestOptions).parse() - override fun executeAgent( - params: SessionExecuteAgentParams, + override fun execute( + params: SessionExecuteParams, requestOptions: RequestOptions, - ): SessionExecuteAgentResponse = - // post /sessions/{id}/agentExecute - withRawResponse().executeAgent(params, requestOptions).parse() + ): SessionExecuteResponse = + // post /v1/sessions/{id}/agentExecute + withRawResponse().execute(params, requestOptions).parse() override fun extract( params: SessionExtractParams, requestOptions: RequestOptions, ): SessionExtractResponse = - // post /sessions/{id}/extract + // post /v1/sessions/{id}/extract withRawResponse().extract(params, requestOptions).parse() override fun navigate( params: SessionNavigateParams, requestOptions: RequestOptions, ): SessionNavigateResponse = - // post /sessions/{id}/navigate + // post /v1/sessions/{id}/navigate withRawResponse().navigate(params, requestOptions).parse() override fun observe( params: SessionObserveParams, requestOptions: RequestOptions, ): SessionObserveResponse = - // post /sessions/{id}/observe + // post /v1/sessions/{id}/observe withRawResponse().observe(params, requestOptions).parse() override fun start( params: SessionStartParams, requestOptions: RequestOptions, ): SessionStartResponse = - // post /sessions/start + // post /v1/sessions/start withRawResponse().start(params, requestOptions).parse() class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : @@ -106,11 +108,14 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO params: SessionActParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "act") + .addPathSegments("v1", "sessions", params._pathParam(0), "act") .body(json(clientOptions.jsonMapper, params._body())) .build() .prepare(clientOptions, params) @@ -134,11 +139,14 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO params: SessionEndParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "end") + .addPathSegments("v1", "sessions", params._pathParam(0), "end") .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } .build() .prepare(clientOptions, params) @@ -155,18 +163,21 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO } } - private val executeAgentHandler: Handler = - jsonHandler(clientOptions.jsonMapper) + private val executeHandler: Handler = + jsonHandler(clientOptions.jsonMapper) - override fun executeAgent( - params: SessionExecuteAgentParams, + override fun execute( + params: SessionExecuteParams, requestOptions: RequestOptions, - ): HttpResponseFor { + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "agentExecute") + .addPathSegments("v1", "sessions", params._pathParam(0), "agentExecute") .body(json(clientOptions.jsonMapper, params._body())) .build() .prepare(clientOptions, params) @@ -174,7 +185,7 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO val response = clientOptions.httpClient.execute(request, requestOptions) return errorHandler.handle(response).parseable { response - .use { executeAgentHandler.handle(it) } + .use { executeHandler.handle(it) } .also { if (requestOptions.responseValidation!!) { it.validate() @@ -190,11 +201,14 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO params: SessionExtractParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "extract") + .addPathSegments("v1", "sessions", params._pathParam(0), "extract") .body(json(clientOptions.jsonMapper, params._body())) .build() .prepare(clientOptions, params) @@ -218,11 +232,14 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO params: SessionNavigateParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "navigate") + .addPathSegments("v1", "sessions", params._pathParam(0), "navigate") .body(json(clientOptions.jsonMapper, params._body())) .build() .prepare(clientOptions, params) @@ -246,11 +263,14 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO params: SessionObserveParams, requestOptions: RequestOptions, ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) val request = HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", params._pathParam(0), "observe") + .addPathSegments("v1", "sessions", params._pathParam(0), "observe") .body(json(clientOptions.jsonMapper, params._body())) .build() .prepare(clientOptions, params) @@ -278,7 +298,7 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO HttpRequest.builder() .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) - .addPathSegments("sessions", "start") + .addPathSegments("v1", "sessions", "start") .body(json(clientOptions.jsonMapper, params._body())) .build() .prepare(clientOptions, params) diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt index 4b81e39..c31444c 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt @@ -4,6 +4,7 @@ package com.browserbase.api.models.sessions import com.browserbase.api.core.JsonValue import com.browserbase.api.core.http.Headers +import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -12,20 +13,36 @@ internal class SessionActParamsTest { @Test fun create() { SessionActParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty("username", JsonValue.from("john_doe")) + .build() + ) + .build() + ) .build() } @Test fun pathParams() { - val params = SessionActParams.builder().id(JsonValue.from(mapOf())).build() + val params = + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .input("Click the login button") + .build() - assertThat(params._pathParam(0)).isEqualTo("[object Object]") + assertThat(params._pathParam(0)).isEqualTo("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") // out-of-bound path param assertThat(params._pathParam(1)).isEqualTo("") } @@ -34,22 +51,46 @@ internal class SessionActParamsTest { fun headers() { val params = SessionActParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty("username", JsonValue.from("john_doe")) + .build() + ) + .build() + ) .build() val headers = params._headers() - assertThat(headers).isEqualTo(Headers.builder().build()) + assertThat(headers) + .isEqualTo( + Headers.builder() + .put("x-language", "typescript") + .put("x-sdk-version", "3.0.6") + .put("x-sent-at", "2025-01-15T10:30:00.000Z") + .put("x-stream-response", "true") + .build() + ) } @Test fun headersWithoutOptionalFields() { - val params = SessionActParams.builder().id(JsonValue.from(mapOf())).build() + val params = + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .input("Click the login button") + .build() val headers = params._headers() @@ -60,23 +101,56 @@ internal class SessionActParamsTest { fun body() { val params = SessionActParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty("username", JsonValue.from("john_doe")) + .build() + ) + .build() + ) .build() val body = params._body() - assertThat(body).isEqualTo(JsonValue.from(mapOf())) + assertThat(body.input()) + .isEqualTo(SessionActParams.Input.ofString("Click the login button")) + assertThat(body.frameId()).contains("frameId") + assertThat(body.options()) + .contains( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty("username", JsonValue.from("john_doe")) + .build() + ) + .build() + ) } @Test fun bodyWithoutOptionalFields() { - val params = SessionActParams.builder().id(JsonValue.from(mapOf())).build() + val params = + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .input("Click the login button") + .build() val body = params._body() + + assertThat(body.input()) + .isEqualTo(SessionActParams.Input.ofString("Click the login button")) } } diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActResponseTest.kt index 83f3fa4..000d7fd 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActResponseTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActResponseTest.kt @@ -11,13 +11,82 @@ internal class SessionActResponseTest { @Test fun create() { - val sessionActResponse = SessionActResponse.builder().build() + val sessionActResponse = + SessionActResponse.builder() + .data( + SessionActResponse.Data.builder() + .result( + SessionActResponse.Data.Result.builder() + .actionDescription("Clicked button with text 'Login'") + .addAction( + Action.builder() + .description("Click the submit button") + .selector("[data-testid='submit-button']") + .addArgument("Hello World") + .method("click") + .build() + ) + .message("Successfully clicked the login button") + .success(true) + .build() + ) + .actionId("actionId") + .build() + ) + .success(SessionActResponse.Success.TRUE) + .build() + + assertThat(sessionActResponse.data()) + .isEqualTo( + SessionActResponse.Data.builder() + .result( + SessionActResponse.Data.Result.builder() + .actionDescription("Clicked button with text 'Login'") + .addAction( + Action.builder() + .description("Click the submit button") + .selector("[data-testid='submit-button']") + .addArgument("Hello World") + .method("click") + .build() + ) + .message("Successfully clicked the login button") + .success(true) + .build() + ) + .actionId("actionId") + .build() + ) + assertThat(sessionActResponse.success()).isEqualTo(SessionActResponse.Success.TRUE) } @Test fun roundtrip() { val jsonMapper = jsonMapper() - val sessionActResponse = SessionActResponse.builder().build() + val sessionActResponse = + SessionActResponse.builder() + .data( + SessionActResponse.Data.builder() + .result( + SessionActResponse.Data.Result.builder() + .actionDescription("Clicked button with text 'Login'") + .addAction( + Action.builder() + .description("Click the submit button") + .selector("[data-testid='submit-button']") + .addArgument("Hello World") + .method("click") + .build() + ) + .message("Successfully clicked the login button") + .success(true) + .build() + ) + .actionId("actionId") + .build() + ) + .success(SessionActResponse.Success.TRUE) + .build() val roundtrippedSessionActResponse = jsonMapper.readValue( diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndParamsTest.kt index 514fc5e..14faac3 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndParamsTest.kt @@ -2,8 +2,8 @@ package com.browserbase.api.models.sessions -import com.browserbase.api.core.JsonValue import com.browserbase.api.core.http.Headers +import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -12,19 +12,19 @@ internal class SessionEndParamsTest { @Test fun create() { SessionEndParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionEndParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionEndParams.XStreamResponse.TRUE) .build() } @Test fun pathParams() { - val params = SessionEndParams.builder().id(JsonValue.from(mapOf())).build() + val params = SessionEndParams.builder().id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123").build() - assertThat(params._pathParam(0)).isEqualTo("[object Object]") + assertThat(params._pathParam(0)).isEqualTo("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") // out-of-bound path param assertThat(params._pathParam(1)).isEqualTo("") } @@ -33,21 +33,29 @@ internal class SessionEndParamsTest { fun headers() { val params = SessionEndParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionEndParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionEndParams.XStreamResponse.TRUE) .build() val headers = params._headers() - assertThat(headers).isEqualTo(Headers.builder().build()) + assertThat(headers) + .isEqualTo( + Headers.builder() + .put("x-language", "typescript") + .put("x-sdk-version", "3.0.6") + .put("x-sent-at", "2025-01-15T10:30:00.000Z") + .put("x-stream-response", "true") + .build() + ) } @Test fun headersWithoutOptionalFields() { - val params = SessionEndParams.builder().id(JsonValue.from(mapOf())).build() + val params = SessionEndParams.builder().id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123").build() val headers = params._headers() diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt index 30e45db..27a2a36 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt @@ -11,13 +11,17 @@ internal class SessionEndResponseTest { @Test fun create() { - val sessionEndResponse = SessionEndResponse.builder().build() + val sessionEndResponse = + SessionEndResponse.builder().success(SessionEndResponse.Success.TRUE).build() + + assertThat(sessionEndResponse.success()).isEqualTo(SessionEndResponse.Success.TRUE) } @Test fun roundtrip() { val jsonMapper = jsonMapper() - val sessionEndResponse = SessionEndResponse.builder().build() + val sessionEndResponse = + SessionEndResponse.builder().success(SessionEndResponse.Success.TRUE).build() val roundtrippedSessionEndResponse = jsonMapper.readValue( diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParamsTest.kt deleted file mode 100644 index 90f1e1f..0000000 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentParamsTest.kt +++ /dev/null @@ -1,85 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.JsonValue -import com.browserbase.api.core.http.Headers -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class SessionExecuteAgentParamsTest { - - @Test - fun create() { - SessionExecuteAgentParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) - .build() - } - - @Test - fun pathParams() { - val params = - SessionExecuteAgentParams.builder().id(JsonValue.from(mapOf())).build() - - assertThat(params._pathParam(0)).isEqualTo("[object Object]") - // out-of-bound path param - assertThat(params._pathParam(1)).isEqualTo("") - } - - @Test - fun headers() { - val params = - SessionExecuteAgentParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) - .build() - - val headers = params._headers() - - assertThat(headers).isEqualTo(Headers.builder().build()) - } - - @Test - fun headersWithoutOptionalFields() { - val params = - SessionExecuteAgentParams.builder().id(JsonValue.from(mapOf())).build() - - val headers = params._headers() - - assertThat(headers).isEqualTo(Headers.builder().build()) - } - - @Test - fun body() { - val params = - SessionExecuteAgentParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) - .build() - - val body = params._body() - - assertThat(body).isEqualTo(JsonValue.from(mapOf())) - } - - @Test - fun bodyWithoutOptionalFields() { - val params = - SessionExecuteAgentParams.builder().id(JsonValue.from(mapOf())).build() - - val body = params._body() - } -} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponseTest.kt deleted file mode 100644 index 0c28d46..0000000 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteAgentResponseTest.kt +++ /dev/null @@ -1,30 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.browserbase.api.models.sessions - -import com.browserbase.api.core.jsonMapper -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class SessionExecuteAgentResponseTest { - - @Test - fun create() { - val sessionExecuteAgentResponse = SessionExecuteAgentResponse.builder().build() - } - - @Test - fun roundtrip() { - val jsonMapper = jsonMapper() - val sessionExecuteAgentResponse = SessionExecuteAgentResponse.builder().build() - - val roundtrippedSessionExecuteAgentResponse = - jsonMapper.readValue( - jsonMapper.writeValueAsString(sessionExecuteAgentResponse), - jacksonTypeRef(), - ) - - assertThat(roundtrippedSessionExecuteAgentResponse).isEqualTo(sessionExecuteAgentResponse) - } -} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteParamsTest.kt new file mode 100644 index 0000000..b40f381 --- /dev/null +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteParamsTest.kt @@ -0,0 +1,199 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.http.Headers +import java.time.OffsetDateTime +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SessionExecuteParamsTest { + + @Test + fun create() { + SessionExecuteParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionExecuteParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionExecuteParams.XStreamResponse.TRUE) + .agentConfig( + SessionExecuteParams.AgentConfig.builder() + .cua(true) + .model("string") + .systemPrompt("systemPrompt") + .build() + ) + .executeOptions( + SessionExecuteParams.ExecuteOptions.builder() + .instruction( + "Log in with username 'demo' and password 'test123', then navigate to settings" + ) + .highlightCursor(true) + .maxSteps(20.0) + .build() + ) + .frameId("frameId") + .build() + } + + @Test + fun pathParams() { + val params = + SessionExecuteParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .agentConfig(SessionExecuteParams.AgentConfig.builder().build()) + .executeOptions( + SessionExecuteParams.ExecuteOptions.builder() + .instruction( + "Log in with username 'demo' and password 'test123', then navigate to settings" + ) + .build() + ) + .build() + + assertThat(params._pathParam(0)).isEqualTo("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun headers() { + val params = + SessionExecuteParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionExecuteParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionExecuteParams.XStreamResponse.TRUE) + .agentConfig( + SessionExecuteParams.AgentConfig.builder() + .cua(true) + .model("string") + .systemPrompt("systemPrompt") + .build() + ) + .executeOptions( + SessionExecuteParams.ExecuteOptions.builder() + .instruction( + "Log in with username 'demo' and password 'test123', then navigate to settings" + ) + .highlightCursor(true) + .maxSteps(20.0) + .build() + ) + .frameId("frameId") + .build() + + val headers = params._headers() + + assertThat(headers) + .isEqualTo( + Headers.builder() + .put("x-language", "typescript") + .put("x-sdk-version", "3.0.6") + .put("x-sent-at", "2025-01-15T10:30:00.000Z") + .put("x-stream-response", "true") + .build() + ) + } + + @Test + fun headersWithoutOptionalFields() { + val params = + SessionExecuteParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .agentConfig(SessionExecuteParams.AgentConfig.builder().build()) + .executeOptions( + SessionExecuteParams.ExecuteOptions.builder() + .instruction( + "Log in with username 'demo' and password 'test123', then navigate to settings" + ) + .build() + ) + .build() + + val headers = params._headers() + + assertThat(headers).isEqualTo(Headers.builder().build()) + } + + @Test + fun body() { + val params = + SessionExecuteParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionExecuteParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionExecuteParams.XStreamResponse.TRUE) + .agentConfig( + SessionExecuteParams.AgentConfig.builder() + .cua(true) + .model("string") + .systemPrompt("systemPrompt") + .build() + ) + .executeOptions( + SessionExecuteParams.ExecuteOptions.builder() + .instruction( + "Log in with username 'demo' and password 'test123', then navigate to settings" + ) + .highlightCursor(true) + .maxSteps(20.0) + .build() + ) + .frameId("frameId") + .build() + + val body = params._body() + + assertThat(body.agentConfig()) + .isEqualTo( + SessionExecuteParams.AgentConfig.builder() + .cua(true) + .model("string") + .systemPrompt("systemPrompt") + .build() + ) + assertThat(body.executeOptions()) + .isEqualTo( + SessionExecuteParams.ExecuteOptions.builder() + .instruction( + "Log in with username 'demo' and password 'test123', then navigate to settings" + ) + .highlightCursor(true) + .maxSteps(20.0) + .build() + ) + assertThat(body.frameId()).contains("frameId") + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + SessionExecuteParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .agentConfig(SessionExecuteParams.AgentConfig.builder().build()) + .executeOptions( + SessionExecuteParams.ExecuteOptions.builder() + .instruction( + "Log in with username 'demo' and password 'test123', then navigate to settings" + ) + .build() + ) + .build() + + val body = params._body() + + assertThat(body.agentConfig()).isEqualTo(SessionExecuteParams.AgentConfig.builder().build()) + assertThat(body.executeOptions()) + .isEqualTo( + SessionExecuteParams.ExecuteOptions.builder() + .instruction( + "Log in with username 'demo' and password 'test123', then navigate to settings" + ) + .build() + ) + } +} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteResponseTest.kt new file mode 100644 index 0000000..d2fb4d9 --- /dev/null +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteResponseTest.kt @@ -0,0 +1,151 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SessionExecuteResponseTest { + + @Test + fun create() { + val sessionExecuteResponse = + SessionExecuteResponse.builder() + .data( + SessionExecuteResponse.Data.builder() + .result( + SessionExecuteResponse.Data.Result.builder() + .addAction( + SessionExecuteResponse.Data.Result.Action.builder() + .type("click") + .action("action") + .instruction("instruction") + .pageText("pageText") + .pageUrl("pageUrl") + .reasoning("reasoning") + .taskCompleted(true) + .timeMs(0.0) + .build() + ) + .completed(true) + .message("Successfully logged in and navigated to dashboard") + .success(true) + .metadata( + SessionExecuteResponse.Data.Result.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .usage( + SessionExecuteResponse.Data.Result.Usage.builder() + .inferenceTimeMs(2500.0) + .inputTokens(1500.0) + .outputTokens(250.0) + .cachedInputTokens(0.0) + .reasoningTokens(0.0) + .build() + ) + .build() + ) + .build() + ) + .success(SessionExecuteResponse.Success.TRUE) + .build() + + assertThat(sessionExecuteResponse.data()) + .isEqualTo( + SessionExecuteResponse.Data.builder() + .result( + SessionExecuteResponse.Data.Result.builder() + .addAction( + SessionExecuteResponse.Data.Result.Action.builder() + .type("click") + .action("action") + .instruction("instruction") + .pageText("pageText") + .pageUrl("pageUrl") + .reasoning("reasoning") + .taskCompleted(true) + .timeMs(0.0) + .build() + ) + .completed(true) + .message("Successfully logged in and navigated to dashboard") + .success(true) + .metadata( + SessionExecuteResponse.Data.Result.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .usage( + SessionExecuteResponse.Data.Result.Usage.builder() + .inferenceTimeMs(2500.0) + .inputTokens(1500.0) + .outputTokens(250.0) + .cachedInputTokens(0.0) + .reasoningTokens(0.0) + .build() + ) + .build() + ) + .build() + ) + assertThat(sessionExecuteResponse.success()).isEqualTo(SessionExecuteResponse.Success.TRUE) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val sessionExecuteResponse = + SessionExecuteResponse.builder() + .data( + SessionExecuteResponse.Data.builder() + .result( + SessionExecuteResponse.Data.Result.builder() + .addAction( + SessionExecuteResponse.Data.Result.Action.builder() + .type("click") + .action("action") + .instruction("instruction") + .pageText("pageText") + .pageUrl("pageUrl") + .reasoning("reasoning") + .taskCompleted(true) + .timeMs(0.0) + .build() + ) + .completed(true) + .message("Successfully logged in and navigated to dashboard") + .success(true) + .metadata( + SessionExecuteResponse.Data.Result.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .usage( + SessionExecuteResponse.Data.Result.Usage.builder() + .inferenceTimeMs(2500.0) + .inputTokens(1500.0) + .outputTokens(250.0) + .cachedInputTokens(0.0) + .reasoningTokens(0.0) + .build() + ) + .build() + ) + .build() + ) + .success(SessionExecuteResponse.Success.TRUE) + .build() + + val roundtrippedSessionExecuteResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(sessionExecuteResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedSessionExecuteResponse).isEqualTo(sessionExecuteResponse) + } +} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt index e631276..4a3c252 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt @@ -4,6 +4,7 @@ package com.browserbase.api.models.sessions import com.browserbase.api.core.JsonValue import com.browserbase.api.core.http.Headers +import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -12,20 +13,34 @@ internal class SessionExtractParamsTest { @Test fun create() { SessionExtractParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionExtractParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionExtractParams.XStreamResponse.TRUE) + .frameId("frameId") + .instruction("Extract all product names and prices from the page") + .options( + SessionExtractParams.Options.builder() + .model("string") + .selector("#main-content") + .timeout(30000.0) + .build() + ) + .schema( + SessionExtractParams.Schema.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .build() } @Test fun pathParams() { - val params = SessionExtractParams.builder().id(JsonValue.from(mapOf())).build() + val params = + SessionExtractParams.builder().id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123").build() - assertThat(params._pathParam(0)).isEqualTo("[object Object]") + assertThat(params._pathParam(0)).isEqualTo("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") // out-of-bound path param assertThat(params._pathParam(1)).isEqualTo("") } @@ -34,22 +49,44 @@ internal class SessionExtractParamsTest { fun headers() { val params = SessionExtractParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionExtractParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionExtractParams.XStreamResponse.TRUE) + .frameId("frameId") + .instruction("Extract all product names and prices from the page") + .options( + SessionExtractParams.Options.builder() + .model("string") + .selector("#main-content") + .timeout(30000.0) + .build() + ) + .schema( + SessionExtractParams.Schema.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .build() val headers = params._headers() - assertThat(headers).isEqualTo(Headers.builder().build()) + assertThat(headers) + .isEqualTo( + Headers.builder() + .put("x-language", "typescript") + .put("x-sdk-version", "3.0.6") + .put("x-sent-at", "2025-01-15T10:30:00.000Z") + .put("x-stream-response", "true") + .build() + ) } @Test fun headersWithoutOptionalFields() { - val params = SessionExtractParams.builder().id(JsonValue.from(mapOf())).build() + val params = + SessionExtractParams.builder().id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123").build() val headers = params._headers() @@ -60,22 +97,52 @@ internal class SessionExtractParamsTest { fun body() { val params = SessionExtractParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionExtractParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionExtractParams.XStreamResponse.TRUE) + .frameId("frameId") + .instruction("Extract all product names and prices from the page") + .options( + SessionExtractParams.Options.builder() + .model("string") + .selector("#main-content") + .timeout(30000.0) + .build() + ) + .schema( + SessionExtractParams.Schema.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .build() val body = params._body() - assertThat(body).isEqualTo(JsonValue.from(mapOf())) + assertThat(body.frameId()).contains("frameId") + assertThat(body.instruction()) + .contains("Extract all product names and prices from the page") + assertThat(body.options()) + .contains( + SessionExtractParams.Options.builder() + .model("string") + .selector("#main-content") + .timeout(30000.0) + .build() + ) + assertThat(body.schema()) + .contains( + SessionExtractParams.Schema.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) } @Test fun bodyWithoutOptionalFields() { - val params = SessionExtractParams.builder().id(JsonValue.from(mapOf())).build() + val params = + SessionExtractParams.builder().id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123").build() val body = params._body() } diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractResponseTest.kt index 04bed64..6cf7056 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractResponseTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractResponseTest.kt @@ -2,6 +2,7 @@ package com.browserbase.api.models.sessions +import com.browserbase.api.core.JsonValue import com.browserbase.api.core.jsonMapper import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import org.assertj.core.api.Assertions.assertThat @@ -11,13 +12,40 @@ internal class SessionExtractResponseTest { @Test fun create() { - val sessionExtractResponse = SessionExtractResponse.builder().build() + val sessionExtractResponse = + SessionExtractResponse.builder() + .data( + SessionExtractResponse.Data.builder() + .result(JsonValue.from(mapOf())) + .actionId("actionId") + .build() + ) + .success(SessionExtractResponse.Success.TRUE) + .build() + + assertThat(sessionExtractResponse.data()) + .isEqualTo( + SessionExtractResponse.Data.builder() + .result(JsonValue.from(mapOf())) + .actionId("actionId") + .build() + ) + assertThat(sessionExtractResponse.success()).isEqualTo(SessionExtractResponse.Success.TRUE) } @Test fun roundtrip() { val jsonMapper = jsonMapper() - val sessionExtractResponse = SessionExtractResponse.builder().build() + val sessionExtractResponse = + SessionExtractResponse.builder() + .data( + SessionExtractResponse.Data.builder() + .result(JsonValue.from(mapOf())) + .actionId("actionId") + .build() + ) + .success(SessionExtractResponse.Success.TRUE) + .build() val roundtrippedSessionExtractResponse = jsonMapper.readValue( diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt index 6d8a60d..aa845c3 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt @@ -2,8 +2,8 @@ package com.browserbase.api.models.sessions -import com.browserbase.api.core.JsonValue import com.browserbase.api.core.http.Headers +import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -12,21 +12,32 @@ internal class SessionNavigateParamsTest { @Test fun create() { SessionNavigateParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionNavigateParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionNavigateParams.XStreamResponse.TRUE) + .url("https://example.com") + .frameId("frameId") + .options( + SessionNavigateParams.Options.builder() + .referer("referer") + .timeout(30000.0) + .waitUntil(SessionNavigateParams.Options.WaitUntil.NETWORKIDLE) + .build() + ) .build() } @Test fun pathParams() { val params = - SessionNavigateParams.builder().id(JsonValue.from(mapOf())).build() + SessionNavigateParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .url("https://example.com") + .build() - assertThat(params._pathParam(0)).isEqualTo("[object Object]") + assertThat(params._pathParam(0)).isEqualTo("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") // out-of-bound path param assertThat(params._pathParam(1)).isEqualTo("") } @@ -35,23 +46,42 @@ internal class SessionNavigateParamsTest { fun headers() { val params = SessionNavigateParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionNavigateParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionNavigateParams.XStreamResponse.TRUE) + .url("https://example.com") + .frameId("frameId") + .options( + SessionNavigateParams.Options.builder() + .referer("referer") + .timeout(30000.0) + .waitUntil(SessionNavigateParams.Options.WaitUntil.NETWORKIDLE) + .build() + ) .build() val headers = params._headers() - assertThat(headers).isEqualTo(Headers.builder().build()) + assertThat(headers) + .isEqualTo( + Headers.builder() + .put("x-language", "typescript") + .put("x-sdk-version", "3.0.6") + .put("x-sent-at", "2025-01-15T10:30:00.000Z") + .put("x-stream-response", "true") + .build() + ) } @Test fun headersWithoutOptionalFields() { val params = - SessionNavigateParams.builder().id(JsonValue.from(mapOf())).build() + SessionNavigateParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .url("https://example.com") + .build() val headers = params._headers() @@ -62,24 +92,46 @@ internal class SessionNavigateParamsTest { fun body() { val params = SessionNavigateParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionNavigateParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionNavigateParams.XStreamResponse.TRUE) + .url("https://example.com") + .frameId("frameId") + .options( + SessionNavigateParams.Options.builder() + .referer("referer") + .timeout(30000.0) + .waitUntil(SessionNavigateParams.Options.WaitUntil.NETWORKIDLE) + .build() + ) .build() val body = params._body() - assertThat(body).isEqualTo(JsonValue.from(mapOf())) + assertThat(body.url()).isEqualTo("https://example.com") + assertThat(body.frameId()).contains("frameId") + assertThat(body.options()) + .contains( + SessionNavigateParams.Options.builder() + .referer("referer") + .timeout(30000.0) + .waitUntil(SessionNavigateParams.Options.WaitUntil.NETWORKIDLE) + .build() + ) } @Test fun bodyWithoutOptionalFields() { val params = - SessionNavigateParams.builder().id(JsonValue.from(mapOf())).build() + SessionNavigateParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .url("https://example.com") + .build() val body = params._body() + + assertThat(body.url()).isEqualTo("https://example.com") } } diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponseTest.kt index 6d62909..e02a0e3 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponseTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponseTest.kt @@ -2,6 +2,7 @@ package com.browserbase.api.models.sessions +import com.browserbase.api.core.JsonValue import com.browserbase.api.core.jsonMapper import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import org.assertj.core.api.Assertions.assertThat @@ -11,13 +12,41 @@ internal class SessionNavigateResponseTest { @Test fun create() { - val sessionNavigateResponse = SessionNavigateResponse.builder().build() + val sessionNavigateResponse = + SessionNavigateResponse.builder() + .data( + SessionNavigateResponse.Data.builder() + .result(JsonValue.from(mapOf())) + .actionId("actionId") + .build() + ) + .success(SessionNavigateResponse.Success.TRUE) + .build() + + assertThat(sessionNavigateResponse.data()) + .isEqualTo( + SessionNavigateResponse.Data.builder() + .result(JsonValue.from(mapOf())) + .actionId("actionId") + .build() + ) + assertThat(sessionNavigateResponse.success()) + .isEqualTo(SessionNavigateResponse.Success.TRUE) } @Test fun roundtrip() { val jsonMapper = jsonMapper() - val sessionNavigateResponse = SessionNavigateResponse.builder().build() + val sessionNavigateResponse = + SessionNavigateResponse.builder() + .data( + SessionNavigateResponse.Data.builder() + .result(JsonValue.from(mapOf())) + .actionId("actionId") + .build() + ) + .success(SessionNavigateResponse.Success.TRUE) + .build() val roundtrippedSessionNavigateResponse = jsonMapper.readValue( diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt index 8943f1d..95ccd9b 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt @@ -2,8 +2,8 @@ package com.browserbase.api.models.sessions -import com.browserbase.api.core.JsonValue import com.browserbase.api.core.http.Headers +import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -12,20 +12,29 @@ internal class SessionObserveParamsTest { @Test fun create() { SessionObserveParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionObserveParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionObserveParams.XStreamResponse.TRUE) + .frameId("frameId") + .instruction("Find all clickable navigation links") + .options( + SessionObserveParams.Options.builder() + .model("string") + .selector("nav") + .timeout(30000.0) + .build() + ) .build() } @Test fun pathParams() { - val params = SessionObserveParams.builder().id(JsonValue.from(mapOf())).build() + val params = + SessionObserveParams.builder().id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123").build() - assertThat(params._pathParam(0)).isEqualTo("[object Object]") + assertThat(params._pathParam(0)).isEqualTo("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") // out-of-bound path param assertThat(params._pathParam(1)).isEqualTo("") } @@ -34,22 +43,39 @@ internal class SessionObserveParamsTest { fun headers() { val params = SessionObserveParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionObserveParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionObserveParams.XStreamResponse.TRUE) + .frameId("frameId") + .instruction("Find all clickable navigation links") + .options( + SessionObserveParams.Options.builder() + .model("string") + .selector("nav") + .timeout(30000.0) + .build() + ) .build() val headers = params._headers() - assertThat(headers).isEqualTo(Headers.builder().build()) + assertThat(headers) + .isEqualTo( + Headers.builder() + .put("x-language", "typescript") + .put("x-sdk-version", "3.0.6") + .put("x-sent-at", "2025-01-15T10:30:00.000Z") + .put("x-stream-response", "true") + .build() + ) } @Test fun headersWithoutOptionalFields() { - val params = SessionObserveParams.builder().id(JsonValue.from(mapOf())).build() + val params = + SessionObserveParams.builder().id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123").build() val headers = params._headers() @@ -60,22 +86,40 @@ internal class SessionObserveParamsTest { fun body() { val params = SessionObserveParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionObserveParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionObserveParams.XStreamResponse.TRUE) + .frameId("frameId") + .instruction("Find all clickable navigation links") + .options( + SessionObserveParams.Options.builder() + .model("string") + .selector("nav") + .timeout(30000.0) + .build() + ) .build() val body = params._body() - assertThat(body).isEqualTo(JsonValue.from(mapOf())) + assertThat(body.frameId()).contains("frameId") + assertThat(body.instruction()).contains("Find all clickable navigation links") + assertThat(body.options()) + .contains( + SessionObserveParams.Options.builder() + .model("string") + .selector("nav") + .timeout(30000.0) + .build() + ) } @Test fun bodyWithoutOptionalFields() { - val params = SessionObserveParams.builder().id(JsonValue.from(mapOf())).build() + val params = + SessionObserveParams.builder().id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123").build() val body = params._body() } diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveResponseTest.kt index b597689..e3d72c3 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveResponseTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveResponseTest.kt @@ -11,13 +11,61 @@ internal class SessionObserveResponseTest { @Test fun create() { - val sessionObserveResponse = SessionObserveResponse.builder().build() + val sessionObserveResponse = + SessionObserveResponse.builder() + .data( + SessionObserveResponse.Data.builder() + .addResult( + Action.builder() + .description("Click the submit button") + .selector("[data-testid='submit-button']") + .addArgument("Hello World") + .method("click") + .build() + ) + .actionId("actionId") + .build() + ) + .success(SessionObserveResponse.Success.TRUE) + .build() + + assertThat(sessionObserveResponse.data()) + .isEqualTo( + SessionObserveResponse.Data.builder() + .addResult( + Action.builder() + .description("Click the submit button") + .selector("[data-testid='submit-button']") + .addArgument("Hello World") + .method("click") + .build() + ) + .actionId("actionId") + .build() + ) + assertThat(sessionObserveResponse.success()).isEqualTo(SessionObserveResponse.Success.TRUE) } @Test fun roundtrip() { val jsonMapper = jsonMapper() - val sessionObserveResponse = SessionObserveResponse.builder().build() + val sessionObserveResponse = + SessionObserveResponse.builder() + .data( + SessionObserveResponse.Data.builder() + .addResult( + Action.builder() + .description("Click the submit button") + .selector("[data-testid='submit-button']") + .addArgument("Hello World") + .method("click") + .build() + ) + .actionId("actionId") + .build() + ) + .success(SessionObserveResponse.Success.TRUE) + .build() val roundtrippedSessionObserveResponse = jsonMapper.readValue( diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt index 627f9ae..13ae538 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt @@ -4,6 +4,7 @@ package com.browserbase.api.models.sessions import com.browserbase.api.core.JsonValue import com.browserbase.api.core.http.Headers +import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -12,11 +13,148 @@ internal class SessionStartParamsTest { @Test fun create() { SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport.builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .type(SessionStartParams.Browser.Type.LOCAL) + .build() + ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams.BrowserSettings.builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams.BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams.BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams.BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region(SessionStartParams.BrowserbaseSessionCreateParams.Region.US_WEST_2) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() } @@ -24,21 +162,170 @@ internal class SessionStartParamsTest { fun headers() { val params = SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport.builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .type(SessionStartParams.Browser.Type.LOCAL) + .build() + ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams.BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region(SessionStartParams.BrowserbaseSessionCreateParams.Region.US_WEST_2) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() val headers = params._headers() - assertThat(headers).isEqualTo(Headers.builder().build()) + assertThat(headers) + .isEqualTo( + Headers.builder() + .put("x-language", "typescript") + .put("x-sdk-version", "3.0.6") + .put("x-sent-at", "2025-01-15T10:30:00.000Z") + .put("x-stream-response", "true") + .build() + ) } @Test fun headersWithoutOptionalFields() { - val params = SessionStartParams.builder().build() + val params = SessionStartParams.builder().modelName("gpt-4o").build() val headers = params._headers() @@ -49,22 +336,304 @@ internal class SessionStartParamsTest { fun body() { val params = SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport.builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .type(SessionStartParams.Browser.Type.LOCAL) + .build() + ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams.BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region(SessionStartParams.BrowserbaseSessionCreateParams.Region.US_WEST_2) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() val body = params._body() - assertThat(body).isEqualTo(JsonValue.from(mapOf())) + assertThat(body.modelName()).isEqualTo("gpt-4o") + assertThat(body.actTimeoutMs()).contains(30000.0) + assertThat(body.browser()) + .contains( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport.builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .type(SessionStartParams.Browser.Type.LOCAL) + .build() + ) + assertThat(body.browserbaseSessionCreateParams()) + .contains( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams.BrowserSettings.builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams.BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams.BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams.BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region(SessionStartParams.BrowserbaseSessionCreateParams.Region.US_WEST_2) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + assertThat(body.browserbaseSessionId()).contains("browserbaseSessionID") + assertThat(body.debugDom()).contains(true) + assertThat(body.domSettleTimeoutMs()).contains(5000.0) + assertThat(body.experimental()).contains(true) + assertThat(body.selfHeal()).contains(true) + assertThat(body.systemPrompt()).contains("systemPrompt") + assertThat(body.verbose()).contains(SessionStartParams.Verbose._1) + assertThat(body.waitForCaptchaSolves()).contains(true) } @Test fun bodyWithoutOptionalFields() { - val params = SessionStartParams.builder().build() + val params = SessionStartParams.builder().modelName("gpt-4o").build() val body = params._body() + + assertThat(body.modelName()).isEqualTo("gpt-4o") } } diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartResponseTest.kt index 51616d7..717d6d6 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartResponseTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartResponseTest.kt @@ -11,13 +11,40 @@ internal class SessionStartResponseTest { @Test fun create() { - val sessionStartResponse = SessionStartResponse.builder().build() + val sessionStartResponse = + SessionStartResponse.builder() + .data( + SessionStartResponse.Data.builder() + .available(true) + .sessionId("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .build() + ) + .success(SessionStartResponse.Success.TRUE) + .build() + + assertThat(sessionStartResponse.data()) + .isEqualTo( + SessionStartResponse.Data.builder() + .available(true) + .sessionId("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .build() + ) + assertThat(sessionStartResponse.success()).isEqualTo(SessionStartResponse.Success.TRUE) } @Test fun roundtrip() { val jsonMapper = jsonMapper() - val sessionStartResponse = SessionStartResponse.builder().build() + val sessionStartResponse = + SessionStartResponse.builder() + .data( + SessionStartResponse.Data.builder() + .available(true) + .sessionId("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .build() + ) + .success(SessionStartResponse.Success.TRUE) + .build() val roundtrippedSessionStartResponse = jsonMapper.readValue( diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt index ccf1223..32b00d3 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt @@ -16,13 +16,14 @@ import com.browserbase.api.errors.StagehandException import com.browserbase.api.errors.UnauthorizedException import com.browserbase.api.errors.UnexpectedStatusCodeException import com.browserbase.api.errors.UnprocessableEntityException -import com.browserbase.api.models.sessions.SessionStartParams +import com.browserbase.api.models.sessions.SessionActParams import com.github.tomakehurst.wiremock.client.WireMock.anyUrl import com.github.tomakehurst.wiremock.client.WireMock.post import com.github.tomakehurst.wiremock.client.WireMock.status import com.github.tomakehurst.wiremock.client.WireMock.stubFor import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo import com.github.tomakehurst.wiremock.junit5.WireMockTest +import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.entry import org.junit.jupiter.api.BeforeEach @@ -61,7 +62,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsStart400() { + fun sessionsAct400() { val sessionService = client.sessions() stubFor( post(anyUrl()) @@ -72,13 +73,29 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.start( - SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.act( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty( + "username", + JsonValue.from("john_doe"), + ) + .build() + ) + .build() + ) .build() ) } @@ -89,7 +106,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsStart400WithRawResponse() { + fun sessionsAct400WithRawResponse() { val sessionService = client.sessions().withRawResponse() stubFor( post(anyUrl()) @@ -100,13 +117,29 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.start( - SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.act( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty( + "username", + JsonValue.from("john_doe"), + ) + .build() + ) + .build() + ) .build() ) } @@ -117,7 +150,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsStart401() { + fun sessionsAct401() { val sessionService = client.sessions() stubFor( post(anyUrl()) @@ -128,13 +161,29 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.start( - SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.act( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty( + "username", + JsonValue.from("john_doe"), + ) + .build() + ) + .build() + ) .build() ) } @@ -145,7 +194,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsStart401WithRawResponse() { + fun sessionsAct401WithRawResponse() { val sessionService = client.sessions().withRawResponse() stubFor( post(anyUrl()) @@ -156,13 +205,29 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.start( - SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.act( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty( + "username", + JsonValue.from("john_doe"), + ) + .build() + ) + .build() + ) .build() ) } @@ -173,7 +238,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsStart403() { + fun sessionsAct403() { val sessionService = client.sessions() stubFor( post(anyUrl()) @@ -184,13 +249,29 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.start( - SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.act( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty( + "username", + JsonValue.from("john_doe"), + ) + .build() + ) + .build() + ) .build() ) } @@ -201,7 +282,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsStart403WithRawResponse() { + fun sessionsAct403WithRawResponse() { val sessionService = client.sessions().withRawResponse() stubFor( post(anyUrl()) @@ -212,13 +293,29 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.start( - SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.act( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty( + "username", + JsonValue.from("john_doe"), + ) + .build() + ) + .build() + ) .build() ) } @@ -229,7 +326,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsStart404() { + fun sessionsAct404() { val sessionService = client.sessions() stubFor( post(anyUrl()) @@ -240,13 +337,29 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.start( - SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.act( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty( + "username", + JsonValue.from("john_doe"), + ) + .build() + ) + .build() + ) .build() ) } @@ -257,7 +370,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsStart404WithRawResponse() { + fun sessionsAct404WithRawResponse() { val sessionService = client.sessions().withRawResponse() stubFor( post(anyUrl()) @@ -268,13 +381,29 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.start( - SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.act( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty( + "username", + JsonValue.from("john_doe"), + ) + .build() + ) + .build() + ) .build() ) } @@ -285,7 +414,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsStart422() { + fun sessionsAct422() { val sessionService = client.sessions() stubFor( post(anyUrl()) @@ -296,13 +425,29 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.start( - SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.act( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty( + "username", + JsonValue.from("john_doe"), + ) + .build() + ) + .build() + ) .build() ) } @@ -313,7 +458,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsStart422WithRawResponse() { + fun sessionsAct422WithRawResponse() { val sessionService = client.sessions().withRawResponse() stubFor( post(anyUrl()) @@ -324,13 +469,29 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.start( - SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.act( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty( + "username", + JsonValue.from("john_doe"), + ) + .build() + ) + .build() + ) .build() ) } @@ -341,7 +502,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsStart429() { + fun sessionsAct429() { val sessionService = client.sessions() stubFor( post(anyUrl()) @@ -352,13 +513,29 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.start( - SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.act( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty( + "username", + JsonValue.from("john_doe"), + ) + .build() + ) + .build() + ) .build() ) } @@ -369,7 +546,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsStart429WithRawResponse() { + fun sessionsAct429WithRawResponse() { val sessionService = client.sessions().withRawResponse() stubFor( post(anyUrl()) @@ -380,13 +557,29 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.start( - SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.act( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty( + "username", + JsonValue.from("john_doe"), + ) + .build() + ) + .build() + ) .build() ) } @@ -397,7 +590,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsStart500() { + fun sessionsAct500() { val sessionService = client.sessions() stubFor( post(anyUrl()) @@ -408,13 +601,29 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.start( - SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.act( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty( + "username", + JsonValue.from("john_doe"), + ) + .build() + ) + .build() + ) .build() ) } @@ -425,7 +634,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsStart500WithRawResponse() { + fun sessionsAct500WithRawResponse() { val sessionService = client.sessions().withRawResponse() stubFor( post(anyUrl()) @@ -436,13 +645,29 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.start( - SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.act( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty( + "username", + JsonValue.from("john_doe"), + ) + .build() + ) + .build() + ) .build() ) } @@ -453,7 +678,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsStart999() { + fun sessionsAct999() { val sessionService = client.sessions() stubFor( post(anyUrl()) @@ -464,13 +689,29 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.start( - SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.act( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty( + "username", + JsonValue.from("john_doe"), + ) + .build() + ) + .build() + ) .build() ) } @@ -481,7 +722,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsStart999WithRawResponse() { + fun sessionsAct999WithRawResponse() { val sessionService = client.sessions().withRawResponse() stubFor( post(anyUrl()) @@ -492,13 +733,29 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.start( - SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.act( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty( + "username", + JsonValue.from("john_doe"), + ) + .build() + ) + .build() + ) .build() ) } @@ -509,7 +766,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsStartInvalidJsonBody() { + fun sessionsActInvalidJsonBody() { val sessionService = client.sessions() stubFor( post(anyUrl()) @@ -518,13 +775,29 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.start( - SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.act( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty( + "username", + JsonValue.from("john_doe"), + ) + .build() + ) + .build() + ) .build() ) } diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt index 8af7ae3..060d011 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt @@ -5,9 +5,10 @@ package com.browserbase.api.services import com.browserbase.api.client.StagehandClient import com.browserbase.api.client.okhttp.StagehandOkHttpClient import com.browserbase.api.core.JsonValue -import com.browserbase.api.models.sessions.SessionStartParams +import com.browserbase.api.models.sessions.SessionActParams import com.github.tomakehurst.wiremock.client.WireMock.anyUrl import com.github.tomakehurst.wiremock.client.WireMock.equalTo +import com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath import com.github.tomakehurst.wiremock.client.WireMock.ok import com.github.tomakehurst.wiremock.client.WireMock.post import com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor @@ -15,6 +16,7 @@ import com.github.tomakehurst.wiremock.client.WireMock.stubFor import com.github.tomakehurst.wiremock.client.WireMock.verify import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo import com.github.tomakehurst.wiremock.junit5.WireMockTest +import java.time.OffsetDateTime import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test @@ -39,19 +41,33 @@ internal class ServiceParamsTest { @Disabled("Prism tests are disabled") @Test - fun start() { + fun act() { val sessionService = client.sessions() stubFor(post(anyUrl()).willReturn(ok("{}"))) - sessionService.start( - SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.act( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty("username", JsonValue.from("john_doe")) + .build() + ) + .build() + ) .putAdditionalHeader("Secret-Header", "42") .putAdditionalQueryParam("secret_query_param", "42") + .putAdditionalBodyProperty("secretProperty", JsonValue.from("42")) .build() ) @@ -59,6 +75,7 @@ internal class ServiceParamsTest { postRequestedFor(anyUrl()) .withHeader("Secret-Header", equalTo("42")) .withQueryParam("secret_query_param", equalTo("42")) + .withRequestBody(matchingJsonPath("$.secretProperty", equalTo("42"))) ) } } diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt index dba84aa..0011f6f 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt @@ -7,11 +7,12 @@ import com.browserbase.api.client.okhttp.StagehandOkHttpClientAsync import com.browserbase.api.core.JsonValue import com.browserbase.api.models.sessions.SessionActParams import com.browserbase.api.models.sessions.SessionEndParams -import com.browserbase.api.models.sessions.SessionExecuteAgentParams +import com.browserbase.api.models.sessions.SessionExecuteParams import com.browserbase.api.models.sessions.SessionExtractParams import com.browserbase.api.models.sessions.SessionNavigateParams import com.browserbase.api.models.sessions.SessionObserveParams import com.browserbase.api.models.sessions.SessionStartParams +import java.time.OffsetDateTime import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -34,12 +35,24 @@ internal class SessionServiceAsyncTest { val responseFuture = sessionServiceAsync.act( SessionActParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty("username", JsonValue.from("john_doe")) + .build() + ) + .build() + ) .build() ) @@ -62,11 +75,11 @@ internal class SessionServiceAsyncTest { val responseFuture = sessionServiceAsync.end( SessionEndParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionEndParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionEndParams.XStreamResponse.TRUE) .build() ) @@ -76,7 +89,7 @@ internal class SessionServiceAsyncTest { @Disabled("Prism tests are disabled") @Test - fun executeAgent() { + fun execute() { val client = StagehandOkHttpClientAsync.builder() .baseUrl(TestServerExtension.BASE_URL) @@ -87,14 +100,30 @@ internal class SessionServiceAsyncTest { val sessionServiceAsync = client.sessions() val responseFuture = - sessionServiceAsync.executeAgent( - SessionExecuteAgentParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionServiceAsync.execute( + SessionExecuteParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionExecuteParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionExecuteParams.XStreamResponse.TRUE) + .agentConfig( + SessionExecuteParams.AgentConfig.builder() + .cua(true) + .model("string") + .systemPrompt("systemPrompt") + .build() + ) + .executeOptions( + SessionExecuteParams.ExecuteOptions.builder() + .instruction( + "Log in with username 'demo' and password 'test123', then navigate to settings" + ) + .highlightCursor(true) + .maxSteps(20.0) + .build() + ) + .frameId("frameId") .build() ) @@ -117,12 +146,25 @@ internal class SessionServiceAsyncTest { val responseFuture = sessionServiceAsync.extract( SessionExtractParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionExtractParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionExtractParams.XStreamResponse.TRUE) + .frameId("frameId") + .instruction("Extract all product names and prices from the page") + .options( + SessionExtractParams.Options.builder() + .model("string") + .selector("#main-content") + .timeout(30000.0) + .build() + ) + .schema( + SessionExtractParams.Schema.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .build() ) @@ -145,12 +187,20 @@ internal class SessionServiceAsyncTest { val responseFuture = sessionServiceAsync.navigate( SessionNavigateParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionNavigateParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionNavigateParams.XStreamResponse.TRUE) + .url("https://example.com") + .frameId("frameId") + .options( + SessionNavigateParams.Options.builder() + .referer("referer") + .timeout(30000.0) + .waitUntil(SessionNavigateParams.Options.WaitUntil.NETWORKIDLE) + .build() + ) .build() ) @@ -173,12 +223,20 @@ internal class SessionServiceAsyncTest { val responseFuture = sessionServiceAsync.observe( SessionObserveParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionObserveParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionObserveParams.XStreamResponse.TRUE) + .frameId("frameId") + .instruction("Find all clickable navigation links") + .options( + SessionObserveParams.Options.builder() + .model("string") + .selector("nav") + .timeout(30000.0) + .build() + ) .build() ) @@ -201,11 +259,155 @@ internal class SessionServiceAsyncTest { val responseFuture = sessionServiceAsync.start( SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport.builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .type(SessionStartParams.Browser.Type.LOCAL) + .build() + ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams.BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region.US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt index 03853cd..3f62ca6 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt @@ -7,11 +7,12 @@ import com.browserbase.api.client.okhttp.StagehandOkHttpClient import com.browserbase.api.core.JsonValue import com.browserbase.api.models.sessions.SessionActParams import com.browserbase.api.models.sessions.SessionEndParams -import com.browserbase.api.models.sessions.SessionExecuteAgentParams +import com.browserbase.api.models.sessions.SessionExecuteParams import com.browserbase.api.models.sessions.SessionExtractParams import com.browserbase.api.models.sessions.SessionNavigateParams import com.browserbase.api.models.sessions.SessionObserveParams import com.browserbase.api.models.sessions.SessionStartParams +import java.time.OffsetDateTime import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -34,12 +35,24 @@ internal class SessionServiceTest { val response = sessionService.act( SessionActParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("string") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty("username", JsonValue.from("john_doe")) + .build() + ) + .build() + ) .build() ) @@ -61,11 +74,11 @@ internal class SessionServiceTest { val response = sessionService.end( SessionEndParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionEndParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionEndParams.XStreamResponse.TRUE) .build() ) @@ -74,7 +87,7 @@ internal class SessionServiceTest { @Disabled("Prism tests are disabled") @Test - fun executeAgent() { + fun execute() { val client = StagehandOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) @@ -85,14 +98,30 @@ internal class SessionServiceTest { val sessionService = client.sessions() val response = - sessionService.executeAgent( - SessionExecuteAgentParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + sessionService.execute( + SessionExecuteParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionExecuteParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionExecuteParams.XStreamResponse.TRUE) + .agentConfig( + SessionExecuteParams.AgentConfig.builder() + .cua(true) + .model("string") + .systemPrompt("systemPrompt") + .build() + ) + .executeOptions( + SessionExecuteParams.ExecuteOptions.builder() + .instruction( + "Log in with username 'demo' and password 'test123', then navigate to settings" + ) + .highlightCursor(true) + .maxSteps(20.0) + .build() + ) + .frameId("frameId") .build() ) @@ -114,12 +143,25 @@ internal class SessionServiceTest { val response = sessionService.extract( SessionExtractParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionExtractParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionExtractParams.XStreamResponse.TRUE) + .frameId("frameId") + .instruction("Extract all product names and prices from the page") + .options( + SessionExtractParams.Options.builder() + .model("string") + .selector("#main-content") + .timeout(30000.0) + .build() + ) + .schema( + SessionExtractParams.Schema.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .build() ) @@ -141,12 +183,20 @@ internal class SessionServiceTest { val response = sessionService.navigate( SessionNavigateParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionNavigateParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionNavigateParams.XStreamResponse.TRUE) + .url("https://example.com") + .frameId("frameId") + .options( + SessionNavigateParams.Options.builder() + .referer("referer") + .timeout(30000.0) + .waitUntil(SessionNavigateParams.Options.WaitUntil.NETWORKIDLE) + .build() + ) .build() ) @@ -168,12 +218,20 @@ internal class SessionServiceTest { val response = sessionService.observe( SessionObserveParams.builder() - .id(JsonValue.from(mapOf())) - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionObserveParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionObserveParams.XStreamResponse.TRUE) + .frameId("frameId") + .instruction("Find all clickable navigation links") + .options( + SessionObserveParams.Options.builder() + .model("string") + .selector("nav") + .timeout(30000.0) + .build() + ) .build() ) @@ -195,11 +253,155 @@ internal class SessionServiceTest { val response = sessionService.start( SessionStartParams.builder() - .xLanguage(JsonValue.from(mapOf())) - .xSdkVersion(JsonValue.from(mapOf())) - .xSentAt(JsonValue.from(mapOf())) - .xStreamResponse(JsonValue.from(mapOf())) - .body(JsonValue.from(mapOf())) + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport.builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .type(SessionStartParams.Browser.Type.LOCAL) + .build() + ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams.BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region.US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) From dd65420fecb521fba36cbf2a623ce675973a27a0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 18:22:21 +0000 Subject: [PATCH 05/13] feat(api): manual updates --- .stats.yml | 6 +- README.md | 28 +- .../api/services/ErrorHandlingTest.kt | 2892 +++++++++++++++-- .../api/services/ServiceParamsTest.kt | 169 + 4 files changed, 2788 insertions(+), 307 deletions(-) diff --git a/.stats.yml b/.stats.yml index 87bd24b..a5338dd 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 7 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-349e1b0f6291eedd731c1660155a50adcb3424fb8cd9e17bbdc0939ff3bbffcd.yml -openapi_spec_hash: 456b593ea71d72bc31a6338a25363e9f -config_hash: 5f6b5ec6e84fb01932ba87c6a9623d9b +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-e6a9dca1a93568e403ac72128d86f30c8c3f1336d4b67017d7e61b1836f10f47.yml +openapi_spec_hash: ef01e0649bb0e283df0aa81c369649df +config_hash: abc9d1eb9779bb5629eaed7074c42809 diff --git a/README.md b/README.md index 019da3c..852c752 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ StagehandClient client = StagehandOkHttpClient.fromEnv(); SessionActParams params = SessionActParams.builder() .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .input("Click the login button") + .input("click the first link on the page") .build(); SessionActResponse response = client.sessions().act(params); ``` @@ -163,7 +163,7 @@ StagehandClient client = StagehandOkHttpClient.fromEnv(); SessionActParams params = SessionActParams.builder() .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .input("Click the login button") + .input("click the first link on the page") .build(); CompletableFuture response = client.async().sessions().act(params); ``` @@ -183,7 +183,7 @@ StagehandClientAsync client = StagehandOkHttpClientAsync.fromEnv(); SessionActParams params = SessionActParams.builder() .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .input("Click the login button") + .input("click the first link on the page") .build(); CompletableFuture response = client.sessions().act(params); ``` @@ -199,14 +199,13 @@ To access this data, prefix any HTTP method call on a client or service with `wi ```java import com.browserbase.api.core.http.Headers; import com.browserbase.api.core.http.HttpResponseFor; -import com.browserbase.api.models.sessions.SessionActParams; -import com.browserbase.api.models.sessions.SessionActResponse; +import com.browserbase.api.models.sessions.SessionStartParams; +import com.browserbase.api.models.sessions.SessionStartResponse; -SessionActParams params = SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .input("Click the login button") +SessionStartParams params = SessionStartParams.builder() + .modelName("gpt-4o") .build(); -HttpResponseFor response = client.sessions().withRawResponse().act(params); +HttpResponseFor response = client.sessions().withRawResponse().start(params); int statusCode = response.statusCode(); Headers headers = response.headers(); @@ -215,9 +214,9 @@ Headers headers = response.headers(); You can still deserialize the response into an instance of a Java class if needed: ```java -import com.browserbase.api.models.sessions.SessionActResponse; +import com.browserbase.api.models.sessions.SessionStartResponse; -SessionActResponse parsedResponse = response.parse(); +SessionStartResponse parsedResponse = response.parse(); ``` ## Error handling @@ -313,9 +312,9 @@ Requests time out after 1 minute by default. To set a custom timeout, configure the method call using the `timeout` method: ```java -import com.browserbase.api.models.sessions.SessionActResponse; +import com.browserbase.api.models.sessions.SessionStartResponse; -SessionActResponse response = client.sessions().act( +SessionStartResponse response = client.sessions().start( params, RequestOptions.builder().timeout(Duration.ofSeconds(30)).build() ); ``` @@ -449,10 +448,11 @@ These properties can be accessed on the nested built object later using the `_ad To set a documented parameter or property to an undocumented or not yet supported _value_, pass a [`JsonValue`](stagehand-java-core/src/main/kotlin/com/browserbase/api/core/Values.kt) object to its setter: ```java +import com.browserbase.api.core.JsonValue; import com.browserbase.api.models.sessions.SessionActParams; SessionActParams params = SessionActParams.builder() - .input("Click the login button") + .input(JsonValue.from(42)) .build(); ``` diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt index 32b00d3..87af3f1 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt @@ -16,7 +16,7 @@ import com.browserbase.api.errors.StagehandException import com.browserbase.api.errors.UnauthorizedException import com.browserbase.api.errors.UnexpectedStatusCodeException import com.browserbase.api.errors.UnprocessableEntityException -import com.browserbase.api.models.sessions.SessionActParams +import com.browserbase.api.models.sessions.SessionStartParams import com.github.tomakehurst.wiremock.client.WireMock.anyUrl import com.github.tomakehurst.wiremock.client.WireMock.post import com.github.tomakehurst.wiremock.client.WireMock.status @@ -62,7 +62,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsAct400() { + fun sessionsStart400() { val sessionService = client.sessions() stubFor( post(anyUrl()) @@ -73,29 +73,165 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.act( - SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + sessionService.start( + SessionStartParams.builder() + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("Click the login button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model("string") - .timeout(30000.0) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty( - "username", - JsonValue.from("john_doe"), + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .type(SessionStartParams.Browser.Type.LOCAL) + .build() + ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region + .US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) .build() ) .build() ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) } @@ -106,7 +242,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsAct400WithRawResponse() { + fun sessionsStart400WithRawResponse() { val sessionService = client.sessions().withRawResponse() stubFor( post(anyUrl()) @@ -117,29 +253,165 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.act( - SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + sessionService.start( + SessionStartParams.builder() + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("Click the login button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model("string") - .timeout(30000.0) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty( - "username", - JsonValue.from("john_doe"), + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport + .builder() + .height(0.0) + .width(0.0) + .build() ) .build() ) + .type(SessionStartParams.Browser.Type.LOCAL) .build() ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region + .US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) } @@ -150,7 +422,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsAct401() { + fun sessionsStart401() { val sessionService = client.sessions() stubFor( post(anyUrl()) @@ -161,29 +433,165 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.act( - SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + sessionService.start( + SessionStartParams.builder() + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("Click the login button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model("string") - .timeout(30000.0) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty( - "username", - JsonValue.from("john_doe"), + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport + .builder() + .height(0.0) + .width(0.0) + .build() ) .build() ) + .type(SessionStartParams.Browser.Type.LOCAL) .build() ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region + .US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) } @@ -194,7 +602,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsAct401WithRawResponse() { + fun sessionsStart401WithRawResponse() { val sessionService = client.sessions().withRawResponse() stubFor( post(anyUrl()) @@ -205,29 +613,165 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.act( - SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + sessionService.start( + SessionStartParams.builder() + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("Click the login button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model("string") - .timeout(30000.0) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty( - "username", - JsonValue.from("john_doe"), + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport + .builder() + .height(0.0) + .width(0.0) + .build() ) .build() ) + .type(SessionStartParams.Browser.Type.LOCAL) .build() ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region + .US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) } @@ -238,7 +782,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsAct403() { + fun sessionsStart403() { val sessionService = client.sessions() stubFor( post(anyUrl()) @@ -249,29 +793,165 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.act( - SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + sessionService.start( + SessionStartParams.builder() + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("Click the login button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model("string") - .timeout(30000.0) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty( - "username", - JsonValue.from("john_doe"), + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .type(SessionStartParams.Browser.Type.LOCAL) + .build() + ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region + .US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) .build() ) .build() ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) } @@ -282,7 +962,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsAct403WithRawResponse() { + fun sessionsStart403WithRawResponse() { val sessionService = client.sessions().withRawResponse() stubFor( post(anyUrl()) @@ -293,29 +973,165 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.act( - SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + sessionService.start( + SessionStartParams.builder() + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("Click the login button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model("string") - .timeout(30000.0) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty( - "username", - JsonValue.from("john_doe"), + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .type(SessionStartParams.Browser.Type.LOCAL) + .build() + ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region + .US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) .build() ) .build() ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) } @@ -326,7 +1142,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsAct404() { + fun sessionsStart404() { val sessionService = client.sessions() stubFor( post(anyUrl()) @@ -337,29 +1153,165 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.act( - SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + sessionService.start( + SessionStartParams.builder() + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("Click the login button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model("string") - .timeout(30000.0) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty( - "username", - JsonValue.from("john_doe"), + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport + .builder() + .height(0.0) + .width(0.0) + .build() ) .build() ) + .type(SessionStartParams.Browser.Type.LOCAL) .build() ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region + .US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) } @@ -370,7 +1322,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsAct404WithRawResponse() { + fun sessionsStart404WithRawResponse() { val sessionService = client.sessions().withRawResponse() stubFor( post(anyUrl()) @@ -381,29 +1333,165 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.act( - SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + sessionService.start( + SessionStartParams.builder() + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("Click the login button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model("string") - .timeout(30000.0) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty( - "username", - JsonValue.from("john_doe"), + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport + .builder() + .height(0.0) + .width(0.0) + .build() ) .build() ) + .type(SessionStartParams.Browser.Type.LOCAL) .build() ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region + .US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) } @@ -414,7 +1502,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsAct422() { + fun sessionsStart422() { val sessionService = client.sessions() stubFor( post(anyUrl()) @@ -425,29 +1513,165 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.act( - SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + sessionService.start( + SessionStartParams.builder() + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("Click the login button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model("string") - .timeout(30000.0) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty( - "username", - JsonValue.from("john_doe"), + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport + .builder() + .height(0.0) + .width(0.0) + .build() ) .build() ) + .type(SessionStartParams.Browser.Type.LOCAL) .build() ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region + .US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) } @@ -458,7 +1682,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsAct422WithRawResponse() { + fun sessionsStart422WithRawResponse() { val sessionService = client.sessions().withRawResponse() stubFor( post(anyUrl()) @@ -469,29 +1693,165 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.act( - SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + sessionService.start( + SessionStartParams.builder() + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("Click the login button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model("string") - .timeout(30000.0) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty( - "username", - JsonValue.from("john_doe"), + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .type(SessionStartParams.Browser.Type.LOCAL) + .build() + ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region + .US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) .build() ) .build() ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) } @@ -502,7 +1862,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsAct429() { + fun sessionsStart429() { val sessionService = client.sessions() stubFor( post(anyUrl()) @@ -513,29 +1873,165 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.act( - SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + sessionService.start( + SessionStartParams.builder() + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("Click the login button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model("string") - .timeout(30000.0) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty( - "username", - JsonValue.from("john_doe"), + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport + .builder() + .height(0.0) + .width(0.0) + .build() ) .build() ) + .type(SessionStartParams.Browser.Type.LOCAL) .build() ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region + .US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) } @@ -546,7 +2042,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsAct429WithRawResponse() { + fun sessionsStart429WithRawResponse() { val sessionService = client.sessions().withRawResponse() stubFor( post(anyUrl()) @@ -557,29 +2053,165 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.act( - SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + sessionService.start( + SessionStartParams.builder() + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("Click the login button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model("string") - .timeout(30000.0) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty( - "username", - JsonValue.from("john_doe"), + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport + .builder() + .height(0.0) + .width(0.0) + .build() ) .build() ) + .type(SessionStartParams.Browser.Type.LOCAL) .build() ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region + .US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) } @@ -590,7 +2222,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsAct500() { + fun sessionsStart500() { val sessionService = client.sessions() stubFor( post(anyUrl()) @@ -601,29 +2233,165 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.act( - SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + sessionService.start( + SessionStartParams.builder() + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("Click the login button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model("string") - .timeout(30000.0) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty( - "username", - JsonValue.from("john_doe"), + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport + .builder() + .height(0.0) + .width(0.0) + .build() ) .build() ) + .type(SessionStartParams.Browser.Type.LOCAL) .build() ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region + .US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) } @@ -634,7 +2402,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsAct500WithRawResponse() { + fun sessionsStart500WithRawResponse() { val sessionService = client.sessions().withRawResponse() stubFor( post(anyUrl()) @@ -645,29 +2413,165 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.act( - SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + sessionService.start( + SessionStartParams.builder() + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("Click the login button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model("string") - .timeout(30000.0) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty( - "username", - JsonValue.from("john_doe"), + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport + .builder() + .height(0.0) + .width(0.0) + .build() ) .build() ) + .type(SessionStartParams.Browser.Type.LOCAL) .build() ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region + .US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) } @@ -678,7 +2582,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsAct999() { + fun sessionsStart999() { val sessionService = client.sessions() stubFor( post(anyUrl()) @@ -689,29 +2593,165 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.act( - SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + sessionService.start( + SessionStartParams.builder() + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("Click the login button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model("string") - .timeout(30000.0) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty( - "username", - JsonValue.from("john_doe"), + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport + .builder() + .height(0.0) + .width(0.0) + .build() ) .build() ) + .type(SessionStartParams.Browser.Type.LOCAL) + .build() + ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region + .US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .build() ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) } @@ -722,7 +2762,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsAct999WithRawResponse() { + fun sessionsStart999WithRawResponse() { val sessionService = client.sessions().withRawResponse() stubFor( post(anyUrl()) @@ -733,29 +2773,165 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.act( - SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + sessionService.start( + SessionStartParams.builder() + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("Click the login button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model("string") - .timeout(30000.0) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty( - "username", - JsonValue.from("john_doe"), + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .type(SessionStartParams.Browser.Type.LOCAL) + .build() + ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() ) .build() ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region + .US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .build() ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) } @@ -766,7 +2942,7 @@ internal class ErrorHandlingTest { } @Test - fun sessionsActInvalidJsonBody() { + fun sessionsStartInvalidJsonBody() { val sessionService = client.sessions() stubFor( post(anyUrl()) @@ -775,29 +2951,165 @@ internal class ErrorHandlingTest { val e = assertThrows { - sessionService.act( - SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") - .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + sessionService.start( + SessionStartParams.builder() + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) - .xStreamResponse(SessionActParams.XStreamResponse.TRUE) - .input("Click the login button") - .frameId("frameId") - .options( - SessionActParams.Options.builder() - .model("string") - .timeout(30000.0) - .variables( - SessionActParams.Options.Variables.builder() - .putAdditionalProperty( - "username", - JsonValue.from("john_doe"), + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .type(SessionStartParams.Browser.Type.LOCAL) + .build() + ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams + .BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region( + SessionStartParams.BrowserbaseSessionCreateParams.Region + .US_WEST_2 + ) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) .build() ) .build() ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) .build() ) } diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt index 060d011..ecf30b0 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt @@ -6,6 +6,7 @@ import com.browserbase.api.client.StagehandClient import com.browserbase.api.client.okhttp.StagehandOkHttpClient import com.browserbase.api.core.JsonValue import com.browserbase.api.models.sessions.SessionActParams +import com.browserbase.api.models.sessions.SessionStartParams import com.github.tomakehurst.wiremock.client.WireMock.anyUrl import com.github.tomakehurst.wiremock.client.WireMock.equalTo import com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath @@ -39,6 +40,174 @@ internal class ServiceParamsTest { .build() } + @Disabled("Prism tests are disabled") + @Test + fun start() { + val sessionService = client.sessions() + stubFor(post(anyUrl()).willReturn(ok("{}"))) + + sessionService.start( + SessionStartParams.builder() + .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) + .modelName("gpt-4o") + .actTimeoutMs(30000.0) + .browser( + SessionStartParams.Browser.builder() + .cdpUrl("ws://localhost:9222") + .launchOptions( + SessionStartParams.Browser.LaunchOptions.builder() + .acceptDownloads(true) + .addArg("string") + .cdpUrl("cdpUrl") + .chromiumSandbox(true) + .connectTimeoutMs(0.0) + .deviceScaleFactor(0.0) + .devtools(true) + .downloadsPath("downloadsPath") + .executablePath("executablePath") + .hasTouch(true) + .headless(true) + .ignoreDefaultArgs(true) + .ignoreHttpsErrors(true) + .locale("locale") + .preserveUserDataDir(true) + .proxy( + SessionStartParams.Browser.LaunchOptions.Proxy.builder() + .server("server") + .bypass("bypass") + .password("password") + .username("username") + .build() + ) + .userDataDir("userDataDir") + .viewport( + SessionStartParams.Browser.LaunchOptions.Viewport.builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .type(SessionStartParams.Browser.Type.LOCAL) + .build() + ) + .browserbaseSessionCreateParams( + SessionStartParams.BrowserbaseSessionCreateParams.builder() + .browserSettings( + SessionStartParams.BrowserbaseSessionCreateParams.BrowserSettings + .builder() + .advancedStealth(true) + .blockAds(true) + .context( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Context + .builder() + .id("id") + .persist(true) + .build() + ) + .extensionId("extensionId") + .fingerprint( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .builder() + .addBrowser( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Browser + .CHROME + ) + .addDevice( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Device + .DESKTOP + ) + .httpVersion( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .HttpVersion + ._1 + ) + .addLocale("string") + .addOperatingSystem( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .OperatingSystem + .ANDROID + ) + .screen( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Fingerprint + .Screen + .builder() + .maxHeight(0.0) + .maxWidth(0.0) + .minHeight(0.0) + .minWidth(0.0) + .build() + ) + .build() + ) + .logSession(true) + .recordSession(true) + .solveCaptchas(true) + .viewport( + SessionStartParams.BrowserbaseSessionCreateParams + .BrowserSettings + .Viewport + .builder() + .height(0.0) + .width(0.0) + .build() + ) + .build() + ) + .extensionId("extensionId") + .keepAlive(true) + .projectId("projectId") + .proxies(true) + .region(SessionStartParams.BrowserbaseSessionCreateParams.Region.US_WEST_2) + .timeout(0.0) + .userMetadata( + SessionStartParams.BrowserbaseSessionCreateParams.UserMetadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + .browserbaseSessionId("browserbaseSessionID") + .debugDom(true) + .domSettleTimeoutMs(5000.0) + .experimental(true) + .selfHeal(true) + .systemPrompt("systemPrompt") + .verbose(SessionStartParams.Verbose._1) + .waitForCaptchaSolves(true) + .putAdditionalHeader("Secret-Header", "42") + .putAdditionalQueryParam("secret_query_param", "42") + .putAdditionalBodyProperty("secretProperty", JsonValue.from("42")) + .build() + ) + + verify( + postRequestedFor(anyUrl()) + .withHeader("Secret-Header", equalTo("42")) + .withQueryParam("secret_query_param", equalTo("42")) + .withRequestBody(matchingJsonPath("$.secretProperty", equalTo("42"))) + ) + } + @Disabled("Prism tests are disabled") @Test fun act() { From adace53fc3e4a0fb4b866172aec98519ec0f29d5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 18:24:23 +0000 Subject: [PATCH 06/13] feat(api): manual updates --- .stats.yml | 2 +- README.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.stats.yml b/.stats.yml index a5338dd..4bcf91f 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 7 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-e6a9dca1a93568e403ac72128d86f30c8c3f1336d4b67017d7e61b1836f10f47.yml openapi_spec_hash: ef01e0649bb0e283df0aa81c369649df -config_hash: abc9d1eb9779bb5629eaed7074c42809 +config_hash: 0f2a6f228fb92683466c107fce3bcd21 diff --git a/README.md b/README.md index 852c752..15d5186 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ import com.browserbase.api.models.sessions.SessionActResponse; StagehandClient client = StagehandOkHttpClient.fromEnv(); SessionActParams params = SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .id("00000000-your-session-id-000000000000") .input("click the first link on the page") .build(); SessionActResponse response = client.sessions().act(params); @@ -162,7 +162,7 @@ import java.util.concurrent.CompletableFuture; StagehandClient client = StagehandOkHttpClient.fromEnv(); SessionActParams params = SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .id("00000000-your-session-id-000000000000") .input("click the first link on the page") .build(); CompletableFuture response = client.async().sessions().act(params); @@ -182,7 +182,7 @@ import java.util.concurrent.CompletableFuture; StagehandClientAsync client = StagehandOkHttpClientAsync.fromEnv(); SessionActParams params = SessionActParams.builder() - .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .id("00000000-your-session-id-000000000000") .input("click the first link on the page") .build(); CompletableFuture response = client.sessions().act(params); From 3cf20739785134610aa7bcbdbce3215c3c3a9970 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 18:26:29 +0000 Subject: [PATCH 07/13] feat(api): manual updates --- .stats.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 4bcf91f..2790605 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 7 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-e6a9dca1a93568e403ac72128d86f30c8c3f1336d4b67017d7e61b1836f10f47.yml openapi_spec_hash: ef01e0649bb0e283df0aa81c369649df -config_hash: 0f2a6f228fb92683466c107fce3bcd21 +config_hash: 88e87ba7021be93d267ecfc8f5e6b891 diff --git a/README.md b/README.md index 15d5186..3c37038 100644 --- a/README.md +++ b/README.md @@ -203,7 +203,7 @@ import com.browserbase.api.models.sessions.SessionStartParams; import com.browserbase.api.models.sessions.SessionStartResponse; SessionStartParams params = SessionStartParams.builder() - .modelName("gpt-4o") + .modelName("openai/gpt-5-nano") .build(); HttpResponseFor response = client.sessions().withRawResponse().start(params); From 07db616b7209716efa346035d65f5d7bf616c992 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 18:46:23 +0000 Subject: [PATCH 08/13] feat(api): manual updates --- .stats.yml | 4 +- .../main/kotlin/stagehand.publish.gradle.kts | 2 +- .../api/models/sessions/SessionActResponse.kt | 143 +---- .../api/models/sessions/SessionEndResponse.kt | 190 +----- .../models/sessions/SessionExecuteResponse.kt | 143 +---- .../models/sessions/SessionExtractResponse.kt | 143 +---- .../sessions/SessionNavigateResponse.kt | 143 +---- .../models/sessions/SessionObserveResponse.kt | 143 +---- .../api/models/sessions/SessionStartParams.kt | 546 +++--------------- .../models/sessions/SessionStartResponse.kt | 143 +---- .../models/sessions/SessionActResponseTest.kt | 6 +- .../models/sessions/SessionEndResponseTest.kt | 8 +- .../sessions/SessionExecuteResponseTest.kt | 6 +- .../sessions/SessionExtractResponseTest.kt | 6 +- .../sessions/SessionNavigateResponseTest.kt | 7 +- .../sessions/SessionObserveResponseTest.kt | 6 +- .../models/sessions/SessionStartParamsTest.kt | 8 +- .../sessions/SessionStartResponseTest.kt | 6 +- .../api/services/ErrorHandlingTest.kt | 34 +- .../api/services/ServiceParamsTest.kt | 2 +- .../services/async/SessionServiceAsyncTest.kt | 2 +- .../services/blocking/SessionServiceTest.kt | 2 +- 22 files changed, 229 insertions(+), 1464 deletions(-) diff --git a/.stats.yml b/.stats.yml index 2790605..08f0cef 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 7 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-e6a9dca1a93568e403ac72128d86f30c8c3f1336d4b67017d7e61b1836f10f47.yml -openapi_spec_hash: ef01e0649bb0e283df0aa81c369649df +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-d571232203ef4e00986a3245224267db6f8aaffdad57780f712e0694dc8d9e37.yml +openapi_spec_hash: d5d635dd7b24a2e1255c6f2a895253ff config_hash: 88e87ba7021be93d267ecfc8f5e6b891 diff --git a/buildSrc/src/main/kotlin/stagehand.publish.gradle.kts b/buildSrc/src/main/kotlin/stagehand.publish.gradle.kts index 796aad4..7b0ce3f 100644 --- a/buildSrc/src/main/kotlin/stagehand.publish.gradle.kts +++ b/buildSrc/src/main/kotlin/stagehand.publish.gradle.kts @@ -10,7 +10,7 @@ configure { pom { name.set("Stagehand API") - description.set("Stagehand SDK for AI browser automation [ALPHA].") + description.set("Stagehand SDK for AI browser automation [ALPHA]. This API allows clients to\nexecute browser automation tasks remotely on the Browserbase cloud.\n\nAll endpoints except /sessions/start require an active session ID. Responses are\nstreamed using Server-Sent Events (SSE) when the `x-stream-response: true`\nheader is provided.\n\nThis SDK is currently ALPHA software and is not production ready! Please try it\nand give us your feedback, stay tuned for upcoming release announcements!") url.set("https://docs.stagehand.dev") licenses { diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActResponse.kt index bfa1f65..db27614 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActResponse.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActResponse.kt @@ -2,7 +2,6 @@ package com.browserbase.api.models.sessions -import com.browserbase.api.core.Enum import com.browserbase.api.core.ExcludeMissing import com.browserbase.api.core.JsonField import com.browserbase.api.core.JsonMissing @@ -24,14 +23,14 @@ class SessionActResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val data: JsonField, - private val success: JsonField, + private val success: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), - @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), + @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), ) : this(data, success, mutableMapOf()) /** @@ -41,10 +40,12 @@ private constructor( fun data(): Data = data.getRequired("data") /** + * Indicates whether the request was successful + * * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ - fun success(): Success = success.getRequired("success") + fun success(): Boolean = success.getRequired("success") /** * Returns the raw JSON value of [data]. @@ -58,7 +59,7 @@ private constructor( * * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success + @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -90,7 +91,7 @@ private constructor( class Builder internal constructor() { private var data: JsonField? = null - private var success: JsonField? = null + private var success: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic @@ -110,15 +111,16 @@ private constructor( */ fun data(data: JsonField) = apply { this.data = data } - fun success(success: Success) = success(JsonField.of(success)) + /** Indicates whether the request was successful */ + fun success(success: Boolean) = success(JsonField.of(success)) /** * Sets [Builder.success] to an arbitrary JSON value. * - * You should usually call [Builder.success] with a well-typed [Success] value instead. This + * You should usually call [Builder.success] with a well-typed [Boolean] value instead. This * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun success(success: JsonField) = apply { this.success = success } + fun success(success: JsonField) = apply { this.success = success } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -168,7 +170,7 @@ private constructor( } data().validate() - success().validate() + success() validated = true } @@ -187,8 +189,7 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (data.asKnown().getOrNull()?.validity() ?: 0) + - (success.asKnown().getOrNull()?.validity() ?: 0) + (data.asKnown().getOrNull()?.validity() ?: 0) + (if (success.asKnown().isPresent) 1 else 0) class Data @JsonCreator(mode = JsonCreator.Mode.DISABLED) @@ -690,124 +691,6 @@ private constructor( "Data{result=$result, actionId=$actionId, additionalProperties=$additionalProperties}" } - class Success @JsonCreator private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val TRUE = of(true) - - @JvmStatic fun of(value: Boolean) = Success(JsonField.of(value)) - } - - /** An enum containing [Success]'s known values. */ - enum class Known { - TRUE - } - - /** - * An enum containing [Success]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Success] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - TRUE, - /** An enum member indicating that [Success] was instantiated with an unknown value. */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - TRUE -> Value.TRUE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws StagehandInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - TRUE -> Known.TRUE - else -> throw StagehandInvalidDataException("Unknown Success: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * @throws StagehandInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asBoolean(): Boolean = - _value().asBoolean().orElseThrow { - StagehandInvalidDataException("Value is not a Boolean") - } - - private var validated: Boolean = false - - fun validate(): Success = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Success && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt index 3bed0ac..3345222 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt @@ -2,12 +2,9 @@ package com.browserbase.api.models.sessions -import com.browserbase.api.core.Enum import com.browserbase.api.core.ExcludeMissing -import com.browserbase.api.core.JsonField import com.browserbase.api.core.JsonMissing import com.browserbase.api.core.JsonValue -import com.browserbase.api.core.checkRequired import com.browserbase.api.errors.StagehandInvalidDataException import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter @@ -15,32 +12,29 @@ import com.fasterxml.jackson.annotation.JsonCreator import com.fasterxml.jackson.annotation.JsonProperty import java.util.Collections import java.util.Objects -import kotlin.jvm.optionals.getOrNull class SessionEndResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - private val success: JsonField, + private val success: JsonValue, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of() + @JsonProperty("success") @ExcludeMissing success: JsonValue = JsonMissing.of() ) : this(success, mutableMapOf()) /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun success(): Success = success.getRequired("success") - - /** - * Returns the raw JSON value of [success]. + * Expected to always return the following: + * ```java + * JsonValue.from(true) + * ``` * - * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). */ - @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success + @JsonProperty("success") @ExcludeMissing fun _success(): JsonValue = success @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -56,21 +50,14 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [SessionEndResponse]. - * - * The following fields are required: - * ```java - * .success() - * ``` - */ + /** Returns a mutable builder for constructing an instance of [SessionEndResponse]. */ @JvmStatic fun builder() = Builder() } /** A builder for [SessionEndResponse]. */ class Builder internal constructor() { - private var success: JsonField? = null + private var success: JsonValue = JsonValue.from(true) private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic @@ -79,15 +66,19 @@ private constructor( additionalProperties = sessionEndResponse.additionalProperties.toMutableMap() } - fun success(success: Success) = success(JsonField.of(success)) - /** - * Sets [Builder.success] to an arbitrary JSON value. + * Sets the field to an arbitrary JSON value. * - * You should usually call [Builder.success] with a well-typed [Success] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from(true) + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. */ - fun success(success: JsonField) = apply { this.success = success } + fun success(success: JsonValue) = apply { this.success = success } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -112,19 +103,9 @@ private constructor( * Returns an immutable instance of [SessionEndResponse]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .success() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): SessionEndResponse = - SessionEndResponse( - checkRequired("success", success), - additionalProperties.toMutableMap(), - ) + SessionEndResponse(success, additionalProperties.toMutableMap()) } private var validated: Boolean = false @@ -134,7 +115,11 @@ private constructor( return@apply } - success().validate() + _success().let { + if (it != JsonValue.from(true)) { + throw StagehandInvalidDataException("'success' is invalid, received $it") + } + } validated = true } @@ -151,125 +136,8 @@ private constructor( * * Used for best match union deserialization. */ - @JvmSynthetic internal fun validity(): Int = (success.asKnown().getOrNull()?.validity() ?: 0) - - class Success @JsonCreator private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val TRUE = of(true) - - @JvmStatic fun of(value: Boolean) = Success(JsonField.of(value)) - } - - /** An enum containing [Success]'s known values. */ - enum class Known { - TRUE - } - - /** - * An enum containing [Success]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Success] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - TRUE, - /** An enum member indicating that [Success] was instantiated with an unknown value. */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - TRUE -> Value.TRUE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws StagehandInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - TRUE -> Known.TRUE - else -> throw StagehandInvalidDataException("Unknown Success: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * @throws StagehandInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asBoolean(): Boolean = - _value().asBoolean().orElseThrow { - StagehandInvalidDataException("Value is not a Boolean") - } - - private var validated: Boolean = false - - fun validate(): Success = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Success && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } + @JvmSynthetic + internal fun validity(): Int = success.let { if (it == JsonValue.from(true)) 1 else 0 } override fun equals(other: Any?): Boolean { if (this === other) { diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteResponse.kt index 2478f77..8718994 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteResponse.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteResponse.kt @@ -2,7 +2,6 @@ package com.browserbase.api.models.sessions -import com.browserbase.api.core.Enum import com.browserbase.api.core.ExcludeMissing import com.browserbase.api.core.JsonField import com.browserbase.api.core.JsonMissing @@ -24,14 +23,14 @@ class SessionExecuteResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val data: JsonField, - private val success: JsonField, + private val success: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), - @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), + @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), ) : this(data, success, mutableMapOf()) /** @@ -41,10 +40,12 @@ private constructor( fun data(): Data = data.getRequired("data") /** + * Indicates whether the request was successful + * * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ - fun success(): Success = success.getRequired("success") + fun success(): Boolean = success.getRequired("success") /** * Returns the raw JSON value of [data]. @@ -58,7 +59,7 @@ private constructor( * * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success + @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -90,7 +91,7 @@ private constructor( class Builder internal constructor() { private var data: JsonField? = null - private var success: JsonField? = null + private var success: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic @@ -110,15 +111,16 @@ private constructor( */ fun data(data: JsonField) = apply { this.data = data } - fun success(success: Success) = success(JsonField.of(success)) + /** Indicates whether the request was successful */ + fun success(success: Boolean) = success(JsonField.of(success)) /** * Sets [Builder.success] to an arbitrary JSON value. * - * You should usually call [Builder.success] with a well-typed [Success] value instead. This + * You should usually call [Builder.success] with a well-typed [Boolean] value instead. This * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun success(success: JsonField) = apply { this.success = success } + fun success(success: JsonField) = apply { this.success = success } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -168,7 +170,7 @@ private constructor( } data().validate() - success().validate() + success() validated = true } @@ -187,8 +189,7 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (data.asKnown().getOrNull()?.validity() ?: 0) + - (success.asKnown().getOrNull()?.validity() ?: 0) + (data.asKnown().getOrNull()?.validity() ?: 0) + (if (success.asKnown().isPresent) 1 else 0) class Data @JsonCreator(mode = JsonCreator.Mode.DISABLED) @@ -1637,124 +1638,6 @@ private constructor( override fun toString() = "Data{result=$result, additionalProperties=$additionalProperties}" } - class Success @JsonCreator private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val TRUE = of(true) - - @JvmStatic fun of(value: Boolean) = Success(JsonField.of(value)) - } - - /** An enum containing [Success]'s known values. */ - enum class Known { - TRUE - } - - /** - * An enum containing [Success]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Success] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - TRUE, - /** An enum member indicating that [Success] was instantiated with an unknown value. */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - TRUE -> Value.TRUE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws StagehandInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - TRUE -> Known.TRUE - else -> throw StagehandInvalidDataException("Unknown Success: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * @throws StagehandInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asBoolean(): Boolean = - _value().asBoolean().orElseThrow { - StagehandInvalidDataException("Value is not a Boolean") - } - - private var validated: Boolean = false - - fun validate(): Success = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Success && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractResponse.kt index f48f24f..e281560 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractResponse.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractResponse.kt @@ -2,7 +2,6 @@ package com.browserbase.api.models.sessions -import com.browserbase.api.core.Enum import com.browserbase.api.core.ExcludeMissing import com.browserbase.api.core.JsonField import com.browserbase.api.core.JsonMissing @@ -22,14 +21,14 @@ class SessionExtractResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val data: JsonField, - private val success: JsonField, + private val success: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), - @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), + @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), ) : this(data, success, mutableMapOf()) /** @@ -39,10 +38,12 @@ private constructor( fun data(): Data = data.getRequired("data") /** + * Indicates whether the request was successful + * * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ - fun success(): Success = success.getRequired("success") + fun success(): Boolean = success.getRequired("success") /** * Returns the raw JSON value of [data]. @@ -56,7 +57,7 @@ private constructor( * * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success + @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -88,7 +89,7 @@ private constructor( class Builder internal constructor() { private var data: JsonField? = null - private var success: JsonField? = null + private var success: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic @@ -108,15 +109,16 @@ private constructor( */ fun data(data: JsonField) = apply { this.data = data } - fun success(success: Success) = success(JsonField.of(success)) + /** Indicates whether the request was successful */ + fun success(success: Boolean) = success(JsonField.of(success)) /** * Sets [Builder.success] to an arbitrary JSON value. * - * You should usually call [Builder.success] with a well-typed [Success] value instead. This + * You should usually call [Builder.success] with a well-typed [Boolean] value instead. This * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun success(success: JsonField) = apply { this.success = success } + fun success(success: JsonField) = apply { this.success = success } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -166,7 +168,7 @@ private constructor( } data().validate() - success().validate() + success() validated = true } @@ -185,8 +187,7 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (data.asKnown().getOrNull()?.validity() ?: 0) + - (success.asKnown().getOrNull()?.validity() ?: 0) + (data.asKnown().getOrNull()?.validity() ?: 0) + (if (success.asKnown().isPresent) 1 else 0) class Data @JsonCreator(mode = JsonCreator.Mode.DISABLED) @@ -355,124 +356,6 @@ private constructor( "Data{result=$result, actionId=$actionId, additionalProperties=$additionalProperties}" } - class Success @JsonCreator private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val TRUE = of(true) - - @JvmStatic fun of(value: Boolean) = Success(JsonField.of(value)) - } - - /** An enum containing [Success]'s known values. */ - enum class Known { - TRUE - } - - /** - * An enum containing [Success]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Success] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - TRUE, - /** An enum member indicating that [Success] was instantiated with an unknown value. */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - TRUE -> Value.TRUE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws StagehandInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - TRUE -> Known.TRUE - else -> throw StagehandInvalidDataException("Unknown Success: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * @throws StagehandInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asBoolean(): Boolean = - _value().asBoolean().orElseThrow { - StagehandInvalidDataException("Value is not a Boolean") - } - - private var validated: Boolean = false - - fun validate(): Success = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Success && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponse.kt index 56a53a4..2518477 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponse.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponse.kt @@ -2,7 +2,6 @@ package com.browserbase.api.models.sessions -import com.browserbase.api.core.Enum import com.browserbase.api.core.ExcludeMissing import com.browserbase.api.core.JsonField import com.browserbase.api.core.JsonMissing @@ -22,14 +21,14 @@ class SessionNavigateResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val data: JsonField, - private val success: JsonField, + private val success: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), - @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), + @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), ) : this(data, success, mutableMapOf()) /** @@ -39,10 +38,12 @@ private constructor( fun data(): Data = data.getRequired("data") /** + * Indicates whether the request was successful + * * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ - fun success(): Success = success.getRequired("success") + fun success(): Boolean = success.getRequired("success") /** * Returns the raw JSON value of [data]. @@ -56,7 +57,7 @@ private constructor( * * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success + @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -88,7 +89,7 @@ private constructor( class Builder internal constructor() { private var data: JsonField? = null - private var success: JsonField? = null + private var success: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic @@ -108,15 +109,16 @@ private constructor( */ fun data(data: JsonField) = apply { this.data = data } - fun success(success: Success) = success(JsonField.of(success)) + /** Indicates whether the request was successful */ + fun success(success: Boolean) = success(JsonField.of(success)) /** * Sets [Builder.success] to an arbitrary JSON value. * - * You should usually call [Builder.success] with a well-typed [Success] value instead. This + * You should usually call [Builder.success] with a well-typed [Boolean] value instead. This * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun success(success: JsonField) = apply { this.success = success } + fun success(success: JsonField) = apply { this.success = success } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -166,7 +168,7 @@ private constructor( } data().validate() - success().validate() + success() validated = true } @@ -185,8 +187,7 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (data.asKnown().getOrNull()?.validity() ?: 0) + - (success.asKnown().getOrNull()?.validity() ?: 0) + (data.asKnown().getOrNull()?.validity() ?: 0) + (if (success.asKnown().isPresent) 1 else 0) class Data @JsonCreator(mode = JsonCreator.Mode.DISABLED) @@ -355,124 +356,6 @@ private constructor( "Data{result=$result, actionId=$actionId, additionalProperties=$additionalProperties}" } - class Success @JsonCreator private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val TRUE = of(true) - - @JvmStatic fun of(value: Boolean) = Success(JsonField.of(value)) - } - - /** An enum containing [Success]'s known values. */ - enum class Known { - TRUE - } - - /** - * An enum containing [Success]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Success] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - TRUE, - /** An enum member indicating that [Success] was instantiated with an unknown value. */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - TRUE -> Value.TRUE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws StagehandInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - TRUE -> Known.TRUE - else -> throw StagehandInvalidDataException("Unknown Success: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * @throws StagehandInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asBoolean(): Boolean = - _value().asBoolean().orElseThrow { - StagehandInvalidDataException("Value is not a Boolean") - } - - private var validated: Boolean = false - - fun validate(): Success = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Success && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveResponse.kt index a06fd48..cb2404e 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveResponse.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveResponse.kt @@ -2,7 +2,6 @@ package com.browserbase.api.models.sessions -import com.browserbase.api.core.Enum import com.browserbase.api.core.ExcludeMissing import com.browserbase.api.core.JsonField import com.browserbase.api.core.JsonMissing @@ -24,14 +23,14 @@ class SessionObserveResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val data: JsonField, - private val success: JsonField, + private val success: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), - @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), + @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), ) : this(data, success, mutableMapOf()) /** @@ -41,10 +40,12 @@ private constructor( fun data(): Data = data.getRequired("data") /** + * Indicates whether the request was successful + * * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ - fun success(): Success = success.getRequired("success") + fun success(): Boolean = success.getRequired("success") /** * Returns the raw JSON value of [data]. @@ -58,7 +59,7 @@ private constructor( * * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success + @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -90,7 +91,7 @@ private constructor( class Builder internal constructor() { private var data: JsonField? = null - private var success: JsonField? = null + private var success: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic @@ -110,15 +111,16 @@ private constructor( */ fun data(data: JsonField) = apply { this.data = data } - fun success(success: Success) = success(JsonField.of(success)) + /** Indicates whether the request was successful */ + fun success(success: Boolean) = success(JsonField.of(success)) /** * Sets [Builder.success] to an arbitrary JSON value. * - * You should usually call [Builder.success] with a well-typed [Success] value instead. This + * You should usually call [Builder.success] with a well-typed [Boolean] value instead. This * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun success(success: JsonField) = apply { this.success = success } + fun success(success: JsonField) = apply { this.success = success } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -168,7 +170,7 @@ private constructor( } data().validate() - success().validate() + success() validated = true } @@ -187,8 +189,7 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (data.asKnown().getOrNull()?.validity() ?: 0) + - (success.asKnown().getOrNull()?.validity() ?: 0) + (data.asKnown().getOrNull()?.validity() ?: 0) + (if (success.asKnown().isPresent) 1 else 0) class Data @JsonCreator(mode = JsonCreator.Mode.DISABLED) @@ -399,124 +400,6 @@ private constructor( "Data{result=$result, actionId=$actionId, additionalProperties=$additionalProperties}" } - class Success @JsonCreator private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val TRUE = of(true) - - @JvmStatic fun of(value: Boolean) = Success(JsonField.of(value)) - } - - /** An enum containing [Success]'s known values. */ - enum class Known { - TRUE - } - - /** - * An enum containing [Success]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Success] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - TRUE, - /** An enum member indicating that [Success] was instantiated with an unknown value. */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - TRUE -> Value.TRUE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws StagehandInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - TRUE -> Known.TRUE - else -> throw StagehandInvalidDataException("Unknown Success: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * @throws StagehandInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asBoolean(): Boolean = - _value().asBoolean().orElseThrow { - StagehandInvalidDataException("Value is not a Boolean") - } - - private var validated: Boolean = false - - fun validate(): Success = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Success && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt index 20ba71d..59c94ad 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt @@ -142,7 +142,7 @@ private constructor( * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ - fun verbose(): Optional = body.verbose() + fun verbose(): Optional = body.verbose() /** * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the @@ -229,7 +229,7 @@ private constructor( * * Unlike [verbose], this method doesn't throw if the JSON field has an unexpected type. */ - fun _verbose(): JsonField = body._verbose() + fun _verbose(): JsonField = body._verbose() /** * Returns the raw JSON value of [waitForCaptchaSolves]. @@ -459,15 +459,15 @@ private constructor( } /** Logging verbosity level (0=quiet, 1=normal, 2=debug) */ - fun verbose(verbose: Verbose) = apply { body.verbose(verbose) } + fun verbose(verbose: Long) = apply { body.verbose(verbose) } /** * Sets [Builder.verbose] to an arbitrary JSON value. * - * You should usually call [Builder.verbose] with a well-typed [Verbose] value instead. This + * You should usually call [Builder.verbose] with a well-typed [Long] value instead. This * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun verbose(verbose: JsonField) = apply { body.verbose(verbose) } + fun verbose(verbose: JsonField) = apply { body.verbose(verbose) } fun waitForCaptchaSolves(waitForCaptchaSolves: Boolean) = apply { body.waitForCaptchaSolves(waitForCaptchaSolves) @@ -653,7 +653,7 @@ private constructor( private val experimental: JsonField, private val selfHeal: JsonField, private val systemPrompt: JsonField, - private val verbose: JsonField, + private val verbose: JsonField, private val waitForCaptchaSolves: JsonField, private val additionalProperties: MutableMap, ) { @@ -689,7 +689,7 @@ private constructor( @JsonProperty("systemPrompt") @ExcludeMissing systemPrompt: JsonField = JsonMissing.of(), - @JsonProperty("verbose") @ExcludeMissing verbose: JsonField = JsonMissing.of(), + @JsonProperty("verbose") @ExcludeMissing verbose: JsonField = JsonMissing.of(), @JsonProperty("waitForCaptchaSolves") @ExcludeMissing waitForCaptchaSolves: JsonField = JsonMissing.of(), @@ -790,7 +790,7 @@ private constructor( * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ - fun verbose(): Optional = verbose.getOptional("verbose") + fun verbose(): Optional = verbose.getOptional("verbose") /** * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if @@ -893,7 +893,7 @@ private constructor( * * Unlike [verbose], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("verbose") @ExcludeMissing fun _verbose(): JsonField = verbose + @JsonProperty("verbose") @ExcludeMissing fun _verbose(): JsonField = verbose /** * Returns the raw JSON value of [waitForCaptchaSolves]. @@ -944,7 +944,7 @@ private constructor( private var experimental: JsonField = JsonMissing.of() private var selfHeal: JsonField = JsonMissing.of() private var systemPrompt: JsonField = JsonMissing.of() - private var verbose: JsonField = JsonMissing.of() + private var verbose: JsonField = JsonMissing.of() private var waitForCaptchaSolves: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -1098,16 +1098,16 @@ private constructor( } /** Logging verbosity level (0=quiet, 1=normal, 2=debug) */ - fun verbose(verbose: Verbose) = verbose(JsonField.of(verbose)) + fun verbose(verbose: Long) = verbose(JsonField.of(verbose)) /** * Sets [Builder.verbose] to an arbitrary JSON value. * - * You should usually call [Builder.verbose] with a well-typed [Verbose] value instead. + * You should usually call [Builder.verbose] with a well-typed [Long] value instead. * This method is primarily for setting the field to an undocumented or not yet * supported value. */ - fun verbose(verbose: JsonField) = apply { this.verbose = verbose } + fun verbose(verbose: JsonField) = apply { this.verbose = verbose } fun waitForCaptchaSolves(waitForCaptchaSolves: Boolean) = waitForCaptchaSolves(JsonField.of(waitForCaptchaSolves)) @@ -1189,7 +1189,7 @@ private constructor( experimental() selfHeal() systemPrompt() - verbose().ifPresent { it.validate() } + verbose() waitForCaptchaSolves() validated = true } @@ -1220,7 +1220,7 @@ private constructor( (if (experimental.asKnown().isPresent) 1 else 0) + (if (selfHeal.asKnown().isPresent) 1 else 0) + (if (systemPrompt.asKnown().isPresent) 1 else 0) + - (verbose.asKnown().getOrNull()?.validity() ?: 0) + + (if (verbose.asKnown().isPresent) 1 else 0) + (if (waitForCaptchaSolves.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { @@ -6084,7 +6084,7 @@ private constructor( class BrowserbaseProxyConfig @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - private val type: JsonField, + private val type: JsonValue, private val domainPattern: JsonField, private val geolocation: JsonField, private val additionalProperties: MutableMap, @@ -6092,9 +6092,7 @@ private constructor( @JsonCreator private constructor( - @JsonProperty("type") - @ExcludeMissing - type: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), @JsonProperty("domainPattern") @ExcludeMissing domainPattern: JsonField = JsonMissing.of(), @@ -6104,11 +6102,15 @@ private constructor( ) : this(type, domainPattern, geolocation, mutableMapOf()) /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected - * type or is unexpectedly missing or null (e.g. if the server responded with - * an unexpected value). + * Expected to always return the following: + * ```java + * JsonValue.from("browserbase") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the + * server responded with an unexpected value). */ - fun type(): Type = type.getRequired("type") + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** * @throws StagehandInvalidDataException if the JSON field has an unexpected @@ -6124,14 +6126,6 @@ private constructor( fun geolocation(): Optional = geolocation.getOptional("geolocation") - /** - * Returns the raw JSON value of [type]. - * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type - /** * Returns the raw JSON value of [domainPattern]. * @@ -6169,11 +6163,6 @@ private constructor( /** * Returns a mutable builder for constructing an instance of * [BrowserbaseProxyConfig]. - * - * The following fields are required: - * ```java - * .type() - * ``` */ @JvmStatic fun builder() = Builder() } @@ -6181,7 +6170,7 @@ private constructor( /** A builder for [BrowserbaseProxyConfig]. */ class Builder internal constructor() { - private var type: JsonField? = null + private var type: JsonValue = JsonValue.from("browserbase") private var domainPattern: JsonField = JsonMissing.of() private var geolocation: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = @@ -6196,16 +6185,19 @@ private constructor( browserbaseProxyConfig.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) - /** - * Sets [Builder.type] to an arbitrary JSON value. + * Sets the field to an arbitrary JSON value. * - * You should usually call [Builder.type] with a well-typed [Type] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. + * It is usually unnecessary to call this method because the field defaults + * to the following: + * ```java + * JsonValue.from("browserbase") + * ``` + * + * This method is primarily for setting the field to an undocumented or not + * yet supported value. */ - fun type(type: JsonField) = apply { this.type = type } + fun type(type: JsonValue) = apply { this.type = type } fun domainPattern(domainPattern: String) = domainPattern(JsonField.of(domainPattern)) @@ -6261,17 +6253,10 @@ private constructor( * Returns an immutable instance of [BrowserbaseProxyConfig]. * * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .type() - * ``` - * - * @throws IllegalStateException if any required field is unset. */ fun build(): BrowserbaseProxyConfig = BrowserbaseProxyConfig( - checkRequired("type", type), + type, domainPattern, geolocation, additionalProperties.toMutableMap(), @@ -6285,7 +6270,13 @@ private constructor( return@apply } - type().validate() + _type().let { + if (it != JsonValue.from("browserbase")) { + throw StagehandInvalidDataException( + "'type' is invalid, received $it" + ) + } + } domainPattern() geolocation().ifPresent { it.validate() } validated = true @@ -6307,139 +6298,10 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (type.asKnown().getOrNull()?.validity() ?: 0) + + type.let { if (it == JsonValue.from("browserbase")) 1 else 0 } + (if (domainPattern.asKnown().isPresent) 1 else 0) + (geolocation.asKnown().getOrNull()?.validity() ?: 0) - class Type - @JsonCreator - private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data - * that doesn't match any known member, and you want to know that value. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - companion object { - - @JvmField val BROWSERBASE = of("browserbase") - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - /** An enum containing [Type]'s known values. */ - enum class Known { - BROWSERBASE - } - - /** - * An enum containing [Type]'s known values, as well as an [_UNKNOWN] - * member. - * - * An instance of [Type] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API - * may respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - BROWSERBASE, - /** - * An enum member indicating that [Type] was instantiated with an - * unknown value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always - * known or if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - BROWSERBASE -> Value.BROWSERBASE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always - * known and don't want to throw for the unknown case. - * - * @throws StagehandInvalidDataException if this class instance's value is a - * not a known member. - */ - fun known(): Known = - when (this) { - BROWSERBASE -> Known.BROWSERBASE - else -> throw StagehandInvalidDataException("Unknown Type: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily - * for debugging and generally doesn't throw. - * - * @throws StagehandInvalidDataException if this class instance's value does - * not have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - StagehandInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Type = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this - * object recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - class Geolocation @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( @@ -6713,7 +6575,7 @@ private constructor( @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val server: JsonField, - private val type: JsonField, + private val type: JsonValue, private val domainPattern: JsonField, private val password: JsonField, private val username: JsonField, @@ -6725,9 +6587,7 @@ private constructor( @JsonProperty("server") @ExcludeMissing server: JsonField = JsonMissing.of(), - @JsonProperty("type") - @ExcludeMissing - type: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), @JsonProperty("domainPattern") @ExcludeMissing domainPattern: JsonField = JsonMissing.of(), @@ -6747,11 +6607,15 @@ private constructor( fun server(): String = server.getRequired("server") /** - * @throws StagehandInvalidDataException if the JSON field has an unexpected - * type or is unexpectedly missing or null (e.g. if the server responded with - * an unexpected value). + * Expected to always return the following: + * ```java + * JsonValue.from("external") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the + * server responded with an unexpected value). */ - fun type(): Type = type.getRequired("type") + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** * @throws StagehandInvalidDataException if the JSON field has an unexpected @@ -6782,14 +6646,6 @@ private constructor( @ExcludeMissing fun _server(): JsonField = server - /** - * Returns the raw JSON value of [type]. - * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type - /** * Returns the raw JSON value of [domainPattern]. * @@ -6841,7 +6697,6 @@ private constructor( * The following fields are required: * ```java * .server() - * .type() * ``` */ @JvmStatic fun builder() = Builder() @@ -6851,7 +6706,7 @@ private constructor( class Builder internal constructor() { private var server: JsonField? = null - private var type: JsonField? = null + private var type: JsonValue = JsonValue.from("external") private var domainPattern: JsonField = JsonMissing.of() private var password: JsonField = JsonMissing.of() private var username: JsonField = JsonMissing.of() @@ -6880,16 +6735,19 @@ private constructor( */ fun server(server: JsonField) = apply { this.server = server } - fun type(type: Type) = type(JsonField.of(type)) - /** - * Sets [Builder.type] to an arbitrary JSON value. + * Sets the field to an arbitrary JSON value. * - * You should usually call [Builder.type] with a well-typed [Type] value - * instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. + * It is usually unnecessary to call this method because the field defaults + * to the following: + * ```java + * JsonValue.from("external") + * ``` + * + * This method is primarily for setting the field to an undocumented or not + * yet supported value. */ - fun type(type: JsonField) = apply { this.type = type } + fun type(type: JsonValue) = apply { this.type = type } fun domainPattern(domainPattern: String) = domainPattern(JsonField.of(domainPattern)) @@ -6961,7 +6819,6 @@ private constructor( * The following fields are required: * ```java * .server() - * .type() * ``` * * @throws IllegalStateException if any required field is unset. @@ -6969,7 +6826,7 @@ private constructor( fun build(): ExternalProxyConfig = ExternalProxyConfig( checkRequired("server", server), - checkRequired("type", type), + type, domainPattern, password, username, @@ -6985,7 +6842,13 @@ private constructor( } server() - type().validate() + _type().let { + if (it != JsonValue.from("external")) { + throw StagehandInvalidDataException( + "'type' is invalid, received $it" + ) + } + } domainPattern() password() username() @@ -7009,140 +6872,11 @@ private constructor( @JvmSynthetic internal fun validity(): Int = (if (server.asKnown().isPresent) 1 else 0) + - (type.asKnown().getOrNull()?.validity() ?: 0) + + type.let { if (it == JsonValue.from("external")) 1 else 0 } + (if (domainPattern.asKnown().isPresent) 1 else 0) + (if (password.asKnown().isPresent) 1 else 0) + (if (username.asKnown().isPresent) 1 else 0) - class Type - @JsonCreator - private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data - * that doesn't match any known member, and you want to know that value. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - companion object { - - @JvmField val EXTERNAL = of("external") - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - /** An enum containing [Type]'s known values. */ - enum class Known { - EXTERNAL - } - - /** - * An enum containing [Type]'s known values, as well as an [_UNKNOWN] - * member. - * - * An instance of [Type] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API - * may respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - EXTERNAL, - /** - * An enum member indicating that [Type] was instantiated with an - * unknown value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always - * known or if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - EXTERNAL -> Value.EXTERNAL - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always - * known and don't want to throw for the unknown case. - * - * @throws StagehandInvalidDataException if this class instance's value is a - * not a known member. - */ - fun known(): Known = - when (this) { - EXTERNAL -> Known.EXTERNAL - else -> throw StagehandInvalidDataException("Unknown Type: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily - * for debugging and generally doesn't throw. - * - * @throws StagehandInvalidDataException if this class instance's value does - * not have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - StagehandInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - fun validate(): Type = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this - * object recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - override fun equals(other: Any?): Boolean { if (this === other) { return true @@ -7456,136 +7190,6 @@ private constructor( "BrowserbaseSessionCreateParams{browserSettings=$browserSettings, extensionId=$extensionId, keepAlive=$keepAlive, projectId=$projectId, proxies=$proxies, region=$region, timeout=$timeout, userMetadata=$userMetadata, additionalProperties=$additionalProperties}" } - /** Logging verbosity level (0=quiet, 1=normal, 2=debug) */ - class Verbose @JsonCreator private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val _0 = of(0.0) - - @JvmField val _1 = of(1.0) - - @JvmField val _2 = of(2.0) - - @JvmStatic fun of(value: Double) = Verbose(JsonField.of(value)) - } - - /** An enum containing [Verbose]'s known values. */ - enum class Known { - _0, - _1, - _2, - } - - /** - * An enum containing [Verbose]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Verbose] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - _0, - _1, - _2, - /** An enum member indicating that [Verbose] was instantiated with an unknown value. */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - _0 -> Value._0 - _1 -> Value._1 - _2 -> Value._2 - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws StagehandInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - _0 -> Known._0 - _1 -> Known._1 - _2 -> Known._2 - else -> throw StagehandInvalidDataException("Unknown Verbose: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * @throws StagehandInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asDouble(): Double = - _value().asNumber().getOrNull()?.toDouble() - ?: throw StagehandInvalidDataException("Value is not a Double") - - private var validated: Boolean = false - - fun validate(): Verbose = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Verbose && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - /** Client SDK language */ class XLanguage @JsonCreator private constructor(private val value: JsonField) : Enum { diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartResponse.kt index 420925f..a172070 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartResponse.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartResponse.kt @@ -2,7 +2,6 @@ package com.browserbase.api.models.sessions -import com.browserbase.api.core.Enum import com.browserbase.api.core.ExcludeMissing import com.browserbase.api.core.JsonField import com.browserbase.api.core.JsonMissing @@ -21,14 +20,14 @@ class SessionStartResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val data: JsonField, - private val success: JsonField, + private val success: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), - @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), + @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of(), ) : this(data, success, mutableMapOf()) /** @@ -38,10 +37,12 @@ private constructor( fun data(): Data = data.getRequired("data") /** + * Indicates whether the request was successful + * * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ - fun success(): Success = success.getRequired("success") + fun success(): Boolean = success.getRequired("success") /** * Returns the raw JSON value of [data]. @@ -55,7 +56,7 @@ private constructor( * * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success + @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -87,7 +88,7 @@ private constructor( class Builder internal constructor() { private var data: JsonField? = null - private var success: JsonField? = null + private var success: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic @@ -107,15 +108,16 @@ private constructor( */ fun data(data: JsonField) = apply { this.data = data } - fun success(success: Success) = success(JsonField.of(success)) + /** Indicates whether the request was successful */ + fun success(success: Boolean) = success(JsonField.of(success)) /** * Sets [Builder.success] to an arbitrary JSON value. * - * You should usually call [Builder.success] with a well-typed [Success] value instead. This + * You should usually call [Builder.success] with a well-typed [Boolean] value instead. This * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun success(success: JsonField) = apply { this.success = success } + fun success(success: JsonField) = apply { this.success = success } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -165,7 +167,7 @@ private constructor( } data().validate() - success().validate() + success() validated = true } @@ -184,8 +186,7 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (data.asKnown().getOrNull()?.validity() ?: 0) + - (success.asKnown().getOrNull()?.validity() ?: 0) + (data.asKnown().getOrNull()?.validity() ?: 0) + (if (success.asKnown().isPresent) 1 else 0) class Data @JsonCreator(mode = JsonCreator.Mode.DISABLED) @@ -388,124 +389,6 @@ private constructor( "Data{available=$available, sessionId=$sessionId, additionalProperties=$additionalProperties}" } - class Success @JsonCreator private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val TRUE = of(true) - - @JvmStatic fun of(value: Boolean) = Success(JsonField.of(value)) - } - - /** An enum containing [Success]'s known values. */ - enum class Known { - TRUE - } - - /** - * An enum containing [Success]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Success] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - TRUE, - /** An enum member indicating that [Success] was instantiated with an unknown value. */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - TRUE -> Value.TRUE - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws StagehandInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - TRUE -> Known.TRUE - else -> throw StagehandInvalidDataException("Unknown Success: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * @throws StagehandInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asBoolean(): Boolean = - _value().asBoolean().orElseThrow { - StagehandInvalidDataException("Value is not a Boolean") - } - - private var validated: Boolean = false - - fun validate(): Success = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Success && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - override fun equals(other: Any?): Boolean { if (this === other) { return true diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActResponseTest.kt index 000d7fd..f5e0363 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActResponseTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActResponseTest.kt @@ -33,7 +33,7 @@ internal class SessionActResponseTest { .actionId("actionId") .build() ) - .success(SessionActResponse.Success.TRUE) + .success(true) .build() assertThat(sessionActResponse.data()) @@ -57,7 +57,7 @@ internal class SessionActResponseTest { .actionId("actionId") .build() ) - assertThat(sessionActResponse.success()).isEqualTo(SessionActResponse.Success.TRUE) + assertThat(sessionActResponse.success()).isEqualTo(true) } @Test @@ -85,7 +85,7 @@ internal class SessionActResponseTest { .actionId("actionId") .build() ) - .success(SessionActResponse.Success.TRUE) + .success(true) .build() val roundtrippedSessionActResponse = diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt index 27a2a36..30e45db 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt @@ -11,17 +11,13 @@ internal class SessionEndResponseTest { @Test fun create() { - val sessionEndResponse = - SessionEndResponse.builder().success(SessionEndResponse.Success.TRUE).build() - - assertThat(sessionEndResponse.success()).isEqualTo(SessionEndResponse.Success.TRUE) + val sessionEndResponse = SessionEndResponse.builder().build() } @Test fun roundtrip() { val jsonMapper = jsonMapper() - val sessionEndResponse = - SessionEndResponse.builder().success(SessionEndResponse.Success.TRUE).build() + val sessionEndResponse = SessionEndResponse.builder().build() val roundtrippedSessionEndResponse = jsonMapper.readValue( diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteResponseTest.kt index d2fb4d9..85a2099 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteResponseTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteResponseTest.kt @@ -51,7 +51,7 @@ internal class SessionExecuteResponseTest { ) .build() ) - .success(SessionExecuteResponse.Success.TRUE) + .success(true) .build() assertThat(sessionExecuteResponse.data()) @@ -92,7 +92,7 @@ internal class SessionExecuteResponseTest { ) .build() ) - assertThat(sessionExecuteResponse.success()).isEqualTo(SessionExecuteResponse.Success.TRUE) + assertThat(sessionExecuteResponse.success()).isEqualTo(true) } @Test @@ -137,7 +137,7 @@ internal class SessionExecuteResponseTest { ) .build() ) - .success(SessionExecuteResponse.Success.TRUE) + .success(true) .build() val roundtrippedSessionExecuteResponse = diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractResponseTest.kt index 6cf7056..3f055cd 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractResponseTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractResponseTest.kt @@ -20,7 +20,7 @@ internal class SessionExtractResponseTest { .actionId("actionId") .build() ) - .success(SessionExtractResponse.Success.TRUE) + .success(true) .build() assertThat(sessionExtractResponse.data()) @@ -30,7 +30,7 @@ internal class SessionExtractResponseTest { .actionId("actionId") .build() ) - assertThat(sessionExtractResponse.success()).isEqualTo(SessionExtractResponse.Success.TRUE) + assertThat(sessionExtractResponse.success()).isEqualTo(true) } @Test @@ -44,7 +44,7 @@ internal class SessionExtractResponseTest { .actionId("actionId") .build() ) - .success(SessionExtractResponse.Success.TRUE) + .success(true) .build() val roundtrippedSessionExtractResponse = diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponseTest.kt index e02a0e3..bca29d9 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponseTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateResponseTest.kt @@ -20,7 +20,7 @@ internal class SessionNavigateResponseTest { .actionId("actionId") .build() ) - .success(SessionNavigateResponse.Success.TRUE) + .success(true) .build() assertThat(sessionNavigateResponse.data()) @@ -30,8 +30,7 @@ internal class SessionNavigateResponseTest { .actionId("actionId") .build() ) - assertThat(sessionNavigateResponse.success()) - .isEqualTo(SessionNavigateResponse.Success.TRUE) + assertThat(sessionNavigateResponse.success()).isEqualTo(true) } @Test @@ -45,7 +44,7 @@ internal class SessionNavigateResponseTest { .actionId("actionId") .build() ) - .success(SessionNavigateResponse.Success.TRUE) + .success(true) .build() val roundtrippedSessionNavigateResponse = diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveResponseTest.kt index e3d72c3..2cc31b8 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveResponseTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveResponseTest.kt @@ -26,7 +26,7 @@ internal class SessionObserveResponseTest { .actionId("actionId") .build() ) - .success(SessionObserveResponse.Success.TRUE) + .success(true) .build() assertThat(sessionObserveResponse.data()) @@ -43,7 +43,7 @@ internal class SessionObserveResponseTest { .actionId("actionId") .build() ) - assertThat(sessionObserveResponse.success()).isEqualTo(SessionObserveResponse.Success.TRUE) + assertThat(sessionObserveResponse.success()).isEqualTo(true) } @Test @@ -64,7 +64,7 @@ internal class SessionObserveResponseTest { .actionId("actionId") .build() ) - .success(SessionObserveResponse.Success.TRUE) + .success(true) .build() val roundtrippedSessionObserveResponse = diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt index 13ae538..0dc5811 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt @@ -153,7 +153,7 @@ internal class SessionStartParamsTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() } @@ -306,7 +306,7 @@ internal class SessionStartParamsTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() @@ -480,7 +480,7 @@ internal class SessionStartParamsTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() @@ -624,7 +624,7 @@ internal class SessionStartParamsTest { assertThat(body.experimental()).contains(true) assertThat(body.selfHeal()).contains(true) assertThat(body.systemPrompt()).contains("systemPrompt") - assertThat(body.verbose()).contains(SessionStartParams.Verbose._1) + assertThat(body.verbose()).contains(1L) assertThat(body.waitForCaptchaSolves()).contains(true) } diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartResponseTest.kt index 717d6d6..3af1696 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartResponseTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartResponseTest.kt @@ -19,7 +19,7 @@ internal class SessionStartResponseTest { .sessionId("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .build() ) - .success(SessionStartResponse.Success.TRUE) + .success(true) .build() assertThat(sessionStartResponse.data()) @@ -29,7 +29,7 @@ internal class SessionStartResponseTest { .sessionId("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .build() ) - assertThat(sessionStartResponse.success()).isEqualTo(SessionStartResponse.Success.TRUE) + assertThat(sessionStartResponse.success()).isEqualTo(true) } @Test @@ -43,7 +43,7 @@ internal class SessionStartResponseTest { .sessionId("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .build() ) - .success(SessionStartResponse.Success.TRUE) + .success(true) .build() val roundtrippedSessionStartResponse = diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt index 87af3f1..967794c 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt @@ -230,7 +230,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -410,7 +410,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -590,7 +590,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -770,7 +770,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -950,7 +950,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -1130,7 +1130,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -1310,7 +1310,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -1490,7 +1490,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -1670,7 +1670,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -1850,7 +1850,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -2030,7 +2030,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -2210,7 +2210,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -2390,7 +2390,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -2570,7 +2570,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -2750,7 +2750,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -2930,7 +2930,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -3108,7 +3108,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt index ecf30b0..beb2b92 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt @@ -192,7 +192,7 @@ internal class ServiceParamsTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .putAdditionalHeader("Secret-Header", "42") .putAdditionalQueryParam("secret_query_param", "42") diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt index 0011f6f..fd11f6e 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt @@ -406,7 +406,7 @@ internal class SessionServiceAsyncTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt index 3f62ca6..ba02cd0 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt @@ -400,7 +400,7 @@ internal class SessionServiceTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) From 28f7978e1f040169dbb20aa68efb8e5ceb9a34d2 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 18:56:01 +0000 Subject: [PATCH 09/13] feat(api): manual updates --- .stats.yml | 4 +- .../api/models/sessions/ModelConfig.kt | 116 +++--- .../api/models/sessions/SessionActParams.kt | 19 +- .../api/models/sessions/SessionEndResponse.kt | 73 ++-- .../models/sessions/SessionExecuteParams.kt | 19 +- .../models/sessions/SessionExtractParams.kt | 19 +- .../models/sessions/SessionObserveParams.kt | 19 +- .../api/models/sessions/SessionStartParams.kt | 352 +++++++++++------- .../api/models/sessions/ModelConfigTest.kt | 44 +-- .../models/sessions/SessionActParamsTest.kt | 8 +- .../models/sessions/SessionEndResponseTest.kt | 6 +- .../sessions/SessionExecuteParamsTest.kt | 8 +- .../sessions/SessionExtractParamsTest.kt | 8 +- .../sessions/SessionObserveParamsTest.kt | 8 +- .../models/sessions/SessionStartParamsTest.kt | 8 +- .../api/services/ErrorHandlingTest.kt | 34 +- .../api/services/ServiceParamsTest.kt | 4 +- .../services/async/SessionServiceAsyncTest.kt | 10 +- .../services/blocking/SessionServiceTest.kt | 10 +- .../api/proguard/ProGuardCompatibilityTest.kt | 2 +- 20 files changed, 473 insertions(+), 298 deletions(-) diff --git a/.stats.yml b/.stats.yml index 08f0cef..38ef77c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 7 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-d571232203ef4e00986a3245224267db6f8aaffdad57780f712e0694dc8d9e37.yml -openapi_spec_hash: d5d635dd7b24a2e1255c6f2a895253ff +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-817d1d4e845b1946dac8ee10fd34b3f533aa36f74ac598582ffb1b0399a5a932.yml +openapi_spec_hash: 9d856db62b34909fec94743235b3d7be config_hash: 88e87ba7021be93d267ecfc8f5e6b891 diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/ModelConfig.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/ModelConfig.kt index 0d210b0..e416a06 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/ModelConfig.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/ModelConfig.kt @@ -27,33 +27,44 @@ import java.util.Collections import java.util.Objects import java.util.Optional +/** + * Model name string with provider prefix (e.g., 'openai/gpt-5-nano', 'anthropic/claude-4.5-opus') + */ @JsonDeserialize(using = ModelConfig.Deserializer::class) @JsonSerialize(using = ModelConfig.Serializer::class) class ModelConfig private constructor( - private val string: String? = null, - private val unionMember1: UnionMember1? = null, + private val name: String? = null, + private val modelConfigObject: ModelConfigObject? = null, private val _json: JsonValue? = null, ) { - fun string(): Optional = Optional.ofNullable(string) + /** + * Model name string with provider prefix (e.g., 'openai/gpt-5-nano', + * 'anthropic/claude-4.5-opus') + */ + fun name(): Optional = Optional.ofNullable(name) - fun unionMember1(): Optional = Optional.ofNullable(unionMember1) + fun modelConfigObject(): Optional = Optional.ofNullable(modelConfigObject) - fun isString(): Boolean = string != null + fun isName(): Boolean = name != null - fun isUnionMember1(): Boolean = unionMember1 != null + fun isModelConfigObject(): Boolean = modelConfigObject != null - fun asString(): String = string.getOrThrow("string") + /** + * Model name string with provider prefix (e.g., 'openai/gpt-5-nano', + * 'anthropic/claude-4.5-opus') + */ + fun asName(): String = name.getOrThrow("name") - fun asUnionMember1(): UnionMember1 = unionMember1.getOrThrow("unionMember1") + fun asModelConfigObject(): ModelConfigObject = modelConfigObject.getOrThrow("modelConfigObject") fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T = when { - string != null -> visitor.visitString(string) - unionMember1 != null -> visitor.visitUnionMember1(unionMember1) + name != null -> visitor.visitName(name) + modelConfigObject != null -> visitor.visitModelConfigObject(modelConfigObject) else -> visitor.unknown(_json) } @@ -66,10 +77,10 @@ private constructor( accept( object : Visitor { - override fun visitString(string: String) {} + override fun visitName(name: String) {} - override fun visitUnionMember1(unionMember1: UnionMember1) { - unionMember1.validate() + override fun visitModelConfigObject(modelConfigObject: ModelConfigObject) { + modelConfigObject.validate() } } ) @@ -93,9 +104,10 @@ private constructor( internal fun validity(): Int = accept( object : Visitor { - override fun visitString(string: String) = 1 + override fun visitName(name: String) = 1 - override fun visitUnionMember1(unionMember1: UnionMember1) = unionMember1.validity() + override fun visitModelConfigObject(modelConfigObject: ModelConfigObject) = + modelConfigObject.validity() override fun unknown(json: JsonValue?) = 0 } @@ -106,25 +118,32 @@ private constructor( return true } - return other is ModelConfig && string == other.string && unionMember1 == other.unionMember1 + return other is ModelConfig && + name == other.name && + modelConfigObject == other.modelConfigObject } - override fun hashCode(): Int = Objects.hash(string, unionMember1) + override fun hashCode(): Int = Objects.hash(name, modelConfigObject) override fun toString(): String = when { - string != null -> "ModelConfig{string=$string}" - unionMember1 != null -> "ModelConfig{unionMember1=$unionMember1}" + name != null -> "ModelConfig{name=$name}" + modelConfigObject != null -> "ModelConfig{modelConfigObject=$modelConfigObject}" _json != null -> "ModelConfig{_unknown=$_json}" else -> throw IllegalStateException("Invalid ModelConfig") } companion object { - @JvmStatic fun ofString(string: String) = ModelConfig(string = string) + /** + * Model name string with provider prefix (e.g., 'openai/gpt-5-nano', + * 'anthropic/claude-4.5-opus') + */ + @JvmStatic fun ofName(name: String) = ModelConfig(name = name) @JvmStatic - fun ofUnionMember1(unionMember1: UnionMember1) = ModelConfig(unionMember1 = unionMember1) + fun ofModelConfigObject(modelConfigObject: ModelConfigObject) = + ModelConfig(modelConfigObject = modelConfigObject) } /** @@ -132,9 +151,13 @@ private constructor( */ interface Visitor { - fun visitString(string: String): T + /** + * Model name string with provider prefix (e.g., 'openai/gpt-5-nano', + * 'anthropic/claude-4.5-opus') + */ + fun visitName(name: String): T - fun visitUnionMember1(unionMember1: UnionMember1): T + fun visitModelConfigObject(modelConfigObject: ModelConfigObject): T /** * Maps an unknown variant of [ModelConfig] to a value of type [T]. @@ -157,11 +180,11 @@ private constructor( val bestMatches = sequenceOf( - tryDeserialize(node, jacksonTypeRef())?.let { - ModelConfig(unionMember1 = it, _json = json) + tryDeserialize(node, jacksonTypeRef())?.let { + ModelConfig(modelConfigObject = it, _json = json) }, tryDeserialize(node, jacksonTypeRef())?.let { - ModelConfig(string = it, _json = json) + ModelConfig(name = it, _json = json) }, ) .filterNotNull() @@ -187,15 +210,15 @@ private constructor( provider: SerializerProvider, ) { when { - value.string != null -> generator.writeObject(value.string) - value.unionMember1 != null -> generator.writeObject(value.unionMember1) + value.name != null -> generator.writeObject(value.name) + value.modelConfigObject != null -> generator.writeObject(value.modelConfigObject) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid ModelConfig") } } } - class UnionMember1 + class ModelConfigObject @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val modelName: JsonField, @@ -214,18 +237,24 @@ private constructor( ) : this(modelName, apiKey, baseUrl, mutableMapOf()) /** + * Model name string without prefix (e.g., 'gpt-5-nano', 'claude-4.5-opus') + * * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ fun modelName(): String = modelName.getRequired("modelName") /** + * API key for the model provider + * * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ fun apiKey(): Optional = apiKey.getOptional("apiKey") /** + * Base URL for the model provider + * * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ @@ -267,7 +296,7 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [UnionMember1]. + * Returns a mutable builder for constructing an instance of [ModelConfigObject]. * * The following fields are required: * ```java @@ -277,7 +306,7 @@ private constructor( @JvmStatic fun builder() = Builder() } - /** A builder for [UnionMember1]. */ + /** A builder for [ModelConfigObject]. */ class Builder internal constructor() { private var modelName: JsonField? = null @@ -286,13 +315,14 @@ private constructor( private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(unionMember1: UnionMember1) = apply { - modelName = unionMember1.modelName - apiKey = unionMember1.apiKey - baseUrl = unionMember1.baseUrl - additionalProperties = unionMember1.additionalProperties.toMutableMap() + internal fun from(modelConfigObject: ModelConfigObject) = apply { + modelName = modelConfigObject.modelName + apiKey = modelConfigObject.apiKey + baseUrl = modelConfigObject.baseUrl + additionalProperties = modelConfigObject.additionalProperties.toMutableMap() } + /** Model name string without prefix (e.g., 'gpt-5-nano', 'claude-4.5-opus') */ fun modelName(modelName: String) = modelName(JsonField.of(modelName)) /** @@ -304,6 +334,7 @@ private constructor( */ fun modelName(modelName: JsonField) = apply { this.modelName = modelName } + /** API key for the model provider */ fun apiKey(apiKey: String) = apiKey(JsonField.of(apiKey)) /** @@ -315,6 +346,7 @@ private constructor( */ fun apiKey(apiKey: JsonField) = apply { this.apiKey = apiKey } + /** Base URL for the model provider */ fun baseUrl(baseUrl: String) = baseUrl(JsonField.of(baseUrl)) /** @@ -346,7 +378,7 @@ private constructor( } /** - * Returns an immutable instance of [UnionMember1]. + * Returns an immutable instance of [ModelConfigObject]. * * Further updates to this [Builder] will not mutate the returned instance. * @@ -357,8 +389,8 @@ private constructor( * * @throws IllegalStateException if any required field is unset. */ - fun build(): UnionMember1 = - UnionMember1( + fun build(): ModelConfigObject = + ModelConfigObject( checkRequired("modelName", modelName), apiKey, baseUrl, @@ -368,7 +400,7 @@ private constructor( private var validated: Boolean = false - fun validate(): UnionMember1 = apply { + fun validate(): ModelConfigObject = apply { if (validated) { return@apply } @@ -404,7 +436,7 @@ private constructor( return true } - return other is UnionMember1 && + return other is ModelConfigObject && modelName == other.modelName && apiKey == other.apiKey && baseUrl == other.baseUrl && @@ -418,6 +450,6 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "UnionMember1{modelName=$modelName, apiKey=$apiKey, baseUrl=$baseUrl, additionalProperties=$additionalProperties}" + "ModelConfigObject{modelName=$modelName, apiKey=$apiKey, baseUrl=$baseUrl, additionalProperties=$additionalProperties}" } } diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt index 7e98b5d..019f026 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt @@ -1133,6 +1133,9 @@ private constructor( ) : this(model, timeout, variables, mutableMapOf()) /** + * Model name string with provider prefix (e.g., 'openai/gpt-5-nano', + * 'anthropic/claude-4.5-opus') + * * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ @@ -1211,6 +1214,10 @@ private constructor( additionalProperties = options.additionalProperties.toMutableMap() } + /** + * Model name string with provider prefix (e.g., 'openai/gpt-5-nano', + * 'anthropic/claude-4.5-opus') + */ fun model(model: ModelConfig) = model(JsonField.of(model)) /** @@ -1222,12 +1229,14 @@ private constructor( */ fun model(model: JsonField) = apply { this.model = model } - /** Alias for calling [model] with `ModelConfig.ofString(string)`. */ - fun model(string: String) = model(ModelConfig.ofString(string)) + /** Alias for calling [model] with `ModelConfig.ofName(name)`. */ + fun model(name: String) = model(ModelConfig.ofName(name)) - /** Alias for calling [model] with `ModelConfig.ofUnionMember1(unionMember1)`. */ - fun model(unionMember1: ModelConfig.UnionMember1) = - model(ModelConfig.ofUnionMember1(unionMember1)) + /** + * Alias for calling [model] with `ModelConfig.ofModelConfigObject(modelConfigObject)`. + */ + fun model(modelConfigObject: ModelConfig.ModelConfigObject) = + model(ModelConfig.ofModelConfigObject(modelConfigObject)) /** Timeout in ms for the action */ fun timeout(timeout: Double) = timeout(JsonField.of(timeout)) diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt index 3345222..3a886e7 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionEndResponse.kt @@ -3,8 +3,10 @@ package com.browserbase.api.models.sessions import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonField import com.browserbase.api.core.JsonMissing import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.checkRequired import com.browserbase.api.errors.StagehandInvalidDataException import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter @@ -16,25 +18,29 @@ import java.util.Objects class SessionEndResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - private val success: JsonValue, + private val success: JsonField, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("success") @ExcludeMissing success: JsonValue = JsonMissing.of() + @JsonProperty("success") @ExcludeMissing success: JsonField = JsonMissing.of() ) : this(success, mutableMapOf()) /** - * Expected to always return the following: - * ```java - * JsonValue.from(true) - * ``` + * Indicates whether the request was successful * - * However, this method can be useful for debugging and logging (e.g. if the server responded - * with an unexpected value). + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ - @JsonProperty("success") @ExcludeMissing fun _success(): JsonValue = success + fun success(): Boolean = success.getRequired("success") + + /** + * Returns the raw JSON value of [success]. + * + * Unlike [success], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("success") @ExcludeMissing fun _success(): JsonField = success @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -50,14 +56,21 @@ private constructor( companion object { - /** Returns a mutable builder for constructing an instance of [SessionEndResponse]. */ + /** + * Returns a mutable builder for constructing an instance of [SessionEndResponse]. + * + * The following fields are required: + * ```java + * .success() + * ``` + */ @JvmStatic fun builder() = Builder() } /** A builder for [SessionEndResponse]. */ class Builder internal constructor() { - private var success: JsonValue = JsonValue.from(true) + private var success: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic @@ -66,19 +79,16 @@ private constructor( additionalProperties = sessionEndResponse.additionalProperties.toMutableMap() } + /** Indicates whether the request was successful */ + fun success(success: Boolean) = success(JsonField.of(success)) + /** - * Sets the field to an arbitrary JSON value. + * Sets [Builder.success] to an arbitrary JSON value. * - * It is usually unnecessary to call this method because the field defaults to the - * following: - * ```java - * JsonValue.from(true) - * ``` - * - * This method is primarily for setting the field to an undocumented or not yet supported - * value. + * You should usually call [Builder.success] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun success(success: JsonValue) = apply { this.success = success } + fun success(success: JsonField) = apply { this.success = success } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -103,9 +113,19 @@ private constructor( * Returns an immutable instance of [SessionEndResponse]. * * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .success() + * ``` + * + * @throws IllegalStateException if any required field is unset. */ fun build(): SessionEndResponse = - SessionEndResponse(success, additionalProperties.toMutableMap()) + SessionEndResponse( + checkRequired("success", success), + additionalProperties.toMutableMap(), + ) } private var validated: Boolean = false @@ -115,11 +135,7 @@ private constructor( return@apply } - _success().let { - if (it != JsonValue.from(true)) { - throw StagehandInvalidDataException("'success' is invalid, received $it") - } - } + success() validated = true } @@ -136,8 +152,7 @@ private constructor( * * Used for best match union deserialization. */ - @JvmSynthetic - internal fun validity(): Int = success.let { if (it == JsonValue.from(true)) 1 else 0 } + @JvmSynthetic internal fun validity(): Int = (if (success.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { if (this === other) { diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteParams.kt index 4b615cf..73880ff 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteParams.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExecuteParams.kt @@ -657,6 +657,9 @@ private constructor( fun cua(): Optional = cua.getOptional("cua") /** + * Model name string with provider prefix (e.g., 'openai/gpt-5-nano', + * 'anthropic/claude-4.5-opus') + * * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ @@ -740,6 +743,10 @@ private constructor( */ fun cua(cua: JsonField) = apply { this.cua = cua } + /** + * Model name string with provider prefix (e.g., 'openai/gpt-5-nano', + * 'anthropic/claude-4.5-opus') + */ fun model(model: ModelConfig) = model(JsonField.of(model)) /** @@ -751,12 +758,14 @@ private constructor( */ fun model(model: JsonField) = apply { this.model = model } - /** Alias for calling [model] with `ModelConfig.ofString(string)`. */ - fun model(string: String) = model(ModelConfig.ofString(string)) + /** Alias for calling [model] with `ModelConfig.ofName(name)`. */ + fun model(name: String) = model(ModelConfig.ofName(name)) - /** Alias for calling [model] with `ModelConfig.ofUnionMember1(unionMember1)`. */ - fun model(unionMember1: ModelConfig.UnionMember1) = - model(ModelConfig.ofUnionMember1(unionMember1)) + /** + * Alias for calling [model] with `ModelConfig.ofModelConfigObject(modelConfigObject)`. + */ + fun model(modelConfigObject: ModelConfig.ModelConfigObject) = + model(ModelConfig.ofModelConfigObject(modelConfigObject)) /** Custom system prompt for the agent */ fun systemPrompt(systemPrompt: String) = systemPrompt(JsonField.of(systemPrompt)) diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractParams.kt index b86cdc3..3a5c4bd 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractParams.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionExtractParams.kt @@ -666,6 +666,9 @@ private constructor( ) : this(model, selector, timeout, mutableMapOf()) /** + * Model name string with provider prefix (e.g., 'openai/gpt-5-nano', + * 'anthropic/claude-4.5-opus') + * * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ @@ -742,6 +745,10 @@ private constructor( additionalProperties = options.additionalProperties.toMutableMap() } + /** + * Model name string with provider prefix (e.g., 'openai/gpt-5-nano', + * 'anthropic/claude-4.5-opus') + */ fun model(model: ModelConfig) = model(JsonField.of(model)) /** @@ -753,12 +760,14 @@ private constructor( */ fun model(model: JsonField) = apply { this.model = model } - /** Alias for calling [model] with `ModelConfig.ofString(string)`. */ - fun model(string: String) = model(ModelConfig.ofString(string)) + /** Alias for calling [model] with `ModelConfig.ofName(name)`. */ + fun model(name: String) = model(ModelConfig.ofName(name)) - /** Alias for calling [model] with `ModelConfig.ofUnionMember1(unionMember1)`. */ - fun model(unionMember1: ModelConfig.UnionMember1) = - model(ModelConfig.ofUnionMember1(unionMember1)) + /** + * Alias for calling [model] with `ModelConfig.ofModelConfigObject(modelConfigObject)`. + */ + fun model(modelConfigObject: ModelConfig.ModelConfigObject) = + model(ModelConfig.ofModelConfigObject(modelConfigObject)) /** CSS selector to scope extraction to a specific element */ fun selector(selector: String) = selector(JsonField.of(selector)) diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveParams.kt index 7e40f70..66c3b91 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveParams.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveParams.kt @@ -606,6 +606,9 @@ private constructor( ) : this(model, selector, timeout, mutableMapOf()) /** + * Model name string with provider prefix (e.g., 'openai/gpt-5-nano', + * 'anthropic/claude-4.5-opus') + * * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ @@ -682,6 +685,10 @@ private constructor( additionalProperties = options.additionalProperties.toMutableMap() } + /** + * Model name string with provider prefix (e.g., 'openai/gpt-5-nano', + * 'anthropic/claude-4.5-opus') + */ fun model(model: ModelConfig) = model(JsonField.of(model)) /** @@ -693,12 +700,14 @@ private constructor( */ fun model(model: JsonField) = apply { this.model = model } - /** Alias for calling [model] with `ModelConfig.ofString(string)`. */ - fun model(string: String) = model(ModelConfig.ofString(string)) + /** Alias for calling [model] with `ModelConfig.ofName(name)`. */ + fun model(name: String) = model(ModelConfig.ofName(name)) - /** Alias for calling [model] with `ModelConfig.ofUnionMember1(unionMember1)`. */ - fun model(unionMember1: ModelConfig.UnionMember1) = - model(ModelConfig.ofUnionMember1(unionMember1)) + /** + * Alias for calling [model] with `ModelConfig.ofModelConfigObject(modelConfigObject)`. + */ + fun model(modelConfigObject: ModelConfig.ModelConfigObject) = + model(ModelConfig.ofModelConfigObject(modelConfigObject)) /** CSS selector to scope observation to a specific element */ fun selector(selector: String) = selector(JsonField.of(selector)) diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt index 59c94ad..57f072f 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt @@ -142,7 +142,7 @@ private constructor( * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ - fun verbose(): Optional = body.verbose() + fun verbose(): Optional = body.verbose() /** * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the @@ -229,7 +229,7 @@ private constructor( * * Unlike [verbose], this method doesn't throw if the JSON field has an unexpected type. */ - fun _verbose(): JsonField = body._verbose() + fun _verbose(): JsonField = body._verbose() /** * Returns the raw JSON value of [waitForCaptchaSolves]. @@ -459,15 +459,15 @@ private constructor( } /** Logging verbosity level (0=quiet, 1=normal, 2=debug) */ - fun verbose(verbose: Long) = apply { body.verbose(verbose) } + fun verbose(verbose: Verbose) = apply { body.verbose(verbose) } /** * Sets [Builder.verbose] to an arbitrary JSON value. * - * You should usually call [Builder.verbose] with a well-typed [Long] value instead. This + * You should usually call [Builder.verbose] with a well-typed [Verbose] value instead. This * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun verbose(verbose: JsonField) = apply { body.verbose(verbose) } + fun verbose(verbose: JsonField) = apply { body.verbose(verbose) } fun waitForCaptchaSolves(waitForCaptchaSolves: Boolean) = apply { body.waitForCaptchaSolves(waitForCaptchaSolves) @@ -653,7 +653,7 @@ private constructor( private val experimental: JsonField, private val selfHeal: JsonField, private val systemPrompt: JsonField, - private val verbose: JsonField, + private val verbose: JsonField, private val waitForCaptchaSolves: JsonField, private val additionalProperties: MutableMap, ) { @@ -689,7 +689,7 @@ private constructor( @JsonProperty("systemPrompt") @ExcludeMissing systemPrompt: JsonField = JsonMissing.of(), - @JsonProperty("verbose") @ExcludeMissing verbose: JsonField = JsonMissing.of(), + @JsonProperty("verbose") @ExcludeMissing verbose: JsonField = JsonMissing.of(), @JsonProperty("waitForCaptchaSolves") @ExcludeMissing waitForCaptchaSolves: JsonField = JsonMissing.of(), @@ -790,7 +790,7 @@ private constructor( * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ - fun verbose(): Optional = verbose.getOptional("verbose") + fun verbose(): Optional = verbose.getOptional("verbose") /** * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if @@ -893,7 +893,7 @@ private constructor( * * Unlike [verbose], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("verbose") @ExcludeMissing fun _verbose(): JsonField = verbose + @JsonProperty("verbose") @ExcludeMissing fun _verbose(): JsonField = verbose /** * Returns the raw JSON value of [waitForCaptchaSolves]. @@ -944,7 +944,7 @@ private constructor( private var experimental: JsonField = JsonMissing.of() private var selfHeal: JsonField = JsonMissing.of() private var systemPrompt: JsonField = JsonMissing.of() - private var verbose: JsonField = JsonMissing.of() + private var verbose: JsonField = JsonMissing.of() private var waitForCaptchaSolves: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -1098,16 +1098,16 @@ private constructor( } /** Logging verbosity level (0=quiet, 1=normal, 2=debug) */ - fun verbose(verbose: Long) = verbose(JsonField.of(verbose)) + fun verbose(verbose: Verbose) = verbose(JsonField.of(verbose)) /** * Sets [Builder.verbose] to an arbitrary JSON value. * - * You should usually call [Builder.verbose] with a well-typed [Long] value instead. + * You should usually call [Builder.verbose] with a well-typed [Verbose] value instead. * This method is primarily for setting the field to an undocumented or not yet * supported value. */ - fun verbose(verbose: JsonField) = apply { this.verbose = verbose } + fun verbose(verbose: JsonField) = apply { this.verbose = verbose } fun waitForCaptchaSolves(waitForCaptchaSolves: Boolean) = waitForCaptchaSolves(JsonField.of(waitForCaptchaSolves)) @@ -1189,7 +1189,7 @@ private constructor( experimental() selfHeal() systemPrompt() - verbose() + verbose().ifPresent { it.validate() } waitForCaptchaSolves() validated = true } @@ -1220,7 +1220,7 @@ private constructor( (if (experimental.asKnown().isPresent) 1 else 0) + (if (selfHeal.asKnown().isPresent) 1 else 0) + (if (systemPrompt.asKnown().isPresent) 1 else 0) + - (if (verbose.asKnown().isPresent) 1 else 0) + + (verbose.asKnown().getOrNull()?.validity() ?: 0) + (if (waitForCaptchaSolves.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { @@ -5862,35 +5862,29 @@ private constructor( @JsonSerialize(using = UnnamedSchemaWithArrayParent0.Serializer::class) class UnnamedSchemaWithArrayParent0 private constructor( - private val browserbaseProxyConfig: BrowserbaseProxyConfig? = null, - private val externalProxyConfig: ExternalProxyConfig? = null, + private val browserbase: Browserbase? = null, + private val external: External? = null, private val _json: JsonValue? = null, ) { - fun browserbaseProxyConfig(): Optional = - Optional.ofNullable(browserbaseProxyConfig) + fun browserbase(): Optional = Optional.ofNullable(browserbase) - fun externalProxyConfig(): Optional = - Optional.ofNullable(externalProxyConfig) + fun external(): Optional = Optional.ofNullable(external) - fun isBrowserbaseProxyConfig(): Boolean = browserbaseProxyConfig != null + fun isBrowserbase(): Boolean = browserbase != null - fun isExternalProxyConfig(): Boolean = externalProxyConfig != null + fun isExternal(): Boolean = external != null - fun asBrowserbaseProxyConfig(): BrowserbaseProxyConfig = - browserbaseProxyConfig.getOrThrow("browserbaseProxyConfig") + fun asBrowserbase(): Browserbase = browserbase.getOrThrow("browserbase") - fun asExternalProxyConfig(): ExternalProxyConfig = - externalProxyConfig.getOrThrow("externalProxyConfig") + fun asExternal(): External = external.getOrThrow("external") fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T = when { - browserbaseProxyConfig != null -> - visitor.visitBrowserbaseProxyConfig(browserbaseProxyConfig) - externalProxyConfig != null -> - visitor.visitExternalProxyConfig(externalProxyConfig) + browserbase != null -> visitor.visitBrowserbase(browserbase) + external != null -> visitor.visitExternal(external) else -> visitor.unknown(_json) } @@ -5903,16 +5897,12 @@ private constructor( accept( object : Visitor { - override fun visitBrowserbaseProxyConfig( - browserbaseProxyConfig: BrowserbaseProxyConfig - ) { - browserbaseProxyConfig.validate() + override fun visitBrowserbase(browserbase: Browserbase) { + browserbase.validate() } - override fun visitExternalProxyConfig( - externalProxyConfig: ExternalProxyConfig - ) { - externalProxyConfig.validate() + override fun visitExternal(external: External) { + external.validate() } } ) @@ -5937,13 +5927,10 @@ private constructor( internal fun validity(): Int = accept( object : Visitor { - override fun visitBrowserbaseProxyConfig( - browserbaseProxyConfig: BrowserbaseProxyConfig - ) = browserbaseProxyConfig.validity() + override fun visitBrowserbase(browserbase: Browserbase) = + browserbase.validity() - override fun visitExternalProxyConfig( - externalProxyConfig: ExternalProxyConfig - ) = externalProxyConfig.validity() + override fun visitExternal(external: External) = external.validity() override fun unknown(json: JsonValue?) = 0 } @@ -5955,19 +5942,17 @@ private constructor( } return other is UnnamedSchemaWithArrayParent0 && - browserbaseProxyConfig == other.browserbaseProxyConfig && - externalProxyConfig == other.externalProxyConfig + browserbase == other.browserbase && + external == other.external } - override fun hashCode(): Int = - Objects.hash(browserbaseProxyConfig, externalProxyConfig) + override fun hashCode(): Int = Objects.hash(browserbase, external) override fun toString(): String = when { - browserbaseProxyConfig != null -> - "UnnamedSchemaWithArrayParent0{browserbaseProxyConfig=$browserbaseProxyConfig}" - externalProxyConfig != null -> - "UnnamedSchemaWithArrayParent0{externalProxyConfig=$externalProxyConfig}" + browserbase != null -> + "UnnamedSchemaWithArrayParent0{browserbase=$browserbase}" + external != null -> "UnnamedSchemaWithArrayParent0{external=$external}" _json != null -> "UnnamedSchemaWithArrayParent0{_unknown=$_json}" else -> throw IllegalStateException("Invalid UnnamedSchemaWithArrayParent0") } @@ -5975,14 +5960,12 @@ private constructor( companion object { @JvmStatic - fun ofBrowserbaseProxyConfig(browserbaseProxyConfig: BrowserbaseProxyConfig) = - UnnamedSchemaWithArrayParent0( - browserbaseProxyConfig = browserbaseProxyConfig - ) + fun ofBrowserbase(browserbase: Browserbase) = + UnnamedSchemaWithArrayParent0(browserbase = browserbase) @JvmStatic - fun ofExternalProxyConfig(externalProxyConfig: ExternalProxyConfig) = - UnnamedSchemaWithArrayParent0(externalProxyConfig = externalProxyConfig) + fun ofExternal(external: External) = + UnnamedSchemaWithArrayParent0(external = external) } /** @@ -5991,11 +5974,9 @@ private constructor( */ interface Visitor { - fun visitBrowserbaseProxyConfig( - browserbaseProxyConfig: BrowserbaseProxyConfig - ): T + fun visitBrowserbase(browserbase: Browserbase): T - fun visitExternalProxyConfig(externalProxyConfig: ExternalProxyConfig): T + fun visitExternal(external: External): T /** * Maps an unknown variant of [UnnamedSchemaWithArrayParent0] to a value of type @@ -6024,38 +6005,22 @@ private constructor( node: JsonNode ): UnnamedSchemaWithArrayParent0 { val json = JsonValue.fromJsonNode(node) + val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { - UnnamedSchemaWithArrayParent0( - browserbaseProxyConfig = it, - _json = json, - ) - }, - tryDeserialize(node, jacksonTypeRef()) - ?.let { - UnnamedSchemaWithArrayParent0( - externalProxyConfig = it, - _json = json, - ) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely - // incompatible with all the possible variants (e.g. deserializing from - // boolean). - 0 -> UnnamedSchemaWithArrayParent0(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then use - // the first completely valid match, or simply the first match if none - // are completely valid. - else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + when (type) { + "browserbase" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + UnnamedSchemaWithArrayParent0(browserbase = it, _json = json) + } ?: UnnamedSchemaWithArrayParent0(_json = json) + } + "external" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + UnnamedSchemaWithArrayParent0(external = it, _json = json) + } ?: UnnamedSchemaWithArrayParent0(_json = json) + } } + + return UnnamedSchemaWithArrayParent0(_json = json) } } @@ -6070,10 +6035,8 @@ private constructor( provider: SerializerProvider, ) { when { - value.browserbaseProxyConfig != null -> - generator.writeObject(value.browserbaseProxyConfig) - value.externalProxyConfig != null -> - generator.writeObject(value.externalProxyConfig) + value.browserbase != null -> generator.writeObject(value.browserbase) + value.external != null -> generator.writeObject(value.external) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid UnnamedSchemaWithArrayParent0") @@ -6081,7 +6044,7 @@ private constructor( } } - class BrowserbaseProxyConfig + class Browserbase @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val type: JsonValue, @@ -6161,13 +6124,12 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of - * [BrowserbaseProxyConfig]. + * Returns a mutable builder for constructing an instance of [Browserbase]. */ @JvmStatic fun builder() = Builder() } - /** A builder for [BrowserbaseProxyConfig]. */ + /** A builder for [Browserbase]. */ class Builder internal constructor() { private var type: JsonValue = JsonValue.from("browserbase") @@ -6177,12 +6139,11 @@ private constructor( mutableMapOf() @JvmSynthetic - internal fun from(browserbaseProxyConfig: BrowserbaseProxyConfig) = apply { - type = browserbaseProxyConfig.type - domainPattern = browserbaseProxyConfig.domainPattern - geolocation = browserbaseProxyConfig.geolocation - additionalProperties = - browserbaseProxyConfig.additionalProperties.toMutableMap() + internal fun from(browserbase: Browserbase) = apply { + type = browserbase.type + domainPattern = browserbase.domainPattern + geolocation = browserbase.geolocation + additionalProperties = browserbase.additionalProperties.toMutableMap() } /** @@ -6250,12 +6211,12 @@ private constructor( } /** - * Returns an immutable instance of [BrowserbaseProxyConfig]. + * Returns an immutable instance of [Browserbase]. * * Further updates to this [Builder] will not mutate the returned instance. */ - fun build(): BrowserbaseProxyConfig = - BrowserbaseProxyConfig( + fun build(): Browserbase = + Browserbase( type, domainPattern, geolocation, @@ -6265,7 +6226,7 @@ private constructor( private var validated: Boolean = false - fun validate(): BrowserbaseProxyConfig = apply { + fun validate(): Browserbase = apply { if (validated) { return@apply } @@ -6554,7 +6515,7 @@ private constructor( return true } - return other is BrowserbaseProxyConfig && + return other is Browserbase && type == other.type && domainPattern == other.domainPattern && geolocation == other.geolocation && @@ -6568,10 +6529,10 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "BrowserbaseProxyConfig{type=$type, domainPattern=$domainPattern, geolocation=$geolocation, additionalProperties=$additionalProperties}" + "Browserbase{type=$type, domainPattern=$domainPattern, geolocation=$geolocation, additionalProperties=$additionalProperties}" } - class ExternalProxyConfig + class External @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val server: JsonField, @@ -6691,8 +6652,7 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of - * [ExternalProxyConfig]. + * Returns a mutable builder for constructing an instance of [External]. * * The following fields are required: * ```java @@ -6702,7 +6662,7 @@ private constructor( @JvmStatic fun builder() = Builder() } - /** A builder for [ExternalProxyConfig]. */ + /** A builder for [External]. */ class Builder internal constructor() { private var server: JsonField? = null @@ -6714,14 +6674,13 @@ private constructor( mutableMapOf() @JvmSynthetic - internal fun from(externalProxyConfig: ExternalProxyConfig) = apply { - server = externalProxyConfig.server - type = externalProxyConfig.type - domainPattern = externalProxyConfig.domainPattern - password = externalProxyConfig.password - username = externalProxyConfig.username - additionalProperties = - externalProxyConfig.additionalProperties.toMutableMap() + internal fun from(external: External) = apply { + server = external.server + type = external.type + domainPattern = external.domainPattern + password = external.password + username = external.username + additionalProperties = external.additionalProperties.toMutableMap() } fun server(server: String) = server(JsonField.of(server)) @@ -6812,7 +6771,7 @@ private constructor( } /** - * Returns an immutable instance of [ExternalProxyConfig]. + * Returns an immutable instance of [External]. * * Further updates to this [Builder] will not mutate the returned instance. * @@ -6823,8 +6782,8 @@ private constructor( * * @throws IllegalStateException if any required field is unset. */ - fun build(): ExternalProxyConfig = - ExternalProxyConfig( + fun build(): External = + External( checkRequired("server", server), type, domainPattern, @@ -6836,7 +6795,7 @@ private constructor( private var validated: Boolean = false - fun validate(): ExternalProxyConfig = apply { + fun validate(): External = apply { if (validated) { return@apply } @@ -6882,7 +6841,7 @@ private constructor( return true } - return other is ExternalProxyConfig && + return other is External && server == other.server && type == other.type && domainPattern == other.domainPattern && @@ -6905,7 +6864,7 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "ExternalProxyConfig{server=$server, type=$type, domainPattern=$domainPattern, password=$password, username=$username, additionalProperties=$additionalProperties}" + "External{server=$server, type=$type, domainPattern=$domainPattern, password=$password, username=$username, additionalProperties=$additionalProperties}" } } } @@ -7190,6 +7149,137 @@ private constructor( "BrowserbaseSessionCreateParams{browserSettings=$browserSettings, extensionId=$extensionId, keepAlive=$keepAlive, projectId=$projectId, proxies=$proxies, region=$region, timeout=$timeout, userMetadata=$userMetadata, additionalProperties=$additionalProperties}" } + /** Logging verbosity level (0=quiet, 1=normal, 2=debug) */ + class Verbose @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val _0 = of(0L) + + @JvmField val _1 = of(1L) + + @JvmField val _2 = of(2L) + + @JvmStatic fun of(value: Long) = Verbose(JsonField.of(value)) + } + + /** An enum containing [Verbose]'s known values. */ + enum class Known { + _0, + _1, + _2, + } + + /** + * An enum containing [Verbose]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Verbose] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + _0, + _1, + _2, + /** An enum member indicating that [Verbose] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + _0 -> Value._0 + _1 -> Value._1 + _2 -> Value._2 + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + _0 -> Known._0 + _1 -> Known._1 + _2 -> Known._2 + else -> throw StagehandInvalidDataException("Unknown Verbose: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asLong(): Long = + _value().asNumber().getOrNull()?.let { + if (it.toDouble() % 1 == 0.0) it.toLong() else null + } ?: throw StagehandInvalidDataException("Value is not a Long") + + private var validated: Boolean = false + + fun validate(): Verbose = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Verbose && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + /** Client SDK language */ class XLanguage @JsonCreator private constructor(private val value: JsonField) : Enum { diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/ModelConfigTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/ModelConfigTest.kt index b45bc3f..d83a01a 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/ModelConfigTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/ModelConfigTest.kt @@ -13,19 +13,19 @@ import org.junit.jupiter.api.assertThrows internal class ModelConfigTest { @Test - fun ofString() { - val string = "string" + fun ofName() { + val name = "openai/gpt-5-nano" - val modelConfig = ModelConfig.ofString(string) + val modelConfig = ModelConfig.ofName(name) - assertThat(modelConfig.string()).contains(string) - assertThat(modelConfig.unionMember1()).isEmpty + assertThat(modelConfig.name()).contains(name) + assertThat(modelConfig.modelConfigObject()).isEmpty } @Test - fun ofStringRoundtrip() { + fun ofNameRoundtrip() { val jsonMapper = jsonMapper() - val modelConfig = ModelConfig.ofString("string") + val modelConfig = ModelConfig.ofName("openai/gpt-5-nano") val roundtrippedModelConfig = jsonMapper.readValue( @@ -37,29 +37,29 @@ internal class ModelConfigTest { } @Test - fun ofUnionMember1() { - val unionMember1 = - ModelConfig.UnionMember1.builder() - .modelName("modelName") - .apiKey("apiKey") - .baseUrl("https://example.com") + fun ofModelConfigObject() { + val modelConfigObject = + ModelConfig.ModelConfigObject.builder() + .modelName("gpt-5-nano") + .apiKey("sk-some-openai-api-key") + .baseUrl("https://api.openai.com/v1") .build() - val modelConfig = ModelConfig.ofUnionMember1(unionMember1) + val modelConfig = ModelConfig.ofModelConfigObject(modelConfigObject) - assertThat(modelConfig.string()).isEmpty - assertThat(modelConfig.unionMember1()).contains(unionMember1) + assertThat(modelConfig.name()).isEmpty + assertThat(modelConfig.modelConfigObject()).contains(modelConfigObject) } @Test - fun ofUnionMember1Roundtrip() { + fun ofModelConfigObjectRoundtrip() { val jsonMapper = jsonMapper() val modelConfig = - ModelConfig.ofUnionMember1( - ModelConfig.UnionMember1.builder() - .modelName("modelName") - .apiKey("apiKey") - .baseUrl("https://example.com") + ModelConfig.ofModelConfigObject( + ModelConfig.ModelConfigObject.builder() + .modelName("gpt-5-nano") + .apiKey("sk-some-openai-api-key") + .baseUrl("https://api.openai.com/v1") .build() ) diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt index c31444c..2b5fb57 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt @@ -22,7 +22,7 @@ internal class SessionActParamsTest { .frameId("frameId") .options( SessionActParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .timeout(30000.0) .variables( SessionActParams.Options.Variables.builder() @@ -60,7 +60,7 @@ internal class SessionActParamsTest { .frameId("frameId") .options( SessionActParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .timeout(30000.0) .variables( SessionActParams.Options.Variables.builder() @@ -110,7 +110,7 @@ internal class SessionActParamsTest { .frameId("frameId") .options( SessionActParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .timeout(30000.0) .variables( SessionActParams.Options.Variables.builder() @@ -129,7 +129,7 @@ internal class SessionActParamsTest { assertThat(body.options()) .contains( SessionActParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .timeout(30000.0) .variables( SessionActParams.Options.Variables.builder() diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt index 30e45db..041295f 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndResponseTest.kt @@ -11,13 +11,15 @@ internal class SessionEndResponseTest { @Test fun create() { - val sessionEndResponse = SessionEndResponse.builder().build() + val sessionEndResponse = SessionEndResponse.builder().success(true).build() + + assertThat(sessionEndResponse.success()).isEqualTo(true) } @Test fun roundtrip() { val jsonMapper = jsonMapper() - val sessionEndResponse = SessionEndResponse.builder().build() + val sessionEndResponse = SessionEndResponse.builder().success(true).build() val roundtrippedSessionEndResponse = jsonMapper.readValue( diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteParamsTest.kt index b40f381..7d7caf8 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteParamsTest.kt @@ -20,7 +20,7 @@ internal class SessionExecuteParamsTest { .agentConfig( SessionExecuteParams.AgentConfig.builder() .cua(true) - .model("string") + .model("openai/gpt-5-nano") .systemPrompt("systemPrompt") .build() ) @@ -69,7 +69,7 @@ internal class SessionExecuteParamsTest { .agentConfig( SessionExecuteParams.AgentConfig.builder() .cua(true) - .model("string") + .model("openai/gpt-5-nano") .systemPrompt("systemPrompt") .build() ) @@ -130,7 +130,7 @@ internal class SessionExecuteParamsTest { .agentConfig( SessionExecuteParams.AgentConfig.builder() .cua(true) - .model("string") + .model("openai/gpt-5-nano") .systemPrompt("systemPrompt") .build() ) @@ -152,7 +152,7 @@ internal class SessionExecuteParamsTest { .isEqualTo( SessionExecuteParams.AgentConfig.builder() .cua(true) - .model("string") + .model("openai/gpt-5-nano") .systemPrompt("systemPrompt") .build() ) diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt index 4a3c252..30bc290 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt @@ -22,7 +22,7 @@ internal class SessionExtractParamsTest { .instruction("Extract all product names and prices from the page") .options( SessionExtractParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .selector("#main-content") .timeout(30000.0) .build() @@ -58,7 +58,7 @@ internal class SessionExtractParamsTest { .instruction("Extract all product names and prices from the page") .options( SessionExtractParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .selector("#main-content") .timeout(30000.0) .build() @@ -106,7 +106,7 @@ internal class SessionExtractParamsTest { .instruction("Extract all product names and prices from the page") .options( SessionExtractParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .selector("#main-content") .timeout(30000.0) .build() @@ -126,7 +126,7 @@ internal class SessionExtractParamsTest { assertThat(body.options()) .contains( SessionExtractParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .selector("#main-content") .timeout(30000.0) .build() diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt index 95ccd9b..98d7d9a 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt @@ -21,7 +21,7 @@ internal class SessionObserveParamsTest { .instruction("Find all clickable navigation links") .options( SessionObserveParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .selector("nav") .timeout(30000.0) .build() @@ -52,7 +52,7 @@ internal class SessionObserveParamsTest { .instruction("Find all clickable navigation links") .options( SessionObserveParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .selector("nav") .timeout(30000.0) .build() @@ -95,7 +95,7 @@ internal class SessionObserveParamsTest { .instruction("Find all clickable navigation links") .options( SessionObserveParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .selector("nav") .timeout(30000.0) .build() @@ -109,7 +109,7 @@ internal class SessionObserveParamsTest { assertThat(body.options()) .contains( SessionObserveParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .selector("nav") .timeout(30000.0) .build() diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt index 0dc5811..13ae538 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt @@ -153,7 +153,7 @@ internal class SessionStartParamsTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() } @@ -306,7 +306,7 @@ internal class SessionStartParamsTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() @@ -480,7 +480,7 @@ internal class SessionStartParamsTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() @@ -624,7 +624,7 @@ internal class SessionStartParamsTest { assertThat(body.experimental()).contains(true) assertThat(body.selfHeal()).contains(true) assertThat(body.systemPrompt()).contains("systemPrompt") - assertThat(body.verbose()).contains(1L) + assertThat(body.verbose()).contains(SessionStartParams.Verbose._1) assertThat(body.waitForCaptchaSolves()).contains(true) } diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt index 967794c..87af3f1 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt @@ -230,7 +230,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) @@ -410,7 +410,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) @@ -590,7 +590,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) @@ -770,7 +770,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) @@ -950,7 +950,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) @@ -1130,7 +1130,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) @@ -1310,7 +1310,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) @@ -1490,7 +1490,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) @@ -1670,7 +1670,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) @@ -1850,7 +1850,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) @@ -2030,7 +2030,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) @@ -2210,7 +2210,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) @@ -2390,7 +2390,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) @@ -2570,7 +2570,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) @@ -2750,7 +2750,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) @@ -2930,7 +2930,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) @@ -3108,7 +3108,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt index beb2b92..a50efce 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt @@ -192,7 +192,7 @@ internal class ServiceParamsTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .putAdditionalHeader("Secret-Header", "42") .putAdditionalQueryParam("secret_query_param", "42") @@ -225,7 +225,7 @@ internal class ServiceParamsTest { .frameId("frameId") .options( SessionActParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .timeout(30000.0) .variables( SessionActParams.Options.Variables.builder() diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt index fd11f6e..8abcbcb 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt @@ -44,7 +44,7 @@ internal class SessionServiceAsyncTest { .frameId("frameId") .options( SessionActParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .timeout(30000.0) .variables( SessionActParams.Options.Variables.builder() @@ -110,7 +110,7 @@ internal class SessionServiceAsyncTest { .agentConfig( SessionExecuteParams.AgentConfig.builder() .cua(true) - .model("string") + .model("openai/gpt-5-nano") .systemPrompt("systemPrompt") .build() ) @@ -155,7 +155,7 @@ internal class SessionServiceAsyncTest { .instruction("Extract all product names and prices from the page") .options( SessionExtractParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .selector("#main-content") .timeout(30000.0) .build() @@ -232,7 +232,7 @@ internal class SessionServiceAsyncTest { .instruction("Find all clickable navigation links") .options( SessionObserveParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .selector("nav") .timeout(30000.0) .build() @@ -406,7 +406,7 @@ internal class SessionServiceAsyncTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt index ba02cd0..937b3ea 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt @@ -44,7 +44,7 @@ internal class SessionServiceTest { .frameId("frameId") .options( SessionActParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .timeout(30000.0) .variables( SessionActParams.Options.Variables.builder() @@ -108,7 +108,7 @@ internal class SessionServiceTest { .agentConfig( SessionExecuteParams.AgentConfig.builder() .cua(true) - .model("string") + .model("openai/gpt-5-nano") .systemPrompt("systemPrompt") .build() ) @@ -152,7 +152,7 @@ internal class SessionServiceTest { .instruction("Extract all product names and prices from the page") .options( SessionExtractParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .selector("#main-content") .timeout(30000.0) .build() @@ -227,7 +227,7 @@ internal class SessionServiceTest { .instruction("Find all clickable navigation links") .options( SessionObserveParams.Options.builder() - .model("string") + .model("openai/gpt-5-nano") .selector("nav") .timeout(30000.0) .build() @@ -400,7 +400,7 @@ internal class SessionServiceTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(1L) + .verbose(SessionStartParams.Verbose._1) .waitForCaptchaSolves(true) .build() ) diff --git a/stagehand-java-proguard-test/src/test/kotlin/com/browserbase/api/proguard/ProGuardCompatibilityTest.kt b/stagehand-java-proguard-test/src/test/kotlin/com/browserbase/api/proguard/ProGuardCompatibilityTest.kt index 63da21d..0d52560 100644 --- a/stagehand-java-proguard-test/src/test/kotlin/com/browserbase/api/proguard/ProGuardCompatibilityTest.kt +++ b/stagehand-java-proguard-test/src/test/kotlin/com/browserbase/api/proguard/ProGuardCompatibilityTest.kt @@ -76,7 +76,7 @@ internal class ProGuardCompatibilityTest { @Test fun modelConfigRoundtrip() { val jsonMapper = jsonMapper() - val modelConfig = ModelConfig.ofString("string") + val modelConfig = ModelConfig.ofName("openai/gpt-5-nano") val roundtrippedModelConfig = jsonMapper.readValue( From f15d8ac7cc7ebfc32e24940c1f1ea5c43b5aae26 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 19:06:17 +0000 Subject: [PATCH 10/13] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 38ef77c..65bd734 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 7 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-817d1d4e845b1946dac8ee10fd34b3f533aa36f74ac598582ffb1b0399a5a932.yml -openapi_spec_hash: 9d856db62b34909fec94743235b3d7be +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-e09ad013e10b6a6bb76dd9b2067696ba92bd7acb862b39bbfe2f296ebdb6eddf.yml +openapi_spec_hash: 2f633591561e4737534842273441a818 config_hash: 88e87ba7021be93d267ecfc8f5e6b891 From 9b6860a4f60d1a740fbb026eef291e40fb8e1845 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 20:09:02 +0000 Subject: [PATCH 11/13] feat(api): manual updates --- .stats.yml | 6 +- .../api/models/sessions/SessionStartParams.kt | 304 ++++-------------- .../models/sessions/SessionActParamsTest.kt | 8 +- .../models/sessions/SessionEndParamsTest.kt | 6 +- .../sessions/SessionExecuteParamsTest.kt | 8 +- .../sessions/SessionExtractParamsTest.kt | 8 +- .../sessions/SessionNavigateParamsTest.kt | 8 +- .../sessions/SessionObserveParamsTest.kt | 8 +- .../models/sessions/SessionStartParamsTest.kt | 16 +- .../api/services/ErrorHandlingTest.kt | 68 ++-- .../api/services/ServiceParamsTest.kt | 6 +- .../services/async/SessionServiceAsyncTest.kt | 16 +- .../services/blocking/SessionServiceTest.kt | 16 +- 13 files changed, 156 insertions(+), 322 deletions(-) diff --git a/.stats.yml b/.stats.yml index 65bd734..604325f 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 7 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-e09ad013e10b6a6bb76dd9b2067696ba92bd7acb862b39bbfe2f296ebdb6eddf.yml -openapi_spec_hash: 2f633591561e4737534842273441a818 -config_hash: 88e87ba7021be93d267ecfc8f5e6b891 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-e96507dd78e76fccc77ba7fb09704da127ead6f4d73ea854e9b2150e90787ff4.yml +openapi_spec_hash: 0c2548b8fdd6de6789b19123e69609c1 +config_hash: c3abb41dbe698d59b3bf12f393013d54 diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt index 57f072f..16eecb4 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartParams.kt @@ -142,7 +142,7 @@ private constructor( * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ - fun verbose(): Optional = body.verbose() + fun verbose(): Optional = body.verbose() /** * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the @@ -229,7 +229,7 @@ private constructor( * * Unlike [verbose], this method doesn't throw if the JSON field has an unexpected type. */ - fun _verbose(): JsonField = body._verbose() + fun _verbose(): JsonField = body._verbose() /** * Returns the raw JSON value of [waitForCaptchaSolves]. @@ -459,15 +459,15 @@ private constructor( } /** Logging verbosity level (0=quiet, 1=normal, 2=debug) */ - fun verbose(verbose: Verbose) = apply { body.verbose(verbose) } + fun verbose(verbose: Long) = apply { body.verbose(verbose) } /** * Sets [Builder.verbose] to an arbitrary JSON value. * - * You should usually call [Builder.verbose] with a well-typed [Verbose] value instead. This + * You should usually call [Builder.verbose] with a well-typed [Long] value instead. This * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun verbose(verbose: JsonField) = apply { body.verbose(verbose) } + fun verbose(verbose: JsonField) = apply { body.verbose(verbose) } fun waitForCaptchaSolves(waitForCaptchaSolves: Boolean) = apply { body.waitForCaptchaSolves(waitForCaptchaSolves) @@ -653,7 +653,7 @@ private constructor( private val experimental: JsonField, private val selfHeal: JsonField, private val systemPrompt: JsonField, - private val verbose: JsonField, + private val verbose: JsonField, private val waitForCaptchaSolves: JsonField, private val additionalProperties: MutableMap, ) { @@ -689,7 +689,7 @@ private constructor( @JsonProperty("systemPrompt") @ExcludeMissing systemPrompt: JsonField = JsonMissing.of(), - @JsonProperty("verbose") @ExcludeMissing verbose: JsonField = JsonMissing.of(), + @JsonProperty("verbose") @ExcludeMissing verbose: JsonField = JsonMissing.of(), @JsonProperty("waitForCaptchaSolves") @ExcludeMissing waitForCaptchaSolves: JsonField = JsonMissing.of(), @@ -790,7 +790,7 @@ private constructor( * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). */ - fun verbose(): Optional = verbose.getOptional("verbose") + fun verbose(): Optional = verbose.getOptional("verbose") /** * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if @@ -893,7 +893,7 @@ private constructor( * * Unlike [verbose], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("verbose") @ExcludeMissing fun _verbose(): JsonField = verbose + @JsonProperty("verbose") @ExcludeMissing fun _verbose(): JsonField = verbose /** * Returns the raw JSON value of [waitForCaptchaSolves]. @@ -944,7 +944,7 @@ private constructor( private var experimental: JsonField = JsonMissing.of() private var selfHeal: JsonField = JsonMissing.of() private var systemPrompt: JsonField = JsonMissing.of() - private var verbose: JsonField = JsonMissing.of() + private var verbose: JsonField = JsonMissing.of() private var waitForCaptchaSolves: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -1098,16 +1098,16 @@ private constructor( } /** Logging verbosity level (0=quiet, 1=normal, 2=debug) */ - fun verbose(verbose: Verbose) = verbose(JsonField.of(verbose)) + fun verbose(verbose: Long) = verbose(JsonField.of(verbose)) /** * Sets [Builder.verbose] to an arbitrary JSON value. * - * You should usually call [Builder.verbose] with a well-typed [Verbose] value instead. + * You should usually call [Builder.verbose] with a well-typed [Long] value instead. * This method is primarily for setting the field to an undocumented or not yet * supported value. */ - fun verbose(verbose: JsonField) = apply { this.verbose = verbose } + fun verbose(verbose: JsonField) = apply { this.verbose = verbose } fun waitForCaptchaSolves(waitForCaptchaSolves: Boolean) = waitForCaptchaSolves(JsonField.of(waitForCaptchaSolves)) @@ -1189,7 +1189,7 @@ private constructor( experimental() selfHeal() systemPrompt() - verbose().ifPresent { it.validate() } + verbose() waitForCaptchaSolves() validated = true } @@ -1220,7 +1220,7 @@ private constructor( (if (experimental.asKnown().isPresent) 1 else 0) + (if (selfHeal.asKnown().isPresent) 1 else 0) + (if (systemPrompt.asKnown().isPresent) 1 else 0) + - (verbose.asKnown().getOrNull()?.validity() ?: 0) + + (if (verbose.asKnown().isPresent) 1 else 0) + (if (waitForCaptchaSolves.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { @@ -3408,13 +3408,9 @@ private constructor( /** Alias for calling [proxies] with `Proxies.ofBool(bool)`. */ fun proxies(bool: Boolean) = proxies(Proxies.ofBool(bool)) - /** - * Alias for calling [proxies] with - * `Proxies.ofUnnamedSchemaWithArrayParent0s(unnamedSchemaWithArrayParent0s)`. - */ - fun proxiesOfUnnamedSchemaWithArrayParent0s( - unnamedSchemaWithArrayParent0s: List - ) = proxies(Proxies.ofUnnamedSchemaWithArrayParent0s(unnamedSchemaWithArrayParent0s)) + /** Alias for calling [proxies] with `Proxies.ofProxyConfigList(proxyConfigList)`. */ + fun proxiesOfProxyConfigList(proxyConfigList: List) = + proxies(Proxies.ofProxyConfigList(proxyConfigList)) fun region(region: Region) = region(JsonField.of(region)) @@ -5668,31 +5664,30 @@ private constructor( class Proxies private constructor( private val bool: Boolean? = null, - private val unnamedSchemaWithArrayParent0s: List? = null, + private val proxyConfigList: List? = null, private val _json: JsonValue? = null, ) { fun bool(): Optional = Optional.ofNullable(bool) - fun unnamedSchemaWithArrayParent0s(): Optional> = - Optional.ofNullable(unnamedSchemaWithArrayParent0s) + fun proxyConfigList(): Optional> = + Optional.ofNullable(proxyConfigList) fun isBool(): Boolean = bool != null - fun isUnnamedSchemaWithArrayParent0s(): Boolean = unnamedSchemaWithArrayParent0s != null + fun isProxyConfigList(): Boolean = proxyConfigList != null fun asBool(): Boolean = bool.getOrThrow("bool") - fun asUnnamedSchemaWithArrayParent0s(): List = - unnamedSchemaWithArrayParent0s.getOrThrow("unnamedSchemaWithArrayParent0s") + fun asProxyConfigList(): List = + proxyConfigList.getOrThrow("proxyConfigList") fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T = when { bool != null -> visitor.visitBool(bool) - unnamedSchemaWithArrayParent0s != null -> - visitor.visitUnnamedSchemaWithArrayParent0s(unnamedSchemaWithArrayParent0s) + proxyConfigList != null -> visitor.visitProxyConfigList(proxyConfigList) else -> visitor.unknown(_json) } @@ -5707,10 +5702,8 @@ private constructor( object : Visitor { override fun visitBool(bool: Boolean) {} - override fun visitUnnamedSchemaWithArrayParent0s( - unnamedSchemaWithArrayParent0s: List - ) { - unnamedSchemaWithArrayParent0s.forEach { it.validate() } + override fun visitProxyConfigList(proxyConfigList: List) { + proxyConfigList.forEach { it.validate() } } } ) @@ -5737,9 +5730,8 @@ private constructor( object : Visitor { override fun visitBool(bool: Boolean) = 1 - override fun visitUnnamedSchemaWithArrayParent0s( - unnamedSchemaWithArrayParent0s: List - ) = unnamedSchemaWithArrayParent0s.sumOf { it.validity().toInt() } + override fun visitProxyConfigList(proxyConfigList: List) = + proxyConfigList.sumOf { it.validity().toInt() } override fun unknown(json: JsonValue?) = 0 } @@ -5752,16 +5744,15 @@ private constructor( return other is Proxies && bool == other.bool && - unnamedSchemaWithArrayParent0s == other.unnamedSchemaWithArrayParent0s + proxyConfigList == other.proxyConfigList } - override fun hashCode(): Int = Objects.hash(bool, unnamedSchemaWithArrayParent0s) + override fun hashCode(): Int = Objects.hash(bool, proxyConfigList) override fun toString(): String = when { bool != null -> "Proxies{bool=$bool}" - unnamedSchemaWithArrayParent0s != null -> - "Proxies{unnamedSchemaWithArrayParent0s=$unnamedSchemaWithArrayParent0s}" + proxyConfigList != null -> "Proxies{proxyConfigList=$proxyConfigList}" _json != null -> "Proxies{_unknown=$_json}" else -> throw IllegalStateException("Invalid Proxies") } @@ -5771,13 +5762,8 @@ private constructor( @JvmStatic fun ofBool(bool: Boolean) = Proxies(bool = bool) @JvmStatic - fun ofUnnamedSchemaWithArrayParent0s( - unnamedSchemaWithArrayParent0s: List - ) = - Proxies( - unnamedSchemaWithArrayParent0s = - unnamedSchemaWithArrayParent0s.toImmutable() - ) + fun ofProxyConfigList(proxyConfigList: List) = + Proxies(proxyConfigList = proxyConfigList.toImmutable()) } /** @@ -5788,9 +5774,7 @@ private constructor( fun visitBool(bool: Boolean): T - fun visitUnnamedSchemaWithArrayParent0s( - unnamedSchemaWithArrayParent0s: List - ): T + fun visitProxyConfigList(proxyConfigList: List): T /** * Maps an unknown variant of [Proxies] to a value of type [T]. @@ -5817,13 +5801,9 @@ private constructor( tryDeserialize(node, jacksonTypeRef())?.let { Proxies(bool = it, _json = json) }, - tryDeserialize( - node, - jacksonTypeRef>(), - ) - ?.let { - Proxies(unnamedSchemaWithArrayParent0s = it, _json = json) - }, + tryDeserialize(node, jacksonTypeRef>())?.let { + Proxies(proxyConfigList = it, _json = json) + }, ) .filterNotNull() .allMaxBy { it.validity() } @@ -5850,17 +5830,17 @@ private constructor( ) { when { value.bool != null -> generator.writeObject(value.bool) - value.unnamedSchemaWithArrayParent0s != null -> - generator.writeObject(value.unnamedSchemaWithArrayParent0s) + value.proxyConfigList != null -> + generator.writeObject(value.proxyConfigList) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid Proxies") } } } - @JsonDeserialize(using = UnnamedSchemaWithArrayParent0.Deserializer::class) - @JsonSerialize(using = UnnamedSchemaWithArrayParent0.Serializer::class) - class UnnamedSchemaWithArrayParent0 + @JsonDeserialize(using = ProxyConfig.Deserializer::class) + @JsonSerialize(using = ProxyConfig.Serializer::class) + class ProxyConfig private constructor( private val browserbase: Browserbase? = null, private val external: External? = null, @@ -5890,7 +5870,7 @@ private constructor( private var validated: Boolean = false - fun validate(): UnnamedSchemaWithArrayParent0 = apply { + fun validate(): ProxyConfig = apply { if (validated) { return@apply } @@ -5941,7 +5921,7 @@ private constructor( return true } - return other is UnnamedSchemaWithArrayParent0 && + return other is ProxyConfig && browserbase == other.browserbase && external == other.external } @@ -5950,27 +5930,24 @@ private constructor( override fun toString(): String = when { - browserbase != null -> - "UnnamedSchemaWithArrayParent0{browserbase=$browserbase}" - external != null -> "UnnamedSchemaWithArrayParent0{external=$external}" - _json != null -> "UnnamedSchemaWithArrayParent0{_unknown=$_json}" - else -> throw IllegalStateException("Invalid UnnamedSchemaWithArrayParent0") + browserbase != null -> "ProxyConfig{browserbase=$browserbase}" + external != null -> "ProxyConfig{external=$external}" + _json != null -> "ProxyConfig{_unknown=$_json}" + else -> throw IllegalStateException("Invalid ProxyConfig") } companion object { @JvmStatic fun ofBrowserbase(browserbase: Browserbase) = - UnnamedSchemaWithArrayParent0(browserbase = browserbase) + ProxyConfig(browserbase = browserbase) - @JvmStatic - fun ofExternal(external: External) = - UnnamedSchemaWithArrayParent0(external = external) + @JvmStatic fun ofExternal(external: External) = ProxyConfig(external = external) } /** - * An interface that defines how to map each variant of - * [UnnamedSchemaWithArrayParent0] to a value of type [T]. + * An interface that defines how to map each variant of [ProxyConfig] to a value of + * type [T]. */ interface Visitor { @@ -5979,58 +5956,47 @@ private constructor( fun visitExternal(external: External): T /** - * Maps an unknown variant of [UnnamedSchemaWithArrayParent0] to a value of type - * [T]. + * Maps an unknown variant of [ProxyConfig] to a value of type [T]. * - * An instance of [UnnamedSchemaWithArrayParent0] can contain an unknown variant - * if it was deserialized from data that doesn't match any known variant. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new variants that the SDK is unaware of. + * An instance of [ProxyConfig] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if + * the SDK is on an older version than the API, then the API may respond with + * new variants that the SDK is unaware of. * * @throws StagehandInvalidDataException in the default implementation. */ fun unknown(json: JsonValue?): T { - throw StagehandInvalidDataException( - "Unknown UnnamedSchemaWithArrayParent0: $json" - ) + throw StagehandInvalidDataException("Unknown ProxyConfig: $json") } } - internal class Deserializer : - BaseDeserializer( - UnnamedSchemaWithArrayParent0::class - ) { + internal class Deserializer : BaseDeserializer(ProxyConfig::class) { - override fun ObjectCodec.deserialize( - node: JsonNode - ): UnnamedSchemaWithArrayParent0 { + override fun ObjectCodec.deserialize(node: JsonNode): ProxyConfig { val json = JsonValue.fromJsonNode(node) val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() when (type) { "browserbase" -> { return tryDeserialize(node, jacksonTypeRef())?.let { - UnnamedSchemaWithArrayParent0(browserbase = it, _json = json) - } ?: UnnamedSchemaWithArrayParent0(_json = json) + ProxyConfig(browserbase = it, _json = json) + } ?: ProxyConfig(_json = json) } "external" -> { return tryDeserialize(node, jacksonTypeRef())?.let { - UnnamedSchemaWithArrayParent0(external = it, _json = json) - } ?: UnnamedSchemaWithArrayParent0(_json = json) + ProxyConfig(external = it, _json = json) + } ?: ProxyConfig(_json = json) } } - return UnnamedSchemaWithArrayParent0(_json = json) + return ProxyConfig(_json = json) } } - internal class Serializer : - BaseSerializer( - UnnamedSchemaWithArrayParent0::class - ) { + internal class Serializer : BaseSerializer(ProxyConfig::class) { override fun serialize( - value: UnnamedSchemaWithArrayParent0, + value: ProxyConfig, generator: JsonGenerator, provider: SerializerProvider, ) { @@ -6038,8 +6004,7 @@ private constructor( value.browserbase != null -> generator.writeObject(value.browserbase) value.external != null -> generator.writeObject(value.external) value._json != null -> generator.writeObject(value._json) - else -> - throw IllegalStateException("Invalid UnnamedSchemaWithArrayParent0") + else -> throw IllegalStateException("Invalid ProxyConfig") } } } @@ -7149,137 +7114,6 @@ private constructor( "BrowserbaseSessionCreateParams{browserSettings=$browserSettings, extensionId=$extensionId, keepAlive=$keepAlive, projectId=$projectId, proxies=$proxies, region=$region, timeout=$timeout, userMetadata=$userMetadata, additionalProperties=$additionalProperties}" } - /** Logging verbosity level (0=quiet, 1=normal, 2=debug) */ - class Verbose @JsonCreator private constructor(private val value: JsonField) : Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val _0 = of(0L) - - @JvmField val _1 = of(1L) - - @JvmField val _2 = of(2L) - - @JvmStatic fun of(value: Long) = Verbose(JsonField.of(value)) - } - - /** An enum containing [Verbose]'s known values. */ - enum class Known { - _0, - _1, - _2, - } - - /** - * An enum containing [Verbose]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Verbose] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - _0, - _1, - _2, - /** An enum member indicating that [Verbose] was instantiated with an unknown value. */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - _0 -> Value._0 - _1 -> Value._1 - _2 -> Value._2 - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws StagehandInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - _0 -> Known._0 - _1 -> Known._1 - _2 -> Known._2 - else -> throw StagehandInvalidDataException("Unknown Verbose: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * @throws StagehandInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asLong(): Long = - _value().asNumber().getOrNull()?.let { - if (it.toDouble() % 1 == 0.0) it.toLong() else null - } ?: throw StagehandInvalidDataException("Value is not a Long") - - private var validated: Boolean = false - - fun validate(): Verbose = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Verbose && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - /** Client SDK language */ class XLanguage @JsonCreator private constructor(private val value: JsonField) : Enum { diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt index 2b5fb57..9c19cb7 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionActParamsTest.kt @@ -16,7 +16,7 @@ internal class SessionActParamsTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionActParams.XStreamResponse.TRUE) .input("Click the login button") .frameId("frameId") @@ -54,7 +54,7 @@ internal class SessionActParamsTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionActParams.XStreamResponse.TRUE) .input("Click the login button") .frameId("frameId") @@ -78,7 +78,7 @@ internal class SessionActParamsTest { Headers.builder() .put("x-language", "typescript") .put("x-sdk-version", "3.0.6") - .put("x-sent-at", "2025-01-15T10:30:00.000Z") + .put("x-sent-at", "2025-01-15T10:30:00Z") .put("x-stream-response", "true") .build() ) @@ -104,7 +104,7 @@ internal class SessionActParamsTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionActParams.XStreamResponse.TRUE) .input("Click the login button") .frameId("frameId") diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndParamsTest.kt index 14faac3..bc50272 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionEndParamsTest.kt @@ -15,7 +15,7 @@ internal class SessionEndParamsTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionEndParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionEndParams.XStreamResponse.TRUE) .build() } @@ -36,7 +36,7 @@ internal class SessionEndParamsTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionEndParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionEndParams.XStreamResponse.TRUE) .build() @@ -47,7 +47,7 @@ internal class SessionEndParamsTest { Headers.builder() .put("x-language", "typescript") .put("x-sdk-version", "3.0.6") - .put("x-sent-at", "2025-01-15T10:30:00.000Z") + .put("x-sent-at", "2025-01-15T10:30:00Z") .put("x-stream-response", "true") .build() ) diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteParamsTest.kt index 7d7caf8..4de6985 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExecuteParamsTest.kt @@ -15,7 +15,7 @@ internal class SessionExecuteParamsTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionExecuteParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionExecuteParams.XStreamResponse.TRUE) .agentConfig( SessionExecuteParams.AgentConfig.builder() @@ -64,7 +64,7 @@ internal class SessionExecuteParamsTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionExecuteParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionExecuteParams.XStreamResponse.TRUE) .agentConfig( SessionExecuteParams.AgentConfig.builder() @@ -92,7 +92,7 @@ internal class SessionExecuteParamsTest { Headers.builder() .put("x-language", "typescript") .put("x-sdk-version", "3.0.6") - .put("x-sent-at", "2025-01-15T10:30:00.000Z") + .put("x-sent-at", "2025-01-15T10:30:00Z") .put("x-stream-response", "true") .build() ) @@ -125,7 +125,7 @@ internal class SessionExecuteParamsTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionExecuteParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionExecuteParams.XStreamResponse.TRUE) .agentConfig( SessionExecuteParams.AgentConfig.builder() diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt index 30bc290..b8d0a00 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionExtractParamsTest.kt @@ -16,7 +16,7 @@ internal class SessionExtractParamsTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionExtractParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionExtractParams.XStreamResponse.TRUE) .frameId("frameId") .instruction("Extract all product names and prices from the page") @@ -52,7 +52,7 @@ internal class SessionExtractParamsTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionExtractParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionExtractParams.XStreamResponse.TRUE) .frameId("frameId") .instruction("Extract all product names and prices from the page") @@ -77,7 +77,7 @@ internal class SessionExtractParamsTest { Headers.builder() .put("x-language", "typescript") .put("x-sdk-version", "3.0.6") - .put("x-sent-at", "2025-01-15T10:30:00.000Z") + .put("x-sent-at", "2025-01-15T10:30:00Z") .put("x-stream-response", "true") .build() ) @@ -100,7 +100,7 @@ internal class SessionExtractParamsTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionExtractParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionExtractParams.XStreamResponse.TRUE) .frameId("frameId") .instruction("Extract all product names and prices from the page") diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt index aa845c3..3bba7d4 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt @@ -15,7 +15,7 @@ internal class SessionNavigateParamsTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionNavigateParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionNavigateParams.XStreamResponse.TRUE) .url("https://example.com") .frameId("frameId") @@ -49,7 +49,7 @@ internal class SessionNavigateParamsTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionNavigateParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionNavigateParams.XStreamResponse.TRUE) .url("https://example.com") .frameId("frameId") @@ -69,7 +69,7 @@ internal class SessionNavigateParamsTest { Headers.builder() .put("x-language", "typescript") .put("x-sdk-version", "3.0.6") - .put("x-sent-at", "2025-01-15T10:30:00.000Z") + .put("x-sent-at", "2025-01-15T10:30:00Z") .put("x-stream-response", "true") .build() ) @@ -95,7 +95,7 @@ internal class SessionNavigateParamsTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionNavigateParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionNavigateParams.XStreamResponse.TRUE) .url("https://example.com") .frameId("frameId") diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt index 98d7d9a..db03460 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt @@ -15,7 +15,7 @@ internal class SessionObserveParamsTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionObserveParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionObserveParams.XStreamResponse.TRUE) .frameId("frameId") .instruction("Find all clickable navigation links") @@ -46,7 +46,7 @@ internal class SessionObserveParamsTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionObserveParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionObserveParams.XStreamResponse.TRUE) .frameId("frameId") .instruction("Find all clickable navigation links") @@ -66,7 +66,7 @@ internal class SessionObserveParamsTest { Headers.builder() .put("x-language", "typescript") .put("x-sdk-version", "3.0.6") - .put("x-sent-at", "2025-01-15T10:30:00.000Z") + .put("x-sent-at", "2025-01-15T10:30:00Z") .put("x-stream-response", "true") .build() ) @@ -89,7 +89,7 @@ internal class SessionObserveParamsTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionObserveParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionObserveParams.XStreamResponse.TRUE) .frameId("frameId") .instruction("Find all clickable navigation links") diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt index 13ae538..56f4736 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartParamsTest.kt @@ -15,7 +15,7 @@ internal class SessionStartParamsTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -153,7 +153,7 @@ internal class SessionStartParamsTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() } @@ -164,7 +164,7 @@ internal class SessionStartParamsTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -306,7 +306,7 @@ internal class SessionStartParamsTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() @@ -317,7 +317,7 @@ internal class SessionStartParamsTest { Headers.builder() .put("x-language", "typescript") .put("x-sdk-version", "3.0.6") - .put("x-sent-at", "2025-01-15T10:30:00.000Z") + .put("x-sent-at", "2025-01-15T10:30:00Z") .put("x-stream-response", "true") .build() ) @@ -338,7 +338,7 @@ internal class SessionStartParamsTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -480,7 +480,7 @@ internal class SessionStartParamsTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() @@ -624,7 +624,7 @@ internal class SessionStartParamsTest { assertThat(body.experimental()).contains(true) assertThat(body.selfHeal()).contains(true) assertThat(body.systemPrompt()).contains("systemPrompt") - assertThat(body.verbose()).contains(SessionStartParams.Verbose._1) + assertThat(body.verbose()).contains(1L) assertThat(body.waitForCaptchaSolves()).contains(true) } diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt index 87af3f1..e453d81 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ErrorHandlingTest.kt @@ -77,7 +77,7 @@ internal class ErrorHandlingTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -230,7 +230,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -257,7 +257,7 @@ internal class ErrorHandlingTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -410,7 +410,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -437,7 +437,7 @@ internal class ErrorHandlingTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -590,7 +590,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -617,7 +617,7 @@ internal class ErrorHandlingTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -770,7 +770,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -797,7 +797,7 @@ internal class ErrorHandlingTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -950,7 +950,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -977,7 +977,7 @@ internal class ErrorHandlingTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -1130,7 +1130,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -1157,7 +1157,7 @@ internal class ErrorHandlingTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -1310,7 +1310,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -1337,7 +1337,7 @@ internal class ErrorHandlingTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -1490,7 +1490,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -1517,7 +1517,7 @@ internal class ErrorHandlingTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -1670,7 +1670,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -1697,7 +1697,7 @@ internal class ErrorHandlingTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -1850,7 +1850,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -1877,7 +1877,7 @@ internal class ErrorHandlingTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -2030,7 +2030,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -2057,7 +2057,7 @@ internal class ErrorHandlingTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -2210,7 +2210,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -2237,7 +2237,7 @@ internal class ErrorHandlingTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -2390,7 +2390,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -2417,7 +2417,7 @@ internal class ErrorHandlingTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -2570,7 +2570,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -2597,7 +2597,7 @@ internal class ErrorHandlingTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -2750,7 +2750,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -2777,7 +2777,7 @@ internal class ErrorHandlingTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -2930,7 +2930,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) @@ -2955,7 +2955,7 @@ internal class ErrorHandlingTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -3108,7 +3108,7 @@ internal class ErrorHandlingTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt index a50efce..0cdc99d 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/ServiceParamsTest.kt @@ -50,7 +50,7 @@ internal class ServiceParamsTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -192,7 +192,7 @@ internal class ServiceParamsTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .putAdditionalHeader("Secret-Header", "42") .putAdditionalQueryParam("secret_query_param", "42") @@ -219,7 +219,7 @@ internal class ServiceParamsTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionActParams.XStreamResponse.TRUE) .input("Click the login button") .frameId("frameId") diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt index 8abcbcb..270a06b 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt @@ -38,7 +38,7 @@ internal class SessionServiceAsyncTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionActParams.XStreamResponse.TRUE) .input("Click the login button") .frameId("frameId") @@ -78,7 +78,7 @@ internal class SessionServiceAsyncTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionEndParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionEndParams.XStreamResponse.TRUE) .build() ) @@ -105,7 +105,7 @@ internal class SessionServiceAsyncTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionExecuteParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionExecuteParams.XStreamResponse.TRUE) .agentConfig( SessionExecuteParams.AgentConfig.builder() @@ -149,7 +149,7 @@ internal class SessionServiceAsyncTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionExtractParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionExtractParams.XStreamResponse.TRUE) .frameId("frameId") .instruction("Extract all product names and prices from the page") @@ -190,7 +190,7 @@ internal class SessionServiceAsyncTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionNavigateParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionNavigateParams.XStreamResponse.TRUE) .url("https://example.com") .frameId("frameId") @@ -226,7 +226,7 @@ internal class SessionServiceAsyncTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionObserveParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionObserveParams.XStreamResponse.TRUE) .frameId("frameId") .instruction("Find all clickable navigation links") @@ -261,7 +261,7 @@ internal class SessionServiceAsyncTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -406,7 +406,7 @@ internal class SessionServiceAsyncTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt index 937b3ea..af06455 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt @@ -38,7 +38,7 @@ internal class SessionServiceTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionActParams.XStreamResponse.TRUE) .input("Click the login button") .frameId("frameId") @@ -77,7 +77,7 @@ internal class SessionServiceTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionEndParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionEndParams.XStreamResponse.TRUE) .build() ) @@ -103,7 +103,7 @@ internal class SessionServiceTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionExecuteParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionExecuteParams.XStreamResponse.TRUE) .agentConfig( SessionExecuteParams.AgentConfig.builder() @@ -146,7 +146,7 @@ internal class SessionServiceTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionExtractParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionExtractParams.XStreamResponse.TRUE) .frameId("frameId") .instruction("Extract all product names and prices from the page") @@ -186,7 +186,7 @@ internal class SessionServiceTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionNavigateParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionNavigateParams.XStreamResponse.TRUE) .url("https://example.com") .frameId("frameId") @@ -221,7 +221,7 @@ internal class SessionServiceTest { .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .xLanguage(SessionObserveParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionObserveParams.XStreamResponse.TRUE) .frameId("frameId") .instruction("Find all clickable navigation links") @@ -255,7 +255,7 @@ internal class SessionServiceTest { SessionStartParams.builder() .xLanguage(SessionStartParams.XLanguage.TYPESCRIPT) .xSdkVersion("3.0.6") - .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00.000Z")) + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) .xStreamResponse(SessionStartParams.XStreamResponse.TRUE) .modelName("gpt-4o") .actTimeoutMs(30000.0) @@ -400,7 +400,7 @@ internal class SessionServiceTest { .experimental(true) .selfHeal(true) .systemPrompt("systemPrompt") - .verbose(SessionStartParams.Verbose._1) + .verbose(1L) .waitForCaptchaSolves(true) .build() ) From b6bdf1a26a45556dcfee59b088983cd7e7839f43 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 18 Dec 2025 01:38:54 +0000 Subject: [PATCH 12/13] feat(api): manual updates --- .stats.yml | 6 +- README.md | 2 + .../client/okhttp/StagehandOkHttpClient.kt | 13 + .../okhttp/StagehandOkHttpClientAsync.kt | 13 + .../com/browserbase/api/core/ClientOptions.kt | 50 + .../api/core/handlers/SseHandler.kt | 137 ++ .../api/core/handlers/StreamHandler.kt | 102 ++ .../browserbase/api/core/http/SseMessage.kt | 74 ++ .../browserbase/api/errors/SseException.kt | 91 ++ .../api/models/sessions/SessionActParams.kt | 326 +---- .../models/sessions/SessionNavigateParams.kt | 81 +- .../models/sessions/SessionStartResponse.kt | 51 +- .../api/models/sessions/StreamEvent.kt | 1175 +++++++++++++++++ .../api/services/async/SessionServiceAsync.kt | 291 ++++ .../services/async/SessionServiceAsyncImpl.kt | 228 ++++ .../api/services/blocking/SessionService.kt | 294 +++++ .../services/blocking/SessionServiceImpl.kt | 202 +++ .../api/core/handlers/SseHandlerTest.kt | 134 ++ .../api/core/handlers/StreamHandlerTest.kt | 94 ++ .../sessions/SessionNavigateParamsTest.kt | 4 + .../sessions/SessionStartResponseTest.kt | 3 + .../api/models/sessions/StreamEventTest.kt | 66 + .../services/async/SessionServiceAsyncTest.kt | 166 +++ .../services/blocking/SessionServiceTest.kt | 166 +++ 24 files changed, 3441 insertions(+), 328 deletions(-) create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/core/handlers/SseHandler.kt create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/core/handlers/StreamHandler.kt create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/core/http/SseMessage.kt create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/errors/SseException.kt create mode 100644 stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/StreamEvent.kt create mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/core/handlers/SseHandlerTest.kt create mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/core/handlers/StreamHandlerTest.kt create mode 100644 stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/StreamEventTest.kt diff --git a/.stats.yml b/.stats.yml index 604325f..5dba58c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 7 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-e96507dd78e76fccc77ba7fb09704da127ead6f4d73ea854e9b2150e90787ff4.yml -openapi_spec_hash: 0c2548b8fdd6de6789b19123e69609c1 -config_hash: c3abb41dbe698d59b3bf12f393013d54 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-f7d6b6489159f611a2bfdc267ce0a6fc0455bed1ffa0c310044baaa5d8381b9b.yml +openapi_spec_hash: cd88d8068abfde8382da0bed674e440c +config_hash: 5c69fb596588b8ace08203858518c149 diff --git a/README.md b/README.md index 3c37038..be1932d 100644 --- a/README.md +++ b/README.md @@ -236,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. diff --git a/stagehand-java-client-okhttp/src/main/kotlin/com/browserbase/api/client/okhttp/StagehandOkHttpClient.kt b/stagehand-java-client-okhttp/src/main/kotlin/com/browserbase/api/client/okhttp/StagehandOkHttpClient.kt index 8955635..40010ee 100644 --- a/stagehand-java-client-okhttp/src/main/kotlin/com/browserbase/api/client/okhttp/StagehandOkHttpClient.kt +++ b/stagehand-java-client-okhttp/src/main/kotlin/com/browserbase/api/client/okhttp/StagehandOkHttpClient.kt @@ -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 @@ -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 @@ -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. * diff --git a/stagehand-java-client-okhttp/src/main/kotlin/com/browserbase/api/client/okhttp/StagehandOkHttpClientAsync.kt b/stagehand-java-client-okhttp/src/main/kotlin/com/browserbase/api/client/okhttp/StagehandOkHttpClientAsync.kt index 2cb208d..33ce68f 100644 --- a/stagehand-java-client-okhttp/src/main/kotlin/com/browserbase/api/client/okhttp/StagehandOkHttpClientAsync.kt +++ b/stagehand-java-client-okhttp/src/main/kotlin/com/browserbase/api/client/okhttp/StagehandOkHttpClientAsync.kt @@ -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 @@ -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 @@ -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. * diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/core/ClientOptions.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/core/ClientOptions.kt index 8692cb0..2da3f9a 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/core/ClientOptions.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/core/ClientOptions.kt @@ -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 @@ -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. */ @@ -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. * @@ -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 @@ -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 @@ -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. * @@ -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) @@ -464,6 +512,7 @@ private constructor( .build(), checkJacksonVersionCompatibility, jsonMapper, + streamHandlerExecutor, sleeper, clock, baseUrl, @@ -491,6 +540,7 @@ private constructor( */ fun close() { httpClient.close() + (streamHandlerExecutor as? ExecutorService)?.shutdown() sleeper.close() } } diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/core/handlers/SseHandler.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/core/handlers/SseHandler.kt new file mode 100644 index 0000000..039faae --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/core/handlers/SseHandler.kt @@ -0,0 +1,137 @@ +// File generated from our OpenAPI spec by Stainless. + +@file:JvmName("SseHandler") + +package com.browserbase.api.core.handlers + +import com.browserbase.api.core.JsonMissing +import com.browserbase.api.core.http.HttpResponse +import com.browserbase.api.core.http.HttpResponse.Handler +import com.browserbase.api.core.http.SseMessage +import com.browserbase.api.core.http.StreamResponse +import com.browserbase.api.core.http.map +import com.browserbase.api.errors.SseException +import com.fasterxml.jackson.databind.json.JsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef + +@JvmSynthetic +internal fun sseHandler(jsonMapper: JsonMapper): Handler> = + streamHandler { response, lines -> + val state = SseState(jsonMapper) + var done = false + for (line in lines) { + // Stop emitting messages, but iterate through the full stream. + if (done) { + continue + } + + val message = state.decode(line) ?: continue + + when { + message.data.startsWith("finished") -> { + // In this case we don't break because we still want to iterate through the full + // stream. + done = true + continue + } + message.data.startsWith("error") -> { + throw SseException.builder() + .statusCode(response.statusCode()) + .headers(response.headers()) + .body( + try { + jsonMapper.readValue(message.data, jacksonTypeRef()) + } catch (e: Exception) { + JsonMissing.of() + } + ) + .build() + } + } + + if (message.event == null) { + yield(message) + } + } + } + +private class SseState( + val jsonMapper: JsonMapper, + var event: String? = null, + val data: MutableList = mutableListOf(), + var lastId: String? = null, + var retry: Int? = null, +) { + // https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation + fun decode(line: String): SseMessage? { + if (line.isEmpty()) { + return flush() + } + + if (line.startsWith(':')) { + return null + } + + val fieldName: String + var value: String + + val colonIndex = line.indexOf(':') + if (colonIndex == -1) { + fieldName = line + value = "" + } else { + fieldName = line.substring(0, colonIndex) + value = line.substring(colonIndex + 1) + } + + if (value.startsWith(' ')) { + value = value.substring(1) + } + + when (fieldName) { + "event" -> event = value + "data" -> data.add(value) + "id" -> { + if (!value.contains('\u0000')) { + lastId = value + } + } + "retry" -> value.toIntOrNull()?.let { retry = it } + } + + return null + } + + private fun flush(): SseMessage? { + if (isEmpty()) { + return null + } + + val message = + SseMessage.builder() + .jsonMapper(jsonMapper) + .event(event) + .data(data.joinToString("\n")) + .id(lastId) + .retry(retry) + .build() + + // NOTE: Per the SSE spec, do not reset lastId. + event = null + data.clear() + retry = null + + return message + } + + private fun isEmpty(): Boolean = + event.isNullOrEmpty() && data.isEmpty() && lastId.isNullOrEmpty() && retry == null +} + +@JvmSynthetic +internal inline fun Handler>.mapJson(): + Handler> = + object : Handler> { + override fun handle(response: HttpResponse): StreamResponse = + this@mapJson.handle(response).map { it.json() } + } diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/core/handlers/StreamHandler.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/core/handlers/StreamHandler.kt new file mode 100644 index 0000000..4cd4f25 --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/core/handlers/StreamHandler.kt @@ -0,0 +1,102 @@ +@file:JvmName("StreamHandler") + +package com.browserbase.api.core.handlers + +import com.browserbase.api.core.http.HttpResponse +import com.browserbase.api.core.http.HttpResponse.Handler +import com.browserbase.api.core.http.PhantomReachableClosingStreamResponse +import com.browserbase.api.core.http.StreamResponse +import com.browserbase.api.errors.StagehandIoException +import java.io.IOException +import java.util.stream.Stream +import kotlin.streams.asStream + +@JvmSynthetic +internal fun streamHandler( + block: suspend SequenceScope.(response: HttpResponse, lines: Sequence) -> Unit +): Handler> = + object : Handler> { + + override fun handle(response: HttpResponse): StreamResponse { + val reader = response.body().bufferedReader() + val sequence = + // Wrap in a `CloseableSequence` to avoid performing a read on the `reader` + // after it has been closed, which would throw an `IOException`. + CloseableSequence( + sequence { + reader.useLines { lines -> + block( + response, + // We wrap the `lines` instead of the top-level sequence because + // we only want to catch `IOException` from the reader; not from + // the user's own code. + IOExceptionWrappingSequence(lines), + ) + } + } + .constrainOnce() + ) + + return PhantomReachableClosingStreamResponse( + object : StreamResponse { + + override fun stream(): Stream = sequence.asStream() + + override fun close() { + sequence.close() + reader.close() + response.close() + } + } + ) + } + } + +/** A sequence that catches, wraps, and rethrows [IOException] as [StagehandIoException]. */ +private class IOExceptionWrappingSequence(private val sequence: Sequence) : Sequence { + + override fun iterator(): Iterator { + val iterator = sequence.iterator() + return object : Iterator { + + override fun next(): T = + try { + iterator.next() + } catch (e: IOException) { + throw StagehandIoException("Stream failed", e) + } + + override fun hasNext(): Boolean = + try { + iterator.hasNext() + } catch (e: IOException) { + throw StagehandIoException("Stream failed", e) + } + } + } +} + +/** + * A sequence that can be closed. + * + * Once [close] is called, it will not yield more elements. It will also no longer consult the + * underlying [Iterator.hasNext] method. + */ +private class CloseableSequence(private val sequence: Sequence) : Sequence { + + private var isClosed: Boolean = false + + override fun iterator(): Iterator { + val iterator = sequence.iterator() + return object : Iterator { + + override fun next(): T = iterator.next() + + override fun hasNext(): Boolean = !isClosed && iterator.hasNext() + } + } + + fun close() { + isClosed = true + } +} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/core/http/SseMessage.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/core/http/SseMessage.kt new file mode 100644 index 0000000..21cc44e --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/core/http/SseMessage.kt @@ -0,0 +1,74 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.core.http + +import com.browserbase.api.errors.StagehandInvalidDataException +import com.fasterxml.jackson.databind.json.JsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.util.Objects + +internal class SseMessage +private constructor( + val jsonMapper: JsonMapper, + val event: String?, + val data: String, + val id: String?, + val retry: Int?, +) { + + companion object { + @JvmStatic fun builder() = Builder() + } + + class Builder internal constructor() { + + private var jsonMapper: JsonMapper? = null + private var event: String? = null + private var data: String = "" + private var id: String? = null + private var retry: Int? = null + + fun jsonMapper(jsonMapper: JsonMapper) = apply { this.jsonMapper = jsonMapper } + + fun event(event: String?) = apply { this.event = event } + + fun data(data: String) = apply { this.data = data } + + fun id(id: String?) = apply { this.id = id } + + fun retry(retry: Int?) = apply { this.retry = retry } + + fun build(): SseMessage = SseMessage(jsonMapper!!, event, data, id, retry) + } + + inline fun json(): T = + try { + jsonMapper.readerFor(jacksonTypeRef()).readValue(jsonNode) + } catch (e: Exception) { + throw StagehandInvalidDataException("Error reading response", e) + } + + private val jsonNode by lazy { + try { + jsonMapper.readTree(data) + } catch (e: Exception) { + throw StagehandInvalidDataException("Error reading response", e) + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SseMessage && + event == other.event && + data == other.data && + id == other.id && + retry == other.retry + } + + override fun hashCode(): Int = Objects.hash(event, data, id, retry) + + override fun toString(): String = "SseMessage{event=$event, data=$data, id=$id, retry=$retry}" +} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/errors/SseException.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/errors/SseException.kt new file mode 100644 index 0000000..0dfdd2f --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/errors/SseException.kt @@ -0,0 +1,91 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.errors + +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.checkRequired +import com.browserbase.api.core.http.Headers +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class SseException +private constructor( + private val statusCode: Int, + private val headers: Headers, + private val body: JsonValue, + cause: Throwable?, +) : StagehandServiceException("$statusCode: $body", cause) { + + override fun statusCode(): Int = statusCode + + override fun headers(): Headers = headers + + override fun body(): JsonValue = body + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [SseException]. + * + * The following fields are required: + * ```java + * .statusCode() + * .headers() + * .body() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SseException]. */ + class Builder internal constructor() { + + private var statusCode: Int? = null + private var headers: Headers? = null + private var body: JsonValue? = null + private var cause: Throwable? = null + + @JvmSynthetic + internal fun from(sseException: SseException) = apply { + statusCode = sseException.statusCode + headers = sseException.headers + body = sseException.body + cause = sseException.cause + } + + fun statusCode(statusCode: Int) = apply { this.statusCode = statusCode } + + fun headers(headers: Headers) = apply { this.headers = headers } + + fun body(body: JsonValue) = apply { this.body = body } + + fun cause(cause: Throwable?) = apply { this.cause = cause } + + /** Alias for calling [Builder.cause] with `cause.orElse(null)`. */ + fun cause(cause: Optional) = cause(cause.getOrNull()) + + /** + * Returns an immutable instance of [SseException]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .statusCode() + * .headers() + * .body() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SseException = + SseException( + checkRequired("statusCode", statusCode), + checkRequired("headers", headers), + checkRequired("body", body), + cause, + ) + } +} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt index 019f026..a37780c 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionActParams.kt @@ -11,7 +11,6 @@ import com.browserbase.api.core.JsonMissing import com.browserbase.api.core.JsonValue import com.browserbase.api.core.Params import com.browserbase.api.core.allMaxBy -import com.browserbase.api.core.checkKnown import com.browserbase.api.core.checkRequired import com.browserbase.api.core.getOrThrow import com.browserbase.api.core.http.Headers @@ -213,7 +212,7 @@ private constructor( fun input(string: String) = apply { body.input(string) } /** Alias for calling [input] with `Input.ofAction(action)`. */ - fun input(action: Input.ActionInput) = apply { body.input(action) } + fun input(action: Action) = apply { body.input(action) } /** Target frame ID for the action */ fun frameId(frameId: String) = apply { body.frameId(frameId) } @@ -515,7 +514,7 @@ private constructor( fun input(string: String) = input(Input.ofString(string)) /** Alias for calling [input] with `Input.ofAction(action)`. */ - fun input(action: Input.ActionInput) = input(Input.ofAction(action)) + fun input(action: Action) = input(Input.ofAction(action)) /** Target frame ID for the action */ fun frameId(frameId: String) = frameId(JsonField.of(frameId)) @@ -641,14 +640,14 @@ private constructor( class Input private constructor( private val string: String? = null, - private val action: ActionInput? = null, + private val action: Action? = null, private val _json: JsonValue? = null, ) { fun string(): Optional = Optional.ofNullable(string) /** Action object returned by observe and used by act */ - fun action(): Optional = Optional.ofNullable(action) + fun action(): Optional = Optional.ofNullable(action) fun isString(): Boolean = string != null @@ -657,7 +656,7 @@ private constructor( fun asString(): String = string.getOrThrow("string") /** Action object returned by observe and used by act */ - fun asAction(): ActionInput = action.getOrThrow("action") + fun asAction(): Action = action.getOrThrow("action") fun _json(): Optional = Optional.ofNullable(_json) @@ -679,7 +678,7 @@ private constructor( object : Visitor { override fun visitString(string: String) {} - override fun visitAction(action: ActionInput) { + override fun visitAction(action: Action) { action.validate() } } @@ -707,7 +706,7 @@ private constructor( object : Visitor { override fun visitString(string: String) = 1 - override fun visitAction(action: ActionInput) = action.validity() + override fun visitAction(action: Action) = action.validity() override fun unknown(json: JsonValue?) = 0 } @@ -736,7 +735,7 @@ private constructor( @JvmStatic fun ofString(string: String) = Input(string = string) /** Action object returned by observe and used by act */ - @JvmStatic fun ofAction(action: ActionInput) = Input(action = action) + @JvmStatic fun ofAction(action: Action) = Input(action = action) } /** An interface that defines how to map each variant of [Input] to a value of type [T]. */ @@ -745,7 +744,7 @@ private constructor( fun visitString(string: String): T /** Action object returned by observe and used by act */ - fun visitAction(action: ActionInput): T + fun visitAction(action: Action): T /** * Maps an unknown variant of [Input] to a value of type [T]. @@ -769,7 +768,7 @@ private constructor( val bestMatches = sequenceOf( - tryDeserialize(node, jacksonTypeRef())?.let { + tryDeserialize(node, jacksonTypeRef())?.let { Input(action = it, _json = json) }, tryDeserialize(node, jacksonTypeRef())?.let { @@ -807,311 +806,6 @@ private constructor( } } } - - /** Action object returned by observe and used by act */ - class ActionInput - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val description: JsonField, - private val selector: JsonField, - private val arguments: JsonField>, - private val method: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("description") - @ExcludeMissing - description: JsonField = JsonMissing.of(), - @JsonProperty("selector") - @ExcludeMissing - selector: JsonField = JsonMissing.of(), - @JsonProperty("arguments") - @ExcludeMissing - arguments: JsonField> = JsonMissing.of(), - @JsonProperty("method") @ExcludeMissing method: JsonField = JsonMissing.of(), - ) : this(description, selector, arguments, method, mutableMapOf()) - - /** - * Human-readable description of the action - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). - */ - fun description(): String = description.getRequired("description") - - /** - * CSS selector or XPath for the element - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). - */ - fun selector(): String = selector.getRequired("selector") - - /** - * Arguments to pass to the method - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun arguments(): Optional> = arguments.getOptional("arguments") - - /** - * The method to execute (click, fill, etc.) - * - * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. - * if the server responded with an unexpected value). - */ - fun method(): Optional = method.getOptional("method") - - /** - * Returns the raw JSON value of [description]. - * - * Unlike [description], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("description") - @ExcludeMissing - fun _description(): JsonField = description - - /** - * Returns the raw JSON value of [selector]. - * - * Unlike [selector], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("selector") @ExcludeMissing fun _selector(): JsonField = selector - - /** - * Returns the raw JSON value of [arguments]. - * - * Unlike [arguments], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("arguments") - @ExcludeMissing - fun _arguments(): JsonField> = arguments - - /** - * Returns the raw JSON value of [method]. - * - * Unlike [method], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("method") @ExcludeMissing fun _method(): JsonField = method - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [ActionInput]. - * - * The following fields are required: - * ```java - * .description() - * .selector() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [ActionInput]. */ - class Builder internal constructor() { - - private var description: JsonField? = null - private var selector: JsonField? = null - private var arguments: JsonField>? = null - private var method: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(actionInput: ActionInput) = apply { - description = actionInput.description - selector = actionInput.selector - arguments = actionInput.arguments.map { it.toMutableList() } - method = actionInput.method - additionalProperties = actionInput.additionalProperties.toMutableMap() - } - - /** Human-readable description of the action */ - fun description(description: String) = description(JsonField.of(description)) - - /** - * Sets [Builder.description] to an arbitrary JSON value. - * - * You should usually call [Builder.description] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun description(description: JsonField) = apply { - this.description = description - } - - /** CSS selector or XPath for the element */ - fun selector(selector: String) = selector(JsonField.of(selector)) - - /** - * Sets [Builder.selector] to an arbitrary JSON value. - * - * You should usually call [Builder.selector] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun selector(selector: JsonField) = apply { this.selector = selector } - - /** Arguments to pass to the method */ - fun arguments(arguments: List) = arguments(JsonField.of(arguments)) - - /** - * Sets [Builder.arguments] to an arbitrary JSON value. - * - * You should usually call [Builder.arguments] with a well-typed `List` - * value instead. This method is primarily for setting the field to an undocumented - * or not yet supported value. - */ - fun arguments(arguments: JsonField>) = apply { - this.arguments = arguments.map { it.toMutableList() } - } - - /** - * Adds a single [String] to [arguments]. - * - * @throws IllegalStateException if the field was previously set to a non-list. - */ - fun addArgument(argument: String) = apply { - arguments = - (arguments ?: JsonField.of(mutableListOf())).also { - checkKnown("arguments", it).add(argument) - } - } - - /** The method to execute (click, fill, etc.) */ - fun method(method: String) = method(JsonField.of(method)) - - /** - * Sets [Builder.method] to an arbitrary JSON value. - * - * You should usually call [Builder.method] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun method(method: JsonField) = apply { this.method = method } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [ActionInput]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .description() - * .selector() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): ActionInput = - ActionInput( - checkRequired("description", description), - checkRequired("selector", selector), - (arguments ?: JsonMissing.of()).map { it.toImmutable() }, - method, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): ActionInput = apply { - if (validated) { - return@apply - } - - description() - selector() - arguments() - method() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: StagehandInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (if (description.asKnown().isPresent) 1 else 0) + - (if (selector.asKnown().isPresent) 1 else 0) + - (arguments.asKnown().getOrNull()?.size ?: 0) + - (if (method.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ActionInput && - description == other.description && - selector == other.selector && - arguments == other.arguments && - method == other.method && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(description, selector, arguments, method, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "ActionInput{description=$description, selector=$selector, arguments=$arguments, method=$method, additionalProperties=$additionalProperties}" - } } class Options diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateParams.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateParams.kt index b07cf2c..112be92 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateParams.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionNavigateParams.kt @@ -73,6 +73,14 @@ private constructor( */ fun options(): Optional = body.options() + /** + * Whether to stream the response via SSE + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun streamResponse(): Optional = body.streamResponse() + /** * Returns the raw JSON value of [url]. * @@ -94,6 +102,13 @@ private constructor( */ fun _options(): JsonField = body._options() + /** + * Returns the raw JSON value of [streamResponse]. + * + * Unlike [streamResponse], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _streamResponse(): JsonField = body._streamResponse() + fun _additionalBodyProperties(): Map = body._additionalProperties() /** Additional headers to send with the request. */ @@ -182,6 +197,7 @@ private constructor( * - [url] * - [frameId] * - [options] + * - [streamResponse] */ fun body(body: Body) = apply { this.body = body.toBuilder() } @@ -217,6 +233,20 @@ private constructor( */ fun options(options: JsonField) = apply { body.options(options) } + /** Whether to stream the response via SSE */ + fun streamResponse(streamResponse: Boolean) = apply { body.streamResponse(streamResponse) } + + /** + * Sets [Builder.streamResponse] to an arbitrary JSON value. + * + * You should usually call [Builder.streamResponse] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun streamResponse(streamResponse: JsonField) = apply { + body.streamResponse(streamResponse) + } + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { body.additionalProperties(additionalBodyProperties) } @@ -386,6 +416,7 @@ private constructor( private val url: JsonField, private val frameId: JsonField, private val options: JsonField, + private val streamResponse: JsonField, private val additionalProperties: MutableMap, ) { @@ -394,7 +425,10 @@ private constructor( @JsonProperty("url") @ExcludeMissing url: JsonField = JsonMissing.of(), @JsonProperty("frameId") @ExcludeMissing frameId: JsonField = JsonMissing.of(), @JsonProperty("options") @ExcludeMissing options: JsonField = JsonMissing.of(), - ) : this(url, frameId, options, mutableMapOf()) + @JsonProperty("streamResponse") + @ExcludeMissing + streamResponse: JsonField = JsonMissing.of(), + ) : this(url, frameId, options, streamResponse, mutableMapOf()) /** * URL to navigate to @@ -418,6 +452,14 @@ private constructor( */ fun options(): Optional = options.getOptional("options") + /** + * Whether to stream the response via SSE + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun streamResponse(): Optional = streamResponse.getOptional("streamResponse") + /** * Returns the raw JSON value of [url]. * @@ -439,6 +481,16 @@ private constructor( */ @JsonProperty("options") @ExcludeMissing fun _options(): JsonField = options + /** + * Returns the raw JSON value of [streamResponse]. + * + * Unlike [streamResponse], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("streamResponse") + @ExcludeMissing + fun _streamResponse(): JsonField = streamResponse + @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) @@ -470,6 +522,7 @@ private constructor( private var url: JsonField? = null private var frameId: JsonField = JsonMissing.of() private var options: JsonField = JsonMissing.of() + private var streamResponse: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic @@ -477,6 +530,7 @@ private constructor( url = body.url frameId = body.frameId options = body.options + streamResponse = body.streamResponse additionalProperties = body.additionalProperties.toMutableMap() } @@ -515,6 +569,21 @@ private constructor( */ fun options(options: JsonField) = apply { this.options = options } + /** Whether to stream the response via SSE */ + fun streamResponse(streamResponse: Boolean) = + streamResponse(JsonField.of(streamResponse)) + + /** + * Sets [Builder.streamResponse] to an arbitrary JSON value. + * + * You should usually call [Builder.streamResponse] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun streamResponse(streamResponse: JsonField) = apply { + this.streamResponse = streamResponse + } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -551,6 +620,7 @@ private constructor( checkRequired("url", url), frameId, options, + streamResponse, additionalProperties.toMutableMap(), ) } @@ -565,6 +635,7 @@ private constructor( url() frameId() options().ifPresent { it.validate() } + streamResponse() validated = true } @@ -586,7 +657,8 @@ private constructor( internal fun validity(): Int = (if (url.asKnown().isPresent) 1 else 0) + (if (frameId.asKnown().isPresent) 1 else 0) + - (options.asKnown().getOrNull()?.validity() ?: 0) + (options.asKnown().getOrNull()?.validity() ?: 0) + + (if (streamResponse.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { if (this === other) { @@ -597,17 +669,18 @@ private constructor( url == other.url && frameId == other.frameId && options == other.options && + streamResponse == other.streamResponse && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash(url, frameId, options, additionalProperties) + Objects.hash(url, frameId, options, streamResponse, additionalProperties) } override fun hashCode(): Int = hashCode override fun toString() = - "Body{url=$url, frameId=$frameId, options=$options, additionalProperties=$additionalProperties}" + "Body{url=$url, frameId=$frameId, options=$options, streamResponse=$streamResponse, additionalProperties=$additionalProperties}" } class Options diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartResponse.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartResponse.kt index a172070..13ed630 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartResponse.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionStartResponse.kt @@ -192,6 +192,7 @@ private constructor( @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val available: JsonField, + private val connectUrl: JsonField, private val sessionId: JsonField, private val additionalProperties: MutableMap, ) { @@ -201,10 +202,13 @@ private constructor( @JsonProperty("available") @ExcludeMissing available: JsonField = JsonMissing.of(), + @JsonProperty("connectUrl") + @ExcludeMissing + connectUrl: JsonField = JsonMissing.of(), @JsonProperty("sessionId") @ExcludeMissing sessionId: JsonField = JsonMissing.of(), - ) : this(available, sessionId, mutableMapOf()) + ) : this(available, connectUrl, sessionId, mutableMapOf()) /** * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is @@ -213,7 +217,15 @@ private constructor( fun available(): Boolean = available.getRequired("available") /** - * Unique session identifier + * CDP WebSocket URL for connecting to the Browserbase cloud browser + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun connectUrl(): String = connectUrl.getRequired("connectUrl") + + /** + * Unique Browserbase session identifier * * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is * unexpectedly missing or null (e.g. if the server responded with an unexpected value). @@ -227,6 +239,15 @@ private constructor( */ @JsonProperty("available") @ExcludeMissing fun _available(): JsonField = available + /** + * Returns the raw JSON value of [connectUrl]. + * + * Unlike [connectUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("connectUrl") + @ExcludeMissing + fun _connectUrl(): JsonField = connectUrl + /** * Returns the raw JSON value of [sessionId]. * @@ -254,6 +275,7 @@ private constructor( * The following fields are required: * ```java * .available() + * .connectUrl() * .sessionId() * ``` */ @@ -264,12 +286,14 @@ private constructor( class Builder internal constructor() { private var available: JsonField? = null + private var connectUrl: JsonField? = null private var sessionId: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(data: Data) = apply { available = data.available + connectUrl = data.connectUrl sessionId = data.sessionId additionalProperties = data.additionalProperties.toMutableMap() } @@ -285,7 +309,19 @@ private constructor( */ fun available(available: JsonField) = apply { this.available = available } - /** Unique session identifier */ + /** CDP WebSocket URL for connecting to the Browserbase cloud browser */ + fun connectUrl(connectUrl: String) = connectUrl(JsonField.of(connectUrl)) + + /** + * Sets [Builder.connectUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.connectUrl] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun connectUrl(connectUrl: JsonField) = apply { this.connectUrl = connectUrl } + + /** Unique Browserbase session identifier */ fun sessionId(sessionId: String) = sessionId(JsonField.of(sessionId)) /** @@ -324,6 +360,7 @@ private constructor( * The following fields are required: * ```java * .available() + * .connectUrl() * .sessionId() * ``` * @@ -332,6 +369,7 @@ private constructor( fun build(): Data = Data( checkRequired("available", available), + checkRequired("connectUrl", connectUrl), checkRequired("sessionId", sessionId), additionalProperties.toMutableMap(), ) @@ -345,6 +383,7 @@ private constructor( } available() + connectUrl() sessionId() validated = true } @@ -366,6 +405,7 @@ private constructor( @JvmSynthetic internal fun validity(): Int = (if (available.asKnown().isPresent) 1 else 0) + + (if (connectUrl.asKnown().isPresent) 1 else 0) + (if (sessionId.asKnown().isPresent) 1 else 0) override fun equals(other: Any?): Boolean { @@ -375,18 +415,19 @@ private constructor( return other is Data && available == other.available && + connectUrl == other.connectUrl && sessionId == other.sessionId && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash(available, sessionId, additionalProperties) + Objects.hash(available, connectUrl, sessionId, additionalProperties) } override fun hashCode(): Int = hashCode override fun toString() = - "Data{available=$available, sessionId=$sessionId, additionalProperties=$additionalProperties}" + "Data{available=$available, connectUrl=$connectUrl, sessionId=$sessionId, additionalProperties=$additionalProperties}" } override fun equals(other: Any?): Boolean { diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/StreamEvent.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/StreamEvent.kt new file mode 100644 index 0000000..d58dc3b --- /dev/null +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/StreamEvent.kt @@ -0,0 +1,1175 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.BaseDeserializer +import com.browserbase.api.core.BaseSerializer +import com.browserbase.api.core.Enum +import com.browserbase.api.core.ExcludeMissing +import com.browserbase.api.core.JsonField +import com.browserbase.api.core.JsonMissing +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.allMaxBy +import com.browserbase.api.core.checkRequired +import com.browserbase.api.core.getOrThrow +import com.browserbase.api.errors.StagehandInvalidDataException +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Server-Sent Event emitted during streaming responses. Events are sent as `data: \n\n`. */ +class StreamEvent +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val id: JsonField, + private val data: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this(id, data, type, mutableMapOf()) + + /** + * Unique identifier for this event + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun id(): String = id.getRequired("id") + + /** + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun data(): Data = data.getRequired("data") + + /** + * Type of stream event - system events or log messages + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun type(): Type = type.getRequired("type") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField = data + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [StreamEvent]. + * + * The following fields are required: + * ```java + * .id() + * .data() + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [StreamEvent]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var data: JsonField? = null + private var type: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(streamEvent: StreamEvent) = apply { + id = streamEvent.id + data = streamEvent.data + type = streamEvent.type + additionalProperties = streamEvent.additionalProperties.toMutableMap() + } + + /** Unique identifier for this event */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + fun data(data: Data) = data(JsonField.of(data)) + + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed [Data] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun data(data: JsonField) = apply { this.data = data } + + /** + * Alias for calling [data] with + * `Data.ofStreamEventSystemDataOutput(streamEventSystemDataOutput)`. + */ + fun data(streamEventSystemDataOutput: Data.StreamEventSystemDataOutput) = + data(Data.ofStreamEventSystemDataOutput(streamEventSystemDataOutput)) + + /** + * Alias for calling [data] with + * `Data.ofStreamEventLogDataOutput(streamEventLogDataOutput)`. + */ + fun data(streamEventLogDataOutput: Data.StreamEventLogDataOutput) = + data(Data.ofStreamEventLogDataOutput(streamEventLogDataOutput)) + + /** Type of stream event - system events or log messages */ + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [StreamEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .data() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): StreamEvent = + StreamEvent( + checkRequired("id", id), + checkRequired("data", data), + checkRequired("type", type), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): StreamEvent = apply { + if (validated) { + return@apply + } + + id() + data().validate() + type().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (id.asKnown().isPresent) 1 else 0) + + (data.asKnown().getOrNull()?.validity() ?: 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + @JsonDeserialize(using = Data.Deserializer::class) + @JsonSerialize(using = Data.Serializer::class) + class Data + private constructor( + private val streamEventSystemDataOutput: StreamEventSystemDataOutput? = null, + private val streamEventLogDataOutput: StreamEventLogDataOutput? = null, + private val _json: JsonValue? = null, + ) { + + fun streamEventSystemDataOutput(): Optional = + Optional.ofNullable(streamEventSystemDataOutput) + + fun streamEventLogDataOutput(): Optional = + Optional.ofNullable(streamEventLogDataOutput) + + fun isStreamEventSystemDataOutput(): Boolean = streamEventSystemDataOutput != null + + fun isStreamEventLogDataOutput(): Boolean = streamEventLogDataOutput != null + + fun asStreamEventSystemDataOutput(): StreamEventSystemDataOutput = + streamEventSystemDataOutput.getOrThrow("streamEventSystemDataOutput") + + fun asStreamEventLogDataOutput(): StreamEventLogDataOutput = + streamEventLogDataOutput.getOrThrow("streamEventLogDataOutput") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + streamEventSystemDataOutput != null -> + visitor.visitStreamEventSystemDataOutput(streamEventSystemDataOutput) + streamEventLogDataOutput != null -> + visitor.visitStreamEventLogDataOutput(streamEventLogDataOutput) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): Data = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitStreamEventSystemDataOutput( + streamEventSystemDataOutput: StreamEventSystemDataOutput + ) { + streamEventSystemDataOutput.validate() + } + + override fun visitStreamEventLogDataOutput( + streamEventLogDataOutput: StreamEventLogDataOutput + ) { + streamEventLogDataOutput.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitStreamEventSystemDataOutput( + streamEventSystemDataOutput: StreamEventSystemDataOutput + ) = streamEventSystemDataOutput.validity() + + override fun visitStreamEventLogDataOutput( + streamEventLogDataOutput: StreamEventLogDataOutput + ) = streamEventLogDataOutput.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Data && + streamEventSystemDataOutput == other.streamEventSystemDataOutput && + streamEventLogDataOutput == other.streamEventLogDataOutput + } + + override fun hashCode(): Int = + Objects.hash(streamEventSystemDataOutput, streamEventLogDataOutput) + + override fun toString(): String = + when { + streamEventSystemDataOutput != null -> + "Data{streamEventSystemDataOutput=$streamEventSystemDataOutput}" + streamEventLogDataOutput != null -> + "Data{streamEventLogDataOutput=$streamEventLogDataOutput}" + _json != null -> "Data{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Data") + } + + companion object { + + @JvmStatic + fun ofStreamEventSystemDataOutput( + streamEventSystemDataOutput: StreamEventSystemDataOutput + ) = Data(streamEventSystemDataOutput = streamEventSystemDataOutput) + + @JvmStatic + fun ofStreamEventLogDataOutput(streamEventLogDataOutput: StreamEventLogDataOutput) = + Data(streamEventLogDataOutput = streamEventLogDataOutput) + } + + /** An interface that defines how to map each variant of [Data] to a value of type [T]. */ + interface Visitor { + + fun visitStreamEventSystemDataOutput( + streamEventSystemDataOutput: StreamEventSystemDataOutput + ): T + + fun visitStreamEventLogDataOutput(streamEventLogDataOutput: StreamEventLogDataOutput): T + + /** + * Maps an unknown variant of [Data] to a value of type [T]. + * + * An instance of [Data] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws StagehandInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw StagehandInvalidDataException("Unknown Data: $json") + } + } + + internal class Deserializer : BaseDeserializer(Data::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Data { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef()) + ?.let { Data(streamEventSystemDataOutput = it, _json = json) }, + tryDeserialize(node, jacksonTypeRef())?.let { + Data(streamEventLogDataOutput = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with + // all the possible variants (e.g. deserializing from boolean). + 0 -> Data(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely + // valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Data::class) { + + override fun serialize( + value: Data, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.streamEventSystemDataOutput != null -> + generator.writeObject(value.streamEventSystemDataOutput) + value.streamEventLogDataOutput != null -> + generator.writeObject(value.streamEventLogDataOutput) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Data") + } + } + } + + class StreamEventSystemDataOutput + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val status: JsonField, + private val error: JsonField, + private val result: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("status") + @ExcludeMissing + status: JsonField = JsonMissing.of(), + @JsonProperty("error") @ExcludeMissing error: JsonField = JsonMissing.of(), + @JsonProperty("result") @ExcludeMissing result: JsonValue = JsonMissing.of(), + ) : this(status, error, result, mutableMapOf()) + + /** + * Current status of the streaming operation + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun status(): Status = status.getRequired("status") + + /** + * Error message (present when status is 'error') + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun error(): Optional = error.getOptional("error") + + /** Operation result (present when status is 'finished') */ + @JsonProperty("result") @ExcludeMissing fun _result(): JsonValue = result + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + /** + * Returns the raw JSON value of [error]. + * + * Unlike [error], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("error") @ExcludeMissing fun _error(): JsonField = error + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [StreamEventSystemDataOutput]. + * + * The following fields are required: + * ```java + * .status() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [StreamEventSystemDataOutput]. */ + class Builder internal constructor() { + + private var status: JsonField? = null + private var error: JsonField = JsonMissing.of() + private var result: JsonValue = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(streamEventSystemDataOutput: StreamEventSystemDataOutput) = + apply { + status = streamEventSystemDataOutput.status + error = streamEventSystemDataOutput.error + result = streamEventSystemDataOutput.result + additionalProperties = + streamEventSystemDataOutput.additionalProperties.toMutableMap() + } + + /** Current status of the streaming operation */ + fun status(status: Status) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [Status] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + /** Error message (present when status is 'error') */ + fun error(error: String) = error(JsonField.of(error)) + + /** + * Sets [Builder.error] to an arbitrary JSON value. + * + * You should usually call [Builder.error] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun error(error: JsonField) = apply { this.error = error } + + /** Operation result (present when status is 'finished') */ + fun result(result: JsonValue) = apply { this.result = result } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [StreamEventSystemDataOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .status() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): StreamEventSystemDataOutput = + StreamEventSystemDataOutput( + checkRequired("status", status), + error, + result, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): StreamEventSystemDataOutput = apply { + if (validated) { + return@apply + } + + status().validate() + error() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (status.asKnown().getOrNull()?.validity() ?: 0) + + (if (error.asKnown().isPresent) 1 else 0) + + /** Current status of the streaming operation */ + class Status @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that + * doesn't match any known member, and you want to know that value. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val STARTING = of("starting") + + @JvmField val CONNECTED = of("connected") + + @JvmField val RUNNING = of("running") + + @JvmField val FINISHED = of("finished") + + @JvmField val ERROR = of("error") + + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) + } + + /** An enum containing [Status]'s known values. */ + enum class Known { + STARTING, + CONNECTED, + RUNNING, + FINISHED, + ERROR, + } + + /** + * An enum containing [Status]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Status] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, + * if the SDK is on an older version than the API, then the API may respond with + * new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + STARTING, + CONNECTED, + RUNNING, + FINISHED, + ERROR, + /** + * An enum member indicating that [Status] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if + * you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + STARTING -> Value.STARTING + CONNECTED -> Value.CONNECTED + RUNNING -> Value.RUNNING + FINISHED -> Value.FINISHED + ERROR -> Value.ERROR + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + STARTING -> Known.STARTING + CONNECTED -> Known.CONNECTED + RUNNING -> Known.RUNNING + FINISHED -> Known.FINISHED + ERROR -> Known.ERROR + else -> throw StagehandInvalidDataException("Unknown Status: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Status = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Status && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is StreamEventSystemDataOutput && + status == other.status && + error == other.error && + result == other.result && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(status, error, result, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "StreamEventSystemDataOutput{status=$status, error=$error, result=$result, additionalProperties=$additionalProperties}" + } + + class StreamEventLogDataOutput + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val message: JsonField, + private val status: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("message") + @ExcludeMissing + message: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonValue = JsonMissing.of(), + ) : this(message, status, mutableMapOf()) + + /** + * Log message from the operation + * + * @throws StagehandInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun message(): String = message.getRequired("message") + + /** + * Expected to always return the following: + * ```java + * JsonValue.from("running") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonValue = status + + /** + * Returns the raw JSON value of [message]. + * + * Unlike [message], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("message") @ExcludeMissing fun _message(): JsonField = message + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [StreamEventLogDataOutput]. + * + * The following fields are required: + * ```java + * .message() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [StreamEventLogDataOutput]. */ + class Builder internal constructor() { + + private var message: JsonField? = null + private var status: JsonValue = JsonValue.from("running") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(streamEventLogDataOutput: StreamEventLogDataOutput) = apply { + message = streamEventLogDataOutput.message + status = streamEventLogDataOutput.status + additionalProperties = + streamEventLogDataOutput.additionalProperties.toMutableMap() + } + + /** Log message from the operation */ + fun message(message: String) = message(JsonField.of(message)) + + /** + * Sets [Builder.message] to an arbitrary JSON value. + * + * You should usually call [Builder.message] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun message(message: JsonField) = apply { this.message = message } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("running") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun status(status: JsonValue) = apply { this.status = status } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [StreamEventLogDataOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .message() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): StreamEventLogDataOutput = + StreamEventLogDataOutput( + checkRequired("message", message), + status, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): StreamEventLogDataOutput = apply { + if (validated) { + return@apply + } + + message() + _status().let { + if (it != JsonValue.from("running")) { + throw StagehandInvalidDataException("'status' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (message.asKnown().isPresent) 1 else 0) + + status.let { if (it == JsonValue.from("running")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is StreamEventLogDataOutput && + message == other.message && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(message, status, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "StreamEventLogDataOutput{message=$message, status=$status, additionalProperties=$additionalProperties}" + } + } + + /** Type of stream event - system events or log messages */ + class Type @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val SYSTEM = of("system") + + @JvmField val LOG = of("log") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + SYSTEM, + LOG, + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + SYSTEM, + LOG, + /** An enum member indicating that [Type] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + SYSTEM -> Value.SYSTEM + LOG -> Value.LOG + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws StagehandInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + SYSTEM -> Known.SYSTEM + LOG -> Known.LOG + else -> throw StagehandInvalidDataException("Unknown Type: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws StagehandInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + StagehandInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Type = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: StagehandInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Type && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is StreamEvent && + id == other.id && + data == other.data && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(id, data, type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "StreamEvent{id=$id, data=$data, type=$type, additionalProperties=$additionalProperties}" +} diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsync.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsync.kt index 423fd57..5c9171e 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsync.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsync.kt @@ -4,7 +4,9 @@ package com.browserbase.api.services.async import com.browserbase.api.core.ClientOptions import com.browserbase.api.core.RequestOptions +import com.browserbase.api.core.http.AsyncStreamResponse import com.browserbase.api.core.http.HttpResponseFor +import com.browserbase.api.core.http.StreamResponse import com.browserbase.api.models.sessions.SessionActParams import com.browserbase.api.models.sessions.SessionActResponse import com.browserbase.api.models.sessions.SessionEndParams @@ -19,6 +21,8 @@ import com.browserbase.api.models.sessions.SessionObserveParams import com.browserbase.api.models.sessions.SessionObserveResponse import com.browserbase.api.models.sessions.SessionStartParams import com.browserbase.api.models.sessions.SessionStartResponse +import com.browserbase.api.models.sessions.StreamEvent +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture import java.util.function.Consumer @@ -60,6 +64,30 @@ interface SessionServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** + * Executes a browser action using natural language instructions or a predefined Action object. + */ + fun actStreaming(id: String, params: SessionActParams): AsyncStreamResponse = + actStreaming(id, params, RequestOptions.none()) + + /** @see actStreaming */ + fun actStreaming( + id: String, + params: SessionActParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): AsyncStreamResponse = + actStreaming(params.toBuilder().id(id).build(), requestOptions) + + /** @see actStreaming */ + fun actStreaming(params: SessionActParams): AsyncStreamResponse = + actStreaming(params, RequestOptions.none()) + + /** @see actStreaming */ + fun actStreaming( + params: SessionActParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): AsyncStreamResponse + /** Terminates the browser session and releases all associated resources. */ fun end(id: String): CompletableFuture = end(id, SessionEndParams.none()) @@ -115,6 +143,30 @@ interface SessionServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** Runs an autonomous AI agent that can perform complex multi-step browser tasks. */ + fun executeStreaming( + id: String, + params: SessionExecuteParams, + ): AsyncStreamResponse = executeStreaming(id, params, RequestOptions.none()) + + /** @see executeStreaming */ + fun executeStreaming( + id: String, + params: SessionExecuteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): AsyncStreamResponse = + executeStreaming(params.toBuilder().id(id).build(), requestOptions) + + /** @see executeStreaming */ + fun executeStreaming(params: SessionExecuteParams): AsyncStreamResponse = + executeStreaming(params, RequestOptions.none()) + + /** @see executeStreaming */ + fun executeStreaming( + params: SessionExecuteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): AsyncStreamResponse + /** Extracts structured data from the current page using AI-powered analysis. */ fun extract(id: String): CompletableFuture = extract(id, SessionExtractParams.none()) @@ -150,6 +202,41 @@ interface SessionServiceAsync { ): CompletableFuture = extract(id, SessionExtractParams.none(), requestOptions) + /** Extracts structured data from the current page using AI-powered analysis. */ + fun extractStreaming(id: String): AsyncStreamResponse = + extractStreaming(id, SessionExtractParams.none()) + + /** @see extractStreaming */ + fun extractStreaming( + id: String, + params: SessionExtractParams = SessionExtractParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): AsyncStreamResponse = + extractStreaming(params.toBuilder().id(id).build(), requestOptions) + + /** @see extractStreaming */ + fun extractStreaming( + id: String, + params: SessionExtractParams = SessionExtractParams.none(), + ): AsyncStreamResponse = extractStreaming(id, params, RequestOptions.none()) + + /** @see extractStreaming */ + fun extractStreaming( + params: SessionExtractParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): AsyncStreamResponse + + /** @see extractStreaming */ + fun extractStreaming(params: SessionExtractParams): AsyncStreamResponse = + extractStreaming(params, RequestOptions.none()) + + /** @see extractStreaming */ + fun extractStreaming( + id: String, + requestOptions: RequestOptions, + ): AsyncStreamResponse = + extractStreaming(id, SessionExtractParams.none(), requestOptions) + /** Navigates the browser to the specified URL. */ fun navigate( id: String, @@ -212,6 +299,44 @@ interface SessionServiceAsync { ): CompletableFuture = observe(id, SessionObserveParams.none(), requestOptions) + /** + * Identifies and returns available actions on the current page that match the given + * instruction. + */ + fun observeStreaming(id: String): AsyncStreamResponse = + observeStreaming(id, SessionObserveParams.none()) + + /** @see observeStreaming */ + fun observeStreaming( + id: String, + params: SessionObserveParams = SessionObserveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): AsyncStreamResponse = + observeStreaming(params.toBuilder().id(id).build(), requestOptions) + + /** @see observeStreaming */ + fun observeStreaming( + id: String, + params: SessionObserveParams = SessionObserveParams.none(), + ): AsyncStreamResponse = observeStreaming(id, params, RequestOptions.none()) + + /** @see observeStreaming */ + fun observeStreaming( + params: SessionObserveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): AsyncStreamResponse + + /** @see observeStreaming */ + fun observeStreaming(params: SessionObserveParams): AsyncStreamResponse = + observeStreaming(params, RequestOptions.none()) + + /** @see observeStreaming */ + fun observeStreaming( + id: String, + requestOptions: RequestOptions, + ): AsyncStreamResponse = + observeStreaming(id, SessionObserveParams.none(), requestOptions) + /** * Creates a new browser session with the specified configuration. Returns a session ID used for * all subsequent operations. @@ -267,6 +392,40 @@ interface SessionServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** + * Returns a raw HTTP response for `post /v1/sessions/{id}/act`, but is otherwise the same + * as [SessionServiceAsync.actStreaming]. + */ + @MustBeClosed + fun actStreaming( + id: String, + params: SessionActParams, + ): CompletableFuture>> = + actStreaming(id, params, RequestOptions.none()) + + /** @see actStreaming */ + @MustBeClosed + fun actStreaming( + id: String, + params: SessionActParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture>> = + actStreaming(params.toBuilder().id(id).build(), requestOptions) + + /** @see actStreaming */ + @MustBeClosed + fun actStreaming( + params: SessionActParams + ): CompletableFuture>> = + actStreaming(params, RequestOptions.none()) + + /** @see actStreaming */ + @MustBeClosed + fun actStreaming( + params: SessionActParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture>> + /** * Returns a raw HTTP response for `post /v1/sessions/{id}/end`, but is otherwise the same * as [SessionServiceAsync.end]. @@ -336,6 +495,40 @@ interface SessionServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** + * Returns a raw HTTP response for `post /v1/sessions/{id}/agentExecute`, but is otherwise + * the same as [SessionServiceAsync.executeStreaming]. + */ + @MustBeClosed + fun executeStreaming( + id: String, + params: SessionExecuteParams, + ): CompletableFuture>> = + executeStreaming(id, params, RequestOptions.none()) + + /** @see executeStreaming */ + @MustBeClosed + fun executeStreaming( + id: String, + params: SessionExecuteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture>> = + executeStreaming(params.toBuilder().id(id).build(), requestOptions) + + /** @see executeStreaming */ + @MustBeClosed + fun executeStreaming( + params: SessionExecuteParams + ): CompletableFuture>> = + executeStreaming(params, RequestOptions.none()) + + /** @see executeStreaming */ + @MustBeClosed + fun executeStreaming( + params: SessionExecuteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture>> + /** * Returns a raw HTTP response for `post /v1/sessions/{id}/extract`, but is otherwise the * same as [SessionServiceAsync.extract]. @@ -377,6 +570,55 @@ interface SessionServiceAsync { ): CompletableFuture> = extract(id, SessionExtractParams.none(), requestOptions) + /** + * Returns a raw HTTP response for `post /v1/sessions/{id}/extract`, but is otherwise the + * same as [SessionServiceAsync.extractStreaming]. + */ + @MustBeClosed + fun extractStreaming( + id: String + ): CompletableFuture>> = + extractStreaming(id, SessionExtractParams.none()) + + /** @see extractStreaming */ + @MustBeClosed + fun extractStreaming( + id: String, + params: SessionExtractParams = SessionExtractParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture>> = + extractStreaming(params.toBuilder().id(id).build(), requestOptions) + + /** @see extractStreaming */ + @MustBeClosed + fun extractStreaming( + id: String, + params: SessionExtractParams = SessionExtractParams.none(), + ): CompletableFuture>> = + extractStreaming(id, params, RequestOptions.none()) + + /** @see extractStreaming */ + @MustBeClosed + fun extractStreaming( + params: SessionExtractParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture>> + + /** @see extractStreaming */ + @MustBeClosed + fun extractStreaming( + params: SessionExtractParams + ): CompletableFuture>> = + extractStreaming(params, RequestOptions.none()) + + /** @see extractStreaming */ + @MustBeClosed + fun extractStreaming( + id: String, + requestOptions: RequestOptions, + ): CompletableFuture>> = + extractStreaming(id, SessionExtractParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /v1/sessions/{id}/navigate`, but is otherwise the * same as [SessionServiceAsync.navigate]. @@ -448,6 +690,55 @@ interface SessionServiceAsync { ): CompletableFuture> = observe(id, SessionObserveParams.none(), requestOptions) + /** + * Returns a raw HTTP response for `post /v1/sessions/{id}/observe`, but is otherwise the + * same as [SessionServiceAsync.observeStreaming]. + */ + @MustBeClosed + fun observeStreaming( + id: String + ): CompletableFuture>> = + observeStreaming(id, SessionObserveParams.none()) + + /** @see observeStreaming */ + @MustBeClosed + fun observeStreaming( + id: String, + params: SessionObserveParams = SessionObserveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture>> = + observeStreaming(params.toBuilder().id(id).build(), requestOptions) + + /** @see observeStreaming */ + @MustBeClosed + fun observeStreaming( + id: String, + params: SessionObserveParams = SessionObserveParams.none(), + ): CompletableFuture>> = + observeStreaming(id, params, RequestOptions.none()) + + /** @see observeStreaming */ + @MustBeClosed + fun observeStreaming( + params: SessionObserveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture>> + + /** @see observeStreaming */ + @MustBeClosed + fun observeStreaming( + params: SessionObserveParams + ): CompletableFuture>> = + observeStreaming(params, RequestOptions.none()) + + /** @see observeStreaming */ + @MustBeClosed + fun observeStreaming( + id: String, + requestOptions: RequestOptions, + ): CompletableFuture>> = + observeStreaming(id, SessionObserveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /v1/sessions/start`, but is otherwise the same as * [SessionServiceAsync.start]. diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsyncImpl.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsyncImpl.kt index 99037bc..82062e4 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsyncImpl.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/async/SessionServiceAsyncImpl.kt @@ -3,18 +3,25 @@ package com.browserbase.api.services.async import com.browserbase.api.core.ClientOptions +import com.browserbase.api.core.JsonValue import com.browserbase.api.core.RequestOptions import com.browserbase.api.core.checkRequired import com.browserbase.api.core.handlers.errorBodyHandler import com.browserbase.api.core.handlers.errorHandler import com.browserbase.api.core.handlers.jsonHandler +import com.browserbase.api.core.handlers.mapJson +import com.browserbase.api.core.handlers.sseHandler +import com.browserbase.api.core.http.AsyncStreamResponse import com.browserbase.api.core.http.HttpMethod import com.browserbase.api.core.http.HttpRequest import com.browserbase.api.core.http.HttpResponse import com.browserbase.api.core.http.HttpResponse.Handler import com.browserbase.api.core.http.HttpResponseFor +import com.browserbase.api.core.http.StreamResponse import com.browserbase.api.core.http.json +import com.browserbase.api.core.http.map import com.browserbase.api.core.http.parseable +import com.browserbase.api.core.http.toAsync import com.browserbase.api.core.prepareAsync import com.browserbase.api.models.sessions.SessionActParams import com.browserbase.api.models.sessions.SessionActResponse @@ -30,6 +37,7 @@ import com.browserbase.api.models.sessions.SessionObserveParams import com.browserbase.api.models.sessions.SessionObserveResponse import com.browserbase.api.models.sessions.SessionStartParams import com.browserbase.api.models.sessions.SessionStartResponse +import com.browserbase.api.models.sessions.StreamEvent import java.util.concurrent.CompletableFuture import java.util.function.Consumer import kotlin.jvm.optionals.getOrNull @@ -53,6 +61,16 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl // post /v1/sessions/{id}/act withRawResponse().act(params, requestOptions).thenApply { it.parse() } + override fun actStreaming( + params: SessionActParams, + requestOptions: RequestOptions, + ): AsyncStreamResponse = + // post /v1/sessions/{id}/act + withRawResponse() + .actStreaming(params, requestOptions) + .thenApply { it.parse() } + .toAsync(clientOptions.streamHandlerExecutor) + override fun end( params: SessionEndParams, requestOptions: RequestOptions, @@ -67,6 +85,16 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl // post /v1/sessions/{id}/agentExecute withRawResponse().execute(params, requestOptions).thenApply { it.parse() } + override fun executeStreaming( + params: SessionExecuteParams, + requestOptions: RequestOptions, + ): AsyncStreamResponse = + // post /v1/sessions/{id}/agentExecute + withRawResponse() + .executeStreaming(params, requestOptions) + .thenApply { it.parse() } + .toAsync(clientOptions.streamHandlerExecutor) + override fun extract( params: SessionExtractParams, requestOptions: RequestOptions, @@ -74,6 +102,16 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl // post /v1/sessions/{id}/extract withRawResponse().extract(params, requestOptions).thenApply { it.parse() } + override fun extractStreaming( + params: SessionExtractParams, + requestOptions: RequestOptions, + ): AsyncStreamResponse = + // post /v1/sessions/{id}/extract + withRawResponse() + .extractStreaming(params, requestOptions) + .thenApply { it.parse() } + .toAsync(clientOptions.streamHandlerExecutor) + override fun navigate( params: SessionNavigateParams, requestOptions: RequestOptions, @@ -88,6 +126,16 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl // post /v1/sessions/{id}/observe withRawResponse().observe(params, requestOptions).thenApply { it.parse() } + override fun observeStreaming( + params: SessionObserveParams, + requestOptions: RequestOptions, + ): AsyncStreamResponse = + // post /v1/sessions/{id}/observe + withRawResponse() + .observeStreaming(params, requestOptions) + .thenApply { it.parse() } + .toAsync(clientOptions.streamHandlerExecutor) + override fun start( params: SessionStartParams, requestOptions: RequestOptions, @@ -142,6 +190,51 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl } } + private val actStreamingHandler: Handler> = + sseHandler(clientOptions.jsonMapper).mapJson() + + override fun actStreaming( + params: SessionActParams, + requestOptions: RequestOptions, + ): CompletableFuture>> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "sessions", params._pathParam(0), "act") + .body( + json( + clientOptions.jsonMapper, + params + ._body() + .toBuilder() + .putAdditionalProperty("streamResponse", JsonValue.from(true)) + .build(), + ) + ) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .let { actStreamingHandler.handle(it) } + .let { streamResponse -> + if (requestOptions.responseValidation!!) { + streamResponse.map { it.validate() } + } else { + streamResponse + } + } + } + } + } + private val endHandler: Handler = jsonHandler(clientOptions.jsonMapper) @@ -210,6 +303,51 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl } } + private val executeStreamingHandler: Handler> = + sseHandler(clientOptions.jsonMapper).mapJson() + + override fun executeStreaming( + params: SessionExecuteParams, + requestOptions: RequestOptions, + ): CompletableFuture>> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "sessions", params._pathParam(0), "agentExecute") + .body( + json( + clientOptions.jsonMapper, + params + ._body() + .toBuilder() + .putAdditionalProperty("streamResponse", JsonValue.from(true)) + .build(), + ) + ) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .let { executeStreamingHandler.handle(it) } + .let { streamResponse -> + if (requestOptions.responseValidation!!) { + streamResponse.map { it.validate() } + } else { + streamResponse + } + } + } + } + } + private val extractHandler: Handler = jsonHandler(clientOptions.jsonMapper) @@ -244,6 +382,51 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl } } + private val extractStreamingHandler: Handler> = + sseHandler(clientOptions.jsonMapper).mapJson() + + override fun extractStreaming( + params: SessionExtractParams, + requestOptions: RequestOptions, + ): CompletableFuture>> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "sessions", params._pathParam(0), "extract") + .body( + json( + clientOptions.jsonMapper, + params + ._body() + .toBuilder() + .putAdditionalProperty("streamResponse", JsonValue.from(true)) + .build(), + ) + ) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .let { extractStreamingHandler.handle(it) } + .let { streamResponse -> + if (requestOptions.responseValidation!!) { + streamResponse.map { it.validate() } + } else { + streamResponse + } + } + } + } + } + private val navigateHandler: Handler = jsonHandler(clientOptions.jsonMapper) @@ -312,6 +495,51 @@ class SessionServiceAsyncImpl internal constructor(private val clientOptions: Cl } } + private val observeStreamingHandler: Handler> = + sseHandler(clientOptions.jsonMapper).mapJson() + + override fun observeStreaming( + params: SessionObserveParams, + requestOptions: RequestOptions, + ): CompletableFuture>> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "sessions", params._pathParam(0), "observe") + .body( + json( + clientOptions.jsonMapper, + params + ._body() + .toBuilder() + .putAdditionalProperty("streamResponse", JsonValue.from(true)) + .build(), + ) + ) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .let { observeStreamingHandler.handle(it) } + .let { streamResponse -> + if (requestOptions.responseValidation!!) { + streamResponse.map { it.validate() } + } else { + streamResponse + } + } + } + } + } + private val startHandler: Handler = jsonHandler(clientOptions.jsonMapper) diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionService.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionService.kt index df7bb72..0d56e93 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionService.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionService.kt @@ -5,6 +5,7 @@ package com.browserbase.api.services.blocking import com.browserbase.api.core.ClientOptions import com.browserbase.api.core.RequestOptions import com.browserbase.api.core.http.HttpResponseFor +import com.browserbase.api.core.http.StreamResponse import com.browserbase.api.models.sessions.SessionActParams import com.browserbase.api.models.sessions.SessionActResponse import com.browserbase.api.models.sessions.SessionEndParams @@ -19,6 +20,7 @@ import com.browserbase.api.models.sessions.SessionObserveParams import com.browserbase.api.models.sessions.SessionObserveResponse import com.browserbase.api.models.sessions.SessionStartParams import com.browserbase.api.models.sessions.SessionStartResponse +import com.browserbase.api.models.sessions.StreamEvent import com.google.errorprone.annotations.MustBeClosed import java.util.function.Consumer @@ -58,6 +60,33 @@ interface SessionService { requestOptions: RequestOptions = RequestOptions.none(), ): SessionActResponse + /** + * Executes a browser action using natural language instructions or a predefined Action object. + */ + @MustBeClosed + fun actStreaming(id: String, params: SessionActParams): StreamResponse = + actStreaming(id, params, RequestOptions.none()) + + /** @see actStreaming */ + @MustBeClosed + fun actStreaming( + id: String, + params: SessionActParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): StreamResponse = actStreaming(params.toBuilder().id(id).build(), requestOptions) + + /** @see actStreaming */ + @MustBeClosed + fun actStreaming(params: SessionActParams): StreamResponse = + actStreaming(params, RequestOptions.none()) + + /** @see actStreaming */ + @MustBeClosed + fun actStreaming( + params: SessionActParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): StreamResponse + /** Terminates the browser session and releases all associated resources. */ fun end(id: String): SessionEndResponse = end(id, SessionEndParams.none()) @@ -106,6 +135,32 @@ interface SessionService { requestOptions: RequestOptions = RequestOptions.none(), ): SessionExecuteResponse + /** Runs an autonomous AI agent that can perform complex multi-step browser tasks. */ + @MustBeClosed + fun executeStreaming(id: String, params: SessionExecuteParams): StreamResponse = + executeStreaming(id, params, RequestOptions.none()) + + /** @see executeStreaming */ + @MustBeClosed + fun executeStreaming( + id: String, + params: SessionExecuteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): StreamResponse = + executeStreaming(params.toBuilder().id(id).build(), requestOptions) + + /** @see executeStreaming */ + @MustBeClosed + fun executeStreaming(params: SessionExecuteParams): StreamResponse = + executeStreaming(params, RequestOptions.none()) + + /** @see executeStreaming */ + @MustBeClosed + fun executeStreaming( + params: SessionExecuteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): StreamResponse + /** Extracts structured data from the current page using AI-powered analysis. */ fun extract(id: String): SessionExtractResponse = extract(id, SessionExtractParams.none()) @@ -136,6 +191,44 @@ interface SessionService { fun extract(id: String, requestOptions: RequestOptions): SessionExtractResponse = extract(id, SessionExtractParams.none(), requestOptions) + /** Extracts structured data from the current page using AI-powered analysis. */ + @MustBeClosed + fun extractStreaming(id: String): StreamResponse = + extractStreaming(id, SessionExtractParams.none()) + + /** @see extractStreaming */ + @MustBeClosed + fun extractStreaming( + id: String, + params: SessionExtractParams = SessionExtractParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): StreamResponse = + extractStreaming(params.toBuilder().id(id).build(), requestOptions) + + /** @see extractStreaming */ + @MustBeClosed + fun extractStreaming( + id: String, + params: SessionExtractParams = SessionExtractParams.none(), + ): StreamResponse = extractStreaming(id, params, RequestOptions.none()) + + /** @see extractStreaming */ + @MustBeClosed + fun extractStreaming( + params: SessionExtractParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): StreamResponse + + /** @see extractStreaming */ + @MustBeClosed + fun extractStreaming(params: SessionExtractParams): StreamResponse = + extractStreaming(params, RequestOptions.none()) + + /** @see extractStreaming */ + @MustBeClosed + fun extractStreaming(id: String, requestOptions: RequestOptions): StreamResponse = + extractStreaming(id, SessionExtractParams.none(), requestOptions) + /** Navigates the browser to the specified URL. */ fun navigate(id: String, params: SessionNavigateParams): SessionNavigateResponse = navigate(id, params, RequestOptions.none()) @@ -190,6 +283,47 @@ interface SessionService { fun observe(id: String, requestOptions: RequestOptions): SessionObserveResponse = observe(id, SessionObserveParams.none(), requestOptions) + /** + * Identifies and returns available actions on the current page that match the given + * instruction. + */ + @MustBeClosed + fun observeStreaming(id: String): StreamResponse = + observeStreaming(id, SessionObserveParams.none()) + + /** @see observeStreaming */ + @MustBeClosed + fun observeStreaming( + id: String, + params: SessionObserveParams = SessionObserveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): StreamResponse = + observeStreaming(params.toBuilder().id(id).build(), requestOptions) + + /** @see observeStreaming */ + @MustBeClosed + fun observeStreaming( + id: String, + params: SessionObserveParams = SessionObserveParams.none(), + ): StreamResponse = observeStreaming(id, params, RequestOptions.none()) + + /** @see observeStreaming */ + @MustBeClosed + fun observeStreaming( + params: SessionObserveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): StreamResponse + + /** @see observeStreaming */ + @MustBeClosed + fun observeStreaming(params: SessionObserveParams): StreamResponse = + observeStreaming(params, RequestOptions.none()) + + /** @see observeStreaming */ + @MustBeClosed + fun observeStreaming(id: String, requestOptions: RequestOptions): StreamResponse = + observeStreaming(id, SessionObserveParams.none(), requestOptions) + /** * Creates a new browser session with the specified configuration. Returns a session ID used for * all subsequent operations. @@ -242,6 +376,38 @@ interface SessionService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** + * Returns a raw HTTP response for `post /v1/sessions/{id}/act`, but is otherwise the same + * as [SessionService.actStreaming]. + */ + @MustBeClosed + fun actStreaming( + id: String, + params: SessionActParams, + ): HttpResponseFor> = + actStreaming(id, params, RequestOptions.none()) + + /** @see actStreaming */ + @MustBeClosed + fun actStreaming( + id: String, + params: SessionActParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor> = + actStreaming(params.toBuilder().id(id).build(), requestOptions) + + /** @see actStreaming */ + @MustBeClosed + fun actStreaming(params: SessionActParams): HttpResponseFor> = + actStreaming(params, RequestOptions.none()) + + /** @see actStreaming */ + @MustBeClosed + fun actStreaming( + params: SessionActParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor> + /** * Returns a raw HTTP response for `post /v1/sessions/{id}/end`, but is otherwise the same * as [SessionService.end]. @@ -313,6 +479,40 @@ interface SessionService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** + * Returns a raw HTTP response for `post /v1/sessions/{id}/agentExecute`, but is otherwise + * the same as [SessionService.executeStreaming]. + */ + @MustBeClosed + fun executeStreaming( + id: String, + params: SessionExecuteParams, + ): HttpResponseFor> = + executeStreaming(id, params, RequestOptions.none()) + + /** @see executeStreaming */ + @MustBeClosed + fun executeStreaming( + id: String, + params: SessionExecuteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor> = + executeStreaming(params.toBuilder().id(id).build(), requestOptions) + + /** @see executeStreaming */ + @MustBeClosed + fun executeStreaming( + params: SessionExecuteParams + ): HttpResponseFor> = + executeStreaming(params, RequestOptions.none()) + + /** @see executeStreaming */ + @MustBeClosed + fun executeStreaming( + params: SessionExecuteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor> + /** * Returns a raw HTTP response for `post /v1/sessions/{id}/extract`, but is otherwise the * same as [SessionService.extract]. @@ -357,6 +557,53 @@ interface SessionService { ): HttpResponseFor = extract(id, SessionExtractParams.none(), requestOptions) + /** + * Returns a raw HTTP response for `post /v1/sessions/{id}/extract`, but is otherwise the + * same as [SessionService.extractStreaming]. + */ + @MustBeClosed + fun extractStreaming(id: String): HttpResponseFor> = + extractStreaming(id, SessionExtractParams.none()) + + /** @see extractStreaming */ + @MustBeClosed + fun extractStreaming( + id: String, + params: SessionExtractParams = SessionExtractParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor> = + extractStreaming(params.toBuilder().id(id).build(), requestOptions) + + /** @see extractStreaming */ + @MustBeClosed + fun extractStreaming( + id: String, + params: SessionExtractParams = SessionExtractParams.none(), + ): HttpResponseFor> = + extractStreaming(id, params, RequestOptions.none()) + + /** @see extractStreaming */ + @MustBeClosed + fun extractStreaming( + params: SessionExtractParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor> + + /** @see extractStreaming */ + @MustBeClosed + fun extractStreaming( + params: SessionExtractParams + ): HttpResponseFor> = + extractStreaming(params, RequestOptions.none()) + + /** @see extractStreaming */ + @MustBeClosed + fun extractStreaming( + id: String, + requestOptions: RequestOptions, + ): HttpResponseFor> = + extractStreaming(id, SessionExtractParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /v1/sessions/{id}/navigate`, but is otherwise the * same as [SessionService.navigate]. @@ -432,6 +679,53 @@ interface SessionService { ): HttpResponseFor = observe(id, SessionObserveParams.none(), requestOptions) + /** + * Returns a raw HTTP response for `post /v1/sessions/{id}/observe`, but is otherwise the + * same as [SessionService.observeStreaming]. + */ + @MustBeClosed + fun observeStreaming(id: String): HttpResponseFor> = + observeStreaming(id, SessionObserveParams.none()) + + /** @see observeStreaming */ + @MustBeClosed + fun observeStreaming( + id: String, + params: SessionObserveParams = SessionObserveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor> = + observeStreaming(params.toBuilder().id(id).build(), requestOptions) + + /** @see observeStreaming */ + @MustBeClosed + fun observeStreaming( + id: String, + params: SessionObserveParams = SessionObserveParams.none(), + ): HttpResponseFor> = + observeStreaming(id, params, RequestOptions.none()) + + /** @see observeStreaming */ + @MustBeClosed + fun observeStreaming( + params: SessionObserveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor> + + /** @see observeStreaming */ + @MustBeClosed + fun observeStreaming( + params: SessionObserveParams + ): HttpResponseFor> = + observeStreaming(params, RequestOptions.none()) + + /** @see observeStreaming */ + @MustBeClosed + fun observeStreaming( + id: String, + requestOptions: RequestOptions, + ): HttpResponseFor> = + observeStreaming(id, SessionObserveParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /v1/sessions/start`, but is otherwise the same as * [SessionService.start]. diff --git a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionServiceImpl.kt b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionServiceImpl.kt index aac8272..4bfce1b 100644 --- a/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionServiceImpl.kt +++ b/stagehand-java-core/src/main/kotlin/com/browserbase/api/services/blocking/SessionServiceImpl.kt @@ -3,17 +3,22 @@ package com.browserbase.api.services.blocking import com.browserbase.api.core.ClientOptions +import com.browserbase.api.core.JsonValue import com.browserbase.api.core.RequestOptions import com.browserbase.api.core.checkRequired import com.browserbase.api.core.handlers.errorBodyHandler import com.browserbase.api.core.handlers.errorHandler import com.browserbase.api.core.handlers.jsonHandler +import com.browserbase.api.core.handlers.mapJson +import com.browserbase.api.core.handlers.sseHandler import com.browserbase.api.core.http.HttpMethod import com.browserbase.api.core.http.HttpRequest import com.browserbase.api.core.http.HttpResponse import com.browserbase.api.core.http.HttpResponse.Handler import com.browserbase.api.core.http.HttpResponseFor +import com.browserbase.api.core.http.StreamResponse import com.browserbase.api.core.http.json +import com.browserbase.api.core.http.map import com.browserbase.api.core.http.parseable import com.browserbase.api.core.prepare import com.browserbase.api.models.sessions.SessionActParams @@ -30,6 +35,7 @@ import com.browserbase.api.models.sessions.SessionObserveParams import com.browserbase.api.models.sessions.SessionObserveResponse import com.browserbase.api.models.sessions.SessionStartParams import com.browserbase.api.models.sessions.SessionStartResponse +import com.browserbase.api.models.sessions.StreamEvent import java.util.function.Consumer import kotlin.jvm.optionals.getOrNull @@ -49,6 +55,13 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO // post /v1/sessions/{id}/act withRawResponse().act(params, requestOptions).parse() + override fun actStreaming( + params: SessionActParams, + requestOptions: RequestOptions, + ): StreamResponse = + // post /v1/sessions/{id}/act + withRawResponse().actStreaming(params, requestOptions).parse() + override fun end(params: SessionEndParams, requestOptions: RequestOptions): SessionEndResponse = // post /v1/sessions/{id}/end withRawResponse().end(params, requestOptions).parse() @@ -60,6 +73,13 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO // post /v1/sessions/{id}/agentExecute withRawResponse().execute(params, requestOptions).parse() + override fun executeStreaming( + params: SessionExecuteParams, + requestOptions: RequestOptions, + ): StreamResponse = + // post /v1/sessions/{id}/agentExecute + withRawResponse().executeStreaming(params, requestOptions).parse() + override fun extract( params: SessionExtractParams, requestOptions: RequestOptions, @@ -67,6 +87,13 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO // post /v1/sessions/{id}/extract withRawResponse().extract(params, requestOptions).parse() + override fun extractStreaming( + params: SessionExtractParams, + requestOptions: RequestOptions, + ): StreamResponse = + // post /v1/sessions/{id}/extract + withRawResponse().extractStreaming(params, requestOptions).parse() + override fun navigate( params: SessionNavigateParams, requestOptions: RequestOptions, @@ -81,6 +108,13 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO // post /v1/sessions/{id}/observe withRawResponse().observe(params, requestOptions).parse() + override fun observeStreaming( + params: SessionObserveParams, + requestOptions: RequestOptions, + ): StreamResponse = + // post /v1/sessions/{id}/observe + withRawResponse().observeStreaming(params, requestOptions).parse() + override fun start( params: SessionStartParams, requestOptions: RequestOptions, @@ -132,6 +166,48 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO } } + private val actStreamingHandler: Handler> = + sseHandler(clientOptions.jsonMapper).mapJson() + + override fun actStreaming( + params: SessionActParams, + requestOptions: RequestOptions, + ): HttpResponseFor> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "sessions", params._pathParam(0), "act") + .body( + json( + clientOptions.jsonMapper, + params + ._body() + .toBuilder() + .putAdditionalProperty("streamResponse", JsonValue.from(true)) + .build(), + ) + ) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .let { actStreamingHandler.handle(it) } + .let { streamResponse -> + if (requestOptions.responseValidation!!) { + streamResponse.map { it.validate() } + } else { + streamResponse + } + } + } + } + private val endHandler: Handler = jsonHandler(clientOptions.jsonMapper) @@ -194,6 +270,48 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO } } + private val executeStreamingHandler: Handler> = + sseHandler(clientOptions.jsonMapper).mapJson() + + override fun executeStreaming( + params: SessionExecuteParams, + requestOptions: RequestOptions, + ): HttpResponseFor> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "sessions", params._pathParam(0), "agentExecute") + .body( + json( + clientOptions.jsonMapper, + params + ._body() + .toBuilder() + .putAdditionalProperty("streamResponse", JsonValue.from(true)) + .build(), + ) + ) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .let { executeStreamingHandler.handle(it) } + .let { streamResponse -> + if (requestOptions.responseValidation!!) { + streamResponse.map { it.validate() } + } else { + streamResponse + } + } + } + } + private val extractHandler: Handler = jsonHandler(clientOptions.jsonMapper) @@ -225,6 +343,48 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO } } + private val extractStreamingHandler: Handler> = + sseHandler(clientOptions.jsonMapper).mapJson() + + override fun extractStreaming( + params: SessionExtractParams, + requestOptions: RequestOptions, + ): HttpResponseFor> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "sessions", params._pathParam(0), "extract") + .body( + json( + clientOptions.jsonMapper, + params + ._body() + .toBuilder() + .putAdditionalProperty("streamResponse", JsonValue.from(true)) + .build(), + ) + ) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .let { extractStreamingHandler.handle(it) } + .let { streamResponse -> + if (requestOptions.responseValidation!!) { + streamResponse.map { it.validate() } + } else { + streamResponse + } + } + } + } + private val navigateHandler: Handler = jsonHandler(clientOptions.jsonMapper) @@ -287,6 +447,48 @@ class SessionServiceImpl internal constructor(private val clientOptions: ClientO } } + private val observeStreamingHandler: Handler> = + sseHandler(clientOptions.jsonMapper).mapJson() + + override fun observeStreaming( + params: SessionObserveParams, + requestOptions: RequestOptions, + ): HttpResponseFor> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "sessions", params._pathParam(0), "observe") + .body( + json( + clientOptions.jsonMapper, + params + ._body() + .toBuilder() + .putAdditionalProperty("streamResponse", JsonValue.from(true)) + .build(), + ) + ) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .let { observeStreamingHandler.handle(it) } + .let { streamResponse -> + if (requestOptions.responseValidation!!) { + streamResponse.map { it.validate() } + } else { + streamResponse + } + } + } + } + private val startHandler: Handler = jsonHandler(clientOptions.jsonMapper) diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/core/handlers/SseHandlerTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/core/handlers/SseHandlerTest.kt new file mode 100644 index 0000000..29105f3 --- /dev/null +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/core/handlers/SseHandlerTest.kt @@ -0,0 +1,134 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.core.handlers + +import com.browserbase.api.core.http.Headers +import com.browserbase.api.core.http.HttpResponse +import com.browserbase.api.core.http.SseMessage +import com.browserbase.api.core.jsonMapper +import java.io.InputStream +import java.util.stream.Collectors.toList +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.catchThrowable +import org.junit.jupiter.api.Test +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +internal class SseHandlerTest { + + enum class TestCase( + internal val body: String, + internal val expectedMessages: List? = null, + internal val expectedException: Exception? = null, + ) { + DATA_MISSING_EVENT( + buildString { + append("data: {\"foo\":true}\n") + append("\n") + }, + listOf(sseMessageBuilder().data("{\"foo\":true}").build()), + ), + MULTIPLE_DATA_MISSING_EVENT( + buildString { + append("data: {\"foo\":true}\n") + append("\n") + append("data: {\"bar\":false}\n") + append("\n") + }, + listOf( + sseMessageBuilder().data("{\"foo\":true}").build(), + sseMessageBuilder().data("{\"bar\":false}").build(), + ), + ), + DATA_JSON_ESCAPED_DOUBLE_NEW_LINE( + buildString { + append("data: {\n") + append("data: \"foo\":\n") + append("data: true}\n") + append("\n\n") + }, + listOf(sseMessageBuilder().data("{\n\"foo\":\ntrue}").build()), + ), + MULTIPLE_DATA_LINES( + buildString { + append("data: {\n") + append("data: \"foo\":\n") + append("data: true}\n") + append("\n\n") + }, + listOf(sseMessageBuilder().data("{\n\"foo\":\ntrue}").build()), + ), + SPECIAL_NEW_LINE_CHARACTER( + buildString { + append("data: {\"content\":\" culpa\"}\n") + append("\n") + append("data: {\"content\":\" \u2028\"}\n") + append("\n") + append("data: {\"content\":\"foo\"}\n") + append("\n") + }, + listOf( + sseMessageBuilder().data("{\"content\":\" culpa\"}").build(), + sseMessageBuilder().data("{\"content\":\" \u2028\"}").build(), + sseMessageBuilder().data("{\"content\":\"foo\"}").build(), + ), + ), + MULTI_BYTE_CHARACTER( + buildString { + append("data: {\"content\":\"\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0438\"}\n") + append("\n") + }, + listOf(sseMessageBuilder().data("{\"content\":\"известни\"}").build()), + ), + } + + @ParameterizedTest + @EnumSource + fun handle(testCase: TestCase) { + val response = httpResponse(testCase.body) + var messages: List? = null + var exception: Exception? = null + + try { + messages = + sseHandler(jsonMapper()).handle(response).use { it.stream().collect(toList()) } + } catch (e: Exception) { + exception = e + } + + if (testCase.expectedMessages != null) { + assertThat(messages).containsExactlyElementsOf(testCase.expectedMessages) + } + if (testCase.expectedException != null) { + assertThat(exception).isInstanceOf(testCase.expectedException.javaClass) + assertThat(exception).hasMessage(testCase.expectedException.message) + } + } + + @Test + fun cannotReuseStream() { + val response = httpResponse("body") + val streamResponse = sseHandler(jsonMapper()).handle(response) + + val throwable = + streamResponse.use { + it.stream().collect(toList()) + catchThrowable { it.stream().collect(toList()) } + } + + assertThat(throwable).isInstanceOf(IllegalStateException::class.java) + } +} + +private fun httpResponse(body: String): HttpResponse = + object : HttpResponse { + override fun statusCode(): Int = 0 + + override fun headers(): Headers = Headers.builder().build() + + override fun body(): InputStream = body.toByteArray().inputStream() + + override fun close() {} + } + +private fun sseMessageBuilder() = SseMessage.builder().jsonMapper(jsonMapper()) diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/core/handlers/StreamHandlerTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/core/handlers/StreamHandlerTest.kt new file mode 100644 index 0000000..7da5378 --- /dev/null +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/core/handlers/StreamHandlerTest.kt @@ -0,0 +1,94 @@ +package com.browserbase.api.core.handlers + +import com.browserbase.api.core.http.Headers +import com.browserbase.api.core.http.HttpResponse +import com.browserbase.api.errors.StagehandIoException +import java.io.IOException +import java.io.InputStream +import kotlin.streams.asSequence +import kotlin.test.Test +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.assertThrows + +internal class StreamHandlerTest { + + @Test + fun streamHandler_splitsStreamOnNewlines() { + val handler = streamHandler { _, lines -> yieldAll(lines) } + val streamResponse = handler.handle(httpResponse("a\nbb\nccc\ndddd".byteInputStream())) + + val lines = streamResponse.stream().asSequence().toList() + + assertThat(lines).containsExactly("a", "bb", "ccc", "dddd") + } + + @Test + fun streamHandler_whenClosedEarly_stopsYielding() { + val handler = streamHandler { _, lines -> yieldAll(lines) } + val streamResponse = handler.handle(httpResponse("a\nbb\nccc\ndddd".byteInputStream())) + + val lines = + streamResponse + .stream() + .asSequence() + .onEach { + if (it == "bb") { + streamResponse.close() + } + } + .toList() + + assertThat(lines).containsExactly("a", "bb") + } + + @Test + fun streamHandler_whenReaderThrowsIOException_wrapsException() { + val handler = streamHandler { _, lines -> lines.forEach {} } + val streamResponse = handler.handle(httpResponse("a\nb\nc\n".byteInputStream().throwing())) + + val e = assertThrows { streamResponse.stream().forEach {} } + assertThat(e).hasMessage("Stream failed") + assertThat(e).hasCauseInstanceOf(IOException::class.java) + } + + @Test + fun streamHandler_whenBlockThrowsIOException_doesNotWrapException() { + val ioException = IOException("BOOM!") + val handler = + streamHandler { _, lines -> + lines.forEachIndexed { index, _ -> + if (index == 2) { + throw ioException + } + } + } + val streamResponse = handler.handle(httpResponse("a\nb\nc\n".byteInputStream())) + + val e = assertThrows { streamResponse.stream().forEach {} } + assertThat(e).isSameAs(ioException) + } + + private fun httpResponse(body: InputStream): HttpResponse = + object : HttpResponse { + + override fun statusCode(): Int = 0 + + override fun headers(): Headers = Headers.builder().build() + + override fun body(): InputStream = body + + override fun close() {} + } + + private fun InputStream.throwing(): InputStream = + object : InputStream() { + + override fun read(): Int { + val byte = this@throwing.read() + if (byte == -1) { + throw IOException("BOOM!") + } + return byte + } + } +} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt index 3bba7d4..169d089 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionNavigateParamsTest.kt @@ -26,6 +26,7 @@ internal class SessionNavigateParamsTest { .waitUntil(SessionNavigateParams.Options.WaitUntil.NETWORKIDLE) .build() ) + .streamResponse(true) .build() } @@ -60,6 +61,7 @@ internal class SessionNavigateParamsTest { .waitUntil(SessionNavigateParams.Options.WaitUntil.NETWORKIDLE) .build() ) + .streamResponse(true) .build() val headers = params._headers() @@ -106,6 +108,7 @@ internal class SessionNavigateParamsTest { .waitUntil(SessionNavigateParams.Options.WaitUntil.NETWORKIDLE) .build() ) + .streamResponse(true) .build() val body = params._body() @@ -120,6 +123,7 @@ internal class SessionNavigateParamsTest { .waitUntil(SessionNavigateParams.Options.WaitUntil.NETWORKIDLE) .build() ) + assertThat(body.streamResponse()).contains(true) } @Test diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartResponseTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartResponseTest.kt index 3af1696..4a712ec 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartResponseTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionStartResponseTest.kt @@ -16,6 +16,7 @@ internal class SessionStartResponseTest { .data( SessionStartResponse.Data.builder() .available(true) + .connectUrl("wss://connect.browserbase.com/?signingKey=abc123") .sessionId("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .build() ) @@ -26,6 +27,7 @@ internal class SessionStartResponseTest { .isEqualTo( SessionStartResponse.Data.builder() .available(true) + .connectUrl("wss://connect.browserbase.com/?signingKey=abc123") .sessionId("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .build() ) @@ -40,6 +42,7 @@ internal class SessionStartResponseTest { .data( SessionStartResponse.Data.builder() .available(true) + .connectUrl("wss://connect.browserbase.com/?signingKey=abc123") .sessionId("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") .build() ) diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/StreamEventTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/StreamEventTest.kt new file mode 100644 index 0000000..9d58bf8 --- /dev/null +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/StreamEventTest.kt @@ -0,0 +1,66 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.browserbase.api.models.sessions + +import com.browserbase.api.core.JsonValue +import com.browserbase.api.core.jsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class StreamEventTest { + + @Test + fun create() { + val streamEvent = + StreamEvent.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .data( + StreamEvent.Data.StreamEventSystemDataOutput.builder() + .status(StreamEvent.Data.StreamEventSystemDataOutput.Status.STARTING) + .error("error") + .result(JsonValue.from(mapOf())) + .build() + ) + .type(StreamEvent.Type.SYSTEM) + .build() + + assertThat(streamEvent.id()).isEqualTo("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + assertThat(streamEvent.data()) + .isEqualTo( + StreamEvent.Data.ofStreamEventSystemDataOutput( + StreamEvent.Data.StreamEventSystemDataOutput.builder() + .status(StreamEvent.Data.StreamEventSystemDataOutput.Status.STARTING) + .error("error") + .result(JsonValue.from(mapOf())) + .build() + ) + ) + assertThat(streamEvent.type()).isEqualTo(StreamEvent.Type.SYSTEM) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val streamEvent = + StreamEvent.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .data( + StreamEvent.Data.StreamEventSystemDataOutput.builder() + .status(StreamEvent.Data.StreamEventSystemDataOutput.Status.STARTING) + .error("error") + .result(JsonValue.from(mapOf())) + .build() + ) + .type(StreamEvent.Type.SYSTEM) + .build() + + val roundtrippedStreamEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(streamEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedStreamEvent).isEqualTo(streamEvent) + } +} diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt index 270a06b..78ba6e7 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt @@ -60,6 +60,47 @@ internal class SessionServiceAsyncTest { response.validate() } + @Disabled("Prism tests are disabled") + @Test + fun actStreaming() { + val client = + StagehandOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionServiceAsync = client.sessions() + + val responseStreamResponse = + sessionServiceAsync.actStreaming( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("openai/gpt-5-nano") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty("username", JsonValue.from("john_doe")) + .build() + ) + .build() + ) + .build() + ) + + val onCompleteFuture = + responseStreamResponse.subscribe { response -> response.validate() }.onCompleteFuture() + onCompleteFuture.get() + } + @Disabled("Prism tests are disabled") @Test fun end() { @@ -131,6 +172,51 @@ internal class SessionServiceAsyncTest { response.validate() } + @Disabled("Prism tests are disabled") + @Test + fun executeStreaming() { + val client = + StagehandOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionServiceAsync = client.sessions() + + val responseStreamResponse = + sessionServiceAsync.executeStreaming( + SessionExecuteParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionExecuteParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) + .xStreamResponse(SessionExecuteParams.XStreamResponse.TRUE) + .agentConfig( + SessionExecuteParams.AgentConfig.builder() + .cua(true) + .model("openai/gpt-5-nano") + .systemPrompt("systemPrompt") + .build() + ) + .executeOptions( + SessionExecuteParams.ExecuteOptions.builder() + .instruction( + "Log in with username 'demo' and password 'test123', then navigate to settings" + ) + .highlightCursor(true) + .maxSteps(20.0) + .build() + ) + .frameId("frameId") + .build() + ) + + val onCompleteFuture = + responseStreamResponse.subscribe { response -> response.validate() }.onCompleteFuture() + onCompleteFuture.get() + } + @Disabled("Prism tests are disabled") @Test fun extract() { @@ -172,6 +258,48 @@ internal class SessionServiceAsyncTest { response.validate() } + @Disabled("Prism tests are disabled") + @Test + fun extractStreaming() { + val client = + StagehandOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionServiceAsync = client.sessions() + + val responseStreamResponse = + sessionServiceAsync.extractStreaming( + SessionExtractParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionExtractParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) + .xStreamResponse(SessionExtractParams.XStreamResponse.TRUE) + .frameId("frameId") + .instruction("Extract all product names and prices from the page") + .options( + SessionExtractParams.Options.builder() + .model("openai/gpt-5-nano") + .selector("#main-content") + .timeout(30000.0) + .build() + ) + .schema( + SessionExtractParams.Schema.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + + val onCompleteFuture = + responseStreamResponse.subscribe { response -> response.validate() }.onCompleteFuture() + onCompleteFuture.get() + } + @Disabled("Prism tests are disabled") @Test fun navigate() { @@ -201,6 +329,7 @@ internal class SessionServiceAsyncTest { .waitUntil(SessionNavigateParams.Options.WaitUntil.NETWORKIDLE) .build() ) + .streamResponse(true) .build() ) @@ -244,6 +373,43 @@ internal class SessionServiceAsyncTest { response.validate() } + @Disabled("Prism tests are disabled") + @Test + fun observeStreaming() { + val client = + StagehandOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionServiceAsync = client.sessions() + + val responseStreamResponse = + sessionServiceAsync.observeStreaming( + SessionObserveParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionObserveParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) + .xStreamResponse(SessionObserveParams.XStreamResponse.TRUE) + .frameId("frameId") + .instruction("Find all clickable navigation links") + .options( + SessionObserveParams.Options.builder() + .model("openai/gpt-5-nano") + .selector("nav") + .timeout(30000.0) + .build() + ) + .build() + ) + + val onCompleteFuture = + responseStreamResponse.subscribe { response -> response.validate() }.onCompleteFuture() + onCompleteFuture.get() + } + @Disabled("Prism tests are disabled") @Test fun start() { diff --git a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt index af06455..3355c14 100644 --- a/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt +++ b/stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt @@ -59,6 +59,47 @@ internal class SessionServiceTest { response.validate() } + @Disabled("Prism tests are disabled") + @Test + fun actStreaming() { + val client = + StagehandOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionService = client.sessions() + + val responseStreamResponse = + sessionService.actStreaming( + SessionActParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionActParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) + .xStreamResponse(SessionActParams.XStreamResponse.TRUE) + .input("Click the login button") + .frameId("frameId") + .options( + SessionActParams.Options.builder() + .model("openai/gpt-5-nano") + .timeout(30000.0) + .variables( + SessionActParams.Options.Variables.builder() + .putAdditionalProperty("username", JsonValue.from("john_doe")) + .build() + ) + .build() + ) + .build() + ) + + responseStreamResponse.use { + responseStreamResponse.stream().forEach { response -> response.validate() } + } + } + @Disabled("Prism tests are disabled") @Test fun end() { @@ -128,6 +169,51 @@ internal class SessionServiceTest { response.validate() } + @Disabled("Prism tests are disabled") + @Test + fun executeStreaming() { + val client = + StagehandOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionService = client.sessions() + + val responseStreamResponse = + sessionService.executeStreaming( + SessionExecuteParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionExecuteParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) + .xStreamResponse(SessionExecuteParams.XStreamResponse.TRUE) + .agentConfig( + SessionExecuteParams.AgentConfig.builder() + .cua(true) + .model("openai/gpt-5-nano") + .systemPrompt("systemPrompt") + .build() + ) + .executeOptions( + SessionExecuteParams.ExecuteOptions.builder() + .instruction( + "Log in with username 'demo' and password 'test123', then navigate to settings" + ) + .highlightCursor(true) + .maxSteps(20.0) + .build() + ) + .frameId("frameId") + .build() + ) + + responseStreamResponse.use { + responseStreamResponse.stream().forEach { response -> response.validate() } + } + } + @Disabled("Prism tests are disabled") @Test fun extract() { @@ -168,6 +254,48 @@ internal class SessionServiceTest { response.validate() } + @Disabled("Prism tests are disabled") + @Test + fun extractStreaming() { + val client = + StagehandOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionService = client.sessions() + + val responseStreamResponse = + sessionService.extractStreaming( + SessionExtractParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionExtractParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) + .xStreamResponse(SessionExtractParams.XStreamResponse.TRUE) + .frameId("frameId") + .instruction("Extract all product names and prices from the page") + .options( + SessionExtractParams.Options.builder() + .model("openai/gpt-5-nano") + .selector("#main-content") + .timeout(30000.0) + .build() + ) + .schema( + SessionExtractParams.Schema.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + + responseStreamResponse.use { + responseStreamResponse.stream().forEach { response -> response.validate() } + } + } + @Disabled("Prism tests are disabled") @Test fun navigate() { @@ -197,6 +325,7 @@ internal class SessionServiceTest { .waitUntil(SessionNavigateParams.Options.WaitUntil.NETWORKIDLE) .build() ) + .streamResponse(true) .build() ) @@ -238,6 +367,43 @@ internal class SessionServiceTest { response.validate() } + @Disabled("Prism tests are disabled") + @Test + fun observeStreaming() { + val client = + StagehandOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .browserbaseApiKey("My Browserbase API Key") + .browserbaseProjectId("My Browserbase Project ID") + .modelApiKey("My Model API Key") + .build() + val sessionService = client.sessions() + + val responseStreamResponse = + sessionService.observeStreaming( + SessionObserveParams.builder() + .id("c4dbf3a9-9a58-4b22-8a1c-9f20f9f9e123") + .xLanguage(SessionObserveParams.XLanguage.TYPESCRIPT) + .xSdkVersion("3.0.6") + .xSentAt(OffsetDateTime.parse("2025-01-15T10:30:00Z")) + .xStreamResponse(SessionObserveParams.XStreamResponse.TRUE) + .frameId("frameId") + .instruction("Find all clickable navigation links") + .options( + SessionObserveParams.Options.builder() + .model("openai/gpt-5-nano") + .selector("nav") + .timeout(30000.0) + .build() + ) + .build() + ) + + responseStreamResponse.use { + responseStreamResponse.stream().forEach { response -> response.validate() } + } + } + @Disabled("Prism tests are disabled") @Test fun start() { From d994886f0eb63ef6ad120861989fb71812eef21a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 18 Dec 2025 01:39:11 +0000 Subject: [PATCH 13/13] release: 0.3.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 17 +++++++++++++++++ README.md | 10 +++++----- build.gradle.kts | 2 +- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 10f3091..6b7b74c 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.2.0" + ".": "0.3.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 04011d6..3a2ee1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/README.md b/README.md index be1932d..d87bf13 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![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) @@ -13,7 +13,7 @@ It is generated with [Stainless](https://www.stainless.com/). -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). @@ -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 @@ -33,7 +33,7 @@ implementation("com.browserbase.api:stagehand-java:0.2.0") com.browserbase.api stagehand-java - 0.2.0 + 0.3.0 ``` diff --git a/build.gradle.kts b/build.gradle.kts index 63a11b4..d06f0a9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -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 {