Skip to content

LCORE-1429: Added configurable search mode option for solr provider#1511

Open
asimurka wants to merge 1 commit intolightspeed-core:mainfrom
asimurka:add_solr_mode_request_attribute
Open

LCORE-1429: Added configurable search mode option for solr provider#1511
asimurka wants to merge 1 commit intolightspeed-core:mainfrom
asimurka:add_solr_mode_request_attribute

Conversation

@asimurka
Copy link
Copy Markdown
Contributor

@asimurka asimurka commented Apr 16, 2026

Description

Introduces a typed solr payload on query and Responses requests with optional mode (semantic / hybrid / lexical) and filters for Solr vector_io; legacy top-level-only filter objects remain accepted via a before-validator but log a deprecation warning. Adds short notes in docs/rag_guide.md and docs/responses.md.

Type of change

  • Refactor
  • New feature
  • Bug fix
  • CVE fix
  • Optimization
  • Documentation Update
  • Configuration Update
  • Bump-up service version
  • Bump-up dependent library
  • Bump-up library or tool used for development (does not change the final image)
  • CI configuration change
  • Konflux configuration change
  • Unit tests improvement
  • Integration tests improvement
  • End to end tests improvement
  • Benchmarks improvement

Tools used to create PR

Identify any AI code assistants used in this PR (for transparency and review context)

  • Assisted-by: (e.g., Claude, CodeRabbit, Ollama, etc., N/A if not used)
  • Generated by: (e.g., tool name and version; N/A if not used)

Related Tickets & Documents

Checklist before requesting a review

  • I have performed a self-review of my code.
  • PR has passed all pre-merge test jobs.
  • If it is a core feature, I have added thorough tests.

Testing

  • Please provide detailed steps to perform tests related to this code change.
  • How were the fix/results from this change verified? Please provide relevant screenshots or results.

Summary by CodeRabbit

  • New Features

    • Per-request search mode selection for Solr-style filtering: semantic, hybrid, or lexical; works with requests that include both mode and filters.
  • Documentation

    • Clarified dynamic per-request filtering, introduced the structured {mode, filters} request shape, provided a JSON example, and documented backward compatibility for legacy filter-only payloads.
  • Tests

    • Added/updated tests to validate structured and legacy Solr request shapes and mode/filter behavior.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 16, 2026

Walkthrough

Adds a structured per-request Solr vector search payload (mode + filters), a Pydantic model to validate it (with legacy-filter coercion), updates request types and vector-search utilities to use the structured shape, and updates docs/tests to reflect and validate the new behavior.

Changes

Cohort / File(s) Summary
Documentation
docs/rag_guide.md, docs/responses.md
Replace prior static workaround guidance with per-request solr semantics: wrapper object { mode, filters }, documented mode options (semantic, hybrid, lexical), filters shape, and legacy top-level filter compatibility.
Request Models
src/models/requests.py
Add SolrVectorSearchRequest Pydantic model (`mode?: "semantic"
Vector Search Implementation
src/utils/vector_search.py
Accept SolrVectorSearchRequest; derive params["mode"] from solr.mode when present (else default constant); only set params["solr"] when solr.filters is provided and pass filters instead of the whole solr object.
Tests
tests/unit/models/requests/test_query_request.py, tests/unit/utils/test_vector_search.py
Add tests for legacy-shaped and structured solr validation; update query-param tests to use SolrVectorSearchRequest; add cases asserting mode handling and that _fetch_solr_rag forwards mode and solr (filters) to vector_io.

Sequence Diagram(s):

sequenceDiagram
    participant Client
    participant API as API Layer
    participant ReqModel as SolrVectorSearchRequest
    participant VectorUtil as vector_search
    participant VectorIO as client.vector_io
    participant Solr as Solr Backend

    Client->>API: send request with `solr` payload
    API->>ReqModel: validate/coerce payload (legacy -> {mode:null, filters:...})
    API->>VectorUtil: build_rag_context/_fetch_solr_rag(solr=ReqModel)
    VectorUtil->>VectorIO: query(..., params={mode, solr: filters?})
    VectorIO->>Solr: forward params and query
    Solr-->>VectorIO: results
    VectorIO-->>VectorUtil: results
    VectorUtil-->>API: enriched RAG context
    API-->>Client: response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly summarizes the main change: adding a configurable search mode option for the Solr provider, which is the primary focus of the PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/rag_guide.md`:
- Around line 362-371: The fenced JSON example after the "Example:" label starts
immediately on the next line which violates MD031; edit the markdown around the
```json fence so there is a blank line before the opening ```json fence and
ensure there is a blank line after the closing ``` fence (i.e., add one empty
line between the "Example:" paragraph and the ```json block and keep a blank
line following the closing fence) to satisfy markdownlint; look for the
"Example:" text and the ```json fenced block to locate the change.

In `@src/models/requests.py`:
- Around line 124-129: Update the SolrVectorSearchRequest Pydantic model
docstring to include an "Attributes:" section that documents each model field
(e.g., mode, filters, provider-related fields) with their types and short
descriptions; modify the docstring in class SolrVectorSearchRequest (subclassing
BaseModel) to enumerate every attribute present on the model so readers and
tools can discover what fields are expected and what they mean.
- Line 6: Replace the current import of Self from typing with an import from
typing_extensions: remove Self from the "from typing import Any, Literal,
Optional, Self" line and instead add "from typing_extensions import Self"; keep
the other typing imports (Any, Literal, Optional) as-is so validator return
annotations that reference Self (used in your model validators) import the
correct symbol per repository standards.

In `@tests/unit/models/requests/test_query_request.py`:
- Around line 144-153: The test test_solr_legacy_plain_dict should also assert
that a deprecation warning is emitted for the legacy solr payload shape: when
constructing QueryRequest(query="q", solr={"fq": ["a:b"]}) and validating via
SolrVectorSearchRequest.model_validate(qr.solr), wrap the validation in a
pytest.warns(ExpectedWarningType) (or warnings.catch_warnings and record) and
assert the warning message or category matches the expected deprecation notice
so the legacy-shape deprecation contract is checked alongside the existing
assertions on mode and filters.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: dcfdce6c-57e0-4ae7-9dc6-9f616b39c2c1

📥 Commits

Reviewing files that changed from the base of the PR and between 2b0d677 and 95197e9.

📒 Files selected for processing (6)
  • docs/rag_guide.md
  • docs/responses.md
  • src/models/requests.py
  • src/utils/vector_search.py
  • tests/unit/models/requests/test_query_request.py
  • tests/unit/utils/test_vector_search.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: Pylinter
  • GitHub Check: build-pr
  • GitHub Check: E2E: server mode / ci / group 2
  • GitHub Check: E2E: server mode / ci / group 1
  • GitHub Check: E2E: library mode / ci / group 1
  • GitHub Check: E2E: library mode / ci / group 3
  • GitHub Check: E2E: server mode / ci / group 3
  • GitHub Check: E2E: library mode / ci / group 2
  • GitHub Check: Konflux kflux-prd-rh02 / lightspeed-stack-on-pull-request
  • GitHub Check: E2E Tests for Lightspeed Evaluation job
🧰 Additional context used
📓 Path-based instructions (4)
tests/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

tests/**/*.py: Use pytest for all unit and integration tests; do not use unittest
Use pytest.mark.asyncio marker for async unit tests

Files:

  • tests/unit/models/requests/test_query_request.py
  • tests/unit/utils/test_vector_search.py
tests/unit/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Use pytest-mock for AsyncMock objects in unit tests

Files:

  • tests/unit/models/requests/test_query_request.py
  • tests/unit/utils/test_vector_search.py
src/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.py: Use absolute imports for internal modules (e.g., from authentication import get_auth_dependency)
Use from llama_stack_client import AsyncLlamaStackClient for Llama Stack imports
Check constants.py for shared constants before defining new ones
All modules start with descriptive docstrings explaining purpose
Use logger = get_logger(__name__) from log.py for module logging
Type aliases defined at module level for clarity
All functions require docstrings with brief descriptions
Use complete type annotations for function parameters and return types
Use union types with modern syntax: str | int instead of Union[str, int]
Use Optional[Type] for optional types in type annotations
Use snake_case with descriptive, action-oriented names for functions (get_, validate_, check_)
Avoid in-place parameter modification anti-patterns: return new data structures instead of modifying parameters
Use async def for I/O operations and external API calls
Handle APIConnectionError from Llama Stack in error handling
Use logger.debug() for detailed diagnostic information
Use logger.info() for general information about program execution
Use logger.warning() for unexpected events or potential problems
Use logger.error() for serious problems that prevented function execution
All classes require descriptive docstrings explaining purpose
Use PascalCase for class names with descriptive names and standard suffixes: Configuration, Error/Exception, Resolver, Interface
Use complete type annotations for all class attributes; avoid using Any
Follow Google Python docstring conventions for all modules, classes, and functions
Include Parameters:, Returns:, Raises: sections in function docstrings as needed

Files:

  • src/utils/vector_search.py
  • src/models/requests.py
src/models/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

src/models/**/*.py: Use @field_validator and @model_validator for custom validation in Pydantic models
Use typing_extensions.Self for model validators in type annotations
Pydantic data models should extend BaseModel
Include Attributes: section in Pydantic model docstrings

Files:

  • src/models/requests.py
🧠 Learnings (6)
📓 Common learnings
Learnt from: are-ces
Repo: lightspeed-core/lightspeed-stack PR: 1335
File: docs/config.md:411-411
Timestamp: 2026-03-17T11:34:53.242Z
Learning: In the lightspeed-stack project (`src/models/config.py`, `docs/config.md`), the internal Solr filter `is_chunk:true` (defined as `SOLR_CHUNK_FILTER_QUERY` in `src/constants.py`) is always injected by the system for OKP searches and is intentionally hidden from users. The `chunk_filter_query` field in `OkpConfiguration` is user-facing and additive-only, but the documentation must NOT mention the internal `is_chunk:true` behavior — this is a deliberate design decision by the maintainers.
📚 Learning: 2026-03-17T11:34:53.242Z
Learnt from: are-ces
Repo: lightspeed-core/lightspeed-stack PR: 1335
File: docs/config.md:411-411
Timestamp: 2026-03-17T11:34:53.242Z
Learning: In the lightspeed-stack project (`src/models/config.py`, `docs/config.md`), the internal Solr filter `is_chunk:true` (defined as `SOLR_CHUNK_FILTER_QUERY` in `src/constants.py`) is always injected by the system for OKP searches and is intentionally hidden from users. The `chunk_filter_query` field in `OkpConfiguration` is user-facing and additive-only, but the documentation must NOT mention the internal `is_chunk:true` behavior — this is a deliberate design decision by the maintainers.

Applied to files:

  • docs/rag_guide.md
  • docs/responses.md
  • src/models/requests.py
📚 Learning: 2026-02-23T14:11:46.950Z
Learnt from: asimurka
Repo: lightspeed-core/lightspeed-stack PR: 1198
File: src/utils/responses.py:184-188
Timestamp: 2026-02-23T14:11:46.950Z
Learning: The query request validator in the Responses API flow requires that `query_request.model` and `query_request.provider` must either both be specified or both be absent. The concatenated format (e.g., `model="provider/model"` with `provider=None`) is not permitted by the validator.

Applied to files:

  • src/models/requests.py
📚 Learning: 2026-02-25T07:46:33.545Z
Learnt from: asimurka
Repo: lightspeed-core/lightspeed-stack PR: 1211
File: src/models/responses.py:8-16
Timestamp: 2026-02-25T07:46:33.545Z
Learning: In the Python codebase, requests.py should use OpenAIResponseInputTool as Tool while responses.py uses OpenAIResponseTool as Tool. This difference is intentional due to differing schemas for input vs output tools in llama-stack-api. Apply this distinction consistently to other models under src/models (e.g., ensure request-related tools use the InputTool variant and response-related tools use the ResponseTool variant). If adding new tools, choose the corresponding InputTool or Tool class based on whether the tool represents input or output, and document the rationale in code comments.

Applied to files:

  • src/models/requests.py
📚 Learning: 2026-01-12T10:58:40.230Z
Learnt from: blublinsky
Repo: lightspeed-core/lightspeed-stack PR: 972
File: src/models/config.py:459-513
Timestamp: 2026-01-12T10:58:40.230Z
Learning: In lightspeed-core/lightspeed-stack, for Python files under src/models, when a user claims a fix is done but the issue persists, verify the current code state before accepting the fix. Steps: review the diff, fetch the latest changes, run relevant tests, reproduce the issue, search the codebase for lingering references to the original problem, confirm the fix is applied and not undone by subsequent commits, and validate with local checks to ensure the issue is resolved.

Applied to files:

  • src/models/requests.py
📚 Learning: 2026-04-15T18:54:07.540Z
Learnt from: Lifto
Repo: lightspeed-core/lightspeed-stack PR: 1510
File: src/models/requests.py:769-773
Timestamp: 2026-04-15T18:54:07.540Z
Learning: In lightspeed-core/lightspeed-stack request models, keep schema-level size limits defined as inline numeric literals (e.g., Pydantic Field max_length values used for validation) rather than extracting them into constants.py. Only extract values intended as configurable runtime defaults (e.g., DEFAULT_* settings like header/file upload sizes). Do not flag inline numeric literals used directly in Pydantic Field constraints or field validators as an extraction-to-constants issue.

Applied to files:

  • src/models/requests.py
🪛 markdownlint-cli2 (0.22.0)
docs/rag_guide.md

[warning] 363-363: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

🔇 Additional comments (3)
tests/unit/utils/test_vector_search.py (1)

78-103: Good Solr mode/filter test coverage.

These additions correctly lock in default/override mode behavior and verify request-level mode/filters are forwarded to vector_io.query.

Also applies to: 634-667

docs/responses.md (1)

111-112: Solr extension documentation is clear and aligned.

The updated solr field description captures both the structured payload and legacy compatibility in a concise way.

Also applies to: 602-603

src/utils/vector_search.py (1)

56-87: Typed Solr plumbing in vector search looks good.

The mode resolution and filters passthrough are correctly separated, and function signatures now enforce the structured Solr contract end-to-end.

Also applies to: 453-457, 529-535

Comment thread docs/rag_guide.md
Comment thread src/models/requests.py
Comment thread src/models/requests.py
Comment thread tests/unit/models/requests/test_query_request.py
@asimurka asimurka force-pushed the add_solr_mode_request_attribute branch 2 times, most recently from 0fe6340 to 528fc87 Compare April 16, 2026 07:30
@asimurka asimurka requested review from Anxhela21 and tisnik April 16, 2026 07:37
@asimurka asimurka force-pushed the add_solr_mode_request_attribute branch from 528fc87 to aa1abc1 Compare April 20, 2026 10:42
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (2)
tests/unit/models/requests/test_query_request.py (1)

144-152: 🧹 Nitpick | 🔵 Trivial

Assert the legacy Solr deprecation warning.

This validates coercion, but still misses the warning contract for deprecated top-level filter payloads.

Proposed test update
-    def test_solr_legacy_plain_dict(self) -> None:
+    def test_solr_legacy_plain_dict(
+        self, caplog: pytest.LogCaptureFixture
+    ) -> None:
         """Legacy clients may send filter keys as a plain object on ``solr``."""
-        qr = QueryRequest(
-            query="q",
-            solr={"fq": ["a:b"]},
-        )  # pyright: ignore[reportCallIssue]
+        with caplog.at_level("WARNING", logger="models.requests"):
+            qr = QueryRequest(
+                query="q",
+                solr={"fq": ["a:b"]},
+            )  # pyright: ignore[reportCallIssue]
         solr_request = SolrVectorSearchRequest.model_validate(qr.solr)
         assert solr_request.mode is None
         assert solr_request.filters == {"fq": ["a:b"]}
+        assert "deprecated and will be removed" in caplog.text
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/models/requests/test_query_request.py` around lines 144 - 152, The
test test_solr_legacy_plain_dict currently verifies coercion but misses
asserting the deprecation warning for top-level Solr filter payloads; update the
test to wrap the call that triggers coercion (the
SolrVectorSearchRequest.model_validate(qr.solr) invocation) in a pytest.warns
context for the expected DeprecationWarning (or the project's specific
deprecation warning class) so the test both validates the resulting
SolrVectorSearchRequest fields and asserts the deprecation warning was emitted
when QueryRequest/solr is validated.
src/models/requests.py (1)

7-7: 🛠️ Refactor suggestion | 🟠 Major

Import Self from typing_extensions.

This module uses Self in Pydantic model validators, and the repository standard requires typing_extensions.Self.

Proposed import fix
-from typing import Any, Literal, Optional, Self
+from typing import Any, Literal, Optional
+
+from typing_extensions import Self

Run this read-only check to verify the import and validator usage:

#!/bin/bash
rg -nP --type=py 'from typing import .*\\bSelf\\b|from typing_extensions import Self|def .*\\(self\\) -> Self' src/models/requests.py

As per coding guidelines: **/*.py: "Use typing_extensions.Self for model validators in Pydantic models".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/models/requests.py` at line 7, The module currently imports Self from
typing but the project standard requires using typing_extensions.Self for
Pydantic model validators; update the import in src/models/requests.py by
removing Self from the "from typing import ..." line and instead import Self
from typing_extensions (e.g., add "from typing_extensions import Self"),
ensuring any validators or annotations that reference Self (used in the Pydantic
model methods/validators in this file) keep the same symbol name but now come
from typing_extensions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/models/requests.py`:
- Line 7: The module currently imports Self from typing but the project standard
requires using typing_extensions.Self for Pydantic model validators; update the
import in src/models/requests.py by removing Self from the "from typing import
..." line and instead import Self from typing_extensions (e.g., add "from
typing_extensions import Self"), ensuring any validators or annotations that
reference Self (used in the Pydantic model methods/validators in this file) keep
the same symbol name but now come from typing_extensions.

In `@tests/unit/models/requests/test_query_request.py`:
- Around line 144-152: The test test_solr_legacy_plain_dict currently verifies
coercion but misses asserting the deprecation warning for top-level Solr filter
payloads; update the test to wrap the call that triggers coercion (the
SolrVectorSearchRequest.model_validate(qr.solr) invocation) in a pytest.warns
context for the expected DeprecationWarning (or the project's specific
deprecation warning class) so the test both validates the resulting
SolrVectorSearchRequest fields and asserts the deprecation warning was emitted
when QueryRequest/solr is validated.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b9d2d0fc-2583-4a4c-8d14-c16e2a393091

📥 Commits

Reviewing files that changed from the base of the PR and between 95197e9 and aa1abc1.

📒 Files selected for processing (6)
  • docs/rag_guide.md
  • docs/responses.md
  • src/models/requests.py
  • src/utils/vector_search.py
  • tests/unit/models/requests/test_query_request.py
  • tests/unit/utils/test_vector_search.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: build-pr
  • GitHub Check: Konflux kflux-prd-rh02 / lightspeed-stack-on-pull-request
  • GitHub Check: E2E: server mode / ci / group 1
  • GitHub Check: E2E: library mode / ci / group 3
  • GitHub Check: E2E: server mode / ci / group 3
  • GitHub Check: E2E: library mode / ci / group 1
  • GitHub Check: E2E: server mode / ci / group 2
  • GitHub Check: E2E: library mode / ci / group 2
  • GitHub Check: E2E Tests for Lightspeed Evaluation job
🧰 Additional context used
📓 Path-based instructions (3)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Use absolute imports for internal modules: from authentication import get_auth_dependency
Import FastAPI dependencies with: from fastapi import APIRouter, HTTPException, Request, status, Depends
Import Llama Stack client with: from llama_stack_client import AsyncLlamaStackClient
Check constants.py for shared constants before defining new ones
All modules start with descriptive docstrings explaining purpose
Use logger = get_logger(__name__) from log.py for module logging
Type aliases defined at module level for clarity
Use Final[type] as type hint for all constants
All functions require docstrings with brief descriptions
Complete type annotations for parameters and return types in functions
Use typing_extensions.Self for model validators in Pydantic models
Use modern union type syntax str | int instead of Union[str, int]
Use Optional[Type] for optional type hints
Use snake_case with descriptive, action-oriented function names (get_, validate_, check_)
Avoid in-place parameter modification anti-patterns; return new data structures instead
Use async def for I/O operations and external API calls
Handle APIConnectionError from Llama Stack in error handling
Use standard log levels with clear purposes: debug, info, warning, error
All classes require descriptive docstrings explaining purpose
Use PascalCase for class names with standard suffixes: Configuration, Error/Exception, Resolver, Interface
Use ABC for abstract base classes with @abstractmethod decorators
Use @model_validator and @field_validator for Pydantic model validation
Complete type annotations for all class attributes; use specific types, not Any
Follow Google Python docstring conventions with Parameters, Returns, Raises, and Attributes sections

Files:

  • tests/unit/models/requests/test_query_request.py
  • src/models/requests.py
  • tests/unit/utils/test_vector_search.py
  • src/utils/vector_search.py
tests/{unit,integration}/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

tests/{unit,integration}/**/*.py: Use pytest for all unit and integration tests
Do not use unittest; pytest is the standard for this project
Use pytest-mock for AsyncMock objects in tests
Use marker pytest.mark.asyncio for async tests
Unit tests require 60% coverage, integration tests 10%

Files:

  • tests/unit/models/requests/test_query_request.py
  • tests/unit/utils/test_vector_search.py
src/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Pydantic models extend ConfigurationBase for config, BaseModel for data models

Files:

  • src/models/requests.py
  • src/utils/vector_search.py
🧠 Learnings (6)
📚 Learning: 2026-02-23T14:11:46.950Z
Learnt from: asimurka
Repo: lightspeed-core/lightspeed-stack PR: 1198
File: src/utils/responses.py:184-188
Timestamp: 2026-02-23T14:11:46.950Z
Learning: The query request validator in the Responses API flow requires that `query_request.model` and `query_request.provider` must either both be specified or both be absent. The concatenated format (e.g., `model="provider/model"` with `provider=None`) is not permitted by the validator.

Applied to files:

  • tests/unit/models/requests/test_query_request.py
  • src/models/requests.py
📚 Learning: 2026-04-19T15:40:25.624Z
Learnt from: CR
Repo: lightspeed-core/lightspeed-stack PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-19T15:40:25.624Z
Learning: Applies to **/*.py : Use `typing_extensions.Self` for model validators in Pydantic models

Applied to files:

  • src/models/requests.py
📚 Learning: 2026-02-25T07:46:33.545Z
Learnt from: asimurka
Repo: lightspeed-core/lightspeed-stack PR: 1211
File: src/models/responses.py:8-16
Timestamp: 2026-02-25T07:46:33.545Z
Learning: In the Python codebase, requests.py should use OpenAIResponseInputTool as Tool while responses.py uses OpenAIResponseTool as Tool. This difference is intentional due to differing schemas for input vs output tools in llama-stack-api. Apply this distinction consistently to other models under src/models (e.g., ensure request-related tools use the InputTool variant and response-related tools use the ResponseTool variant). If adding new tools, choose the corresponding InputTool or Tool class based on whether the tool represents input or output, and document the rationale in code comments.

Applied to files:

  • src/models/requests.py
📚 Learning: 2026-03-17T11:34:53.242Z
Learnt from: are-ces
Repo: lightspeed-core/lightspeed-stack PR: 1335
File: docs/config.md:411-411
Timestamp: 2026-03-17T11:34:53.242Z
Learning: In the lightspeed-stack project (`src/models/config.py`, `docs/config.md`), the internal Solr filter `is_chunk:true` (defined as `SOLR_CHUNK_FILTER_QUERY` in `src/constants.py`) is always injected by the system for OKP searches and is intentionally hidden from users. The `chunk_filter_query` field in `OkpConfiguration` is user-facing and additive-only, but the documentation must NOT mention the internal `is_chunk:true` behavior — this is a deliberate design decision by the maintainers.

Applied to files:

  • src/models/requests.py
  • docs/rag_guide.md
📚 Learning: 2026-01-12T10:58:40.230Z
Learnt from: blublinsky
Repo: lightspeed-core/lightspeed-stack PR: 972
File: src/models/config.py:459-513
Timestamp: 2026-01-12T10:58:40.230Z
Learning: In lightspeed-core/lightspeed-stack, for Python files under src/models, when a user claims a fix is done but the issue persists, verify the current code state before accepting the fix. Steps: review the diff, fetch the latest changes, run relevant tests, reproduce the issue, search the codebase for lingering references to the original problem, confirm the fix is applied and not undone by subsequent commits, and validate with local checks to ensure the issue is resolved.

Applied to files:

  • src/models/requests.py
📚 Learning: 2026-04-15T18:54:07.540Z
Learnt from: Lifto
Repo: lightspeed-core/lightspeed-stack PR: 1510
File: src/models/requests.py:769-773
Timestamp: 2026-04-15T18:54:07.540Z
Learning: In lightspeed-core/lightspeed-stack request models, keep schema-level size limits defined as inline numeric literals (e.g., Pydantic Field max_length values used for validation) rather than extracting them into constants.py. Only extract values intended as configurable runtime defaults (e.g., DEFAULT_* settings like header/file upload sizes). Do not flag inline numeric literals used directly in Pydantic Field constraints or field validators as an extraction-to-constants issue.

Applied to files:

  • src/models/requests.py
🔇 Additional comments (7)
docs/responses.md (1)

111-111: LGTM — the Responses docs now reflect the structured Solr payload.

The updated text clearly documents the optional mode, filters, and legacy filter-only compatibility.

Also applies to: 602-602

tests/unit/models/requests/test_query_request.py (1)

154-162: LGTM — structured Solr payload coverage is clear.

This verifies both explicit mode forwarding and filter preservation for the new request shape.

src/models/requests.py (2)

126-173: LGTM — the Solr request model preserves compatibility cleanly.

The structured fields, extra="forbid", and before-validator provide typed request handling while preserving legacy filter-only payloads.


191-191: LGTM — request models now expose the typed Solr payload.

QueryRequest and ResponsesRequest consistently use Optional[SolrVectorSearchRequest], which keeps downstream vector search code type-safe.

Also applies to: 282-292, 755-755, 781-781

docs/rag_guide.md (1)

342-342: LGTM — OKP/Solr request-mode guidance is aligned.

The guide documents the default mode, per-request solr payload, and legacy compatibility without exposing internal Solr-only filters.

Also applies to: 360-372

src/utils/vector_search.py (1)

20-20: LGTM — Solr query params now use the typed request shape.

mode is correctly defaulted when absent, and only filters is forwarded as the provider-specific solr payload.

Also applies to: 56-87, 453-456, 529-535

tests/unit/utils/test_vector_search.py (1)

72-102: LGTM — vector-search Solr mode coverage is solid.

The tests cover explicit mode, defaulting, filter forwarding, and the actual vector_io.query params path.

Also applies to: 634-666

@tisnik
Copy link
Copy Markdown
Contributor

tisnik commented Apr 20, 2026

PR Reviewer Guide 🔍

(Review updated until commit aa1abc1)

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ No major issues detected

@tisnik
Copy link
Copy Markdown
Contributor

tisnik commented Apr 20, 2026

Persistent review updated to latest commit aa1abc1

@tisnik
Copy link
Copy Markdown
Contributor

tisnik commented Apr 20, 2026

🛠️ PR-Agent Configurations:
==================== CONFIG ====================
config.cli_mode = True  
config.model = 'gpt-5.4-2026-03-05'  
config.fallback_models = ['o4-mini']  
config.git_provider = 'github'  
config.publish_output = True  
config.publish_output_progress = True  
config.verbosity_level = 0  
config.use_extra_bad_extensions = False  
config.log_level = 'DEBUG'  
config.use_wiki_settings_file = True  
config.use_repo_settings_file = True  
config.use_global_settings_file = True  
config.disable_auto_feedback = False  
config.ai_timeout = 120  
config.custom_reasoning_model = False  
config.response_language = 'en-US'  
config.patch_extension_skip_types = ['.md', '.txt']  
config.allow_dynamic_context = True  
config.max_extra_lines_before_dynamic_context = 10  
config.patch_extra_lines_before = 5  
config.patch_extra_lines_after = 1  
config.output_relevant_configurations = False  
config.large_patch_policy = 'clip'  
config.duplicate_prompt_examples = False  
config.seed = -1  
config.temperature = 0.2  
config.ignore_pr_title = ['^\\[Auto\\]', '^Auto']  
config.ignore_pr_target_branches = []  
config.ignore_pr_source_branches = []  
config.ignore_pr_labels = []  
config.ignore_pr_authors = []  
config.ignore_repositories = []  
config.ignore_language_framework = []  
config.is_auto_command = False  
config.enable_ai_metadata = False  
config.reasoning_effort = 'medium'  
config.enable_claude_extended_thinking = False  
config.extract_issue_from_branch = True  
config.branch_issue_regex = ''  
config.enable_custom_labels = False  

==================== PR_REVIEWER ====================
pr_reviewer.require_score_review = False  
pr_reviewer.require_tests_review = True  
pr_reviewer.require_estimate_effort_to_review = True  
pr_reviewer.require_can_be_split_review = False  
pr_reviewer.require_security_review = True  
pr_reviewer.require_estimate_contribution_time_cost = False  
pr_reviewer.require_todo_scan = False  
pr_reviewer.require_ticket_analysis_review = True  
pr_reviewer.publish_output_no_suggestions = True  
pr_reviewer.persistent_comment = True  
pr_reviewer.extra_instructions = ''  
pr_reviewer.num_max_findings = 3  
pr_reviewer.final_update_message = True  
pr_reviewer.enable_review_labels_security = True  
pr_reviewer.enable_review_labels_effort = True  
pr_reviewer.require_all_thresholds_for_incremental_review = False  
pr_reviewer.minimal_commits_for_incremental_review = 0  
pr_reviewer.minimal_minutes_for_incremental_review = 0  
pr_reviewer.enable_intro_text = True  
pr_reviewer.enable_help_text = False  

==================== PR_DESCRIPTION ====================
pr_description.publish_labels = False  
pr_description.add_original_user_description = True  
pr_description.generate_ai_title = False  
pr_description.use_bullet_points = True  
pr_description.extra_instructions = ''  
pr_description.enable_pr_type = True  
pr_description.final_update_message = True  
pr_description.enable_help_text = False  
pr_description.enable_help_comment = False  
pr_description.enable_pr_diagram = True  
pr_description.publish_description_as_comment = False  
pr_description.publish_description_as_comment_persistent = True  
pr_description.enable_semantic_files_types = True  
pr_description.collapsible_file_list = 'adaptive'  
pr_description.collapsible_file_list_threshold = 6  
pr_description.inline_file_summary = False  
pr_description.use_description_markers = False  
pr_description.enable_large_pr_handling = True  
pr_description.include_generated_by_header = True  
pr_description.max_ai_calls = 4  
pr_description.async_ai_calls = True  

==================== PR_QUESTIONS ====================
pr_questions.enable_help_text = False  
pr_questions.use_conversation_history = True  

==================== PR_CODE_SUGGESTIONS ====================
pr_code_suggestions.commitable_code_suggestions = False  
pr_code_suggestions.dual_publishing_score_threshold = -1  
pr_code_suggestions.focus_only_on_problems = True  
pr_code_suggestions.extra_instructions = ''  
pr_code_suggestions.enable_help_text = False  
pr_code_suggestions.enable_chat_text = False  
pr_code_suggestions.persistent_comment = True  
pr_code_suggestions.max_history_len = 4  
pr_code_suggestions.publish_output_no_suggestions = True  
pr_code_suggestions.suggestions_score_threshold = 0  
pr_code_suggestions.new_score_mechanism = True  
pr_code_suggestions.new_score_mechanism_th_high = 9  
pr_code_suggestions.new_score_mechanism_th_medium = 7  
pr_code_suggestions.auto_extended_mode = True  
pr_code_suggestions.num_code_suggestions_per_chunk = 3  
pr_code_suggestions.max_number_of_calls = 3  
pr_code_suggestions.parallel_calls = True  
pr_code_suggestions.final_clip_factor = 0.8  
pr_code_suggestions.decouple_hunks = False  
pr_code_suggestions.demand_code_suggestions_self_review = False  
pr_code_suggestions.code_suggestions_self_review_text = '**Author self-review**: I have reviewed the PR code suggestions, and addressed the relevant ones.'  
pr_code_suggestions.approve_pr_on_self_review = False  
pr_code_suggestions.fold_suggestions_on_self_review = True  

==================== PR_CUSTOM_PROMPT ====================
pr_custom_prompt.prompt = 'The code suggestions should focus only on the following:\n- ...\n- ...\n...\n'  
pr_custom_prompt.suggestions_score_threshold = 0  
pr_custom_prompt.num_code_suggestions_per_chunk = 3  
pr_custom_prompt.self_reflect_on_custom_suggestions = True  
pr_custom_prompt.enable_help_text = False  

==================== PR_ADD_DOCS ====================
pr_add_docs.extra_instructions = ''  
pr_add_docs.docs_style = 'Sphinx'  
pr_add_docs.file = ''  
pr_add_docs.class_name = ''  

==================== PR_UPDATE_CHANGELOG ====================
pr_update_changelog.push_changelog_changes = False  
pr_update_changelog.extra_instructions = ''  
pr_update_changelog.add_pr_link = True  
pr_update_changelog.skip_ci_on_push = True  

==================== PR_ANALYZE ====================
pr_analyze.enable_help_text = True  

==================== PR_TEST ====================
pr_test.extra_instructions = ''  
pr_test.testing_framework = ''  
pr_test.num_tests = 3  
pr_test.avoid_mocks = True  
pr_test.file = ''  
pr_test.class_name = ''  
pr_test.enable_help_text = False  

==================== PR_IMPROVE_COMPONENT ====================
pr_improve_component.num_code_suggestions = 4  
pr_improve_component.extra_instructions = ''  
pr_improve_component.file = ''  
pr_improve_component.class_name = ''  

==================== PR_HELP ====================
pr_help.force_local_db = False  
pr_help.num_retrieved_snippets = 5  

==================== PR_HELP_DOCS ====================
pr_help_docs.repo_url = ''  
pr_help_docs.repo_default_branch = 'main'  
pr_help_docs.docs_path = 'docs'  
pr_help_docs.exclude_root_readme = False  
pr_help_docs.supported_doc_exts = ['.md', '.mdx', '.rst']  
pr_help_docs.enable_help_text = False  

==================== PR_SIMILAR_ISSUE ====================
pr_similar_issue.skip_comments = False  
pr_similar_issue.force_update_dataset = False  
pr_similar_issue.max_issues_to_scan = 500  
pr_similar_issue.vectordb = 'pinecone'  

==================== PR_FIND_SIMILAR_COMPONENT ====================
pr_find_similar_component.class_name = ''  
pr_find_similar_component.file = ''  
pr_find_similar_component.search_from_org = False  
pr_find_similar_component.allow_fallback_less_words = True  
pr_find_similar_component.number_of_results = 5  

@tisnik
Copy link
Copy Markdown
Contributor

tisnik commented Apr 20, 2026

Persistent review updated to latest commit aa1abc1

Comment thread src/models/requests.py
media_type: The optional media type for response format (application/json or text/plain).
vector_store_ids: The optional list of specific vector store IDs to query for RAG.
shield_ids: The optional list of safety shield IDs to apply.
solr: Optional Solr inline RAG options (mode, filters) or legacy filter-only dict.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For mode this is fine, but I think we will have to make filters available for any RAG provider. WDYT?

Copy link
Copy Markdown
Contributor Author

@asimurka asimurka Apr 20, 2026

Choose a reason for hiding this comment

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

I'm not sure what's a long term goal. But what is now solr.filters was solr before. What I'm trying to achieve is that it is clear that mode attribute is related to solr.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants