agentscope-runtime 1.0.1__py3-none-any.whl → 1.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agentscope_runtime/adapters/agentscope/message.py +32 -7
- agentscope_runtime/adapters/agentscope/stream.py +121 -91
- agentscope_runtime/adapters/agno/__init__.py +0 -0
- agentscope_runtime/adapters/agno/message.py +30 -0
- agentscope_runtime/adapters/agno/stream.py +122 -0
- agentscope_runtime/adapters/langgraph/__init__.py +12 -0
- agentscope_runtime/adapters/langgraph/message.py +257 -0
- agentscope_runtime/adapters/langgraph/stream.py +205 -0
- agentscope_runtime/cli/__init__.py +7 -0
- agentscope_runtime/cli/cli.py +63 -0
- agentscope_runtime/cli/commands/__init__.py +2 -0
- agentscope_runtime/cli/commands/chat.py +815 -0
- agentscope_runtime/cli/commands/deploy.py +1062 -0
- agentscope_runtime/cli/commands/invoke.py +58 -0
- agentscope_runtime/cli/commands/list_cmd.py +103 -0
- agentscope_runtime/cli/commands/run.py +176 -0
- agentscope_runtime/cli/commands/sandbox.py +128 -0
- agentscope_runtime/cli/commands/status.py +60 -0
- agentscope_runtime/cli/commands/stop.py +185 -0
- agentscope_runtime/cli/commands/web.py +166 -0
- agentscope_runtime/cli/loaders/__init__.py +6 -0
- agentscope_runtime/cli/loaders/agent_loader.py +295 -0
- agentscope_runtime/cli/state/__init__.py +10 -0
- agentscope_runtime/cli/utils/__init__.py +18 -0
- agentscope_runtime/cli/utils/console.py +378 -0
- agentscope_runtime/cli/utils/validators.py +118 -0
- agentscope_runtime/engine/app/agent_app.py +7 -4
- agentscope_runtime/engine/deployers/__init__.py +1 -0
- agentscope_runtime/engine/deployers/agentrun_deployer.py +152 -22
- agentscope_runtime/engine/deployers/base.py +27 -2
- agentscope_runtime/engine/deployers/kubernetes_deployer.py +158 -31
- agentscope_runtime/engine/deployers/local_deployer.py +188 -25
- agentscope_runtime/engine/deployers/modelstudio_deployer.py +109 -18
- agentscope_runtime/engine/deployers/state/__init__.py +9 -0
- agentscope_runtime/engine/deployers/state/manager.py +388 -0
- agentscope_runtime/engine/deployers/state/schema.py +96 -0
- agentscope_runtime/engine/deployers/utils/build_cache.py +736 -0
- agentscope_runtime/engine/deployers/utils/detached_app.py +105 -30
- agentscope_runtime/engine/deployers/utils/docker_image_utils/docker_image_builder.py +31 -10
- agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +15 -8
- agentscope_runtime/engine/deployers/utils/docker_image_utils/image_factory.py +30 -2
- agentscope_runtime/engine/deployers/utils/k8s_utils.py +241 -0
- agentscope_runtime/engine/deployers/utils/package.py +56 -6
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +16 -2
- agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +155 -5
- agentscope_runtime/engine/deployers/utils/wheel_packager.py +107 -123
- agentscope_runtime/engine/runner.py +25 -6
- agentscope_runtime/engine/schemas/exception.py +580 -0
- agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +113 -39
- agentscope_runtime/sandbox/box/shared/routers/mcp_utils.py +20 -4
- agentscope_runtime/sandbox/utils.py +2 -0
- agentscope_runtime/version.py +1 -1
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.2.dist-info}/METADATA +24 -7
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.2.dist-info}/RECORD +58 -28
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.2.dist-info}/entry_points.txt +1 -0
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.2.dist-info}/WHEEL +0 -0
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.2.dist-info}/licenses/LICENSE +0 -0
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.2.dist-info}/top_level.txt +0 -0
|
@@ -374,9 +374,10 @@ def message_to_agentscope_msg(
|
|
|
374
374
|
|
|
375
375
|
if message.type in (
|
|
376
376
|
MessageType.PLUGIN_CALL,
|
|
377
|
+
MessageType.MCP_TOOL_CALL,
|
|
377
378
|
MessageType.FUNCTION_CALL,
|
|
378
379
|
):
|
|
379
|
-
# convert
|
|
380
|
+
# convert CALL to ToolUseBlock
|
|
380
381
|
tool_args = None
|
|
381
382
|
for cnt in reversed(message.content):
|
|
382
383
|
if hasattr(cnt, "data"):
|
|
@@ -398,10 +399,10 @@ def message_to_agentscope_msg(
|
|
|
398
399
|
]
|
|
399
400
|
elif message.type in (
|
|
400
401
|
MessageType.PLUGIN_CALL_OUTPUT,
|
|
402
|
+
MessageType.MCP_TOOL_CALL_OUTPUT,
|
|
401
403
|
MessageType.FUNCTION_CALL_OUTPUT,
|
|
402
404
|
):
|
|
403
|
-
# convert
|
|
404
|
-
# ToolResultBlock
|
|
405
|
+
# convert CALL_OUTPUT to ToolResultBlock
|
|
405
406
|
out = None
|
|
406
407
|
raw_output = ""
|
|
407
408
|
for cnt in reversed(message.content):
|
|
@@ -425,6 +426,22 @@ def message_to_agentscope_msg(
|
|
|
425
426
|
|
|
426
427
|
if isinstance(blk, list):
|
|
427
428
|
if not all(is_valid_block(item) for item in blk):
|
|
429
|
+
try:
|
|
430
|
+
# Try to convert MCP content list to blocks
|
|
431
|
+
call_tool_result = {
|
|
432
|
+
"content": blk,
|
|
433
|
+
"structuredContent": None,
|
|
434
|
+
"isError": False,
|
|
435
|
+
}
|
|
436
|
+
blk = MCPClientBase._convert_mcp_content_to_as_blocks(
|
|
437
|
+
CallToolResult.model_validate(
|
|
438
|
+
call_tool_result,
|
|
439
|
+
).content,
|
|
440
|
+
)
|
|
441
|
+
except Exception:
|
|
442
|
+
blk = raw_output
|
|
443
|
+
elif isinstance(blk, dict):
|
|
444
|
+
if not is_valid_block(blk):
|
|
428
445
|
try:
|
|
429
446
|
# Try to convert to MCP CallToolResult then to blocks
|
|
430
447
|
blk = CallToolResult.model_validate(blk)
|
|
@@ -433,9 +450,6 @@ def message_to_agentscope_msg(
|
|
|
433
450
|
)
|
|
434
451
|
except Exception:
|
|
435
452
|
blk = raw_output
|
|
436
|
-
elif isinstance(blk, dict):
|
|
437
|
-
if not is_valid_block(blk):
|
|
438
|
-
blk = raw_output
|
|
439
453
|
else:
|
|
440
454
|
blk = raw_output
|
|
441
455
|
|
|
@@ -459,6 +473,7 @@ def message_to_agentscope_msg(
|
|
|
459
473
|
"text": (TextBlock, "text"),
|
|
460
474
|
"image": (ImageBlock, "image_url"),
|
|
461
475
|
"audio": (AudioBlock, "data"),
|
|
476
|
+
"data": (TextBlock, "data"),
|
|
462
477
|
# "video": (VideoBlock, "video_url", True),
|
|
463
478
|
# TODO: support video
|
|
464
479
|
}
|
|
@@ -533,7 +548,17 @@ def message_to_agentscope_msg(
|
|
|
533
548
|
block_cls(type=cnt_type, source=base64_source),
|
|
534
549
|
)
|
|
535
550
|
else:
|
|
536
|
-
|
|
551
|
+
# text & data
|
|
552
|
+
if isinstance(value, str):
|
|
553
|
+
msg_content.append(
|
|
554
|
+
TextBlock(type="text", text=value),
|
|
555
|
+
)
|
|
556
|
+
else:
|
|
557
|
+
try:
|
|
558
|
+
json_str = json.dumps(value, ensure_ascii=False)
|
|
559
|
+
except Exception:
|
|
560
|
+
json_str = str(value)
|
|
561
|
+
msg_content.append(TextBlock(text=json_str))
|
|
537
562
|
|
|
538
563
|
result["content"] = msg_content
|
|
539
564
|
_msg = Msg(**result)
|
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
import copy
|
|
4
4
|
import json
|
|
5
5
|
|
|
6
|
-
from typing import AsyncIterator, Tuple, List
|
|
6
|
+
from typing import AsyncIterator, Tuple, List, Union
|
|
7
7
|
from urllib.parse import urlparse
|
|
8
8
|
|
|
9
|
+
from agentscope import setup_logger
|
|
9
10
|
from agentscope.message import Msg
|
|
10
11
|
|
|
11
12
|
from ...engine.schemas.agent_schemas import (
|
|
12
13
|
Message,
|
|
14
|
+
Content,
|
|
13
15
|
TextContent,
|
|
14
16
|
ImageContent,
|
|
15
17
|
AudioContent,
|
|
@@ -21,6 +23,8 @@ from ...engine.schemas.agent_schemas import (
|
|
|
21
23
|
MessageType,
|
|
22
24
|
)
|
|
23
25
|
|
|
26
|
+
setup_logger("ERROR")
|
|
27
|
+
|
|
24
28
|
|
|
25
29
|
def _update_obj_attrs(obj, **attrs):
|
|
26
30
|
for key, value in attrs.items():
|
|
@@ -31,7 +35,7 @@ def _update_obj_attrs(obj, **attrs):
|
|
|
31
35
|
|
|
32
36
|
async def adapt_agentscope_message_stream(
|
|
33
37
|
source_stream: AsyncIterator[Tuple[Msg, bool]],
|
|
34
|
-
) -> AsyncIterator[Message]:
|
|
38
|
+
) -> AsyncIterator[Union[Message, Content]]:
|
|
35
39
|
# Initialize variables to avoid uncaught errors
|
|
36
40
|
msg_id = None
|
|
37
41
|
last_content = ""
|
|
@@ -48,6 +52,7 @@ async def adapt_agentscope_message_stream(
|
|
|
48
52
|
should_start_message = True
|
|
49
53
|
should_start_reasoning_message = True
|
|
50
54
|
tool_use_messages_dict = {}
|
|
55
|
+
tool_result_messages_dict = {}
|
|
51
56
|
index = None
|
|
52
57
|
|
|
53
58
|
# Run agent
|
|
@@ -262,95 +267,69 @@ async def adapt_agentscope_message_stream(
|
|
|
262
267
|
fc_cls = FunctionCall
|
|
263
268
|
fc_kwargs = {}
|
|
264
269
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
)
|
|
269
|
-
|
|
270
|
-
if plugin_call_message is None:
|
|
271
|
-
# Only one tool use message yields, we fake
|
|
272
|
-
# Build a new tool call message
|
|
273
|
-
plugin_call_message = Message(
|
|
274
|
-
type=msg_type,
|
|
275
|
-
role="assistant",
|
|
276
|
-
)
|
|
277
|
-
|
|
278
|
-
data_delta_content = DataContent(
|
|
279
|
-
index=0,
|
|
280
|
-
data=fc_cls(
|
|
281
|
-
call_id=element.get("id"),
|
|
282
|
-
name=element.get("name"),
|
|
283
|
-
arguments="",
|
|
284
|
-
**fc_kwargs,
|
|
285
|
-
).model_dump(),
|
|
286
|
-
delta=False,
|
|
287
|
-
)
|
|
288
|
-
|
|
289
|
-
plugin_call_message = _update_obj_attrs(
|
|
290
|
-
plugin_call_message,
|
|
291
|
-
metadata=metadata,
|
|
292
|
-
usage=usage,
|
|
293
|
-
)
|
|
294
|
-
yield plugin_call_message.in_progress()
|
|
295
|
-
yield data_delta_content.in_progress()
|
|
270
|
+
plugin_call_message = tool_use_messages_dict.get(
|
|
271
|
+
call_id,
|
|
272
|
+
)
|
|
296
273
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
274
|
+
if plugin_call_message is None:
|
|
275
|
+
# Create a new message
|
|
276
|
+
plugin_call_message = Message(
|
|
277
|
+
type=msg_type,
|
|
278
|
+
role="assistant",
|
|
300
279
|
)
|
|
301
280
|
data_delta_content = DataContent(
|
|
302
|
-
index=
|
|
281
|
+
index=0,
|
|
303
282
|
data=fc_cls(
|
|
304
|
-
call_id=element
|
|
283
|
+
call_id=element["id"],
|
|
305
284
|
name=element.get("name"),
|
|
306
|
-
arguments=
|
|
285
|
+
arguments="",
|
|
307
286
|
**fc_kwargs,
|
|
308
287
|
).model_dump(),
|
|
309
288
|
delta=False,
|
|
310
289
|
)
|
|
311
|
-
plugin_call_message.add_content(
|
|
312
|
-
new_content=data_delta_content,
|
|
313
|
-
)
|
|
314
|
-
yield data_delta_content.completed()
|
|
315
290
|
plugin_call_message = _update_obj_attrs(
|
|
316
291
|
plugin_call_message,
|
|
317
292
|
metadata=metadata,
|
|
318
293
|
usage=usage,
|
|
319
294
|
)
|
|
320
|
-
yield plugin_call_message.
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
295
|
+
yield plugin_call_message.in_progress()
|
|
296
|
+
data_delta_content.msg_id = plugin_call_message.id
|
|
297
|
+
yield data_delta_content.in_progress()
|
|
298
|
+
tool_use_messages_dict[
|
|
299
|
+
call_id
|
|
300
|
+
] = plugin_call_message
|
|
301
|
+
|
|
302
|
+
# Update arguments
|
|
303
|
+
json_str = json.dumps(
|
|
304
|
+
element.get("input"),
|
|
305
|
+
ensure_ascii=False,
|
|
306
|
+
)
|
|
307
|
+
data_delta_content = DataContent(
|
|
308
|
+
index=None if last else 0,
|
|
309
|
+
data=fc_cls(
|
|
310
|
+
call_id=element["id"],
|
|
311
|
+
name=element.get("name"),
|
|
312
|
+
arguments=json_str,
|
|
313
|
+
**fc_kwargs,
|
|
314
|
+
).model_dump(),
|
|
315
|
+
delta=False,
|
|
316
|
+
)
|
|
342
317
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
yield plugin_call_message.in_progress()
|
|
349
|
-
yield data_delta_content.in_progress()
|
|
318
|
+
plugin_call_message = _update_obj_attrs(
|
|
319
|
+
plugin_call_message,
|
|
320
|
+
metadata=metadata,
|
|
321
|
+
usage=usage,
|
|
322
|
+
)
|
|
350
323
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
324
|
+
if last:
|
|
325
|
+
plugin_call_message.add_content(
|
|
326
|
+
new_content=data_delta_content,
|
|
327
|
+
)
|
|
328
|
+
yield data_delta_content.completed()
|
|
329
|
+
yield plugin_call_message.completed()
|
|
330
|
+
else:
|
|
331
|
+
data_delta_content.msg_id = plugin_call_message.id
|
|
332
|
+
yield data_delta_content.in_progress()
|
|
354
333
|
|
|
355
334
|
elif element.get("type") == "tool_result": # Tool result
|
|
356
335
|
call_id = element.get("id")
|
|
@@ -372,35 +351,86 @@ async def adapt_agentscope_message_stream(
|
|
|
372
351
|
msg_type = MessageType.MCP_TOOL_CALL_OUTPUT
|
|
373
352
|
fc_cls = McpCallOutput
|
|
374
353
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
ensure_ascii=False,
|
|
354
|
+
plugin_output_message = tool_result_messages_dict.get(
|
|
355
|
+
call_id,
|
|
378
356
|
)
|
|
357
|
+
|
|
358
|
+
if plugin_output_message is None:
|
|
359
|
+
# Create a new message
|
|
360
|
+
plugin_output_message = Message(
|
|
361
|
+
type=msg_type,
|
|
362
|
+
role="tool",
|
|
363
|
+
)
|
|
364
|
+
data_delta_content = DataContent(
|
|
365
|
+
index=0,
|
|
366
|
+
data=fc_cls(
|
|
367
|
+
call_id=element.get("id"),
|
|
368
|
+
name=element.get("name"),
|
|
369
|
+
output="",
|
|
370
|
+
).model_dump(),
|
|
371
|
+
delta=False,
|
|
372
|
+
)
|
|
373
|
+
plugin_output_message = _update_obj_attrs(
|
|
374
|
+
plugin_output_message,
|
|
375
|
+
metadata=metadata,
|
|
376
|
+
usage=usage,
|
|
377
|
+
)
|
|
378
|
+
yield plugin_output_message.in_progress()
|
|
379
|
+
data_delta_content.msg_id = (
|
|
380
|
+
plugin_output_message.id
|
|
381
|
+
)
|
|
382
|
+
yield data_delta_content.in_progress()
|
|
383
|
+
tool_result_messages_dict[
|
|
384
|
+
call_id
|
|
385
|
+
] = plugin_output_message
|
|
386
|
+
|
|
387
|
+
# Update output
|
|
388
|
+
try:
|
|
389
|
+
json_str = json.dumps(
|
|
390
|
+
element.get("output"),
|
|
391
|
+
ensure_ascii=False,
|
|
392
|
+
)
|
|
393
|
+
except Exception:
|
|
394
|
+
# For non-JSON outputs, we just use the string
|
|
395
|
+
# representation
|
|
396
|
+
json_str = str(element.get("output"))
|
|
397
|
+
|
|
379
398
|
data_delta_content = DataContent(
|
|
380
|
-
index=
|
|
399
|
+
index=None if last else 0,
|
|
381
400
|
data=fc_cls(
|
|
382
401
|
call_id=element.get("id"),
|
|
383
402
|
name=element.get("name"),
|
|
384
403
|
output=json_str,
|
|
385
404
|
).model_dump(),
|
|
405
|
+
delta=False,
|
|
386
406
|
)
|
|
387
|
-
|
|
388
|
-
type=msg_type,
|
|
389
|
-
role="tool",
|
|
390
|
-
content=[data_delta_content],
|
|
391
|
-
)
|
|
407
|
+
|
|
392
408
|
plugin_output_message = _update_obj_attrs(
|
|
393
409
|
plugin_output_message,
|
|
394
410
|
metadata=metadata,
|
|
395
411
|
usage=usage,
|
|
396
412
|
)
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
413
|
+
|
|
414
|
+
if last:
|
|
415
|
+
plugin_output_message.add_content(
|
|
416
|
+
new_content=data_delta_content,
|
|
417
|
+
)
|
|
418
|
+
yield data_delta_content.completed()
|
|
419
|
+
yield plugin_output_message.completed()
|
|
420
|
+
|
|
421
|
+
message = Message(
|
|
422
|
+
type=MessageType.MESSAGE,
|
|
423
|
+
role="assistant",
|
|
424
|
+
)
|
|
425
|
+
should_start_message = True
|
|
426
|
+
index = None
|
|
427
|
+
|
|
428
|
+
else:
|
|
429
|
+
data_delta_content.msg_id = (
|
|
430
|
+
plugin_output_message.id
|
|
431
|
+
)
|
|
432
|
+
yield data_delta_content.in_progress()
|
|
433
|
+
|
|
404
434
|
else:
|
|
405
435
|
# TODO: handle image/audio/video block
|
|
406
436
|
if should_start_message:
|
|
File without changes
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from typing import Union, List
|
|
3
|
+
|
|
4
|
+
from agentscope.formatter import OpenAIChatFormatter
|
|
5
|
+
|
|
6
|
+
from ...engine.schemas.agent_schemas import Message
|
|
7
|
+
from ..agentscope.message import message_to_agentscope_msg
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
async def message_to_agno_message(
|
|
11
|
+
messages: Union[Message, List[Message]],
|
|
12
|
+
) -> Union[dict, List[dict]]:
|
|
13
|
+
"""
|
|
14
|
+
Convert AgentScope runtime Message(s) to Agno Message(s).
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
messages: A single AgentScope runtime Message or list of Messages.
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
A single AgnoMessage object or a list of AgnoMessage objects.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
as_msgs = message_to_agentscope_msg(messages)
|
|
24
|
+
raw_list = isinstance(as_msgs, list)
|
|
25
|
+
as_msgs = as_msgs if raw_list else [as_msgs]
|
|
26
|
+
|
|
27
|
+
formatter = OpenAIChatFormatter()
|
|
28
|
+
agno_message = await formatter.format(as_msgs)
|
|
29
|
+
|
|
30
|
+
return agno_message if raw_list else agno_message[0]
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# pylint:disable=too-many-branches,too-many-statements
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
from typing import AsyncIterator, Union
|
|
6
|
+
|
|
7
|
+
from agno.run.agent import (
|
|
8
|
+
BaseAgentRunEvent,
|
|
9
|
+
RunContentEvent,
|
|
10
|
+
RunCompletedEvent,
|
|
11
|
+
RunContentCompletedEvent,
|
|
12
|
+
RunStartedEvent,
|
|
13
|
+
# ReasoningStartedEvent, # Not support now
|
|
14
|
+
# ReasoningStepEvent,
|
|
15
|
+
# ReasoningCompletedEvent,
|
|
16
|
+
ToolCallStartedEvent,
|
|
17
|
+
ToolCallCompletedEvent,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
from ...engine.schemas.agent_schemas import (
|
|
22
|
+
Message,
|
|
23
|
+
Content,
|
|
24
|
+
DataContent,
|
|
25
|
+
FunctionCall,
|
|
26
|
+
FunctionCallOutput,
|
|
27
|
+
MessageType,
|
|
28
|
+
)
|
|
29
|
+
from ...engine.helpers.agent_api_builder import ResponseBuilder
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
async def adapt_agno_message_stream(
|
|
33
|
+
source_stream: AsyncIterator[BaseAgentRunEvent],
|
|
34
|
+
) -> AsyncIterator[Union[Message, Content]]:
|
|
35
|
+
rb = ResponseBuilder()
|
|
36
|
+
mb = None
|
|
37
|
+
cb = None
|
|
38
|
+
mb_type = None
|
|
39
|
+
|
|
40
|
+
should_start_new_message = True
|
|
41
|
+
|
|
42
|
+
async for event in source_stream:
|
|
43
|
+
if isinstance(event, RunStartedEvent):
|
|
44
|
+
should_start_new_message = True
|
|
45
|
+
elif isinstance(event, RunCompletedEvent):
|
|
46
|
+
# Placeholder
|
|
47
|
+
return
|
|
48
|
+
elif isinstance(event, RunContentEvent):
|
|
49
|
+
if event.reasoning_content:
|
|
50
|
+
message_type = MessageType.REASONING
|
|
51
|
+
content = event.reasoning_content
|
|
52
|
+
else:
|
|
53
|
+
message_type = MessageType.MESSAGE
|
|
54
|
+
content = event.content
|
|
55
|
+
|
|
56
|
+
if message_type != mb_type:
|
|
57
|
+
# Complete previous message
|
|
58
|
+
should_start_new_message = True
|
|
59
|
+
mb_type = message_type
|
|
60
|
+
if cb is not None:
|
|
61
|
+
yield cb.complete()
|
|
62
|
+
if mb is not None:
|
|
63
|
+
yield mb.complete()
|
|
64
|
+
|
|
65
|
+
if should_start_new_message:
|
|
66
|
+
should_start_new_message = False
|
|
67
|
+
mb = rb.create_message_builder(
|
|
68
|
+
message_type=message_type,
|
|
69
|
+
role="assistant",
|
|
70
|
+
)
|
|
71
|
+
yield mb.get_message_data()
|
|
72
|
+
|
|
73
|
+
cb = mb.create_content_builder(
|
|
74
|
+
content_type="text",
|
|
75
|
+
)
|
|
76
|
+
yield cb.add_text_delta(content)
|
|
77
|
+
elif isinstance(event, RunContentCompletedEvent):
|
|
78
|
+
yield cb.complete()
|
|
79
|
+
yield mb.complete()
|
|
80
|
+
mb = None
|
|
81
|
+
cb = None
|
|
82
|
+
should_start_new_message = True
|
|
83
|
+
elif isinstance(event, ToolCallStartedEvent):
|
|
84
|
+
json_str = json.dumps(event.tool.tool_args, ensure_ascii=False)
|
|
85
|
+
data = DataContent(
|
|
86
|
+
data=FunctionCall(
|
|
87
|
+
call_id=event.tool.tool_call_id,
|
|
88
|
+
name=event.tool.tool_name,
|
|
89
|
+
arguments=json_str,
|
|
90
|
+
).model_dump(),
|
|
91
|
+
)
|
|
92
|
+
# Not support streaming tool call
|
|
93
|
+
message = Message(
|
|
94
|
+
type=MessageType.PLUGIN_CALL,
|
|
95
|
+
role="assistant",
|
|
96
|
+
content=[data],
|
|
97
|
+
)
|
|
98
|
+
# No stream tool call
|
|
99
|
+
yield message.completed()
|
|
100
|
+
|
|
101
|
+
should_start_new_message = True
|
|
102
|
+
elif isinstance(event, ToolCallCompletedEvent):
|
|
103
|
+
try:
|
|
104
|
+
json_str = json.dumps(event.tool.result, ensure_ascii=False)
|
|
105
|
+
except Exception:
|
|
106
|
+
json_str = str(event.tool.result)
|
|
107
|
+
|
|
108
|
+
data = DataContent(
|
|
109
|
+
data=FunctionCallOutput(
|
|
110
|
+
name=event.tool.tool_name,
|
|
111
|
+
call_id=event.tool.tool_call_id,
|
|
112
|
+
output=json_str,
|
|
113
|
+
).model_dump(),
|
|
114
|
+
)
|
|
115
|
+
message = Message(
|
|
116
|
+
type=MessageType.PLUGIN_CALL_OUTPUT,
|
|
117
|
+
role="tool",
|
|
118
|
+
content=[data],
|
|
119
|
+
)
|
|
120
|
+
yield message.completed()
|
|
121
|
+
|
|
122
|
+
should_start_new_message = True
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""LangGraph adapter for AgentScope runtime."""
|
|
3
|
+
|
|
4
|
+
# todo Message(reasoning) Adapter
|
|
5
|
+
# todo Memory Adapter
|
|
6
|
+
# todo Sandbox Tools Adapter
|
|
7
|
+
from .message import langgraph_msg_to_message, message_to_langgraph_msg
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"langgraph_msg_to_message",
|
|
11
|
+
"message_to_langgraph_msg",
|
|
12
|
+
]
|