agentscope-runtime 1.0.4a1__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 (79) hide show
  1. agentscope_runtime/adapters/agentscope/stream.py +2 -8
  2. agentscope_runtime/adapters/langgraph/stream.py +120 -70
  3. agentscope_runtime/adapters/ms_agent_framework/__init__.py +0 -0
  4. agentscope_runtime/adapters/ms_agent_framework/message.py +205 -0
  5. agentscope_runtime/adapters/ms_agent_framework/stream.py +418 -0
  6. agentscope_runtime/adapters/utils.py +6 -0
  7. agentscope_runtime/cli/commands/deploy.py +836 -1
  8. agentscope_runtime/cli/commands/stop.py +16 -0
  9. agentscope_runtime/common/container_clients/__init__.py +52 -0
  10. agentscope_runtime/common/container_clients/agentrun_client.py +6 -4
  11. agentscope_runtime/common/container_clients/boxlite_client.py +442 -0
  12. agentscope_runtime/common/container_clients/docker_client.py +0 -20
  13. agentscope_runtime/common/container_clients/fc_client.py +6 -4
  14. agentscope_runtime/common/container_clients/gvisor_client.py +38 -0
  15. agentscope_runtime/common/container_clients/knative_client.py +467 -0
  16. agentscope_runtime/common/utils/deprecation.py +164 -0
  17. agentscope_runtime/engine/__init__.py +4 -0
  18. agentscope_runtime/engine/app/agent_app.py +16 -4
  19. agentscope_runtime/engine/constant.py +1 -0
  20. agentscope_runtime/engine/deployers/__init__.py +34 -11
  21. agentscope_runtime/engine/deployers/adapter/__init__.py +8 -0
  22. agentscope_runtime/engine/deployers/adapter/a2a/__init__.py +26 -51
  23. agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +23 -13
  24. agentscope_runtime/engine/deployers/adapter/a2a/a2a_registry.py +4 -201
  25. agentscope_runtime/engine/deployers/adapter/a2a/nacos_a2a_registry.py +152 -25
  26. agentscope_runtime/engine/deployers/adapter/agui/__init__.py +8 -0
  27. agentscope_runtime/engine/deployers/adapter/agui/agui_adapter_utils.py +652 -0
  28. agentscope_runtime/engine/deployers/adapter/agui/agui_protocol_adapter.py +225 -0
  29. agentscope_runtime/engine/deployers/agentrun_deployer.py +2 -2
  30. agentscope_runtime/engine/deployers/fc_deployer.py +1506 -0
  31. agentscope_runtime/engine/deployers/knative_deployer.py +290 -0
  32. agentscope_runtime/engine/deployers/pai_deployer.py +2335 -0
  33. agentscope_runtime/engine/deployers/utils/net_utils.py +37 -0
  34. agentscope_runtime/engine/deployers/utils/oss_utils.py +38 -0
  35. agentscope_runtime/engine/deployers/utils/package.py +46 -42
  36. agentscope_runtime/engine/helpers/agent_api_client.py +372 -0
  37. agentscope_runtime/engine/runner.py +13 -0
  38. agentscope_runtime/engine/schemas/agent_schemas.py +9 -3
  39. agentscope_runtime/engine/services/agent_state/__init__.py +7 -0
  40. agentscope_runtime/engine/services/memory/__init__.py +7 -0
  41. agentscope_runtime/engine/services/memory/redis_memory_service.py +15 -16
  42. agentscope_runtime/engine/services/session_history/__init__.py +7 -0
  43. agentscope_runtime/engine/tracing/local_logging_handler.py +2 -3
  44. agentscope_runtime/engine/tracing/wrapper.py +18 -4
  45. agentscope_runtime/sandbox/__init__.py +14 -6
  46. agentscope_runtime/sandbox/box/base/__init__.py +2 -2
  47. agentscope_runtime/sandbox/box/base/base_sandbox.py +51 -1
  48. agentscope_runtime/sandbox/box/browser/__init__.py +2 -2
  49. agentscope_runtime/sandbox/box/browser/browser_sandbox.py +198 -2
  50. agentscope_runtime/sandbox/box/filesystem/__init__.py +2 -2
  51. agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +99 -2
  52. agentscope_runtime/sandbox/box/gui/__init__.py +2 -2
  53. agentscope_runtime/sandbox/box/gui/gui_sandbox.py +117 -1
  54. agentscope_runtime/sandbox/box/mobile/__init__.py +2 -2
  55. agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +247 -100
  56. agentscope_runtime/sandbox/box/sandbox.py +102 -65
  57. agentscope_runtime/sandbox/box/shared/routers/generic.py +36 -29
  58. agentscope_runtime/sandbox/client/__init__.py +6 -1
  59. agentscope_runtime/sandbox/client/async_http_client.py +339 -0
  60. agentscope_runtime/sandbox/client/base.py +74 -0
  61. agentscope_runtime/sandbox/client/http_client.py +108 -329
  62. agentscope_runtime/sandbox/enums.py +7 -0
  63. agentscope_runtime/sandbox/manager/sandbox_manager.py +275 -29
  64. agentscope_runtime/sandbox/manager/server/app.py +7 -1
  65. agentscope_runtime/sandbox/manager/server/config.py +3 -1
  66. agentscope_runtime/sandbox/model/manager_config.py +11 -9
  67. agentscope_runtime/tools/modelstudio_memory/__init__.py +106 -0
  68. agentscope_runtime/tools/modelstudio_memory/base.py +220 -0
  69. agentscope_runtime/tools/modelstudio_memory/config.py +86 -0
  70. agentscope_runtime/tools/modelstudio_memory/core.py +594 -0
  71. agentscope_runtime/tools/modelstudio_memory/exceptions.py +60 -0
  72. agentscope_runtime/tools/modelstudio_memory/schemas.py +253 -0
  73. agentscope_runtime/version.py +1 -1
  74. {agentscope_runtime-1.0.4a1.dist-info → agentscope_runtime-1.0.5.dist-info}/METADATA +186 -73
  75. {agentscope_runtime-1.0.4a1.dist-info → agentscope_runtime-1.0.5.dist-info}/RECORD +79 -55
  76. {agentscope_runtime-1.0.4a1.dist-info → agentscope_runtime-1.0.5.dist-info}/WHEEL +0 -0
  77. {agentscope_runtime-1.0.4a1.dist-info → agentscope_runtime-1.0.5.dist-info}/entry_points.txt +0 -0
  78. {agentscope_runtime-1.0.4a1.dist-info → agentscope_runtime-1.0.5.dist-info}/licenses/LICENSE +0 -0
  79. {agentscope_runtime-1.0.4a1.dist-info → agentscope_runtime-1.0.5.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,10 @@
1
1
  # -*- coding: utf-8 -*-
2
+ from functools import lru_cache
2
3
  import ipaddress
3
4
  import os
4
5
  import socket
5
6
  from typing import Optional
7
+ from urllib import parse
6
8
 
7
9
  import psutil
8
10
 
@@ -63,3 +65,38 @@ def get_first_non_loopback_ip() -> Optional[str]:
63
65
  pass
64
66
 
65
67
  return None
68
+
69
+
70
+ @lru_cache()
71
+ def is_tcp_reachable(
72
+ endpoint: str,
73
+ port: int = None,
74
+ timeout: int = 1,
75
+ ) -> bool:
76
+ """Check if a domain is connectable, intelligently determining the port."""
77
+
78
+ parsed_url = parse.urlparse(endpoint)
79
+
80
+ scheme = parsed_url.scheme or "http"
81
+ hostname = parsed_url.hostname or endpoint
82
+
83
+ if not hostname:
84
+ return False
85
+
86
+ if port is not None:
87
+ port_to_use = port
88
+ elif scheme == "https":
89
+ port_to_use = 443
90
+ else:
91
+ port_to_use = 80
92
+
93
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
94
+ sock.settimeout(timeout)
95
+ try:
96
+ ip = socket.gethostbyname(hostname)
97
+ sock.connect((ip, port_to_use))
98
+ return True
99
+ except (socket.timeout, socket.gaierror, socket.error):
100
+ return False
101
+ finally:
102
+ sock.close()
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8 -*-
2
+ import logging
3
+ from typing import Optional, Tuple
4
+ from urllib import parse
5
+
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+
10
+ def parse_oss_uri(oss_uri: str) -> Tuple[str, Optional[str], str]:
11
+ """
12
+ Parse the oss uri to the format of
13
+ ("<bucket_name>", <endpoint>, <object_key>)
14
+
15
+ Example:
16
+ oss://my-bucket.oss-cn-hangzhou.aliyuncs.com/my-object-key
17
+ -> ("my-bucket", "oss-cn-hangzhou.aliyuncs.com", "my-object-key")
18
+
19
+ oss://my-bucket/my-object-key
20
+ -> ("my-bucket", None, "my-object-key")
21
+
22
+ Args:
23
+ oss_uri: The OSS URI to parse
24
+
25
+ Returns:
26
+ A tuple of (bucket_name, endpoint, object_key)
27
+ """
28
+ parsed_result = parse.urlparse(oss_uri)
29
+ if parsed_result.scheme != "oss":
30
+ raise ValueError(f"require oss uri but given '{oss_uri}'")
31
+ hostname = parsed_result.hostname
32
+ if hostname and "." in hostname:
33
+ bucket_name, endpoint = hostname.split(".", 1)
34
+ else:
35
+ bucket_name = hostname
36
+ endpoint = None
37
+ object_key = parsed_result.path
38
+ return bucket_name, endpoint, object_key.lstrip("/")
@@ -593,60 +593,64 @@ def package(
593
593
  Package an AgentApp or Runner for deployment.
594
594
 
595
595
  This function supports two deployment patterns:
596
+
596
597
  1. Object-style: package(app=my_app) or package(runner=my_runner)
597
- 2. Entrypoint-style: package(entrypoint="app.py") or package(
598
- entrypoint="project_dir/")
598
+ 2. Entrypoint-style: package(entrypoint="app.py") or
599
+ package(entrypoint="project_dir/")
599
600
 
600
601
  For object-style deployment, this function will:
601
- 1. Extract the project directory containing the app/runner
602
- 2. Generate a new main.py that imports and runs the app/runner
603
- 3. Package the project with the generated main.py as entrypoint
602
+
603
+ 1. Extract the project directory containing the app/runner.
604
+ 2. Generate a new main.py that imports and runs the app/runner.
605
+ 3. Package the project with the generated main.py as entrypoint.
604
606
 
605
607
  Build directory naming:
608
+
606
609
  - When output_dir=None (default), creates workspace directory with
607
- platform-aware naming
608
- - Directory format: cwd/.agentscope_runtime/builds/<platform>_
609
- <timestamp>_<code>/
610
- - Explicit output_dir uses the provided path
610
+ platform-aware naming.
611
+ - Directory format: cwd/.agentscope_runtime/builds/
612
+ <platform>_<timestamp>_<code>/
613
+ - Explicit output_dir uses the provided path.
611
614
 
612
615
  Args:
613
- app: AgentApp instance (for object-style deployment)
614
- runner: Runner instance (for object-style deployment)
615
- entrypoint: Entrypoint specification (for CLI-style deployment)
616
- output_dir: Output directory (creates temp dir if None)
617
- host: Default host for the service (default: "0.0.0.0")
618
- port: Default port for the service (default: 8090)
619
- extra_parameters: Additional runtime parameters to expose via CLI
620
- requirements: Additional pip requirements
621
- platform: Deployment platform (k8s, modelstudio, agentrun, local)
622
- **kwargs: Additional keyword arguments (ignored)
616
+ app: AgentApp instance (for object-style deployment).
617
+ runner: Runner instance (for object-style deployment).
618
+ entrypoint: Entrypoint specification (for CLI-style deployment).
619
+ output_dir: Output directory (creates temp dir if None).
620
+ host: Default host for the service (default: "0.0.0.0").
621
+ port: Default port for the service (default: 8090).
622
+ extra_parameters: Additional runtime parameters to expose via CLI.
623
+ requirements: Additional pip requirements.
624
+ platform: Deployment platform (k8s, modelstudio, agentrun, local).
625
+ **kwargs: Additional keyword arguments (ignored).
623
626
 
624
627
  Returns:
625
- Tuple of (package_path, project_info)
626
- - package_path: Path to the deployment package directory
627
- - project_info: ProjectInfo with project metadata
628
+ Tuple of (package_path, project_info).
628
629
 
629
- Raises:
630
- ValueError: If neither app/runner nor entrypoint is provided
631
- RuntimeError: If packaging fails
630
+ - package_path: Path to the deployment package directory.
631
+ - project_info: ProjectInfo with project metadata.
632
632
 
633
- Example:
634
- >>> # Package with extra parameters
635
- >>> extra_params = [
636
- ... RuntimeParameter(
637
- ... name="log_level",
638
- ... type="str",
639
- ... default="info",
640
- ... help="Logging level"
641
- ... ),
642
- ... RuntimeParameter(
643
- ... name="workers",
644
- ... type="int",
645
- ... default=4,
646
- ... help="Number of worker threads"
647
- ... ),
648
- ... ]
649
- >>> package(app=my_app, extra_parameters=extra_params, platform="k8s")
633
+ Raises:
634
+ ValueError: If neither app/runner nor entrypoint is provided.
635
+ RuntimeError: If packaging fails.
636
+
637
+ Example::
638
+
639
+ extra_params = [
640
+ RuntimeParameter(
641
+ name="log_level",
642
+ type="str",
643
+ default="info",
644
+ help="Logging level",
645
+ ),
646
+ RuntimeParameter(
647
+ name="workers",
648
+ type="int",
649
+ default=4,
650
+ help="Number of worker threads",
651
+ ),
652
+ ]
653
+ package(app=my_app, extra_parameters=extra_params, platform="k8s")
650
654
  """
651
655
  # Determine project info and target object
652
656
  target_obj = None
@@ -0,0 +1,372 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Agent API Protocol Client Library.
4
+ """
5
+
6
+ import json
7
+ import logging
8
+ from abc import ABC, abstractmethod
9
+ from typing import AsyncIterator, Dict, Iterator, Optional
10
+
11
+ import httpx
12
+
13
+ from agentscope_runtime.engine.schemas.agent_schemas import (
14
+ AgentRequest,
15
+ AgentResponse,
16
+ Content,
17
+ DataContent,
18
+ Event,
19
+ ImageContent,
20
+ Message,
21
+ TextContent,
22
+ )
23
+
24
+ logger = logging.getLogger(__name__)
25
+
26
+
27
+ class AgentAPIClientBase(ABC):
28
+ """
29
+ Abstract base class for Agent API Protocol clients.
30
+
31
+ All Agent API clients must implement this interface, which defines
32
+ the core method for streaming requests and responses according to
33
+ the Agent API Protocol.
34
+ """
35
+
36
+ @abstractmethod
37
+ def stream(self, request: AgentRequest) -> Iterator[Event]:
38
+ """
39
+ Send a request and stream the response events (synchronous).
40
+
41
+ Args:
42
+ request: AgentRequest object
43
+
44
+ Yields:
45
+ Event objects (Message, Content, AgentResponse, etc.)
46
+
47
+ Raises:
48
+ Exception: If the request fails
49
+ """
50
+ raise NotImplementedError
51
+
52
+ @abstractmethod
53
+ async def astream(self, request: AgentRequest) -> AsyncIterator[Event]:
54
+ """
55
+ Send a request and stream the response events (asynchronous).
56
+
57
+ Args:
58
+ request: AgentRequest object
59
+
60
+ Yields:
61
+ Event objects (Message, Content, AgentResponse, etc.)
62
+
63
+ Raises:
64
+ Exception: If the request fails
65
+ """
66
+ raise NotImplementedError
67
+ # Make this an async generator for proper type checking
68
+ yield # pylint: disable=unreachable
69
+
70
+
71
+ # ============================================================================
72
+ # HTTP Implementation
73
+ # ============================================================================
74
+
75
+
76
+ def parse_sse_line_bytes(line: bytes) -> tuple[Optional[str], Optional[str]]:
77
+ """
78
+ Parse a single SSE (Server-Sent Events) line from bytes.
79
+
80
+ Args:
81
+ line: SSE line as bytes
82
+
83
+ Returns:
84
+ Tuple of (field, value) where field can be 'data', 'event',
85
+ 'id', or 'retry'
86
+ """
87
+ line_str = line.decode("utf-8").strip()
88
+ return parse_sse_line(line_str)
89
+
90
+
91
+ def parse_sse_line(line: str) -> tuple[Optional[str], Optional[str]]:
92
+ """
93
+ Parse a single SSE (Server-Sent Events) line.
94
+
95
+ Args:
96
+ line: SSE line string (already decoded from bytes)
97
+
98
+ Returns:
99
+ Tuple of (field, value) where field can be 'data', 'event',
100
+ 'id', or 'retry'
101
+ """
102
+ line_str = line.strip()
103
+ if line_str.startswith("data: "):
104
+ return "data", line_str[6:]
105
+ elif line_str.startswith("event:"):
106
+ return "event", line_str[7:].strip()
107
+ elif line_str.startswith("id: "):
108
+ return "id", line_str[4:].strip()
109
+ elif line_str.startswith("retry:"):
110
+ return "retry", line_str[7:].strip()
111
+ return None, None
112
+
113
+
114
+ def parse_event_from_json(data: Dict) -> Optional[Event]:
115
+ """
116
+ Parse an Event object from JSON data according to Agent API Protocol.
117
+
118
+ Args:
119
+ data: Parsed JSON response data
120
+
121
+ Returns:
122
+ Event object (Message, Content, or AgentResponse) if valid,
123
+ None otherwise
124
+ """
125
+ try:
126
+ obj_type = data.get("object")
127
+
128
+ if obj_type == "response":
129
+ return AgentResponse(**data)
130
+ if obj_type == "message":
131
+ return Message(**data)
132
+ if obj_type == "content":
133
+ content_type = data.get("type", "")
134
+ content_class_map = {
135
+ "text": TextContent,
136
+ "image": ImageContent,
137
+ "data": DataContent,
138
+ }
139
+ content_class = content_class_map.get(content_type, Content)
140
+ return content_class(**data)
141
+ # Unknown object type, return as generic event if it has
142
+ # required fields
143
+ if "object" in data:
144
+ return Event(**data)
145
+ return None
146
+ except Exception as e:
147
+ logger.warning(
148
+ "Failed to parse event from JSON: %s, error: %s",
149
+ data,
150
+ e,
151
+ )
152
+ return None
153
+
154
+
155
+ class HTTPAgentAPIClient(AgentAPIClientBase):
156
+ """
157
+ HTTP/SSE implementation of Agent API Protocol client.
158
+
159
+ This client uses HTTP POST with Server-Sent Events (SSE) for streaming
160
+ responses from Agent API Protocol endpoints.
161
+
162
+ Attributes:
163
+ endpoint: API endpoint URL
164
+ token: Optional authorization token
165
+ timeout: Request timeout in seconds
166
+ headers: Additional custom headers
167
+ """
168
+
169
+ def __init__(
170
+ self,
171
+ endpoint: str,
172
+ token: Optional[str] = None,
173
+ timeout: float = 300.0,
174
+ headers: Optional[Dict[str, str]] = None,
175
+ ):
176
+ """
177
+ Initialize HTTP Agent API client.
178
+
179
+ Args:
180
+ endpoint: API endpoint URL
181
+ (e.g., "https://api.example.com/process")
182
+ token: Optional authorization token (Bearer token)
183
+ timeout: Request timeout in seconds (default: 300)
184
+ headers: Optional additional custom headers
185
+ """
186
+ self.endpoint = endpoint
187
+ self.token = token
188
+ self.timeout = timeout
189
+ self.headers = headers or {}
190
+
191
+ def _prepare_headers(self) -> Dict[str, str]:
192
+ """Prepare HTTP headers for the request."""
193
+ headers = {
194
+ "Content-Type": "application/json",
195
+ "Accept": "text/event-stream",
196
+ "Cache-Control": "no-cache",
197
+ }
198
+
199
+ # Add custom headers
200
+ headers.update(self.headers)
201
+
202
+ # Add authorization if token is provided
203
+ if self.token:
204
+ headers["Authorization"] = f"Bearer {self.token}"
205
+
206
+ return headers
207
+
208
+ def stream(self, request: AgentRequest) -> Iterator[Event]:
209
+ """
210
+ Send a request and stream the response events (synchronous).
211
+
212
+ Args:
213
+ request: AgentRequest object
214
+
215
+ Yields:
216
+ Event objects (Message, Content, AgentResponse, etc.)
217
+
218
+ Raises:
219
+ requests.exceptions.RequestException: If the HTTP request fails
220
+ """
221
+ import requests
222
+
223
+ headers = self._prepare_headers()
224
+ payload = request.model_dump(exclude_none=True)
225
+
226
+ try:
227
+ response = requests.post(
228
+ self.endpoint,
229
+ json=payload,
230
+ headers=headers,
231
+ stream=True,
232
+ timeout=self.timeout,
233
+ )
234
+ response.raise_for_status()
235
+
236
+ # Parse SSE stream
237
+ for line in response.iter_lines():
238
+ if not line:
239
+ continue
240
+ field, value = parse_sse_line_bytes(line)
241
+ if field != "data" or not value:
242
+ continue
243
+ try:
244
+ data = json.loads(value)
245
+ event = parse_event_from_json(data)
246
+ if event:
247
+ yield event
248
+ except json.JSONDecodeError:
249
+ logger.debug("Failed to parse JSON: %s", value)
250
+
251
+ except requests.exceptions.RequestException as e:
252
+ logger.error("HTTP request failed: %s", e)
253
+ raise
254
+
255
+ async def astream(self, request: AgentRequest) -> AsyncIterator[Event]:
256
+ """
257
+ Send a request and stream the response events (asynchronous).
258
+
259
+ Args:
260
+ request: AgentRequest object
261
+
262
+ Yields:
263
+ Event objects (Message, Content, AgentResponse, etc.)
264
+
265
+ Raises:
266
+ httpx.HTTPError: If the HTTP request fails
267
+ """
268
+ headers = self._prepare_headers()
269
+ payload = request.model_dump(exclude_none=True)
270
+
271
+ try:
272
+ async with httpx.AsyncClient(timeout=self.timeout) as client:
273
+ async with client.stream(
274
+ "POST",
275
+ self.endpoint,
276
+ json=payload,
277
+ headers=headers,
278
+ ) as response:
279
+ # chunks = ""
280
+
281
+ # async for c in response.aiter_bytes():
282
+ # if c:
283
+ # chunks += c.decode("utf-8")
284
+ # print(chunks)
285
+
286
+ response.raise_for_status()
287
+
288
+ # Parse SSE stream
289
+ async for line in response.aiter_lines():
290
+ if not line:
291
+ continue
292
+ field, value = parse_sse_line(line)
293
+ if field != "data" or not value:
294
+ continue
295
+ try:
296
+ data = json.loads(value)
297
+ event = parse_event_from_json(data)
298
+ if event:
299
+ yield event
300
+ except json.JSONDecodeError:
301
+ logger.debug(
302
+ "Failed to parse JSON: %s",
303
+ value,
304
+ )
305
+
306
+ except httpx.HTTPError as e:
307
+ logger.error("HTTP request failed: %s", e)
308
+ raise
309
+
310
+
311
+ # ============================================================================
312
+ # Convenience Utilities
313
+ # ============================================================================
314
+
315
+
316
+ def extract_text_from_event(event: Event) -> Optional[str]:
317
+ """
318
+ Extract text content from an Event.
319
+
320
+ Args:
321
+ event: Event object
322
+
323
+ Returns:
324
+ Text string if the event contains text content, None otherwise
325
+ """
326
+ if isinstance(event, TextContent):
327
+ return event.text
328
+ elif isinstance(event, Message):
329
+ # Extract text from completed messages
330
+ if event.status == "completed" and event.content:
331
+ texts = []
332
+ for content_item in event.content:
333
+ if isinstance(content_item, TextContent) and content_item.text:
334
+ texts.append(content_item.text)
335
+ return "".join(texts) if texts else None
336
+ return None
337
+
338
+
339
+ def create_simple_text_request(
340
+ query: str,
341
+ session_id: Optional[str] = None,
342
+ **kwargs,
343
+ ) -> AgentRequest:
344
+ """
345
+ Create a simple AgentRequest with a text query.
346
+
347
+ Args:
348
+ query: User query text
349
+ session_id: Optional session ID for conversation continuity
350
+ **kwargs: Additional parameters for AgentRequest
351
+
352
+ Returns:
353
+ AgentRequest object
354
+ """
355
+ message = Message(
356
+ role="user",
357
+ type="message",
358
+ content=[TextContent(type="text", text=query)],
359
+ )
360
+
361
+ request_params = {
362
+ "input": [message],
363
+ "stream": True,
364
+ }
365
+
366
+ if session_id:
367
+ request_params["session_id"] = session_id
368
+
369
+ # Merge with any additional parameters
370
+ request_params.update(kwargs)
371
+
372
+ return AgentRequest(**request_params)
@@ -236,6 +236,7 @@ class Runner:
236
236
 
237
237
  query_kwargs = {
238
238
  "request": request,
239
+ "response": response,
239
240
  }
240
241
 
241
242
  if self.framework_type == "text":
@@ -272,6 +273,18 @@ class Runner:
272
273
  kwargs.update(
273
274
  {"msgs": await message_to_agno_message(request.input)},
274
275
  )
276
+ elif self.framework_type == "ms_agent_framework":
277
+ from ..adapters.ms_agent_framework.stream import (
278
+ adapt_ms_agent_framework_message_stream,
279
+ )
280
+ from ..adapters.ms_agent_framework.message import (
281
+ message_to_ms_agent_framework_message,
282
+ )
283
+
284
+ stream_adapter = adapt_ms_agent_framework_message_stream
285
+ kwargs.update(
286
+ {"msgs": message_to_ms_agent_framework_message(request.input)},
287
+ )
275
288
  # TODO: support other frameworks
276
289
  else:
277
290
 
@@ -622,15 +622,17 @@ class Message(Event):
622
622
 
623
623
  # new content
624
624
  if new_content.index is None:
625
+ content_index = len(self.content)
625
626
  copy = deepcopy(new_content)
626
627
  copy.delta = None
627
- copy.index = None
628
- copy.msg_id = None
628
+ copy.index = content_index
629
+ copy.msg_id = self.id
629
630
  self.content.append(copy)
630
631
 
631
- new_content.index = len(self.content) - 1
632
+ new_content.index = content_index
632
633
  new_content.msg_id = self.id
633
634
  new_content.in_progress()
635
+
634
636
  return new_content
635
637
 
636
638
  # delta content
@@ -869,6 +871,10 @@ class BaseResponse(Event):
869
871
  self.output = self.output or []
870
872
  self.output.append(message)
871
873
 
874
+ def completed(self) -> Self:
875
+ self.completed_at = int(datetime.now().timestamp())
876
+ return super().completed()
877
+
872
878
 
873
879
  class AgentResponse(BaseResponse):
874
880
  """agent response"""
@@ -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.session",
10
+ )
4
11
 
5
12
  if TYPE_CHECKING:
6
13
  from .state_service import StateService, InMemoryStateService
@@ -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 .memory_service import MemoryService, InMemoryMemoryService