agent-framework-devui 0.0.1a0__py3-none-any.whl → 1.0.0b251007__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.
Potentially problematic release.
This version of agent-framework-devui might be problematic. Click here for more details.
- agent_framework_devui/__init__.py +151 -0
- agent_framework_devui/_cli.py +143 -0
- agent_framework_devui/_discovery.py +822 -0
- agent_framework_devui/_executor.py +777 -0
- agent_framework_devui/_mapper.py +558 -0
- agent_framework_devui/_server.py +577 -0
- agent_framework_devui/_session.py +191 -0
- agent_framework_devui/_tracing.py +168 -0
- agent_framework_devui/_utils.py +421 -0
- agent_framework_devui/models/__init__.py +72 -0
- agent_framework_devui/models/_discovery_models.py +58 -0
- agent_framework_devui/models/_openai_custom.py +209 -0
- agent_framework_devui/ui/agentframework.svg +33 -0
- agent_framework_devui/ui/assets/index-D0SfShuZ.js +445 -0
- agent_framework_devui/ui/assets/index-WsCIE0bH.css +1 -0
- agent_framework_devui/ui/index.html +14 -0
- agent_framework_devui/ui/vite.svg +1 -0
- agent_framework_devui-1.0.0b251007.dist-info/METADATA +172 -0
- agent_framework_devui-1.0.0b251007.dist-info/RECORD +22 -0
- {agent_framework_devui-0.0.1a0.dist-info → agent_framework_devui-1.0.0b251007.dist-info}/WHEEL +1 -2
- agent_framework_devui-1.0.0b251007.dist-info/entry_points.txt +3 -0
- agent_framework_devui-1.0.0b251007.dist-info/licenses/LICENSE +21 -0
- agent_framework_devui-0.0.1a0.dist-info/METADATA +0 -18
- agent_framework_devui-0.0.1a0.dist-info/RECORD +0 -5
- agent_framework_devui-0.0.1a0.dist-info/licenses/LICENSE +0 -9
- agent_framework_devui-0.0.1a0.dist-info/top_level.txt +0 -1
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
# Copyright (c) Microsoft. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Utility functions for DevUI."""
|
|
4
|
+
|
|
5
|
+
import inspect
|
|
6
|
+
import json
|
|
7
|
+
import logging
|
|
8
|
+
from dataclasses import fields, is_dataclass
|
|
9
|
+
from typing import Any, get_args, get_origin
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
# ============================================================================
|
|
14
|
+
# Type System Utilities
|
|
15
|
+
# ============================================================================
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def is_serialization_mixin(cls: type) -> bool:
|
|
19
|
+
"""Check if class is a SerializationMixin subclass.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
cls: Class to check
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
True if class is a SerializationMixin subclass
|
|
26
|
+
"""
|
|
27
|
+
try:
|
|
28
|
+
from agent_framework._serialization import SerializationMixin
|
|
29
|
+
|
|
30
|
+
return isinstance(cls, type) and issubclass(cls, SerializationMixin)
|
|
31
|
+
except ImportError:
|
|
32
|
+
return False
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _type_to_schema(type_hint: Any, field_name: str) -> dict[str, Any]:
|
|
36
|
+
"""Convert a type hint to JSON schema.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
type_hint: Type hint to convert
|
|
40
|
+
field_name: Name of the field (for documentation)
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
JSON schema dict
|
|
44
|
+
"""
|
|
45
|
+
type_str = str(type_hint)
|
|
46
|
+
|
|
47
|
+
# Handle None/Optional
|
|
48
|
+
if type_hint is type(None):
|
|
49
|
+
return {"type": "null"}
|
|
50
|
+
|
|
51
|
+
# Handle basic types
|
|
52
|
+
if type_hint is str or "str" in type_str:
|
|
53
|
+
return {"type": "string"}
|
|
54
|
+
if type_hint is int or "int" in type_str:
|
|
55
|
+
return {"type": "integer"}
|
|
56
|
+
if type_hint is float or "float" in type_str:
|
|
57
|
+
return {"type": "number"}
|
|
58
|
+
if type_hint is bool or "bool" in type_str:
|
|
59
|
+
return {"type": "boolean"}
|
|
60
|
+
|
|
61
|
+
# Handle Literal types (for enum-like values)
|
|
62
|
+
if "Literal" in type_str:
|
|
63
|
+
origin = get_origin(type_hint)
|
|
64
|
+
if origin is not None:
|
|
65
|
+
args = get_args(type_hint)
|
|
66
|
+
if args:
|
|
67
|
+
return {"type": "string", "enum": list(args)}
|
|
68
|
+
|
|
69
|
+
# Handle Union/Optional
|
|
70
|
+
if "Union" in type_str or "Optional" in type_str:
|
|
71
|
+
origin = get_origin(type_hint)
|
|
72
|
+
if origin is not None:
|
|
73
|
+
args = get_args(type_hint)
|
|
74
|
+
# Filter out None type
|
|
75
|
+
non_none_args = [arg for arg in args if arg is not type(None)]
|
|
76
|
+
if len(non_none_args) == 1:
|
|
77
|
+
return _type_to_schema(non_none_args[0], field_name)
|
|
78
|
+
# Multiple types - pick first non-None
|
|
79
|
+
if non_none_args:
|
|
80
|
+
return _type_to_schema(non_none_args[0], field_name)
|
|
81
|
+
|
|
82
|
+
# Handle collections
|
|
83
|
+
if "list" in type_str or "List" in type_str or "Sequence" in type_str:
|
|
84
|
+
origin = get_origin(type_hint)
|
|
85
|
+
if origin is not None:
|
|
86
|
+
args = get_args(type_hint)
|
|
87
|
+
if args:
|
|
88
|
+
items_schema = _type_to_schema(args[0], field_name)
|
|
89
|
+
return {"type": "array", "items": items_schema}
|
|
90
|
+
return {"type": "array"}
|
|
91
|
+
|
|
92
|
+
if "dict" in type_str or "Dict" in type_str or "Mapping" in type_str:
|
|
93
|
+
return {"type": "object"}
|
|
94
|
+
|
|
95
|
+
# Default fallback
|
|
96
|
+
return {"type": "string", "description": f"Type: {type_hint}"}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def generate_schema_from_serialization_mixin(cls: type[Any]) -> dict[str, Any]:
|
|
100
|
+
"""Generate JSON schema from SerializationMixin class.
|
|
101
|
+
|
|
102
|
+
Introspects the __init__ signature to extract parameter types and defaults.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
cls: SerializationMixin subclass
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
JSON schema dict
|
|
109
|
+
"""
|
|
110
|
+
sig = inspect.signature(cls)
|
|
111
|
+
|
|
112
|
+
# Get type hints
|
|
113
|
+
try:
|
|
114
|
+
from typing import get_type_hints
|
|
115
|
+
|
|
116
|
+
type_hints = get_type_hints(cls)
|
|
117
|
+
except Exception:
|
|
118
|
+
type_hints = {}
|
|
119
|
+
|
|
120
|
+
properties: dict[str, Any] = {}
|
|
121
|
+
required: list[str] = []
|
|
122
|
+
|
|
123
|
+
for param_name, param in sig.parameters.items():
|
|
124
|
+
if param_name in ("self", "kwargs"):
|
|
125
|
+
continue
|
|
126
|
+
|
|
127
|
+
# Get type annotation
|
|
128
|
+
param_type = type_hints.get(param_name, str)
|
|
129
|
+
|
|
130
|
+
# Generate schema for this parameter
|
|
131
|
+
param_schema = _type_to_schema(param_type, param_name)
|
|
132
|
+
properties[param_name] = param_schema
|
|
133
|
+
|
|
134
|
+
# Check if required (no default value, not VAR_KEYWORD)
|
|
135
|
+
if param.default == inspect.Parameter.empty and param.kind != inspect.Parameter.VAR_KEYWORD:
|
|
136
|
+
required.append(param_name)
|
|
137
|
+
|
|
138
|
+
schema: dict[str, Any] = {"type": "object", "properties": properties}
|
|
139
|
+
|
|
140
|
+
if required:
|
|
141
|
+
schema["required"] = required
|
|
142
|
+
|
|
143
|
+
return schema
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def generate_schema_from_dataclass(cls: type[Any]) -> dict[str, Any]:
|
|
147
|
+
"""Generate JSON schema from dataclass.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
cls: Dataclass type
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
JSON schema dict
|
|
154
|
+
"""
|
|
155
|
+
if not is_dataclass(cls):
|
|
156
|
+
return {"type": "object"}
|
|
157
|
+
|
|
158
|
+
properties: dict[str, Any] = {}
|
|
159
|
+
required: list[str] = []
|
|
160
|
+
|
|
161
|
+
for field in fields(cls):
|
|
162
|
+
# Generate schema for field type
|
|
163
|
+
field_schema = _type_to_schema(field.type, field.name)
|
|
164
|
+
properties[field.name] = field_schema
|
|
165
|
+
|
|
166
|
+
# Check if required (no default value)
|
|
167
|
+
if field.default == field.default_factory: # No default
|
|
168
|
+
required.append(field.name)
|
|
169
|
+
|
|
170
|
+
schema: dict[str, Any] = {"type": "object", "properties": properties}
|
|
171
|
+
|
|
172
|
+
if required:
|
|
173
|
+
schema["required"] = required
|
|
174
|
+
|
|
175
|
+
return schema
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def generate_input_schema(input_type: type) -> dict[str, Any]:
|
|
179
|
+
"""Generate JSON schema for workflow input type.
|
|
180
|
+
|
|
181
|
+
Supports multiple input types in priority order:
|
|
182
|
+
1. Built-in types (str, dict, int, etc.)
|
|
183
|
+
2. Pydantic models (via model_json_schema)
|
|
184
|
+
3. SerializationMixin classes (via __init__ introspection)
|
|
185
|
+
4. Dataclasses (via fields introspection)
|
|
186
|
+
5. Fallback to string
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
input_type: Input type to generate schema for
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
JSON schema dict
|
|
193
|
+
"""
|
|
194
|
+
# 1. Built-in types
|
|
195
|
+
if input_type is str:
|
|
196
|
+
return {"type": "string"}
|
|
197
|
+
if input_type is dict:
|
|
198
|
+
return {"type": "object"}
|
|
199
|
+
if input_type is int:
|
|
200
|
+
return {"type": "integer"}
|
|
201
|
+
if input_type is float:
|
|
202
|
+
return {"type": "number"}
|
|
203
|
+
if input_type is bool:
|
|
204
|
+
return {"type": "boolean"}
|
|
205
|
+
|
|
206
|
+
# 2. Pydantic models (legacy support)
|
|
207
|
+
if hasattr(input_type, "model_json_schema"):
|
|
208
|
+
return input_type.model_json_schema() # type: ignore
|
|
209
|
+
|
|
210
|
+
# 3. SerializationMixin classes (ChatMessage, etc.)
|
|
211
|
+
if is_serialization_mixin(input_type):
|
|
212
|
+
return generate_schema_from_serialization_mixin(input_type)
|
|
213
|
+
|
|
214
|
+
# 4. Dataclasses
|
|
215
|
+
if is_dataclass(input_type):
|
|
216
|
+
return generate_schema_from_dataclass(input_type)
|
|
217
|
+
|
|
218
|
+
# 5. Fallback to string
|
|
219
|
+
type_name = getattr(input_type, "__name__", str(input_type))
|
|
220
|
+
return {"type": "string", "description": f"Input type: {type_name}"}
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
# ============================================================================
|
|
224
|
+
# Input Parsing Utilities
|
|
225
|
+
# ============================================================================
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def parse_input_for_type(input_data: Any, target_type: type) -> Any:
|
|
229
|
+
"""Parse input data to match the target type.
|
|
230
|
+
|
|
231
|
+
Handles conversion from raw input (string, dict) to the expected type:
|
|
232
|
+
- Built-in types: direct conversion
|
|
233
|
+
- Pydantic models: use model_validate or model_validate_json
|
|
234
|
+
- SerializationMixin: use from_dict or construct from string
|
|
235
|
+
- Dataclasses: construct from dict
|
|
236
|
+
|
|
237
|
+
Args:
|
|
238
|
+
input_data: Raw input data (string, dict, or already correct type)
|
|
239
|
+
target_type: Expected type for the input
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
Parsed input matching target_type, or original input if parsing fails
|
|
243
|
+
"""
|
|
244
|
+
# If already correct type, return as-is
|
|
245
|
+
if isinstance(input_data, target_type):
|
|
246
|
+
return input_data
|
|
247
|
+
|
|
248
|
+
# Handle string input
|
|
249
|
+
if isinstance(input_data, str):
|
|
250
|
+
return _parse_string_input(input_data, target_type)
|
|
251
|
+
|
|
252
|
+
# Handle dict input
|
|
253
|
+
if isinstance(input_data, dict):
|
|
254
|
+
return _parse_dict_input(input_data, target_type)
|
|
255
|
+
|
|
256
|
+
# Fallback: return original
|
|
257
|
+
return input_data
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def _parse_string_input(input_str: str, target_type: type) -> Any:
|
|
261
|
+
"""Parse string input to target type.
|
|
262
|
+
|
|
263
|
+
Args:
|
|
264
|
+
input_str: Input string
|
|
265
|
+
target_type: Target type
|
|
266
|
+
|
|
267
|
+
Returns:
|
|
268
|
+
Parsed input or original string
|
|
269
|
+
"""
|
|
270
|
+
# Built-in types
|
|
271
|
+
if target_type is str:
|
|
272
|
+
return input_str
|
|
273
|
+
if target_type is int:
|
|
274
|
+
try:
|
|
275
|
+
return int(input_str)
|
|
276
|
+
except ValueError:
|
|
277
|
+
return input_str
|
|
278
|
+
elif target_type is float:
|
|
279
|
+
try:
|
|
280
|
+
return float(input_str)
|
|
281
|
+
except ValueError:
|
|
282
|
+
return input_str
|
|
283
|
+
elif target_type is bool:
|
|
284
|
+
return input_str.lower() in ("true", "1", "yes")
|
|
285
|
+
|
|
286
|
+
# Pydantic models
|
|
287
|
+
if hasattr(target_type, "model_validate_json"):
|
|
288
|
+
try:
|
|
289
|
+
# Try parsing as JSON first
|
|
290
|
+
if input_str.strip().startswith("{"):
|
|
291
|
+
return target_type.model_validate_json(input_str) # type: ignore
|
|
292
|
+
|
|
293
|
+
# Try common field names with the string value
|
|
294
|
+
common_fields = ["text", "message", "content", "input", "data"]
|
|
295
|
+
for field in common_fields:
|
|
296
|
+
try:
|
|
297
|
+
return target_type(**{field: input_str}) # type: ignore
|
|
298
|
+
except Exception as e:
|
|
299
|
+
logger.debug(f"Failed to parse string input with field '{field}': {e}")
|
|
300
|
+
continue
|
|
301
|
+
except Exception as e:
|
|
302
|
+
logger.debug(f"Failed to parse string as Pydantic model: {e}")
|
|
303
|
+
|
|
304
|
+
# SerializationMixin (like ChatMessage)
|
|
305
|
+
if is_serialization_mixin(target_type):
|
|
306
|
+
try:
|
|
307
|
+
# Try parsing as JSON dict first
|
|
308
|
+
if input_str.strip().startswith("{"):
|
|
309
|
+
data = json.loads(input_str)
|
|
310
|
+
if hasattr(target_type, "from_dict"):
|
|
311
|
+
return target_type.from_dict(data) # type: ignore
|
|
312
|
+
return target_type(**data) # type: ignore
|
|
313
|
+
|
|
314
|
+
# For ChatMessage specifically: create from text
|
|
315
|
+
# Try common field patterns
|
|
316
|
+
common_fields = ["text", "message", "content"]
|
|
317
|
+
sig = inspect.signature(target_type)
|
|
318
|
+
params = list(sig.parameters.keys())
|
|
319
|
+
|
|
320
|
+
# If it has 'text' param, use it
|
|
321
|
+
if "text" in params:
|
|
322
|
+
try:
|
|
323
|
+
return target_type(role="user", text=input_str) # type: ignore
|
|
324
|
+
except Exception as e:
|
|
325
|
+
logger.debug(f"Failed to create SerializationMixin with text field: {e}")
|
|
326
|
+
|
|
327
|
+
# Try other common fields
|
|
328
|
+
for field in common_fields:
|
|
329
|
+
if field in params:
|
|
330
|
+
try:
|
|
331
|
+
return target_type(**{field: input_str}) # type: ignore
|
|
332
|
+
except Exception as e:
|
|
333
|
+
logger.debug(f"Failed to create SerializationMixin with field '{field}': {e}")
|
|
334
|
+
continue
|
|
335
|
+
except Exception as e:
|
|
336
|
+
logger.debug(f"Failed to parse string as SerializationMixin: {e}")
|
|
337
|
+
|
|
338
|
+
# Dataclasses
|
|
339
|
+
if is_dataclass(target_type):
|
|
340
|
+
try:
|
|
341
|
+
# Try parsing as JSON
|
|
342
|
+
if input_str.strip().startswith("{"):
|
|
343
|
+
data = json.loads(input_str)
|
|
344
|
+
return target_type(**data) # type: ignore
|
|
345
|
+
|
|
346
|
+
# Try common field names
|
|
347
|
+
common_fields = ["text", "message", "content", "input", "data"]
|
|
348
|
+
for field in common_fields:
|
|
349
|
+
try:
|
|
350
|
+
return target_type(**{field: input_str}) # type: ignore
|
|
351
|
+
except Exception as e:
|
|
352
|
+
logger.debug(f"Failed to create dataclass with field '{field}': {e}")
|
|
353
|
+
continue
|
|
354
|
+
except Exception as e:
|
|
355
|
+
logger.debug(f"Failed to parse string as dataclass: {e}")
|
|
356
|
+
|
|
357
|
+
# Fallback: return original string
|
|
358
|
+
return input_str
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
def _parse_dict_input(input_dict: dict[str, Any], target_type: type) -> Any:
|
|
362
|
+
"""Parse dict input to target type.
|
|
363
|
+
|
|
364
|
+
Args:
|
|
365
|
+
input_dict: Input dictionary
|
|
366
|
+
target_type: Target type
|
|
367
|
+
|
|
368
|
+
Returns:
|
|
369
|
+
Parsed input or original dict
|
|
370
|
+
"""
|
|
371
|
+
# Handle primitive types - extract from common field names
|
|
372
|
+
if target_type in (str, int, float, bool):
|
|
373
|
+
try:
|
|
374
|
+
# If it's already the right type, return as-is
|
|
375
|
+
if isinstance(input_dict, target_type):
|
|
376
|
+
return input_dict
|
|
377
|
+
|
|
378
|
+
# Try "input" field first (common for workflow inputs)
|
|
379
|
+
if "input" in input_dict:
|
|
380
|
+
return target_type(input_dict["input"]) # type: ignore
|
|
381
|
+
|
|
382
|
+
# If single-key dict, extract the value
|
|
383
|
+
if len(input_dict) == 1:
|
|
384
|
+
value = next(iter(input_dict.values()))
|
|
385
|
+
return target_type(value) # type: ignore
|
|
386
|
+
|
|
387
|
+
# Otherwise, return as-is
|
|
388
|
+
return input_dict
|
|
389
|
+
except (ValueError, TypeError) as e:
|
|
390
|
+
logger.debug(f"Failed to convert dict to {target_type}: {e}")
|
|
391
|
+
return input_dict
|
|
392
|
+
|
|
393
|
+
# If target is dict, return as-is
|
|
394
|
+
if target_type is dict:
|
|
395
|
+
return input_dict
|
|
396
|
+
|
|
397
|
+
# Pydantic models
|
|
398
|
+
if hasattr(target_type, "model_validate"):
|
|
399
|
+
try:
|
|
400
|
+
return target_type.model_validate(input_dict) # type: ignore
|
|
401
|
+
except Exception as e:
|
|
402
|
+
logger.debug(f"Failed to validate dict as Pydantic model: {e}")
|
|
403
|
+
|
|
404
|
+
# SerializationMixin
|
|
405
|
+
if is_serialization_mixin(target_type):
|
|
406
|
+
try:
|
|
407
|
+
if hasattr(target_type, "from_dict"):
|
|
408
|
+
return target_type.from_dict(input_dict) # type: ignore
|
|
409
|
+
return target_type(**input_dict) # type: ignore
|
|
410
|
+
except Exception as e:
|
|
411
|
+
logger.debug(f"Failed to parse dict as SerializationMixin: {e}")
|
|
412
|
+
|
|
413
|
+
# Dataclasses
|
|
414
|
+
if is_dataclass(target_type):
|
|
415
|
+
try:
|
|
416
|
+
return target_type(**input_dict) # type: ignore
|
|
417
|
+
except Exception as e:
|
|
418
|
+
logger.debug(f"Failed to parse dict as dataclass: {e}")
|
|
419
|
+
|
|
420
|
+
# Fallback: return original dict
|
|
421
|
+
return input_dict
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Copyright (c) Microsoft. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Agent Framework DevUI Models - OpenAI-compatible types and custom extensions."""
|
|
4
|
+
|
|
5
|
+
# Import discovery models
|
|
6
|
+
# Import all OpenAI types directly from the openai package
|
|
7
|
+
from openai.types.responses import (
|
|
8
|
+
Response,
|
|
9
|
+
ResponseErrorEvent,
|
|
10
|
+
ResponseFunctionCallArgumentsDeltaEvent,
|
|
11
|
+
ResponseInputParam,
|
|
12
|
+
ResponseOutputMessage,
|
|
13
|
+
ResponseOutputText,
|
|
14
|
+
ResponseReasoningTextDeltaEvent,
|
|
15
|
+
ResponseStreamEvent,
|
|
16
|
+
ResponseTextDeltaEvent,
|
|
17
|
+
ResponseUsage,
|
|
18
|
+
ToolParam,
|
|
19
|
+
)
|
|
20
|
+
from openai.types.responses.response_usage import InputTokensDetails, OutputTokensDetails
|
|
21
|
+
from openai.types.shared import Metadata, ResponsesModel
|
|
22
|
+
|
|
23
|
+
from ._discovery_models import DiscoveryResponse, EntityInfo
|
|
24
|
+
from ._openai_custom import (
|
|
25
|
+
AgentFrameworkRequest,
|
|
26
|
+
OpenAIError,
|
|
27
|
+
ResponseFunctionResultComplete,
|
|
28
|
+
ResponseFunctionResultDelta,
|
|
29
|
+
ResponseTraceEvent,
|
|
30
|
+
ResponseTraceEventComplete,
|
|
31
|
+
ResponseTraceEventDelta,
|
|
32
|
+
ResponseUsageEventComplete,
|
|
33
|
+
ResponseUsageEventDelta,
|
|
34
|
+
ResponseWorkflowEventComplete,
|
|
35
|
+
ResponseWorkflowEventDelta,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# Type alias for compatibility
|
|
39
|
+
OpenAIResponse = Response
|
|
40
|
+
|
|
41
|
+
# Export all types for easy importing
|
|
42
|
+
__all__ = [
|
|
43
|
+
"AgentFrameworkRequest",
|
|
44
|
+
"DiscoveryResponse",
|
|
45
|
+
"EntityInfo",
|
|
46
|
+
"InputTokensDetails",
|
|
47
|
+
"Metadata",
|
|
48
|
+
"OpenAIError",
|
|
49
|
+
"OpenAIResponse",
|
|
50
|
+
"OutputTokensDetails",
|
|
51
|
+
"Response",
|
|
52
|
+
"ResponseErrorEvent",
|
|
53
|
+
"ResponseFunctionCallArgumentsDeltaEvent",
|
|
54
|
+
"ResponseFunctionResultComplete",
|
|
55
|
+
"ResponseFunctionResultDelta",
|
|
56
|
+
"ResponseInputParam",
|
|
57
|
+
"ResponseOutputMessage",
|
|
58
|
+
"ResponseOutputText",
|
|
59
|
+
"ResponseReasoningTextDeltaEvent",
|
|
60
|
+
"ResponseStreamEvent",
|
|
61
|
+
"ResponseTextDeltaEvent",
|
|
62
|
+
"ResponseTraceEvent",
|
|
63
|
+
"ResponseTraceEventComplete",
|
|
64
|
+
"ResponseTraceEventDelta",
|
|
65
|
+
"ResponseUsage",
|
|
66
|
+
"ResponseUsageEventComplete",
|
|
67
|
+
"ResponseUsageEventDelta",
|
|
68
|
+
"ResponseWorkflowEventComplete",
|
|
69
|
+
"ResponseWorkflowEventDelta",
|
|
70
|
+
"ResponsesModel",
|
|
71
|
+
"ToolParam",
|
|
72
|
+
]
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Copyright (c) Microsoft. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Discovery API models for entity information."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel, Field
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class EnvVarRequirement(BaseModel):
|
|
13
|
+
"""Environment variable requirement for an entity."""
|
|
14
|
+
|
|
15
|
+
name: str
|
|
16
|
+
description: str
|
|
17
|
+
required: bool = True
|
|
18
|
+
example: str | None = None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class EntityInfo(BaseModel):
|
|
22
|
+
"""Entity information for discovery and detailed views."""
|
|
23
|
+
|
|
24
|
+
# Always present (core entity data)
|
|
25
|
+
id: str
|
|
26
|
+
type: str # "agent", "workflow"
|
|
27
|
+
name: str
|
|
28
|
+
description: str | None = None
|
|
29
|
+
framework: str
|
|
30
|
+
tools: list[str | dict[str, Any]] | None = None
|
|
31
|
+
metadata: dict[str, Any] = Field(default_factory=dict)
|
|
32
|
+
|
|
33
|
+
# Source information
|
|
34
|
+
source: str = "directory" # "directory", "in_memory", "remote_gallery"
|
|
35
|
+
original_url: str | None = None
|
|
36
|
+
|
|
37
|
+
# Environment variable requirements
|
|
38
|
+
required_env_vars: list[EnvVarRequirement] | None = None
|
|
39
|
+
|
|
40
|
+
# Agent-specific fields (optional, populated when available)
|
|
41
|
+
instructions: str | None = None
|
|
42
|
+
model_id: str | None = None
|
|
43
|
+
chat_client_type: str | None = None
|
|
44
|
+
context_providers: list[str] | None = None
|
|
45
|
+
middleware: list[str] | None = None
|
|
46
|
+
|
|
47
|
+
# Workflow-specific fields (populated only for detailed info requests)
|
|
48
|
+
executors: list[str] | None = None
|
|
49
|
+
workflow_dump: dict[str, Any] | None = None
|
|
50
|
+
input_schema: dict[str, Any] | None = None
|
|
51
|
+
input_type_name: str | None = None
|
|
52
|
+
start_executor_id: str | None = None
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class DiscoveryResponse(BaseModel):
|
|
56
|
+
"""Response model for entity discovery."""
|
|
57
|
+
|
|
58
|
+
entities: list[EntityInfo] = Field(default_factory=list)
|