2424from ._models import FinalRequestOptions
2525from ._version import __version__
2626from ._streaming import Stream as Stream , AsyncStream as AsyncStream
27- from ._exceptions import APIStatusError , StagehandError
27+ from ._exceptions import APIStatusError
2828from ._base_client import (
2929 DEFAULT_MAX_RETRIES ,
3030 SyncAPIClient ,
@@ -52,7 +52,7 @@ class Stagehand(SyncAPIClient):
5252 # client options
5353 browserbase_api_key : str | None
5454 browserbase_project_id : str | None
55- model_api_key : str
55+ model_api_key : str | None
5656
5757 def __init__ (
5858 self ,
@@ -67,7 +67,6 @@ def __init__(
6767 local_headless : bool = True ,
6868 local_chrome_path : str | None = None ,
6969 local_ready_timeout_s : float = 10.0 ,
70- local_openai_api_key : str | None = None ,
7170 local_shutdown_on_close : bool = True ,
7271 base_url : str | httpx .URL | None = None ,
7372 timeout : float | Timeout | None | NotGiven = not_given ,
@@ -93,7 +92,10 @@ def __init__(
9392 This automatically infers the following arguments from their corresponding environment variables if they are not provided:
9493 - `browserbase_api_key` from `BROWSERBASE_API_KEY`
9594 - `browserbase_project_id` from `BROWSERBASE_PROJECT_ID`
96- - `model_api_key` from `MODEL_API_KEY`
95+
96+ `model_api_key` is intentionally not inferred from any AI provider environment variable.
97+ Pass it explicitly when you want the SDK to send `x-model-api-key` on remote requests or
98+ to forward `MODEL_API_KEY` to the local SEA child process.
9799 """
98100 self ._server_mode : Literal ["remote" , "local" ] = server
99101 self ._local_stagehand_binary_path = _local_stagehand_binary_path
@@ -102,7 +104,6 @@ def __init__(
102104 self ._local_headless = local_headless
103105 self ._local_chrome_path = local_chrome_path
104106 self ._local_ready_timeout_s = local_ready_timeout_s
105- self ._local_openai_api_key = local_openai_api_key
106107 self ._local_shutdown_on_close = local_shutdown_on_close
107108
108109 if browserbase_api_key is None :
@@ -113,12 +114,6 @@ def __init__(
113114 self .browserbase_api_key = browserbase_api_key
114115 self .browserbase_project_id = browserbase_project_id
115116
116- if model_api_key is None :
117- model_api_key = os .environ .get ("MODEL_API_KEY" )
118- if model_api_key is None :
119- raise StagehandError (
120- "The model_api_key client option must be set either by passing model_api_key to the client or by setting the MODEL_API_KEY environment variable"
121- )
122117 self .model_api_key = model_api_key
123118
124119 self ._sea_server : SeaServerManager | None = None
@@ -127,14 +122,13 @@ def __init__(
127122 if base_url is None :
128123 base_url = "http://127.0.0.1"
129124
130- openai_api_key = local_openai_api_key or os .environ .get ("OPENAI_API_KEY" ) or model_api_key
131125 self ._sea_server = SeaServerManager (
132126 config = SeaServerConfig (
133127 host = local_host ,
134128 port = local_port ,
135129 headless = local_headless ,
136130 ready_timeout_s = local_ready_timeout_s ,
137- openai_api_key = openai_api_key ,
131+ model_api_key = model_api_key ,
138132 chrome_path = local_chrome_path ,
139133 shutdown_on_close = local_shutdown_on_close ,
140134 ),
@@ -210,7 +204,7 @@ def _bb_project_id_auth(self) -> dict[str, str]:
210204 @property
211205 def _llm_model_api_key_auth (self ) -> dict [str , str ]:
212206 model_api_key = self .model_api_key
213- return {"x-model-api-key" : model_api_key }
207+ return {"x-model-api-key" : model_api_key } if model_api_key else {}
214208
215209 @property
216210 @override
@@ -236,7 +230,6 @@ def copy(
236230 local_headless : bool | None = None ,
237231 local_chrome_path : str | None = None ,
238232 local_ready_timeout_s : float | None = None ,
239- local_openai_api_key : str | None = None ,
240233 local_shutdown_on_close : bool | None = None ,
241234 base_url : str | httpx .URL | None = None ,
242235 timeout : float | Timeout | None | NotGiven = not_given ,
@@ -283,9 +276,6 @@ def copy(
283276 local_ready_timeout_s = local_ready_timeout_s
284277 if local_ready_timeout_s is not None
285278 else self ._local_ready_timeout_s ,
286- local_openai_api_key = local_openai_api_key
287- if local_openai_api_key is not None
288- else self ._local_openai_api_key ,
289279 local_shutdown_on_close = local_shutdown_on_close
290280 if local_shutdown_on_close is not None
291281 else self ._local_shutdown_on_close ,
@@ -340,7 +330,7 @@ class AsyncStagehand(AsyncAPIClient):
340330 # client options
341331 browserbase_api_key : str | None
342332 browserbase_project_id : str | None
343- model_api_key : str
333+ model_api_key : str | None
344334
345335 def __init__ (
346336 self ,
@@ -355,7 +345,6 @@ def __init__(
355345 local_headless : bool = True ,
356346 local_chrome_path : str | None = None ,
357347 local_ready_timeout_s : float = 10.0 ,
358- local_openai_api_key : str | None = None ,
359348 local_shutdown_on_close : bool = True ,
360349 base_url : str | httpx .URL | None = None ,
361350 timeout : float | Timeout | None | NotGiven = not_given ,
@@ -381,7 +370,10 @@ def __init__(
381370 This automatically infers the following arguments from their corresponding environment variables if they are not provided:
382371 - `browserbase_api_key` from `BROWSERBASE_API_KEY`
383372 - `browserbase_project_id` from `BROWSERBASE_PROJECT_ID`
384- - `model_api_key` from `MODEL_API_KEY`
373+
374+ `model_api_key` is intentionally not inferred from any AI provider environment variable.
375+ Pass it explicitly when you want the SDK to send `x-model-api-key` on remote requests or
376+ to forward `MODEL_API_KEY` to the local SEA child process.
385377 """
386378 self ._server_mode : Literal ["remote" , "local" ] = server
387379 self ._local_stagehand_binary_path = _local_stagehand_binary_path
@@ -390,7 +382,6 @@ def __init__(
390382 self ._local_headless = local_headless
391383 self ._local_chrome_path = local_chrome_path
392384 self ._local_ready_timeout_s = local_ready_timeout_s
393- self ._local_openai_api_key = local_openai_api_key
394385 self ._local_shutdown_on_close = local_shutdown_on_close
395386
396387 if browserbase_api_key is None :
@@ -401,27 +392,20 @@ def __init__(
401392 self .browserbase_api_key = browserbase_api_key
402393 self .browserbase_project_id = browserbase_project_id
403394
404- if model_api_key is None :
405- model_api_key = os .environ .get ("MODEL_API_KEY" )
406- if model_api_key is None :
407- raise StagehandError (
408- "The model_api_key client option must be set either by passing model_api_key to the client or by setting the MODEL_API_KEY environment variable"
409- )
410395 self .model_api_key = model_api_key
411396
412397 self ._sea_server : SeaServerManager | None = None
413398 if server == "local" :
414399 if base_url is None :
415400 base_url = "http://127.0.0.1"
416401
417- openai_api_key = local_openai_api_key or os .environ .get ("OPENAI_API_KEY" ) or model_api_key
418402 self ._sea_server = SeaServerManager (
419403 config = SeaServerConfig (
420404 host = local_host ,
421405 port = local_port ,
422406 headless = local_headless ,
423407 ready_timeout_s = local_ready_timeout_s ,
424- openai_api_key = openai_api_key ,
408+ model_api_key = model_api_key ,
425409 chrome_path = local_chrome_path ,
426410 shutdown_on_close = local_shutdown_on_close ,
427411 ),
@@ -497,7 +481,7 @@ def _bb_project_id_auth(self) -> dict[str, str]:
497481 @property
498482 def _llm_model_api_key_auth (self ) -> dict [str , str ]:
499483 model_api_key = self .model_api_key
500- return {"x-model-api-key" : model_api_key }
484+ return {"x-model-api-key" : model_api_key } if model_api_key else {}
501485
502486 @property
503487 @override
@@ -523,7 +507,6 @@ def copy(
523507 local_headless : bool | None = None ,
524508 local_chrome_path : str | None = None ,
525509 local_ready_timeout_s : float | None = None ,
526- local_openai_api_key : str | None = None ,
527510 local_shutdown_on_close : bool | None = None ,
528511 base_url : str | httpx .URL | None = None ,
529512 timeout : float | Timeout | None | NotGiven = not_given ,
@@ -570,9 +553,6 @@ def copy(
570553 local_ready_timeout_s = local_ready_timeout_s
571554 if local_ready_timeout_s is not None
572555 else self ._local_ready_timeout_s ,
573- local_openai_api_key = local_openai_api_key
574- if local_openai_api_key is not None
575- else self ._local_openai_api_key ,
576556 local_shutdown_on_close = local_shutdown_on_close
577557 if local_shutdown_on_close is not None
578558 else self ._local_shutdown_on_close ,
0 commit comments