Skip to content

[High] Implement Memory Files (AMPLIFIER.md) #19

@marklicata

Description

@marklicata

Summary

Implement memory files (AMPLIFIER.md) that provide persistent context loaded automatically at session start, enabling project-specific instructions, conventions, and context to persist across sessions.

Current State

Amplifier CLI has no equivalent to Claude Code's CLAUDE.md files:

  • No automatic context loading
  • No hierarchy of memory files (user → project → local)
  • Instructions must be repeated each session or put in profiles

Proposed Implementation

1. Memory File Hierarchy

~/.amplifier/AMPLIFIER.md           # User-level (global preferences)
~/projects/myapp/AMPLIFIER.md       # Project root (team conventions)
~/projects/myapp/src/AMPLIFIER.md   # Subdirectory (component-specific)

Load order: User → Project → Local (later files can override/extend)

2. Memory File Format

# AMPLIFIER.md

## Project Context
This is a Python web application using FastAPI and SQLAlchemy.

## Conventions
- Use `ruff` for linting, not `flake8`
- All API endpoints go in `src/api/`
- Database models go in `src/models/`
- Never commit `.env` files

## Commands
- `uv run pytest` - Run tests
- `uv run ruff check .` - Lint code

## Preferences  
- Prefer composition over inheritance
- Use dataclasses for DTOs
- Always add type hints

## Context
<!-- This section can be appended to via # prefix in interactive mode -->
- Working on the auth module refactor
- User prefers detailed explanations

3. Loading Behavior

def load_memory_files(working_dir: Path) -> str:
    """Load and merge all applicable AMPLIFIER.md files."""
    memory_parts = []
    
    # 1. User-level (always load if exists)
    user_memory = Path.home() / ".amplifier" / "AMPLIFIER.md"
    if user_memory.exists():
        memory_parts.append(f"# User Preferences\n{user_memory.read_text()}")
    
    # 2. Walk from working_dir to root, collect all AMPLIFIER.md
    project_memories = []
    current = working_dir
    while current != current.parent:
        memory_file = current / "AMPLIFIER.md"
        if memory_file.exists():
            project_memories.append((current, memory_file.read_text()))
        current = current.parent
    
    # Add project memories in root-to-local order
    for path, content in reversed(project_memories):
        memory_parts.append(f"# Context from {path}\n{content}")
    
    return "\n\n---\n\n".join(memory_parts)

4. Interactive Memory Append (# Prefix)

In interactive mode, lines starting with # append to memory:

amplifier> # Remember: user prefers verbose output
[Appended to session memory]

amplifier> # The auth module uses JWT tokens stored in Redis
[Appended to session memory]

This should:

  1. Immediately add to session context
  2. Optionally persist to local AMPLIFIER.md (with confirmation)

5. New Module Structure

src/amplifier_app_cli/memory/
├── __init__.py
├── loader.py         # Load and merge memory files
├── writer.py         # Append to memory files
├── parser.py         # Parse sections from markdown
└── context.py        # Build context string for session

6. Core Interfaces

from pathlib import Path
from dataclasses import dataclass

@dataclass
class MemoryFile:
    path: Path
    content: str
    scope: Literal["user", "project", "local"]

@dataclass
class MemoryContext:
    files: list[MemoryFile]
    session_additions: list[str]  # From # prefix
    
    def to_context_string(self) -> str:
        """Format all memory as context for the AI."""
        ...
    
    def append(self, text: str, persist: bool = False) -> None:
        """Add to session memory, optionally persist to file."""
        ...

class MemoryLoader:
    def __init__(self, user_dir: Path, working_dir: Path): ...
    
    def load(self) -> MemoryContext:
        """Load all applicable memory files."""
        ...

class MemoryWriter:
    def append_to_file(
        self, 
        path: Path, 
        text: str, 
        section: str = "Context"
    ) -> None:
        """Append text to a memory file's section."""
        ...

7. Integration Points

  1. Session start: Load memory files and inject into system prompt
  2. Interactive mode: Handle # prefix for memory append
  3. Slash command: Add /memory command to view/edit memory
  4. Config: Add memory.enabled, memory.auto_persist settings

8. Slash Commands

/memory              # Show all loaded memory
/memory show         # Same as above
/memory add <text>   # Add to local AMPLIFIER.md
/memory edit         # Open AMPLIFIER.md in $EDITOR
/memory path         # Show paths of all loaded memory files

9. CLI Flags

# Disable memory loading
amplifier run -p "task" --no-memory

# Use specific memory file
amplifier run -p "task" --memory ./custom-memory.md

# Add one-time memory context
amplifier run -p "task" --context "This is a Django project"

10. Configuration

# In amplifier.yaml
memory:
  enabled: true
  auto_persist: false          # Auto-save # additions to file
  persist_prompt: true         # Ask before persisting
  max_file_size_kb: 100        # Ignore huge files
  filenames:                   # Custom memory file names
    - "AMPLIFIER.md"
    - ".amplifier-memory.md"

Acceptance Criteria

  • User-level ~/.amplifier/AMPLIFIER.md loads automatically
  • Project-level AMPLIFIER.md files discovered up directory tree
  • Memory files merged in correct order (user → root → local)
  • # prefix in interactive mode appends to session memory
  • Optional persistence of # additions to file
  • /memory slash command shows current memory
  • --no-memory flag disables memory loading
  • --context flag adds one-time context
  • Memory injected into session context/system prompt
  • Large memory files handled gracefully (truncate with warning)
  • Unit tests for loader and merger
  • Integration tests for interactive memory

Related

  • Depends on: None
  • Enhances: Session experience, project onboarding

Estimated Effort

Low-Medium - 1 week

This is a high-value, relatively easy feature to implement. Recommended as an early win.

Files to Create/Modify

  • src/amplifier_app_cli/memory/ (new module)
  • src/amplifier_app_cli/ui/interactive.py (# prefix handling)
  • src/amplifier_app_cli/commands/slash.py (/memory command)
  • src/amplifier_app_cli/lib/session.py (context injection)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions