UNPKG

pulse-ai-utils

Version:

Utility functions and helpers for AI-powered applications

247 lines (179 loc) 8.3 kB
# Pulse AI Utils A powerful TypeScript library for AI-powered applications with multi-provider LLM support. Provides unified interfaces for OpenAI, Gemini, Claude, and 100+ models via OpenRouter. ## Features - 🤖 **Multi-Provider Support**: OpenAI, Gemini, Claude, and 100+ models - 🔄 **Unified Interface**: Same API for all providers - 🔑 **BYOK Support**: Bring Your Own Key for provider-specific APIs - 📊 **Structured Data**: Built-in Zod schema validation - 🌐 **Web Search**: AI-powered web queries with caching - 🎯 **Type-Safe**: Full TypeScript support with proper types ## Installation ```bash npm install pulse-ai-utils ``` ## 🚀 Quick Start ```typescript import { OpenAIHelper, OpenRouter } from 'pulse-ai-utils'; // Auto-loads API keys from your .env file const openai = new OpenAIHelper(); // Uses OPENAI_API_KEY from .env // Auto-loads keys for different providers const gemini = OpenRouter.forGemini(); // Uses OPENROUTER_API_KEY + GEMINI_API_KEY from .env const claude = OpenRouter.forClaude(); // Uses OPENROUTER_API_KEY + CLAUDE_API_KEY from .env // Use remote config for dynamic model selection (recommended) const smartOpenai = await OpenAIHelper.createWithRemoteConfig(); const smartGemini = await OpenRouter.forGeminiWithRemoteConfig(); const webOptimized = await OpenRouter.createForWebFetching(); // Or pass keys explicitly if needed const customOpenai = new OpenAIHelper('your-openai-key'); const customGemini = OpenRouter.forGemini('openrouter-key', 'gemini-key'); ``` ### Environment Configuration The library automatically reads API keys from your project's root `.env` file. Simply create a `.env` file in your project root: ```bash # .env file in your project root OPENAI_API_KEY=your-openai-key OPENROUTER_API_KEY=your-openrouter-key GEMINI_API_KEY=your-gemini-key CLAUDE_API_KEY=your-claude-key ``` **No need to call `dotenv.config()`** - the library handles this automatically! ### Remote Configuration (Firebase Remote Config) The library also supports dynamic model selection via Firebase Remote Config. This allows you to change models without code deployments: ```bash # Firebase Remote Config Parameters (optional) pulse-ai-util-openai-model=gpt-4o # OpenAI model selection pulse-ai-util-openrouter-model=google/gemini-2.0-flash-exp # OpenRouter model pulse-ai-util-gemini-model=google/gemini-2.0-flash-exp # Gemini-specific model pulse-ai-web-openrouter-model=claude-3-5-sonnet-20241022 # Optimized for web fetching ``` These remote config values take precedence over environment variables, providing dynamic configuration capabilities. #### Required Environment Variables At least one of these is required: ```bash OPENAI_API_KEY=your-openai-key # For direct OpenAI access OPENROUTER_API_KEY=your-openrouter-key # For multi-provider access via OpenRouter ``` #### Optional Environment Variables ```bash # Provider-specific keys for BYOK (Bring Your Own Key) GEMINI_API_KEY=your-gemini-key # Google AI Studio key CLAUDE_API_KEY=your-claude-key # Anthropic Claude key # Model Selection (optional - smart defaults provided) OPENROUTER_MODEL=google/gemini-2.0-flash-exp # Default OpenRouter model GEMINI_MODEL=google/gemini-2.0-flash-exp # Default Gemini model # Optional Configuration OPENROUTER_BASE_URL=https://openrouter.ai/api/v1 # Custom OpenRouter URL LLM_CACHE_DB_ID=llmCache # Firestore cache collection ``` ## Usage ### LLMQueryHandler Fetch arbitrary structured data using web search. ```typescript import { LLMQueryHandler } from 'pulse-ai-utils'; const queryHandler = new LLMQueryHandler('your-api-key'); // Use in an Express route app.post('/llm-query', (req, res) => queryHandler.query(req, res)); ``` ## 🤖 LLM Providers ### OpenAI Helper - Direct OpenAI API ```typescript import { OpenAIHelper } from 'pulse-ai-utils'; // Auto-loads from OPENAI_API_KEY env var, or pass explicitly const openai = new OpenAIHelper(undefined, undefined, 'gpt-4o'); // Or with explicit key: new OpenAIHelper('your-api-key', undefined, 'gpt-4o'); // 🌟 Recommended: Use remote config for dynamic model selection const smartOpenai = await OpenAIHelper.createWithRemoteConfig(); // Update model from remote config for long-running processes await openai.updateModelFromRemoteConfig(); // Fetch structured data from the web const result = await openai.fetchStructuredDataFromWeb({ prompt: 'Find upcoming tech events in San Francisco', zodSchema: yourZodSchema, userLocation: { type: 'approximate', country: 'US', region: 'CA', city: 'San Francisco' }, locationGranularity: 'city', }); // Get available OpenAI models const models = await openai.getAvailableModels(); // Returns: ['gpt-4o', 'gpt-4', 'gpt-3.5-turbo', ...] ``` ### OpenRouter - Universal Multi-Provider Access Access 100+ models from multiple providers through a unified interface: ```typescript import { OpenRouter } from 'pulse-ai-utils'; // Auto-loads from environment variables (.env file) const router = new OpenRouter(); // Factory methods auto-load from .env - no keys needed! const gemini = OpenRouter.forGemini(); // Uses OPENROUTER_API_KEY + GEMINI_API_KEY const claude = OpenRouter.forClaude(); // Uses OPENROUTER_API_KEY + CLAUDE_API_KEY const gpt = OpenRouter.forGPT(); // Uses OPENROUTER_API_KEY // 🌟 Recommended: Use remote config for dynamic model selection const smartRouter = await OpenRouter.createWithRemoteConfig(); const smartGemini = await OpenRouter.forGeminiWithRemoteConfig(); const webOptimized = await OpenRouter.createForWebFetching(); // Uses pulse-ai-web-openrouter-model // Update model from remote config for long-running processes await router.updateModelFromRemoteConfig(); await router.updateModelFromRemoteConfig(true); // Use web-optimized model // Or pass keys explicitly if needed const customGemini = OpenRouter.forGemini('openrouter-key', 'gemini-key'); const customClaude = OpenRouter.forClaude('openrouter-key', 'claude-key'); // Get available models with provider info const models = await router.getAvailableModels(); // Returns: [ // { id: 'google/gemini-2.0-flash-exp', name: 'Gemini 2.0 Flash', provider: 'Google' }, // { id: 'anthropic/claude-3.5-sonnet', name: 'Claude 3.5 Sonnet', provider: 'Anthropic' }, // ... // ] ``` ### Model Selection Guide ```typescript // 🌟 Best: Remote config with dynamic model selection (recommended) const smartOpenai = await OpenAIHelper.createWithRemoteConfig(); const smartGemini = await OpenRouter.forGeminiWithRemoteConfig(); const webOptimized = await OpenRouter.createForWebFetching(); // Special web-optimized model // ✅ Good: Environment variables (auto-loads from .env) const openai = new OpenAIHelper(); const gemini = OpenRouter.forGemini(); const claude = OpenRouter.forClaude(); // ✅ Fallback: Explicit configuration const customGemini = OpenRouter.forGemini(undefined, undefined, 'google/gemini-2.0-flash-exp'); const customClaude = OpenRouter.forClaude(undefined, undefined, 'anthropic/claude-3.5-sonnet'); ``` ### Remote Config Priority Order 1. **Firebase Remote Config** (highest priority) - `pulse-ai-util-*-model` 2. **Environment Variables** (.env file) - `OPENAI_MODEL`, `OPENROUTER_MODEL`, etc. 3. **Default Values** (fallback) - `gpt-4o`, `google/gemini-2.0-flash-exp`, etc. ### Utility Functions ```typescript import { getSchemaByCategory, sanitizeId, zodToJsonSchema } from 'pulse-ai-utils'; // Get schema for a category const schema = getSchemaByCategory('events'); // Sanitize an ID const cleanId = sanitizeId('https://example.com/path/'); // Result: 'example.com-path' // Convert Zod schema to JSON schema const jsonSchema = zodToJsonSchema(myZodSchema); ``` ## License 0BSD ## Versioning and Publishing To release a new version of this package: 1. Open `package.json` in this directory and update the `version` field to the desired version tag (for example, `"3.4.1"`). 2. In your terminal, ensure you're in this directory: ```bash cd lib ``` 3. Build and publish to npm: ```bash npm run build npm publish ``` Your new version will be published under the `latest` tag on npm.