agentscope-runtime 1.0.5.post1__py3-none-any.whl → 1.1.0b2__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 (71) hide show
  1. agentscope_runtime/__init__.py +3 -0
  2. agentscope_runtime/adapters/agentscope/message.py +36 -295
  3. agentscope_runtime/adapters/agentscope/stream.py +89 -2
  4. agentscope_runtime/adapters/agno/message.py +11 -2
  5. agentscope_runtime/adapters/agno/stream.py +1 -0
  6. agentscope_runtime/adapters/langgraph/__init__.py +1 -3
  7. agentscope_runtime/adapters/langgraph/message.py +11 -106
  8. agentscope_runtime/adapters/langgraph/stream.py +1 -0
  9. agentscope_runtime/adapters/ms_agent_framework/message.py +11 -1
  10. agentscope_runtime/adapters/ms_agent_framework/stream.py +1 -0
  11. agentscope_runtime/adapters/text/stream.py +1 -0
  12. agentscope_runtime/common/container_clients/agentrun_client.py +0 -3
  13. agentscope_runtime/common/container_clients/boxlite_client.py +26 -15
  14. agentscope_runtime/common/container_clients/fc_client.py +0 -11
  15. agentscope_runtime/common/utils/deprecation.py +14 -17
  16. agentscope_runtime/common/utils/logging.py +44 -0
  17. agentscope_runtime/engine/app/agent_app.py +5 -5
  18. agentscope_runtime/engine/app/celery_mixin.py +43 -4
  19. agentscope_runtime/engine/deployers/adapter/agui/__init__.py +8 -1
  20. agentscope_runtime/engine/deployers/adapter/agui/agui_adapter_utils.py +6 -1
  21. agentscope_runtime/engine/deployers/adapter/agui/agui_protocol_adapter.py +2 -2
  22. agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +13 -0
  23. agentscope_runtime/engine/runner.py +31 -6
  24. agentscope_runtime/engine/schemas/agent_schemas.py +28 -0
  25. agentscope_runtime/engine/services/sandbox/sandbox_service.py +41 -9
  26. agentscope_runtime/sandbox/box/base/base_sandbox.py +4 -0
  27. agentscope_runtime/sandbox/box/browser/browser_sandbox.py +4 -0
  28. agentscope_runtime/sandbox/box/dummy/dummy_sandbox.py +9 -2
  29. agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +4 -0
  30. agentscope_runtime/sandbox/box/gui/gui_sandbox.py +5 -1
  31. agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +4 -0
  32. agentscope_runtime/sandbox/box/sandbox.py +122 -13
  33. agentscope_runtime/sandbox/client/async_http_client.py +1 -0
  34. agentscope_runtime/sandbox/client/base.py +0 -1
  35. agentscope_runtime/sandbox/client/http_client.py +0 -2
  36. agentscope_runtime/sandbox/manager/heartbeat_mixin.py +486 -0
  37. agentscope_runtime/sandbox/manager/sandbox_manager.py +740 -153
  38. agentscope_runtime/sandbox/manager/server/app.py +18 -11
  39. agentscope_runtime/sandbox/manager/server/config.py +10 -2
  40. agentscope_runtime/sandbox/mcp_server.py +0 -1
  41. agentscope_runtime/sandbox/model/__init__.py +2 -1
  42. agentscope_runtime/sandbox/model/container.py +90 -3
  43. agentscope_runtime/sandbox/model/manager_config.py +45 -1
  44. agentscope_runtime/version.py +1 -1
  45. {agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b2.dist-info}/METADATA +36 -54
  46. {agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b2.dist-info}/RECORD +50 -69
  47. agentscope_runtime/adapters/agentscope/long_term_memory/__init__.py +0 -6
  48. agentscope_runtime/adapters/agentscope/long_term_memory/_long_term_memory_adapter.py +0 -258
  49. agentscope_runtime/adapters/agentscope/memory/__init__.py +0 -6
  50. agentscope_runtime/adapters/agentscope/memory/_memory_adapter.py +0 -152
  51. agentscope_runtime/engine/services/agent_state/__init__.py +0 -25
  52. agentscope_runtime/engine/services/agent_state/redis_state_service.py +0 -166
  53. agentscope_runtime/engine/services/agent_state/state_service.py +0 -179
  54. agentscope_runtime/engine/services/agent_state/state_service_factory.py +0 -52
  55. agentscope_runtime/engine/services/memory/__init__.py +0 -33
  56. agentscope_runtime/engine/services/memory/mem0_memory_service.py +0 -128
  57. agentscope_runtime/engine/services/memory/memory_service.py +0 -292
  58. agentscope_runtime/engine/services/memory/memory_service_factory.py +0 -126
  59. agentscope_runtime/engine/services/memory/redis_memory_service.py +0 -290
  60. agentscope_runtime/engine/services/memory/reme_personal_memory_service.py +0 -109
  61. agentscope_runtime/engine/services/memory/reme_task_memory_service.py +0 -11
  62. agentscope_runtime/engine/services/memory/tablestore_memory_service.py +0 -301
  63. agentscope_runtime/engine/services/session_history/__init__.py +0 -32
  64. agentscope_runtime/engine/services/session_history/redis_session_history_service.py +0 -283
  65. agentscope_runtime/engine/services/session_history/session_history_service.py +0 -267
  66. agentscope_runtime/engine/services/session_history/session_history_service_factory.py +0 -73
  67. agentscope_runtime/engine/services/session_history/tablestore_session_history_service.py +0 -288
  68. {agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b2.dist-info}/WHEEL +0 -0
  69. {agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b2.dist-info}/entry_points.txt +0 -0
  70. {agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b2.dist-info}/licenses/LICENSE +0 -0
  71. {agentscope_runtime-1.0.5.post1.dist-info → agentscope_runtime-1.1.0b2.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  from .version import __version__
3
+ from .common.utils.logging import setup_logger
4
+
5
+ setup_logger()
3
6
 
4
7
  __all__ = ["__version__"]
@@ -4,7 +4,7 @@
4
4
  import json
5
5
 
6
6
  from collections import OrderedDict
7
- from typing import Union, List
7
+ from typing import Union, List, Callable, Optional, Dict
8
8
  from urllib.parse import urlparse
9
9
 
10
10
  from mcp.types import CallToolResult
@@ -24,11 +24,8 @@ from agentscope.mcp._client_base import MCPClientBase
24
24
 
25
25
  from ...engine.schemas.agent_schemas import (
26
26
  Message,
27
- FunctionCall,
28
- FunctionCallOutput,
29
27
  MessageType,
30
28
  )
31
- from ...engine.helpers.agent_api_builder import ResponseBuilder
32
29
 
33
30
 
34
31
  def matches_typed_dict_structure(obj, typed_dict_cls):
@@ -38,303 +35,20 @@ def matches_typed_dict_structure(obj, typed_dict_cls):
38
35
  return expected_keys == set(obj.keys())
39
36
 
40
37
 
41
- def agentscope_msg_to_message(
42
- messages: Union[Msg, List[Msg]],
43
- ) -> List[Message]:
44
- """
45
- Convert AgentScope Msg(s) into one or more runtime Message objects
46
-
47
- Args:
48
- messages: AgentScope message(s) from streaming.
49
-
50
- Returns:
51
- List[Message]: One or more constructed runtime Message objects.
52
- """
53
- if isinstance(messages, Msg):
54
- msgs = [messages]
55
- elif isinstance(messages, list):
56
- msgs = messages
57
- else:
58
- raise TypeError(f"Expected Msg or list[Msg], got {type(messages)}")
59
-
60
- results: List[Message] = []
61
-
62
- for msg in msgs:
63
- role = msg.role or "assistant"
64
-
65
- if isinstance(msg.content, str):
66
- # Only text
67
- rb = ResponseBuilder()
68
- mb = rb.create_message_builder(
69
- role=role,
70
- message_type=MessageType.MESSAGE,
71
- )
72
- # add meta field to store old id and name
73
- mb.message.metadata = {
74
- "original_id": msg.id,
75
- "original_name": msg.name,
76
- "metadata": msg.metadata,
77
- }
78
- cb = mb.create_content_builder(content_type="text")
79
- cb.set_text(msg.content)
80
- cb.complete()
81
- mb.complete()
82
- results.append(mb.get_message_data())
83
- continue
84
-
85
- # msg.content is a list of blocks
86
- # We group blocks by high-level message type
87
- current_mb = None
88
- current_type = None
89
-
90
- for block in msg.content:
91
- if isinstance(block, dict):
92
- btype = block.get("type", "text")
93
- else:
94
- continue
95
-
96
- if btype == "text":
97
- # Create/continue MESSAGE type
98
- if current_type != MessageType.MESSAGE:
99
- if current_mb:
100
- current_mb.complete()
101
- results.append(current_mb.get_message_data())
102
- rb = ResponseBuilder()
103
- current_mb = rb.create_message_builder(
104
- role=role,
105
- message_type=MessageType.MESSAGE,
106
- )
107
- # add meta field to store old id and name
108
- current_mb.message.metadata = {
109
- "original_id": msg.id,
110
- "original_name": msg.name,
111
- "metadata": msg.metadata,
112
- }
113
- current_type = MessageType.MESSAGE
114
- cb = current_mb.create_content_builder(content_type="text")
115
- cb.set_text(block.get("text", ""))
116
- cb.complete()
117
-
118
- elif btype == "thinking":
119
- # Create/continue REASONING type
120
- if current_type != MessageType.REASONING:
121
- if current_mb:
122
- current_mb.complete()
123
- results.append(current_mb.get_message_data())
124
- rb = ResponseBuilder()
125
- current_mb = rb.create_message_builder(
126
- role=role,
127
- message_type=MessageType.REASONING,
128
- )
129
- # add meta field to store old id and name
130
- current_mb.message.metadata = {
131
- "original_id": msg.id,
132
- "original_name": msg.name,
133
- "metadata": msg.metadata,
134
- }
135
- current_type = MessageType.REASONING
136
- cb = current_mb.create_content_builder(content_type="text")
137
- cb.set_text(block.get("thinking", ""))
138
- cb.complete()
139
-
140
- elif btype == "tool_use":
141
- # Always start a new PLUGIN_CALL message
142
- if current_mb:
143
- current_mb.complete()
144
- results.append(current_mb.get_message_data())
145
- rb = ResponseBuilder()
146
- current_mb = rb.create_message_builder(
147
- role=role,
148
- message_type=MessageType.PLUGIN_CALL,
149
- )
150
- # add meta field to store old id and name
151
- current_mb.message.metadata = {
152
- "original_id": msg.id,
153
- "original_name": msg.name,
154
- "metadata": msg.metadata,
155
- }
156
- current_type = MessageType.PLUGIN_CALL
157
- cb = current_mb.create_content_builder(content_type="data")
158
-
159
- if isinstance(block.get("input"), (dict, list)):
160
- arguments = json.dumps(block.get("input"))
161
- else:
162
- arguments = block.get("input")
163
-
164
- call_data = FunctionCall(
165
- call_id=block.get("id"),
166
- name=block.get("name"),
167
- arguments=arguments,
168
- ).model_dump()
169
- cb.set_data(call_data)
170
- cb.complete()
171
-
172
- elif btype == "tool_result":
173
- # Always start a new PLUGIN_CALL_OUTPUT message
174
- if current_mb:
175
- current_mb.complete()
176
- results.append(current_mb.get_message_data())
177
- rb = ResponseBuilder()
178
- current_mb = rb.create_message_builder(
179
- role=role,
180
- message_type=MessageType.PLUGIN_CALL_OUTPUT,
181
- )
182
- # add meta field to store old id and name
183
- current_mb.message.metadata = {
184
- "original_id": msg.id,
185
- "original_name": msg.name,
186
- "metadata": msg.metadata,
187
- }
188
- current_type = MessageType.PLUGIN_CALL_OUTPUT
189
- cb = current_mb.create_content_builder(content_type="data")
190
-
191
- if isinstance(block.get("output"), (dict, list)):
192
- output = json.dumps(block.get("output"))
193
- else:
194
- output = block.get("output")
195
-
196
- output_data = FunctionCallOutput(
197
- call_id=block.get("id"),
198
- name=block.get("name"),
199
- output=output,
200
- ).model_dump(exclude_none=True)
201
- cb.set_data(output_data)
202
- cb.complete()
203
-
204
- elif btype == "image":
205
- # Create/continue MESSAGE type with image
206
- if current_type != MessageType.MESSAGE:
207
- if current_mb:
208
- current_mb.complete()
209
- results.append(current_mb.get_message_data())
210
- rb = ResponseBuilder()
211
- current_mb = rb.create_message_builder(
212
- role=role,
213
- message_type=MessageType.MESSAGE,
214
- )
215
- # add meta field to store old id and name
216
- current_mb.message.metadata = {
217
- "original_id": msg.id,
218
- "original_name": msg.name,
219
- "metadata": msg.metadata,
220
- }
221
- current_type = MessageType.MESSAGE
222
- cb = current_mb.create_content_builder(content_type="image")
223
-
224
- if (
225
- isinstance(block.get("source"), dict)
226
- and block.get("source", {}).get("type") == "url"
227
- ):
228
- cb.set_image_url(block.get("source", {}).get("url"))
229
-
230
- elif (
231
- isinstance(block.get("source"), dict)
232
- and block.get("source").get(
233
- "type",
234
- )
235
- == "base64"
236
- ):
237
- media_type = block.get("source", {}).get(
238
- "media_type",
239
- "image/jpeg",
240
- )
241
- base64_data = block.get("source", {}).get("data", "")
242
- url = f"data:{media_type};base64,{base64_data}"
243
- cb.set_image_url(url)
244
-
245
- cb.complete()
246
-
247
- elif btype == "audio":
248
- # Create/continue MESSAGE type with audio
249
- if current_type != MessageType.MESSAGE:
250
- if current_mb:
251
- current_mb.complete()
252
- results.append(current_mb.get_message_data())
253
- rb = ResponseBuilder()
254
- current_mb = rb.create_message_builder(
255
- role=role,
256
- message_type=MessageType.MESSAGE,
257
- )
258
- # add meta field to store old id and name
259
- current_mb.message.metadata = {
260
- "original_id": msg.id,
261
- "original_name": msg.name,
262
- "metadata": msg.metadata,
263
- }
264
- current_type = MessageType.MESSAGE
265
- cb = current_mb.create_content_builder(content_type="audio")
266
- # URLSource runtime check (dict with type == "url")
267
- if (
268
- isinstance(block.get("source"), dict)
269
- and block.get("source", {}).get(
270
- "type",
271
- )
272
- == "url"
273
- ):
274
- url = block.get("source", {}).get("url")
275
- cb.content.data = url
276
- try:
277
- cb.content.format = urlparse(url).path.split(".")[-1]
278
- except (AttributeError, IndexError, ValueError):
279
- cb.content.format = None
280
-
281
- # Base64Source runtime check (dict with type == "base64")
282
- elif (
283
- isinstance(block.get("source"), dict)
284
- and block.get("source").get(
285
- "type",
286
- )
287
- == "base64"
288
- ):
289
- media_type = block.get("source", {}).get(
290
- "media_type",
291
- )
292
- base64_data = block.get("source", {}).get("data", "")
293
- url = f"data:{media_type};base64,{base64_data}"
294
-
295
- cb.content.data = url
296
- cb.content.format = media_type
297
-
298
- cb.complete()
299
-
300
- else:
301
- # Fallback to MESSAGE type
302
- if current_type != MessageType.MESSAGE:
303
- if current_mb:
304
- current_mb.complete()
305
- results.append(current_mb.get_message_data())
306
- rb = ResponseBuilder()
307
- current_mb = rb.create_message_builder(
308
- role=role,
309
- message_type=MessageType.MESSAGE,
310
- )
311
- # add meta field to store old id and name
312
- current_mb.message.metadata = {
313
- "original_id": msg.id,
314
- "original_name": msg.name,
315
- "metadata": msg.metadata,
316
- }
317
- current_type = MessageType.MESSAGE
318
- cb = current_mb.create_content_builder(content_type="text")
319
- cb.set_text(str(block))
320
- cb.complete()
321
-
322
- # finalize last open message builder
323
- if current_mb:
324
- current_mb.complete()
325
- results.append(current_mb.get_message_data())
326
-
327
- return results
328
-
329
-
330
38
  def message_to_agentscope_msg(
331
39
  messages: Union[Message, List[Message]],
40
+ type_converters: Optional[Dict[str, Callable]] = None,
332
41
  ) -> Union[Msg, List[Msg]]:
333
42
  """
334
43
  Convert AgentScope runtime Message(s) to AgentScope Msg(s).
335
44
 
336
45
  Args:
337
46
  messages: A single AgentScope runtime Message or list of Messages.
47
+ type_converters: Optional mapping from ``message.type`` to a callable
48
+ ``converter(message)``. When provided and the current
49
+ ``message.type`` exists in the mapping, the corresponding converter
50
+ will be used and the built-in conversion logic will be skipped for
51
+ that message.
338
52
 
339
53
  Returns:
340
54
  A single Msg object or a list of Msg objects.
@@ -351,6 +65,10 @@ def message_to_agentscope_msg(
351
65
  return default
352
66
 
353
67
  def _convert_one(message: Message) -> Msg:
68
+ # Used for custom conversion
69
+ if type_converters and message.type in type_converters:
70
+ return type_converters[message.type](message)
71
+
354
72
  # Normalize role
355
73
  if message.role == "tool":
356
74
  role_label = "system" # AgentScope not support tool as role
@@ -474,8 +192,7 @@ def message_to_agentscope_msg(
474
192
  "image": (ImageBlock, "image_url"),
475
193
  "audio": (AudioBlock, "data"),
476
194
  "data": (TextBlock, "data"),
477
- # "video": (VideoBlock, "video_url", True),
478
- # TODO: support video
195
+ "video": (VideoBlock, "video_url"),
479
196
  }
480
197
 
481
198
  msg_content = []
@@ -547,6 +264,30 @@ def message_to_agentscope_msg(
547
264
  msg_content.append(
548
265
  block_cls(type=cnt_type, source=base64_source),
549
266
  )
267
+ elif cnt_type == "video":
268
+ if (
269
+ value
270
+ and isinstance(value, str)
271
+ and value.startswith("data:")
272
+ ):
273
+ mediatype_part = value.split(";")[0].replace(
274
+ "data:",
275
+ "",
276
+ )
277
+ base64_data = value.split(",")[1]
278
+ base64_source = Base64Source(
279
+ type="base64",
280
+ media_type=mediatype_part,
281
+ data=base64_data,
282
+ )
283
+ msg_content.append(
284
+ block_cls(type=cnt_type, source=base64_source),
285
+ )
286
+ else:
287
+ url_source = URLSource(type="url", url=value)
288
+ msg_content.append(
289
+ block_cls(type=cnt_type, source=url_source),
290
+ )
550
291
  else:
551
292
  # text & data
552
293
  if isinstance(value, str):
@@ -1,9 +1,10 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # pylint: disable=too-many-nested-blocks,too-many-branches,too-many-statements
3
3
  import copy
4
+ import inspect
4
5
  import json
5
6
 
6
- from typing import AsyncIterator, Tuple, List, Union
7
+ from typing import AsyncIterator, Tuple, List, Union, Optional, Callable, Dict
7
8
  from urllib.parse import urlparse
8
9
 
9
10
  from agentscope import setup_logger
@@ -16,6 +17,7 @@ from ...engine.schemas.agent_schemas import (
16
17
  TextContent,
17
18
  ImageContent,
18
19
  AudioContent,
20
+ VideoContent,
19
21
  DataContent,
20
22
  McpCall,
21
23
  McpCallOutput,
@@ -29,6 +31,8 @@ setup_logger("ERROR")
29
31
 
30
32
  async def adapt_agentscope_message_stream(
31
33
  source_stream: AsyncIterator[Tuple[Msg, bool]],
34
+ type_converters: Optional[Dict[str, Callable]] = None,
35
+ **kwargs, # pylint:disable=unused-argument
32
36
  ) -> AsyncIterator[Union[Message, Content]]:
33
37
  # Initialize variables to avoid uncaught errors
34
38
  msg_id = None
@@ -136,6 +140,44 @@ async def adapt_agentscope_message_stream(
136
140
  index = text_delta_content.index
137
141
  yield text_delta_content
138
142
  elif isinstance(element, dict):
143
+ # Used for custom conversion
144
+ if (
145
+ type_converters
146
+ and element.get("type") in type_converters
147
+ ):
148
+ blk_type = element.get("type")
149
+ if not isinstance(blk_type, str):
150
+ continue
151
+ fn = type_converters[blk_type]
152
+ # Send message, element, last, tool_start, metadata
153
+ # and usage
154
+ out = fn(
155
+ element,
156
+ message,
157
+ last,
158
+ tool_start,
159
+ metadata,
160
+ usage,
161
+ )
162
+ # Case 1: async generator / async iterator
163
+ if hasattr(out, "__aiter__"):
164
+ async for ev in out:
165
+ yield ev
166
+ continue
167
+
168
+ # Case 2: sync generator / iterator
169
+ if inspect.isgenerator(out):
170
+ for ev in out:
171
+ yield ev
172
+ continue
173
+
174
+ # Only generator styles are supported
175
+ raise TypeError(
176
+ f"type_converters['{blk_type}'] must return a "
177
+ f"generator/iterator or an async generator/async "
178
+ f"iterator, got: {type(out)}",
179
+ )
180
+
139
181
  if element.get("type") == "text": # Text
140
182
  text = element.get(
141
183
  "text",
@@ -446,7 +488,12 @@ async def adapt_agentscope_message_stream(
446
488
  == "url"
447
489
  ):
448
490
  kwargs.update(
449
- {"image_url": element.get("source")},
491
+ {
492
+ "image_url": element.get(
493
+ "source",
494
+ {},
495
+ ).get("url"),
496
+ },
450
497
  )
451
498
 
452
499
  elif (
@@ -515,6 +562,46 @@ async def adapt_agentscope_message_stream(
515
562
  index=index,
516
563
  **kwargs,
517
564
  )
565
+ elif element.get("type") == "video":
566
+ kwargs = {}
567
+ if (
568
+ isinstance(element.get("source"), dict)
569
+ and element.get("source", {}).get(
570
+ "type",
571
+ )
572
+ == "url"
573
+ ):
574
+ kwargs.update(
575
+ {
576
+ "video_url": element.get(
577
+ "source",
578
+ {},
579
+ ).get("url"),
580
+ },
581
+ )
582
+
583
+ elif (
584
+ isinstance(element.get("source"), dict)
585
+ and element.get("source").get(
586
+ "type",
587
+ )
588
+ == "base64"
589
+ ):
590
+ media_type = element.get("source", {}).get(
591
+ "media_type",
592
+ "video/mp4",
593
+ )
594
+ base64_data = element.get("source", {}).get(
595
+ "data",
596
+ "",
597
+ )
598
+ url = f"data:{media_type};base64,{base64_data}"
599
+ kwargs.update({"video_url": url})
600
+ delta_content = VideoContent(
601
+ delta=True,
602
+ index=index,
603
+ **kwargs,
604
+ )
518
605
  else:
519
606
  delta_content = TextContent(
520
607
  delta=True,
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
- from typing import Union, List
2
+ from typing import Union, List, Callable, Optional, Dict
3
3
 
4
4
  from agentscope.formatter import OpenAIChatFormatter
5
5
 
@@ -9,18 +9,27 @@ from ..agentscope.message import message_to_agentscope_msg
9
9
 
10
10
  async def message_to_agno_message(
11
11
  messages: Union[Message, List[Message]],
12
+ type_converters: Optional[Dict[str, Callable]] = None,
12
13
  ) -> Union[dict, List[dict]]:
13
14
  """
14
15
  Convert AgentScope runtime Message(s) to Agno Message(s).
15
16
 
16
17
  Args:
17
18
  messages: A single AgentScope runtime Message or list of Messages.
19
+ type_converters: Optional mapping from ``message.type`` to a callable
20
+ ``converter(message)``. When provided and the current
21
+ ``message.type`` exists in the mapping, the corresponding converter
22
+ will be used and the built-in conversion logic will be skipped for
23
+ that message.
18
24
 
19
25
  Returns:
20
26
  A single AgnoMessage object or a list of AgnoMessage objects.
21
27
  """
22
28
 
23
- as_msgs = message_to_agentscope_msg(messages)
29
+ as_msgs = message_to_agentscope_msg(
30
+ messages,
31
+ type_converters=type_converters,
32
+ )
24
33
  raw_list = isinstance(as_msgs, list)
25
34
  as_msgs = as_msgs if raw_list else [as_msgs]
26
35
 
@@ -31,6 +31,7 @@ from ...engine.helpers.agent_api_builder import ResponseBuilder
31
31
 
32
32
  async def adapt_agno_message_stream(
33
33
  source_stream: AsyncIterator[BaseAgentRunEvent],
34
+ **kwargs, # pylint:disable=unused-argument
34
35
  ) -> AsyncIterator[Union[Message, Content]]:
35
36
  rb = ResponseBuilder()
36
37
  mb = None
@@ -2,11 +2,9 @@
2
2
  """LangGraph adapter for AgentScope runtime."""
3
3
 
4
4
  # todo Message(reasoning) Adapter
5
- # todo Memory Adapter
6
5
  # todo Sandbox Tools Adapter
7
- from .message import langgraph_msg_to_message, message_to_langgraph_msg
6
+ from .message import message_to_langgraph_msg
8
7
 
9
8
  __all__ = [
10
- "langgraph_msg_to_message",
11
9
  "message_to_langgraph_msg",
12
10
  ]