Compare commits

..

3 commits

Author SHA1 Message Date
bc3fc9d347 chore(deps): update dependency @types/node to v25.9.3 2026-06-12 16:27:03 +00:00
2cab42355f
Fix CLS clustering: include temporal_next edges in cluster building
_build_hebbian_clusters() only used hebbian edges, but 97% of hebbian
edges are self-loops from reinforce_record(). Only 7 are cross-record.
temporal_next edges (140) provide the cross-record connectivity needed
to form clusters >= CLUSTER_MIN_SIZE. Without them, consolidation never
creates summaries, no consolidated_from edges exist, and the graph
remains fragmented with 514 isolated nodes and max CC=58.
2026-06-12 18:07:24 +02:00
1b7c89de3b
Fix QdrantStore.all_records missing with_vectors=True
Qdrant's scroll() defaults to returning only payloads, not vectors.
Without with_vectors=True, all 1963 records had empty embeddings,
causing community detection to fail (0 communities) and topology
to show insufficient_data. Now 1959/1963 records have 1024-dim
embeddings and 1844 communities are detected.
2026-06-12 17:54:44 +02:00
2 changed files with 11 additions and 4 deletions

View file

@ -644,6 +644,7 @@ class QdrantStore:
offset=offset,
scroll_filter=table_filter,
with_payload=True,
with_vectors=True,
)
all_points.extend(points)
if next_offset is None:

View file

@ -296,16 +296,22 @@ def run_light_consolidation(
def _build_hebbian_clusters(store: MemoryStore) -> list[list[UUID]]:
"""Find connected components in the hebbian edge graph with size >= CLUSTER_MIN_SIZE."""
"""Find connected components in the hebbian+temporal_next edge graph
with size >= CLUSTER_MIN_SIZE.
Hebbian edges capture semantic similarity (dedup/reinforce);
temporal_next edges capture sequential proximity (same-session inserts
within 5 minutes). Both are valid signals for CLS clustering.
"""
edges_df = store.db.open_table(EDGES_TABLE).to_pandas()
if edges_df.empty:
return []
hebbian = edges_df[edges_df["edge_type"] == "hebbian"]
if hebbian.empty:
relevant = edges_df[edges_df["edge_type"].isin(("hebbian", "temporal_next"))]
if relevant.empty:
return []
adj: dict[UUID, set[UUID]] = {}
for _, row in hebbian.iterrows():
for _, row in relevant.iterrows():
src = UUID(row["src"])
dst = UUID(row["dst"])
adj.setdefault(src, set()).add(dst)