UNPKG

@juspay/neurolink

Version:

The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002

350 lines (349 loc) • 11.1 kB
/** * Model-related type definitions for NeuroLink * Consolidates all model configuration, dynamic model, and provider model types */ import { z } from "zod"; import type { JsonValue } from "./common.js"; import { AIProviderName } from "../constants/enums.js"; import type { TaskType } from "./taskClassification.js"; /** * Model performance tier definition */ export type ModelTier = "fast" | "balanced" | "quality"; /** * Model configuration source type */ export type ConfigSource = "default" | "environment" | "file" | "dynamic"; /** * Model configuration for a specific provider */ export type ModelConfig = { /** Model identifier */ id: string; /** Display name */ name: string; /** Performance tier */ tier: ModelTier; /** Cost per 1K tokens */ cost: { input: number; output: number; }; /** Model capabilities */ capabilities: string[]; /** Model-specific options */ options?: Record<string, JsonValue>; }; /** * Provider configuration for model management */ export type ProviderConfiguration = { /** Provider name */ provider: string; /** Available models by tier */ models: Record<ModelTier, string>; /** Default cost per token (fallback) */ defaultCost: { input: number; output: number; }; /** Required environment variables */ requiredEnvVars: string[]; /** Provider-specific performance metrics */ performance: { speed: number; quality: number; cost: number; }; /** Provider-specific model configurations */ modelConfigs?: Record<string, ModelConfig>; /** Provider-specific model behavior configurations */ modelBehavior?: { /** Models that have issues with maxTokens parameter */ maxTokensIssues?: string[]; /** Models that require special handling */ specialHandling?: Record<string, JsonValue>; /** Models that support tool calling (Ollama-specific) */ toolCapableModels?: string[]; }; }; /** * Zod schema for model configuration validation */ export declare const ModelConfigSchema: z.ZodObject<{ id: z.ZodString; displayName: z.ZodString; capabilities: z.ZodArray<z.ZodString>; deprecated: z.ZodBoolean; pricing: z.ZodObject<{ input: z.ZodNumber; output: z.ZodNumber; }, z.core.$strip>; contextWindow: z.ZodNumber; releaseDate: z.ZodString; }, z.core.$strip>; /** * Zod schema for model registry validation */ export declare const ModelRegistrySchema: z.ZodObject<{ version: z.ZodString; lastUpdated: z.ZodString; models: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodObject<{ id: z.ZodString; displayName: z.ZodString; capabilities: z.ZodArray<z.ZodString>; deprecated: z.ZodBoolean; pricing: z.ZodObject<{ input: z.ZodNumber; output: z.ZodNumber; }, z.core.$strip>; contextWindow: z.ZodNumber; releaseDate: z.ZodString; }, z.core.$strip>>>; aliases: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>; defaults: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>; }, z.core.$strip>; /** * Dynamic model configuration type */ export type DynamicModelConfig = z.infer<typeof ModelConfigSchema>; /** * Dynamic model registry type */ export type ModelRegistry = z.infer<typeof ModelRegistrySchema>; /** * What a request should carry in place of `thinking: {type: "disabled"}` for a * Claude model: the original (`keep`), `between_tools`, or no `thinking` field * at all (`omit`, i.e. adaptive). */ export type ClaudeDisabledThinkingReplacement = "keep" | "between_tools" | "omit"; /** * Model capabilities interface */ export type ModelCapabilities = { vision: boolean; functionCalling: boolean; codeGeneration: boolean; reasoning: boolean; multimodal: boolean; streaming: boolean; jsonMode: boolean; /** * Whether the model accepts classic sampling parameters * (`temperature` / `topP`). Reasoning-effort models (Claude Sonnet 5, * Opus 4.7+, Fable 5 families) reject them. Optional: unset means * supported, and `modelSupportsSamplingParams` falls back to the known * family patterns. */ samplingParams?: boolean; }; /** * Model pricing information */ export type ModelPricingInfo = { inputCostPer1K: number; outputCostPer1K: number; currency: string; }; /** * Model performance characteristics */ export type ModelPerformance = { speed: "fast" | "medium" | "slow"; quality: "high" | "medium" | "low"; accuracy: "high" | "medium" | "low"; }; /** * Model limitations and constraints */ export type ModelLimits = { maxContextTokens: number; maxOutputTokens: number; maxRequestsPerMinute?: number; maxRequestsPerDay?: number; }; /** * Use case suitability scores (1-10 scale) */ export type UseCaseSuitability = { coding: number; creative: number; analysis: number; conversation: number; reasoning: number; translation: number; summarization: number; }; /** * Complete model information */ export type ModelInfo = { id: string; name: string; provider: AIProviderName; description: string; capabilities: ModelCapabilities; pricing: ModelPricingInfo; performance: ModelPerformance; limits: ModelLimits; useCases: UseCaseSuitability; aliases: string[]; deprecated: boolean; isLocal: boolean; releaseDate?: string; category: "general" | "coding" | "creative" | "vision" | "reasoning"; }; /** * Model search filters */ export type ModelSearchFilters = { provider?: AIProviderName | AIProviderName[]; capability?: keyof ModelCapabilities | (keyof ModelCapabilities)[]; useCase?: keyof UseCaseSuitability; maxCost?: number; minContextSize?: number; maxContextSize?: number; performance?: ModelPerformance["speed"] | ModelPerformance["quality"]; category?: ModelInfo["category"] | ModelInfo["category"][]; }; /** * Model search result with ranking */ export type ModelSearchResult = { model: ModelInfo; score: number; matchReasons: string[]; }; /** * Model recommendation context */ export type RecommendationContext = { useCase?: keyof UseCaseSuitability; maxCost?: number; minQuality?: "low" | "medium" | "high"; requireCapabilities?: (keyof ModelCapabilities)[]; excludeProviders?: AIProviderName[]; contextSize?: number; preferLocal?: boolean; }; /** * Model recommendation result */ export type ModelRecommendation = { model: ModelInfo; score: number; reasoning: string[]; alternatives: ModelInfo[]; }; /** * Model comparison result */ export type ModelComparison = { models: ModelInfo[]; comparison: { capabilities: Record<keyof ModelCapabilities, ModelInfo[]>; pricing: { cheapest: ModelInfo; mostExpensive: ModelInfo; }; performance: Record<string, ModelInfo[]>; contextSize: { largest: ModelInfo; smallest: ModelInfo; }; }; }; export type ModelRoute = { provider: string; model: string; reasoning: string; confidence: number; }; export type ModelRoutingOptions = { /** Override the task classification */ forceTaskType?: TaskType; /** Require specific performance characteristics */ requireFast?: boolean; /** Require specific capability (reasoning, creativity, etc.) */ requireCapability?: string; /** Fallback strategy if primary choice fails */ fallbackStrategy?: "fast" | "reasoning" | "auto"; }; /** * A single model's metadata inside a provider's manifest. This is the one * canonical shape every model-metadata consumer (context windows, pricing, * MODEL_REGISTRY, vision capability, output-token ceilings) reads from — * contextWindows.ts, pricing.ts, modelRegistry.ts, providerImageAdapter.ts and * core/constants.ts. * * `pricingPerMTok` is optional by design: a model with no verified price * (e.g. a just-announced model pricing.ts hasn't priced yet) must not report * a fabricated rate. Absence here means "unknown", not "free" — callers that * need to distinguish "free" from "unknown" already have `hasPricing()` * (src/lib/utils/pricing.ts) for that. */ export type ProviderModelManifestEntry = { /** Alternate identifiers that resolve to this canonical model id. */ aliases: string[]; /** Human-readable name. Falls back to a mechanical id-derived name when absent. */ displayName?: string; contextWindow: number; maxOutputTokens: number; pricingPerMTok?: { input: number; output: number; cacheRead?: number; cacheWrite?: number; }; vision: boolean; nativeAudio?: boolean; functionCalling: boolean; reasoning?: boolean; jsonMode?: boolean; /** * Whether the model accepts classic sampling parameters (temperature/topP). * Mirrors ModelCapabilities.samplingParams (src/lib/types/model.ts:131) — * unset means supported. */ samplingParams?: boolean; /** * Hand-tuned ModelInfo.performance/useCases/category values, carried * forward verbatim for the ids that already had a MODEL_REGISTRY entry * before this migration. Absent for every id that never had one — those * get performance/useCases/category derived mechanically instead (see * buildManifestDerivedEntries in src/lib/models/modelRegistry.ts). Never * populate this for a genuinely new model: mechanical derivation is the * correct default, and a fabricated "curated" value would be worse than an * honestly-derived one. */ curated?: { performance?: ModelPerformance; useCases?: UseCaseSuitability; category?: ModelInfo["category"]; }; }; /** * A regex-driven patch applied to an unlisted, gateway-shaped model id that * matches `pattern` (e.g. "vertex_ai/claude-sonnet-5@20260203"). Generalizes * the pattern VISION_FAMILY_RULES (src/lib/adapters/providerImageAdapter.ts) * and SAMPLING_PARAM_REJECTING_FAMILIES (src/lib/models/modelRegistry.ts) * already use independently, keyed per-provider instead of globally. */ export type ManifestFamilyRule = { pattern: RegExp; patch: Partial<ProviderModelManifestEntry>; }; /** * One provider's complete model manifest: every model NeuroLink knows about * for that provider, plus the provider-wide fallback used when a caller * passes a model id the manifest has never seen (a symbolic/local provider * model, or a brand-new release the manifest hasn't been updated for yet). */ export type ProviderModelManifest = { /** Used for `_default`-key lookups and providers with no named-model list. */ defaultContextWindow: number; /** Applied, in order, to the resolved entry (see manifestRegistry.ts). */ familyRules?: ManifestFamilyRule[]; /** Keyed by canonical model id (the same id `ModelInfo.id` / AIProvider calls use). */ models: Record<string, ProviderModelManifestEntry>; };