Spaces:
Paused
Paused
| """ | |
| Configuration Models for Flare Platform | |
| """ | |
| from pydantic import BaseModel, Field, field_serializer | |
| from datetime import datetime | |
| from typing import Optional, List, Dict, Any | |
| class BaseModelWithDatetime(BaseModel): | |
| """Base model with consistent datetime serialization""" | |
| class Config: | |
| # Datetime'ları her zaman ISO 8601 formatında serialize et | |
| json_encoders = { | |
| datetime: lambda v: v.isoformat() if v else None | |
| } | |
| # ===================== User & Auth ===================== | |
| class UserConfig(BaseModelWithDatetime): | |
| username: str | |
| password_hash: str | |
| salt: Optional[str] = None | |
| # ===================== Provider Models ===================== | |
| class ProviderDefinition(BaseModelWithDatetime): | |
| type: str # llm, tts, stt | |
| name: str | |
| display_name: str | |
| requires_endpoint: bool | |
| requires_api_key: bool | |
| requires_repo_info: Optional[bool] = False | |
| description: str | |
| features: Optional[Dict[str, Any]] = Field(default_factory=dict) | |
| def has_feature(self, feature_name: str) -> bool: | |
| """Check if provider has a specific feature""" | |
| return feature_name in self.features if self.features else False | |
| def get_feature(self, feature_name: str, default: Any = None) -> Any: | |
| """Get feature value with default""" | |
| if not self.features: | |
| return default | |
| return self.features.get(feature_name, default) | |
| def get_feature_bool(self, feature_name: str, default: bool = False) -> bool: | |
| """Get boolean feature value""" | |
| if not self.features: | |
| return default | |
| value = self.features.get(feature_name, default) | |
| if isinstance(value, bool): | |
| return value | |
| if isinstance(value, str): | |
| return value.lower() in ('true', '1', 'yes', 'on') | |
| return bool(value) | |
| def get_feature_int(self, feature_name: str, default: int = 0) -> int: | |
| """Get integer feature value""" | |
| if not self.features: | |
| return default | |
| value = self.features.get(feature_name, default) | |
| try: | |
| return int(value) | |
| except (ValueError, TypeError): | |
| return default | |
| def get_feature_str(self, feature_name: str, default: str = "") -> str: | |
| """Get string feature value""" | |
| if not self.features: | |
| return default | |
| value = self.features.get(feature_name, default) | |
| return str(value) if value is not None else default | |
| class ProviderSettings(BaseModelWithDatetime): | |
| name: str | |
| api_key: Optional[str] = None | |
| endpoint: Optional[str] = None | |
| settings: Optional[Dict[str, Any]] = Field(default_factory=dict) | |
| # ===================== Global Config ===================== | |
| class GlobalConfig(BaseModelWithDatetime): | |
| llm_provider: ProviderSettings = Field( | |
| default_factory=lambda: ProviderSettings( | |
| name="spark_cloud", | |
| api_key="", | |
| endpoint="http://localhost:8080", | |
| settings={} | |
| ) | |
| ) | |
| tts_provider: ProviderSettings = Field( | |
| default_factory=lambda: ProviderSettings( | |
| name="no_tts", | |
| api_key="", | |
| endpoint=None, | |
| settings={} | |
| ) | |
| ) | |
| stt_provider: ProviderSettings = Field( | |
| default_factory=lambda: ProviderSettings( | |
| name="no_stt", | |
| api_key="", | |
| endpoint=None, | |
| settings={} | |
| ) | |
| ) | |
| providers: List[ProviderDefinition] = Field(default_factory=list) | |
| users: List[UserConfig] = Field(default_factory=list) | |
| last_update_date: Optional[str] = None | |
| last_update_user: Optional[str] = None | |
| def is_cloud_mode(self) -> bool: | |
| """Check if running in cloud mode""" | |
| import os | |
| return bool(os.environ.get("SPACE_ID")) | |
| def get_provider_config(self, provider_type: str, provider_name: str) -> Optional[ProviderDefinition]: | |
| """Get provider definition by type and name""" | |
| return next( | |
| (p for p in self.providers if p.type == provider_type and p.name == provider_name), | |
| None | |
| ) | |
| # ===================== Localization Models ===================== | |
| class LocalizedExample(BaseModelWithDatetime): | |
| locale_code: str | |
| example: str | |
| class LocalizedCaption(BaseModelWithDatetime): | |
| locale_code: str | |
| caption: str | |
| # ===================== Parameter Models ===================== | |
| class ParameterConfig(BaseModelWithDatetime): | |
| name: str | |
| caption: List[LocalizedCaption] | |
| type: str # str, int, float, bool, date | |
| required: bool = True | |
| variable_name: str | |
| extraction_prompt: Optional[str] = None | |
| validation_regex: Optional[str] = None | |
| invalid_prompt: Optional[str] = None | |
| type_error_prompt: Optional[str] = None | |
| def canonical_type(self) -> str: | |
| """Get canonical type name""" | |
| return self.type.lower() | |
| def get_caption_for_locale(self, locale: str) -> str: | |
| """Get caption for specific locale""" | |
| for cap in self.caption: | |
| if cap.locale_code == locale: | |
| return cap.caption | |
| # Fallback to first caption | |
| return self.caption[0].caption if self.caption else self.name | |
| # ===================== Intent Models ===================== | |
| class IntentConfig(BaseModelWithDatetime): | |
| name: str | |
| caption: str | |
| requiresApproval: Optional[bool] = False | |
| dependencies: List[str] = Field(default_factory=list) | |
| examples: List[LocalizedExample] = Field(default_factory=list) | |
| detection_prompt: str | |
| parameters: List[ParameterConfig] = Field(default_factory=list) | |
| action: str | |
| fallback_timeout_prompt: Optional[str] = None | |
| fallback_error_prompt: Optional[str] = None | |
| def get_examples_for_locale(self, locale: str) -> List[str]: | |
| """Get examples for specific locale""" | |
| examples = [] | |
| for ex in self.examples: | |
| if ex.locale_code == locale: | |
| examples.append(ex.example) | |
| # Fallback to any available examples if locale not found | |
| if not examples and self.examples: | |
| # Try language part only (tr-TR -> tr) | |
| if '-' in locale: | |
| lang_code = locale.split('-')[0] | |
| for ex in self.examples: | |
| if ex.locale_code.startswith(lang_code): | |
| examples.append(ex.example) | |
| # If still no examples, return all examples | |
| if not examples: | |
| examples = [ex.example for ex in self.examples] | |
| return examples | |
| def get_examples_for_locale(self, locale: str) -> List[str]: | |
| """Get examples for specific locale""" | |
| examples = [] | |
| for ex in self.examples: | |
| if ex.locale_code == locale: | |
| examples.append(ex.example) | |
| # Fallback to any available examples if locale not found | |
| if not examples and self.examples: | |
| # Try language part only (tr-TR -> tr) | |
| if '-' in locale: | |
| lang_code = locale.split('-')[0] | |
| for ex in self.examples: | |
| if ex.locale_code.startswith(lang_code): | |
| examples.append(ex.example) | |
| # If still no examples, return all examples | |
| if not examples: | |
| examples = [ex.example for ex in self.examples] | |
| return examples | |
| # ===================== LLM Configuration ===================== | |
| class GenerationConfig(BaseModelWithDatetime): | |
| max_new_tokens: int = 512 | |
| temperature: float = 0.7 | |
| top_p: float = 0.9 | |
| top_k: Optional[int] = None | |
| repetition_penalty: Optional[float] = None | |
| do_sample: Optional[bool] = True | |
| num_beams: Optional[int] = None | |
| length_penalty: Optional[float] = None | |
| early_stopping: Optional[bool] = None | |
| class LLMConfiguration(BaseModelWithDatetime): | |
| repo_id: str | |
| generation_config: GenerationConfig = Field(default_factory=GenerationConfig) | |
| use_fine_tune: bool = False | |
| fine_tune_zip: Optional[str] = "" | |
| # ===================== Version Models ===================== | |
| class VersionConfig(BaseModelWithDatetime): | |
| no: int | |
| caption: str | |
| description: Optional[str] = None | |
| published: bool = False | |
| deleted: bool = False | |
| general_prompt: str | |
| welcome_prompt: Optional[str] = None | |
| llm: LLMConfiguration | |
| intents: List[IntentConfig] = Field(default_factory=list) | |
| created_date: str | |
| created_by: str | |
| publish_date: Optional[str] = None | |
| published_by: Optional[str] = None | |
| last_update_date: Optional[str] = None | |
| last_update_user: Optional[str] = None | |
| # ===================== Project Models ===================== | |
| class ProjectConfig(BaseModelWithDatetime): | |
| id: int | |
| name: str | |
| caption: str | |
| icon: Optional[str] = "folder" | |
| description: Optional[str] = None | |
| enabled: bool = True | |
| default_locale: str = "tr" | |
| supported_locales: List[str] = Field(default_factory=lambda: ["tr"]) | |
| timezone: str = "Europe/Istanbul" | |
| region: str = "tr-TR" | |
| versions: List[VersionConfig] = Field(default_factory=list) | |
| version_id_counter: int = 1 | |
| deleted: bool = False | |
| created_date: str | |
| created_by: str | |
| last_update_date: Optional[str] = None | |
| last_update_user: Optional[str] = None | |
| # ===================== API Models ===================== | |
| class RetryConfig(BaseModelWithDatetime): | |
| retry_count: int = 3 | |
| backoff_seconds: int = 2 | |
| strategy: str = "static" # static, exponential | |
| class AuthConfig(BaseModelWithDatetime): | |
| enabled: bool | |
| token_endpoint: Optional[str] = None | |
| response_token_path: Optional[str] = None | |
| token_request_body: Optional[Dict[str, Any]] = None | |
| token_refresh_endpoint: Optional[str] = None | |
| token_refresh_body: Optional[Dict[str, Any]] = None | |
| class ResponseMapping(BaseModelWithDatetime): | |
| variable_name: str | |
| type: str # str, int, float, bool, date | |
| json_path: str | |
| caption: List[LocalizedCaption] | |
| class APIConfig(BaseModelWithDatetime): | |
| name: str | |
| url: str | |
| method: str = "POST" | |
| headers: Dict[str, str] = Field(default_factory=dict) | |
| body_template: Dict[str, Any] = Field(default_factory=dict) | |
| timeout_seconds: int = 10 | |
| retry: RetryConfig = Field(default_factory=RetryConfig) | |
| proxy: Optional[str] = None | |
| auth: Optional[AuthConfig] = None | |
| response_prompt: Optional[str] = None | |
| response_mappings: List[ResponseMapping] = Field(default_factory=list) | |
| deleted: bool = False | |
| created_date: Optional[str] = None | |
| created_by: Optional[str] = None | |
| last_update_date: Optional[str] = None | |
| last_update_user: Optional[str] = None | |
| # ===================== Activity Log ===================== | |
| class ActivityLogEntry(BaseModelWithDatetime): | |
| id: Optional[int] = None | |
| timestamp: str | |
| username: str | |
| action: str | |
| entity_type: str | |
| entity_name: Optional[str] = None | |
| details: Optional[str] = None | |
| # ===================== Root Configuration ===================== | |
| class ServiceConfig(BaseModelWithDatetime): | |
| global_config: GlobalConfig = Field(alias="config") | |
| projects: List[ProjectConfig] = Field(default_factory=list) | |
| apis: List[APIConfig] = Field(default_factory=list) | |
| activity_log: List[ActivityLogEntry] = Field(default_factory=list) | |
| project_id_counter: int = 1 | |
| last_update_date: Optional[str] = None | |
| last_update_user: Optional[str] = None | |
| class Config: | |
| populate_by_name = True | |
| def build_index(self) -> None: | |
| """Build indexes for quick lookup""" | |
| # This method can be extended to build various indexes | |
| pass | |
| def get_api(self, api_name: str) -> Optional[APIConfig]: | |
| """Get API config by name""" | |
| return next((api for api in self.apis if api.name == api_name), None) | |
| # For backward compatibility - alias | |
| GlobalConfiguration = GlobalConfig |