Revert "Merge from main"

This reverts commit b8206a85d7.
This commit is contained in:
Dmytro Struk
2025-11-11 18:44:25 -08:00
Unverified
parent b8206a85d7
commit 85fcd230bf
231 changed files with 4138 additions and 19654 deletions
@@ -27,18 +27,14 @@ from openai.types.responses import (
from openai.types.responses.response_usage import InputTokensDetails, OutputTokensDetails
from openai.types.shared import Metadata, ResponsesModel
from ._discovery_models import Deployment, DeploymentConfig, DeploymentEvent, DiscoveryResponse, EntityInfo
from ._discovery_models import DiscoveryResponse, EntityInfo
from ._openai_custom import (
AgentFrameworkRequest,
CustomResponseOutputItemAddedEvent,
CustomResponseOutputItemDoneEvent,
ExecutorActionItem,
MetaResponse,
OpenAIError,
ResponseFunctionResultComplete,
ResponseOutputData,
ResponseOutputFile,
ResponseOutputImage,
ResponseTraceEvent,
ResponseTraceEventComplete,
ResponseWorkflowEventComplete,
@@ -55,14 +51,10 @@ __all__ = [
"ConversationItem",
"CustomResponseOutputItemAddedEvent",
"CustomResponseOutputItemDoneEvent",
"Deployment",
"DeploymentConfig",
"DeploymentEvent",
"DiscoveryResponse",
"EntityInfo",
"ExecutorActionItem",
"InputTokensDetails",
"MetaResponse",
"Metadata",
"OpenAIError",
"OpenAIResponse",
@@ -75,9 +67,6 @@ __all__ = [
"ResponseFunctionToolCall",
"ResponseFunctionToolCallOutputItem",
"ResponseInputParam",
"ResponseOutputData",
"ResponseOutputFile",
"ResponseOutputImage",
"ResponseOutputItemAddedEvent",
"ResponseOutputItemDoneEvent",
"ResponseOutputMessage",
@@ -4,10 +4,9 @@
from __future__ import annotations
import re
from typing import Any
from pydantic import BaseModel, Field, field_validator
from pydantic import BaseModel, Field
class EnvVarRequirement(BaseModel):
@@ -37,10 +36,6 @@ class EntityInfo(BaseModel):
# Environment variable requirements
required_env_vars: list[EnvVarRequirement] | None = None
# Deployment support
deployment_supported: bool = False # Whether entity can be deployed
deployment_reason: str | None = None # Explanation of why/why not entity can be deployed
# Agent-specific fields (optional, populated when available)
instructions: str | None = None
model_id: str | None = None
@@ -60,144 +55,3 @@ class DiscoveryResponse(BaseModel):
"""Response model for entity discovery."""
entities: list[EntityInfo] = Field(default_factory=list)
# ============================================================================
# Deployment Models
# ============================================================================
class DeploymentConfig(BaseModel):
"""Configuration for deploying an entity."""
entity_id: str = Field(description="Entity ID to deploy")
resource_group: str = Field(description="Azure resource group name")
app_name: str = Field(description="Azure Container App name")
region: str = Field(default="eastus", description="Azure region")
ui_mode: str = Field(default="user", description="UI mode (user or developer)")
ui_enabled: bool = Field(default=True, description="Whether to enable web interface")
stream: bool = Field(default=True, description="Stream deployment events")
@field_validator("app_name")
@classmethod
def validate_app_name(cls, v: str) -> str:
"""Validate Azure Container App name format.
Azure Container App names must:
- Be 3-32 characters long
- Contain only lowercase letters, numbers, and hyphens
- Start with a lowercase letter
- End with a lowercase letter or number
- Not contain consecutive hyphens
"""
if not v:
raise ValueError("app_name cannot be empty")
if len(v) < 3 or len(v) > 32:
raise ValueError("app_name must be between 3 and 32 characters")
if not re.match(r"^[a-z][a-z0-9-]*[a-z0-9]$", v):
raise ValueError(
"app_name must start with a lowercase letter, "
"end with a letter or number, and contain only lowercase letters, numbers, and hyphens"
)
if "--" in v:
raise ValueError("app_name cannot contain consecutive hyphens")
return v
@field_validator("resource_group")
@classmethod
def validate_resource_group(cls, v: str) -> str:
"""Validate Azure resource group name format.
Azure resource group names must:
- Be 1-90 characters long
- Contain only alphanumeric, underscore, parentheses, hyphen, period (except at end)
- Not end with a period
"""
if not v:
raise ValueError("resource_group cannot be empty")
if len(v) > 90:
raise ValueError("resource_group must be 90 characters or less")
if not re.match(r"^[a-zA-Z0-9._()-]+$", v):
raise ValueError(
"resource_group can only contain alphanumeric characters, "
"underscores, hyphens, periods, and parentheses"
)
if v.endswith("."):
raise ValueError("resource_group cannot end with a period")
return v
@field_validator("region")
@classmethod
def validate_region(cls, v: str) -> str:
"""Validate Azure region format.
Validates that the region string is a reasonable format.
Does not validate against the full list of Azure regions (which changes).
"""
if not v:
raise ValueError("region cannot be empty")
if len(v) > 50:
raise ValueError("region name too long")
# Azure regions are typically lowercase with no spaces (e.g., eastus, westeurope)
if not re.match(r"^[a-z0-9]+$", v):
raise ValueError("region must contain only lowercase letters and numbers (e.g., eastus, westeurope)")
return v
@field_validator("entity_id")
@classmethod
def validate_entity_id(cls, v: str) -> str:
"""Validate entity_id format to prevent injection attacks."""
if not v:
raise ValueError("entity_id cannot be empty")
if len(v) > 256:
raise ValueError("entity_id too long")
# Allow alphanumeric, hyphens, underscores, and periods
if not re.match(r"^[a-zA-Z0-9._-]+$", v):
raise ValueError("entity_id contains invalid characters")
return v
@field_validator("ui_mode")
@classmethod
def validate_ui_mode(cls, v: str) -> str:
"""Validate ui_mode is one of the allowed values."""
if v not in ("user", "developer"):
raise ValueError("ui_mode must be 'user' or 'developer'")
return v
class DeploymentEvent(BaseModel):
"""Real-time deployment event (SSE)."""
type: str = Field(description="Event type (e.g., deploy.validating, deploy.building)")
message: str = Field(description="Human-readable message")
url: str | None = Field(default=None, description="Deployment URL (on completion)")
auth_token: str | None = Field(default=None, description="Auth token (on completion, shown once)")
class Deployment(BaseModel):
"""Deployment record."""
id: str = Field(description="Deployment ID (UUID)")
entity_id: str = Field(description="Entity ID that was deployed")
resource_group: str = Field(description="Azure resource group")
app_name: str = Field(description="Azure Container App name")
region: str = Field(description="Azure region")
url: str = Field(description="Deployment URL")
status: str = Field(description="Deployment status (deploying, deployed, failed)")
created_at: str = Field(description="ISO 8601 timestamp")
error: str | None = Field(default=None, description="Error message if failed")
@@ -80,16 +80,9 @@ class CustomResponseOutputItemDoneEvent(BaseModel):
class ResponseWorkflowEventComplete(BaseModel):
"""Complete workflow event data.
"""Complete workflow event data."""
DevUI extension for workflow execution events (debugging/observability).
Uses past-tense 'completed' to follow OpenAI's event naming pattern.
Workflow events are shown in the debug panel for monitoring execution flow,
not in main chat. Use response.output_item.added for user-facing content.
"""
type: Literal["response.workflow_event.completed"] = "response.workflow_event.completed"
type: Literal["response.workflow_event.complete"] = "response.workflow_event.complete"
data: dict[str, Any] # Complete event data, not delta
executor_id: str | None = None
item_id: str
@@ -98,17 +91,9 @@ class ResponseWorkflowEventComplete(BaseModel):
class ResponseTraceEventComplete(BaseModel):
"""Complete trace event data.
"""Complete trace event data."""
DevUI extension for non-displayable debugging/metadata events.
Uses past-tense 'completed' to follow OpenAI's event naming pattern
(e.g., response.completed, response.output_item.added).
Trace events are shown in the Traces debug panel, not in main chat.
Use response.output_item.added for user-facing content.
"""
type: Literal["response.trace.completed"] = "response.trace.completed"
type: Literal["response.trace.complete"] = "response.trace.complete"
data: dict[str, Any] # Complete trace data, not delta
span_id: str | None = None
item_id: str
@@ -139,139 +124,6 @@ class ResponseFunctionResultComplete(BaseModel):
timestamp: str | None = None # Optional timestamp for UI display
class ResponseRequestInfoEvent(BaseModel):
"""DevUI extension: Workflow requests human input.
This is a DevUI extension because:
- OpenAI Responses API doesn't have a concept of workflow human-in-the-loop pausing
- Agent Framework workflows can pause via RequestInfoExecutor to collect external information
- Clients need to render forms and submit responses to continue workflow execution
When a workflow emits this event, it enters IDLE_WITH_PENDING_REQUESTS state.
Client should render a form based on request_schema and submit responses via
a new request with workflow_hil_response content type.
"""
type: Literal["response.request_info.requested"] = "response.request_info.requested"
request_id: str
"""Unique identifier for correlating this request with the response."""
source_executor_id: str
"""ID of the executor that is waiting for this response."""
request_type: str
"""Fully qualified type name of the request (e.g., 'module.path:ClassName')."""
request_data: dict[str, Any]
"""Current data from the RequestInfoMessage (may contain defaults/context)."""
request_schema: dict[str, Any]
"""JSON schema describing the request data structure (what the workflow is asking about)."""
response_schema: dict[str, Any] | None = None
"""JSON schema describing the expected response structure for form rendering (what user should provide)."""
item_id: str
"""OpenAI item ID for correlation."""
output_index: int = 0
"""Output index for OpenAI compatibility."""
sequence_number: int
"""Sequence number for ordering events."""
timestamp: str
"""ISO timestamp when the request was made."""
# DevUI Output Content Types - for agent-generated media/data
# These extend ResponseOutputItem to support rich content outputs that OpenAI's API doesn't natively support
class ResponseOutputImage(BaseModel):
"""DevUI extension: Agent-generated image output.
This is a DevUI extension because:
- OpenAI Responses API only supports text output in ResponseOutputMessage.content
- ImageGenerationCall exists but is for tool calls (generating images), not returning existing images
- Agent Framework agents can return images via DataContent/UriContent that need proper display
This type allows images to be displayed inline in chat rather than hidden in trace logs.
"""
id: str
"""The unique ID of the image output."""
image_url: str
"""The URL or data URI of the image (e.g., data:image/png;base64,...)"""
type: Literal["output_image"] = "output_image"
"""The type of the output. Always `output_image`."""
alt_text: str | None = None
"""Optional alt text for accessibility."""
mime_type: str = "image/png"
"""The MIME type of the image (e.g., image/png, image/jpeg)."""
class ResponseOutputFile(BaseModel):
"""DevUI extension: Agent-generated file output.
This is a DevUI extension because:
- OpenAI Responses API only supports text output in ResponseOutputMessage.content
- Agent Framework agents can return files via DataContent/UriContent that need proper display
- Supports PDFs, audio files, and other media types
This type allows files to be displayed inline in chat with appropriate renderers.
"""
id: str
"""The unique ID of the file output."""
filename: str
"""The filename (used to determine rendering and download)."""
type: Literal["output_file"] = "output_file"
"""The type of the output. Always `output_file`."""
file_url: str | None = None
"""Optional URL to the file."""
file_data: str | None = None
"""Optional base64-encoded file data."""
mime_type: str = "application/octet-stream"
"""The MIME type of the file (e.g., application/pdf, audio/mp3)."""
class ResponseOutputData(BaseModel):
"""DevUI extension: Agent-generated generic data output.
This is a DevUI extension because:
- OpenAI Responses API only supports text output in ResponseOutputMessage.content
- Agent Framework agents can return arbitrary structured data that needs display
- Useful for debugging and displaying non-text content
This type allows generic data to be displayed inline in chat.
"""
id: str
"""The unique ID of the data output."""
data: str
"""The data payload (string representation)."""
type: Literal["output_data"] = "output_data"
"""The type of the output. Always `output_data`."""
mime_type: str
"""The MIME type of the data."""
description: str | None = None
"""Optional description of the data."""
# Agent Framework extension fields
class AgentFrameworkExtraBody(BaseModel):
"""Agent Framework specific routing fields for OpenAI requests."""
@@ -292,7 +144,7 @@ class AgentFrameworkRequest(BaseModel):
"""
# All OpenAI fields from ResponseCreateParams
model: str | None = None
model: str # Used as entity_id in DevUI!
input: str | list[Any] | dict[str, Any] # ResponseInputParam + dict for workflow structured input
stream: bool | None = False
@@ -304,25 +156,20 @@ class AgentFrameworkRequest(BaseModel):
metadata: dict[str, Any] | None = None
temperature: float | None = None
max_output_tokens: int | None = None
top_p: float | None = None
tools: list[dict[str, Any]] | None = None
# Reasoning parameters (for o-series models)
reasoning: dict[str, Any] | None = None # {"effort": "low" | "medium" | "high" | "minimal"}
# Optional extra_body for advanced use cases
extra_body: dict[str, Any] | None = None
model_config = ConfigDict(extra="allow")
def get_entity_id(self) -> str | None:
"""Get entity_id from metadata.entity_id.
def get_entity_id(self) -> str:
"""Get entity_id from model field.
In DevUI, entity_id is specified in metadata for routing.
In DevUI, model IS the entity_id (agent/workflow name).
Simple and clean!
"""
if self.metadata:
return self.metadata.get("entity_id")
return None
return self.model
def get_conversation_id(self) -> str | None:
"""Extract conversation_id from conversation parameter.
@@ -371,40 +218,11 @@ class OpenAIError(BaseModel):
return self.model_dump_json()
class MetaResponse(BaseModel):
"""Server metadata response for /meta endpoint.
Provides information about the DevUI server configuration and capabilities.
"""
ui_mode: Literal["developer", "user"] = "developer"
"""UI interface mode - 'developer' shows debug tools, 'user' shows simplified interface."""
version: str
"""DevUI version string."""
framework: str = "agent_framework"
"""Backend framework identifier."""
runtime: Literal["python", "dotnet"] = "python"
"""Backend runtime/language - 'python' or 'dotnet' for deployment guides and feature availability."""
capabilities: dict[str, bool] = {}
"""Server capabilities (e.g., tracing, openai_proxy)."""
auth_required: bool = False
"""Whether the server requires Bearer token authentication."""
# Export all custom types
__all__ = [
"AgentFrameworkRequest",
"MetaResponse",
"OpenAIError",
"ResponseFunctionResultComplete",
"ResponseOutputData",
"ResponseOutputFile",
"ResponseOutputImage",
"ResponseTraceEvent",
"ResponseTraceEventComplete",
"ResponseWorkflowEventComplete",