Spaces:
Sleeping
Sleeping
| """ | |
| Strict type definitions using newtype pattern for maximum type safety. | |
| This module defines all the domain-specific types used throughout the application. | |
| """ | |
| from typing import NewType, List, Tuple, Dict, Any, Union, Literal | |
| from dataclasses import dataclass | |
| from abc import ABC, abstractmethod | |
| # === Base Protocol for Newtype Pattern === | |
| class Unwrappable(ABC): | |
| """Protocol for types that can be unwrapped.""" | |
| def unwrap(self) -> Any: | |
| """Unwrap the newtype to get the underlying value.""" | |
| pass | |
| # === Core Domain Types === | |
| # Model-related types | |
| ModelId = NewType('ModelId', str) | |
| ModelName = NewType('ModelName', str) | |
| ModelMemoryUsage = NewType('ModelMemoryUsage', float) # GB | |
| ModelPriority = NewType('ModelPriority', int) | |
| # Conversation-related types | |
| ConversationId = NewType('ConversationId', str) | |
| UserMessage = NewType('UserMessage', str) | |
| AssistantResponse = NewType('AssistantResponse', str) | |
| Prompt = NewType('Prompt', str) | |
| MessagePair = NewType('MessagePair', Tuple[UserMessage, AssistantResponse]) | |
| ConversationHistory = NewType('ConversationHistory', List[MessagePair]) | |
| # Generation parameters | |
| Temperature = NewType('Temperature', float) | |
| TopP = NewType('TopP', float) | |
| RepetitionPenalty = NewType('RepetitionPenalty', float) | |
| NoRepeatNGramSize = NewType('NoRepeatNGramSize', int) | |
| MaxNewTokens = NewType('MaxNewTokens', int) | |
| TokensUsed = NewType('TokensUsed', int) | |
| ContextLength = NewType('ContextLength', int) | |
| # System resource types | |
| GPUMemoryUsage = NewType('GPUMemoryUsage', float) # Fraction 0.0-1.0 | |
| GPUMemoryTotal = NewType('GPUMemoryTotal', float) # GB | |
| CPUMemoryUsage = NewType('CPUMemoryUsage', float) # Fraction 0.0-1.0 | |
| Timestamp = NewType('Timestamp', float) | |
| # API types | |
| APIHost = NewType('APIHost', str) | |
| APIPort = NewType('APIPort', int) | |
| HFToken = NewType('HFToken', str) | |
| LogLevel = NewType('LogLevel', str) | |
| # Configuration types | |
| MaxConversations = NewType('MaxConversations', int) | |
| MaxMessagesPerConversation = NewType('MaxMessagesPerConversation', int) | |
| MaxModelsInMemory = NewType('MaxModelsInMemory', int) | |
| # === Wrapped Types with Newtype Pattern === | |
| class ModelIdWrapper: | |
| """Wrapper for ModelId with validation.""" | |
| _value: ModelId | |
| def __post_init__(self) -> None: | |
| if not self._value.strip(): | |
| raise ValueError("ModelId cannot be empty") | |
| # Allow any thoughtcast/* model (wildcard support) | |
| if self._value.startswith('thoughtcast/'): | |
| if len(self._value.split('/')) != 2 or not self._value.split('/')[1].strip(): | |
| raise ValueError("thoughtcast models must be in format 'thoughtcast/model-name'") | |
| return | |
| # Allow any doma-dev/* model (wildcard support) | |
| if self._value.startswith('doma-dev/'): | |
| if len(self._value.split('/')) != 2 or not self._value.split('/')[1].strip(): | |
| raise ValueError("doma-dev models must be in format 'doma-dev/model-name'") | |
| return | |
| # Allow any mistralai/* model (wildcard support) | |
| if self._value.startswith('mistralai/'): | |
| if len(self._value.split('/')) != 2 or not self._value.split('/')[1].strip(): | |
| raise ValueError("mistralai models must be in format 'mistralai/model-name'") | |
| return | |
| # Allow specific whitelisted models | |
| allowed_models = { | |
| 'TinyLlama/TinyLlama-1.1B-Chat-v1.0', | |
| 'microsoft/DialoGPT-medium', | |
| 'microsoft/DialoGPT-small', | |
| } | |
| if self._value in allowed_models: | |
| return | |
| # For other models, require org/model format and explicit allowlisting | |
| if '/' not in self._value: | |
| raise ValueError("ModelId must be in format 'org/model' or be a whitelisted model") | |
| org, model_name = self._value.split('/', 1) | |
| if not org.strip() or not model_name.strip(): | |
| raise ValueError("ModelId must have valid organization and model name") | |
| raise ValueError( | |
| f"Model '{self._value}' is not allowed. Only thoughtcast/*, doma-dev/*, mistralai/*, or explicitly whitelisted models are supported." | |
| ) | |
| def unwrap(self) -> ModelId: | |
| return self._value | |
| def __str__(self) -> str: # type: ignore[override] | |
| return str(self._value) | |
| def __repr__(self) -> str: # type: ignore[override] | |
| return f"ModelIdWrapper({self._value!r})" | |
| class ConversationIdWrapper: | |
| """Wrapper for ConversationId with validation.""" | |
| _value: ConversationId | |
| def __post_init__(self) -> None: | |
| if not self._value.strip(): | |
| raise ValueError("ConversationId cannot be empty") | |
| if len(self._value) > 128: | |
| raise ValueError("ConversationId cannot be longer than 128 characters") | |
| def unwrap(self) -> ConversationId: | |
| return self._value | |
| def __str__(self) -> str: # type: ignore[override] | |
| return str(self._value) | |
| def __repr__(self) -> str: # type: ignore[override] | |
| return f"ConversationIdWrapper({self._value!r})" | |
| class TemperatureWrapper: | |
| """Wrapper for Temperature with validation.""" | |
| _value: Temperature | |
| def __post_init__(self) -> None: | |
| if not (0.0 <= self._value <= 2.0): | |
| raise ValueError("Temperature must be between 0.0 and 2.0") | |
| def unwrap(self) -> Temperature: | |
| return self._value | |
| def __float__(self) -> float: | |
| return float(self._value) | |
| def __repr__(self) -> str: # type: ignore[override] | |
| return f"TemperatureWrapper({self._value!r})" | |
| class TopPWrapper: | |
| """Wrapper for TopP with validation.""" | |
| _value: TopP | |
| def __post_init__(self) -> None: | |
| if not (0.0 <= self._value <= 1.0): | |
| raise ValueError("TopP must be between 0.0 and 1.0") | |
| def unwrap(self) -> TopP: | |
| return self._value | |
| def __float__(self) -> float: | |
| return float(self._value) | |
| def __repr__(self) -> str: # type: ignore[override] | |
| return f"TopPWrapper({self._value!r})" | |
| class RepetitionPenaltyWrapper: | |
| """Wrapper for RepetitionPenalty with validation.""" | |
| _value: RepetitionPenalty | |
| def __post_init__(self) -> None: | |
| if not (0.1 <= self._value <= 2.0): | |
| raise ValueError("RepetitionPenalty must be between 0.1 and 2.0") | |
| def unwrap(self) -> RepetitionPenalty: | |
| return self._value | |
| def __float__(self) -> float: | |
| return float(self._value) | |
| def __repr__(self) -> str: # type: ignore[override] | |
| return f"RepetitionPenaltyWrapper({self._value!r})" | |
| class MaxNewTokensWrapper: | |
| """Wrapper for MaxNewTokens with validation.""" | |
| _value: MaxNewTokens | |
| def __post_init__(self) -> None: | |
| if not (1 <= self._value <= 2048): | |
| raise ValueError("MaxNewTokens must be between 1 and 2048") | |
| def unwrap(self) -> MaxNewTokens: | |
| return self._value | |
| def __int__(self) -> int: | |
| return int(self._value) | |
| def __repr__(self) -> str: # type: ignore[override] | |
| return f"MaxNewTokensWrapper({self._value!r})" | |
| class NoRepeatNGramSizeWrapper: | |
| """Wrapper for NoRepeatNGramSize with validation.""" | |
| _value: NoRepeatNGramSize | |
| def __post_init__(self) -> None: | |
| if not (0 <= self._value <= 10): | |
| raise ValueError("NoRepeatNGramSize must be between 0 and 10") | |
| def unwrap(self) -> NoRepeatNGramSize: | |
| return self._value | |
| def __int__(self) -> int: | |
| return int(self._value) | |
| def __repr__(self) -> str: # type: ignore[override] | |
| return f"NoRepeatNGramSizeWrapper({self._value!r})" | |
| class GPUMemoryUsageWrapper: | |
| """Wrapper for GPUMemoryUsage with validation.""" | |
| _value: GPUMemoryUsage | |
| def __post_init__(self) -> None: | |
| if not (0.0 <= self._value <= 1.0): | |
| raise ValueError("GPUMemoryUsage must be between 0.0 and 1.0") | |
| def unwrap(self) -> GPUMemoryUsage: | |
| return self._value | |
| def __float__(self) -> float: | |
| return float(self._value) | |
| def __repr__(self) -> str: # type: ignore[override] | |
| return f"GPUMemoryUsageWrapper({self._value!r})" | |
| class UserMessageWrapper: | |
| """Wrapper for UserMessage with validation.""" | |
| _value: UserMessage | |
| def __post_init__(self) -> None: | |
| if not self._value.strip(): | |
| raise ValueError("UserMessage cannot be empty") | |
| if len(self._value) > 4096: | |
| raise ValueError("UserMessage cannot be longer than 4096 characters") | |
| def unwrap(self) -> UserMessage: | |
| return self._value | |
| def __str__(self) -> str: # type: ignore[override] | |
| return str(self._value) | |
| def __repr__(self) -> str: # type: ignore[override] | |
| return f"UserMessageWrapper({self._value!r})" | |
| class AssistantResponseWrapper: | |
| """Wrapper for AssistantResponse with validation.""" | |
| _value: AssistantResponse | |
| def __post_init__(self) -> None: | |
| if len(self._value) > 4096: | |
| raise ValueError("AssistantResponse cannot be longer than 4096 characters") | |
| def unwrap(self) -> AssistantResponse: | |
| return self._value | |
| def __str__(self) -> str: # type: ignore[override] | |
| return str(self._value) | |
| def __repr__(self) -> str: # type: ignore[override] | |
| return f"AssistantResponseWrapper({self._value!r})" | |
| # === External Library Type Wrappers === | |
| class HuggingFaceModel: | |
| """Wrapper for HuggingFace model objects.""" | |
| _value: Any | |
| def unwrap(self) -> Any: | |
| """Get the underlying HuggingFace model.""" | |
| return self._value | |
| class HuggingFaceTokenizer: | |
| """Wrapper for HuggingFace tokenizer objects.""" | |
| _value: Any | |
| def unwrap(self) -> Any: | |
| """Get the underlying HuggingFace tokenizer.""" | |
| return self._value | |
| class HuggingFaceGenerationConfig: | |
| """Wrapper for HuggingFace generation config objects.""" | |
| _value: Any | |
| def unwrap(self) -> Any: | |
| """Get the underlying HuggingFace generation config.""" | |
| return self._value | |
| class TorchTensor: | |
| """Wrapper for PyTorch tensor objects.""" | |
| _value: Any | |
| def unwrap(self) -> Any: | |
| """Get the underlying PyTorch tensor.""" | |
| return self._value | |
| class TorchDevice: | |
| """Wrapper for PyTorch device objects.""" | |
| _value: Any | |
| def unwrap(self) -> Any: | |
| """Get the underlying PyTorch device.""" | |
| return self._value | |
| # === Type Aliases for Complex Types === | |
| ModelDict = Dict[ModelId, Any] | |
| ConversationDict = Dict[ConversationId, Any] | |
| GenerationConfig = Dict[str, Union[int, float, bool]] | |
| ModelKwargs = Dict[str, Any] | |
| # === Factory Functions === | |
| def create_model_id(value: str) -> ModelIdWrapper: | |
| """Create a validated ModelId.""" | |
| return ModelIdWrapper(ModelId(value)) | |
| def create_conversation_id(value: str) -> ConversationIdWrapper: | |
| """Create a validated ConversationId.""" | |
| return ConversationIdWrapper(ConversationId(value)) | |
| def create_temperature(value: float) -> TemperatureWrapper: | |
| """Create a validated Temperature.""" | |
| return TemperatureWrapper(Temperature(value)) | |
| def create_top_p(value: float) -> TopPWrapper: | |
| """Create a validated TopP.""" | |
| return TopPWrapper(TopP(value)) | |
| def create_repetition_penalty(value: float) -> RepetitionPenaltyWrapper: | |
| """Create a validated RepetitionPenalty.""" | |
| return RepetitionPenaltyWrapper(RepetitionPenalty(value)) | |
| def create_max_new_tokens(value: int) -> MaxNewTokensWrapper: | |
| """Create a validated MaxNewTokens.""" | |
| return MaxNewTokensWrapper(MaxNewTokens(value)) | |
| def create_no_repeat_ngram_size(value: int) -> NoRepeatNGramSizeWrapper: | |
| """Create a validated NoRepeatNGramSize.""" | |
| return NoRepeatNGramSizeWrapper(NoRepeatNGramSize(value)) | |
| def create_gpu_memory_usage(value: float) -> GPUMemoryUsageWrapper: | |
| """Create a validated GPUMemoryUsage.""" | |
| return GPUMemoryUsageWrapper(GPUMemoryUsage(value)) | |
| def create_user_message(value: str) -> UserMessageWrapper: | |
| """Create a validated UserMessage.""" | |
| return UserMessageWrapper(UserMessage(value)) | |
| def create_assistant_response(value: str) -> AssistantResponseWrapper: | |
| """Create a validated AssistantResponse.""" | |
| return AssistantResponseWrapper(AssistantResponse(value)) | |
| # === External Library Factory Functions === | |
| def create_huggingface_model(value: Any) -> HuggingFaceModel: | |
| """Create a wrapped HuggingFace model.""" | |
| return HuggingFaceModel(value) | |
| def create_huggingface_tokenizer(value: Any) -> HuggingFaceTokenizer: | |
| """Create a wrapped HuggingFace tokenizer.""" | |
| return HuggingFaceTokenizer(value) | |
| def create_huggingface_generation_config(value: Any) -> HuggingFaceGenerationConfig: | |
| """Create a wrapped HuggingFace generation config.""" | |
| return HuggingFaceGenerationConfig(value) | |
| def create_torch_tensor(value: Any) -> TorchTensor: | |
| """Create a wrapped PyTorch tensor.""" | |
| return TorchTensor(value) | |
| def create_torch_device(value: Any) -> TorchDevice: | |
| """Create a wrapped PyTorch device.""" | |
| return TorchDevice(value) | |
| # === Status Types === | |
| HealthStatus = Literal["healthy", "unhealthy", "degraded"] | |
| ModelStatus = Literal["loaded", "unloaded", "loading", "failed"] | |
| ConversationStatus = Literal["active", "inactive", "archived"] | |
| # === Error Types === | |
| class ModelError: | |
| """Represents a model-related error.""" | |
| model_id: ModelIdWrapper | |
| message: str | |
| error_type: Literal["loading", "generation", "memory", "validation"] | |
| class ConversationError: | |
| """Represents a conversation-related error.""" | |
| conversation_id: ConversationIdWrapper | |
| message: str | |
| error_type: Literal["not_found", "validation", "storage"] | |
| # === Result Types === | |
| class GenerationResult: | |
| """Result of text generation.""" | |
| response: AssistantResponseWrapper | |
| tokens_used: TokensUsed | |
| model_id: ModelIdWrapper | |
| conversation_id: ConversationIdWrapper | |
| class HealthResult: | |
| """Result of health check.""" | |
| status: HealthStatus | |
| models_loaded: List[ModelIdWrapper] | |
| gpu_memory_used: GPUMemoryUsageWrapper | |
| active_conversations: int | |
| timestamp: Timestamp | |
| # === Model Information Types === | |
| class ModelInformation: | |
| """Complete information about a model.""" | |
| model_id: ModelIdWrapper | |
| memory_used: ModelMemoryUsage | |
| last_used: Timestamp | |
| status: ModelStatus | |
| priority: ModelPriority | |
| context_length: ContextLength |