Skip to content

Commit aa7ad0c

Browse files
feat: [feat]: add ignoreSelectors to observe()
1 parent bbbc501 commit aa7ad0c

5 files changed

Lines changed: 78 additions & 7 deletions

File tree

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 8
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase/stagehand-49b40c7425adba9e67fc102838c5216c45ca1f7ef4c10823c5665fd413538504.yml
3-
openapi_spec_hash: 6880dc029df2e88dfe8943c0dec5a3a5
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase/stagehand-eae8400fade7b2c8329c4148f56de92e147c34c0feecb420c015aab6544a9acc.yml
3+
openapi_spec_hash: 0a9eff1ac1d464e89cbd9db64709b08a
44
config_hash: 1fb12ae9b478488bc1e56bfbdc210b01

stagehand-java-core/src/main/kotlin/com/browserbase/api/models/sessions/SessionObserveParams.kt

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import com.browserbase.api.core.JsonMissing
1111
import com.browserbase.api.core.JsonValue
1212
import com.browserbase.api.core.Params
1313
import com.browserbase.api.core.allMaxBy
14+
import com.browserbase.api.core.checkKnown
1415
import com.browserbase.api.core.getOrThrow
1516
import com.browserbase.api.core.http.Headers
1617
import com.browserbase.api.core.http.QueryParams
@@ -573,6 +574,7 @@ private constructor(
573574
class Options
574575
@JsonCreator(mode = JsonCreator.Mode.DISABLED)
575576
private constructor(
577+
private val ignoreSelectors: JsonField<List<String>>,
576578
private val model: JsonField<Model>,
577579
private val selector: JsonField<String>,
578580
private val timeout: JsonField<Double>,
@@ -582,6 +584,9 @@ private constructor(
582584

583585
@JsonCreator
584586
private constructor(
587+
@JsonProperty("ignoreSelectors")
588+
@ExcludeMissing
589+
ignoreSelectors: JsonField<List<String>> = JsonMissing.of(),
585590
@JsonProperty("model") @ExcludeMissing model: JsonField<Model> = JsonMissing.of(),
586591
@JsonProperty("selector")
587592
@ExcludeMissing
@@ -590,7 +595,16 @@ private constructor(
590595
@JsonProperty("variables")
591596
@ExcludeMissing
592597
variables: JsonField<Variables> = JsonMissing.of(),
593-
) : this(model, selector, timeout, variables, mutableMapOf())
598+
) : this(ignoreSelectors, model, selector, timeout, variables, mutableMapOf())
599+
600+
/**
601+
* Selectors for elements and subtrees that should be excluded from observation
602+
*
603+
* @throws StagehandInvalidDataException if the JSON field has an unexpected type (e.g. if
604+
* the server responded with an unexpected value).
605+
*/
606+
fun ignoreSelectors(): Optional<List<String>> =
607+
ignoreSelectors.getOptional("ignoreSelectors")
594608

595609
/**
596610
* Model configuration object or model name string (e.g., 'openai/gpt-5-nano')
@@ -626,6 +640,16 @@ private constructor(
626640
*/
627641
fun variables(): Optional<Variables> = variables.getOptional("variables")
628642

643+
/**
644+
* Returns the raw JSON value of [ignoreSelectors].
645+
*
646+
* Unlike [ignoreSelectors], this method doesn't throw if the JSON field has an unexpected
647+
* type.
648+
*/
649+
@JsonProperty("ignoreSelectors")
650+
@ExcludeMissing
651+
fun _ignoreSelectors(): JsonField<List<String>> = ignoreSelectors
652+
629653
/**
630654
* Returns the raw JSON value of [model].
631655
*
@@ -677,6 +701,7 @@ private constructor(
677701
/** A builder for [Options]. */
678702
class Builder internal constructor() {
679703

704+
private var ignoreSelectors: JsonField<MutableList<String>>? = null
680705
private var model: JsonField<Model> = JsonMissing.of()
681706
private var selector: JsonField<String> = JsonMissing.of()
682707
private var timeout: JsonField<Double> = JsonMissing.of()
@@ -685,13 +710,41 @@ private constructor(
685710

686711
@JvmSynthetic
687712
internal fun from(options: Options) = apply {
713+
ignoreSelectors = options.ignoreSelectors.map { it.toMutableList() }
688714
model = options.model
689715
selector = options.selector
690716
timeout = options.timeout
691717
variables = options.variables
692718
additionalProperties = options.additionalProperties.toMutableMap()
693719
}
694720

721+
/** Selectors for elements and subtrees that should be excluded from observation */
722+
fun ignoreSelectors(ignoreSelectors: List<String>) =
723+
ignoreSelectors(JsonField.of(ignoreSelectors))
724+
725+
/**
726+
* Sets [Builder.ignoreSelectors] to an arbitrary JSON value.
727+
*
728+
* You should usually call [Builder.ignoreSelectors] with a well-typed `List<String>`
729+
* value instead. This method is primarily for setting the field to an undocumented or
730+
* not yet supported value.
731+
*/
732+
fun ignoreSelectors(ignoreSelectors: JsonField<List<String>>) = apply {
733+
this.ignoreSelectors = ignoreSelectors.map { it.toMutableList() }
734+
}
735+
736+
/**
737+
* Adds a single [String] to [ignoreSelectors].
738+
*
739+
* @throws IllegalStateException if the field was previously set to a non-list.
740+
*/
741+
fun addIgnoreSelector(ignoreSelector: String) = apply {
742+
ignoreSelectors =
743+
(ignoreSelectors ?: JsonField.of(mutableListOf())).also {
744+
checkKnown("ignoreSelectors", it).add(ignoreSelector)
745+
}
746+
}
747+
695748
/** Model configuration object or model name string (e.g., 'openai/gpt-5-nano') */
696749
fun model(model: Model) = model(JsonField.of(model))
697750

@@ -775,7 +828,14 @@ private constructor(
775828
* Further updates to this [Builder] will not mutate the returned instance.
776829
*/
777830
fun build(): Options =
778-
Options(model, selector, timeout, variables, additionalProperties.toMutableMap())
831+
Options(
832+
(ignoreSelectors ?: JsonMissing.of()).map { it.toImmutable() },
833+
model,
834+
selector,
835+
timeout,
836+
variables,
837+
additionalProperties.toMutableMap(),
838+
)
779839
}
780840

781841
private var validated: Boolean = false
@@ -794,6 +854,7 @@ private constructor(
794854
return@apply
795855
}
796856

857+
ignoreSelectors()
797858
model().ifPresent { it.validate() }
798859
selector()
799860
timeout()
@@ -817,7 +878,8 @@ private constructor(
817878
*/
818879
@JvmSynthetic
819880
internal fun validity(): Int =
820-
(model.asKnown().getOrNull()?.validity() ?: 0) +
881+
(ignoreSelectors.asKnown().getOrNull()?.size ?: 0) +
882+
(model.asKnown().getOrNull()?.validity() ?: 0) +
821883
(if (selector.asKnown().isPresent) 1 else 0) +
822884
(if (timeout.asKnown().isPresent) 1 else 0) +
823885
(variables.asKnown().getOrNull()?.validity() ?: 0)
@@ -1157,6 +1219,7 @@ private constructor(
11571219
}
11581220

11591221
return other is Options &&
1222+
ignoreSelectors == other.ignoreSelectors &&
11601223
model == other.model &&
11611224
selector == other.selector &&
11621225
timeout == other.timeout &&
@@ -1165,13 +1228,13 @@ private constructor(
11651228
}
11661229

11671230
private val hashCode: Int by lazy {
1168-
Objects.hash(model, selector, timeout, variables, additionalProperties)
1231+
Objects.hash(ignoreSelectors, model, selector, timeout, variables, additionalProperties)
11691232
}
11701233

11711234
override fun hashCode(): Int = hashCode
11721235

11731236
override fun toString() =
1174-
"Options{model=$model, selector=$selector, timeout=$timeout, variables=$variables, additionalProperties=$additionalProperties}"
1237+
"Options{ignoreSelectors=$ignoreSelectors, model=$model, selector=$selector, timeout=$timeout, variables=$variables, additionalProperties=$additionalProperties}"
11751238
}
11761239

11771240
/** Whether to stream the response via SSE */

stagehand-java-core/src/test/kotlin/com/browserbase/api/models/sessions/SessionObserveParamsTest.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ internal class SessionObserveParamsTest {
1818
.instruction("Find all clickable navigation links")
1919
.options(
2020
SessionObserveParams.Options.builder()
21+
.ignoreSelectors(listOf("nav", ".cookie-banner", "#sidebar-ads"))
2122
.model(
2223
ModelConfig.builder()
2324
.modelName("openai/gpt-5.4-mini")
@@ -72,6 +73,7 @@ internal class SessionObserveParamsTest {
7273
.instruction("Find all clickable navigation links")
7374
.options(
7475
SessionObserveParams.Options.builder()
76+
.ignoreSelectors(listOf("nav", ".cookie-banner", "#sidebar-ads"))
7577
.model(
7678
ModelConfig.builder()
7779
.modelName("openai/gpt-5.4-mini")
@@ -130,6 +132,7 @@ internal class SessionObserveParamsTest {
130132
.instruction("Find all clickable navigation links")
131133
.options(
132134
SessionObserveParams.Options.builder()
135+
.ignoreSelectors(listOf("nav", ".cookie-banner", "#sidebar-ads"))
133136
.model(
134137
ModelConfig.builder()
135138
.modelName("openai/gpt-5.4-mini")
@@ -170,6 +173,7 @@ internal class SessionObserveParamsTest {
170173
assertThat(body.options())
171174
.contains(
172175
SessionObserveParams.Options.builder()
176+
.ignoreSelectors(listOf("nav", ".cookie-banner", "#sidebar-ads"))
173177
.model(
174178
ModelConfig.builder()
175179
.modelName("openai/gpt-5.4-mini")

stagehand-java-core/src/test/kotlin/com/browserbase/api/services/async/SessionServiceAsyncTest.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ internal class SessionServiceAsyncTest {
461461
.instruction("Find all clickable navigation links")
462462
.options(
463463
SessionObserveParams.Options.builder()
464+
.ignoreSelectors(listOf("nav", ".cookie-banner", "#sidebar-ads"))
464465
.model(
465466
ModelConfig.builder()
466467
.modelName("openai/gpt-5.4-mini")
@@ -519,6 +520,7 @@ internal class SessionServiceAsyncTest {
519520
.instruction("Find all clickable navigation links")
520521
.options(
521522
SessionObserveParams.Options.builder()
523+
.ignoreSelectors(listOf("nav", ".cookie-banner", "#sidebar-ads"))
522524
.model(
523525
ModelConfig.builder()
524526
.modelName("openai/gpt-5.4-mini")

stagehand-java-core/src/test/kotlin/com/browserbase/api/services/blocking/SessionServiceTest.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@ internal class SessionServiceTest {
456456
.instruction("Find all clickable navigation links")
457457
.options(
458458
SessionObserveParams.Options.builder()
459+
.ignoreSelectors(listOf("nav", ".cookie-banner", "#sidebar-ads"))
459460
.model(
460461
ModelConfig.builder()
461462
.modelName("openai/gpt-5.4-mini")
@@ -513,6 +514,7 @@ internal class SessionServiceTest {
513514
.instruction("Find all clickable navigation links")
514515
.options(
515516
SessionObserveParams.Options.builder()
517+
.ignoreSelectors(listOf("nav", ".cookie-banner", "#sidebar-ads"))
516518
.model(
517519
ModelConfig.builder()
518520
.modelName("openai/gpt-5.4-mini")

0 commit comments

Comments
 (0)