Initial release: iai-mcp v0.1.0
Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: XNLLLLH <XNLLLLH@users.noreply.github.com>
This commit is contained in:
commit
f6b876fbe7
332 changed files with 97258 additions and 0 deletions
121
tests/test_curiosity_bridge_edges.py
Normal file
121
tests/test_curiosity_bridge_edges.py
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
"""Tests for curiosity_bridge edges.
|
||||
|
||||
curiosity_bridge edges:
|
||||
- Created when fire_curiosity surfaces a mid/high-entropy question.
|
||||
- Weight proportional to entropy.
|
||||
- Persist in the edges table with edge_type='curiosity_bridge'.
|
||||
- adds fading on resolution.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
import pytest
|
||||
|
||||
from iai_mcp.store import EDGES_TABLE, MemoryStore
|
||||
from iai_mcp.types import EMBED_DIM, MemoryRecord
|
||||
|
||||
|
||||
def _rec(vec=None, tags=None):
|
||||
vec = vec or [1.0] + [0.0] * (EMBED_DIM - 1)
|
||||
now = datetime.now(timezone.utc)
|
||||
return MemoryRecord(
|
||||
id=uuid4(),
|
||||
tier="episodic",
|
||||
literal_surface="r",
|
||||
aaak_index="",
|
||||
embedding=vec,
|
||||
community_id=None,
|
||||
centrality=0.0,
|
||||
detail_level=2,
|
||||
pinned=False,
|
||||
stability=0.0,
|
||||
difficulty=0.0,
|
||||
last_reviewed=None,
|
||||
never_decay=False,
|
||||
never_merge=False,
|
||||
provenance=[],
|
||||
created_at=now,
|
||||
updated_at=now,
|
||||
tags=list(tags or []),
|
||||
language="en",
|
||||
)
|
||||
|
||||
|
||||
class _Hit:
|
||||
def __init__(self, rid: UUID, score: float):
|
||||
self.record_id = rid
|
||||
self.score = score
|
||||
|
||||
|
||||
def test_curiosity_bridge_edge_on_fire(tmp_path):
|
||||
"""fire_curiosity creates curiosity_bridge edges from question id -> triggering records."""
|
||||
from iai_mcp.curiosity import fire_curiosity
|
||||
|
||||
store = MemoryStore(path=tmp_path)
|
||||
recs = [_rec() for _ in range(3)]
|
||||
for r in recs:
|
||||
store.insert(r)
|
||||
hits = [_Hit(r.id, 0.5) for r in recs]
|
||||
|
||||
q = fire_curiosity(
|
||||
store, hits, "ambiguous", entropy=0.85,
|
||||
session_id="s-bridge", turn=1,
|
||||
)
|
||||
assert q is not None
|
||||
|
||||
edges = store.db.open_table(EDGES_TABLE).to_pandas()
|
||||
cb = edges[edges["edge_type"] == "curiosity_bridge"]
|
||||
assert len(cb) >= 3 # One per triggering record
|
||||
|
||||
|
||||
def test_curiosity_bridge_edge_weight_proportional_entropy(tmp_path):
|
||||
"""Higher entropy -> larger edge delta."""
|
||||
from iai_mcp.curiosity import fire_curiosity
|
||||
|
||||
store = MemoryStore(path=tmp_path)
|
||||
r1 = _rec()
|
||||
r2 = _rec()
|
||||
store.insert(r1)
|
||||
store.insert(r2)
|
||||
hits_low = [_Hit(r1.id, 0.5)]
|
||||
hits_high = [_Hit(r2.id, 0.5)]
|
||||
|
||||
q1 = fire_curiosity(store, hits_low, "a", 0.75, session_id="s-a", turn=1)
|
||||
assert q1 is not None
|
||||
# Different session to bypass cooldown
|
||||
q2 = fire_curiosity(store, hits_high, "b", 0.95, session_id="s-b", turn=1)
|
||||
assert q2 is not None
|
||||
|
||||
edges = store.db.open_table(EDGES_TABLE).to_pandas()
|
||||
cb = edges[edges["edge_type"] == "curiosity_bridge"]
|
||||
# Records should have edges with delta reflecting the respective entropies.
|
||||
# Low-entropy-linked edges should have weights below 0.9
|
||||
# High-entropy-linked edges should have weights above 0.9
|
||||
assert (cb["weight"] > 0).all()
|
||||
|
||||
|
||||
def test_curiosity_bridge_edge_never_decays_in_sweep(tmp_path):
|
||||
"""curiosity_bridge edges not decayed by hebbian-only sweep."""
|
||||
from datetime import timedelta
|
||||
|
||||
from iai_mcp.curiosity import fire_curiosity
|
||||
from iai_mcp.sleep import _decay_edges
|
||||
|
||||
store = MemoryStore(path=tmp_path)
|
||||
r = _rec()
|
||||
store.insert(r)
|
||||
hits = [_Hit(r.id, 0.5)]
|
||||
fire_curiosity(store, hits, "c", 0.9, "s-never", turn=1)
|
||||
|
||||
edges_tbl = store.db.open_table(EDGES_TABLE)
|
||||
ancient = datetime.now(timezone.utc) - timedelta(days=500)
|
||||
edges_tbl.update(
|
||||
where="edge_type = 'curiosity_bridge'",
|
||||
values={"updated_at": ancient, "weight": 0.0001},
|
||||
)
|
||||
_decay_edges(store)
|
||||
df = edges_tbl.to_pandas()
|
||||
cb = df[df["edge_type"] == "curiosity_bridge"]
|
||||
assert len(cb) >= 1
|
||||
Loading…
Add table
Add a link
Reference in a new issue