agentscope-runtime 1.0.5.post1__py3-none-any.whl → 1.1.0b3__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/__init__.py +3 -0
- agentscope_runtime/adapters/agentscope/message.py +85 -295
- agentscope_runtime/adapters/agentscope/stream.py +133 -3
- agentscope_runtime/adapters/agno/message.py +11 -2
- agentscope_runtime/adapters/agno/stream.py +1 -0
- agentscope_runtime/adapters/langgraph/__init__.py +1 -3
- agentscope_runtime/adapters/langgraph/message.py +11 -106
- agentscope_runtime/adapters/langgraph/stream.py +1 -0
- agentscope_runtime/adapters/ms_agent_framework/message.py +11 -1
- agentscope_runtime/adapters/ms_agent_framework/stream.py +1 -0
- agentscope_runtime/adapters/text/stream.py +1 -0
- agentscope_runtime/common/container_clients/agentrun_client.py +0 -3
- agentscope_runtime/common/container_clients/boxlite_client.py +26 -15
- agentscope_runtime/common/container_clients/fc_client.py +0 -11
- agentscope_runtime/common/utils/deprecation.py +14 -17
- agentscope_runtime/common/utils/logging.py +44 -0
- agentscope_runtime/engine/app/agent_app.py +5 -5
- agentscope_runtime/engine/app/celery_mixin.py +43 -4
- agentscope_runtime/engine/deployers/adapter/agui/__init__.py +8 -1
- agentscope_runtime/engine/deployers/adapter/agui/agui_adapter_utils.py +6 -1
- agentscope_runtime/engine/deployers/adapter/agui/agui_protocol_adapter.py +2 -2
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +13 -0
- agentscope_runtime/engine/runner.py +31 -6
- agentscope_runtime/engine/schemas/agent_schemas.py +28 -0
- agentscope_runtime/engine/services/sandbox/sandbox_service.py +41 -9
- agentscope_runtime/sandbox/box/base/base_sandbox.py +4 -0
- agentscope_runtime/sandbox/box/browser/browser_sandbox.py +4 -0
- agentscope_runtime/sandbox/box/dummy/dummy_sandbox.py +9 -2
- agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +4 -0
- agentscope_runtime/sandbox/box/gui/gui_sandbox.py +5 -1
- agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +4 -0
- agentscope_runtime/sandbox/box/sandbox.py +122 -13
- agentscope_runtime/sandbox/client/async_http_client.py +1 -0
- agentscope_runtime/sandbox/client/base.py +0 -1
- agentscope_runtime/sandbox/client/http_client.py +0 -2
- agentscope_runtime/sandbox/manager/heartbeat_mixin.py +486 -0
- agentscope_runtime/sandbox/manager/sandbox_manager.py +740 -153
- agentscope_runtime/sandbox/manager/server/app.py +18 -11
- agentscope_runtime/sandbox/manager/server/config.py +10 -2
- agentscope_runtime/sandbox/mcp_server.py +0 -1
- agentscope_runtime/sandbox/model/__init__.py +2 -1
- agentscope_runtime/sandbox/model/container.py +90 -3
- agentscope_runtime/sandbox/model/manager_config.py +45 -1
- agentscope_runtime/version.py +1 -1
- {agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b3.dist-info}/METADATA +37 -54
- {agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b3.dist-info}/RECORD +50 -69
- agentscope_runtime/adapters/agentscope/long_term_memory/__init__.py +0 -6
- agentscope_runtime/adapters/agentscope/long_term_memory/_long_term_memory_adapter.py +0 -258
- agentscope_runtime/adapters/agentscope/memory/__init__.py +0 -6
- agentscope_runtime/adapters/agentscope/memory/_memory_adapter.py +0 -152
- agentscope_runtime/engine/services/agent_state/__init__.py +0 -25
- agentscope_runtime/engine/services/agent_state/redis_state_service.py +0 -166
- agentscope_runtime/engine/services/agent_state/state_service.py +0 -179
- agentscope_runtime/engine/services/agent_state/state_service_factory.py +0 -52
- agentscope_runtime/engine/services/memory/__init__.py +0 -33
- agentscope_runtime/engine/services/memory/mem0_memory_service.py +0 -128
- agentscope_runtime/engine/services/memory/memory_service.py +0 -292
- agentscope_runtime/engine/services/memory/memory_service_factory.py +0 -126
- agentscope_runtime/engine/services/memory/redis_memory_service.py +0 -290
- agentscope_runtime/engine/services/memory/reme_personal_memory_service.py +0 -109
- agentscope_runtime/engine/services/memory/reme_task_memory_service.py +0 -11
- agentscope_runtime/engine/services/memory/tablestore_memory_service.py +0 -301
- agentscope_runtime/engine/services/session_history/__init__.py +0 -32
- agentscope_runtime/engine/services/session_history/redis_session_history_service.py +0 -283
- agentscope_runtime/engine/services/session_history/session_history_service.py +0 -267
- agentscope_runtime/engine/services/session_history/session_history_service_factory.py +0 -73
- agentscope_runtime/engine/services/session_history/tablestore_session_history_service.py +0 -288
- {agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b3.dist-info}/WHEEL +0 -0
- {agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b3.dist-info}/entry_points.txt +0 -0
- {agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b3.dist-info}/licenses/LICENSE +0 -0
- {agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b3.dist-info}/top_level.txt +0 -0
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
import copy
|
|
3
|
-
import uuid
|
|
4
|
-
from abc import abstractmethod
|
|
5
|
-
from typing import List, Dict, Optional, Union, Any
|
|
6
|
-
|
|
7
|
-
from ..base import ServiceWithLifecycleManager
|
|
8
|
-
from ...schemas.session import Session
|
|
9
|
-
from ...schemas.agent_schemas import Message
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class SessionHistoryService(ServiceWithLifecycleManager):
|
|
13
|
-
"""Abstract base class for session history management services.
|
|
14
|
-
|
|
15
|
-
This class defines the standard interface for creating, retrieving,
|
|
16
|
-
updating, and deleting conversation sessions. Concrete implementations
|
|
17
|
-
(like InMemorySessionHistoryService) will handle the actual storage logic.
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
async def start(self) -> None:
|
|
21
|
-
pass
|
|
22
|
-
|
|
23
|
-
async def stop(self) -> None:
|
|
24
|
-
pass
|
|
25
|
-
|
|
26
|
-
@abstractmethod
|
|
27
|
-
async def create_session(
|
|
28
|
-
self,
|
|
29
|
-
user_id: str,
|
|
30
|
-
session_id: Optional[str] = None,
|
|
31
|
-
) -> Session:
|
|
32
|
-
"""Creates a new session for a given user.
|
|
33
|
-
|
|
34
|
-
Args:
|
|
35
|
-
user_id: The identifier for the user.
|
|
36
|
-
session_id: Could be defined by user
|
|
37
|
-
Returns:
|
|
38
|
-
The newly created Session object.
|
|
39
|
-
"""
|
|
40
|
-
|
|
41
|
-
@abstractmethod
|
|
42
|
-
async def get_session(
|
|
43
|
-
self,
|
|
44
|
-
user_id: str,
|
|
45
|
-
session_id: str,
|
|
46
|
-
) -> (Session | None):
|
|
47
|
-
"""Retrieves a specific session.
|
|
48
|
-
|
|
49
|
-
Args:
|
|
50
|
-
user_id: The identifier for the user.
|
|
51
|
-
session_id: The identifier for the session to retrieve.
|
|
52
|
-
|
|
53
|
-
Returns:
|
|
54
|
-
The Session object if found, otherwise should raise an error or
|
|
55
|
-
return None in concrete implementations.
|
|
56
|
-
"""
|
|
57
|
-
|
|
58
|
-
@abstractmethod
|
|
59
|
-
async def delete_session(self, user_id: str, session_id: str):
|
|
60
|
-
"""Deletes a specific session.
|
|
61
|
-
|
|
62
|
-
Args:
|
|
63
|
-
user_id: The identifier for the user.
|
|
64
|
-
session_id: The identifier for the session to delete.
|
|
65
|
-
"""
|
|
66
|
-
|
|
67
|
-
@abstractmethod
|
|
68
|
-
async def list_sessions(self, user_id: str) -> list[Session]:
|
|
69
|
-
"""Lists all sessions for a given user.
|
|
70
|
-
|
|
71
|
-
Args:
|
|
72
|
-
user_id: The identifier for the user.
|
|
73
|
-
|
|
74
|
-
Returns:
|
|
75
|
-
A list of Session objects.
|
|
76
|
-
"""
|
|
77
|
-
return []
|
|
78
|
-
|
|
79
|
-
async def append_message(
|
|
80
|
-
self,
|
|
81
|
-
session: Session,
|
|
82
|
-
message: Union[
|
|
83
|
-
Message,
|
|
84
|
-
List[Message],
|
|
85
|
-
Dict[str, Any],
|
|
86
|
-
List[Dict[str, Any]],
|
|
87
|
-
],
|
|
88
|
-
):
|
|
89
|
-
"""Appends a message to the history of a specific session.
|
|
90
|
-
|
|
91
|
-
Args:
|
|
92
|
-
session: The session to which the message should be appended.
|
|
93
|
-
message: The message or list of messages to append. Supports both
|
|
94
|
-
dictionary format and Message objects.
|
|
95
|
-
"""
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
class InMemorySessionHistoryService(SessionHistoryService):
|
|
99
|
-
"""An in-memory implementation of the SessionHistoryService.
|
|
100
|
-
|
|
101
|
-
This service stores all session data in a dictionary, making it suitable
|
|
102
|
-
for development, testing, and scenarios where persistence is not required.
|
|
103
|
-
|
|
104
|
-
Attributes:
|
|
105
|
-
_store: A dictionary holding all session objects, keyed by user ID
|
|
106
|
-
and then by session ID.
|
|
107
|
-
"""
|
|
108
|
-
|
|
109
|
-
def __init__(self) -> None:
|
|
110
|
-
"""Initializes the InMemorySessionHistoryService."""
|
|
111
|
-
self._store: Optional[Dict[str, Dict[str, Session]]] = None
|
|
112
|
-
self._health = False
|
|
113
|
-
|
|
114
|
-
async def start(self) -> None:
|
|
115
|
-
"""Initialize the in-memory store."""
|
|
116
|
-
if self._store is None:
|
|
117
|
-
self._store = {}
|
|
118
|
-
self._health = True
|
|
119
|
-
|
|
120
|
-
async def stop(self) -> None:
|
|
121
|
-
"""Clear all in-memory data."""
|
|
122
|
-
if self._store is not None:
|
|
123
|
-
self._store.clear()
|
|
124
|
-
self._store = None
|
|
125
|
-
self._health = False
|
|
126
|
-
|
|
127
|
-
async def health(self) -> bool:
|
|
128
|
-
"""Service health check: always True."""
|
|
129
|
-
return self._health
|
|
130
|
-
|
|
131
|
-
async def create_session(
|
|
132
|
-
self,
|
|
133
|
-
user_id: str,
|
|
134
|
-
session_id: Optional[str] = None,
|
|
135
|
-
) -> Session:
|
|
136
|
-
"""Creates a new session for a given user and stores it.
|
|
137
|
-
|
|
138
|
-
Args:
|
|
139
|
-
user_id: The identifier for the user creating the session.
|
|
140
|
-
session_id: The identifier for the session to delete.
|
|
141
|
-
|
|
142
|
-
Returns:
|
|
143
|
-
A deep copy of the newly created Session object.
|
|
144
|
-
"""
|
|
145
|
-
if self._store is None:
|
|
146
|
-
raise RuntimeError("Service not started")
|
|
147
|
-
|
|
148
|
-
session_id = (
|
|
149
|
-
session_id.strip()
|
|
150
|
-
if session_id and session_id.strip()
|
|
151
|
-
else str(uuid.uuid4())
|
|
152
|
-
)
|
|
153
|
-
session = Session(id=session_id, user_id=user_id)
|
|
154
|
-
self._store.setdefault(user_id, {})[session_id] = session
|
|
155
|
-
return copy.deepcopy(session)
|
|
156
|
-
|
|
157
|
-
async def get_session(
|
|
158
|
-
self,
|
|
159
|
-
user_id: str,
|
|
160
|
-
session_id: str,
|
|
161
|
-
) -> Session | None:
|
|
162
|
-
"""Retrieves a specific session from memory.
|
|
163
|
-
|
|
164
|
-
Args:
|
|
165
|
-
user_id: The identifier for the user.
|
|
166
|
-
session_id: The identifier for the session to retrieve.
|
|
167
|
-
|
|
168
|
-
Returns:
|
|
169
|
-
A deep copy of the Session object if found, otherwise None.
|
|
170
|
-
"""
|
|
171
|
-
if self._store is None:
|
|
172
|
-
raise RuntimeError("Service not started")
|
|
173
|
-
|
|
174
|
-
session = self._store.get(user_id, {}).get(session_id)
|
|
175
|
-
if not session:
|
|
176
|
-
session = Session(id=session_id, user_id=user_id)
|
|
177
|
-
self._store.setdefault(user_id, {})[session_id] = session
|
|
178
|
-
return copy.deepcopy(session) if session else None
|
|
179
|
-
|
|
180
|
-
async def delete_session(self, user_id: str, session_id: str) -> None:
|
|
181
|
-
"""Deletes a specific session from memory.
|
|
182
|
-
|
|
183
|
-
If the session does not exist, the method does nothing.
|
|
184
|
-
|
|
185
|
-
Args:
|
|
186
|
-
user_id: The identifier for the user.
|
|
187
|
-
session_id: The identifier for the session to delete.
|
|
188
|
-
"""
|
|
189
|
-
if self._store is None:
|
|
190
|
-
raise RuntimeError("Service not started")
|
|
191
|
-
|
|
192
|
-
if user_id in self._store and session_id in self._store[user_id]:
|
|
193
|
-
del self._store[user_id][session_id]
|
|
194
|
-
|
|
195
|
-
async def list_sessions(self, user_id: str) -> list[Session]:
|
|
196
|
-
"""Lists all sessions for a given user.
|
|
197
|
-
|
|
198
|
-
To improve performance and reduce data transfer, the returned session
|
|
199
|
-
objects do not contain the detailed response history.
|
|
200
|
-
|
|
201
|
-
Args:
|
|
202
|
-
user_id: The identifier of the user whose sessions to list.
|
|
203
|
-
|
|
204
|
-
Returns:
|
|
205
|
-
A list of Session objects belonging to the user, without history.
|
|
206
|
-
"""
|
|
207
|
-
if self._store is None:
|
|
208
|
-
raise RuntimeError("Service not started")
|
|
209
|
-
|
|
210
|
-
user_sessions = self._store.get(user_id, {})
|
|
211
|
-
# Return sessions without their potentially large history for
|
|
212
|
-
# efficiency.
|
|
213
|
-
sessions_without_history = []
|
|
214
|
-
for session in user_sessions.values():
|
|
215
|
-
copied_session = copy.deepcopy(session)
|
|
216
|
-
copied_session.messages = []
|
|
217
|
-
sessions_without_history.append(copied_session)
|
|
218
|
-
return sessions_without_history
|
|
219
|
-
|
|
220
|
-
async def append_message(
|
|
221
|
-
self,
|
|
222
|
-
session: Session,
|
|
223
|
-
message: Union[
|
|
224
|
-
Message,
|
|
225
|
-
List[Message],
|
|
226
|
-
Dict[str, Any],
|
|
227
|
-
List[Dict[str, Any]],
|
|
228
|
-
],
|
|
229
|
-
) -> None:
|
|
230
|
-
"""Appends message to a session's history in memory.
|
|
231
|
-
|
|
232
|
-
This method finds the authoritative session object in the in-memory
|
|
233
|
-
storage and appends the message to its history. It supports both
|
|
234
|
-
dictionary format messages and Message objects.
|
|
235
|
-
|
|
236
|
-
Args:
|
|
237
|
-
session: The session object, typically from the context. The
|
|
238
|
-
user_id and id from this object are used for lookup.
|
|
239
|
-
message: The message or list of messages to append to the
|
|
240
|
-
session's history.
|
|
241
|
-
"""
|
|
242
|
-
if self._store is None:
|
|
243
|
-
raise RuntimeError("Service not started")
|
|
244
|
-
|
|
245
|
-
# Normalize to list
|
|
246
|
-
if not isinstance(message, list):
|
|
247
|
-
message = [message]
|
|
248
|
-
|
|
249
|
-
norm_message = []
|
|
250
|
-
for msg in message:
|
|
251
|
-
if msg is not None:
|
|
252
|
-
if not isinstance(msg, Message):
|
|
253
|
-
msg = Message.model_validate(msg)
|
|
254
|
-
norm_message.append(msg)
|
|
255
|
-
session.messages.extend(norm_message)
|
|
256
|
-
|
|
257
|
-
# update the in memory copy
|
|
258
|
-
storage_session = self._store.get(session.user_id, {}).get(
|
|
259
|
-
session.id,
|
|
260
|
-
)
|
|
261
|
-
if storage_session:
|
|
262
|
-
storage_session.messages.extend(message)
|
|
263
|
-
else:
|
|
264
|
-
print(
|
|
265
|
-
f"Warning: Session {session.id} not found in storage for "
|
|
266
|
-
f"append_message.",
|
|
267
|
-
)
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
|
|
3
|
-
from typing import Callable, Dict
|
|
4
|
-
|
|
5
|
-
from ..service_factory import ServiceFactory
|
|
6
|
-
from .session_history_service import (
|
|
7
|
-
SessionHistoryService,
|
|
8
|
-
InMemorySessionHistoryService,
|
|
9
|
-
)
|
|
10
|
-
from .redis_session_history_service import RedisSessionHistoryService
|
|
11
|
-
|
|
12
|
-
try:
|
|
13
|
-
from .tablestore_session_history_service import (
|
|
14
|
-
TablestoreSessionHistoryService,
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
TABLESTORE_AVAILABLE = True
|
|
18
|
-
except ImportError:
|
|
19
|
-
TABLESTORE_AVAILABLE = False
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class SessionHistoryServiceFactory(ServiceFactory[SessionHistoryService]):
|
|
23
|
-
"""
|
|
24
|
-
Factory for SessionHistoryService, supporting both environment variables
|
|
25
|
-
and keyword arguments.
|
|
26
|
-
|
|
27
|
-
Usage examples:
|
|
28
|
-
1. Start with only environment variables:
|
|
29
|
-
export SESSION_HISTORY_BACKEND=redis
|
|
30
|
-
export SESSION_HISTORY_REDIS_REDIS_URL="redis://localhost:6379/5"
|
|
31
|
-
service = await SessionHistoryServiceFactory.create()
|
|
32
|
-
|
|
33
|
-
2. Override environment variables with arguments:
|
|
34
|
-
export SESSION_HISTORY_BACKEND=redis
|
|
35
|
-
export SESSION_HISTORY_REDIS_REDIS_URL="redis://localhost:6379/5"
|
|
36
|
-
service = await SessionHistoryServiceFactory.create(
|
|
37
|
-
redis_url="redis://otherhost:6379/1"
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
3. Register a custom backend:
|
|
41
|
-
from my_backend import PostgresSessionHistoryService
|
|
42
|
-
SessionHistoryServiceFactory.register_backend(
|
|
43
|
-
"postgres",
|
|
44
|
-
PostgresSessionHistoryService,
|
|
45
|
-
)
|
|
46
|
-
export SESSION_HISTORY_BACKEND=postgres
|
|
47
|
-
export SESSION_HISTORY_POSTGRES_DSN="postgresql://user:pass@localhost/db" # noqa
|
|
48
|
-
export SESSION_HISTORY_POSTGRES_POOL_SIZE="20"
|
|
49
|
-
service = await SessionHistoryServiceFactory.create()
|
|
50
|
-
"""
|
|
51
|
-
|
|
52
|
-
_registry: Dict[str, Callable[..., SessionHistoryService]] = {}
|
|
53
|
-
_env_prefix = "SESSION_HISTORY_"
|
|
54
|
-
_default_backend = "in_memory"
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
# === Default built-in backend registration ===
|
|
58
|
-
|
|
59
|
-
SessionHistoryServiceFactory.register_backend(
|
|
60
|
-
"in_memory",
|
|
61
|
-
InMemorySessionHistoryService,
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
SessionHistoryServiceFactory.register_backend(
|
|
65
|
-
"redis",
|
|
66
|
-
RedisSessionHistoryService,
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
if TABLESTORE_AVAILABLE:
|
|
70
|
-
SessionHistoryServiceFactory.register_backend(
|
|
71
|
-
"tablestore",
|
|
72
|
-
TablestoreSessionHistoryService,
|
|
73
|
-
)
|
|
@@ -1,288 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
# pylint: disable=redefined-outer-name
|
|
3
|
-
import asyncio
|
|
4
|
-
import uuid
|
|
5
|
-
from typing import Any, Dict, List, Optional, Union
|
|
6
|
-
|
|
7
|
-
import tablestore
|
|
8
|
-
from tablestore import AsyncOTSClient as AsyncTablestoreClient
|
|
9
|
-
from tablestore_for_agent_memory.base.base_memory_store import (
|
|
10
|
-
Session as TablestoreSession,
|
|
11
|
-
)
|
|
12
|
-
from tablestore_for_agent_memory.base.common import MetaType, Order
|
|
13
|
-
from tablestore_for_agent_memory.memory.async_memory_store import (
|
|
14
|
-
AsyncMemoryStore,
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
from .session_history_service import SessionHistoryService
|
|
18
|
-
from ...schemas.agent_schemas import Message
|
|
19
|
-
from ...schemas.session import Session
|
|
20
|
-
from ..utils.tablestore_service_utils import (
|
|
21
|
-
convert_message_to_tablestore_message,
|
|
22
|
-
convert_tablestore_session_to_session,
|
|
23
|
-
tablestore_log,
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class TablestoreSessionHistoryService(SessionHistoryService):
|
|
28
|
-
"""An aliyun tablestore implementation of the SessionHistoryService
|
|
29
|
-
based on tablestore_for_agent_memory
|
|
30
|
-
(https://github.com/aliyun/
|
|
31
|
-
alibabacloud-tablestore-for-agent-memory/blob/main/python/docs/memory_store_tutorial.ipynb).
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
_SESSION_SECONDARY_INDEX_NAME = (
|
|
35
|
-
"agentscope_runtime_session_secondary_index"
|
|
36
|
-
)
|
|
37
|
-
_SESSION_SEARCH_INDEX_NAME = "agentscope_runtime_session_search_index"
|
|
38
|
-
_MESSAGE_SECONDARY_INDEX_NAME = (
|
|
39
|
-
"agentscope_runtime_message_secondary_index"
|
|
40
|
-
)
|
|
41
|
-
_MESSAGE_SEARCH_INDEX_NAME = "agentscope_runtime_message_search_index"
|
|
42
|
-
|
|
43
|
-
def __init__(
|
|
44
|
-
self,
|
|
45
|
-
tablestore_client: AsyncTablestoreClient,
|
|
46
|
-
session_table_name: Optional[str] = "agentscope_runtime_session",
|
|
47
|
-
message_table_name: Optional[str] = "agentscope_runtime_message",
|
|
48
|
-
session_secondary_index_meta: Optional[Dict[str, MetaType]] = None,
|
|
49
|
-
session_search_index_schema: Optional[
|
|
50
|
-
List[tablestore.FieldSchema]
|
|
51
|
-
] = None,
|
|
52
|
-
message_search_index_schema: Optional[
|
|
53
|
-
List[tablestore.FieldSchema]
|
|
54
|
-
] = None,
|
|
55
|
-
**kwargs: Any,
|
|
56
|
-
) -> None:
|
|
57
|
-
"""Initializes the TablestoreSessionHistoryService."""
|
|
58
|
-
self._tablestore_client = tablestore_client
|
|
59
|
-
self._session_table_name = session_table_name
|
|
60
|
-
self._message_table_name = message_table_name
|
|
61
|
-
self._session_secondary_index_meta = session_secondary_index_meta
|
|
62
|
-
self._session_search_index_schema = session_search_index_schema
|
|
63
|
-
self._message_search_index_schema = message_search_index_schema
|
|
64
|
-
self._memory_store: Optional[AsyncMemoryStore] = None
|
|
65
|
-
self._memory_store_init_parameter_kwargs = kwargs
|
|
66
|
-
|
|
67
|
-
async def _init_memory_store(self) -> None:
|
|
68
|
-
self._memory_store = AsyncMemoryStore(
|
|
69
|
-
tablestore_client=self._tablestore_client,
|
|
70
|
-
session_table_name=self._session_table_name,
|
|
71
|
-
message_table_name=self._message_table_name,
|
|
72
|
-
session_secondary_index_name=self._SESSION_SECONDARY_INDEX_NAME,
|
|
73
|
-
session_search_index_name=self._SESSION_SEARCH_INDEX_NAME,
|
|
74
|
-
message_secondary_index_name=self._MESSAGE_SECONDARY_INDEX_NAME,
|
|
75
|
-
message_search_index_name=self._MESSAGE_SEARCH_INDEX_NAME,
|
|
76
|
-
session_secondary_index_meta=self._session_secondary_index_meta,
|
|
77
|
-
session_search_index_schema=self._session_search_index_schema,
|
|
78
|
-
message_search_index_schema=self._message_search_index_schema,
|
|
79
|
-
**self._memory_store_init_parameter_kwargs,
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
await self._memory_store.init_table()
|
|
83
|
-
await self._memory_store.init_search_index()
|
|
84
|
-
|
|
85
|
-
async def start(self) -> None:
|
|
86
|
-
"""Start the tablestore service"""
|
|
87
|
-
if self._memory_store:
|
|
88
|
-
return
|
|
89
|
-
await self._init_memory_store()
|
|
90
|
-
|
|
91
|
-
async def stop(self) -> None:
|
|
92
|
-
"""Close the tablestore service"""
|
|
93
|
-
if self._memory_store is None:
|
|
94
|
-
return
|
|
95
|
-
memory_store = self._memory_store
|
|
96
|
-
self._memory_store = None
|
|
97
|
-
await memory_store.close()
|
|
98
|
-
|
|
99
|
-
async def health(self) -> bool:
|
|
100
|
-
"""Checks the health of the service."""
|
|
101
|
-
if self._memory_store is None:
|
|
102
|
-
tablestore_log(
|
|
103
|
-
"Tablestore session history service is not started.",
|
|
104
|
-
)
|
|
105
|
-
return False
|
|
106
|
-
|
|
107
|
-
try:
|
|
108
|
-
async for _ in await self._memory_store.list_all_sessions():
|
|
109
|
-
return True
|
|
110
|
-
return True
|
|
111
|
-
except Exception as e:
|
|
112
|
-
tablestore_log(
|
|
113
|
-
f"Tablestore session history service "
|
|
114
|
-
f"cannot access Tablestore, error: {str(e)}.",
|
|
115
|
-
)
|
|
116
|
-
return False
|
|
117
|
-
|
|
118
|
-
async def create_session(
|
|
119
|
-
self,
|
|
120
|
-
user_id: str,
|
|
121
|
-
session_id: Optional[str] = None,
|
|
122
|
-
) -> Session:
|
|
123
|
-
"""Creates a new session for a given user and stores it.
|
|
124
|
-
|
|
125
|
-
Args:
|
|
126
|
-
user_id: The identifier for the user creating the session.
|
|
127
|
-
session_id: The identifier for the session to delete.
|
|
128
|
-
|
|
129
|
-
Returns:
|
|
130
|
-
A newly created Session object.
|
|
131
|
-
"""
|
|
132
|
-
session_id = (
|
|
133
|
-
session_id.strip()
|
|
134
|
-
if session_id and session_id.strip()
|
|
135
|
-
else str(uuid.uuid4())
|
|
136
|
-
)
|
|
137
|
-
tablestore_session = TablestoreSession(
|
|
138
|
-
session_id=session_id,
|
|
139
|
-
user_id=user_id,
|
|
140
|
-
)
|
|
141
|
-
|
|
142
|
-
await self._memory_store.put_session(tablestore_session)
|
|
143
|
-
return convert_tablestore_session_to_session(tablestore_session)
|
|
144
|
-
|
|
145
|
-
async def get_session(
|
|
146
|
-
self,
|
|
147
|
-
user_id: str,
|
|
148
|
-
session_id: str,
|
|
149
|
-
) -> Session | None:
|
|
150
|
-
"""Retrieves a specific session from memory.
|
|
151
|
-
|
|
152
|
-
Args:
|
|
153
|
-
user_id: The identifier for the user.
|
|
154
|
-
session_id: The identifier for the session to retrieve.
|
|
155
|
-
|
|
156
|
-
Returns:
|
|
157
|
-
A Session object if found, otherwise None.
|
|
158
|
-
"""
|
|
159
|
-
|
|
160
|
-
tablestore_session = await self._memory_store.get_session(
|
|
161
|
-
user_id=user_id,
|
|
162
|
-
session_id=session_id,
|
|
163
|
-
)
|
|
164
|
-
|
|
165
|
-
if not tablestore_session:
|
|
166
|
-
tablestore_session = TablestoreSession(
|
|
167
|
-
session_id=session_id,
|
|
168
|
-
user_id=user_id,
|
|
169
|
-
)
|
|
170
|
-
await self._memory_store.put_session(tablestore_session)
|
|
171
|
-
tablestore_messages = None
|
|
172
|
-
else:
|
|
173
|
-
messages_iterator = await self._memory_store.list_messages(
|
|
174
|
-
session_id=session_id,
|
|
175
|
-
order=Order.ASC,
|
|
176
|
-
# Sort by timestamp,
|
|
177
|
-
# keeping the most recent information at the end of the list.
|
|
178
|
-
)
|
|
179
|
-
tablestore_messages = [
|
|
180
|
-
message async for message in messages_iterator
|
|
181
|
-
]
|
|
182
|
-
|
|
183
|
-
return convert_tablestore_session_to_session(
|
|
184
|
-
tablestore_session,
|
|
185
|
-
tablestore_messages,
|
|
186
|
-
)
|
|
187
|
-
|
|
188
|
-
async def delete_session(self, user_id: str, session_id: str) -> None:
|
|
189
|
-
"""Deletes a specific session from memory.
|
|
190
|
-
|
|
191
|
-
If the session does not exist, the method does nothing.
|
|
192
|
-
|
|
193
|
-
Args:
|
|
194
|
-
user_id: The identifier for the user.
|
|
195
|
-
session_id: The identifier for the session to delete.
|
|
196
|
-
"""
|
|
197
|
-
await self._memory_store.delete_session_and_messages(
|
|
198
|
-
user_id=user_id,
|
|
199
|
-
session_id=session_id,
|
|
200
|
-
)
|
|
201
|
-
|
|
202
|
-
async def list_sessions(self, user_id: str) -> list[Session]:
|
|
203
|
-
"""Lists all sessions for a given user.
|
|
204
|
-
|
|
205
|
-
To improve performance and reduce data transfer, the returned session
|
|
206
|
-
objects do not contain the detailed response history.
|
|
207
|
-
|
|
208
|
-
Args:
|
|
209
|
-
user_id: The identifier of the user whose sessions to list.
|
|
210
|
-
|
|
211
|
-
Returns:
|
|
212
|
-
A list of Session objects belonging to the user, without history.
|
|
213
|
-
"""
|
|
214
|
-
tablestore_sessions = await self._memory_store.list_sessions(user_id)
|
|
215
|
-
return [
|
|
216
|
-
convert_tablestore_session_to_session(tablestore_session)
|
|
217
|
-
async for tablestore_session in tablestore_sessions
|
|
218
|
-
]
|
|
219
|
-
|
|
220
|
-
async def append_message(
|
|
221
|
-
self,
|
|
222
|
-
session: Session,
|
|
223
|
-
message: Union[
|
|
224
|
-
Message,
|
|
225
|
-
List[Message],
|
|
226
|
-
Dict[str, Any],
|
|
227
|
-
List[Dict[str, Any]],
|
|
228
|
-
],
|
|
229
|
-
) -> None:
|
|
230
|
-
"""Appends message to a session's history in memory.
|
|
231
|
-
|
|
232
|
-
This method finds the authoritative session object in the in-memory
|
|
233
|
-
storage and appends the message to its history. It supports both
|
|
234
|
-
dictionary format messages and Message objects.
|
|
235
|
-
|
|
236
|
-
Args:
|
|
237
|
-
session: The session object, typically from the context. The
|
|
238
|
-
user_id and id from this object are used for lookup.
|
|
239
|
-
message: The message or list of messages to append to the
|
|
240
|
-
session's history.
|
|
241
|
-
"""
|
|
242
|
-
# Normalize to list
|
|
243
|
-
if not isinstance(message, list):
|
|
244
|
-
message = [message]
|
|
245
|
-
|
|
246
|
-
norm_message = []
|
|
247
|
-
for msg in message:
|
|
248
|
-
if msg is None:
|
|
249
|
-
continue
|
|
250
|
-
|
|
251
|
-
if not isinstance(msg, Message):
|
|
252
|
-
msg = Message.model_validate(msg)
|
|
253
|
-
norm_message.append(msg)
|
|
254
|
-
session.messages.extend(norm_message)
|
|
255
|
-
|
|
256
|
-
tablestore_session = await self._memory_store.get_session(
|
|
257
|
-
session_id=session.id,
|
|
258
|
-
user_id=session.user_id,
|
|
259
|
-
)
|
|
260
|
-
if tablestore_session:
|
|
261
|
-
put_tasks = [
|
|
262
|
-
self._memory_store.put_message(
|
|
263
|
-
convert_message_to_tablestore_message(message, session),
|
|
264
|
-
)
|
|
265
|
-
for message in norm_message
|
|
266
|
-
]
|
|
267
|
-
await asyncio.gather(*put_tasks)
|
|
268
|
-
|
|
269
|
-
else:
|
|
270
|
-
tablestore_log(
|
|
271
|
-
f"Warning: Session {session.id} not found "
|
|
272
|
-
f"in tablestore storage for "
|
|
273
|
-
f"append_message.",
|
|
274
|
-
)
|
|
275
|
-
|
|
276
|
-
async def delete_user_sessions(self, user_id: str) -> None:
|
|
277
|
-
"""
|
|
278
|
-
Deletes all session history data for a specific user.
|
|
279
|
-
|
|
280
|
-
Args:
|
|
281
|
-
user_id (str): The ID of the user whose session history data should
|
|
282
|
-
be deleted
|
|
283
|
-
"""
|
|
284
|
-
delete_tasks = [
|
|
285
|
-
self.delete_session(user_id, session.id)
|
|
286
|
-
for session in (await self.list_sessions(user_id=user_id))
|
|
287
|
-
]
|
|
288
|
-
await asyncio.gather(*delete_tasks)
|
|
File without changes
|
{agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b3.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b3.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
{agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b3.dist-info}/top_level.txt
RENAMED
|
File without changes
|