{"id":34639885,"url":"https://github.com/projectsaturnstudios/llm-speak-gemini","last_synced_at":"2026-06-01T07:31:52.865Z","repository":{"id":304648627,"uuid":"1012552383","full_name":"projectsaturnstudios/llm-speak-gemini","owner":"projectsaturnstudios","description":"A Laravel package for integrating Google Gemini into LLMSpeak","archived":false,"fork":false,"pushed_at":"2025-07-31T19:06:29.000Z","size":39,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-13T06:31:56.561Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/projectsaturnstudios.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-02T14:01:37.000Z","updated_at":"2025-07-31T19:06:21.000Z","dependencies_parsed_at":"2025-07-14T13:59:00.999Z","dependency_job_id":"07e46d62-d251-440d-9cce-42ed04f9d64d","html_url":"https://github.com/projectsaturnstudios/llm-speak-gemini","commit_stats":null,"previous_names":["projectsaturnstudios/llm-speak-gemini"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/projectsaturnstudios/llm-speak-gemini","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/projectsaturnstudios%2Fllm-speak-gemini","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/projectsaturnstudios%2Fllm-speak-gemini/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/projectsaturnstudios%2Fllm-speak-gemini/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/projectsaturnstudios%2Fllm-speak-gemini/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/projectsaturnstudios","download_url":"https://codeload.github.com/projectsaturnstudios/llm-speak-gemini/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/projectsaturnstudios%2Fllm-speak-gemini/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33765378,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-24T17:15:42.790Z","updated_at":"2026-06-01T07:31:52.851Z","avatar_url":"https://github.com/projectsaturnstudios.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LLMSpeak Google Gemini\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![PHP](https://img.shields.io/badge/PHP-8.2%2B-blue.svg)](https://php.net/releases/)\n[![Laravel](https://img.shields.io/badge/Laravel-10.x%7C11.x%7C12.x-red.svg)](https://laravel.com)\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/llm-speak/google-gemini.svg?style=flat-square)](https://packagist.org/packages/llm-speak/google-gemini)\n[![Total Downloads](https://img.shields.io/packagist/dt/llm-speak/google-gemini.svg?style=flat-square)](https://packagist.org/packages/llm-speak/google-gemini)\n\n**LLMSpeak Google Gemini** is a Laravel package that provides a fluent, Laravel-native interface for integrating with Google's Gemini AI models. Built as part of the LLMSpeak ecosystem, it offers seamless integration with Laravel applications through automatic service discovery and expressive request builders.\n\n\u003e **Note:** This package is part of the larger [LLMSpeak ecosystem](https://github.com/projectsaturnstudios/llm-speak). For universal provider switching and standardized interfaces, check out the [LLMSpeak Core](https://github.com/projectsaturnstudios/llm-speak-core) package.\n\n## Table of Contents\n- [Features](#features)\n- [Get Started](#get-started)\n- [Usage](#usage)\n  - [Content Generation](#content-generation)\n  - [Embeddings](#embeddings)\n  - [Fluent Request Building](#fluent-request-building)\n  - [System Instructions](#system-instructions)\n  - [Tool Calling](#tool-calling)\n  - [Thinking Mode](#thinking-mode)\n  - [Safety Settings](#safety-settings)\n  - [Advanced Configuration](#advanced-configuration)\n- [Response Handling](#response-handling)\n- [Testing](#testing)\n- [Credits](#credits)\n- [License](#license)\n\n## Features\n\n- **🚀 Laravel Native**: Full Laravel integration with automatic service discovery\n- **🔧 Fluent Interface**: Expressive request builders with method chaining\n- **📊 Laravel Data**: Powered by Spatie Laravel Data for robust data validation\n- **🛠️ Tool Support**: Complete function calling capabilities\n- **🧠 Thinking Mode**: Support for Gemini 2.0+ extended thinking features\n- **🛡️ Safety Controls**: Built-in safety filtering and content moderation\n- **📝 Embeddings**: Full text embedding support with task-specific optimization\n- **🎯 Type Safety**: Full PHP 8.2+ type declarations and IDE support\n- **🔐 Secure**: Built-in API key management and request validation\n\n## Get Started\n\n\u003e **Requires [PHP 8.2+](https://php.net/releases/) and Laravel 10.x/11.x/12.x**\n\nInstall the package via [Composer](https://getcomposer.org/):\n\n```bash\ncomposer require llm-speak/google-gemini\n```\n\nThe package will automatically register itself via Laravel's package discovery.\n\n### Environment Configuration\n\nAdd your Google API key to your `.env` file:\n\n```env\nGEMINI_API_KEY=your_google_api_key_here\n```\n\n## Usage\n\n### Content Generation\n\nThe simplest way to generate content with Gemini:\n\n```php\nuse LLMSpeak\\Gemini\\GeminiGenerateRequest;\n\n$request = new GeminiGenerateRequest(\n    model: 'gemini-2.0-flash-exp',\n    contents: [\n        [\n            'parts' =\u003e [\n                ['text' =\u003e 'Explain quantum computing in simple terms']\n            ]\n        ]\n    ]\n);\n\n$response = $request-\u003epost();\n\necho $response-\u003egetTextContent(); // \"Quantum computing is like...\"\n```\n\n### Embeddings\n\nGenerate embeddings for text with task-specific optimization:\n\n```php\nuse LLMSpeak\\Gemini\\GeminiEmbeddingsRequest;\n\n// Simple text embedding\n$request = GeminiEmbeddingsRequest::withText(\n    model: 'text-embedding-004',\n    text: 'Generate embeddings for this text'\n);\n\n$response = $request-\u003epost();\n\n$embeddings = $response-\u003egetEmbeddings();\n$dimensions = $response-\u003egetDimensionality();\n\n// Task-specific embedding\n$request = new GeminiEmbeddingsRequest(\n    model: 'text-embedding-004',\n    content: [\n        'parts' =\u003e [\n            ['text' =\u003e 'Research paper abstract content']\n        ]\n    ]\n)\n-\u003esetTaskType('RETRIEVAL_DOCUMENT')\n-\u003esetTitle('Research Paper: AI in Healthcare')\n-\u003esetOutputDimensionality(768);\n\n$response = $request-\u003epost();\n```\n\n### Universal LLMSpeak Interface\n\nFor **provider-agnostic embeddings** that work across Gemini, Mistral, Ollama, and other providers, use the universal LLMSpeak interface:\n\n```php\nuse LLMSpeak\\Core\\Support\\Facades\\LLMSpeak;\nuse LLMSpeak\\Core\\Support\\Requests\\LLMSpeakEmbeddingsRequest;\n\n// Universal request works with ANY provider\n$request = new LLMSpeakEmbeddingsRequest(\n    model: 'text-embedding-004',\n    input: 'Generate embeddings for this text',\n    encoding_format: null,           // Optional: 'float' or 'base64'\n    dimensions: null,                // Optional: Custom dimensions (Matryoshka)\n    task_type: 'SEMANTIC_SIMILARITY' // Optional: Gemini task optimization\n);\n\n// Execute with Gemini - same code works with other providers!\n$response = LLMSpeak::embeddingsFrom('gemini', $request);\n\n// Universal response methods\n$embeddings = $response-\u003egetAllEmbeddings();\n$firstVector = $response-\u003egetFirstEmbedding();\n$dimensions = $response-\u003egetDimensions();\n$tokenUsage = $response-\u003egetTotalTokens();\n```\n\n### Advanced Universal Features\n\nLeverage Gemini's unique capabilities through the universal interface:\n\n```php\n// Task-specific optimization\n$request = new LLMSpeakEmbeddingsRequest(\n    model: 'text-embedding-004',\n    input: 'Research paper about artificial intelligence',\n    encoding_format: 'float',\n    dimensions: 768,                    // Matryoshka representation  \n    task_type: 'RETRIEVAL_DOCUMENT'    // Gemini-specific optimization\n);\n\n$response = LLMSpeak::embeddingsFrom('gemini', $request);\n\n// Batch processing with universal interface\n$batchRequest = new LLMSpeakEmbeddingsRequest(\n    model: 'text-embedding-004', \n    input: [\n        'Document one content',\n        'Document two content', \n        'Document three content'\n    ],\n    encoding_format: 'float',\n    dimensions: 512,\n    task_type: 'CLUSTERING'\n);\n\n$batchResponse = LLMSpeak::embeddingsFrom('gemini', $batchRequest);\n\necho \"Generated {$batchResponse-\u003egetEmbeddingCount()} embeddings\";\necho \"Vector dimensions: {$batchResponse-\u003egetDimensions()}\";\n```\n\n### Why Use Universal Interface?\n\n**✅ Provider Independence:** Switch between Gemini, Mistral, Ollama with zero code changes  \n**✅ Future Proof:** New providers automatically supported  \n**✅ Consistent API:** Same methods across all providers  \n**✅ Type Safety:** Full PHP type declarations and IDE support  \n**✅ Best of Both:** Access provider-specific features when needed  \n\n```php\n// Same request works with different providers!\n$request = new LLMSpeakEmbeddingsRequest(/*...*/);\n\n$geminiResponse = LLMSpeak::embeddingsFrom('gemini', $request);   // Google AI\n$mistralResponse = LLMSpeak::embeddingsFrom('mistral', $request); // Mistral AI  \n$ollamaResponse = LLMSpeak::embeddingsFrom('ollama', $request);   // Local models\n```\n\n### Fluent Request Building\n\nBuild complex requests using the fluent interface:\n\n```php\nuse LLMSpeak\\Gemini\\GeminiGenerateRequest;\n\n$request = new GeminiGenerateRequest(\n    model: 'gemini-2.0-flash-exp',\n    contents: [\n        [\n            'parts' =\u003e [\n                ['text' =\u003e 'Write a creative story about space exploration']\n            ]\n        ]\n    ]\n)\n-\u003esetTemperature(0.9)\n-\u003esetMaxOutputTokens(2048)\n-\u003esetTopP(0.8)\n-\u003esetTopK(40)\n-\u003esetResponseMimeType('application/json')\n-\u003esetStopSequences(['THE END']);\n\n$response = $request-\u003epost();\n\n// Access response properties\necho $response-\u003egetTextContent();\necho $response-\u003egetTotalTokens();\necho $response-\u003egetModelVersion();\n```\n\n### Batch Configuration\n\nSet multiple parameters at once:\n\n```php\n$request = new GeminiGenerateRequest(\n    model: 'gemini-2.0-flash-exp',\n    contents: $conversation\n)-\u003esetMultiple([\n    'temperature' =\u003e 0.7,\n    'maxOutputTokens' =\u003e 1024,\n    'topP' =\u003e 0.9,\n    'topK' =\u003e 50,\n    'stopSequences' =\u003e ['Human:', 'Assistant:']\n]);\n```\n\n### System Instructions\n\nProvide system-level instructions to guide model behavior:\n\n```php\n$request = new GeminiGenerateRequest(\n    model: 'gemini-2.0-flash-exp',\n    contents: [\n        [\n            'parts' =\u003e [\n                ['text' =\u003e 'Explain machine learning concepts']\n            ]\n        ]\n    ]\n)-\u003esetSystemInstruction([\n    'parts' =\u003e [\n        [\n            'text' =\u003e 'You are an expert computer science professor. ' .\n                     'Provide detailed explanations with examples and analogies. ' .\n                     'Always include practical applications.'\n        ]\n    ]\n]);\n\n$response = $request-\u003epost();\n```\n\n### Tool Calling\n\nEnable Gemini to use external functions and tools:\n\n```php\n$tools = [\n    'functionDeclarations' =\u003e [\n        [\n            'name' =\u003e 'get_current_weather',\n            'description' =\u003e 'Get the current weather for a specific location',\n            'parameters' =\u003e [\n                'type' =\u003e 'object',\n                'properties' =\u003e [\n                    'location' =\u003e [\n                        'type' =\u003e 'string',\n                        'description' =\u003e 'The city and state/country'\n                    ],\n                    'unit' =\u003e [\n                        'type' =\u003e 'string',\n                        'enum' =\u003e ['celsius', 'fahrenheit']\n                    ]\n                ],\n                'required' =\u003e ['location']\n            ]\n        ]\n    ]\n];\n\n$request = new GeminiGenerateRequest(\n    model: 'gemini-2.0-flash-exp',\n    contents: [\n        [\n            'parts' =\u003e [\n                ['text' =\u003e 'What\\'s the weather like in Tokyo?']\n            ]\n        ]\n    ]\n)\n-\u003esetTools($tools)\n-\u003esetToolConfig([\n    'functionCallingConfig' =\u003e [\n        'mode' =\u003e 'AUTO'\n    ]\n]);\n\n$response = $request-\u003epost();\n\n// Check for tool usage\nif ($response-\u003eusedTools()) {\n    $toolCalls = $response-\u003egetToolCalls();\n    foreach ($toolCalls as $call) {\n        echo \"Function: {$call['name']}\\n\";\n        echo \"Arguments: \" . json_encode($call['args']) . \"\\n\";\n    }\n}\n```\n\n### Thinking Mode\n\nEnable Gemini 2.0+ extended thinking capabilities:\n\n```php\n$request = new GeminiGenerateRequest(\n    model: 'gemini-2.0-flash-thinking-exp',\n    contents: [\n        [\n            'parts' =\u003e [\n                ['text' =\u003e 'Solve this complex math problem: What is the derivative of x^3 + 2x^2 - 5x + 3?']\n            ]\n        ]\n    ]\n)\n-\u003esetThinkingBudget(1024)  // Allow up to 1024 thinking tokens\n-\u003esetIncludeThoughts(true); // Include reasoning in response\n\n$response = $request-\u003epost();\n\n// Access thinking content\n$thoughts = $response-\u003egetThinkingContent();\n$finalAnswer = $response-\u003egetTextContent();\n$thinkingRatio = $response-\u003egetThinkingRatio();\n\necho \"Reasoning: \" . $thoughts;\necho \"Answer: \" . $finalAnswer;\necho \"Thinking used: \" . ($thinkingRatio * 100) . \"% of budget\";\n```\n\n### Safety Settings\n\nConfigure content safety and filtering:\n\n```php\n$request = new GeminiGenerateRequest(\n    model: 'gemini-2.0-flash-exp',\n    contents: $contents\n)-\u003esetSafetySettings([\n    [\n        'category' =\u003e 'HARM_CATEGORY_HATE_SPEECH',\n        'threshold' =\u003e 'BLOCK_MEDIUM_AND_ABOVE'\n    ],\n    [\n        'category' =\u003e 'HARM_CATEGORY_DANGEROUS_CONTENT',\n        'threshold' =\u003e 'BLOCK_ONLY_HIGH'\n    ]\n]);\n\n$response = $request-\u003epost();\n\n// Check safety feedback\n$promptFeedback = $response-\u003egetPromptFeedback();\nif ($promptFeedback \u0026\u0026 isset($promptFeedback['blockReason'])) {\n    echo \"Content blocked: \" . $promptFeedback['blockReason'];\n}\n```\n\n### Advanced Configuration\n\nConfigure advanced parameters for optimal performance:\n\n```php\n$request = new GeminiGenerateRequest(\n    model: 'gemini-2.0-flash-exp',\n    contents: $conversation\n)\n-\u003esetTemperature(0.8)\n-\u003esetMaxOutputTokens(4096)\n-\u003esetTopP(0.95)\n-\u003esetTopK(64)\n-\u003esetResponseMimeType('application/json')\n-\u003esetResponseSchema($jsonSchema)\n-\u003esetCachedContent($cachedContentName)\n-\u003esetPresencePenalty(0.2)\n-\u003esetFrequencyPenalty(0.3);\n\n$response = $request-\u003epost();\n```\n\n## Response Handling\n\nAccess comprehensive response data:\n\n```php\n$response = $request-\u003epost();\n\n// Basic response info\n$textContent = $response-\u003egetTextContent();\n$allCandidates = $response-\u003egetAllCandidates();\n$bestCandidate = $response-\u003egetBestCandidate();\n\n// Token usage\n$totalTokens = $response-\u003egetTotalTokens();\n$inputTokens = $response-\u003egetInputTokens();\n$outputTokens = $response-\u003egetOutputTokens();\n$cachedTokens = $response-\u003egetCachedContentTokenCount();\n\n// Model information\n$modelVersion = $response-\u003egetModelVersion();\n$finishReason = $response-\u003egetFinishReason();\n\n// Safety and feedback\n$promptFeedback = $response-\u003egetPromptFeedback();\n$safetyRatings = $response-\u003egetSafetyRatings();\n\n// Tool usage\n$usedTools = $response-\u003eusedTools();\n$toolCalls = $response-\u003egetToolCalls();\n\n// Thinking mode (Gemini 2.0+)\n$thinkingContent = $response-\u003egetThinkingContent();\n$thinkingRatio = $response-\u003egetThinkingRatio();\n\n// Completion status\n$completedNaturally = $response-\u003ecompletedNaturally();\n$hitTokenLimit = $response-\u003ereachedTokenLimit();\n$wasBlocked = $response-\u003ewasBlockedBySafety();\n\n// Convert to array for storage\n$responseArray = $response-\u003etoArray();\n```\n\n## Testing\n\nThe package provides testing utilities for mocking Gemini responses:\n\n```php\nuse LLMSpeak\\Gemini\\GeminiGenerateRequest;\nuse LLMSpeak\\Gemini\\GeminiGenerateResponse;\n\n// Create a mock response\n$mockResponse = new GeminiGenerateResponse(\n    candidates: [\n        [\n            'content' =\u003e [\n                'parts' =\u003e [\n                    ['text' =\u003e 'Mock response content']\n                ]\n            ],\n            'finishReason' =\u003e 'STOP'\n        ]\n    ],\n    usageMetadata: [\n        'promptTokenCount' =\u003e 10,\n        'candidatesTokenCount' =\u003e 15,\n        'totalTokenCount' =\u003e 25\n    ],\n    modelVersion: 'gemini-2.0-flash-exp'\n);\n\n// Test your application logic\n$this-\u003eassertEquals('Mock response content', $mockResponse-\u003egetTextContent());\n$this-\u003eassertEquals(25, $mockResponse-\u003egetTotalTokens());\n```\n\n## Credits\n\n- [Project Saturn Studios](https://github.com/projectsaturnstudios)\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n\n---\n\n**Part of the LLMSpeak Ecosystem** - Made with ADHD by [Project Saturn Studios](https://projectsaturnstudios.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprojectsaturnstudios%2Fllm-speak-gemini","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprojectsaturnstudios%2Fllm-speak-gemini","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprojectsaturnstudios%2Fllm-speak-gemini/lists"}