@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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/letta.js +92 -69
  3. 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 Developer Platform](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 [self-hosted Letta server](https://docs.letta.com/letta-code/configuration#self-hosted-server) by setting `LETTA_BASE_URL`
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.3",
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
- if (values.new) {
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
- const conversation = await client.conversations.create({
53877
- agent_id: agent.id,
53878
- isolated_block_labels: isolatedBlockLabels
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
- const conversation = await client.conversations.create({
53885
- agent_id: agent.id,
53886
- isolated_block_labels: isolatedBlockLabels
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: "Start a new conversation (keep agent memory)",
63083
+ desc: "Clear in-context messages",
63080
63084
  order: 18,
63081
63085
  handler: () => {
63082
- return "Starting new conversation...";
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 (same as /clear)",
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 = isPinned ? [
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 newConversation = await client.conversations.create({
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
- `Started a new conversation with **${agentLabel}**.`,
76742
- `⎿ Type /resume to resume a previous conversation`
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() === "/clear" || msg.trim() === "/new") {
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-messages") {
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: "Resetting agent messages...",
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(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)
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 from profile or create new agent (shows selector)
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 Create a new agent directly (skip profile selector)
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 agent directly (skip profile selection)
83829
- --init-blocks <list> Comma-separated memory blocks to initialize when using --new (e.g., "persona,skills")
83830
- --base-tools <list> Comma-separated base tools to attach when using --new (e.g., "memory,web_search,conversation_search")
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
- if (values.new) {
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
- const conversation = await client.conversations.create({
84860
- agent_id: agent.id,
84861
- isolated_block_labels: [...ISOLATED_BLOCK_LABELS2]
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=A2D04DEC6336411264756E2164756E21
85036
+ //# debugId=C994E1F7CD4B4AD164756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letta-ai/letta-code",
3
- "version": "0.13.3",
3
+ "version": "0.13.4",
4
4
  "description": "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
5
5
  "type": "module",
6
6
  "bin": {