@@ -54,7 +54,7 @@ class APIRemoteWorkspace(RemoteWorkspace):
5454 default = 1 , description = "Resource scaling (1, 2, 4, or 8)"
5555 )
5656 runtime_class : str | None = Field (
57- default = "sysbox" , description = "Runtime class (e.g., 'sysbox')"
57+ default = "sysbox-runc " , description = "Runtime class (e.g., 'sysbox')"
5858 )
5959 init_timeout : float = Field (
6060 default = 300.0 , description = "Runtime init timeout (seconds)"
@@ -71,6 +71,21 @@ class APIRemoteWorkspace(RemoteWorkspace):
7171 _runtime_url : str | None = PrivateAttr (default = None )
7272 _session_api_key : str | None = PrivateAttr (default = None )
7373
74+ @property
75+ def _api_headers (self ):
76+ """Headers for runtime API requests."
77+
78+ This is used to manage new container runtimes via Runtime API.
79+
80+ For actual interaction with the remote agent server, the
81+ `client` property is used, which includes the session API key
82+ defined by ._headers property.
83+ """
84+ headers = {}
85+ if self .runtime_api_key :
86+ headers ["X-API-Key" ] = self .runtime_api_key
87+ return headers
88+
7489 def model_post_init (self , context : Any ) -> None :
7590 """Set up the remote runtime and initialize the workspace."""
7691 if self .resource_factor not in [1 , 2 , 4 , 8 ]:
@@ -97,12 +112,18 @@ def _start_or_attach_to_runtime(self) -> None:
97112 logger .info (f"Runtime ready at { self ._runtime_url } " )
98113 self .host = self ._runtime_url .rstrip ("/" )
99114 self .api_key = self ._session_api_key
115+ self ._client = None # Reset HTTP client with new host and API key
116+ _ = self .client # Initialize client by accessing the property
117+ assert self .client is not None
118+ assert self .client .base_url == self .host
100119
101120 def _check_existing_runtime (self ) -> bool :
102121 """Check if there's an existing runtime for this session."""
103122 try :
104123 resp = self ._send_api_request (
105- "GET" , f"{ self .runtime_api_url } /sessions/{ self .session_id } "
124+ "GET" ,
125+ f"{ self .runtime_api_url } /sessions/{ self .session_id } " ,
126+ headers = self ._api_headers ,
106127 )
107128 data = resp .json ()
108129 status = data .get ("status" )
@@ -149,6 +170,7 @@ def _start_runtime(self) -> None:
149170 f"{ self .runtime_api_url } /start" ,
150171 json = payload ,
151172 timeout = self .init_timeout ,
173+ headers = self ._api_headers ,
152174 )
153175 self ._parse_runtime_response (resp )
154176 logger .info (f"Runtime { self ._runtime_id } at { self ._runtime_url } " )
@@ -160,6 +182,7 @@ def _resume_runtime(self) -> None:
160182 f"{ self .runtime_api_url } /resume" ,
161183 json = {"runtime_id" : self ._runtime_id },
162184 timeout = self .init_timeout ,
185+ headers = self ._api_headers ,
163186 )
164187 self ._parse_runtime_response (resp )
165188
@@ -183,7 +206,9 @@ def _wait_until_runtime_alive(self) -> None:
183206 logger .info ("Waiting for runtime to become alive..." )
184207
185208 resp = self ._send_api_request (
186- "GET" , f"{ self .runtime_api_url } /sessions/{ self .session_id } "
209+ "GET" ,
210+ f"{ self .runtime_api_url } /sessions/{ self .session_id } " ,
211+ headers = self ._api_headers ,
187212 )
188213 data = resp .json ()
189214 pod_status = data .get ("pod_status" , "" ).lower ()
@@ -244,12 +269,15 @@ def _wait_until_runtime_alive(self) -> None:
244269 def _send_api_request (self , method : str , url : str , ** kwargs : Any ) -> httpx .Response :
245270 """Send an API request with error handling."""
246271 logger .debug (f"Sending { method } request to { url } " )
247- logger .debug (f"Client headers: { self ._headers } " )
272+ logger .debug (f"Request kwargs: { kwargs .keys ()} " )
273+
248274 response = self .client .request (method , url , ** kwargs )
249275 try :
250276 response .raise_for_status ()
251277 except httpx .HTTPStatusError :
252- logger .debug (f"Request headers: { response .request .headers } " )
278+ # Log only header keys, not values (to avoid exposing API keys)
279+ header_keys = list (response .request .headers .keys ())
280+ logger .debug (f"Request header keys: { header_keys } " )
253281 try :
254282 error_detail = response .json ()
255283 logger .info (f"API request failed: { error_detail } " )
@@ -274,9 +302,10 @@ def cleanup(self) -> None:
274302 f"{ self .runtime_api_url } /{ action } " ,
275303 json = {"runtime_id" : self ._runtime_id },
276304 timeout = 30.0 ,
305+ headers = self ._api_headers ,
277306 )
278307 except Exception as e :
279- logger .error (f"Cleanup error: { e } " )
308+ logger .warning (f"Cleanup error: { e } " )
280309 finally :
281310 self ._runtime_id = None
282311 self ._runtime_url = None
0 commit comments