agent-dev-cli 0.0.1b260119__py3-none-any.whl → 0.0.1b260205__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.
- {agent_dev_cli-0.0.1b260119.dist-info → agent_dev_cli-0.0.1b260205.dist-info}/METADATA +7 -6
- {agent_dev_cli-0.0.1b260119.dist-info → agent_dev_cli-0.0.1b260205.dist-info}/RECORD +12 -12
- agentdev/__init__.py +4 -4
- agentdev/_hooks.py +4 -4
- agentdev/_version.py +1 -1
- agentdev/backend/_utils.py +5 -5
- agentdev/backend/event_mapper.py +120 -21
- agentdev/backend/server.py +7 -0
- agentdev/localdebug.py +46 -10
- {agent_dev_cli-0.0.1b260119.dist-info → agent_dev_cli-0.0.1b260205.dist-info}/WHEEL +0 -0
- {agent_dev_cli-0.0.1b260119.dist-info → agent_dev_cli-0.0.1b260205.dist-info}/entry_points.txt +0 -0
- {agent_dev_cli-0.0.1b260119.dist-info → agent_dev_cli-0.0.1b260205.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-dev-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.1b260205
|
|
4
4
|
Summary: AI Toolkit - CLI and SDK for agent debugging and workflow visualization
|
|
5
5
|
Keywords: ai,agent,toolkit,debugging,workflow,visualization
|
|
6
6
|
Author-email: Microsoft <aitkfeedback@microsoft.com>
|
|
@@ -26,9 +26,10 @@ Requires-Dist: python-dotenv>=1.2.1
|
|
|
26
26
|
Requires-Dist: azure-ai-agents>=1.2.0b5
|
|
27
27
|
Requires-Dist: starlette>=0.49.3
|
|
28
28
|
Requires-Dist: openai>=1.109.1
|
|
29
|
-
Requires-Dist: agent-framework-azure-ai>=1.0.0b251211
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
Requires-Dist: azure-ai-agentserver-
|
|
29
|
+
Requires-Dist: agent-framework-azure-ai>=1.0.0b251211,<=1.0.0b260107
|
|
30
|
+
Requires-Dist: agent-framework-core>=1.0.0b251211,<=1.0.0b260107
|
|
31
|
+
Requires-Dist: azure-ai-agentserver-agentframework==1.0.0b10
|
|
32
|
+
Requires-Dist: azure-ai-agentserver-core==1.0.0b10
|
|
32
33
|
Requires-Dist: click>=8.1.0
|
|
33
34
|
Requires-Dist: azure-ai-projects>=2.0.0b2
|
|
34
35
|
Project-URL: Documentation, https://github.com/microsoft/vscode-ai-toolkit#readme
|
|
@@ -78,7 +79,7 @@ The CLI automatically:
|
|
|
78
79
|
If you prefer explicit control, you can integrate agentdev directly:
|
|
79
80
|
|
|
80
81
|
```python
|
|
81
|
-
from agentdev import
|
|
82
|
+
from agentdev import configure_agent_server
|
|
82
83
|
from azure.ai.agentserver.agentframework import from_agent_framework
|
|
83
84
|
|
|
84
85
|
# Create your agent
|
|
@@ -88,7 +89,7 @@ agent = build_agent(chat_client)
|
|
|
88
89
|
agent_server = from_agent_framework(agent)
|
|
89
90
|
|
|
90
91
|
# Setup workflow visualization
|
|
91
|
-
|
|
92
|
+
configure_agent_server(agent_server)
|
|
92
93
|
|
|
93
94
|
# Run the server
|
|
94
95
|
await agent_server.run_async()
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
agentdev/__init__.py,sha256=
|
|
1
|
+
agentdev/__init__.py,sha256=bl3B1MKFUJIhoLxHnfEktKYNvWweqJ-ppd9Kf0YOLlw,585
|
|
2
2
|
agentdev/__main__.py,sha256=lHwzD56r-Jd0A_VOGRmv2PcP2AZ56dWz61o3zCBGxzY,135
|
|
3
|
-
agentdev/_hooks.py,sha256
|
|
4
|
-
agentdev/_version.py,sha256=
|
|
3
|
+
agentdev/_hooks.py,sha256=-K2vFMhhZh1D46dEUA1uGgGdU92k6qbXnU98TpgmjTw,9847
|
|
4
|
+
agentdev/_version.py,sha256=QTmmRJaAMr6GP280-vG-90EtyBrbr7gex8cu8UwRCiA,79
|
|
5
5
|
agentdev/bootstrap.py,sha256=sL9CobtPdK4n2piHhFr1-K12AlWgTfgfbdzyfTYWuxc,2192
|
|
6
6
|
agentdev/cli.py,sha256=SWM_SHfZdmLr6ZH8yuGtiMLcd9lhta5YjQxW9xICXac,4948
|
|
7
|
-
agentdev/localdebug.py,sha256=
|
|
7
|
+
agentdev/localdebug.py,sha256=KL3CHFaPskgYU7knTcvY74BthVT7aCOxUZy6ccm12ug,3401
|
|
8
8
|
agentdev/backend/__init__.py,sha256=BFiYU9_0aAfygA0oTs0o70etmH65_gX9cN53ZcMwFIY,197
|
|
9
9
|
agentdev/backend/_conversations.py,sha256=ui62ml5pise0fF9ri7HITM_l4irMdmm2jJ7d_U1FL74,18518
|
|
10
|
-
agentdev/backend/_utils.py,sha256=
|
|
10
|
+
agentdev/backend/_utils.py,sha256=MmysFnqhNmfCyb1cTfLtpGR66yJ2nElpcDQq8j_4hT0,3412
|
|
11
11
|
agentdev/backend/code_analyzer.py,sha256=-B_1Qrf3cbWhvcxjxgk7xbHyfjKuL11GvtzY9wA1hkM,1565
|
|
12
12
|
agentdev/backend/errors.py,sha256=95geZNBeAfxAWyJDCaGFXSFsCifUZ2V0PHmsPOYsmt4,53
|
|
13
|
-
agentdev/backend/event_mapper.py,sha256=
|
|
14
|
-
agentdev/backend/server.py,sha256=
|
|
13
|
+
agentdev/backend/event_mapper.py,sha256=SG-FwGwRJAdwXrBzFtkucqa_P8Wj4QjNcgzdXk7XgQs,17442
|
|
14
|
+
agentdev/backend/server.py,sha256=WEXu37PkXyTpBHlddh_LhAksTNMWS5LEwkT7nMLEGaA,12685
|
|
15
15
|
agentdev/backend/structs/__init__.py,sha256=UKpDMo_sjEtvmHI8Rys6_s4dUYaE0lz3-jw0T_BWoQ8,212
|
|
16
16
|
agentdev/backend/structs/entity_response.py,sha256=dGG-9J3gpGxqu4LV_6UqeoyzjdBqFn8tiesu2EPXzmc,1079
|
|
17
17
|
agentdev/backend/structs/request.py,sha256=lG0Tcp3bvR505DobO9u8XPfeVg-0DGKvt7mhPbGFJRg,2044
|
|
18
|
-
agent_dev_cli-0.0.
|
|
19
|
-
agent_dev_cli-0.0.
|
|
20
|
-
agent_dev_cli-0.0.
|
|
21
|
-
agent_dev_cli-0.0.
|
|
22
|
-
agent_dev_cli-0.0.
|
|
18
|
+
agent_dev_cli-0.0.1b260205.dist-info/entry_points.txt,sha256=Zeb1F0rPDO1dIQorHn7Q-hpOg09ZDE7elz4fowvO6BQ,46
|
|
19
|
+
agent_dev_cli-0.0.1b260205.dist-info/licenses/LICENSE,sha256=spth2ab8cfDqNmKBLSbKHNqnlnDIj-bYaw8insufb2w,3000
|
|
20
|
+
agent_dev_cli-0.0.1b260205.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
21
|
+
agent_dev_cli-0.0.1b260205.dist-info/METADATA,sha256=ykBKkXqRr5E1-vUGohdI2GHh15o0w4rEpDZfAXAEOnU,4504
|
|
22
|
+
agent_dev_cli-0.0.1b260205.dist-info/RECORD,,
|
agentdev/__init__.py
CHANGED
|
@@ -12,11 +12,11 @@ This package provides two ways to use agentdev:
|
|
|
12
12
|
|
|
13
13
|
2. Programmatic API (Requires code modification):
|
|
14
14
|
|
|
15
|
-
from agentdev import
|
|
16
|
-
|
|
15
|
+
from agentdev import configure_agent_server
|
|
16
|
+
configure_agent_server(agent_server)
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
|
-
from .localdebug import
|
|
19
|
+
from .localdebug import configure_agent_server
|
|
20
20
|
from ._version import __version__
|
|
21
21
|
|
|
22
|
-
__all__ = ["
|
|
22
|
+
__all__ = ["configure_agent_server", "__version__"]
|
agentdev/_hooks.py
CHANGED
|
@@ -7,7 +7,7 @@ capabilities without requiring user code modifications.
|
|
|
7
7
|
|
|
8
8
|
The hook intercepts:
|
|
9
9
|
- `azure.ai.agentserver.agentframework.from_agent_framework()`
|
|
10
|
-
to automatically call `
|
|
10
|
+
to automatically call `configure_agent_server()` on the created server.
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
import sys
|
|
@@ -31,7 +31,7 @@ def _create_patched_from_agent_framework(original_func: Callable) -> Callable:
|
|
|
31
31
|
original_func: The original from_agent_framework function
|
|
32
32
|
|
|
33
33
|
Returns:
|
|
34
|
-
Patched function that calls
|
|
34
|
+
Patched function that calls configure_agent_server automatically
|
|
35
35
|
"""
|
|
36
36
|
@functools.wraps(original_func)
|
|
37
37
|
def patched_from_agent_framework(agent: Any, **kwargs) -> Any:
|
|
@@ -48,8 +48,8 @@ def _create_patched_from_agent_framework(original_func: Callable) -> Callable:
|
|
|
48
48
|
|
|
49
49
|
# Auto-inject agentdev visualization
|
|
50
50
|
try:
|
|
51
|
-
from agentdev.localdebug import
|
|
52
|
-
|
|
51
|
+
from agentdev.localdebug import configure_agent_server
|
|
52
|
+
configure_agent_server(server)
|
|
53
53
|
|
|
54
54
|
if verbose:
|
|
55
55
|
print(f"agentdev Hook: Successfully injected agentdev instrumentation", file=sys.stderr)
|
agentdev/_version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""Version information for agentdev package."""
|
|
2
|
-
__version__ = "0.0.
|
|
2
|
+
__version__ = "0.0.1b260205"
|
agentdev/backend/_utils.py
CHANGED
|
@@ -36,11 +36,6 @@ def serialize_data(data: Any, max_depth: int = 10) -> Any:
|
|
|
36
36
|
if isinstance(data, dict):
|
|
37
37
|
return {k: serialize_data(v, max_depth - 1) for k, v in data.items()}
|
|
38
38
|
|
|
39
|
-
# Handle ChatMessage - show as {"role":"xxx", "text":"xxx"}
|
|
40
|
-
if isinstance(data, ChatMessage):
|
|
41
|
-
role_str = data.role.value if hasattr(data.role, 'value') else str(data.role)
|
|
42
|
-
return {"role": role_str, "text": data.text}
|
|
43
|
-
|
|
44
39
|
# Handle AgentExecutorResponse
|
|
45
40
|
if isinstance(data, AgentExecutorResponse):
|
|
46
41
|
result = {}
|
|
@@ -57,6 +52,11 @@ def serialize_data(data: Any, max_depth: int = 10) -> Any:
|
|
|
57
52
|
return serialize_data(dict_data, max_depth - 1)
|
|
58
53
|
except Exception:
|
|
59
54
|
pass
|
|
55
|
+
|
|
56
|
+
# Handle ChatMessage - Fallback if to_dict failed or is not available
|
|
57
|
+
if isinstance(data, ChatMessage):
|
|
58
|
+
role_str = data.role.value if hasattr(data.role, 'value') else str(data.role)
|
|
59
|
+
return {"role": role_str, "text": data.text, "contents": serialize_data(data.contents, max_depth - 1)}
|
|
60
60
|
|
|
61
61
|
# Handle Pydantic models with model_dump()
|
|
62
62
|
if hasattr(data, "model_dump") and callable(data.model_dump):
|
agentdev/backend/event_mapper.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import json
|
|
1
2
|
import time
|
|
2
3
|
from typing import Callable, Type, Any
|
|
3
4
|
from functools import wraps
|
|
@@ -132,16 +133,82 @@ class EventMapper():
|
|
|
132
133
|
|
|
133
134
|
@event_mapper(AgentRunUpdateEvent)
|
|
134
135
|
def _map_agent_run_update_event(self, ctx: MapperContext, event: AgentRunUpdateEvent) -> list[dict]:
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
136
|
+
events = []
|
|
137
|
+
update = event.data
|
|
138
|
+
logging.debug(f"[EventMapper] AgentRunUpdateEvent received, executor_id={event.executor_id}, contents={len(update.contents) if update.contents else 0}")
|
|
139
|
+
if not ctx.item_id:
|
|
140
|
+
# Fallback if item_id not set
|
|
141
|
+
ctx.item_id = f"exec_{event.executor_id}_{str(uuid.uuid4())[:8]}"
|
|
142
|
+
|
|
143
|
+
message_item_id = ctx.item_id + "_message"
|
|
144
|
+
|
|
145
|
+
for content in update.contents:
|
|
146
|
+
logging.debug(f"[EventMapper] Processing content type: {type(content).__name__}")
|
|
147
|
+
if isinstance(content, TextContent):
|
|
148
|
+
events.append({
|
|
149
|
+
"type":"response.output_text.delta",
|
|
150
|
+
"content_index":0,
|
|
151
|
+
"delta": content.text,
|
|
152
|
+
"item_id": message_item_id,
|
|
153
|
+
"logprobs":[],
|
|
154
|
+
"output_index":ctx.output_index,
|
|
155
|
+
})
|
|
156
|
+
elif isinstance(content, FunctionCallContent):
|
|
157
|
+
if content.call_id != ctx.call_id:
|
|
158
|
+
ctx.call_id = content.call_id
|
|
159
|
+
ctx.output_index += 1
|
|
160
|
+
events.append({
|
|
161
|
+
"type":"response.output_item.added",
|
|
162
|
+
"output_index": ctx.output_index,
|
|
163
|
+
"item":{
|
|
164
|
+
"type":"function_call",
|
|
165
|
+
"arguments":"",
|
|
166
|
+
"call_id": ctx.call_id,
|
|
167
|
+
"name": content.name,
|
|
168
|
+
"id": content.call_id,
|
|
169
|
+
"status":"in_progress",
|
|
170
|
+
},
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
# Handle arguments delta
|
|
174
|
+
delta_args = ""
|
|
175
|
+
if isinstance(content.arguments, str):
|
|
176
|
+
delta_args = content.arguments
|
|
177
|
+
elif content.arguments:
|
|
178
|
+
# Serialize dictionary arguments
|
|
179
|
+
try:
|
|
180
|
+
delta_args = json.dumps(serialize_data(content.arguments))
|
|
181
|
+
except Exception as e:
|
|
182
|
+
logging.warning(f"Failed to serialize arguments: {e}")
|
|
183
|
+
delta_args = str(content.arguments)
|
|
184
|
+
|
|
185
|
+
if delta_args:
|
|
186
|
+
events.append({
|
|
187
|
+
"type": "response.function_call_arguments.delta",
|
|
188
|
+
"output_index": ctx.output_index,
|
|
189
|
+
"item_id": ctx.call_id,
|
|
190
|
+
"delta": delta_args,
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
elif isinstance(content, FunctionResultContent):
|
|
194
|
+
serialized_result = None
|
|
195
|
+
try:
|
|
196
|
+
serialized_result = serialize_data(content.result)
|
|
197
|
+
except Exception as e:
|
|
198
|
+
logging.warning(f"Failed to serialize function result: {e}")
|
|
199
|
+
serialized_result = str(content.result)
|
|
200
|
+
|
|
201
|
+
events.append({
|
|
202
|
+
"type":"response.function_result.complete",
|
|
203
|
+
"call_id": content.call_id,
|
|
204
|
+
"output_index": ctx.output_index,
|
|
205
|
+
"output": serialized_result,
|
|
206
|
+
"status":"completed",
|
|
207
|
+
"item_id": ctx.item_id,
|
|
208
|
+
"timestamp":datetime.now().isoformat(),
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
return events
|
|
145
212
|
|
|
146
213
|
@event_mapper(ExecutorEvent)
|
|
147
214
|
def _map_executor_event(self, ctx: MapperContext, event: ExecutorEvent) -> list[dict]:
|
|
@@ -225,6 +292,7 @@ class EventMapper():
|
|
|
225
292
|
@event_mapper(AgentRunResponseUpdate)
|
|
226
293
|
def _map_agent_run_response_update(self, ctx: MapperContext, event: AgentRunResponseUpdate) -> list[dict]:
|
|
227
294
|
item_id = event.message_id
|
|
295
|
+
logging.debug(f"[EventMapper] AgentRunResponseUpdate received, message_id={item_id}, contents={len(event.contents) if event.contents else 0}")
|
|
228
296
|
results = []
|
|
229
297
|
if item_id and item_id != ctx.item_id:
|
|
230
298
|
ctx.item_id = item_id
|
|
@@ -253,16 +321,26 @@ class EventMapper():
|
|
|
253
321
|
|
|
254
322
|
for content in event.contents:
|
|
255
323
|
if isinstance(content, FunctionCallContent):
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
if
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
324
|
+
is_same_call = ctx.call_id and content.call_id == ctx.call_id
|
|
325
|
+
|
|
326
|
+
if is_same_call and content.arguments:
|
|
327
|
+
delta_args = ""
|
|
328
|
+
if isinstance(content.arguments, str):
|
|
329
|
+
delta_args = content.arguments
|
|
330
|
+
elif content.arguments:
|
|
331
|
+
try:
|
|
332
|
+
delta_args = json.dumps(serialize_data(content.arguments))
|
|
333
|
+
except Exception as e:
|
|
334
|
+
logging.warning(f"Failed to serialize arguments: {e}")
|
|
335
|
+
delta_args = str(content.arguments)
|
|
336
|
+
|
|
337
|
+
if delta_args:
|
|
338
|
+
results.append({
|
|
339
|
+
"type": "response.function_call_arguments.delta",
|
|
340
|
+
"output_index": ctx.output_index,
|
|
341
|
+
"item_id": ctx.call_id,
|
|
342
|
+
"delta": delta_args,
|
|
343
|
+
})
|
|
266
344
|
else:
|
|
267
345
|
if content.call_id != ctx.call_id:
|
|
268
346
|
ctx.call_id = content.call_id
|
|
@@ -279,6 +357,24 @@ class EventMapper():
|
|
|
279
357
|
"status":"in_progress",
|
|
280
358
|
},
|
|
281
359
|
})
|
|
360
|
+
if content.arguments:
|
|
361
|
+
initial_args = ""
|
|
362
|
+
if isinstance(content.arguments, str):
|
|
363
|
+
initial_args = content.arguments
|
|
364
|
+
elif content.arguments:
|
|
365
|
+
try:
|
|
366
|
+
initial_args = json.dumps(serialize_data(content.arguments))
|
|
367
|
+
except Exception as e:
|
|
368
|
+
logging.warning(f"Failed to serialize initial arguments: {e}")
|
|
369
|
+
initial_args = str(content.arguments)
|
|
370
|
+
|
|
371
|
+
if initial_args:
|
|
372
|
+
results.append({
|
|
373
|
+
"type": "response.function_call_arguments.delta",
|
|
374
|
+
"output_index": ctx.output_index,
|
|
375
|
+
"item_id": ctx.call_id,
|
|
376
|
+
"delta": initial_args,
|
|
377
|
+
})
|
|
282
378
|
elif isinstance(content, FunctionResultContent):
|
|
283
379
|
results.append({
|
|
284
380
|
"type":"response.function_result.complete",
|
|
@@ -306,10 +402,13 @@ class EventMapper():
|
|
|
306
402
|
|
|
307
403
|
def map_event(self, ctx: MapperContext, event: Any) -> list[dict]:
|
|
308
404
|
"""Map an Agent Framework event to OpenAI Responses API events"""
|
|
405
|
+
logging.debug(f"[EventMapper] map_event called with event type: {type(event).__name__}")
|
|
309
406
|
mapper = self._get_event_mapper(type(event))
|
|
310
407
|
if not mapper:
|
|
311
408
|
logging.warning("Unknown event: %s", type(event))
|
|
312
409
|
return []
|
|
313
410
|
|
|
314
|
-
|
|
411
|
+
result = mapper(ctx, event)
|
|
412
|
+
logging.debug(f"[EventMapper] Mapped to {len(result)} output events: {[e.get('type') for e in result]}")
|
|
413
|
+
return result
|
|
315
414
|
|
agentdev/backend/server.py
CHANGED
|
@@ -18,6 +18,8 @@ from starlette.websockets import WebSocket, WebSocketDisconnect
|
|
|
18
18
|
|
|
19
19
|
from agent_framework import Workflow, ChatMessage, AgentProtocol, Executor
|
|
20
20
|
|
|
21
|
+
from .._version import __version__
|
|
22
|
+
|
|
21
23
|
from .event_mapper import EventMapper, MapperContext
|
|
22
24
|
from .structs.request import AgentFrameworkRequest
|
|
23
25
|
from .structs.entity_response import EntityResponse
|
|
@@ -81,6 +83,7 @@ class TestToolServer:
|
|
|
81
83
|
app = Starlette(routes=[
|
|
82
84
|
# Responses API for workflow and agent
|
|
83
85
|
Route("/v1/responses", endpoint=self.responses, methods=["POST"]),
|
|
86
|
+
Route("/version", endpoint=self.get_version, methods=["GET"]),
|
|
84
87
|
Route("/entities", endpoint=self.list_entities, methods=["GET"]),
|
|
85
88
|
Route("/entities/{entity_id}/info", endpoint=self.get_entity_info, methods=["GET"]),
|
|
86
89
|
Route("/entities/{entity_id}/executor/{executor_id}/location", endpoint=self.get_executor_location, methods=["GET"]),
|
|
@@ -90,6 +93,10 @@ class TestToolServer:
|
|
|
90
93
|
])
|
|
91
94
|
root_app.mount("/agentdev/", app)
|
|
92
95
|
|
|
96
|
+
async def get_version(self, raw_request: Request):
|
|
97
|
+
"""Return the CLI version for compatibility checking."""
|
|
98
|
+
return JSONResponse({"version": __version__})
|
|
99
|
+
|
|
93
100
|
async def list_entities(self, raw_request: Request):
|
|
94
101
|
entities_info = []
|
|
95
102
|
for entity in self._entities:
|
agentdev/localdebug.py
CHANGED
|
@@ -7,9 +7,41 @@ This module provides functionality to set up workflow or agent visualization
|
|
|
7
7
|
from agent_framework import WorkflowAgent
|
|
8
8
|
import logging
|
|
9
9
|
import time
|
|
10
|
+
from typing import Any, Optional
|
|
10
11
|
|
|
11
12
|
|
|
12
|
-
def
|
|
13
|
+
def _get_agent_from_server(agent_server: Any) -> Optional[Any]:
|
|
14
|
+
"""
|
|
15
|
+
Extract the agent from an agent server instance.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
agent_server: The agent server instance
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
The agent instance, or None if not found
|
|
22
|
+
"""
|
|
23
|
+
if hasattr(agent_server, '_agent') and agent_server._agent is not None:
|
|
24
|
+
return agent_server._agent
|
|
25
|
+
|
|
26
|
+
if hasattr(agent_server, 'agent') and agent_server.agent is not None:
|
|
27
|
+
return agent_server.agent
|
|
28
|
+
|
|
29
|
+
if hasattr(agent_server, '_workflow_factory') and agent_server._workflow_factory is not None:
|
|
30
|
+
try:
|
|
31
|
+
return agent_server._workflow_factory().as_agent()
|
|
32
|
+
except Exception as e:
|
|
33
|
+
logging.debug("Failed to build workflow agent (%s): %s", type(e).__name__, e)
|
|
34
|
+
|
|
35
|
+
if hasattr(agent_server, '_build_agent'):
|
|
36
|
+
try:
|
|
37
|
+
return agent_server._build_agent()
|
|
38
|
+
except Exception as e:
|
|
39
|
+
logging.debug("Failed to call _build_agent (%s): %s", type(e).__name__, e)
|
|
40
|
+
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def configure_agent_server(agent_server):
|
|
13
45
|
"""
|
|
14
46
|
Set up workflow or agent visualization for an agent server.
|
|
15
47
|
|
|
@@ -18,12 +50,14 @@ def setup_test_tool(agent_server):
|
|
|
18
50
|
|
|
19
51
|
Args:
|
|
20
52
|
agent_server: The agent server instance to set up visualization for.
|
|
21
|
-
Should have 'app' (Starlette)
|
|
53
|
+
Should have 'app' (Starlette) attribute. The agent is
|
|
54
|
+
extracted using `_get_agent_from_server()` which supports
|
|
55
|
+
both old and new SDK versions.
|
|
22
56
|
|
|
23
57
|
Example:
|
|
24
58
|
>>> from azure.ai.agentserver.agentframework import from_agent_framework
|
|
25
59
|
>>> agent_server = from_agent_framework(agent)
|
|
26
|
-
>>>
|
|
60
|
+
>>> configure_agent_server(agent_server)
|
|
27
61
|
>>> await agent_server.run_async()
|
|
28
62
|
"""
|
|
29
63
|
from starlette.applications import Starlette
|
|
@@ -37,20 +71,22 @@ def setup_test_tool(agent_server):
|
|
|
37
71
|
return JSONResponse({"status": "ok"}, status_code=200)
|
|
38
72
|
|
|
39
73
|
app = agent_server.app
|
|
40
|
-
agent = agent_server
|
|
74
|
+
agent = _get_agent_from_server(agent_server)
|
|
75
|
+
|
|
76
|
+
if agent is None:
|
|
77
|
+
logging.warning("agentdev: Could not extract agent from server, visualization may be limited")
|
|
41
78
|
|
|
42
|
-
# Mount health check endpoint
|
|
43
79
|
app.mount(
|
|
44
80
|
"/agentdev/health",
|
|
45
81
|
Starlette(routes=[Route("/", health_check)])
|
|
46
82
|
)
|
|
47
83
|
|
|
48
|
-
# Prepare entities for visualization
|
|
49
84
|
entities = []
|
|
50
|
-
if
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
85
|
+
if agent is not None:
|
|
86
|
+
if isinstance(agent, WorkflowAgent):
|
|
87
|
+
entities.append(agent.workflow)
|
|
88
|
+
else:
|
|
89
|
+
entities.append(agent)
|
|
54
90
|
|
|
55
91
|
test_tool_server = TestToolServer(entities)
|
|
56
92
|
test_tool_server.mount_backend(app)
|
|
File without changes
|
{agent_dev_cli-0.0.1b260119.dist-info → agent_dev_cli-0.0.1b260205.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{agent_dev_cli-0.0.1b260119.dist-info → agent_dev_cli-0.0.1b260205.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|