feat: Make --new safe by default, add --fresh-blocks for isolation (#91)
Co-authored-by: Letta <noreply@letta.com>
This commit is contained in:
26
README.md
26
README.md
@@ -194,6 +194,32 @@ letta --agent <id> --unlink # Remove Letta Code tools
|
|||||||
|
|
||||||
When you attach tools with `/link` or `--link`, they are added to the agent with approval rules enabled (human-in-the-loop). This means the agent can use these tools, but you'll be prompted to approve each tool call. Use permission modes to control approval behavior (see Permissions section below).
|
When you attach tools with `/link` or `--link`, they are added to the agent with approval rules enabled (human-in-the-loop). This means the agent can use these tools, but you'll be prompted to approve each tool call. Use permission modes to control approval behavior (see Permissions section below).
|
||||||
|
|
||||||
|
#### Available Tools
|
||||||
|
|
||||||
|
Letta Code provides the following tools for filesystem and shell operations:
|
||||||
|
|
||||||
|
**File Operations:**
|
||||||
|
- **Read** - Read files from the filesystem, supports offset/limit for large files
|
||||||
|
- **Write** - Write or overwrite files, creates directories automatically
|
||||||
|
- **Edit** - Perform exact string replacements in files (single edit)
|
||||||
|
- **MultiEdit** - Perform multiple find-and-replace operations in a single file efficiently
|
||||||
|
- **LS** - List files and directories, supports ignore patterns
|
||||||
|
|
||||||
|
**Search & Discovery:**
|
||||||
|
- **Glob** - Fast file pattern matching with glob patterns (`**/*.js`, `src/**/*.ts`)
|
||||||
|
- **Grep** - Powerful search using ripgrep, supports regex and various output modes
|
||||||
|
|
||||||
|
**Shell Operations:**
|
||||||
|
- **Bash** - Execute shell commands in a persistent session with timeout support
|
||||||
|
- **BashOutput** - Retrieve output from background bash shells
|
||||||
|
- **KillBash** - Terminate running background bash shells
|
||||||
|
|
||||||
|
**Task Management:**
|
||||||
|
- **TodoWrite** - Create and manage structured task lists for tracking progress
|
||||||
|
- **ExitPlanMode** - Signal completion of planning phase and readiness to implement
|
||||||
|
|
||||||
|
All tools support approval rules and permission modes for safe execution. See the Permissions section for details on controlling tool access.
|
||||||
|
|
||||||
### Headless Mode
|
### Headless Mode
|
||||||
```bash
|
```bash
|
||||||
letta -p "Run bun lint and correct errors" # Auto-resumes project agent
|
letta -p "Run bun lint and correct errors" # Auto-resumes project agent
|
||||||
|
|||||||
33
src/index.ts
33
src/index.ts
@@ -15,7 +15,8 @@ Letta Code is a general purpose CLI for interacting with Letta agents
|
|||||||
USAGE
|
USAGE
|
||||||
# interactive TUI
|
# interactive TUI
|
||||||
letta Auto-resume project agent (from .letta/settings.local.json)
|
letta Auto-resume project agent (from .letta/settings.local.json)
|
||||||
letta --new Force create a new agent
|
letta --new Create a new agent (reuses global persona/human blocks)
|
||||||
|
letta --fresh-blocks Create a new agent with all new memory blocks
|
||||||
letta --continue Resume global last agent (deprecated, use project-based)
|
letta --continue Resume global last agent (deprecated, use project-based)
|
||||||
letta --agent <id> Open a specific agent by ID
|
letta --agent <id> Open a specific agent by ID
|
||||||
|
|
||||||
@@ -25,7 +26,8 @@ USAGE
|
|||||||
OPTIONS
|
OPTIONS
|
||||||
-h, --help Show this help and exit
|
-h, --help Show this help and exit
|
||||||
-v, --version Print version and exit
|
-v, --version Print version and exit
|
||||||
--new Force create new agent (skip auto-resume)
|
--new Create new agent (reuses global blocks like persona/human)
|
||||||
|
--fresh-blocks Force create all new memory blocks (isolate from other agents)
|
||||||
-c, --continue Resume previous session (uses global lastAgent, deprecated)
|
-c, --continue Resume previous session (uses global lastAgent, deprecated)
|
||||||
-a, --agent <id> Use a specific agent ID
|
-a, --agent <id> Use a specific agent ID
|
||||||
-m, --model <id> Model ID or handle (e.g., "opus" or "anthropic/claude-opus-4-1-20250805")
|
-m, --model <id> Model ID or handle (e.g., "opus" or "anthropic/claude-opus-4-1-20250805")
|
||||||
@@ -37,15 +39,23 @@ OPTIONS
|
|||||||
|
|
||||||
BEHAVIOR
|
BEHAVIOR
|
||||||
By default, letta auto-resumes the last agent used in the current directory
|
By default, letta auto-resumes the last agent used in the current directory
|
||||||
(stored in .letta/settings.local.json). Use --new to force a new agent.
|
(stored in .letta/settings.local.json).
|
||||||
|
|
||||||
|
Memory blocks (persona, human, project, skills) are shared between agents:
|
||||||
|
- Global blocks (persona, human) are shared across all agents
|
||||||
|
- Local blocks (project, skills) are shared within the current directory
|
||||||
|
|
||||||
|
Use --new to create a new agent that reuses your global persona/human blocks.
|
||||||
|
Use --fresh-blocks to create a completely isolated agent with new blocks.
|
||||||
|
|
||||||
If no credentials are configured, you'll be prompted to authenticate via
|
If no credentials are configured, you'll be prompted to authenticate via
|
||||||
Letta Cloud OAuth on first run.
|
Letta Cloud OAuth on first run.
|
||||||
|
|
||||||
EXAMPLES
|
EXAMPLES
|
||||||
# when installed as an executable
|
# when installed as an executable
|
||||||
letta # Auto-resume project agent or create new
|
letta # Auto-resume project agent or create new
|
||||||
letta --new # Force new agent
|
letta --new # New agent, keeps your persona/human blocks
|
||||||
|
letta --fresh-blocks # New agent, all blocks fresh (full isolation)
|
||||||
letta --agent agent_123
|
letta --agent agent_123
|
||||||
|
|
||||||
# inside the interactive session
|
# inside the interactive session
|
||||||
@@ -83,6 +93,7 @@ async function main() {
|
|||||||
version: { type: "boolean", short: "v" },
|
version: { type: "boolean", short: "v" },
|
||||||
continue: { type: "boolean", short: "c" },
|
continue: { type: "boolean", short: "c" },
|
||||||
new: { type: "boolean" },
|
new: { type: "boolean" },
|
||||||
|
"fresh-blocks": { type: "boolean" },
|
||||||
agent: { type: "string", short: "a" },
|
agent: { type: "string", short: "a" },
|
||||||
model: { type: "string", short: "m" },
|
model: { type: "string", short: "m" },
|
||||||
prompt: { type: "boolean", short: "p" },
|
prompt: { type: "boolean", short: "p" },
|
||||||
@@ -136,6 +147,7 @@ async function main() {
|
|||||||
|
|
||||||
const shouldContinue = (values.continue as boolean | undefined) ?? false;
|
const shouldContinue = (values.continue as boolean | undefined) ?? false;
|
||||||
const forceNew = (values.new as boolean | undefined) ?? false;
|
const forceNew = (values.new as boolean | undefined) ?? false;
|
||||||
|
const freshBlocks = (values["fresh-blocks"] as boolean | undefined) ?? false;
|
||||||
const specifiedAgentId = (values.agent as string | undefined) ?? null;
|
const specifiedAgentId = (values.agent as string | undefined) ?? null;
|
||||||
const specifiedModel = (values.model as string | undefined) ?? undefined;
|
const specifiedModel = (values.model as string | undefined) ?? undefined;
|
||||||
const skillsDirectory = (values.skills as string | undefined) ?? undefined;
|
const skillsDirectory = (values.skills as string | undefined) ?? undefined;
|
||||||
@@ -277,12 +289,14 @@ async function main() {
|
|||||||
function LoadingApp({
|
function LoadingApp({
|
||||||
continueSession,
|
continueSession,
|
||||||
forceNew,
|
forceNew,
|
||||||
|
freshBlocks,
|
||||||
agentIdArg,
|
agentIdArg,
|
||||||
model,
|
model,
|
||||||
skillsDirectory,
|
skillsDirectory,
|
||||||
}: {
|
}: {
|
||||||
continueSession: boolean;
|
continueSession: boolean;
|
||||||
forceNew: boolean;
|
forceNew: boolean;
|
||||||
|
freshBlocks: boolean;
|
||||||
agentIdArg: string | null;
|
agentIdArg: string | null;
|
||||||
model?: string;
|
model?: string;
|
||||||
skillsDirectory?: string;
|
skillsDirectory?: string;
|
||||||
@@ -357,14 +371,14 @@ async function main() {
|
|||||||
|
|
||||||
// Priority 2: Check if --new flag was passed (skip all resume logic)
|
// Priority 2: Check if --new flag was passed (skip all resume logic)
|
||||||
if (!agent && forceNew) {
|
if (!agent && forceNew) {
|
||||||
// Create new agent with new memory blocks
|
// Create new agent (reuses global blocks unless --fresh-blocks passed)
|
||||||
const updateArgs = getModelUpdateArgs(model);
|
const updateArgs = getModelUpdateArgs(model);
|
||||||
agent = await createAgent(
|
agent = await createAgent(
|
||||||
undefined,
|
undefined,
|
||||||
model,
|
model,
|
||||||
undefined,
|
undefined,
|
||||||
updateArgs,
|
updateArgs,
|
||||||
forceNew,
|
freshBlocks, // Only create new blocks if --fresh-blocks passed
|
||||||
skillsDirectory,
|
skillsDirectory,
|
||||||
settings.parallelToolCalls,
|
settings.parallelToolCalls,
|
||||||
sleeptimeFlag ?? settings.enableSleeptime,
|
sleeptimeFlag ?? settings.enableSleeptime,
|
||||||
@@ -410,7 +424,7 @@ async function main() {
|
|||||||
model,
|
model,
|
||||||
undefined,
|
undefined,
|
||||||
updateArgs,
|
updateArgs,
|
||||||
false,
|
false, // Don't force new blocks when auto-creating (reuse shared blocks)
|
||||||
skillsDirectory,
|
skillsDirectory,
|
||||||
settings.parallelToolCalls,
|
settings.parallelToolCalls,
|
||||||
sleeptimeFlag ?? settings.enableSleeptime,
|
sleeptimeFlag ?? settings.enableSleeptime,
|
||||||
@@ -451,7 +465,7 @@ async function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}, [continueSession, forceNew, agentIdArg, model]);
|
}, [continueSession, forceNew, freshBlocks, agentIdArg, model]);
|
||||||
|
|
||||||
if (!agentId) {
|
if (!agentId) {
|
||||||
return React.createElement(App, {
|
return React.createElement(App, {
|
||||||
@@ -481,6 +495,7 @@ async function main() {
|
|||||||
React.createElement(LoadingApp, {
|
React.createElement(LoadingApp, {
|
||||||
continueSession: shouldContinue,
|
continueSession: shouldContinue,
|
||||||
forceNew: forceNew,
|
forceNew: forceNew,
|
||||||
|
freshBlocks: freshBlocks,
|
||||||
agentIdArg: specifiedAgentId,
|
agentIdArg: specifiedAgentId,
|
||||||
model: specifiedModel,
|
model: specifiedModel,
|
||||||
skillsDirectory: skillsDirectory,
|
skillsDirectory: skillsDirectory,
|
||||||
|
|||||||
Reference in New Issue
Block a user