Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 110 additions & 7 deletions .amplifier/digital-twin-universe/profiles/memory-bundle-e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,12 @@ provision:
echo 'export PATH="/root/.local/bin:$PATH"' >> /root/.bashrc
export PATH="/root/.local/bin:$PATH"

# 4. Install mempalace + pytest (system-wide via pip with break-system-packages)
# 4. Install mempalace + pytest + pytest-asyncio (system-wide via pip with break-system-packages)
# --ignore-installed skips reinstalling packages already present (e.g. rich
# installed by Debian's python3-rich package which has no RECORD file).
# pytest is required to run tests/integration/ inside the DTU.
- pip install --break-system-packages --ignore-installed mempalace pytest
# pytest-asyncio is required for async test support in test_event_wiring.py.
- pip install --break-system-packages --ignore-installed mempalace pytest pytest-asyncio

# 5. Create the palace directory — mempalace mine will populate it.
# mempalace init is a project-level entity-detection setup command;
Expand Down Expand Up @@ -108,6 +109,20 @@ provision:
export PATH="/root/.local/bin:$PATH"
uv tool install -vv git+https://github.com/microsoft/amplifier

# 12.5. Pin amplifier-core to 1.4.1 and reinstall amplifier-app-cli from latest git
# amplifier-core >= 1.4.1 is required: register_contributor / collect_contributions
# and the on_session_ready lifecycle work correctly only from this version.
# The meta-package uv install above may resolve an older PyPI release; this guarantees
# the correct versions are present before the bundle is added.
- |
export PATH="/root/.local/bin:$PATH"
VENV_PY=/root/.local/share/uv/tools/amplifier/bin/python
uv pip install --python "$VENV_PY" \
--reinstall-package amplifier-core \
--reinstall-package amplifier-app-cli \
'amplifier-core==1.4.1' \
git+https://github.com/microsoft/amplifier-app-cli@main

# 13. Write API keys to keys.env (passthrough env vars; chmod 600 for security)
- |
mkdir -p /root/.amplifier
Expand All @@ -119,19 +134,107 @@ provision:
export PATH="/root/.local/bin:$PATH"
amplifier bundle add --app "git+https://github.com/michaeljabbour/amplifier-bundle-memory@main#subdirectory=behaviors/mempalace.yaml"

# 15. Validate that both tools are installed and reachable
# 15. Install hooks-logging fork with on_session_ready + collect_contributions support
#
# Why this fork: stock hooks-logging predates amplifier-core 1.4.1's on_session_ready
# lifecycle. Without it, collect_contributions("observability.events") is never called,
# so no handlers register for memory-mempalace:* events and events.jsonl stays empty.
#
# Why delete the cache dir (not just install via pip):
# Amplifier prepends ~/.amplifier/cache/<module>-<hash>/ to sys.path BEFORE site-packages.
# Even after `uv pip install --force-reinstall`, the old cache copy (without on_session_ready)
# is imported first and placed in sys.modules — the fork in site-packages is never reached.
# Deleting the cache dir lets Python fall through to site-packages on every session start.
# No timing dependency, no primer session needed. (Investigated in session 9201aaf7.)
- |
set -euo pipefail
export PATH="/root/.local/bin:$PATH"
VENV_PY=/root/.local/share/uv/tools/amplifier/bin/python
uv pip install --python "$VENV_PY" --force-reinstall \
git+https://github.com/colombod/amplifier-module-hooks-logging@feat/on-session-ready
# Delete any pre-existing cache that would shadow site-packages
rm -rf /root/.amplifier/cache/amplifier-module-hooks-logging-*
echo "[hooks-logging] fork installed and shadowing cache cleared"
# Verify the fork is reachable and exposes on_session_ready
"$VENV_PY" -c "
import amplifier_module_hooks_logging as m
assert hasattr(m, 'on_session_ready'), f'FAIL: on_session_ready missing at {m.__file__}'
print(f'[hooks-logging] OK: on_session_ready present ({m.__file__})')
"

# 16. Validate that both tools are installed and reachable
- |
export PATH="/root/.local/bin:$PATH"
amplifier --version
mempalace --version || true

# 17. Post-provision smoke test — fail fast if coordinator events are not flowing.
# Runs a real Amplifier session and verifies that memory-mempalace:* events appear
# in events.jsonl. Surfaces broken wiring before the developer discovers it manually.
- |
set -euo pipefail
export PATH="/root/.local/bin:$PATH"
VENV_PY=/root/.local/share/uv/tools/amplifier/bin/python

echo "=== DTU smoke test ==="

# 1. on_session_ready accessible
"$VENV_PY" -c "
import amplifier_module_hooks_logging as m
assert hasattr(m, 'on_session_ready'), f'FAIL: on_session_ready missing at {m.__file__}'
print('PASS hooks-logging has on_session_ready')
"

# 2. No shadowing cache dir
SHADOW=$(find /root/.amplifier/cache -maxdepth 1 -type d \
-name 'amplifier-module-hooks-logging-*' 2>/dev/null | wc -l)
[ "$SHADOW" -eq 0 ] \
&& echo "PASS no shadowing hooks-logging cache" \
|| echo "WARN $SHADOW shadowing cache dir(s) present — coordinator events may not flow"

# 3. Session produces coordinator events
cd /workspace
amplifier run 'hello' >/tmp/smoke.log 2>&1 || true
LATEST=$(ls -t /root/.amplifier/projects/*/sessions/*/events.jsonl 2>/dev/null | head -1)
if [ -n "$LATEST" ]; then
COUNT=$(grep -c '"memory-mempalace:' "$LATEST" 2>/dev/null || echo 0)
[ "$COUNT" -gt 0 ] \
&& echo "PASS coordinator events flowing ($COUNT memory-mempalace:* events)" \
|| { echo "FAIL zero coordinator events in $LATEST"; cat /tmp/smoke.log; exit 1; }
else
echo "WARN no events.jsonl found — run a session manually to verify"
fi

echo "=== smoke test passed ==="

update:
refresh_pypi: true
cmds:
# Clear Amplifier module cache so re-add fetches the latest bundle from Gitea.
# The palace is intentionally NOT reset here — accumulated memories are preserved
# across updates. Use reset-palace manually to restore the seed state.
- rm -rf /root/.amplifier/cache/
# Targeted cache invalidation — ONLY the memory bundle modules and hooks-logging.
# NEVER wipe the whole cache (rm -rf /root/.amplifier/cache/) — that removes
# provider-anthropic, loop-streaming, and all foundation modules, breaking every
# session until Amplifier is fully reinstalled (5-10 min).
# The palace is intentionally NOT reset — accumulated memories are preserved.
# Use reset-palace manually to restore the seed state.
- |
rm -rf /root/.amplifier/cache/amplifier-module-hooks-mempalace-*
rm -rf /root/.amplifier/cache/amplifier-module-tool-mempalace-*
rm -rf /root/.amplifier/cache/amplifier-module-hooks-project-context-*
rm -rf /root/.amplifier/cache/amplifier-module-hooks-logging-*
echo "[update] cleared memory bundle + hooks-logging caches"
- |
export PATH="/root/.local/bin:$PATH"
amplifier bundle add --app "git+https://github.com/michaeljabbour/amplifier-bundle-memory@main#subdirectory=behaviors/mempalace.yaml"
# Re-apply hooks-logging fork (same approach as provision step 15)
- |
set -euo pipefail
export PATH="/root/.local/bin:$PATH"
VENV_PY=/root/.local/share/uv/tools/amplifier/bin/python
uv pip install --python "$VENV_PY" --force-reinstall \
git+https://github.com/colombod/amplifier-module-hooks-logging@feat/on-session-ready
rm -rf /root/.amplifier/cache/amplifier-module-hooks-logging-*
"$VENV_PY" -c "
import amplifier_module_hooks_logging as m
assert hasattr(m, 'on_session_ready'), f'FAIL: on_session_ready missing at {m.__file__}'
print(f'[hooks-logging] OK: on_session_ready present')
"
7 changes: 7 additions & 0 deletions agents/archivist.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
---
name: archivist
description: |
The Archivist is the read path for the memory system. It answers memory
queries, navigates the palace graph, surfaces context from the knowledge
graph and agent diaries, and reads project-context coordination files.
Note: session:start briefings are handled by hooks-mempalace-briefing;
the Archivist is invoked on-demand for deeper retrieval.
agent:
name: archivist
namespace: mempalace
Expand Down
7 changes: 7 additions & 0 deletions agents/curator.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
---
name: curator
description: |
The Curator is the write path for the memory system. It processes raw
hook captures, curates them into well-categorized palace drawers, updates
the knowledge graph, maintains palace hygiene, and updates the
project-context coordination files (HANDOFF.md, PROVENANCE.md, GLOSSARY.md,
WAYSOFWORKING.md) at session end.
agent:
name: curator
namespace: mempalace
Expand Down
7 changes: 7 additions & 0 deletions agents/docent.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
---
name: docent
description: |
Conversational memory assistant. Answers natural-language questions
about what's stored in the palace, what happened in prior sessions,
which decisions were made, and how the project's understanding has
evolved. Synthesizes responses from palace search, knowledge graph,
agent diaries, session event log, and coordination files.
agent:
name: docent
namespace: mempalace
Expand Down
97 changes: 97 additions & 0 deletions bundle.dot
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// This repository packages a "memory palace" assistant that captures, curates, and recalls knowledge across sessions.
digraph memory {
rankdir=LR
fontname="Helvetica"
fontsize=12
label="Memory Palace Bundle\nA shared workspace for capturing, curating, and recalling knowledge\nv1.2.0"
labelloc=t
labeljust=c
nodesep=0.6
ranksep=0.7
bgcolor="white"
source_hash="a0b2b4ee554828d5e237da750bcb9e3020519a046becba3a1cf0378fd59ce450"

node [fontname="Helvetica", fontsize=11, style="filled,rounded"]
edge [fontname="Helvetica", fontsize=9]

root_memory [label="Memory Palace (this bundle)\nv1.2.0\n0 tools · 0 agents\n~1530 tok aggregate", shape=box, fillcolor="#80cbc4", style="filled,rounded,bold", penwidth=2]

subgraph cluster_behaviors {
label="Behaviors — bundled capabilities the assistant can use"
style="filled"
fillcolor="#f9f9f9"
color="#999999"

beh_mempalace_behavior [label="Memory Palace Behavior\nThe core remember/recall capability\n7 tools · 2 ctx\n~3418 tok", shape=box, fillcolor="#e0f2f1", style="filled,rounded"]
}

subgraph cluster_agents {
label="Agents — specialist helpers, each with a role"
style="filled"
fillcolor="#f9f9f9"
color="#999999"

agt_archivist [label="Archivist\nSaves new memories\n~0 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"]
agt_curator [label="Curator\nOrganizes and prunes memories\n~0 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"]
agt_docent [label="Docent\nGuides recall and retrieval\n~0 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"]
}

subgraph cluster_modules {
label="Modules — building blocks the behavior plugs together"
style="filled"
fillcolor="#f9f9f9"
color="#999999"

mod_hooks_mempalace_briefing [label="Briefing Hook\nShares relevant memories\nat the start of a session\n(hooks-mempalace-briefing)", shape=box, fillcolor="#bbdefb", style="filled,rounded"]
mod_hooks_mempalace_capture [label="Capture Hook\nNotices things worth\nremembering as you work\n(hooks-mempalace-capture)", shape=box, fillcolor="#bbdefb", style="filled,rounded"]
mod_hooks_mempalace_interject [label="Interject Hook\nSpeaks up when a memory\nis useful right now\n(hooks-mempalace-interject)", shape=box, fillcolor="#bbdefb", style="filled,rounded"]
mod_hooks_project_context [label="Project Context Hook\nKeeps project-specific\nbackground in view\n(hooks-project-context)", shape=box, fillcolor="#bbdefb", style="filled,rounded"]
mod_tool_mempalace [label="Memory Palace Tool\nThe action that reads &\nwrites memories\n(tool-mempalace)", shape=box, fillcolor="#bbdefb", style="filled,rounded"]
}

subgraph cluster_context {
label="Context Files — written guidance loaded into the assistant"
style="filled"
fillcolor="#f9f9f9"
color="#999999"

ctx_instructions_md [label="How-to-Use Instructions\n(instructions.md)\n~1335 tok", shape=box, fillcolor="#e1bee7", style="filled,rounded"]
ctx_project_context_guide_md [label="Project Context Guide\n(project-context-guide.md)\n~759 tok", shape=box, fillcolor="#e1bee7", style="filled,rounded"]
}

subgraph cluster_legend {
label="Legend — what each color means"
style="filled"
fillcolor="white"
color="#cccccc"
fontsize=9

leg_root [label="this bundle (root)", shape=box, fillcolor="#80cbc4", style="filled,rounded,bold", fontsize=9]
leg_behavior [label="behavior (capability)", shape=box, fillcolor="#e0f2f1", style="filled,rounded", fontsize=9]
leg_agent [label="agent (specialist helper)", shape=box, fillcolor="#c8e6c9", style="filled,rounded", fontsize=9]
leg_module [label="module (building block)", shape=box, fillcolor="#bbdefb", style="filled,rounded", fontsize=9]
leg_provider [label="provider (AI service)", shape=box, fillcolor="#e0e0e0", style="filled,rounded", fontsize=9]
leg_context [label="context (written guidance)", shape=box, fillcolor="#e1bee7", style="filled,rounded", fontsize=9]
leg_standalone [label="standalone piece", shape=box, fillcolor="#80cbc4", style="filled,rounded", fontsize=9]
leg_experiment [label="experiment", shape=box, fillcolor="#e1bee7", style="filled,rounded", fontsize=9]
leg_ext_cost [label="external dependency\n(adds hidden cost)", shape=box, fillcolor="#80cbc4", style="dashed", color="red", penwidth=2, fontsize=9]
leg_ext_muted [label="external dependency\n(no extra cost)", shape=box, fillcolor="#f5f5f5", style="dashed", fontsize=9]
}

disclaimer [label="Token estimates: ~4 chars/token\nSolid border = local (counted)\nDashed + red = external, hidden cost (not counted)\nDashed + muted = external, no cost\nExcludes: sub-session costs, runtime-dynamic", shape=note, fillcolor="#eceff1", style="filled", fontsize=9]

ext_githttps___github_com_microsoft_amplifier_foundation_main [label="Amplifier Foundation\nShared base brought in from GitHub\n(external, cost)", shape=box, fillcolor="#80cbc4", style="dashed", color="red", penwidth=2]

root_memory -> ext_githttps___github_com_microsoft_amplifier_foundation_main [style=dashed]
root_memory -> beh_mempalace_behavior [label="composes"]
beh_mempalace_behavior -> agt_archivist [label="owns"]
beh_mempalace_behavior -> agt_curator [label="owns"]
beh_mempalace_behavior -> mod_tool_mempalace [label="uses", penwidth=0.8]
beh_mempalace_behavior -> mod_hooks_mempalace_capture [label="uses", penwidth=0.8]
beh_mempalace_behavior -> mod_hooks_mempalace_briefing [label="uses", penwidth=0.8]
beh_mempalace_behavior -> mod_hooks_project_context [label="uses", penwidth=0.8]
beh_mempalace_behavior -> mod_hooks_mempalace_interject [label="uses", penwidth=0.8]
beh_mempalace_behavior -> ctx_instructions_md [style=dotted, color=purple]
beh_mempalace_behavior -> ctx_project_context_guide_md [style=dotted, color=purple]
root_memory -> ctx_instructions_md [style=dotted, color=purple]
}
Loading
Loading