"""Pydantic schemas for AI UI Control commands and feedback.""" from __future__ import annotations from enum import Enum from typing import Any from pydantic import BaseModel, Field class UICommandType(str, Enum): """Supported UI command types.""" navigate = "navigate" filter = "filter" open_contact = "open_contact" modal = "modal" tab = "tab" settings = "settings" class UICommandStatus(str, Enum): """Status of a UI command execution.""" pending = "pending" delivered = "delivered" success = "success" failed = "failed" timeout = "timeout" class UICommand(BaseModel): """A UI command sent by an AI agent to control the frontend. Task 4.1: UI-Command-Protokoll JSON protocol for UI commands with action types: - navigate: {action: 'navigate', path: '/contacts/123'} - filter: {action: 'filter', entity: 'contacts', filter: {type: 'company'}} - open_contact: {action: 'open_contact', id: '...'} - modal: {action: 'modal', modal: 'edit', contactId: '...'} - tab: {action: 'tab', tab: 'emails', contactId: '...'} - settings: {action: 'settings', section: 'ai', key: 'model', value: 'gpt-4'} """ command_id: str = Field(..., description="Unique command ID") action: UICommandType = Field(..., description="Command type") # navigate path: str | None = Field(None, description="Target path for navigate command") # filter entity: str | None = Field(None, description="Entity type for filter command") filter: dict[str, Any] | None = Field(None, description="Filter criteria") # open_contact contact_id: str | None = Field(None, description="Contact ID for open_contact command") # modal modal: str | None = Field(None, description="Modal type: 'edit', 'create', 'delete', 'close'") # tab tab: str | None = Field(None, description="Tab name: 'emails', 'files', 'calendar', etc.") # settings section: str | None = Field(None, description="Settings section") key: str | None = Field(None, description="Setting key") value: Any | None = Field(None, description="Setting value") # metadata timestamp: str | None = Field(None, description="Command timestamp ISO format") description: str | None = Field(None, description="Human-readable description of the command") class UICommandCreate(BaseModel): """Request body for creating a UI command (sent by AI agent).""" action: UICommandType = Field(..., description="Command type") path: str | None = None entity: str | None = None filter: dict[str, Any] | None = None contact_id: str | None = None modal: str | None = None tab: str | None = None section: str | None = None key: str | None = None value: Any | None = None description: str | None = None class UICommandFeedback(BaseModel): """Feedback from frontend after executing a command. Task 4.10: UI-Action-Feedback an KI Frontend sends confirmation back: {action: 'navigate', status: 'success', current_path: '/contacts/123'} """ command_id: str = Field(..., description="ID of the command being acknowledged") status: UICommandStatus = Field(..., description="Execution status") action: UICommandType | None = None current_path: str | None = Field(None, description="Current URL path after command") current_tab: str | None = Field(None, description="Current active tab") message: str | None = Field(None, description="Optional message") error: str | None = Field(None, description="Error message if failed") data: dict[str, Any] | None = Field(None, description="Additional response data") class UICommandResponse(BaseModel): """Response after creating a command.""" command_id: str status: UICommandStatus action: UICommandType message: str | None = None class UICommandStatusResponse(BaseModel): """Status response for polling command execution result.""" command_id: str status: UICommandStatus action: UICommandType | None = None feedback: UICommandFeedback | None = None