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.
- agentscope_runtime/adapters/__init__.py +0 -0
- agentscope_runtime/adapters/agentscope/__init__.py +0 -0
- agentscope_runtime/adapters/agentscope/long_term_memory/__init__.py +6 -0
- agentscope_runtime/adapters/agentscope/long_term_memory/_long_term_memory_adapter.py +258 -0
- agentscope_runtime/adapters/agentscope/memory/__init__.py +6 -0
- agentscope_runtime/adapters/agentscope/memory/_memory_adapter.py +152 -0
- agentscope_runtime/adapters/agentscope/message.py +535 -0
- agentscope_runtime/adapters/agentscope/stream.py +506 -0
- agentscope_runtime/adapters/agentscope/tool/__init__.py +9 -0
- agentscope_runtime/adapters/agentscope/tool/sandbox_tool.py +69 -0
- agentscope_runtime/adapters/agentscope/tool/tool.py +233 -0
- agentscope_runtime/adapters/autogen/__init__.py +0 -0
- agentscope_runtime/adapters/autogen/tool/__init__.py +7 -0
- agentscope_runtime/adapters/autogen/tool/tool.py +211 -0
- agentscope_runtime/adapters/text/__init__.py +0 -0
- agentscope_runtime/adapters/text/stream.py +29 -0
- agentscope_runtime/common/collections/redis_mapping.py +4 -1
- agentscope_runtime/common/container_clients/fc_client.py +855 -0
- agentscope_runtime/common/utils/__init__.py +0 -0
- agentscope_runtime/common/utils/lazy_loader.py +57 -0
- agentscope_runtime/engine/__init__.py +25 -18
- agentscope_runtime/engine/app/agent_app.py +161 -91
- agentscope_runtime/engine/app/base_app.py +4 -118
- agentscope_runtime/engine/constant.py +8 -0
- agentscope_runtime/engine/deployers/__init__.py +8 -0
- agentscope_runtime/engine/deployers/adapter/__init__.py +2 -0
- agentscope_runtime/engine/deployers/adapter/a2a/a2a_adapter_utils.py +0 -21
- agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +28 -9
- agentscope_runtime/engine/deployers/adapter/responses/__init__.py +2 -0
- agentscope_runtime/engine/deployers/adapter/responses/response_api_adapter_utils.py +5 -2
- agentscope_runtime/engine/deployers/adapter/responses/response_api_protocol_adapter.py +1 -1
- agentscope_runtime/engine/deployers/agentrun_deployer.py +2541 -0
- agentscope_runtime/engine/deployers/cli_fc_deploy.py +1 -1
- agentscope_runtime/engine/deployers/kubernetes_deployer.py +9 -21
- agentscope_runtime/engine/deployers/local_deployer.py +47 -74
- agentscope_runtime/engine/deployers/modelstudio_deployer.py +216 -50
- agentscope_runtime/engine/deployers/utils/app_runner_utils.py +29 -0
- agentscope_runtime/engine/deployers/utils/detached_app.py +510 -0
- agentscope_runtime/engine/deployers/utils/docker_image_utils/__init__.py +1 -1
- agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +1 -1
- agentscope_runtime/engine/deployers/utils/docker_image_utils/{runner_image_factory.py → image_factory.py} +121 -61
- agentscope_runtime/engine/deployers/utils/package.py +693 -0
- agentscope_runtime/engine/deployers/utils/service_utils/__init__.py +0 -5
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +301 -282
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_templates.py +2 -4
- agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +23 -1
- agentscope_runtime/engine/deployers/utils/templates/app_main.py.j2 +84 -0
- agentscope_runtime/engine/deployers/utils/templates/runner_main.py.j2 +95 -0
- agentscope_runtime/engine/deployers/utils/{service_utils → templates}/standalone_main.py.j2 +0 -45
- agentscope_runtime/engine/deployers/utils/wheel_packager.py +119 -18
- agentscope_runtime/engine/helpers/runner.py +40 -0
- agentscope_runtime/engine/runner.py +171 -130
- agentscope_runtime/engine/schemas/agent_schemas.py +114 -3
- agentscope_runtime/engine/schemas/modelstudio_llm.py +4 -2
- agentscope_runtime/engine/schemas/oai_llm.py +23 -23
- agentscope_runtime/engine/schemas/response_api.py +65 -0
- agentscope_runtime/engine/schemas/session.py +24 -0
- agentscope_runtime/engine/services/__init__.py +0 -9
- agentscope_runtime/engine/services/agent_state/__init__.py +16 -0
- agentscope_runtime/engine/services/agent_state/redis_state_service.py +113 -0
- agentscope_runtime/engine/services/agent_state/state_service.py +179 -0
- agentscope_runtime/engine/services/memory/__init__.py +24 -0
- agentscope_runtime/engine/services/{mem0_memory_service.py → memory/mem0_memory_service.py} +17 -13
- agentscope_runtime/engine/services/{memory_service.py → memory/memory_service.py} +28 -7
- agentscope_runtime/engine/services/{redis_memory_service.py → memory/redis_memory_service.py} +1 -1
- agentscope_runtime/engine/services/{reme_personal_memory_service.py → memory/reme_personal_memory_service.py} +9 -6
- agentscope_runtime/engine/services/{reme_task_memory_service.py → memory/reme_task_memory_service.py} +2 -2
- agentscope_runtime/engine/services/{tablestore_memory_service.py → memory/tablestore_memory_service.py} +12 -18
- agentscope_runtime/engine/services/sandbox/__init__.py +13 -0
- agentscope_runtime/engine/services/{sandbox_service.py → sandbox/sandbox_service.py} +86 -71
- agentscope_runtime/engine/services/session_history/__init__.py +23 -0
- agentscope_runtime/engine/services/{redis_session_history_service.py → session_history/redis_session_history_service.py} +3 -2
- agentscope_runtime/engine/services/{session_history_service.py → session_history/session_history_service.py} +44 -34
- agentscope_runtime/engine/services/{tablestore_session_history_service.py → session_history/tablestore_session_history_service.py} +14 -19
- agentscope_runtime/engine/services/utils/tablestore_service_utils.py +2 -2
- agentscope_runtime/engine/tracing/base.py +10 -9
- agentscope_runtime/engine/tracing/message_util.py +1 -1
- agentscope_runtime/engine/tracing/tracing_util.py +7 -2
- agentscope_runtime/engine/tracing/wrapper.py +49 -31
- agentscope_runtime/sandbox/__init__.py +10 -2
- agentscope_runtime/sandbox/box/agentbay/__init__.py +4 -0
- agentscope_runtime/sandbox/box/agentbay/agentbay_sandbox.py +559 -0
- agentscope_runtime/sandbox/box/base/base_sandbox.py +12 -0
- agentscope_runtime/sandbox/box/browser/browser_sandbox.py +115 -11
- agentscope_runtime/sandbox/box/cloud/__init__.py +4 -0
- agentscope_runtime/sandbox/box/cloud/cloud_sandbox.py +254 -0
- agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +66 -0
- agentscope_runtime/sandbox/box/gui/gui_sandbox.py +42 -0
- agentscope_runtime/sandbox/box/mobile/__init__.py +4 -0
- agentscope_runtime/sandbox/box/mobile/box/__init__.py +0 -0
- agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +216 -0
- agentscope_runtime/sandbox/box/training_box/training_box.py +2 -2
- agentscope_runtime/sandbox/client/http_client.py +1 -0
- agentscope_runtime/sandbox/enums.py +2 -0
- agentscope_runtime/sandbox/manager/sandbox_manager.py +15 -2
- agentscope_runtime/sandbox/manager/server/app.py +12 -0
- agentscope_runtime/sandbox/manager/server/config.py +19 -0
- agentscope_runtime/sandbox/model/manager_config.py +79 -2
- agentscope_runtime/sandbox/utils.py +0 -18
- agentscope_runtime/tools/RAGs/__init__.py +0 -0
- agentscope_runtime/tools/RAGs/modelstudio_rag.py +377 -0
- agentscope_runtime/tools/RAGs/modelstudio_rag_lite.py +219 -0
- agentscope_runtime/tools/__init__.py +119 -0
- agentscope_runtime/tools/_constants.py +18 -0
- agentscope_runtime/tools/alipay/__init__.py +4 -0
- agentscope_runtime/tools/alipay/base.py +334 -0
- agentscope_runtime/tools/alipay/payment.py +835 -0
- agentscope_runtime/tools/alipay/subscribe.py +551 -0
- agentscope_runtime/tools/base.py +264 -0
- agentscope_runtime/tools/cli/__init__.py +0 -0
- agentscope_runtime/tools/cli/modelstudio_mcp_server.py +78 -0
- agentscope_runtime/tools/generations/__init__.py +75 -0
- agentscope_runtime/tools/generations/async_image_to_video.py +350 -0
- agentscope_runtime/tools/generations/async_image_to_video_wan25.py +366 -0
- agentscope_runtime/tools/generations/async_speech_to_video.py +422 -0
- agentscope_runtime/tools/generations/async_text_to_video.py +320 -0
- agentscope_runtime/tools/generations/async_text_to_video_wan25.py +334 -0
- agentscope_runtime/tools/generations/image_edit.py +208 -0
- agentscope_runtime/tools/generations/image_edit_wan25.py +193 -0
- agentscope_runtime/tools/generations/image_generation.py +202 -0
- agentscope_runtime/tools/generations/image_generation_wan25.py +201 -0
- agentscope_runtime/tools/generations/image_style_repaint.py +208 -0
- agentscope_runtime/tools/generations/image_to_video.py +233 -0
- agentscope_runtime/tools/generations/qwen_image_edit.py +205 -0
- agentscope_runtime/tools/generations/qwen_image_generation.py +214 -0
- agentscope_runtime/tools/generations/qwen_text_to_speech.py +154 -0
- agentscope_runtime/tools/generations/speech_to_text.py +260 -0
- agentscope_runtime/tools/generations/speech_to_video.py +314 -0
- agentscope_runtime/tools/generations/text_to_video.py +221 -0
- agentscope_runtime/tools/mcp_wrapper.py +215 -0
- agentscope_runtime/tools/realtime_clients/__init__.py +13 -0
- agentscope_runtime/tools/realtime_clients/asr_client.py +27 -0
- agentscope_runtime/tools/realtime_clients/azure_asr_client.py +195 -0
- agentscope_runtime/tools/realtime_clients/azure_tts_client.py +383 -0
- agentscope_runtime/tools/realtime_clients/modelstudio_asr_client.py +151 -0
- agentscope_runtime/tools/realtime_clients/modelstudio_tts_client.py +199 -0
- agentscope_runtime/tools/realtime_clients/realtime_tool.py +55 -0
- agentscope_runtime/tools/realtime_clients/tts_client.py +33 -0
- agentscope_runtime/tools/searches/__init__.py +3 -0
- agentscope_runtime/tools/searches/modelstudio_search.py +877 -0
- agentscope_runtime/tools/searches/modelstudio_search_lite.py +310 -0
- agentscope_runtime/tools/utils/__init__.py +0 -0
- agentscope_runtime/tools/utils/api_key_util.py +45 -0
- agentscope_runtime/tools/utils/crypto_utils.py +99 -0
- agentscope_runtime/tools/utils/mcp_util.py +35 -0
- agentscope_runtime/version.py +1 -1
- {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0.dist-info}/METADATA +240 -168
- agentscope_runtime-1.0.0.dist-info/RECORD +240 -0
- {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0.dist-info}/entry_points.txt +1 -0
- agentscope_runtime/engine/agents/__init__.py +0 -2
- agentscope_runtime/engine/agents/agentscope_agent.py +0 -488
- agentscope_runtime/engine/agents/agno_agent.py +0 -220
- agentscope_runtime/engine/agents/autogen_agent.py +0 -250
- agentscope_runtime/engine/agents/base_agent.py +0 -29
- agentscope_runtime/engine/agents/langgraph_agent.py +0 -59
- agentscope_runtime/engine/agents/utils.py +0 -53
- agentscope_runtime/engine/deployers/utils/package_project_utils.py +0 -1163
- agentscope_runtime/engine/deployers/utils/service_utils/service_config.py +0 -75
- agentscope_runtime/engine/deployers/utils/service_utils/service_factory.py +0 -220
- agentscope_runtime/engine/helpers/helper.py +0 -179
- agentscope_runtime/engine/schemas/context.py +0 -54
- agentscope_runtime/engine/services/context_manager.py +0 -164
- agentscope_runtime/engine/services/environment_manager.py +0 -50
- agentscope_runtime/engine/services/manager.py +0 -174
- agentscope_runtime/engine/services/rag_service.py +0 -195
- agentscope_runtime/engine/services/tablestore_rag_service.py +0 -143
- agentscope_runtime/sandbox/tools/__init__.py +0 -12
- agentscope_runtime/sandbox/tools/base/__init__.py +0 -8
- agentscope_runtime/sandbox/tools/base/tool.py +0 -52
- agentscope_runtime/sandbox/tools/browser/__init__.py +0 -57
- agentscope_runtime/sandbox/tools/browser/tool.py +0 -597
- agentscope_runtime/sandbox/tools/filesystem/__init__.py +0 -32
- agentscope_runtime/sandbox/tools/filesystem/tool.py +0 -319
- agentscope_runtime/sandbox/tools/function_tool.py +0 -321
- agentscope_runtime/sandbox/tools/gui/__init__.py +0 -7
- agentscope_runtime/sandbox/tools/gui/tool.py +0 -77
- agentscope_runtime/sandbox/tools/mcp_tool.py +0 -195
- agentscope_runtime/sandbox/tools/sandbox_tool.py +0 -104
- agentscope_runtime/sandbox/tools/tool.py +0 -238
- agentscope_runtime/sandbox/tools/utils.py +0 -68
- agentscope_runtime-0.2.0b2.dist-info/RECORD +0 -183
- {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0.dist-info}/WHEEL +0 -0
- {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0.dist-info}/licenses/LICENSE +0 -0
- {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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
72
|
+
self.service = None
|
|
73
|
+
self._health = False
|
|
70
74
|
|
|
71
75
|
async def health(self):
|
|
72
|
-
|
|
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
|
|
9
|
-
from
|
|
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
|
-
"""
|
|
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
|
|
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
|
|
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
|
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
|
+
)
|