Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions src/dakera/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -699,19 +699,34 @@ class RecalledMemory:
memory_type: str
importance: float
score: float
"""Ranking score — equals smart_score when present, then weighted_score, then raw score."""
smart_score: float | None = None
"""Raw smart_score from the server (the primary ranking key)."""
weighted_score: float | None = None
"""Raw weighted_score from the server."""
metadata: dict[str, Any] | None = None
created_at: str | None = None
depth: int | None = None
"""KG-3: hop depth at which this memory was found (only set on associated memories)."""

@classmethod
def from_dict(cls, data: dict[str, Any]) -> "RecalledMemory":
smart_score = data.get("smart_score")
weighted_score = data.get("weighted_score")
if smart_score is not None:
score = smart_score
elif weighted_score is not None:
score = weighted_score
else:
score = data.get("score", 0.0)
return cls(
id=data["id"],
content=data["content"],
memory_type=data.get("memory_type", "episodic"),
importance=data.get("importance", 0.5),
score=data.get("score", 0.0),
score=score,
smart_score=smart_score,
weighted_score=weighted_score,
metadata=data.get("metadata"),
created_at=data.get("created_at"),
depth=data.get("depth"),
Expand All @@ -733,9 +748,13 @@ class RecallResponse:

@classmethod
def _normalize_memory(cls, m: dict[str, Any]) -> dict[str, Any]:
"""Flatten nested {memory: {...}, score: ...} into a single dict."""
"""Flatten nested {memory: {...}, score, weighted_score, smart_score} into a single dict."""
if "memory" in m and isinstance(m["memory"], dict):
flat = {**m["memory"], "score": m.get("score", 0.0)}
if "smart_score" in m:
flat["smart_score"] = m["smart_score"]
if "weighted_score" in m:
flat["weighted_score"] = m["weighted_score"]
return flat
return m

Expand Down
89 changes: 89 additions & 0 deletions tests/test_smart_score.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
"""Tests for RecalledMemory.score priority: smart_score > weighted_score > raw score."""

import pytest

from dakera.models import RecalledMemory, RecallResponse


def test_smart_score_takes_priority():
data = {
"id": "m1", "content": "test", "memory_type": "episodic", "importance": 0.8,
"score": 0.5, "weighted_score": 0.7, "smart_score": 0.9,
}
m = RecalledMemory.from_dict(data)
assert m.score == pytest.approx(0.9), ".score must equal smart_score when present"
assert m.smart_score == pytest.approx(0.9)
assert m.weighted_score == pytest.approx(0.7)


def test_weighted_score_fallback():
data = {
"id": "m2", "content": "test", "memory_type": "episodic", "importance": 0.8,
"score": 0.5, "weighted_score": 0.7,
}
m = RecalledMemory.from_dict(data)
assert m.score == pytest.approx(0.7), ".score must equal weighted_score when smart_score absent"
assert m.smart_score is None
assert m.weighted_score == pytest.approx(0.7)


def test_raw_score_fallback():
data = {
"id": "m3", "content": "test", "memory_type": "episodic", "importance": 0.8,
"score": 0.55,
}
m = RecalledMemory.from_dict(data)
assert m.score == pytest.approx(0.55), (
".score must equal raw score when neither smart_score nor weighted_score"
)
assert m.smart_score is None
assert m.weighted_score is None


def test_recall_response_normalize_forwards_smart_score():
raw = {
"memories": [
{
"memory": {
"id": "m4",
"content": "nested",
"memory_type": "episodic",
"importance": 0.9,
"created_at": "2026-01-01T00:00:00Z",
"tags": [],
},
"score": 0.4,
"weighted_score": 0.6,
"smart_score": 0.85,
}
]
}
resp = RecallResponse.from_dict(raw)
assert len(resp.memories) == 1
m = resp.memories[0]
assert m.score == pytest.approx(0.85)
assert m.smart_score == pytest.approx(0.85)
assert m.weighted_score == pytest.approx(0.6)


def test_recall_response_normalize_without_smart_score():
raw = {
"memories": [
{
"memory": {
"id": "m5",
"content": "nested2",
"memory_type": "semantic",
"importance": 0.7,
"created_at": "2026-01-01T00:00:00Z",
"tags": [],
},
"score": 0.3,
"weighted_score": 0.55,
}
]
}
resp = RecallResponse.from_dict(raw)
m = resp.memories[0]
assert m.score == pytest.approx(0.55)
assert m.smart_score is None
Loading