agentscope-runtime 1.0.5.post1__py3-none-any.whl → 1.1.0b2__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 (71) hide show
  1. agentscope_runtime/__init__.py +3 -0
  2. agentscope_runtime/adapters/agentscope/message.py +36 -295
  3. agentscope_runtime/adapters/agentscope/stream.py +89 -2
  4. agentscope_runtime/adapters/agno/message.py +11 -2
  5. agentscope_runtime/adapters/agno/stream.py +1 -0
  6. agentscope_runtime/adapters/langgraph/__init__.py +1 -3
  7. agentscope_runtime/adapters/langgraph/message.py +11 -106
  8. agentscope_runtime/adapters/langgraph/stream.py +1 -0
  9. agentscope_runtime/adapters/ms_agent_framework/message.py +11 -1
  10. agentscope_runtime/adapters/ms_agent_framework/stream.py +1 -0
  11. agentscope_runtime/adapters/text/stream.py +1 -0
  12. agentscope_runtime/common/container_clients/agentrun_client.py +0 -3
  13. agentscope_runtime/common/container_clients/boxlite_client.py +26 -15
  14. agentscope_runtime/common/container_clients/fc_client.py +0 -11
  15. agentscope_runtime/common/utils/deprecation.py +14 -17
  16. agentscope_runtime/common/utils/logging.py +44 -0
  17. agentscope_runtime/engine/app/agent_app.py +5 -5
  18. agentscope_runtime/engine/app/celery_mixin.py +43 -4
  19. agentscope_runtime/engine/deployers/adapter/agui/__init__.py +8 -1
  20. agentscope_runtime/engine/deployers/adapter/agui/agui_adapter_utils.py +6 -1
  21. agentscope_runtime/engine/deployers/adapter/agui/agui_protocol_adapter.py +2 -2
  22. agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +13 -0
  23. agentscope_runtime/engine/runner.py +31 -6
  24. agentscope_runtime/engine/schemas/agent_schemas.py +28 -0
  25. agentscope_runtime/engine/services/sandbox/sandbox_service.py +41 -9
  26. agentscope_runtime/sandbox/box/base/base_sandbox.py +4 -0
  27. agentscope_runtime/sandbox/box/browser/browser_sandbox.py +4 -0
  28. agentscope_runtime/sandbox/box/dummy/dummy_sandbox.py +9 -2
  29. agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +4 -0
  30. agentscope_runtime/sandbox/box/gui/gui_sandbox.py +5 -1
  31. agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +4 -0
  32. agentscope_runtime/sandbox/box/sandbox.py +122 -13
  33. agentscope_runtime/sandbox/client/async_http_client.py +1 -0
  34. agentscope_runtime/sandbox/client/base.py +0 -1
  35. agentscope_runtime/sandbox/client/http_client.py +0 -2
  36. agentscope_runtime/sandbox/manager/heartbeat_mixin.py +486 -0
  37. agentscope_runtime/sandbox/manager/sandbox_manager.py +740 -153
  38. agentscope_runtime/sandbox/manager/server/app.py +18 -11
  39. agentscope_runtime/sandbox/manager/server/config.py +10 -2
  40. agentscope_runtime/sandbox/mcp_server.py +0 -1
  41. agentscope_runtime/sandbox/model/__init__.py +2 -1
  42. agentscope_runtime/sandbox/model/container.py +90 -3
  43. agentscope_runtime/sandbox/model/manager_config.py +45 -1
  44. agentscope_runtime/version.py +1 -1
  45. {agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b2.dist-info}/METADATA +36 -54
  46. {agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b2.dist-info}/RECORD +50 -69
  47. agentscope_runtime/adapters/agentscope/long_term_memory/__init__.py +0 -6
  48. agentscope_runtime/adapters/agentscope/long_term_memory/_long_term_memory_adapter.py +0 -258
  49. agentscope_runtime/adapters/agentscope/memory/__init__.py +0 -6
  50. agentscope_runtime/adapters/agentscope/memory/_memory_adapter.py +0 -152
  51. agentscope_runtime/engine/services/agent_state/__init__.py +0 -25
  52. agentscope_runtime/engine/services/agent_state/redis_state_service.py +0 -166
  53. agentscope_runtime/engine/services/agent_state/state_service.py +0 -179
  54. agentscope_runtime/engine/services/agent_state/state_service_factory.py +0 -52
  55. agentscope_runtime/engine/services/memory/__init__.py +0 -33
  56. agentscope_runtime/engine/services/memory/mem0_memory_service.py +0 -128
  57. agentscope_runtime/engine/services/memory/memory_service.py +0 -292
  58. agentscope_runtime/engine/services/memory/memory_service_factory.py +0 -126
  59. agentscope_runtime/engine/services/memory/redis_memory_service.py +0 -290
  60. agentscope_runtime/engine/services/memory/reme_personal_memory_service.py +0 -109
  61. agentscope_runtime/engine/services/memory/reme_task_memory_service.py +0 -11
  62. agentscope_runtime/engine/services/memory/tablestore_memory_service.py +0 -301
  63. agentscope_runtime/engine/services/session_history/__init__.py +0 -32
  64. agentscope_runtime/engine/services/session_history/redis_session_history_service.py +0 -283
  65. agentscope_runtime/engine/services/session_history/session_history_service.py +0 -267
  66. agentscope_runtime/engine/services/session_history/session_history_service_factory.py +0 -73
  67. agentscope_runtime/engine/services/session_history/tablestore_session_history_service.py +0 -288
  68. {agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b2.dist-info}/WHEEL +0 -0
  69. {agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b2.dist-info}/entry_points.txt +0 -0
  70. {agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b2.dist-info}/licenses/LICENSE +0 -0
  71. {agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b2.dist-info}/top_level.txt +0 -0
@@ -25,8 +25,6 @@ from ...model.manager_config import SandboxManagerEnvConfig
25
25
  from ...utils import dynamic_import, http_to_ws
26
26
  from ....version import __version__
27
27
 
28
- # Configure logging
29
- logging.basicConfig(level=logging.INFO)
30
28
  logger = logging.getLogger(__name__)
31
29
 
32
30
  # Create FastAPI app
@@ -65,6 +63,7 @@ def get_config() -> SandboxManagerEnvConfig:
65
63
  container_deployment=settings.CONTAINER_DEPLOYMENT,
66
64
  default_mount_dir=settings.DEFAULT_MOUNT_DIR,
67
65
  readonly_mounts=settings.READONLY_MOUNTS,
66
+ allow_mount_dir=settings.ALLOW_MOUNT_DIR,
68
67
  storage_folder=settings.STORAGE_FOLDER,
69
68
  port_range=settings.PORT_RANGE,
70
69
  pool_size=settings.POOL_SIZE,
@@ -105,6 +104,11 @@ def get_config() -> SandboxManagerEnvConfig:
105
104
  fc_prefix=settings.FC_PREFIX,
106
105
  fc_log_project=settings.FC_LOG_PROJECT,
107
106
  fc_log_store=settings.FC_LOG_STORE,
107
+ heartbeat_timeout=settings.HEARTBEAT_TIMEOUT,
108
+ heartbeat_lock_ttl=settings.HEARTBEAT_LOCK_TTL,
109
+ watcher_scan_interval=settings.WATCHER_SCAN_INTERVAL,
110
+ released_key_ttl=settings.RELEASE_KET_TTL,
111
+ max_sandbox_instances=settings.MAX_SANDBOX_INSTANCES,
108
112
  )
109
113
  return _config
110
114
 
@@ -208,15 +212,25 @@ async def startup_event():
208
212
  get_sandbox_manager()
209
213
  register_routes(app, _sandbox_manager)
210
214
 
215
+ # Start heartbeat watcher on server side
216
+ _sandbox_manager.start_watcher()
217
+
211
218
 
212
219
  @app.on_event("shutdown")
213
220
  async def shutdown_event():
214
221
  """Cleanup resources on shutdown"""
215
222
  global _sandbox_manager
216
223
  settings = get_settings()
217
- if _sandbox_manager and settings.AUTO_CLEANUP:
224
+ if not _sandbox_manager:
225
+ return
226
+
227
+ # stop watcher first
228
+ _sandbox_manager.stop_watcher()
229
+
230
+ if settings.AUTO_CLEANUP:
218
231
  _sandbox_manager.cleanup()
219
- _sandbox_manager = None
232
+
233
+ _sandbox_manager = None
220
234
 
221
235
 
222
236
  @app.get(
@@ -355,13 +369,6 @@ def setup_logging(log_level: str):
355
369
 
356
370
  level = level_mapping.get(log_level.upper(), logging.INFO)
357
371
 
358
- # Reconfigure logging
359
- logging.basicConfig(
360
- level=level,
361
- format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
362
- force=True, # This will reconfigure existing loggers
363
- )
364
-
365
372
  # Update the logger for this module
366
373
  global logger
367
374
  logger.setLevel(level)
@@ -38,7 +38,8 @@ class Settings(BaseSettings):
38
38
  # READONLY_MOUNTS={"\/opt\/shared": "\/mnt\/shared", "\/etc\/timezone":
39
39
  # "\/etc\/timezone"}
40
40
  READONLY_MOUNTS: Optional[Dict[str, str]] = None
41
- STORAGE_FOLDER: str = "runtime_sandbox_storage"
41
+ ALLOW_MOUNT_DIR: Optional[bool] = False
42
+ STORAGE_FOLDER: Optional[str] = None
42
43
  PORT_RANGE: Tuple[int, int] = (49152, 59152)
43
44
 
44
45
  # Redis settings
@@ -98,8 +99,15 @@ class Settings(BaseSettings):
98
99
  FC_LOG_PROJECT: Optional[str] = None
99
100
  FC_LOG_STORE: Optional[str] = None
100
101
 
102
+ # Heartbeat related
103
+ HEARTBEAT_TIMEOUT: int = 300
104
+ HEARTBEAT_LOCK_TTL: int = 120
105
+ WATCHER_SCAN_INTERVAL: int = 1 # 0 to disable watcher
106
+ RELEASE_KET_TTL: int = 3600
107
+
108
+ MAX_SANDBOX_INSTANCES: int = 0 # 0 means unlimited
109
+
101
110
  model_config = ConfigDict(
102
- case_sensitive=True,
103
111
  extra="allow",
104
112
  )
105
113
 
@@ -9,7 +9,6 @@ from .box.browser.browser_sandbox import BrowserSandbox
9
9
  from .box.filesystem.filesystem_sandbox import FilesystemSandbox
10
10
  from .enums import SandboxType
11
11
 
12
- logging.basicConfig(level=logging.INFO)
13
12
  logger = logging.getLogger(__name__)
14
13
 
15
14
  mcp = FastMCP("AgentRuntime Sandbox MCP Server")
@@ -1,8 +1,9 @@
1
1
  # -*- coding: utf-8 -*-
2
- from .container import ContainerModel
2
+ from .container import ContainerModel, ContainerState
3
3
  from .manager_config import SandboxManagerEnvConfig
4
4
 
5
5
  __all__ = [
6
6
  "ContainerModel",
7
+ "ContainerState",
7
8
  "SandboxManagerEnvConfig",
8
9
  ]
@@ -1,10 +1,23 @@
1
1
  # -*- coding: utf-8 -*-
2
+ import copy
3
+ import time
4
+ from enum import Enum
2
5
  from typing import List, Optional, Dict
3
6
 
4
- from pydantic import BaseModel, Field
7
+ from pydantic import BaseModel, Field, ConfigDict, model_validator
8
+
9
+
10
+ class ContainerState(str, Enum):
11
+ WARM = "warm"
12
+ RUNNING = "running"
13
+ RECYCLED = "recycled"
14
+ ERROR = "error"
15
+ RELEASED = "released"
5
16
 
6
17
 
7
18
  class ContainerModel(BaseModel):
19
+ model_config = ConfigDict(extra="allow")
20
+
8
21
  session_id: str = Field(
9
22
  ...,
10
23
  description="Unique identifier for the session",
@@ -59,5 +72,79 @@ class ContainerModel(BaseModel):
59
72
  ge=0,
60
73
  )
61
74
 
62
- class Config:
63
- extra = "allow"
75
+ sandbox_type: Optional[str] = Field(
76
+ default=None,
77
+ description="Sandbox type (e.g. base/browser/...). Usually "
78
+ "SandboxType.value.",
79
+ )
80
+
81
+ state: ContainerState = Field(
82
+ default=ContainerState.RUNNING,
83
+ description="Lifecycle state",
84
+ )
85
+
86
+ # Pull session_ctx_id up from meta for easier indexing/logic
87
+ session_ctx_id: Optional[str] = Field(
88
+ default=None,
89
+ description="Bound session context id "
90
+ "(copied from meta['session_ctx_id'] for compatibility)",
91
+ )
92
+
93
+ # Heartbeat timestamp (unix seconds)
94
+ last_active_at: Optional[float] = Field(
95
+ default=None,
96
+ description="Last activity timestamp (unix seconds)",
97
+ )
98
+
99
+ # Recycle/release timestamps
100
+ recycled_at: Optional[float] = Field(
101
+ default=None,
102
+ description="Recycled timestamp (unix seconds)",
103
+ )
104
+ released_at: Optional[float] = Field(
105
+ default=None,
106
+ description="Released timestamp (unix seconds)",
107
+ )
108
+ updated_at: Optional[float] = Field(
109
+ default=None,
110
+ description="Last model update timestamp (unix seconds)",
111
+ )
112
+
113
+ recycle_reason: Optional[str] = Field(
114
+ default=None,
115
+ description="Reason for recycle",
116
+ )
117
+
118
+ @model_validator(mode="after")
119
+ def _compat_and_defaults(self):
120
+ """Compatibility layer for ContainerModel.
121
+
122
+ This validator ensures backward compatibility and default value
123
+ population:
124
+ - Reads session_ctx_id from meta if not provided
125
+ - Writes session_ctx_id back to meta for old code compatibility
126
+ - Ensures updated_at is always populated
127
+
128
+ Returns:
129
+ `ContainerModel`:
130
+ The validated model instance
131
+ """
132
+ # normalize meta
133
+ if self.meta is None:
134
+ self.meta = {}
135
+
136
+ # meta -> session_ctx_id
137
+ if not self.session_ctx_id:
138
+ v = self.meta.get("session_ctx_id")
139
+ if v:
140
+ self.session_ctx_id = v
141
+
142
+ # session_ctx_id -> meta
143
+ if self.session_ctx_id:
144
+ self.meta["session_ctx_id"] = copy.deepcopy(self.session_ctx_id)
145
+
146
+ # default updated_at
147
+ if self.updated_at is None:
148
+ self.updated_at = time.time()
149
+
150
+ return self
@@ -20,7 +20,7 @@ class SandboxManagerEnvConfig(BaseModel):
20
20
  description="Type of file system to use: 'local' or 'oss'.",
21
21
  )
22
22
  storage_folder: Optional[str] = Field(
23
- "runtime_sandbox_storage",
23
+ None,
24
24
  description="Folder path in storage.",
25
25
  )
26
26
  redis_enabled: bool = Field(
@@ -53,6 +53,15 @@ class SandboxManagerEnvConfig(BaseModel):
53
53
  "'/etc/timezone' }",
54
54
  )
55
55
 
56
+ allow_mount_dir: bool = Field(
57
+ default=False,
58
+ description=(
59
+ "Whether to allow passing `mount_dir`. "
60
+ "Disable by default to prevent mounting server-local paths when "
61
+ "running as a manager service."
62
+ ),
63
+ )
64
+
56
65
  port_range: Tuple[int, int] = Field(
57
66
  (49152, 59152),
58
67
  description="Range of ports to be used by the manager.",
@@ -239,6 +248,41 @@ class SandboxManagerEnvConfig(BaseModel):
239
248
  description="Log store for FC.",
240
249
  )
241
250
 
251
+ # Heartbeat related
252
+ heartbeat_timeout: int = Field(
253
+ default=300,
254
+ description="Idle timeout in seconds before session is reaped.",
255
+ gt=0,
256
+ )
257
+ heartbeat_lock_ttl: int = Field(
258
+ default=120,
259
+ description="Redis distributed lock TTL in seconds for reaping.",
260
+ gt=0,
261
+ )
262
+ watcher_scan_interval: int = Field(
263
+ default=1,
264
+ description=(
265
+ "Background watcher loop interval in seconds. "
266
+ "0 disables watcher. Watcher includes heartbeat scan, pool "
267
+ "replenish, and released-record cleanup."
268
+ ),
269
+ ge=0,
270
+ )
271
+ released_key_ttl: int = Field(
272
+ default=3600,
273
+ description=(
274
+ "TTL in seconds for keeping RELEASED container records in "
275
+ "container_mapping. 0 disables cleanup."
276
+ ),
277
+ ge=0,
278
+ )
279
+ max_sandbox_instances: int = Field(
280
+ default=0,
281
+ description="Maximum number of sandbox instances allowed. "
282
+ "0 means unlimited.",
283
+ ge=0,
284
+ )
285
+
242
286
  @model_validator(mode="after")
243
287
  def check_settings(self):
244
288
  if self.default_mount_dir:
@@ -1,2 +1,2 @@
1
1
  # -*- coding: utf-8 -*-
2
- __version__ = "v1.0.5.post1"
2
+ __version__ = "v1.1.0b2"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentscope-runtime
3
- Version: 1.0.5.post1
3
+ Version: 1.1.0b2
4
4
  Summary: A production-ready runtime framework for agent applications, providing secure sandboxed execution environments and scalable deployment solutions with multi-framework support.
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -11,7 +11,7 @@ Requires-Dist: uvicorn[standard]>=0.24.0
11
11
  Requires-Dist: openai
12
12
  Requires-Dist: pydantic>=2.11.7
13
13
  Requires-Dist: requests>=2.32.4
14
- Requires-Dist: agentscope<1.0.12,>=1.0.9
14
+ Requires-Dist: agentscope>=1.0.14
15
15
  Requires-Dist: docker>=7.1.0
16
16
  Requires-Dist: redis>=6.0.0
17
17
  Requires-Dist: oss2>=2.19.1
@@ -50,7 +50,6 @@ Requires-Dist: mem0ai>=0.1.117; extra == "ext"
50
50
  Requires-Dist: alibabacloud-agentrun20250910>=2.0.1; extra == "ext"
51
51
  Requires-Dist: alibabacloud_tea_openapi>=0.4.0; extra == "ext"
52
52
  Requires-Dist: alibabacloud-fc20230330>=4.4.0; extra == "ext"
53
- Requires-Dist: tablestore-for-agent-memory>=1.1.0; extra == "ext"
54
53
  Requires-Dist: langchain-community>=0.3.27; extra == "ext"
55
54
  Requires-Dist: wuying-agentbay-sdk<0.13.0,>=0.5.0; extra == "ext"
56
55
  Requires-Dist: alipay-sdk-python; extra == "ext"
@@ -90,7 +89,7 @@ Dynamic: license-file
90
89
  [![GitHub Forks](https://img.shields.io/github/forks/agentscope-ai/agentscope-runtime?style=flat&logo=github&color=purple&label=Forks)](https://github.com/agentscope-ai/agentscope-runtime/network)
91
90
  [![Build Status](https://img.shields.io/badge/build-passing-brightgreen.svg?logo=githubactions&label=Build)](https://github.com/agentscope-ai/agentscope-runtime/actions)
92
91
  [![Cookbook](https://img.shields.io/badge/📚_Cookbook-English|中文-teal.svg)](https://runtime.agentscope.io)
93
- [![DeepWiki](https://img.shields.io/badge/DeepWiki-agentscope--runtime-navy.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAyCAYAAAAnWDnqAAAAAXNSR0IArs4c6QAAA05JREFUaEPtmUtyEzEQhtWTQyQLHNak2AB7ZnyXZMEjXMGeK/AIi+QuHrMnbChYY7MIh8g01fJoopFb0uhhEqqcbWTp06/uv1saEDv4O3n3dV60RfP947Mm9/SQc0ICFQgzfc4CYZoTPAswgSJCCUJUnAAoRHOAUOcATwbmVLWdGoH//PB8mnKqScAhsD0kYP3j/Yt5LPQe2KvcXmGvRHcDnpxfL2zOYJ1mFwrryWTz0advv1Ut4CJgf5uhDuDj5eUcAUoahrdY/56ebRWeraTjMt/00Sh3UDtjgHtQNHwcRGOC98BJEAEymycmYcWwOprTgcB6VZ5JK5TAJ+fXGLBm3FDAmn6oPPjR4rKCAoJCal2eAiQp2x0vxTPB3ALO2CRkwmDy5WohzBDwSEFKRwPbknEggCPB/imwrycgxX2NzoMCHhPkDwqYMr9tRcP5qNrMZHkVnOjRMWwLCcr8ohBVb1OMjxLwGCvjTikrsBOiA6fNyCrm8V1rP93iVPpwaE+gO0SsWmPiXB+jikdf6SizrT5qKasx5j8ABbHpFTx+vFXp9EnYQmLx02h1QTTrl6eDqxLnGjporxl3NL3agEvXdT0WmEost648sQOYAeJS9Q7bfUVoMGnjo4AZdUMQku50McDcMWcBPvr0SzbTAFDfvJqwLzgxwATnCgnp4wDl6Aa+Ax283gghmj+vj7feE2KBBRMW3FzOpLOADl0Isb5587h/U4gGvkt5v60Z1VLG8BhYjbzRwyQZemwAd6cCR5/XFWLYZRIMpX39AR0tjaGGiGzLVyhse5C9RKC6ai42ppWPKiBagOvaYk8lO7DajerabOZP46Lby5wKjw1HCRx7p9sVMOWGzb/vA1hwiWc6jm3MvQDTogQkiqIhJV0nBQBTU+3okKCFDy9WwferkHjtxib7t3xIUQtHxnIwtx4mpg26/HfwVNVDb4oI9RHmx5WGelRVlrtiw43zboCLaxv46AZeB3IlTkwouebTr1y2NjSpHz68WNFjHvupy3q8TFn3Hos2IAk4Ju5dCo8B3wP7VPr/FGaKiG+T+v+TQqIrOqMTL1VdWV1DdmcbO8KXBz6esmYWYKPwDL5b5FA1a0hwapHiom0r/cKaoqr+27/XcrS5UwSMbQAAAABJRU5ErkJggg==)](https://deepwiki.com/agentscope-ai/agentscope-runtime)
92
+ [![DeepWiki](https://img.shields.io/badge/DeepWiki-Ask_Devin-navy.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAyCAYAAAAnWDnqAAAAAXNSR0IArs4c6QAAA05JREFUaEPtmUtyEzEQhtWTQyQLHNak2AB7ZnyXZMEjXMGeK/AIi+QuHrMnbChYY7MIh8g01fJoopFb0uhhEqqcbWTp06/uv1saEDv4O3n3dV60RfP947Mm9/SQc0ICFQgzfc4CYZoTPAswgSJCCUJUnAAoRHOAUOcATwbmVLWdGoH//PB8mnKqScAhsD0kYP3j/Yt5LPQe2KvcXmGvRHcDnpxfL2zOYJ1mFwrryWTz0advv1Ut4CJgf5uhDuDj5eUcAUoahrdY/56ebRWeraTjMt/00Sh3UDtjgHtQNHwcRGOC98BJEAEymycmYcWwOprTgcB6VZ5JK5TAJ+fXGLBm3FDAmn6oPPjR4rKCAoJCal2eAiQp2x0vxTPB3ALO2CRkwmDy5WohzBDwSEFKRwPbknEggCPB/imwrycgxX2NzoMCHhPkDwqYMr9tRcP5qNrMZHkVnOjRMWwLCcr8ohBVb1OMjxLwGCvjTikrsBOiA6fNyCrm8V1rP93iVPpwaE+gO0SsWmPiXB+jikdf6SizrT5qKasx5j8ABbHpFTx+vFXp9EnYQmLx02h1QTTrl6eDqxLnGjporxl3NL3agEvXdT0WmEost648sQOYAeJS9Q7bfUVoMGnjo4AZdUMQku50McDcMWcBPvr0SzbTAFDfvJqwLzgxwATnCgnp4wDl6Aa+Ax283gghmj+vj7feE2KBBRMW3FzOpLOADl0Isb5587h/U4gGvkt5v60Z1VLG8BhYjbzRwyQZemwAd6cCR5/XFWLYZRIMpX39AR0tjaGGiGzLVyhse5C9RKC6ai42ppWPKiBagOvaYk8lO7DajerabOZP46Lby5wKjw1HCRx7p9sVMOWGzb/vA1hwiWc6jm3MvQDTogQkiqIhJV0nBQBTU+3okKCFDy9WwferkHjtxib7t3xIUQtHxnIwtx4mpg26/HfwVNVDb4oI9RHmx5WGelRVlrtiw43zboCLaxv46AZeB3IlTkwouebTr1y2NjSpHz68WNFjHvupy3q8TFn3Hos2IAk4Ju5dCo8B3wP7VPr/FGaKiG+T+v+TQqIrOqMTL1VdWV1DdmcbO8KXBz6esmYWYKPwDL5b5FA1a0hwapHiom0r/cKaoqr+27/XcrS5UwSMbQAAAABJRU5ErkJggg==)](https://deepwiki.com/agentscope-ai/agentscope-runtime)
94
93
  [![A2A](https://img.shields.io/badge/A2A-Agent_to_Agent-blue.svg?label=A2A)](https://a2a-protocol.org/)
95
94
  [![MCP](https://img.shields.io/badge/MCP-Model_Context_Protocol-purple.svg?logo=plug&label=MCP)](https://modelcontextprotocol.io/)
96
95
  [![Discord](https://img.shields.io/badge/Discord-Join_Us-blueviolet.svg?logo=discord)](https://discord.gg/eYMpfnkG8h)
@@ -171,13 +170,13 @@ Dynamic: license-file
171
170
  >
172
171
  > **About Framework-Agnostic**: Currently, AgentScope Runtime supports the **AgentScope** framework. We plan to extend compatibility to more agent development frameworks in the future. This table shows the current version’s adapter support for different frameworks. The level of support for each functionality varies across frameworks:
173
172
  >
174
- > | Framework/Feature | Message/Event | Tool | Service |
175
- > | ------------------------------------------------------------ | ------------- | ---- | ------- |
176
- > | [AgentScope](https://runtime.agentscope.io/en/quickstart.html) | ✅ | ✅ | ✅ |
177
- > | [LangGraph](https://runtime.agentscope.io/en/langgraph_guidelines.html) | ✅ | 🚧 | 🚧 |
178
- > | [Microsoft Agent Framework](https://runtime.agentscope.io/en/ms_agent_framework_guidelines.html) | ✅ | ✅ | 🚧 |
179
- > | [Agno](https://runtime.agentscope.io/en/agno_guidelines.html) | ✅ | ✅ | 🚧 |
180
- > | AutoGen | 🚧 | ✅ | 🚧 |
173
+ > | Framework/Feature | Message/Event | Tool |
174
+ > | ------------------------------------------------------------ | ------------- | ---- |
175
+ > | [AgentScope](https://runtime.agentscope.io/en/quickstart.html) | ✅ | ✅ |
176
+ > | [LangGraph](https://runtime.agentscope.io/en/langgraph_guidelines.html) | ✅ | 🚧 |
177
+ > | [Microsoft Agent Framework](https://runtime.agentscope.io/en/ms_agent_framework_guidelines.html) | ✅ | ✅ |
178
+ > | [Agno](https://runtime.agentscope.io/en/agno_guidelines.html) | ✅ | ✅ |
179
+ > | AutoGen | 🚧 | ✅ |
181
180
 
182
181
  ---
183
182
 
@@ -230,18 +229,11 @@ from agentscope.model import DashScopeChatModel
230
229
  from agentscope.formatter import DashScopeChatFormatter
231
230
  from agentscope.tool import Toolkit, execute_python_code
232
231
  from agentscope.pipeline import stream_printing_messages
232
+ from agentscope.memory import InMemoryMemory
233
+ from agentscope.session import RedisSession
233
234
 
234
235
  from agentscope_runtime.engine import AgentApp
235
236
  from agentscope_runtime.engine.schemas.agent_schemas import AgentRequest
236
- from agentscope_runtime.adapters.agentscope.memory import (
237
- AgentScopeSessionHistoryMemory,
238
- )
239
- from agentscope_runtime.engine.services.agent_state import (
240
- InMemoryStateService,
241
- )
242
- from agentscope_runtime.engine.services.session_history import (
243
- InMemorySessionHistoryService,
244
- )
245
237
 
246
238
  agent_app = AgentApp(
247
239
  app_name="Friday",
@@ -251,17 +243,13 @@ agent_app = AgentApp(
251
243
 
252
244
  @agent_app.init
253
245
  async def init_func(self):
254
- self.state_service = InMemoryStateService()
255
- self.session_service = InMemorySessionHistoryService()
256
-
257
- await self.state_service.start()
258
- await self.session_service.start()
246
+ import fakeredis
259
247
 
260
-
261
- @agent_app.shutdown
262
- async def shutdown_func(self):
263
- await self.state_service.stop()
264
- await self.session_service.stop()
248
+ fake_redis = fakeredis.aioredis.FakeRedis(decode_responses=True)
249
+ # NOTE: This FakeRedis instance is for development/testing only.
250
+ # In production, replace it with your own Redis client/connection
251
+ # (e.g., aioredis.Redis)
252
+ self.session = RedisSession(connection_pool=fake_redis.connection_pool)
265
253
 
266
254
 
267
255
  @agent_app.query(framework="agentscope")
@@ -274,11 +262,6 @@ async def query_func(
274
262
  session_id = request.session_id
275
263
  user_id = request.user_id
276
264
 
277
- state = await self.state_service.export_state(
278
- session_id=session_id,
279
- user_id=user_id,
280
- )
281
-
282
265
  toolkit = Toolkit()
283
266
  toolkit.register_tool_function(execute_python_code)
284
267
 
@@ -291,17 +274,16 @@ async def query_func(
291
274
  ),
292
275
  sys_prompt="You're a helpful assistant named Friday.",
293
276
  toolkit=toolkit,
294
- memory=AgentScopeSessionHistoryMemory(
295
- service=self.session_service,
296
- session_id=session_id,
297
- user_id=user_id,
298
- ),
277
+ memory=InMemoryMemory(),
299
278
  formatter=DashScopeChatFormatter(),
300
279
  )
301
280
  agent.set_console_output_enabled(enabled=False)
302
281
 
303
- if state:
304
- agent.load_state_dict(state)
282
+ await self.session.load_session_state(
283
+ session_id=session_id,
284
+ user_id=user_id,
285
+ agent=agent,
286
+ )
305
287
 
306
288
  async for msg, last in stream_printing_messages(
307
289
  agents=[agent],
@@ -309,12 +291,10 @@ async def query_func(
309
291
  ):
310
292
  yield msg, last
311
293
 
312
- state = agent.state_dict()
313
-
314
- await self.state_service.save_state(
315
- user_id=user_id,
294
+ await self.session.save_session_state(
316
295
  session_id=session_id,
317
- state=state,
296
+ user_id=user_id,
297
+ agent=agent,
318
298
  )
319
299
 
320
300
 
@@ -394,7 +374,7 @@ from agentscope_runtime.sandbox import BaseSandboxAsync
394
374
 
395
375
  async with BaseSandboxAsync() as box:
396
376
  # Default image is `agentscope/runtime-sandbox-base:latest`
397
- print(await box.list_tools()) # List all available tools
377
+ print(await box.list_tools_async()) # List all available tools
398
378
  print(await box.run_ipython_cell(code="print('hi')")) # Run Python code
399
379
  print(await box.run_shell_command(command="echo hello")) # Run shell command
400
380
  input("Press Enter to continue...")
@@ -423,7 +403,7 @@ from agentscope_runtime.sandbox import GuiSandboxAsync
423
403
 
424
404
  async with GuiSandboxAsync() as box:
425
405
  # Default image is `agentscope/runtime-sandbox-gui:latest`
426
- print(await box.list_tools()) # List all available tools
406
+ print(await box.list_tools_async()) # List all available tools
427
407
  print(box.desktop_url) # Web desktop access URL
428
408
  print(await box.computer_use(action="get_cursor_position")) # Get mouse cursor position
429
409
  print(await box.computer_use(action="get_screenshot")) # Capture screenshot
@@ -452,7 +432,7 @@ from agentscope_runtime.sandbox import BrowserSandboxAsync
452
432
 
453
433
  async with BrowserSandboxAsync() as box:
454
434
  # Default image is `agentscope/runtime-sandbox-browser:latest`
455
- print(await box.list_tools()) # List all available tools
435
+ print(await box.list_tools_async()) # List all available tools
456
436
  print(box.desktop_url) # Web desktop access URL
457
437
  await box.browser_navigate("https://www.google.com/") # Open a webpage
458
438
  input("Press Enter to continue...")
@@ -480,7 +460,7 @@ from agentscope_runtime.sandbox import FilesystemSandboxAsync
480
460
 
481
461
  async with FilesystemSandboxAsync() as box:
482
462
  # Default image is `agentscope/runtime-sandbox-filesystem:latest`
483
- print(await box.list_tools()) # List all available tools
463
+ print(await box.list_tools_async()) # List all available tools
484
464
  print(box.desktop_url) # Web desktop access URL
485
465
  await box.create_directory("test") # Create a directory
486
466
  input("Press Enter to continue...")
@@ -526,7 +506,7 @@ from agentscope_runtime.sandbox import MobileSandboxAsync
526
506
 
527
507
  async with MobileSandboxAsync() as box:
528
508
  # Default image is 'agentscope/runtime-sandbox-mobile:latest'
529
- print(await box.list_tools()) # List all available tools
509
+ print(await box.list_tools_async()) # List all available tools
530
510
  print(await box.mobile_get_screen_resolution()) # Get the screen resolution
531
511
  print(await box.mobile_tap([500, 1000])) # Tap at coordinate (500, 1000)
532
512
  print(await box.mobile_input_text("Hello from AgentScope!")) # Input text
@@ -649,7 +629,7 @@ After deployment, users can also access this service using the Response API of t
649
629
  ```python
650
630
  from openai import OpenAI
651
631
 
652
- client = OpenAI(base_url="http://0.0.0.0:8090/compatible-mode/v1")
632
+ client = OpenAI(base_url="http://localhost:8090/compatible-mode/v1")
653
633
 
654
634
  response = client.responses.create(
655
635
  model="any_name",
@@ -763,7 +743,7 @@ limitations under the License.
763
743
 
764
744
  ## ✨ Contributors
765
745
  <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
766
- [![All Contributors](https://img.shields.io/badge/all_contributors-32-orange.svg?style=flat-square)](#contributors-)
746
+ [![All Contributors](https://img.shields.io/badge/all_contributors-34-orange.svg?style=flat-square)](#contributors-)
767
747
  <!-- ALL-CONTRIBUTORS-BADGE:END -->
768
748
 
769
749
  Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/emoji-key/)):
@@ -814,6 +794,8 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/e
814
794
  <td align="center" valign="top" width="14.28%"><a href="https://allenli178.top"><img src="https://avatars.githubusercontent.com/u/53218750?v=4?s=100" width="100px;" alt="YuYan"/><br /><sub><b>YuYan</b></sub></a><br /><a href="https://github.com/agentscope-ai/agentscope-runtime/commits?author=allenli178" title="Documentation">📖</a></td>
815
795
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/rlp2006"><img src="https://avatars.githubusercontent.com/u/212365247?v=4?s=100" width="100px;" alt="Li Peng (Yuan Yi)"/><br /><sub><b>Li Peng (Yuan Yi)</b></sub></a><br /><a href="https://github.com/agentscope-ai/agentscope-runtime/commits?author=rlp2006" title="Code">💻</a> <a href="https://github.com/agentscope-ai/agentscope-runtime/commits?author=rlp2006" title="Documentation">📖</a> <a href="#example-rlp2006" title="Examples">💡</a></td>
816
796
  <td align="center" valign="top" width="14.28%"><a href="http://dorianzheng.github.io"><img src="https://avatars.githubusercontent.com/u/8065637?v=4?s=100" width="100px;" alt="dorianzheng"/><br /><sub><b>dorianzheng</b></sub></a><br /><a href="https://github.com/agentscope-ai/agentscope-runtime/pulls?q=is%3Apr+reviewed-by%3ADorianZheng" title="Reviewed Pull Requests">👀</a> <a href="#platform-DorianZheng" title="Packaging/porting to new platform">📦</a></td>
797
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/cainiao1992"><img src="https://avatars.githubusercontent.com/u/18435004?v=4?s=100" width="100px;" alt="Xiangfang Chen"/><br /><sub><b>Xiangfang Chen</b></sub></a><br /><a href="https://github.com/agentscope-ai/agentscope-runtime/commits?author=cainiao1992" title="Documentation">📖</a></td>
798
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/Eggiverse"><img src="https://avatars.githubusercontent.com/u/36877740?v=4?s=100" width="100px;" alt="Zhang Shitian"/><br /><sub><b>Zhang Shitian</b></sub></a><br /><a href="https://github.com/agentscope-ai/agentscope-runtime/issues?q=author%3AEggiverse" title="Bug reports">🐛</a> <a href="https://github.com/agentscope-ai/agentscope-runtime/commits?author=Eggiverse" title="Code">💻</a></td>
817
799
  </tr>
818
800
  </tbody>
819
801
  <tfoot>