@letta-ai/letta-code 0.12.9-next.5 → 0.12.9-next.7

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 (2) hide show
  1. package/letta.js +154 -21
  2. package/package.json +1 -1
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.12.9-next.5",
3068
+ version: "0.12.9-next.7",
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: {
@@ -5452,6 +5452,43 @@ async function getDefaultMemoryBlocks() {
5452
5452
  }
5453
5453
  return cachedMemoryBlocks;
5454
5454
  }
5455
+ async function ensureSkillsBlocks(agentId) {
5456
+ const { getClient: getClient3 } = await init_client2().then(() => exports_client);
5457
+ const client = await getClient3();
5458
+ const blocksResponse = await client.agents.blocks.list(agentId);
5459
+ const blocks = Array.isArray(blocksResponse) ? blocksResponse : blocksResponse.items || [];
5460
+ const existingLabels = new Set(blocks.map((b) => b.label));
5461
+ const createdLabels = [];
5462
+ for (const label of ISOLATED_BLOCK_LABELS) {
5463
+ if (existingLabels.has(label)) {
5464
+ continue;
5465
+ }
5466
+ const content = MEMORY_PROMPTS[`${label}.mdx`];
5467
+ if (!content) {
5468
+ console.warn(`Missing embedded prompt file for ${label}.mdx`);
5469
+ continue;
5470
+ }
5471
+ const { frontmatter, body } = parseMdxFrontmatter(content);
5472
+ const blockData = {
5473
+ label,
5474
+ value: body,
5475
+ read_only: true
5476
+ };
5477
+ if (frontmatter.description) {
5478
+ blockData.description = frontmatter.description;
5479
+ }
5480
+ if (frontmatter.limit) {
5481
+ const limit2 = parseInt(frontmatter.limit, 10);
5482
+ if (!Number.isNaN(limit2) && limit2 > 0) {
5483
+ blockData.limit = limit2;
5484
+ }
5485
+ }
5486
+ const createdBlock = await client.blocks.create(blockData);
5487
+ await client.agents.blocks.attach(createdBlock.id, { agent_id: agentId });
5488
+ createdLabels.push(label);
5489
+ }
5490
+ return createdLabels;
5491
+ }
5455
5492
  var GLOBAL_BLOCK_LABELS, PROJECT_BLOCK_LABELS, MEMORY_BLOCK_LABELS, READ_ONLY_BLOCK_LABELS, ISOLATED_BLOCK_LABELS, cachedMemoryBlocks = null;
5456
5493
  var init_memory = __esm(() => {
5457
5494
  init_promptAssets();
@@ -51224,7 +51261,6 @@ async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingM
51224
51261
  const defaultBaseTools = options.baseTools ?? [
51225
51262
  baseMemoryTool,
51226
51263
  "web_search",
51227
- "conversation_search",
51228
51264
  "fetch_webpage"
51229
51265
  ];
51230
51266
  let toolNames = [...defaultBaseTools];
@@ -52684,6 +52720,7 @@ async function handleHeadlessCommand(argv, model, skillsDirectory) {
52684
52720
  continue: { type: "boolean", short: "c" },
52685
52721
  resume: { type: "boolean", short: "r" },
52686
52722
  conversation: { type: "string" },
52723
+ "new-agent": { type: "boolean" },
52687
52724
  new: { type: "boolean" },
52688
52725
  agent: { type: "string", short: "a" },
52689
52726
  model: { type: "string", short: "m" },
@@ -52769,11 +52806,16 @@ In headless mode, use:
52769
52806
  --conversation <id> Resume a specific conversation by ID`);
52770
52807
  process.exit(1);
52771
52808
  }
52809
+ if (values.new) {
52810
+ console.error(`Error: --new has been renamed to --new-agent
52811
+ Usage: letta -p "..." --new-agent`);
52812
+ process.exit(1);
52813
+ }
52772
52814
  let agent = null;
52773
52815
  const specifiedAgentId = values.agent;
52774
52816
  const specifiedConversationId = values.conversation;
52775
52817
  const shouldContinue = values.continue;
52776
- const forceNew = values.new;
52818
+ const forceNew = values["new-agent"];
52777
52819
  const systemPromptPreset = values.system;
52778
52820
  const systemCustom = values["system-custom"];
52779
52821
  const systemAppend = values["system-append"];
@@ -53006,6 +53048,10 @@ In headless mode, use:
53006
53048
  agentId: agent.id,
53007
53049
  conversationId
53008
53050
  });
53051
+ const createdBlocks = await ensureSkillsBlocks(agent.id);
53052
+ if (createdBlocks.length > 0) {
53053
+ console.log("Created missing skills blocks for agent compatibility");
53054
+ }
53009
53055
  setAgentContext2(agent.id, skillsDirectory);
53010
53056
  await initializeLoadedSkillsFlag2();
53011
53057
  try {
@@ -60558,6 +60604,7 @@ function getMessageStats2(messages) {
60558
60604
  }
60559
60605
  function ConversationSelector2({
60560
60606
  agentId,
60607
+ agentName,
60561
60608
  currentConversationId,
60562
60609
  onSelect,
60563
60610
  onNewConversation,
@@ -60859,8 +60906,11 @@ function ConversationSelector2({
60859
60906
  children: [
60860
60907
  /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
60861
60908
  dimColor: true,
60862
- children: "No conversations found"
60863
- }, undefined, false, undefined, this),
60909
+ children: [
60910
+ "No conversations for ",
60911
+ agentName || agentId.slice(0, 12)
60912
+ ]
60913
+ }, undefined, true, undefined, this),
60864
60914
  /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
60865
60915
  dimColor: true,
60866
60916
  children: "Press N to start a new conversation"
@@ -70352,8 +70402,8 @@ function MemoryDiffRenderer({
70352
70402
  const blockName = path20.split("/").pop() || path20;
70353
70403
  switch (command) {
70354
70404
  case "str_replace": {
70355
- const oldStr = args.old_str || "";
70356
- const newStr = args.new_str || "";
70405
+ const oldStr = args.old_string || args.old_str || "";
70406
+ const newStr = args.new_string || args.new_str || "";
70357
70407
  return /* @__PURE__ */ jsx_dev_runtime54.jsxDEV(MemoryStrReplaceDiff, {
70358
70408
  blockName,
70359
70409
  oldStr,
@@ -73830,6 +73880,7 @@ function App2({
73830
73880
  const prevColumnsRef = import_react83.useRef(columns);
73831
73881
  const [staticRenderEpoch, setStaticRenderEpoch] = import_react83.useState(0);
73832
73882
  const resizeClearTimeout = import_react83.useRef(null);
73883
+ const isInitialResizeRef = import_react83.useRef(true);
73833
73884
  import_react83.useEffect(() => {
73834
73885
  const prev = prevColumnsRef.current;
73835
73886
  if (columns === prev)
@@ -73838,13 +73889,18 @@ function App2({
73838
73889
  clearTimeout(resizeClearTimeout.current);
73839
73890
  resizeClearTimeout.current = null;
73840
73891
  }
73841
- if (columns < prev - 3 && typeof process !== "undefined" && process.stdout && "write" in process.stdout && process.stdout.isTTY) {
73842
- resizeClearTimeout.current = setTimeout(() => {
73843
- resizeClearTimeout.current = null;
73844
- process.stdout.write(CLEAR_SCREEN_AND_HOME);
73845
- }, 150);
73892
+ if (isInitialResizeRef.current) {
73893
+ isInitialResizeRef.current = false;
73894
+ prevColumnsRef.current = columns;
73895
+ return;
73846
73896
  }
73847
- setStaticRenderEpoch((epoch) => epoch + 1);
73897
+ resizeClearTimeout.current = setTimeout(() => {
73898
+ resizeClearTimeout.current = null;
73899
+ if (typeof process !== "undefined" && process.stdout && "write" in process.stdout && process.stdout.isTTY) {
73900
+ process.stdout.write(CLEAR_SCREEN_AND_HOME);
73901
+ }
73902
+ setStaticRenderEpoch((epoch) => epoch + 1);
73903
+ }, 150);
73848
73904
  prevColumnsRef.current = columns;
73849
73905
  return () => {
73850
73906
  if (resizeClearTimeout.current) {
@@ -78123,6 +78179,7 @@ Plan file path: ${planFilePath}`;
78123
78179
  }, undefined, false, undefined, this),
78124
78180
  activeOverlay === "conversations" && /* @__PURE__ */ jsx_dev_runtime60.jsxDEV(ConversationSelector2, {
78125
78181
  agentId,
78182
+ agentName: agentName ?? undefined,
78126
78183
  currentConversationId: conversationId,
78127
78184
  onSelect: async (convId) => {
78128
78185
  closeOverlay();
@@ -78942,6 +78999,7 @@ async function ensureDefaultAgents(client) {
78942
78999
  const existingMemo = await findDefaultAgent(client, MEMO_TAG);
78943
79000
  if (existingMemo) {
78944
79001
  memoAgent = existingMemo;
79002
+ settingsManager.pinGlobal(existingMemo.id);
78945
79003
  } else {
78946
79004
  const { agent } = await createAgent(DEFAULT_AGENT_CONFIGS.memo);
78947
79005
  await addTagToAgent(client, agent.id, MEMO_TAG);
@@ -78949,7 +79007,9 @@ async function ensureDefaultAgents(client) {
78949
79007
  settingsManager.pinGlobal(agent.id);
78950
79008
  }
78951
79009
  const existingIncognito = await findDefaultAgent(client, INCOGNITO_TAG);
78952
- if (!existingIncognito) {
79010
+ if (existingIncognito) {
79011
+ settingsManager.pinGlobal(existingIncognito.id);
79012
+ } else {
78953
79013
  const { agent } = await createAgent(DEFAULT_AGENT_CONFIGS.incognito);
78954
79014
  await addTagToAgent(client, agent.id, INCOGNITO_TAG);
78955
79015
  settingsManager.pinGlobal(agent.id);
@@ -78980,7 +79040,7 @@ var init_defaults = __esm(async () => {
78980
79040
  name: "Incognito",
78981
79041
  description: INCOGNITO_DESCRIPTION,
78982
79042
  initBlocks: ["skills", "loaded_skills"],
78983
- baseTools: ["web_search", "conversation_search", "fetch_webpage", "Skill"]
79043
+ baseTools: ["web_search", "fetch_webpage"]
78984
79044
  }
78985
79045
  };
78986
79046
  });
@@ -79032,7 +79092,6 @@ async function createAgent2(nameOrOptions = DEFAULT_AGENT_NAME, model, embedding
79032
79092
  const defaultBaseTools = options.baseTools ?? [
79033
79093
  baseMemoryTool,
79034
79094
  "web_search",
79035
- "conversation_search",
79036
79095
  "fetch_webpage"
79037
79096
  ];
79038
79097
  let toolNames = [...defaultBaseTools];
@@ -79773,6 +79832,63 @@ var MEMORY_BLOCK_LABELS2 = [
79773
79832
  ...PROJECT_BLOCK_LABELS2
79774
79833
  ];
79775
79834
  var ISOLATED_BLOCK_LABELS2 = ["skills", "loaded_skills"];
79835
+ function parseMdxFrontmatter2(content) {
79836
+ const frontmatterRegex = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
79837
+ const match = content.match(frontmatterRegex);
79838
+ if (!match || !match[1] || !match[2]) {
79839
+ return { frontmatter: {}, body: content };
79840
+ }
79841
+ const frontmatterText = match[1];
79842
+ const body = match[2];
79843
+ const frontmatter = {};
79844
+ for (const line of frontmatterText.split(`
79845
+ `)) {
79846
+ const colonIndex = line.indexOf(":");
79847
+ if (colonIndex > 0) {
79848
+ const key = line.slice(0, colonIndex).trim();
79849
+ const value = line.slice(colonIndex + 1).trim();
79850
+ frontmatter[key] = value;
79851
+ }
79852
+ }
79853
+ return { frontmatter, body: body.trim() };
79854
+ }
79855
+ async function ensureSkillsBlocks2(agentId) {
79856
+ const { getClient: getClient3 } = await init_client2().then(() => exports_client);
79857
+ const client = await getClient3();
79858
+ const blocksResponse = await client.agents.blocks.list(agentId);
79859
+ const blocks = Array.isArray(blocksResponse) ? blocksResponse : blocksResponse.items || [];
79860
+ const existingLabels = new Set(blocks.map((b) => b.label));
79861
+ const createdLabels = [];
79862
+ for (const label of ISOLATED_BLOCK_LABELS2) {
79863
+ if (existingLabels.has(label)) {
79864
+ continue;
79865
+ }
79866
+ const content = MEMORY_PROMPTS[`${label}.mdx`];
79867
+ if (!content) {
79868
+ console.warn(`Missing embedded prompt file for ${label}.mdx`);
79869
+ continue;
79870
+ }
79871
+ const { frontmatter, body } = parseMdxFrontmatter2(content);
79872
+ const blockData = {
79873
+ label,
79874
+ value: body,
79875
+ read_only: true
79876
+ };
79877
+ if (frontmatter.description) {
79878
+ blockData.description = frontmatter.description;
79879
+ }
79880
+ if (frontmatter.limit) {
79881
+ const limit2 = parseInt(frontmatter.limit, 10);
79882
+ if (!Number.isNaN(limit2) && limit2 > 0) {
79883
+ blockData.limit = limit2;
79884
+ }
79885
+ }
79886
+ const createdBlock = await client.blocks.create(blockData);
79887
+ await client.agents.blocks.attach(createdBlock.id, { agent_id: agentId });
79888
+ createdLabels.push(label);
79889
+ }
79890
+ return createdLabels;
79891
+ }
79776
79892
 
79777
79893
  // src/index.ts
79778
79894
  init_oauth2();
@@ -79888,6 +80004,7 @@ function getMessageStats(messages) {
79888
80004
  }
79889
80005
  function ConversationSelector({
79890
80006
  agentId,
80007
+ agentName,
79891
80008
  currentConversationId,
79892
80009
  onSelect,
79893
80010
  onNewConversation,
@@ -80189,8 +80306,11 @@ function ConversationSelector({
80189
80306
  children: [
80190
80307
  /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
80191
80308
  dimColor: true,
80192
- children: "No conversations found"
80193
- }, undefined, false, undefined, this),
80309
+ children: [
80310
+ "No conversations for ",
80311
+ agentName || agentId.slice(0, 12)
80312
+ ]
80313
+ }, undefined, true, undefined, this),
80194
80314
  /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
80195
80315
  dimColor: true,
80196
80316
  children: "Press N to start a new conversation"
@@ -81927,6 +82047,7 @@ async function main() {
81927
82047
  continue: { type: "boolean" },
81928
82048
  resume: { type: "boolean", short: "r" },
81929
82049
  conversation: { type: "string", short: "C" },
82050
+ "new-agent": { type: "boolean" },
81930
82051
  new: { type: "boolean" },
81931
82052
  "init-blocks": { type: "string" },
81932
82053
  "base-tools": { type: "string" },
@@ -81993,7 +82114,12 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
81993
82114
  const shouldContinue = values.continue ?? false;
81994
82115
  const shouldResume = values.resume ?? false;
81995
82116
  const specifiedConversationId = values.conversation ?? null;
81996
- const forceNew = values.new ?? false;
82117
+ const forceNew = values["new-agent"] ?? false;
82118
+ if (values.new) {
82119
+ console.error(`Error: --new has been renamed to --new-agent
82120
+ Usage: letta --new-agent`);
82121
+ process.exit(1);
82122
+ }
81997
82123
  const initBlocksRaw = values["init-blocks"];
81998
82124
  const baseToolsRaw = values["base-tools"];
81999
82125
  let specifiedAgentId = values.agent ?? null;
@@ -82251,6 +82377,7 @@ Error: ${message}`);
82251
82377
  const [agentProvenance, setAgentProvenance] = useState40(null);
82252
82378
  const [selectedGlobalAgentId, setSelectedGlobalAgentId] = useState40(null);
82253
82379
  const [resumeAgentId, setResumeAgentId] = useState40(null);
82380
+ const [resumeAgentName, setResumeAgentName] = useState40(null);
82254
82381
  const [selectedConversationId, setSelectedConversationId] = useState40(null);
82255
82382
  const [userRequestedNewAgent, setUserRequestedNewAgent] = useState40(false);
82256
82383
  useEffect28(() => {
@@ -82334,8 +82461,9 @@ Error: ${message}`);
82334
82461
  const lastAgentId = lastSession?.agentId ?? localSettings.lastAgent;
82335
82462
  if (lastAgentId) {
82336
82463
  try {
82337
- await client.agents.retrieve(lastAgentId);
82464
+ const agent = await client.agents.retrieve(lastAgentId);
82338
82465
  setResumeAgentId(lastAgentId);
82466
+ setResumeAgentName(agent.name ?? null);
82339
82467
  setLoadingState("selecting_conversation");
82340
82468
  return;
82341
82469
  } catch {}
@@ -82473,6 +82601,10 @@ Error: ${message}`);
82473
82601
  }
82474
82602
  settingsManager2.updateLocalProjectSettings({ lastAgent: agent.id });
82475
82603
  settingsManager2.updateSettings({ lastAgent: agent.id });
82604
+ const createdBlocks = await ensureSkillsBlocks2(agent.id);
82605
+ if (createdBlocks.length > 0) {
82606
+ console.log("Created missing skills blocks for agent compatibility");
82607
+ }
82476
82608
  setAgentContext(agent.id, skillsDirectory2);
82477
82609
  await initializeLoadedSkillsFlag();
82478
82610
  try {
@@ -82643,6 +82775,7 @@ Error during initialization: ${message}`);
82643
82775
  if (loadingState === "selecting_conversation" && resumeAgentId) {
82644
82776
  return React14.createElement(ConversationSelector, {
82645
82777
  agentId: resumeAgentId,
82778
+ agentName: resumeAgentName ?? undefined,
82646
82779
  currentConversationId: "",
82647
82780
  onSelect: (conversationId2) => {
82648
82781
  setSelectedConversationId(conversationId2);
@@ -82720,4 +82853,4 @@ Error during initialization: ${message}`);
82720
82853
  }
82721
82854
  main();
82722
82855
 
82723
- //# debugId=53EB17306046010E64756E2164756E21
82856
+ //# debugId=B78147833F5E9E6664756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letta-ai/letta-code",
3
- "version": "0.12.9-next.5",
3
+ "version": "0.12.9-next.7",
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": {