agentscope-runtime 1.0.4__py3-none-any.whl → 1.0.4a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. agentscope_runtime/adapters/agentscope/stream.py +7 -1
  2. agentscope_runtime/cli/commands/deploy.py +0 -371
  3. agentscope_runtime/engine/__init__.py +0 -4
  4. agentscope_runtime/engine/constant.py +0 -1
  5. agentscope_runtime/engine/deployers/__init__.py +0 -12
  6. agentscope_runtime/engine/deployers/adapter/a2a/__init__.py +51 -26
  7. agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +10 -19
  8. agentscope_runtime/engine/deployers/adapter/a2a/a2a_registry.py +201 -4
  9. agentscope_runtime/engine/deployers/adapter/a2a/nacos_a2a_registry.py +25 -134
  10. agentscope_runtime/engine/deployers/agentrun_deployer.py +2 -2
  11. agentscope_runtime/engine/runner.py +0 -12
  12. agentscope_runtime/engine/tracing/wrapper.py +4 -18
  13. agentscope_runtime/sandbox/__init__.py +6 -14
  14. agentscope_runtime/sandbox/box/base/__init__.py +2 -2
  15. agentscope_runtime/sandbox/box/base/base_sandbox.py +1 -51
  16. agentscope_runtime/sandbox/box/browser/__init__.py +2 -2
  17. agentscope_runtime/sandbox/box/browser/browser_sandbox.py +2 -198
  18. agentscope_runtime/sandbox/box/filesystem/__init__.py +2 -2
  19. agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +2 -99
  20. agentscope_runtime/sandbox/box/gui/__init__.py +2 -2
  21. agentscope_runtime/sandbox/box/gui/gui_sandbox.py +1 -117
  22. agentscope_runtime/sandbox/box/mobile/__init__.py +2 -2
  23. agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +100 -247
  24. agentscope_runtime/sandbox/box/sandbox.py +65 -98
  25. agentscope_runtime/sandbox/box/shared/routers/generic.py +29 -36
  26. agentscope_runtime/sandbox/client/__init__.py +1 -6
  27. agentscope_runtime/sandbox/client/http_client.py +329 -108
  28. agentscope_runtime/sandbox/enums.py +0 -7
  29. agentscope_runtime/sandbox/manager/sandbox_manager.py +4 -264
  30. agentscope_runtime/sandbox/manager/server/app.py +1 -7
  31. agentscope_runtime/version.py +1 -1
  32. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.4a1.dist-info}/METADATA +28 -102
  33. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.4a1.dist-info}/RECORD +37 -46
  34. agentscope_runtime/adapters/ms_agent_framework/__init__.py +0 -0
  35. agentscope_runtime/adapters/ms_agent_framework/message.py +0 -205
  36. agentscope_runtime/adapters/ms_agent_framework/stream.py +0 -418
  37. agentscope_runtime/adapters/utils.py +0 -6
  38. agentscope_runtime/common/container_clients/knative_client.py +0 -466
  39. agentscope_runtime/engine/deployers/fc_deployer.py +0 -1506
  40. agentscope_runtime/engine/deployers/knative_deployer.py +0 -290
  41. agentscope_runtime/sandbox/client/async_http_client.py +0 -339
  42. agentscope_runtime/sandbox/client/base.py +0 -74
  43. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.4a1.dist-info}/WHEEL +0 -0
  44. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.4a1.dist-info}/entry_points.txt +0 -0
  45. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.4a1.dist-info}/licenses/LICENSE +0 -0
  46. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.4a1.dist-info}/top_level.txt +0 -0
@@ -2,8 +2,6 @@
2
2
  # pylint: disable=redefined-outer-name, protected-access
3
3
  # pylint: disable=too-many-branches, too-many-statements
4
4
  # pylint: disable=redefined-outer-name, protected-access, too-many-branches
5
- # pylint: disable=too-many-public-methods
6
- import asyncio
7
5
  import inspect
8
6
  import json
9
7
  import logging
@@ -15,13 +13,8 @@ from typing import Optional, Dict, Union, List
15
13
 
16
14
  import requests
17
15
  import shortuuid
18
- import httpx
19
16
 
20
- from ..client import (
21
- SandboxHttpClient,
22
- TrainingSandboxClient,
23
- SandboxHttpAsyncClient,
24
- )
17
+ from ..client import SandboxHttpClient, TrainingSandboxClient
25
18
  from ..enums import SandboxType
26
19
  from ..manager.storage import (
27
20
  LocalStorage,
@@ -38,7 +31,6 @@ from ...common.collections import (
38
31
  InMemoryMapping,
39
32
  InMemoryQueue,
40
33
  )
41
- from ..constant import TIMEOUT
42
34
 
43
35
  logging.basicConfig(level=logging.INFO)
44
36
  logger = logging.getLogger(__name__)
@@ -84,51 +76,6 @@ def remote_wrapper(
84
76
  return decorator
85
77
 
86
78
 
87
- def remote_wrapper_async(
88
- method: str = "POST",
89
- success_key: str = "data",
90
- ):
91
- """
92
- Async decorator to handle both remote and local method execution.
93
- Supports awaitable functions.
94
- """
95
-
96
- def decorator(func):
97
- @wraps(func)
98
- async def wrapper(self, *args, **kwargs):
99
- # Remote mode
100
- if hasattr(self, "httpx_client") and self.httpx_client is not None:
101
- endpoint = "/" + func.__name__
102
-
103
- # Build JSON data from args/kwargs
104
- sig = inspect.signature(func)
105
- param_names = list(sig.parameters.keys())[1:] # Skip 'self'
106
- data = dict(zip(param_names, args))
107
- data.update(kwargs)
108
-
109
- # Make async HTTP request
110
- response = await self._make_request_async(
111
- method,
112
- endpoint,
113
- data,
114
- )
115
-
116
- if success_key:
117
- return response.get(success_key)
118
- return response
119
-
120
- # Local mode
121
- return await func(self, *args, **kwargs)
122
-
123
- wrapper._is_remote_wrapper = True
124
- wrapper._http_method = method
125
- wrapper._path = "/" + func.__name__
126
-
127
- return wrapper
128
-
129
- return decorator
130
-
131
-
132
79
  class SandboxManager:
133
80
  def __init__(
134
81
  self,
@@ -145,23 +92,16 @@ class SandboxManager:
145
92
  # Initialize HTTP session for remote mode with bearer token
146
93
  # authentication
147
94
  self.http_session = requests.Session()
148
-
149
- # For async HTTP
150
- self.httpx_client = httpx.AsyncClient(timeout=TIMEOUT)
151
-
95
+ self.http_session.timeout = 30
152
96
  self.base_url = base_url.rstrip("/")
153
97
  if bearer_token:
154
98
  self.http_session.headers.update(
155
99
  {"Authorization": f"Bearer {bearer_token}"},
156
100
  )
157
- self.httpx_client.headers.update(
158
- {"Authorization": f"Bearer {bearer_token}"},
159
- )
160
101
  # Remote mode, return directly
161
102
  return
162
103
  else:
163
104
  self.http_session = None
164
- self.httpx_client = None
165
105
  self.base_url = None
166
106
 
167
107
  if not config:
@@ -286,51 +226,6 @@ class SandboxManager:
286
226
  )
287
227
  self.cleanup()
288
228
 
289
- if self.http_session:
290
- try:
291
- self.http_session.close()
292
- logger.debug("HTTP session closed.")
293
- except Exception as e:
294
- logger.warning(f"Error closing http_session: {e}")
295
-
296
- if self.httpx_client:
297
- try:
298
- loop = asyncio.get_event_loop()
299
- if loop.is_running():
300
- asyncio.ensure_future(self.httpx_client.aclose())
301
- else:
302
- loop.run_until_complete(self.httpx_client.aclose())
303
- logger.debug("HTTPX async client closed.")
304
- except Exception as e:
305
- logger.warning(f"Error closing httpx_client: {e}")
306
-
307
- async def __aenter__(self):
308
- logger.debug(
309
- "Entering SandboxManager context (async). "
310
- "Cleanup will be performed automatically on async exit.",
311
- )
312
- return self
313
-
314
- async def __aexit__(self, exc_type, exc_value, tb):
315
- logger.debug(
316
- "Exiting SandboxManager context (async). Cleaning up resources.",
317
- )
318
- await self.cleanup_async()
319
-
320
- if self.http_session:
321
- try:
322
- self.http_session.close()
323
- logger.debug("HTTP session closed.")
324
- except Exception as e:
325
- logger.warning(f"Error closing http_session: {e}")
326
-
327
- if self.httpx_client:
328
- try:
329
- await self.httpx_client.aclose()
330
- logger.debug("HTTPX async client closed.")
331
- except Exception as e:
332
- logger.warning(f"Error closing httpx_client: {e}")
333
-
334
229
  def _generate_container_key(self, session_id):
335
230
  return f"{self.prefix}{session_id}"
336
231
 
@@ -340,14 +235,9 @@ class SandboxManager:
340
235
  """
341
236
  url = f"{self.base_url}/{endpoint.lstrip('/')}"
342
237
  if method.upper() == "GET":
343
- response = self.http_session.get(url, params=data, timeout=TIMEOUT)
238
+ response = self.http_session.get(url, params=data)
344
239
  else:
345
- response = self.http_session.request(
346
- method,
347
- url,
348
- json=data,
349
- timeout=TIMEOUT,
350
- )
240
+ response = self.http_session.request(method, url, json=data)
351
241
 
352
242
  try:
353
243
  response.raise_for_status()
@@ -384,56 +274,6 @@ class SandboxManager:
384
274
 
385
275
  return response.json()
386
276
 
387
- async def _make_request_async(
388
- self,
389
- method: str,
390
- endpoint: str,
391
- data: dict,
392
- ):
393
- """
394
- Make an asynchronous HTTP request to the specified endpoint.
395
- """
396
- url = f"{self.base_url}/{endpoint.lstrip('/')}"
397
- if method.upper() == "GET":
398
- response = await self.httpx_client.get(url, params=data)
399
- else:
400
- response = await self.httpx_client.request(method, url, json=data)
401
-
402
- try:
403
- response.raise_for_status()
404
- except httpx.HTTPStatusError as e:
405
- error_components = [
406
- f"HTTP {response.status_code} Error: {str(e)}",
407
- ]
408
-
409
- try:
410
- server_response = response.json()
411
- if "detail" in server_response:
412
- error_components.append(
413
- f"Server Detail: {server_response['detail']}",
414
- )
415
- elif "error" in server_response:
416
- error_components.append(
417
- f"Server Error: {server_response['error']}",
418
- )
419
- else:
420
- error_components.append(
421
- f"Server Response: {server_response}",
422
- )
423
- except (ValueError, json.JSONDecodeError):
424
- if response.text:
425
- error_components.append(
426
- f"Server Response: {response.text}",
427
- )
428
-
429
- error = " | ".join(error_components)
430
-
431
- logger.error(f"Error making request: {error}")
432
-
433
- return {"data": f"Error: {error}"}
434
-
435
- return response.json()
436
-
437
277
  def _init_container_pool(self):
438
278
  """
439
279
  Init runtime pool
@@ -497,11 +337,6 @@ class SandboxManager:
497
337
  f"Error cleaning up container {key}: {e}",
498
338
  )
499
339
 
500
- @remote_wrapper_async()
501
- async def cleanup_async(self, *args, **kwargs):
502
- """Async wrapper for cleanup()."""
503
- return await asyncio.to_thread(self.cleanup, *args, **kwargs)
504
-
505
340
  @remote_wrapper()
506
341
  def create_from_pool(self, sandbox_type=None, meta: Optional[Dict] = None):
507
342
  """Try to get a container from runtime pool"""
@@ -609,11 +444,6 @@ class SandboxManager:
609
444
  logger.debug(f"{e}: {traceback.format_exc()}")
610
445
  return self.create()
611
446
 
612
- @remote_wrapper_async()
613
- async def create_from_pool_async(self, *args, **kwargs):
614
- """Async wrapper for create_from_pool()."""
615
- return await asyncio.to_thread(self.create_from_pool, *args, **kwargs)
616
-
617
447
  @remote_wrapper()
618
448
  def create(
619
449
  self,
@@ -791,11 +621,6 @@ class SandboxManager:
791
621
  self.release(identity=container_name)
792
622
  return None
793
623
 
794
- @remote_wrapper_async()
795
- async def create_async(self, *args, **kwargs):
796
- """Async wrapper for create()."""
797
- return await asyncio.to_thread(self.create, *args, **kwargs)
798
-
799
624
  @remote_wrapper()
800
625
  def release(self, identity):
801
626
  try:
@@ -846,11 +671,6 @@ class SandboxManager:
846
671
  logger.debug(f"{traceback.format_exc()}")
847
672
  return False
848
673
 
849
- @remote_wrapper_async()
850
- async def release_async(self, *args, **kwargs):
851
- """Async wrapper for release()."""
852
- return await asyncio.to_thread(self.release, *args, **kwargs)
853
-
854
674
  @remote_wrapper()
855
675
  def start(self, identity):
856
676
  try:
@@ -883,11 +703,6 @@ class SandboxManager:
883
703
  )
884
704
  return False
885
705
 
886
- @remote_wrapper_async()
887
- async def start_async(self, *args, **kwargs):
888
- """Async wrapper for start()."""
889
- return await asyncio.to_thread(self.start, *args, **kwargs)
890
-
891
706
  @remote_wrapper()
892
707
  def stop(self, identity):
893
708
  try:
@@ -918,21 +733,11 @@ class SandboxManager:
918
733
  )
919
734
  return False
920
735
 
921
- @remote_wrapper_async()
922
- async def stop_async(self, *args, **kwargs):
923
- """Async wrapper for stop()."""
924
- return await asyncio.to_thread(self.stop, *args, **kwargs)
925
-
926
736
  @remote_wrapper()
927
737
  def get_status(self, identity):
928
738
  """Get container status by container_name or container_id."""
929
739
  return self.client.get_status(identity)
930
740
 
931
- @remote_wrapper_async()
932
- async def get_status_async(self, *args, **kwargs):
933
- """Async wrapper for get_status()."""
934
- return await asyncio.to_thread(self.get_status, *args, **kwargs)
935
-
936
741
  @remote_wrapper()
937
742
  def get_info(self, identity):
938
743
  """Get container information by container_name or container_id."""
@@ -948,11 +753,6 @@ class SandboxManager:
948
753
 
949
754
  return container_model
950
755
 
951
- @remote_wrapper_async()
952
- async def get_info_async(self, *args, **kwargs):
953
- """Async wrapper for get_info()."""
954
- return await asyncio.to_thread(self.get_info, *args, **kwargs)
955
-
956
756
  def _establish_connection(self, identity):
957
757
  container_model = ContainerModel(**self.get_info(identity))
958
758
 
@@ -969,54 +769,24 @@ class SandboxManager:
969
769
  container_model,
970
770
  ).__enter__()
971
771
 
972
- async def _establish_connection_async(self, identity):
973
- container_model = ContainerModel(**self.get_info(identity))
974
-
975
- # TODO: TrainingSandboxClient lacks async, can use asyncio.to_thread()
976
- if (
977
- "sandbox-appworld" in container_model.version
978
- or "sandbox-bfcl" in container_model.version
979
- ):
980
- client = TrainingSandboxClient(base_url=container_model.url)
981
- return client.__enter__()
982
- async_client = SandboxHttpAsyncClient(container_model)
983
- await async_client.__aenter__()
984
- return async_client
985
-
986
772
  @remote_wrapper()
987
773
  def check_health(self, identity):
988
774
  """List tool"""
989
775
  client = self._establish_connection(identity)
990
776
  return client.check_health()
991
777
 
992
- @remote_wrapper_async()
993
- async def check_health_async(self, identity):
994
- client = await self._establish_connection_async(identity)
995
- return await client.check_health()
996
-
997
778
  @remote_wrapper()
998
779
  def list_tools(self, identity, tool_type=None, **kwargs):
999
780
  """List tool"""
1000
781
  client = self._establish_connection(identity)
1001
782
  return client.list_tools(tool_type=tool_type, **kwargs)
1002
783
 
1003
- @remote_wrapper_async()
1004
- async def list_tools_async(self, identity, tool_type=None, **kwargs):
1005
- client = await self._establish_connection_async(identity)
1006
- return await client.list_tools(tool_type=tool_type, **kwargs)
1007
-
1008
784
  @remote_wrapper()
1009
785
  def call_tool(self, identity, tool_name=None, arguments=None):
1010
786
  """Call tool"""
1011
787
  client = self._establish_connection(identity)
1012
788
  return client.call_tool(tool_name, arguments)
1013
789
 
1014
- @remote_wrapper_async()
1015
- async def call_tool_async(self, identity, tool_name=None, arguments=None):
1016
- """Call tool (async)"""
1017
- client = await self._establish_connection_async(identity)
1018
- return await client.call_tool(tool_name, arguments)
1019
-
1020
790
  @remote_wrapper()
1021
791
  def add_mcp_servers(self, identity, server_configs, overwrite=False):
1022
792
  """
@@ -1028,36 +798,11 @@ class SandboxManager:
1028
798
  overwrite=overwrite,
1029
799
  )
1030
800
 
1031
- @remote_wrapper_async()
1032
- async def add_mcp_servers_async(
1033
- self,
1034
- identity,
1035
- server_configs,
1036
- overwrite=False,
1037
- ):
1038
- """
1039
- Add MCP servers to runtime (async).
1040
- """
1041
- client = await self._establish_connection_async(identity)
1042
- return await client.add_mcp_servers(
1043
- server_configs=server_configs,
1044
- overwrite=overwrite,
1045
- )
1046
-
1047
801
  @remote_wrapper()
1048
802
  def get_session_mapping(self, session_ctx_id: str) -> list:
1049
803
  """Get all container names bound to a session context"""
1050
804
  return self.session_mapping.get(session_ctx_id) or []
1051
805
 
1052
- @remote_wrapper_async()
1053
- async def get_session_mapping_async(self, *args, **kwargs):
1054
- """Async wrapper for get_session_mapping()."""
1055
- return await asyncio.to_thread(
1056
- self.get_session_mapping,
1057
- *args,
1058
- **kwargs,
1059
- )
1060
-
1061
806
  @remote_wrapper()
1062
807
  def list_session_keys(self) -> list:
1063
808
  """Return all session_ctx_id keys currently in mapping"""
@@ -1065,8 +810,3 @@ class SandboxManager:
1065
810
  for key in self.session_mapping.scan():
1066
811
  session_keys.append(key)
1067
812
  return session_keys
1068
-
1069
- @remote_wrapper_async()
1070
- async def list_session_keys_async(self, *args, **kwargs):
1071
- """Async wrapper for list_session_keys()."""
1072
- return await asyncio.to_thread(self.list_session_keys, *args, **kwargs)
@@ -245,13 +245,7 @@ async def proxy_vnc_static(sandbox_id: str, path: str):
245
245
  target_url = f"{base_url}/{path}"
246
246
 
247
247
  try:
248
- async with httpx.AsyncClient(
249
- headers={ # For FC
250
- "Content-Type": "application/json",
251
- "x-agentrun-session-id": "s" + sandbox_id,
252
- "x-agentscope-runtime-session-id": "s" + sandbox_id,
253
- },
254
- ) as client:
248
+ async with httpx.AsyncClient() as client:
255
249
  upstream = await client.get(target_url)
256
250
  return Response(
257
251
  content=upstream.content,
@@ -1,2 +1,2 @@
1
1
  # -*- coding: utf-8 -*-
2
- __version__ = "v1.0.4"
2
+ __version__ = "v1.0.4a1"