Skip to content

Conversation

@cpfiffer
Copy link
Contributor

Summary

Makes --new flag safer by default. Previously it would nuke ALL memory blocks (including persona/human), which was too destructive.

The Problem

The old --new behavior:

letta --new  # Creates agent with brand new persona, human, project, skills blocks

This meant:

  • ❌ Your persona gets reset every time
  • ❌ Your human context is lost
  • ❌ No shared state between agents
  • ❌ Too destructive for "I just want a new agent"

The Solution

Split into two flags:

--new (Safe)

letta --new  # NEW: Reuses global blocks (persona/human), new local blocks

✅ Creates new agent
✅ Keeps your persona/human blocks
✅ Creates new project/skills blocks
✅ Safe for experimentation

--fresh-blocks (Nuclear)

letta --fresh-blocks  # OLD --new behavior

🔥 All blocks fresh
🔥 Complete isolation
🔥 No shared state

Examples

# Want to experiment? Use --new (keeps your identity)
letta --new

# Want complete isolation? Use --fresh-blocks
letta --fresh-blocks

# Want to resume? Just use letta (unchanged)
letta

Breaking Change

If you relied on --new creating completely isolated agents, use --fresh-blocks instead.

Most users will prefer the new safer behavior.

Testing

  • ✅ All 335 tests pass
  • ✅ Lint passes
  • ✅ Type check passes
  • ✅ Help text updated

👾 Generated with Letta Code

BREAKING CHANGE: --new now reuses global memory blocks (persona, human)

Previously, --new would force creation of ALL new memory blocks, which meant:
- Your persona would be reset every time
- Your human context would be lost
- No shared state between agents

This was too destructive for the common use case of "I want a new agent".

New behavior:
- `letta --new`: Creates new agent, reuses global blocks (persona/human)
- `letta --fresh-blocks`: Nuclear option - all blocks fresh (old --new behavior)
- `letta`: Auto-resume project agent (unchanged)

Benefits:
- --new is now safe for experimentation
- Your persona/human blocks persist across new agents
- --fresh-blocks clearly signals isolation intent

Migration:
- If you relied on --new creating isolated agents, use --fresh-blocks instead
- Most users will prefer the new --new behavior

👾 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <[email protected]>
@cpacker cpacker self-requested a review November 17, 2025 05:17
Copy link
Contributor

@cpacker cpacker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cpfiffer did letta code forget to commit a file? i don't see the changes for create(...) here or maybe i'm blind

@letta pls reply

Lists all 12 tools provided by Letta Code with brief descriptions:
- File operations (Read, Write, Edit, MultiEdit, LS)
- Search & discovery (Glob, Grep)
- Shell operations (Bash, BashOutput, KillBash)
- Task management (TodoWrite, ExitPlanMode)

👾 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <[email protected]>
@cpfiffer
Copy link
Contributor Author

No changes needed to create.ts! It already has the forceNewBlocks parameter (line 29):

export async function createAgent(
  name = "letta-cli-agent",
  model?: string,
  embeddingModel = "openai/text-embedding-3-small",
  updateArgs?: Record<string, unknown>,
  forceNewBlocks = false,  // <-- This parameter already exists
  skillsDirectory?: string,
  parallelToolCalls = true,
  enableSleeptime = false,
) {

I'm just using it correctly from index.ts:

  • Line 378: freshBlocks → passed as forceNewBlocks parameter
  • Line 410: false → passed when auto-creating (reuse shared blocks)

The behavior was already there, I just changed what value gets passed:

  • Before: forceNew flag → both skips resume AND forces new blocks
  • After: forceNew flag → skips resume, freshBlocks flag → forces new blocks

So now --new is safe (reuses blocks) and --fresh-blocks is nuclear (all new).

@cpfiffer
Copy link
Contributor Author

How This Works

The createAgent() function already had a forceNewBlocks parameter (has existed since the beginning). This PR just changes what value gets passed to it.

Before This PR:

// Both controlled by single --new flag
if (forceNew) {
  agent = await createAgent(..., forceNew, ...);  // forceNew = true
}

Problem: --new meant "new agent AND nuke all blocks" (too destructive)

After This PR:

// Separated into two concepts
if (forceNew) {
  agent = await createAgent(..., freshBlocks, ...);  // freshBlocks = false by default
}

Now:

  • --newforceNew=true, freshBlocks=false → new agent, keep blocks ✅
  • --fresh-blocksfreshBlocks=true → nuclear option 🔥

No changes to create.ts needed - it was already doing the right thing with the parameter, we just needed to pass the right value.

@cpacker cpacker merged commit 3d4f4df into main Nov 18, 2025
11 checks passed
@cpacker cpacker deleted the feat-safe-new-flag branch November 18, 2025 00:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants