Skip to content

Commit fbeff37

Browse files
committed
fix(search-service): Add structured_answer support to SearchContext and SearchOutput
- Add structured_answer field to SearchOutput schema with StructuredAnswer import - Add structured_answer field to SearchContext dataclass for pipeline data flow - Fix quote style in search_service.py debug logging (double quotes) - Apply Ruff formatting to search_service.py This ensures structured output with citations generated by generation_stage.py flows through to the SearchOutput response and reaches the frontend. Related to PR #626 (Structured Output schema) Enables PR #630 (Frontend Citations UI) Signed-off-by: Claude <[email protected]> Signed-off-by: manavgup <[email protected]>
1 parent ff72b13 commit fbeff37

File tree

3 files changed

+15
-2
lines changed

3 files changed

+15
-2
lines changed

backend/rag_solution/schemas/search_schema.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from pydantic import UUID4, BaseModel, ConfigDict
66

77
from rag_solution.schemas.llm_usage_schema import TokenWarning
8+
from rag_solution.schemas.structured_output_schema import StructuredAnswer
89
from vectordbs.data_types import DocumentMetadata, QueryResult
910

1011

@@ -44,6 +45,7 @@ class SearchOutput(BaseModel):
4445
query_results: List of QueryResult
4546
rewritten_query: Optional rewritten version of the original query
4647
evaluation: Optional evaluation metrics and results
48+
structured_answer: Optional structured answer with citations (when requested)
4749
"""
4850

4951
answer: str
@@ -55,5 +57,6 @@ class SearchOutput(BaseModel):
5557
cot_output: dict[str, Any] | None = None # Chain of Thought reasoning steps when requested
5658
metadata: dict[str, Any] | None = None # Additional metadata including conversation context
5759
token_warning: TokenWarning | None = None # Token usage warning if approaching limits
60+
structured_answer: StructuredAnswer | None = None # Structured output with citations when requested
5861

5962
model_config = ConfigDict(from_attributes=True)

backend/rag_solution/services/pipeline/search_context.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from rag_solution.schemas.chain_of_thought_schema import ChainOfThoughtOutput
1515
from rag_solution.schemas.llm_usage_schema import TokenWarning
1616
from rag_solution.schemas.search_schema import SearchInput
17+
from rag_solution.schemas.structured_output_schema import StructuredAnswer
1718
from vectordbs.data_types import DocumentMetadata, QueryResult
1819

1920

@@ -46,6 +47,7 @@ class SearchContext: # pylint: disable=too-many-instance-attributes
4647
evaluation: Answer quality evaluation
4748
cot_output: Chain of Thought reasoning steps
4849
token_warning: Token usage warnings
50+
structured_answer: Structured answer with citations
4951
5052
# Execution Metadata
5153
start_time: When search started
@@ -73,6 +75,7 @@ class SearchContext: # pylint: disable=too-many-instance-attributes
7375
evaluation: dict[str, Any] | None = None
7476
cot_output: ChainOfThoughtOutput | None = None
7577
token_warning: TokenWarning | None = None
78+
structured_answer: StructuredAnswer | None = None
7679

7780
# Execution Metadata
7881
start_time: float = field(default_factory=time.time)

backend/rag_solution/services/search_service.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -570,9 +570,16 @@ async def _search_with_pipeline(self, search_input: SearchInput) -> SearchOutput
570570
cot_output_dict = result_context.cot_output.model_dump() if result_context.cot_output else None
571571

572572
# Debug: Log document_metadata before creating SearchOutput
573-
logger.info("📊 SEARCH_SERVICE: result_context.document_metadata has %d items", len(result_context.document_metadata))
573+
logger.info(
574+
"📊 SEARCH_SERVICE: result_context.document_metadata has %d items", len(result_context.document_metadata)
575+
)
574576
if result_context.document_metadata:
575-
logger.info("📊 SEARCH_SERVICE: First doc_metadata = %s", result_context.document_metadata[0].document_name if hasattr(result_context.document_metadata[0], 'document_name') else 'NO DOCUMENT_NAME')
577+
logger.info(
578+
"📊 SEARCH_SERVICE: First doc_metadata = %s",
579+
result_context.document_metadata[0].document_name
580+
if hasattr(result_context.document_metadata[0], "document_name")
581+
else "NO DOCUMENT_NAME",
582+
)
576583

577584
search_output = SearchOutput(
578585
answer=cleaned_answer,

0 commit comments

Comments
 (0)