// src/interfaces/ai-provider.ts
// Copyright (C) 2026 Rob Colbert <rob.colbert@openplatform.us>
// Licensed under the Apache License, Version 2.0

import { HydratedDocument } from "mongoose";
import { GadgetId } from "../lib/gadget-id.ts";

export type AiApiType = "ollama" | "openai";

/**
 * Normalised capability flags stored with each model record.  These are
 * populated during model refresh from provider-specific metadata and drive
 * slot-based filtering in the UI (e.g. only canCallTools models for Agent).
 */
export interface IAiModelSettings {
  temperature?: number;
  topP?: number;
  topK?: number;
  numCtx?: number;
  /** Ollama: maximum number of tokens to predict (-1 = unlimited, generate until natural stop or context limit) */
  numPredict?: number;
  /** OpenAI-compatible: maximum number of completion tokens the model can generate */
  maxCompletionTokens?: number;
}

export interface IAiModelCapabilities {
  /** Model supports structured function / tool calling via the API. */
  canCallTools: boolean;
  /** Model accepts image inputs (multimodal / vision). */
  hasVision: boolean;
  /** Model can produce vector embeddings (required for the Vector slot). */
  hasEmbedding: boolean;
  /** Model has an explicit reasoning / thinking phase (e.g. o1, QwQ). */
  hasThinking: boolean;
  /** Model is instruction-tuned / chat-tuned (as opposed to a base model). */
  isInstructTuned: boolean;
}

export interface IAiModel {
  id: string;
  name: string;
  /**
   * Raw parameter count in billions (float).  Use parameterLabel for display.
   */
  parameterCount?: number;
  /**
   * Human-readable parameter size label sourced directly from the provider,
   * e.g. "7b", "70b", "3.8b".
   */
  parameterLabel?: string;
  contextWindow?: number;
  capabilities: IAiModelCapabilities;
  settings?: IAiModelSettings;
}

export interface IAiProvider {
  _id: GadgetId;
  name: string;
  apiType: AiApiType;
  baseUrl: string;
  apiKey: string;
  enabled: boolean;
  models: IAiModel[];
  lastModelRefresh: Date;
}

export type AiProviderDocument = HydratedDocument<IAiProvider>;

/**
 * Drone-side model configuration that accepts the database IAiProvider type.
 * This is the canonical interface used by the drone to configure AI API calls,
 * carrying the model's stored inference settings (numCtx, numPredict, etc.)
 * from the provider's cached model data through to the AI package.
 */
export interface IDroneModelConfig {
  provider: IAiProvider | GadgetId;
  modelId: string;
  params: {
    reasoning: boolean | "low" | "medium" | "high";
    temperature: number;
    topP: number;
    topK: number;
    /** Ollama: -1 = unlimited (generate until natural stop or context limit) */
    numPredict: number;
    /** Context window size (input + output tokens); Ollama passes as num_ctx */
    numCtx: number;
    /** OpenAI-compatible: maximum completion tokens the model can generate */
    maxCompletionTokens: number;
  };
}
