Python: DevUI: Use metadata.entity_id instead of model field (#1984)

* DevUI: Use metadata.entity_id for agent/workflow name instead of model field

* OpenAI Responses: add explicit request validation

* Review feedback
This commit is contained in:
Reuben Bond
2025-11-07 14:16:55 -08:00
committed by GitHub
Unverified
parent 778a9fec5c
commit f71faa80f9
23 changed files with 783 additions and 459 deletions
@@ -273,7 +273,7 @@ class MessageMapper:
id=f"resp_{uuid.uuid4().hex[:12]}",
object="response",
created_at=datetime.now().timestamp(),
model=request.model,
model=request.model or "devui",
output=[response_output_message],
usage=usage,
parallel_tool_calls=False,
@@ -495,8 +495,9 @@ class MessageMapper:
from .models._openai_custom import AgentCompletedEvent, AgentFailedEvent, AgentStartedEvent
try:
# Get model name from context (the agent name)
model_name = context.get("request", {}).model if context.get("request") else "agent"
# Get model name from request or use 'devui' as default
request_obj = context.get("request")
model_name = request_obj.model if request_obj and request_obj.model else "devui"
if isinstance(event, AgentStartedEvent):
execution_id = f"agent_{uuid4().hex[:12]}"
@@ -603,16 +604,16 @@ class MessageMapper:
# Return proper OpenAI event objects
events: list[Any] = []
# Determine the model name - use request model or default to "workflow"
# The request model will be the agent name for agents, workflow name for workflows
model_name = context.get("request", {}).model if context.get("request") else "workflow"
# Get model name from request or use 'devui' as default
request_obj = context.get("request")
model_name = request_obj.model if request_obj and request_obj.model else "devui"
# Create a full Response object with all required fields
response_obj = Response(
id=f"resp_{workflow_id}",
object="response",
created_at=float(time.time()),
model=model_name, # Use the actual model/agent name
model=model_name,
output=[], # Empty output list initially
status="in_progress",
# Required fields with safe defaults
@@ -643,8 +644,9 @@ class MessageMapper:
# Import Response type for proper construction
from openai.types.responses import Response
# Get model name from context
model_name = context.get("request", {}).model if context.get("request") else "workflow"
# Get model name from request or use 'devui' as default
request_obj = context.get("request")
model_name = request_obj.model if request_obj and request_obj.model else "devui"
# Create a full Response object for completed state
response_obj = Response(
@@ -672,8 +674,9 @@ class MessageMapper:
# Import Response and ResponseError types
from openai.types.responses import Response, ResponseError
# Get model name from context
model_name = context.get("request", {}).model if context.get("request") else "workflow"
# Get model name from request or use 'devui' as default
request_obj = context.get("request")
model_name = request_obj.model if request_obj and request_obj.model else "devui"
# Create error object
error_message = str(error_info) if error_info else "Unknown error"
@@ -1208,7 +1211,7 @@ class MessageMapper:
id=f"resp_{uuid.uuid4().hex[:12]}",
object="response",
created_at=datetime.now().timestamp(),
model=request.model,
model=request.model or "devui",
output=[response_output_message],
usage=usage,
parallel_tool_calls=False,
@@ -359,14 +359,14 @@ class DevServer:
try:
raw_body = await raw_request.body()
logger.info(f"Raw request body: {raw_body.decode()}")
logger.info(f"Parsed request: model={request.model}, extra_body={request.extra_body}")
logger.info(f"Parsed request: metadata={request.metadata}")
# Get entity_id using the new method
# Get entity_id from metadata
entity_id = request.get_entity_id()
logger.info(f"Extracted entity_id: {entity_id}")
if not entity_id:
error = OpenAIError.create(f"Missing entity_id. Request extra_body: {request.extra_body}")
error = OpenAIError.create("Missing entity_id in metadata. Provide metadata.entity_id in request.")
return JSONResponse(status_code=400, content=error.to_dict())
# Get executor and validate entity exists
@@ -144,7 +144,7 @@ class AgentFrameworkRequest(BaseModel):
"""
# All OpenAI fields from ResponseCreateParams
model: str # Used as entity_id in DevUI!
model: str | None = None
input: str | list[Any] | dict[str, Any] # ResponseInputParam + dict for workflow structured input
stream: bool | None = False
@@ -163,13 +163,14 @@ class AgentFrameworkRequest(BaseModel):
model_config = ConfigDict(extra="allow")
def get_entity_id(self) -> str:
"""Get entity_id from model field.
def get_entity_id(self) -> str | None:
"""Get entity_id from metadata.entity_id.
In DevUI, model IS the entity_id (agent/workflow name).
Simple and clean!
In DevUI, entity_id is specified in metadata for routing.
"""
return self.model
if self.metadata:
return self.metadata.get("entity_id")
return None
def get_conversation_id(self) -> str | None:
"""Extract conversation_id from conversation parameter.
File diff suppressed because one or more lines are too long