agent-framework-devui 0.0.1a0__tar.gz → 1.0.0b251001__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.

Files changed (111) hide show
  1. agent_framework_devui-1.0.0b251001/.gitignore +19 -0
  2. agent_framework_devui-1.0.0b251001/LICENSE +21 -0
  3. agent_framework_devui-1.0.0b251001/PKG-INFO +172 -0
  4. agent_framework_devui-1.0.0b251001/README.md +139 -0
  5. agent_framework_devui-1.0.0b251001/agent_framework_devui/__init__.py +151 -0
  6. agent_framework_devui-1.0.0b251001/agent_framework_devui/_cli.py +143 -0
  7. agent_framework_devui-1.0.0b251001/agent_framework_devui/_discovery.py +724 -0
  8. agent_framework_devui-1.0.0b251001/agent_framework_devui/_executor.py +770 -0
  9. agent_framework_devui-1.0.0b251001/agent_framework_devui/_mapper.py +582 -0
  10. agent_framework_devui-1.0.0b251001/agent_framework_devui/_server.py +530 -0
  11. agent_framework_devui-1.0.0b251001/agent_framework_devui/_session.py +191 -0
  12. agent_framework_devui-1.0.0b251001/agent_framework_devui/_tracing.py +168 -0
  13. agent_framework_devui-1.0.0b251001/agent_framework_devui/models/__init__.py +72 -0
  14. agent_framework_devui-1.0.0b251001/agent_framework_devui/models/_discovery_models.py +51 -0
  15. agent_framework_devui-1.0.0b251001/agent_framework_devui/models/_openai_custom.py +209 -0
  16. agent_framework_devui-1.0.0b251001/agent_framework_devui/ui/assets/index-D1AmQWga.css +1 -0
  17. agent_framework_devui-1.0.0b251001/agent_framework_devui/ui/assets/index-DPEaaIdK.js +435 -0
  18. agent_framework_devui-1.0.0b251001/agent_framework_devui/ui/index.html +14 -0
  19. agent_framework_devui-1.0.0b251001/agent_framework_devui/ui/vite.svg +1 -0
  20. agent_framework_devui-1.0.0b251001/dev.md +111 -0
  21. agent_framework_devui-1.0.0b251001/docs/devuiscreen.png +0 -0
  22. agent_framework_devui-1.0.0b251001/frontend/.gitignore +23 -0
  23. agent_framework_devui-1.0.0b251001/frontend/README.md +69 -0
  24. agent_framework_devui-1.0.0b251001/frontend/components.json +21 -0
  25. agent_framework_devui-1.0.0b251001/frontend/eslint.config.js +23 -0
  26. agent_framework_devui-1.0.0b251001/frontend/index.html +13 -0
  27. agent_framework_devui-1.0.0b251001/frontend/package.json +46 -0
  28. agent_framework_devui-1.0.0b251001/frontend/public/vite.svg +1 -0
  29. agent_framework_devui-1.0.0b251001/frontend/src/App.css +42 -0
  30. agent_framework_devui-1.0.0b251001/frontend/src/App.tsx +470 -0
  31. agent_framework_devui-1.0.0b251001/frontend/src/assets/react.svg +1 -0
  32. agent_framework_devui-1.0.0b251001/frontend/src/components/agent/agent-view.tsx +1082 -0
  33. agent_framework_devui-1.0.0b251001/frontend/src/components/gallery/gallery-view.tsx +412 -0
  34. agent_framework_devui-1.0.0b251001/frontend/src/components/gallery/index.ts +5 -0
  35. agent_framework_devui-1.0.0b251001/frontend/src/components/message_renderer/ContentRenderer.tsx +331 -0
  36. agent_framework_devui-1.0.0b251001/frontend/src/components/message_renderer/MessageRenderer.tsx +38 -0
  37. agent_framework_devui-1.0.0b251001/frontend/src/components/message_renderer/StreamingRenderer.tsx +114 -0
  38. agent_framework_devui-1.0.0b251001/frontend/src/components/message_renderer/index.ts +8 -0
  39. agent_framework_devui-1.0.0b251001/frontend/src/components/message_renderer/types.ts +48 -0
  40. agent_framework_devui-1.0.0b251001/frontend/src/components/mode-toggle.tsx +39 -0
  41. agent_framework_devui-1.0.0b251001/frontend/src/components/shared/about-modal.tsx +55 -0
  42. agent_framework_devui-1.0.0b251001/frontend/src/components/shared/app-header.tsx +54 -0
  43. agent_framework_devui-1.0.0b251001/frontend/src/components/shared/debug-panel.tsx +1394 -0
  44. agent_framework_devui-1.0.0b251001/frontend/src/components/shared/entity-selector.tsx +258 -0
  45. agent_framework_devui-1.0.0b251001/frontend/src/components/shared/settings-modal.tsx +195 -0
  46. agent_framework_devui-1.0.0b251001/frontend/src/components/theme-provider.tsx +33 -0
  47. agent_framework_devui-1.0.0b251001/frontend/src/components/ui/attachment-gallery.tsx +123 -0
  48. agent_framework_devui-1.0.0b251001/frontend/src/components/ui/badge.tsx +36 -0
  49. agent_framework_devui-1.0.0b251001/frontend/src/components/ui/button.tsx +59 -0
  50. agent_framework_devui-1.0.0b251001/frontend/src/components/ui/card.tsx +92 -0
  51. agent_framework_devui-1.0.0b251001/frontend/src/components/ui/checkbox.tsx +32 -0
  52. agent_framework_devui-1.0.0b251001/frontend/src/components/ui/dialog.tsx +104 -0
  53. agent_framework_devui-1.0.0b251001/frontend/src/components/ui/dropdown-menu.tsx +255 -0
  54. agent_framework_devui-1.0.0b251001/frontend/src/components/ui/file-upload.tsx +141 -0
  55. agent_framework_devui-1.0.0b251001/frontend/src/components/ui/input.tsx +21 -0
  56. agent_framework_devui-1.0.0b251001/frontend/src/components/ui/label.tsx +22 -0
  57. agent_framework_devui-1.0.0b251001/frontend/src/components/ui/loading-spinner.tsx +23 -0
  58. agent_framework_devui-1.0.0b251001/frontend/src/components/ui/loading-state.tsx +52 -0
  59. agent_framework_devui-1.0.0b251001/frontend/src/components/ui/scroll-area.tsx +46 -0
  60. agent_framework_devui-1.0.0b251001/frontend/src/components/ui/select.tsx +183 -0
  61. agent_framework_devui-1.0.0b251001/frontend/src/components/ui/tabs.tsx +53 -0
  62. agent_framework_devui-1.0.0b251001/frontend/src/components/ui/textarea.tsx +18 -0
  63. agent_framework_devui-1.0.0b251001/frontend/src/components/workflow/executor-node.tsx +235 -0
  64. agent_framework_devui-1.0.0b251001/frontend/src/components/workflow/workflow-flow.tsx +517 -0
  65. agent_framework_devui-1.0.0b251001/frontend/src/components/workflow/workflow-input-form.tsx +503 -0
  66. agent_framework_devui-1.0.0b251001/frontend/src/components/workflow/workflow-view.tsx +959 -0
  67. agent_framework_devui-1.0.0b251001/frontend/src/data/gallery/index.ts +5 -0
  68. agent_framework_devui-1.0.0b251001/frontend/src/data/gallery/sample-entities.ts +185 -0
  69. agent_framework_devui-1.0.0b251001/frontend/src/hooks/useWorkflowEventCorrelation.ts +126 -0
  70. agent_framework_devui-1.0.0b251001/frontend/src/index.css +147 -0
  71. agent_framework_devui-1.0.0b251001/frontend/src/main.tsx +18 -0
  72. agent_framework_devui-1.0.0b251001/frontend/src/services/api.ts +497 -0
  73. agent_framework_devui-1.0.0b251001/frontend/src/types/agent-framework.ts +319 -0
  74. agent_framework_devui-1.0.0b251001/frontend/src/types/index.ts +152 -0
  75. agent_framework_devui-1.0.0b251001/frontend/src/types/openai.ts +228 -0
  76. agent_framework_devui-1.0.0b251001/frontend/src/types/workflow.ts +159 -0
  77. agent_framework_devui-1.0.0b251001/frontend/src/utils/simple-layout.ts +139 -0
  78. agent_framework_devui-1.0.0b251001/frontend/src/utils/workflow-utils.ts +519 -0
  79. agent_framework_devui-1.0.0b251001/frontend/src/vite-env.d.ts +9 -0
  80. agent_framework_devui-1.0.0b251001/frontend/tsconfig.app.json +29 -0
  81. agent_framework_devui-1.0.0b251001/frontend/tsconfig.json +13 -0
  82. agent_framework_devui-1.0.0b251001/frontend/tsconfig.node.json +23 -0
  83. agent_framework_devui-1.0.0b251001/frontend/vite.config.ts +34 -0
  84. agent_framework_devui-1.0.0b251001/frontend/yarn.lock +2455 -0
  85. agent_framework_devui-1.0.0b251001/pyproject.toml +96 -0
  86. agent_framework_devui-1.0.0b251001/samples/__init__.py +3 -0
  87. agent_framework_devui-1.0.0b251001/samples/fanout_workflow/__init__.py +3 -0
  88. agent_framework_devui-1.0.0b251001/samples/fanout_workflow/workflow.py +700 -0
  89. agent_framework_devui-1.0.0b251001/samples/foundry_agent/__init__.py +7 -0
  90. agent_framework_devui-1.0.0b251001/samples/foundry_agent/agent.py +81 -0
  91. agent_framework_devui-1.0.0b251001/samples/in_memory_mode.py +71 -0
  92. agent_framework_devui-1.0.0b251001/samples/spam_workflow/__init__.py +7 -0
  93. agent_framework_devui-1.0.0b251001/samples/spam_workflow/workflow.py +333 -0
  94. agent_framework_devui-1.0.0b251001/samples/weather_agent/__init__.py +7 -0
  95. agent_framework_devui-1.0.0b251001/samples/weather_agent/agent.py +69 -0
  96. agent_framework_devui-1.0.0b251001/samples/weather_agent_azure/__init__.py +7 -0
  97. agent_framework_devui-1.0.0b251001/samples/weather_agent_azure/agent.py +71 -0
  98. agent_framework_devui-1.0.0b251001/tests/capture_messages.py +284 -0
  99. agent_framework_devui-1.0.0b251001/tests/test_discovery.py +99 -0
  100. agent_framework_devui-1.0.0b251001/tests/test_execution.py +184 -0
  101. agent_framework_devui-1.0.0b251001/tests/test_mapper.py +419 -0
  102. agent_framework_devui-1.0.0b251001/tests/test_server.py +132 -0
  103. agent_framework_devui-0.0.1a0/LICENSE +0 -9
  104. agent_framework_devui-0.0.1a0/PKG-INFO +0 -18
  105. agent_framework_devui-0.0.1a0/README.md +0 -3
  106. agent_framework_devui-0.0.1a0/agent_framework_devui.egg-info/PKG-INFO +0 -18
  107. agent_framework_devui-0.0.1a0/agent_framework_devui.egg-info/SOURCES.txt +0 -7
  108. agent_framework_devui-0.0.1a0/agent_framework_devui.egg-info/dependency_links.txt +0 -1
  109. agent_framework_devui-0.0.1a0/agent_framework_devui.egg-info/top_level.txt +0 -1
  110. agent_framework_devui-0.0.1a0/pyproject.toml +0 -20
  111. agent_framework_devui-0.0.1a0/setup.cfg +0 -4
@@ -0,0 +1,19 @@
1
+ # Test artifacts
2
+ tests/captured_messages/
3
+
4
+ # Python cache
5
+ __pycache__/
6
+ *.py[cod]
7
+ *$py.class
8
+
9
+ # Local development files
10
+ .env
11
+ *.log
12
+
13
+ # IDE files
14
+ .vscode/
15
+ .idea/
16
+
17
+ # OS files
18
+ .DS_Store
19
+ Thumbs.db
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Microsoft Corporation.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE
@@ -0,0 +1,172 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-framework-devui
3
+ Version: 1.0.0b251001
4
+ Summary: Debug UI for Microsoft Agent Framework with OpenAI-compatible API server.
5
+ Author-email: Microsoft <af-support@microsoft.com>
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Typing :: Typed
17
+ License-File: LICENSE
18
+ Requires-Dist: agent-framework-core
19
+ Requires-Dist: fastapi>=0.104.0
20
+ Requires-Dist: uvicorn[standard]>=0.24.0
21
+ Requires-Dist: python-dotenv>=1.0.0
22
+ Requires-Dist: pytest>=7.0.0 ; extra == "all"
23
+ Requires-Dist: watchdog>=3.0.0 ; extra == "all"
24
+ Requires-Dist: pytest>=7.0.0 ; extra == "dev"
25
+ Requires-Dist: watchdog>=3.0.0 ; extra == "dev"
26
+ Project-URL: homepage, https://aka.ms/agent-framework
27
+ Project-URL: issues, https://github.com/microsoft/agent-framework/issues
28
+ Project-URL: release_notes, https://github.com/microsoft/agent-framework/releases?q=tag%3Apython-1&expanded=true
29
+ Project-URL: source, https://github.com/microsoft/agent-framework/tree/main/python
30
+ Provides-Extra: all
31
+ Provides-Extra: dev
32
+
33
+ # DevUI - A Sample App for Running Agents and Workflows
34
+
35
+ A lightweight, standalone sample app interface for running entities (agents/workflows) in the Microsoft Agent Framework supporting **directory-based discovery**, **in-memory entity registration**, and **sample entity gallery**.
36
+
37
+ > [!IMPORTANT]
38
+ > DevUI is a **sample app** to help you get started with the Agent Framework. It is **not** intended for production use. For production, or for features beyond what is provided in this sample app, it is recommended that you build your own custom interface and API server using the Agent Framework SDK.
39
+
40
+ ![DevUI Screenshot](./docs/devuiscreen.png)
41
+
42
+ ## Quick Start
43
+
44
+ ```bash
45
+ # Install
46
+ pip install agent-framework-devui
47
+ ```
48
+
49
+ You can also launch it programmatically
50
+
51
+ ```python
52
+ from agent_framework import ChatAgent
53
+ from agent_framework.openai import OpenAIChatClient
54
+ from agent_framework.devui import serve
55
+
56
+ def get_weather(location: str) -> str:
57
+ """Get weather for a location."""
58
+ return f"Weather in {location}: 72°F and sunny"
59
+
60
+ # Create your agent
61
+ agent = ChatAgent(
62
+ name="WeatherAgent",
63
+ chat_client=OpenAIChatClient(),
64
+ tools=[get_weather]
65
+ )
66
+
67
+ # Launch debug UI - that's it!
68
+ serve(entities=[agent], auto_open=True)
69
+ # → Opens browser to http://localhost:8080
70
+ ```
71
+
72
+ In addition, if you have agents/workflows defined in a specific directory structure (see below), you can launch DevUI from the _cli_ to discover and run them.
73
+
74
+ ```bash
75
+
76
+ # Launch web UI + API server
77
+ devui ./agents --port 8080
78
+ # → Web UI: http://localhost:8080
79
+ # → API: http://localhost:8080/v1/*
80
+ ```
81
+
82
+ When DevUI starts with no discovered entities, it displays a **sample entity gallery** with curated examples from the Agent Framework repository to help you get started quickly.
83
+
84
+ ## Directory Structure
85
+
86
+ 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`).
87
+
88
+ **Note**: `.env` files are optional but will be automatically loaded if present in the agent/workflow directory or parent entities directory. Use them to store API keys, configuration variables, and other environment-specific settings.
89
+
90
+ ```
91
+ agents/
92
+ ├── weather_agent/
93
+ │ ├── __init__.py # Must export: agent = ChatAgent(...)
94
+ │ ├── agent.py
95
+ │ └── .env # Optional: API keys, config vars
96
+ ├── my_workflow/
97
+ │ ├── __init__.py # Must export: workflow = WorkflowBuilder()...
98
+ │ ├── workflow.py
99
+ │ └── .env # Optional: environment variables
100
+ └── .env # Optional: shared environment variables
101
+ ```
102
+
103
+ ## Viewing Telemetry (Otel Traces) in DevUI
104
+
105
+ Agent Framework emits OpenTelemetry (Otel) traces for various operations. You can view these traces in DevUI by enabling tracing when starting the server.
106
+
107
+ ```bash
108
+ devui ./agents --tracing framework
109
+ ```
110
+
111
+ ## OpenAI-Compatible API
112
+
113
+ For convenience, you can interact with the agents/workflows using the standard OpenAI API format. Just specify the `entity_id` in the `extra_body` field. This can be an `agent_id` or `workflow_id`.
114
+
115
+ ```bash
116
+ # Standard OpenAI format
117
+ curl -X POST http://localhost:8080/v1/responses \
118
+ -H "Content-Type: application/json" \
119
+ -d @- << 'EOF'
120
+ {
121
+ "model": "agent-framework",
122
+ "input": "Hello world",
123
+ "extra_body": {"entity_id": "weather_agent"}
124
+ }
125
+
126
+ ```
127
+
128
+ ## CLI Options
129
+
130
+ ```bash
131
+ devui [directory] [options]
132
+
133
+ Options:
134
+ --port, -p Port (default: 8080)
135
+ --host Host (default: 127.0.0.1)
136
+ --headless API only, no UI
137
+ --config YAML config file
138
+ --tracing none|framework|workflow|all
139
+ --reload Enable auto-reload
140
+ ```
141
+
142
+ ## Key Endpoints
143
+
144
+ - `GET /v1/entities` - List discovered agents/workflows
145
+ - `GET /v1/entities/{entity_id}/info` - Get detailed entity information
146
+ - `POST /v1/entities/add` - Add entity from URL (for gallery samples)
147
+ - `DELETE /v1/entities/{entity_id}` - Remove remote entity
148
+ - `POST /v1/responses` - Execute agent/workflow (streaming or sync)
149
+ - `GET /health` - Health check
150
+ - `POST /v1/threads` - Create thread for agent (optional)
151
+ - `GET /v1/threads?agent_id={id}` - List threads for agent
152
+ - `GET /v1/threads/{thread_id}` - Get thread info
153
+ - `DELETE /v1/threads/{thread_id}` - Delete thread
154
+ - `GET /v1/threads/{thread_id}/messages` - Get thread messages
155
+
156
+ ## Implementation
157
+
158
+ - **Discovery**: `agent_framework_devui/_discovery.py`
159
+ - **Execution**: `agent_framework_devui/_executor.py`
160
+ - **Message Mapping**: `agent_framework_devui/_mapper.py`
161
+ - **Session Management**: `agent_framework_devui/_session.py`
162
+ - **API Server**: `agent_framework_devui/_server.py`
163
+ - **CLI**: `agent_framework_devui/_cli.py`
164
+
165
+ ## Examples
166
+
167
+ See `samples/` for working agent and workflow implementations.
168
+
169
+ ## License
170
+
171
+ MIT
172
+
@@ -0,0 +1,139 @@
1
+ # DevUI - A Sample App for Running Agents and Workflows
2
+
3
+ A lightweight, standalone sample app interface for running entities (agents/workflows) in the Microsoft Agent Framework supporting **directory-based discovery**, **in-memory entity registration**, and **sample entity gallery**.
4
+
5
+ > [!IMPORTANT]
6
+ > DevUI is a **sample app** to help you get started with the Agent Framework. It is **not** intended for production use. For production, or for features beyond what is provided in this sample app, it is recommended that you build your own custom interface and API server using the Agent Framework SDK.
7
+
8
+ ![DevUI Screenshot](./docs/devuiscreen.png)
9
+
10
+ ## Quick Start
11
+
12
+ ```bash
13
+ # Install
14
+ pip install agent-framework-devui
15
+ ```
16
+
17
+ You can also launch it programmatically
18
+
19
+ ```python
20
+ from agent_framework import ChatAgent
21
+ from agent_framework.openai import OpenAIChatClient
22
+ from agent_framework.devui import serve
23
+
24
+ def get_weather(location: str) -> str:
25
+ """Get weather for a location."""
26
+ return f"Weather in {location}: 72°F and sunny"
27
+
28
+ # Create your agent
29
+ agent = ChatAgent(
30
+ name="WeatherAgent",
31
+ chat_client=OpenAIChatClient(),
32
+ tools=[get_weather]
33
+ )
34
+
35
+ # Launch debug UI - that's it!
36
+ serve(entities=[agent], auto_open=True)
37
+ # → Opens browser to http://localhost:8080
38
+ ```
39
+
40
+ In addition, if you have agents/workflows defined in a specific directory structure (see below), you can launch DevUI from the _cli_ to discover and run them.
41
+
42
+ ```bash
43
+
44
+ # Launch web UI + API server
45
+ devui ./agents --port 8080
46
+ # → Web UI: http://localhost:8080
47
+ # → API: http://localhost:8080/v1/*
48
+ ```
49
+
50
+ When DevUI starts with no discovered entities, it displays a **sample entity gallery** with curated examples from the Agent Framework repository to help you get started quickly.
51
+
52
+ ## Directory Structure
53
+
54
+ 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`).
55
+
56
+ **Note**: `.env` files are optional but will be automatically loaded if present in the agent/workflow directory or parent entities directory. Use them to store API keys, configuration variables, and other environment-specific settings.
57
+
58
+ ```
59
+ agents/
60
+ ├── weather_agent/
61
+ │ ├── __init__.py # Must export: agent = ChatAgent(...)
62
+ │ ├── agent.py
63
+ │ └── .env # Optional: API keys, config vars
64
+ ├── my_workflow/
65
+ │ ├── __init__.py # Must export: workflow = WorkflowBuilder()...
66
+ │ ├── workflow.py
67
+ │ └── .env # Optional: environment variables
68
+ └── .env # Optional: shared environment variables
69
+ ```
70
+
71
+ ## Viewing Telemetry (Otel Traces) in DevUI
72
+
73
+ Agent Framework emits OpenTelemetry (Otel) traces for various operations. You can view these traces in DevUI by enabling tracing when starting the server.
74
+
75
+ ```bash
76
+ devui ./agents --tracing framework
77
+ ```
78
+
79
+ ## OpenAI-Compatible API
80
+
81
+ For convenience, you can interact with the agents/workflows using the standard OpenAI API format. Just specify the `entity_id` in the `extra_body` field. This can be an `agent_id` or `workflow_id`.
82
+
83
+ ```bash
84
+ # Standard OpenAI format
85
+ curl -X POST http://localhost:8080/v1/responses \
86
+ -H "Content-Type: application/json" \
87
+ -d @- << 'EOF'
88
+ {
89
+ "model": "agent-framework",
90
+ "input": "Hello world",
91
+ "extra_body": {"entity_id": "weather_agent"}
92
+ }
93
+
94
+ ```
95
+
96
+ ## CLI Options
97
+
98
+ ```bash
99
+ devui [directory] [options]
100
+
101
+ Options:
102
+ --port, -p Port (default: 8080)
103
+ --host Host (default: 127.0.0.1)
104
+ --headless API only, no UI
105
+ --config YAML config file
106
+ --tracing none|framework|workflow|all
107
+ --reload Enable auto-reload
108
+ ```
109
+
110
+ ## Key Endpoints
111
+
112
+ - `GET /v1/entities` - List discovered agents/workflows
113
+ - `GET /v1/entities/{entity_id}/info` - Get detailed entity information
114
+ - `POST /v1/entities/add` - Add entity from URL (for gallery samples)
115
+ - `DELETE /v1/entities/{entity_id}` - Remove remote entity
116
+ - `POST /v1/responses` - Execute agent/workflow (streaming or sync)
117
+ - `GET /health` - Health check
118
+ - `POST /v1/threads` - Create thread for agent (optional)
119
+ - `GET /v1/threads?agent_id={id}` - List threads for agent
120
+ - `GET /v1/threads/{thread_id}` - Get thread info
121
+ - `DELETE /v1/threads/{thread_id}` - Delete thread
122
+ - `GET /v1/threads/{thread_id}/messages` - Get thread messages
123
+
124
+ ## Implementation
125
+
126
+ - **Discovery**: `agent_framework_devui/_discovery.py`
127
+ - **Execution**: `agent_framework_devui/_executor.py`
128
+ - **Message Mapping**: `agent_framework_devui/_mapper.py`
129
+ - **Session Management**: `agent_framework_devui/_session.py`
130
+ - **API Server**: `agent_framework_devui/_server.py`
131
+ - **CLI**: `agent_framework_devui/_cli.py`
132
+
133
+ ## Examples
134
+
135
+ See `samples/` for working agent and workflow implementations.
136
+
137
+ ## License
138
+
139
+ MIT
@@ -0,0 +1,151 @@
1
+ # Copyright (c) Microsoft. All rights reserved.
2
+
3
+ """Agent Framework DevUI - Debug interface with OpenAI compatible API server."""
4
+
5
+ import importlib.metadata
6
+ import logging
7
+ import webbrowser
8
+ from typing import Any
9
+
10
+ from ._server import DevServer
11
+ from .models import AgentFrameworkRequest, OpenAIError, OpenAIResponse, ResponseStreamEvent
12
+ from .models._discovery_models import DiscoveryResponse, EntityInfo, EnvVarRequirement
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+ try:
17
+ __version__ = importlib.metadata.version(__name__)
18
+ except importlib.metadata.PackageNotFoundError:
19
+ __version__ = "0.0.0" # Fallback for development mode
20
+
21
+
22
+ def serve(
23
+ entities: list[Any] | None = None,
24
+ entities_dir: str | None = None,
25
+ port: int = 8080,
26
+ host: str = "127.0.0.1",
27
+ auto_open: bool = False,
28
+ cors_origins: list[str] | None = None,
29
+ ui_enabled: bool = True,
30
+ tracing_enabled: bool = False,
31
+ ) -> None:
32
+ """Launch Agent Framework DevUI with simple API.
33
+
34
+ Args:
35
+ entities: List of entities for in-memory registration (IDs auto-generated)
36
+ entities_dir: Directory to scan for entities
37
+ port: Port to run server on
38
+ host: Host to bind server to
39
+ auto_open: Whether to automatically open browser
40
+ cors_origins: List of allowed CORS origins
41
+ ui_enabled: Whether to enable the UI
42
+ tracing_enabled: Whether to enable OpenTelemetry tracing
43
+ """
44
+ import re
45
+
46
+ import uvicorn
47
+
48
+ # Validate host parameter early for security
49
+ if not re.match(r"^(localhost|127\.0\.0\.1|0\.0\.0\.0|[a-zA-Z0-9.-]+)$", host):
50
+ raise ValueError(f"Invalid host: {host}. Must be localhost, IP address, or valid hostname")
51
+
52
+ # Validate port parameter
53
+ if not isinstance(port, int) or not (1 <= port <= 65535):
54
+ raise ValueError(f"Invalid port: {port}. Must be integer between 1 and 65535")
55
+
56
+ # Configure tracing environment variables if enabled
57
+ if tracing_enabled:
58
+ import os
59
+
60
+ # Only set if not already configured by user
61
+ if not os.environ.get("ENABLE_OTEL"):
62
+ os.environ["ENABLE_OTEL"] = "true"
63
+ logger.info("Set ENABLE_OTEL=true for tracing")
64
+
65
+ if not os.environ.get("ENABLE_SENSITIVE_DATA"):
66
+ os.environ["ENABLE_SENSITIVE_DATA"] = "true"
67
+ logger.info("Set ENABLE_SENSITIVE_DATA=true for tracing")
68
+
69
+ if not os.environ.get("OTLP_ENDPOINT"):
70
+ os.environ["OTLP_ENDPOINT"] = "http://localhost:4317"
71
+ logger.info("Set OTLP_ENDPOINT=http://localhost:4317 for tracing")
72
+
73
+ # Create server with direct parameters
74
+ server = DevServer(
75
+ entities_dir=entities_dir, port=port, host=host, cors_origins=cors_origins, ui_enabled=ui_enabled
76
+ )
77
+
78
+ # Register in-memory entities if provided
79
+ if entities:
80
+ logger.info(f"Registering {len(entities)} in-memory entities")
81
+ # Store entities for later registration during server startup
82
+ server._pending_entities = entities
83
+
84
+ app = server.get_app()
85
+
86
+ if auto_open:
87
+
88
+ def open_browser() -> None:
89
+ import http.client
90
+ import re
91
+ import time
92
+
93
+ # Validate host and port for security
94
+ if not re.match(r"^(localhost|127\.0\.0\.1|0\.0\.0\.0|[a-zA-Z0-9.-]+)$", host):
95
+ logger.warning(f"Invalid host for auto-open: {host}")
96
+ return
97
+
98
+ if not isinstance(port, int) or not (1 <= port <= 65535):
99
+ logger.warning(f"Invalid port for auto-open: {port}")
100
+ return
101
+
102
+ # Wait for server to be ready by checking health endpoint
103
+ browser_url = f"http://{host}:{port}"
104
+
105
+ for _ in range(30): # 15 second timeout (30 * 0.5s)
106
+ try:
107
+ # Use http.client for safe connection handling (standard library)
108
+ conn = http.client.HTTPConnection(host, port, timeout=1)
109
+ try:
110
+ conn.request("GET", "/health")
111
+ response = conn.getresponse()
112
+ if response.status == 200:
113
+ webbrowser.open(browser_url)
114
+ return
115
+ finally:
116
+ conn.close()
117
+ except (http.client.HTTPException, OSError, TimeoutError):
118
+ pass
119
+ time.sleep(0.5)
120
+
121
+ # Fallback: open browser anyway after timeout
122
+ webbrowser.open(browser_url)
123
+
124
+ import threading
125
+
126
+ threading.Thread(target=open_browser, daemon=True).start()
127
+
128
+ logger.info(f"Starting Agent Framework DevUI on {host}:{port}")
129
+ uvicorn.run(app, host=host, port=port, log_level="info")
130
+
131
+
132
+ def main() -> None:
133
+ """CLI entry point for devui command."""
134
+ from ._cli import main as cli_main
135
+
136
+ cli_main()
137
+
138
+
139
+ # Export main public API
140
+ __all__ = [
141
+ "AgentFrameworkRequest",
142
+ "DevServer",
143
+ "DiscoveryResponse",
144
+ "EntityInfo",
145
+ "EnvVarRequirement",
146
+ "OpenAIError",
147
+ "OpenAIResponse",
148
+ "ResponseStreamEvent",
149
+ "main",
150
+ "serve",
151
+ ]
@@ -0,0 +1,143 @@
1
+ # Copyright (c) Microsoft. All rights reserved.
2
+
3
+ """Command line interface for Agent Framework DevUI."""
4
+
5
+ import argparse
6
+ import logging
7
+ import os
8
+ import sys
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ def setup_logging(level: str = "INFO") -> None:
14
+ """Configure logging for the server."""
15
+ log_format = "%(asctime)s [%(levelname)s] %(name)s: %(message)s"
16
+ logging.basicConfig(level=getattr(logging, level.upper()), format=log_format, datefmt="%Y-%m-%d %H:%M:%S")
17
+
18
+
19
+ def create_cli_parser() -> argparse.ArgumentParser:
20
+ """Create the command line argument parser."""
21
+ parser = argparse.ArgumentParser(
22
+ prog="devui",
23
+ description="Launch Agent Framework DevUI - Debug interface with OpenAI compatible API",
24
+ formatter_class=argparse.RawDescriptionHelpFormatter,
25
+ epilog="""
26
+ Examples:
27
+ devui # Scan current directory
28
+ devui ./agents # Scan specific directory
29
+ devui --port 8000 # Custom port
30
+ devui --headless # API only, no UI
31
+ devui --tracing # Enable OpenTelemetry tracing
32
+ """,
33
+ )
34
+
35
+ parser.add_argument(
36
+ "directory", nargs="?", default=".", help="Directory to scan for entities (default: current directory)"
37
+ )
38
+
39
+ parser.add_argument("--port", "-p", type=int, default=8080, help="Port to run server on (default: 8080)")
40
+
41
+ parser.add_argument("--host", default="127.0.0.1", help="Host to bind server to (default: 127.0.0.1)")
42
+
43
+ parser.add_argument("--no-open", action="store_true", help="Don't automatically open browser")
44
+
45
+ parser.add_argument("--headless", action="store_true", help="Run without UI (API only)")
46
+
47
+ parser.add_argument(
48
+ "--log-level",
49
+ choices=["DEBUG", "INFO", "WARNING", "ERROR"],
50
+ default="INFO",
51
+ help="Logging level (default: INFO)",
52
+ )
53
+
54
+ parser.add_argument("--reload", action="store_true", help="Enable auto-reload for development")
55
+
56
+ parser.add_argument("--tracing", action="store_true", help="Enable OpenTelemetry tracing for Agent Framework")
57
+
58
+ parser.add_argument("--version", action="version", version=f"Agent Framework DevUI {get_version()}")
59
+
60
+ return parser
61
+
62
+
63
+ def get_version() -> str:
64
+ """Get the package version."""
65
+ try:
66
+ from . import __version__
67
+
68
+ return __version__
69
+ except ImportError:
70
+ return "unknown"
71
+
72
+
73
+ def validate_directory(directory: str) -> str:
74
+ """Validate and normalize the entities directory."""
75
+ if not directory:
76
+ directory = "."
77
+
78
+ abs_dir = os.path.abspath(directory)
79
+
80
+ if not os.path.exists(abs_dir):
81
+ print(f"❌ Error: Directory '{directory}' does not exist", file=sys.stderr) # noqa: T201
82
+ sys.exit(1)
83
+
84
+ if not os.path.isdir(abs_dir):
85
+ print(f"❌ Error: '{directory}' is not a directory", file=sys.stderr) # noqa: T201
86
+ sys.exit(1)
87
+
88
+ return abs_dir
89
+
90
+
91
+ def print_startup_info(entities_dir: str, host: str, port: int, ui_enabled: bool, reload: bool) -> None:
92
+ """Print startup information."""
93
+ print("🤖 Agent Framework DevUI") # noqa: T201
94
+ print("=" * 50) # noqa: T201
95
+ print(f"📁 Entities directory: {entities_dir}") # noqa: T201
96
+ print(f"🌐 Server URL: http://{host}:{port}") # noqa: T201
97
+ print(f"🎨 UI enabled: {'Yes' if ui_enabled else 'No'}") # noqa: T201
98
+ print(f"🔄 Auto-reload: {'Yes' if reload else 'No'}") # noqa: T201
99
+ print("=" * 50) # noqa: T201
100
+ print("🔍 Scanning for entities...") # noqa: T201
101
+
102
+
103
+ def main() -> None:
104
+ """Main CLI entry point."""
105
+ parser = create_cli_parser()
106
+ args = parser.parse_args()
107
+
108
+ # Setup logging
109
+ setup_logging(args.log_level)
110
+
111
+ # Validate directory
112
+ entities_dir = validate_directory(args.directory)
113
+
114
+ # Extract parameters directly from args
115
+ ui_enabled = not args.headless
116
+
117
+ # Print startup info
118
+ print_startup_info(entities_dir, args.host, args.port, ui_enabled, args.reload)
119
+
120
+ # Import and start server
121
+ try:
122
+ from . import serve
123
+
124
+ serve(
125
+ entities_dir=entities_dir,
126
+ port=args.port,
127
+ host=args.host,
128
+ auto_open=not args.no_open,
129
+ ui_enabled=ui_enabled,
130
+ tracing_enabled=args.tracing,
131
+ )
132
+
133
+ except KeyboardInterrupt:
134
+ print("\n👋 Shutting down Agent Framework DevUI...") # noqa: T201
135
+ sys.exit(0)
136
+ except Exception as e:
137
+ logger.exception("Failed to start server")
138
+ print(f"❌ Error: {e}", file=sys.stderr) # noqa: T201
139
+ sys.exit(1)
140
+
141
+
142
+ if __name__ == "__main__":
143
+ main()