agentscope-runtime 0.1.5b1__py3-none-any.whl → 0.1.6__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/engine/agents/agentscope_agent.py +447 -0
- agentscope_runtime/engine/agents/agno_agent.py +19 -18
- agentscope_runtime/engine/agents/autogen_agent.py +13 -8
- agentscope_runtime/engine/agents/utils.py +53 -0
- agentscope_runtime/engine/deployers/__init__.py +0 -13
- agentscope_runtime/engine/deployers/local_deployer.py +501 -356
- agentscope_runtime/engine/helpers/helper.py +60 -41
- agentscope_runtime/engine/runner.py +11 -36
- agentscope_runtime/engine/schemas/agent_schemas.py +2 -70
- agentscope_runtime/engine/services/sandbox_service.py +62 -70
- agentscope_runtime/engine/services/tablestore_memory_service.py +304 -0
- agentscope_runtime/engine/services/tablestore_rag_service.py +143 -0
- agentscope_runtime/engine/services/tablestore_session_history_service.py +293 -0
- agentscope_runtime/engine/services/utils/tablestore_service_utils.py +352 -0
- agentscope_runtime/sandbox/__init__.py +2 -0
- agentscope_runtime/sandbox/box/base/__init__.py +4 -0
- agentscope_runtime/sandbox/box/base/base_sandbox.py +4 -3
- agentscope_runtime/sandbox/box/browser/__init__.py +4 -0
- agentscope_runtime/sandbox/box/browser/browser_sandbox.py +8 -13
- agentscope_runtime/sandbox/box/dummy/__init__.py +4 -0
- agentscope_runtime/sandbox/box/filesystem/__init__.py +4 -0
- agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +8 -6
- agentscope_runtime/sandbox/box/gui/__init__.py +4 -0
- agentscope_runtime/sandbox/box/gui/gui_sandbox.py +80 -0
- agentscope_runtime/sandbox/box/sandbox.py +5 -2
- agentscope_runtime/sandbox/box/shared/routers/generic.py +20 -1
- agentscope_runtime/sandbox/box/training_box/__init__.py +4 -0
- agentscope_runtime/sandbox/box/training_box/training_box.py +10 -15
- agentscope_runtime/sandbox/build.py +143 -58
- agentscope_runtime/sandbox/client/http_client.py +43 -49
- agentscope_runtime/sandbox/client/training_client.py +0 -1
- agentscope_runtime/sandbox/constant.py +24 -1
- agentscope_runtime/sandbox/custom/custom_sandbox.py +5 -5
- agentscope_runtime/sandbox/custom/example.py +2 -2
- agentscope_runtime/sandbox/enums.py +1 -0
- agentscope_runtime/sandbox/manager/collections/in_memory_mapping.py +11 -6
- agentscope_runtime/sandbox/manager/collections/redis_mapping.py +25 -9
- agentscope_runtime/sandbox/manager/container_clients/__init__.py +0 -10
- agentscope_runtime/sandbox/manager/container_clients/agentrun_client.py +1098 -0
- agentscope_runtime/sandbox/manager/container_clients/docker_client.py +33 -205
- agentscope_runtime/sandbox/manager/container_clients/kubernetes_client.py +8 -555
- agentscope_runtime/sandbox/manager/sandbox_manager.py +187 -88
- agentscope_runtime/sandbox/manager/server/app.py +82 -14
- agentscope_runtime/sandbox/manager/server/config.py +50 -3
- agentscope_runtime/sandbox/model/container.py +6 -23
- agentscope_runtime/sandbox/model/manager_config.py +93 -5
- agentscope_runtime/sandbox/tools/gui/__init__.py +7 -0
- agentscope_runtime/sandbox/tools/gui/tool.py +77 -0
- agentscope_runtime/sandbox/tools/mcp_tool.py +6 -2
- agentscope_runtime/sandbox/utils.py +124 -0
- agentscope_runtime/version.py +1 -1
- {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/METADATA +168 -77
- {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/RECORD +59 -78
- {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/entry_points.txt +0 -1
- agentscope_runtime/engine/agents/agentscope_agent/__init__.py +0 -6
- agentscope_runtime/engine/agents/agentscope_agent/agent.py +0 -401
- agentscope_runtime/engine/agents/agentscope_agent/hooks.py +0 -169
- agentscope_runtime/engine/agents/llm_agent.py +0 -51
- agentscope_runtime/engine/deployers/adapter/responses/response_api_adapter_utils.py +0 -2886
- agentscope_runtime/engine/deployers/adapter/responses/response_api_agent_adapter.py +0 -51
- agentscope_runtime/engine/deployers/adapter/responses/response_api_protocol_adapter.py +0 -314
- agentscope_runtime/engine/deployers/cli_fc_deploy.py +0 -143
- agentscope_runtime/engine/deployers/kubernetes_deployer.py +0 -265
- agentscope_runtime/engine/deployers/modelstudio_deployer.py +0 -626
- agentscope_runtime/engine/deployers/utils/deployment_modes.py +0 -14
- agentscope_runtime/engine/deployers/utils/docker_image_utils/__init__.py +0 -8
- agentscope_runtime/engine/deployers/utils/docker_image_utils/docker_image_builder.py +0 -429
- agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +0 -240
- agentscope_runtime/engine/deployers/utils/docker_image_utils/runner_image_factory.py +0 -297
- agentscope_runtime/engine/deployers/utils/package_project_utils.py +0 -932
- agentscope_runtime/engine/deployers/utils/service_utils/__init__.py +0 -9
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +0 -504
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_templates.py +0 -157
- agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +0 -268
- agentscope_runtime/engine/deployers/utils/service_utils/service_config.py +0 -75
- agentscope_runtime/engine/deployers/utils/service_utils/service_factory.py +0 -220
- agentscope_runtime/engine/deployers/utils/wheel_packager.py +0 -389
- agentscope_runtime/engine/helpers/agent_api_builder.py +0 -651
- agentscope_runtime/engine/llms/__init__.py +0 -3
- agentscope_runtime/engine/llms/base_llm.py +0 -60
- agentscope_runtime/engine/llms/qwen_llm.py +0 -47
- agentscope_runtime/engine/schemas/embedding.py +0 -37
- agentscope_runtime/engine/schemas/modelstudio_llm.py +0 -310
- agentscope_runtime/engine/schemas/oai_llm.py +0 -538
- agentscope_runtime/engine/schemas/realtime.py +0 -254
- /agentscope_runtime/engine/{deployers/adapter/responses → services/utils}/__init__.py +0 -0
- /agentscope_runtime/{engine/deployers/utils → sandbox/box/gui/box}/__init__.py +0 -0
- {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/WHEEL +0 -0
- {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/licenses/LICENSE +0 -0
- {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# pylint:disable=too-many-nested-blocks, too-many-branches, too-many-statements
|
|
3
|
+
# pylint:disable=line-too-long, protected-access
|
|
4
|
+
import copy
|
|
5
|
+
import logging
|
|
6
|
+
import json
|
|
7
|
+
import traceback
|
|
8
|
+
from functools import partial
|
|
9
|
+
from typing import Optional, Type, List
|
|
10
|
+
|
|
11
|
+
from agentscope import setup_logger
|
|
12
|
+
from agentscope.agent import AgentBase, ReActAgent
|
|
13
|
+
from agentscope.formatter import (
|
|
14
|
+
FormatterBase,
|
|
15
|
+
DashScopeChatFormatter,
|
|
16
|
+
OpenAIChatFormatter,
|
|
17
|
+
AnthropicChatFormatter,
|
|
18
|
+
OllamaChatFormatter,
|
|
19
|
+
GeminiChatFormatter,
|
|
20
|
+
)
|
|
21
|
+
from agentscope.memory import InMemoryMemory
|
|
22
|
+
from agentscope.message import (
|
|
23
|
+
Msg,
|
|
24
|
+
ToolUseBlock,
|
|
25
|
+
ToolResultBlock,
|
|
26
|
+
TextBlock,
|
|
27
|
+
ImageBlock,
|
|
28
|
+
# AudioBlock, # TODO: support
|
|
29
|
+
# VideoBlock, # TODO: support
|
|
30
|
+
URLSource,
|
|
31
|
+
)
|
|
32
|
+
from agentscope.model import (
|
|
33
|
+
ChatModelBase,
|
|
34
|
+
DashScopeChatModel,
|
|
35
|
+
OpenAIChatModel,
|
|
36
|
+
AnthropicChatModel,
|
|
37
|
+
OllamaChatModel,
|
|
38
|
+
GeminiChatModel,
|
|
39
|
+
)
|
|
40
|
+
from agentscope.pipeline import stream_printing_messages
|
|
41
|
+
from agentscope.tool import (
|
|
42
|
+
Toolkit,
|
|
43
|
+
ToolResponse,
|
|
44
|
+
)
|
|
45
|
+
from agentscope.tool._toolkit import RegisteredToolFunction
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
from .utils import build_agent
|
|
49
|
+
from ..agents import Agent
|
|
50
|
+
from ..schemas.agent_schemas import (
|
|
51
|
+
Message,
|
|
52
|
+
TextContent,
|
|
53
|
+
DataContent,
|
|
54
|
+
FunctionCall,
|
|
55
|
+
FunctionCallOutput,
|
|
56
|
+
MessageType,
|
|
57
|
+
)
|
|
58
|
+
from ..schemas.context import Context
|
|
59
|
+
|
|
60
|
+
# Disable logging from agentscope
|
|
61
|
+
setup_logger(level="CRITICAL")
|
|
62
|
+
logger = logging.getLogger(__name__)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class AgentScopeContextAdapter:
|
|
66
|
+
def __init__(self, context: Context, attr: dict):
|
|
67
|
+
self.context = context
|
|
68
|
+
self.attr = attr
|
|
69
|
+
|
|
70
|
+
# Adapted attribute
|
|
71
|
+
self.toolkit = None
|
|
72
|
+
self.model = None
|
|
73
|
+
self.memory = None
|
|
74
|
+
self.new_message = None
|
|
75
|
+
|
|
76
|
+
async def initialize(self):
|
|
77
|
+
self.model, self.formatter = await self.adapt_model()
|
|
78
|
+
self.memory = await self.adapt_memory()
|
|
79
|
+
self.new_message = await self.adapt_new_message()
|
|
80
|
+
self.toolkit = await self.adapt_tools()
|
|
81
|
+
|
|
82
|
+
async def adapt_memory(self):
|
|
83
|
+
memory = self.attr["agent_config"].get("memory", InMemoryMemory())
|
|
84
|
+
messages = []
|
|
85
|
+
|
|
86
|
+
# Build context
|
|
87
|
+
for msg in self.context.session.messages[:-1]: # Exclude the last one
|
|
88
|
+
messages.append(AgentScopeContextAdapter.converter(msg))
|
|
89
|
+
|
|
90
|
+
state_dict = {"content": [_.to_dict() for _ in messages]}
|
|
91
|
+
memory.load_state_dict(state_dict)
|
|
92
|
+
|
|
93
|
+
return memory
|
|
94
|
+
|
|
95
|
+
@staticmethod
|
|
96
|
+
def converter(message: Message) -> Msg:
|
|
97
|
+
if message.role not in ["user", "system", "assistant"]:
|
|
98
|
+
role_label = "user"
|
|
99
|
+
else:
|
|
100
|
+
role_label = message.role
|
|
101
|
+
|
|
102
|
+
result = {
|
|
103
|
+
"name": message.role,
|
|
104
|
+
"role": role_label,
|
|
105
|
+
"invocation_id": message.id,
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if message.type in (
|
|
109
|
+
MessageType.PLUGIN_CALL,
|
|
110
|
+
MessageType.FUNCTION_CALL,
|
|
111
|
+
):
|
|
112
|
+
# convert PLUGIN_CALL, FUNCTION_CALL to ToolUseBlock
|
|
113
|
+
result["content"] = [
|
|
114
|
+
ToolUseBlock(
|
|
115
|
+
type="tool_use",
|
|
116
|
+
id=message.content[0].data["call_id"],
|
|
117
|
+
name=message.role,
|
|
118
|
+
input=json.loads(message.content[0].data["arguments"]),
|
|
119
|
+
),
|
|
120
|
+
]
|
|
121
|
+
elif message.type in (
|
|
122
|
+
MessageType.PLUGIN_CALL_OUTPUT,
|
|
123
|
+
MessageType.FUNCTION_CALL_OUTPUT,
|
|
124
|
+
):
|
|
125
|
+
# convert PLUGIN_CALL_OUTPUT, FUNCTION_CALL_OUTPUT to
|
|
126
|
+
# ToolResultBlock
|
|
127
|
+
result["content"] = [
|
|
128
|
+
ToolResultBlock(
|
|
129
|
+
type="tool_result",
|
|
130
|
+
id=message.content[0].data["call_id"],
|
|
131
|
+
name=message.role,
|
|
132
|
+
output=message.content[0].data["output"],
|
|
133
|
+
),
|
|
134
|
+
]
|
|
135
|
+
else:
|
|
136
|
+
type_mapping = {
|
|
137
|
+
"text": (TextBlock, "text", None),
|
|
138
|
+
"image": (ImageBlock, "image_url", True),
|
|
139
|
+
# "audio": (AudioBlock, "audio_url", True), # TODO: support
|
|
140
|
+
# "video": (VideoBlock, "video_url", True), # TODO: support
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
msg_content = []
|
|
144
|
+
for cnt in message.content:
|
|
145
|
+
cnt_type = cnt.type or "text"
|
|
146
|
+
|
|
147
|
+
if cnt_type not in type_mapping:
|
|
148
|
+
raise ValueError(f"Unsupported message type: {cnt_type}")
|
|
149
|
+
|
|
150
|
+
block_cls, attr_name, is_url = type_mapping[cnt_type]
|
|
151
|
+
value = getattr(cnt, attr_name)
|
|
152
|
+
|
|
153
|
+
if is_url:
|
|
154
|
+
url_source = URLSource(type="url", url=value)
|
|
155
|
+
msg_content.append(
|
|
156
|
+
block_cls(type=cnt_type, source=url_source),
|
|
157
|
+
)
|
|
158
|
+
else:
|
|
159
|
+
msg_content.append(block_cls(type=cnt_type, text=value))
|
|
160
|
+
|
|
161
|
+
result["content"] = msg_content
|
|
162
|
+
return Msg(**result)
|
|
163
|
+
|
|
164
|
+
async def adapt_new_message(self):
|
|
165
|
+
last_message = self.context.session.messages[-1]
|
|
166
|
+
return AgentScopeContextAdapter.converter(last_message)
|
|
167
|
+
|
|
168
|
+
async def adapt_model(self):
|
|
169
|
+
model = self.attr["model"]
|
|
170
|
+
formatter = self.attr["agent_config"].get("formatter")
|
|
171
|
+
if formatter and isinstance(formatter, FormatterBase):
|
|
172
|
+
return model, formatter
|
|
173
|
+
|
|
174
|
+
if isinstance(model, OpenAIChatModel):
|
|
175
|
+
formatter = OpenAIChatFormatter()
|
|
176
|
+
elif isinstance(model, DashScopeChatModel):
|
|
177
|
+
formatter = DashScopeChatFormatter()
|
|
178
|
+
elif isinstance(model, AnthropicChatModel):
|
|
179
|
+
formatter = AnthropicChatFormatter()
|
|
180
|
+
elif isinstance(model, OllamaChatModel):
|
|
181
|
+
formatter = OllamaChatFormatter()
|
|
182
|
+
elif isinstance(model, GeminiChatModel):
|
|
183
|
+
formatter = GeminiChatFormatter()
|
|
184
|
+
|
|
185
|
+
return model, formatter
|
|
186
|
+
|
|
187
|
+
async def adapt_tools(self):
|
|
188
|
+
def func_wrapper(func, **kwargs):
|
|
189
|
+
func_res = func(**kwargs)
|
|
190
|
+
return ToolResponse(
|
|
191
|
+
content=func_res["content"],
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
toolkit = self.attr["agent_config"].get("toolkit", Toolkit())
|
|
195
|
+
|
|
196
|
+
# Deepcopy to avoid modify the original toolkit
|
|
197
|
+
try:
|
|
198
|
+
toolkit = copy.deepcopy(toolkit)
|
|
199
|
+
except Exception as e:
|
|
200
|
+
logger.warning(
|
|
201
|
+
f"Failed to deepcopy toolkit for agent "
|
|
202
|
+
f"'{self.attr.get('agent_config', {}).get('name')}' "
|
|
203
|
+
f"Error: {e}\nTraceback:\n{traceback.format_exc()}",
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
tools = self.attr["tools"]
|
|
207
|
+
|
|
208
|
+
# in case, tools is None and tools == []
|
|
209
|
+
if not tools:
|
|
210
|
+
return toolkit
|
|
211
|
+
|
|
212
|
+
if self.context.activate_tools:
|
|
213
|
+
# Only add activated tool
|
|
214
|
+
activated_tools = self.context.activate_tools
|
|
215
|
+
else:
|
|
216
|
+
# Lazy import
|
|
217
|
+
from ...sandbox.tools.utils import setup_tools
|
|
218
|
+
|
|
219
|
+
activated_tools = setup_tools(
|
|
220
|
+
tools=self.attr["tools"],
|
|
221
|
+
environment_manager=self.context.environment_manager,
|
|
222
|
+
session_id=self.context.session.id,
|
|
223
|
+
user_id=self.context.session.user_id,
|
|
224
|
+
include_schemas=False,
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
for tool in activated_tools:
|
|
228
|
+
function = RegisteredToolFunction(
|
|
229
|
+
name=tool.name,
|
|
230
|
+
source="mcp_server",
|
|
231
|
+
mcp_name=tool.tool_type,
|
|
232
|
+
original_func=partial(
|
|
233
|
+
func_wrapper,
|
|
234
|
+
tool,
|
|
235
|
+
),
|
|
236
|
+
json_schema=tool.schema,
|
|
237
|
+
group="basic",
|
|
238
|
+
)
|
|
239
|
+
toolkit.tools[tool.name] = function
|
|
240
|
+
|
|
241
|
+
return toolkit
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
class AgentScopeAgent(Agent):
|
|
245
|
+
def __init__(
|
|
246
|
+
self,
|
|
247
|
+
name: str,
|
|
248
|
+
model: ChatModelBase,
|
|
249
|
+
tools=None,
|
|
250
|
+
agent_config=None,
|
|
251
|
+
agent_builder: Optional[Type[AgentBase]] = ReActAgent,
|
|
252
|
+
):
|
|
253
|
+
super().__init__(name=name, agent_config=agent_config)
|
|
254
|
+
assert isinstance(
|
|
255
|
+
model,
|
|
256
|
+
ChatModelBase,
|
|
257
|
+
), "model must be a subclass of ChatModelBase in AgentScope"
|
|
258
|
+
|
|
259
|
+
# Set default agent_builder
|
|
260
|
+
if agent_builder is None:
|
|
261
|
+
agent_builder = ReActAgent
|
|
262
|
+
|
|
263
|
+
assert issubclass(
|
|
264
|
+
agent_builder,
|
|
265
|
+
AgentBase,
|
|
266
|
+
), "agent_builder must be a subclass of AgentBase in AgentScope"
|
|
267
|
+
|
|
268
|
+
# Replace name if not exists
|
|
269
|
+
self.agent_config["name"] = self.agent_config.get("name") or name
|
|
270
|
+
|
|
271
|
+
self._attr = {
|
|
272
|
+
"model": model,
|
|
273
|
+
"tools": tools,
|
|
274
|
+
"agent_config": self.agent_config,
|
|
275
|
+
"agent_builder": agent_builder,
|
|
276
|
+
}
|
|
277
|
+
self.tools = tools
|
|
278
|
+
|
|
279
|
+
def copy(self) -> "AgentScopeAgent":
|
|
280
|
+
return AgentScopeAgent(**self._attr)
|
|
281
|
+
|
|
282
|
+
def build(self, as_context) -> AgentBase:
|
|
283
|
+
params = {
|
|
284
|
+
**self._attr["agent_config"],
|
|
285
|
+
**{
|
|
286
|
+
"model": as_context.model,
|
|
287
|
+
"formatter": self._attr["agent_config"].get(
|
|
288
|
+
"formatter",
|
|
289
|
+
as_context.formatter,
|
|
290
|
+
),
|
|
291
|
+
"memory": as_context.memory,
|
|
292
|
+
"toolkit": as_context.toolkit,
|
|
293
|
+
},
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
builder_cls = self._attr["agent_builder"]
|
|
297
|
+
_agent = build_agent(builder_cls, params)
|
|
298
|
+
_agent.set_console_output_enabled(False)
|
|
299
|
+
|
|
300
|
+
return _agent
|
|
301
|
+
|
|
302
|
+
async def run_async(
|
|
303
|
+
self,
|
|
304
|
+
context,
|
|
305
|
+
**kwargs,
|
|
306
|
+
):
|
|
307
|
+
as_context = AgentScopeContextAdapter(context=context, attr=self._attr)
|
|
308
|
+
await as_context.initialize()
|
|
309
|
+
local_truncate_memory = ""
|
|
310
|
+
|
|
311
|
+
# We should always build a new agent since the state is manage outside
|
|
312
|
+
# the agent
|
|
313
|
+
_agent = self.build(as_context)
|
|
314
|
+
|
|
315
|
+
# Yield new Msg instances as they are logged
|
|
316
|
+
last_content = ""
|
|
317
|
+
|
|
318
|
+
message = Message(type=MessageType.MESSAGE, role="assistant")
|
|
319
|
+
yield message.in_progress()
|
|
320
|
+
index = None
|
|
321
|
+
|
|
322
|
+
# Run agent
|
|
323
|
+
async for msg, last in stream_printing_messages(
|
|
324
|
+
agents=[_agent],
|
|
325
|
+
coroutine_task=_agent(as_context.new_message),
|
|
326
|
+
):
|
|
327
|
+
# deepcopy required to avoid modifying the original message object
|
|
328
|
+
# which may be used elsewhere in the streaming pipeline
|
|
329
|
+
msg = copy.deepcopy(msg)
|
|
330
|
+
|
|
331
|
+
# Filter out unfinished tool_use messages
|
|
332
|
+
if not last:
|
|
333
|
+
new_blocks = []
|
|
334
|
+
if isinstance(msg.content, List):
|
|
335
|
+
for block in msg.content:
|
|
336
|
+
if block.get("type", "") != "tool_use":
|
|
337
|
+
new_blocks.append(block)
|
|
338
|
+
msg.content = new_blocks
|
|
339
|
+
|
|
340
|
+
if not msg.content:
|
|
341
|
+
continue
|
|
342
|
+
|
|
343
|
+
# TODO: make this as a message converter
|
|
344
|
+
content = msg.content
|
|
345
|
+
if isinstance(content, str):
|
|
346
|
+
last_content = content
|
|
347
|
+
else:
|
|
348
|
+
for element in content:
|
|
349
|
+
if isinstance(element, str) and element:
|
|
350
|
+
text_delta_content = TextContent(
|
|
351
|
+
delta=True,
|
|
352
|
+
index=index,
|
|
353
|
+
text=element,
|
|
354
|
+
)
|
|
355
|
+
text_delta_content = message.add_delta_content(
|
|
356
|
+
new_content=text_delta_content,
|
|
357
|
+
)
|
|
358
|
+
index = text_delta_content.index
|
|
359
|
+
yield text_delta_content
|
|
360
|
+
elif isinstance(element, dict):
|
|
361
|
+
if element.get("type") == "text":
|
|
362
|
+
text = element.get(
|
|
363
|
+
"text",
|
|
364
|
+
"",
|
|
365
|
+
)
|
|
366
|
+
if text:
|
|
367
|
+
text_delta_content = TextContent(
|
|
368
|
+
delta=True,
|
|
369
|
+
index=index,
|
|
370
|
+
text=text.removeprefix(
|
|
371
|
+
local_truncate_memory,
|
|
372
|
+
),
|
|
373
|
+
)
|
|
374
|
+
local_truncate_memory = element.get(
|
|
375
|
+
"text",
|
|
376
|
+
"",
|
|
377
|
+
)
|
|
378
|
+
text_delta_content = message.add_delta_content(
|
|
379
|
+
new_content=text_delta_content,
|
|
380
|
+
)
|
|
381
|
+
index = text_delta_content.index
|
|
382
|
+
|
|
383
|
+
# Only yield valid text
|
|
384
|
+
if text_delta_content.text:
|
|
385
|
+
yield text_delta_content
|
|
386
|
+
|
|
387
|
+
if last:
|
|
388
|
+
yield message.completed()
|
|
389
|
+
message = Message(
|
|
390
|
+
type=MessageType.MESSAGE,
|
|
391
|
+
role="assistant",
|
|
392
|
+
)
|
|
393
|
+
index = None
|
|
394
|
+
|
|
395
|
+
elif element.get("type") == "tool_use":
|
|
396
|
+
json_str = json.dumps(element.get("input"))
|
|
397
|
+
data_delta_content = DataContent(
|
|
398
|
+
index=index,
|
|
399
|
+
data=FunctionCall(
|
|
400
|
+
call_id=element.get("id"),
|
|
401
|
+
name=element.get("name"),
|
|
402
|
+
arguments=json_str,
|
|
403
|
+
).model_dump(),
|
|
404
|
+
)
|
|
405
|
+
plugin_call_message = Message(
|
|
406
|
+
type=MessageType.PLUGIN_CALL,
|
|
407
|
+
role="assistant",
|
|
408
|
+
content=[data_delta_content],
|
|
409
|
+
)
|
|
410
|
+
yield plugin_call_message.completed()
|
|
411
|
+
elif element.get("type") == "tool_result":
|
|
412
|
+
data_delta_content = DataContent(
|
|
413
|
+
index=index,
|
|
414
|
+
data=FunctionCallOutput(
|
|
415
|
+
call_id=element.get("id"),
|
|
416
|
+
output=str(element.get("output")),
|
|
417
|
+
).model_dump(),
|
|
418
|
+
)
|
|
419
|
+
plugin_output_message = Message(
|
|
420
|
+
type=MessageType.PLUGIN_CALL_OUTPUT,
|
|
421
|
+
role="assistant",
|
|
422
|
+
content=[data_delta_content],
|
|
423
|
+
)
|
|
424
|
+
yield plugin_output_message.completed()
|
|
425
|
+
else:
|
|
426
|
+
text_delta_content = TextContent(
|
|
427
|
+
delta=True,
|
|
428
|
+
index=index,
|
|
429
|
+
text=f"{element}",
|
|
430
|
+
)
|
|
431
|
+
text_delta_content = message.add_delta_content(
|
|
432
|
+
new_content=text_delta_content,
|
|
433
|
+
)
|
|
434
|
+
index = text_delta_content.index
|
|
435
|
+
yield text_delta_content
|
|
436
|
+
|
|
437
|
+
if last_content:
|
|
438
|
+
text_delta_content = TextContent(
|
|
439
|
+
delta=True,
|
|
440
|
+
index=index,
|
|
441
|
+
text=last_content,
|
|
442
|
+
)
|
|
443
|
+
text_delta_content = message.add_delta_content(
|
|
444
|
+
new_content=text_delta_content,
|
|
445
|
+
)
|
|
446
|
+
yield text_delta_content
|
|
447
|
+
yield message.completed()
|
|
@@ -12,6 +12,7 @@ from agno.run.response import (
|
|
|
12
12
|
)
|
|
13
13
|
from agno.tools.function import Function
|
|
14
14
|
|
|
15
|
+
from .utils import build_agent
|
|
15
16
|
from ..agents import Agent
|
|
16
17
|
from ..schemas.context import Context
|
|
17
18
|
from ..schemas.agent_schemas import (
|
|
@@ -64,7 +65,7 @@ class AgnoContextAdapter:
|
|
|
64
65
|
return self.attr["model"]
|
|
65
66
|
|
|
66
67
|
async def adapt_tools(self):
|
|
67
|
-
toolkit = self.attr["agent_config"].get("
|
|
68
|
+
toolkit = self.attr["agent_config"].get("tools", [])
|
|
68
69
|
tools = self.attr["tools"]
|
|
69
70
|
|
|
70
71
|
# in case, tools is None and tools == []
|
|
@@ -131,30 +132,38 @@ class AgnoAgent(Agent):
|
|
|
131
132
|
"agent_config": self.agent_config,
|
|
132
133
|
"agent_builder": agent_builder,
|
|
133
134
|
}
|
|
134
|
-
self._agent = None
|
|
135
135
|
self.tools = tools
|
|
136
136
|
|
|
137
137
|
def copy(self) -> "AgnoAgent":
|
|
138
138
|
return AgnoAgent(**self._attr)
|
|
139
139
|
|
|
140
140
|
def build(self, as_context):
|
|
141
|
-
|
|
141
|
+
params = {
|
|
142
142
|
**self._attr["agent_config"],
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
143
|
+
**{
|
|
144
|
+
"model": as_context.model,
|
|
145
|
+
"tools": as_context.toolkit,
|
|
146
|
+
}, # Context will be added at `_agent.arun`
|
|
147
|
+
}
|
|
146
148
|
|
|
147
|
-
|
|
149
|
+
builder_cls = self._attr["agent_builder"]
|
|
150
|
+
_agent = build_agent(builder_cls, params)
|
|
148
151
|
|
|
149
|
-
|
|
152
|
+
return _agent
|
|
153
|
+
|
|
154
|
+
async def run_async(
|
|
155
|
+
self,
|
|
156
|
+
context,
|
|
157
|
+
**kwargs,
|
|
158
|
+
):
|
|
150
159
|
ag_context = AgnoContextAdapter(context=context, attr=self._attr)
|
|
151
160
|
await ag_context.initialize()
|
|
152
161
|
|
|
153
162
|
# We should always build a new agent since the state is manage outside
|
|
154
163
|
# the agent
|
|
155
|
-
|
|
164
|
+
_agent = self.build(ag_context)
|
|
156
165
|
|
|
157
|
-
resp = await
|
|
166
|
+
resp = await _agent.arun(
|
|
158
167
|
ag_context.new_message,
|
|
159
168
|
messages=ag_context.memory,
|
|
160
169
|
stream=True,
|
|
@@ -211,11 +220,3 @@ class AgnoAgent(Agent):
|
|
|
211
220
|
if is_text_delta:
|
|
212
221
|
yield text_message.content_completed(text_delta_content.index)
|
|
213
222
|
yield text_message.completed()
|
|
214
|
-
|
|
215
|
-
async def run_async(
|
|
216
|
-
self,
|
|
217
|
-
context,
|
|
218
|
-
**kwargs,
|
|
219
|
-
):
|
|
220
|
-
async for event in self.run(context):
|
|
221
|
-
yield event
|
|
@@ -11,6 +11,7 @@ from autogen_agentchat.messages import (
|
|
|
11
11
|
ModelClientStreamingChunkEvent,
|
|
12
12
|
)
|
|
13
13
|
|
|
14
|
+
from .utils import build_agent
|
|
14
15
|
from ..agents import Agent
|
|
15
16
|
from ..schemas.context import Context
|
|
16
17
|
from ..schemas.agent_schemas import (
|
|
@@ -136,20 +137,24 @@ class AutogenAgent(Agent):
|
|
|
136
137
|
"agent_config": self.agent_config,
|
|
137
138
|
"agent_builder": agent_builder,
|
|
138
139
|
}
|
|
139
|
-
self._agent = None
|
|
140
140
|
self.tools = tools
|
|
141
141
|
|
|
142
142
|
def copy(self) -> "AutogenAgent":
|
|
143
143
|
return AutogenAgent(**self._attr)
|
|
144
144
|
|
|
145
145
|
def build(self, as_context):
|
|
146
|
-
|
|
146
|
+
params = {
|
|
147
147
|
**self._attr["agent_config"],
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
**{
|
|
149
|
+
"model_client": as_context.model,
|
|
150
|
+
"tools": as_context.toolkit,
|
|
151
|
+
}, # Context will be added at `_agent.run_stream`
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
builder_cls = self._attr["agent_builder"]
|
|
155
|
+
_agent = build_agent(builder_cls, params)
|
|
151
156
|
|
|
152
|
-
return
|
|
157
|
+
return _agent
|
|
153
158
|
|
|
154
159
|
async def run(self, context):
|
|
155
160
|
ag_context = AutogenContextAdapter(context=context, attr=self._attr)
|
|
@@ -157,9 +162,9 @@ class AutogenAgent(Agent):
|
|
|
157
162
|
|
|
158
163
|
# We should always build a new agent since the state is manage outside
|
|
159
164
|
# the agent
|
|
160
|
-
|
|
165
|
+
_agent = self.build(ag_context)
|
|
161
166
|
|
|
162
|
-
resp =
|
|
167
|
+
resp = _agent.run_stream(
|
|
163
168
|
task=ag_context.memory + [ag_context.new_message],
|
|
164
169
|
)
|
|
165
170
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import inspect
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
logger = logging.getLogger(__name__)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def build_agent(builder_cls, params):
|
|
9
|
+
"""
|
|
10
|
+
Filters out unsupported parameters based on the __init__ signature of
|
|
11
|
+
builder_cls
|
|
12
|
+
and instantiates the class.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
builder_cls (type): The class to instantiate.
|
|
16
|
+
params (dict): Dictionary of parameters to pass to the constructor.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
object: An instance of builder_cls.
|
|
20
|
+
"""
|
|
21
|
+
try:
|
|
22
|
+
# Get the signature of the __init__ method
|
|
23
|
+
sig = inspect.signature(builder_cls.__init__)
|
|
24
|
+
allowed_params = set(sig.parameters.keys())
|
|
25
|
+
# Remove 'self' from the list of allowed parameters
|
|
26
|
+
allowed_params.discard("self")
|
|
27
|
+
except (TypeError, ValueError):
|
|
28
|
+
# If signature cannot be inspected, allow all given params
|
|
29
|
+
allowed_params = set(params.keys())
|
|
30
|
+
|
|
31
|
+
filtered_params = {} # Parameters that are accepted by the constructor
|
|
32
|
+
unsupported = [] # Parameters that are not accepted
|
|
33
|
+
|
|
34
|
+
# Separate supported and unsupported parameters
|
|
35
|
+
for k, v in params.items():
|
|
36
|
+
if k in allowed_params:
|
|
37
|
+
filtered_params[k] = v
|
|
38
|
+
else:
|
|
39
|
+
unsupported.append(f"{k}={v!r}")
|
|
40
|
+
|
|
41
|
+
# Log a warning if there are unsupported parameters
|
|
42
|
+
if unsupported:
|
|
43
|
+
unsupported_str = ", ".join(unsupported)
|
|
44
|
+
logger.warning(
|
|
45
|
+
f"The following parameters are not supported by "
|
|
46
|
+
f"{builder_cls.__name__} and have been ignored: "
|
|
47
|
+
f"{unsupported_str}. If you require these parameters, "
|
|
48
|
+
f"please update the `__init__` method of "
|
|
49
|
+
f"{builder_cls.__name__} to accept and handle them.",
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# Instantiate the class with only supported parameters
|
|
53
|
+
return builder_cls(**filtered_params)
|
|
@@ -1,16 +1,3 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
from .base import DeployManager
|
|
3
3
|
from .local_deployer import LocalDeployManager
|
|
4
|
-
from .kubernetes_deployer import (
|
|
5
|
-
KubernetesDeployManager,
|
|
6
|
-
)
|
|
7
|
-
from .modelstudio_deployer import (
|
|
8
|
-
ModelstudioDeployManager,
|
|
9
|
-
)
|
|
10
|
-
|
|
11
|
-
__all__ = [
|
|
12
|
-
"DeployManager",
|
|
13
|
-
"LocalDeployManager",
|
|
14
|
-
"KubernetesDeployManager",
|
|
15
|
-
"ModelstudioDeployManager",
|
|
16
|
-
]
|