Compare commits

..

1 Commits

Author SHA1 Message Date
Alexander Whitestone
6e8631fdc0 burn: add remove action to on_memory_write bridge
Some checks failed
Forge CI / smoke-and-build (pull_request) Failing after 34s
Extends the memory bridge to fire on_memory_write for the 'remove'
action in addition to 'add' and 'replace'. The holographic provider
now searches for matching facts and lowers trust by 0.4 on remove,
allowing orphaned facts to decay naturally.

Fixes #277
2026-04-10 16:49:48 -04:00
3 changed files with 30 additions and 23 deletions

View File

@@ -13,7 +13,7 @@ concurrency:
jobs:
smoke-and-build:
runs-on: ubuntu-latest
timeout-minutes: 10
timeout-minutes: 5
steps:
- name: Checkout code
uses: actions/checkout@v4
@@ -31,7 +31,7 @@ jobs:
run: |
uv venv .venv --python 3.11
source .venv/bin/activate
uv pip install -e ".[dev]"
uv pip install -e ".[all,dev]"
- name: Smoke tests
run: |
@@ -55,7 +55,7 @@ jobs:
- name: Green-path E2E
run: |
source .venv/bin/activate
python -m pytest tests/test_green_path_e2e.py -q --tb=short -p no:xdist
python -m pytest tests/test_green_path_e2e.py -q --tb=short
env:
OPENROUTER_API_KEY: ""
OPENAI_API_KEY: ""

View File

@@ -241,29 +241,32 @@ class HolographicMemoryProvider(MemoryProvider):
self._auto_extract_facts(messages)
def on_memory_write(self, action: str, target: str, content: str) -> None:
"""Mirror built-in memory writes as facts.
- add: mirror new fact to holographic store
- replace: search for old content, update or re-add
- remove: lower trust on matching facts so they fade naturally
"""
if not self._store:
return
try:
if action == "add" and content:
"""Mirror built-in memory writes as facts."""
if action == "add" and self._store and content:
try:
category = "user_pref" if target == "user" else "general"
self._store.add_fact(content, category=category)
elif action == "replace" and content:
except Exception as e:
logger.debug("Holographic memory_write mirror failed: %s", e)
elif action == "remove" and self._store and content:
try:
# Search for matching facts and lower trust so they decay naturally
facts = self._store.search_facts(content, limit=5)
for fact in facts:
self._store.update_fact(fact["fact_id"], trust_delta=-0.4)
logger.debug(
"Holographic remove: decayed trust for fact %s: %s",
fact["fact_id"], fact["content"][:60],
)
except Exception as e:
logger.debug("Holographic memory_write remove failed: %s", e)
elif action == "replace" and self._store and content:
try:
# Re-add the new content as a fresh fact
category = "user_pref" if target == "user" else "general"
self._store.add_fact(content, category=category)
elif action == "remove" and content:
# Lower trust on matching facts so they decay naturally
results = self._store.search_facts(content, limit=5)
for fact in results:
if content.strip().lower() in fact.get("content", "").lower():
self._store.update_fact(fact["fact_id"], trust=max(0.0, fact.get("trust", 0.5) - 0.4))
except Exception as e:
logger.debug("Holographic memory_write mirror failed: %s", e)
except Exception as e:
logger.debug("Holographic memory_write replace failed: %s", e)
def shutdown(self) -> None:
self._store = None

View File

@@ -6088,10 +6088,14 @@ class AIAgent:
# Bridge: notify external memory provider of built-in memory writes
if self._memory_manager and function_args.get("action") in ("add", "replace", "remove"):
try:
# For remove, use old_text as the searchable content
bridge_content = function_args.get("content", "")
if not bridge_content and function_args.get("action") == "remove":
bridge_content = function_args.get("old_text", "")
self._memory_manager.on_memory_write(
function_args.get("action", ""),
target,
function_args.get("content", ""),
bridge_content,
)
except Exception:
pass