125 lines
3.6 KiB
TypeScript
125 lines
3.6 KiB
TypeScript
// src/models/ai-provider.ts
|
|
// Copyright (C) 2025 DTP Technologies, LLC
|
|
// All Rights Reserved
|
|
|
|
import { Schema, Document, model } from "mongoose";
|
|
|
|
export type ApiType = "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;
|
|
}
|
|
|
|
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 const AiModelCapabilitiesSchema = new Schema<IAiModelCapabilities>(
|
|
{
|
|
canCallTools: { type: Boolean, default: false },
|
|
hasVision: { type: Boolean, default: false },
|
|
hasEmbedding: { type: Boolean, default: false },
|
|
hasThinking: { type: Boolean, default: false },
|
|
isInstructTuned: { type: Boolean, default: false },
|
|
},
|
|
{ _id: false },
|
|
);
|
|
|
|
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 const AiModelSettingsSchema = new Schema<IAiModelSettings>(
|
|
{
|
|
temperature: { type: Number },
|
|
topP: { type: Number },
|
|
topK: { type: Number },
|
|
numCtx: { type: Number },
|
|
},
|
|
{ _id: false },
|
|
);
|
|
|
|
export const AiModelSchema = new Schema<IAiModel>(
|
|
{
|
|
id: { type: String, required: true },
|
|
name: { type: String, required: true },
|
|
parameterCount: { type: Number },
|
|
parameterLabel: { type: String },
|
|
contextWindow: { type: Number },
|
|
capabilities: {
|
|
type: AiModelCapabilitiesSchema,
|
|
default: () => ({
|
|
canCallTools: false,
|
|
hasVision: false,
|
|
hasEmbedding: false,
|
|
hasThinking: false,
|
|
isInstructTuned: false,
|
|
}),
|
|
},
|
|
settings: {
|
|
type: AiModelSettingsSchema,
|
|
default: undefined,
|
|
},
|
|
},
|
|
{ _id: false },
|
|
);
|
|
|
|
export interface IAiProvider extends Document {
|
|
name: string;
|
|
apiType: ApiType;
|
|
baseUrl: string;
|
|
apiKey: string;
|
|
enabled: boolean;
|
|
models: IAiModel[];
|
|
lastModelRefresh: Date;
|
|
}
|
|
|
|
export const AiProviderSchema = new Schema<IAiProvider>({
|
|
name: { type: String, required: true },
|
|
apiType: { type: String, enum: ["ollama", "openai"], required: true },
|
|
baseUrl: { type: String, required: true },
|
|
apiKey: { type: String, required: true, select: false },
|
|
enabled: { type: Boolean, default: true, required: true },
|
|
models: { type: [AiModelSchema], default: [], required: true },
|
|
lastModelRefresh: { type: Date, default: Date.now },
|
|
});
|
|
|
|
AiProviderSchema.index({ name: 1 }, { unique: true });
|
|
|
|
export const AiProvider = model<IAiProvider>("AiProvider", AiProviderSchema);
|
|
export default AiProvider;
|
|
|
|
// Note: Index synchronization is now handled during application startup
|
|
// to ensure the database connection is established first.
|
|
// See src/lib/db.ts for the syncDatabaseIndexes function.
|