agentscope-runtime 0.2.0b2__py3-none-any.whl → 1.0.0__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 (184) hide show
  1. agentscope_runtime/adapters/__init__.py +0 -0
  2. agentscope_runtime/adapters/agentscope/__init__.py +0 -0
  3. agentscope_runtime/adapters/agentscope/long_term_memory/__init__.py +6 -0
  4. agentscope_runtime/adapters/agentscope/long_term_memory/_long_term_memory_adapter.py +258 -0
  5. agentscope_runtime/adapters/agentscope/memory/__init__.py +6 -0
  6. agentscope_runtime/adapters/agentscope/memory/_memory_adapter.py +152 -0
  7. agentscope_runtime/adapters/agentscope/message.py +535 -0
  8. agentscope_runtime/adapters/agentscope/stream.py +506 -0
  9. agentscope_runtime/adapters/agentscope/tool/__init__.py +9 -0
  10. agentscope_runtime/adapters/agentscope/tool/sandbox_tool.py +69 -0
  11. agentscope_runtime/adapters/agentscope/tool/tool.py +233 -0
  12. agentscope_runtime/adapters/autogen/__init__.py +0 -0
  13. agentscope_runtime/adapters/autogen/tool/__init__.py +7 -0
  14. agentscope_runtime/adapters/autogen/tool/tool.py +211 -0
  15. agentscope_runtime/adapters/text/__init__.py +0 -0
  16. agentscope_runtime/adapters/text/stream.py +29 -0
  17. agentscope_runtime/common/collections/redis_mapping.py +4 -1
  18. agentscope_runtime/common/container_clients/fc_client.py +855 -0
  19. agentscope_runtime/common/utils/__init__.py +0 -0
  20. agentscope_runtime/common/utils/lazy_loader.py +57 -0
  21. agentscope_runtime/engine/__init__.py +25 -18
  22. agentscope_runtime/engine/app/agent_app.py +161 -91
  23. agentscope_runtime/engine/app/base_app.py +4 -118
  24. agentscope_runtime/engine/constant.py +8 -0
  25. agentscope_runtime/engine/deployers/__init__.py +8 -0
  26. agentscope_runtime/engine/deployers/adapter/__init__.py +2 -0
  27. agentscope_runtime/engine/deployers/adapter/a2a/a2a_adapter_utils.py +0 -21
  28. agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +28 -9
  29. agentscope_runtime/engine/deployers/adapter/responses/__init__.py +2 -0
  30. agentscope_runtime/engine/deployers/adapter/responses/response_api_adapter_utils.py +5 -2
  31. agentscope_runtime/engine/deployers/adapter/responses/response_api_protocol_adapter.py +1 -1
  32. agentscope_runtime/engine/deployers/agentrun_deployer.py +2541 -0
  33. agentscope_runtime/engine/deployers/cli_fc_deploy.py +1 -1
  34. agentscope_runtime/engine/deployers/kubernetes_deployer.py +9 -21
  35. agentscope_runtime/engine/deployers/local_deployer.py +47 -74
  36. agentscope_runtime/engine/deployers/modelstudio_deployer.py +216 -50
  37. agentscope_runtime/engine/deployers/utils/app_runner_utils.py +29 -0
  38. agentscope_runtime/engine/deployers/utils/detached_app.py +510 -0
  39. agentscope_runtime/engine/deployers/utils/docker_image_utils/__init__.py +1 -1
  40. agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +1 -1
  41. agentscope_runtime/engine/deployers/utils/docker_image_utils/{runner_image_factory.py → image_factory.py} +121 -61
  42. agentscope_runtime/engine/deployers/utils/package.py +693 -0
  43. agentscope_runtime/engine/deployers/utils/service_utils/__init__.py +0 -5
  44. agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +301 -282
  45. agentscope_runtime/engine/deployers/utils/service_utils/fastapi_templates.py +2 -4
  46. agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +23 -1
  47. agentscope_runtime/engine/deployers/utils/templates/app_main.py.j2 +84 -0
  48. agentscope_runtime/engine/deployers/utils/templates/runner_main.py.j2 +95 -0
  49. agentscope_runtime/engine/deployers/utils/{service_utils → templates}/standalone_main.py.j2 +0 -45
  50. agentscope_runtime/engine/deployers/utils/wheel_packager.py +119 -18
  51. agentscope_runtime/engine/helpers/runner.py +40 -0
  52. agentscope_runtime/engine/runner.py +171 -130
  53. agentscope_runtime/engine/schemas/agent_schemas.py +114 -3
  54. agentscope_runtime/engine/schemas/modelstudio_llm.py +4 -2
  55. agentscope_runtime/engine/schemas/oai_llm.py +23 -23
  56. agentscope_runtime/engine/schemas/response_api.py +65 -0
  57. agentscope_runtime/engine/schemas/session.py +24 -0
  58. agentscope_runtime/engine/services/__init__.py +0 -9
  59. agentscope_runtime/engine/services/agent_state/__init__.py +16 -0
  60. agentscope_runtime/engine/services/agent_state/redis_state_service.py +113 -0
  61. agentscope_runtime/engine/services/agent_state/state_service.py +179 -0
  62. agentscope_runtime/engine/services/memory/__init__.py +24 -0
  63. agentscope_runtime/engine/services/{mem0_memory_service.py → memory/mem0_memory_service.py} +17 -13
  64. agentscope_runtime/engine/services/{memory_service.py → memory/memory_service.py} +28 -7
  65. agentscope_runtime/engine/services/{redis_memory_service.py → memory/redis_memory_service.py} +1 -1
  66. agentscope_runtime/engine/services/{reme_personal_memory_service.py → memory/reme_personal_memory_service.py} +9 -6
  67. agentscope_runtime/engine/services/{reme_task_memory_service.py → memory/reme_task_memory_service.py} +2 -2
  68. agentscope_runtime/engine/services/{tablestore_memory_service.py → memory/tablestore_memory_service.py} +12 -18
  69. agentscope_runtime/engine/services/sandbox/__init__.py +13 -0
  70. agentscope_runtime/engine/services/{sandbox_service.py → sandbox/sandbox_service.py} +86 -71
  71. agentscope_runtime/engine/services/session_history/__init__.py +23 -0
  72. agentscope_runtime/engine/services/{redis_session_history_service.py → session_history/redis_session_history_service.py} +3 -2
  73. agentscope_runtime/engine/services/{session_history_service.py → session_history/session_history_service.py} +44 -34
  74. agentscope_runtime/engine/services/{tablestore_session_history_service.py → session_history/tablestore_session_history_service.py} +14 -19
  75. agentscope_runtime/engine/services/utils/tablestore_service_utils.py +2 -2
  76. agentscope_runtime/engine/tracing/base.py +10 -9
  77. agentscope_runtime/engine/tracing/message_util.py +1 -1
  78. agentscope_runtime/engine/tracing/tracing_util.py +7 -2
  79. agentscope_runtime/engine/tracing/wrapper.py +49 -31
  80. agentscope_runtime/sandbox/__init__.py +10 -2
  81. agentscope_runtime/sandbox/box/agentbay/__init__.py +4 -0
  82. agentscope_runtime/sandbox/box/agentbay/agentbay_sandbox.py +559 -0
  83. agentscope_runtime/sandbox/box/base/base_sandbox.py +12 -0
  84. agentscope_runtime/sandbox/box/browser/browser_sandbox.py +115 -11
  85. agentscope_runtime/sandbox/box/cloud/__init__.py +4 -0
  86. agentscope_runtime/sandbox/box/cloud/cloud_sandbox.py +254 -0
  87. agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +66 -0
  88. agentscope_runtime/sandbox/box/gui/gui_sandbox.py +42 -0
  89. agentscope_runtime/sandbox/box/mobile/__init__.py +4 -0
  90. agentscope_runtime/sandbox/box/mobile/box/__init__.py +0 -0
  91. agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +216 -0
  92. agentscope_runtime/sandbox/box/training_box/training_box.py +2 -2
  93. agentscope_runtime/sandbox/client/http_client.py +1 -0
  94. agentscope_runtime/sandbox/enums.py +2 -0
  95. agentscope_runtime/sandbox/manager/sandbox_manager.py +15 -2
  96. agentscope_runtime/sandbox/manager/server/app.py +12 -0
  97. agentscope_runtime/sandbox/manager/server/config.py +19 -0
  98. agentscope_runtime/sandbox/model/manager_config.py +79 -2
  99. agentscope_runtime/sandbox/utils.py +0 -18
  100. agentscope_runtime/tools/RAGs/__init__.py +0 -0
  101. agentscope_runtime/tools/RAGs/modelstudio_rag.py +377 -0
  102. agentscope_runtime/tools/RAGs/modelstudio_rag_lite.py +219 -0
  103. agentscope_runtime/tools/__init__.py +119 -0
  104. agentscope_runtime/tools/_constants.py +18 -0
  105. agentscope_runtime/tools/alipay/__init__.py +4 -0
  106. agentscope_runtime/tools/alipay/base.py +334 -0
  107. agentscope_runtime/tools/alipay/payment.py +835 -0
  108. agentscope_runtime/tools/alipay/subscribe.py +551 -0
  109. agentscope_runtime/tools/base.py +264 -0
  110. agentscope_runtime/tools/cli/__init__.py +0 -0
  111. agentscope_runtime/tools/cli/modelstudio_mcp_server.py +78 -0
  112. agentscope_runtime/tools/generations/__init__.py +75 -0
  113. agentscope_runtime/tools/generations/async_image_to_video.py +350 -0
  114. agentscope_runtime/tools/generations/async_image_to_video_wan25.py +366 -0
  115. agentscope_runtime/tools/generations/async_speech_to_video.py +422 -0
  116. agentscope_runtime/tools/generations/async_text_to_video.py +320 -0
  117. agentscope_runtime/tools/generations/async_text_to_video_wan25.py +334 -0
  118. agentscope_runtime/tools/generations/image_edit.py +208 -0
  119. agentscope_runtime/tools/generations/image_edit_wan25.py +193 -0
  120. agentscope_runtime/tools/generations/image_generation.py +202 -0
  121. agentscope_runtime/tools/generations/image_generation_wan25.py +201 -0
  122. agentscope_runtime/tools/generations/image_style_repaint.py +208 -0
  123. agentscope_runtime/tools/generations/image_to_video.py +233 -0
  124. agentscope_runtime/tools/generations/qwen_image_edit.py +205 -0
  125. agentscope_runtime/tools/generations/qwen_image_generation.py +214 -0
  126. agentscope_runtime/tools/generations/qwen_text_to_speech.py +154 -0
  127. agentscope_runtime/tools/generations/speech_to_text.py +260 -0
  128. agentscope_runtime/tools/generations/speech_to_video.py +314 -0
  129. agentscope_runtime/tools/generations/text_to_video.py +221 -0
  130. agentscope_runtime/tools/mcp_wrapper.py +215 -0
  131. agentscope_runtime/tools/realtime_clients/__init__.py +13 -0
  132. agentscope_runtime/tools/realtime_clients/asr_client.py +27 -0
  133. agentscope_runtime/tools/realtime_clients/azure_asr_client.py +195 -0
  134. agentscope_runtime/tools/realtime_clients/azure_tts_client.py +383 -0
  135. agentscope_runtime/tools/realtime_clients/modelstudio_asr_client.py +151 -0
  136. agentscope_runtime/tools/realtime_clients/modelstudio_tts_client.py +199 -0
  137. agentscope_runtime/tools/realtime_clients/realtime_tool.py +55 -0
  138. agentscope_runtime/tools/realtime_clients/tts_client.py +33 -0
  139. agentscope_runtime/tools/searches/__init__.py +3 -0
  140. agentscope_runtime/tools/searches/modelstudio_search.py +877 -0
  141. agentscope_runtime/tools/searches/modelstudio_search_lite.py +310 -0
  142. agentscope_runtime/tools/utils/__init__.py +0 -0
  143. agentscope_runtime/tools/utils/api_key_util.py +45 -0
  144. agentscope_runtime/tools/utils/crypto_utils.py +99 -0
  145. agentscope_runtime/tools/utils/mcp_util.py +35 -0
  146. agentscope_runtime/version.py +1 -1
  147. {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0.dist-info}/METADATA +240 -168
  148. agentscope_runtime-1.0.0.dist-info/RECORD +240 -0
  149. {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0.dist-info}/entry_points.txt +1 -0
  150. agentscope_runtime/engine/agents/__init__.py +0 -2
  151. agentscope_runtime/engine/agents/agentscope_agent.py +0 -488
  152. agentscope_runtime/engine/agents/agno_agent.py +0 -220
  153. agentscope_runtime/engine/agents/autogen_agent.py +0 -250
  154. agentscope_runtime/engine/agents/base_agent.py +0 -29
  155. agentscope_runtime/engine/agents/langgraph_agent.py +0 -59
  156. agentscope_runtime/engine/agents/utils.py +0 -53
  157. agentscope_runtime/engine/deployers/utils/package_project_utils.py +0 -1163
  158. agentscope_runtime/engine/deployers/utils/service_utils/service_config.py +0 -75
  159. agentscope_runtime/engine/deployers/utils/service_utils/service_factory.py +0 -220
  160. agentscope_runtime/engine/helpers/helper.py +0 -179
  161. agentscope_runtime/engine/schemas/context.py +0 -54
  162. agentscope_runtime/engine/services/context_manager.py +0 -164
  163. agentscope_runtime/engine/services/environment_manager.py +0 -50
  164. agentscope_runtime/engine/services/manager.py +0 -174
  165. agentscope_runtime/engine/services/rag_service.py +0 -195
  166. agentscope_runtime/engine/services/tablestore_rag_service.py +0 -143
  167. agentscope_runtime/sandbox/tools/__init__.py +0 -12
  168. agentscope_runtime/sandbox/tools/base/__init__.py +0 -8
  169. agentscope_runtime/sandbox/tools/base/tool.py +0 -52
  170. agentscope_runtime/sandbox/tools/browser/__init__.py +0 -57
  171. agentscope_runtime/sandbox/tools/browser/tool.py +0 -597
  172. agentscope_runtime/sandbox/tools/filesystem/__init__.py +0 -32
  173. agentscope_runtime/sandbox/tools/filesystem/tool.py +0 -319
  174. agentscope_runtime/sandbox/tools/function_tool.py +0 -321
  175. agentscope_runtime/sandbox/tools/gui/__init__.py +0 -7
  176. agentscope_runtime/sandbox/tools/gui/tool.py +0 -77
  177. agentscope_runtime/sandbox/tools/mcp_tool.py +0 -195
  178. agentscope_runtime/sandbox/tools/sandbox_tool.py +0 -104
  179. agentscope_runtime/sandbox/tools/tool.py +0 -238
  180. agentscope_runtime/sandbox/tools/utils.py +0 -68
  181. agentscope_runtime-0.2.0b2.dist-info/RECORD +0 -183
  182. {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0.dist-info}/WHEEL +0 -0
  183. {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0.dist-info}/licenses/LICENSE +0 -0
  184. {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,65 @@
1
+ # -*- coding: utf-8 -*-
2
+ from typing import Dict, Literal, TypeAlias
3
+ from pydantic import ConfigDict
4
+ from pydantic.main import BaseModel
5
+ from openai.types.shared import Reasoning
6
+
7
+ from openai.types.responses import (
8
+ ResponseFunctionToolCall,
9
+ ResponseInputItemParam,
10
+ ResponsePrompt,
11
+ ResponseReasoningItem,
12
+ )
13
+ from openai.types.responses.response_input_param import Message
14
+ from openai.types.responses.response import ToolChoice
15
+
16
+ # Backward compatibility for OpenAI client versions
17
+ try: # For older openai versions (< 1.100.0)
18
+ from openai.types.responses import ResponseTextConfig
19
+ except ImportError: # For newer openai versions (>= 1.100.0)
20
+ from openai.types.responses import (
21
+ ResponseFormatTextConfig as ResponseTextConfig,
22
+ )
23
+
24
+
25
+ class OpenAIBaseModel(BaseModel):
26
+ # OpenAI API does allow extra fields
27
+ model_config = ConfigDict(extra="allow")
28
+
29
+
30
+ ResponseInputOutputItem: TypeAlias = (
31
+ ResponseInputItemParam | ResponseReasoningItem | ResponseFunctionToolCall
32
+ )
33
+
34
+
35
+ class ResponseAPI(OpenAIBaseModel):
36
+ # Ordered by official OpenAI API documentation
37
+ # https://platform.openai.com/docs/api-reference/responses/create
38
+ background: bool | None = False
39
+ include: list[str] | None = None
40
+ input: str | list[Message]
41
+ instructions: str | None = None
42
+ max_output_tokens: int | None = None
43
+ max_tool_calls: int | None = None
44
+ metadata: Dict[str, str] | None = None
45
+ model: str | None = None
46
+ parallel_tool_calls: bool | None = True
47
+ previous_response_id: str | None = None
48
+ prompt: ResponsePrompt | None = None
49
+ reasoning: Reasoning | None = None
50
+ service_tier: Literal[
51
+ "auto",
52
+ "default",
53
+ "flex",
54
+ "scale",
55
+ "priority",
56
+ ] = "auto"
57
+ store: bool | None = True
58
+ stream: bool | None = False
59
+ temperature: float | None = None
60
+ text: ResponseTextConfig | None = None
61
+ tool_choice: ToolChoice = "auto"
62
+ top_logprobs: int | None = 0
63
+ top_p: float | None = None
64
+ truncation: Literal["auto", "disabled"] | None = "disabled"
65
+ user: str | None = None
@@ -0,0 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+ from typing import List, Union, Dict, Any
3
+
4
+ from pydantic import BaseModel
5
+
6
+ from .agent_schemas import Message
7
+
8
+
9
+ class Session(BaseModel):
10
+ """Represents a single conversation session.
11
+
12
+ A session contains the history of a conversation, including all
13
+ messages, and is uniquely identified by its ID.
14
+
15
+ Attributes:
16
+ id: The unique identifier for the session.
17
+ user_id: The identifier of the user who owns the session.
18
+ messages: A list of messages formatted for Agent response
19
+
20
+ """
21
+
22
+ id: str
23
+ user_id: str
24
+ messages: List[Union[Message, Dict[str, Any]]] = []
@@ -1,9 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- from .base import (
3
- Service,
4
- ServiceWithLifecycleManager,
5
- ServiceLifecycleManagerMixin,
6
- )
7
- from .sandbox_service import SandboxService
8
- from .memory_service import MemoryService
9
- from .session_history_service import SessionHistoryService
@@ -0,0 +1,16 @@
1
+ # -*- coding: utf-8 -*-
2
+ from typing import TYPE_CHECKING
3
+ from ....common.utils.lazy_loader import install_lazy_loader
4
+
5
+ if TYPE_CHECKING:
6
+ from .state_service import StateService, InMemoryStateService
7
+ from .redis_state_service import RedisStateService
8
+
9
+ install_lazy_loader(
10
+ globals(),
11
+ {
12
+ "StateService": ".state_service",
13
+ "InMemoryStateService": ".state_service",
14
+ "RedisStateService": ".redis_state_service",
15
+ },
16
+ )
@@ -0,0 +1,113 @@
1
+ # -*- coding: utf-8 -*-
2
+ import json
3
+ from typing import Optional, Dict, Any
4
+
5
+ import redis.asyncio as aioredis
6
+
7
+ from .state_service import StateService
8
+
9
+
10
+ class RedisStateService(StateService):
11
+ """
12
+ Redis-based implementation of StateService.
13
+
14
+ Stores agent states in Redis using a hash per (user_id, session_id),
15
+ with round_id as the hash field and serialized state as the value.
16
+ """
17
+
18
+ _DEFAULT_SESSION_ID = "default"
19
+
20
+ def __init__(
21
+ self,
22
+ redis_url: str = "redis://localhost:6379/0",
23
+ redis_client: Optional[aioredis.Redis] = None,
24
+ ):
25
+ self._redis_url = redis_url
26
+ self._redis = redis_client
27
+ self._health = False
28
+
29
+ async def start(self) -> None:
30
+ """Initialize the Redis connection."""
31
+ if self._redis is None:
32
+ self._redis = aioredis.from_url(
33
+ self._redis_url,
34
+ decode_responses=True,
35
+ )
36
+ self._health = True
37
+
38
+ async def stop(self) -> None:
39
+ """Close the Redis connection."""
40
+ if self._redis:
41
+ await self._redis.close()
42
+ self._redis = None
43
+ self._health = False
44
+
45
+ async def health(self) -> bool:
46
+ """Service health check."""
47
+ if not self._redis:
48
+ return False
49
+ try:
50
+ pong = await self._redis.ping()
51
+ return pong is True or pong == "PONG"
52
+ except Exception:
53
+ return False
54
+
55
+ def _session_key(self, user_id: str, session_id: str) -> str:
56
+ """Generate the Redis key for a user's session."""
57
+ return f"user_state:{user_id}:{session_id}"
58
+
59
+ async def save_state(
60
+ self,
61
+ user_id: str,
62
+ state: Dict[str, Any],
63
+ session_id: Optional[str] = None,
64
+ round_id: Optional[int] = None,
65
+ ) -> int:
66
+ if not self._redis:
67
+ raise RuntimeError("Redis connection is not available")
68
+
69
+ sid = session_id or self._DEFAULT_SESSION_ID
70
+ key = self._session_key(user_id, sid)
71
+
72
+ existing_fields = await self._redis.hkeys(key)
73
+ existing_rounds = sorted(
74
+ int(f) for f in existing_fields if f.isdigit()
75
+ )
76
+
77
+ if round_id is None:
78
+ if existing_rounds:
79
+ round_id = max(existing_rounds) + 1
80
+ else:
81
+ round_id = 1
82
+
83
+ await self._redis.hset(key, round_id, json.dumps(state))
84
+ return round_id
85
+
86
+ async def export_state(
87
+ self,
88
+ user_id: str,
89
+ session_id: Optional[str] = None,
90
+ round_id: Optional[int] = None,
91
+ ) -> Optional[Dict[str, Any]]:
92
+ if not self._redis:
93
+ raise RuntimeError("Redis connection is not available")
94
+
95
+ sid = session_id or self._DEFAULT_SESSION_ID
96
+ key = self._session_key(user_id, sid)
97
+
98
+ existing_fields = await self._redis.hkeys(key)
99
+ if not existing_fields:
100
+ return None
101
+
102
+ if round_id is None:
103
+ numeric_fields = [int(f) for f in existing_fields if f.isdigit()]
104
+ if not numeric_fields:
105
+ return None
106
+ latest_round_id = max(numeric_fields)
107
+ state_json = await self._redis.hget(key, latest_round_id)
108
+ else:
109
+ state_json = await self._redis.hget(key, round_id)
110
+
111
+ if state_json is None:
112
+ return None
113
+ return json.loads(state_json)
@@ -0,0 +1,179 @@
1
+ # -*- coding: utf-8 -*-
2
+ import copy
3
+
4
+ from abc import abstractmethod
5
+ from typing import Dict, Any, Optional
6
+
7
+ from ..base import ServiceWithLifecycleManager
8
+
9
+
10
+ class StateService(ServiceWithLifecycleManager):
11
+ """
12
+ Abstract base class for agent state management services.
13
+
14
+ Stores and manages agent states organized by user_id, session_id,
15
+ and round_id. Supports saving, retrieving, listing, and deleting states.
16
+ """
17
+
18
+ async def start(self) -> None:
19
+ pass
20
+
21
+ async def stop(self) -> None:
22
+ pass
23
+
24
+ @abstractmethod
25
+ async def save_state(
26
+ self,
27
+ user_id: str,
28
+ state: Dict[str, Any],
29
+ session_id: Optional[str] = None,
30
+ round_id: Optional[int] = None,
31
+ ) -> int:
32
+ """
33
+ Save serialized state data for a specific user/session.
34
+
35
+ If round_id is provided, store the state in that round.
36
+ If round_id is None, append as a new round with automatically
37
+ assigned round_id.
38
+
39
+ Args:
40
+ user_id: The unique ID of the user.
41
+ state: A dictionary representing serialized agent state.
42
+ session_id: Optional session/conversation ID. Defaults to
43
+ "default".
44
+ round_id: Optional conversation round number.
45
+
46
+ Returns:
47
+ The round_id in which the state was saved.
48
+ """
49
+
50
+ @abstractmethod
51
+ async def export_state(
52
+ self,
53
+ user_id: str,
54
+ session_id: Optional[str] = None,
55
+ round_id: Optional[int] = None,
56
+ ) -> Optional[Dict[str, Any]]:
57
+ """
58
+ Retrieve serialized state data for a user/session.
59
+
60
+ If round_id is provided, return that round's state.
61
+ If round_id is None, return the latest round's state.
62
+
63
+ Args:
64
+ user_id: The unique ID of the user.
65
+ session_id: Optional session/conversation ID.
66
+ round_id: Optional round number.
67
+
68
+ Returns:
69
+ A dictionary representing the agent state, or None if not found.
70
+ """
71
+
72
+
73
+ class InMemoryStateService(StateService):
74
+ """
75
+ In-memory implementation of StateService using dictionaries
76
+ for sparse round storage.
77
+
78
+ - Multiple users, sessions, and non-contiguous round IDs are supported.
79
+ - If round_id is None when saving, a new round is appended automatically.
80
+ - If round_id is None when exporting, the latest round is returned.
81
+ """
82
+
83
+ _DEFAULT_SESSION_ID = "default"
84
+
85
+ def __init__(self) -> None:
86
+ # Structure:
87
+ # { user_id: { session_id: { round_id: state_dict } } }
88
+ self._store: Optional[
89
+ Dict[str, Dict[str, Dict[int, Dict[str, Any]]]]
90
+ ] = None
91
+ self._health = False
92
+
93
+ async def start(self) -> None:
94
+ """Initialize the in-memory store."""
95
+ if self._store is None:
96
+ self._store = {}
97
+ self._health = True
98
+
99
+ async def stop(self) -> None:
100
+ """Clear all in-memory state data."""
101
+ if self._store is not None:
102
+ self._store.clear()
103
+ self._store = None
104
+ self._health = False
105
+
106
+ async def health(self) -> bool:
107
+ """Service health check."""
108
+ return self._health
109
+
110
+ async def save_state(
111
+ self,
112
+ user_id: str,
113
+ state: Dict[str, Any],
114
+ session_id: Optional[str] = None,
115
+ round_id: Optional[int] = None,
116
+ ) -> int:
117
+ """
118
+ Save serialized state in sparse dict storage.
119
+
120
+ If round_id is None, a new round_id will be assigned
121
+ as (max existing round_id + 1) or 1 if none exist.
122
+ Otherwise, the given round_id will be overwritten.
123
+
124
+ Returns:
125
+ The round_id where the state was saved.
126
+ """
127
+ if self._store is None:
128
+ raise RuntimeError("Service not started")
129
+
130
+ sid = session_id or self._DEFAULT_SESSION_ID
131
+
132
+ self._store.setdefault(user_id, {})
133
+ self._store[user_id].setdefault(sid, {})
134
+
135
+ rounds_dict = self._store[user_id][sid]
136
+
137
+ # Auto-generate round_id if not provided
138
+ if round_id is None:
139
+ if rounds_dict:
140
+ round_id = max(rounds_dict.keys()) + 1
141
+ else:
142
+ round_id = 1
143
+
144
+ # Store a deep copy so caller modifications don't affect saved state
145
+ rounds_dict[round_id] = copy.deepcopy(state)
146
+
147
+ return round_id
148
+
149
+ async def export_state(
150
+ self,
151
+ user_id: str,
152
+ session_id: Optional[str] = None,
153
+ round_id: Optional[int] = None,
154
+ ) -> Optional[Dict[str, Any]]:
155
+ """
156
+ Retrieve state data for given user/session/round.
157
+
158
+ If round_id is None: return the latest round.
159
+ If round_id is provided: return that round's state.
160
+
161
+ Returns:
162
+ Dictionary representing the agent state, or None if not found.
163
+ """
164
+ if self._store is None:
165
+ raise RuntimeError("Service not started")
166
+
167
+ sid = session_id or self._DEFAULT_SESSION_ID
168
+ sessions = self._store.get(user_id, {})
169
+ rounds_dict = sessions.get(sid, {})
170
+
171
+ if not rounds_dict:
172
+ return None
173
+
174
+ if round_id is None:
175
+ # Get the latest round_id
176
+ latest_round_id = max(rounds_dict.keys())
177
+ return rounds_dict[latest_round_id]
178
+
179
+ return rounds_dict.get(round_id)
@@ -0,0 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+ from typing import TYPE_CHECKING
3
+ from ....common.utils.lazy_loader import install_lazy_loader
4
+
5
+ if TYPE_CHECKING:
6
+ from .memory_service import MemoryService, InMemoryMemoryService
7
+ from .redis_memory_service import RedisMemoryService
8
+ from .reme_task_memory_service import ReMeTaskMemoryService
9
+ from .reme_personal_memory_service import ReMePersonalMemoryService
10
+ from .mem0_memory_service import Mem0MemoryService
11
+ from .tablestore_memory_service import TablestoreMemoryService
12
+
13
+ install_lazy_loader(
14
+ globals(),
15
+ {
16
+ "MemoryService": ".memory_service",
17
+ "InMemoryMemoryService": ".memory_service",
18
+ "RedisMemoryService": ".redis_memory_service",
19
+ "ReMeTaskMemoryService": ".reme_task_memory_service",
20
+ "ReMePersonalMemoryService": ".reme_personal_memory_service",
21
+ "Mem0MemoryService": ".mem0_memory_service",
22
+ "TablestoreMemoryService": ".tablestore_memory_service",
23
+ },
24
+ )
@@ -1,8 +1,11 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  import os
3
3
  from typing import Optional, Dict, Any, List
4
+
5
+ from mem0 import AsyncMemoryClient
6
+
4
7
  from .memory_service import MemoryService
5
- from ..schemas.agent_schemas import Message, MessageType, ContentType
8
+ from ...schemas.agent_schemas import Message, MessageType, ContentType
6
9
 
7
10
 
8
11
  class Mem0MemoryService(MemoryService):
@@ -14,15 +17,8 @@ class Mem0MemoryService(MemoryService):
14
17
 
15
18
  def __init__(self, **kwargs):
16
19
  super().__init__(**kwargs)
17
- from mem0 import AsyncMemoryClient
18
-
19
- mem0_api_key = os.getenv("MEM0_API_KEY")
20
- if mem0_api_key is None:
21
- raise ValueError("MEM0_API_KEY is not set")
22
- mem0_api_key = os.getenv("MEM0_API_KEY")
23
-
24
- # get the mem0 client instance
25
- self.service = AsyncMemoryClient(api_key=mem0_api_key)
20
+ self.service = None
21
+ self._health = False
26
22
 
27
23
  @staticmethod
28
24
  async def get_query_text(message: Message) -> str:
@@ -63,13 +59,21 @@ class Mem0MemoryService(MemoryService):
63
59
  return [self.transform_message(message) for message in messages]
64
60
 
65
61
  async def start(self):
66
- pass
62
+ mem0_api_key = os.getenv("MEM0_API_KEY")
63
+ if mem0_api_key is None:
64
+ raise ValueError("MEM0_API_KEY is not set")
65
+ mem0_api_key = os.getenv("MEM0_API_KEY")
66
+
67
+ # get the mem0 client instance
68
+ self.service = AsyncMemoryClient(api_key=mem0_api_key)
69
+ self._health = True
67
70
 
68
71
  async def stop(self):
69
- pass
72
+ self.service = None
73
+ self._health = False
70
74
 
71
75
  async def health(self):
72
- pass
76
+ return self._health
73
77
 
74
78
  async def add_memory(
75
79
  self,
@@ -5,8 +5,8 @@ from typing import Optional, Dict, Any
5
5
 
6
6
  from pydantic import Field
7
7
 
8
- from .base import ServiceWithLifecycleManager
9
- from ..schemas.agent_schemas import MessageType, Message
8
+ from ..base import ServiceWithLifecycleManager
9
+ from ...schemas.agent_schemas import MessageType, Message
10
10
 
11
11
 
12
12
  class MemoryService(ServiceWithLifecycleManager):
@@ -99,20 +99,29 @@ class InMemoryMemoryService(MemoryService):
99
99
  An in-memory implementation of the memory service.
100
100
  """
101
101
 
102
- _store: Dict[str, Dict[str, list]] = {}
103
102
  _DEFAULT_SESSION_ID = "default"
104
103
 
104
+ def __init__(self) -> None:
105
+ """Initializes the InMemorySessionHistoryService."""
106
+ self._store: Optional[Dict[str, Dict[str, list]]] = None
107
+ self._health = False
108
+
105
109
  async def start(self) -> None:
106
- """Starts the service."""
107
- self._store = {}
110
+ """Initialize the in-memory store."""
111
+ if self._store is None:
112
+ self._store = {}
113
+ self._health = True
108
114
 
109
115
  async def stop(self) -> None:
110
116
  """Stops the service."""
111
- self._store = {}
117
+ if self._store is not None:
118
+ self._store.clear()
119
+ self._store = None
120
+ self._health = False
112
121
 
113
122
  async def health(self) -> bool:
114
123
  """Checks the health of the service."""
115
- return True
124
+ return self._health
116
125
 
117
126
  async def add_memory(
118
127
  self,
@@ -129,6 +138,9 @@ class InMemoryMemoryService(MemoryService):
129
138
  session_id: An optional session identifier. If not provided,
130
139
  a default session is used.
131
140
  """
141
+ if self._store is None:
142
+ raise RuntimeError("Service not started")
143
+
132
144
  if user_id not in self._store:
133
145
  self._store[user_id] = {}
134
146
 
@@ -160,6 +172,9 @@ class InMemoryMemoryService(MemoryService):
160
172
  Returns:
161
173
  A list of matching messages from the store.
162
174
  """
175
+ if self._store is None:
176
+ raise RuntimeError("Service not started")
177
+
163
178
  if user_id not in self._store:
164
179
  return []
165
180
 
@@ -231,6 +246,9 @@ class InMemoryMemoryService(MemoryService):
231
246
  Returns:
232
247
  A paginated list of messages.
233
248
  """
249
+ if self._store is None:
250
+ raise RuntimeError("Service not started")
251
+
234
252
  if user_id not in self._store:
235
253
  return []
236
254
 
@@ -260,6 +278,9 @@ class InMemoryMemoryService(MemoryService):
260
278
  session_id: If provided, only deletes the messages for that
261
279
  session. Otherwise, deletes all messages for the user.
262
280
  """
281
+ if self._store is None:
282
+ raise RuntimeError("Service not started")
283
+
263
284
  if user_id not in self._store:
264
285
  return
265
286
 
@@ -5,7 +5,7 @@ import redis.asyncio as aioredis
5
5
 
6
6
 
7
7
  from .memory_service import MemoryService
8
- from ..schemas.agent_schemas import Message, MessageType
8
+ from ...schemas.agent_schemas import Message, MessageType
9
9
 
10
10
 
11
11
  class RedisMemoryService(MemoryService):
@@ -2,8 +2,12 @@
2
2
  import os
3
3
  from typing import Optional, Dict, Any, List
4
4
 
5
+ from reme_ai.service.personal_memory_service import (
6
+ PersonalMemoryService,
7
+ )
8
+
5
9
  from .memory_service import MemoryService
6
- from ..schemas.agent_schemas import Message
10
+ from ...schemas.agent_schemas import Message
7
11
 
8
12
 
9
13
  class ReMePersonalMemoryService(MemoryService):
@@ -26,10 +30,6 @@ class ReMePersonalMemoryService(MemoryService):
26
30
  if os.getenv(key) is None:
27
31
  raise ValueError(f"{key} is not set")
28
32
 
29
- from reme_ai.service.personal_memory_service import (
30
- PersonalMemoryService,
31
- )
32
-
33
33
  self.service = PersonalMemoryService()
34
34
 
35
35
  @staticmethod
@@ -65,7 +65,10 @@ class ReMePersonalMemoryService(MemoryService):
65
65
  return await self.service.stop()
66
66
 
67
67
  async def health(self) -> bool:
68
- return await self.service.health()
68
+ try:
69
+ return await self.service.health()
70
+ except Exception:
71
+ return False
69
72
 
70
73
  async def add_memory(
71
74
  self,
@@ -1,4 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
+ from reme_ai.service.task_memory_service import TaskMemoryService
3
+
2
4
  from .reme_personal_memory_service import ReMePersonalMemoryService
3
5
 
4
6
 
@@ -6,6 +8,4 @@ class ReMeTaskMemoryService(ReMePersonalMemoryService):
6
8
  def __init__(self, **kwargs):
7
9
  super().__init__(**kwargs)
8
10
 
9
- from reme_ai.service.task_memory_service import TaskMemoryService
10
-
11
11
  self.service = TaskMemoryService()
@@ -5,25 +5,19 @@ import copy
5
5
  from enum import Enum
6
6
  from typing import Any, Dict, List, Optional
7
7
 
8
- try:
9
- import tablestore
10
- from langchain_community.embeddings import DashScopeEmbeddings
11
- from langchain_core.embeddings import Embeddings
12
- from tablestore import AsyncOTSClient as AsyncTablestoreClient
13
- from tablestore import VectorMetricType
14
- from tablestore_for_agent_memory.base.filter import Filters
15
- from tablestore_for_agent_memory.knowledge.async_knowledge_store import (
16
- AsyncKnowledgeStore,
17
- )
18
- except ImportError as e:
19
- raise ImportError(
20
- "aliyun_tablestore is not available. "
21
- "Please run pip install agentscope-runtime[aliyun_tablestore_ext]",
22
- ) from e
23
-
24
- from ..schemas.agent_schemas import Message, MessageType
8
+ import tablestore
9
+ from langchain_community.embeddings import DashScopeEmbeddings
10
+ from langchain_core.embeddings import Embeddings
11
+ from tablestore import AsyncOTSClient as AsyncTablestoreClient
12
+ from tablestore import VectorMetricType
13
+ from tablestore_for_agent_memory.base.filter import Filters
14
+ from tablestore_for_agent_memory.knowledge.async_knowledge_store import (
15
+ AsyncKnowledgeStore,
16
+ )
17
+
18
+ from ...schemas.agent_schemas import Message, MessageType
25
19
  from .memory_service import MemoryService
26
- from .utils.tablestore_service_utils import (
20
+ from ..utils.tablestore_service_utils import (
27
21
  convert_messages_to_tablestore_documents,
28
22
  convert_tablestore_document_to_message,
29
23
  get_message_metadata_names,
@@ -0,0 +1,13 @@
1
+ # -*- coding: utf-8 -*-
2
+ from typing import TYPE_CHECKING
3
+ from ....common.utils.lazy_loader import install_lazy_loader
4
+
5
+ if TYPE_CHECKING:
6
+ from .sandbox_service import SandboxService
7
+
8
+ install_lazy_loader(
9
+ globals(),
10
+ {
11
+ "SandboxService": ".sandbox_service",
12
+ },
13
+ )