forked from interviewstreet/hackerrank-orchestrate-june26
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcache.py
More file actions
59 lines (45 loc) · 1.69 KB
/
Copy pathcache.py
File metadata and controls
59 lines (45 loc) · 1.69 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
"""Deterministic on-disk cache for VLM model calls.
Keys are derived from (model, temperature, prompt, image hashes) so that a
cache hit is reproducible and crash-safe (US-006: resume without reprocessing
completed claims). Cache store lives under code/.cache/ (git-ignored).
"""
import hashlib
import json
from pathlib import Path
from typing import Any, Optional
from config import CACHE_DIR
def _key_str(*parts: Any) -> str:
return "\u0001".join(str(p) for p in parts)
def cache_key(model: str, temperature, system_prompt: str, user_prompt: str,
image_hashes) -> str:
"""Compute a stable SHA-256 cache key for a model call."""
h = hashlib.sha256()
h.update(_key_str(model, temperature, system_prompt, user_prompt).encode("utf-8"))
for ih in sorted(image_hashes or []):
h.update(ih.encode("utf-8"))
return h.hexdigest()
def cache_path(key: str) -> Path:
return CACHE_DIR / f"{key}.json"
def cache_get(key: str) -> Optional[Any]:
p = cache_path(key)
if not p.exists():
return None
try:
return json.loads(p.read_text(encoding="utf-8"))
except Exception:
return None
def cache_set(key: str, value: Any) -> None:
p = cache_path(key)
try:
p.write_text(json.dumps(value, ensure_ascii=False), encoding="utf-8")
except Exception:
# Cache is best-effort; never crash the pipeline on a write failure.
pass
def get_or_compute(key: str, compute):
"""Return cached value for ``key`` or compute, cache, and return it."""
cached = cache_get(key)
if cached is not None:
return cached, True # (value, was_cache_hit)
value = compute()
cache_set(key, value)
return value, False