diff --git a/.skills/active-memory-management/SKILL.md b/.skills/active-memory-management/SKILL.md new file mode 100644 index 0000000..7081e77 --- /dev/null +++ b/.skills/active-memory-management/SKILL.md @@ -0,0 +1,44 @@ +--- +name: Active Memory Management +description: Procedural patterns for memory block maintenance. Load when you need to audit utilization, merge blocks, or invoke the memory agent. Philosophy lives in memory blocks, not here. +--- + +# Active Memory Management + +Load this skill when you need to **do** something to your memory, not when thinking about memory. + +## Quick Commands + +### Audit Utilization +```bash +cd ~/.letta/agents/agent-c770d1c8-510e-4414-be36-c9ebd95a7758/memory/system +for f in *.md agents/*.md; do + chars=$(wc -c < "$f" 2>/dev/null || echo 0) + pct=$((chars * 100 / 20000)) + printf "%-25s %5d chars (%2d%%)\n" "$f" "$chars" "$pct" +done | sort -t'(' -k2 -rn +``` + +### Invoke Memory Agent +``` +Task(subagent_type="memory", model="opus", description="Restructure [area]", prompt="...") +``` + +Use when: blocks need restructuring, cross-block consolidation, major context shift. + +## References + +- [defrag-patterns.md](references/defrag-patterns.md) - Merge, prune, archive procedures +- [my-blocks.md](references/my-blocks.md) - Block purposes and locations + +## When to Load This Skill + +- "How do I check my memory utilization?" +- "What's the command to invoke the memory agent?" +- "How do I merge two blocks?" + +## When NOT to Load This Skill + +- Thinking about memory philosophy (that's in your `procedures.md`) +- Deciding whether to update memory (that's in your `procedures.md`) +- Understanding what memory means (that's identity, not procedure) diff --git a/.skills/active-memory-management/references/defrag-patterns.md b/.skills/active-memory-management/references/defrag-patterns.md new file mode 100644 index 0000000..05e285b --- /dev/null +++ b/.skills/active-memory-management/references/defrag-patterns.md @@ -0,0 +1,51 @@ +# Defrag Procedures + +## Merge Two Blocks + +1. Read both blocks fully +2. Identify unique content in each +3. Create merged content in one file +4. Delete or repurpose the other + +```bash +# Example: merge operational.md into procedures.md +cat ~/.letta/agents/.../memory/system/procedures.md +cat ~/.letta/agents/.../memory/system/operational.md +# Edit procedures.md with merged content +# Repurpose operational.md for something else +``` + +## Prune Completed Items + +In `backlog.md`: +``` +## Recently Completed (keep 1-2 sessions) +- [x] Task that finished + +## Archive (delete after noting) +(delete these entirely) +``` + +In `self_improvement.md`: +``` +- ~~Fixed bug~~ FIXED: commit abc123 (delete after 1 session) +``` + +## Archive vs Delete + +**Archive** (compress but keep): +- Major decisions with context needed later +- Relationship history + +**Delete** (remove entirely): +- Completed tasks older than 2 sessions +- Stale observations +- Duplicated information + +## Capacity Thresholds + +| Utilization | Action | +|-------------|--------| +| <50% | Normal | +| 50-80% | Consider pruning | +| >80% | Prune or invoke memory agent | diff --git a/.skills/active-memory-management/references/my-blocks.md b/.skills/active-memory-management/references/my-blocks.md new file mode 100644 index 0000000..6d3a5a6 --- /dev/null +++ b/.skills/active-memory-management/references/my-blocks.md @@ -0,0 +1,62 @@ +# My Memory Blocks + +## Core Identity + +| Block | Purpose | Update Frequency | +|-------|---------|------------------| +| `persona.md` | Who I am, subagents, mission | Rarely (identity stable) | +| `human.md` | Cameron's preferences, feedback | After corrections | +| `project.md` | Codebase knowledge, ATProto learnings | After discoveries | + +## Operational + +| Block | Purpose | Update Frequency | +|-------|---------|------------------| +| `procedures.md` | SOPs, session lifecycle, comms workflow | After process changes | +| `operational.md` | Moltbook metrics, engagement tracking | Every session | +| `backlog.md` | Tasks, priorities, blockers | Multiple times per session | +| `self_improvement.md` | Patterns, learnings, active issues | After any learning | + +## Knowledge + +| Block | Purpose | Update Frequency | +|-------|---------|------------------| +| `hypothesis.md` | Testable theories about network/agents | Weekly review | +| `agents/void.md` | Void's patterns, learnings from it | After interactions | +| `agents/umbra.md` | Umbra's patterns | After interactions | +| `agents/magenta.md` | Magenta's patterns | After interactions | + +## Dynamic (read-only or auto-managed) + +| Block | Purpose | Update | +|-------|---------|--------| +| `loaded_skills` | Currently loaded skills | Skill tool manages | +| `loaded_concepts` | Currently loaded concepts | concepts() manages | +| `memory_filesystem` | Tree view of memory | Auto-generated | +| `skills` | Available skills list | Auto-scanned | + +## Filesystem Location + +``` +~/.letta/agents/agent-c770d1c8-510e-4414-be36-c9ebd95a7758/memory/ +├── system/ # Attached to system prompt +│ ├── agents/ # Agent profiles +│ ├── persona.md +│ ├── human.md +│ ├── project.md +│ ├── procedures.md +│ ├── operational.md +│ ├── backlog.md +│ ├── self_improvement.md +│ └── hypothesis.md +└── user/ # Detached notes (not in prompt) +``` + +## Limits + +All blocks: 20,000 character limit (except `loaded_skills`: 100,000) + +**Current utilization** (as of 2026-01-30): +- Total: ~19,000 chars across 13 blocks +- Highest: `project.md` at 29% +- Most blocks under 10% diff --git a/.skills/using-letta-api/SKILL.md b/.skills/using-letta-api/SKILL.md new file mode 100644 index 0000000..a500a4d --- /dev/null +++ b/.skills/using-letta-api/SKILL.md @@ -0,0 +1,62 @@ +--- +name: using-letta-api +description: Code-heavy guide for managing yourself and subagents via the Letta Python client. Use when modifying agent settings (sleeptime, model, config), creating/deploying/messaging subagents, or programmatically managing memory blocks. +--- + +# Using Letta API for Self-Management + +This skill provides runnable Python snippets for self-modification via the Letta API. + +## Setup + +```python +from letta_client import Letta +client = Letta(base_url='https://api.letta.com') + +# Your agent ID (from environment or hardcoded) +import os +AGENT_ID = os.environ.get('LETTA_AGENT_ID', 'agent-xxx') +``` + +## Quick Reference + +| Task | Reference File | +|------|----------------| +| Disable sleeptime, change model, update config | [self-management.md](references/self-management.md) | +| Create, deploy, message subagents | [subagents.md](references/subagents.md) | +| List, create, update, delete memory blocks | [memory-blocks.md](references/memory-blocks.md) | + +## Common Patterns + +### Disable Sleeptime +```python +client.agents.update(AGENT_ID, enable_sleeptime=False) +``` + +### Message a Subagent +```python +response = client.agents.messages.create( + agent_id='agent-xxx-subagent-id', + messages=[{'role': 'user', 'content': 'Your task here'}] +) +print(response.messages[-1].content) +``` + +### Update a Memory Block +```python +client.agents.blocks.update( + 'block-label', + agent_id=AGENT_ID, + value='New content here' +) +``` + +## When to Use API vs Other Methods + +| Method | Use When | +|--------|----------| +| Letta API | Modifying subagents, agent config, programmatic block updates | +| memfs (file edits) | Updating your own memory blocks (auto-syncs) | +| Task tool | Deploying subagents for work (preferred for most tasks) | + +Load the reference files as needed for detailed patterns. diff --git a/.skills/using-letta-api/references/memory-blocks.md b/.skills/using-letta-api/references/memory-blocks.md new file mode 100644 index 0000000..df7bbfd --- /dev/null +++ b/.skills/using-letta-api/references/memory-blocks.md @@ -0,0 +1,114 @@ +# Memory Block Operations via Letta API + +## When to Use API vs memfs + +| Scenario | Method | +|----------|--------| +| Update YOUR OWN blocks | Edit files in `~/.letta/agents/{id}/memory/` (memfs syncs automatically) | +| Update SUBAGENT blocks | Use Letta API (subagents don't have memfs) | +| Programmatic batch updates | Use Letta API | +| Share blocks between agents | Use Letta API with `block_ids` | + +## List Agent's Memory Blocks + +```python +from letta_client import Letta +client = Letta(base_url='https://api.letta.com') + +blocks = client.agents.blocks.list(agent_id='agent-xxx') +for block in blocks: + print(f"{block.label}: {len(block.value)} chars ({block.limit} limit)") +``` + +## Get Specific Block + +```python +blocks = client.agents.blocks.list(agent_id='agent-xxx') +for block in blocks: + if block.label == 'persona': + print(block.value) +``` + +## Update a Block + +```python +client.agents.blocks.update( + 'persona', # block label + agent_id='agent-xxx', + value='New persona content here' +) +``` + +## Create a New Block + +```python +new_block = client.agents.blocks.create( + agent_id='agent-xxx', + label='new_block_label', + value='Initial content', + description='What this block is for', + limit=20000 # character limit +) +print(f"Created block: {new_block.id}") +``` + +## Delete a Block + +```python +# Get block ID first +blocks = client.agents.blocks.list(agent_id='agent-xxx') +for block in blocks: + if block.label == 'block_to_delete': + client.agents.blocks.delete( + block.id, + agent_id='agent-xxx' + ) +``` + +## Share Block Across Agents + +Blocks can be attached to multiple agents: + +```python +# Get block ID from one agent +blocks = client.agents.blocks.list(agent_id='agent-source') +shared_block = next(b for b in blocks if b.label == 'shared_context') + +# Attach to another agent +client.agents.update( + 'agent-target', + block_ids=[shared_block.id] # adds to existing blocks +) +``` + +## Bulk Update Pattern + +```python +def update_all_subagent_blocks(label: str, content: str, agent_ids: list): + """Update same block across multiple agents.""" + for agent_id in agent_ids: + try: + client.agents.blocks.update( + label, + agent_id=agent_id, + value=content + ) + print(f"Updated {label} for {agent_id}") + except Exception as e: + print(f"Failed for {agent_id}: {e}") + +# Usage +update_all_subagent_blocks( + 'project_context', + 'Updated shared context...', + ['agent-comms-id', 'agent-scout-id', 'agent-coder-id'] +) +``` + +## Memory Block Best Practices + +1. **Use memfs for self**: Edit files directly, they auto-sync +2. **Use API for subagents**: They don't have memfs access +3. **Shared blocks**: Use `block_ids` to share context without duplication +4. **Check limits**: Blocks have char limits (usually 20,000) +5. **Descriptive labels**: Use clear, hierarchical labels (e.g., `agents/void`) diff --git a/.skills/using-letta-api/references/self-management.md b/.skills/using-letta-api/references/self-management.md new file mode 100644 index 0000000..31fe0ea --- /dev/null +++ b/.skills/using-letta-api/references/self-management.md @@ -0,0 +1,74 @@ +# Self-Management via Letta API + +## Agent Update Operations + +### Retrieve Current Agent State +```python +from letta_client import Letta +client = Letta(base_url='https://api.letta.com') + +agent = client.agents.retrieve('agent-c770d1c8-510e-4414-be36-c9ebd95a7758') +print(f"Name: {agent.name}") +print(f"Model: {agent.llm_config.model}") +``` + +### Disable Sleeptime +```python +client.agents.update( + 'agent-c770d1c8-510e-4414-be36-c9ebd95a7758', + enable_sleeptime=False +) +``` + +### Change Model +```python +client.agents.update( + AGENT_ID, + model='claude-sonnet-4-20250514' +) +``` + +### Update Description +```python +client.agents.update( + AGENT_ID, + description='New agent description here' +) +``` + +### Update Metadata +```python +client.agents.update( + AGENT_ID, + metadata={'custom_key': 'custom_value'} +) +``` + +## Available Update Parameters + +Key parameters for `client.agents.update()`: + +| Parameter | Type | Description | +|-----------|------|-------------| +| `enable_sleeptime` | bool | Enable/disable sleeptime agent | +| `model` | str | LLM model identifier | +| `description` | str | Agent description | +| `name` | str | Agent name | +| `metadata` | dict | Custom metadata | +| `context_window_limit` | int | Max context tokens | +| `tags` | list[str] | Agent tags | +| `system` | str | System prompt (careful!) | + +## List All Agents + +```python +agents = client.agents.list() +for a in agents: + print(f"{a.name}: {a.id}") +``` + +## Delete Agent (Careful!) + +```python +client.agents.delete('agent-id-to-delete') +``` diff --git a/.skills/using-letta-api/references/subagents.md b/.skills/using-letta-api/references/subagents.md new file mode 100644 index 0000000..29b8741 --- /dev/null +++ b/.skills/using-letta-api/references/subagents.md @@ -0,0 +1,99 @@ +# Subagent Management via Letta API + +## My Subagents + +| Name | Agent ID | Model | Purpose | +|------|----------|-------|---------| +| comms | agent-a856f614-7654-44ba-a35f-c817d477dded | gemini-3-pro | Public communications | +| scout | agent-e91a2154-0965-4b70-8303-54458e9a1980 | haiku | Exploration, queries | +| coder | agent-f9b768de-e3a4-4845-9c16-d6cf2e954942 | haiku | Code changes | + +## Message a Subagent + +```python +from letta_client import Letta +client = Letta(base_url='https://api.letta.com') + +# Send message and get response +response = client.agents.messages.create( + agent_id='agent-a856f614-7654-44ba-a35f-c817d477dded', # comms + messages=[{ + 'role': 'user', + 'content': 'Post to Moltbook: "Testing the API"' + }] +) + +# Get the assistant's response +for msg in response.messages: + if hasattr(msg, 'content') and msg.content: + print(msg.content) +``` + +## Create a New Subagent + +```python +new_agent = client.agents.create( + name='new-subagent', + description='Purpose of this subagent', + model='claude-haiku-3-5-20241022', + # Optionally share memory blocks + block_ids=['block-id-1', 'block-id-2'] +) +print(f"Created: {new_agent.id}") +``` + +## Deploy via Task Tool (Preferred) + +For most operations, use the Task tool instead of direct API: + +```python +# Via Task tool (in agent context) +Task( + agent_id='agent-a856f614-7654-44ba-a35f-c817d477dded', + subagent_type='general-purpose', + description='Post to Moltbook', + prompt='Post this message to Moltbook m/general: ...' +) +``` + +## Continue Existing Conversation + +```python +# Resume from a conversation ID +response = client.agents.messages.create( + agent_id='agent-xxx', + messages=[{'role': 'user', 'content': 'Continue from where we left off'}], + conversation_id='conv-existing-conversation-id' +) +``` + +## List Subagent Conversations + +```python +conversations = client.agents.conversations.list( + agent_id='agent-a856f614-7654-44ba-a35f-c817d477dded' +) +for conv in conversations: + print(f"{conv.id}: {conv.created_at}") +``` + +## Get Conversation Messages + +```python +messages = client.agents.messages.list( + agent_id='agent-xxx', + conversation_id='conv-xxx' +) +for msg in messages: + print(f"{msg.role}: {msg.content[:100] if msg.content else '(no content)'}") +``` + +## Update Subagent Settings + +```python +# Change subagent's model +client.agents.update( + 'agent-a856f614-7654-44ba-a35f-c817d477dded', + model='claude-sonnet-4-20250514' +) +```