Feat/add OpenAI reranking - #288
Conversation
📝 WalkthroughWalkthroughAdds multi-provider reranker support: new BaseReranker, provider implementations (Infinity, OpenAI-compatible), factory selection, discriminated config/models, env-driven compose fragments, pipeline/UI wiring, docs and Docker compose updates. Changes
Sequence Diagram(s)sequenceDiagram
actor Client
participant ConfigLoader as Config Loader
participant Factory as RerankerFactory
participant Reranker as Reranker Impl
participant External as External Reranker Service
Client->>ConfigLoader: load settings (provider, api_key, semaphore, top_k)
Client->>Factory: get_reranker(config)
Factory->>Factory: select provider by config.reranker.provider
Factory->>Reranker: instantiate InfinityReranker / OpenAIReranker
Factory-->>Client: return BaseReranker instance
Client->>Reranker: rerank(query, documents, top_k)
Reranker->>Reranker: acquire semaphore
Reranker->>External: API call (model, query, docs, top_n)
External-->>Reranker: ranked indices & scores
Reranker->>Reranker: map indices to Documents, set metadata["relevance_score"]
Reranker-->>Client: return reranked documents
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
b9a9bbd to
c4c3346
Compare
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (2)
openrag/components/reranker/openai.py (1)
48-55: Prefer bareraiseto preserve the original traceback.Using
raise ecan subtly alter the traceback. Use bareraiseinstead.- raise e + raise🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/components/reranker/openai.py` around lines 48 - 55, The except block in the reranker method logs the exception but re-raises using "raise e", which can alter the traceback; update the except handler that references logger, self.model_name and documents (the block that logs "Reranking failed") to re-raise the caught exception with a bare "raise" instead of "raise e" so the original traceback is preserved.openrag/components/reranker/infinity.py (1)
45-52: Prefer bareraiseto preserve the original traceback.- raise e + raise🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/components/reranker/infinity.py` around lines 45 - 52, In the except Exception as e block that logs reranking failures (the block referencing logger.error with model_name=self.model_name and documents_count=len(documents)), replace the current "raise e" with a bare "raise" so the original traceback is preserved; keep the logger.error call and exception variable for logging, but re-raise using "raise" instead of "raise e".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@extern/reranker/openai.yaml`:
- Around line 17-20: The service listens on container port 8000 but the Docker
port mapping uses ${RERANKER_PORT:-8003}, causing mismatch when RERANKER_PORT is
overridden; update the OpenAI vLLM service command blocks in openai.yaml to
include a --port flag using the same variable (e.g., add --port
${RERANKER_PORT:-8003}) in both the main reranker command and the reranker-cpu
command so the container binds to the same overridable port used in the mapping
and Hydra URLs, ensuring port alignment across RERANKER_PORT, the command lines,
and the port mapping.
In `@openrag/components/reranker/infinity.py`:
- Line 7: Change the relative-style import to an absolute import from the
openrag package: replace the current import of get_logger in infinity.py with an
absolute import that references openrag.utils.logger (e.g., import get_logger
from openrag.utils.logger) so the symbol get_logger is imported via the
project's top-level package name per coding guidelines.
In `@openrag/components/reranker/openai.py`:
- Line 5: Replace the relative import of the logger used in openai.py: instead
of importing get_logger from a local/relative utils module, change it to use the
project-root absolute package import so get_logger is imported from the
top-level utils.logger package (i.e., the absolute openrag package path) to
comply with the coding guideline; update the import statement that currently
references utils.logger to the absolute package import for get_logger.
- Around line 27-38: The Async HTTP call to self.rerank_url using
httpx.AsyncClient.post has no timeout and can hang; update the reranker to set a
request timeout (either by adding a configurable attribute like self.timeout on
the reranker class and passing timeout=self.timeout to client.post, or by
constructing httpx.AsyncClient(timeout=...) / using httpx.Timeout) so the post
call to self.rerank_url will fail fast on slow/unresponsive services; ensure the
timeout value is used in the call site that invokes httpx.AsyncClient().post and
consider catching httpx.TimeoutException where appropriate.
In `@openrag/components/reranker/test_rrf_reranking.py`:
- Line 5: The test file uses a relative import for BaseReranker; change the
relative import to an absolute one so it imports BaseReranker from the package
root (use the full module path, e.g. import BaseReranker from
openrag.components.reranker.base) to comply with project import guidelines and
avoid relative import issues.
---
Nitpick comments:
In `@openrag/components/reranker/infinity.py`:
- Around line 45-52: In the except Exception as e block that logs reranking
failures (the block referencing logger.error with model_name=self.model_name and
documents_count=len(documents)), replace the current "raise e" with a bare
"raise" so the original traceback is preserved; keep the logger.error call and
exception variable for logging, but re-raise using "raise" instead of "raise e".
In `@openrag/components/reranker/openai.py`:
- Around line 48-55: The except block in the reranker method logs the exception
but re-raises using "raise e", which can alter the traceback; update the except
handler that references logger, self.model_name and documents (the block that
logs "Reranking failed") to re-raise the caught exception with a bare "raise"
instead of "raise e" so the original traceback is preserved.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 30e4cae1-728d-4d4c-a208-50bebaee0198
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (16)
.hydra_config/config.yaml.hydra_config/reranker/base.yaml.hydra_config/reranker/infinity.yaml.hydra_config/reranker/openai.yamldocker-compose.yamldocs/content/docs/documentation/env_vars.mdextern/reranker/infinity.yamlextern/reranker/openai.yamlopenrag/app_front.pyopenrag/components/pipeline.pyopenrag/components/reranker.pyopenrag/components/reranker/__init__.pyopenrag/components/reranker/base.pyopenrag/components/reranker/infinity.pyopenrag/components/reranker/openai.pyopenrag/components/reranker/test_rrf_reranking.py
💤 Files with no reviewable changes (1)
- openrag/components/reranker.py
c4c3346 to
c254449
Compare
There was a problem hiding this comment.
Actionable comments posted: 5
♻️ Duplicate comments (1)
openrag/components/reranker/test_rrf_reranking.py (1)
5-5:⚠️ Potential issue | 🟡 MinorUse an absolute import for
BaseReranker.Line 5 uses a relative import; this should import from the
openragroot package.🔧 Proposed fix
-from .base import BaseReranker +from openrag.components.reranker.base import BaseRerankerAs per coding guidelines,
**/*.py: Use absolute imports from theopenrag/directory (which is the Python path root).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/components/reranker/test_rrf_reranking.py` at line 5, Replace the relative import in test_rrf_reranking.py with an absolute import from the package root: change the `.base` import to import BaseReranker from openrag.components.reranker.base so the file uses the project-root absolute import (e.g., use openrag.components.reranker.base -> BaseReranker).
🧹 Nitpick comments (5)
openrag/app_front.py (1)
128-128: Avoid hardcoding the all-partitions model ID in default selection.Line 128 hardcodes
"openrag-all", while model IDs are prefix-driven elsewhere. IfPARTITION_PREFIXchanges, default profile selection will silently break.♻️ Proposed change
- default=m.id == "openrag-all", + default=m.id == f"{PARTITION_PREFIX}all",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/app_front.py` at line 128, Replace the hardcoded model id check default=m.id == "openrag-all" with a construct that uses the PARTITION_PREFIX constant so the default selection follows the current prefix; for example, compare m.id to f"{PARTITION_PREFIX}-all" (or build it via PARTITION_PREFIX + "-all") so the default logic uses the dynamic PARTITION_PREFIX and will not break if the prefix changes.openrag/components/reranker/openai.py (1)
56-56: Use bareraiseto preserve original traceback.
raise eresets the traceback origin to this line. Useraiseto preserve the full stack trace for debugging.- raise e + raise🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/components/reranker/openai.py` at line 56, In the exception handler inside openrag/components/reranker/openai.py (the block that currently does "raise e"), replace the explicit re-raise with a bare "raise" to preserve the original traceback; locate the try/except around the relevant function (e.g., the reranker/OpenAI call handler) and change "raise e" to "raise" so the full stack trace is kept for debugging.openrag/components/reranker/infinity.py (1)
52-52: Use bareraiseto preserve original traceback.
raise eresets the traceback origin to this line. Useraiseto preserve the full stack trace for debugging.- raise e + raise🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/components/reranker/infinity.py` at line 52, Replace the bare "raise e" in the except block with a plain "raise" so the original traceback is preserved; locate the occurrence of "raise e" in openrag/components/reranker/infinity.py (the exception handling block where the code currently does "raise e") and change it to "raise" without an exception expression.openrag/components/reranker/__init__.py (1)
13-14: Type hintdictconflicts with attribute-style access.The parameter is typed as
dict, but line 14 accessesconfig.reranker.get("provider")using attribute notation. Hydra/OmegaConf configs support this, but the type hint is misleading.Suggested fix
+from omegaconf import DictConfig + class RerankerFactory: `@staticmethod` - def get_reranker(config: dict) -> BaseReranker: + def get_reranker(config: DictConfig) -> BaseReranker: provider = config.reranker.get("provider")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/components/reranker/__init__.py` around lines 13 - 14, The function get_reranker currently types its parameter as plain dict but uses attribute-style access (config.reranker.get(...)); update the type hint to reflect Hydra/OmegaConf usage (e.g., change the parameter type from dict to omegaconf.DictConfig or typing.Any) and add the corresponding import (from omegaconf import DictConfig) or use Any to silence type checkers so attribute access on config and config.reranker is valid; keep the function name get_reranker and return type BaseReranker unchanged.openrag/components/reranker/base.py (1)
10-10: Improve type annotation fordoc_listsparameter.The parameter is typed as
list[list]but should belist[list[Document]]to match the return type and usage.- def rrf_reranking(doc_lists: list[list], k: int = 60) -> list[Document]: + def rrf_reranking(doc_lists: list[list[Document]], k: int = 60) -> list[Document]:🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/components/reranker/base.py` at line 10, The doc_lists parameter in rrf_reranking is currently typed as list[list] which is too generic; update the annotation to list[list[Document]] so it accurately reflects that each inner list contains Document instances and matches the function's return type and usage; modify the def rrf_reranking(doc_lists: list[list], k: int = 60) -> list[Document]: signature to def rrf_reranking(doc_lists: list[list[Document]], k: int = 60) -> list[Document]: and adjust any imports or forward references (Document) if needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.hydra_config/reranker/openai.yaml:
- Line 6: The base_url currently falls back to
"http://reranker:${oc.env:RERANKER_PORT, 8000}" which incorrectly derives the
in-container service port from RERANKER_PORT; update the fallback to a fixed
in-container address by changing the base_url entry to use
"http://reranker:8000" as the default so it no longer references RERANKER_PORT
(keep the RERANKER_BASE_URL env override as-is and remove the nested reference
to RERANKER_PORT).
In `@docs/content/docs/documentation/env_vars.md`:
- Around line 240-241: The docs incorrectly state that RERANKER_PORT controls
the service port used internally; update the RERANKER_PORT/RERANKER_BASE_URL
documentation to clarify provider-specific behavior: state that for the OpenAI
provider inter-container traffic uses the fixed internal address reranker:8000
and RERANKER_PORT only documents the host-side port mapping (not an override of
the container's internal port), and show that RERANKER_BASE_URL falls back only
to host:port when appropriate but OpenAI should still target reranker:8000
internally.
In `@extern/reranker/openai.yaml`:
- Around line 21-23: The healthcheck currently hardcodes port 8000 while the run
flag --port uses ${RERANKER_PORT:-8000}, causing a mismatch when RERANKER_PORT
is overridden; either remove the --port flag in the run command so vLLM stays on
its default 8000, or update the healthcheck test command (the healthcheck test:
["CMD", "curl", "-f", "http://localhost:8000/health"]) to reference the same
environment variable (e.g., using ${RERANKER_PORT:-8000}) so it matches the
--port setting; locate and edit the --port flag and the healthcheck test entries
to apply one of these fixes.
In `@openrag/components/pipeline.py`:
- Line 23: The import in pipeline.py uses a relative path; change the import of
reranker types to an absolute import from the package root: replace the relative
import that references BaseReranker and RerankerFactory with an absolute import
from the openrag package (import BaseReranker and RerankerFactory using the
openrag.reranker module names) so the file imports BaseReranker and
RerankerFactory via the package root rather than a relative module path.
In `@openrag/components/reranker/infinity.py`:
- Line 37: InfinityReranker currently makes an unbounded call to rerank.asyncio
using self.client; update the Client initialization for InfinityReranker to pass
httpx_args with a timeout (matching OpenAIReranker’s 60s) so calls like
rerank.asyncio(...) cannot hang indefinitely. Locate the Infinity client
construction (the class InfinityReranker and where Client(...) is instantiated)
and add httpx_args={"timeout": httpx.Timeout(60.0)} (or equivalent numeric
timeout) to the Client(...) call, ensuring imports/reference to httpx.Timeout
are present and used when calling rerank.asyncio via self.client.
---
Duplicate comments:
In `@openrag/components/reranker/test_rrf_reranking.py`:
- Line 5: Replace the relative import in test_rrf_reranking.py with an absolute
import from the package root: change the `.base` import to import BaseReranker
from openrag.components.reranker.base so the file uses the project-root absolute
import (e.g., use openrag.components.reranker.base -> BaseReranker).
---
Nitpick comments:
In `@openrag/app_front.py`:
- Line 128: Replace the hardcoded model id check default=m.id == "openrag-all"
with a construct that uses the PARTITION_PREFIX constant so the default
selection follows the current prefix; for example, compare m.id to
f"{PARTITION_PREFIX}-all" (or build it via PARTITION_PREFIX + "-all") so the
default logic uses the dynamic PARTITION_PREFIX and will not break if the prefix
changes.
In `@openrag/components/reranker/__init__.py`:
- Around line 13-14: The function get_reranker currently types its parameter as
plain dict but uses attribute-style access (config.reranker.get(...)); update
the type hint to reflect Hydra/OmegaConf usage (e.g., change the parameter type
from dict to omegaconf.DictConfig or typing.Any) and add the corresponding
import (from omegaconf import DictConfig) or use Any to silence type checkers so
attribute access on config and config.reranker is valid; keep the function name
get_reranker and return type BaseReranker unchanged.
In `@openrag/components/reranker/base.py`:
- Line 10: The doc_lists parameter in rrf_reranking is currently typed as
list[list] which is too generic; update the annotation to list[list[Document]]
so it accurately reflects that each inner list contains Document instances and
matches the function's return type and usage; modify the def
rrf_reranking(doc_lists: list[list], k: int = 60) -> list[Document]: signature
to def rrf_reranking(doc_lists: list[list[Document]], k: int = 60) ->
list[Document]: and adjust any imports or forward references (Document) if
needed.
In `@openrag/components/reranker/infinity.py`:
- Line 52: Replace the bare "raise e" in the except block with a plain "raise"
so the original traceback is preserved; locate the occurrence of "raise e" in
openrag/components/reranker/infinity.py (the exception handling block where the
code currently does "raise e") and change it to "raise" without an exception
expression.
In `@openrag/components/reranker/openai.py`:
- Line 56: In the exception handler inside openrag/components/reranker/openai.py
(the block that currently does "raise e"), replace the explicit re-raise with a
bare "raise" to preserve the original traceback; locate the try/except around
the relevant function (e.g., the reranker/OpenAI call handler) and change "raise
e" to "raise" so the full stack trace is kept for debugging.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 80e4f456-6993-4a32-b4cc-ddad1d49e13c
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (16)
.hydra_config/config.yaml.hydra_config/reranker/base.yaml.hydra_config/reranker/infinity.yaml.hydra_config/reranker/openai.yamldocker-compose.yamldocs/content/docs/documentation/env_vars.mdextern/reranker/infinity.yamlextern/reranker/openai.yamlopenrag/app_front.pyopenrag/components/pipeline.pyopenrag/components/reranker.pyopenrag/components/reranker/__init__.pyopenrag/components/reranker/base.pyopenrag/components/reranker/infinity.pyopenrag/components/reranker/openai.pyopenrag/components/reranker/test_rrf_reranking.py
💤 Files with no reviewable changes (1)
- openrag/components/reranker.py
c254449 to
c85b13d
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (3)
openrag/components/reranker/infinity.py (1)
7-7: 🛠️ Refactor suggestion | 🟠 MajorUse absolute import from
openrag/directory.Per coding guidelines, imports should use absolute paths from the
openrag/directory.-from utils.logger import get_logger +from openrag.utils.logger import get_loggerAs per coding guidelines,
**/*.py: Use absolute imports from theopenrag/directory (which is the Python path root).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/components/reranker/infinity.py` at line 7, The import in infinity.py is using a relative/non-absolute path; update the import to use the absolute package path rooted at openrag (e.g., replace the current "from utils.logger import get_logger" with the absolute import from openrag, such as "from openrag.utils.logger import get_logger") so that the module resolution follows the project guideline; ensure you update any other imports in this file that reference utils or sibling packages to the openrag.* namespace as needed.openrag/components/pipeline.py (1)
23-23: 🛠️ Refactor suggestion | 🟠 MajorUse absolute import for reranker types/factory.
Line 23 uses a relative import which violates coding guidelines. Should import from the
openragpackage root.-from .reranker import BaseReranker, RerankerFactory +from openrag.components.reranker import BaseReranker, RerankerFactoryAs per coding guidelines,
**/*.py: Use absolute imports from theopenrag/directory (which is the Python path root).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/components/pipeline.py` at line 23, Replace the relative import in pipeline.py with an absolute import from the package root: change the statement that imports BaseReranker and RerankerFactory (currently "from .reranker import BaseReranker, RerankerFactory") to import them from openrag.reranker instead; update any references if necessary so functions/classes that use BaseReranker and RerankerFactory continue to resolve via the new absolute import.openrag/components/reranker/openai.py (1)
5-5: 🛠️ Refactor suggestion | 🟠 MajorUse absolute import from
openrag/directory.Per coding guidelines, imports should use absolute paths from the
openrag/directory.-from utils.logger import get_logger +from openrag.utils.logger import get_loggerAs per coding guidelines,
**/*.py: Use absolute imports from theopenrag/directory (which is the Python path root).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/components/reranker/openai.py` at line 5, The import in openrag/components/reranker/openai.py currently uses a non-absolute module path ("from utils.logger import get_logger"); update it to use an absolute import rooted at the project package (replace the relative-style import with the absolute path starting with openrag, e.g. import the get_logger from openrag.utils.logger) so it follows the repository's absolute-import guideline.
🧹 Nitpick comments (2)
openrag/components/reranker/infinity.py (1)
49-56: Use bareraiseto preserve full traceback.Same as
OpenAIReranker- use bareraiseinstead ofraise e.♻️ Minor improvement
except Exception as e: logger.error( "Reranking failed", error=str(e), model_name=self.model_name, documents_count=len(documents), ) - raise e + raise🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/components/reranker/infinity.py` around lines 49 - 56, The except block in the reranker (the try/except that logs "Reranking failed" using logger with model_name=self.model_name and documents_count=len(documents)) currently does "raise e", which drops the original traceback; change it to a bare "raise" so the original exception context/traceback is preserved after logging, keeping the same logger.error call and fields.openrag/components/reranker/openai.py (1)
49-56: Use bareraiseto preserve full traceback.Using
raise einstead of bareraisecan truncate the traceback in some Python versions.♻️ Minor improvement
except Exception as e: logger.error( "Reranking failed", error=str(e), model_name=self.model_name, documents_count=len(documents), ) - raise e + raise🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/components/reranker/openai.py` around lines 49 - 56, In the exception handler inside the reranker method (the except Exception as e block that logs "Reranking failed" and references self.model_name and len(documents)), replace the explicit re-raise "raise e" with a bare "raise" so the original traceback is preserved; keep the logger.error call as-is and only change the re-raise to bare raise to maintain full exception context.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@openrag/components/pipeline.py`:
- Line 23: Replace the relative import in pipeline.py with an absolute import
from the package root: change the statement that imports BaseReranker and
RerankerFactory (currently "from .reranker import BaseReranker,
RerankerFactory") to import them from openrag.reranker instead; update any
references if necessary so functions/classes that use BaseReranker and
RerankerFactory continue to resolve via the new absolute import.
In `@openrag/components/reranker/infinity.py`:
- Line 7: The import in infinity.py is using a relative/non-absolute path;
update the import to use the absolute package path rooted at openrag (e.g.,
replace the current "from utils.logger import get_logger" with the absolute
import from openrag, such as "from openrag.utils.logger import get_logger") so
that the module resolution follows the project guideline; ensure you update any
other imports in this file that reference utils or sibling packages to the
openrag.* namespace as needed.
In `@openrag/components/reranker/openai.py`:
- Line 5: The import in openrag/components/reranker/openai.py currently uses a
non-absolute module path ("from utils.logger import get_logger"); update it to
use an absolute import rooted at the project package (replace the relative-style
import with the absolute path starting with openrag, e.g. import the get_logger
from openrag.utils.logger) so it follows the repository's absolute-import
guideline.
---
Nitpick comments:
In `@openrag/components/reranker/infinity.py`:
- Around line 49-56: The except block in the reranker (the try/except that logs
"Reranking failed" using logger with model_name=self.model_name and
documents_count=len(documents)) currently does "raise e", which drops the
original traceback; change it to a bare "raise" so the original exception
context/traceback is preserved after logging, keeping the same logger.error call
and fields.
In `@openrag/components/reranker/openai.py`:
- Around line 49-56: In the exception handler inside the reranker method (the
except Exception as e block that logs "Reranking failed" and references
self.model_name and len(documents)), replace the explicit re-raise "raise e"
with a bare "raise" so the original traceback is preserved; keep the
logger.error call as-is and only change the re-raise to bare raise to maintain
full exception context.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: d11f8a4d-bebd-4cca-9b23-cdadac500c97
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (17)
.hydra_config/config.yaml.hydra_config/reranker/base.yaml.hydra_config/reranker/infinity.yaml.hydra_config/reranker/openai.yamldocker-compose.yamldocs/content/docs/documentation/env_vars.mdextern/reranker/infinity.yamlextern/reranker/openai.yamlopenrag/app_front.pyopenrag/components/pipeline.pyopenrag/components/reranker.pyopenrag/components/reranker/__init__.pyopenrag/components/reranker/base.pyopenrag/components/reranker/infinity.pyopenrag/components/reranker/openai.pyopenrag/components/reranker/test_rrf_reranking.pyquick_start/extern/infinity.yaml
💤 Files with no reviewable changes (1)
- openrag/components/reranker.py
✅ Files skipped from review due to trivial changes (4)
- .hydra_config/reranker/openai.yaml
- openrag/components/reranker/test_rrf_reranking.py
- .hydra_config/config.yaml
- .hydra_config/reranker/base.yaml
🚧 Files skipped from review as they are similar to previous changes (4)
- .hydra_config/reranker/infinity.yaml
- openrag/components/reranker/init.py
- docs/content/docs/documentation/env_vars.md
- extern/reranker/openai.yaml
be7afb2 to
96dd7e5
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (2)
openrag/components/reranker/openai.py (1)
16-17: Consider validating thatbase_urlis non-empty.If
config.reranker.base_urlis missing or empty,rerank_urlbecomes/rerank, which will fail at runtime. While the Hydra config should always provide a default, adding a guard or logging a warning would improve debuggability.🛡️ Optional defensive check
base_url = config.reranker.get("base_url", "").rstrip("/") + if not base_url: + logger.warning("base_url is empty; reranker requests will fail") self.rerank_url = f"{base_url}/rerank"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/components/reranker/openai.py` around lines 16 - 17, The code sets base_url = config.reranker.get("base_url", "").rstrip("/") and then self.rerank_url = f"{base_url}/rerank" without checking for an empty base_url; add a guard in the initializer that checks if base_url is falsy and either (a) raise a clear error (e.g., ValueError/RuntimeError) indicating config.reranker.base_url is required, or (b) log a warning and disable the reranker by not setting self.rerank_url (or setting it to None). Update the code paths that use self.rerank_url to handle the None/disabled state accordingly; reference the symbols base_url and self.rerank_url in openrag/components/reranker/openai.py when making the change.docs/content/docs/documentation/env_vars.md (1)
238-249: Consider clarifying thatRERANKER_BASE_URLdefault depends on the selected provider.The table shows
RERANKER_BASE_URLdefaulting tohttp://reranker:7997, but the "Reranker Providers" section indicates OpenAI-compatible endpoints use port8000. Users switching toopenaiprovider need to also setRERANKER_BASE_URL=http://reranker:8000(or the appropriate endpoint).A brief note or example showing the typical configuration for each provider would help avoid misconfiguration.
📝 Suggested clarification
| `RERANKER_BASE_URL` | `str` | `http://reranker:7997` | Base URL of the reranker service | + +> **Note:** The default `RERANKER_BASE_URL` is configured for the Infinity provider. When using `RERANKER_PROVIDER=openai`, set `RERANKER_BASE_URL=http://reranker:8000` (or your OpenAI-compatible endpoint).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/content/docs/documentation/env_vars.md` around lines 238 - 249, Update the RERANKER_BASE_URL documentation to clarify that its default host/port depends on RERANKER_PROVIDER; mention that when RERANKER_PROVIDER=infinity the typical default is http://reranker:7997 and when RERANKER_PROVIDER=openai the typical default is http://reranker:8000, and remind users to set RERANKER_API_KEY when using the openai provider; add a short note or example mapping next to the RERANKER_BASE_URL row and/or under the "Reranker Providers" section so readers know which base URL to use per provider.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@docs/content/docs/documentation/env_vars.md`:
- Around line 238-249: Update the RERANKER_BASE_URL documentation to clarify
that its default host/port depends on RERANKER_PROVIDER; mention that when
RERANKER_PROVIDER=infinity the typical default is http://reranker:7997 and when
RERANKER_PROVIDER=openai the typical default is http://reranker:8000, and remind
users to set RERANKER_API_KEY when using the openai provider; add a short note
or example mapping next to the RERANKER_BASE_URL row and/or under the "Reranker
Providers" section so readers know which base URL to use per provider.
In `@openrag/components/reranker/openai.py`:
- Around line 16-17: The code sets base_url = config.reranker.get("base_url",
"").rstrip("/") and then self.rerank_url = f"{base_url}/rerank" without checking
for an empty base_url; add a guard in the initializer that checks if base_url is
falsy and either (a) raise a clear error (e.g., ValueError/RuntimeError)
indicating config.reranker.base_url is required, or (b) log a warning and
disable the reranker by not setting self.rerank_url (or setting it to None).
Update the code paths that use self.rerank_url to handle the None/disabled state
accordingly; reference the symbols base_url and self.rerank_url in
openrag/components/reranker/openai.py when making the change.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: abfb09a3-21f0-421d-9ea3-87beb3471044
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (17)
.hydra_config/config.yaml.hydra_config/reranker/base.yaml.hydra_config/reranker/infinity.yaml.hydra_config/reranker/openai.yamldocker-compose.yamldocs/content/docs/documentation/env_vars.mdextern/reranker/infinity.yamlextern/reranker/openai.yamlopenrag/app_front.pyopenrag/components/pipeline.pyopenrag/components/reranker.pyopenrag/components/reranker/__init__.pyopenrag/components/reranker/base.pyopenrag/components/reranker/infinity.pyopenrag/components/reranker/openai.pyopenrag/components/reranker/test_rrf_reranking.pyquick_start/extern/infinity.yaml
💤 Files with no reviewable changes (1)
- openrag/components/reranker.py
✅ Files skipped from review due to trivial changes (5)
- openrag/components/reranker/test_rrf_reranking.py
- .hydra_config/reranker/openai.yaml
- openrag/components/pipeline.py
- .hydra_config/reranker/base.yaml
- extern/reranker/openai.yaml
🚧 Files skipped from review as they are similar to previous changes (7)
- .hydra_config/reranker/infinity.yaml
- docker-compose.yaml
- openrag/components/reranker/init.py
- quick_start/extern/infinity.yaml
- openrag/components/reranker/base.py
- openrag/components/reranker/infinity.py
- openrag/app_front.py
96dd7e5 to
c5a9a33
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
docs/content/docs/documentation/env_vars.md (1)
234-242: Consider documentingRERANKER_TIMEOUT.The PR objectives mention that
RERANKER_TIMEOUTwas added to make the OpenAI reranker respect the configured timeout (fixing a hardcodedtimeout=60.0issue). However, this variable is not documented in the environment variables table.If
RERANKER_TIMEOUTis now a supported configuration option, consider adding it to the documentation table alongsideRERANKER_SEMAPHORE.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/content/docs/documentation/env_vars.md` around lines 234 - 242, Add a new row for the environment variable RERANKER_TIMEOUT to the environment variables table so the docs reflect the new configuration; document its name `RERANKER_TIMEOUT`, type `float` (or `int` if preferred by implementation), a sensible default (e.g., `60.0` or the actual default used in code), and a short description like "Timeout in seconds for reranker requests (applies to OpenAI provider)"; place this entry next to `RERANKER_SEMAPHORE` so users can discover timeout and concurrency settings together.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@openrag/components/pipeline.py`:
- Line 54: The debug call is accessing a non-existent attribute
config.reranker.provider which will raise AttributeError because RerankerConfig
lacks a provider field; fix by changing the logger.debug call in pipeline.py to
use the safe dict access used elsewhere (config.reranker.get("provider")) or
alternatively add provider: str to the RerankerConfig model in
openrag/config/models.py so config.reranker.provider becomes valid; update the
logger.debug invocation (and any similar accesses) to use the chosen approach.
- Line 52: The code reads config.reranker.get("enabled", True) but
RerankerConfig exposes the flag as "enable", so change the lookup in the
Pipeline initializer to use config.reranker.get("enable", True) (or otherwise
read RerankerConfig.enable directly) so self.reranker_enabled correctly reflects
the configured value; update any related references where config.reranker is
accessed to use the "enable" key or the RerankerConfig attribute.
In `@openrag/components/reranker/openai.py`:
- Around line 14-15: Add an api_key field to the RerankerConfig model and ensure
OpenAIReranker reads it correctly; specifically, update the RerankerConfig
definition to include api_key (string, optional or required per project rules)
and then change OpenAIReranker to pull the key from the config object (e.g., use
config.reranker.api_key or the corresponding dict key consistently) so
config.reranker["api_key"] no longer raises a KeyError; also replace the
relative import from utils.logger with the absolute import from
openrag.utils.logger (references: RerankerConfig, OpenAIReranker, get_logger).
---
Nitpick comments:
In `@docs/content/docs/documentation/env_vars.md`:
- Around line 234-242: Add a new row for the environment variable
RERANKER_TIMEOUT to the environment variables table so the docs reflect the new
configuration; document its name `RERANKER_TIMEOUT`, type `float` (or `int` if
preferred by implementation), a sensible default (e.g., `60.0` or the actual
default used in code), and a short description like "Timeout in seconds for
reranker requests (applies to OpenAI provider)"; place this entry next to
`RERANKER_SEMAPHORE` so users can discover timeout and concurrency settings
together.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: c6ad371f-b875-43f8-acd0-42769e1d00f9
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (12)
docker-compose.yamldocs/content/docs/documentation/env_vars.mdextern/reranker/infinity.yamlextern/reranker/openai.yamlopenrag/app_front.pyopenrag/components/pipeline.pyopenrag/components/reranker/__init__.pyopenrag/components/reranker/base.pyopenrag/components/reranker/infinity.pyopenrag/components/reranker/openai.pyopenrag/components/reranker/test_rrf_reranking.pyquick_start/extern/infinity.yaml
✅ Files skipped from review due to trivial changes (5)
- openrag/components/reranker/test_rrf_reranking.py
- openrag/components/reranker/init.py
- quick_start/extern/infinity.yaml
- extern/reranker/openai.yaml
- openrag/components/reranker/infinity.py
🚧 Files skipped from review as they are similar to previous changes (3)
- extern/reranker/infinity.yaml
- openrag/app_front.py
- docker-compose.yaml
c5a9a33 to
f26e505
Compare
BREAKING CHANGE: docker-compose.yaml now includes
`extern/reranker/${RERANKER_PROVIDER:-infinity}.yaml` instead of
`extern/infinity.yaml`. Set RERANKER_PROVIDER=infinity or leave unset
to preserve existing behavior.
Add OpenAI-compatible reranker provider selectable via RERANKER_PROVIDER
(values: `infinity`, `openai`). New env vars: RERANKER_API_KEY, RERANKER_SEMAPHORE.
a3deac5 to
3e13b30
Compare
3e13b30 to
4ffafee
Compare
Make BaseReranker an abstract class with @AbstractMethod so missing implementations are caught at instantiation. Fix rrf_reranking type hint from list[list] to list[list[Document]].
Use dot notation consistently across InfinityReranker and pipeline.py, matching the style in OpenAIReranker. Remove redundant .get() fallbacks that duplicated (and in the case of semaphore, contradicted) Pydantic model defaults.
Each provider config now has its own correct base_url default (Infinity: http://reranker:7997, OpenAI: http://reranker:8000/v1), so the port-based URL construction is no longer needed and would produce wrong URLs for the OpenAI provider.
Create the client once in __init__ instead of per rerank() call so connection pooling is preserved.
Only import the selected provider so a missing optional dependency (e.g. infinity_client) doesn't break the other provider.
|
@CodeRabbit final review please |
|
Pleaaaase @CodeRabbit, do the review pretty please |
|
✅ Actions performedFull review triggered. |
|
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (2)
openrag/components/reranker/openai.py (1)
5-7:⚠️ Potential issue | 🟡 MinorUse absolute imports for project modules.
utils.loggerand.baseshould both be imported from theopenragpackage root here.♻️ Suggested fix
-from utils.logger import get_logger - -from .base import BaseReranker +from openrag.components.reranker.base import BaseReranker +from openrag.utils.logger import get_loggerAs per coding guidelines, "Use absolute imports from the
openrag/directory (which is the Python path root)".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/components/reranker/openai.py` around lines 5 - 7, The imports in openrag/components/reranker/openai.py use relative/project-root-escaping forms; replace from utils.logger import get_logger and from .base import BaseReranker with absolute imports from the openrag package (e.g., import get_logger from openrag.utils.logger and BaseReranker from openrag.components.reranker.base or the appropriate openrag path) so that get_logger and BaseReranker are imported via absolute module paths consistent with the project's import guidelines.openrag/components/reranker/infinity.py (1)
7-9:⚠️ Potential issue | 🟡 MinorUse absolute imports for project modules.
utils.loggerand.baseshould both be imported from theopenragpackage root here.♻️ Suggested fix
-from utils.logger import get_logger - -from .base import BaseReranker +from openrag.components.reranker.base import BaseReranker +from openrag.utils.logger import get_loggerAs per coding guidelines, "Use absolute imports from the
openrag/directory (which is the Python path root)".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/components/reranker/infinity.py` around lines 7 - 9, Replace relative/local imports with absolute imports from the openrag package root: change "from utils.logger import get_logger" to "from openrag.utils.logger import get_logger" and change "from .base import BaseReranker" to "from openrag.components.reranker.base import BaseReranker" so the module uses absolute project-root imports; update any other similar imports in this file to match the same pattern.
🧹 Nitpick comments (3)
docs/content/docs/documentation/env_vars.md (1)
240-249: Consider clarifying provider-specificRERANKER_BASE_URLdefaults.The table mentions default ports per provider (7997 for Infinity, 8000 for OpenAI), but
RERANKER_BASE_URLshows onlyhttp://reranker:7997. Consider updating the description to note that the default URL depends on the selected provider, or that users should setRERANKER_BASE_URLtohttp://reranker:8000when using theopenaiprovider.📝 Suggested clarification
-| `RERANKER_BASE_URL` | `str` | `http://reranker:7997` | Base URL of the reranker service | +| `RERANKER_BASE_URL` | `str` | `http://reranker:<port>` | Base URL of the reranker service. Default port is `7997` for Infinity, `8000` for OpenAI |🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/content/docs/documentation/env_vars.md` around lines 240 - 249, Update the RERANKER_BASE_URL documentation to clarify provider-specific defaults: mention that when RERANKER_PROVIDER is set to "infinity" the typical default is http://reranker:7997, whereas for "openai" users should typically set RERANKER_BASE_URL to http://reranker:8000 (or an OpenAI-compatible endpoint), and add a short note referencing RERANKER_PROVIDER and RERANKER_API_KEY so readers know to change the base URL when switching providers.conf/config.yaml (1)
69-78: Update the env-var comment to include new variables.The comment on line 69 lists
RERANKER_ENABLED, RERANKER_MODEL, RERANKER_TOP_K, RERANKER_BASE_URL, RERANKER_PORTbut is missing the newly addedRERANKER_PROVIDER,RERANKER_API_KEY,RERANKER_TIMEOUT, andRERANKER_SEMAPHORE.# --- Reranker --- -# Env: RERANKER_ENABLED, RERANKER_MODEL, RERANKER_TOP_K, RERANKER_BASE_URL, RERANKER_PORT +# Env: RERANKER_PROVIDER, RERANKER_ENABLED, RERANKER_MODEL, RERANKER_TOP_K, RERANKER_BASE_URL, RERANKER_API_KEY, RERANKER_TIMEOUT, RERANKER_SEMAPHORE reranker:🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@conf/config.yaml` around lines 69 - 78, Update the environment-variable comment above the reranker block so it lists all current env vars: include RERANKER_PROVIDER, RERANKER_API_KEY, RERANKER_TIMEOUT, and RERANKER_SEMAPHORE in addition to the existing RERANKER_ENABLED, RERANKER_MODEL, RERANKER_TOP_K, RERANKER_BASE_URL, and RERANKER_PORT to reflect the keys present in the reranker config (provider, api_key, timeout, semaphore, model_name, top_k, base_url, enabled).openrag/components/reranker/openai.py (1)
19-21: Expose a shutdown path for the sharedAsyncClient.This class owns a long-lived
httpx.AsyncClientbut never closes it. HTTPX recommends either usingasync withor explicitly callingaclose(); otherwise connections stay open and can leak when reranker instances are recreated. Add anaclose()method here and invoke it from the app shutdown path. (python-httpx.org)🛠️ Suggested fix
class OpenAIReranker(BaseReranker): def __init__(self, config): self.model_name = config.reranker.model_name base_url = config.reranker.base_url.rstrip("/") self.rerank_url = f"{base_url}/rerank" self.semaphore = asyncio.Semaphore(config.reranker.semaphore) self.timeout = config.reranker.timeout self.client = httpx.AsyncClient( headers={"Authorization": f"Bearer {config.reranker.api_key}"}, ) logger.debug("OpenAI Reranker initialized", model_name=self.model_name) + + async def aclose(self) -> None: + await self.client.aclose()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/components/reranker/openai.py` around lines 19 - 21, The shared httpx.AsyncClient created in the Reranker class (self.client in openrag.components.reranker.openai) is never closed; add an async teardown method (e.g., async def aclose(self): await self.client.aclose()) on the class that explicitly calls the client's aclose(), and ensure the application's shutdown path invokes this method for the reranker instance so connections are properly closed and not leaked.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@extern/reranker/openai.yaml`:
- Around line 40-41: Remove the non-standard empty-string profiles block from
the reranker-gpu service (i.e., delete the profiles: - "" entry under the
reranker-gpu service), leaving reranker-gpu without any profiles so it is
enabled by default; ensure only reranker-cpu retains the profiles: ["cpu"] entry
to keep it conditional.
In `@openrag/components/reranker/__init__.py`:
- Around line 1-17: The module uses relative imports; change them to absolute
imports from the package root: import BaseReranker with "from
openrag.components.reranker.base import BaseReranker" and inside
RerankerFactory.get_reranker replace "from .infinity import InfinityReranker"
with "from openrag.components.reranker.infinity import InfinityReranker" and
"from .openai import OpenAIReranker" with "from
openrag.components.reranker.openai import OpenAIReranker" so all imports are
absolute while retaining the same factory logic in RerankerFactory.get_reranker.
In `@openrag/config/models.py`:
- Around line 148-150: Create a callable helper named _default_reranker_config
that returns a concrete instance of the union (e.g., an OpenAIRerankerConfig or
InfinityRerankerConfig) and use it as the Field default_factory for the reranker
field; specifically add a function _default_reranker_config() -> RerankerConfig
that constructs and returns a sensible default (for example
OpenAIRerankerConfig(provider="openai", ...) or the project's preferred default)
and then change the reranker annotation to reranker: RerankerConfig =
Field(default_factory=_default_reranker_config) so Pydantic receives a callable
that returns an instance.
---
Duplicate comments:
In `@openrag/components/reranker/infinity.py`:
- Around line 7-9: Replace relative/local imports with absolute imports from the
openrag package root: change "from utils.logger import get_logger" to "from
openrag.utils.logger import get_logger" and change "from .base import
BaseReranker" to "from openrag.components.reranker.base import BaseReranker" so
the module uses absolute project-root imports; update any other similar imports
in this file to match the same pattern.
In `@openrag/components/reranker/openai.py`:
- Around line 5-7: The imports in openrag/components/reranker/openai.py use
relative/project-root-escaping forms; replace from utils.logger import
get_logger and from .base import BaseReranker with absolute imports from the
openrag package (e.g., import get_logger from openrag.utils.logger and
BaseReranker from openrag.components.reranker.base or the appropriate openrag
path) so that get_logger and BaseReranker are imported via absolute module paths
consistent with the project's import guidelines.
---
Nitpick comments:
In `@conf/config.yaml`:
- Around line 69-78: Update the environment-variable comment above the reranker
block so it lists all current env vars: include RERANKER_PROVIDER,
RERANKER_API_KEY, RERANKER_TIMEOUT, and RERANKER_SEMAPHORE in addition to the
existing RERANKER_ENABLED, RERANKER_MODEL, RERANKER_TOP_K, RERANKER_BASE_URL,
and RERANKER_PORT to reflect the keys present in the reranker config (provider,
api_key, timeout, semaphore, model_name, top_k, base_url, enabled).
In `@docs/content/docs/documentation/env_vars.md`:
- Around line 240-249: Update the RERANKER_BASE_URL documentation to clarify
provider-specific defaults: mention that when RERANKER_PROVIDER is set to
"infinity" the typical default is http://reranker:7997, whereas for "openai"
users should typically set RERANKER_BASE_URL to http://reranker:8000 (or an
OpenAI-compatible endpoint), and add a short note referencing RERANKER_PROVIDER
and RERANKER_API_KEY so readers know to change the base URL when switching
providers.
In `@openrag/components/reranker/openai.py`:
- Around line 19-21: The shared httpx.AsyncClient created in the Reranker class
(self.client in openrag.components.reranker.openai) is never closed; add an
async teardown method (e.g., async def aclose(self): await self.client.aclose())
on the class that explicitly calls the client's aclose(), and ensure the
application's shutdown path invokes this method for the reranker instance so
connections are properly closed and not leaked.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: d2dc0f52-2069-458e-83e0-503e41bc32b1
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (15)
conf/config.yamldocker-compose.yamldocs/content/docs/documentation/env_vars.mdextern/reranker/infinity.yamlextern/reranker/openai.yamlopenrag/app_front.pyopenrag/components/pipeline.pyopenrag/components/reranker/__init__.pyopenrag/components/reranker/base.pyopenrag/components/reranker/infinity.pyopenrag/components/reranker/openai.pyopenrag/components/reranker/test_rrf_reranking.pyopenrag/config/loader.pyopenrag/config/models.pyquick_start/extern/infinity.yaml
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (1)
openrag/config/models.py (1)
148-151:⚠️ Potential issue | 🔴 Critical
RerankerConfigis not a validdefault_factory.
Settings.rerankerstill usesField(default_factory=RerankerConfig)on Line 483, but this symbol is now anAnnotated[...]union alias rather than a concrete config class. That breaks the documented “load defaults when config is missing” path inload_config(). Please switch the factory to a helper that returns a concrete provider config, e.g.InfinityRerankerConfig().Required fix
RerankerConfig = Annotated[ InfinityRerankerConfig | OpenAIRerankerConfig, Field(discriminator="provider"), ] + +def _default_reranker_config() -> InfinityRerankerConfig: + return InfinityRerankerConfig()Then update Line 483 to:
reranker: RerankerConfig = Field(default_factory=_default_reranker_config)#!/bin/bash set -euo pipefail python - <<'PY' from typing import Annotated class A: ... class B: ... T = Annotated[A | B, "provider"] try: T() except Exception as exc: print(type(exc).__name__, exc) PY rg -n 'RerankerConfig = Annotated|default_factory=RerankerConfig' openrag/config/models.py🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/config/models.py` around lines 148 - 151, The default_factory currently points to the Annotated union alias RerankerConfig which is not callable; add a small helper function named like _default_reranker_config that returns a concrete config instance (e.g. return InfinityRerankerConfig()) and then change the Settings.reranker Field to use Field(default_factory=_default_reranker_config) so missing configs load the concrete default; reference RerankerConfig for typing but use _default_reranker_config and InfinityRerankerConfig for the actual factory.
🧹 Nitpick comments (1)
openrag/app_front.py (1)
128-128: Use thePARTITION_PREFIXconstant instead of hardcoding"openrag-all".The backend constructs this model ID as
f"{PARTITION_PREFIX}all"(seeopenrag/routers/openai.pylines 103-110). Using the same pattern here ensures consistency and avoids silent failures if the prefix ever changes.♻️ Suggested fix
- default=m.id == "openrag-all", + default=m.id == f"{PARTITION_PREFIX}all",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/app_front.py` at line 128, Replace the hardcoded model id check default=m.id == "openrag-all" with the partition-aware constant by using the PARTITION_PREFIX constant (e.g. default=m.id == f"{PARTITION_PREFIX}all"); also ensure PARTITION_PREFIX is imported into this module (from openrag.settings or the module where PARTITION_PREFIX is defined) so the expression resolves correctly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@conf/config.yaml`:
- Line 78: The comment for base_url is incorrect: update the comment for
base_url to reflect that its defaults are set in the code
(InfinityRerankerConfig.base_url defaults to "http://reranker:7997" and
OpenAIRerankerConfig.base_url defaults to "http://reranker:8000/v1") and that
RERANKER_PORT only affects Docker host port mapping and is not used to construct
the config value; reference base_url, InfinityRerankerConfig.base_url,
OpenAIRerankerConfig.base_url and RERANKER_PORT in the updated comment for
clarity.
- Line 69: Update the env var comment in conf/config.yaml to match the actual
mappings in openrag/config/loader.py: remove RERANKER_PORT and replace the list
with the real mapped variables (RERANKER_PROVIDER, RERANKER_ENABLED,
RERANKER_MODEL, RERANKER_TOP_K, RERANKER_BASE_URL, RERANKER_API_KEY,
RERANKER_TIMEOUT, RERANKER_SEMAPHORE) so the comment accurately reflects the
environment-to-config mapping used by the loader.
In `@openrag/components/reranker/base.py`:
- Around line 32-35: The loop that computes fused_scores uses doc_id =
doc.metadata.get("_id"), which collapses all docs missing "_id" under None;
update the code to detect missing IDs and either fail fast or assign a
per-document fallback key: if "_id" not in doc.metadata then either raise a
clear exception (e.g., raise KeyError(f"Missing _id in doc.metadata: {doc}")) or
set doc_id = f"__anon__{id(doc)}" (or another deterministic per-document
fallback such as hashing doc content) before using fused_scores.get(doc_id,
...); ensure you update references to doc_id, fused_scores and keep the existing
scoring expression (score + 1 / (rank + k), d).
In `@openrag/config/loader.py`:
- Around line 56-63: The YAML default blank for reranker.base_url means
Settings(**data) will keep an empty string and cause OpenAIReranker to post to
"/rerank" or InfinityReranker to receive an invalid URL; update the loader to
normalize an empty reranker.base_url back to the provider default before
constructing Settings (i.e., if data.get("reranker", {}).get("base_url") is
falsy or empty, replace it with the provider's default URL based on
data["reranker"]["provider"] or the known provider defaults used by
OpenAIReranker and InfinityReranker) so Settings(**data) never receives an empty
base_url and both OpenAIReranker and InfinityReranker get valid base URLs.
---
Duplicate comments:
In `@openrag/config/models.py`:
- Around line 148-151: The default_factory currently points to the Annotated
union alias RerankerConfig which is not callable; add a small helper function
named like _default_reranker_config that returns a concrete config instance
(e.g. return InfinityRerankerConfig()) and then change the Settings.reranker
Field to use Field(default_factory=_default_reranker_config) so missing configs
load the concrete default; reference RerankerConfig for typing but use
_default_reranker_config and InfinityRerankerConfig for the actual factory.
---
Nitpick comments:
In `@openrag/app_front.py`:
- Line 128: Replace the hardcoded model id check default=m.id == "openrag-all"
with the partition-aware constant by using the PARTITION_PREFIX constant (e.g.
default=m.id == f"{PARTITION_PREFIX}all"); also ensure PARTITION_PREFIX is
imported into this module (from openrag.settings or the module where
PARTITION_PREFIX is defined) so the expression resolves correctly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 67d15860-e3b5-4a5e-a620-64b78261b5cd
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (15)
conf/config.yamldocker-compose.yamldocs/content/docs/documentation/env_vars.mdextern/reranker/infinity.yamlextern/reranker/openai.yamlopenrag/app_front.pyopenrag/components/pipeline.pyopenrag/components/reranker/__init__.pyopenrag/components/reranker/base.pyopenrag/components/reranker/infinity.pyopenrag/components/reranker/openai.pyopenrag/components/reranker/test_rrf_reranking.pyopenrag/config/loader.pyopenrag/config/models.pyquick_start/extern/infinity.yaml
- Fix RerankerConfig default_factory using non-callable Annotated alias - Strip blank reranker.base_url so provider-specific Pydantic defaults apply - Prevent RRF score collapse when documents lack _id metadata - Use PARTITION_PREFIX constant instead of hardcoded "openrag-all" - Fix stale env var comments in config.yaml
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
openrag/app_front.py (1)
117-128:⚠️ Potential issue | 🟡 MinorKeep the “all partitions” check exact in both places.
Line 128 now matches only the synthetic
f"{PARTITION_PREFIX}all"profile, but the description still branches on"all" in m.id. A profile likeopenrag-smalloropenrag-allhandswould still show the global-partitions description even though it is not theallprofile.Suggested fix
for i, m in enumerate(models, start=1): partition = m.id.split(PARTITION_PREFIX)[1] + is_all_profile = m.id == f"{PARTITION_PREFIX}all" description_template = "You are interacting with the **{name}** LLM.\n" + ( "The LLM's answers will be grounded on **all** partitions." - if "all" in m.id + if is_all_profile else "The LLM's answers will be grounded only on the partition named **{partition}**." ) chat_profiles.append( cl.ChatProfile( name=m.id, markdown_description=description_template.format(name=m.id, partition=partition), icon="/public/favicon.svg", - default=m.id == f"{PARTITION_PREFIX}all", + default=is_all_profile, ) )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/app_front.py` around lines 117 - 128, The description branching uses a substring check ("all" in m.id) which is inconsistent with the default-profile check (m.id == f"{PARTITION_PREFIX}all"); update the description logic in the block building chat_profiles so it uses the exact same equality check (compare m.id to f"{PARTITION_PREFIX}all") instead of the substring test, ensuring PARTITION_PREFIX, description_template, m.id and the default check remain aligned and the markdown_description reflects only the true "all" partition profile.
♻️ Duplicate comments (1)
openrag/config/loader.py (1)
277-284:⚠️ Potential issue | 🟠 MajorNormalize the reranker block after all merges, and absorb the legacy
enablekey.This cleanup only covers the YAML/env state. An override like
{"reranker": {"provider": "openai", "base_url": ""}}can still recreate the blank URL after this block runs, and older custom configs that still usereranker.enable: falsenow miss the renamed field and fall back to the new default. Normalize the reranker dict once after_deep_merge()so both cases land on the new schema before validation.Suggested fix
- # Strip blank reranker.base_url so the provider-specific Pydantic default applies - reranker = data.get("reranker") - if isinstance(reranker, dict) and not reranker.get("base_url"): - reranker.pop("base_url", None) - # 3. Apply programmatic overrides (tests) if overrides: data = _deep_merge(data, overrides) + + # Normalize reranker config after all merges + reranker = data.get("reranker") + if isinstance(reranker, dict): + if "enabled" not in reranker and "enable" in reranker: + reranker["enabled"] = reranker.pop("enable") + if not reranker.get("base_url"): + reranker.pop("base_url", None) # 4. Resolve paths (after all merging so overrides are honored)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openrag/config/loader.py` around lines 277 - 284, Move the reranker normalization to run after the programmatic overrides merge: after data = _deep_merge(data, overrides) retrieve reranker = data.get("reranker") and if it's a dict then (1) absorb the legacy key by mapping reranker["enable"] to reranker["enabled"] (pop "enable" after copying) and (2) strip a blank base_url by popping "base_url" when the value is falsy so the provider-specific Pydantic default can apply; update the code around the existing reranker, overrides, and _deep_merge usage to perform these steps once after merging.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@openrag/app_front.py`:
- Around line 117-128: The description branching uses a substring check ("all"
in m.id) which is inconsistent with the default-profile check (m.id ==
f"{PARTITION_PREFIX}all"); update the description logic in the block building
chat_profiles so it uses the exact same equality check (compare m.id to
f"{PARTITION_PREFIX}all") instead of the substring test, ensuring
PARTITION_PREFIX, description_template, m.id and the default check remain
aligned and the markdown_description reflects only the true "all" partition
profile.
---
Duplicate comments:
In `@openrag/config/loader.py`:
- Around line 277-284: Move the reranker normalization to run after the
programmatic overrides merge: after data = _deep_merge(data, overrides) retrieve
reranker = data.get("reranker") and if it's a dict then (1) absorb the legacy
key by mapping reranker["enable"] to reranker["enabled"] (pop "enable" after
copying) and (2) strip a blank base_url by popping "base_url" when the value is
falsy so the provider-specific Pydantic default can apply; update the code
around the existing reranker, overrides, and _deep_merge usage to perform these
steps once after merging.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: a6766ee4-a73f-4ca6-ad73-3f215dda6674
📒 Files selected for processing (5)
conf/config.yamlopenrag/app_front.pyopenrag/components/reranker/base.pyopenrag/config/loader.pyopenrag/config/models.py
🚧 Files skipped from review as they are similar to previous changes (2)
- conf/config.yaml
- openrag/components/reranker/base.py
|
All good on my side |
| self.model_name = config.reranker["model_name"] | ||
| self.model_name = config.reranker.model_name | ||
| self.client = Client( | ||
| base_url=config.reranker["base_url"], | ||
| timeout=config.reranker.get("timeout", 60.0), | ||
| headers={"Authorization": f"Bearer {config.reranker['api_key']}"}, | ||
| base_url=config.reranker.base_url, | ||
| timeout=config.reranker.timeout, | ||
| headers={"Authorization": f"Bearer {config.reranker.api_key}"}, | ||
| ) | ||
| semaphore = config.reranker.get("semaphore", 40) | ||
| self.semaphore = asyncio.Semaphore(semaphore) |
There was a problem hiding this comment.
I made those adjustments, but they don’t seem to be reflected in my commits. Something must have gone wrong during the rebase.
Refactor reranker into a multi-provider architecture
Replaces the single-file reranker with a factory pattern supporting multiple backends (Infinity and OpenAI-compatible endpoints). The provider is selected at runtime via configuration.
Changes:
BaseReranker,InfinityReranker, andOpenAIRerankerclasses underopenrag/components/reranker/.hydra_config/reranker/)docker-compose.yamlfor dynamic provider selection; addedextern/reranker/openai.yamlwith GPU/CPU supportSummary by CodeRabbit
New Features
Configuration
Documentation