agentscope-runtime 1.0.4a1__py3-none-any.whl → 1.0.5.post1__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.post1.dist-info}/METADATA +187 -74
  75. {agentscope_runtime-1.0.4a1.dist-info → agentscope_runtime-1.0.5.post1.dist-info}/RECORD +79 -55
  76. {agentscope_runtime-1.0.4a1.dist-info → agentscope_runtime-1.0.5.post1.dist-info}/WHEEL +1 -1
  77. {agentscope_runtime-1.0.4a1.dist-info → agentscope_runtime-1.0.5.post1.dist-info}/entry_points.txt +0 -0
  78. {agentscope_runtime-1.0.4a1.dist-info → agentscope_runtime-1.0.5.post1.dist-info}/licenses/LICENSE +0 -0
  79. {agentscope_runtime-1.0.4a1.dist-info → agentscope_runtime-1.0.5.post1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,418 @@
1
+ # -*- coding: utf-8 -*-
2
+ # pylint: disable=too-many-branches,too-many-statements
3
+ import copy
4
+ import json
5
+
6
+ from typing import AsyncIterator, Union, List
7
+
8
+ from agent_framework import (
9
+ AgentRunResponseUpdate,
10
+ TextContent as MSTextContent,
11
+ DataContent as MSDataContent,
12
+ TextReasoningContent,
13
+ UriContent,
14
+ FunctionCallContent,
15
+ FunctionResultContent,
16
+ ErrorContent,
17
+ UsageContent,
18
+ )
19
+
20
+ from ..utils import _update_obj_attrs
21
+ from ...engine.schemas.exception import AgentRuntimeErrorException
22
+ from ...engine.schemas.agent_schemas import (
23
+ Message,
24
+ TextContent,
25
+ Content,
26
+ DataContent,
27
+ FunctionCall,
28
+ FunctionCallOutput,
29
+ MessageType,
30
+ ImageContent,
31
+ AudioContent,
32
+ FileContent,
33
+ )
34
+
35
+
36
+ async def adapt_ms_agent_framework_message_stream(
37
+ source_stream: AsyncIterator[AgentRunResponseUpdate],
38
+ ) -> AsyncIterator[Union[Message, Content]]:
39
+ # Initialize variables to avoid uncaught errors
40
+ msg_id = None
41
+ usage = None
42
+ tool_start = False
43
+ message = None
44
+ reasoning_message = None
45
+ plugin_call_message = None
46
+ call_id = None
47
+ text_delta_content = None
48
+ data_delta_content = None
49
+ index = None
50
+
51
+ # Run agent
52
+ async for msg in source_stream:
53
+ # deepcopy required to avoid modifying the original message object
54
+ # which may be used elsewhere in the streaming pipeline
55
+ msg = copy.deepcopy(msg)
56
+
57
+ assert isinstance(
58
+ msg,
59
+ AgentRunResponseUpdate,
60
+ ), f"Expected AgentRunResponseUpdate, got {type(msg)}"
61
+
62
+ # If a new message, create new Message
63
+ if msg.message_id != msg_id:
64
+ # If a new message, yield previous content
65
+ if text_delta_content is not None:
66
+ yield text_delta_content.completed()
67
+ text_delta_content = None
68
+
69
+ if data_delta_content is not None:
70
+ yield data_delta_content.completed()
71
+ data_delta_content = None
72
+
73
+ if message is not None:
74
+ message = _update_obj_attrs(
75
+ message,
76
+ usage=usage,
77
+ )
78
+
79
+ yield message.completed()
80
+ message = None
81
+
82
+ if reasoning_message is not None:
83
+ reasoning_message = _update_obj_attrs(
84
+ reasoning_message,
85
+ usage=usage,
86
+ )
87
+
88
+ yield reasoning_message.completed()
89
+ reasoning_message = None
90
+
91
+ if plugin_call_message is not None:
92
+ plugin_call_message = _update_obj_attrs(
93
+ plugin_call_message,
94
+ usage=usage,
95
+ )
96
+
97
+ yield plugin_call_message.completed()
98
+ plugin_call_message = None
99
+
100
+ index = None
101
+
102
+ # Note: Tool use content only happens in the last of messages
103
+ tool_start = False
104
+
105
+ # Cache msg id
106
+ msg_id = msg.message_id
107
+
108
+ new_blocks = []
109
+ new_tool_blocks = []
110
+ if isinstance(msg.contents, List):
111
+ for block in msg.contents:
112
+ if block.type != "function_call":
113
+ new_blocks.append(block)
114
+ else:
115
+ new_tool_blocks.append(block)
116
+ if new_tool_blocks:
117
+ if tool_start:
118
+ msg.contents = new_tool_blocks
119
+ else:
120
+ msg.contents = new_blocks
121
+ tool_start = True
122
+
123
+ else:
124
+ msg.contents = new_blocks
125
+
126
+ if not msg.contents:
127
+ continue
128
+
129
+ # msg content
130
+ content = msg.contents
131
+
132
+ for element in content:
133
+ if isinstance(element, UsageContent):
134
+ # TODO: consider keeping the same format with as
135
+ usage = element.details.to_dict()
136
+
137
+ elif isinstance(element, MSTextContent): # Text
138
+ text = element.text
139
+ if text:
140
+ if message is None:
141
+ message = Message(
142
+ role="assistant",
143
+ type=MessageType.MESSAGE,
144
+ )
145
+
146
+ index = None
147
+ message = _update_obj_attrs(
148
+ message,
149
+ usage=usage,
150
+ )
151
+ yield message.in_progress()
152
+
153
+ text_delta_content = TextContent(
154
+ delta=True,
155
+ index=index,
156
+ text=text,
157
+ )
158
+ text_delta_content = message.add_delta_content(
159
+ new_content=text_delta_content,
160
+ )
161
+ index = text_delta_content.index
162
+
163
+ # Only yield valid text
164
+ if text_delta_content.text:
165
+ yield text_delta_content
166
+
167
+ if tool_start:
168
+ text_delta_content = message.content[index]
169
+ if text_delta_content.text:
170
+ yield text_delta_content.completed()
171
+ text_delta_content = None
172
+
173
+ message = _update_obj_attrs(
174
+ message,
175
+ usage=usage,
176
+ )
177
+ yield message.completed()
178
+ message = None
179
+ index = None
180
+
181
+ elif isinstance(element, TextReasoningContent): # Thinking
182
+ reasoning = element.text
183
+ if reasoning:
184
+ if reasoning_message is None:
185
+ index = None
186
+ reasoning_message = Message(
187
+ role="assistant",
188
+ type=MessageType.REASONING,
189
+ )
190
+
191
+ reasoning_message = _update_obj_attrs(
192
+ reasoning_message,
193
+ usage=usage,
194
+ )
195
+ yield reasoning_message.in_progress()
196
+
197
+ text_delta_content = TextContent(
198
+ delta=True,
199
+ index=index,
200
+ text=reasoning,
201
+ )
202
+ text_delta_content = reasoning_message.add_delta_content(
203
+ new_content=text_delta_content,
204
+ )
205
+ index = text_delta_content.index
206
+
207
+ # Only yield valid text
208
+ if text_delta_content.text:
209
+ yield text_delta_content
210
+
211
+ if tool_start:
212
+ text_delta_content = reasoning_message.content[index]
213
+ if text_delta_content.text:
214
+ yield text_delta_content.completed()
215
+ text_delta_content = None
216
+
217
+ reasoning_message = _update_obj_attrs(
218
+ reasoning_message,
219
+ usage=usage,
220
+ )
221
+ yield reasoning_message.completed()
222
+ reasoning_message = None
223
+ index = None
224
+
225
+ elif isinstance(element, FunctionCallContent): # Tool use
226
+ msg_type = MessageType.PLUGIN_CALL
227
+ fc_cls = FunctionCall
228
+ fc_kwargs = {}
229
+
230
+ if element.call_id is not None: # New tool call
231
+ index = None
232
+ call_id = element.call_id
233
+ plugin_call_message = Message(
234
+ type=msg_type,
235
+ role="assistant",
236
+ )
237
+ plugin_call_message = _update_obj_attrs(
238
+ plugin_call_message,
239
+ usage=usage,
240
+ )
241
+ yield plugin_call_message.in_progress()
242
+ else:
243
+ # The last plugin_call_message is completed
244
+ if data_delta_content is not None:
245
+ yield data_delta_content.completed()
246
+ data_delta_content = None
247
+ if plugin_call_message is not None:
248
+ plugin_call_message = _update_obj_attrs(
249
+ plugin_call_message,
250
+ usage=usage,
251
+ )
252
+ yield plugin_call_message.completed()
253
+ plugin_call_message = None
254
+ index = None
255
+
256
+ data_delta_content = DataContent(
257
+ index=index,
258
+ data=fc_cls(
259
+ call_id=call_id,
260
+ name=element.name,
261
+ arguments=element.arguments,
262
+ **fc_kwargs,
263
+ ).model_dump(),
264
+ delta=True,
265
+ msg_id=plugin_call_message.id,
266
+ )
267
+ yield data_delta_content.in_progress()
268
+
269
+ plugin_call_message = _update_obj_attrs(
270
+ plugin_call_message,
271
+ usage=usage,
272
+ )
273
+ yield plugin_call_message.in_progress()
274
+
275
+ elif isinstance(element, FunctionResultContent): # Tool result
276
+ try:
277
+ json_str = json.dumps(
278
+ element.result,
279
+ ensure_ascii=False,
280
+ )
281
+ except Exception:
282
+ json_str = str(element.result)
283
+
284
+ data_delta_content = DataContent(
285
+ index=None,
286
+ data=FunctionCallOutput(
287
+ call_id=element.call_id,
288
+ output=json_str,
289
+ ).model_dump(),
290
+ )
291
+ plugin_output_message = Message(
292
+ type=MessageType.PLUGIN_CALL_OUTPUT,
293
+ role="tool",
294
+ content=[data_delta_content],
295
+ )
296
+ plugin_output_message = _update_obj_attrs(
297
+ plugin_output_message,
298
+ usage=usage,
299
+ )
300
+ yield plugin_output_message.completed()
301
+ message = None
302
+ reasoning_message = None
303
+
304
+ index = None
305
+
306
+ elif isinstance(element, MSDataContent):
307
+ delta_content = DataContent(
308
+ delta=True,
309
+ index=index,
310
+ data=element.uri,
311
+ type=element.type,
312
+ )
313
+ delta_content = message.add_delta_content(
314
+ new_content=delta_content,
315
+ )
316
+ index = delta_content.index
317
+ yield delta_content
318
+
319
+ elif isinstance(element, UriContent):
320
+ kwargs = {}
321
+
322
+ if "image" in element.type:
323
+ cnt_cls = ImageContent
324
+ kwargs.update(
325
+ {
326
+ "type": element.type,
327
+ "image_url": element.uri,
328
+ },
329
+ )
330
+ elif "audio" in element.type:
331
+ cnt_cls = AudioContent
332
+ kwargs.update(
333
+ {
334
+ "type": element.type,
335
+ "data": element.uri,
336
+ "format": element.media_type,
337
+ },
338
+ )
339
+ elif "video" in element.type:
340
+ # TODO: support video type
341
+ cnt_cls = ImageContent
342
+ kwargs.update(
343
+ {
344
+ "type": element.media_type,
345
+ "image_url": element.uri,
346
+ },
347
+ )
348
+ else:
349
+ cnt_cls = FileContent
350
+ kwargs.update(
351
+ {
352
+ "type": element.type,
353
+ "file_url": element.uri,
354
+ },
355
+ )
356
+
357
+ delta_content = cnt_cls(
358
+ delta=False,
359
+ index=index,
360
+ **kwargs,
361
+ )
362
+ delta_content = message.add_delta_content(
363
+ new_content=delta_content,
364
+ )
365
+ index = delta_content.index
366
+ yield delta_content
367
+
368
+ elif isinstance(element, ErrorContent):
369
+ raise AgentRuntimeErrorException(
370
+ code=element.error_code,
371
+ message=element.message,
372
+ details=element.details,
373
+ )
374
+
375
+ else:
376
+ raise ValueError(f"Unknown element type: {type(element)}")
377
+
378
+ if (
379
+ text_delta_content is not None
380
+ and text_delta_content.status == "in_progress"
381
+ ):
382
+ yield text_delta_content.completed()
383
+
384
+ if (
385
+ data_delta_content is not None
386
+ and data_delta_content.status == "in_progress"
387
+ ):
388
+ yield data_delta_content.completed()
389
+
390
+ if message is not None and message.status == "in_progress":
391
+ message = _update_obj_attrs(
392
+ message,
393
+ usage=usage,
394
+ )
395
+
396
+ yield message.completed()
397
+
398
+ if (
399
+ reasoning_message is not None
400
+ and reasoning_message.status == "in_progress"
401
+ ):
402
+ reasoning_message = _update_obj_attrs(
403
+ reasoning_message,
404
+ usage=usage,
405
+ )
406
+
407
+ yield reasoning_message.completed()
408
+
409
+ if (
410
+ plugin_call_message is not None
411
+ and plugin_call_message.status == "in_progress"
412
+ ):
413
+ plugin_call_message = _update_obj_attrs(
414
+ plugin_call_message,
415
+ usage=usage,
416
+ )
417
+
418
+ yield plugin_call_message.completed()
@@ -0,0 +1,6 @@
1
+ # -*- coding: utf-8 -*-
2
+ def _update_obj_attrs(obj, **attrs):
3
+ for key, value in attrs.items():
4
+ if hasattr(obj, key):
5
+ setattr(obj, key, value)
6
+ return obj