Skip to content

Commit fb2772f

Browse files
committed
Removing attachment metadata and streamlining conversation attachments.
1 parent be812e7 commit fb2772f

6 files changed

Lines changed: 95 additions & 9 deletions

File tree

src/app/endpoints/conversations_v2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ def build_conversation_turn_from_cache_entry(entry: CacheEntry) -> ConversationT
257257
"""
258258
# Create Message objects for user and assistant
259259
messages = [
260-
Message(content=entry.query, type="user"),
260+
Message(content=entry.query, type="user", attachments=entry.attachments),
261261
Message(content=entry.response, type="assistant"),
262262
]
263263

src/cache/postgres_cache.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class PostgresCache(Cache):
3636
referenced_documents | jsonb | |
3737
tool_calls | jsonb | |
3838
tool_results | jsonb | |
39+
attachments | jsonb | |
3940
Indexes:
4041
"cache_pkey" PRIMARY KEY, btree (user_id, conversation_id, created_at)
4142
"timestamps" btree (created_at)
@@ -60,6 +61,7 @@ class PostgresCache(Cache):
6061
referenced_documents jsonb,
6162
tool_calls jsonb,
6263
tool_results jsonb,
64+
attachments jsonb,
6365
PRIMARY KEY(user_id, conversation_id, created_at)
6466
);
6567
"""
@@ -81,7 +83,7 @@ class PostgresCache(Cache):
8183

8284
SELECT_CONVERSATION_HISTORY_STATEMENT = """
8385
SELECT query, response, provider, model, started_at, completed_at,
84-
referenced_documents, tool_calls, tool_results
86+
referenced_documents, tool_calls, tool_results, attachments
8587
FROM cache
8688
WHERE user_id=%s AND conversation_id=%s
8789
ORDER BY created_at
@@ -90,8 +92,8 @@ class PostgresCache(Cache):
9092
INSERT_CONVERSATION_HISTORY_STATEMENT = """
9193
INSERT INTO cache(user_id, conversation_id, created_at, started_at, completed_at,
9294
query, response, provider, model, referenced_documents,
93-
tool_calls, tool_results)
94-
VALUES (%s, %s, CURRENT_TIMESTAMP, %s, %s, %s, %s, %s, %s, %s, %s, %s)
95+
tool_calls, tool_results, attachments)
96+
VALUES (%s, %s, CURRENT_TIMESTAMP, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
9597
"""
9698

9799
QUERY_CACHE_SIZE = """
@@ -321,6 +323,24 @@ def get( # pylint: disable=R0914
321323
e,
322324
)
323325

326+
# Parse attachments back into Attachment objects
327+
attachments_data = conversation_entry[9]
328+
attachments_obj = None
329+
if attachments_data:
330+
try:
331+
from models.requests import Attachment
332+
333+
attachments_obj = [
334+
Attachment.model_validate(att) for att in attachments_data
335+
]
336+
except (ValueError, TypeError) as e:
337+
logger.warning(
338+
"Failed to deserialize attachments for "
339+
"conversation %s: %s",
340+
conversation_id,
341+
e,
342+
)
343+
324344
cache_entry = CacheEntry(
325345
query=conversation_entry[0],
326346
response=conversation_entry[1],
@@ -331,6 +351,7 @@ def get( # pylint: disable=R0914
331351
referenced_documents=docs_obj,
332352
tool_calls=tool_calls_obj,
333353
tool_results=tool_results_obj,
354+
attachments=attachments_obj,
334355
)
335356
result.append(cache_entry)
336357

@@ -405,6 +426,20 @@ def insert_or_append(
405426
e,
406427
)
407428

429+
attachments_json = None
430+
if cache_entry.attachments:
431+
try:
432+
attachments_as_dicts = [
433+
att.model_dump(mode="json") for att in cache_entry.attachments
434+
]
435+
attachments_json = json.dumps(attachments_as_dicts)
436+
except (TypeError, ValueError) as e:
437+
logger.warning(
438+
"Failed to serialize attachments for conversation %s: %s",
439+
conversation_id,
440+
e,
441+
)
442+
408443
# the whole operation is run in one transaction
409444
with self.connection.cursor() as cursor:
410445
cursor.execute(
@@ -421,6 +456,7 @@ def insert_or_append(
421456
referenced_documents_json,
422457
tool_calls_json,
423458
tool_results_json,
459+
attachments_json,
424460
),
425461
)
426462

src/cache/sqlite_cache.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class SQLiteCache(Cache):
3737
referenced_documents | text | |
3838
tool_calls | text | |
3939
tool_results | text | |
40+
attachments | text | |
4041
Indexes:
4142
"cache_pkey" PRIMARY KEY, btree (user_id, conversation_id, created_at)
4243
"cache_key_key" UNIQUE CONSTRAINT, btree (key)
@@ -59,6 +60,7 @@ class SQLiteCache(Cache):
5960
referenced_documents text,
6061
tool_calls text,
6162
tool_results text,
63+
attachments text,
6264
PRIMARY KEY(user_id, conversation_id, created_at)
6365
);
6466
"""
@@ -80,7 +82,7 @@ class SQLiteCache(Cache):
8082

8183
SELECT_CONVERSATION_HISTORY_STATEMENT = """
8284
SELECT query, response, provider, model, started_at, completed_at,
83-
referenced_documents, tool_calls, tool_results
85+
referenced_documents, tool_calls, tool_results, attachments
8486
FROM cache
8587
WHERE user_id=? AND conversation_id=?
8688
ORDER BY created_at
@@ -89,8 +91,8 @@ class SQLiteCache(Cache):
8991
INSERT_CONVERSATION_HISTORY_STATEMENT = """
9092
INSERT INTO cache(user_id, conversation_id, created_at, started_at, completed_at,
9193
query, response, provider, model, referenced_documents,
92-
tool_calls, tool_results)
93-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
94+
tool_calls, tool_results, attachments)
95+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
9496
"""
9597

9698
QUERY_CACHE_SIZE = """
@@ -301,6 +303,24 @@ def get( # pylint: disable=R0914
301303
e,
302304
)
303305

306+
# Parse attachments back into Attachment objects
307+
attachments_json_str = conversation_entry[9]
308+
attachments_obj = None
309+
if attachments_json_str:
310+
try:
311+
from models.requests import Attachment
312+
313+
attachments_data = json.loads(attachments_json_str)
314+
attachments_obj = [
315+
Attachment.model_validate(att) for att in attachments_data
316+
]
317+
except (json.JSONDecodeError, ValueError) as e:
318+
logger.warning(
319+
"Failed to deserialize attachments for conversation %s: %s",
320+
conversation_id,
321+
e,
322+
)
323+
304324
cache_entry = CacheEntry(
305325
query=conversation_entry[0],
306326
response=conversation_entry[1],
@@ -311,6 +331,7 @@ def get( # pylint: disable=R0914
311331
referenced_documents=docs_obj,
312332
tool_calls=tool_calls_obj,
313333
tool_results=tool_results_obj,
334+
attachments=attachments_obj,
314335
)
315336
result.append(cache_entry)
316337

@@ -386,6 +407,20 @@ def insert_or_append(
386407
e,
387408
)
388409

410+
attachments_json = None
411+
if cache_entry.attachments:
412+
try:
413+
attachments_as_dicts = [
414+
att.model_dump(mode="json") for att in cache_entry.attachments
415+
]
416+
attachments_json = json.dumps(attachments_as_dicts)
417+
except (TypeError, ValueError) as e:
418+
logger.warning(
419+
"Failed to serialize attachments for conversation %s: %s",
420+
conversation_id,
421+
e,
422+
)
423+
389424
cursor.execute(
390425
self.INSERT_CONVERSATION_HISTORY_STATEMENT,
391426
(
@@ -401,6 +436,7 @@ def insert_or_append(
401436
referenced_documents_json,
402437
tool_calls_json,
403438
tool_results_json,
439+
attachments_json,
404440
),
405441
)
406442

src/models/cache_entry.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
"""Model for conversation history cache entry."""
22

3-
from typing import Optional
3+
from typing import TYPE_CHECKING, Optional
44
from pydantic import BaseModel
55
from utils.types import ReferencedDocument, ToolCallSummary, ToolResultSummary
66

7+
if TYPE_CHECKING:
8+
from models.requests import Attachment
9+
710

811
class CacheEntry(BaseModel):
912
"""Model representing a cache entry.
@@ -16,6 +19,7 @@ class CacheEntry(BaseModel):
1619
referenced_documents: List of documents referenced by the response
1720
tool_calls: List of tool calls made during response generation
1821
tool_results: List of tool results from tool calls
22+
attachments: Optional list of attachments included with the query
1923
"""
2024

2125
query: str
@@ -27,3 +31,4 @@ class CacheEntry(BaseModel):
2731
referenced_documents: Optional[list[ReferencedDocument]] = None
2832
tool_calls: Optional[list[ToolCallSummary]] = None
2933
tool_results: Optional[list[ToolResultSummary]] = None
34+
attachments: Optional[list["Attachment"]] = None

src/models/responses.py

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

33
"""Models for REST API responses."""
44

5-
from typing import Any, ClassVar, Literal, Optional, Union
5+
from typing import Any, ClassVar, Literal, Optional, Union, TYPE_CHECKING
66

77
from fastapi import status
88
from pydantic import BaseModel, Field
@@ -13,6 +13,9 @@
1313
from quota.quota_exceed_error import QuotaExceedError
1414
from utils.types import RAGChunk, ReferencedDocument, ToolCallSummary, ToolResultSummary
1515

16+
if TYPE_CHECKING:
17+
from models.requests import Attachment
18+
1619
SUCCESSFUL_RESPONSE_DESCRIPTION = "Successful response"
1720
BAD_REQUEST_DESCRIPTION = "Invalid request format"
1821
UNAUTHORIZED_DESCRIPTION = "Unauthorized"
@@ -810,6 +813,7 @@ class Message(BaseModel):
810813
Attributes:
811814
content: The message content.
812815
type: The type of message.
816+
attachments: Optional list of attachments included with the message.
813817
"""
814818

815819
content: str = Field(
@@ -822,6 +826,10 @@ class Message(BaseModel):
822826
description="The type of message",
823827
examples=["user", "assistant", "system", "developer"],
824828
)
829+
attachments: Optional[list["Attachment"]] = Field(
830+
default=None,
831+
description="Optional attachments included with this message",
832+
)
825833

826834

827835
class ConversationTurn(BaseModel):

src/utils/query.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ def store_query_results( # pylint: disable=too-many-arguments,too-many-locals
420420
referenced_documents=summary.referenced_documents,
421421
tool_calls=summary.tool_calls,
422422
tool_results=summary.tool_results,
423+
attachments=query_request.attachments,
423424
)
424425

425426
logger.info("Storing conversation in cache")

0 commit comments

Comments
 (0)