Skip to content

refactor(12C): load retrieval/query prompts via core loader, drop components.prompts - #437

Merged
EnjoyBacon7 merged 1 commit into
refactor/phase-12a-loggerfrom
refactor/phase-12c-prompts
May 29, 2026
Merged

refactor(12C): load retrieval/query prompts via core loader, drop components.prompts#437
EnjoyBacon7 merged 1 commit into
refactor/phase-12a-loggerfrom
refactor/phase-12c-prompts

Conversation

@EnjoyBacon7

@EnjoyBacon7 EnjoyBacon7 commented May 29, 2026

Copy link
Copy Markdown
Collaborator

Phase 12C — Migrate prompt constants off components.prompts

Removes the last from components.prompts import … consumers so the shim can be deleted in 12H.

Based on the Phase-12 integration tip (refactor/phase-12a-logger @ c7be6380, which already bundles 12A/12D/12E/12G), so the diff is just 12C's 3 files. Independent of 12B (#436).

Design note — deviation from the guide's letter, faithful to its intent

The 12C plan assumed these were Python string constants to inline into core/prompts/ builders. They are notcomponents/prompts/prompts.py is a shim whose "constants" (HYDE_PROMPT, MULTI_QUERY_PROMPT, SYS_PROMPT_TMPLT, QUERY_CONTEXTUALIZER_PROMPT, SPOKEN_STYLE_ANSWER_PROMPT) are disk templates eager-loaded via load_config() at import.

Distributing them as eager module-level constants into the builders would add import-time disk I/O + a config dependency to the entire core.prompts package (its __init__ imports every builder) — an architectural regression that also breaks core's import-time purity.

Instead, each orchestrator loads its templates from the injected Settings using the existing pure core.prompts.load_template_by_key(prompts_dir, mapping, key) — precisely the call shape template_loader's docstring prescribes for callers. This removes the shim dependency, keeps core pure, and binds prompts to the instance's config (more correct than the old process-global eager load). The real per-template-file migration remains Phase 13D.

Changes

  • retrieval_service.pymultiQuery / hyde branches load "multi_query" / "hyde" from config (already a constructor arg) instead of the inline shim import.
  • query_service.py — load "query_contextualizer" / "spoken_style_answer" / "sys_prompt" once in __init__ from the injected config, stored on the instance; use sites updated.
  • test_query_service.py — extend the fake SimpleNamespace config with the real paths/prompts so QueryService can resolve templates.

Verification

  • grep "components.prompts" outside components/ → zero results
  • ruff check on all changed files → clean
  • test_query_service.py + test_retrieval_service.py + core/prompts/ → 55 passed
  • Smoke-checked all 5 template keys resolve against the real config
  • Full collection: 1211 tests, no import errors

Note: the multiQuery/hyde retrieval branches have no existing unit test (true before this change too — the old inline imports were equally uncovered). Verified manually that both keys resolve.

Summary by CodeRabbit

  • Refactor
    • Centralized prompt template management by loading templates from a unified configuration source instead of using dispersed constants. This improves maintainability and consistency across the query and retrieval orchestration services.

Review Change Stack

…ts.prompts

Phase 12C. The orchestrators imported HYDE/MULTI_QUERY/SYS/CONTEXTUALIZER/
SPOKEN_STYLE prompts from the components.prompts shim. Those are not Python
string constants — they are disk templates the shim eager-loads at import
via load_config(). Distributing them as eager module-level constants into
core/prompts builders would add import-time disk I/O and a config dependency
to the whole core.prompts package (its __init__ imports every builder), so
instead each service loads its templates from the injected Settings using the
existing pure core.prompts.load_template_by_key(prompts_dir, mapping, key) —
exactly the call shape template_loader documents for its callers.

- retrieval_service.py: multiQuery / hyde branches load "multi_query" / "hyde"
  from `config` (already in __init__) instead of importing the shim inline.
- query_service.py: load "query_contextualizer" / "spoken_style_answer" /
  "sys_prompt" once in __init__ from the injected config; store on the
  instance. Per-instance config binding replaces the old global eager load.
- test_query_service.py: extend the fake config with the real paths/prompts
  so QueryService can resolve templates.

No remaining `components.prompts` imports outside components/ itself.
@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR migrates QueryService and RetrievalService from using compile-time prompt constants to dynamically loading prompt templates from disk via load_template_by_key(). Instance attributes store loaded templates, enabling runtime configuration-driven prompt selection in query generation and system prompt assembly.

Changes

Prompt Template Dynamic Loading

Layer / File(s) Summary
QueryService prompt template loading and usage
openrag/services/orchestrators/query_service.py
Import changes replace legacy components.prompts constants with load_template_by_key from core.prompts. Initialization loads query_contextualizer, spoken_style_answer, and sys_prompt templates from config and stores them as instance attributes. Query generation and system prompt assembly switch from using imported constants to using the loaded instance attributes.
RetrievalService template loading for retrievers
openrag/services/orchestrators/retrieval_service.py
Import adds load_template_by_key support. MultiQuery and hyde retriever construction now load template strings from config (prompts directory + prompt key set) instead of using compile-time prompt constants.
Test configuration and prompt loading
openrag/services/orchestrators/test_query_service.py
Module loads real prompt configuration from disk at import time via load_config() into _PROMPT_CFG. Test config helper is extended to pass prompt-related paths and prompts into the config object used for QueryService construction.

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

A prompt once cast in code so tight,
Now dances free in config light,
The templates load, the queries sing,
Each service bends to runtime's wing. 🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main refactoring: migrating prompt loading from components.prompts to the core loader.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/phase-12c-prompts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
openrag/services/orchestrators/test_query_service.py (1)

22-24: 💤 Low value

Optional: defer load_config() to a fixture instead of import time.

Calling load_config() at module scope runs disk I/O during test collection and couples this module's import to a resolvable config. A session-scoped fixture (or lazy call inside _config()) keeps collection cheap and failures localized to the tests that need real prompts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@openrag/services/orchestrators/test_query_service.py` around lines 22 - 24,
The module currently calls load_config() at import time via the _PROMPT_CFG
variable which causes disk I/O during test collection; change this to a
lazily-evaluated or fixture-based approach by removing the module-scope
_PROMPT_CFG = load_config() and either (a) add a session-scoped pytest fixture
(e.g., def prompt_cfg_session(): return load_config()) and update tests to
accept that fixture, or (b) replace _PROMPT_CFG with a helper function (e.g.,
def _prompt_cfg(): return load_config()) and call it inside tests/setup where
needed; update references to _PROMPT_CFG accordingly (tests that currently
reference _PROMPT_CFG should use the fixture name or call _prompt_cfg()) so disk
I/O happens only when those tests run.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@openrag/services/orchestrators/test_query_service.py`:
- Around line 22-24: The module currently calls load_config() at import time via
the _PROMPT_CFG variable which causes disk I/O during test collection; change
this to a lazily-evaluated or fixture-based approach by removing the
module-scope _PROMPT_CFG = load_config() and either (a) add a session-scoped
pytest fixture (e.g., def prompt_cfg_session(): return load_config()) and update
tests to accept that fixture, or (b) replace _PROMPT_CFG with a helper function
(e.g., def _prompt_cfg(): return load_config()) and call it inside tests/setup
where needed; update references to _PROMPT_CFG accordingly (tests that currently
reference _PROMPT_CFG should use the fixture name or call _prompt_cfg()) so disk
I/O happens only when those tests run.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0678379b-2970-4438-bd71-ab91d46ec10b

📥 Commits

Reviewing files that changed from the base of the PR and between c7be638 and 6eda2b6.

📒 Files selected for processing (3)
  • openrag/services/orchestrators/query_service.py
  • openrag/services/orchestrators/retrieval_service.py
  • openrag/services/orchestrators/test_query_service.py

@EnjoyBacon7
EnjoyBacon7 merged commit 9b999f6 into refactor/phase-12a-logger May 29, 2026
8 checks passed
@EnjoyBacon7
EnjoyBacon7 deleted the refactor/phase-12c-prompts branch May 29, 2026 14:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants