agent-framework-devui 1.0.0b251016__tar.gz → 1.0.0b251028__tar.gz
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.
Potentially problematic release.
This version of agent-framework-devui might be problematic. Click here for more details.
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/PKG-INFO +57 -22
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/README.md +56 -21
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/agent_framework_devui/_discovery.py +2 -2
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/agent_framework_devui/_executor.py +19 -8
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/agent_framework_devui/_mapper.py +469 -13
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/agent_framework_devui/_server.py +43 -1
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/agent_framework_devui/_utils.py +24 -2
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/agent_framework_devui/models/__init__.py +6 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/agent_framework_devui/models/_openai_custom.py +67 -2
- agent_framework_devui-1.0.0b251028/agent_framework_devui/ui/assets/index-D_Y1oSGu.js +577 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/agent_framework_devui/ui/index.html +1 -1
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/package.json +1 -1
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/App.tsx +3 -1
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/features/workflow/workflow-view.tsx +101 -30
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/layout/debug-panel.tsx +35 -2
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/markdown-renderer.tsx +3 -3
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/services/api.ts +1 -3
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/types/agent-framework.ts +2 -2
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/types/index.ts +8 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/types/openai.ts +79 -10
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/utils/workflow-utils.ts +52 -2
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/yarn.lock +4 -4
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/pyproject.toml +1 -1
- agent_framework_devui-1.0.0b251028/tests/test_mapper.py +445 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/tests/test_server.py +98 -0
- agent_framework_devui-1.0.0b251016/agent_framework_devui/ui/assets/index-DmL7WSFa.js +0 -577
- agent_framework_devui-1.0.0b251016/tests/test_mapper.py +0 -212
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/.gitignore +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/LICENSE +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/agent_framework_devui/__init__.py +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/agent_framework_devui/_cli.py +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/agent_framework_devui/_conversations.py +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/agent_framework_devui/_session.py +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/agent_framework_devui/_tracing.py +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/agent_framework_devui/models/_discovery_models.py +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/agent_framework_devui/ui/agentframework.svg +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/agent_framework_devui/ui/assets/index-CE4pGoXh.css +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/agent_framework_devui/ui/vite.svg +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/dev.md +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/docs/devuiscreen.png +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/.gitignore +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/README.md +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/components.json +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/eslint.config.js +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/index.html +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/public/agentframework.svg +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/public/vite.svg +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/App.css +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/assets/react.svg +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/features/agent/agent-details-modal.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/features/agent/agent-view.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/features/agent/index.ts +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/features/agent/message-renderers/OpenAIContentRenderer.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/features/agent/message-renderers/OpenAIMessageRenderer.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/features/agent/message-renderers/index.ts +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/features/gallery/gallery-view.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/features/gallery/index.ts +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/features/gallery/setup-instructions-modal.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/features/workflow/executor-node.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/features/workflow/index.ts +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/features/workflow/workflow-details-modal.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/features/workflow/workflow-flow.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/features/workflow/workflow-input-form.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/layout/about-modal.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/layout/app-header.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/layout/deployment-modal.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/layout/entity-selector.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/layout/index.ts +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/layout/settings-modal.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/mode-toggle.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/theme-provider.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/alert.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/attachment-gallery.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/badge.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/button.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/card.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/checkbox.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/dialog.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/dropdown-menu.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/file-upload.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/input.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/label.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/loading-spinner.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/loading-state.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/scroll-area.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/select.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/tabs.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/textarea.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/components/ui/toast.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/data/gallery/index.ts +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/data/gallery/sample-entities.ts +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/hooks/useWorkflowEventCorrelation.ts +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/index.css +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/lib/utils.ts +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/main.tsx +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/stores/devuiStore.ts +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/stores/index.ts +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/types/workflow.ts +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/utils/simple-layout.ts +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/src/vite-env.d.ts +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/tsconfig.app.json +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/tsconfig.json +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/tsconfig.node.json +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/frontend/vite.config.ts +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/samples/README.md +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/samples/__init__.py +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/tests/capture_messages.py +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/tests/test_conversations.py +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/tests/test_discovery.py +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/tests/test_execution.py +0 -0
- {agent_framework_devui-1.0.0b251016 → agent_framework_devui-1.0.0b251028}/tests/test_schema_generation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-framework-devui
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.0b251028
|
|
4
4
|
Summary: Debug UI for Microsoft Agent Framework with OpenAI-compatible API server.
|
|
5
5
|
Author-email: Microsoft <af-support@microsoft.com>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -81,6 +81,19 @@ devui ./agents --port 8080
|
|
|
81
81
|
|
|
82
82
|
When DevUI starts with no discovered entities, it displays a **sample entity gallery** with curated examples from the Agent Framework repository. You can download these samples, review them, and run them locally to get started quickly.
|
|
83
83
|
|
|
84
|
+
## Using MCP Tools
|
|
85
|
+
|
|
86
|
+
**Important:** Don't use `async with` context managers when creating agents with MCP tools for DevUI - connections will close before execution.
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
# ✅ Correct - DevUI handles cleanup automatically
|
|
90
|
+
mcp_tool = MCPStreamableHTTPTool(url="http://localhost:8011/mcp", chat_client=chat_client)
|
|
91
|
+
agent = ChatAgent(tools=mcp_tool)
|
|
92
|
+
serve(entities=[agent])
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
MCP tools use lazy initialization and connect automatically on first use. DevUI attempts to clean up connections on shutdown
|
|
96
|
+
|
|
84
97
|
## Directory Structure
|
|
85
98
|
|
|
86
99
|
For your agents to be discovered by the DevUI, they must be organized in a directory structure like below. Each agent/workflow must have an `__init__.py` that exports the required variable (`agent` or `workflow`).
|
|
@@ -189,42 +202,62 @@ Options:
|
|
|
189
202
|
|
|
190
203
|
Given that DevUI offers an OpenAI Responses API, it internally maps messages and events from Agent Framework to OpenAI Responses API events (in `_mapper.py`). For transparency, this mapping is shown below:
|
|
191
204
|
|
|
192
|
-
| Agent Framework Content
|
|
193
|
-
|
|
|
194
|
-
|
|
|
195
|
-
| `
|
|
196
|
-
| `
|
|
197
|
-
| `
|
|
198
|
-
| `
|
|
199
|
-
| `
|
|
200
|
-
| `
|
|
201
|
-
|
|
|
202
|
-
| `
|
|
203
|
-
| `
|
|
204
|
-
| `
|
|
205
|
-
| `
|
|
206
|
-
| `
|
|
207
|
-
| `
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
205
|
+
| OpenAI Event/Type | Agent Framework Content | Status |
|
|
206
|
+
| ------------------------------------------------------------ | --------------------------------- | -------- |
|
|
207
|
+
| | **Lifecycle Events** | |
|
|
208
|
+
| `response.created` + `response.in_progress` | `AgentStartedEvent` | OpenAI |
|
|
209
|
+
| `response.completed` | `AgentCompletedEvent` | OpenAI |
|
|
210
|
+
| `response.failed` | `AgentFailedEvent` | OpenAI |
|
|
211
|
+
| `response.created` + `response.in_progress` | `WorkflowStartedEvent` | OpenAI |
|
|
212
|
+
| `response.completed` | `WorkflowCompletedEvent` | OpenAI |
|
|
213
|
+
| `response.failed` | `WorkflowFailedEvent` | OpenAI |
|
|
214
|
+
| | **Content Types** | |
|
|
215
|
+
| `response.content_part.added` + `response.output_text.delta` | `TextContent` | OpenAI |
|
|
216
|
+
| `response.reasoning_text.delta` | `TextReasoningContent` | OpenAI |
|
|
217
|
+
| `response.output_item.added` | `FunctionCallContent` (initial) | OpenAI |
|
|
218
|
+
| `response.function_call_arguments.delta` | `FunctionCallContent` (args) | OpenAI |
|
|
219
|
+
| `response.function_result.complete` | `FunctionResultContent` | DevUI |
|
|
220
|
+
| `response.function_approval.requested` | `FunctionApprovalRequestContent` | DevUI |
|
|
221
|
+
| `response.function_approval.responded` | `FunctionApprovalResponseContent` | DevUI |
|
|
222
|
+
| `error` | `ErrorContent` | OpenAI |
|
|
223
|
+
| Final `Response.usage` field (not streamed) | `UsageContent` | OpenAI |
|
|
224
|
+
| | **Workflow Events** | |
|
|
225
|
+
| `response.output_item.added` (ExecutorActionItem)* | `ExecutorInvokedEvent` | OpenAI |
|
|
226
|
+
| `response.output_item.done` (ExecutorActionItem)* | `ExecutorCompletedEvent` | OpenAI |
|
|
227
|
+
| `response.output_item.done` (ExecutorActionItem with error)* | `ExecutorFailedEvent` | OpenAI |
|
|
228
|
+
| `response.workflow_event.complete` | `WorkflowEvent` (other) | DevUI |
|
|
229
|
+
| `response.trace.complete` | `WorkflowStatusEvent` | DevUI |
|
|
230
|
+
| `response.trace.complete` | `WorkflowWarningEvent` | DevUI |
|
|
231
|
+
| | **Trace Content** | |
|
|
232
|
+
| `response.trace.complete` | `DataContent` | DevUI |
|
|
233
|
+
| `response.trace.complete` | `UriContent` | DevUI |
|
|
234
|
+
| `response.trace.complete` | `HostedFileContent` | DevUI |
|
|
235
|
+
| `response.trace.complete` | `HostedVectorStoreContent` | DevUI |
|
|
236
|
+
|
|
237
|
+
\*Uses standard OpenAI event structure but carries DevUI-specific `ExecutorActionItem` payload
|
|
238
|
+
|
|
239
|
+
- **OpenAI** = Standard OpenAI Responses API event types
|
|
240
|
+
- **DevUI** = Custom event types specific to Agent Framework (e.g., workflows, traces, function approvals)
|
|
211
241
|
|
|
212
242
|
### OpenAI Responses API Compliance
|
|
213
243
|
|
|
214
244
|
DevUI follows the OpenAI Responses API specification for maximum compatibility:
|
|
215
245
|
|
|
216
|
-
**Standard
|
|
246
|
+
**OpenAI Standard Event Types Used:**
|
|
247
|
+
|
|
217
248
|
- `ResponseOutputItemAddedEvent` - Output item notifications (function calls and results)
|
|
249
|
+
- `ResponseOutputItemDoneEvent` - Output item completion notifications
|
|
218
250
|
- `Response.usage` - Token usage (in final response, not streamed)
|
|
219
251
|
- All standard text, reasoning, and function call events
|
|
220
252
|
|
|
221
253
|
**Custom DevUI Extensions:**
|
|
254
|
+
|
|
222
255
|
- `response.function_approval.requested` - Function approval requests (for interactive approval workflows)
|
|
223
256
|
- `response.function_approval.responded` - Function approval responses (user approval/rejection)
|
|
224
257
|
- `response.workflow_event.complete` - Agent Framework workflow events
|
|
225
258
|
- `response.trace.complete` - Execution traces and internal content (DataContent, UriContent, hosted files/stores)
|
|
226
259
|
|
|
227
|
-
These custom extensions are clearly namespaced and can be safely ignored by standard OpenAI clients.
|
|
260
|
+
These custom extensions are clearly namespaced and can be safely ignored by standard OpenAI clients. Note that DevUI also uses standard OpenAI events with custom payloads (e.g., `ExecutorActionItem` within `response.output_item.added`).
|
|
228
261
|
|
|
229
262
|
### Entity Management
|
|
230
263
|
|
|
@@ -256,12 +289,14 @@ These custom extensions are clearly namespaced and can be safely ignored by stan
|
|
|
256
289
|
DevUI is designed as a **sample application for local development** and should not be exposed to untrusted networks or used in production environments.
|
|
257
290
|
|
|
258
291
|
**Security features:**
|
|
292
|
+
|
|
259
293
|
- Only loads entities from local directories or in-memory registration
|
|
260
294
|
- No remote code execution capabilities
|
|
261
295
|
- Binds to localhost (127.0.0.1) by default
|
|
262
296
|
- All samples must be manually downloaded and reviewed before running
|
|
263
297
|
|
|
264
298
|
**Best practices:**
|
|
299
|
+
|
|
265
300
|
- Never expose DevUI to the internet
|
|
266
301
|
- Review all agent/workflow code before running
|
|
267
302
|
- Only load entities from trusted sources
|
|
@@ -49,6 +49,19 @@ devui ./agents --port 8080
|
|
|
49
49
|
|
|
50
50
|
When DevUI starts with no discovered entities, it displays a **sample entity gallery** with curated examples from the Agent Framework repository. You can download these samples, review them, and run them locally to get started quickly.
|
|
51
51
|
|
|
52
|
+
## Using MCP Tools
|
|
53
|
+
|
|
54
|
+
**Important:** Don't use `async with` context managers when creating agents with MCP tools for DevUI - connections will close before execution.
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
# ✅ Correct - DevUI handles cleanup automatically
|
|
58
|
+
mcp_tool = MCPStreamableHTTPTool(url="http://localhost:8011/mcp", chat_client=chat_client)
|
|
59
|
+
agent = ChatAgent(tools=mcp_tool)
|
|
60
|
+
serve(entities=[agent])
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
MCP tools use lazy initialization and connect automatically on first use. DevUI attempts to clean up connections on shutdown
|
|
64
|
+
|
|
52
65
|
## Directory Structure
|
|
53
66
|
|
|
54
67
|
For your agents to be discovered by the DevUI, they must be organized in a directory structure like below. Each agent/workflow must have an `__init__.py` that exports the required variable (`agent` or `workflow`).
|
|
@@ -157,42 +170,62 @@ Options:
|
|
|
157
170
|
|
|
158
171
|
Given that DevUI offers an OpenAI Responses API, it internally maps messages and events from Agent Framework to OpenAI Responses API events (in `_mapper.py`). For transparency, this mapping is shown below:
|
|
159
172
|
|
|
160
|
-
| Agent Framework Content
|
|
161
|
-
|
|
|
162
|
-
|
|
|
163
|
-
| `
|
|
164
|
-
| `
|
|
165
|
-
| `
|
|
166
|
-
| `
|
|
167
|
-
| `
|
|
168
|
-
| `
|
|
169
|
-
|
|
|
170
|
-
| `
|
|
171
|
-
| `
|
|
172
|
-
| `
|
|
173
|
-
| `
|
|
174
|
-
| `
|
|
175
|
-
| `
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
173
|
+
| OpenAI Event/Type | Agent Framework Content | Status |
|
|
174
|
+
| ------------------------------------------------------------ | --------------------------------- | -------- |
|
|
175
|
+
| | **Lifecycle Events** | |
|
|
176
|
+
| `response.created` + `response.in_progress` | `AgentStartedEvent` | OpenAI |
|
|
177
|
+
| `response.completed` | `AgentCompletedEvent` | OpenAI |
|
|
178
|
+
| `response.failed` | `AgentFailedEvent` | OpenAI |
|
|
179
|
+
| `response.created` + `response.in_progress` | `WorkflowStartedEvent` | OpenAI |
|
|
180
|
+
| `response.completed` | `WorkflowCompletedEvent` | OpenAI |
|
|
181
|
+
| `response.failed` | `WorkflowFailedEvent` | OpenAI |
|
|
182
|
+
| | **Content Types** | |
|
|
183
|
+
| `response.content_part.added` + `response.output_text.delta` | `TextContent` | OpenAI |
|
|
184
|
+
| `response.reasoning_text.delta` | `TextReasoningContent` | OpenAI |
|
|
185
|
+
| `response.output_item.added` | `FunctionCallContent` (initial) | OpenAI |
|
|
186
|
+
| `response.function_call_arguments.delta` | `FunctionCallContent` (args) | OpenAI |
|
|
187
|
+
| `response.function_result.complete` | `FunctionResultContent` | DevUI |
|
|
188
|
+
| `response.function_approval.requested` | `FunctionApprovalRequestContent` | DevUI |
|
|
189
|
+
| `response.function_approval.responded` | `FunctionApprovalResponseContent` | DevUI |
|
|
190
|
+
| `error` | `ErrorContent` | OpenAI |
|
|
191
|
+
| Final `Response.usage` field (not streamed) | `UsageContent` | OpenAI |
|
|
192
|
+
| | **Workflow Events** | |
|
|
193
|
+
| `response.output_item.added` (ExecutorActionItem)* | `ExecutorInvokedEvent` | OpenAI |
|
|
194
|
+
| `response.output_item.done` (ExecutorActionItem)* | `ExecutorCompletedEvent` | OpenAI |
|
|
195
|
+
| `response.output_item.done` (ExecutorActionItem with error)* | `ExecutorFailedEvent` | OpenAI |
|
|
196
|
+
| `response.workflow_event.complete` | `WorkflowEvent` (other) | DevUI |
|
|
197
|
+
| `response.trace.complete` | `WorkflowStatusEvent` | DevUI |
|
|
198
|
+
| `response.trace.complete` | `WorkflowWarningEvent` | DevUI |
|
|
199
|
+
| | **Trace Content** | |
|
|
200
|
+
| `response.trace.complete` | `DataContent` | DevUI |
|
|
201
|
+
| `response.trace.complete` | `UriContent` | DevUI |
|
|
202
|
+
| `response.trace.complete` | `HostedFileContent` | DevUI |
|
|
203
|
+
| `response.trace.complete` | `HostedVectorStoreContent` | DevUI |
|
|
204
|
+
|
|
205
|
+
\*Uses standard OpenAI event structure but carries DevUI-specific `ExecutorActionItem` payload
|
|
206
|
+
|
|
207
|
+
- **OpenAI** = Standard OpenAI Responses API event types
|
|
208
|
+
- **DevUI** = Custom event types specific to Agent Framework (e.g., workflows, traces, function approvals)
|
|
179
209
|
|
|
180
210
|
### OpenAI Responses API Compliance
|
|
181
211
|
|
|
182
212
|
DevUI follows the OpenAI Responses API specification for maximum compatibility:
|
|
183
213
|
|
|
184
|
-
**Standard
|
|
214
|
+
**OpenAI Standard Event Types Used:**
|
|
215
|
+
|
|
185
216
|
- `ResponseOutputItemAddedEvent` - Output item notifications (function calls and results)
|
|
217
|
+
- `ResponseOutputItemDoneEvent` - Output item completion notifications
|
|
186
218
|
- `Response.usage` - Token usage (in final response, not streamed)
|
|
187
219
|
- All standard text, reasoning, and function call events
|
|
188
220
|
|
|
189
221
|
**Custom DevUI Extensions:**
|
|
222
|
+
|
|
190
223
|
- `response.function_approval.requested` - Function approval requests (for interactive approval workflows)
|
|
191
224
|
- `response.function_approval.responded` - Function approval responses (user approval/rejection)
|
|
192
225
|
- `response.workflow_event.complete` - Agent Framework workflow events
|
|
193
226
|
- `response.trace.complete` - Execution traces and internal content (DataContent, UriContent, hosted files/stores)
|
|
194
227
|
|
|
195
|
-
These custom extensions are clearly namespaced and can be safely ignored by standard OpenAI clients.
|
|
228
|
+
These custom extensions are clearly namespaced and can be safely ignored by standard OpenAI clients. Note that DevUI also uses standard OpenAI events with custom payloads (e.g., `ExecutorActionItem` within `response.output_item.added`).
|
|
196
229
|
|
|
197
230
|
### Entity Management
|
|
198
231
|
|
|
@@ -224,12 +257,14 @@ These custom extensions are clearly namespaced and can be safely ignored by stan
|
|
|
224
257
|
DevUI is designed as a **sample application for local development** and should not be exposed to untrusted networks or used in production environments.
|
|
225
258
|
|
|
226
259
|
**Security features:**
|
|
260
|
+
|
|
227
261
|
- Only loads entities from local directories or in-memory registration
|
|
228
262
|
- No remote code execution capabilities
|
|
229
263
|
- Binds to localhost (127.0.0.1) by default
|
|
230
264
|
- All samples must be manually downloaded and reviewed before running
|
|
231
265
|
|
|
232
266
|
**Best practices:**
|
|
267
|
+
|
|
233
268
|
- Never expose DevUI to the internet
|
|
234
269
|
- Review all agent/workflow code before running
|
|
235
270
|
- Only load entities from trusted sources
|
|
@@ -127,7 +127,7 @@ class EntityDiscovery:
|
|
|
127
127
|
|
|
128
128
|
# Cache the loaded object
|
|
129
129
|
self._loaded_objects[entity_id] = entity_obj
|
|
130
|
-
logger.info(f"
|
|
130
|
+
logger.info(f"Successfully loaded entity: {entity_id} (type: {enriched_info.type})")
|
|
131
131
|
|
|
132
132
|
return entity_obj
|
|
133
133
|
|
|
@@ -217,7 +217,7 @@ class EntityDiscovery:
|
|
|
217
217
|
if entity_info and "lazy_loaded" in entity_info.metadata:
|
|
218
218
|
entity_info.metadata["lazy_loaded"] = False
|
|
219
219
|
|
|
220
|
-
logger.info(f"
|
|
220
|
+
logger.info(f"Entity invalidated: {entity_id} (will reload on next access)")
|
|
221
221
|
|
|
222
222
|
def invalidate_all(self) -> None:
|
|
223
223
|
"""Invalidate all cached entities.
|
|
@@ -217,6 +217,11 @@ class AgentFrameworkExecutor:
|
|
|
217
217
|
Agent update events and trace events
|
|
218
218
|
"""
|
|
219
219
|
try:
|
|
220
|
+
# Emit agent lifecycle start event
|
|
221
|
+
from .models._openai_custom import AgentStartedEvent
|
|
222
|
+
|
|
223
|
+
yield AgentStartedEvent()
|
|
224
|
+
|
|
220
225
|
# Convert input to proper ChatMessage or string
|
|
221
226
|
user_message = self._convert_input_to_chat_message(request.input)
|
|
222
227
|
|
|
@@ -266,8 +271,19 @@ class AgentFrameworkExecutor:
|
|
|
266
271
|
else:
|
|
267
272
|
raise ValueError("Agent must implement either run() or run_stream() method")
|
|
268
273
|
|
|
274
|
+
# Emit agent lifecycle completion event
|
|
275
|
+
from .models._openai_custom import AgentCompletedEvent
|
|
276
|
+
|
|
277
|
+
yield AgentCompletedEvent()
|
|
278
|
+
|
|
269
279
|
except Exception as e:
|
|
270
280
|
logger.error(f"Error in agent execution: {e}")
|
|
281
|
+
# Emit agent lifecycle failure event
|
|
282
|
+
from .models._openai_custom import AgentFailedEvent
|
|
283
|
+
|
|
284
|
+
yield AgentFailedEvent(error=e)
|
|
285
|
+
|
|
286
|
+
# Still yield the error for backward compatibility
|
|
271
287
|
yield {"type": "error", "message": f"Agent execution error: {e!s}"}
|
|
272
288
|
|
|
273
289
|
async def _execute_workflow(
|
|
@@ -284,14 +300,9 @@ class AgentFrameworkExecutor:
|
|
|
284
300
|
Workflow events and trace events
|
|
285
301
|
"""
|
|
286
302
|
try:
|
|
287
|
-
# Get input data
|
|
288
|
-
input_data
|
|
289
|
-
|
|
290
|
-
input_data = request.extra_body.get("input_data") # type: ignore
|
|
291
|
-
logger.debug(f"Using structured input_data from extra_body: {type(input_data)}")
|
|
292
|
-
else:
|
|
293
|
-
input_data = request.input
|
|
294
|
-
logger.debug(f"Using input field as fallback: {type(input_data)}")
|
|
303
|
+
# Get input data directly from request.input field
|
|
304
|
+
input_data = request.input
|
|
305
|
+
logger.debug(f"Using input field: {type(input_data)}")
|
|
295
306
|
|
|
296
307
|
# Parse input based on workflow's expected input type
|
|
297
308
|
parsed_input = await self._parse_workflow_input(workflow, input_data)
|