- Add migrating-memory bundled skill with 4 scripts: - list-agents.ts: List all accessible agents - get-agent-blocks.ts: Get memory blocks from an agent - copy-block.ts: Copy a block to create independent copy - attach-block.ts: Attach existing block (shared) - Scripts auto-target current agent for safety (no accidental modifications) - Skill.ts now includes "# Skill Directory:" when loading skills with additional files - Update initializing-memory to suggest migration option - Add unit tests for all migration scripts 🐙 Generated with [Letta Code](https://letta.com) Co-Authored-By: Letta <noreply@letta.com>
Client-side tool guidelines
How to implement tools that run locally in Letta Code.
Contract
- Function signature:
(args, opts?) => Promise<{ toolReturn: string; status: "success" | "error"; stdout?: string[]; stderr?: string[] }> - Optional
opts.signal?: AbortSignal. If you spawn a subprocess, wire this signal to it so Esc/abort can kill it cleanly. If you’re pure in-process, you can ignore it.
Subprocess tools (e.g., Bash)
- Pass the provided
AbortSignaltoexec/spawnso abort kills the child. Normalize abort errors totoolReturn: "User interrupted tool execution", status: "error". - Avoid running multiple subprocesses unless you also expose a cancel hook; we execute tools serially to avoid races.
In-process tools (read/write/edit)
- You can ignore the signal, but still return a clear
toolReturnandstatus. - Be deterministic and side-effect aware; the runner keeps tools serial to avoid file races.
Errors
- Return a concise error message in
toolReturnand setstatus: "error". - Don’t
console.errorfrom tools; the UI surfaces the returned message.