"""AIExecution — immutable record of a single inference call. Stored after every real (or mock) AI invocation so that: - usage/cost is attributable to a tenant + project + job - inputs/outputs can be audited / replayed - the AI Gateway can train / evaluate routing policies later """ from __future__ import annotations from typing import Any, Optional, Dict from pydantic import Field from asf_domain.base import ( ASFBaseModel, TenantScopedModel, ASFFieldID, UTCDatetime, generate_id, ) class AIExecutionBase(ASFBaseModel): capability: str = Field( ..., max_length=128, description="ASF capability requested (e.g. chat, analyze_code, generate_tests).", ) provider: str = Field( ..., max_length=64, description="Adapter used (e.g. mock, openai, nvidia, local)." ) model: str = Field( ..., max_length=128, description="Concrete model identifier reported by the adapter." ) success: bool = True class AIExecutionCreate(AIExecutionBase): job_id: Optional[ASFFieldID] = None project_id: Optional[ASFFieldID] = None input_ref: Optional[str] = Field( None, max_length=512, description="MinIO ref or short fingerprint of the input payload (never raw secrets).", ) output_ref: Optional[str] = Field( None, max_length=512, description="MinIO ref / fingerprint of the response." ) input_tokens: Optional[int] = Field(None, ge=0) output_tokens: Optional[int] = Field(None, ge=0) duration_ms: Optional[int] = Field(None, ge=0) estimated_cost: Optional[float] = Field(None, ge=0) error_message: Optional[str] = Field(None, max_length=2000) metadata: Dict[str, Any] = Field(default_factory=dict) class AIExecution(TenantScopedModel, AIExecutionBase): id: ASFFieldID = Field(default_factory=generate_id) job_id: Optional[ASFFieldID] = None project_id: Optional[ASFFieldID] = None input_ref: Optional[str] = None output_ref: Optional[str] = None input_tokens: Optional[int] = None output_tokens: Optional[int] = None duration_ms: Optional[int] = None estimated_cost: Optional[float] = None error_message: Optional[str] = None metadata: Dict[str, Any] = Field(default_factory=dict) created_at: UTCDatetime = ...