Skip to content

Commit 788f5e3

Browse files
committed
First draft of referenced_documents caching
Signed-off-by: Maysun J Faisal <maysunaneek@gmail.com>
1 parent 44435d2 commit 788f5e3

11 files changed

Lines changed: 139 additions & 78 deletions

File tree

src/app/endpoints/conversations_v2.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,13 +240,23 @@ def check_conversation_existence(user_id: str, conversation_id: str) -> None:
240240

241241
def transform_chat_message(entry: CacheEntry) -> dict[str, Any]:
242242
"""Transform the message read from cache into format used by response payload."""
243+
user_message = {
244+
"content": entry.query,
245+
"type": "user"
246+
}
247+
assistant_message: dict[str, Any] = {
248+
"content": entry.response,
249+
"type": "assistant"
250+
}
251+
252+
# Check for additional_kwargs and add it to the assistant message if it exists
253+
if entry.additional_kwargs:
254+
assistant_message["additional_kwargs"] = entry.additional_kwargs.model_dump()
255+
243256
return {
244257
"provider": entry.provider,
245258
"model": entry.model,
246-
"messages": [
247-
{"content": entry.query, "type": "user"},
248-
{"content": entry.response, "type": "assistant"},
249-
],
259+
"messages": [user_message, assistant_message],
250260
"started_at": entry.started_at,
251261
"completed_at": entry.completed_at,
252262
}

src/app/endpoints/query.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from llama_stack_client.types.model_list_response import ModelListResponse
2323
from llama_stack_client.types.shared.interleaved_content_item import TextContentItem
2424
from llama_stack_client.types.tool_execution_step import ToolExecutionStep
25+
from pydantic import AnyUrl
2526

2627
import constants
2728
import metrics
@@ -32,6 +33,7 @@
3233
from client import AsyncLlamaStackClientHolder
3334
from configuration import configuration
3435
from metrics.utils import update_llm_token_count_from_turn
36+
from models.cache_entry import CacheEntry, AdditionalKwargs
3537
from models.config import Action
3638
from models.database.conversations import UserConversation
3739
from models.requests import Attachment, QueryRequest
@@ -331,16 +333,27 @@ async def query_endpoint_handler( # pylint: disable=R0914
331333
)
332334

333335
completed_at = datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%SZ")
336+
337+
additional_kwargs_obj = None
338+
if referenced_documents:
339+
additional_kwargs_obj = AdditionalKwargs(
340+
referenced_documents=referenced_documents
341+
)
342+
cache_entry = CacheEntry(
343+
query=query_request.query,
344+
response=summary.llm_response,
345+
provider=provider_id,
346+
model=model_id,
347+
started_at=started_at,
348+
completed_at=completed_at,
349+
additional_kwargs=additional_kwargs_obj
350+
)
351+
334352
store_conversation_into_cache(
335353
configuration,
336354
user_id,
337355
conversation_id,
338-
provider_id,
339-
model_id,
340-
query_request.query,
341-
summary.llm_response,
342-
started_at,
343-
completed_at,
356+
cache_entry,
344357
_skip_userid_check,
345358
topic_summary,
346359
)

src/app/endpoints/streaming_query.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
)
2121
from llama_stack_client.types.shared import ToolCall
2222
from llama_stack_client.types.shared.interleaved_content_item import TextContentItem
23+
from pydantic import AnyUrl
2324

2425
from app.database import get_session
2526
from app.endpoints.query import (
@@ -42,10 +43,11 @@
4243
from constants import DEFAULT_RAG_TOOL
4344
import metrics
4445
from metrics.utils import update_llm_token_count_from_turn
46+
from models.cache_entry import CacheEntry, AdditionalKwargs
4547
from models.config import Action
4648
from models.database.conversations import UserConversation
4749
from models.requests import QueryRequest
48-
from models.responses import ForbiddenResponse, UnauthorizedResponse
50+
from models.responses import ForbiddenResponse, UnauthorizedResponse, ReferencedDocument
4951
from utils.endpoints import (
5052
check_configuration_loaded,
5153
create_referenced_documents_with_metadata,
@@ -733,16 +735,29 @@ async def response_generator(
733735
)
734736

735737
completed_at = datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%SZ")
738+
739+
referenced_documents = create_referenced_documents_with_metadata(summary, metadata_map)
740+
741+
additional_kwargs_obj = None
742+
if referenced_documents:
743+
additional_kwargs_obj = AdditionalKwargs(
744+
referenced_documents=referenced_documents
745+
)
746+
cache_entry = CacheEntry(
747+
query=query_request.query,
748+
response=summary.llm_response,
749+
provider=provider_id,
750+
model=model_id,
751+
started_at=started_at,
752+
completed_at=completed_at,
753+
additional_kwargs=additional_kwargs_obj
754+
)
755+
736756
store_conversation_into_cache(
737757
configuration,
738758
user_id,
739759
conversation_id,
740-
provider_id,
741-
model_id,
742-
query_request.query,
743-
summary.llm_response,
744-
started_at,
745-
completed_at,
760+
cache_entry,
746761
_skip_userid_check,
747762
topic_summary,
748763
)

src/cache/cache.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
from abc import ABC, abstractmethod
44

5-
from models.cache_entry import CacheEntry, ConversationData
5+
from models.cache_entry import CacheEntry
6+
from models.responses import ConversationData
67
from utils.suid import check_suid
78

89

src/cache/in_memory_cache.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
"""In-memory cache implementation."""
22

33
from cache.cache import Cache
4-
from models.cache_entry import CacheEntry, ConversationData
4+
from models.cache_entry import CacheEntry
55
from models.config import InMemoryCacheConfig
6+
from models.responses import ConversationData
67
from log import get_logger
78
from utils.connection_decorator import connection
89

src/cache/noop_cache.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
"""No-operation cache implementation."""
22

33
from cache.cache import Cache
4-
from models.cache_entry import CacheEntry, ConversationData
4+
from models.cache_entry import CacheEntry
5+
from models.responses import ConversationData
56
from log import get_logger
67
from utils.connection_decorator import connection
78

src/cache/postgres_cache.py

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55
from cache.cache import Cache
66
from cache.cache_error import CacheError
7-
from models.cache_entry import CacheEntry, ConversationData
7+
from models.cache_entry import CacheEntry, AdditionalKwargs
88
from models.config import PostgreSQLDatabaseConfiguration
9+
from models.responses import ConversationData
910
from log import get_logger
1011
from utils.connection_decorator import connection
1112

@@ -37,15 +38,16 @@ class PostgresCache(Cache):
3738

3839
CREATE_CACHE_TABLE = """
3940
CREATE TABLE IF NOT EXISTS cache (
40-
user_id text NOT NULL,
41-
conversation_id text NOT NULL,
42-
created_at timestamp NOT NULL,
43-
started_at text,
44-
completed_at text,
45-
query text,
46-
response text,
47-
provider text,
48-
model text,
41+
user_id text NOT NULL,
42+
conversation_id text NOT NULL,
43+
created_at timestamp NOT NULL,
44+
started_at text,
45+
completed_at text,
46+
query text,
47+
response text,
48+
provider text,
49+
model text,
50+
additional_kwargs jsonb,
4951
PRIMARY KEY(user_id, conversation_id, created_at)
5052
);
5153
"""
@@ -66,16 +68,16 @@ class PostgresCache(Cache):
6668
"""
6769

6870
SELECT_CONVERSATION_HISTORY_STATEMENT = """
69-
SELECT query, response, provider, model, started_at, completed_at
71+
SELECT query, response, provider, model, started_at, completed_at, additional_kwargs
7072
FROM cache
7173
WHERE user_id=%s AND conversation_id=%s
7274
ORDER BY created_at
7375
"""
7476

7577
INSERT_CONVERSATION_HISTORY_STATEMENT = """
7678
INSERT INTO cache(user_id, conversation_id, created_at, started_at, completed_at,
77-
query, response, provider, model)
78-
VALUES (%s, %s, CURRENT_TIMESTAMP, %s, %s, %s, %s, %s, %s)
79+
query, response, provider, model, additional_kwargs)
80+
VALUES (%s, %s, CURRENT_TIMESTAMP, %s, %s, %s, %s, %s, %s, %s)
7981
"""
8082

8183
QUERY_CACHE_SIZE = """
@@ -211,13 +213,19 @@ def get(
211213

212214
result = []
213215
for conversation_entry in conversation_entries:
216+
# Parse it back into an LLMResponse object
217+
additional_kwargs_data = conversation_entry[6]
218+
additional_kwargs_obj = None
219+
if additional_kwargs_data:
220+
additional_kwargs_obj = AdditionalKwargs.model_validate(additional_kwargs_data)
214221
cache_entry = CacheEntry(
215222
query=conversation_entry[0],
216223
response=conversation_entry[1],
217224
provider=conversation_entry[2],
218225
model=conversation_entry[3],
219226
started_at=conversation_entry[4],
220227
completed_at=conversation_entry[5],
228+
additional_kwargs=additional_kwargs_obj,
221229
)
222230
result.append(cache_entry)
223231

@@ -245,6 +253,10 @@ def insert_or_append(
245253
raise CacheError("insert_or_append: cache is disconnected")
246254

247255
try:
256+
additional_kwargs_json = None
257+
if cache_entry.additional_kwargs:
258+
# Use exclude_none=True to keep JSON clean
259+
additional_kwargs_json = cache_entry.additional_kwargs.model_dump_json(exclude_none=True)
248260
# the whole operation is run in one transaction
249261
with self.connection.cursor() as cursor:
250262
cursor.execute(
@@ -258,6 +270,7 @@ def insert_or_append(
258270
cache_entry.response,
259271
cache_entry.provider,
260272
cache_entry.model,
273+
additional_kwargs_json,
261274
),
262275
)
263276

src/cache/sqlite_cache.py

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
from time import time
44

55
import sqlite3
6+
import json
67

78
from cache.cache import Cache
89
from cache.cache_error import CacheError
9-
from models.cache_entry import CacheEntry, ConversationData
10+
from models.cache_entry import CacheEntry, AdditionalKwargs
1011
from models.config import SQLiteDatabaseConfiguration
12+
from models.responses import ConversationData
1113
from log import get_logger
1214
from utils.connection_decorator import connection
1315

@@ -41,15 +43,16 @@ class SQLiteCache(Cache):
4143

4244
CREATE_CACHE_TABLE = """
4345
CREATE TABLE IF NOT EXISTS cache (
44-
user_id text NOT NULL,
45-
conversation_id text NOT NULL,
46-
created_at int NOT NULL,
47-
started_at text,
48-
completed_at text,
49-
query text,
50-
response text,
51-
provider text,
52-
model text,
46+
user_id text NOT NULL,
47+
conversation_id text NOT NULL,
48+
created_at int NOT NULL,
49+
started_at text,
50+
completed_at text,
51+
query text,
52+
response text,
53+
provider text,
54+
model text,
55+
additional_kwargs text,
5356
PRIMARY KEY(user_id, conversation_id, created_at)
5457
);
5558
"""
@@ -70,16 +73,16 @@ class SQLiteCache(Cache):
7073
"""
7174

7275
SELECT_CONVERSATION_HISTORY_STATEMENT = """
73-
SELECT query, response, provider, model, started_at, completed_at
76+
SELECT query, response, provider, model, started_at, completed_at, additional_kwargs
7477
FROM cache
7578
WHERE user_id=? AND conversation_id=?
7679
ORDER BY created_at
7780
"""
7881

7982
INSERT_CONVERSATION_HISTORY_STATEMENT = """
8083
INSERT INTO cache(user_id, conversation_id, created_at, started_at, completed_at,
81-
query, response, provider, model)
82-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
84+
query, response, provider, model, additional_kwargs)
85+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
8386
"""
8487

8588
QUERY_CACHE_SIZE = """
@@ -209,13 +212,18 @@ def get(
209212

210213
result = []
211214
for conversation_entry in conversation_entries:
215+
additional_kwargs_json = conversation_entry[6]
216+
additional_kwargs_obj = None
217+
if additional_kwargs_json:
218+
additional_kwargs_obj = AdditionalKwargs.model_validate_json(additional_kwargs_json)
212219
cache_entry = CacheEntry(
213220
query=conversation_entry[0],
214221
response=conversation_entry[1],
215222
provider=conversation_entry[2],
216223
model=conversation_entry[3],
217224
started_at=conversation_entry[4],
218225
completed_at=conversation_entry[5],
226+
additional_kwargs=additional_kwargs_obj,
219227
)
220228
result.append(cache_entry)
221229

@@ -244,6 +252,11 @@ def insert_or_append(
244252

245253
cursor = self.connection.cursor()
246254
current_time = time()
255+
256+
additional_kwargs_json = None
257+
if cache_entry.additional_kwargs:
258+
additional_kwargs_json = cache_entry.additional_kwargs.model_dump_json(exclude_none=True)
259+
247260
cursor.execute(
248261
self.INSERT_CONVERSATION_HISTORY_STATEMENT,
249262
(
@@ -256,6 +269,7 @@ def insert_or_append(
256269
cache_entry.response,
257270
cache_entry.provider,
258271
cache_entry.model,
272+
additional_kwargs_json,
259273
),
260274
)
261275

0 commit comments

Comments
 (0)