forked from odysseus-dev/odysseus
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathattachment_refs.py
More file actions
164 lines (143 loc) · 5.63 KB
/
Copy pathattachment_refs.py
File metadata and controls
164 lines (143 loc) · 5.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
"""Attachment reference helpers for chat storage and tool manifests.
Live model calls may need provider-specific data URLs for the current turn.
Persisted history and search indexes should keep stable upload references and
human-readable text instead of duplicating raw media bytes.
"""
from __future__ import annotations
import json
import re
from typing import Any, Iterable
DATA_URL_RE = re.compile(
r"data:[^;,\s\"']+;base64,[A-Za-z0-9+/=]+",
re.IGNORECASE,
)
MEDIA_BLOCK_TYPES = {
"image",
"image_url",
"input_image",
"audio",
"input_audio",
"file",
}
def strip_inline_data_urls(text: str) -> str:
"""Replace inline data URLs with a compact marker."""
if not isinstance(text, str) or ";base64," not in text:
return text
return DATA_URL_RE.sub("[inline media omitted from persisted history]", text)
def attachment_ref(info: dict[str, Any]) -> dict[str, Any]:
"""Return the stable attachment reference shape used outside raw uploads."""
upload_id = str(info.get("id") or info.get("attachment_id") or "").strip()
try:
size = int(info.get("size") or 0)
except (TypeError, ValueError):
size = 0
ref = {
"type": "attachment_ref",
"attachment_id": upload_id,
"name": info.get("name") or info.get("original_name") or upload_id,
"mime": info.get("mime") or "application/octet-stream",
"size": size,
}
checksum = info.get("checksum_sha256") or info.get("sha256") or info.get("hash")
if checksum:
ref["checksum_sha256"] = checksum
created_at = info.get("created_at") or info.get("uploaded_at")
if created_at:
ref["created_at"] = created_at
for key in ("width", "height", "vision", "vision_model", "gallery_id"):
value = info.get(key)
if value is not None:
ref[key] = value
return ref
def attachment_refs_from_metadata(metadata: dict[str, Any] | None) -> list[dict[str, Any]]:
"""Extract attachment refs from message metadata."""
attachments = (metadata or {}).get("attachments") or []
if not isinstance(attachments, list):
return []
refs: list[dict[str, Any]] = []
for item in attachments:
if isinstance(item, dict):
ref = attachment_ref(item)
if ref.get("attachment_id"):
refs.append(ref)
return refs
def _ref_line(ref: dict[str, Any]) -> str:
parts = [f"Attachment: {ref.get('name') or ref.get('attachment_id') or 'upload'}"]
if ref.get("attachment_id"):
parts.append(f"id={ref['attachment_id']}")
if ref.get("mime"):
parts.append(f"mime={ref['mime']}")
if ref.get("size"):
parts.append(f"size={ref['size']} bytes")
if ref.get("checksum_sha256"):
parts.append(f"sha256={ref['checksum_sha256']}")
line = "[" + " | ".join(parts) + "]"
if ref.get("vision"):
line += f"\n[Attachment description: {str(ref['vision']).strip()}]"
return line
def _text_from_blocks(blocks: Iterable[Any]) -> str:
lines: list[str] = []
omitted_media = 0
for block in blocks:
if isinstance(block, str):
lines.append(strip_inline_data_urls(block))
continue
if not isinstance(block, dict):
continue
block_type = block.get("type")
if block_type == "text":
text = block.get("text")
if isinstance(text, str) and text:
lines.append(strip_inline_data_urls(text))
elif block_type == "attachment_ref":
lines.append(_ref_line(block))
elif block_type in MEDIA_BLOCK_TYPES:
omitted_media += 1
else:
try:
encoded = json.dumps(block, ensure_ascii=True, sort_keys=True)
except TypeError:
encoded = str(block)
lines.append(strip_inline_data_urls(encoded))
if omitted_media:
plural = "s" if omitted_media != 1 else ""
lines.append(f"[{omitted_media} inline media payload{plural} omitted]")
return "\n".join(line for line in lines if line).strip()
def persistable_message_content(
content: Any,
metadata: dict[str, Any] | None = None,
) -> str:
"""Return content safe for DB persistence and FTS indexing.
Multimodal provider blocks are collapsed to readable text plus stable
attachment reference lines from metadata. This avoids storing base64 media
in ``chat_messages.content`` while preserving enough context for reloads,
search, and later turns.
"""
if isinstance(content, list):
text = _text_from_blocks(content)
refs = attachment_refs_from_metadata(metadata)
ref_lines = [_ref_line(ref) for ref in refs]
if ref_lines:
text = "\n".join([part for part in (text, "\n".join(ref_lines)) if part]).strip()
return text
if isinstance(content, str):
return strip_inline_data_urls(content)
try:
return strip_inline_data_urls(json.dumps(content, ensure_ascii=True, sort_keys=True))
except TypeError:
return strip_inline_data_urls(str(content))
def search_index_text(content: Any) -> str:
"""Best-effort searchable text for legacy stored content."""
if isinstance(content, str):
raw = content.strip()
if raw.startswith("[") and '"type"' in raw:
try:
parsed = json.loads(content)
except (TypeError, ValueError):
parsed = None
if isinstance(parsed, list):
return _text_from_blocks(parsed)
return strip_inline_data_urls(content)
if isinstance(content, list):
return _text_from_blocks(content)
return persistable_message_content(content)