Spaces:
Building
Building
""" | |
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 |