{"id":34639884,"url":"https://github.com/projectsaturnstudios/llm-speak-open-router","last_synced_at":"2026-01-20T16:44:54.139Z","repository":{"id":307341925,"uuid":"1029245906","full_name":"projectsaturnstudios/llm-speak-open-router","owner":"projectsaturnstudios","description":null,"archived":false,"fork":false,"pushed_at":"2025-07-31T15:11:09.000Z","size":15,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-05T11:58:00.539Z","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-30T18:35:19.000Z","updated_at":"2025-07-31T15:11:00.000Z","dependencies_parsed_at":"2025-07-30T20:18:09.179Z","dependency_job_id":"77c5246c-04ca-4188-8799-fd431a65f8b3","html_url":"https://github.com/projectsaturnstudios/llm-speak-open-router","commit_stats":null,"previous_names":["projectsaturnstudios/llm-speak-open-router"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/projectsaturnstudios/llm-speak-open-router","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/projectsaturnstudios%2Fllm-speak-open-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/projectsaturnstudios%2Fllm-speak-open-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/projectsaturnstudios%2Fllm-speak-open-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/projectsaturnstudios%2Fllm-speak-open-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/projectsaturnstudios","download_url":"https://codeload.github.com/projectsaturnstudios/llm-speak-open-router/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/projectsaturnstudios%2Fllm-speak-open-router/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28005414,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-24T02:00:07.193Z","response_time":83,"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.662Z","updated_at":"2025-12-24T17:15:44.976Z","avatar_url":"https://github.com/projectsaturnstudios.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LLMSpeak OpenRouter\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/open-router.svg?style=flat-square)](https://packagist.org/packages/llm-speak/open-router)\n[![Total Downloads](https://img.shields.io/packagist/dt/llm-speak/open-router.svg?style=flat-square)](https://packagist.org/packages/llm-speak/open-router)\n\n**LLMSpeak OpenRouter** is a Laravel package that provides a fluent, Laravel-native interface for integrating with OpenRouter's unified AI model gateway. Built as part of the LLMSpeak ecosystem, it offers seamless access to 100+ AI models from providers like Anthropic, OpenAI, Google, Meta, and more through a single, consistent API.\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  - [Basic Request](#basic-request)\n  - [Model Selection](#model-selection)\n  - [Fluent Request Building](#fluent-request-building)\n  - [Tool Calling](#tool-calling)\n  - [Reasoning Mode](#reasoning-mode)\n  - [Advanced Sampling](#advanced-sampling)\n  - [Log Probabilities](#log-probabilities)\n  - [Streaming Responses](#streaming-responses)\n  - [Advanced Configuration](#advanced-configuration)\n- [Response Handling](#response-handling)\n- [Testing](#testing)\n- [Credits](#credits)\n- [License](#license)\n\n## Features\n\n- **🌐 Multi-Provider Access**: Access 100+ models from Anthropic, OpenAI, Google, Meta, Mistral, and more\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 with parallel execution\n- **🧠 Reasoning Mode**: OpenRouter's unique \"thinking\" tokens for enhanced reasoning\n- **📈 Log Probabilities**: Advanced probability analysis and token confidence scoring\n- **🎛️ Advanced Sampling**: Fine-grained control over model behavior with multiple sampling methods\n- **💨 Streaming**: Real-time streaming responses\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/open-router\n```\n\nThe package will automatically register itself via Laravel's package discovery.\n\n### Environment Configuration\n\nAdd your OpenRouter API key to your `.env` file:\n\n```env\nOPENROUTER_API_KEY=your_openrouter_api_key_here\n```\n\nGet your API key from [OpenRouter.ai](https://openrouter.ai/keys).\n\n## Usage\n\n### Basic Request\n\nThe simplest way to chat with any AI model through OpenRouter:\n\n```php\nuse LLMSpeak\\OpenRouter\\OpenRouterCompletionsRequest;\n\n$request = new OpenRouterCompletionsRequest(\n    model: 'anthropic/claude-3.5-sonnet',\n    messages: [\n        ['role' =\u003e 'user', 'content' =\u003e 'Hello! What can you help me with?']\n    ]\n);\n\n$response = $request-\u003epost();\n\necho $response-\u003egetTextContent(); // \"Hello! I'm here to help...\"\n```\n\n### Model Selection\n\nOpenRouter provides access to 100+ models. Choose the right model for your use case:\n\n```php\n// High-quality reasoning models\n$request = new OpenRouterCompletionsRequest(\n    model: 'anthropic/claude-3.5-sonnet',\n    messages: $messages\n);\n\n// Fast, cost-effective models\n$request = new OpenRouterCompletionsRequest(\n    model: 'anthropic/claude-3.5-haiku',\n    messages: $messages\n);\n\n// Cutting-edge experimental models\n$request = new OpenRouterCompletionsRequest(\n    model: 'openai/gpt-4o',\n    messages: $messages\n);\n\n// Open-source models\n$request = new OpenRouterCompletionsRequest(\n    model: 'meta-llama/llama-3.1-70b-instruct',\n    messages: $messages\n);\n\n// Specialized models\n$request = new OpenRouterCompletionsRequest(\n    model: 'google/gemini-pro-1.5',\n    messages: $messages\n);\n```\n\n### Fluent Request Building\n\nBuild complex requests using the fluent interface:\n\n```php\nuse LLMSpeak\\OpenRouter\\OpenRouterCompletionsRequest;\n\n$request = new OpenRouterCompletionsRequest(\n    model: 'anthropic/claude-3.5-sonnet',\n    messages: [\n        ['role' =\u003e 'user', 'content' =\u003e 'Write a creative story about time travel']\n    ]\n)\n-\u003esetMaxTokens(2000)\n-\u003esetTemperature(0.8)\n-\u003esetTopP(0.9)\n-\u003esetTopK(50)\n-\u003esetFrequencyPenalty(0.1)\n-\u003esetPresencePenalty(0.1);\n\n$response = $request-\u003epost();\n\n// Access response properties\necho $response-\u003eid;                    // chat-completion-abc123\necho $response-\u003emodel;                 // anthropic/claude-3.5-sonnet\necho $response-\u003egetTotalTokens();      // 1850\necho $response-\u003egetTextContent();      // Generated story content\n```\n\n### Batch Configuration\n\nSet multiple parameters at once:\n\n```php\n$request = new OpenRouterCompletionsRequest(\n    model: 'openai/gpt-4o',\n    messages: $conversation\n)-\u003esetMultiple([\n    'maxTokens' =\u003e 1500,\n    'temperature' =\u003e 0.7,\n    'topP' =\u003e 0.95,\n    'frequencyPenalty' =\u003e 0.2,\n    'presencePenalty' =\u003e 0.1,\n    'stop' =\u003e ['Human:', 'Assistant:'],\n    'seed' =\u003e 12345,\n    'user' =\u003e 'user_123'\n]);\n```\n\n### Tool Calling\n\nEnable models to use external functions and tools:\n\n```php\n$tools = [\n    [\n        'type' =\u003e 'function',\n        'function' =\u003e [\n            'name' =\u003e 'get_stock_price',\n            'description' =\u003e 'Get the current stock price for a given symbol',\n            'parameters' =\u003e [\n                'type' =\u003e 'object',\n                'properties' =\u003e [\n                    'symbol' =\u003e [\n                        'type' =\u003e 'string',\n                        'description' =\u003e 'Stock symbol (e.g., AAPL, GOOGL)'\n                    ],\n                    'currency' =\u003e [\n                        'type' =\u003e 'string',\n                        'enum' =\u003e ['USD', 'EUR'],\n                        'description' =\u003e 'Currency for the price'\n                    ]\n                ],\n                'required' =\u003e ['symbol']\n            ]\n        ]\n    ]\n];\n\n$request = new OpenRouterCompletionsRequest(\n    model: 'openai/gpt-4o',\n    messages: [\n        ['role' =\u003e 'user', 'content' =\u003e 'What\\'s the current price of Apple stock?']\n    ]\n)\n-\u003esetTools($tools)\n-\u003esetToolChoice('auto')\n-\u003esetParallelFunctionCalling(true);\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['function']['name']}\\n\";\n        echo \"Arguments: \" . json_encode($call['function']['arguments']) . \"\\n\";\n    }\n}\n```\n\n### Reasoning Mode\n\nEnable OpenRouter's unique reasoning capabilities for enhanced problem-solving:\n\n```php\n$request = new OpenRouterCompletionsRequest(\n    model: 'anthropic/claude-3.5-sonnet',\n    messages: [\n        [\n            'role' =\u003e 'user', \n            'content' =\u003e 'Solve this step-by-step: A train leaves Station A at 2 PM traveling at 60 mph. Another train leaves Station B at 3 PM traveling at 80 mph toward Station A. If the stations are 300 miles apart, when do the trains meet?'\n        ]\n    ]\n)\n-\u003esetReasoning(['effort' =\u003e 'high'])\n-\u003esetMaxTokens(3000);\n\n$response = $request-\u003epost();\n\n// Access reasoning content\n$reasoning = $response-\u003egetReasoningContent();\n$finalAnswer = $response-\u003egetTextContent();\n\necho \"Reasoning process:\\n\" . $reasoning . \"\\n\\n\";\necho \"Final answer:\\n\" . $finalAnswer;\n\n// Check reasoning efficiency\n$reasoningTokens = $response-\u003egetReasoningTokens();\n$efficiency = $response-\u003egetReasoningEfficiency();\necho \"Used {$reasoningTokens} reasoning tokens ({$efficiency}% of output)\";\n```\n\n### Advanced Sampling\n\nFine-tune model behavior with advanced sampling parameters:\n\n```php\n$request = new OpenRouterCompletionsRequest(\n    model: 'meta-llama/llama-3.1-70b-instruct',\n    messages: $messages\n)\n-\u003esetTemperature(0.8)           // Creativity level (0.0-2.0)\n-\u003esetTopP(0.9)                  // Nucleus sampling (0.0-1.0)\n-\u003esetTopK(40)                   // Top-K sampling (0+)\n-\u003esetMinP(0.05)                 // Minimum probability threshold\n-\u003esetTopA(0.2)                  // Top-A sampling\n-\u003esetRepetitionPenalty(1.1)     // Prevent repetition\n-\u003esetFrequencyPenalty(0.1)      // Frequency-based penalty\n-\u003esetPresencePenalty(0.1)       // Presence-based penalty\n-\u003esetSeed(42);                  // Deterministic output\n\n$response = $request-\u003epost();\n```\n\n### Log Probabilities\n\nAnalyze token probabilities and model confidence:\n\n```php\n$request = new OpenRouterCompletionsRequest(\n    model: 'openai/gpt-4o',\n    messages: [\n        ['role' =\u003e 'user', 'content' =\u003e 'Is this statement true or false: The Earth is flat?']\n    ]\n)\n-\u003esetLogprobs(true)\n-\u003esetTopLogprobs(5)  // Get top 5 token probabilities\n-\u003esetMaxTokens(100);\n\n$response = $request-\u003epost();\n\n// Analyze confidence\n$logProbs = $response-\u003egetLogProbs();\n$avgConfidence = $response-\u003egetAverageLogProb();\n$tokenConfidence = $response-\u003egetTokenConfidence();\n\necho \"Average confidence: \" . ($avgConfidence * 100) . \"%\\n\";\necho \"High confidence tokens: \" . count($tokenConfidence['high']) . \"\\n\";\necho \"Low confidence tokens: \" . count($tokenConfidence['low']) . \"\\n\";\n```\n\n### Streaming Responses\n\nEnable real-time streaming for long responses:\n\n```php\n$request = new OpenRouterCompletionsRequest(\n    model: 'anthropic/claude-3.5-sonnet',\n    messages: [\n        ['role' =\u003e 'user', 'content' =\u003e 'Write a detailed essay about renewable energy']\n    ]\n)\n-\u003esetStream(true)\n-\u003esetMaxTokens(4000);\n\n$response = $request-\u003epost();\n\n// Stream handling will be processed by the CompletionsEndpoint\n// Response contains streaming data format\n```\n\n### Advanced Configuration\n\nConfigure advanced parameters for optimal performance:\n\n```php\n$request = new OpenRouterCompletionsRequest(\n    model: 'google/gemini-pro-1.5',\n    messages: $conversationHistory\n)\n-\u003esetMaxTokens(8000)\n-\u003esetTemperature(0.7)\n-\u003esetTopP(0.95)\n-\u003esetFrequencyPenalty(0.3)\n-\u003esetPresencePenalty(0.2)\n-\u003esetRepetitionPenalty(1.05)\n-\u003esetStop(['[END]', '###', 'Human:'])\n-\u003esetSeed(12345)\n-\u003esetUser('analytics_user_456')\n-\u003esetLogitBias([50256 =\u003e -100])  // Suppress specific tokens\n-\u003esetResponseFormat(['type' =\u003e 'json_object']);\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$responseId = $response-\u003eid;\n$modelUsed = $response-\u003emodel;\n$timestamp = $response-\u003ecreated;\n\n// Content access\n$textContent = $response-\u003egetTextContent();\n$allChoices = $response-\u003echoices;\n$firstChoice = $response-\u003egetFirstChoice();\n\n// Token usage analysis\n$totalTokens = $response-\u003egetTotalTokens();\n$inputTokens = $response-\u003egetInputTokens();\n$outputTokens = $response-\u003egetOutputTokens();\n$reasoningTokens = $response-\u003egetReasoningTokens();\n\n// Completion analysis\n$finishReason = $response-\u003egetFinishReason();\n$completedNaturally = $response-\u003ecompletedNaturally();\n$hitTokenLimit = $response-\u003ereachedTokenLimit();\n$wasStopped = $response-\u003estoppedBySequence();\n\n// Tool usage\n$usedTools = $response-\u003eusedTools();\n$toolCalls = $response-\u003egetToolCalls();\n\n// Reasoning analysis (if enabled)\n$hasReasoning = $response-\u003ehasReasoning();\n$reasoningContent = $response-\u003egetReasoningContent();\n$reasoningEfficiency = $response-\u003egetReasoningEfficiency();\n\n// Log probability analysis (if enabled)\n$logProbs = $response-\u003egetLogProbs();\n$avgLogProb = $response-\u003egetAverageLogProb();\n$tokenConfidence = $response-\u003egetTokenConfidence();\n\n// Quality metrics\n$responseQuality = $response-\u003ecalculateQualityScore();\n$confidenceLevel = $response-\u003egetConfidenceLevel();\n\n// Convert to array for storage\n$responseArray = $response-\u003etoArray();\n```\n\n## Testing\n\nThe package provides testing utilities for mocking OpenRouter responses:\n\n```php\nuse LLMSpeak\\OpenRouter\\OpenRouterCompletionsRequest;\nuse LLMSpeak\\OpenRouter\\OpenRouterCompletionsResponse;\n\n// Create a mock response\n$mockResponse = new OpenRouterCompletionsResponse(\n    id: 'chatcmpl-test123',\n    model: 'anthropic/claude-3.5-sonnet',\n    created: time(),\n    choices: [\n        [\n            'index' =\u003e 0,\n            'message' =\u003e [\n                'role' =\u003e 'assistant',\n                'content' =\u003e 'Test response content'\n            ],\n            'finish_reason' =\u003e 'stop'\n        ]\n    ],\n    usage: [\n        'prompt_tokens' =\u003e 10,\n        'completion_tokens' =\u003e 15,\n        'total_tokens' =\u003e 25\n    ]\n);\n\n// Test your application logic\n$this-\u003eassertEquals('Test response content', $mockResponse-\u003egetTextContent());\n$this-\u003eassertEquals(25, $mockResponse-\u003egetTotalTokens());\n$this-\u003eassertTrue($mockResponse-\u003ecompletedNaturally());\n```\n\n## Credits\n\n- [Project Saturn Studios](https://github.com/projectsaturnstudios)\n- [OpenRouter.ai](https://openrouter.ai) for providing the unified AI model gateway\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** - Built with ❤️ by [Project Saturn Studios](https://projectsaturnstudios.com)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprojectsaturnstudios%2Fllm-speak-open-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprojectsaturnstudios%2Fllm-speak-open-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprojectsaturnstudios%2Fllm-speak-open-router/lists"}