/**
 * Shared types for the Settings > AI governance layer.
 *
 * Phases 1-2 cover provider connections (encrypted keys) and a dynamic,
 * normalized model catalog. Feature config, budget, and data-policy shapes are
 * declared here for forward-compatibility (enforcement + metering land in later
 * phases) but only `features[].enabled` and `budget.monthlyTokenLimit` are
 * wired into the UI for now.
 */
/** Provider keys are stable code identifiers. `openai` covers OpenAI/ChatGPT. */
export type AIProviderKey = 'openai' | 'anthropic' | 'xai' | 'custom';
/** Where a provider's API key actually comes from at runtime. */
export type AIKeySource = 'environment' | 'database' | 'config';
/** Connection health surfaced in the UI (always rendered as text, not color-only). */
export type AIConnectionStatus = 'connected' | 'invalid_key' | 'rate_limited' | 'provider_down' | 'needs_setup' | 'unknown';
/** Availability of a catalog model relative to the connected account. */
export type AIModelStatus = 'available' | 'unavailable' | 'deprecated' | 'unknown';
export interface AIModelCapabilities {
    text: boolean;
    vision: boolean;
    imageGeneration: boolean;
    embeddings: boolean;
    toolCalling: boolean;
    structuredOutput: boolean;
    streaming: boolean;
    reasoning: boolean;
    longContext: boolean;
}
export interface AIModelPricing {
    inputPerMillion?: number;
    outputPerMillion?: number;
    image?: number;
    search?: number;
}
/** Normalized model record (merged from live listing + curated metadata). */
export interface AIModel {
    /** Stable internal id: `${provider}:${providerModelId}`. */
    id: string;
    provider: AIProviderKey;
    providerModelId: string;
    displayName: string;
    description?: string;
    status: AIModelStatus;
    capabilities: AIModelCapabilities;
    contextWindow?: number;
    maxOutputTokens?: number;
    inputModalities: string[];
    outputModalities: string[];
    pricing?: AIModelPricing;
    aliases?: string[];
    lastSyncedAt: string;
    source: 'provider' | 'manual' | 'config';
    metadata: Record<string, unknown>;
}
/**
 * Stored provider connection. The encrypted key NEVER leaves the server — API
 * responses use {@link AIProviderConnectionPublic}.
 */
export interface AIProviderConnection {
    id: string;
    provider: AIProviderKey;
    displayName: string;
    enabled: boolean;
    status: AIConnectionStatus;
    /** Encrypted via `encryptSecret`. Absent when the key is env-managed. */
    apiKeyEncrypted?: string;
    apiKeyLast4?: string;
    baseUrl?: string;
    organizationId?: string;
    projectId?: string;
    lastTestedAt?: string;
    lastSuccessfulRunAt?: string;
    lastModelSyncAt?: string;
    createdAt: string;
    updatedAt: string;
    updatedBy: string;
}
/** Client-safe provider view: no key material, source resolved dynamically. */
export type AIProviderConnectionPublic = Omit<AIProviderConnection, 'apiKeyEncrypted'> & {
    apiKeySource: AIKeySource;
    /** True when the key is env-managed and therefore not editable in the UI. */
    keyManagedExternally: boolean;
    hasKey: boolean;
};
export type AIFeatureCategory = 'seo' | 'media' | 'content' | 'forms' | 'security' | 'developer' | 'search';
export interface AIFeatureConfig {
    key: string;
    label: string;
    description: string;
    enabled: boolean;
    category: AIFeatureCategory;
    requiredCapabilities: string[];
    providerId?: string;
    modelId?: string;
    fallbackModelIds?: string[];
    approvalRequired: boolean;
    allowBulkApply: boolean;
    maxMonthlyTokens?: number;
    maxRequestsPerDay?: number;
    rolesAllowed: string[];
    permissionsRequired: string[];
    dataPolicyKey?: string;
}
export interface AIBudgetSettings {
    monthlyTokenLimit?: number;
    monthlyCostLimit?: number;
    alertAtPercentages: number[];
    disableWhenExceeded: boolean;
    perFeatureLimits?: Record<string, number>;
    perUserLimits?: Record<string, number>;
}
/**
 * Brand voice profile. A reusable description of how generated copy should
 * sound, injected into the system prompt of content-generation features so
 * every AI surface writes in one consistent, on-brand voice. Contains no
 * secrets — safe to return to the client.
 */
export interface BrandVoiceProfile {
    /** When false, the profile is stored but not injected into prompts. */
    enabled: boolean;
    /** Friendly label (e.g. "Acme Marketing"). */
    name: string;
    /** Tone descriptors (e.g. "confident, warm, plain-spoken"). */
    tone: string;
    /** Who the copy speaks to (e.g. "busy IT directors at mid-market SaaS"). */
    audience?: string;
    /** Free-form do/don't rules the model must follow. */
    guidelines?: string;
    /** Representative on-brand copy the model can pattern-match against. */
    sampleText?: string;
    updatedAt?: string;
    updatedBy?: string;
}
export interface AISettings {
    defaultProviderId?: string;
    defaultModelId?: string;
    defaultTextModelId?: string;
    defaultReasoningModelId?: string;
    defaultVisionModelId?: string;
    defaultEmbeddingModelId?: string;
    defaultImageGenerationModelId?: string;
    features: AIFeatureConfig[];
    budget: AIBudgetSettings;
    logsRetentionDays: number;
    /** Active brand voice. Absent until an admin configures it. */
    brandVoice?: BrandVoiceProfile;
}
/**
 * Cached, normalized model catalog keyed by provider connection id. Persisted in
 * the `__ai_config__` document so the model selector renders without a live call.
 */
export interface AICatalogEntry {
    models: AIModel[];
    lastSyncedAt: string;
    /** True when the entry came from the curated fallback (no live listing). */
    fromFallback: boolean;
}
/** Shape of the `data` blob on the `__ai_config__` Document. */
export interface AIConfigDocument {
    providers: AIProviderConnection[];
    settings: AISettings;
    catalog?: Record<string, AICatalogEntry>;
    updatedAt?: string;
    updatedBy?: string;
}
/** Monthly usage summary for the budget meter (real counts; 0 until Phase 4). */
export interface AIUsageSummary {
    totalTokens: number;
    promptTokens: number;
    completionTokens: number;
    estimatedCost?: number;
    monthlyTokenLimit?: number;
    periodStart: string;
    periodEnd: string;
    runCount: number;
}
/** Result of an adapter connection test. */
export interface AIConnectionTestResult {
    ok: boolean;
    status: AIConnectionStatus;
    /** Human-readable detail (safe to show; never contains the key). */
    message: string;
    testedAt: string;
}
//# sourceMappingURL=types.d.ts.map