مخزن اختصاصی برنامهٔ وب؛ محتوای پوشهٔ web در ریشهٔ مخزن قرار گرفت. تاریخچهٔ پروژهٔ ربات (agy-bot) در این مخزن وجود ندارد و هیچ وابستگی runtime به آن نیست.
110 lines
2.9 KiB
Python
110 lines
2.9 KiB
Python
"""AI Control Plane domain: providers, credentials, models, routing, rate cards.
|
|
|
|
Everything here is platform-owner-only. A normal customer never receives these
|
|
records through the API — the application layer strips them.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
from datetime import datetime
|
|
from enum import StrEnum
|
|
|
|
from app.domain.base import new_id, utcnow
|
|
|
|
|
|
class ProviderType(StrEnum):
|
|
MOCK = "mock"
|
|
OPENAI_COMPATIBLE = "openai_compatible"
|
|
ANTHROPIC = "anthropic"
|
|
GEMINI = "gemini"
|
|
OPENROUTER = "openrouter"
|
|
|
|
|
|
class RoutingMode(StrEnum):
|
|
FAST = "fast"
|
|
CHEAP = "cheap"
|
|
BALANCED = "balanced"
|
|
REASONING = "reasoning"
|
|
VISION = "vision"
|
|
CODING = "coding"
|
|
|
|
|
|
class Capability(StrEnum):
|
|
TEXT = "text"
|
|
VISION = "vision"
|
|
TOOLS = "tools"
|
|
REASONING = "reasoning"
|
|
LONG_CONTEXT = "long_context"
|
|
CODE = "code"
|
|
|
|
|
|
class RateUnit(StrEnum):
|
|
MODEL_INPUT_TOKENS = "model_input_tokens"
|
|
MODEL_OUTPUT_TOKENS = "model_output_tokens"
|
|
SANDBOX_CPU_SECOND = "sandbox_cpu_second"
|
|
SANDBOX_MEMORY_GB_SECOND = "sandbox_memory_gb_second"
|
|
STORAGE_GB_DAY = "storage_gb_day"
|
|
TOOL_CALL = "tool_call"
|
|
PREMIUM_EMPLOYEE_RUN = "premium_employee_run"
|
|
|
|
|
|
@dataclass(slots=True, kw_only=True)
|
|
class Provider:
|
|
name: str
|
|
type: ProviderType = ProviderType.MOCK
|
|
base_url: str = ""
|
|
id: str = field(default_factory=new_id)
|
|
is_active: bool = True
|
|
created_at: datetime = field(default_factory=utcnow)
|
|
|
|
|
|
@dataclass(slots=True, kw_only=True)
|
|
class ModelCredential:
|
|
provider_id: str
|
|
name: str
|
|
encrypted_api_key: str
|
|
id: str = field(default_factory=new_id)
|
|
is_active: bool = True
|
|
created_at: datetime = field(default_factory=utcnow)
|
|
|
|
|
|
@dataclass(slots=True, kw_only=True)
|
|
class AiModel:
|
|
provider_id: str
|
|
internal_name: str
|
|
display_name_for_admin: str
|
|
capabilities: list[str] = field(default_factory=list)
|
|
input_price_per_1m: float = 0.0
|
|
output_price_per_1m: float = 0.0
|
|
id: str = field(default_factory=new_id)
|
|
is_active: bool = True
|
|
created_at: datetime = field(default_factory=utcnow)
|
|
|
|
def supports(self, capability: str | Capability) -> bool:
|
|
return str(capability) in set(self.capabilities)
|
|
|
|
|
|
@dataclass(slots=True, kw_only=True)
|
|
class RoutingPolicy:
|
|
name: str
|
|
mode: RoutingMode = RoutingMode.BALANCED
|
|
description: str = ""
|
|
fallback_policy_json: dict = field(default_factory=dict)
|
|
budget_limits_json: dict = field(default_factory=dict)
|
|
id: str = field(default_factory=new_id)
|
|
is_default: bool = False
|
|
is_active: bool = True
|
|
created_at: datetime = field(default_factory=utcnow)
|
|
|
|
|
|
@dataclass(slots=True, kw_only=True)
|
|
class RateCard:
|
|
name: str
|
|
unit: RateUnit
|
|
customer_price: float
|
|
internal_cost_estimate: float = 0.0
|
|
id: str = field(default_factory=new_id)
|
|
is_active: bool = True
|
|
created_at: datetime = field(default_factory=utcnow)
|