gateway/modules/datamodels/datamodelAi.py
2025-10-23 14:32:24 +02:00

215 lines
9.8 KiB
Python

from typing import Optional, List, Dict, Any, Literal, Callable, TYPE_CHECKING
from pydantic import BaseModel, Field
from enum import Enum
if TYPE_CHECKING:
from modules.datamodels.datamodelExtraction import ContentPart
# Operation Types
class OperationTypeEnum(str, Enum):
GENERAL = "general"
PLAN = "plan"
ANALYSE = "analyse"
GENERATE = "generate"
EXTRACT = "extract"
WEB_RESEARCH = "webResearch"
IMAGE_ANALYSE = "imageAnalyse"
IMAGE_GENERATE = "imageGenerate"
# Processing Modes
class ProcessingModeEnum(str, Enum):
BASIC = "basic"
ADVANCED = "advanced"
DETAILED = "detailed"
# Priority Levels
class PriorityEnum(str, Enum):
SPEED = "speed"
QUALITY = "quality"
COST = "cost"
BALANCED = "balanced"
# Model Capabilities Enumeration
class ModelCapabilitiesEnum(str, Enum):
# Text generation capabilities
TEXT_GENERATION = "text_generation"
CHAT = "chat"
REASONING = "reasoning"
ANALYSIS = "analysis"
# Image capabilities
IMAGE_ANALYSE = "imageAnalyse"
IMAGE_GENERATE = "imageGenerate"
VISION = "vision"
MULTIMODAL = "multimodal"
ART = "art"
VISUAL_CREATION = "visual_creation"
# Web capabilities
WEB_SEARCH = "web_search"
WEB_CRAWLING = "web_crawling"
CONTENT_EXTRACTION = "content_extraction"
TEXT_EXTRACTION = "text_extraction"
INFORMATION_RETRIEVAL = "information_retrieval"
URL_DISCOVERY = "url_discovery"
MAPPING = "mapping"
# Research capabilities
RESEARCH = "research"
QUESTION_ANSWERING = "question_answering"
INFORMATION_GATHERING = "information_gathering"
NEWS = "news"
CURRENT_EVENTS = "current_events"
class AiModel(BaseModel):
"""Enhanced AI model definition with dynamic capabilities."""
# Core identification
name: str = Field(description="Unique model identifier")
displayName: str = Field(description="Human-readable model name")
connectorType: str = Field(description="Type of connector (openai, anthropic, perplexity, tavily, etc.)")
# Token and context limits
maxTokens: int = Field(description="Maximum tokens this model can generate")
contextLength: int = Field(description="Maximum context length this model can handle")
# Cost information
costPer1kTokensInput: float = Field(default=0.0, description="Cost per 1000 input tokens")
costPer1kTokensOutput: float = Field(default=0.0, description="Cost per 1000 output tokens")
# Performance ratings
speedRating: int = Field(ge=1, le=10, description="Speed rating (1-10, higher = faster)")
qualityRating: int = Field(ge=1, le=10, description="Quality rating (1-10, higher = better)")
# Function reference (not serialized)
functionCall: Optional[Callable] = Field(default=None, exclude=True, description="Function to call for this model")
calculatePriceUsd: Optional[Callable] = Field(default=None, exclude=True, description="Function to calculate price in USD")
# Selection criteria
capabilities: List[ModelCapabilitiesEnum] = Field(description="List of model capabilities. See ModelCapabilitiesEnum enum for available values.")
priority: PriorityEnum = Field(default=PriorityEnum.BALANCED, description="Default priority for this model. See PriorityEnum for available values.")
processingMode: ProcessingModeEnum = Field(default=ProcessingModeEnum.BASIC, description="Default processing mode. See ProcessingModeEnum for available values.")
operationTypes: List[OperationTypeEnum] = Field(default=[], description="Operation types this model should avoid")
minContextLength: Optional[int] = Field(default=None, description="Minimum context length required")
isAvailable: bool = Field(default=True, description="Whether model is currently available")
# Metadata
version: Optional[str] = Field(default=None, description="Model version")
lastUpdated: Optional[str] = Field(default=None, description="Last update timestamp")
class Config:
arbitraryTypesAllowed = True # Allow Callable type
class SelectionRule(BaseModel):
"""A rule for model selection."""
name: str = Field(description="Rule name identifier")
condition: str = Field(description="Description of when this rule applies")
weight: float = Field(description="Weight for scoring (higher = more important)")
operationTypes: List[OperationTypeEnum] = Field(description="Operation types this rule applies to")
priority: PriorityEnum = Field(default=PriorityEnum.BALANCED, description="Priority level for this rule")
capabilities: List[ModelCapabilitiesEnum] = Field(default=[], description="Required capabilities for this rule")
minQualityRating: Optional[int] = Field(default=None, description="Minimum quality rating")
maxCost: Optional[float] = Field(default=None, description="Maximum cost threshold")
minContextLength: Optional[int] = Field(default=None, description="Minimum context length required")
class AiCallOptions(BaseModel):
"""Options for centralized AI processing with clear operation types and tags."""
operationType: OperationTypeEnum = Field(default=OperationTypeEnum.GENERAL, description="Type of operation")
priority: PriorityEnum = Field(default=PriorityEnum.BALANCED, description="Priority level")
compressPrompt: bool = Field(default=True, description="Whether to compress the prompt")
compressContext: bool = Field(default=True, description="If False: process each chunk; If True: summarize and work on summary")
processDocumentsIndividually: bool = Field(default=True, description="If True, process each document separately; else pool docs")
maxContextBytes: Optional[int] = Field(default=None, description="Hard cap for extracted context size passed to the model")
maxCost: Optional[float] = Field(default=None, description="Max cost budget")
maxProcessingTime: Optional[int] = Field(default=None, description="Max processing time in seconds")
processingMode: ProcessingModeEnum = Field(default=ProcessingModeEnum.BASIC, description="Processing mode")
resultFormat: Optional[str] = Field(default=None, description="Expected result format: txt, json, csv, xml, etc.")
safetyMargin: float = Field(default=0.1, ge=0.0, le=0.5, description="Safety margin for token limits (0.0-0.5)")
capabilities: Optional[List[ModelCapabilitiesEnum]] = Field(default=None, description="Required model capabilities for filtering")
# Model generation parameters
temperature: Optional[float] = Field(default=None, ge=0.0, le=2.0, description="Temperature for response generation (0.0-2.0, lower = more consistent)")
maxTokens: Optional[int] = Field(default=None, ge=1, le=32000, description="Maximum tokens in response")
maxParts: Optional[int] = Field(default=1000, ge=1, le=1000, description="Maximum number of continuation parts to fetch")
class AiCallRequest(BaseModel):
"""Centralized AI call request payload for interface use."""
prompt: str = Field(description="The user prompt")
context: Optional[str] = Field(default=None, description="Optional external context (e.g., extracted docs)")
options: AiCallOptions = Field(default_factory=AiCallOptions)
contentParts: Optional[List['ContentPart']] = None # NEW: Content parts for model-aware chunking
class AiCallResponse(BaseModel):
"""Standardized AI call response."""
content: str = Field(description="AI response content")
modelName: str = Field(description="Selected model name")
priceUsd: float = Field(default=0.0, description="Calculated price in USD")
processingTime: float = Field(default=0.0, description="Duration in seconds")
bytesSent: int = Field(default=0, description="Input data size in bytes")
bytesReceived: int = Field(default=0, description="Output data size in bytes")
errorCount: int = Field(default=0, description="0 for success, 1+ for errors")
class EnhancedAiCallOptions(AiCallOptions):
"""Enhanced options for improved document processing with chunk mapping."""
# Parallel processing
enableParallelProcessing: bool = Field(
default=True,
description="Enable parallel processing of chunks"
)
maxConcurrentChunks: int = Field(
default=5,
ge=1,
le=20,
description="Maximum number of chunks to process concurrently"
)
# Chunk mapping
preserveChunkMetadata: bool = Field(
default=True,
description="Preserve chunk metadata during processing"
)
chunkSeparator: str = Field(
default="\n\n---\n\n",
description="Separator between chunks in merged output"
)
class AiModelCall(BaseModel):
"""Standardized input for AI model calls."""
messages: List[Dict[str, Any]] = Field(description="Messages in OpenAI format (role, content)")
model: Optional[AiModel] = Field(default=None, description="The AI model being called")
options: Dict[str, Any] = Field(default_factory=dict, description="Additional model-specific options")
class Config:
arbitraryTypesAllowed = True
class AiModelResponse(BaseModel):
"""Standardized output from AI model calls."""
content: str = Field(description="The AI response content")
success: bool = Field(default=True, description="Whether the call was successful")
error: Optional[str] = Field(default=None, description="Error message if success=False")
# Optional metadata that models can include
modelId: Optional[str] = Field(default=None, description="Model identifier used")
processingTime: Optional[float] = Field(default=None, description="Processing time in seconds")
tokensUsed: Optional[Dict[str, int]] = Field(default=None, description="Token usage (input, output, total)")
metadata: Optional[Dict[str, Any]] = Field(default=None, description="Additional model-specific metadata")
class Config:
arbitraryTypesAllowed = True