@@ -101,6 +101,7 @@ def __init__(
101101 chat_thread : ChatThread | None = None ,
102102 existing_chats : list [Chat ] | None = None ,
103103 workspace_dir : str = "./bluebox_workspace" ,
104+ auth_headers_provider : Callable [[], dict [str , str ]] | None = None ,
104105 ) -> None :
105106 """
106107 Initialize the BlueBox Agent.
@@ -115,10 +116,13 @@ def __init__(
115116 existing_chats: Existing Chat messages if loading from persistence.
116117 workspace_dir: Root workspace directory. Raw routine results go in raw/,
117118 agent-generated output files go in outputs/.
119+ auth_headers_provider: Optional callback that returns auth headers for
120+ downstream API calls. If not provided, falls back to Config.VECTORLY_API_KEY.
118121 """
119122 # Validate required config
120- if not Config .VECTORLY_API_KEY :
121- raise ValueError ("VECTORLY_API_KEY is not set" )
123+ self ._auth_headers_provider = auth_headers_provider
124+ if not auth_headers_provider and not Config .VECTORLY_API_KEY :
125+ raise ValueError ("Either auth_headers_provider or VECTORLY_API_KEY must be provided" )
122126 if not Config .VECTORLY_API_BASE :
123127 raise ValueError ("VECTORLY_API_BASE is not set" )
124128
@@ -146,6 +150,18 @@ def __init__(
146150 self ._thread .id ,
147151 )
148152
153+ ## Auth
154+
155+ def _get_auth_headers (self ) -> dict [str , str ]:
156+ """Build auth headers for downstream API calls.
157+ Uses auth_headers_provider if set, otherwise falls back to Config.VECTORLY_API_KEY."""
158+ if self ._auth_headers_provider :
159+ return self ._auth_headers_provider ()
160+ return {
161+ "Content-Type" : "application/json" ,
162+ "X-Service-Token" : Config .VECTORLY_API_KEY ,
163+ }
164+
149165 ## Abstract method implementations
150166
151167 def _get_system_prompt (self ) -> str :
@@ -206,10 +222,7 @@ def _search_routines(self, task: str) -> dict[str, Any]:
206222 task: Task description to search for.
207223 """
208224 url = f"{ Config .VECTORLY_API_BASE } /routines/semantic-search"
209- headers = {
210- "Content-Type" : "application/json" ,
211- "X-Service-Token" : Config .VECTORLY_API_KEY ,
212- }
225+ headers = self ._get_auth_headers ()
213226 payload = {
214227 "query" : task ,
215228 "top_n" : 5 ,
@@ -247,10 +260,7 @@ def _execute_routines_in_parallel(
247260 if validation_errors :
248261 return {"error" : "Parameter validation failed. Fix and retry.\n " + "\n " .join (validation_errors )}
249262
250- headers = {
251- "Content-Type" : "application/json" ,
252- "X-Service-Token" : Config .VECTORLY_API_KEY ,
253- }
263+ headers = self ._get_auth_headers ()
254264
255265 def save_result (result : dict [str , Any ]) -> dict [str , Any ]:
256266 """Save a single routine result to a JSON file in raw/."""
@@ -327,10 +337,7 @@ def _execute_browser_task(
327337 if not task or not task .strip ():
328338 return {"error" : "Task description cannot be empty" }
329339
330- headers = {
331- "Content-Type" : "application/json" ,
332- "X-Service-Token" : Config .VECTORLY_API_KEY ,
333- }
340+ headers = self ._get_auth_headers ()
334341
335342 payload = {
336343 "task" : task ,
0 commit comments