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
122
src/iai_mcp/hebbian_structure.py
Normal file
122
src/iai_mcp/hebbian_structure.py
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
"""Plan 03-01 CONN-05 D-TEM-04: structure-edge Hebbian LTP.
|
||||
|
||||
Mirrors content-edge Hebbian (retrieve.reinforce_edges -> store.boost_edges
|
||||
with edge_type="hebbian"). Co-retrieval of two records whose structure_hv
|
||||
hypervectors are sufficiently similar (Hamming similarity >= 0.7 by default)
|
||||
strengthens a "hebbian_structure" edge between them. FSRS decay on the new
|
||||
edge type is identical to the content-edge formula in sleep._decay_edges.
|
||||
|
||||
Constitutional fit:
|
||||
- D-TEM-04: Hebbian LTP on structure edges. Autopoiesis applied to structure;
|
||||
the brain reinforces structural co-occurrence the same way it reinforces
|
||||
content co-occurrence in Phase 1.
|
||||
- Flat layout (PATTERNS.md): no `connectome/` subpackage. Module path is
|
||||
src/iai_mcp/hebbian_structure.py.
|
||||
- Same shape as retrieve.reinforce_edges -- pairwise iterate, compute
|
||||
similarity, call store.boost_edges with edge_type="hebbian_structure".
|
||||
|
||||
Public API:
|
||||
- STRUCTURAL_SIMILARITY_THRESHOLD: pairs above this fire LTP (default 0.7).
|
||||
- structural_similarity(a, b): 1 - hamming_distance(a, b) / D in [0, 1].
|
||||
- strengthen_structure_edge(store, src_id, dst_id, gain=1.0): boost the
|
||||
structure edge between two records.
|
||||
- co_retrieval_trigger(store, hits): pairwise scan of co-retrieved hits;
|
||||
fire strengthen_structure_edge for every pair above the threshold.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from itertools import combinations
|
||||
from uuid import UUID
|
||||
|
||||
import numpy as np
|
||||
|
||||
from iai_mcp.store import MemoryStore
|
||||
from iai_mcp.types import STRUCTURE_HV_DIM
|
||||
|
||||
|
||||
# D-TEM-04 default trigger (per plan Task 2b behavior contract):
|
||||
# co-retrieval LTP fires when structural similarity >= 0.7 (Hamming distance
|
||||
# fraction <= 0.3). Tunable later via the profile registry if a knob is added.
|
||||
STRUCTURAL_SIMILARITY_THRESHOLD: float = 0.7
|
||||
|
||||
|
||||
def structural_similarity(a: bytes, b: bytes) -> float:
|
||||
"""Return 1 - hamming_distance(a, b) / STRUCTURE_HV_DIM in [0.0, 1.0].
|
||||
|
||||
Empty / unequal-length / corrupt inputs return 0.0 (graceful degradation).
|
||||
"""
|
||||
if not a or not b or len(a) != len(b):
|
||||
return 0.0
|
||||
aa = np.frombuffer(a, dtype=np.uint8)
|
||||
bb = np.frombuffer(b, dtype=np.uint8)
|
||||
# popcount of XOR -> hamming distance in bits.
|
||||
xor = np.bitwise_xor(aa, bb)
|
||||
# numpy >= 2.x has np.bitwise_count; fall back to unpackbits sum on older.
|
||||
try:
|
||||
ham_bits = int(np.bitwise_count(xor).sum())
|
||||
except AttributeError:
|
||||
ham_bits = int(np.unpackbits(xor).sum())
|
||||
return 1.0 - (ham_bits / STRUCTURE_HV_DIM)
|
||||
|
||||
|
||||
def strengthen_structure_edge(
|
||||
store: MemoryStore,
|
||||
src_id: UUID,
|
||||
dst_id: UUID,
|
||||
gain: float = 1.0,
|
||||
) -> dict[tuple[str, str], float]:
|
||||
"""Plan 03-01 D-TEM-04: structure-edge LTP via store.boost_edges.
|
||||
|
||||
Returns the new weights dict (same shape as retrieve.reinforce_edges'
|
||||
underlying call). Mirrors content-edge LTP shape so downstream code
|
||||
(events, audit, decay sweep) treats structure edges identically.
|
||||
"""
|
||||
return store.boost_edges(
|
||||
[(src_id, dst_id)],
|
||||
delta=float(gain),
|
||||
edge_type="hebbian_structure",
|
||||
)
|
||||
|
||||
|
||||
def co_retrieval_trigger(
|
||||
store: MemoryStore,
|
||||
hits,
|
||||
*,
|
||||
threshold: float = STRUCTURAL_SIMILARITY_THRESHOLD,
|
||||
gain: float = 1.0,
|
||||
) -> int:
|
||||
"""Pairwise scan of co-retrieved hits; fire strengthen_structure_edge
|
||||
for each pair whose structural_similarity >= threshold.
|
||||
|
||||
`hits` may be a list of MemoryHit (record_id only -- structure_hv is
|
||||
fetched lazily from store.get) OR a list of MemoryRecord (faster path,
|
||||
structure_hv read directly).
|
||||
|
||||
Returns the number of structure edges strengthened. A structurally-
|
||||
isolated co-retrieved set returns 0 -- this is expected (means no two
|
||||
hits shared structure to reinforce).
|
||||
"""
|
||||
# Materialise (id, structure_hv) tuples once.
|
||||
pairs: list[tuple[UUID, bytes]] = []
|
||||
for h in hits:
|
||||
rec_id = getattr(h, "record_id", None) or getattr(h, "id", None)
|
||||
if rec_id is None:
|
||||
continue
|
||||
hv = getattr(h, "structure_hv", None)
|
||||
if hv is None:
|
||||
rec = store.get(rec_id)
|
||||
if rec is None:
|
||||
continue
|
||||
hv = rec.structure_hv
|
||||
pairs.append((rec_id, hv or b""))
|
||||
|
||||
fired = 0
|
||||
for (a_id, a_hv), (b_id, b_hv) in combinations(pairs, 2):
|
||||
if structural_similarity(a_hv, b_hv) >= threshold:
|
||||
try:
|
||||
strengthen_structure_edge(store, a_id, b_id, gain=gain)
|
||||
fired += 1
|
||||
except Exception:
|
||||
# Diagnostic only -- never block the pipeline on edge failure.
|
||||
continue
|
||||
return fired
|
||||
Loading…
Add table
Add a link
Reference in a new issue