# Code generated by typegen. DO NOT EDIT.

from __future__ import annotations

from enum import Enum, IntEnum
from typing import Any, Dict, List, Optional, TypedDict, Union
from datetime import datetime


##########
# source: agent.go

# InternalToolsConfig controls which built-in tools are enabled for an agent
class InternalToolsConfig(TypedDict, total=False):
    plan: bool
    memory: bool
    widget: bool
    finish: bool
    skills: bool

class ToolType(str, Enum):
    APP = "app"
    AGENT = "agent"
    HOOK = "hook"
    CLIENT = "client"
    INTERNAL = "internal"

# AppToolConfig contains configuration for an app tool
class AppToolConfig(TypedDict, total=False):
    # Ref is the human-readable reference: "namespace/name@shortVersionId"
    # This is what users specify in configs/SDKs
    ref: str
    # ID and VersionID are resolved full database UUIDs (populated at runtime)
    id: str
    version_id: str
    # Resolved app object (populated at runtime)
    app: App
    # Function to call on multi-function apps (empty = app's default function)
    function: str
    # SessionEnabled allows the agent to control sessions for this tool
    # When true, agent can pass session parameter and sees session_id in output
    session_enabled: bool
    # Pre-configured values
    setup: Any
    input: Any

# AgentToolConfig contains configuration for a sub-agent tool
class AgentToolConfig(TypedDict, total=False):
    # Ref is the human-readable reference: "namespace/name@shortVersionId"
    # This is what users specify in configs/SDKs
    ref: str
    # ID and VersionID are resolved full database UUIDs (populated at runtime)
    id: str
    version_id: str
    # Resolved agent object (populated at runtime)
    agent: Agent

# HookToolConfig contains configuration for a webhook tool
class HookToolConfig(TypedDict, total=False):
    url: str
    secret: str
    input_schema: Any
    output_schema: Any

# ClientToolConfig contains configuration for a frontend-executed tool
class ClientToolConfig(TypedDict, total=False):
    input_schema: Any
    output_schema: Any

# AgentTool represents a unified tool that can be used by an agent
class AgentTool(TypedDict, total=False):
    name: str
    display_name: str
    description: str
    type: ToolType
    # Human-in-the-Loop: if true, tool execution requires user approval
    require_approval: bool
    # Type-specific config (exactly one should be set based on Type)
    app: AppToolConfig
    agent: AgentToolConfig
    hook: HookToolConfig
    client: ClientToolConfig
    internal: InternalToolConfig

# InternalToolConfig contains configuration for internal/built-in tools
class InternalToolConfig(TypedDict, total=False):
    category: str
    operation: str

# AgentToolDTO for API responses
class AgentToolDTO(TypedDict, total=False):
    name: str
    display_name: str
    description: str
    type: ToolType
    # Human-in-the-Loop: if true, tool execution requires user approval
    require_approval: bool
    app: AppToolConfigDTO
    agent: AgentToolConfigDTO
    hook: HookToolConfigDTO
    client: ClientToolConfigDTO

class AppToolConfigDTO(TypedDict, total=False):
    ref: str
    id: str
    version_id: str
    app: AppDTO
    # Function to call on multi-function apps
    function: str
    # SessionEnabled allows the agent to control sessions for this tool
    session_enabled: bool
    # Pre-configured values
    setup: Any
    input: Any

class AgentToolConfigDTO(TypedDict, total=False):
    ref: str
    id: str
    version_id: str
    agent: AgentDTO

class HookToolConfigDTO(TypedDict, total=False):
    url: str
    secret: str
    input_schema: Any
    output_schema: Any

class ClientToolConfigDTO(TypedDict, total=False):
    input_schema: Any
    output_schema: Any

# CoreAppConfig references an app used as the agent's core
class CoreAppConfig(TypedDict, total=False):
    id: str
    version_id: str
    # CoreAppRef is the user-facing ref (namespace/name@shortid) - used in ad-hoc configs, resolved at creation
    ref: str
    # Setup values for the core app (one-time configuration)
    setup: Any
    # Input default values for the core app
    input: Any

# AgentImages contains display images for an agent (like AppImages)
class AgentImages(TypedDict, total=False):
    card: str
    thumbnail: str
    banner: str

class Agent(TypedDict, total=False):
    # Basic info
    namespace: str
    name: str
    # Display images (like App)
    images: AgentImages
    version_id: str
    version: AgentVersion

# AgentDTO for API responses
class AgentDTO(TypedDict, total=False):
    namespace: str
    name: str
    # Display images (like AppDTO)
    images: AgentImages
    version_id: str
    version: AgentVersionDTO

# SkillConfig defines a skill available to the agent.
# Skills are loaded on-demand via the skill_get internal tool.
class SkillConfig(TypedDict, total=False):
    name: str
    description: str
    url: str
    content: str

# AgentConfig contains the shared configuration fields for agent execution.
# This is embedded by both AgentVersion (DB model) and API request structs.
# Using Go embedding flattens these fields in JSON serialization.
class AgentConfig(TypedDict, total=False):
    # Optional name for the agent (used for adhoc agent deduplication — reuses existing agent by name).
    # Not persisted as a DB column; only used in API requests.
    name: str
    description: str
    system_prompt: str
    example_prompts: List[str]
    # Core LLM configuration
    core_app: CoreAppConfig
    # Tools (apps, agents, hooks, client tools)
    tools: List[Optional[AgentTool]]
    # Skills available to this agent (loaded on-demand via skill_get tool)
    skills: List[SkillConfig]
    # Internal tools configuration (plan, memory, widget, finish, skills)
    internal_tools: InternalToolsConfig
    # Output schema for custom finish tool (sub-agents only)
    output_schema: Any

class AgentVersion(TypedDict, total=False):
    agent_id: str
    # ConfigHash for deduplication - SHA256 of config content
    config_hash: str

class CoreAppConfigDTO(TypedDict, total=False):
    id: str
    version_id: str
    ref: str
    app: AppDTO
    # Setup values for the core app (one-time configuration)
    setup: Any
    # Input default values for the core app
    input: Any

class AgentVersionDTO(TypedDict, total=False):
    description: str
    system_prompt: str
    example_prompts: List[str]
    core_app: CoreAppConfigDTO
    # Unified tools array (apps, agents, hooks, client)
    tools: List[Optional[AgentToolDTO]]
    # Skills available to this agent (loaded on-demand via skill_get tool)
    skills: List[SkillConfig]
    # Internal tools configuration (plan, memory, widget, finish, skills)
    internal_tools: InternalToolsConfig
    # Output schema for custom finish tool (sub-agents only)
    output_schema: Any


##########
# source: api.go

class APIRequest(TypedDict, total=False):
    timestamp: str
    data: Any

class APIResponse(TypedDict, total=False):
    success: bool
    status: int
    data: Any
    error: APIError

class APIError(TypedDict, total=False):
    code: str
    message: str

# ApiAppRunRequest is the request body for /apps/run endpoint.
# Supports two ways to specify the app:
# 1. App ref (recommended): "namespace/name@shortid" in the App field
# 2. Direct IDs: app_id + version_id fields (for internal platform use)
class ApiAppRunRequest(TypedDict, total=False):
    # App reference in format: namespace/name@shortid (version required)
    # Example: "okaris/flux@abc1"
    # The short ID ensures your code always runs the same version.
    app: str
    # Deprecated: use App ref instead. Direct ID bypasses ref routing.
    app_id: str
    version_id: str
    infra: Infra
    workers: List[str]
    webhook: str
    setup: Any
    input: Any
    # If true, returns SSE stream instead of JSON response
    stream: bool
    # Function to call on multi-function apps (defaults to "run" or app's default_function)
    function: str
    # Session control: "new" to start a new session, "sess_xxx" to continue existing session
    # When using sessions, the worker is leased and state persists across calls
    session: str
    # Session timeout in seconds (1-3600). Only valid when session="new"
    session_timeout: int

# ApiAgentRunRequest is the request body for /agents/run endpoint.
# Supports both template agents and ad-hoc agents.
class ApiAgentRunRequest(TypedDict, total=False):
    # Existing chat ID to continue a conversation (optional)
    chat_id: str
    # Template agent reference in format: namespace/name@shortid
    # Example: "my-org/assistant@abc123"
    # Use this OR AgentConfig, not both
    agent: str
    # Ad-hoc agent configuration
    # For ad-hoc agents, set core_app.ref to the LLM app reference
    # Example: { "core_app": { "ref": "infsh/claude-sonnet-4@abc123" }, "system_prompt": "..." }
    agent_config: AgentConfig
    # Optional name for the adhoc agent (used for deduplication and display)
    agent_name: str
    # The message to send
    input: ChatTaskInput
    # If true, returns SSE stream instead of JSON response
    stream: bool

class CreateAgentMessageRequest(TypedDict, total=False):
    chat_id: str
    agent_id: str
    agent_version_id: str
    agent: str
    tool_call_id: str
    input: ChatTaskInput
    integration_context: IntegrationContext
    # Ad-hoc agent config - use this instead of Agent for embedded configs
    # If provided, creates a chat with this config directly (no agent reference)
    agent_config: AgentConfig
    # Optional name for the adhoc agent (used for deduplication and display)
    agent_name: str

class CreateAgentMessageResponse(TypedDict, total=False):
    user_message: ChatMessageDTO
    assistant_message: ChatMessageDTO

# ToolResultRequest represents a tool result submission
# For widget actions, clients should JSON-serialize { action, form_data } as the result string
class ToolResultRequest(TypedDict, total=False):
    result: str

# HookPayload represents the request body sent to a webhook when a hook tool is invoked
class HookPayload(TypedDict, total=False):
    # Identification
    tool_invocation_id: str
    hook_name: str
    # Callback - use this to submit the result back
    callback_url: str
    callback_method: str
    # Timestamp in RFC3339 format
    timestamp: str
    # The actual tool arguments from the LLM
    arguments: Dict[str, Any]

# HookResponse represents the expected response from the hook URL
# The hook should return 200 with success:true to acknowledge receipt
# The actual result should be sent via the callback URL
class HookResponse(TypedDict, total=False):
    success: bool
    message: str

class PartialFile(TypedDict, total=False):
    uri: str
    path: str
    content_type: str
    size: int
    filename: str

class FileCreateRequest(TypedDict, total=False):
    # Category determines the storage path prefix: "uploads" (default), "inputs", "outputs", "repos"
    category: str
    files: List[PartialFile]

class CreateFlowRequest(TypedDict, total=False):
    name: str

class CreateFlowRunRequest(TypedDict, total=False):
    flow: str
    input: Any

# CreateAgentRequest is the request body for POST /agents
# For new agents: omit ID, backend generates it
# For new version of existing agent: include ID
class CreateAgentRequest(TypedDict, total=False):
    # Existing agent ID (if updating/versioning)
    id: str
    # Agent metadata
    name: str
    namespace: str
    images: AgentImages
    # Version config (embedded - backend generates version ID, timestamps, etc)
    version: AgentConfig

# SDKTypes is a phantom struct that references types needed by the SDK.
# This ensures the typegen traces these types without creating aliases.
# Frontend uses generics like CursorListResponse<FlowDTO> directly.
class SDKTypes(TypedDict, total=False):
    pass

class CheckoutCreateRequest(TypedDict, total=False):
    amount: int
    success_url: str
    cancel_url: str

class CheckoutCompleteRequest(TypedDict, total=False):
    session_id: str

# Legacy aliases for backward compatibility
StripeCheckoutCreateRequest = CheckoutCreateRequest

StripeCheckoutCompleteRequest = CheckoutCompleteRequest

# DeviceAuthResponse is returned when a device initiates auth
class DeviceAuthResponse(TypedDict, total=False):
    user_code: str
    device_code: str
    poll_url: str
    approve_url: str
    expires_in: int
    interval: int

# DeviceAuthPollResponse is returned when polling for auth status
class DeviceAuthPollResponse(TypedDict, total=False):
    status: DeviceAuthStatus
    api_key: str
    team_id: str

# DeviceAuthApproveRequest is sent when user approves the auth request
class DeviceAuthApproveRequest(TypedDict, total=False):
    code: str
    team_id: str

# DeviceAuthApproveResponse is returned after approval
class DeviceAuthApproveResponse(TypedDict, total=False):
    success: bool
    message: str

# DeviceAuthCodeInfo contains info about a pending auth code (for display on approve page)
class DeviceAuthCodeInfo(TypedDict, total=False):
    user_code: str
    expires_at: str
    valid: bool
    status: DeviceAuthStatus

# MeResponse is returned from GET /me with user and current team info
class MeResponse(TypedDict, total=False):
    user: UserDTO
    team: TeamDTO

class TeamCreateRequest(TypedDict, total=False):
    name: str
    username: str
    email: str

# TeamSetupRequest is used for completing team setup (choosing username)
# This marks the team as setup_completed=true after validation
class TeamSetupRequest(TypedDict, total=False):
    username: str

class TeamMemberAddRequest(TypedDict, total=False):
    email: str
    role: TeamRole

class TeamMemberUpdateRoleRequest(TypedDict, total=False):
    role: TeamRole

# SecretCreateRequest for creating a new secret
class SecretCreateRequest(TypedDict, total=False):
    key: str
    value: str
    description: str

# SecretUpdateRequest for updating a secret value
class SecretUpdateRequest(TypedDict, total=False):
    value: str
    description: str

# IntegrationConnectRequest for initiating an integration connection
class IntegrationConnectRequest(TypedDict, total=False):
    provider: str
    type: str
    scopes: List[str]
    # For API Key type
    api_key: str
    # For BYOK integrations (e.g., X.com) - contains user-provided credentials
    metadata: Dict[str, Any]

# IntegrationCompleteOAuthRequest for completing an OAuth flow
class IntegrationCompleteOAuthRequest(TypedDict, total=False):
    provider: str
    type: str
    code: str
    state: str
    # For PKCE - code_verifier to complete the exchange (required by some providers like X/Twitter)
    code_verifier: str

# IntegrationConnectResponse after connecting
class IntegrationConnectResponse(TypedDict, total=False):
    integration: IntegrationDTO
    # For OAuth - redirect URL to start the flow
    auth_url: str
    # For OAuth - state to be returned with the callback (frontend stores this)
    state: str
    # For PKCE - code_verifier to be stored and sent back with CompleteOAuth (required by some providers like X/Twitter)
    code_verifier: str
    # For service accounts - instructions
    instructions: str

class ProjectCreateRequest(TypedDict, total=False):
    name: str
    type: ProjectType

class ProjectUpdateRequest(TypedDict, total=False):
    name: str

class MoveAgentToProjectRequest(TypedDict, total=False):
    agent_id: str
    project_id: str


##########
# source: api_internal.go

class WorkerGPUConfig(TypedDict, total=False):
    gpus: List[int]

class WorkerCPUConfig(TypedDict, total=False):
    count: int

class WorkerConfig(TypedDict, total=False):
    gpu: List[WorkerGPUConfig]
    cpu: WorkerCPUConfig

class EngineConfig(TypedDict, total=False):
    id: str
    name: str
    api_url: str
    engine_port: str
    workers: WorkerConfig
    api_key: str
    container_mode: bool
    network_name: str
    cache_path: str
    gpus: List[str]


##########
# source: app.go

class AppCategory(str, Enum):
    IMAGE = "image"
    VIDEO = "video"
    AUDIO = "audio"
    TEXT = "text"
    CHAT = "chat"
    _3_D = "3d"
    OTHER = "other"
    FLOW = "flow"

class GPUType(str, Enum):
    ANY = "any"
    NONE = "none"
    INTEL = "intel"
    NVIDIA = "nvidia"
    A_M_D = "amd"
    APPLE = "apple"

class AppImages(TypedDict, total=False):
    card: str
    thumbnail: str
    banner: str

class App(TypedDict, total=False):
    # Namespace is copied from team.username at creation time and is IMMUTABLE.
    # This ensures stable references like "namespace/name" even if team username changes.
    # Default empty string allows GORM migration to add column, then MigrateAppNamespaces populates it.
    namespace: str
    # Name is IMMUTABLE after creation. Combined with Namespace forms unique identifier.
    name: str
    description: str
    agent_description: str
    # Category is a fundamental classification of the app (image, video, audio, text, chat, 3d, other)
    category: AppCategory
    # Developer's images
    images: AppImages
    # Current version (developer's latest)
    version_id: str
    version: AppVersion

class AppGPUResource(TypedDict, total=False):
    count: int
    vram: int
    type: GPUType

class AppResources(TypedDict, total=False):
    gpu: AppGPUResource
    ram: int

class AppVariant(TypedDict, total=False):
    name: str
    order: int
    resources: AppResources
    env: Dict[str, str]
    python: str

# AppFunction represents a callable entry point within an app version.
# Each function has its own input/output schema while sharing the app's setup.
class AppFunction(TypedDict, total=False):
    name: str
    description: str
    input_schema: Any
    output_schema: Any

class AppVersion(TypedDict, total=False):
    app_id: str
    metadata: Dict[str, Any]
    repository: str
    flow_version_id: str
    flow_version: FlowVersion
    setup_schema: Any
    input_schema: Any
    output_schema: Any
    # Functions contains the callable entry points for this app version.
    # Each function has its own input/output schema. If nil/empty, the app uses legacy single-function mode
    # with InputSchema/OutputSchema at the version level.
    functions: Dict[str, AppFunction]
    default_function: str
    variants: Dict[str, AppVariant]
    env: Dict[str, str]
    kernel: str
    # App requirements - secrets and integrations needed to run this app
    required_secrets: List[SecretRequirement]
    required_integrations: List[IntegrationRequirement]
    resources: AppResources
    # Checksum is the SHA256 checksum of the uploaded zip file
    checksum: str

class LicenseRecord(TypedDict, total=False):
    user_id: str
    app_id: str
    license: str

class AppDTO(TypedDict, total=False):
    namespace: str
    name: str
    description: str
    agent_description: str
    category: AppCategory
    images: AppImages
    version_id: str
    version: AppVersionDTO

class AppVersionDTO(TypedDict, total=False):
    metadata: Dict[str, Any]
    repository: str
    flow_version_id: str
    flow_version: FlowVersionDTO
    setup_schema: Any
    input_schema: Any
    output_schema: Any
    functions: Dict[str, AppFunction]
    default_function: str
    variants: Dict[str, AppVariant]
    env: Dict[str, str]
    kernel: str
    # App requirements
    required_secrets: List[SecretRequirement]
    required_integrations: List[IntegrationRequirement]
    resources: AppResources
    # Checksum is the SHA256 checksum of the uploaded zip file
    checksum: str


##########
# source: app_session.go

class AppSessionStatus(str, Enum):
    ACTIVE = "active"
    ENDED = "ended"
    EXPIRED = "expired"

class AppSession(TypedDict, total=False):
    # Affinity binding
    worker_id: str
    app_id: str
    app_version_id: str
    # Lifecycle
    status: AppSessionStatus
    expires_at: str
    ended_at: str
    # Billing link
    task_id: str
    # Stats
    call_count: int
    last_call_at: str
    # Custom idle timeout in seconds (nil = use default)
    idle_timeout: int
    # Relations
    worker: WorkerState
    task: Task


##########
# source: base.go

class BaseModel(TypedDict, total=False):
    id: str
    short_id: str
    created_at: str
    updated_at: str
    deleted_at: str

class Visibility(str, Enum):
    PRIVATE = "private"
    PUBLIC = "public"
    UNLISTED = "unlisted"

class PermissionModel(TypedDict, total=False):
    user_id: str
    user: User
    team_id: str
    team: Team
    visibility: Visibility

class PermissionModelDTO(TypedDict, total=False):
    user_id: str
    user: UserRelationDTO
    team_id: str
    team: TeamRelationDTO
    visibility: Visibility


##########
# source: chat.go

class ChatStatus(str, Enum):
    BUSY = "busy"
    IDLE = "idle"
    AWAITING_INPUT = "awaiting_input"
    COMPLETED = "completed"

class IntegrationContext(TypedDict, total=False):
    integration_type: IntegrationType
    integration_metadata: Any

# ChatData contains agent-specific data for a chat session
class ChatData(TypedDict, total=False):
    plan_steps: List[PlanStep]
    memory: StringEncodedMap
    always_allowed_tools: List[str]

# PlanStep represents a step in an agent's execution plan
class PlanStep(TypedDict, total=False):
    index: int
    title: str
    description: str
    notes: str
    status: PlanStepStatus

class PlanStepStatus(str, Enum):
    PENDING = "pending"
    IN_PROGRESS = "in_progress"
    COMPLETED = "completed"
    CANCELLED = "cancelled"

class ChatMessageRole(str, Enum):
    SYSTEM = "system"
    USER = "user"
    ASSISTANT = "assistant"
    TOOL = "tool"

class ChatMessageStatus(str, Enum):
    PENDING = "pending"
    READY = "ready"
    FAILED = "failed"
    CANCELLED = "cancelled"

class ChatMessageContentType(str, Enum):
    TEXT = "text"
    REASONING = "reasoning"
    IMAGE = "image"
    FILE = "file"
    TOOL = "tool"

class IntegrationType(str, Enum):
    SLACK = "slack"
    DISCORD = "discord"
    TEAMS = "teams"
    TELEGRAM = "telegram"

class ChatMessageContent(TypedDict, total=False):
    type: ChatMessageContentType
    error: str
    text: str
    image: str
    file: str
    tool_calls: List[ToolCall]

# ToolCall represents a tool call from an LLM response (wire format)
# This is a transport object for parsing LLM responses, not a database model
class ToolCall(TypedDict, total=False):
    id: str
    type: str
    function: ToolCallFunction

# ToolCallFunction contains the function name and arguments from an LLM tool call
class ToolCallFunction(TypedDict, total=False):
    name: str
    arguments: StringEncodedMap

class ChatTaskInput(TypedDict, total=False):
    model: str
    context_size: int
    temperature: float
    top_p: float
    reasoning_effort: str
    reasoning_max_tokens: int
    system_prompt: str
    context: List[ChatTaskContextMessage]
    role: ChatMessageRole
    text: str
    reasoning: str
    images: List[str]
    files: List[str]
    tools: List[Tool]
    tool_call_id: str

class ChatTaskContextMessage(TypedDict, total=False):
    role: ChatMessageRole
    text: str
    reasoning: str
    images: List[str]
    files: List[str]
    tools: List[Tool]
    tool_calls: List[ToolCall]
    tool_call_id: str

class ChatDTO(TypedDict, total=False):
    parent_id: str
    parent: ChatDTO
    children: List[Optional[ChatDTO]]
    status: ChatStatus
    # Agent version reference
    agent_id: str
    agent: AgentDTO
    agent_version_id: str
    agent_version: AgentVersionDTO
    name: str
    description: str
    chat_messages: List[ChatMessageDTO]
    agent_data: ChatData

class ChatMessageDTO(TypedDict, total=False):
    chat_id: str
    chat: ChatDTO
    order: int
    status: ChatMessageStatus
    task_id: str
    role: ChatMessageRole
    content: List[ChatMessageContent]
    tools: List[Tool]
    tool_call_id: str
    tool_invocations: List[ToolInvocationDTO]


##########
# source: common.go

StringEncodedMap = Dict[str, Any]


##########
# source: cursor.go

# SearchRequest represents a search request
class SearchRequest(TypedDict, total=False):
    fields: List[str]
    term: str
    exact: bool

# Filter represents a single filter condition
class Filter(TypedDict, total=False):
    field: str
    operator: FilterOperator
    value: Any

class FilterOperator(str, Enum):
    OP_EQUAL = "eq"
    OP_NOT_EQUAL = "neq"
    OP_IN = "in"
    OP_NOT_IN = "not_in"
    OP_GREATER = "gt"
    OP_GREATER_EQUAL = "gte"
    OP_LESS = "lt"
    OP_LESS_EQUAL = "lte"
    OP_LIKE = "like"
    OP_I_LIKE = "ilike"
    OP_CONTAINS = "contains"
    OP_NOT_CONTAINS = "not_contains"
    # Null checks
    OP_IS_NULL = "is_null"
    OP_IS_NOT_NULL = "is_not_null"
    # Empty checks (for strings)
    OP_IS_EMPTY = "is_empty"
    OP_IS_NOT_EMPTY = "is_not_empty"

# SortOrder represents sorting configuration
class SortOrder(TypedDict, total=False):
    field: str
    dir: str

# CursorListRequest represents a cursor-based list request with all options
class CursorListRequest(TypedDict, total=False):
    cursor: str
    page: int
    limit: int
    direction: str
    search: SearchRequest
    filters: List[Filter]
    preloads: List[str]
    sort: List[SortOrder]
    fields: List[str]
    permissions: List[str]
    include_others: bool

# CursorListResponse represents a cursor-based paginated response
class CursorListResponse(TypedDict, total=False):
    items: List[Any]
    next_cursor: str
    prev_cursor: str
    has_next: bool
    has_previous: bool
    items_per_page: int
    total_items: int


##########
# source: deviceauth.go

class DeviceAuthStatus(str, Enum):
    PENDING = "pending"
    APPROVED = "approved"
    EXPIRED = "expired"
    DENIED = "denied"
    VALID = "valid"
    INVALID = "invalid"
    LOADING = "loading"


##########
# source: engine.go

class EngineStatus(str, Enum):
    RUNNING = "running"
    PENDING = "pending"
    STOPPING = "stopping"
    STOPPED = "stopped"

class EngineState(TypedDict, total=False):
    instance: Instance
    transaction_id: str
    config: EngineConfig
    public_key: str
    name: str
    api_url: str
    status: str
    system_info: SystemInfo
    workers: List[Optional[WorkerState]]

class EngineStateDTO(TypedDict, total=False):
    instance: Instance
    config: EngineConfig
    name: str
    api_url: str
    status: str
    system_info: SystemInfo
    workers: List[Optional[WorkerStateDTO]]

class EngineStateSummary(TypedDict, total=False):
    instance: Instance
    name: str
    status: str
    workers: List[Optional[WorkerStateSummary]]

class WorkerState(TypedDict, total=False):
    index: int
    status: str
    status_updated_at: str
    engine_id: str
    engine: EngineState
    task_id: str
    app_id: str
    app_version_id: str
    # App session lease
    active_session_id: str
    active_session: AppSession
    gpus: List[WorkerGPU]
    cpus: List[WorkerCPU]
    rams: List[WorkerRAM]
    SystemInfo: SystemInfo
    # WarmApps tracks app+version combos with warm containers for scheduling optimization.
    # Format: "appID:versionID@setupHash" - managed by Engine, synced via heartbeat.
    # Not persisted to DB - this is ephemeral runtime state.
    warm_apps: List[str]

class WorkerGPU(TypedDict, total=False):
    id: str
    worker_id: str
    gpu_id: str
    type: GPUType
    name: str
    vram: int

class WorkerCPU(TypedDict, total=False):
    id: str
    worker_id: str
    name: str
    vendor_id: str
    family: str
    model: str
    cores: int
    frequency: str

class WorkerRAM(TypedDict, total=False):
    id: str
    worker_id: str
    total: int

class WorkerStateDTO(TypedDict, total=False):
    user_id: str
    team_id: str
    index: int
    status: str
    engine_id: str
    task_id: str
    app_id: str
    app_version_id: str
    active_session_id: str
    gpus: List[WorkerGPU]
    cpus: List[WorkerCPU]
    rams: List[WorkerRAM]
    system_info: SystemInfo
    warm_apps: List[str]

class WorkerStateSummary(TypedDict, total=False):
    id: str
    user_id: str
    index: int
    status: str
    engine_id: str
    engine_name: str
    task_id: str
    app_id: str
    app_version_id: str
    active_session_id: str
    gpus: List[WorkerGPU]
    cpus: List[WorkerCPU]
    rams: List[WorkerRAM]


##########
# source: file.go

# FileMetadata holds probed media metadata cached on File records.
class FileMetadata(TypedDict, total=False):
    type: str
    width: int
    height: int
    duration: float
    fps: float
    sample_rate: int
    channels: int
    codec: str

class File(TypedDict, total=False):
    path: str
    remote_path: str
    upload_url: str
    uri: str
    content_type: str
    size: int
    filename: str
    rating: ContentRating
    metadata: FileMetadata

class FileDTO(TypedDict, total=False):
    path: str
    remote_path: str
    upload_url: str
    uri: str
    content_type: str
    size: int
    filename: str
    rating: ContentRating
    metadata: FileMetadata


##########
# source: flow.go

class FlowVersion(TypedDict, total=False):
    # Permission fields - nullable for migration from existing data
    # After migration these will be populated from parent Flow
    user_id: str
    user: User
    team_id: str
    team: Team
    flow_id: str
    # ConfigHash for deduplication - SHA256 of config content
    config_hash: str
    # Flow graph configuration
    input_schema: Any
    input: FlowRunInputs
    output_schema: Any
    output_mappings: OutputMappings
    node_data: FlowNodeDataMap
    nodes: List[FlowNode]
    edges: List[FlowEdge]
    viewport: FlowViewport

class FlowViewport(TypedDict, total=False):
    x: float
    y: float
    zoom: float

class FlowNode(TypedDict, total=False):
    id: str
    type: str
    position: FlowNodePosition

class FlowNodePosition(TypedDict, total=False):
    x: float
    y: float

class FlowNodeData(TypedDict, total=False):
    app: AppDTO
    app_id: str
    app_version_id: str
    function: str
    infra: Infra
    workers: List[str]
    setup: Any
    additional: Any
    task: TaskDTO
    task_id: str

FlowNodeDataMap = Dict[str, "FlowNodeData"]

class FlowEdge(TypedDict, total=False):
    id: str
    type: str
    source: str
    target: str
    source_handle: str
    target_handle: str

# OutputFieldMapping represents a mapping from a source node's field to an output field in the flow output schema.
class OutputFieldMapping(TypedDict, total=False):
    sourceNodeId: str
    sourceFieldPath: str
    outputFieldName: str
    type: str
    schema: Any

# OutputMappings is a map of output field name to OutputFieldMapping.
OutputMappings = Dict[str, "OutputFieldMapping"]

class FlowDTO(TypedDict, total=False):
    name: str
    description: str
    card_image: str
    thumbnail: str
    banner_image: str
    # Version references
    draft_version_id: str
    draft_version: FlowVersionDTO
    published_version_id: str
    published_version: FlowVersionDTO
    # Flattened draft version fields for backward compatibility
    # These come from the draft version (the editable one)
    input_schema: Any
    input: FlowRunInputs
    output_schema: Any
    output_mappings: OutputMappings
    node_data: FlowNodeDataMap
    nodes: List[FlowNode]
    edges: List[FlowEdge]
    viewport: FlowViewport

class FlowVersionDTO(TypedDict, total=False):
    input_schema: Any
    input: FlowRunInputs
    output_schema: Any
    output_mappings: OutputMappings
    node_data: FlowNodeDataMap
    nodes: List[FlowNode]
    edges: List[FlowEdge]
    viewport: FlowViewport

class NodeTaskDTO(TypedDict, total=False):
    task_id: str
    task: TaskDTO

class FlowRunStatus(IntEnum):
    UNKNOWN = 0
    PENDING = 1
    RUNNING = 2
    COMPLETED = 3
    FAILED = 4
    CANCELLED = 5

class FlowRunDTO(TypedDict, total=False):
    flow_id: str
    flow_version_id: str
    flow_version: FlowVersionDTO
    task_id: str
    status: FlowRunStatus
    error: str
    flow_run_started: str
    flow_run_finished: str
    flow_run_cancelled: str
    input: FlowRunInputs
    fail_on_error: bool
    output: Any
    node_tasks: Dict[str, Optional[NodeTaskDTO]]

# Connection represents a connection between nodes in a flow
class FlowNodeConnection(TypedDict, total=False):
    nodeId: str
    key: str
    type: str
    previousValue: Any

FlowRunInputs = Dict[str, Dict[str, "FlowRunInput"]]

class FlowRunInput(TypedDict, total=False):
    Connection: FlowNodeConnection
    Value: Any


##########
# source: graph.go

class GraphNodeType(str, Enum):
    UNKNOWN = "unknown"
    JOIN = "join"
    SPLIT = "split"
    EXECUTION = "execution"
    RESOURCE = "resource"
    APPROVAL = "approval"
    CONDITIONAL = "conditional"
    FLOW_NODE = "flow_node"

class GraphNodeStatus(str, Enum):
    PENDING = "pending"
    READY = "ready"
    RUNNING = "running"
    COMPLETED = "completed"
    FAILED = "failed"
    CANCELLED = "cancelled"
    SKIPPED = "skipped"
    BLOCKED = "blocked"

class GraphEdgeType(str, Enum):
    DEPENDENCY = "dependency"
    FLOW = "flow"
    CONDITIONAL = "conditional"
    EXECUTION = "execution"

# GraphNodeDTO is the API representation of a graph node
class GraphNodeDTO(TypedDict, total=False):
    graph_id: str
    type: GraphNodeType
    label: str
    resource_id: str
    resource_type: str
    status: GraphNodeStatus
    metadata: StringEncodedMap
    ready_at: str
    started_at: str
    completed_at: str
    duration_ms: int

# GraphEdgeDTO is the API representation of a graph edge
class GraphEdgeDTO(TypedDict, total=False):
    type: GraphEdgeType
    from_node: str
    to_node: str

# ChatTraceDTO is the trace response for chat observability
class ChatTraceDTO(TypedDict, total=False):
    graph_id: str
    nodes: List[Optional[GraphNodeDTO]]
    edges: List[Optional[GraphEdgeDTO]]
    # Summary stats
    total_steps: int
    completed_steps: int
    running_steps: int
    failed_steps: int


##########
# source: integration.go

# StringSlice is a custom type for storing string slices in the database
StringSlice = List[str]

# IntegrationDTO for API responses (never exposes tokens)
class IntegrationDTO(TypedDict, total=False):
    provider: str
    type: str
    status: str
    display_name: str
    scopes: StringSlice
    expires_at: str
    service_account_email: str
    metadata: Dict[str, Any]
    account_identifier: str
    account_name: str
    is_primary: bool
    error_message: str


##########
# source: project.go

class ProjectType(str, Enum):
    AGENT = "agent"
    APP = "app"
    FLOW = "flow"
    OTHER = "other"

# ProjectModel provides optional project association for models
class ProjectModel(TypedDict, total=False):
    project_id: str
    project: Project

class ProjectModelDTO(TypedDict, total=False):
    project_id: str
    project: ProjectDTO

# Project represents a container for organizing related resources
class Project(TypedDict, total=False):
    name: str
    description: str
    type: ProjectType
    color: str
    icon: str
    # For future: nested folders/projects
    parent_id: str
    parent: Project
    children: List[Optional[Project]]

# ProjectDTO for API responses
class ProjectDTO(TypedDict, total=False):
    name: str
    description: str
    type: ProjectType
    color: str
    icon: str
    parent_id: str
    parent: ProjectDTO
    children: List[Optional[ProjectDTO]]


##########
# source: rating.go

class ContentRating(str, Enum):
    CONTENT_SAFE = "safe"
    # sexual content
    CONTENT_SEXUAL_SUGGESTIVE = "sexual_suggestive"
    CONTENT_SEXUAL_EXPLICIT = "sexual_explicit"
    # violence
    CONTENT_VIOLENCE_NON_GRAPHIC = "violence_non_graphic"
    CONTENT_VIOLENCE_GRAPHIC = "violence_graphic"
    # gore
    CONTENT_GORE = "gore"
    # other regulated content
    CONTENT_DRUGS = "drugs"
    CONTENT_SELF_HARM = "self_harm"
    CONTENT_UNRATED = "unrated"


##########
# source: requirements.go

# SecretRequirement defines a secret that an app requires to run
class SecretRequirement(TypedDict, total=False):
    key: str
    description: str
    optional: bool

# IntegrationRequirement defines an integration capability that an app requires
class IntegrationRequirement(TypedDict, total=False):
    key: str
    description: str
    optional: bool

# RequirementError represents a single missing requirement with actionable info
class RequirementError(TypedDict, total=False):
    type: str
    key: str
    message: str
    action: SetupAction

# SetupAction provides actionable info for resolving a missing requirement
class SetupAction(TypedDict, total=False):
    type: str
    provider: str
    scopes: List[str]


##########
# source: secrets.go

# SecretRef tracks which Secret record provided a value for a task (for billing)
class SecretRef(TypedDict, total=False):
    key: str
    id: str
    team_id: str


##########
# source: shadeform.go

class InstanceCloudProvider(str, Enum):
    CLOUD_A_W_S = "aws"
    CLOUD_AZURE = "azure"
    CLOUD_LAMBDA_LABS = "lambdalabs"
    CLOUD_TENSOR_DOCK = "tensordock"
    CLOUD_RUN_POD = "runpod"
    CLOUD_LATITUDE = "latitude"
    CLOUD_JARVIS_LABS = "jarvislabs"
    CLOUD_OBLIVUS = "oblivus"
    CLOUD_PAPERSPACE = "paperspace"
    CLOUD_DATACRUNCH = "datacrunch"
    CLOUD_MASSED_COMPUTE = "massedcompute"
    CLOUD_VULTR = "vultr"
    CLOUD_SHADE = "shade"

class InstanceStatus(str, Enum):
    PENDING = "pending"
    ACTIVE = "active"
    DELETED = "deleted"

class Instance(TypedDict, total=False):
    cloud: InstanceCloudProvider
    name: str
    region: str
    shade_cloud: bool
    shade_instance_type: str
    cloud_instance_type: str
    cloud_assigned_id: str
    os: str
    ssh_key_id: str
    ssh_user: str
    ssh_port: int
    ip: str
    status: InstanceStatus
    cost_estimate: str
    hourly_price: int
    template_id: str
    volume_ids: List[str]
    tags: List[str]
    configuration: InstanceConfiguration
    launch_configuration: InstanceLaunchConfiguration
    auto_delete: InstanceThresholdConfig
    alert: InstanceThresholdConfig
    volume_mount: InstanceVolumeMountConfig
    envs: List[InstanceEnvVar]

class InstanceConfiguration(TypedDict, total=False):
    gpu_type: str
    interconnect: str
    memory_in_gb: int
    num_gpus: int
    os: str
    storage_in_gb: int
    vcpus: int
    vram_per_gpu_in_gb: int

class InstanceLaunchConfiguration(TypedDict, total=False):
    type: str
    docker_configuration: InstanceDockerConfig
    script_configuration: InstanceScriptConfig

class InstanceDockerConfig(TypedDict, total=False):
    image: str
    args: str
    shared_memory_in_gb: int
    envs: List[InstanceEnvVar]
    port_mappings: List[InstancePortMapping]
    volume_mounts: List[InstanceVolumeMount]

class InstanceScriptConfig(TypedDict, total=False):
    base64_script: str

class InstancePortMapping(TypedDict, total=False):
    host_port: int
    container_port: int

class InstanceVolumeMount(TypedDict, total=False):
    host_path: str
    container_path: str

class InstanceThresholdConfig(TypedDict, total=False):
    date_threshold: str
    spend_threshold: str

class InstanceVolumeMountConfig(TypedDict, total=False):
    auto: bool

class InstanceEnvVar(TypedDict, total=False):
    name: str
    value: str


##########
# source: system_info.go

# Hardware/System related types
class SystemInfo(TypedDict, total=False):
    hostname: str
    engine_version: str
    ipv4: str
    ipv6: str
    mac_address: str
    os: str
    docker: Docker
    wsl2: WSL2
    cpus: List[CPU]
    ram: RAM
    volumes: List[Volume]
    hf_cache: HFCacheInfo
    gpus: List[GPU]

class TelemetrySystemInfo(TypedDict, total=False):
    cpus: List[CPU]
    ram: RAM
    gpus: List[GPU]
    volumes: List[Volume]

class Docker(TypedDict, total=False):
    binary_path: str
    installed: bool
    socket_path: str
    socket_available: bool
    running: bool
    version: str

class WSL2(TypedDict, total=False):
    installed: bool
    enabled: bool
    version: str

class CPU(TypedDict, total=False):
    name: str
    vendor_id: str
    family: str
    model: str
    cores: int
    frequency: str
    usage: float
    normalized_usage: float

class Volume(TypedDict, total=False):
    name: str
    size: int
    used: int
    free: int
    usage: float

class RAM(TypedDict, total=False):
    total: int
    available: int
    used: int
    free: int
    usage: float
    total_physical: int
    total_usable: int
    bootloader_usage: int
    swap_total: int
    swap_used: int
    swap_free: int
    swap_usage: float

class GPU(TypedDict, total=False):
    id: str
    name: str
    index: int
    cuda_version: str
    driver_version: str
    memory_used: int
    memory_total: int
    temperature: int

# CachedRevisionInfo represents information about a cached revision
class CachedRevisionInfo(TypedDict, total=False):
    commit_hash: str
    snapshot_path: str
    last_modified: str
    size_on_disk: int
    size_on_disk_str: str
    nb_files: int
    refs: List[str]

# CachedRepoInfo represents information about a cached repository
class CachedRepoInfo(TypedDict, total=False):
    repo_id: str
    repo_type: str
    repo_path: str
    last_accessed: str
    last_modified: str
    size_on_disk: int
    size_on_disk_str: str
    nb_files: int
    refs: List[str]
    Revisions: List[CachedRevisionInfo]

# HFCacheInfo represents information about the Huggingface cache
class HFCacheInfo(TypedDict, total=False):
    cache_dir: str
    repos: List[CachedRepoInfo]
    size_on_disk: int
    warnings: List[str]


##########
# source: task.go

class TaskStatus(IntEnum):
    UNKNOWN = 0
    RECEIVED = 1
    QUEUED = 2
    SCHEDULED = 3
    PREPARING = 4
    SERVING = 5
    SETTING_UP = 6
    RUNNING = 7
    CANCELLING = 8
    UPLOADING = 9
    COMPLETED = 10
    FAILED = 11
    CANCELLED = 12

class Infra(str, Enum):
    PRIVATE = "private"
    CLOUD = "cloud"
    PRIVATE_FIRST = "private_first"

class Task(TypedDict, total=False):
    is_featured: bool
    status: str
    # Foreign keys
    app_id: str
    app: App
    version_id: str
    app_version: AppVersion
    # Deprecated: Will be removed in favor of Setup
    variant: str
    # Function is the specific function to call on multi-function apps.
    # DEPRECATED: Standardizing on explicit function name.
    # Defaults to "run" for legacy tasks (backfilled via migration).
    function: str
    infra: Infra
    workers: List[str]
    engine_id: str
    engine: EngineState
    worker_id: str
    worker: WorkerState
    # Belongs to:
    flow_run_id: str
    chat_id: str
    # Owns: (Can be replaced with graph execution edge/node)
    sub_flow_run_id: str
    webhook: str
    setup: Any
    input: Any
    output: Any
    error: str
    rating: ContentRating
    # Relationships
    events: List[TaskEvent]
    logs: List[TaskLog]
    telemetry: List[TimescaleTask]
    usage_events: List[Optional[UsageEvent]]
    transaction_id: str
    transaction: Transaction
    # Secret refs for billing (tracks ownership to determine partner fee)
    secrets: List[SecretRef]
    # App session reference (for session calls)
    # Special value "new" means scheduler should create session when dispatching.
    session_id: str
    session: AppSession
    # Session timeout in seconds (only used when session="new")
    session_timeout: int

class TaskEvent(TypedDict, total=False):
    id: str
    created_at: str
    event_time: str
    task_id: str
    status: str

class TaskLogType(IntEnum):
    BUILD = 0
    RUN = 1
    SERVE = 2
    SETUP = 3
    TASK = 4

class TaskLog(TypedDict, total=False):
    id: str
    created_at: str
    updated_at: str
    task_id: str
    log_type: TaskLogType
    content: bytes

class TaskDTO(TypedDict, total=False):
    graph_id: str
    user_public_key: bytes
    engine_public_key: bytes
    is_featured: bool
    status: str
    app_id: str
    app: AppDTO
    app_version_id: str
    app_version: AppVersionDTO
    app_variant: str
    function: str
    infra: Infra
    workers: List[str]
    flow_run_id: str
    chat_id: str
    sub_flow_run_id: str
    agent_id: str
    agent_version_id: str
    agent: AgentDTO
    engine_id: str
    engine: EngineStateSummary
    worker_id: str
    worker: WorkerStateSummary
    webhook: str
    setup: Any
    input: Any
    output: Any
    error: str
    rating: ContentRating
    events: List[TaskEvent]
    logs: List[TaskLog]
    telemetry: List[TimescaleTask]
    usage_events: List[Optional[UsageEvent]]
    transaction_id: str
    transaction: Transaction
    session_id: str
    session_timeout: int

class TimescaleTask(TypedDict, total=False):
    id: str
    timestamp: str
    task_id: str
    task_seq: int
    app_id: str
    app_version_id: str
    engine_id: str
    engine_resources: TelemetrySystemInfo
    worker_id: str
    system_info: TelemetrySystemInfo


##########
# source: team.go

class TeamType(str, Enum):
    PERSONAL = "personal"
    TEAM = "team"
    SYSTEM = "system"

class Team(TypedDict, total=False):
    type: TeamType
    username: str
    email: str
    name: str
    avatar_url: str
    # SetupCompleted indicates whether the team has completed initial setup (chosen a username)
    # Personal teams start with SetupCompleted=false and a generated temporary username
    setup_completed: bool

class TeamDTO(TypedDict, total=False):
    type: TeamType
    name: str
    username: str
    avatar_url: str
    email: str
    setup_completed: bool

class TeamRole(str, Enum):
    OWNER = "owner"
    ADMIN = "admin"
    MEMBER = "member"

# Team-related types
class TeamRelationDTO(TypedDict, total=False):
    id: str
    created_at: str
    updated_at: str
    type: TeamType
    username: str
    avatar_url: str
    setup_completed: bool


##########
# source: tools.go

# ToolInvocationFunction contains the function details for a tool invocation
class ToolInvocationFunction(TypedDict, total=False):
    name: str
    arguments: StringEncodedMap

class ToolInvocationStatus(str, Enum):
    PENDING = "pending"
    IN_PROGRESS = "in_progress"
    AWAITING_INPUT = "awaiting_input"
    AWAITING_APPROVAL = "awaiting_approval"
    COMPLETED = "completed"
    FAILED = "failed"
    CANCELLED = "cancelled"

# ToolInvocationDTO for API responses
class ToolInvocationDTO(TypedDict, total=False):
    chat_message_id: str
    tool_invocation_id: str
    type: ToolType
    execution_id: str
    function: ToolInvocationFunction
    status: ToolInvocationStatus
    result: str
    # Unified fields
    data: Any
    widget: Widget

class Tool(TypedDict, total=False):
    type: str
    function: ToolFunction

class ToolFunction(TypedDict, total=False):
    name: str
    description: str
    parameters: ToolParameters
    required: List[str]

class ToolParameters(TypedDict, total=False):
    type: str
    title: str
    properties: ToolParameterProperties
    required: List[str]

ToolParameterProperties = Dict[str, "ToolParameterProperty"]

class ToolParameterProperty(TypedDict, total=False):
    type: str
    title: str
    description: str
    properties: ToolParameterProperties
    items: ToolParameterProperty
    required: List[str]


##########
# source: tx.go

class TransactionType(str, Enum):
    CREDIT = "credit"
    DEBIT = "debit"

# Transaction represents a single credit transaction
class Transaction(TypedDict, total=False):
    type: TransactionType
    amount: int
    reference: str
    notes: str
    # Link to payment record for payment transactions (top-ups, auto-recharge)
    PaymentRecordID: Optional[str]
    PaymentRecord: Optional[PaymentRecord]
    UsageBillingRecordID: Optional[str]
    UsageBillingRecord: Optional[UsageBillingRecord]
    UsageBillingRefundID: Optional[str]
    UsageBillingRefund: Optional[UsageBillingRefund]
    # Metadata for the transaction
    metadata: Dict[str, Any]
    # SideEffectsProcessed tracks whether side effects (notifications, auto-recharge,
    # billing status changes) have been processed for this transaction.
    # Set to true via WithSkipTxSideEffects context to skip side effects (e.g. migrations).
    side_effects_processed: bool

class PaymentRecordStatus(IntEnum):
    PENDING = 0
    COMPLETE = 1
    FAILED = 2
    EXPIRED = 3

class PaymentRecordType(str, Enum):
    CHECKOUT = "checkout"
    AUTO_RECHARGE = "auto_recharge"

# PaymentRecord stores Stripe payment details for both checkout sessions and direct charges
class PaymentRecord(TypedDict, total=False):
    type: PaymentRecordType
    status: PaymentRecordStatus
    amount: int
    service_fee: int
    stripe_customer_id: str
    payment_intent_id: str
    receipt_url: str
    # Checkout-specific fields (only set for checkout type)
    session_id: str
    session_url: str


##########
# source: usage.go

class UsageEventResourceTier(str, Enum):
    PRIVATE = "private"
    CLOUD = "cloud"

class MetaItemType(str, Enum):
    TEXT = "text"
    IMAGE = "image"
    VIDEO = "video"
    AUDIO = "audio"
    RAW = "raw"

class VideoResolution(str, Enum):
    VIDEO_RES480_P = "480p"
    VIDEO_RES720_P = "720p"
    VIDEO_RES1080_P = "1080p"
    VIDEO_RES1440_P = "1440p"
    VIDEO_RES4_K = "4k"

# MetaItem represents metadata about an input or output item
class MetaItem(TypedDict, total=False):
    type: MetaItemType
    # Text fields
    tokens: int
    # Image/Video shared fields
    width: int
    height: int
    resolution_mp: float
    # Image specific fields
    steps: int
    count: int
    # Video specific fields
    resolution: VideoResolution
    seconds: float
    fps: int
    # Audio specific fields
    sample_rate: int
    # App-specific key-value pairs for custom pricing factors
    extra: Dict[str, Any]

# OutputMeta contains structured metadata about task inputs and outputs for pricing calculation
class OutputMeta(TypedDict, total=False):
    inputs: List[MetaItem]
    outputs: List[MetaItem]

class UsageEvent(TypedDict, total=False):
    usage_billing_record_id: str
    reference_id: str
    resource_id: str
    # Resource tier
    tier: UsageEventResourceTier
    type: str
    model: str
    quantity: int
    unit: str

# DiscountItem represents a single discount applied to a billing record
class DiscountItem(TypedDict, total=False):
    reason: str
    amount: int

class UsageBillingRecord(TypedDict, total=False):
    # Fee breakdown (all in microcents)
    total: int
    discount: int
    # User debit (total charged)
    user_debit_transaction_id: str
    user_debit_transaction: Transaction
    # Resource owner credit (for providing compute)
    resource_credit_transaction_id: str
    resource_credit_transaction: Transaction
    # Creator royalty credit (app creator earnings)
    royalty_credit_transaction_id: str
    royalty_credit_transaction: Transaction
    # Inference fee credit (platform fee)
    inference_credit_transaction_id: str
    inference_credit_transaction: Transaction
    # Partner fee credit (cloud API fee)
    partner_credit_transaction_id: str
    partner_credit_transaction: Transaction

class UsageBillingRefund(TypedDict, total=False):
    usage_billing_record_id: str
    usage_billing_record: UsageBillingRecord
    # User refund (total refunded)
    user_debit_refund_transaction_id: str
    user_debit_refund_transaction: Transaction
    # Resource owner reversal
    resource_credit_refund_transaction_id: str
    resource_credit_refund_transaction: Transaction
    # Creator royalty reversal
    royalty_credit_refund_transaction_id: str
    royalty_credit_refund_transaction: Transaction
    # Inference fee reversal
    inference_credit_refund_transaction_id: str
    inference_credit_refund_transaction: Transaction
    # Partner fee reversal
    partner_credit_refund_transaction_id: str
    partner_credit_refund_transaction: Transaction


##########
# source: user.go

# User-related types
class User(TypedDict, total=False):
    default_team_id: str
    role: str
    email: str
    email_verified: bool
    name: str
    full_name: str
    avatar_url: str
    metadata: UserMetadata

class Role(str, Enum):
    GUEST = "guest"
    USER = "user"
    ADMIN = "admin"
    SYSTEM = "system"

class UserDTO(TypedDict, total=False):
    default_team_id: str
    role: str
    email: str
    name: str
    full_name: str
    avatar_url: str
    metadata: UserMetadata

# User-related types
class UserRelationDTO(TypedDict, total=False):
    id: str
    created_at: str
    updated_at: str
    role: str
    avatar_url: str

class UserMetadata(TypedDict, total=False):
    user_id: str
    completed_onboarding: bool
    use_case: str
    use_case_reason: str
    use_case_privacy: str


##########
# source: widget.go

# WidgetAction represents an action triggered by a widget button
class WidgetAction(TypedDict, total=False):
    type: str
    payload: Dict[str, Any]

# WidgetActionButton represents a button in a widget's action bar
class WidgetActionButton(TypedDict, total=False):
    label: str
    action: WidgetAction
    variant: str

class WidgetNodeType(str, Enum):
    # Primitive node types (render literal values)
    TEXT = "text"
    MARKDOWN = "markdown"
    IMAGE = "image"
    BADGE = "badge"
    BUTTON = "button"
    INPUT = "input"
    SELECT = "select"
    CHECKBOX = "checkbox"
    ROW = "row"
    COL = "col"
    # Layout node types
    BOX = "box"
    SPACER = "spacer"
    DIVIDER = "divider"
    FORM = "form"
    # Typography node types
    TITLE = "title"
    CAPTION = "caption"
    LABEL = "label"
    # Control node types
    TEXTAREA = "textarea"
    RADIO_GROUP = "radio-group"
    DATE_PICKER = "date-picker"
    # Content node types
    ICON = "icon"
    CHART = "chart"
    TRANSITION = "transition"
    # Data-bound node types (deprecated - use templates instead)
    PLAN_LIST = "plan-list"
    KEY_VALUE = "key-value"
    STATUS_BADGE = "status-badge"

# WidgetNode represents a UI element in a widget (text, input, select, etc.)
class WidgetNode(TypedDict, total=False):
    type: WidgetNodeType
    value: str
    src: str
    alt: str
    label: str
    name: str
    placeholder: str
    defaultValue: str
    variant: str
    action: WidgetAction
    options: List[WidgetSelectOption]
    defaultChecked: bool
    children: List[WidgetNode]
    gap: int
    # Layout props (Box, Row, Col, Form)
    align: str
    justify: str
    padding: Any
    background: Any
    radius: str
    direction: str
    wrap: str
    flex: Any
    # Typography props (Text, Title, Caption, Label)
    size: str
    weight: str
    color: Any
    textAlign: str
    truncate: bool
    maxLines: int
    # Control props (Input, Textarea, Select, Checkbox, RadioGroup, DatePicker, Button)
    disabled: bool
    required: bool
    rows: int
    fieldName: str
    submit: bool
    pattern: str
    min: str
    max: str
    clearable: bool
    # Action handler for buttons (form data is collected locally and sent with action)
    onClickAction: WidgetAction
    # Content props (Icon, Spacer, Divider, Chart)
    iconName: str
    spacing: Any
    minSize: Any
    height: Any
    width: Any
    # Chart specific props
    chartData: Any
    chartSeries: Any
    xAxis: Any
    showYAxis: bool
    showLegend: bool
    showTooltip: bool
    # Form-specific props
    onSubmitAction: WidgetAction
    # Data binding (deprecated - use templates instead)
    dataKey: str

# WidgetSelectOption represents an option in a select widget
class WidgetSelectOption(TypedDict, total=False):
    label: str
    value: str

# Widget represents an interactive widget for display in chat
# Type is either "ui" (structured nodes) or "html" (raw HTML)
# For "ui" widgets, data-bound nodes read values from ToolInvocation.Data
class Widget(TypedDict, total=False):
    type: str
    interactive: bool
    title: str
    html: str
    json: str
    children: List[WidgetNode]
    actions: List[WidgetActionButton]

