@letta-ai/letta-code 0.13.3 → 0.13.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/letta.js +92 -69
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ npm install -g @letta-ai/letta-code
|
|
|
16
16
|
Navigate to your project directory and run `letta` (see various command-line options [on the docs](https://docs.letta.com/letta-code/commands)).
|
|
17
17
|
|
|
18
18
|
> [!NOTE]
|
|
19
|
-
> By default, Letta Code will connect to the [Letta
|
|
19
|
+
> By default, Letta Code will connect to the [Letta API](https://app.letta.com/) (includes a free tier), which you can connect to via OAuth or setting a `LETTA_API_KEY`. You can also connect it to a [Docker server](https://docs.letta.com/letta-code/configuration#docker) by setting `LETTA_BASE_URL`
|
|
20
20
|
|
|
21
21
|
## Philosophy
|
|
22
22
|
Letta Code is built around long-lived agents that persist across sessions and improve with use. Rather than working in independent sessions, each session is tied to a persisted agent that learns.
|
package/letta.js
CHANGED
|
@@ -3065,7 +3065,7 @@ var package_default;
|
|
|
3065
3065
|
var init_package = __esm(() => {
|
|
3066
3066
|
package_default = {
|
|
3067
3067
|
name: "@letta-ai/letta-code",
|
|
3068
|
-
version: "0.13.
|
|
3068
|
+
version: "0.13.4",
|
|
3069
3069
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
3070
3070
|
type: "module",
|
|
3071
3071
|
bin: {
|
|
@@ -20010,7 +20010,7 @@ function buildSubagentArgs(type, config, model, userPrompt, existingAgentId, exi
|
|
|
20010
20010
|
if (existingConversationId) {
|
|
20011
20011
|
args.push("--conv", existingConversationId);
|
|
20012
20012
|
} else if (existingAgentId) {
|
|
20013
|
-
args.push("--agent", existingAgentId);
|
|
20013
|
+
args.push("--agent", existingAgentId, "--new");
|
|
20014
20014
|
}
|
|
20015
20015
|
args.push("--no-skills");
|
|
20016
20016
|
} else {
|
|
@@ -53584,11 +53584,7 @@ In headless mode, use:
|
|
|
53584
53584
|
--conversation <id> Resume a specific conversation by ID`);
|
|
53585
53585
|
process.exit(1);
|
|
53586
53586
|
}
|
|
53587
|
-
|
|
53588
|
-
console.error(`Error: --new has been renamed to --new-agent
|
|
53589
|
-
Usage: letta -p "..." --new-agent`);
|
|
53590
|
-
process.exit(1);
|
|
53591
|
-
}
|
|
53587
|
+
const forceNewConversation = values.new ?? false;
|
|
53592
53588
|
let agent = null;
|
|
53593
53589
|
let specifiedAgentId = values.agent;
|
|
53594
53590
|
let specifiedConversationId = values.conversation;
|
|
@@ -53643,6 +53639,16 @@ Usage: letta -p "..." --new-agent`);
|
|
|
53643
53639
|
process.exit(1);
|
|
53644
53640
|
}
|
|
53645
53641
|
}
|
|
53642
|
+
if (forceNewConversation) {
|
|
53643
|
+
if (shouldContinue) {
|
|
53644
|
+
console.error("Error: --new cannot be used with --continue");
|
|
53645
|
+
process.exit(1);
|
|
53646
|
+
}
|
|
53647
|
+
if (specifiedConversationId) {
|
|
53648
|
+
console.error("Error: --new cannot be used with --conversation");
|
|
53649
|
+
process.exit(1);
|
|
53650
|
+
}
|
|
53651
|
+
}
|
|
53646
53652
|
if (fromAfFile) {
|
|
53647
53653
|
if (specifiedAgentId) {
|
|
53648
53654
|
console.error("Error: --from-af cannot be used with --agent");
|
|
@@ -53873,26 +53879,24 @@ Usage: letta -p "..." --new-agent`);
|
|
|
53873
53879
|
await client.conversations.retrieve(lastSession.conversationId);
|
|
53874
53880
|
conversationId = lastSession.conversationId;
|
|
53875
53881
|
} catch {
|
|
53876
|
-
|
|
53877
|
-
|
|
53878
|
-
|
|
53879
|
-
});
|
|
53880
|
-
conversationId = conversation.id;
|
|
53882
|
+
console.error(`Attempting to resume conversation ${lastSession.conversationId}, but conversation was not found.`);
|
|
53883
|
+
console.error("Resume the default conversation with 'letta -p ...', view recent conversations with 'letta --resume', or start a new conversation with 'letta -p ... --new'.");
|
|
53884
|
+
process.exit(1);
|
|
53881
53885
|
}
|
|
53882
53886
|
}
|
|
53883
53887
|
} else {
|
|
53884
|
-
|
|
53885
|
-
|
|
53886
|
-
|
|
53887
|
-
});
|
|
53888
|
-
conversationId = conversation.id;
|
|
53888
|
+
console.error("No previous session found for this agent to resume.");
|
|
53889
|
+
console.error("Resume the default conversation with 'letta -p ...', or start a new conversation with 'letta -p ... --new'.");
|
|
53890
|
+
process.exit(1);
|
|
53889
53891
|
}
|
|
53890
|
-
} else {
|
|
53892
|
+
} else if (forceNewConversation) {
|
|
53891
53893
|
const conversation = await client.conversations.create({
|
|
53892
53894
|
agent_id: agent.id,
|
|
53893
53895
|
isolated_block_labels: isolatedBlockLabels
|
|
53894
53896
|
});
|
|
53895
53897
|
conversationId = conversation.id;
|
|
53898
|
+
} else {
|
|
53899
|
+
conversationId = "default";
|
|
53896
53900
|
}
|
|
53897
53901
|
markMilestone("HEADLESS_CONVERSATION_READY");
|
|
53898
53902
|
if (!isSubagent) {
|
|
@@ -63076,22 +63080,14 @@ var init_registry = __esm(() => {
|
|
|
63076
63080
|
}
|
|
63077
63081
|
},
|
|
63078
63082
|
"/clear": {
|
|
63079
|
-
desc: "
|
|
63083
|
+
desc: "Clear in-context messages",
|
|
63080
63084
|
order: 18,
|
|
63081
63085
|
handler: () => {
|
|
63082
|
-
return "
|
|
63083
|
-
}
|
|
63084
|
-
},
|
|
63085
|
-
"/clear-messages": {
|
|
63086
|
-
desc: "Reset all agent messages (destructive)",
|
|
63087
|
-
order: 19,
|
|
63088
|
-
hidden: true,
|
|
63089
|
-
handler: () => {
|
|
63090
|
-
return "Resetting agent messages...";
|
|
63086
|
+
return "Clearing in-context messages...";
|
|
63091
63087
|
}
|
|
63092
63088
|
},
|
|
63093
63089
|
"/new": {
|
|
63094
|
-
desc: "Start a new conversation (
|
|
63090
|
+
desc: "Start a new conversation (keep agent memory)",
|
|
63095
63091
|
order: 20,
|
|
63096
63092
|
handler: () => {
|
|
63097
63093
|
return "Starting new conversation...";
|
|
@@ -63292,7 +63288,6 @@ Location: ${keybindingsPath}`;
|
|
|
63292
63288
|
},
|
|
63293
63289
|
"/compact": {
|
|
63294
63290
|
desc: "Summarize conversation history (compaction)",
|
|
63295
|
-
hidden: true,
|
|
63296
63291
|
handler: () => {
|
|
63297
63292
|
return "Compacting conversation...";
|
|
63298
63293
|
}
|
|
@@ -75673,7 +75668,13 @@ function App2({
|
|
|
75673
75668
|
console.log(`[DEBUG] Header: resumedExistingConversation=${resumedExistingConversation}, messageHistory.length=${messageHistory.length}`);
|
|
75674
75669
|
}
|
|
75675
75670
|
const headerMessage = isResumingConversation ? `Resuming conversation with **${agentName2}**` : `Starting new conversation with **${agentName2}**`;
|
|
75676
|
-
const commandHints =
|
|
75671
|
+
const commandHints = isResumingConversation ? [
|
|
75672
|
+
"→ **/agents** list all agents",
|
|
75673
|
+
"→ **/resume** browse all conversations",
|
|
75674
|
+
"→ **/new** start a new conversation",
|
|
75675
|
+
"→ **/init** initialize your agent's memory",
|
|
75676
|
+
"→ **/remember** teach your agent"
|
|
75677
|
+
] : isPinned ? [
|
|
75677
75678
|
"→ **/agents** list all agents",
|
|
75678
75679
|
"→ **/resume** resume a previous conversation",
|
|
75679
75680
|
"→ **/memory** view your agent's memory blocks",
|
|
@@ -76712,11 +76713,7 @@ ${newState.originalPrompt}`
|
|
|
76712
76713
|
try {
|
|
76713
76714
|
const client = await getClient2();
|
|
76714
76715
|
const agent = await client.agents.retrieve(targetAgentId);
|
|
76715
|
-
const
|
|
76716
|
-
agent_id: targetAgentId,
|
|
76717
|
-
isolated_block_labels: [...ISOLATED_BLOCK_LABELS]
|
|
76718
|
-
});
|
|
76719
|
-
const targetConversationId = newConversation.id;
|
|
76716
|
+
const targetConversationId = "default";
|
|
76720
76717
|
await updateProjectSettings({ lastAgent: targetAgentId });
|
|
76721
76718
|
settingsManager.setLocalLastSession({ agentId: targetAgentId, conversationId: targetConversationId }, process.cwd());
|
|
76722
76719
|
settingsManager.setGlobalLastSession({
|
|
@@ -76738,8 +76735,9 @@ ${newState.originalPrompt}`
|
|
|
76738
76735
|
setConversationId(targetConversationId);
|
|
76739
76736
|
const agentLabel = agent.name || targetAgentId;
|
|
76740
76737
|
const successOutput = [
|
|
76741
|
-
`
|
|
76742
|
-
`⎿ Type /resume to
|
|
76738
|
+
`Resumed the default conversation with **${agentLabel}**.`,
|
|
76739
|
+
`⎿ Type /resume to browse all conversations`,
|
|
76740
|
+
`⎿ Type /new to start a new conversation`
|
|
76743
76741
|
].join(`
|
|
76744
76742
|
`);
|
|
76745
76743
|
const successItem = {
|
|
@@ -77444,7 +77442,7 @@ Type your task to begin the loop.`,
|
|
|
77444
77442
|
}
|
|
77445
77443
|
return { submitted: true };
|
|
77446
77444
|
}
|
|
77447
|
-
if (msg.trim() === "/
|
|
77445
|
+
if (msg.trim() === "/new") {
|
|
77448
77446
|
const cmdId2 = uid4("cmd");
|
|
77449
77447
|
buffersRef.current.byId.set(cmdId2, {
|
|
77450
77448
|
kind: "command",
|
|
@@ -77495,13 +77493,13 @@ Type your task to begin the loop.`,
|
|
|
77495
77493
|
}
|
|
77496
77494
|
return { submitted: true };
|
|
77497
77495
|
}
|
|
77498
|
-
if (msg.trim() === "/clear
|
|
77496
|
+
if (msg.trim() === "/clear") {
|
|
77499
77497
|
const cmdId2 = uid4("cmd");
|
|
77500
77498
|
buffersRef.current.byId.set(cmdId2, {
|
|
77501
77499
|
kind: "command",
|
|
77502
77500
|
id: cmdId2,
|
|
77503
77501
|
input: msg,
|
|
77504
|
-
output: "
|
|
77502
|
+
output: "Clearing in-context messages...",
|
|
77505
77503
|
phase: "running"
|
|
77506
77504
|
});
|
|
77507
77505
|
buffersRef.current.order.push(cmdId2);
|
|
@@ -80025,17 +80023,21 @@ Plan file path: ${planFilePath}`;
|
|
|
80025
80023
|
color: colors.link.url,
|
|
80026
80024
|
children: agentName && (settingsManager.getLocalPinnedAgents().includes(agentId) || settingsManager.getGlobalPinnedAgents().includes(agentId)) ? `letta -n "${agentName}"` : `letta --agent ${agentId}`
|
|
80027
80025
|
}, undefined, false, undefined, this),
|
|
80028
|
-
/* @__PURE__ */ jsx_dev_runtime61.jsxDEV(
|
|
80029
|
-
children:
|
|
80030
|
-
|
|
80031
|
-
|
|
80032
|
-
|
|
80033
|
-
|
|
80034
|
-
|
|
80035
|
-
|
|
80036
|
-
|
|
80037
|
-
|
|
80038
|
-
|
|
80026
|
+
conversationId !== "default" && /* @__PURE__ */ jsx_dev_runtime61.jsxDEV(jsx_dev_runtime61.Fragment, {
|
|
80027
|
+
children: [
|
|
80028
|
+
/* @__PURE__ */ jsx_dev_runtime61.jsxDEV(Text, {
|
|
80029
|
+
children: " "
|
|
80030
|
+
}, undefined, false, undefined, this),
|
|
80031
|
+
/* @__PURE__ */ jsx_dev_runtime61.jsxDEV(Text, {
|
|
80032
|
+
dimColor: true,
|
|
80033
|
+
children: "Resume this conversation with:"
|
|
80034
|
+
}, undefined, false, undefined, this),
|
|
80035
|
+
/* @__PURE__ */ jsx_dev_runtime61.jsxDEV(Text, {
|
|
80036
|
+
color: colors.link.url,
|
|
80037
|
+
children: `letta --conv ${conversationId}`
|
|
80038
|
+
}, undefined, false, undefined, this)
|
|
80039
|
+
]
|
|
80040
|
+
}, undefined, true, undefined, this)
|
|
80039
80041
|
]
|
|
80040
80042
|
}, undefined, true, undefined, this),
|
|
80041
80043
|
/* @__PURE__ */ jsx_dev_runtime61.jsxDEV(Box_default, {
|
|
@@ -80934,6 +80936,10 @@ var init_release_notes = __esm(async () => {
|
|
|
80934
80936
|
init_version();
|
|
80935
80937
|
await init_settings_manager();
|
|
80936
80938
|
releaseNotes = {
|
|
80939
|
+
"0.13.4": `\uD83D\uDD04 **Letta Code 0.13.4: Back to the OG experience**
|
|
80940
|
+
→ Running **letta** now resumes your "default" conversation (instead of spawning a new one)
|
|
80941
|
+
→ Use **letta --new** if you want to create a new conversation for concurrent sessions
|
|
80942
|
+
→ Read more: https://docs.letta.com/letta-code/changelog#0134`,
|
|
80937
80943
|
"0.13.0": `\uD83C\uDF81 **Letta Code 0.13.0: Introducing Conversations!**
|
|
80938
80944
|
→ Letta Code now starts a new conversation on each startup (memory is shared across all conversations)
|
|
80939
80945
|
→ Use **/resume** to switch conversations, or run **letta --continue** to continue an existing conversation
|
|
@@ -83807,10 +83813,11 @@ Letta Code is a general purpose CLI for interacting with Letta agents
|
|
|
83807
83813
|
|
|
83808
83814
|
USAGE
|
|
83809
83815
|
# interactive TUI
|
|
83810
|
-
letta Resume
|
|
83816
|
+
letta Resume default conversation (OG single-threaded experience)
|
|
83817
|
+
letta --new Create a new conversation (for concurrent sessions)
|
|
83811
83818
|
letta --continue Resume last session (agent + conversation) directly
|
|
83812
83819
|
letta --resume Open agent selector UI to pick agent/conversation
|
|
83813
|
-
letta --new
|
|
83820
|
+
letta --new-agent Create a new agent directly (skip profile selector)
|
|
83814
83821
|
letta --agent <id> Open a specific agent by ID
|
|
83815
83822
|
|
|
83816
83823
|
# headless
|
|
@@ -83825,9 +83832,10 @@ OPTIONS
|
|
|
83825
83832
|
--info Show current directory, skills, and pinned agents
|
|
83826
83833
|
--continue Resume last session (agent + conversation) directly
|
|
83827
83834
|
-r, --resume Open agent selector UI after loading
|
|
83828
|
-
--new Create new
|
|
83829
|
-
--
|
|
83830
|
-
--
|
|
83835
|
+
--new Create new conversation (for concurrent sessions)
|
|
83836
|
+
--new-agent Create new agent directly (skip profile selection)
|
|
83837
|
+
--init-blocks <list> Comma-separated memory blocks to initialize when using --new-agent (e.g., "persona,skills")
|
|
83838
|
+
--base-tools <list> Comma-separated base tools to attach when using --new-agent (e.g., "memory,web_search,conversation_search")
|
|
83831
83839
|
-a, --agent <id> Use a specific agent ID
|
|
83832
83840
|
-n, --name <name> Resume agent by name (from pinned agents, case-insensitive)
|
|
83833
83841
|
-m, --model <id> Model ID or handle (e.g., "opus-4.5" or "anthropic/claude-opus-4-5")
|
|
@@ -84118,11 +84126,7 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
84118
84126
|
}
|
|
84119
84127
|
specifiedConversationId = "default";
|
|
84120
84128
|
}
|
|
84121
|
-
|
|
84122
|
-
console.error(`Error: --new has been renamed to --new-agent
|
|
84123
|
-
Usage: letta --new-agent`);
|
|
84124
|
-
process.exit(1);
|
|
84125
|
-
}
|
|
84129
|
+
const forceNewConversation = values.new ?? false;
|
|
84126
84130
|
const initBlocksRaw = values["init-blocks"];
|
|
84127
84131
|
const baseToolsRaw = values["base-tools"];
|
|
84128
84132
|
let specifiedAgentId = values.agent ?? null;
|
|
@@ -84246,6 +84250,20 @@ Usage: letta --new-agent`);
|
|
|
84246
84250
|
process.exit(1);
|
|
84247
84251
|
}
|
|
84248
84252
|
}
|
|
84253
|
+
if (forceNewConversation) {
|
|
84254
|
+
if (shouldContinue) {
|
|
84255
|
+
console.error("Error: --new cannot be used with --continue");
|
|
84256
|
+
process.exit(1);
|
|
84257
|
+
}
|
|
84258
|
+
if (specifiedConversationId) {
|
|
84259
|
+
console.error("Error: --new cannot be used with --conversation");
|
|
84260
|
+
process.exit(1);
|
|
84261
|
+
}
|
|
84262
|
+
if (shouldResume) {
|
|
84263
|
+
console.error("Error: --new cannot be used with --resume");
|
|
84264
|
+
process.exit(1);
|
|
84265
|
+
}
|
|
84266
|
+
}
|
|
84249
84267
|
if (fromAfFile) {
|
|
84250
84268
|
if (specifiedAgentId) {
|
|
84251
84269
|
console.error("Error: --from-af cannot be used with --agent");
|
|
@@ -84856,11 +84874,9 @@ Error: ${message}`);
|
|
|
84856
84874
|
}
|
|
84857
84875
|
}
|
|
84858
84876
|
if (!resumedSuccessfully) {
|
|
84859
|
-
|
|
84860
|
-
|
|
84861
|
-
|
|
84862
|
-
});
|
|
84863
|
-
conversationIdToUse = conversation.id;
|
|
84877
|
+
console.error(`Attempting to resume conversation ${lastSession?.conversationId ?? "(unknown)"}, but conversation was not found.`);
|
|
84878
|
+
console.error("Resume the default conversation with 'letta', view recent conversations with 'letta --resume', or start a new conversation with 'letta --new'.");
|
|
84879
|
+
process.exit(1);
|
|
84864
84880
|
}
|
|
84865
84881
|
} else if (selectedConversationId) {
|
|
84866
84882
|
try {
|
|
@@ -84877,12 +84893,19 @@ Error: ${message}`);
|
|
|
84877
84893
|
}
|
|
84878
84894
|
throw error;
|
|
84879
84895
|
}
|
|
84880
|
-
} else {
|
|
84896
|
+
} else if (forceNewConversation) {
|
|
84881
84897
|
const conversation = await client.conversations.create({
|
|
84882
84898
|
agent_id: agent.id,
|
|
84883
84899
|
isolated_block_labels: [...ISOLATED_BLOCK_LABELS2]
|
|
84884
84900
|
});
|
|
84885
84901
|
conversationIdToUse = conversation.id;
|
|
84902
|
+
} else {
|
|
84903
|
+
conversationIdToUse = "default";
|
|
84904
|
+
setLoadingState("checking");
|
|
84905
|
+
const freshAgent = await client.agents.retrieve(agent.id);
|
|
84906
|
+
const data = await getResumeData(client, freshAgent, "default");
|
|
84907
|
+
setResumeData(data);
|
|
84908
|
+
setResumedExistingConversation(true);
|
|
84886
84909
|
}
|
|
84887
84910
|
const isSubagent = process.env.LETTA_CODE_AGENT_ROLE === "subagent";
|
|
84888
84911
|
if (!isSubagent) {
|
|
@@ -85010,4 +85033,4 @@ Error during initialization: ${message}`);
|
|
|
85010
85033
|
}
|
|
85011
85034
|
main();
|
|
85012
85035
|
|
|
85013
|
-
//# debugId=
|
|
85036
|
+
//# debugId=C994E1F7CD4B4AD164756E2164756E21
|