Skip to content

Commit e30e4eb

Browse files
committed
fix: route uploaded resource requests to RAG
1 parent d0476c0 commit e30e4eb

5 files changed

Lines changed: 30 additions & 7 deletions

File tree

docs/architecture.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ Routing policy:
6666

6767
- Greetings and other social turns normally resolve directly.
6868
- Weak or empty RAG context does not automatically trigger web search.
69+
- Missing pre-retrieved RAG context does not mean resources are absent; explicit requests about uploaded documents route to `answer_from_rag`, then retrieval runs.
6970
- Web search is selected for external, fresh, or otherwise web-dependent information.
7071
- A URL in the message or history is available context, not an automatic fetch instruction.
7172
- Direct URL fetching happens only when inspecting the resource is necessary.

scripts/finetune/router_prompt.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
1818
Routing rules:
1919
- answer_direct: question answerable from general knowledge, no live data or documents needed
20-
- answer_from_rag: question about uploaded documents or the knowledge base
20+
- answer_from_rag: question about uploaded documents or the knowledge base; select this even when no context has been retrieved yet, because retrieval happens after routing
2121
- web_search: needs current or live information (news, recent events, live prices)
2222
- asset_price: user wants current price or quote for a specific stock or crypto (symbols required)
2323
- search_finance_tools: user needs financial ratios, statements, or structured data via a tool (query required)
@@ -34,9 +34,13 @@ def format_user_turn(
3434
parts: list[str] = [f"User message: {message.strip()}"]
3535

3636
if rag_context.strip():
37-
parts.append(f"Available RAG context: yes — {rag_context.strip()}")
37+
parts.append(f"Pre-retrieved RAG context: yes — {rag_context.strip()}")
3838
else:
39-
parts.append("Available RAG context: no")
39+
parts.append(
40+
"Pre-retrieved RAG context: none. Resource availability: unknown; "
41+
"context is retrieved after routing. If the message asks about uploaded "
42+
"documents or the knowledge base, choose answer_from_rag."
43+
)
4044

4145
if history:
4246
last = history[-1]

src/api/rag_chat_helpers.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ def should_bind_composio_tools(
203203
204204
Routing rules:
205205
- answer_direct: question answerable from general knowledge, no live data or documents needed
206-
- answer_from_rag: question about uploaded documents or the knowledge base
206+
- answer_from_rag: question about uploaded documents or the knowledge base; select this even when no context has been retrieved yet, because retrieval happens after routing
207207
- web_search: needs current or live information (news, recent events, live prices)
208208
- asset_price: user wants current price or quote for a specific stock or crypto (symbols required)
209209
- search_finance_tools: user needs financial ratios, statements, or structured data via a tool (query required)
@@ -253,9 +253,13 @@ def _get_router_action_schema() -> str:
253253

254254
def _format_router_user_turn(*, message: str, rag_context: str) -> str:
255255
if rag_context.strip():
256-
context_line = f"Available RAG context: yes — {rag_context.strip()}"
256+
context_line = f"Pre-retrieved RAG context: yes — {rag_context.strip()}"
257257
else:
258-
context_line = "Available RAG context: no"
258+
context_line = (
259+
"Pre-retrieved RAG context: none. Resource availability: unknown; "
260+
"context is retrieved after routing. If the message asks about uploaded "
261+
"documents or the knowledge base, choose answer_from_rag."
262+
)
259263
return f"User message: {message.strip()}\n{context_line}"
260264

261265

tests/finetune/test_router_prompt.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ def test_system_prompt_contains_all_actions():
1717
def test_format_user_turn_no_context():
1818
result = format_user_turn(message="What is a P/E ratio?")
1919
assert "User message: What is a P/E ratio?" in result
20-
assert "Available RAG context: no" in result
20+
assert "Resource availability: unknown" in result
21+
assert "context is retrieved after routing" in result
2122
assert "Conversation history: none" in result
2223

2324

tests/test_rag_chat_helpers.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,19 @@ def test_router_has_no_disable_flag():
616616
assert "router_enabled" not in Settings.model_fields
617617

618618

619+
def test_router_turn_does_not_treat_missing_context_as_missing_resources():
620+
from src.api.rag_chat_helpers import _format_router_user_turn
621+
622+
turn = _format_router_user_turn(
623+
message="Using only my uploaded resources, summarize the key findings.",
624+
rag_context="",
625+
)
626+
627+
assert "Resource availability: unknown" in turn
628+
assert "context is retrieved after routing" in turn
629+
assert "Available RAG context: no" not in turn
630+
631+
619632
@pytest.mark.asyncio
620633
async def test_classify_chat_action_parses_valid_response():
621634
from unittest.mock import AsyncMock, patch

0 commit comments

Comments
 (0)