feat: implement RAG capabilities and Context Pane integration

- Add RAG capabilities using LlamaIndex and ChromaDB
- Implement RAGManager for PHB indexing and retrieval
- Integrate RAG pipeline into orchestrator to trigger queries based on extracted entities
- Update TUI to include a 3-column layout with a real-time Context Pane
- Define ContextUpdate data models in src/llm/models.py
- Update requirements.txt with new dependencies
This commit is contained in:
2026-05-26 22:07:12 -07:00
parent f4c98fb2b9
commit 954f2f50d8
6 changed files with 281 additions and 5 deletions
+49 -3
View File
@@ -6,8 +6,9 @@ from typing import List, Optional
import numpy as np
from src.llm.models import ExtractionResult
from src.llm.models import ContextUpdate, ExtractionResult
from src.llm.processor import LLMProcessor
from src.rag.manager import RAGManager
from src.stt.listener import AudioListener
from src.stt.transcriber import Transcriber
from src.ui.tui import ConfirmationApp
@@ -37,10 +38,12 @@ class PipelineOrchestrator:
self.listener = AudioListener(loop=self.loop)
self.transcriber = Transcriber(model_size="small")
self.processor = LLMProcessor()
self.rag_manager = RAGManager()
# Queues
self.transcript_queue = asyncio.Queue()
self.proposal_queue = asyncio.Queue()
self.context_queue = asyncio.Queue()
self.is_running = False
@@ -148,6 +151,9 @@ class PipelineOrchestrator:
f"LLM Worker: Proposal generated. Putting into proposal queue. (Lore: {len(result.lore_updates)}, Char: {len(result.character_updates)})"
)
await self.proposal_queue.put(result)
# Trigger RAG query based on extracted entities
await self._trigger_rag_queries(result)
else:
logger.info("LLM Worker: No relevant game data extracted.")
@@ -157,6 +163,43 @@ class PipelineOrchestrator:
# Small sleep
await asyncio.sleep(0.1)
async def _trigger_rag_queries(self, result: ExtractionResult):
"""
Triggers RAG queries based on the extracted entities and results.
"""
queries = set()
# Collect entities from lore updates
for update in result.lore_updates:
if update.entity_name:
queries.add(update.entity_name)
# Collect entities from character updates
for update in result.character_updates:
if update.character_name:
queries.add(update.character_name)
# Collect events as potential queries
for event in result.significant_events:
queries.add(event)
if not queries:
logger.info("RAG: No query terms identified from extraction result.")
return
for query in queries:
logger.info(f"RAG: Triggering query for: {query}")
try:
# Run retrieval in a thread to avoid blocking the event loop
updates = await asyncio.to_thread(self.rag_manager.retrieve, query)
for update in updates:
await self.context_queue.put(update)
logger.info(
f"RAG: Retrieved snippet for {query} from {update.source}"
)
except Exception as e:
logger.error(f"RAG: Error retrieving context for {query}: {e}")
def _get_wiki_context(self) -> str:
"""
Reads all files in the lore directory and returns them as a 저희 context string.
@@ -188,8 +231,11 @@ class PipelineOrchestrator:
logger.info("TUI Worker started.")
try:
# Launch TUI exactly once.
# Pass the proposal queue to the app.
app = ConfirmationApp(proposal_queue=self.proposal_queue)
# Pass the proposal queue and context queue to the app.
app = ConfirmationApp(
proposal_queue=self.proposal_queue,
context_queue=self.context_queue,
)
await app.run_async()
self.stop()
except Exception as e: