From d6ff8d03197ec100590ac94c234862afbf713d6a Mon Sep 17 00:00:00 2001 From: DennyHo0917 <149746199+DennyHo0917@users.noreply.github.com> Date: Fri, 18 Sep 2026 09:19:06 +0800 Subject: [PATCH] feat: add API Route as an LLM Advisor provider --- CHANGELOG.md | 1 + docs/llm-advisor.md | 5 +- docs/llm-provider/llm_provider_api_route.md | 74 +++++++++++++++++++ docs/llm-providers.md | 3 +- megalinter/llm_provider/README.md | 1 + megalinter/llm_provider/__init__.py | 1 + .../llm_provider/llm_provider_api_route.py | 72 ++++++++++++++++++ .../llm_provider/llm_provider_factory.py | 3 + mkdocs.yml | 1 + 9 files changed, 158 insertions(+), 3 deletions(-) create mode 100644 docs/llm-provider/llm_provider_api_route.md create mode 100644 megalinter/llm_provider/llm_provider_api_route.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 790e5482e24..56cd6515586 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Note: Can be used with `oxsecurity/megalinter@beta` in your GitHub Action mega-l - Breaking changes - Core + - The **LLM Advisor** supports **API Route**, an OpenAI-compatible multi-model gateway: set **`LLM_PROVIDER: api-route`** and **`API_ROUTE_API_KEY`** to use API Route models through MegaLinter. - New linters diff --git a/docs/llm-advisor.md b/docs/llm-advisor.md index a56f46efb60..66e75958983 100644 --- a/docs/llm-advisor.md +++ b/docs/llm-advisor.md @@ -6,7 +6,7 @@ MegaLinter includes an AI-powered advisor that provides intelligent fix suggesti ## Features -- **Multi-Provider Support**: Works with OpenAI, Anthropic, Google Gemini, Hugging Face, Mistral AI, DeepSeek, Grok, OrcaRouter, and local Ollama models +- **Multi-Provider Support**: Works with OpenAI, Anthropic, Google Gemini, Hugging Face, Mistral AI, DeepSeek, Grok, OrcaRouter, API Route, and local Ollama models - **Context-Aware Suggestions**: Analyzes code context around errors for better recommendations - **Integrated Reporting**: AI suggestions appear directly in MegaLinter reports - **Configurable**: Control which models to use and how many errors to analyze @@ -22,6 +22,7 @@ MegaLinter includes an AI-powered advisor that provides intelligent fix suggesti | [DeepSeek](llm-provider/llm_provider_deepseek.md) | Yes | Cloud | [Setup Guide](llm-provider/llm_provider_deepseek.md) | | [Grok](llm-provider/llm_provider_grok.md) | Yes | Cloud | [Setup Guide](llm-provider/llm_provider_grok.md) | | [OrcaRouter](llm-provider/llm_provider_orcarouter.md) | Yes | Cloud | [Setup Guide](llm-provider/llm_provider_orcarouter.md) | +| [API Route](llm-provider/llm_provider_api_route.md) | Yes | Cloud | [Setup Guide](llm-provider/llm_provider_api_route.md) | | [Ollama](llm-provider/llm_provider_ollama.md) | No | Local | [Setup Guide](llm-provider/llm_provider_ollama.md) | | [Hugging Face](llm-provider/llm_provider_huggingface.md) | Optional | Local/Cloud | [Setup Guide](llm-provider/llm_provider_huggingface.md) | @@ -38,7 +39,7 @@ See [All LLM Providers](llm-providers.md) for a complete comparison and setup in LLM_ADVISOR_ENABLED: true # Choose your provider and model -LLM_PROVIDER: openai # openai, anthropic, google, huggingface, mistral, deepseek, grok, orcarouter, ollama +LLM_PROVIDER: openai # openai, anthropic, google, huggingface, mistral, deepseek, grok, orcarouter, api-route, ollama LLM_MODEL_NAME: gpt-4.1-mini LLM_MAX_TOKENS: 1000 LLM_TEMPERATURE: 0.1 diff --git a/docs/llm-provider/llm_provider_api_route.md b/docs/llm-provider/llm_provider_api_route.md new file mode 100644 index 00000000000..4b2f2f27d61 --- /dev/null +++ b/docs/llm-provider/llm_provider_api_route.md @@ -0,0 +1,74 @@ +
+ API Route Logo +
+ +# API Route Provider + +[API Route](https://www.api-route.com) is an OpenAI-compatible multi-model AI API gateway. It provides one base URL and API key for accessing models from multiple providers, including GPT, Claude, Gemini, Kimi, and Qwen. + +## Setup + +1. **Get API Key**: Sign in to [API Route](https://www.api-route.com) and create an API key. + +2. **Set Environment Variable**: + +Set **API_ROUTE_API_KEY=your-api-key** in your CI/CD secret variables. + +> Make sure the secret variable is sent to MegaLinter from your CI/CD workflow. Example in GitHub Action: `API_ROUTE_API_KEY: ${{ secrets.API_ROUTE_API_KEY }}` + +3. **Configure MegaLinter**: + +```yaml +LLM_ADVISOR_ENABLED: true +LLM_PROVIDER: api-route +LLM_MODEL_NAME: gpt-5.6-sol +LLM_MAX_TOKENS: 1000 +LLM_TEMPERATURE: 0.1 +``` + +## Model List + +For the current list of models available through API Route, see: + +- [API Route Pricing and Models](https://www.api-route.com/pricing) + +## Configuration Options + +### Basic Configuration + +```yaml +LLM_PROVIDER: api-route +LLM_MODEL_NAME: gpt-5.6-sol +``` + +### Advanced Configuration + +```yaml +# Custom API endpoint (if needed) +API_ROUTE_BASE_URL: https://global.api-route.com/v1 +``` + +## Troubleshooting + +### Common Issues + +1. **"Invalid API key"** + + - Verify `API_ROUTE_API_KEY` is correct + - Check that the key is active and has available balance + +2. **"Rate limit exceeded"** + + - Check your API Route usage and rate limits + - Retry with appropriate backoff + +3. **"Model not available"** + + - Verify the value of `LLM_MODEL_NAME` + - Check the current model list on the [API Route pricing page](https://www.api-route.com/pricing) + +### Debug Mode + +```yaml +LOG_LEVEL: DEBUG +``` diff --git a/docs/llm-providers.md b/docs/llm-providers.md index 148d73eb249..3a9ccd094d6 100644 --- a/docs/llm-providers.md +++ b/docs/llm-providers.md @@ -12,7 +12,8 @@ This page provides a comprehensive comparison of all supported LLM providers for | [Mistral AI](llm-provider/llm_provider_mistralai.md) | $ | Cloud | Easy | European alternative | | [DeepSeek](llm-provider/llm_provider_deepseek.md) | $ | Cloud | Easy | Code-focused models | | [Grok](llm-provider/llm_provider_grok.md) | $$ | Cloud | Easy | xAI's conversational model | -| [OrcaRouter](llm-provider/llm_provider_orcarouter.md) | $$ | Cloud | Easy | Multi-model AI gateway | +| [OrcaRouter](llm-provider/llm_provider_orcarouter.md) | $ | Cloud | Easy | Multi-model AI gateway | +| [API Route](llm-provider/llm_provider_api_route.md) | $ | Cloud | Easy | Unified multi-model gateway | | [Ollama](llm-provider/llm_provider_ollama.md) | Free | Local | Medium | Privacy, offline use | | [Hugging Face](llm-provider/llm_provider_huggingface.md) | Free* | Local/Cloud | Hard | Open models, customization | diff --git a/megalinter/llm_provider/README.md b/megalinter/llm_provider/README.md index 350851b8f03..b66236a296f 100644 --- a/megalinter/llm_provider/README.md +++ b/megalinter/llm_provider/README.md @@ -21,6 +21,7 @@ This directory contains the modular LLM provider system for MegaLinter's AI-powe | DeepSeek | `llm_provider_deepseek.py` | DeepSeek Chat, DeepSeek Coder | Yes | | Grok | `llm_provider_grok.py` | Grok Beta (xAI) | Yes | | OrcaRouter | `llm_provider_orcarouter.py` | Any model routed by OrcaRouter | Yes | +| API Route | `llm_provider_api_route.py` | GPT, Claude, Gemini, and more | Yes | | Hugging Face | `llm_provider_huggingface.py` | Any HF transformer model | Optional | | Ollama | `llm_provider_ollama.py` | Llama, CodeLlama, Mistral, etc. | No | diff --git a/megalinter/llm_provider/__init__.py b/megalinter/llm_provider/__init__.py index 62911f22367..3e4c4f838da 100644 --- a/megalinter/llm_provider/__init__.py +++ b/megalinter/llm_provider/__init__.py @@ -22,6 +22,7 @@ "DeepSeekProvider": "llm_provider_deepseek", "GrokProvider": "llm_provider_grok", "OrcaRouterProvider": "llm_provider_orcarouter", + "ApiRouteProvider": "llm_provider_api_route", } __all__ = [ diff --git a/megalinter/llm_provider/llm_provider_api_route.py b/megalinter/llm_provider/llm_provider_api_route.py new file mode 100644 index 00000000000..ce0475c7acb --- /dev/null +++ b/megalinter/llm_provider/llm_provider_api_route.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +""" +API Route LLM Provider for MegaLinter +""" + +import logging +from typing import Any, Dict, Optional + +from langchain_openai import ChatOpenAI +from megalinter import config + +from .llm_provider import LLMProvider + + +class ApiRouteProvider(LLMProvider): + + def get_default_model(self) -> str: + return "gpt-5.6-sol" + + def load_config(self, request_id: Optional[str] = None) -> Dict[str, Any]: + return { + "api_key": config.get(request_id, "API_ROUTE_API_KEY", ""), + "base_url": config.get( + request_id, + "API_ROUTE_BASE_URL", + "https://global.api-route.com/v1", + ), + "model_name": config.get(request_id, "LLM_MODEL_NAME", ""), + "temperature": float( + config.get( + request_id, + "LLM_TEMPERATURE", + str(self.get_default_config_value("temperature")), + ) + ), + "max_tokens": int( + config.get( + request_id, + "LLM_MAX_TOKENS", + str(self.get_default_config_value("max_tokens")), + ) + ), + } + + def initialize(self) -> bool: + try: + api_key = self.get_config_value("api_key") + if not api_key: + raise ValueError("API_ROUTE_API_KEY is required") + + model_name = self.get_config_value("model_name") or self.get_default_model() + base_url = self.get_config_value( + "base_url", "https://global.api-route.com/v1" + ) + temperature = self.get_config_value("temperature") + max_tokens = self.get_config_value("max_tokens") + + # API Route exposes an OpenAI-compatible API. + self.llm = ChatOpenAI( + model=model_name, + temperature=temperature, + max_tokens=max_tokens, + api_key=api_key, + base_url=base_url, + ) + + logging.debug(f"API Route provider initialized with model {model_name}") + return True + + except Exception as e: + logging.error(f"Failed to initialize API Route provider: {str(e)}") + return False diff --git a/megalinter/llm_provider/llm_provider_factory.py b/megalinter/llm_provider/llm_provider_factory.py index 50e7a20e8fc..5fe6cb80365 100644 --- a/megalinter/llm_provider/llm_provider_factory.py +++ b/megalinter/llm_provider/llm_provider_factory.py @@ -24,6 +24,7 @@ class LLMProviderFactory: "deepseek": ("llm_provider_deepseek", "DeepSeekProvider"), "grok": ("llm_provider_grok", "GrokProvider"), "orcarouter": ("llm_provider_orcarouter", "OrcaRouterProvider"), + "api-route": ("llm_provider_api_route", "ApiRouteProvider"), } @classmethod @@ -78,6 +79,7 @@ def get_supported_providers(cls) -> Dict[str, str]: "deepseek": "DeepSeek models", "grok": "Grok (xAI) models", "orcarouter": "OrcaRouter models", + "api-route": "API Route models", } @classmethod @@ -92,4 +94,5 @@ def get_supported_providers_api_key_var_names(cls) -> list[str]: "DEEPSEEK_API_KEY", "GROK_API_KEY", "ORCAROUTER_API_KEY", + "API_ROUTE_API_KEY", ] diff --git a/mkdocs.yml b/mkdocs.yml index 12a41a68bd5..83526b2ad2d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -409,6 +409,7 @@ nav: - "MistralAI": "llm-provider/llm_provider_mistralai.md" - "OpenAI": "llm-provider/llm_provider_openai.md" - "OrcaRouter": "llm-provider/llm_provider_orcarouter.md" + - "API Route": "llm-provider/llm_provider_api_route.md" - "Ollama": "llm-provider/llm_provider_ollama.md" - "Hugging Face": "llm-provider/llm_provider_huggingface.md" - "Flavors":