Skip to content

feat: Universal LiteLLM Backend (Issue #234)#296

Open
whoisjayd wants to merge 30 commits intovitali87:mainfrom
whoisjayd:feature/litellm-universal-backend
Open

feat: Universal LiteLLM Backend (Issue #234)#296
whoisjayd wants to merge 30 commits intovitali87:mainfrom
whoisjayd:feature/litellm-universal-backend

Conversation

@whoisjayd
Copy link
Contributor

@whoisjayd whoisjayd commented Feb 4, 2026

Summary

This PR replaces the legacy multi-provider architecture (Google, OpenAI, Ollama specific classes) with a single LiteLLMProvider. This enables support for 100+ LLM providers including OpenAI, Anthropic, Gemini, DeepSeek, Ollama, Azure, and more—all without code changes.

It also introduces support for extra headers, enabling integration with 3rd party gateways like Portkey and Helicone.

Key Changes

  • Universal Backend: Implemented codebase_rag/providers/litellm.py.
  • Legacy Removal: Deleted GoogleProvider, OpenAIProvider, and OllamaProvider.
  • Dynamic Registry: constants.py now dynamically lists available providers from the installed litellm version.
  • Tool Refactor: DocumentAnalyzer tool no longer depends on google-generativeai SDK; it uses the unified backend.
  • Documentation: Added docs/SUPPORTED_PROVIDERS.md and docs/LLM_CONFIGURATION.md.

Issues Resolved

Test Plan

  • Unit Tests: make test passed (3000+ tests).
  • New Tests: Added test_litellm_provider_full.py covering dynamic loading, config mapping, extra headers, and error handling.
  • Integration: Verified DocumentAnalyzer works with mocked backend responses.
  • Pre-commit: All linting (ruff), formatting, and type checks (ty) passed.

- Replace legacy Google/OpenAI/Ollama providers with generic LiteLLMProvider
- Update configuration to support dynamic provider routing
- Add dynamic provider listing in constants
- Remove hardcoded Google GenAI dependency from DocumentAnalyzer
- Update dependencies to include litellm>=1.52.0
- Add test_litellm_provider_full.py for comprehensive provider testing
- Update test_tool_calling.py to use pydantic_ai.models.test.TestModel
- Fix type checks in conftest.py
- Update test_provider_classes.py for dynamic provider list and remove legacy providers
- Update test_document_analyzer.py to mock LiteLLM provider logic
Includes detailed setup for all major providers, troubleshooting, and best practices.
Generated dynamic list of 100+ supported providers and updated main documentation.
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @whoisjayd, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant architectural overhaul to the LLM integration, transitioning from a fragmented, provider-specific setup to a unified, highly extensible LiteLLM backend. This change dramatically expands the range of supported language models and enables advanced features like custom API headers for gateway integration, all while simplifying the underlying codebase and improving future maintainability. The core purpose is to provide a flexible and future-proof foundation for interacting with diverse LLM services.

Highlights

  • Universal LLM Backend: Replaced the legacy multi-provider architecture (Google, OpenAI, Ollama specific classes) with a single, universal LiteLLMProvider.
  • Expanded Provider Support: Enabled support for over 100 LLM providers, including OpenAI, Anthropic, Gemini, DeepSeek, Ollama, and Azure, without requiring code changes for new integrations.
  • Extra Headers Support: Introduced support for extra_headers in model configurations, facilitating integration with third-party API gateways like Portkey and Helicone.
  • Dynamic Provider Registry: The constants.py file now dynamically lists available providers by querying the installed litellm version, ensuring up-to-date support.
  • Document Analyzer Refactor: The DocumentAnalyzer tool has been updated to utilize the new unified LiteLLM backend, removing its previous dependency on the google-generativeai SDK.
  • Comprehensive Documentation: Added new documentation files (docs/LLM_CONFIGURATION.md and docs/SUPPORTED_PROVIDERS.md) to guide users on configuring LLMs and viewing the extensive list of supported models.
Changelog
  • README.md
    • Added a new 'Latest News' section highlighting the universal LLM support via LiteLLM.
    • Included links to the new LLM Configuration Guide and Supported Providers List.
    • Added 'litellm' to the list of project dependencies.
  • codebase_rag/config.py
    • Introduced extra_headers field to ModelConfig for custom HTTP headers.
    • Updated AppConfig to include environment variables for orchestrator and cypher extra_headers.
    • Modified _get_default_config to correctly pass extra_headers to ModelConfig.
    • Enhanced parse_model_string to support '/' as a provider/model separator, in addition to ':'.
  • codebase_rag/constants.py
    • Updated Provider enum with a docstring clarifying its role as a static subset.
    • Added LITELLM, GROQ, and MISTRAL to the Provider enum.
    • Implemented get_all_providers() to dynamically fetch and cache the full list of providers from litellm.
  • codebase_rag/main.py
    • Refactored _create_configuration_table to display orchestrator and cypher endpoints more generically, removing Ollama-specific checks.
    • Adjusted _create_model_from_string and _update_single_model_setting to handle the LOCAL provider type and refine Ollama endpoint logic.
  • codebase_rag/providers/base.py
    • Removed the deprecated GoogleProvider, OpenAIProvider, and OllamaProvider classes.
    • Updated PROVIDER_REGISTRY to map all common providers to the new LiteLLMProvider.
    • Modified get_provider to use LiteLLMProvider as a fallback for unknown providers and handle type casting.
    • Updated list_providers to include dynamically discovered providers from litellm.
  • codebase_rag/providers/interface.py
    • Added new file: Defines the ModelProvider abstract base class, establishing a common interface for all LLM providers.
  • codebase_rag/providers/litellm.py
    • Added new file: Implements the LiteLLMProvider class, serving as the universal adapter for LiteLLM.
    • Handles various configuration parameters like API key, endpoint, project ID, region, and extra_headers.
    • Manages model ID formatting (e.g., provider/model) and sets environment variables for specific providers like Vertex AI.
    • Integrates extra_headers by updating litellm's module-level configuration.
  • codebase_rag/services/llm.py
    • Updated DocumentAnalyzer.__init__ to use a more flexible is_local check for system prompts, replacing the direct OLLAMA provider check.
  • codebase_rag/tests/test_document_analyzer.py
    • Removed _NotSupportedClient and associated tests.
    • Updated mock_settings to reflect the new default provider (OPENAI) and model (gpt-4o).
    • Replaced Google-specific client mocking with a mock for Agent.run_sync, aligning with the new unified backend.
  • codebase_rag/tests/test_litellm_provider_full.py
    • Added new file: Contains comprehensive unit tests for LiteLLMProvider, covering dynamic provider loading, model ID parsing, environment variable handling, API key passing, and extra_headers functionality.
  • codebase_rag/tests/test_provider_classes.py
    • Updated tests to reflect the removal of individual provider classes and the universal adoption of LiteLLMProvider.
    • Adjusted assertions for get_provider and list_providers to match the new LiteLLM-centric behavior.
    • Modified CustomProvider in test_register_custom_provider to align with the updated ModelProvider interface.
  • codebase_rag/tools/document_analyzer.py
    • Removed the _NotSupportedClient class and Google-specific client initialization.
    • Streamlined error handling by removing _extract_response_text and _handle_analyze_error.
    • Updated the analyze method to leverage _create_provider_model and pydantic_ai.Agent for LLM interactions, directly passing binary content.
  • docs/LLM_CONFIGURATION.md
    • Added new file: Provides a detailed guide on configuring LLMs, covering environment variables, CLI flags, specific provider setups, advanced configurations (API Gateways, Multi-Model Strategy), troubleshooting, and best practices.
  • docs/SUPPORTED_PROVIDERS.md
    • Added new file: Lists all LLM providers and models dynamically supported through the LiteLLM integration, categorized for easy reference.
  • pyproject.toml
    • Added litellm>=1.52.0 to the project dependencies.
  • uv.lock
    • Updated graph-code version to 0.0.50.
    • Added litellm and its dependency fastuuid to the lock file.
Activity
  • The pull request introduces a major architectural shift by integrating LiteLLM as a universal backend for LLM interactions.
  • Significant refactoring was performed, including the removal of three legacy provider-specific classes and the introduction of two new core files for the universal provider and its interface.
  • Comprehensive documentation has been added to guide users through the new LLM configuration process and list supported models.
  • New tests specifically for the LiteLLM provider were added, and existing tests for the DocumentAnalyzer were updated to reflect the new backend, ensuring functionality and stability.
  • Dependency management files (pyproject.toml and uv.lock) were updated to include litellm and its sub-dependencies.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This is an excellent and significant refactoring that replaces multiple provider-specific implementations with a universal LiteLLMProvider. This change greatly enhances the tool's flexibility, supporting over 100 LLM providers without code modifications. The codebase is now cleaner, more maintainable, and the new documentation is a valuable addition. I've identified a few areas for improvement, including a potential race condition when handling API headers, some dead code that can be removed for clarity, and a minor regression in error handling specificity in one of the tools, which has been updated to reference repository guidelines. Overall, this is a fantastic contribution that significantly improves the project's architecture.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 4, 2026

Greptile Overview

Greptile Summary

This PR successfully replaces the legacy multi-provider architecture with a unified LiteLLM backend, enabling support for 100+ LLM providers through a single implementation. The refactor removes ~176k lines (mostly docs/optimize artifacts) and adds comprehensive test coverage.

Major Changes:

  • Implemented LiteLLMProvider with thread-safe Vertex AI environment variable handling via context manager
  • Removed legacy GoogleProvider, OpenAIProvider, and OllamaProvider classes
  • Refactored DocumentAnalyzer to use universal backend instead of Google-specific SDK
  • Added support for extra headers (Portkey, Helicone integration)
  • Dynamic provider registry using litellm.provider_list with caching
  • Added extra_headers field to ModelConfig with security validation (CRLF injection, dangerous headers)

Issues Found:

  • Critical: Test files have multiple runtime bugs where ModelSettings (Pydantic BaseModel) is accessed like a dict using settings["key"] instead of settings.key - these will fail when tests run
  • Code Quality: Multiple hardcoded strings in litellm.py violate project standards (env var names, provider names, dict keys should be in constants)

The architecture is sound and the implementation correctly uses PydanticAI's model abstraction, but the test bugs need immediate fixing before merge.

Confidence Score: 3/5

  • Not safe to merge - test suite has critical runtime bugs that will cause test failures
  • The core implementation is architecturally sound and properly abstracts provider differences, but test_litellm_provider_full.py and test_litellm_provider_concurrent.py have 6+ assertions treating ModelSettings as dict which will fail at runtime. Additionally, hardcoded strings throughout litellm.py violate coding standards.
  • Fix test_litellm_provider_full.py and test_litellm_provider_concurrent.py immediately - all dict-style access to ModelSettings will fail. Move hardcoded strings in litellm.py to constants.

Important Files Changed

Filename Overview
codebase_rag/providers/litellm.py New universal LiteLLM provider implementation with context manager for Vertex AI; has hardcoded strings that need moving to constants
codebase_rag/providers/interface.py Clean ABC interface for model providers, properly uses Any for flexible kwargs
codebase_rag/providers/base.py Simplified registry and factory functions, removed legacy Google/OpenAI/Ollama provider classes
codebase_rag/tests/test_litellm_provider_full.py Comprehensive test suite with critical bugs - multiple assertions treat ModelSettings Pydantic model as dict, causing runtime failures
codebase_rag/tests/test_litellm_provider_concurrent.py Concurrency tests for thread safety; has dict access bug on ModelSettings object
codebase_rag/tools/document_analyzer.py Refactored to use universal LiteLLM backend via PydanticAI Agent instead of Google-specific SDK

Sequence Diagram

sequenceDiagram
    participant User
    participant Main
    participant Config
    participant BaseProvider
    participant LiteLLMProvider
    participant PydanticLiteLLM
    participant OpenAIChatModel
    participant Agent

    User->>Main: Start application
    Main->>Config: Load settings from .env
    Config-->>Main: ModelConfig (provider, model_id, api_key, etc.)
    
    Main->>BaseProvider: get_provider_from_config(config)
    BaseProvider->>BaseProvider: Check PROVIDER_REGISTRY
    BaseProvider->>LiteLLMProvider: new LiteLLMProvider(provider, **config)
    LiteLLMProvider-->>BaseProvider: provider instance
    BaseProvider-->>Main: provider instance
    
    Main->>LiteLLMProvider: create_model(model_id)
    LiteLLMProvider->>LiteLLMProvider: validate_config()
    LiteLLMProvider->>LiteLLMProvider: Build full_model_id (provider/model)
    LiteLLMProvider->>PydanticLiteLLM: new PydanticLiteLLMProvider(api_key, api_base)
    
    alt Vertex AI provider
        LiteLLMProvider->>LiteLLMProvider: Enter _vertex_env_context
        Note over LiteLLMProvider: Set VERTEXAI_PROJECT, VERTEXAI_LOCATION env vars
    end
    
    LiteLLMProvider->>LiteLLMProvider: Build ModelSettings (extra_headers, extra_body, timeout)
    LiteLLMProvider->>OpenAIChatModel: new OpenAIChatModel(full_model_id, provider, settings)
    
    alt Error handling
        OpenAIChatModel-->>LiteLLMProvider: RateLimitError/Timeout/InvalidRequestError
        LiteLLMProvider-->>Main: Wrapped ValueError with context
    end
    
    OpenAIChatModel-->>LiteLLMProvider: model instance
    
    alt Vertex AI provider
        LiteLLMProvider->>LiteLLMProvider: Exit _vertex_env_context
        Note over LiteLLMProvider: Restore original env vars
    end
    
    LiteLLMProvider-->>Main: model instance
    Main->>Agent: new Agent(model, tools, system_prompt)
    Agent-->>Main: agent instance
    Main->>Agent: run_sync(user_query)
    Agent->>OpenAIChatModel: Generate response via LiteLLM
    OpenAIChatModel->>PydanticLiteLLM: API call to provider
    PydanticLiteLLM-->>OpenAIChatModel: LLM response
    OpenAIChatModel-->>Agent: Parsed response
    Agent-->>Main: RunResult with output
    Main-->>User: Display result
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 files reviewed, 6 comments

Edit Code Review Agent Settings | Greptile

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modernizes the LLM provider architecture by replacing legacy provider-specific implementations (Google, OpenAI, Ollama) with a unified LiteLLMProvider backend. This enables support for 100+ LLM providers through LiteLLM's abstraction layer, including OpenAI, Anthropic, Google Gemini, DeepSeek, Ollama, Azure, Groq, and more. The PR also introduces support for custom headers to enable integration with third-party API gateways like Portkey and Helicone.

Changes:

  • Implemented universal LiteLLMProvider replacing three legacy provider classes
  • Added dynamic provider discovery from LiteLLM's provider list via get_all_providers()
  • Refactored DocumentAnalyzer to use unified backend instead of Google-specific SDK
  • Added comprehensive documentation for LLM configuration and supported providers

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
uv.lock Added litellm 1.81.7 and its dependency fastuuid 0.14.0
pyproject.toml Added litellm>=1.52.0 dependency
codebase_rag/providers/litellm.py New universal provider implementation using LiteLLM
codebase_rag/providers/interface.py Extracted base ModelProvider interface
codebase_rag/providers/base.py Refactored to use LiteLLMProvider for all providers
codebase_rag/constants.py Added dynamic provider discovery function
codebase_rag/config.py Added extra_headers support and updated model string parsing
codebase_rag/tools/document_analyzer.py Migrated from google-generativeai SDK to unified backend
codebase_rag/services/llm.py Updated local model detection logic
codebase_rag/main.py Simplified endpoint configuration display
codebase_rag/tests/test_provider_classes.py Updated tests for LiteLLMProvider
codebase_rag/tests/test_litellm_provider_full.py New comprehensive tests for LiteLLM integration
codebase_rag/tests/test_document_analyzer.py Updated to test with mocked Agent instead of Google SDK
docs/LLM_CONFIGURATION.md New comprehensive configuration guide
docs/SUPPORTED_PROVIDERS.md Auto-generated list of 2800+ supported model strings
README.md Added links to new documentation
Comments suppressed due to low confidence (1)

codebase_rag/config.py:323

  • The parse_model_string() method now prioritizes "/" over ":" as a delimiter (checking "/" first at line 315). This could be a breaking change if users have model strings containing "/" that were previously parsed differently. The logic should handle edge cases where both separators are present in the string.
    def parse_model_string(self, model_string: str) -> tuple[str, str]:
        if "/" in model_string:
            provider, model = model_string.split("/", 1)
            return provider.lower(), model
        if ":" not in model_string:
            return cs.Provider.OLLAMA, model_string
        provider, model = model_string.split(":", 1)
        if not provider:
            raise ValueError(ex.PROVIDER_EMPTY)
        return provider.lower(), model

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@whoisjayd whoisjayd marked this pull request as draft February 4, 2026 10:39
@whoisjayd whoisjayd marked this pull request as ready for review February 4, 2026 12:28
@whoisjayd
Copy link
Contributor Author

/gemini review

@whoisjayd
Copy link
Contributor Author

/gemini summary

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This is a significant and well-executed pull request that refactors the LLM provider architecture to use LiteLLM, greatly improving provider support and maintainability. The removal of legacy provider classes and the introduction of a universal LiteLLMProvider is a major step forward. The new documentation is also very thorough and helpful. I've identified a few areas for improvement to enhance robustness and correctness, particularly around configuration validation and provider instantiation logic, all of which align with best practices for error handling and code clarity.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

This pull request significantly overhauls the system's interaction with Large Language Models by migrating from a legacy multi-provider setup to a unified LiteLLM backend. This strategic shift dramatically expands compatibility with a vast array of LLM services and introduces flexible configuration options, such as custom request headers for API gateways. The change aims to streamline future integrations, enhance maintainability, and provide a robust, adaptable foundation for all LLM-related functionalities.

Highlights

  • Universal LLM Backend: Replaced the previous fragmented, provider-specific LLM architecture with a single, universal "LiteLLMProvider" powered by LiteLLM.
  • Expanded Provider Support: Enabled seamless integration with over 100 LLM providers (e.g., OpenAI, Anthropic, Gemini, DeepSeek, Ollama, Azure) without requiring code changes for new integrations.
  • Advanced Configuration: Introduced support for "extra_headers" in model configurations, allowing integration with third-party API gateways like Portkey and Helicone, and added a "field_validator" for JSON parsing of these headers.
  • Dynamic Provider Discovery: The "constants.py" file now dynamically fetches and caches the full list of available providers directly from the installed "litellm" library.
  • Document Analyzer Modernization: The "DocumentAnalyzer" tool was refactored to use the new unified LiteLLM backend and "pydantic_ai.Agent", removing its dependency on the "google-generativeai" SDK.
  • Comprehensive Documentation: New documentation files ("docs/LLM_CONFIGURATION.md" and "docs/SUPPORTED_PROVIDERS.md") were added to guide users on configuring LLMs and list all supported models.
Changelog
  • README.md
    • Added a new 'Latest News' section highlighting universal LLM support via LiteLLM, with links to new configuration and supported providers documentation.
    • Included 'litellm' in the list of project dependencies.
  • codebase_rag/config.py
    • Imported 'field_validator' from 'pydantic'.
    • Added 'extra_headers: dict[str, str] | None' to 'ModelConfig'.
    • Updated 'AppConfig' to include environment variables for orchestrator and cypher 'extra_headers'.
    • Implemented 'parse_json_headers' validator to parse JSON strings for 'extra_headers'.
    • Modified '_get_default_config' to pass 'extra_headers' to 'ModelConfig'.
    • Enhanced 'parse_model_string' to support '/' as a provider/model separator, in addition to ':'.
  • codebase_rag/constants.py
    • Added a docstring to the 'Provider' enum, clarifying its role as a static subset.
    • Added 'LITELLM', 'GROQ', and 'MISTRAL' to the 'Provider' enum.
    • Implemented 'get_all_providers()' to dynamically fetch and cache the full list of providers from 'litellm'.
  • codebase_rag/main.py
    • Refactored '_create_configuration_table' to display orchestrator and cypher endpoints more generically, removing Ollama-specific checks.
    • Adjusted '_create_model_from_string' and '_update_single_model_setting' to handle the 'LOCAL' provider type and refine Ollama endpoint logic.
  • codebase_rag/providers/base.py
    • Removed the deprecated 'GoogleProvider', 'OpenAIProvider', and 'OllamaProvider' classes.
    • Updated 'PROVIDER_REGISTRY' to map all common providers to the new 'LiteLLMProvider'.
    • Modified 'get_provider' to use 'LiteLLMProvider' as a fallback for unknown providers and handle type casting.
    • Updated 'list_providers' to include dynamically discovered providers from 'litellm'.
    • Imported 'Any' and 'ModelProvider' from the new 'interface.py'.
  • codebase_rag/providers/interface.py
    • Added new file: Defines the 'ModelProvider' abstract base class, establishing a common interface for all LLM providers.
  • codebase_rag/providers/litellm.py
    • Added new file: Implements the 'LiteLLMProvider' class, serving as the universal adapter for LiteLLM.
    • Handles various configuration parameters like API key, endpoint, project ID, region, and 'extra_headers'.
    • Manages model ID formatting (e.g., 'provider/model') and sets environment variables for specific providers like Vertex AI.
    • Integrates 'extra_headers' and 'thinking_budget' by passing them via 'ModelSettings' to 'OpenAIChatModel'.
  • codebase_rag/services/llm.py
    • Updated 'DocumentAnalyzer.init' to use a more flexible 'is_local' check for system prompts, including 'OLLAMA', 'LOCAL', and 'VLLM'.
  • codebase_rag/tests/integration/test_document_analyzer_integration.py
    • Removed 'Provider' import.
    • Updated 'mock_settings' to use 'openai' and 'gpt-4o' instead of Google-specific settings.
    • Replaced 'mock_genai_client' with 'mock_agent_run' (mocking 'Agent.run_sync').
    • Removed 'genai.Client' patching and added '_create_provider_model' patching.
    • Adjusted assertions to check 'mock_agent_run.assert_called_once()'.
    • Modified 'test_unsupported_provider_returns_error' to mock '_create_provider_model' with a 'ValueError'.
    • Updated 'test_handles_response_with_candidates' and 'test_handles_empty_response' to use 'Agent' mocking.
  • codebase_rag/tests/integration/test_tool_calling.py
    • Added a 'try-except' block around 'agent.run(prompt)' to skip tests on LLM connection errors.
    • Moved 'tracker', 'tracking_tools', and 'agent' fixtures to the end of the file.
  • codebase_rag/tests/test_document_analyzer.py
    • Removed '_NotSupportedClient' import and associated tests.
    • Updated 'mock_settings' to use 'Provider.OPENAI' and 'gpt-4o', and set various config fields to 'None'.
    • Replaced 'mock_genai_client' with 'mock_agent_run' and added 'mock_create_model'.
    • Removed 'genai.Client' patching.
    • Updated 'test_analyze_existing_file_returns_response' and 'test_analyze_with_absolute_path' to assert 'mock_agent_run.assert_called_once()'.
    • Added 'test_analyze_handles_agent_error' to test agent-related errors.
  • codebase_rag/tests/test_litellm_provider_full.py
    • Added new file: Contains comprehensive unit tests for 'LiteLLMProvider', covering dynamic provider loading, model ID parsing, environment variable handling, API key passing, and 'extra_headers' functionality.
  • codebase_rag/tests/test_provider_classes.py
    • Removed 'GoogleProvider', 'OpenAIProvider', 'OllamaProvider' imports and tests.
    • Updated 'TestProviderRegistry' to assert 'LiteLLMProvider' instances and a larger number of providers from 'list_providers'.
    • Modified 'CustomProvider' to inherit from the new 'ModelProvider' interface and return 'str' for 'provider_name'.
    • Added 'TestLiteLLMProvider' with tests for initialization, 'create_model', and Vertex AI environment variables.
  • codebase_rag/tools/document_analyzer.py
    • Removed the '_NotSupportedClient' class and Google-specific client initialization.
    • Removed '_extract_response_text' and '_handle_analyze_error' methods.
    • Updated the 'analyze' method to use '_create_provider_model' and 'pydantic_ai.Agent' for LLM interactions, directly passing binary content.
    • Simplified error handling to catch '(ValueError, OSError)' and a generic 'Exception'.
  • docs/LLM_CONFIGURATION.md
    • Added new file: Provides a detailed guide on LLM configuration, covering environment variables, CLI flags, specific provider setups (OpenAI, Anthropic, Gemini, Ollama, DeepSeek, Azure, Groq), advanced configurations (API Gateways, Multi-Model Strategy), troubleshooting, and best practices.
  • docs/SUPPORTED_PROVIDERS.md
    • Added new file: Lists all LLM providers and models dynamically supported through the LiteLLM integration, categorized for easy reference.
  • pyproject.toml
    • Added 'litellm>=1.52.0' to the project dependencies.
  • uv.lock
    • Updated 'graph-code' version to '0.0.50'.
    • Added 'litellm' and its dependency 'fastuuid' to the lock file.
Activity
  • The pull request introduces a major architectural shift by integrating LiteLLM as a universal backend for LLM interactions.
  • Significant refactoring was performed, including the removal of three legacy provider-specific classes and the introduction of two new core files for the universal provider and its interface.
  • Comprehensive documentation has been added to guide users through the new LLM configuration process and list supported models.
  • New tests specifically for the LiteLLM provider were added, and existing tests for the 'DocumentAnalyzer' were updated to reflect the new backend, ensuring functionality and stability.
  • Dependency management files ('pyproject.toml' and 'uv.lock') were updated to include 'litellm' and its sub-dependencies.
  • Review comments from 'gemini-code-assist[bot]' and 'greptile-apps[bot]' highlighted potential issues with module-level state mutation for 'litellm.extra_headers' and 'os.environ', unreachable code in 'constants.py', and a regression in error handling specificity in 'document_analyzer.py'.
  • Further review comments from 'Copilot' echoed concerns about global state mutation, incomplete validation in 'LiteLLMProvider.validate_config', ignored 'thinking_budget' parameters, incorrect model ID parsing, and unhandled 'service_account_file' parameters.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 files reviewed, 5 comments

Edit Code Review Agent Settings | Greptile

@whoisjayd
Copy link
Contributor Author

/gemini review

@whoisjayd
Copy link
Contributor Author

@greptile

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This is an excellent pull request that significantly refactors the LLM provider architecture to use litellm as a universal backend. This change greatly increases the number of supported LLM providers and simplifies the configuration and codebase by removing provider-specific classes. The introduction of extra_headers support is also a valuable addition for integrating with API gateways. The code changes are well-structured, and the new documentation is comprehensive and very helpful for users. I've found a couple of minor issues in the new tests, but overall, this is a fantastic improvement for the project.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

6 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

@whoisjayd
Copy link
Contributor Author

/gemini review

@whoisjayd
Copy link
Contributor Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is an excellent and significant refactoring that unifies the LLM backend by introducing a universal LiteLLMProvider. This greatly enhances the project's flexibility, adding support for over 100 LLM providers and enabling integration with API gateways through custom headers. The legacy provider-specific classes have been cleanly removed, and the configuration has been centralized and improved. The addition of comprehensive documentation and a thorough test suite, including concurrency tests, demonstrates high-quality engineering.

My review includes a suggestion to complete an incomplete concurrency test and a recommendation to add back some core system settings to the .env.example file for user clarity. Overall, this is a fantastic contribution that significantly improves the project's architecture and usability.

@whoisjayd
Copy link
Contributor Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This is an excellent and significant refactoring that replaces the specific provider implementations with a universal LiteLLM backend. This greatly expands model compatibility, simplifies configuration, and reduces maintenance. The introduction of support for extra headers for API gateways is a great addition. The code is well-structured, and the inclusion of comprehensive tests, especially for concurrency, is commendable. I have found one potential issue with model string construction that could affect models with colons in their names, but otherwise, this is a very solid pull request.

@whoisjayd

This comment was marked as resolved.

@whoisjayd
Copy link
Contributor Author

🤷

@whoisjayd
Copy link
Contributor Author

This is i guess my last attempt 😶‍🌫️

@whoisjayd
Copy link
Contributor Author

/gemini review

@whoisjayd
Copy link
Contributor Author

@greptile

@whoisjayd
Copy link
Contributor Author

/gemini summary

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a major and well-executed refactoring to replace the multi-provider LLM architecture with a universal backend using LiteLLM. This is a significant improvement that enables support for over 100 providers. The changes are extensive, touching configuration, provider implementation, documentation, and tests. The new LiteLLMProvider is robust, with considerations for thread safety and detailed error handling. The documentation has been significantly expanded and improved, which will be great for users. The test suite has also been updated and expanded with new tests for concurrency and the new provider, which is excellent. Overall, this is a high-quality contribution. I have one suggestion for improvement regarding header validation, as detailed in the comment.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

This pull request introduces a significant architectural overhaul to the system's Large Language Model (LLM) integration. By transitioning from a fragmented, provider-specific setup to a unified LiteLLM backend, the project dramatically expands its compatibility with a vast array of LLM services. This change not only simplifies the codebase and enhances maintainability but also provides a flexible and future-proof foundation for interacting with diverse LLM providers and advanced features like custom API gateways.

Highlights

  • Universal LLM Backend: The legacy multi-provider architecture (Google, OpenAI, Ollama specific classes) has been replaced with a single, universal LiteLLMProvider, enabling support for over 100 LLM providers including OpenAI, Anthropic, Gemini, DeepSeek, Ollama, and Azure without requiring code changes for new integrations.
  • Extra Headers Support: Support for extra_headers has been introduced in model configurations, facilitating integration with third-party API gateways like Portkey and Helicone, complete with robust validation for security.
  • Dynamic Provider Registry: The constants.py file now dynamically lists available providers by querying the installed litellm version, ensuring up-to-date support and caching the results for efficiency.
  • Document Analyzer Refactor: The DocumentAnalyzer tool has been updated to utilize the new unified LiteLLM backend and pydantic_ai.Agent, removing its previous dependency on the google-generativeai SDK.
  • Comprehensive Documentation: New documentation files (docs/LLM_CONFIGURATION.md, docs/SUPPORTED_PROVIDERS.md, docs/getting-started/quick-start.md, docs/usage/basic-usage.md, docs/advanced/code-optimization.md, docs/advanced/graph-export.md, docs/advanced/real-time-updates.md) have been added to guide users on configuring LLMs and viewing the extensive list of supported models and features.
  • Thread-Safe Configuration: A context manager (_vertex_env_context) has been implemented to ensure thread-safe handling of environment variables for Vertex AI configurations, preventing leakage between concurrent requests.
Changelog
  • .env.example
    • Completely overhauled the example environment file with detailed configuration options for various LLM providers (Ollama, Gemini, OpenAI, Anthropic, Groq, Azure, Vertex AI).
    • Added sections for advanced features like API Gateway integration and thinking budget.
    • Included sections for model naming conventions, automatic features, popular model recommendations, and troubleshooting tips.
    • Moved core system settings (Memgraph, repository path) to a separate, less prominent section.
  • README.md
    • Added a Code Coverage badge to the badges section.
    • Introduced a 'Quick Links' section with direct links to new documentation pages for quick start, LLM configuration, supported providers, and contributing.
    • Updated the 'Latest News' section to highlight the new Universal LLM Support via LiteLLM.
    • Expanded the installation instructions for cmake and ripgrep to include Linux (CentOS/RHEL/Rocky/Alma) and Windows (Chocolatey, Scoop, winget) platforms, along with a universal fallback.
    • Simplified the 'Usage' section, replacing detailed step-by-step instructions with a 'Quick Start' and 'Advanced Features' overview, linking to new dedicated documentation files.
    • Updated references from cgr to graph-code in CLI examples.
    • Added litellm to the list of project dependencies.
  • codebase_rag/config.py
    • Added json, re, and warnings imports.
    • Introduced _validate_header function for secure HTTP header validation (CRLF prevention, size limits, dangerous header blocking).
    • Added extra_headers: dict[str, str] | None to the ModelConfig dataclass.
    • Added ORCHESTRATOR_EXTRA_HEADERS and CYPHER_EXTRA_HEADERS fields to AppConfig.
    • Implemented parse_json_headers as a field_validator to correctly parse JSON strings from environment variables into dictionaries for extra_headers.
    • Updated _get_default_config to retrieve and assign extra_headers to the ModelConfig instance.
    • Modified parse_model_string to prioritize / as a provider/model delimiter and issue a DeprecationWarning for the old : delimiter.
  • codebase_rag/constants.py
    • Added a docstring to the Provider enum clarifying its role as a static subset.
    • Added LITELLM, GROQ, and MISTRAL to the Provider enum.
    • Implemented get_all_providers() function to dynamically fetch and cache the full list of supported providers from the litellm library.
  • codebase_rag/logs.py
    • Added new log messages related to the real-time watcher: WATCHER_UPDATE_FAILED, WATCHER_FLUSH_FAILED, WATCHER_INTERRUPT, and WATCHER_UNEXPECTED_ERROR.
  • codebase_rag/main.py
    • Refactored _create_configuration_table to display orchestrator and cypher endpoints more generically, removing specific checks for Ollama endpoints.
    • Adjusted _create_model_from_string and _update_single_model_setting to correctly handle the LOCAL provider type and refine the logic for setting Ollama endpoints.
  • codebase_rag/parsers/stdlib_extractor.py
    • Modified _resolve_js_entity_module_path to consistently strip the last component of a fully qualified name for JavaScript/TypeScript entities, handling both PascalCase and camelCase entity names.
  • codebase_rag/providers/base.py
    • Removed the deprecated GoogleProvider, OpenAIProvider, and OllamaProvider classes.
    • Updated PROVIDER_REGISTRY to map all common providers to the new LiteLLMProvider.
    • Modified get_provider to use LiteLLMProvider as a fallback for any unknown provider and to handle type casting.
    • Updated list_providers to include dynamically discovered providers from litellm in addition to the statically defined ones.
  • codebase_rag/providers/interface.py
    • Added new file: Defines the ModelProvider abstract base class, establishing a common interface for all LLM providers with abstract methods for create_model, validate_config, and provider_name.
  • codebase_rag/providers/litellm.py
    • Added new file: Implements the LiteLLMProvider class, serving as the universal adapter for LiteLLM.
    • Includes _vertex_env_context as a context manager for thread-safe handling of Vertex AI environment variables.
    • Handles various configuration parameters such as API key, endpoint, project ID, region, provider type, thinking budget, service account file, and extra headers.
    • Manages model ID formatting (e.g., provider/model) and integrates extra_headers and thinking_budget into ModelSettings.
    • Implements robust error handling for litellm exceptions like RateLimitError, Timeout, and InvalidRequestError.
  • codebase_rag/services/llm.py
    • Updated the CypherService.__init__ method to use a more flexible is_local check for determining system prompts, now including OLLAMA, LOCAL, and VLLM providers.
  • codebase_rag/tests/conftest.py
    • Imported QueryProtocol.
    • Modified mock_ingestor fixture to register QueryProtocol with the mocked MemgraphIngestor and mock additional methods like fetch_all, execute_write, ensure_node_batch, ensure_relationship_batch, and flush_all.
    • Added mocks for remove_file_from_state and _process_function_calls to the mock_updater fixture.
  • codebase_rag/tests/integration/test_document_analyzer_integration.py
    • Removed Provider import.
    • Updated mock_settings to use openai as the provider and gpt-4o as the model, replacing Google-specific settings.
    • Replaced mock_genai_client fixture with mock_agent_run to mock Agent.run_sync.
    • Removed patching for genai.Client and added patching for _create_provider_model.
    • Adjusted test assertions to check mock_agent_run.assert_called_once().
    • Modified test_unsupported_provider_returns_error to mock _create_provider_model with a ValueError to simulate provider errors.
    • Updated test_handles_response_with_candidates and test_handles_empty_response to use Agent mocking for response handling.
  • codebase_rag/tests/integration/test_shell_command_integration.py
    • Added shutil import.
    • Added @pytest.mark.skipif decorators to test_rg_searches_content, test_cat_pipe_rg, and test_find_pipe_rg_pipe_wc to skip these tests if ripgrep is not installed.
  • codebase_rag/tests/integration/test_tool_calling.py
    • Added a try-except block around agent.run(prompt) to skip tests if an LLM connection error occurs.
    • Moved the tracker, tracking_tools, and agent fixtures to the end of the file.
  • codebase_rag/tests/test_build_binary.py
    • Updated import paths for _build_package_args and _get_treesitter_packages from build_binary to scripts.build_binary.
    • Updated patch targets for toml.load to reflect the new module path.
  • codebase_rag/tests/test_cli_smoke.py
    • Increased the timeout for test_help_command_works to 45 seconds.
    • Added logic to remove ANSI escape codes from stdout for more robust assertion of help command output.
  • codebase_rag/tests/test_document_analyzer.py
    • Removed _NotSupportedClient import and associated tests.
    • Updated mock_settings to use Provider.OPENAI and gpt-4o as the default, and explicitly set various config fields to None.
    • Replaced mock_genai_client fixture with mock_agent_run and added mock_create_model fixture.
    • Removed patching for genai.Client.
    • Updated test_analyze_existing_file_returns_response and test_analyze_with_absolute_path to assert mock_agent_run.assert_called_once().
    • Added test_analyze_handles_agent_error to verify error handling when the agent encounters an exception.
  • codebase_rag/tests/test_github_issues_integration.py
    • Updated test cases for parse_model_string to use / as the provider/model delimiter instead of : for consistency with the new convention.
  • codebase_rag/tests/test_litellm_provider_concurrent.py
    • Added new file: Contains unit tests for LiteLLMProvider to verify thread safety, specifically for concurrent Vertex AI configurations (ensuring no environment variable leakage) and concurrent extra headers (ensuring no collision).
  • codebase_rag/tests/test_litellm_provider_full.py
    • Added new file: Provides comprehensive unit tests for LiteLLMProvider, covering dynamic provider loading, model ID parsing, environment variable handling, API key passing, extra headers functionality, service account file path resolution, timeout configuration, Vertex AI environment cleanup, and thinking budget integration.
  • codebase_rag/tests/test_provider_classes.py
    • Removed imports and tests for GoogleProvider, OpenAIProvider, and OllamaProvider.
    • Updated TestProviderRegistry to assert LiteLLMProvider instances and verify that list_providers returns a larger, dynamically generated list of providers.
    • Modified CustomProvider in test_register_custom_provider to inherit from the new ModelProvider interface and return a str for provider_name.
    • Added TestLiteLLMProvider with tests for initialization, create_model, and Vertex AI environment variable handling.
  • codebase_rag/tests/test_provider_configuration.py
    • Updated test cases for test_custom_model_names_with_colons to use / as the provider/model delimiter instead of :.
  • codebase_rag/tests/test_python_standard_library_imports.py
    • Added tempfile import.
    • Modified mock_updater to create a temporary directory for the test repository, ensuring test isolation and cleanup.
  • codebase_rag/tests/test_shell_command.py
    • Added shutil and sys imports.
    • Added @pytest.mark.skipif decorators to test_find_with_wc (for Windows) and test_rg_in_pipeline (if ripgrep is not installed).
  • codebase_rag/tests/test_stdlib_extractor.py
    • Modified several test cases (test_js_stdlib_lowercase_entity_without_node, test_ts_lowercase_returns_unchanged, test_js_extractor_fallback_on_entity_not_found, test_js_extractor_fallback_on_json_decode_error, test_js_extractor_fallback_on_timeout) to reflect the updated JavaScript/TypeScript standard library extraction logic, which now strips the module path more aggressively.
  • codebase_rag/tools/document_analyzer.py
    • Removed the _NotSupportedClient class and Google-specific client initialization logic.
    • Removed _extract_response_text and _handle_analyze_error methods, streamlining error handling.
    • Updated the analyze method to use _create_provider_model and pydantic_ai.Agent for LLM interactions, directly passing binary content. Error handling is now more generic, catching ValueError, OSError, and other Exception types.
  • codebase_rag/tools/health_checker.py
    • Improved the check_external_tool function to handle cases where the which command returns no output, providing a more informative error message.
  • codebase_rag/tools/shell_command.py
    • Enhanced the _is_dangerous_rm_path function to improve path resolution and checks for dangerous rm targets, including better handling of absolute paths, symlinks, and system directories.
  • codebase_rag/types_defs.py
    • Added extra_headers: dict[str, str] | None to the ModelConfigKwargs TypedDict.
  • codebase_rag/unixcoder.py
    • Added runtime checks for self.nextYs and self.prevKs to prevent IndexError in getCurrentState and getCurrentOrigin if these lists are empty.
    • Added checks for the length of self.nextYs before accessing elements in advance and getFinal to prevent IndexError.
  • docs/advanced/code-optimization.md
    • Added new file: Provides detailed documentation for AI-powered code optimization, including quick start, how it works, example sessions, reference document support, optimization categories, CLI options, and best practices.
  • docs/advanced/graph-export.md
    • Added new file: Provides detailed documentation for exporting and analyzing graph data, including quick export methods, working with exported data, use cases, and export format.
  • docs/advanced/real-time-updates.md
    • Added new file: Provides detailed documentation for real-time graph updates, including what it does, basic usage, custom Memgraph settings, multi-terminal workflow, what gets watched, performance considerations, and troubleshooting.
  • docs/getting-started/claude-code-setup.md
    • Renamed from docs/claude-code-setup.md to docs/getting-started/claude-code-setup.md.
    • Updated related documentation links.
  • docs/getting-started/quick-start.md
    • Added new file: Provides a quick start guide for LLM setup, including choosing a provider, configuration examples for Ollama, Google Gemini, OpenAI, and Anthropic Claude, and instructions on how to run the system.
  • docs/llm/configuration.md
    • Added new file: Provides a comprehensive guide on LLM configuration, covering detailed provider setups (OpenAI, Anthropic, Gemini, Ollama, DeepSeek, Groq, Azure, Vertex AI), advanced features (multi-model strategy, API gateway integration, thinking budget, CLI override), troubleshooting, model recommendations, and environment variable reference.
  • docs/llm/supported-providers.md
    • Added new file: Lists all LLM providers and models dynamically supported through the LiteLLM integration, categorized for easy reference.
  • docs/usage/basic-usage.md
    • Added new file: Provides a basic usage guide, including steps to parse a repository, query the codebase with examples, and common CLI arguments.
  • pyproject.toml
    • Added litellm>=1.52.0 to the project dependencies.
  • realtime_updater.py
    • Modified _is_relevant to use path.relative_to(self.updater.repo_path) for more accurate filtering of ignore patterns.
    • Added a try-except block around the file processing logic in dispatch to catch and log errors during updates, including flushing pending changes.
    • Added error logging for KeyboardInterrupt and generic Exception in _run_watcher_loop.
  • scripts/build_binary.py
    • Renamed from build_binary.py to scripts/build_binary.py.
    • Improved _get_treesitter_packages function to handle various version specifiers more robustly when extracting package names.
  • scripts/code_to_text.sh
    • Renamed from optimize/code_to_text.sh to scripts/code_to_text.sh.
  • uv.lock
    • Updated graph-code version to 0.0.50.
    • Added litellm and its dependency fastuuid to the lock file, reflecting the new dependencies.
Ignored Files
  • Ignored by pattern: .github/workflows/** (2)
    • .github/workflows/build-binaries.yml
    • .github/workflows/ci.yml
Activity
  • The pull request introduces a major architectural shift by integrating LiteLLM as a universal backend for LLM interactions.
  • Significant refactoring was performed, including the removal of three legacy provider-specific classes and the introduction of two new core files for the universal provider and its interface.
  • Comprehensive documentation has been added to guide users through the new LLM configuration process and list supported models.
  • New tests specifically for the LiteLLM provider were added, and existing tests for the DocumentAnalyzer were updated to reflect the new backend, ensuring functionality and stability.
  • Dependency management files (pyproject.toml and uv.lock) were updated to include litellm and its sub-dependencies.
  • Automated review bots (Gemini Code Assist and Greptile) provided feedback on potential issues, including module-level state mutation for litellm.extra_headers and os.environ, unreachable code, regression in error handling specificity, use of # type: ignore, loose type signatures, validate_config being a no-op, thinking_budget being ignored, incorrect model ID parsing, extra_headers type mismatch in AppConfig, service_account_file being ignored, local model detection logic, API key validation, ModelConfigKwargs missing extra_headers, extra_body or None redundancy, test assertions for ModelSettings vs dict, .env.example completeness, test for concurrent headers, and str(value) for header validation.
  • The author addressed several of these concerns in subsequent commits, such as adding extra_headers to ModelConfigKwargs, implementing _vertex_env_context for thread-safe environment variable handling, improving parse_json_headers validation, refining full_model_id construction, enhancing LiteLLMProvider.validate_config with API key checks, passing thinking_budget to extra_body, and adding a test for concurrent headers. Some concerns were dismissed by the author as incorrect or automated.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

6 files reviewed, 10 comments

Edit Code Review Agent Settings | Greptile

@whoisjayd
Copy link
Contributor Author

@gemini-code-assist @greptile

ModelSettings is a TypedDict (returns dict, not BaseModel). Your suggestions for attribute access don't apply here - dict access is correct.
Check
https://github.com/pydantic/pydantic-ai/blob/f74a093ae387b3bc92970c65eb6eef81e4be2b29/pydantic_ai_slim/pydantic_ai/settings.py#L7

Keep as-is or create Pydantic wrapper?

@gemini-code-assist
Copy link
Contributor

Thank you for the clarification, @whoisjayd. You are absolutely correct that ModelSettings is a TypedDict, and therefore, dictionary-style access is indeed the appropriate and correct way to interact with it. My apologies for the oversight in the previous review comment regarding this specific detail.

Given that pydantic-ai itself defines ModelSettings as a TypedDict (as you pointed out with the link to the source code), it is best to keep it as-is. TypedDict is the correct tool for providing type hints for dictionary structures, and using dictionary access aligns with its intended use. Creating a Pydantic BaseModel wrapper would introduce an unnecessary layer of abstraction and potentially break compatibility with how pydantic-ai expects ModelSettings to be handled. So, please keep it as-is.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 5, 2026

You're correct. ModelSettings is a TypedDict, not a BaseModel, so dictionary access (settings["extra_headers"]) is the proper way to access its fields.

Looking at your test code (lines 123, 36, etc.), your current implementation using settings["key"] is correct for a TypedDict. The review comment suggesting attribute access (settings.extra_headers) would only apply if it were a Pydantic BaseModel.

Recommendation: Keep as-is

The TypedDict approach is appropriate here since:

  1. PydanticAI defines ModelSettings as a TypedDict for flexibility
  2. Dictionary access is the standard interface for TypedDict
  3. Your tests correctly validate this structure

No changes needed - your implementation matches PydanticAI's design.

@whoisjayd
Copy link
Contributor Author

whoisjayd commented Feb 5, 2026

image

https://github.com/whoisjayd/code-graph-rag/blob/feature/litellm-universal-backend/codebase_rag/embedder.py

@vitali87 The failing test appears to be caused by a transient network issue rather than a code regression, so I’ve left it unchanged for now. I believe it can be mitigated with the cache handling fix shown above.

Please review the PR when you have a chance

Also i have noticed you haven't set codecov token in secrets it would be better to store it : https://app.codecov.io/gh/vitali87/code-graph-rag

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

1 participant