fix: improve auto-edge reliability — error visibility, similarity-based strength, heuristic docs
- Surface auto-edge errors in store response (auto_edge_error key) instead of silently swallowing exceptions, making failures diagnosable - Pass similarity score as edge strength so higher-confidence matches get stronger edges instead of always defaulting to 0.8 - Document why same-type pairs and REQUIRES/FOLLOWS are excluded from the heuristic table vs edge-proposer.py Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
194990d424
commit
5312402a7b
@ -22,6 +22,9 @@ SYNC_SCRIPT = Path(__file__).parent / "scripts" / "memory-git-sync.sh"
|
|||||||
|
|
||||||
# Auto-edge heuristics: (new_type, match_type) -> (rel_type, direction)
|
# Auto-edge heuristics: (new_type, match_type) -> (rel_type, direction)
|
||||||
# direction "ab" = new->match, "ba" = match->new
|
# direction "ab" = new->match, "ba" = match->new
|
||||||
|
# Subset of edge-proposer.py's TYPE_HEURISTICS — excludes:
|
||||||
|
# - Same-type pairs (decision/decision, fix/fix, solution/solution): too noisy for auto-edges
|
||||||
|
# - REQUIRES/FOLLOWS pairs: need stronger signal than title recall provides
|
||||||
AUTO_EDGE_HEURISTICS = {
|
AUTO_EDGE_HEURISTICS = {
|
||||||
("fix", "problem"): ("SOLVES", "ab"),
|
("fix", "problem"): ("SOLVES", "ab"),
|
||||||
("solution", "problem"): ("SOLVES", "ab"),
|
("solution", "problem"): ("SOLVES", "ab"),
|
||||||
@ -555,7 +558,8 @@ def _auto_create_edges(
|
|||||||
|
|
||||||
Uses recall to find similar memories and heuristic type-pairs to choose
|
Uses recall to find similar memories and heuristic type-pairs to choose
|
||||||
relationship types. Returns list of created edge info dicts.
|
relationship types. Returns list of created edge info dicts.
|
||||||
Never raises — failures are silently swallowed so store always succeeds.
|
Never raises — returns partial results or empty list with error info so
|
||||||
|
store always succeeds. Returns (edges_list, error_string_or_None).
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# Build recall query from title + tags for better precision (#4)
|
# Build recall query from title + tags for better precision (#4)
|
||||||
@ -613,11 +617,15 @@ def _auto_create_edges(
|
|||||||
from_title = title if from_id == memory_id else match_title
|
from_title = title if from_id == memory_id else match_title
|
||||||
to_title = match_title if to_id == match_id else title
|
to_title = match_title if to_id == match_id else title
|
||||||
desc = f"Auto-edge: {from_title} → {to_title}"
|
desc = f"Auto-edge: {from_title} → {to_title}"
|
||||||
|
# Use similarity as edge strength when available (default 0.8)
|
||||||
|
sim = result.get("similarity")
|
||||||
|
strength = round(sim, 2) if sim is not None else 0.8
|
||||||
edge_id = client.relate(
|
edge_id = client.relate(
|
||||||
from_id=from_id,
|
from_id=from_id,
|
||||||
to_id=to_id,
|
to_id=to_id,
|
||||||
rel_type=rel_type,
|
rel_type=rel_type,
|
||||||
description=desc,
|
description=desc,
|
||||||
|
strength=strength,
|
||||||
)
|
)
|
||||||
|
|
||||||
if edge_id: # Empty string means duplicate
|
if edge_id: # Empty string means duplicate
|
||||||
@ -630,9 +638,9 @@ def _auto_create_edges(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
return created_edges
|
return created_edges, None
|
||||||
except Exception:
|
except Exception as e:
|
||||||
return []
|
return [], f"{type(e).__name__}: {e}"
|
||||||
|
|
||||||
|
|
||||||
def handle_tool_call(tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
|
def handle_tool_call(tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
@ -669,16 +677,19 @@ def handle_tool_call(tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any
|
|||||||
tags=tags,
|
tags=tags,
|
||||||
)
|
)
|
||||||
episode_logged = True
|
episode_logged = True
|
||||||
auto_edges = _auto_create_edges(client, memory_id, title, mem_type, tags)
|
auto_edges, auto_edge_error = _auto_create_edges(
|
||||||
_trigger_git_sync()
|
client, memory_id, title, mem_type, tags
|
||||||
return ok(
|
|
||||||
{
|
|
||||||
"success": True,
|
|
||||||
"memory_id": memory_id,
|
|
||||||
"episode_logged": episode_logged,
|
|
||||||
"auto_edges": auto_edges,
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
_trigger_git_sync()
|
||||||
|
result = {
|
||||||
|
"success": True,
|
||||||
|
"memory_id": memory_id,
|
||||||
|
"episode_logged": episode_logged,
|
||||||
|
"auto_edges": auto_edges,
|
||||||
|
}
|
||||||
|
if auto_edge_error:
|
||||||
|
result["auto_edge_error"] = auto_edge_error
|
||||||
|
return ok(result)
|
||||||
|
|
||||||
elif tool_name == "memory_recall":
|
elif tool_name == "memory_recall":
|
||||||
results = client.recall(
|
results = client.recall(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user