agentscope-runtime 1.0.4__py3-none-any.whl → 1.0.5__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 (49) hide show
  1. agentscope_runtime/adapters/agentscope/stream.py +1 -1
  2. agentscope_runtime/adapters/langgraph/stream.py +120 -70
  3. agentscope_runtime/cli/commands/deploy.py +465 -1
  4. agentscope_runtime/cli/commands/stop.py +16 -0
  5. agentscope_runtime/common/container_clients/__init__.py +52 -0
  6. agentscope_runtime/common/container_clients/agentrun_client.py +6 -4
  7. agentscope_runtime/common/container_clients/boxlite_client.py +442 -0
  8. agentscope_runtime/common/container_clients/docker_client.py +0 -20
  9. agentscope_runtime/common/container_clients/fc_client.py +6 -4
  10. agentscope_runtime/common/container_clients/gvisor_client.py +38 -0
  11. agentscope_runtime/common/container_clients/knative_client.py +1 -0
  12. agentscope_runtime/common/utils/deprecation.py +164 -0
  13. agentscope_runtime/engine/app/agent_app.py +16 -4
  14. agentscope_runtime/engine/deployers/__init__.py +31 -20
  15. agentscope_runtime/engine/deployers/adapter/__init__.py +8 -0
  16. agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +9 -8
  17. agentscope_runtime/engine/deployers/adapter/a2a/nacos_a2a_registry.py +19 -1
  18. agentscope_runtime/engine/deployers/adapter/agui/__init__.py +8 -0
  19. agentscope_runtime/engine/deployers/adapter/agui/agui_adapter_utils.py +652 -0
  20. agentscope_runtime/engine/deployers/adapter/agui/agui_protocol_adapter.py +225 -0
  21. agentscope_runtime/engine/deployers/pai_deployer.py +2335 -0
  22. agentscope_runtime/engine/deployers/utils/net_utils.py +37 -0
  23. agentscope_runtime/engine/deployers/utils/oss_utils.py +38 -0
  24. agentscope_runtime/engine/deployers/utils/package.py +46 -42
  25. agentscope_runtime/engine/helpers/agent_api_client.py +372 -0
  26. agentscope_runtime/engine/runner.py +1 -0
  27. agentscope_runtime/engine/schemas/agent_schemas.py +9 -3
  28. agentscope_runtime/engine/services/agent_state/__init__.py +7 -0
  29. agentscope_runtime/engine/services/memory/__init__.py +7 -0
  30. agentscope_runtime/engine/services/memory/redis_memory_service.py +15 -16
  31. agentscope_runtime/engine/services/session_history/__init__.py +7 -0
  32. agentscope_runtime/engine/tracing/local_logging_handler.py +2 -3
  33. agentscope_runtime/sandbox/box/sandbox.py +4 -0
  34. agentscope_runtime/sandbox/manager/sandbox_manager.py +11 -25
  35. agentscope_runtime/sandbox/manager/server/config.py +3 -1
  36. agentscope_runtime/sandbox/model/manager_config.py +11 -9
  37. agentscope_runtime/tools/modelstudio_memory/__init__.py +106 -0
  38. agentscope_runtime/tools/modelstudio_memory/base.py +220 -0
  39. agentscope_runtime/tools/modelstudio_memory/config.py +86 -0
  40. agentscope_runtime/tools/modelstudio_memory/core.py +594 -0
  41. agentscope_runtime/tools/modelstudio_memory/exceptions.py +60 -0
  42. agentscope_runtime/tools/modelstudio_memory/schemas.py +253 -0
  43. agentscope_runtime/version.py +1 -1
  44. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/METADATA +101 -62
  45. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/RECORD +49 -34
  46. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/WHEEL +0 -0
  47. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/entry_points.txt +0 -0
  48. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/licenses/LICENSE +0 -0
  49. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,13 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  from typing import TYPE_CHECKING
3
3
  from ....common.utils.lazy_loader import install_lazy_loader
4
+ from ....common.utils.deprecation import deprecated_module
5
+
6
+ deprecated_module(
7
+ module_name=__name__,
8
+ removed_in="v1.1",
9
+ alternative="agentscope.memory",
10
+ )
4
11
 
5
12
  if TYPE_CHECKING:
6
13
  from .session_history_service import (
@@ -7,7 +7,7 @@ from datetime import datetime
7
7
  from logging.handlers import RotatingFileHandler
8
8
  from typing import Any, Dict, Optional
9
9
 
10
- from pydantic import BaseModel
10
+ from pydantic import BaseModel, ConfigDict
11
11
 
12
12
  from . import TracingUtil
13
13
  from .base import TracerHandler
@@ -39,8 +39,7 @@ class LogContext(BaseModel):
39
39
  ds_service_id: str = ""
40
40
  ds_service_name: str = ""
41
41
 
42
- class Config:
43
- extra = "ignore" # ignore additional key
42
+ model_config = ConfigDict(extra="allow")
44
43
 
45
44
 
46
45
  class JsonFormatter(logging.Formatter):
@@ -6,6 +6,7 @@ from typing import Any, Optional
6
6
 
7
7
  from ..enums import SandboxType
8
8
  from ..manager.sandbox_manager import SandboxManager
9
+ from ..manager.server.app import get_config
9
10
 
10
11
 
11
12
  logging.basicConfig(level=logging.INFO)
@@ -32,12 +33,15 @@ class SandboxBase:
32
33
  self._sandbox_id = sandbox_id
33
34
 
34
35
  if base_url:
36
+ # Remote Manager
35
37
  self.manager_api = SandboxManager(
36
38
  base_url=base_url,
37
39
  bearer_token=bearer_token,
38
40
  )
39
41
  else:
42
+ # Embedded Manager
40
43
  self.manager_api = SandboxManager(
44
+ config=get_config(),
41
45
  default_type=sandbox_type,
42
46
  )
43
47
 
@@ -38,6 +38,7 @@ from ...common.collections import (
38
38
  InMemoryMapping,
39
39
  InMemoryQueue,
40
40
  )
41
+ from ...common.container_clients import ContainerClientFactory
41
42
  from ..constant import TIMEOUT
42
43
 
43
44
  logging.basicConfig(level=logging.INFO)
@@ -164,7 +165,12 @@ class SandboxManager:
164
165
  self.httpx_client = None
165
166
  self.base_url = None
166
167
 
167
- if not config:
168
+ if config:
169
+ logger.debug(
170
+ f"Launching sandbox manager with config:"
171
+ f"\n{config.model_dump()}",
172
+ )
173
+ else:
168
174
  config = SandboxManagerEnvConfig(
169
175
  file_system="local",
170
176
  redis_enabled=False,
@@ -230,30 +236,10 @@ class SandboxManager:
230
236
  self.container_deployment = self.config.container_deployment
231
237
 
232
238
  if base_url is None:
233
- if self.container_deployment == "docker":
234
- from ...common.container_clients.docker_client import (
235
- DockerClient,
236
- )
237
-
238
- self.client = DockerClient(config=self.config)
239
- elif self.container_deployment == "k8s":
240
- from ...common.container_clients.kubernetes_client import (
241
- KubernetesClient,
242
- )
243
-
244
- self.client = KubernetesClient(config=self.config)
245
- elif self.container_deployment == "agentrun":
246
- from ...common.container_clients.agentrun_client import (
247
- AgentRunClient,
248
- )
249
-
250
- self.client = AgentRunClient(config=self.config)
251
- elif self.container_deployment == "fc":
252
- from ...common.container_clients.fc_client import FCClient
253
-
254
- self.client = FCClient(config=self.config)
255
- else:
256
- raise NotImplementedError("Not implemented")
239
+ self.client = ContainerClientFactory.create_client(
240
+ deployment_type=self.container_deployment,
241
+ config=self.config,
242
+ )
257
243
  else:
258
244
  self.client = None
259
245
 
@@ -20,7 +20,7 @@ class Settings(BaseSettings):
20
20
 
21
21
  # Runtime Manager settings
22
22
  DEFAULT_SANDBOX_TYPE: Union[str, List[str]] = "base"
23
- POOL_SIZE: int = 1
23
+ POOL_SIZE: int = 0
24
24
  AUTO_CLEANUP: bool = True
25
25
  CONTAINER_PREFIX_KEY: str = "runtime_sandbox_container_"
26
26
  CONTAINER_DEPLOYMENT: Literal[
@@ -29,6 +29,8 @@ class Settings(BaseSettings):
29
29
  "k8s",
30
30
  "agentrun",
31
31
  "fc",
32
+ "gvisor",
33
+ "boxlite",
32
34
  ] = "docker"
33
35
  DEFAULT_MOUNT_DIR: str = "sessions_mount_dir"
34
36
  # Read-only mounts (host_path -> container_path)
@@ -16,15 +16,15 @@ class SandboxManagerEnvConfig(BaseModel):
16
16
  )
17
17
 
18
18
  file_system: Literal["local", "oss"] = Field(
19
- ...,
19
+ "local",
20
20
  description="Type of file system to use: 'local' or 'oss'.",
21
21
  )
22
22
  storage_folder: Optional[str] = Field(
23
- "",
23
+ "runtime_sandbox_storage",
24
24
  description="Folder path in storage.",
25
25
  )
26
26
  redis_enabled: bool = Field(
27
- ...,
27
+ False,
28
28
  description="Indicates if Redis is enabled.",
29
29
  )
30
30
  container_deployment: Literal[
@@ -33,14 +33,16 @@ class SandboxManagerEnvConfig(BaseModel):
33
33
  "k8s",
34
34
  "agentrun",
35
35
  "fc",
36
+ "gvisor",
37
+ "boxlite",
36
38
  ] = Field(
37
- ...,
39
+ "docker",
38
40
  description="Container deployment backend: 'docker', 'cloud', 'k8s'"
39
- " 'agentrun' or 'fc'.",
41
+ " 'agentrun', 'fc', 'knative', or 'gvisor'.",
40
42
  )
41
43
 
42
44
  default_mount_dir: Optional[str] = Field(
43
- None,
45
+ "sessions_mount_dir",
44
46
  description="Path for local file system storage.",
45
47
  )
46
48
 
@@ -67,16 +69,16 @@ class SandboxManagerEnvConfig(BaseModel):
67
69
  description="OSS endpoint URL. Required if file_system is 'oss'.",
68
70
  )
69
71
  oss_access_key_id: Optional[str] = Field(
70
- None,
72
+ "your-access-key-id",
71
73
  description="Access key ID for OSS. Required if file_system is 'oss'.",
72
74
  )
73
75
  oss_access_key_secret: Optional[str] = Field(
74
- None,
76
+ "your-access-key-secret",
75
77
  description="Access key secret for OSS. Required if file_system is "
76
78
  "'oss'.",
77
79
  )
78
80
  oss_bucket_name: Optional[str] = Field(
79
- None,
81
+ "your-bucket-name",
80
82
  description="Bucket name in OSS. Required if file_system is 'oss'.",
81
83
  )
82
84
 
@@ -0,0 +1,106 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ ModelStudio Memory Components.
4
+
5
+ This package provides components for interacting with the ModelStudio Memory
6
+ service.
7
+
8
+ Components:
9
+ - AddMemory: Store conversation messages as memory nodes
10
+ - SearchMemory: Search for relevant memories
11
+ - ListMemory: List memory nodes with pagination
12
+ - DeleteMemory: Delete a specific memory node
13
+ - CreateProfileSchema: Create a user profile schema
14
+ - GetUserProfile: Retrieve a user profile
15
+
16
+ Schemas:
17
+ All Pydantic schemas for input/output are available in the schemas
18
+ submodule.
19
+
20
+ Exceptions:
21
+ Custom exceptions for better error handling are available in the
22
+ exceptions submodule.
23
+
24
+ Configuration:
25
+ Configuration can be managed through environment variables or by
26
+ providing a MemoryServiceConfig instance.
27
+ """
28
+
29
+ # Configuration
30
+ from .config import MemoryServiceConfig
31
+
32
+ # Exceptions
33
+ from .exceptions import (
34
+ MemoryAPIError,
35
+ MemoryAuthenticationError,
36
+ MemoryNetworkError,
37
+ MemoryNotFoundError,
38
+ MemoryValidationError,
39
+ )
40
+
41
+ # Components
42
+ from .core import (
43
+ AddMemory,
44
+ SearchMemory,
45
+ ListMemory,
46
+ DeleteMemory,
47
+ CreateProfileSchema,
48
+ GetUserProfile,
49
+ )
50
+
51
+ # Schemas - Import commonly used schemas for convenience
52
+ from .schemas import (
53
+ AddMemoryInput,
54
+ AddMemoryOutput,
55
+ CreateProfileSchemaInput,
56
+ CreateProfileSchemaOutput,
57
+ DeleteMemoryInput,
58
+ DeleteMemoryOutput,
59
+ GetUserProfileInput,
60
+ GetUserProfileOutput,
61
+ ListMemoryInput,
62
+ ListMemoryOutput,
63
+ MemoryNode,
64
+ Message,
65
+ ProfileAttribute,
66
+ SearchMemoryInput,
67
+ SearchMemoryOutput,
68
+ UserProfile,
69
+ UserProfileAttribute,
70
+ )
71
+
72
+ __all__ = [
73
+ # Core Components
74
+ "AddMemory",
75
+ "SearchMemory",
76
+ "ListMemory",
77
+ "DeleteMemory",
78
+ "CreateProfileSchema",
79
+ "GetUserProfile",
80
+ # Configuration
81
+ "MemoryServiceConfig",
82
+ # Exceptions
83
+ "MemoryAPIError",
84
+ "MemoryAuthenticationError",
85
+ "MemoryNetworkError",
86
+ "MemoryNotFoundError",
87
+ "MemoryValidationError",
88
+ # Schemas
89
+ "Message",
90
+ "MemoryNode",
91
+ "AddMemoryInput",
92
+ "AddMemoryOutput",
93
+ "SearchMemoryInput",
94
+ "SearchMemoryOutput",
95
+ "ListMemoryInput",
96
+ "ListMemoryOutput",
97
+ "DeleteMemoryInput",
98
+ "DeleteMemoryOutput",
99
+ "ProfileAttribute",
100
+ "CreateProfileSchemaInput",
101
+ "CreateProfileSchemaOutput",
102
+ "UserProfileAttribute",
103
+ "UserProfile",
104
+ "GetUserProfileInput",
105
+ "GetUserProfileOutput",
106
+ ]
@@ -0,0 +1,220 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Base class for ModelStudio Memory components.
4
+ """
5
+ import logging
6
+ from types import TracebackType
7
+ from typing import Any, Dict, Optional, Type
8
+
9
+ import aiohttp
10
+
11
+ from .config import (
12
+ MemoryServiceConfig,
13
+ )
14
+ from .exceptions import (
15
+ MemoryAPIError,
16
+ MemoryAuthenticationError,
17
+ MemoryNetworkError,
18
+ MemoryNotFoundError,
19
+ MemoryValidationError,
20
+ )
21
+
22
+ logger = logging.getLogger(__name__)
23
+
24
+
25
+ class ModelStudioMemoryBase:
26
+ """
27
+ Base class for ModelStudio Memory API components.
28
+
29
+ This class provides common functionality for all memory components,
30
+ including:
31
+ - Configuration management
32
+ - HTTP request handling with error handling
33
+ - Common headers generation
34
+ - Session management
35
+
36
+ Attributes:
37
+ config: Configuration for the memory service
38
+ """
39
+
40
+ def __init__(self, config: Optional[MemoryServiceConfig] = None):
41
+ """
42
+ Initialize the base memory component.
43
+
44
+ Args:
45
+ config: Optional configuration. If not provided, will be loaded
46
+ from environment variables.
47
+
48
+ Raises:
49
+ ValueError: If required configuration is missing
50
+ """
51
+ self.config = config or MemoryServiceConfig.from_env()
52
+ self._session: Optional[aiohttp.ClientSession] = None
53
+
54
+ def _get_headers(self) -> Dict[str, str]:
55
+ """
56
+ Get common HTTP headers for API requests.
57
+
58
+ Returns:
59
+ Dictionary of HTTP headers
60
+ """
61
+ return {
62
+ "Content-Type": "application/json",
63
+ "User-Agent": "agentscope-runtime",
64
+ "Authorization": f"Bearer {self.config.api_key}",
65
+ }
66
+
67
+ async def _get_session(self) -> aiohttp.ClientSession:
68
+ """
69
+ Get or create an aiohttp session.
70
+
71
+ Returns:
72
+ An aiohttp ClientSession
73
+ """
74
+ if self._session is None or self._session.closed:
75
+ self._session = aiohttp.ClientSession()
76
+ return self._session
77
+
78
+ async def _request(
79
+ self,
80
+ method: str,
81
+ url: str,
82
+ **kwargs: Any,
83
+ ) -> Dict[str, Any]:
84
+ """
85
+ Common HTTP request handler with comprehensive error handling.
86
+
87
+ Args:
88
+ method: HTTP method (GET, POST, DELETE, etc.)
89
+ url: Request URL
90
+ **kwargs: Additional arguments for the request
91
+
92
+ Returns:
93
+ Response JSON as dictionary
94
+
95
+ Raises:
96
+ MemoryAuthenticationError: If authentication fails (401)
97
+ MemoryNotFoundError: If resource not found (404)
98
+ MemoryAPIError: For other API errors
99
+ MemoryNetworkError: For network-related errors
100
+ """
101
+ try:
102
+ session = await self._get_session()
103
+ logger.debug(f"Making {method} request to {url}")
104
+
105
+ async with session.request(
106
+ method,
107
+ url,
108
+ headers=self._get_headers(),
109
+ **kwargs,
110
+ ) as response:
111
+ # Handle successful response
112
+ if response.status == 200:
113
+ result = await response.json()
114
+ logger.debug(
115
+ f"Request successful: {method} {url}",
116
+ )
117
+ return result
118
+
119
+ # Handle error responses (4XX, 5XX)
120
+ # Try to parse JSON error response first
121
+ error_data = None
122
+ try:
123
+ error_data = await response.json()
124
+ except Exception:
125
+ # If JSON parsing fails, fall back to text
126
+ error_text = await response.text()
127
+ error_data = {"message": error_text}
128
+
129
+ # Extract error information
130
+ error_code = error_data.get("code", "Unknown")
131
+ error_message = error_data.get("message", "Unknown error")
132
+ request_id = error_data.get("request_id", "")
133
+
134
+ # Format error log
135
+ error_log = (
136
+ f"API Error - Status: {response.status}, "
137
+ f"Code: {error_code}, Message: {error_message}, "
138
+ f"Request ID: {request_id}"
139
+ )
140
+ logger.error(error_log)
141
+
142
+ # Raise appropriate exception based on status code
143
+ if response.status in [401, 403]:
144
+ raise MemoryAuthenticationError(
145
+ error_message,
146
+ status_code=response.status,
147
+ error_code=error_code,
148
+ request_id=request_id,
149
+ )
150
+ if response.status == 404:
151
+ raise MemoryNotFoundError(
152
+ error_message,
153
+ status_code=response.status,
154
+ error_code=error_code,
155
+ request_id=request_id,
156
+ )
157
+ if response.status == 400:
158
+ raise MemoryValidationError(
159
+ error_message,
160
+ status_code=response.status,
161
+ error_code=error_code,
162
+ request_id=request_id,
163
+ )
164
+ if 400 <= response.status < 500:
165
+ # Other 4XX errors
166
+ raise MemoryValidationError(
167
+ error_message,
168
+ status_code=response.status,
169
+ error_code=error_code,
170
+ request_id=request_id,
171
+ )
172
+ raise MemoryAPIError(
173
+ error_message,
174
+ status_code=response.status,
175
+ error_code=error_code,
176
+ request_id=request_id,
177
+ )
178
+
179
+ except aiohttp.ClientError as e:
180
+ logger.exception(f"Network error: {str(e)}")
181
+ raise MemoryNetworkError(
182
+ f"Network error during {method} request to {url}: {str(e)}",
183
+ ) from e
184
+ except (
185
+ MemoryAuthenticationError,
186
+ MemoryNotFoundError,
187
+ MemoryValidationError,
188
+ MemoryAPIError,
189
+ ):
190
+ # Re-raise our custom exceptions (already have proper error info)
191
+ raise
192
+ except Exception as e:
193
+ logger.exception(f"Unexpected error: {str(e)}")
194
+ raise MemoryAPIError(
195
+ f"Unexpected error during {method} request to {url}: {str(e)}",
196
+ ) from e
197
+
198
+ async def close(self) -> None:
199
+ """
200
+ Close the HTTP session.
201
+
202
+ Should be called when the component is no longer needed to clean up
203
+ resources.
204
+ """
205
+ if self._session and not self._session.closed:
206
+ await self._session.close()
207
+ logger.debug("Session closed")
208
+
209
+ async def __aenter__(self) -> "ModelStudioMemoryBase":
210
+ """Support async context manager."""
211
+ return self
212
+
213
+ async def __aexit__(
214
+ self,
215
+ exc_type: Optional[Type[BaseException]],
216
+ exc_val: Optional[BaseException],
217
+ exc_tb: Optional[TracebackType],
218
+ ) -> None:
219
+ """Support async context manager."""
220
+ await self.close()
@@ -0,0 +1,86 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Configuration management for ModelStudio Memory service.
4
+ """
5
+ import os
6
+ from dataclasses import dataclass
7
+
8
+
9
+ # Default endpoint
10
+ DEFAULT_MEMORY_SERVICE_ENDPOINT = (
11
+ "https://dashscope.aliyuncs.com/api/v2/apps/memory"
12
+ )
13
+
14
+
15
+ @dataclass
16
+ class MemoryServiceConfig:
17
+ """
18
+ Configuration for ModelStudio Memory Service.
19
+
20
+ Attributes:
21
+ api_key: DashScope API key for authentication
22
+ service_endpoint: Base URL for the memory service API
23
+ service_id: Service identifier
24
+ """
25
+
26
+ api_key: str
27
+ service_endpoint: str = DEFAULT_MEMORY_SERVICE_ENDPOINT
28
+ service_id: str = "memory_service"
29
+
30
+ @classmethod
31
+ def from_env(cls) -> "MemoryServiceConfig":
32
+ """
33
+ Create configuration from environment variables.
34
+
35
+ Environment Variables:
36
+ DASHSCOPE_API_KEY: Required. API key for authentication
37
+ MEMORY_SERVICE_ENDPOINT: Optional. API endpoint URL
38
+ MODELSTUDIO_SERVICE_ID: Optional. Service identifier
39
+
40
+ Returns:
41
+ MemoryServiceConfig: Configuration instance
42
+
43
+ Raises:
44
+ ValueError: If DASHSCOPE_API_KEY is not set
45
+ """
46
+ api_key = os.getenv("DASHSCOPE_API_KEY")
47
+ if not api_key:
48
+ raise ValueError(
49
+ "DASHSCOPE_API_KEY environment variable is required. "
50
+ "Please set it before using ModelStudio Memory components.",
51
+ )
52
+
53
+ return cls(
54
+ api_key=api_key,
55
+ service_endpoint=os.getenv(
56
+ "MEMORY_SERVICE_ENDPOINT",
57
+ DEFAULT_MEMORY_SERVICE_ENDPOINT,
58
+ ),
59
+ service_id=os.getenv("MODELSTUDIO_SERVICE_ID", "memory_service"),
60
+ )
61
+
62
+ def get_add_memory_url(self) -> str:
63
+ """Get URL for adding memory."""
64
+ return f"{self.service_endpoint}/add"
65
+
66
+ def get_search_memory_url(self) -> str:
67
+ """Get URL for searching memory."""
68
+ return f"{self.service_endpoint}/memory_nodes/search"
69
+
70
+ def get_list_memory_url(self) -> str:
71
+ """Get URL for listing memory."""
72
+ return f"{self.service_endpoint}/memory_nodes"
73
+
74
+ def get_delete_memory_url(self, memory_node_id: str) -> str:
75
+ """Get URL for deleting a specific memory node."""
76
+ return f"{self.service_endpoint}/memory_nodes/{memory_node_id}"
77
+
78
+ def get_create_profile_schema_url(self) -> str:
79
+ """Get URL for creating profile schema."""
80
+ return f"{self.service_endpoint}/profile_schemas"
81
+
82
+ def get_user_profile_url(self, schema_id: str) -> str:
83
+ """Get URL for getting user profile."""
84
+ return (
85
+ f"{self.service_endpoint}/profile_schemas/{schema_id}/user_profile"
86
+ )