From fc2ef363da02fff6663b6a72889e6cf98fce3873 Mon Sep 17 00:00:00 2001 From: Kyle D Date: Fri, 27 Feb 2026 04:18:53 +0000 Subject: [PATCH 1/4] feat: add Avian as an LLM provider Add Avian (https://api.avian.io) as a supported LLM supplier in quivr-core. Avian provides an OpenAI-compatible API with access to models like DeepSeek-V3.2, Kimi-K2.5, GLM-5, and MiniMax-M2.5. - Add AVIAN to DefaultModelSuppliers enum - Add model configs with context/output token limits - Add AVIAN supplier handling in LLMEndpoint using ChatOpenAI (OpenAI-compatible, defaults to https://api.avian.io/v1) - Add test for Avian endpoint configuration --- core/quivr_core/llm/llm_endpoint.py | 10 ++++++++++ core/quivr_core/rag/entities/config.py | 19 +++++++++++++++++++ core/tests/test_llm_endpoint.py | 20 +++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/core/quivr_core/llm/llm_endpoint.py b/core/quivr_core/llm/llm_endpoint.py index 524e4d5bc9fe..55f4aee162b0 100644 --- a/core/quivr_core/llm/llm_endpoint.py +++ b/core/quivr_core/llm/llm_endpoint.py @@ -291,6 +291,16 @@ def from_config(cls, config: LLMEndpointConfig = LLMEndpointConfig()): max_tokens=config.max_output_tokens, temperature=config.temperature, ) + elif config.supplier == DefaultModelSuppliers.AVIAN: + _llm = ChatOpenAI( + model=config.model, + api_key=SecretStr(config.llm_api_key) + if config.llm_api_key + else None, + base_url=config.llm_base_url or "https://api.avian.io/v1", + max_completion_tokens=config.max_output_tokens, + temperature=config.temperature, + ) else: _llm = ChatOpenAI( diff --git a/core/quivr_core/rag/entities/config.py b/core/quivr_core/rag/entities/config.py index ad9b38366a89..c948ceaa8248 100644 --- a/core/quivr_core/rag/entities/config.py +++ b/core/quivr_core/rag/entities/config.py @@ -75,6 +75,7 @@ class DefaultModelSuppliers(str, Enum): MISTRAL = "mistral" GROQ = "groq" GEMINI = "gemini" + AVIAN = "avian" class LLMConfig(QuivrBaseConfig): @@ -275,6 +276,24 @@ class LLMModelConfig: tokenizer_hub="Quivr/gemini-tokenizer", ), }, + DefaultModelSuppliers.AVIAN: { + "deepseek/deepseek-v3.2": LLMConfig( + max_context_tokens=164000, + max_output_tokens=65000, + ), + "moonshotai/kimi-k2.5": LLMConfig( + max_context_tokens=131000, + max_output_tokens=8192, + ), + "z-ai/glm-5": LLMConfig( + max_context_tokens=131000, + max_output_tokens=16384, + ), + "minimax/minimax-m2.5": LLMConfig( + max_context_tokens=1000000, + max_output_tokens=1000000, + ), + }, } @classmethod diff --git a/core/tests/test_llm_endpoint.py b/core/tests/test_llm_endpoint.py index c26570591a0d..58fb74d770d5 100644 --- a/core/tests/test_llm_endpoint.py +++ b/core/tests/test_llm_endpoint.py @@ -3,7 +3,7 @@ import pytest from langchain_core.language_models import FakeListChatModel from pydantic import ValidationError -from quivr_core.rag.entities.config import LLMEndpointConfig +from quivr_core.rag.entities.config import DefaultModelSuppliers, LLMEndpointConfig from quivr_core.llm import LLMEndpoint @@ -46,3 +46,21 @@ def test_llm_endpoint_constructor(): ) assert not llm_endpoint.supports_func_calling() + + +@pytest.mark.base +def test_llm_endpoint_avian(): + from langchain_openai import ChatOpenAI + + config = LLMEndpointConfig( + supplier=DefaultModelSuppliers.AVIAN, + model="deepseek/deepseek-v3.2", + llm_api_key="test", + ) + llm = LLMEndpoint.from_config(config) + + assert llm.supports_func_calling() + assert isinstance(llm._llm, ChatOpenAI) + assert llm._llm.openai_api_base == "https://api.avian.io/v1" + assert config.max_output_tokens == 65000 + assert config.max_context_tokens <= 164000 From ac9fa033ba16fab4ea356711353b2cbbcb6b8102 Mon Sep 17 00:00:00 2001 From: Kyle D Date: Tue, 3 Mar 2026 19:47:09 +0000 Subject: [PATCH 2/4] fix(docs): fix ReadTheDocs build by resolving dependency conflict and path issue Update megaparse-sdk from 0.1.10 to 0.1.11 in docs lock files to satisfy quivr-core's requirement of megaparse-sdk>=0.1.11. Also fix the ${PROJECT_ROOT} variable in the RTD build commands which was not being resolved by uv, causing it to fall back to PyPI instead of using the local quivr-core source. Fixed mkdocs configuration path to point to the correct docs/mkdocs.yml. Co-Authored-By: Claude Opus 4.6 --- .readthedocs.yaml | 6 ++---- docs/requirements-dev.lock | 2 +- docs/requirements.lock | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 132b5f1df010..eaa02dabe94a 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -14,12 +14,10 @@ build: - asdf install uv latest - asdf global uv latest - uv venv + - sed -i "s|file:///\${PROJECT_ROOT}/\.\./core|file://$PWD/core|g" docs/requirements.lock - cd docs && UV_INDEX_STRATEGY=unsafe-first-match uv pip install -r requirements.lock - cd docs/ && ls -la && NO_COLOR=1 ../.venv/bin/mkdocs build --strict --site-dir $READTHEDOCS_OUTPUT/html --config-file mkdocs.yml - - mkdocs: - configuration: backend/docs/mkdocs.yml - + configuration: docs/mkdocs.yml diff --git a/docs/requirements-dev.lock b/docs/requirements-dev.lock index e35705e2d5b4..b144006b6b4c 100644 --- a/docs/requirements-dev.lock +++ b/docs/requirements-dev.lock @@ -217,7 +217,7 @@ mdit-py-plugins==0.4.1 # via jupytext mdurl==0.1.2 # via markdown-it-py -megaparse-sdk==0.1.10 +megaparse-sdk==0.1.11 # via quivr-core mergedeep==1.3.4 # via mkdocs diff --git a/docs/requirements.lock b/docs/requirements.lock index e35705e2d5b4..b144006b6b4c 100644 --- a/docs/requirements.lock +++ b/docs/requirements.lock @@ -217,7 +217,7 @@ mdit-py-plugins==0.4.1 # via jupytext mdurl==0.1.2 # via markdown-it-py -megaparse-sdk==0.1.10 +megaparse-sdk==0.1.11 # via quivr-core mergedeep==1.3.4 # via mkdocs From 86dc001e2fcd5b74eb6fa56212c7a8fa51a108ca Mon Sep 17 00:00:00 2001 From: Kyle D Date: Tue, 3 Mar 2026 19:48:37 +0000 Subject: [PATCH 3/4] fix(docs): install quivr-core from local source before other deps The previous approach of using sed to fix the file:// path in the lockfile didn't work because uv pip install can't resolve local file:// references in lockfiles. Instead, install quivr-core directly from the local ./core directory first, then install the remaining dependencies from the lock file (filtered to exclude the quivr-core line). Co-Authored-By: Claude Opus 4.6 --- .readthedocs.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index eaa02dabe94a..07af2bbad484 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -14,8 +14,8 @@ build: - asdf install uv latest - asdf global uv latest - uv venv - - sed -i "s|file:///\${PROJECT_ROOT}/\.\./core|file://$PWD/core|g" docs/requirements.lock - - cd docs && UV_INDEX_STRATEGY=unsafe-first-match uv pip install -r requirements.lock + - .venv/bin/python -m pip install ./core + - grep -v '^quivr-core' docs/requirements.lock > /tmp/requirements-filtered.lock && cd docs && UV_INDEX_STRATEGY=unsafe-first-match uv pip install -r /tmp/requirements-filtered.lock - cd docs/ && ls -la && NO_COLOR=1 ../.venv/bin/mkdocs build --strict --site-dir $READTHEDOCS_OUTPUT/html --config-file mkdocs.yml From 818dcedc8219b33322ef1776a88356d9bae0e144 Mon Sep 17 00:00:00 2001 From: Kyle D Date: Tue, 3 Mar 2026 19:49:42 +0000 Subject: [PATCH 4/4] fix(docs): use uv pip install for local quivr-core (venv has no pip) The uv-created venv doesn't include pip, so use 'uv pip install' directly instead of '.venv/bin/python -m pip install'. Co-Authored-By: Claude Opus 4.6 --- .readthedocs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 07af2bbad484..420d6bb1ba08 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -14,7 +14,7 @@ build: - asdf install uv latest - asdf global uv latest - uv venv - - .venv/bin/python -m pip install ./core + - uv pip install ./core - grep -v '^quivr-core' docs/requirements.lock > /tmp/requirements-filtered.lock && cd docs && UV_INDEX_STRATEGY=unsafe-first-match uv pip install -r /tmp/requirements-filtered.lock - cd docs/ && ls -la && NO_COLOR=1 ../.venv/bin/mkdocs build --strict --site-dir $READTHEDOCS_OUTPUT/html --config-file mkdocs.yml