UNPKG

pulse-ai-utils

Version:

Utility functions and helpers for AI-powered applications

227 lines (226 loc) 7.93 kB
import OpenAI from 'openai'; import { z, ZodTypeAny } from 'zod'; import QueryCache from './query-cache'; import { VectorSearchOptions, ContentSearchResult } from '../supabase/vector-search'; export interface LLMConfig { model: string; apiKey?: string; baseURL?: string; headers?: Record<string, string>; } export declare abstract class LLMBase { protected openai: OpenAI; protected defaultModel: string; protected cache: QueryCache; constructor(config: LLMConfig, openaiInstance?: OpenAI, cache?: QueryCache); protected abstract createOpenAIInstance(config: LLMConfig): OpenAI; protected getApiKey(): string; protected abstract getProviderName(): string; protected isTestMode(): boolean; get model(): string; get client(): OpenAI; protected parseModelResponse<T extends ZodTypeAny>(response: any, zodSchema: T): z.infer<T>; protected enhanceWithImages(items: any[], responseFormatName: string): Promise<void>; fetchStructuredDataFromWeb<T extends ZodTypeAny>({ model, prompt, recommendedSources, zodSchema, userLocation, locationGranularity, systemPrompt, timeline, responseFormatName, customFormat, options }: { model?: string; prompt: string; recommendedSources?: string[]; zodSchema: T; userLocation: any; locationGranularity: string; systemPrompt?: string; timeline?: string; responseFormatName?: string; customFormat?: (schema: ZodTypeAny, name: string) => any; options?: Record<string, any>; }): Promise<z.infer<T>>; fetchStructuredData<T extends ZodTypeAny>({ model, prompt, html, zodSchema, responseFormatName, }: { model?: string; prompt: string; html: string; zodSchema: T; responseFormatName?: string; }): Promise<z.infer<T>>; runQuery({ prompt, categories, systemPrompt, model, area, source, country, region, category, timeline, strategy, options }: { prompt?: string; categories?: string[]; systemPrompt?: string; model?: string; area?: string; source?: string; country?: string; region?: string; category?: string; timeline?: string; strategy?: 'web_search' | 'rag_vector' | 'rag_cache' | 'rag_hybrid' | 'query_cache' | 'vector_only' | 'hybrid_only'; options?: Record<string, any>; }): Promise<any>; /** * Search content using vector similarity from Supabase * This replaces Pinecone functionality with Supabase pgvector */ searchContentVectors(query: string, options?: Partial<VectorSearchOptions>): Promise<ContentSearchResult[]>; /** * Search content chunks for longer documents */ searchChunks(query: string, limit?: number, threshold?: number): Promise<any[]>; /** * Hybrid search combining vector and full-text search */ hybridContentSearch(query: string, options?: { vectorWeight?: number; textWeight?: number; limit?: number; filters?: VectorSearchOptions['filters']; }): Promise<ContentSearchResult[]>; /** * Generate embedding for a given text * Used for custom vector operations */ generateEmbedding(text: string): Promise<number[]>; /** * Search and format results based on categories */ searchAndFormat(query: string, categories?: string[], area?: string, limit?: number): Promise<any>; /** * Query with RAG (Retrieval Augmented Generation) * Combines vector search context with LLM generation */ queryWithContext({ query, systemPrompt, categories, searchOptions, model, useHybridSearch, contextLimit }: { query: string; systemPrompt?: string; categories?: string[]; searchOptions?: Partial<VectorSearchOptions>; model?: string; useHybridSearch?: boolean; contextLimit?: number; }): Promise<{ response: string; context: ContentSearchResult[]; }>; /** * Generate embeddings and search in one call (convenience method) */ semanticSearch(query: string, options?: { categories?: string[]; limit?: number; threshold?: number; useCache?: boolean; }): Promise<ContentSearchResult[]>; /** * Live web search with LLM processing (separate from RAG) * This method is designed to be called independently for real-time web data */ liveWebSearch<T extends ZodTypeAny>({ query, categories, area, region, country, timeline, zodSchema, responseFormatName, model, systemPrompt }: { query: string; categories?: string[]; area: string; region?: string; country?: string; timeline?: string; zodSchema?: T; responseFormatName?: string; model?: string; systemPrompt?: string; }): Promise<{ data: T extends ZodTypeAny ? z.infer<T> : any; source: 'web_search'; executionTime: number; metadata: { searchQuery: string; area: string; categories: string[]; }; }>; /** * Execute waterfall strategy with automatic fallback and rag_level ceiling */ executeWaterfallStrategy({ strategy, prompt, area, region, country, timeline, category, enableFallbacks, maxFallbacks, systemPrompt, options }: { strategy: 'query_cache' | 'rag_cache' | 'rag_vector' | 'rag_hybrid' | 'web_search_llm'; prompt: string; area?: string; region?: string; country?: string; timeline?: string; category?: string; enableFallbacks?: boolean; maxFallbacks?: number; systemPrompt?: string; options?: Record<string, any>; }): Promise<{ success: boolean; data: any[]; source: string; strategy: string; originalStrategy?: string; fallbackUsed?: string; fallbackChain: string[]; timing: { primary_ms: number; fallback_ms: number; total_ms: number; }; meta: { original_count: number; flyer_count: number; total_items: number; cache_hit: boolean; }; timestamp: string; }>; /** * Get RAG level ceiling from remote config */ private getRagLevel; /** * Infer timeline from query text */ private inferTimelineFromQuery; /** * Enhanced parallel execution using waterfall strategies * Returns fastest cache + web search results in parallel */ executeParallelSearch({ prompt, area, region, country, timeline, category, enableFallbacks, systemPrompt }: { prompt: string; area?: string; region?: string; country?: string; timeline?: string; category?: string; enableFallbacks?: boolean; systemPrompt?: string; }): Promise<{ success: boolean; cache: any; webSearch: any; timing: { total_ms: number; cache_completed: boolean; web_completed: boolean; }; timestamp: string; }>; /** * Legacy parallel execution (kept for backwards compatibility) * Returns results as they become available for better UX */ parallelSearch({ query, area, region, country, timeline, categories, zodSchema, includeWebSearch, model }: { query: string; area: string; region?: string; country?: string; timeline?: string; categories?: string[]; zodSchema?: ZodTypeAny; includeWebSearch?: boolean; model?: string; }): Promise<{ rag: any; webSearch?: any; timing: { ragTime: number; webSearchTime: number; totalTime: number; }; }>; }