UNPKG

@ts-dspy/gemini

Version:

Gemini API integration for TS-DSPy - enables type-safe LLM interactions with Gemini models for TypeScript

421 lines (317 loc) β€’ 12.5 kB
# @ts-dspy/gemini [![npm version](https://badge.fury.io/js/@ts-dspy%2Fgemini.svg)](https://badge.fury.io/js/@ts-dspy%2Fgemini) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) **Google Gemini API integration for TS-DSPy - enables type-safe LLM interactions with Gemini models for TypeScript applications.** This package provides seamless integration between TS-DSPy and Google's Gemini language models, allowing you to build powerful, type-safe applications with Gemini 2.0 Flash and other Gemini models. ## πŸš€ Features - **Full Gemini Support**: Works with Gemini 2.0 Flash, Gemini 1.0 Pro, and other Gemini models - **Type-Safe Integration**: Fully compatible with TS-DSPy signatures and modules - **Structured Output**: Built-in JSON schema support for structured responses - **Safety Settings**: Configurable content filtering and safety controls - **Error Handling**: Robust error handling with detailed feedback - **Flexible Configuration**: Support for all Gemini parameters - **Advanced Context**: Support for large context windows (32k+ tokens) ## πŸ“¦ Installation ```bash npm install @ts-dspy/gemini @ts-dspy/core # Install ts-node for proper execution (recommended) npm install -g ts-node ``` **⚠️ Important: Use `ts-node` to run TypeScript files directly. Transpiling to JavaScript may cause issues with decorators and type information.** ```bash # Run your scripts with ts-node npx ts-node your-script.ts # Or install globally and use directly npm install -g ts-node ts-node your-script.ts ``` ## πŸ”‘ Setup Get your Gemini API key from [Google AI Studio](https://makersuite.google.com/app/apikey). ```typescript import { GeminiLM } from '@ts-dspy/gemini'; const lm = new GeminiLM({ apiKey: process.env.GEMINI_API_KEY, // Your Gemini API key model: 'gemini-2.0-flash', // or 'gemini-1.0-pro', etc. }); ``` ## 🎯 Quick Start ### Basic Usage ```typescript import { Signature, InputField, OutputField, Predict, configure } from '@ts-dspy/core'; import { GeminiLM } from '@ts-dspy/gemini'; // Define your signature class Translator extends Signature { static description = "Translate text between languages"; @InputField({ description: "Text to translate" }) text!: string; @InputField({ description: "Target language" }) target_language!: string; @OutputField({ description: "Translated text" }) translation!: string; @OutputField({ description: "Confidence score from 0-1", type: "number" }) confidence!: number; } // Setup Gemini model configure({ lm: new GeminiLM({ apiKey: process.env.GEMINI_API_KEY, model: 'gemini-2.0-flash' }) }); // Create and use predictor const translator = new Predict(Translator); const result = await translator.forward({ text: "Hello, how are you?", target_language: "Spanish" }); console.log(result.translation); // "Hola, ΒΏcΓ³mo estΓ‘s?" console.log(result.confidence); // 0.95 ``` ### With Global Configuration ```typescript import { configure } from '@ts-dspy/core'; import { GeminiLM } from '@ts-dspy/gemini'; // Configure globally configure({ lm: new GeminiLM({ apiKey: process.env.GEMINI_API_KEY, model: 'gemini-2.0-flash' }) }); // Now you can use modules without passing the language model const predictor = new Predict("question -> answer"); ``` ## βš™οΈ Configuration Options ### Model Configuration ```typescript const lm = new GeminiLM({ // Required apiKey: 'your-api-key', // Model selection model: 'gemini-2.0-flash', // gemini-2.0-flash, gemini-1.0-pro, etc. }); // You can also set generation parameters through LLMCallOptions const result = await predictor.forward( { question: "What is AI?" }, { temperature: 0.7, // 0-1, controls creativity maxTokens: 1000, // Maximum tokens to generate topP: 0.9, // Nucleus sampling parameter stopSequences: ['END'], // Stop generation at these sequences } ); ``` ### Supported Models - **Gemini 2.0**: `gemini-2.0-flash` (latest and fastest) - **Gemini 1.0**: `gemini-1.0-pro` - **Legacy**: Other Gemini model variants ### Model Capabilities ```typescript const capabilities = lm.getCapabilities(); console.log(capabilities); // { // supportsStreaming: false, // supportsStructuredOutput: true, // supportsFunctionCalling: false, // supportsVision: false, // maxContextLength: 32768, // supportedFormats: ['json_object'] // } ``` ## πŸ“Š Structured Output Gemini excels at generating structured JSON responses: ```typescript import { Signature, InputField, OutputField } from '@ts-dspy/core'; class ProductAnalysis extends Signature { @InputField({ description: "Product description" }) description!: string; @OutputField({ description: "Product category" }) category!: string; @OutputField({ description: "Price range", type: "string" }) priceRange!: 'budget' | 'mid-range' | 'premium'; @OutputField({ description: "Key features as array", type: "array" }) features!: string[]; @OutputField({ description: "Sentiment score", type: "number" }) sentiment!: number; } const analyzer = new Predict(ProductAnalysis); const result = await analyzer.forward({ description: "Latest smartphone with AI camera, long battery life, and premium design" }); console.log(result.category); // "Electronics" console.log(result.priceRange); // "premium" console.log(result.features); // ["AI camera", "long battery", "premium design"] console.log(result.sentiment); // 0.8 ``` ## πŸ›‘οΈ Safety and Content Filtering Gemini includes built-in safety settings to filter harmful content: ```typescript // The GeminiLM automatically configures safety settings // Default: BLOCK_MEDIUM_AND_ABOVE for harassment // If content is blocked, you'll receive a descriptive error: try { const result = await predictor.forward({ question: "Inappropriate content..." }); } catch (error) { if (error.message.includes('blockReason')) { console.log('Content was blocked by Gemini safety filters'); // Handle content filtering gracefully } } ``` ## 🎨 Advanced Usage ### Chain of Thought Reasoning ```typescript import { ChainOfThought } from '@ts-dspy/core'; const reasoner = new ChainOfThought("problem -> solution: int"); const result = await reasoner.forward({ problem: "A store sells apples for $2 each and oranges for $3 each. If someone buys 4 apples and 3 oranges, how much do they pay in total?" }); console.log(result.reasoning); // "First, calculate apples: 4 Γ— $2 = $8..." console.log(result.solution); // 17 ``` ### ReAct Pattern with Tools ```typescript import { RespAct } from '@ts-dspy/core'; const agent = new RespAct("question -> answer", { tools: { calculate: { description: "Performs mathematical calculations including arithmetic operations. Use this when you need to compute numerical results.", function: (expression: string) => { try { return new Function('return ' + expression)(); } catch (error) { return `Error: ${error}`; } } }, convertCurrency: { description: "Converts between currencies. Provide amount and currency codes (e.g., '100 USD to EUR').", function: async (query: string) => { // Implementation would call a currency API return "Converted amount: ..."; } } }, maxSteps: 5 }); const result = await agent.forward({ question: "What is 15 * 24 + 100 - 50 in USD converted to EUR?" }); ``` ### Sentiment Analysis Example ```typescript class SentimentAnalysis extends Signature { @InputField({ description: "Text to analyze for sentiment" }) text!: string; @OutputField({ description: "Sentiment classification" }) sentiment!: 'positive' | 'negative' | 'neutral'; @OutputField({ description: "Confidence score between 0 and 1" }) confidence!: number; @OutputField({ description: "Key emotional indicators found" }) emotions!: string[]; static description = "Analyze the sentiment and emotions in the given text"; } const classifier = new Predict(SentimentAnalysis); const result = await classifier.forward({ text: "I absolutely love this new framework! It's incredibly powerful and easy to use." }); console.log(result.sentiment); // "positive" console.log(result.confidence); // 0.92 console.log(result.emotions); // ["love", "enthusiasm", "satisfaction"] ``` ## πŸ”„ Chat and Conversation ```typescript // Multi-turn conversations const chatModel = new GeminiLM({ apiKey: process.env.GEMINI_API_KEY, model: 'gemini-2.0-flash' }); const messages = [ { role: 'user', content: 'Hello! What is TypeScript?' }, { role: 'assistant', content: 'TypeScript is a superset of JavaScript...' }, { role: 'user', content: 'How does it help with large applications?' } ]; const response = await chatModel.chat(messages); console.log(response); ``` ## πŸ›‘οΈ Error Handling Comprehensive error handling for Gemini-specific issues: ```typescript try { const result = await predictor.forward({ question: "Complex question" }); } catch (error) { if (error.message.includes('blockReason')) { console.log('Content blocked by safety filters'); // Try rephrasing the question } else if (error.message.includes('API key')) { console.log('Invalid or missing API key'); // Check your API key configuration } else if (error.message.includes('quota')) { console.log('API quota exceeded'); // Implement retry with backoff } else { console.log('Unexpected error:', error.message); } } ``` ## πŸ“ˆ Usage Tracking Note: Gemini API currently doesn't provide detailed token usage statistics through the SDK: ```typescript const lm = new GeminiLM({ apiKey: process.env.GEMINI_API_KEY, model: 'gemini-2.0-flash' }); // Make some predictions const predictor = new Predict("question -> answer", lm); await predictor.forward({ question: "What is AI?" }); // Get usage statistics (currently limited) const usage = lm.getUsage(); console.log(`Requests made: ${usage.requestCount || 'Not available'}`); console.log('Note: Detailed token usage not yet available in Gemini API'); ``` ## πŸ†š Gemini vs OpenAI Comparison | Feature | Gemini | OpenAI | |---------|--------|--------| | **Models** | Gemini 2.0 Flash, 1.0 Pro | GPT-4, GPT-3.5-turbo | | **Context Length** | 32k+ tokens | 8k-128k tokens | | **Structured Output** | βœ… Native JSON | βœ… JSON mode | | **Streaming** | ❌ Not yet supported | βœ… Full support | | **Function Calling** | βœ… Full support | βœ… Full support | | **Safety Filtering** | βœ… Built-in | ⚠️ Moderation API | | **Cost** | Generally lower | Higher for advanced models | | **Speed** | Very fast (Flash model) | Variable by model | ## πŸ”§ Troubleshooting ### Common Issues 1. **API Key Issues** ```bash # Set your API key export GEMINI_API_KEY="your-key-here" ``` 2. **Content Blocked** - Gemini has strict safety filters - Try rephrasing sensitive queries - Check the error message for specific block reasons 3. **Model Not Found** - Ensure you're using supported model names - Check [Google AI Studio](https://makersuite.google.com/) for available models 4. **Rate Limiting** - Implement exponential backoff - Check your API quotas in Google Cloud Console ## πŸ“š More Examples Check out the complete examples in the [TS-DSPy repository](https://github.com/ardada2468/LLMTypeSafe/tree/main/examples): - `basic-gemini-example.ts` - Comprehensive usage examples - Integration with other TS-DSPy modules - Real-world application patterns ## 🀝 Contributing Contributions are welcome! Please see the main [TS-DSPy repository](https://github.com/ardada2468/LLMTypeSafe) for contribution guidelines. ## πŸ“„ License MIT License - see the [LICENSE](../../LICENSE) file for details. ## πŸ”— Related Packages - [`@ts-dspy/core`](https://www.npmjs.com/package/@ts-dspy/core) - Core TS-DSPy framework - [`@ts-dspy/openai`](https://www.npmjs.com/package/@ts-dspy/openai) - OpenAI integration ## πŸ†˜ Support - πŸ“– [Documentation](https://github.com/ardada2468/LLMTypeSafe#readme) - πŸ› [Issue Tracker](https://github.com/ardada2468/LLMTypeSafe/issues) - πŸ’¬ [Discussions](https://github.com/ardada2468/LLMTypeSafe/discussions) --- **Made with ❀️ for the TypeScript + AI community**