Wire up query history: localStorage session persistence + sidebar UI

This commit is contained in:
2026-08-14 17:44:36 +07:00
parent 9be5819710
commit 057d4ed9dc
23 changed files with 1231 additions and 30 deletions
+44 -5
View File
@@ -20,6 +20,7 @@ class RetrievalTrace:
citations: tuple[dict[str, Any], ...]
correlation_id: str | None = None
otel_trace_id: str | None = None
conversation_id: str | None = None
created_at: datetime | None = None
@@ -63,6 +64,7 @@ class PostgresTraceRepository:
citations: tuple[dict[str, Any], ...],
correlation_id: str | None = None,
otel_trace_id: str | None = None,
conversation_id: str | None = None,
) -> str:
import psycopg
@@ -73,13 +75,13 @@ class PostgresTraceRepository:
INSERT INTO rag_retrieval_trace (
trace_id, query_text, subject_scope, query_intent,
decision, reason, resolved_drug_id, citations,
correlation_id, otel_trace_id
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s::jsonb, %s, %s)
correlation_id, otel_trace_id, conversation_id
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s::jsonb, %s, %s, %s)
""",
(
trace_id, query, subject_scope, intent, decision, reason,
resolved_drug_id, json.dumps(citations, ensure_ascii=False),
correlation_id, otel_trace_id,
correlation_id, otel_trace_id, conversation_id,
),
)
return trace_id
@@ -92,7 +94,7 @@ class PostgresTraceRepository:
"""
SELECT trace_id::text, query_text, subject_scope, query_intent,
decision, reason, resolved_drug_id, citations,
correlation_id, otel_trace_id, created_at
correlation_id, otel_trace_id, conversation_id, created_at
FROM rag_retrieval_trace WHERE trace_id = %s
""",
(trace_id,),
@@ -103,9 +105,46 @@ class PostgresTraceRepository:
trace_id=row[0], query=row[1], subject_scope=row[2], intent=row[3],
decision=row[4], reason=row[5], resolved_drug_id=row[6],
citations=tuple(row[7]), correlation_id=row[8], otel_trace_id=row[9],
created_at=row[10],
conversation_id=row[10], created_at=row[11],
)
def list_by_conversation(
self, conversation_id: str, limit: int
) -> list[RetrievalTrace]:
"""Past queries for one session — Feature-List #25 (lịch sử tra
cứu), most recent first. Scoped to `conversation_id` on purpose:
this system has no auth anywhere (`apps/api-gateway`/`auth-service`
are unbuilt — see README), so an unscoped listing would mix every
browser's/user's queries together. Citations/answer text are NOT
persisted here (only decision/reason/resolved_drug_id) — a history
entry is for re-running the same query, not replaying its old
answer verbatim.
"""
import psycopg
with psycopg.connect(self._dsn, connect_timeout=5) as connection:
rows = connection.execute(
"""
SELECT trace_id::text, query_text, subject_scope, query_intent,
decision, reason, resolved_drug_id, citations,
correlation_id, otel_trace_id, conversation_id, created_at
FROM rag_retrieval_trace
WHERE conversation_id = %s
ORDER BY created_at DESC
LIMIT %s
""",
(conversation_id, limit),
).fetchall()
return [
RetrievalTrace(
trace_id=row[0], query=row[1], subject_scope=row[2], intent=row[3],
decision=row[4], reason=row[5], resolved_drug_id=row[6],
citations=tuple(row[7]), correlation_id=row[8], otel_trace_id=row[9],
conversation_id=row[10], created_at=row[11],
)
for row in rows
]
def save_feedback(
self,
*,