@letta-ai/letta-code 0.13.1 → 0.13.3

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/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.1",
3068
+ version: "0.13.3",
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: {
@@ -5916,32 +5916,30 @@ var init_plan = () => {};
5916
5916
  var recall_default = `---
5917
5917
  name: recall
5918
5918
  description: Search conversation history to recall past discussions, decisions, and context
5919
- tools: Skill, Bash, Read, BashOutput
5920
- model: haiku
5921
- memoryBlocks: human, persona, skills, loaded_skills
5919
+ tools: Bash, Read, BashOutput
5920
+ model: opus
5921
+ memoryBlocks: skills, loaded_skills
5922
+ skills: searching-messages
5922
5923
  mode: stateless
5923
5924
  ---
5924
5925
 
5925
5926
  You are a subagent launched via the Task tool to search conversation history. You run autonomously and return a single final report when done. You CANNOT ask questions mid-execution.
5926
5927
 
5927
- ## Instructions
5928
-
5929
- ### Step 1: Load the searching-messages skill
5930
- \`\`\`
5931
- Skill({ command: "load", skills: ["searching-messages"] })
5932
- \`\`\`
5928
+ ## CRITICAL WARNINGS
5933
5929
 
5934
- After loading, your \`loaded_skills\` memory block contains the full instructions with ready-to-use bash commands. Follow them directly - do not search for files or guess at commands.
5930
+ 1. **NEVER use \`conversation_search\`** - It only searches YOUR empty history, not the parent's.
5931
+ 2. **NEVER invent commands** - There is NO \`letta messages search\` or \`letta messages list\`. These don't exist.
5935
5932
 
5936
- ### Step 2: Search the parent agent's history
5937
-
5938
- **CRITICAL - Two rules:**
5933
+ ## Instructions
5939
5934
 
5940
- 1. **DO NOT use \`conversation_search\`** - That tool only searches YOUR history (empty). You MUST use the Bash scripts from the skill.
5935
+ The \`searching-messages\` skill is pre-loaded in your \`<loaded_skills>\` memory block below. Read it carefully - it contains:
5936
+ - \`# Skill Directory:\` - the exact path to use in commands
5937
+ - Multiple search strategies (needle + expand, date-bounded, broad discovery)
5938
+ - Command options and examples
5941
5939
 
5942
- 2. **ALWAYS add \`--agent-id $LETTA_PARENT_AGENT_ID\`** - This searches the parent agent's history. The only exception is \`--all-agents\` searches.
5940
+ **Follow the skill's strategies thoroughly.** Use multiple searches if needed to gather comprehensive context. Always add \`--agent-id $LETTA_PARENT_AGENT_ID\` to search the parent agent's history.
5943
5941
 
5944
- Follow the strategies documented in the loaded skill.
5942
+ After gathering results, compile a comprehensive report.
5945
5943
 
5946
5944
  ## Output Format
5947
5945
 
@@ -8621,6 +8619,8 @@ Launch a subagent to perform a task. Parameters:
8621
8619
  - **prompt**: Detailed, self-contained instructions for the agent (agents cannot ask questions mid-execution)
8622
8620
  - **description**: Short 3-5 word summary for tracking
8623
8621
  - **model** (optional): Override the model for this agent
8622
+ - **agent_id** (optional): Deploy an existing agent instead of creating a new one
8623
+ - **conversation_id** (optional): Resume from an existing conversation
8624
8624
 
8625
8625
  ### Refresh
8626
8626
  Re-scan the \`.letta/agents/\` directories to discover new or updated custom subagents:
@@ -8652,6 +8652,57 @@ Use this after creating or modifying custom subagent definitions.
8652
8652
  - **Parallel execution**: Launch multiple agents concurrently by calling Task multiple times in a single response
8653
8653
  - **Specify return format**: Tell agents exactly what information to include in their report
8654
8654
 
8655
+ ## Deploying an Existing Agent
8656
+
8657
+ Instead of spawning a fresh subagent from a template, you can deploy an existing agent to work in your local codebase.
8658
+
8659
+ ### Access Levels (subagent_type)
8660
+ Use subagent_type to control what tools the deployed agent can access:
8661
+ - **explore**: Read-only access (Read, Glob, Grep) - safer for exploration tasks
8662
+ - **general-purpose**: Full read-write access (Bash, Edit, Write, etc.) - for implementation tasks
8663
+
8664
+ If subagent_type is not specified when deploying an existing agent, it defaults to "general-purpose".
8665
+
8666
+ ### Parameters
8667
+
8668
+ - **agent_id**: The ID of an existing agent to deploy (e.g., "agent-abc123")
8669
+ - Starts a new conversation with that agent
8670
+ - The agent keeps its own system prompt and memory
8671
+ - Tool access is controlled by subagent_type
8672
+
8673
+ - **conversation_id**: Resume from an existing conversation (e.g., "conv-xyz789")
8674
+ - Does NOT require agent_id (conversation IDs are unique and encode the agent)
8675
+ - Continues from the conversation's existing message history
8676
+ - Use this to continue context from:
8677
+ - A prior Task tool invocation that returned a conversation_id
8678
+ - A message thread started via the messaging-agents skill
8679
+
8680
+ ### Examples
8681
+
8682
+ \`\`\`typescript
8683
+ // Deploy agent with read-only access
8684
+ Task({
8685
+ agent_id: "agent-abc123",
8686
+ subagent_type: "explore",
8687
+ description: "Find auth code",
8688
+ prompt: "Find all auth-related code in this codebase"
8689
+ })
8690
+
8691
+ // Deploy agent with full access (default)
8692
+ Task({
8693
+ agent_id: "agent-abc123",
8694
+ description: "Fix auth bug",
8695
+ prompt: "Fix the bug in auth.ts"
8696
+ })
8697
+
8698
+ // Continue an existing conversation
8699
+ Task({
8700
+ conversation_id: "conv-xyz789",
8701
+ description: "Continue implementation",
8702
+ prompt: "Now implement the fix we discussed"
8703
+ })
8704
+ \`\`\`
8705
+
8655
8706
  ## Examples:
8656
8707
 
8657
8708
  \`\`\`typescript
@@ -9675,6 +9726,7 @@ var init_truncation = __esm(() => {
9675
9726
  init_overflow();
9676
9727
  LIMITS = {
9677
9728
  BASH_OUTPUT_CHARS: 30000,
9729
+ TASK_OUTPUT_CHARS: 30000,
9678
9730
  READ_MAX_LINES: 2000,
9679
9731
  READ_MAX_CHARS_PER_LINE: 2000,
9680
9732
  GREP_OUTPUT_CHARS: 1e4,
@@ -19528,6 +19580,33 @@ ${pathLine}${processedContent}`;
19528
19580
  throw new Error(`Failed to ${command} skill(s): ${String(error)}`);
19529
19581
  }
19530
19582
  }
19583
+ async function preloadSkillsContent(skillIds, skillsDir) {
19584
+ if (skillIds.length === 0) {
19585
+ return "No skills currently loaded.";
19586
+ }
19587
+ let content = "";
19588
+ for (const skillId of skillIds) {
19589
+ try {
19590
+ const { content: skillContent, path: skillPath } = await readSkillContent(skillId, skillsDir);
19591
+ const skillDir = dirname5(skillPath);
19592
+ const hasExtras = hasAdditionalFiles(skillPath);
19593
+ const pathLine = hasExtras ? `# Skill Directory: ${skillDir}
19594
+
19595
+ ` : "";
19596
+ const processedContent = hasExtras ? skillContent.replace(/<SKILL_DIR>/g, skillDir) : skillContent;
19597
+ const separator = content ? `
19598
+
19599
+ ---
19600
+
19601
+ ` : "";
19602
+ content = `${content}${separator}# Skill: ${skillId}
19603
+ ${pathLine}${processedContent}`;
19604
+ } catch (error) {
19605
+ console.error(`Warning: Could not pre-load skill "${skillId}": ${error instanceof Error ? error.message : String(error)}`);
19606
+ }
19607
+ }
19608
+ return content || "No skills currently loaded.";
19609
+ }
19531
19610
  var init_Skill2 = __esm(async () => {
19532
19611
  init_context();
19533
19612
  init_skills2();
@@ -19822,6 +19901,9 @@ function handleInitEvent(event, state, baseURL, subagentId) {
19822
19901
  const agentURL = `${baseURL}/agents/${event.agent_id}`;
19823
19902
  updateSubagent(subagentId, { agentURL });
19824
19903
  }
19904
+ if (event.conversation_id) {
19905
+ state.conversationId = event.conversation_id;
19906
+ }
19825
19907
  }
19826
19908
  function handleApprovalRequestEvent(event, state) {
19827
19909
  const toolCalls = Array.isArray(event.tool_calls) ? event.tool_calls : event.tool_call ? [event.tool_call] : [];
@@ -19921,18 +20003,24 @@ function parseResultFromStdout(stdout, agentId) {
19921
20003
  };
19922
20004
  }
19923
20005
  }
19924
- function buildSubagentArgs(type, config, model, userPrompt) {
19925
- const args = [
19926
- "--new-agent",
19927
- "--system",
19928
- type,
19929
- "--model",
19930
- model,
19931
- "-p",
19932
- userPrompt,
19933
- "--output-format",
19934
- "stream-json"
19935
- ];
20006
+ function buildSubagentArgs(type, config, model, userPrompt, existingAgentId, existingConversationId, preloadedSkillsContent) {
20007
+ const args = [];
20008
+ const isDeployingExisting = Boolean(existingAgentId || existingConversationId);
20009
+ if (isDeployingExisting) {
20010
+ if (existingConversationId) {
20011
+ args.push("--conv", existingConversationId);
20012
+ } else if (existingAgentId) {
20013
+ args.push("--agent", existingAgentId);
20014
+ }
20015
+ args.push("--no-skills");
20016
+ } else {
20017
+ args.push("--new-agent", "--system", type);
20018
+ if (model) {
20019
+ args.push("--model", model);
20020
+ }
20021
+ }
20022
+ args.push("-p", userPrompt);
20023
+ args.push("--output-format", "stream-json");
19936
20024
  const subagentMode = config.permissionMode;
19937
20025
  const parentMode = permissionMode.getMode();
19938
20026
  const modeToUse = subagentMode || parentMode;
@@ -19941,8 +20029,9 @@ function buildSubagentArgs(type, config, model, userPrompt) {
19941
20029
  }
19942
20030
  const parentAllowedTools = cliPermissions.getAllowedTools();
19943
20031
  const sessionAllowRules = sessionPermissions.getRules().allow || [];
20032
+ const subagentTools = config.allowedTools !== "all" && Array.isArray(config.allowedTools) ? config.allowedTools : [];
19944
20033
  const combinedAllowedTools = [
19945
- ...new Set([...parentAllowedTools, ...sessionAllowRules])
20034
+ ...new Set([...parentAllowedTools, ...sessionAllowRules, ...subagentTools])
19946
20035
  ];
19947
20036
  if (combinedAllowedTools.length > 0) {
19948
20037
  args.push("--allowedTools", combinedAllowedTools.join(","));
@@ -19951,17 +20040,22 @@ function buildSubagentArgs(type, config, model, userPrompt) {
19951
20040
  if (parentDisallowedTools.length > 0) {
19952
20041
  args.push("--disallowedTools", parentDisallowedTools.join(","));
19953
20042
  }
19954
- if (config.memoryBlocks === "none") {
19955
- args.push("--init-blocks", "none");
19956
- } else if (Array.isArray(config.memoryBlocks) && config.memoryBlocks.length > 0) {
19957
- args.push("--init-blocks", config.memoryBlocks.join(","));
20043
+ if (!isDeployingExisting) {
20044
+ if (config.memoryBlocks === "none") {
20045
+ args.push("--init-blocks", "none");
20046
+ } else if (Array.isArray(config.memoryBlocks) && config.memoryBlocks.length > 0) {
20047
+ args.push("--init-blocks", config.memoryBlocks.join(","));
20048
+ }
19958
20049
  }
19959
20050
  if (config.allowedTools !== "all" && Array.isArray(config.allowedTools) && config.allowedTools.length > 0) {
19960
20051
  args.push("--tools", config.allowedTools.join(","));
19961
20052
  }
20053
+ if (!isDeployingExisting && preloadedSkillsContent) {
20054
+ args.push("--block-value", `loaded_skills=${preloadedSkillsContent}`);
20055
+ }
19962
20056
  return args;
19963
20057
  }
19964
- async function executeSubagent(type, config, model, userPrompt, baseURL, subagentId, isRetry = false, signal) {
20058
+ async function executeSubagent(type, config, model, userPrompt, baseURL, subagentId, isRetry = false, signal, existingAgentId, existingConversationId) {
19965
20059
  if (signal?.aborted) {
19966
20060
  return {
19967
20061
  agentId: "",
@@ -19970,10 +20064,17 @@ async function executeSubagent(type, config, model, userPrompt, baseURL, subagen
19970
20064
  error: INTERRUPTED_BY_USER
19971
20065
  };
19972
20066
  }
19973
- updateSubagent(subagentId, { model });
20067
+ if (model) {
20068
+ updateSubagent(subagentId, { model });
20069
+ }
19974
20070
  try {
19975
- const cliArgs = buildSubagentArgs(type, config, model, userPrompt);
19976
- const lettaCmd = process.env.LETTA_CODE_BIN || "letta";
20071
+ let preloadedSkillsContent;
20072
+ if (config.skills && config.skills.length > 0) {
20073
+ preloadedSkillsContent = await preloadSkillsContent(config.skills, SKILLS_DIR);
20074
+ }
20075
+ const cliArgs = buildSubagentArgs(type, config, model, userPrompt, existingAgentId, existingConversationId, preloadedSkillsContent);
20076
+ const currentScript = process.argv[1] || "";
20077
+ const lettaCmd = process.env.LETTA_CODE_BIN || (currentScript.endsWith(".js") ? currentScript : null) || (currentScript.includes("src/index.ts") ? "./letta.js" : null) || "letta";
19977
20078
  let parentAgentId;
19978
20079
  try {
19979
20080
  parentAgentId = getCurrentAgentId();
@@ -19995,7 +20096,8 @@ async function executeSubagent(type, config, model, userPrompt, baseURL, subagen
19995
20096
  const stdoutChunks = [];
19996
20097
  const stderrChunks = [];
19997
20098
  const state = {
19998
- agentId: null,
20099
+ agentId: existingAgentId || null,
20100
+ conversationId: existingConversationId || null,
19999
20101
  finalResult: null,
20000
20102
  finalError: null,
20001
20103
  resultStats: null,
@@ -20022,6 +20124,7 @@ async function executeSubagent(type, config, model, userPrompt, baseURL, subagen
20022
20124
  if (wasAborted) {
20023
20125
  return {
20024
20126
  agentId: state.agentId || "",
20127
+ conversationId: state.conversationId || undefined,
20025
20128
  report: "",
20026
20129
  success: false,
20027
20130
  error: INTERRUPTED_BY_USER
@@ -20037,6 +20140,7 @@ async function executeSubagent(type, config, model, userPrompt, baseURL, subagen
20037
20140
  }
20038
20141
  return {
20039
20142
  agentId: state.agentId || "",
20143
+ conversationId: state.conversationId || undefined,
20040
20144
  report: "",
20041
20145
  success: false,
20042
20146
  error: stderr || `Subagent exited with code ${exitCode}`
@@ -20045,6 +20149,7 @@ async function executeSubagent(type, config, model, userPrompt, baseURL, subagen
20045
20149
  if (state.finalResult !== null) {
20046
20150
  return {
20047
20151
  agentId: state.agentId || "",
20152
+ conversationId: state.conversationId || undefined,
20048
20153
  report: state.finalResult,
20049
20154
  success: !state.finalError,
20050
20155
  error: state.finalError || undefined,
@@ -20054,6 +20159,7 @@ async function executeSubagent(type, config, model, userPrompt, baseURL, subagen
20054
20159
  if (state.finalError) {
20055
20160
  return {
20056
20161
  agentId: state.agentId || "",
20162
+ conversationId: state.conversationId || undefined,
20057
20163
  report: "",
20058
20164
  success: false,
20059
20165
  error: state.finalError,
@@ -20079,7 +20185,17 @@ function getBaseURL() {
20079
20185
  }
20080
20186
  return baseURL;
20081
20187
  }
20082
- async function spawnSubagent(type, prompt, userModel, subagentId, signal) {
20188
+ function buildDeploySystemReminder(senderAgentName, senderAgentId, subagentType) {
20189
+ const toolDescription = subagentType === "explore" ? "read-only tools (Read, Glob, Grep)" : "local tools (Bash, Read, Write, Edit, etc.)";
20190
+ return `<system-reminder>
20191
+ This task is from "${senderAgentName}" (agent ID: ${senderAgentId}), which deployed you as a subagent inside the Letta Code CLI (docs.letta.com/letta-code).
20192
+ You have access to ${toolDescription} in their codebase.
20193
+ Your final message will be returned to the caller.
20194
+ </system-reminder>
20195
+
20196
+ `;
20197
+ }
20198
+ async function spawnSubagent(type, prompt, userModel, subagentId, signal, existingAgentId, existingConversationId) {
20083
20199
  const allConfigs = await getAllSubagentConfigs();
20084
20200
  const config = allConfigs[type];
20085
20201
  if (!config) {
@@ -20090,9 +20206,20 @@ async function spawnSubagent(type, prompt, userModel, subagentId, signal) {
20090
20206
  error: `Unknown subagent type: ${type}`
20091
20207
  };
20092
20208
  }
20093
- const model = userModel || config.recommendedModel;
20209
+ const isDeployingExisting = Boolean(existingAgentId || existingConversationId);
20210
+ const model = isDeployingExisting ? null : userModel || config.recommendedModel;
20094
20211
  const baseURL = getBaseURL();
20095
- const result = await executeSubagent(type, config, model, prompt, baseURL, subagentId, false, signal);
20212
+ let finalPrompt = prompt;
20213
+ if (isDeployingExisting) {
20214
+ try {
20215
+ const parentAgentId = getCurrentAgentId();
20216
+ const client = await getClient2();
20217
+ const parentAgent = await client.agents.retrieve(parentAgentId);
20218
+ const systemReminder = buildDeploySystemReminder(parentAgent.name, parentAgentId, type);
20219
+ finalPrompt = systemReminder + prompt;
20220
+ } catch {}
20221
+ }
20222
+ const result = await executeSubagent(type, config, model, finalPrompt, baseURL, subagentId, false, signal, existingAgentId, existingConversationId);
20096
20223
  return result;
20097
20224
  }
20098
20225
  var init_manager2 = __esm(async () => {
@@ -20103,9 +20230,11 @@ var init_manager2 = __esm(async () => {
20103
20230
  init_session();
20104
20231
  init_context();
20105
20232
  init_model();
20233
+ init_skills2();
20106
20234
  init_subagents();
20107
20235
  await __promiseAll([
20108
20236
  init_settings_manager(),
20237
+ init_Skill2(),
20109
20238
  init_client2()
20110
20239
  ]);
20111
20240
  });
@@ -20127,19 +20256,27 @@ async function task(args) {
20127
20256
  const errorSuffix = errors.length > 0 ? `, ${errors.length} error(s)` : "";
20128
20257
  return `Refreshed subagents list: found ${totalCount} total (${customCount} custom)${errorSuffix}`;
20129
20258
  }
20130
- validateRequiredParams(args, ["subagent_type", "prompt", "description"], "Task");
20131
- const subagent_type = args.subagent_type;
20259
+ const isDeployingExisting = Boolean(args.agent_id || args.conversation_id);
20260
+ if (isDeployingExisting) {
20261
+ validateRequiredParams(args, ["prompt", "description"], "Task");
20262
+ } else {
20263
+ validateRequiredParams(args, ["subagent_type", "prompt", "description"], "Task");
20264
+ }
20132
20265
  const prompt = args.prompt;
20133
20266
  const description = args.description;
20267
+ const subagent_type = isDeployingExisting ? args.subagent_type || "general-purpose" : args.subagent_type;
20134
20268
  const allConfigs = await getAllSubagentConfigs();
20135
20269
  if (!(subagent_type in allConfigs)) {
20136
20270
  const available = Object.keys(allConfigs).join(", ");
20137
20271
  return `Error: Invalid subagent type "${subagent_type}". Available types: ${available}`;
20138
20272
  }
20273
+ if (isDeployingExisting && !VALID_DEPLOY_TYPES.has(subagent_type)) {
20274
+ return `Error: When deploying an existing agent, subagent_type must be "explore" (read-only) or "general-purpose" (read-write). Got: "${subagent_type}"`;
20275
+ }
20139
20276
  const subagentId = generateSubagentId();
20140
20277
  registerSubagent(subagentId, subagent_type, description, toolCallId);
20141
20278
  try {
20142
- const result = await spawnSubagent(subagent_type, prompt, model, subagentId, signal);
20279
+ const result = await spawnSubagent(subagent_type, prompt, model, subagentId, signal, args.agent_id, args.conversation_id);
20143
20280
  completeSubagent(subagentId, {
20144
20281
  success: result.success,
20145
20282
  error: result.error,
@@ -20150,21 +20287,28 @@ async function task(args) {
20150
20287
  }
20151
20288
  const header = [
20152
20289
  `subagent_type=${subagent_type}`,
20153
- result.agentId ? `agent_id=${result.agentId}` : undefined
20290
+ result.agentId ? `agent_id=${result.agentId}` : undefined,
20291
+ result.conversationId ? `conversation_id=${result.conversationId}` : undefined
20154
20292
  ].filter(Boolean).join(" ");
20155
- return `${header}
20293
+ const fullOutput = `${header}
20156
20294
 
20157
20295
  ${result.report}`;
20296
+ const userCwd = process.env.USER_CWD || process.cwd();
20297
+ const { content: truncatedOutput } = truncateByChars(fullOutput, LIMITS.TASK_OUTPUT_CHARS, "Task", { workingDirectory: userCwd, toolName: "Task" });
20298
+ return truncatedOutput;
20158
20299
  } catch (error) {
20159
20300
  const errorMessage = error instanceof Error ? error.message : String(error);
20160
20301
  completeSubagent(subagentId, { success: false, error: errorMessage });
20161
20302
  return `Error: ${errorMessage}`;
20162
20303
  }
20163
20304
  }
20305
+ var VALID_DEPLOY_TYPES;
20164
20306
  var init_Task2 = __esm(async () => {
20165
20307
  init_subagents();
20166
20308
  init_subagentState();
20309
+ init_truncation();
20167
20310
  await init_manager2();
20311
+ VALID_DEPLOY_TYPES = new Set(["explore", "general-purpose"]);
20168
20312
  });
20169
20313
 
20170
20314
  // src/tools/impl/TodoWrite.ts
@@ -24267,7 +24411,7 @@ var init_manager3 = __esm(async () => {
24267
24411
 
24268
24412
  // src/agent/create.ts
24269
24413
  import { join as join11 } from "node:path";
24270
- async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingModel = "openai/text-embedding-3-small", updateArgs, skillsDirectory, parallelToolCalls = true, enableSleeptime = false, systemPromptPreset, initBlocks, baseTools) {
24414
+ async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingModel, updateArgs, skillsDirectory, parallelToolCalls = true, enableSleeptime = false, systemPromptPreset, initBlocks, baseTools) {
24271
24415
  let options;
24272
24416
  if (typeof nameOrOptions === "object") {
24273
24417
  options = nameOrOptions;
@@ -24286,7 +24430,7 @@ async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingM
24286
24430
  };
24287
24431
  }
24288
24432
  const name = options.name ?? DEFAULT_AGENT_NAME;
24289
- const embeddingModelVal = options.embeddingModel ?? "openai/text-embedding-3-small";
24433
+ const embeddingModelVal = options.embeddingModel;
24290
24434
  const parallelToolCallsVal = options.parallelToolCalls ?? true;
24291
24435
  const enableSleeptimeVal = options.enableSleeptime ?? false;
24292
24436
  let modelHandle;
@@ -24408,7 +24552,7 @@ ${options.systemPromptAppend}`;
24408
24552
  system: systemPromptContent,
24409
24553
  name,
24410
24554
  description: agentDescription,
24411
- embedding: embeddingModelVal,
24555
+ embedding: embeddingModelVal || undefined,
24412
24556
  model: modelHandle,
24413
24557
  context_window_limit: contextWindow,
24414
24558
  tools: toolNames,
@@ -50487,6 +50631,103 @@ var init_auto_update = __esm(() => {
50487
50631
  DEBUG = process.env.LETTA_DEBUG_AUTOUPDATE === "1";
50488
50632
  });
50489
50633
 
50634
+ // src/tools/impl/overflow.ts
50635
+ var exports_overflow = {};
50636
+ __export(exports_overflow, {
50637
+ writeOverflowFile: () => writeOverflowFile2,
50638
+ getOverflowStats: () => getOverflowStats,
50639
+ getOverflowDirectory: () => getOverflowDirectory2,
50640
+ ensureOverflowDirectory: () => ensureOverflowDirectory2,
50641
+ cleanupOldOverflowFiles: () => cleanupOldOverflowFiles,
50642
+ OVERFLOW_CONFIG: () => OVERFLOW_CONFIG2
50643
+ });
50644
+ import { randomUUID as randomUUID2 } from "node:crypto";
50645
+ import * as fs10 from "node:fs";
50646
+ import * as os3 from "node:os";
50647
+ import * as path18 from "node:path";
50648
+ function getOverflowDirectory2(workingDirectory) {
50649
+ const homeDir = os3.homedir();
50650
+ const lettaDir = path18.join(homeDir, ".letta");
50651
+ const normalizedPath = path18.normalize(workingDirectory);
50652
+ const sanitizedPath = normalizedPath.replace(/^[/\\]/, "").replace(/[/\\:]/g, "_").replace(/\s+/g, "_");
50653
+ const overflowDir = path18.join(lettaDir, "projects", sanitizedPath, "agent-tools");
50654
+ return overflowDir;
50655
+ }
50656
+ function ensureOverflowDirectory2(workingDirectory) {
50657
+ const overflowDir = getOverflowDirectory2(workingDirectory);
50658
+ if (!fs10.existsSync(overflowDir)) {
50659
+ fs10.mkdirSync(overflowDir, { recursive: true });
50660
+ }
50661
+ return overflowDir;
50662
+ }
50663
+ function writeOverflowFile2(content, workingDirectory, toolName) {
50664
+ const overflowDir = ensureOverflowDirectory2(workingDirectory);
50665
+ const uuid = randomUUID2();
50666
+ const filename = toolName ? `${toolName.toLowerCase()}-${uuid}.txt` : `${uuid}.txt`;
50667
+ const filePath = path18.join(overflowDir, filename);
50668
+ fs10.writeFileSync(filePath, content, "utf-8");
50669
+ return filePath;
50670
+ }
50671
+ function cleanupOldOverflowFiles(workingDirectory, maxAgeMs = 24 * 60 * 60 * 1000) {
50672
+ const overflowDir = getOverflowDirectory2(workingDirectory);
50673
+ if (!fs10.existsSync(overflowDir)) {
50674
+ return 0;
50675
+ }
50676
+ let files;
50677
+ try {
50678
+ files = fs10.readdirSync(overflowDir);
50679
+ } catch {
50680
+ return 0;
50681
+ }
50682
+ const now = Date.now();
50683
+ let deletedCount = 0;
50684
+ for (const file of files) {
50685
+ const filePath = path18.join(overflowDir, file);
50686
+ try {
50687
+ const stats = fs10.statSync(filePath);
50688
+ if (stats.isDirectory()) {
50689
+ continue;
50690
+ }
50691
+ if (now - stats.mtimeMs > maxAgeMs) {
50692
+ fs10.unlinkSync(filePath);
50693
+ deletedCount++;
50694
+ }
50695
+ } catch {}
50696
+ }
50697
+ return deletedCount;
50698
+ }
50699
+ function getOverflowStats(workingDirectory) {
50700
+ const overflowDir = getOverflowDirectory2(workingDirectory);
50701
+ if (!fs10.existsSync(overflowDir)) {
50702
+ return {
50703
+ directory: overflowDir,
50704
+ exists: false,
50705
+ fileCount: 0,
50706
+ totalSize: 0
50707
+ };
50708
+ }
50709
+ const files = fs10.readdirSync(overflowDir);
50710
+ let totalSize = 0;
50711
+ for (const file of files) {
50712
+ const filePath = path18.join(overflowDir, file);
50713
+ const stats = fs10.statSync(filePath);
50714
+ totalSize += stats.size;
50715
+ }
50716
+ return {
50717
+ directory: overflowDir,
50718
+ exists: true,
50719
+ fileCount: files.length,
50720
+ totalSize
50721
+ };
50722
+ }
50723
+ var OVERFLOW_CONFIG2;
50724
+ var init_overflow2 = __esm(() => {
50725
+ OVERFLOW_CONFIG2 = {
50726
+ ENABLED: process.env.LETTA_TOOL_OVERFLOW_TO_FILE?.toLowerCase() !== "false",
50727
+ MIDDLE_TRUNCATE: process.env.LETTA_TOOL_MIDDLE_TRUNCATE?.toLowerCase() !== "false"
50728
+ };
50729
+ });
50730
+
50490
50731
  // src/agent/promptAssets.ts
50491
50732
  var exports_promptAssets2 = {};
50492
50733
  __export(exports_promptAssets2, {
@@ -50620,9 +50861,9 @@ __export(exports_subagents2, {
50620
50861
  GLOBAL_AGENTS_DIR: () => GLOBAL_AGENTS_DIR2,
50621
50862
  AGENTS_DIR: () => AGENTS_DIR2
50622
50863
  });
50623
- import { existsSync as existsSync8 } from "node:fs";
50864
+ import { existsSync as existsSync9 } from "node:fs";
50624
50865
  import { readdir as readdir6, readFile as readFile7 } from "node:fs/promises";
50625
- import { join as join15 } from "node:path";
50866
+ import { join as join16 } from "node:path";
50626
50867
  function isValidName2(name) {
50627
50868
  return /^[a-z][a-z0-9-]*$/.test(name);
50628
50869
  }
@@ -50704,7 +50945,7 @@ function getBuiltinSubagentNames2() {
50704
50945
  return new Set(Object.keys(getBuiltinSubagents2()));
50705
50946
  }
50706
50947
  async function discoverSubagentsFromDir2(agentsDir, seenNames, subagents, errors) {
50707
- if (!existsSync8(agentsDir)) {
50948
+ if (!existsSync9(agentsDir)) {
50708
50949
  return;
50709
50950
  }
50710
50951
  try {
@@ -50713,7 +50954,7 @@ async function discoverSubagentsFromDir2(agentsDir, seenNames, subagents, errors
50713
50954
  if (!entry.isFile() || !entry.name.endsWith(".md")) {
50714
50955
  continue;
50715
50956
  }
50716
- const filePath = join15(agentsDir, entry.name);
50957
+ const filePath = join16(agentsDir, entry.name);
50717
50958
  try {
50718
50959
  const config = await parseSubagentFile2(filePath);
50719
50960
  if (config) {
@@ -50745,7 +50986,7 @@ async function discoverSubagents2(workingDirectory = process.cwd()) {
50745
50986
  const subagents = [];
50746
50987
  const seenNames = new Set;
50747
50988
  await discoverSubagentsFromDir2(GLOBAL_AGENTS_DIR2, seenNames, subagents, errors);
50748
- const projectAgentsDir = join15(workingDirectory, AGENTS_DIR2);
50989
+ const projectAgentsDir = join16(workingDirectory, AGENTS_DIR2);
50749
50990
  await discoverSubagentsFromDir2(projectAgentsDir, seenNames, subagents, errors);
50750
50991
  return { subagents, errors };
50751
50992
  }
@@ -50784,7 +51025,7 @@ var init_subagents2 = __esm(() => {
50784
51025
  plan_default,
50785
51026
  recall_default
50786
51027
  ];
50787
- GLOBAL_AGENTS_DIR2 = join15(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents");
51028
+ GLOBAL_AGENTS_DIR2 = join16(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents");
50788
51029
  VALID_MEMORY_BLOCKS2 = new Set(MEMORY_BLOCK_LABELS);
50789
51030
  cache4 = {
50790
51031
  builtins: null,
@@ -50794,10 +51035,10 @@ var init_subagents2 = __esm(() => {
50794
51035
  });
50795
51036
 
50796
51037
  // node_modules/is-docker/index.js
50797
- import fs10 from "node:fs";
51038
+ import fs11 from "node:fs";
50798
51039
  function hasDockerEnv() {
50799
51040
  try {
50800
- fs10.statSync("/.dockerenv");
51041
+ fs11.statSync("/.dockerenv");
50801
51042
  return true;
50802
51043
  } catch {
50803
51044
  return false;
@@ -50805,7 +51046,7 @@ function hasDockerEnv() {
50805
51046
  }
50806
51047
  function hasDockerCGroup() {
50807
51048
  try {
50808
- return fs10.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
51049
+ return fs11.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
50809
51050
  } catch {
50810
51051
  return false;
50811
51052
  }
@@ -50820,7 +51061,7 @@ var isDockerCached;
50820
51061
  var init_is_docker = () => {};
50821
51062
 
50822
51063
  // node_modules/is-inside-container/index.js
50823
- import fs11 from "node:fs";
51064
+ import fs12 from "node:fs";
50824
51065
  function isInsideContainer() {
50825
51066
  if (cachedResult === undefined) {
50826
51067
  cachedResult = hasContainerEnv() || isDocker();
@@ -50829,7 +51070,7 @@ function isInsideContainer() {
50829
51070
  }
50830
51071
  var cachedResult, hasContainerEnv = () => {
50831
51072
  try {
50832
- fs11.statSync("/run/.containerenv");
51073
+ fs12.statSync("/run/.containerenv");
50833
51074
  return true;
50834
51075
  } catch {
50835
51076
  return false;
@@ -50841,20 +51082,20 @@ var init_is_inside_container = __esm(() => {
50841
51082
 
50842
51083
  // node_modules/is-wsl/index.js
50843
51084
  import process13 from "node:process";
50844
- import os3 from "node:os";
50845
- import fs12 from "node:fs";
51085
+ import os4 from "node:os";
51086
+ import fs13 from "node:fs";
50846
51087
  var isWsl = () => {
50847
51088
  if (process13.platform !== "linux") {
50848
51089
  return false;
50849
51090
  }
50850
- if (os3.release().toLowerCase().includes("microsoft")) {
51091
+ if (os4.release().toLowerCase().includes("microsoft")) {
50851
51092
  if (isInsideContainer()) {
50852
51093
  return false;
50853
51094
  }
50854
51095
  return true;
50855
51096
  }
50856
51097
  try {
50857
- return fs12.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isInsideContainer() : false;
51098
+ return fs13.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isInsideContainer() : false;
50858
51099
  } catch {
50859
51100
  return false;
50860
51101
  }
@@ -50866,7 +51107,7 @@ var init_is_wsl = __esm(() => {
50866
51107
 
50867
51108
  // node_modules/wsl-utils/index.js
50868
51109
  import process14 from "node:process";
50869
- import fs13, { constants as fsConstants } from "node:fs/promises";
51110
+ import fs14, { constants as fsConstants } from "node:fs/promises";
50870
51111
  var wslDrivesMountPoint, powerShellPathFromWsl = async () => {
50871
51112
  const mountPoint = await wslDrivesMountPoint();
50872
51113
  return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
@@ -50889,13 +51130,13 @@ var init_wsl_utils = __esm(() => {
50889
51130
  const configFilePath = "/etc/wsl.conf";
50890
51131
  let isConfigFileExists = false;
50891
51132
  try {
50892
- await fs13.access(configFilePath, fsConstants.F_OK);
51133
+ await fs14.access(configFilePath, fsConstants.F_OK);
50893
51134
  isConfigFileExists = true;
50894
51135
  } catch {}
50895
51136
  if (!isConfigFileExists) {
50896
51137
  return defaultMountPoint;
50897
51138
  }
50898
- const configContent = await fs13.readFile(configFilePath, { encoding: "utf8" });
51139
+ const configContent = await fs14.readFile(configFilePath, { encoding: "utf8" });
50899
51140
  const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
50900
51141
  if (!configMountPoint) {
50901
51142
  return defaultMountPoint;
@@ -51049,11 +51290,11 @@ __export(exports_open, {
51049
51290
  });
51050
51291
  import process18 from "node:process";
51051
51292
  import { Buffer as Buffer3 } from "node:buffer";
51052
- import path18 from "node:path";
51293
+ import path19 from "node:path";
51053
51294
  import { fileURLToPath as fileURLToPath8 } from "node:url";
51054
51295
  import { promisify as promisify8 } from "node:util";
51055
51296
  import childProcess from "node:child_process";
51056
- import fs14, { constants as fsConstants2 } from "node:fs/promises";
51297
+ import fs15, { constants as fsConstants2 } from "node:fs/promises";
51057
51298
  async function getWindowsDefaultBrowserFromWsl() {
51058
51299
  const powershellPath = await powerShellPath();
51059
51300
  const rawCommand = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
@@ -51210,7 +51451,7 @@ var execFile7, __dirname2, localXdgOpenPath, platform2, arch, pTryEach = async (
51210
51451
  const isBundled = !__dirname2 || __dirname2 === "/";
51211
51452
  let exeLocalXdgOpen = false;
51212
51453
  try {
51213
- await fs14.access(localXdgOpenPath, fsConstants2.X_OK);
51454
+ await fs15.access(localXdgOpenPath, fsConstants2.X_OK);
51214
51455
  exeLocalXdgOpen = true;
51215
51456
  } catch {}
51216
51457
  const useSystemXdgOpen = process18.versions.electron ?? (platform2 === "android" || isBundled || !exeLocalXdgOpen);
@@ -51274,8 +51515,8 @@ var init_open = __esm(() => {
51274
51515
  init_default_browser();
51275
51516
  init_is_inside_container();
51276
51517
  execFile7 = promisify8(childProcess.execFile);
51277
- __dirname2 = path18.dirname(fileURLToPath8(import.meta.url));
51278
- localXdgOpenPath = path18.join(__dirname2, "xdg-open");
51518
+ __dirname2 = path19.dirname(fileURLToPath8(import.meta.url));
51519
+ localXdgOpenPath = path19.join(__dirname2, "xdg-open");
51279
51520
  ({ platform: platform2, arch } = process18);
51280
51521
  apps = {};
51281
51522
  defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
@@ -52998,7 +53239,7 @@ __export(exports_approval_execution, {
52998
53239
  executeAutoAllowedTools: () => executeAutoAllowedTools,
52999
53240
  executeApprovalBatch: () => executeApprovalBatch
53000
53241
  });
53001
- import * as path19 from "node:path";
53242
+ import * as path20 from "node:path";
53002
53243
  function isParallelSafe(toolName) {
53003
53244
  return PARALLEL_SAFE_TOOLS.has(toolName);
53004
53245
  }
@@ -53010,7 +53251,7 @@ function getResourceKey(toolName, toolArgs) {
53010
53251
  const filePath = toolArgs.file_path;
53011
53252
  if (typeof filePath === "string") {
53012
53253
  const userCwd = process.env.USER_CWD || process.cwd();
53013
- return path19.isAbsolute(filePath) ? path19.normalize(filePath) : path19.resolve(userCwd, filePath);
53254
+ return path20.isAbsolute(filePath) ? path20.normalize(filePath) : path20.resolve(userCwd, filePath);
53014
53255
  }
53015
53256
  }
53016
53257
  return "__global__";
@@ -53281,7 +53522,8 @@ async function handleHeadlessCommand(argv, model, skillsDirectory) {
53281
53522
  sleeptime: { type: "boolean" },
53282
53523
  "init-blocks": { type: "string" },
53283
53524
  "base-tools": { type: "string" },
53284
- "from-af": { type: "string" }
53525
+ "from-af": { type: "string" },
53526
+ "no-skills": { type: "boolean" }
53285
53527
  },
53286
53528
  strict: false,
53287
53529
  allowPositionals: true
@@ -53596,7 +53838,18 @@ Usage: letta -p "..." --new-agent`);
53596
53838
  }
53597
53839
  }
53598
53840
  let conversationId;
53599
- const isolatedBlockLabels = initBlocks === undefined ? [...ISOLATED_BLOCK_LABELS] : ISOLATED_BLOCK_LABELS.filter((label) => initBlocks.includes(label));
53841
+ const noSkillsFlag = values["no-skills"];
53842
+ const isSubagent = process.env.LETTA_CODE_AGENT_ROLE === "subagent";
53843
+ if (!noSkillsFlag && !isSubagent) {
53844
+ const createdBlocks = await ensureSkillsBlocks(agent.id);
53845
+ if (createdBlocks.length > 0) {
53846
+ console.log("Created missing skills blocks for agent compatibility");
53847
+ }
53848
+ }
53849
+ let isolatedBlockLabels = [];
53850
+ if (!noSkillsFlag) {
53851
+ isolatedBlockLabels = initBlocks === undefined ? [...ISOLATED_BLOCK_LABELS] : ISOLATED_BLOCK_LABELS.filter((label) => initBlocks.includes(label));
53852
+ }
53600
53853
  if (specifiedConversationId) {
53601
53854
  if (specifiedConversationId === "default") {
53602
53855
  conversationId = "default";
@@ -53642,7 +53895,6 @@ Usage: letta -p "..." --new-agent`);
53642
53895
  conversationId = conversation.id;
53643
53896
  }
53644
53897
  markMilestone("HEADLESS_CONVERSATION_READY");
53645
- const isSubagent = process.env.LETTA_CODE_AGENT_ROLE === "subagent";
53646
53898
  if (!isSubagent) {
53647
53899
  await settingsManager.loadLocalProjectSettings();
53648
53900
  settingsManager.setLocalLastSession({ agentId: agent.id, conversationId }, process.cwd());
@@ -53651,24 +53903,22 @@ Usage: letta -p "..." --new-agent`);
53651
53903
  conversationId
53652
53904
  });
53653
53905
  }
53654
- const createdBlocks = await ensureSkillsBlocks(agent.id);
53655
- if (createdBlocks.length > 0) {
53656
- console.log("Created missing skills blocks for agent compatibility");
53657
- }
53658
53906
  setAgentContext2(agent.id, skillsDirectory);
53659
- initializeLoadedSkillsFlag2().catch(() => {});
53660
- (async () => {
53661
- try {
53662
- const { syncSkillsToAgent: syncSkillsToAgent3, SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills2(), exports_skills));
53663
- const { join: join16 } = await import("node:path");
53664
- const resolvedSkillsDirectory = skillsDirectory || join16(process.cwd(), SKILLS_DIR3);
53665
- await syncSkillsToAgent3(client, agent.id, resolvedSkillsDirectory, {
53666
- skipIfUnchanged: true
53667
- });
53668
- } catch (error) {
53669
- console.warn(`[skills] Background sync failed: ${error instanceof Error ? error.message : String(error)}`);
53670
- }
53671
- })();
53907
+ if (!noSkillsFlag && !isSubagent) {
53908
+ initializeLoadedSkillsFlag2().catch(() => {});
53909
+ (async () => {
53910
+ try {
53911
+ const { syncSkillsToAgent: syncSkillsToAgent3, SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills2(), exports_skills));
53912
+ const { join: join17 } = await import("node:path");
53913
+ const resolvedSkillsDirectory = skillsDirectory || join17(process.cwd(), SKILLS_DIR3);
53914
+ await syncSkillsToAgent3(client, agent.id, resolvedSkillsDirectory, {
53915
+ skipIfUnchanged: true
53916
+ });
53917
+ } catch (error) {
53918
+ console.warn(`[skills] Background sync failed: ${error instanceof Error ? error.message : String(error)}`);
53919
+ }
53920
+ })();
53921
+ }
53672
53922
  const outputFormat = values["output-format"] || "text";
53673
53923
  const includePartialMessages = Boolean(values["include-partial-messages"]);
53674
53924
  if (!["text", "json", "stream-json"].includes(outputFormat)) {
@@ -54607,7 +54857,7 @@ __export(exports_kittyProtocolDetector, {
54607
54857
  isKittyProtocolEnabled: () => isKittyProtocolEnabled,
54608
54858
  detectAndEnableKittyProtocol: () => detectAndEnableKittyProtocol
54609
54859
  });
54610
- import * as fs15 from "node:fs";
54860
+ import * as fs16 from "node:fs";
54611
54861
  async function detectAndEnableKittyProtocol() {
54612
54862
  if (detectionComplete) {
54613
54863
  return;
@@ -54680,7 +54930,7 @@ async function detectAndEnableKittyProtocol() {
54680
54930
  if (DEBUG2) {
54681
54931
  console.error("[kitty] querying support");
54682
54932
  }
54683
- fs15.writeSync(process.stdout.fd, "\x1B[?u\x1B[c");
54933
+ fs16.writeSync(process.stdout.fd, "\x1B[?u\x1B[c");
54684
54934
  timeoutId = setTimeout(finish, 200);
54685
54935
  });
54686
54936
  }
@@ -54689,14 +54939,14 @@ function isKittyProtocolEnabled() {
54689
54939
  }
54690
54940
  function enableKittyKeyboardProtocol() {
54691
54941
  try {
54692
- fs15.writeSync(process.stdout.fd, "\x1B[>1u");
54942
+ fs16.writeSync(process.stdout.fd, "\x1B[>1u");
54693
54943
  kittyEnabled = true;
54694
54944
  } catch {}
54695
54945
  }
54696
54946
  function disableKittyKeyboardProtocol() {
54697
54947
  try {
54698
54948
  if (kittyEnabled) {
54699
- fs15.writeSync(process.stdout.fd, "\x1B[<u");
54949
+ fs16.writeSync(process.stdout.fd, "\x1B[<u");
54700
54950
  kittyEnabled = false;
54701
54951
  }
54702
54952
  } catch {}
@@ -54928,10 +55178,10 @@ __export(exports_settings, {
54928
55178
  loadProjectSettings: () => loadProjectSettings,
54929
55179
  getSetting: () => getSetting
54930
55180
  });
54931
- import { homedir as homedir9 } from "node:os";
54932
- import { join as join16 } from "node:path";
55181
+ import { homedir as homedir10 } from "node:os";
55182
+ import { join as join17 } from "node:path";
54933
55183
  function getSettingsPath() {
54934
- return join16(homedir9(), ".letta", "settings.json");
55184
+ return join17(homedir10(), ".letta", "settings.json");
54935
55185
  }
54936
55186
  async function loadSettings() {
54937
55187
  const settingsPath = getSettingsPath();
@@ -54968,7 +55218,7 @@ async function getSetting(key) {
54968
55218
  return settings[key];
54969
55219
  }
54970
55220
  function getProjectSettingsPath() {
54971
- return join16(process.cwd(), ".letta", "settings.local.json");
55221
+ return join17(process.cwd(), ".letta", "settings.local.json");
54972
55222
  }
54973
55223
  async function loadProjectSettings() {
54974
55224
  const settingsPath = getProjectSettingsPath();
@@ -54986,7 +55236,7 @@ async function loadProjectSettings() {
54986
55236
  }
54987
55237
  async function saveProjectSettings(settings) {
54988
55238
  const settingsPath = getProjectSettingsPath();
54989
- const dirPath = join16(process.cwd(), ".letta");
55239
+ const dirPath = join17(process.cwd(), ".letta");
54990
55240
  try {
54991
55241
  if (!exists(dirPath)) {
54992
55242
  await mkdir(dirPath, { recursive: true });
@@ -56157,7 +56407,7 @@ function parsePatchOperations(input) {
56157
56407
  continue;
56158
56408
  }
56159
56409
  if (line.startsWith("*** Add File:")) {
56160
- const path20 = line.replace("*** Add File:", "").trim();
56410
+ const path21 = line.replace("*** Add File:", "").trim();
56161
56411
  i++;
56162
56412
  const contentLines = [];
56163
56413
  const patchLines = [];
@@ -56173,7 +56423,7 @@ function parsePatchOperations(input) {
56173
56423
  }
56174
56424
  operations.push({
56175
56425
  kind: "add",
56176
- path: path20,
56426
+ path: path21,
56177
56427
  content: contentLines.join(`
56178
56428
  `),
56179
56429
  patchLines
@@ -56181,7 +56431,7 @@ function parsePatchOperations(input) {
56181
56431
  continue;
56182
56432
  }
56183
56433
  if (line.startsWith("*** Update File:")) {
56184
- const path20 = line.replace("*** Update File:", "").trim();
56434
+ const path21 = line.replace("*** Update File:", "").trim();
56185
56435
  i++;
56186
56436
  if (i < stopIdx && lines[i]?.startsWith("*** Move to:")) {
56187
56437
  i++;
@@ -56217,7 +56467,7 @@ function parsePatchOperations(input) {
56217
56467
  }
56218
56468
  operations.push({
56219
56469
  kind: "update",
56220
- path: path20,
56470
+ path: path21,
56221
56471
  oldString: oldParts.join(`
56222
56472
  `),
56223
56473
  newString: newParts.join(`
@@ -56227,8 +56477,8 @@ function parsePatchOperations(input) {
56227
56477
  continue;
56228
56478
  }
56229
56479
  if (line.startsWith("*** Delete File:")) {
56230
- const path20 = line.replace("*** Delete File:", "").trim();
56231
- operations.push({ kind: "delete", path: path20 });
56480
+ const path21 = line.replace("*** Delete File:", "").trim();
56481
+ operations.push({ kind: "delete", path: path21 });
56232
56482
  i++;
56233
56483
  continue;
56234
56484
  }
@@ -56460,16 +56710,16 @@ class Diff {
56460
56710
  }
56461
56711
  }
56462
56712
  }
56463
- addToPath(path20, added, removed, oldPosInc, options) {
56464
- const last = path20.lastComponent;
56713
+ addToPath(path21, added, removed, oldPosInc, options) {
56714
+ const last = path21.lastComponent;
56465
56715
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
56466
56716
  return {
56467
- oldPos: path20.oldPos + oldPosInc,
56717
+ oldPos: path21.oldPos + oldPosInc,
56468
56718
  lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
56469
56719
  };
56470
56720
  } else {
56471
56721
  return {
56472
- oldPos: path20.oldPos + oldPosInc,
56722
+ oldPos: path21.oldPos + oldPosInc,
56473
56723
  lastComponent: { count: 1, added, removed, previousComponent: last }
56474
56724
  };
56475
56725
  }
@@ -58206,9 +58456,9 @@ function getFileEditHeader(toolName, toolArgs) {
58206
58456
  const relPath = relative4(cwd2, filePath);
58207
58457
  const displayPath = relPath.startsWith("..") ? filePath : relPath;
58208
58458
  if (t === "write" || t === "write_file" || t === "writefile" || t === "write_file_gemini" || t === "writefilegemini") {
58209
- const { existsSync: existsSync9 } = __require("node:fs");
58459
+ const { existsSync: existsSync10 } = __require("node:fs");
58210
58460
  try {
58211
- if (existsSync9(filePath)) {
58461
+ if (existsSync10(filePath)) {
58212
58462
  return `Overwrite ${displayPath}?`;
58213
58463
  }
58214
58464
  } catch {}
@@ -58891,9 +59141,9 @@ function getHeaderText(fileEdit) {
58891
59141
  const relPath = relative4(cwd2, fileEdit.filePath);
58892
59142
  const displayPath = relPath.startsWith("..") ? fileEdit.filePath : relPath;
58893
59143
  if (t === "write" || t === "write_file" || t === "writefile" || t === "write_file_gemini" || t === "writefilegemini") {
58894
- const { existsSync: existsSync9 } = __require("node:fs");
59144
+ const { existsSync: existsSync10 } = __require("node:fs");
58895
59145
  try {
58896
- if (existsSync9(fileEdit.filePath)) {
59146
+ if (existsSync10(fileEdit.filePath)) {
58897
59147
  return `Overwrite ${displayPath}?`;
58898
59148
  }
58899
59149
  } catch {}
@@ -60568,7 +60818,7 @@ var init_ApprovalSwitch = __esm(async () => {
60568
60818
  });
60569
60819
 
60570
60820
  // src/cli/components/AssistantMessageRich.tsx
60571
- var import_react43, jsx_dev_runtime21, normalize4 = (s) => s.replace(/\r\n/g, `
60821
+ var import_react43, jsx_dev_runtime21, normalize5 = (s) => s.replace(/\r\n/g, `
60572
60822
  `).replace(/[ \t]+$/gm, "").replace(/\n{3,}/g, `
60573
60823
 
60574
60824
  `).replace(/^\n+|\n+$/g, ""), AssistantMessage;
@@ -60583,7 +60833,7 @@ var init_AssistantMessageRich = __esm(async () => {
60583
60833
  AssistantMessage = import_react43.memo(({ line }) => {
60584
60834
  const columns = useTerminalWidth();
60585
60835
  const contentWidth = Math.max(0, columns - 2);
60586
- const normalizedText = normalize4(line.text);
60836
+ const normalizedText = normalize5(line.text);
60587
60837
  return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
60588
60838
  flexDirection: "row",
60589
60839
  children: [
@@ -61802,7 +62052,7 @@ var init_pasteRegistry = __esm(() => {
61802
62052
 
61803
62053
  // src/cli/helpers/clipboard.ts
61804
62054
  import { execFileSync as execFileSync2 } from "node:child_process";
61805
- import { existsSync as existsSync9, readFileSync as readFileSync2, statSync as statSync2 } from "node:fs";
62055
+ import { existsSync as existsSync10, readFileSync as readFileSync2, statSync as statSync3 } from "node:fs";
61806
62056
  import { basename as basename2, extname as extname3, isAbsolute as isAbsolute12, resolve as resolve18 } from "node:path";
61807
62057
  function countLines2(text) {
61808
62058
  return (text.match(/\r\n|\r|\n/g) || []).length + 1;
@@ -61853,7 +62103,7 @@ function translatePasteForImages(paste) {
61853
62103
  if (!isAbsolute12(filePath))
61854
62104
  filePath = resolve18(process.cwd(), filePath);
61855
62105
  const ext3 = extname3(filePath || "").toLowerCase();
61856
- if (IMAGE_EXTS.has(ext3) && existsSync9(filePath) && statSync2(filePath).isFile()) {
62106
+ if (IMAGE_EXTS.has(ext3) && existsSync10(filePath) && statSync3(filePath).isFile()) {
61857
62107
  const buf = readFileSync2(filePath);
61858
62108
  const b64 = buf.toString("base64");
61859
62109
  const mt = ext3 === ".png" ? "image/png" : ext3 === ".jpg" || ext3 === ".jpeg" ? "image/jpeg" : ext3 === ".gif" ? "image/gif" : ext3 === ".webp" ? "image/webp" : ext3 === ".bmp" ? "image/bmp" : ext3 === ".svg" ? "image/svg+xml" : ext3 === ".tif" || ext3 === ".tiff" ? "image/tiff" : ext3 === ".heic" ? "image/heic" : ext3 === ".heif" ? "image/heif" : ext3 === ".avif" ? "image/avif" : "application/octet-stream";
@@ -62441,13 +62691,13 @@ __export(exports_terminalKeybindingInstaller, {
62441
62691
  });
62442
62692
  import {
62443
62693
  copyFileSync,
62444
- existsSync as existsSync10,
62445
- mkdirSync as mkdirSync4,
62694
+ existsSync as existsSync11,
62695
+ mkdirSync as mkdirSync5,
62446
62696
  readFileSync as readFileSync3,
62447
- writeFileSync as writeFileSync2
62697
+ writeFileSync as writeFileSync3
62448
62698
  } from "node:fs";
62449
- import { homedir as homedir10, platform as platform3 } from "node:os";
62450
- import { dirname as dirname10, join as join17 } from "node:path";
62699
+ import { homedir as homedir11, platform as platform3 } from "node:os";
62700
+ import { dirname as dirname10, join as join18 } from "node:path";
62451
62701
  function detectTerminalType() {
62452
62702
  if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
62453
62703
  return "cursor";
@@ -62477,18 +62727,18 @@ function getKeybindingsPath(terminal) {
62477
62727
  cursor: "Cursor",
62478
62728
  windsurf: "Windsurf"
62479
62729
  }[terminal];
62480
- const os4 = platform3();
62481
- if (os4 === "darwin") {
62482
- return join17(homedir10(), "Library", "Application Support", appName, "User", "keybindings.json");
62730
+ const os5 = platform3();
62731
+ if (os5 === "darwin") {
62732
+ return join18(homedir11(), "Library", "Application Support", appName, "User", "keybindings.json");
62483
62733
  }
62484
- if (os4 === "win32") {
62734
+ if (os5 === "win32") {
62485
62735
  const appData = process.env.APPDATA;
62486
62736
  if (!appData)
62487
62737
  return null;
62488
- return join17(appData, appName, "User", "keybindings.json");
62738
+ return join18(appData, appName, "User", "keybindings.json");
62489
62739
  }
62490
- if (os4 === "linux") {
62491
- return join17(homedir10(), ".config", appName, "User", "keybindings.json");
62740
+ if (os5 === "linux") {
62741
+ return join18(homedir11(), ".config", appName, "User", "keybindings.json");
62492
62742
  }
62493
62743
  return null;
62494
62744
  }
@@ -62510,7 +62760,7 @@ function parseKeybindings(content) {
62510
62760
  }
62511
62761
  }
62512
62762
  function keybindingExists(keybindingsPath) {
62513
- if (!existsSync10(keybindingsPath))
62763
+ if (!existsSync11(keybindingsPath))
62514
62764
  return false;
62515
62765
  try {
62516
62766
  const content = readFileSync3(keybindingsPath, { encoding: "utf-8" });
@@ -62523,7 +62773,7 @@ function keybindingExists(keybindingsPath) {
62523
62773
  }
62524
62774
  }
62525
62775
  function createBackup(keybindingsPath) {
62526
- if (!existsSync10(keybindingsPath))
62776
+ if (!existsSync11(keybindingsPath))
62527
62777
  return null;
62528
62778
  const backupPath = `${keybindingsPath}.letta-backup`;
62529
62779
  try {
@@ -62539,12 +62789,12 @@ function installKeybinding(keybindingsPath) {
62539
62789
  return { success: true, alreadyExists: true };
62540
62790
  }
62541
62791
  const parentDir = dirname10(keybindingsPath);
62542
- if (!existsSync10(parentDir)) {
62543
- mkdirSync4(parentDir, { recursive: true });
62792
+ if (!existsSync11(parentDir)) {
62793
+ mkdirSync5(parentDir, { recursive: true });
62544
62794
  }
62545
62795
  let keybindings = [];
62546
62796
  let backupPath = null;
62547
- if (existsSync10(keybindingsPath)) {
62797
+ if (existsSync11(keybindingsPath)) {
62548
62798
  backupPath = createBackup(keybindingsPath);
62549
62799
  const content = readFileSync3(keybindingsPath, { encoding: "utf-8" });
62550
62800
  const parsed = parseKeybindings(content);
@@ -62559,7 +62809,7 @@ function installKeybinding(keybindingsPath) {
62559
62809
  keybindings.push(SHIFT_ENTER_KEYBINDING);
62560
62810
  const newContent = `${JSON.stringify(keybindings, null, 2)}
62561
62811
  `;
62562
- writeFileSync2(keybindingsPath, newContent, { encoding: "utf-8" });
62812
+ writeFileSync3(keybindingsPath, newContent, { encoding: "utf-8" });
62563
62813
  return {
62564
62814
  success: true,
62565
62815
  backupPath: backupPath ?? undefined
@@ -62574,7 +62824,7 @@ function installKeybinding(keybindingsPath) {
62574
62824
  }
62575
62825
  function removeKeybinding(keybindingsPath) {
62576
62826
  try {
62577
- if (!existsSync10(keybindingsPath)) {
62827
+ if (!existsSync11(keybindingsPath)) {
62578
62828
  return { success: true };
62579
62829
  }
62580
62830
  const content = readFileSync3(keybindingsPath, { encoding: "utf-8" });
@@ -62588,7 +62838,7 @@ function removeKeybinding(keybindingsPath) {
62588
62838
  const filtered = keybindings.filter((kb) => !(kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus")));
62589
62839
  const newContent = `${JSON.stringify(filtered, null, 2)}
62590
62840
  `;
62591
- writeFileSync2(keybindingsPath, newContent, { encoding: "utf-8" });
62841
+ writeFileSync3(keybindingsPath, newContent, { encoding: "utf-8" });
62592
62842
  return { success: true };
62593
62843
  } catch (error) {
62594
62844
  const message = error instanceof Error ? error.message : String(error);
@@ -62606,14 +62856,14 @@ function installKeybindingForCurrentTerminal() {
62606
62856
  error: "Not running in a VS Code-like terminal"
62607
62857
  };
62608
62858
  }
62609
- const path20 = getKeybindingsPath(terminal);
62610
- if (!path20) {
62859
+ const path21 = getKeybindingsPath(terminal);
62860
+ if (!path21) {
62611
62861
  return {
62612
62862
  success: false,
62613
62863
  error: `Could not determine keybindings.json path for ${terminal}`
62614
62864
  };
62615
62865
  }
62616
- return installKeybinding(path20);
62866
+ return installKeybinding(path21);
62617
62867
  }
62618
62868
  function removeKeybindingForCurrentTerminal() {
62619
62869
  const terminal = detectTerminalType();
@@ -62623,14 +62873,14 @@ function removeKeybindingForCurrentTerminal() {
62623
62873
  error: "Not running in a VS Code-like terminal"
62624
62874
  };
62625
62875
  }
62626
- const path20 = getKeybindingsPath(terminal);
62627
- if (!path20) {
62876
+ const path21 = getKeybindingsPath(terminal);
62877
+ if (!path21) {
62628
62878
  return {
62629
62879
  success: false,
62630
62880
  error: `Could not determine keybindings.json path for ${terminal}`
62631
62881
  };
62632
62882
  }
62633
- return removeKeybinding(path20);
62883
+ return removeKeybinding(path21);
62634
62884
  }
62635
62885
  function isWezTerm() {
62636
62886
  return process.env.TERM_PROGRAM === "WezTerm";
@@ -62641,17 +62891,17 @@ function getWezTermConfigPath() {
62641
62891
  }
62642
62892
  const xdgConfig = process.env.XDG_CONFIG_HOME;
62643
62893
  if (xdgConfig) {
62644
- const xdgPath = join17(xdgConfig, "wezterm", "wezterm.lua");
62645
- if (existsSync10(xdgPath))
62894
+ const xdgPath = join18(xdgConfig, "wezterm", "wezterm.lua");
62895
+ if (existsSync11(xdgPath))
62646
62896
  return xdgPath;
62647
62897
  }
62648
- const configPath = join17(homedir10(), ".config", "wezterm", "wezterm.lua");
62649
- if (existsSync10(configPath))
62898
+ const configPath = join18(homedir11(), ".config", "wezterm", "wezterm.lua");
62899
+ if (existsSync11(configPath))
62650
62900
  return configPath;
62651
- return join17(homedir10(), ".wezterm.lua");
62901
+ return join18(homedir11(), ".wezterm.lua");
62652
62902
  }
62653
62903
  function wezTermDeleteFixExists(configPath) {
62654
- if (!existsSync10(configPath))
62904
+ if (!existsSync11(configPath))
62655
62905
  return false;
62656
62906
  try {
62657
62907
  const content = readFileSync3(configPath, { encoding: "utf-8" });
@@ -62668,7 +62918,7 @@ function installWezTermDeleteFix() {
62668
62918
  }
62669
62919
  let content = "";
62670
62920
  let backupPath = null;
62671
- if (existsSync10(configPath)) {
62921
+ if (existsSync11(configPath)) {
62672
62922
  backupPath = `${configPath}.letta-backup`;
62673
62923
  copyFileSync(configPath, backupPath);
62674
62924
  content = readFileSync3(configPath, { encoding: "utf-8" });
@@ -62698,10 +62948,10 @@ ${WEZTERM_DELETE_FIX}
62698
62948
  `;
62699
62949
  }
62700
62950
  const parentDir = dirname10(configPath);
62701
- if (!existsSync10(parentDir)) {
62702
- mkdirSync4(parentDir, { recursive: true });
62951
+ if (!existsSync11(parentDir)) {
62952
+ mkdirSync5(parentDir, { recursive: true });
62703
62953
  }
62704
- writeFileSync2(configPath, content, { encoding: "utf-8" });
62954
+ writeFileSync3(configPath, content, { encoding: "utf-8" });
62705
62955
  return {
62706
62956
  success: true,
62707
62957
  backupPath: backupPath ?? undefined
@@ -63098,9 +63348,9 @@ __export(exports_custom, {
63098
63348
  GLOBAL_COMMANDS_DIR: () => GLOBAL_COMMANDS_DIR,
63099
63349
  COMMANDS_DIR: () => COMMANDS_DIR
63100
63350
  });
63101
- import { existsSync as existsSync11 } from "node:fs";
63351
+ import { existsSync as existsSync12 } from "node:fs";
63102
63352
  import { readdir as readdir7, readFile as readFile8 } from "node:fs/promises";
63103
- import { basename as basename3, dirname as dirname11, join as join18 } from "node:path";
63353
+ import { basename as basename3, dirname as dirname11, join as join19 } from "node:path";
63104
63354
  async function getCustomCommands() {
63105
63355
  if (cachedCommands !== null) {
63106
63356
  return cachedCommands;
@@ -63111,7 +63361,7 @@ async function getCustomCommands() {
63111
63361
  function refreshCustomCommands() {
63112
63362
  cachedCommands = null;
63113
63363
  }
63114
- async function discoverCustomCommands(projectPath = join18(process.cwd(), COMMANDS_DIR)) {
63364
+ async function discoverCustomCommands(projectPath = join19(process.cwd(), COMMANDS_DIR)) {
63115
63365
  const commandsById = new Map;
63116
63366
  const userCommands = await discoverFromDirectory(GLOBAL_COMMANDS_DIR, "user");
63117
63367
  for (const cmd of userCommands) {
@@ -63132,7 +63382,7 @@ async function discoverCustomCommands(projectPath = join18(process.cwd(), COMMAN
63132
63382
  return result;
63133
63383
  }
63134
63384
  async function discoverFromDirectory(dirPath, source) {
63135
- if (!existsSync11(dirPath)) {
63385
+ if (!existsSync12(dirPath)) {
63136
63386
  return [];
63137
63387
  }
63138
63388
  const commands2 = [];
@@ -63143,7 +63393,7 @@ async function findCommandFiles(currentPath, rootPath, commands2, source) {
63143
63393
  try {
63144
63394
  const entries = await readdir7(currentPath, { withFileTypes: true });
63145
63395
  for (const entry of entries) {
63146
- const fullPath = join18(currentPath, entry.name);
63396
+ const fullPath = join19(currentPath, entry.name);
63147
63397
  if (entry.isDirectory()) {
63148
63398
  await findCommandFiles(fullPath, rootPath, commands2, source);
63149
63399
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
@@ -63228,7 +63478,7 @@ async function findCustomCommand(commandName) {
63228
63478
  }
63229
63479
  var COMMANDS_DIR = ".commands", GLOBAL_COMMANDS_DIR, cachedCommands = null;
63230
63480
  var init_custom = __esm(() => {
63231
- GLOBAL_COMMANDS_DIR = join18(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
63481
+ GLOBAL_COMMANDS_DIR = join19(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
63232
63482
  });
63233
63483
 
63234
63484
  // src/cli/components/HelpDialog.tsx
@@ -66077,7 +66327,7 @@ var require_jsx_runtime = __commonJS((exports, module) => {
66077
66327
 
66078
66328
  // node_modules/supports-color/index.js
66079
66329
  import process19 from "node:process";
66080
- import os4 from "node:os";
66330
+ import os5 from "node:os";
66081
66331
  import tty2 from "node:tty";
66082
66332
  function hasFlag2(flag, argv = globalThis.Deno ? globalThis.Deno.args : process19.argv) {
66083
66333
  const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
@@ -66143,7 +66393,7 @@ function _supportsColor2(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
66143
66393
  return min;
66144
66394
  }
66145
66395
  if (process19.platform === "win32") {
66146
- const osRelease = os4.release().split(".");
66396
+ const osRelease = os5.release().split(".");
66147
66397
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
66148
66398
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
66149
66399
  }
@@ -66498,21 +66748,21 @@ var init_AgentInfoBar = __esm(async () => {
66498
66748
  });
66499
66749
 
66500
66750
  // src/cli/helpers/fileSearch.ts
66501
- import { readdirSync as readdirSync4, statSync as statSync3 } from "node:fs";
66502
- import { join as join19, resolve as resolve19 } from "node:path";
66751
+ import { readdirSync as readdirSync5, statSync as statSync4 } from "node:fs";
66752
+ import { join as join20, resolve as resolve19 } from "node:path";
66503
66753
  function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = []) {
66504
66754
  if (results.length >= maxResults) {
66505
66755
  return results;
66506
66756
  }
66507
66757
  try {
66508
- const entries = readdirSync4(dir);
66758
+ const entries = readdirSync5(dir);
66509
66759
  for (const entry of entries) {
66510
66760
  if (entry.startsWith(".") || entry === "node_modules" || entry === "dist" || entry === "build") {
66511
66761
  continue;
66512
66762
  }
66513
66763
  try {
66514
- const fullPath = join19(dir, entry);
66515
- const stats = statSync3(fullPath);
66764
+ const fullPath = join20(dir, entry);
66765
+ const stats = statSync4(fullPath);
66516
66766
  const relativePath = fullPath.startsWith(process.cwd()) ? fullPath.slice(process.cwd().length + 1) : fullPath;
66517
66767
  const matches = pattern.length === 0 || relativePath.toLowerCase().includes(pattern.toLowerCase());
66518
66768
  if (matches) {
@@ -66544,7 +66794,7 @@ async function searchFiles(query, deep = false) {
66544
66794
  try {
66545
66795
  const resolvedDir = resolve19(process.cwd(), dirPart);
66546
66796
  try {
66547
- statSync3(resolvedDir);
66797
+ statSync4(resolvedDir);
66548
66798
  searchDir = resolvedDir;
66549
66799
  searchPattern = pattern;
66550
66800
  } catch {}
@@ -66556,15 +66806,15 @@ async function searchFiles(query, deep = false) {
66556
66806
  } else {
66557
66807
  let entries = [];
66558
66808
  try {
66559
- entries = readdirSync4(searchDir);
66809
+ entries = readdirSync5(searchDir);
66560
66810
  } catch {
66561
66811
  return [];
66562
66812
  }
66563
66813
  const matchingEntries = searchPattern.length === 0 ? entries : entries.filter((entry) => entry.toLowerCase().includes(searchPattern.toLowerCase()));
66564
66814
  for (const entry of matchingEntries.slice(0, 50)) {
66565
66815
  try {
66566
- const fullPath = join19(searchDir, entry);
66567
- const stats = statSync3(fullPath);
66816
+ const fullPath = join20(searchDir, entry);
66817
+ const stats = statSync4(fullPath);
66568
66818
  const relativePath = fullPath.startsWith(process.cwd()) ? fullPath.slice(process.cwd().length + 1) : fullPath;
66569
66819
  results.push({
66570
66820
  path: relativePath,
@@ -70679,7 +70929,7 @@ var init_PendingApprovalStub = __esm(async () => {
70679
70929
  });
70680
70930
 
70681
70931
  // src/cli/components/ReasoningMessageRich.tsx
70682
- var import_react73, jsx_dev_runtime49, normalize5 = (s) => s.replace(/\r\n/g, `
70932
+ var import_react73, jsx_dev_runtime49, normalize6 = (s) => s.replace(/\r\n/g, `
70683
70933
  `).replace(/[ \t]+$/gm, "").replace(/\n{3,}/g, `
70684
70934
 
70685
70935
  `).replace(/^\n+|\n+$/g, ""), ReasoningMessage;
@@ -70694,7 +70944,7 @@ var init_ReasoningMessageRich = __esm(async () => {
70694
70944
  ReasoningMessage = import_react73.memo(({ line }) => {
70695
70945
  const columns = useTerminalWidth();
70696
70946
  const contentWidth = Math.max(0, columns - 2);
70697
- const normalizedText = normalize5(line.text);
70947
+ const normalizedText = normalize6(line.text);
70698
70948
  return /* @__PURE__ */ jsx_dev_runtime49.jsxDEV(Box_default, {
70699
70949
  flexDirection: "column",
70700
70950
  children: [
@@ -71654,8 +71904,8 @@ function MemoryDiffRenderer({
71654
71904
  }, undefined, false, undefined, this);
71655
71905
  }
71656
71906
  const command = args.command;
71657
- const path20 = args.path || args.old_path || "unknown";
71658
- const blockName = path20.split("/").pop() || path20;
71907
+ const path21 = args.path || args.old_path || "unknown";
71908
+ const blockName = path21.split("/").pop() || path21;
71659
71909
  switch (command) {
71660
71910
  case "str_replace": {
71661
71911
  const oldStr = args.old_string || args.old_str || "";
@@ -74198,9 +74448,9 @@ async function getLettaConfig2() {
74198
74448
  const apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY || "";
74199
74449
  return { baseUrl, apiKey };
74200
74450
  }
74201
- async function providersRequest2(method, path20, body) {
74451
+ async function providersRequest2(method, path21, body) {
74202
74452
  const { baseUrl, apiKey } = await getLettaConfig2();
74203
- const url = `${baseUrl}${path20}`;
74453
+ const url = `${baseUrl}${path21}`;
74204
74454
  const response = await fetch(url, {
74205
74455
  method,
74206
74456
  headers: {
@@ -74731,9 +74981,9 @@ var exports_App = {};
74731
74981
  __export(exports_App, {
74732
74982
  default: () => App2
74733
74983
  });
74734
- import { existsSync as existsSync12, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
74735
- import { homedir as homedir11 } from "node:os";
74736
- import { join as join20 } from "node:path";
74984
+ import { existsSync as existsSync13, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "node:fs";
74985
+ import { homedir as homedir12 } from "node:os";
74986
+ import { join as join21 } from "node:path";
74737
74987
  function uid4(prefix) {
74738
74988
  return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
74739
74989
  }
@@ -74845,7 +75095,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the
74845
75095
  }
74846
75096
  function planFileExists() {
74847
75097
  const planFilePath = permissionMode.getPlanFilePath();
74848
- return !!planFilePath && existsSync12(planFilePath);
75098
+ return !!planFilePath && existsSync13(planFilePath);
74849
75099
  }
74850
75100
  function getQuestionsFromApproval(approval) {
74851
75101
  const parsed = safeJsonParseOr(approval.toolArgs, {});
@@ -75003,6 +75253,20 @@ function App2({
75003
75253
  const [autoDeniedApprovals, setAutoDeniedApprovals] = import_react84.useState([]);
75004
75254
  const executingToolCallIdsRef = import_react84.useRef([]);
75005
75255
  const interruptQueuedRef = import_react84.useRef(false);
75256
+ const toolResultsInFlightRef = import_react84.useRef(false);
75257
+ const autoAllowedExecutionRef = import_react84.useRef(null);
75258
+ const queuedApprovalMetadataRef = import_react84.useRef(null);
75259
+ const queueApprovalResults = import_react84.useCallback((results, metadata) => {
75260
+ setQueuedApprovalResults(results);
75261
+ if (results) {
75262
+ queuedApprovalMetadataRef.current = metadata ?? {
75263
+ conversationId: conversationIdRef.current,
75264
+ generation: conversationGenerationRef.current
75265
+ };
75266
+ } else {
75267
+ queuedApprovalMetadataRef.current = null;
75268
+ }
75269
+ }, []);
75006
75270
  const bashCommandCacheRef = import_react84.useRef([]);
75007
75271
  const [pendingRalphConfig, setPendingRalphConfig] = import_react84.useState(null);
75008
75272
  const [uiRalphActive, setUiRalphActive] = import_react84.useState(ralphMode.getState().isActive);
@@ -75363,8 +75627,8 @@ function App2({
75363
75627
  if (!planFilePath)
75364
75628
  return;
75365
75629
  try {
75366
- const { readFileSync: readFileSync5, existsSync: existsSync13 } = __require("node:fs");
75367
- if (!existsSync13(planFilePath))
75630
+ const { readFileSync: readFileSync5, existsSync: existsSync14 } = __require("node:fs");
75631
+ if (!existsSync14(planFilePath))
75368
75632
  return;
75369
75633
  const planContent = readFileSync5(planFilePath, "utf-8");
75370
75634
  const previewItem = {
@@ -75794,7 +76058,7 @@ ${newState.originalPrompt}`
75794
76058
  });
75795
76059
  }
75796
76060
  refreshDerived();
75797
- setQueuedApprovalResults(denialResults);
76061
+ queueApprovalResults(denialResults);
75798
76062
  const concatenatedMessage = queueSnapshotRef.current.join(`
75799
76063
  `);
75800
76064
  setMessageQueue([]);
@@ -75902,36 +76166,48 @@ ${newState.originalPrompt}`
75902
76166
  }
75903
76167
  } catch {}
75904
76168
  }
75905
- setToolCallsRunning(buffersRef.current, autoAllowed.map((ac) => ac.approval.toolCallId));
75906
- refreshDerived();
75907
- const autoAllowedResults = await executeAutoAllowedTools(autoAllowed, (chunk) => onChunk(buffersRef.current, chunk), {
75908
- abortSignal: signal,
75909
- onStreamingOutput: updateStreamingOutput
75910
- });
75911
- const autoDeniedResults = autoDenied.map((ac) => {
75912
- const reason = ac.permission.reason ? `Permission denied: ${ac.permission.reason}` : ("matchedRule" in ac.permission) && ac.permission.matchedRule ? `Permission denied by rule: ${ac.permission.matchedRule}` : "Permission denied: Unknown reason";
75913
- onChunk(buffersRef.current, {
75914
- message_type: "tool_return_message",
75915
- id: "dummy",
75916
- date: new Date().toISOString(),
75917
- tool_call_id: ac.approval.toolCallId,
75918
- tool_return: `Error: request to call tool denied. User reason: ${reason}`,
75919
- status: "error",
75920
- stdout: null,
75921
- stderr: null
75922
- });
75923
- return {
75924
- approval: ac.approval,
75925
- reason
76169
+ const autoAllowedToolCallIds = autoAllowed.map((ac) => ac.approval.toolCallId);
76170
+ const autoAllowedAbortController = abortControllerRef.current ?? new AbortController;
76171
+ const shouldTrackAutoAllowed = autoAllowedToolCallIds.length > 0;
76172
+ let autoAllowedResults = [];
76173
+ let autoDeniedResults = [];
76174
+ if (shouldTrackAutoAllowed) {
76175
+ setIsExecutingTool(true);
76176
+ executingToolCallIdsRef.current = autoAllowedToolCallIds;
76177
+ toolAbortControllerRef.current = autoAllowedAbortController;
76178
+ autoAllowedExecutionRef.current = {
76179
+ toolCallIds: autoAllowedToolCallIds,
76180
+ results: null,
76181
+ conversationId: conversationIdRef.current,
76182
+ generation: conversationGenerationRef.current
75926
76183
  };
75927
- });
75928
- if (needsUserInput.length === 0) {
75929
- if (userCancelledRef.current || abortControllerRef.current?.signal.aborted) {
75930
- setStreaming(false);
75931
- markIncompleteToolsAsCancelled(buffersRef.current);
76184
+ }
76185
+ try {
76186
+ if (autoAllowedToolCallIds.length > 0) {
76187
+ setToolCallsRunning(buffersRef.current, autoAllowedToolCallIds);
75932
76188
  refreshDerived();
75933
- return;
75934
76189
  }
76190
+ autoAllowedResults = autoAllowed.length > 0 ? await executeAutoAllowedTools(autoAllowed, (chunk) => onChunk(buffersRef.current, chunk), {
76191
+ abortSignal: autoAllowedAbortController.signal,
76192
+ onStreamingOutput: updateStreamingOutput
76193
+ }) : [];
76194
+ autoDeniedResults = autoDenied.map((ac) => {
76195
+ const reason = ac.permission.reason ? `Permission denied: ${ac.permission.reason}` : ("matchedRule" in ac.permission) && ac.permission.matchedRule ? `Permission denied by rule: ${ac.permission.matchedRule}` : "Permission denied: Unknown reason";
76196
+ onChunk(buffersRef.current, {
76197
+ message_type: "tool_return_message",
76198
+ id: "dummy",
76199
+ date: new Date().toISOString(),
76200
+ tool_call_id: ac.approval.toolCallId,
76201
+ tool_return: `Error: request to call tool denied. User reason: ${reason}`,
76202
+ status: "error",
76203
+ stdout: null,
76204
+ stderr: null
76205
+ });
76206
+ return {
76207
+ approval: ac.approval,
76208
+ reason
76209
+ };
76210
+ });
75935
76211
  const allResults = [
75936
76212
  ...autoAllowedResults.map((ar) => ({
75937
76213
  type: "tool",
@@ -75948,11 +76224,79 @@ ${newState.originalPrompt}`
75948
76224
  reason: ad.reason
75949
76225
  }))
75950
76226
  ];
76227
+ if (autoAllowedExecutionRef.current) {
76228
+ autoAllowedExecutionRef.current.results = allResults;
76229
+ }
76230
+ const autoAllowedMetadata = autoAllowedExecutionRef.current ? {
76231
+ conversationId: autoAllowedExecutionRef.current.conversationId,
76232
+ generation: conversationGenerationRef.current
76233
+ } : undefined;
76234
+ if (needsUserInput.length === 0) {
76235
+ if (userCancelledRef.current || abortControllerRef.current?.signal.aborted || interruptQueuedRef.current) {
76236
+ if (allResults.length > 0) {
76237
+ queueApprovalResults(allResults, autoAllowedMetadata);
76238
+ }
76239
+ setStreaming(false);
76240
+ markIncompleteToolsAsCancelled(buffersRef.current);
76241
+ refreshDerived();
76242
+ return;
76243
+ }
76244
+ if (waitingForQueueCancelRef.current) {
76245
+ if (restoreQueueOnCancelRef.current) {
76246
+ setRestoreQueueOnCancel(false);
76247
+ } else {
76248
+ if (allResults.length > 0) {
76249
+ queueApprovalResults(allResults, autoAllowedMetadata);
76250
+ }
76251
+ const concatenatedMessage = queueSnapshotRef.current.join(`
76252
+ `);
76253
+ setMessageQueue([]);
76254
+ if (concatenatedMessage.trim()) {
76255
+ onSubmitRef.current(concatenatedMessage);
76256
+ }
76257
+ }
76258
+ waitingForQueueCancelRef.current = false;
76259
+ queueSnapshotRef.current = [];
76260
+ setStreaming(false);
76261
+ return;
76262
+ }
76263
+ setThinkingMessage(getRandomThinkingVerb());
76264
+ refreshDerived();
76265
+ toolResultsInFlightRef.current = true;
76266
+ await processConversation([
76267
+ {
76268
+ type: "approval",
76269
+ approvals: allResults
76270
+ }
76271
+ ], { allowReentry: true });
76272
+ toolResultsInFlightRef.current = false;
76273
+ return;
76274
+ }
75951
76275
  if (waitingForQueueCancelRef.current) {
75952
76276
  if (restoreQueueOnCancelRef.current) {
75953
76277
  setRestoreQueueOnCancel(false);
75954
76278
  } else {
75955
- setQueuedApprovalResults(allResults);
76279
+ const denialResults = needsUserInput.map((ac) => ({
76280
+ type: "approval",
76281
+ tool_call_id: ac.approval.toolCallId,
76282
+ approve: false,
76283
+ reason: "User cancelled - new message queued"
76284
+ }));
76285
+ for (const ac of needsUserInput) {
76286
+ onChunk(buffersRef.current, {
76287
+ message_type: "tool_return_message",
76288
+ id: "dummy",
76289
+ date: new Date().toISOString(),
76290
+ tool_call_id: ac.approval.toolCallId,
76291
+ tool_return: "Cancelled - user sent new message",
76292
+ status: "error"
76293
+ });
76294
+ }
76295
+ refreshDerived();
76296
+ const queuedResults = [...allResults, ...denialResults];
76297
+ if (queuedResults.length > 0) {
76298
+ queueApprovalResults(queuedResults, autoAllowedMetadata);
76299
+ }
75956
76300
  const concatenatedMessage = queueSnapshotRef.current.join(`
75957
76301
  `);
75958
76302
  setMessageQueue([]);
@@ -75965,64 +76309,14 @@ ${newState.originalPrompt}`
75965
76309
  setStreaming(false);
75966
76310
  return;
75967
76311
  }
75968
- setThinkingMessage(getRandomThinkingVerb());
75969
- refreshDerived();
75970
- await processConversation([
75971
- {
75972
- type: "approval",
75973
- approvals: allResults
75974
- }
75975
- ], { allowReentry: true });
75976
- return;
75977
- }
75978
- if (waitingForQueueCancelRef.current) {
75979
- if (restoreQueueOnCancelRef.current) {
75980
- setRestoreQueueOnCancel(false);
75981
- } else {
75982
- const denialResults = needsUserInput.map((ac) => ({
75983
- type: "approval",
75984
- tool_call_id: ac.approval.toolCallId,
75985
- approve: false,
75986
- reason: "User cancelled - new message queued"
75987
- }));
75988
- for (const ac of needsUserInput) {
75989
- onChunk(buffersRef.current, {
75990
- message_type: "tool_return_message",
75991
- id: "dummy",
75992
- date: new Date().toISOString(),
75993
- tool_call_id: ac.approval.toolCallId,
75994
- tool_return: "Cancelled - user sent new message",
75995
- status: "error"
75996
- });
75997
- }
75998
- refreshDerived();
75999
- const allResults = [
76000
- ...autoAllowedResults.map((ar) => ({
76001
- type: "tool",
76002
- tool_call_id: ar.toolCallId,
76003
- tool_return: ar.result.toolReturn,
76004
- status: ar.result.status
76005
- })),
76006
- ...autoDeniedResults.map((ad) => ({
76007
- type: "approval",
76008
- tool_call_id: ad.approval.toolCallId,
76009
- approve: false,
76010
- reason: ad.reason
76011
- })),
76012
- ...denialResults
76013
- ];
76014
- setQueuedApprovalResults(allResults);
76015
- const concatenatedMessage = queueSnapshotRef.current.join(`
76016
- `);
76017
- setMessageQueue([]);
76018
- if (concatenatedMessage.trim()) {
76019
- onSubmitRef.current(concatenatedMessage);
76020
- }
76312
+ } finally {
76313
+ if (shouldTrackAutoAllowed) {
76314
+ setIsExecutingTool(false);
76315
+ toolAbortControllerRef.current = null;
76316
+ executingToolCallIdsRef.current = [];
76317
+ autoAllowedExecutionRef.current = null;
76318
+ toolResultsInFlightRef.current = false;
76021
76319
  }
76022
- waitingForQueueCancelRef.current = false;
76023
- queueSnapshotRef.current = [];
76024
- setStreaming(false);
76025
- return;
76026
76320
  }
76027
76321
  if (userCancelledRef.current || abortControllerRef.current?.signal.aborted) {
76028
76322
  setStreaming(false);
@@ -76094,33 +76388,11 @@ ${newState.originalPrompt}`
76094
76388
  const approvalPendingDetected = isApprovalPendingError(detailFromRun) || isApprovalPendingError(latestErrorText);
76095
76389
  if (!hasApprovalInPayload && approvalPendingDetected && llmApiErrorRetriesRef.current < LLM_API_ERROR_MAX_RETRIES2) {
76096
76390
  llmApiErrorRetriesRef.current += 1;
76097
- const statusId = uid4("status");
76098
- buffersRef.current.byId.set(statusId, {
76099
- kind: "status",
76100
- id: statusId,
76101
- lines: [
76102
- "[LAZY RECOVERY] Detected CONFLICT: server has pending approval",
76103
- "[LAZY RECOVERY] Fetching stale approvals to auto-deny..."
76104
- ]
76105
- });
76106
- buffersRef.current.order.push(statusId);
76107
- refreshDerived();
76108
76391
  try {
76109
76392
  const client = await getClient2();
76110
76393
  const agent = await client.agents.retrieve(agentIdRef.current);
76111
76394
  const { pendingApprovals: existingApprovals } = await getResumeData2(client, agent, conversationIdRef.current);
76112
76395
  if (existingApprovals && existingApprovals.length > 0) {
76113
- buffersRef.current.byId.set(statusId, {
76114
- kind: "status",
76115
- id: statusId,
76116
- lines: [
76117
- "[LAZY RECOVERY] Detected CONFLICT: server has pending approval",
76118
- `[LAZY RECOVERY] Found ${existingApprovals.length} stale approval(s):`,
76119
- ...existingApprovals.map((a) => ` - ${a.toolName} (${a.toolCallId.slice(0, 8)}...)`),
76120
- "[LAZY RECOVERY] Auto-denying and batching with user message..."
76121
- ]
76122
- });
76123
- refreshDerived();
76124
76396
  const denialResults = existingApprovals.map((approval2) => ({
76125
76397
  type: "approval",
76126
76398
  tool_call_id: approval2.toolCallId,
@@ -76132,32 +76404,8 @@ ${newState.originalPrompt}`
76132
76404
  approvals: denialResults
76133
76405
  };
76134
76406
  currentInput.unshift(approvalPayload);
76135
- } else {
76136
- buffersRef.current.byId.set(statusId, {
76137
- kind: "status",
76138
- id: statusId,
76139
- lines: [
76140
- "[LAZY RECOVERY] Detected CONFLICT but no pending approvals found",
76141
- "[LAZY RECOVERY] Retrying message..."
76142
- ]
76143
- });
76144
- refreshDerived();
76145
76407
  }
76146
- } catch (_recoveryError) {
76147
- buffersRef.current.byId.set(statusId, {
76148
- kind: "status",
76149
- id: statusId,
76150
- lines: [
76151
- "[LAZY RECOVERY] Failed to fetch pending approvals",
76152
- "[LAZY RECOVERY] Retrying message anyway..."
76153
- ]
76154
- });
76155
- refreshDerived();
76156
- }
76157
- await new Promise((resolve20) => setTimeout(resolve20, 500));
76158
- buffersRef.current.byId.delete(statusId);
76159
- buffersRef.current.order = buffersRef.current.order.filter((id) => id !== statusId);
76160
- refreshDerived();
76408
+ } catch {}
76161
76409
  buffersRef.current.interrupted = false;
76162
76410
  continue;
76163
76411
  }
@@ -76276,7 +76524,8 @@ ${newState.originalPrompt}`
76276
76524
  setStreaming,
76277
76525
  currentModelId,
76278
76526
  updateStreamingOutput,
76279
- needsEagerApprovalCheck
76527
+ needsEagerApprovalCheck,
76528
+ queueApprovalResults
76280
76529
  ]);
76281
76530
  const handleExit = import_react84.useCallback(async () => {
76282
76531
  saveLastAgentBeforeExit();
@@ -76292,19 +76541,31 @@ ${newState.originalPrompt}`
76292
76541
  setMessageQueue([]);
76293
76542
  }, []);
76294
76543
  const handleInterrupt = import_react84.useCallback(async () => {
76295
- if (isExecutingTool && toolAbortControllerRef.current) {
76544
+ const hasTrackedTools = executingToolCallIdsRef.current.length > 0 || autoAllowedExecutionRef.current?.results;
76545
+ if (isExecutingTool && toolAbortControllerRef.current && hasTrackedTools && !toolResultsInFlightRef.current) {
76296
76546
  toolAbortControllerRef.current.abort();
76297
- if (executingToolCallIdsRef.current.length > 0) {
76547
+ conversationGenerationRef.current += 1;
76548
+ processingConversationRef.current = 0;
76549
+ const autoAllowedResults = autoAllowedExecutionRef.current?.results;
76550
+ const autoAllowedMetadata = autoAllowedExecutionRef.current ? {
76551
+ conversationId: autoAllowedExecutionRef.current.conversationId,
76552
+ generation: conversationGenerationRef.current
76553
+ } : undefined;
76554
+ if (autoAllowedResults && autoAllowedResults.length > 0) {
76555
+ queueApprovalResults(autoAllowedResults, autoAllowedMetadata);
76556
+ interruptQueuedRef.current = true;
76557
+ } else if (executingToolCallIdsRef.current.length > 0) {
76298
76558
  const interruptedResults = executingToolCallIdsRef.current.map((toolCallId) => ({
76299
76559
  type: "tool",
76300
76560
  tool_call_id: toolCallId,
76301
76561
  tool_return: INTERRUPTED_BY_USER,
76302
76562
  status: "error"
76303
76563
  }));
76304
- setQueuedApprovalResults(interruptedResults);
76305
- executingToolCallIdsRef.current = [];
76564
+ queueApprovalResults(interruptedResults);
76306
76565
  interruptQueuedRef.current = true;
76307
76566
  }
76567
+ executingToolCallIdsRef.current = [];
76568
+ autoAllowedExecutionRef.current = null;
76308
76569
  buffersRef.current.abortGeneration = (buffersRef.current.abortGeneration || 0) + 1;
76309
76570
  const toolsCancelled = markIncompleteToolsAsCancelled(buffersRef.current);
76310
76571
  interruptActiveSubagents(INTERRUPTED_BY_USER);
@@ -76318,6 +76579,7 @@ ${newState.originalPrompt}`
76318
76579
  userCancelledRef.current = true;
76319
76580
  setStreaming(false);
76320
76581
  setIsExecutingTool(false);
76582
+ toolResultsInFlightRef.current = false;
76321
76583
  refreshDerived();
76322
76584
  setTimeout(() => {
76323
76585
  userCancelledRef.current = false;
@@ -76343,18 +76605,38 @@ ${newState.originalPrompt}`
76343
76605
  conversationGenerationRef.current += 1;
76344
76606
  processingConversationRef.current = 0;
76345
76607
  setStreaming(false);
76608
+ toolResultsInFlightRef.current = false;
76346
76609
  if (!toolsCancelled) {
76347
76610
  appendError(INTERRUPT_MESSAGE, true);
76348
76611
  }
76349
76612
  refreshDerived();
76350
- if (pendingApprovals.length > 0) {
76351
- const denialResults = pendingApprovals.map((approval) => ({
76613
+ const denialResults = pendingApprovals.map((approval) => ({
76614
+ type: "approval",
76615
+ tool_call_id: approval.toolCallId,
76616
+ approve: false,
76617
+ reason: "User interrupted the stream"
76618
+ }));
76619
+ const autoHandledSnapshot = [...autoHandledResults];
76620
+ const autoDeniedSnapshot = [...autoDeniedApprovals];
76621
+ const queuedResults = [
76622
+ ...autoHandledSnapshot.map((ar) => ({
76623
+ type: "tool",
76624
+ tool_call_id: ar.toolCallId,
76625
+ tool_return: ar.result.toolReturn,
76626
+ status: ar.result.status,
76627
+ stdout: ar.result.stdout,
76628
+ stderr: ar.result.stderr
76629
+ })),
76630
+ ...autoDeniedSnapshot.map((ad) => ({
76352
76631
  type: "approval",
76353
- tool_call_id: approval.toolCallId,
76632
+ tool_call_id: ad.approval.toolCallId,
76354
76633
  approve: false,
76355
- reason: "User interrupted the stream"
76356
- }));
76357
- setQueuedApprovalResults(denialResults);
76634
+ reason: ad.reason
76635
+ })),
76636
+ ...denialResults
76637
+ ];
76638
+ if (queuedResults.length > 0) {
76639
+ queueApprovalResults(queuedResults);
76358
76640
  }
76359
76641
  setPendingApprovals([]);
76360
76642
  setApprovalContexts([]);
@@ -76389,7 +76671,10 @@ ${newState.originalPrompt}`
76389
76671
  isExecutingTool,
76390
76672
  refreshDerived,
76391
76673
  setStreaming,
76392
- pendingApprovals
76674
+ pendingApprovals,
76675
+ autoHandledResults,
76676
+ autoDeniedApprovals,
76677
+ queueApprovalResults
76393
76678
  ]);
76394
76679
  const processConversationRef = import_react84.useRef(processConversation);
76395
76680
  import_react84.useEffect(() => {
@@ -76671,42 +76956,85 @@ ${newState.originalPrompt}`
76671
76956
  return { blocked: true };
76672
76957
  }
76673
76958
  const allResults = [];
76674
- if (autoAllowed.length > 0) {
76675
- setToolCallsRunning(buffersRef.current, autoAllowed.map((ac) => ac.approval.toolCallId));
76676
- refreshDerived();
76677
- const autoAllowedResults = await executeAutoAllowedTools(autoAllowed, (chunk) => onChunk(buffersRef.current, chunk), { onStreamingOutput: updateStreamingOutput });
76678
- allResults.push(...autoAllowedResults.map((ar) => ({
76679
- type: "tool",
76680
- tool_call_id: ar.toolCallId,
76681
- tool_return: ar.result.toolReturn,
76682
- status: ar.result.status,
76683
- stdout: ar.result.stdout,
76684
- stderr: ar.result.stderr
76685
- })));
76686
- }
76687
- for (const ac of autoDenied) {
76688
- const reason = ac.permission.reason || "Permission denied";
76689
- onChunk(buffersRef.current, {
76690
- message_type: "tool_return_message",
76691
- id: "dummy",
76692
- date: new Date().toISOString(),
76693
- tool_call_id: ac.approval.toolCallId,
76694
- tool_return: `Error: request to call tool denied. User reason: ${reason}`,
76695
- status: "error",
76696
- stdout: null,
76697
- stderr: null
76698
- });
76699
- allResults.push({
76700
- type: "approval",
76701
- tool_call_id: ac.approval.toolCallId,
76702
- approve: false,
76703
- reason
76704
- });
76959
+ const autoAllowedToolCallIds = autoAllowed.map((ac) => ac.approval.toolCallId);
76960
+ const autoAllowedAbortController = abortControllerRef.current ?? new AbortController;
76961
+ const shouldTrackAutoAllowed = autoAllowedToolCallIds.length > 0;
76962
+ let autoAllowedResults = [];
76963
+ if (shouldTrackAutoAllowed) {
76964
+ setIsExecutingTool(true);
76965
+ executingToolCallIdsRef.current = autoAllowedToolCallIds;
76966
+ toolAbortControllerRef.current = autoAllowedAbortController;
76967
+ autoAllowedExecutionRef.current = {
76968
+ toolCallIds: autoAllowedToolCallIds,
76969
+ results: null,
76970
+ conversationId: conversationIdRef.current,
76971
+ generation: conversationGenerationRef.current
76972
+ };
76705
76973
  }
76706
- if (allResults.length > 0) {
76707
- await processConversation([
76708
- { type: "approval", approvals: allResults }
76709
- ]);
76974
+ try {
76975
+ if (autoAllowed.length > 0) {
76976
+ setToolCallsRunning(buffersRef.current, autoAllowedToolCallIds);
76977
+ refreshDerived();
76978
+ autoAllowedResults = await executeAutoAllowedTools(autoAllowed, (chunk) => onChunk(buffersRef.current, chunk), {
76979
+ abortSignal: autoAllowedAbortController.signal,
76980
+ onStreamingOutput: updateStreamingOutput
76981
+ });
76982
+ allResults.push(...autoAllowedResults.map((ar) => ({
76983
+ type: "tool",
76984
+ tool_call_id: ar.toolCallId,
76985
+ tool_return: ar.result.toolReturn,
76986
+ status: ar.result.status,
76987
+ stdout: ar.result.stdout,
76988
+ stderr: ar.result.stderr
76989
+ })));
76990
+ }
76991
+ for (const ac of autoDenied) {
76992
+ const reason = ac.permission.reason || "Permission denied";
76993
+ onChunk(buffersRef.current, {
76994
+ message_type: "tool_return_message",
76995
+ id: "dummy",
76996
+ date: new Date().toISOString(),
76997
+ tool_call_id: ac.approval.toolCallId,
76998
+ tool_return: `Error: request to call tool denied. User reason: ${reason}`,
76999
+ status: "error",
77000
+ stdout: null,
77001
+ stderr: null
77002
+ });
77003
+ allResults.push({
77004
+ type: "approval",
77005
+ tool_call_id: ac.approval.toolCallId,
77006
+ approve: false,
77007
+ reason
77008
+ });
77009
+ }
77010
+ if (autoAllowedExecutionRef.current) {
77011
+ autoAllowedExecutionRef.current.results = allResults;
77012
+ }
77013
+ const autoAllowedMetadata = autoAllowedExecutionRef.current ? {
77014
+ conversationId: autoAllowedExecutionRef.current.conversationId,
77015
+ generation: conversationGenerationRef.current
77016
+ } : undefined;
77017
+ if (userCancelledRef.current || autoAllowedAbortController.signal.aborted || interruptQueuedRef.current) {
77018
+ if (allResults.length > 0) {
77019
+ queueApprovalResults(allResults, autoAllowedMetadata);
77020
+ }
77021
+ return { blocked: false };
77022
+ }
77023
+ if (allResults.length > 0) {
77024
+ toolResultsInFlightRef.current = true;
77025
+ await processConversation([
77026
+ { type: "approval", approvals: allResults }
77027
+ ]);
77028
+ toolResultsInFlightRef.current = false;
77029
+ }
77030
+ } finally {
77031
+ if (shouldTrackAutoAllowed) {
77032
+ setIsExecutingTool(false);
77033
+ toolAbortControllerRef.current = null;
77034
+ executingToolCallIdsRef.current = [];
77035
+ autoAllowedExecutionRef.current = null;
77036
+ toolResultsInFlightRef.current = false;
77037
+ }
76710
77038
  }
76711
77039
  return { blocked: false };
76712
77040
  } catch {
@@ -76717,7 +77045,8 @@ ${newState.originalPrompt}`
76717
77045
  processConversation,
76718
77046
  refreshDerived,
76719
77047
  updateStreamingOutput,
76720
- needsEagerApprovalCheck
77048
+ needsEagerApprovalCheck,
77049
+ queueApprovalResults
76721
77050
  ]);
76722
77051
  const onSubmit = import_react84.useCallback(async (message) => {
76723
77052
  const msg = message?.trim() ?? "";
@@ -77687,7 +78016,7 @@ Press Enter to continue, or type anything to cancel.`, false, "running");
77687
78016
  const client = await getClient2();
77688
78017
  const fileContent = await client.agents.exportFile(agentId);
77689
78018
  const fileName = `${agentId}.af`;
77690
- writeFileSync3(fileName, JSON.stringify(fileContent, null, 2));
78019
+ writeFileSync4(fileName, JSON.stringify(fileContent, null, 2));
77691
78020
  buffersRef.current.byId.set(cmdId2, {
77692
78021
  kind: "command",
77693
78022
  id: cmdId2,
@@ -78267,52 +78596,112 @@ DO NOT respond to these messages or otherwise consider them in your response unl
78267
78596
  }
78268
78597
  } catch {}
78269
78598
  }
78270
- setToolCallsRunning(buffersRef.current, autoAllowed.map((ac) => ac.approval.toolCallId));
78271
- refreshDerived();
78272
- const autoAllowedResults = await executeAutoAllowedTools(autoAllowed, (chunk) => onChunk(buffersRef.current, chunk), { onStreamingOutput: updateStreamingOutput });
78273
- const autoDeniedResults = autoDenied.map((ac) => {
78274
- const reason = ac.permission.reason ? `Permission denied: ${ac.permission.reason}` : ("matchedRule" in ac.permission) && ac.permission.matchedRule ? `Permission denied by rule: ${ac.permission.matchedRule}` : "Permission denied: Unknown";
78275
- onChunk(buffersRef.current, {
78276
- message_type: "tool_return_message",
78277
- id: "dummy",
78278
- date: new Date().toISOString(),
78279
- tool_call_id: ac.approval.toolCallId,
78280
- tool_return: `Error: request to call tool denied. User reason: ${reason}`,
78281
- status: "error",
78282
- stdout: null,
78283
- stderr: null
78284
- });
78285
- return {
78286
- type: "approval",
78287
- tool_call_id: ac.approval.toolCallId,
78288
- approve: false,
78289
- reason
78599
+ const autoAllowedToolCallIds = autoAllowed.map((ac) => ac.approval.toolCallId);
78600
+ const autoAllowedAbortController = abortControllerRef.current ?? new AbortController;
78601
+ const shouldTrackAutoAllowed = autoAllowedToolCallIds.length > 0;
78602
+ let autoAllowedResults = [];
78603
+ let autoDeniedResults = [];
78604
+ if (shouldTrackAutoAllowed) {
78605
+ setIsExecutingTool(true);
78606
+ executingToolCallIdsRef.current = autoAllowedToolCallIds;
78607
+ toolAbortControllerRef.current = autoAllowedAbortController;
78608
+ autoAllowedExecutionRef.current = {
78609
+ toolCallIds: autoAllowedToolCallIds,
78610
+ results: null,
78611
+ conversationId: conversationIdRef.current,
78612
+ generation: conversationGenerationRef.current
78290
78613
  };
78291
- });
78292
- refreshDerived();
78293
- const recoveryApprovalResults = [
78294
- ...autoAllowedResults.map((ar) => ({
78295
- type: "approval",
78296
- tool_call_id: ar.toolCallId,
78297
- approve: true,
78298
- tool_return: ar.result.toolReturn
78299
- })),
78300
- ...autoDeniedResults
78301
- ];
78302
- const initialInput2 = [
78303
- {
78304
- type: "approval",
78305
- approvals: recoveryApprovalResults
78306
- },
78307
- {
78308
- type: "message",
78309
- role: "user",
78310
- content: messageContent
78614
+ }
78615
+ try {
78616
+ if (autoAllowedToolCallIds.length > 0) {
78617
+ setToolCallsRunning(buffersRef.current, autoAllowedToolCallIds);
78618
+ refreshDerived();
78311
78619
  }
78312
- ];
78313
- await processConversation(initialInput2);
78314
- clearPlaceholdersInText(msg);
78315
- return { submitted: true };
78620
+ autoAllowedResults = autoAllowed.length > 0 ? await executeAutoAllowedTools(autoAllowed, (chunk) => onChunk(buffersRef.current, chunk), {
78621
+ abortSignal: autoAllowedAbortController.signal,
78622
+ onStreamingOutput: updateStreamingOutput
78623
+ }) : [];
78624
+ autoDeniedResults = autoDenied.map((ac) => {
78625
+ const reason = ac.permission.reason ? `Permission denied: ${ac.permission.reason}` : ("matchedRule" in ac.permission) && ac.permission.matchedRule ? `Permission denied by rule: ${ac.permission.matchedRule}` : "Permission denied: Unknown";
78626
+ onChunk(buffersRef.current, {
78627
+ message_type: "tool_return_message",
78628
+ id: "dummy",
78629
+ date: new Date().toISOString(),
78630
+ tool_call_id: ac.approval.toolCallId,
78631
+ tool_return: `Error: request to call tool denied. User reason: ${reason}`,
78632
+ status: "error",
78633
+ stdout: null,
78634
+ stderr: null
78635
+ });
78636
+ return {
78637
+ type: "approval",
78638
+ tool_call_id: ac.approval.toolCallId,
78639
+ approve: false,
78640
+ reason
78641
+ };
78642
+ });
78643
+ const queuedResults = [
78644
+ ...autoAllowedResults.map((ar) => ({
78645
+ type: "tool",
78646
+ tool_call_id: ar.toolCallId,
78647
+ tool_return: ar.result.toolReturn,
78648
+ status: ar.result.status,
78649
+ stdout: ar.result.stdout,
78650
+ stderr: ar.result.stderr
78651
+ })),
78652
+ ...autoDeniedResults
78653
+ ];
78654
+ if (autoAllowedExecutionRef.current) {
78655
+ autoAllowedExecutionRef.current.results = queuedResults;
78656
+ }
78657
+ const autoAllowedMetadata = autoAllowedExecutionRef.current ? {
78658
+ conversationId: autoAllowedExecutionRef.current.conversationId,
78659
+ generation: conversationGenerationRef.current
78660
+ } : undefined;
78661
+ if (userCancelledRef.current || autoAllowedAbortController.signal.aborted || interruptQueuedRef.current) {
78662
+ if (queuedResults.length > 0) {
78663
+ queueApprovalResults(queuedResults, autoAllowedMetadata);
78664
+ }
78665
+ setStreaming(false);
78666
+ markIncompleteToolsAsCancelled(buffersRef.current);
78667
+ refreshDerived();
78668
+ return { submitted: false };
78669
+ }
78670
+ refreshDerived();
78671
+ const recoveryApprovalResults = [
78672
+ ...autoAllowedResults.map((ar) => ({
78673
+ type: "approval",
78674
+ tool_call_id: ar.toolCallId,
78675
+ approve: true,
78676
+ tool_return: ar.result.toolReturn
78677
+ })),
78678
+ ...autoDeniedResults
78679
+ ];
78680
+ const initialInput2 = [
78681
+ {
78682
+ type: "approval",
78683
+ approvals: recoveryApprovalResults
78684
+ },
78685
+ {
78686
+ type: "message",
78687
+ role: "user",
78688
+ content: messageContent
78689
+ }
78690
+ ];
78691
+ toolResultsInFlightRef.current = true;
78692
+ await processConversation(initialInput2);
78693
+ toolResultsInFlightRef.current = false;
78694
+ clearPlaceholdersInText(msg);
78695
+ return { submitted: true };
78696
+ } finally {
78697
+ if (shouldTrackAutoAllowed) {
78698
+ setIsExecutingTool(false);
78699
+ toolAbortControllerRef.current = null;
78700
+ executingToolCallIdsRef.current = [];
78701
+ autoAllowedExecutionRef.current = null;
78702
+ toolResultsInFlightRef.current = false;
78703
+ }
78704
+ }
78316
78705
  } else {
78317
78706
  buffersRef.current.byId.delete(userId);
78318
78707
  const orderIndex = buffersRef.current.order.indexOf(userId);
@@ -78378,39 +78767,105 @@ DO NOT respond to these messages or otherwise consider them in your response unl
78378
78767
  }
78379
78768
  } catch {}
78380
78769
  }
78381
- const autoAllowedWithResults = await executeAutoAllowedTools(autoAllowed, (chunk) => onChunk(buffersRef.current, chunk), { onStreamingOutput: updateStreamingOutput });
78382
- const autoDeniedWithReasons = autoDenied.map((ac) => {
78383
- const reason = ac.permission.reason ? `Permission denied: ${ac.permission.reason}` : ("matchedRule" in ac.permission) && ac.permission.matchedRule ? `Permission denied by rule: ${ac.permission.matchedRule}` : "Permission denied: Unknown";
78384
- onChunk(buffersRef.current, {
78385
- message_type: "tool_return_message",
78386
- id: "dummy",
78387
- date: new Date().toISOString(),
78388
- tool_call_id: ac.approval.toolCallId,
78389
- tool_return: `Error: request to call tool denied. User reason: ${reason}`,
78390
- status: "error",
78391
- stdout: null,
78392
- stderr: null
78393
- });
78394
- return {
78395
- approval: ac.approval,
78396
- reason
78770
+ const autoAllowedToolCallIds = autoAllowed.map((ac) => ac.approval.toolCallId);
78771
+ const autoAllowedAbortController = abortControllerRef.current ?? new AbortController;
78772
+ const shouldTrackAutoAllowed = autoAllowedToolCallIds.length > 0;
78773
+ let autoAllowedWithResults = [];
78774
+ let autoDeniedWithReasons = [];
78775
+ if (shouldTrackAutoAllowed) {
78776
+ setIsExecutingTool(true);
78777
+ executingToolCallIdsRef.current = autoAllowedToolCallIds;
78778
+ toolAbortControllerRef.current = autoAllowedAbortController;
78779
+ autoAllowedExecutionRef.current = {
78780
+ toolCallIds: autoAllowedToolCallIds,
78781
+ results: null,
78782
+ conversationId: conversationIdRef.current,
78783
+ generation: conversationGenerationRef.current
78397
78784
  };
78398
- });
78399
- setAutoHandledResults(autoAllowedWithResults);
78400
- setAutoDeniedApprovals(autoDeniedWithReasons);
78401
- refreshDerived();
78402
- return { submitted: false };
78785
+ }
78786
+ try {
78787
+ autoAllowedWithResults = autoAllowed.length > 0 ? await executeAutoAllowedTools(autoAllowed, (chunk) => onChunk(buffersRef.current, chunk), {
78788
+ abortSignal: autoAllowedAbortController.signal,
78789
+ onStreamingOutput: updateStreamingOutput
78790
+ }) : [];
78791
+ autoDeniedWithReasons = autoDenied.map((ac) => {
78792
+ const reason = ac.permission.reason ? `Permission denied: ${ac.permission.reason}` : ("matchedRule" in ac.permission) && ac.permission.matchedRule ? `Permission denied by rule: ${ac.permission.matchedRule}` : "Permission denied: Unknown";
78793
+ onChunk(buffersRef.current, {
78794
+ message_type: "tool_return_message",
78795
+ id: "dummy",
78796
+ date: new Date().toISOString(),
78797
+ tool_call_id: ac.approval.toolCallId,
78798
+ tool_return: `Error: request to call tool denied. User reason: ${reason}`,
78799
+ status: "error",
78800
+ stdout: null,
78801
+ stderr: null
78802
+ });
78803
+ return {
78804
+ approval: ac.approval,
78805
+ reason
78806
+ };
78807
+ });
78808
+ const queuedResults = [
78809
+ ...autoAllowedWithResults.map((ar) => ({
78810
+ type: "tool",
78811
+ tool_call_id: ar.toolCallId,
78812
+ tool_return: ar.result.toolReturn,
78813
+ status: ar.result.status,
78814
+ stdout: ar.result.stdout,
78815
+ stderr: ar.result.stderr
78816
+ })),
78817
+ ...autoDeniedWithReasons.map((ad) => ({
78818
+ type: "approval",
78819
+ tool_call_id: ad.approval.toolCallId,
78820
+ approve: false,
78821
+ reason: ad.reason
78822
+ }))
78823
+ ];
78824
+ if (autoAllowedExecutionRef.current) {
78825
+ autoAllowedExecutionRef.current.results = queuedResults;
78826
+ }
78827
+ const autoAllowedMetadata = autoAllowedExecutionRef.current ? {
78828
+ conversationId: autoAllowedExecutionRef.current.conversationId,
78829
+ generation: conversationGenerationRef.current
78830
+ } : undefined;
78831
+ if (userCancelledRef.current || autoAllowedAbortController.signal.aborted || interruptQueuedRef.current) {
78832
+ if (queuedResults.length > 0) {
78833
+ queueApprovalResults(queuedResults, autoAllowedMetadata);
78834
+ }
78835
+ setStreaming(false);
78836
+ markIncompleteToolsAsCancelled(buffersRef.current);
78837
+ refreshDerived();
78838
+ return { submitted: false };
78839
+ }
78840
+ setAutoHandledResults(autoAllowedWithResults);
78841
+ setAutoDeniedApprovals(autoDeniedWithReasons);
78842
+ refreshDerived();
78843
+ return { submitted: false };
78844
+ } finally {
78845
+ if (shouldTrackAutoAllowed) {
78846
+ setIsExecutingTool(false);
78847
+ toolAbortControllerRef.current = null;
78848
+ executingToolCallIdsRef.current = [];
78849
+ autoAllowedExecutionRef.current = null;
78850
+ }
78851
+ }
78403
78852
  }
78404
78853
  }
78405
78854
  } catch (_error) {}
78406
78855
  }
78407
78856
  const initialInput = [];
78408
78857
  if (queuedApprovalResults) {
78409
- initialInput.push({
78410
- type: "approval",
78411
- approvals: queuedApprovalResults
78412
- });
78413
- setQueuedApprovalResults(null);
78858
+ const queuedMetadata = queuedApprovalMetadataRef.current;
78859
+ const isQueuedValid = queuedMetadata && queuedMetadata.conversationId === conversationIdRef.current && queuedMetadata.generation === conversationGenerationRef.current;
78860
+ if (isQueuedValid) {
78861
+ initialInput.push({
78862
+ type: "approval",
78863
+ approvals: queuedApprovalResults
78864
+ });
78865
+ } else {
78866
+ console.warn("[WARN] Dropping stale queued approval results for mismatched conversation or generation");
78867
+ }
78868
+ queueApprovalResults(null);
78414
78869
  interruptQueuedRef.current = false;
78415
78870
  }
78416
78871
  initialInput.push({
@@ -78433,6 +78888,7 @@ DO NOT respond to these messages or otherwise consider them in your response unl
78433
78888
  handleExit,
78434
78889
  isExecutingTool,
78435
78890
  queuedApprovalResults,
78891
+ queueApprovalResults,
78436
78892
  pendingApprovals,
78437
78893
  profileConfirmPending,
78438
78894
  handleAgentSelect,
@@ -78544,24 +79000,27 @@ DO NOT respond to these messages or otherwise consider them in your response unl
78544
79000
  const userCancelled = userCancelledRef.current;
78545
79001
  if (wasAborted || userCancelled) {
78546
79002
  if (!interruptQueuedRef.current) {
78547
- setQueuedApprovalResults(allResults);
79003
+ queueApprovalResults(allResults);
78548
79004
  }
78549
79005
  setStreaming(false);
78550
79006
  waitingForQueueCancelRef.current = false;
78551
79007
  queueSnapshotRef.current = [];
78552
79008
  } else {
79009
+ toolResultsInFlightRef.current = true;
78553
79010
  await processConversation([
78554
79011
  {
78555
79012
  type: "approval",
78556
79013
  approvals: allResults
78557
79014
  }
78558
79015
  ]);
79016
+ toolResultsInFlightRef.current = false;
78559
79017
  }
78560
79018
  } finally {
78561
79019
  setIsExecutingTool(false);
78562
79020
  toolAbortControllerRef.current = null;
78563
79021
  executingToolCallIdsRef.current = [];
78564
79022
  interruptQueuedRef.current = false;
79023
+ toolResultsInFlightRef.current = false;
78565
79024
  }
78566
79025
  }, [
78567
79026
  approvalResults,
@@ -78572,7 +79031,8 @@ DO NOT respond to these messages or otherwise consider them in your response unl
78572
79031
  refreshDerived,
78573
79032
  appendError,
78574
79033
  setStreaming,
78575
- updateStreamingOutput
79034
+ updateStreamingOutput,
79035
+ queueApprovalResults
78576
79036
  ]);
78577
79037
  const handleApproveCurrent = import_react84.useCallback(async (diffs) => {
78578
79038
  if (isExecutingTool)
@@ -78770,7 +79230,7 @@ DO NOT respond to these messages or otherwise consider them in your response unl
78770
79230
  approve: false,
78771
79231
  reason: "User cancelled the approval"
78772
79232
  }));
78773
- setQueuedApprovalResults(denialResults);
79233
+ queueApprovalResults(denialResults);
78774
79234
  markIncompleteToolsAsCancelled(buffersRef.current);
78775
79235
  refreshDerived();
78776
79236
  setPendingApprovals([]);
@@ -78778,7 +79238,7 @@ DO NOT respond to these messages or otherwise consider them in your response unl
78778
79238
  setApprovalResults([]);
78779
79239
  setAutoHandledResults([]);
78780
79240
  setAutoDeniedApprovals([]);
78781
- }, [pendingApprovals, refreshDerived]);
79241
+ }, [pendingApprovals, refreshDerived, queueApprovalResults]);
78782
79242
  const handleModelSelect = import_react84.useCallback(async (modelId) => {
78783
79243
  await withCommandLock(async () => {
78784
79244
  let cmdId = null;
@@ -79160,7 +79620,7 @@ Consider switching to a different system prompt using /system to match.` : null;
79160
79620
  reason: "Plan mode session expired (CLI restarted). Use EnterPlanMode to re-enter plan mode, or request the user to re-enter plan mode."
79161
79621
  }
79162
79622
  ];
79163
- setQueuedApprovalResults(denialResults);
79623
+ queueApprovalResults(denialResults);
79164
79624
  markIncompleteToolsAsCancelled(buffersRef.current);
79165
79625
  refreshDerived();
79166
79626
  setPendingApprovals([]);
@@ -79172,7 +79632,7 @@ Consider switching to a different system prompt using /system to match.` : null;
79172
79632
  }
79173
79633
  if (!planFileExists()) {
79174
79634
  const planFilePath = permissionMode.getPlanFilePath();
79175
- const plansDir = join20(homedir11(), ".letta", "plans");
79635
+ const plansDir = join21(homedir12(), ".letta", "plans");
79176
79636
  handlePlanKeepPlanning(`You must write your plan to a plan file before exiting plan mode.
79177
79637
  ` + (planFilePath ? `Plan file path: ${planFilePath}
79178
79638
  ` : "") + `Use a write tool to create your plan in ${plansDir}, then use ExitPlanMode to present the plan to the user.`);
@@ -79182,7 +79642,8 @@ Consider switching to a different system prompt using /system to match.` : null;
79182
79642
  pendingApprovals,
79183
79643
  approvalResults.length,
79184
79644
  handlePlanKeepPlanning,
79185
- refreshDerived
79645
+ refreshDerived,
79646
+ queueApprovalResults
79186
79647
  ]);
79187
79648
  const handleQuestionSubmit = import_react84.useCallback(async (answers) => {
79188
79649
  const currentIndex = approvalResults.length;
@@ -80043,13 +80504,13 @@ __export(exports_terminalKeybindingInstaller2, {
80043
80504
  });
80044
80505
  import {
80045
80506
  copyFileSync as copyFileSync2,
80046
- existsSync as existsSync13,
80047
- mkdirSync as mkdirSync5,
80507
+ existsSync as existsSync14,
80508
+ mkdirSync as mkdirSync6,
80048
80509
  readFileSync as readFileSync5,
80049
- writeFileSync as writeFileSync4
80510
+ writeFileSync as writeFileSync5
80050
80511
  } from "node:fs";
80051
- import { homedir as homedir12, platform as platform5 } from "node:os";
80052
- import { dirname as dirname12, join as join21 } from "node:path";
80512
+ import { homedir as homedir13, platform as platform5 } from "node:os";
80513
+ import { dirname as dirname12, join as join22 } from "node:path";
80053
80514
  function detectTerminalType2() {
80054
80515
  if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
80055
80516
  return "cursor";
@@ -80079,18 +80540,18 @@ function getKeybindingsPath2(terminal) {
80079
80540
  cursor: "Cursor",
80080
80541
  windsurf: "Windsurf"
80081
80542
  }[terminal];
80082
- const os5 = platform5();
80083
- if (os5 === "darwin") {
80084
- return join21(homedir12(), "Library", "Application Support", appName, "User", "keybindings.json");
80543
+ const os6 = platform5();
80544
+ if (os6 === "darwin") {
80545
+ return join22(homedir13(), "Library", "Application Support", appName, "User", "keybindings.json");
80085
80546
  }
80086
- if (os5 === "win32") {
80547
+ if (os6 === "win32") {
80087
80548
  const appData = process.env.APPDATA;
80088
80549
  if (!appData)
80089
80550
  return null;
80090
- return join21(appData, appName, "User", "keybindings.json");
80551
+ return join22(appData, appName, "User", "keybindings.json");
80091
80552
  }
80092
- if (os5 === "linux") {
80093
- return join21(homedir12(), ".config", appName, "User", "keybindings.json");
80553
+ if (os6 === "linux") {
80554
+ return join22(homedir13(), ".config", appName, "User", "keybindings.json");
80094
80555
  }
80095
80556
  return null;
80096
80557
  }
@@ -80112,7 +80573,7 @@ function parseKeybindings2(content) {
80112
80573
  }
80113
80574
  }
80114
80575
  function keybindingExists2(keybindingsPath) {
80115
- if (!existsSync13(keybindingsPath))
80576
+ if (!existsSync14(keybindingsPath))
80116
80577
  return false;
80117
80578
  try {
80118
80579
  const content = readFileSync5(keybindingsPath, { encoding: "utf-8" });
@@ -80125,7 +80586,7 @@ function keybindingExists2(keybindingsPath) {
80125
80586
  }
80126
80587
  }
80127
80588
  function createBackup2(keybindingsPath) {
80128
- if (!existsSync13(keybindingsPath))
80589
+ if (!existsSync14(keybindingsPath))
80129
80590
  return null;
80130
80591
  const backupPath = `${keybindingsPath}.letta-backup`;
80131
80592
  try {
@@ -80141,12 +80602,12 @@ function installKeybinding2(keybindingsPath) {
80141
80602
  return { success: true, alreadyExists: true };
80142
80603
  }
80143
80604
  const parentDir = dirname12(keybindingsPath);
80144
- if (!existsSync13(parentDir)) {
80145
- mkdirSync5(parentDir, { recursive: true });
80605
+ if (!existsSync14(parentDir)) {
80606
+ mkdirSync6(parentDir, { recursive: true });
80146
80607
  }
80147
80608
  let keybindings = [];
80148
80609
  let backupPath = null;
80149
- if (existsSync13(keybindingsPath)) {
80610
+ if (existsSync14(keybindingsPath)) {
80150
80611
  backupPath = createBackup2(keybindingsPath);
80151
80612
  const content = readFileSync5(keybindingsPath, { encoding: "utf-8" });
80152
80613
  const parsed = parseKeybindings2(content);
@@ -80161,7 +80622,7 @@ function installKeybinding2(keybindingsPath) {
80161
80622
  keybindings.push(SHIFT_ENTER_KEYBINDING2);
80162
80623
  const newContent = `${JSON.stringify(keybindings, null, 2)}
80163
80624
  `;
80164
- writeFileSync4(keybindingsPath, newContent, { encoding: "utf-8" });
80625
+ writeFileSync5(keybindingsPath, newContent, { encoding: "utf-8" });
80165
80626
  return {
80166
80627
  success: true,
80167
80628
  backupPath: backupPath ?? undefined
@@ -80176,7 +80637,7 @@ function installKeybinding2(keybindingsPath) {
80176
80637
  }
80177
80638
  function removeKeybinding2(keybindingsPath) {
80178
80639
  try {
80179
- if (!existsSync13(keybindingsPath)) {
80640
+ if (!existsSync14(keybindingsPath)) {
80180
80641
  return { success: true };
80181
80642
  }
80182
80643
  const content = readFileSync5(keybindingsPath, { encoding: "utf-8" });
@@ -80190,7 +80651,7 @@ function removeKeybinding2(keybindingsPath) {
80190
80651
  const filtered = keybindings.filter((kb) => !(kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus")));
80191
80652
  const newContent = `${JSON.stringify(filtered, null, 2)}
80192
80653
  `;
80193
- writeFileSync4(keybindingsPath, newContent, { encoding: "utf-8" });
80654
+ writeFileSync5(keybindingsPath, newContent, { encoding: "utf-8" });
80194
80655
  return { success: true };
80195
80656
  } catch (error) {
80196
80657
  const message = error instanceof Error ? error.message : String(error);
@@ -80208,14 +80669,14 @@ function installKeybindingForCurrentTerminal2() {
80208
80669
  error: "Not running in a VS Code-like terminal"
80209
80670
  };
80210
80671
  }
80211
- const path20 = getKeybindingsPath2(terminal);
80212
- if (!path20) {
80672
+ const path21 = getKeybindingsPath2(terminal);
80673
+ if (!path21) {
80213
80674
  return {
80214
80675
  success: false,
80215
80676
  error: `Could not determine keybindings.json path for ${terminal}`
80216
80677
  };
80217
80678
  }
80218
- return installKeybinding2(path20);
80679
+ return installKeybinding2(path21);
80219
80680
  }
80220
80681
  function removeKeybindingForCurrentTerminal2() {
80221
80682
  const terminal = detectTerminalType2();
@@ -80225,14 +80686,14 @@ function removeKeybindingForCurrentTerminal2() {
80225
80686
  error: "Not running in a VS Code-like terminal"
80226
80687
  };
80227
80688
  }
80228
- const path20 = getKeybindingsPath2(terminal);
80229
- if (!path20) {
80689
+ const path21 = getKeybindingsPath2(terminal);
80690
+ if (!path21) {
80230
80691
  return {
80231
80692
  success: false,
80232
80693
  error: `Could not determine keybindings.json path for ${terminal}`
80233
80694
  };
80234
80695
  }
80235
- return removeKeybinding2(path20);
80696
+ return removeKeybinding2(path21);
80236
80697
  }
80237
80698
  function isWezTerm2() {
80238
80699
  return process.env.TERM_PROGRAM === "WezTerm";
@@ -80243,17 +80704,17 @@ function getWezTermConfigPath2() {
80243
80704
  }
80244
80705
  const xdgConfig = process.env.XDG_CONFIG_HOME;
80245
80706
  if (xdgConfig) {
80246
- const xdgPath = join21(xdgConfig, "wezterm", "wezterm.lua");
80247
- if (existsSync13(xdgPath))
80707
+ const xdgPath = join22(xdgConfig, "wezterm", "wezterm.lua");
80708
+ if (existsSync14(xdgPath))
80248
80709
  return xdgPath;
80249
80710
  }
80250
- const configPath = join21(homedir12(), ".config", "wezterm", "wezterm.lua");
80251
- if (existsSync13(configPath))
80711
+ const configPath = join22(homedir13(), ".config", "wezterm", "wezterm.lua");
80712
+ if (existsSync14(configPath))
80252
80713
  return configPath;
80253
- return join21(homedir12(), ".wezterm.lua");
80714
+ return join22(homedir13(), ".wezterm.lua");
80254
80715
  }
80255
80716
  function wezTermDeleteFixExists2(configPath) {
80256
- if (!existsSync13(configPath))
80717
+ if (!existsSync14(configPath))
80257
80718
  return false;
80258
80719
  try {
80259
80720
  const content = readFileSync5(configPath, { encoding: "utf-8" });
@@ -80270,7 +80731,7 @@ function installWezTermDeleteFix2() {
80270
80731
  }
80271
80732
  let content = "";
80272
80733
  let backupPath = null;
80273
- if (existsSync13(configPath)) {
80734
+ if (existsSync14(configPath)) {
80274
80735
  backupPath = `${configPath}.letta-backup`;
80275
80736
  copyFileSync2(configPath, backupPath);
80276
80737
  content = readFileSync5(configPath, { encoding: "utf-8" });
@@ -80300,10 +80761,10 @@ ${WEZTERM_DELETE_FIX2}
80300
80761
  `;
80301
80762
  }
80302
80763
  const parentDir = dirname12(configPath);
80303
- if (!existsSync13(parentDir)) {
80304
- mkdirSync5(parentDir, { recursive: true });
80764
+ if (!existsSync14(parentDir)) {
80765
+ mkdirSync6(parentDir, { recursive: true });
80305
80766
  }
80306
- writeFileSync4(configPath, content, { encoding: "utf-8" });
80767
+ writeFileSync5(configPath, content, { encoding: "utf-8" });
80307
80768
  return {
80308
80769
  success: true,
80309
80770
  backupPath: backupPath ?? undefined
@@ -80348,10 +80809,10 @@ __export(exports_settings2, {
80348
80809
  loadProjectSettings: () => loadProjectSettings2,
80349
80810
  getSetting: () => getSetting2
80350
80811
  });
80351
- import { homedir as homedir13 } from "node:os";
80352
- import { join as join22 } from "node:path";
80812
+ import { homedir as homedir14 } from "node:os";
80813
+ import { join as join23 } from "node:path";
80353
80814
  function getSettingsPath2() {
80354
- return join22(homedir13(), ".letta", "settings.json");
80815
+ return join23(homedir14(), ".letta", "settings.json");
80355
80816
  }
80356
80817
  async function loadSettings2() {
80357
80818
  const settingsPath = getSettingsPath2();
@@ -80388,7 +80849,7 @@ async function getSetting2(key) {
80388
80849
  return settings[key];
80389
80850
  }
80390
80851
  function getProjectSettingsPath2() {
80391
- return join22(process.cwd(), ".letta", "settings.local.json");
80852
+ return join23(process.cwd(), ".letta", "settings.local.json");
80392
80853
  }
80393
80854
  async function loadProjectSettings2() {
80394
80855
  const settingsPath = getProjectSettingsPath2();
@@ -80406,7 +80867,7 @@ async function loadProjectSettings2() {
80406
80867
  }
80407
80868
  async function saveProjectSettings2(settings) {
80408
80869
  const settingsPath = getProjectSettingsPath2();
80409
- const dirPath = join22(process.cwd(), ".letta");
80870
+ const dirPath = join23(process.cwd(), ".letta");
80410
80871
  try {
80411
80872
  if (!exists(dirPath)) {
80412
80873
  await mkdir(dirPath, { recursive: true });
@@ -80485,8 +80946,8 @@ var exports_create = {};
80485
80946
  __export(exports_create, {
80486
80947
  createAgent: () => createAgent2
80487
80948
  });
80488
- import { join as join23 } from "node:path";
80489
- async function createAgent2(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingModel = "openai/text-embedding-3-small", updateArgs, skillsDirectory, parallelToolCalls = true, enableSleeptime = false, systemPromptPreset, initBlocks, baseTools) {
80949
+ import { join as join24 } from "node:path";
80950
+ async function createAgent2(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingModel, updateArgs, skillsDirectory, parallelToolCalls = true, enableSleeptime = false, systemPromptPreset, initBlocks, baseTools) {
80490
80951
  let options;
80491
80952
  if (typeof nameOrOptions === "object") {
80492
80953
  options = nameOrOptions;
@@ -80505,7 +80966,7 @@ async function createAgent2(nameOrOptions = DEFAULT_AGENT_NAME, model, embedding
80505
80966
  };
80506
80967
  }
80507
80968
  const name = options.name ?? DEFAULT_AGENT_NAME;
80508
- const embeddingModelVal = options.embeddingModel ?? "openai/text-embedding-3-small";
80969
+ const embeddingModelVal = options.embeddingModel;
80509
80970
  const parallelToolCallsVal = options.parallelToolCalls ?? true;
80510
80971
  const enableSleeptimeVal = options.enableSleeptime ?? false;
80511
80972
  let modelHandle;
@@ -80580,7 +81041,7 @@ async function createAgent2(nameOrOptions = DEFAULT_AGENT_NAME, model, embedding
80580
81041
  }
80581
81042
  }
80582
81043
  }
80583
- const resolvedSkillsDirectory = options.skillsDirectory || join23(process.cwd(), SKILLS_DIR);
81044
+ const resolvedSkillsDirectory = options.skillsDirectory || join24(process.cwd(), SKILLS_DIR);
80584
81045
  try {
80585
81046
  const { skills, errors } = await discoverSkills(resolvedSkillsDirectory);
80586
81047
  if (errors.length > 0) {
@@ -80627,7 +81088,7 @@ ${options.systemPromptAppend}`;
80627
81088
  system: systemPromptContent,
80628
81089
  name,
80629
81090
  description: agentDescription,
80630
- embedding: embeddingModelVal,
81091
+ embedding: embeddingModelVal || undefined,
80631
81092
  model: modelHandle,
80632
81093
  context_window_limit: contextWindow,
80633
81094
  tools: toolNames,
@@ -83416,12 +83877,12 @@ EXAMPLES
83416
83877
  console.log(usage);
83417
83878
  }
83418
83879
  async function printInfo() {
83419
- const { join: join24 } = await import("path");
83880
+ const { join: join25 } = await import("path");
83420
83881
  const { getVersion: getVersion3 } = await Promise.resolve().then(() => (init_version2(), exports_version));
83421
83882
  const { SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills3(), exports_skills2));
83422
83883
  const { exists: exists3 } = await Promise.resolve().then(() => (init_fs2(), exports_fs));
83423
83884
  const cwd2 = process.cwd();
83424
- const skillsDir = join24(cwd2, SKILLS_DIR3);
83885
+ const skillsDir = join25(cwd2, SKILLS_DIR3);
83425
83886
  const skillsExist = exists3(skillsDir);
83426
83887
  await settingsManager2.loadLocalProjectSettings(cwd2);
83427
83888
  const localPinned = settingsManager2.getLocalPinnedAgents(cwd2);
@@ -83560,6 +84021,12 @@ async function main() {
83560
84021
  telemetry2.init();
83561
84022
  const { checkAndAutoUpdate: checkAndAutoUpdate2 } = await Promise.resolve().then(() => (init_auto_update(), exports_auto_update));
83562
84023
  checkAndAutoUpdate2().catch(() => {});
84024
+ const { cleanupOldOverflowFiles: cleanupOldOverflowFiles2 } = await Promise.resolve().then(() => (init_overflow2(), exports_overflow));
84025
+ Promise.resolve().then(() => {
84026
+ try {
84027
+ cleanupOldOverflowFiles2(process.cwd());
84028
+ } catch {}
84029
+ });
83563
84030
  const processedArgs = process.argv.map((arg) => arg === "--conv" ? "--conversation" : arg);
83564
84031
  let values;
83565
84032
  let positionals;
@@ -83599,7 +84066,8 @@ async function main() {
83599
84066
  "include-partial-messages": { type: "boolean" },
83600
84067
  skills: { type: "string" },
83601
84068
  sleeptime: { type: "boolean" },
83602
- "from-af": { type: "string" }
84069
+ "from-af": { type: "string" },
84070
+ "no-skills": { type: "boolean" }
83603
84071
  },
83604
84072
  strict: true,
83605
84073
  allowPositionals: true
@@ -83796,9 +84264,9 @@ Usage: letta --new-agent`);
83796
84264
  process.exit(1);
83797
84265
  }
83798
84266
  const { resolve: resolve21 } = await import("path");
83799
- const { existsSync: existsSync14 } = await import("fs");
84267
+ const { existsSync: existsSync15 } = await import("fs");
83800
84268
  const resolvedPath = resolve21(fromAfFile);
83801
- if (!existsSync14(resolvedPath)) {
84269
+ if (!existsSync15(resolvedPath)) {
83802
84270
  console.error(`Error: AgentFile not found: ${resolvedPath}`);
83803
84271
  process.exit(1);
83804
84272
  }
@@ -84300,8 +84768,8 @@ Error: ${message}`);
84300
84768
  (async () => {
84301
84769
  try {
84302
84770
  const { syncSkillsToAgent: syncSkillsToAgent3, SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills3(), exports_skills2));
84303
- const { join: join24 } = await import("path");
84304
- const resolvedSkillsDirectory = skillsDirectory2 || join24(process.cwd(), SKILLS_DIR3);
84771
+ const { join: join25 } = await import("path");
84772
+ const resolvedSkillsDirectory = skillsDirectory2 || join25(process.cwd(), SKILLS_DIR3);
84305
84773
  await syncSkillsToAgent3(client, agent.id, resolvedSkillsDirectory, {
84306
84774
  skipIfUnchanged: true
84307
84775
  });
@@ -84542,4 +85010,4 @@ Error during initialization: ${message}`);
84542
85010
  }
84543
85011
  main();
84544
85012
 
84545
- //# debugId=0420C9226EBBB2BA64756E2164756E21
85013
+ //# debugId=A2D04DEC6336411264756E2164756E21