@letta-ai/letta-code 0.16.15 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/letta.js +1620 -743
  3. package/package.json +2 -2
package/letta.js CHANGED
@@ -342,7 +342,7 @@ var init_values = __esm(() => {
342
342
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
343
343
 
344
344
  // node_modules/@letta-ai/letta-client/version.mjs
345
- var VERSION = "1.7.9";
345
+ var VERSION = "1.7.11";
346
346
 
347
347
  // node_modules/@letta-ai/letta-client/internal/detect-platform.mjs
348
348
  function getDetectedPlatform() {
@@ -868,9 +868,11 @@ var init_stringify = __esm(() => {
868
868
  sentinel = {};
869
869
  });
870
870
 
871
- // node_modules/@letta-ai/letta-client/internal/qs/index.mjs
872
- var init_qs = __esm(() => {
873
- init_formats();
871
+ // node_modules/@letta-ai/letta-client/internal/utils/query.mjs
872
+ function stringifyQuery(query) {
873
+ return stringify(query, { allowDots: true, arrayFormat: "repeat" });
874
+ }
875
+ var init_query = __esm(() => {
874
876
  init_stringify();
875
877
  });
876
878
 
@@ -2273,8 +2275,12 @@ var init_conversations = __esm(() => {
2273
2275
  delete(conversationID, options) {
2274
2276
  return this._client.delete(path`/v1/conversations/${conversationID}`, options);
2275
2277
  }
2276
- cancel(conversationID, options) {
2277
- return this._client.post(path`/v1/conversations/${conversationID}/cancel`, options);
2278
+ cancel(conversationID, params = {}, options) {
2279
+ const { agent_id } = params ?? {};
2280
+ return this._client.post(path`/v1/conversations/${conversationID}/cancel`, {
2281
+ query: { agent_id },
2282
+ ...options
2283
+ });
2278
2284
  }
2279
2285
  };
2280
2286
  Conversations.Messages = Messages2;
@@ -2841,7 +2847,7 @@ class Letta {
2841
2847
  return buildHeaders([{ Authorization: `Bearer ${this.apiKey}` }]);
2842
2848
  }
2843
2849
  stringifyQuery(query) {
2844
- return stringify(query, { allowDots: true, arrayFormat: "repeat" });
2850
+ return stringifyQuery(query);
2845
2851
  }
2846
2852
  getUserAgent() {
2847
2853
  return `${this.constructor.name}/JS ${VERSION}`;
@@ -3137,7 +3143,7 @@ var init_client = __esm(() => {
3137
3143
  init_tslib();
3138
3144
  init_values();
3139
3145
  init_detect_platform();
3140
- init_qs();
3146
+ init_query();
3141
3147
  init_error();
3142
3148
  init_pagination();
3143
3149
  init_uploads2();
@@ -3216,7 +3222,7 @@ var package_default;
3216
3222
  var init_package = __esm(() => {
3217
3223
  package_default = {
3218
3224
  name: "@letta-ai/letta-code",
3219
- version: "0.16.15",
3225
+ version: "0.17.1",
3220
3226
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
3221
3227
  type: "module",
3222
3228
  bin: {
@@ -3249,7 +3255,7 @@ var init_package = __esm(() => {
3249
3255
  access: "public"
3250
3256
  },
3251
3257
  dependencies: {
3252
- "@letta-ai/letta-client": "^1.7.9",
3258
+ "@letta-ai/letta-client": "^1.7.11",
3253
3259
  glob: "^13.0.0",
3254
3260
  "ink-link": "^5.0.0",
3255
3261
  open: "^10.2.0",
@@ -4695,6 +4701,12 @@ var approval_recovery_alert_default = `<system-reminder>Automated keep-alive pin
4695
4701
  `;
4696
4702
  var init_approval_recovery_alert = () => {};
4697
4703
 
4704
+ // src/agent/prompts/auto_init_reminder.txt
4705
+ var auto_init_reminder_default = `<system-reminder>
4706
+ A background agent is initializing this agent's memory system. Briefly let the user know that memory is being set up in the background, then respond to their message normally.
4707
+ </system-reminder>`;
4708
+ var init_auto_init_reminder = () => {};
4709
+
4698
4710
  // src/agent/prompts/claude.md
4699
4711
  var claude_default = `You are Letta Code, a state-of-the-art coding agent running within the Letta Code CLI on a user's computer.
4700
4712
  You are an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.
@@ -7182,6 +7194,7 @@ __export(exports_promptAssets, {
7182
7194
  MEMORY_PROMPTS: () => MEMORY_PROMPTS,
7183
7195
  MEMORY_CHECK_REMINDER: () => MEMORY_CHECK_REMINDER,
7184
7196
  INTERRUPT_RECOVERY_ALERT: () => INTERRUPT_RECOVERY_ALERT,
7197
+ AUTO_INIT_REMINDER: () => AUTO_INIT_REMINDER,
7185
7198
  APPROVAL_RECOVERY_PROMPT: () => APPROVAL_RECOVERY_PROMPT
7186
7199
  });
7187
7200
  async function resolveSystemPrompt(systemPromptPreset) {
@@ -7200,9 +7213,10 @@ async function resolveSystemPrompt(systemPromptPreset) {
7200
7213
  }
7201
7214
  return SYSTEM_PROMPT;
7202
7215
  }
7203
- var SYSTEM_PROMPT, SYSTEM_PROMPT_MEMORY_ADDON, SYSTEM_PROMPT_MEMFS_ADDON, PLAN_MODE_REMINDER, SKILL_CREATOR_PROMPT, REMEMBER_PROMPT, MEMORY_CHECK_REMINDER, MEMORY_REFLECTION_REMINDER, APPROVAL_RECOVERY_PROMPT, INTERRUPT_RECOVERY_ALERT, MEMORY_PROMPTS, SYSTEM_PROMPTS;
7216
+ var SYSTEM_PROMPT, SYSTEM_PROMPT_MEMORY_ADDON, SYSTEM_PROMPT_MEMFS_ADDON, PLAN_MODE_REMINDER, SKILL_CREATOR_PROMPT, REMEMBER_PROMPT, MEMORY_CHECK_REMINDER, MEMORY_REFLECTION_REMINDER, APPROVAL_RECOVERY_PROMPT, AUTO_INIT_REMINDER, INTERRUPT_RECOVERY_ALERT, MEMORY_PROMPTS, SYSTEM_PROMPTS;
7204
7217
  var init_promptAssets = __esm(() => {
7205
7218
  init_approval_recovery_alert();
7219
+ init_auto_init_reminder();
7206
7220
  init_claude();
7207
7221
  init_codex();
7208
7222
  init_gemini();
@@ -7235,6 +7249,7 @@ var init_promptAssets = __esm(() => {
7235
7249
  MEMORY_CHECK_REMINDER = memory_check_reminder_default;
7236
7250
  MEMORY_REFLECTION_REMINDER = memory_reflection_reminder_default;
7237
7251
  APPROVAL_RECOVERY_PROMPT = approval_recovery_alert_default;
7252
+ AUTO_INIT_REMINDER = auto_init_reminder_default;
7238
7253
  INTERRUPT_RECOVERY_ALERT = interrupt_recovery_alert_default;
7239
7254
  MEMORY_PROMPTS = {
7240
7255
  "persona.mdx": persona_default,
@@ -7301,6 +7316,20 @@ var init_promptAssets = __esm(() => {
7301
7316
  var models_default;
7302
7317
  var init_models2 = __esm(() => {
7303
7318
  models_default = [
7319
+ {
7320
+ id: "auto",
7321
+ handle: "letta/auto",
7322
+ label: "Auto (Beta)",
7323
+ description: "Automatically select the best model",
7324
+ isFeatured: true
7325
+ },
7326
+ {
7327
+ id: "auto-fast",
7328
+ handle: "letta/auto-fast",
7329
+ label: "Auto Fast (Beta)",
7330
+ description: "Automatically select the best fast model",
7331
+ isFeatured: true
7332
+ },
7304
7333
  {
7305
7334
  id: "sonnet",
7306
7335
  handle: "anthropic/claude-sonnet-4-6",
@@ -7370,6 +7399,19 @@ var init_models2 = __esm(() => {
7370
7399
  parallel_tool_calls: true
7371
7400
  }
7372
7401
  },
7402
+ {
7403
+ id: "sonnet-4.6-xhigh",
7404
+ handle: "anthropic/claude-sonnet-4-6",
7405
+ label: "Sonnet 4.6",
7406
+ description: "Sonnet 4.6 (max reasoning)",
7407
+ updateArgs: {
7408
+ context_window: 200000,
7409
+ max_output_tokens: 128000,
7410
+ reasoning_effort: "xhigh",
7411
+ enable_reasoner: true,
7412
+ parallel_tool_calls: true
7413
+ }
7414
+ },
7373
7415
  {
7374
7416
  id: "sonnet-4.5",
7375
7417
  handle: "anthropic/claude-sonnet-4-5-20250929",
@@ -7449,18 +7491,74 @@ var init_models2 = __esm(() => {
7449
7491
  parallel_tool_calls: true
7450
7492
  }
7451
7493
  },
7494
+ {
7495
+ id: "opus-4.6-xhigh",
7496
+ handle: "anthropic/claude-opus-4-6",
7497
+ label: "Opus 4.6",
7498
+ description: "Opus 4.6 (max reasoning)",
7499
+ updateArgs: {
7500
+ context_window: 200000,
7501
+ max_output_tokens: 128000,
7502
+ reasoning_effort: "xhigh",
7503
+ enable_reasoner: true,
7504
+ parallel_tool_calls: true
7505
+ }
7506
+ },
7452
7507
  {
7453
7508
  id: "opus-4.5",
7454
7509
  handle: "anthropic/claude-opus-4-5-20251101",
7455
7510
  label: "Opus 4.5",
7456
- description: "Anthropic's (legacy) best model",
7511
+ description: "Anthropic's (legacy) best model (high reasoning)",
7457
7512
  updateArgs: {
7458
7513
  context_window: 180000,
7459
7514
  max_output_tokens: 64000,
7515
+ reasoning_effort: "high",
7516
+ enable_reasoner: true,
7460
7517
  max_reasoning_tokens: 31999,
7461
7518
  parallel_tool_calls: true
7462
7519
  }
7463
7520
  },
7521
+ {
7522
+ id: "opus-4.5-no-reasoning",
7523
+ handle: "anthropic/claude-opus-4-5-20251101",
7524
+ label: "Opus 4.5",
7525
+ description: "Opus 4.5 with no reasoning (faster)",
7526
+ updateArgs: {
7527
+ context_window: 180000,
7528
+ max_output_tokens: 64000,
7529
+ reasoning_effort: "none",
7530
+ enable_reasoner: false,
7531
+ parallel_tool_calls: true
7532
+ }
7533
+ },
7534
+ {
7535
+ id: "opus-4.5-low",
7536
+ handle: "anthropic/claude-opus-4-5-20251101",
7537
+ label: "Opus 4.5",
7538
+ description: "Opus 4.5 (low reasoning)",
7539
+ updateArgs: {
7540
+ context_window: 180000,
7541
+ max_output_tokens: 64000,
7542
+ reasoning_effort: "low",
7543
+ enable_reasoner: true,
7544
+ max_reasoning_tokens: 4000,
7545
+ parallel_tool_calls: true
7546
+ }
7547
+ },
7548
+ {
7549
+ id: "opus-4.5-medium",
7550
+ handle: "anthropic/claude-opus-4-5-20251101",
7551
+ label: "Opus 4.5",
7552
+ description: "Opus 4.5 (med reasoning)",
7553
+ updateArgs: {
7554
+ context_window: 180000,
7555
+ max_output_tokens: 64000,
7556
+ reasoning_effort: "medium",
7557
+ enable_reasoner: true,
7558
+ max_reasoning_tokens: 12000,
7559
+ parallel_tool_calls: true
7560
+ }
7561
+ },
7464
7562
  {
7465
7563
  id: "bedrock-opus",
7466
7564
  handle: "bedrock/us.anthropic.claude-opus-4-5-20251101-v1:0",
@@ -7810,6 +7908,72 @@ var init_models2 = __esm(() => {
7810
7908
  parallel_tool_calls: true
7811
7909
  }
7812
7910
  },
7911
+ {
7912
+ id: "gpt-5.4-none",
7913
+ handle: "openai/gpt-5.4",
7914
+ label: "GPT-5.4",
7915
+ description: "OpenAI's most capable model (no reasoning)",
7916
+ updateArgs: {
7917
+ reasoning_effort: "none",
7918
+ verbosity: "medium",
7919
+ context_window: 272000,
7920
+ max_output_tokens: 128000,
7921
+ parallel_tool_calls: true
7922
+ }
7923
+ },
7924
+ {
7925
+ id: "gpt-5.4-low",
7926
+ handle: "openai/gpt-5.4",
7927
+ label: "GPT-5.4",
7928
+ description: "OpenAI's most capable model (low reasoning)",
7929
+ updateArgs: {
7930
+ reasoning_effort: "low",
7931
+ verbosity: "medium",
7932
+ context_window: 272000,
7933
+ max_output_tokens: 128000,
7934
+ parallel_tool_calls: true
7935
+ }
7936
+ },
7937
+ {
7938
+ id: "gpt-5.4-medium",
7939
+ handle: "openai/gpt-5.4",
7940
+ label: "GPT-5.4",
7941
+ description: "OpenAI's most capable model (med reasoning)",
7942
+ updateArgs: {
7943
+ reasoning_effort: "medium",
7944
+ verbosity: "medium",
7945
+ context_window: 272000,
7946
+ max_output_tokens: 128000,
7947
+ parallel_tool_calls: true
7948
+ }
7949
+ },
7950
+ {
7951
+ id: "gpt-5.4-high",
7952
+ handle: "openai/gpt-5.4",
7953
+ label: "GPT-5.4",
7954
+ description: "OpenAI's most capable model (high reasoning)",
7955
+ isFeatured: true,
7956
+ updateArgs: {
7957
+ reasoning_effort: "high",
7958
+ verbosity: "medium",
7959
+ context_window: 272000,
7960
+ max_output_tokens: 128000,
7961
+ parallel_tool_calls: true
7962
+ }
7963
+ },
7964
+ {
7965
+ id: "gpt-5.4-xhigh",
7966
+ handle: "openai/gpt-5.4",
7967
+ label: "GPT-5.4",
7968
+ description: "OpenAI's most capable model (max reasoning)",
7969
+ updateArgs: {
7970
+ reasoning_effort: "xhigh",
7971
+ verbosity: "medium",
7972
+ context_window: 272000,
7973
+ max_output_tokens: 128000,
7974
+ parallel_tool_calls: true
7975
+ }
7976
+ },
7813
7977
  {
7814
7978
  id: "gpt-5.3-codex-none",
7815
7979
  handle: "openai/gpt-5.3-codex",
@@ -8458,7 +8622,7 @@ function getDefaultModel() {
8458
8622
  }
8459
8623
  function getDefaultModelForTier(billingTier) {
8460
8624
  if (billingTier?.toLowerCase() === "free") {
8461
- const freeDefault = models.find((m) => m.id === "minimax-m2.5");
8625
+ const freeDefault = models.find((m) => m.id === "glm-5");
8462
8626
  if (freeDefault)
8463
8627
  return freeDefault.handle;
8464
8628
  }
@@ -34613,6 +34777,27 @@ var init_MarkdownDisplay = __esm(async () => {
34613
34777
  defaultHeaderStyle = { italic: true };
34614
34778
  });
34615
34779
 
34780
+ // src/cli/helpers/appUrls.ts
34781
+ function buildChatUrl(agentId, options) {
34782
+ const base2 = `${APP_BASE}/chat/${agentId}`;
34783
+ const params = new URLSearchParams;
34784
+ if (options?.view) {
34785
+ params.set("view", options.view);
34786
+ }
34787
+ if (options?.deviceId) {
34788
+ params.set("deviceId", options.deviceId);
34789
+ }
34790
+ if (options?.conversationId && options.conversationId !== "default") {
34791
+ params.set("conversation", options.conversationId);
34792
+ }
34793
+ const qs = params.toString();
34794
+ return qs ? `${base2}?${qs}` : base2;
34795
+ }
34796
+ function buildAppUrl(path2) {
34797
+ return `${APP_BASE}${path2}`;
34798
+ }
34799
+ var APP_BASE = "https://app.letta.com";
34800
+
34616
34801
  // src/cli/helpers/errorContext.ts
34617
34802
  function setErrorContext(context2) {
34618
34803
  currentContext = { ...currentContext, ...context2 };
@@ -34740,7 +34925,7 @@ function getDefaultModel2() {
34740
34925
  }
34741
34926
  function getDefaultModelForTier2(billingTier) {
34742
34927
  if (billingTier?.toLowerCase() === "free") {
34743
- const freeDefault = models2.find((m) => m.id === "minimax-m2.5");
34928
+ const freeDefault = models2.find((m) => m.id === "glm-5");
34744
34929
  if (freeDefault)
34745
34930
  return freeDefault.handle;
34746
34931
  }
@@ -60259,6 +60444,15 @@ async function getPrimaryAgentModelHandle() {
60259
60444
  return null;
60260
60445
  }
60261
60446
  }
60447
+ async function getCurrentBillingTier() {
60448
+ try {
60449
+ const client = await getClient2();
60450
+ const balance = await client.get("/v1/metadata/balance");
60451
+ return balance.billing_tier ?? null;
60452
+ } catch {
60453
+ return null;
60454
+ }
60455
+ }
60262
60456
  function isProviderNotSupportedError(errorOutput) {
60263
60457
  return errorOutput.includes("Provider") && errorOutput.includes("is not supported") && errorOutput.includes("supported providers:");
60264
60458
  }
@@ -60282,13 +60476,16 @@ function swapProviderPrefix(parentHandle, recommendedHandle) {
60282
60476
  return `${parentProvider}/${modelPortion}`;
60283
60477
  }
60284
60478
  async function resolveSubagentModel(options) {
60285
- const { userModel, recommendedModel, parentModelHandle } = options;
60479
+ const { userModel, recommendedModel, parentModelHandle, billingTier } = options;
60286
60480
  if (userModel)
60287
60481
  return userModel;
60288
60482
  let recommendedHandle = null;
60289
60483
  if (recommendedModel && recommendedModel !== "inherit") {
60290
60484
  recommendedHandle = resolveModel2(recommendedModel);
60291
60485
  }
60486
+ if (recommendedModel !== "inherit" && billingTier?.toLowerCase() === "free") {
60487
+ recommendedHandle = getDefaultModelForTier2(billingTier);
60488
+ }
60292
60489
  let availableHandles = options.availableHandles ?? null;
60293
60490
  const isAvailable = async (handle) => {
60294
60491
  try {
@@ -60492,6 +60689,7 @@ function buildSubagentArgs(type, config, model, userPrompt, existingAgentId, exi
60492
60689
  }
60493
60690
  } else {
60494
60691
  args.push("--new-agent", "--system", type);
60692
+ args.push("--tags", `type:${type}`);
60495
60693
  if (model) {
60496
60694
  args.push("--model", model);
60497
60695
  }
@@ -60690,10 +60888,12 @@ async function spawnSubagent(type, prompt, userModel, subagentId, signal, existi
60690
60888
  }
60691
60889
  const isDeployingExisting = Boolean(existingAgentId || existingConversationId);
60692
60890
  const parentModelHandle = await getPrimaryAgentModelHandle();
60891
+ const billingTier = await getCurrentBillingTier();
60693
60892
  const model = isDeployingExisting ? null : await resolveSubagentModel({
60694
60893
  userModel,
60695
60894
  recommendedModel: config.recommendedModel,
60696
- parentModelHandle
60895
+ parentModelHandle,
60896
+ billingTier
60697
60897
  });
60698
60898
  const baseURL = getBaseURL();
60699
60899
  let finalPrompt = prompt;
@@ -65671,7 +65871,7 @@ async function loadSpecificTools(toolNames) {
65671
65871
  releaseSwitchLock();
65672
65872
  }
65673
65873
  }
65674
- async function loadTools(modelIdentifier) {
65874
+ async function loadTools(modelIdentifier, options) {
65675
65875
  acquireSwitchLock();
65676
65876
  try {
65677
65877
  const { toolFilter: toolFilter2 } = await Promise.resolve().then(() => (init_filter(), exports_filter));
@@ -65692,6 +65892,10 @@ async function loadTools(modelIdentifier) {
65692
65892
  } else {
65693
65893
  baseToolNames = TOOL_NAMES;
65694
65894
  }
65895
+ if (options?.exclude && options.exclude.length > 0) {
65896
+ const excludeSet = new Set(options.exclude);
65897
+ baseToolNames = baseToolNames.filter((name) => !excludeSet.has(name));
65898
+ }
65695
65899
  const newRegistry = new Map;
65696
65900
  for (const name of baseToolNames) {
65697
65901
  if (!toolFilter2.isEnabled(name)) {
@@ -66473,340 +66677,6 @@ var init_approval_execution = __esm(async () => {
66473
66677
  ]);
66474
66678
  });
66475
66679
 
66476
- // src/agent/check-approval.ts
66477
- var exports_check_approval = {};
66478
- __export(exports_check_approval, {
66479
- prepareMessageHistory: () => prepareMessageHistory2,
66480
- getResumeData: () => getResumeData2,
66481
- extractApprovals: () => extractApprovals2
66482
- });
66483
- function isPrimaryMessageType2(messageType) {
66484
- return messageType === "user_message" || messageType === "assistant_message" || messageType === "event_message" || messageType === "summary_message";
66485
- }
66486
- function isAnchorMessageType2(messageType) {
66487
- return messageType === "user_message" || messageType === "assistant_message";
66488
- }
66489
- function isBackfillEnabled2() {
66490
- const val = process.env.LETTA_BACKFILL;
66491
- return val !== "0" && val !== "false";
66492
- }
66493
- function extractApprovals2(messageToCheck) {
66494
- const approvalMsg = messageToCheck;
66495
- const toolCalls = Array.isArray(approvalMsg.tool_calls) ? approvalMsg.tool_calls : approvalMsg.tool_call ? [approvalMsg.tool_call] : [];
66496
- const pendingApprovals = toolCalls.filter((tc) => !!tc && !!tc.tool_call_id).map((tc) => ({
66497
- toolCallId: tc.tool_call_id,
66498
- toolName: tc.name || "",
66499
- toolArgs: tc.arguments || ""
66500
- }));
66501
- const pendingApproval = pendingApprovals[0] || null;
66502
- if (pendingApprovals.length > 0) {
66503
- debugWarn("check-approval", `Found ${pendingApprovals.length} pending approval(s): ${pendingApprovals.map((a) => a.toolName).join(", ")}`);
66504
- }
66505
- return { pendingApproval, pendingApprovals };
66506
- }
66507
- function prepareMessageHistory2(messages, opts) {
66508
- const isRenderable = (msg) => {
66509
- const t = msg.message_type;
66510
- if (t === "user_message" || t === "assistant_message" || t === "reasoning_message" || t === "tool_call_message" || t === "tool_return_message" || t === "approval_request_message" || t === "approval_response_message") {
66511
- return true;
66512
- }
66513
- const ts = t;
66514
- return ts === "event_message" || ts === "summary_message";
66515
- };
66516
- const renderable = messages.filter(isRenderable);
66517
- if (opts?.primaryOnly) {
66518
- const convo = renderable.filter((m) => isPrimaryMessageType2(m.message_type));
66519
- let trimmed = convo.slice(-BACKFILL_PRIMARY_MESSAGE_LIMIT2);
66520
- const hasAssistant = trimmed.some((m) => m.message_type === "assistant_message");
66521
- if (!hasAssistant) {
66522
- const lastAssistantIndex = convo.map((m) => m.message_type).lastIndexOf("assistant_message");
66523
- if (lastAssistantIndex >= 0) {
66524
- const lastAssistant = convo[lastAssistantIndex];
66525
- if (lastAssistant) {
66526
- const tailLimit = Math.max(BACKFILL_PRIMARY_MESSAGE_LIMIT2 - 1, 0);
66527
- const newestTail = tailLimit > 0 ? convo.slice(-tailLimit) : [];
66528
- trimmed = [lastAssistant, ...newestTail];
66529
- }
66530
- }
66531
- }
66532
- if (trimmed.length > 0)
66533
- return trimmed;
66534
- const reasoning = renderable.filter((m) => m.message_type === "reasoning_message");
66535
- if (reasoning.length > 0) {
66536
- return reasoning.slice(-BACKFILL_PRIMARY_MESSAGE_LIMIT2);
66537
- }
66538
- return [];
66539
- }
66540
- const isPrimary = (msg) => {
66541
- const t = msg.message_type;
66542
- return t === "user_message" || t === "assistant_message" || t === "reasoning_message" || t === "event_message" || t === "summary_message";
66543
- };
66544
- let primaryCount = 0;
66545
- let startIndex = Math.max(0, renderable.length - 1);
66546
- for (let i = renderable.length - 1;i >= 0; i -= 1) {
66547
- const msg = renderable[i];
66548
- if (!msg)
66549
- continue;
66550
- if (isPrimary(msg)) {
66551
- primaryCount += 1;
66552
- if (primaryCount >= BACKFILL_PRIMARY_MESSAGE_LIMIT2) {
66553
- startIndex = i;
66554
- break;
66555
- }
66556
- }
66557
- startIndex = i;
66558
- }
66559
- let messageHistory = renderable.slice(startIndex);
66560
- if (messageHistory.length > BACKFILL_MAX_RENDERABLE_MESSAGES2) {
66561
- messageHistory = messageHistory.slice(-BACKFILL_MAX_RENDERABLE_MESSAGES2);
66562
- }
66563
- if (messageHistory[0]?.message_type === "tool_return_message") {
66564
- messageHistory = messageHistory.slice(1);
66565
- }
66566
- return messageHistory;
66567
- }
66568
- function sortChronological2(messages) {
66569
- return [...messages].sort((a, b) => {
66570
- const ta = a.date ? new Date(a.date).getTime() : 0;
66571
- const tb = b.date ? new Date(b.date).getTime() : 0;
66572
- if (!Number.isFinite(ta) && !Number.isFinite(tb))
66573
- return 0;
66574
- if (!Number.isFinite(ta))
66575
- return -1;
66576
- if (!Number.isFinite(tb))
66577
- return 1;
66578
- return ta - tb;
66579
- });
66580
- }
66581
- async function fetchConversationBackfillMessages2(client, conversationId) {
66582
- const collected = [];
66583
- const seen = new Set;
66584
- let cursorBefore = null;
66585
- let assistantCount = 0;
66586
- let anchorCount = 0;
66587
- for (let pageIndex = 0;pageIndex < BACKFILL_MAX_PAGES2; pageIndex += 1) {
66588
- const page = await client.conversations.messages.list(conversationId, {
66589
- limit: BACKFILL_PAGE_LIMIT2,
66590
- order: "desc",
66591
- ...cursorBefore ? { before: cursorBefore } : {}
66592
- });
66593
- const items = page.getPaginatedItems();
66594
- if (items.length === 0)
66595
- break;
66596
- cursorBefore = items[items.length - 1]?.id ?? null;
66597
- for (const m of items) {
66598
- if (!m?.id)
66599
- continue;
66600
- const key = "otid" in m && m.otid ? `otid:${String(m.otid)}` : `id:${m.id}:${m.message_type ?? ""}`;
66601
- if (seen.has(key))
66602
- continue;
66603
- seen.add(key);
66604
- collected.push(m);
66605
- if (m.message_type === "assistant_message")
66606
- assistantCount += 1;
66607
- if (isAnchorMessageType2(m.message_type))
66608
- anchorCount += 1;
66609
- }
66610
- if (assistantCount >= BACKFILL_MIN_ASSISTANT2 && anchorCount >= BACKFILL_ANCHOR_MESSAGE_LIMIT2) {
66611
- break;
66612
- }
66613
- if (items.length < BACKFILL_PAGE_LIMIT2)
66614
- break;
66615
- }
66616
- if (assistantCount < BACKFILL_MIN_ASSISTANT2) {
66617
- debugWarn("check-approval", `Backfill scan found 0 assistant messages in last ${collected.length} messages (tool-heavy conversation?)`);
66618
- }
66619
- return sortChronological2(collected);
66620
- }
66621
- async function getResumeData2(client, agent, conversationId, options = {}) {
66622
- try {
66623
- const includeMessageHistory = options.includeMessageHistory ?? true;
66624
- let inContextMessageIds;
66625
- let messages = [];
66626
- const useConversationsApi = conversationId && conversationId !== "default";
66627
- if (process.env.DEBUG) {
66628
- console.log(`[DEBUG] getResumeData: conversationId=${conversationId}, useConversationsApi=${useConversationsApi}, agentId=${agent.id}`);
66629
- }
66630
- if (useConversationsApi) {
66631
- const conversation = await client.conversations.retrieve(conversationId);
66632
- inContextMessageIds = conversation.in_context_message_ids;
66633
- if (!inContextMessageIds || inContextMessageIds.length === 0) {
66634
- debugWarn("check-approval", "No in-context messages - no pending approvals");
66635
- if (includeMessageHistory && isBackfillEnabled2()) {
66636
- try {
66637
- const backfill = await fetchConversationBackfillMessages2(client, conversationId);
66638
- return {
66639
- pendingApproval: null,
66640
- pendingApprovals: [],
66641
- messageHistory: prepareMessageHistory2(backfill, {
66642
- primaryOnly: true
66643
- })
66644
- };
66645
- } catch (backfillError) {
66646
- debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
66647
- }
66648
- }
66649
- return {
66650
- pendingApproval: null,
66651
- pendingApprovals: [],
66652
- messageHistory: []
66653
- };
66654
- }
66655
- const lastInContextId = inContextMessageIds.at(-1);
66656
- if (!lastInContextId) {
66657
- throw new Error("Expected at least one in-context message");
66658
- }
66659
- const retrievedMessages = await client.messages.retrieve(lastInContextId);
66660
- if (includeMessageHistory && isBackfillEnabled2()) {
66661
- try {
66662
- messages = await fetchConversationBackfillMessages2(client, conversationId);
66663
- } catch (backfillError) {
66664
- debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
66665
- }
66666
- }
66667
- const messageToCheck = retrievedMessages.find((msg) => msg.message_type === "approval_request_message") ?? retrievedMessages[0];
66668
- if (messageToCheck) {
66669
- debugWarn("check-approval", `Found last in-context message: ${messageToCheck.id} (type: ${messageToCheck.message_type})` + (retrievedMessages.length > 1 ? ` - had ${retrievedMessages.length} variants` : ""));
66670
- if (messageToCheck.message_type === "approval_request_message") {
66671
- const { pendingApproval, pendingApprovals } = extractApprovals2(messageToCheck);
66672
- return {
66673
- pendingApproval,
66674
- pendingApprovals,
66675
- messageHistory: prepareMessageHistory2(messages, {
66676
- primaryOnly: true
66677
- })
66678
- };
66679
- }
66680
- } else {
66681
- debugWarn("check-approval", `Last in-context message ${lastInContextId} not found via retrieve`);
66682
- }
66683
- return {
66684
- pendingApproval: null,
66685
- pendingApprovals: [],
66686
- messageHistory: prepareMessageHistory2(messages, { primaryOnly: true })
66687
- };
66688
- } else {
66689
- inContextMessageIds = agent.message_ids;
66690
- if (!inContextMessageIds || inContextMessageIds.length === 0) {
66691
- debugWarn("check-approval", "No in-context messages (default/agent API) - no pending approvals");
66692
- return {
66693
- pendingApproval: null,
66694
- pendingApprovals: [],
66695
- messageHistory: []
66696
- };
66697
- }
66698
- const lastInContextId = inContextMessageIds.at(-1);
66699
- if (!lastInContextId) {
66700
- throw new Error("Expected at least one in-context message");
66701
- }
66702
- const retrievedMessages = await client.messages.retrieve(lastInContextId);
66703
- if (includeMessageHistory && isBackfillEnabled2()) {
66704
- try {
66705
- const messagesPage = await client.conversations.messages.list(agent.id, {
66706
- limit: BACKFILL_PAGE_LIMIT2,
66707
- order: "desc"
66708
- });
66709
- messages = sortChronological2(messagesPage.getPaginatedItems());
66710
- if (process.env.DEBUG) {
66711
- console.log(`[DEBUG] conversations.messages.list(${agent.id}) returned ${messages.length} messages`);
66712
- }
66713
- } catch (backfillError) {
66714
- debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
66715
- }
66716
- }
66717
- const messageToCheck = retrievedMessages.find((msg) => msg.message_type === "approval_request_message") ?? retrievedMessages[0];
66718
- if (messageToCheck) {
66719
- debugWarn("check-approval", `Found last in-context message: ${messageToCheck.id} (type: ${messageToCheck.message_type})` + (retrievedMessages.length > 1 ? ` - had ${retrievedMessages.length} variants` : ""));
66720
- if (messageToCheck.message_type === "approval_request_message") {
66721
- const { pendingApproval, pendingApprovals } = extractApprovals2(messageToCheck);
66722
- return {
66723
- pendingApproval,
66724
- pendingApprovals,
66725
- messageHistory: prepareMessageHistory2(messages, {
66726
- primaryOnly: true
66727
- })
66728
- };
66729
- }
66730
- } else {
66731
- debugWarn("check-approval", `Last in-context message ${lastInContextId} not found via retrieve (default/agent API)`);
66732
- }
66733
- return {
66734
- pendingApproval: null,
66735
- pendingApprovals: [],
66736
- messageHistory: prepareMessageHistory2(messages, { primaryOnly: true })
66737
- };
66738
- }
66739
- } catch (error) {
66740
- if (error instanceof APIError2 && (error.status === 404 || error.status === 422)) {
66741
- throw error;
66742
- }
66743
- console.error("Error getting resume data:", error);
66744
- return { pendingApproval: null, pendingApprovals: [], messageHistory: [] };
66745
- }
66746
- }
66747
- var BACKFILL_PRIMARY_MESSAGE_LIMIT2 = 12, BACKFILL_MAX_RENDERABLE_MESSAGES2 = 80, BACKFILL_ANCHOR_MESSAGE_LIMIT2 = 6, BACKFILL_PAGE_LIMIT2 = 200, BACKFILL_MAX_PAGES2 = 25, BACKFILL_MIN_ASSISTANT2 = 1;
66748
- var init_check_approval = __esm(() => {
66749
- init_error();
66750
- init_debug();
66751
- });
66752
-
66753
- // src/agent/message.ts
66754
- function getStreamRequestStartTime(stream2) {
66755
- return streamRequestStartTimes.get(stream2);
66756
- }
66757
- function getStreamToolContextId(stream2) {
66758
- return streamToolContextIds.get(stream2) ?? null;
66759
- }
66760
- function getStreamRequestContext(stream2) {
66761
- return streamRequestContexts.get(stream2);
66762
- }
66763
- async function sendMessageStream(conversationId, messages, opts = { streamTokens: true, background: true }, requestOptions = {
66764
- maxRetries: 0
66765
- }) {
66766
- const requestStartTime = isTimingsEnabled() ? performance.now() : undefined;
66767
- const requestStartedAtMs = Date.now();
66768
- const client = await getClient2();
66769
- await waitForToolsetReady();
66770
- const { clientTools, contextId } = captureToolExecutionContext();
66771
- const resolvedConversationId = conversationId === "default" ? opts.agentId : conversationId;
66772
- if (!resolvedConversationId) {
66773
- throw new Error("agentId is required in opts when using default conversation");
66774
- }
66775
- if (process.env.DEBUG) {
66776
- console.log(`[DEBUG] sendMessageStream: conversationId=${conversationId}, resolved=${resolvedConversationId}`);
66777
- }
66778
- const stream2 = await client.conversations.messages.create(resolvedConversationId, {
66779
- messages,
66780
- streaming: true,
66781
- stream_tokens: opts.streamTokens ?? true,
66782
- background: opts.background ?? true,
66783
- client_tools: clientTools,
66784
- include_compaction_messages: true
66785
- }, requestOptions);
66786
- if (requestStartTime !== undefined) {
66787
- streamRequestStartTimes.set(stream2, requestStartTime);
66788
- }
66789
- streamToolContextIds.set(stream2, contextId);
66790
- streamRequestContexts.set(stream2, {
66791
- conversationId,
66792
- resolvedConversationId,
66793
- agentId: opts.agentId ?? null,
66794
- requestStartedAtMs
66795
- });
66796
- return stream2;
66797
- }
66798
- var streamRequestStartTimes, streamToolContextIds, streamRequestContexts;
66799
- var init_message = __esm(async () => {
66800
- init_timing();
66801
- await __promiseAll([
66802
- init_manager3(),
66803
- init_client2()
66804
- ]);
66805
- streamRequestStartTimes = new WeakMap;
66806
- streamToolContextIds = new WeakMap;
66807
- streamRequestContexts = new WeakMap;
66808
- });
66809
-
66810
66680
  // src/cli/helpers/errorFormatter.ts
66811
66681
  function extractReasonList2(value) {
66812
66682
  if (!Array.isArray(value))
@@ -67262,14 +67132,16 @@ function getProviderDisplayName() {
67262
67132
  return ENDPOINT_TYPE_DISPLAY_NAMES[modelEndpointType] ?? modelEndpointType;
67263
67133
  }
67264
67134
  function createAgentLink2(runId, agentId, conversationId) {
67265
- const url = `https://app.letta.com/agents/${agentId}${conversationId && conversationId !== "default" ? `?conversation=${conversationId}` : ""}`;
67135
+ const url = buildChatUrl(agentId, { conversationId });
67266
67136
  return `View agent: \x1B]8;;${url}\x1B\\${agentId}\x1B]8;;\x1B\\ (run: ${runId})`;
67267
67137
  }
67268
- var LETTA_USAGE_URL2 = "https://app.letta.com/settings/organization/usage", LETTA_AGENTS_URL2 = "https://app.letta.com/projects/default-project/agents", CLOUDFLARE_EDGE_5XX_MARKER_PATTERN2, CLOUDFLARE_EDGE_5XX_TITLE_PATTERN2, CHATGPT_USAGE_LIMIT_HINT2 = "Switch models with /model, or connect your own provider keys with /connect.", ENCRYPTED_CONTENT_HINT2, DEFAULT_RETRY_MESSAGE = "Unexpected downstream LLM API error, retrying...", ENDPOINT_TYPE_DISPLAY_NAMES;
67138
+ var LETTA_USAGE_URL2, LETTA_AGENTS_URL2, CLOUDFLARE_EDGE_5XX_MARKER_PATTERN2, CLOUDFLARE_EDGE_5XX_TITLE_PATTERN2, CHATGPT_USAGE_LIMIT_HINT2 = "Switch models with /model, or connect your own provider keys with /connect.", ENCRYPTED_CONTENT_HINT2, DEFAULT_RETRY_MESSAGE = "Unexpected downstream LLM API error, retrying...", ENDPOINT_TYPE_DISPLAY_NAMES;
67269
67139
  var init_errorFormatter = __esm(() => {
67270
67140
  init_error();
67271
67141
  init_errorContext();
67272
67142
  init_zaiErrors();
67143
+ LETTA_USAGE_URL2 = buildAppUrl("/settings/organization/usage");
67144
+ LETTA_AGENTS_URL2 = buildAppUrl("/projects/default-project/agents");
67273
67145
  CLOUDFLARE_EDGE_5XX_MARKER_PATTERN2 = /(^|\s)(502|52[0-6])\s*<!doctype html|error code\s*(502|52[0-6])/i;
67274
67146
  CLOUDFLARE_EDGE_5XX_TITLE_PATTERN2 = /\|\s*(502|52[0-6])\s*:/i;
67275
67147
  ENCRYPTED_CONTENT_HINT2 = [
@@ -67508,6 +67380,359 @@ var init_turn_recovery_policy = __esm(() => {
67508
67380
  RETRYABLE_429_PATTERN = /Error code:\s*429|rate limit|too many requests/i;
67509
67381
  });
67510
67382
 
67383
+ // src/agent/approval-recovery.ts
67384
+ async function fetchRunErrorDetail(runId) {
67385
+ if (!runId)
67386
+ return null;
67387
+ try {
67388
+ const client = await getClient2();
67389
+ const run = await client.runs.retrieve(runId);
67390
+ const metaError = run.metadata?.error;
67391
+ return metaError?.detail ?? metaError?.message ?? metaError?.error?.detail ?? metaError?.error?.message ?? null;
67392
+ } catch {
67393
+ return null;
67394
+ }
67395
+ }
67396
+ var init_approval_recovery = __esm(async () => {
67397
+ init_turn_recovery_policy();
67398
+ await init_client2();
67399
+ });
67400
+
67401
+ // src/agent/check-approval.ts
67402
+ var exports_check_approval = {};
67403
+ __export(exports_check_approval, {
67404
+ prepareMessageHistory: () => prepareMessageHistory2,
67405
+ getResumeData: () => getResumeData2,
67406
+ extractApprovals: () => extractApprovals2
67407
+ });
67408
+ function isPrimaryMessageType2(messageType) {
67409
+ return messageType === "user_message" || messageType === "assistant_message" || messageType === "event_message" || messageType === "summary_message";
67410
+ }
67411
+ function isAnchorMessageType2(messageType) {
67412
+ return messageType === "user_message" || messageType === "assistant_message";
67413
+ }
67414
+ function isBackfillEnabled2() {
67415
+ const val = process.env.LETTA_BACKFILL;
67416
+ return val !== "0" && val !== "false";
67417
+ }
67418
+ function extractApprovals2(messageToCheck) {
67419
+ const approvalMsg = messageToCheck;
67420
+ const toolCalls = Array.isArray(approvalMsg.tool_calls) ? approvalMsg.tool_calls : approvalMsg.tool_call ? [approvalMsg.tool_call] : [];
67421
+ const pendingApprovals = toolCalls.filter((tc) => !!tc && !!tc.tool_call_id).map((tc) => ({
67422
+ toolCallId: tc.tool_call_id,
67423
+ toolName: tc.name || "",
67424
+ toolArgs: tc.arguments || ""
67425
+ }));
67426
+ const pendingApproval = pendingApprovals[0] || null;
67427
+ if (pendingApprovals.length > 0) {
67428
+ debugWarn("check-approval", `Found ${pendingApprovals.length} pending approval(s): ${pendingApprovals.map((a) => a.toolName).join(", ")}`);
67429
+ }
67430
+ return { pendingApproval, pendingApprovals };
67431
+ }
67432
+ function prepareMessageHistory2(messages, opts) {
67433
+ const isRenderable = (msg) => {
67434
+ const t = msg.message_type;
67435
+ if (t === "user_message" || t === "assistant_message" || t === "reasoning_message" || t === "tool_call_message" || t === "tool_return_message" || t === "approval_request_message" || t === "approval_response_message") {
67436
+ return true;
67437
+ }
67438
+ const ts = t;
67439
+ return ts === "event_message" || ts === "summary_message";
67440
+ };
67441
+ const renderable = messages.filter(isRenderable);
67442
+ if (opts?.primaryOnly) {
67443
+ const convo = renderable.filter((m) => isPrimaryMessageType2(m.message_type));
67444
+ let trimmed = convo.slice(-BACKFILL_PRIMARY_MESSAGE_LIMIT2);
67445
+ const hasAssistant = trimmed.some((m) => m.message_type === "assistant_message");
67446
+ if (!hasAssistant) {
67447
+ const lastAssistantIndex = convo.map((m) => m.message_type).lastIndexOf("assistant_message");
67448
+ if (lastAssistantIndex >= 0) {
67449
+ const lastAssistant = convo[lastAssistantIndex];
67450
+ if (lastAssistant) {
67451
+ const tailLimit = Math.max(BACKFILL_PRIMARY_MESSAGE_LIMIT2 - 1, 0);
67452
+ const newestTail = tailLimit > 0 ? convo.slice(-tailLimit) : [];
67453
+ trimmed = [lastAssistant, ...newestTail];
67454
+ }
67455
+ }
67456
+ }
67457
+ if (trimmed.length > 0)
67458
+ return trimmed;
67459
+ const reasoning = renderable.filter((m) => m.message_type === "reasoning_message");
67460
+ if (reasoning.length > 0) {
67461
+ return reasoning.slice(-BACKFILL_PRIMARY_MESSAGE_LIMIT2);
67462
+ }
67463
+ return [];
67464
+ }
67465
+ const isPrimary = (msg) => {
67466
+ const t = msg.message_type;
67467
+ return t === "user_message" || t === "assistant_message" || t === "reasoning_message" || t === "event_message" || t === "summary_message";
67468
+ };
67469
+ let primaryCount = 0;
67470
+ let startIndex = Math.max(0, renderable.length - 1);
67471
+ for (let i = renderable.length - 1;i >= 0; i -= 1) {
67472
+ const msg = renderable[i];
67473
+ if (!msg)
67474
+ continue;
67475
+ if (isPrimary(msg)) {
67476
+ primaryCount += 1;
67477
+ if (primaryCount >= BACKFILL_PRIMARY_MESSAGE_LIMIT2) {
67478
+ startIndex = i;
67479
+ break;
67480
+ }
67481
+ }
67482
+ startIndex = i;
67483
+ }
67484
+ let messageHistory = renderable.slice(startIndex);
67485
+ if (messageHistory.length > BACKFILL_MAX_RENDERABLE_MESSAGES2) {
67486
+ messageHistory = messageHistory.slice(-BACKFILL_MAX_RENDERABLE_MESSAGES2);
67487
+ }
67488
+ if (messageHistory[0]?.message_type === "tool_return_message") {
67489
+ messageHistory = messageHistory.slice(1);
67490
+ }
67491
+ return messageHistory;
67492
+ }
67493
+ function sortChronological2(messages) {
67494
+ return [...messages].sort((a, b) => {
67495
+ const ta = a.date ? new Date(a.date).getTime() : 0;
67496
+ const tb = b.date ? new Date(b.date).getTime() : 0;
67497
+ if (!Number.isFinite(ta) && !Number.isFinite(tb))
67498
+ return 0;
67499
+ if (!Number.isFinite(ta))
67500
+ return -1;
67501
+ if (!Number.isFinite(tb))
67502
+ return 1;
67503
+ return ta - tb;
67504
+ });
67505
+ }
67506
+ async function fetchConversationBackfillMessages2(client, conversationId) {
67507
+ const collected = [];
67508
+ const seen = new Set;
67509
+ let cursorBefore = null;
67510
+ let assistantCount = 0;
67511
+ let anchorCount = 0;
67512
+ for (let pageIndex = 0;pageIndex < BACKFILL_MAX_PAGES2; pageIndex += 1) {
67513
+ const page = await client.conversations.messages.list(conversationId, {
67514
+ limit: BACKFILL_PAGE_LIMIT2,
67515
+ order: "desc",
67516
+ ...cursorBefore ? { before: cursorBefore } : {}
67517
+ });
67518
+ const items = page.getPaginatedItems();
67519
+ if (items.length === 0)
67520
+ break;
67521
+ cursorBefore = items[items.length - 1]?.id ?? null;
67522
+ for (const m of items) {
67523
+ if (!m?.id)
67524
+ continue;
67525
+ const key = "otid" in m && m.otid ? `otid:${String(m.otid)}` : `id:${m.id}:${m.message_type ?? ""}`;
67526
+ if (seen.has(key))
67527
+ continue;
67528
+ seen.add(key);
67529
+ collected.push(m);
67530
+ if (m.message_type === "assistant_message")
67531
+ assistantCount += 1;
67532
+ if (isAnchorMessageType2(m.message_type))
67533
+ anchorCount += 1;
67534
+ }
67535
+ if (assistantCount >= BACKFILL_MIN_ASSISTANT2 && anchorCount >= BACKFILL_ANCHOR_MESSAGE_LIMIT2) {
67536
+ break;
67537
+ }
67538
+ if (items.length < BACKFILL_PAGE_LIMIT2)
67539
+ break;
67540
+ }
67541
+ if (assistantCount < BACKFILL_MIN_ASSISTANT2) {
67542
+ debugWarn("check-approval", `Backfill scan found 0 assistant messages in last ${collected.length} messages (tool-heavy conversation?)`);
67543
+ }
67544
+ return sortChronological2(collected);
67545
+ }
67546
+ async function getResumeData2(client, agent, conversationId, options = {}) {
67547
+ try {
67548
+ const includeMessageHistory = options.includeMessageHistory ?? true;
67549
+ let inContextMessageIds;
67550
+ let messages = [];
67551
+ const useConversationsApi = conversationId && conversationId !== "default";
67552
+ if (useConversationsApi) {
67553
+ const conversation = await client.conversations.retrieve(conversationId);
67554
+ inContextMessageIds = conversation.in_context_message_ids;
67555
+ if (!inContextMessageIds || inContextMessageIds.length === 0) {
67556
+ debugWarn("check-approval", "No in-context messages - no pending approvals");
67557
+ if (includeMessageHistory && isBackfillEnabled2()) {
67558
+ try {
67559
+ const backfill = await fetchConversationBackfillMessages2(client, conversationId);
67560
+ return {
67561
+ pendingApproval: null,
67562
+ pendingApprovals: [],
67563
+ messageHistory: prepareMessageHistory2(backfill, {
67564
+ primaryOnly: true
67565
+ })
67566
+ };
67567
+ } catch (backfillError) {
67568
+ debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
67569
+ }
67570
+ }
67571
+ return {
67572
+ pendingApproval: null,
67573
+ pendingApprovals: [],
67574
+ messageHistory: []
67575
+ };
67576
+ }
67577
+ const lastInContextId = inContextMessageIds.at(-1);
67578
+ if (!lastInContextId) {
67579
+ throw new Error("Expected at least one in-context message");
67580
+ }
67581
+ const retrievedMessages = await client.messages.retrieve(lastInContextId);
67582
+ if (includeMessageHistory && isBackfillEnabled2()) {
67583
+ try {
67584
+ messages = await fetchConversationBackfillMessages2(client, conversationId);
67585
+ } catch (backfillError) {
67586
+ debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
67587
+ }
67588
+ }
67589
+ const messageToCheck = retrievedMessages.find((msg) => msg.message_type === "approval_request_message") ?? retrievedMessages[0];
67590
+ if (messageToCheck) {
67591
+ debugWarn("check-approval", `Found last in-context message: ${messageToCheck.id} (type: ${messageToCheck.message_type})` + (retrievedMessages.length > 1 ? ` - had ${retrievedMessages.length} variants` : ""));
67592
+ if (messageToCheck.message_type === "approval_request_message") {
67593
+ const { pendingApproval, pendingApprovals } = extractApprovals2(messageToCheck);
67594
+ return {
67595
+ pendingApproval,
67596
+ pendingApprovals,
67597
+ messageHistory: prepareMessageHistory2(messages, {
67598
+ primaryOnly: true
67599
+ })
67600
+ };
67601
+ }
67602
+ } else {
67603
+ debugWarn("check-approval", `Last in-context message ${lastInContextId} not found via retrieve`);
67604
+ }
67605
+ return {
67606
+ pendingApproval: null,
67607
+ pendingApprovals: [],
67608
+ messageHistory: prepareMessageHistory2(messages, { primaryOnly: true })
67609
+ };
67610
+ } else {
67611
+ inContextMessageIds = agent.message_ids;
67612
+ if (!inContextMessageIds || inContextMessageIds.length === 0) {
67613
+ debugWarn("check-approval", "No in-context messages (default/agent API) - no pending approvals");
67614
+ return {
67615
+ pendingApproval: null,
67616
+ pendingApprovals: [],
67617
+ messageHistory: []
67618
+ };
67619
+ }
67620
+ const lastInContextId = inContextMessageIds.at(-1);
67621
+ if (!lastInContextId) {
67622
+ throw new Error("Expected at least one in-context message");
67623
+ }
67624
+ const retrievedMessages = await client.messages.retrieve(lastInContextId);
67625
+ if (includeMessageHistory && isBackfillEnabled2()) {
67626
+ try {
67627
+ const messagesPage = await client.conversations.messages.list("default", {
67628
+ agent_id: agent.id,
67629
+ limit: BACKFILL_PAGE_LIMIT2,
67630
+ order: "desc"
67631
+ });
67632
+ messages = sortChronological2(messagesPage.getPaginatedItems());
67633
+ if (process.env.DEBUG) {
67634
+ console.log(`[DEBUG] conversations.messages.list(default, agent_id=${agent.id}) returned ${messages.length} messages`);
67635
+ }
67636
+ } catch (backfillError) {
67637
+ debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
67638
+ }
67639
+ }
67640
+ const messageToCheck = retrievedMessages.find((msg) => msg.message_type === "approval_request_message") ?? retrievedMessages[0];
67641
+ if (messageToCheck) {
67642
+ debugWarn("check-approval", `Found last in-context message: ${messageToCheck.id} (type: ${messageToCheck.message_type})` + (retrievedMessages.length > 1 ? ` - had ${retrievedMessages.length} variants` : ""));
67643
+ if (messageToCheck.message_type === "approval_request_message") {
67644
+ const { pendingApproval, pendingApprovals } = extractApprovals2(messageToCheck);
67645
+ return {
67646
+ pendingApproval,
67647
+ pendingApprovals,
67648
+ messageHistory: prepareMessageHistory2(messages, {
67649
+ primaryOnly: true
67650
+ })
67651
+ };
67652
+ }
67653
+ } else {
67654
+ debugWarn("check-approval", `Last in-context message ${lastInContextId} not found via retrieve (default/agent API)`);
67655
+ }
67656
+ return {
67657
+ pendingApproval: null,
67658
+ pendingApprovals: [],
67659
+ messageHistory: prepareMessageHistory2(messages, { primaryOnly: true })
67660
+ };
67661
+ }
67662
+ } catch (error) {
67663
+ if (error instanceof APIError2 && (error.status === 404 || error.status === 422)) {
67664
+ throw error;
67665
+ }
67666
+ console.error("Error getting resume data:", error);
67667
+ return { pendingApproval: null, pendingApprovals: [], messageHistory: [] };
67668
+ }
67669
+ }
67670
+ var BACKFILL_PRIMARY_MESSAGE_LIMIT2 = 12, BACKFILL_MAX_RENDERABLE_MESSAGES2 = 80, BACKFILL_ANCHOR_MESSAGE_LIMIT2 = 6, BACKFILL_PAGE_LIMIT2 = 200, BACKFILL_MAX_PAGES2 = 25, BACKFILL_MIN_ASSISTANT2 = 1;
67671
+ var init_check_approval = __esm(() => {
67672
+ init_error();
67673
+ init_debug();
67674
+ });
67675
+
67676
+ // src/agent/message.ts
67677
+ function getStreamRequestStartTime(stream2) {
67678
+ return streamRequestStartTimes.get(stream2);
67679
+ }
67680
+ function getStreamToolContextId(stream2) {
67681
+ return streamToolContextIds.get(stream2) ?? null;
67682
+ }
67683
+ function getStreamRequestContext(stream2) {
67684
+ return streamRequestContexts.get(stream2);
67685
+ }
67686
+ async function sendMessageStream(conversationId, messages, opts = { streamTokens: true, background: true }, requestOptions = {
67687
+ maxRetries: 0
67688
+ }) {
67689
+ const requestStartTime = isTimingsEnabled() ? performance.now() : undefined;
67690
+ const requestStartedAtMs = Date.now();
67691
+ const client = await getClient2();
67692
+ await waitForToolsetReady();
67693
+ const { clientTools, contextId } = captureToolExecutionContext();
67694
+ const isDefaultConversation = conversationId === "default";
67695
+ if (isDefaultConversation && !opts.agentId) {
67696
+ throw new Error("agentId is required in opts when using default conversation");
67697
+ }
67698
+ const resolvedConversationId = conversationId;
67699
+ const requestBody = {
67700
+ messages,
67701
+ streaming: true,
67702
+ stream_tokens: opts.streamTokens ?? true,
67703
+ background: opts.background ?? true,
67704
+ client_tools: clientTools,
67705
+ include_compaction_messages: true,
67706
+ ...isDefaultConversation ? { agent_id: opts.agentId } : {}
67707
+ };
67708
+ if (process.env.DEBUG) {
67709
+ console.log(`[DEBUG] sendMessageStream: conversationId=${conversationId}, agentId=${opts.agentId ?? "(none)"}`);
67710
+ }
67711
+ const stream2 = await client.conversations.messages.create(resolvedConversationId, requestBody, requestOptions);
67712
+ if (requestStartTime !== undefined) {
67713
+ streamRequestStartTimes.set(stream2, requestStartTime);
67714
+ }
67715
+ streamToolContextIds.set(stream2, contextId);
67716
+ streamRequestContexts.set(stream2, {
67717
+ conversationId,
67718
+ resolvedConversationId,
67719
+ agentId: opts.agentId ?? null,
67720
+ requestStartedAtMs
67721
+ });
67722
+ return stream2;
67723
+ }
67724
+ var streamRequestStartTimes, streamToolContextIds, streamRequestContexts;
67725
+ var init_message = __esm(async () => {
67726
+ init_timing();
67727
+ await __promiseAll([
67728
+ init_manager3(),
67729
+ init_client2()
67730
+ ]);
67731
+ streamRequestStartTimes = new WeakMap;
67732
+ streamToolContextIds = new WeakMap;
67733
+ streamRequestContexts = new WeakMap;
67734
+ });
67735
+
67511
67736
  // src/cli/helpers/backfill.ts
67512
67737
  function getDisplayableToolReturn2(content) {
67513
67738
  if (!content)
@@ -70931,6 +71156,9 @@ function createRuntime() {
70931
71156
  cancelRequested: false,
70932
71157
  isRecoveringApprovals: false,
70933
71158
  pendingApprovalBatchByToolCallId: new Map,
71159
+ pendingInterruptedResults: null,
71160
+ pendingInterruptedContext: null,
71161
+ continuationEpoch: 0,
70934
71162
  coalescedSkipQueueItemIds: new Set,
70935
71163
  pendingTurns: 0,
70936
71164
  queueRuntime: null
@@ -71045,6 +71273,12 @@ function resolvePendingApprovalBatchId(runtime, pendingApprovals) {
71045
71273
  }
71046
71274
  return batchIds.values().next().value ?? null;
71047
71275
  }
71276
+ function resolveRecoveryBatchId(runtime, pendingApprovals) {
71277
+ if (runtime.pendingApprovalBatchByToolCallId.size === 0) {
71278
+ return `recovery-${crypto.randomUUID()}`;
71279
+ }
71280
+ return resolvePendingApprovalBatchId(runtime, pendingApprovals);
71281
+ }
71048
71282
  function clearPendingApprovalBatchIds(runtime, approvals) {
71049
71283
  for (const approval of approvals) {
71050
71284
  runtime.pendingApprovalBatchByToolCallId.delete(approval.toolCallId);
@@ -71059,6 +71293,9 @@ function stopRuntime(runtime, suppressCallbacks) {
71059
71293
  clearRuntimeTimers(runtime);
71060
71294
  rejectPendingApprovalResolvers(runtime, "Listener runtime stopped");
71061
71295
  runtime.pendingApprovalBatchByToolCallId.clear();
71296
+ runtime.pendingInterruptedResults = null;
71297
+ runtime.pendingInterruptedContext = null;
71298
+ runtime.continuationEpoch++;
71062
71299
  if (!runtime.socket) {
71063
71300
  return;
71064
71301
  }
@@ -71243,9 +71480,201 @@ function emitToWS(socket, event) {
71243
71480
  socket.send(JSON.stringify(outbound));
71244
71481
  }
71245
71482
  }
71483
+ function normalizeToolReturnValue(value) {
71484
+ if (typeof value === "string") {
71485
+ return value;
71486
+ }
71487
+ if (value === null || value === undefined) {
71488
+ return "";
71489
+ }
71490
+ try {
71491
+ return JSON.stringify(value);
71492
+ } catch {
71493
+ return String(value);
71494
+ }
71495
+ }
71496
+ function extractInterruptToolReturns(approvals) {
71497
+ if (!approvals || approvals.length === 0) {
71498
+ return [];
71499
+ }
71500
+ return approvals.flatMap((approval) => {
71501
+ if (!approval || typeof approval !== "object") {
71502
+ return [];
71503
+ }
71504
+ if ("type" in approval && approval.type === "tool") {
71505
+ const toolCallId = "tool_call_id" in approval && typeof approval.tool_call_id === "string" ? approval.tool_call_id : null;
71506
+ if (!toolCallId) {
71507
+ return [];
71508
+ }
71509
+ const status = "status" in approval && approval.status === "success" ? "success" : "error";
71510
+ const stdout = "stdout" in approval && Array.isArray(approval.stdout) ? approval.stdout.filter((entry) => typeof entry === "string") : undefined;
71511
+ const stderr = "stderr" in approval && Array.isArray(approval.stderr) ? approval.stderr.filter((entry) => typeof entry === "string") : undefined;
71512
+ return [
71513
+ {
71514
+ tool_call_id: toolCallId,
71515
+ status,
71516
+ tool_return: "tool_return" in approval ? normalizeToolReturnValue(approval.tool_return) : "",
71517
+ ...stdout ? { stdout } : {},
71518
+ ...stderr ? { stderr } : {}
71519
+ }
71520
+ ];
71521
+ }
71522
+ if ("type" in approval && approval.type === "approval") {
71523
+ const toolCallId = "tool_call_id" in approval && typeof approval.tool_call_id === "string" ? approval.tool_call_id : null;
71524
+ if (!toolCallId) {
71525
+ return [];
71526
+ }
71527
+ const reason = "reason" in approval && typeof approval.reason === "string" ? approval.reason : "User interrupted the stream";
71528
+ return [
71529
+ {
71530
+ tool_call_id: toolCallId,
71531
+ status: "error",
71532
+ tool_return: reason
71533
+ }
71534
+ ];
71535
+ }
71536
+ return [];
71537
+ });
71538
+ }
71539
+ function emitInterruptToolReturnMessage(socket, runtime, approvals, runId, uuidPrefix = "interrupt-tool-return") {
71540
+ const toolReturns = extractInterruptToolReturns(approvals);
71541
+ if (toolReturns.length === 0) {
71542
+ return;
71543
+ }
71544
+ const resolvedRunId = runId ?? runtime.activeRunId ?? undefined;
71545
+ for (const toolReturn of toolReturns) {
71546
+ emitToWS(socket, {
71547
+ type: "message",
71548
+ message_type: "tool_return_message",
71549
+ id: `message-${crypto.randomUUID()}`,
71550
+ date: new Date().toISOString(),
71551
+ run_id: resolvedRunId,
71552
+ tool_call_id: toolReturn.tool_call_id,
71553
+ tool_return: toolReturn.tool_return,
71554
+ status: toolReturn.status,
71555
+ ...toolReturn.stdout ? { stdout: toolReturn.stdout } : {},
71556
+ ...toolReturn.stderr ? { stderr: toolReturn.stderr } : {},
71557
+ tool_returns: [toolReturn],
71558
+ session_id: runtime.sessionId,
71559
+ uuid: `${uuidPrefix}-${crypto.randomUUID()}`
71560
+ });
71561
+ }
71562
+ }
71563
+ function getInterruptApprovalsForEmission(runtime, params) {
71564
+ if (params.lastExecutionResults && params.lastExecutionResults.length > 0) {
71565
+ return params.lastExecutionResults;
71566
+ }
71567
+ const context3 = runtime.pendingInterruptedContext;
71568
+ if (!context3 || context3.agentId !== params.agentId || context3.conversationId !== params.conversationId || context3.continuationEpoch !== runtime.continuationEpoch) {
71569
+ return null;
71570
+ }
71571
+ if (!runtime.pendingInterruptedResults || runtime.pendingInterruptedResults.length === 0) {
71572
+ return null;
71573
+ }
71574
+ return runtime.pendingInterruptedResults;
71575
+ }
71576
+ function populateInterruptQueue(runtime, input) {
71577
+ const shouldPopulate = !runtime.pendingInterruptedResults || runtime.pendingInterruptedResults.length === 0 || !runtime.pendingInterruptedContext;
71578
+ if (!shouldPopulate)
71579
+ return false;
71580
+ if (input.lastExecutionResults && input.lastExecutionResults.length > 0) {
71581
+ runtime.pendingInterruptedResults = input.lastExecutionResults;
71582
+ runtime.pendingInterruptedContext = {
71583
+ agentId: input.agentId,
71584
+ conversationId: input.conversationId,
71585
+ continuationEpoch: runtime.continuationEpoch
71586
+ };
71587
+ return true;
71588
+ }
71589
+ const batchToolCallIds = [...runtime.pendingApprovalBatchByToolCallId.keys()];
71590
+ const pendingIds = batchToolCallIds.length > 0 ? batchToolCallIds : input.lastNeedsUserInputToolCallIds;
71591
+ if (pendingIds.length > 0) {
71592
+ runtime.pendingInterruptedResults = pendingIds.map((toolCallId) => ({
71593
+ type: "approval",
71594
+ tool_call_id: toolCallId,
71595
+ approve: false,
71596
+ reason: "User interrupted the stream"
71597
+ }));
71598
+ runtime.pendingInterruptedContext = {
71599
+ agentId: input.agentId,
71600
+ conversationId: input.conversationId,
71601
+ continuationEpoch: runtime.continuationEpoch
71602
+ };
71603
+ return true;
71604
+ }
71605
+ if (process.env.DEBUG) {
71606
+ console.warn("[Listen] Cancel during approval loop but no tool_call_ids available " + "for interrupted queue — next turn may hit pre-stream conflict. " + `batchMap=${runtime.pendingApprovalBatchByToolCallId.size}, ` + `lastNeedsUserInput=${input.lastNeedsUserInputToolCallIds.length}`);
71607
+ }
71608
+ return false;
71609
+ }
71610
+ function consumeInterruptQueue(runtime, agentId, conversationId) {
71611
+ if (!runtime.pendingInterruptedResults || runtime.pendingInterruptedResults.length === 0) {
71612
+ return null;
71613
+ }
71614
+ const ctx = runtime.pendingInterruptedContext;
71615
+ let result = null;
71616
+ if (ctx && ctx.agentId === agentId && ctx.conversationId === conversationId && ctx.continuationEpoch === runtime.continuationEpoch) {
71617
+ result = {
71618
+ type: "approval",
71619
+ approvals: runtime.pendingInterruptedResults
71620
+ };
71621
+ }
71622
+ runtime.pendingInterruptedResults = null;
71623
+ runtime.pendingInterruptedContext = null;
71624
+ runtime.pendingApprovalBatchByToolCallId.clear();
71625
+ return result;
71626
+ }
71627
+ async function resolveStaleApprovals(runtime, abortSignal) {
71628
+ if (!runtime.activeAgentId)
71629
+ return;
71630
+ const client = await getClient2();
71631
+ let agent;
71632
+ try {
71633
+ agent = await client.agents.retrieve(runtime.activeAgentId);
71634
+ } catch (err) {
71635
+ if (err instanceof APIError2 && (err.status === 404 || err.status === 422)) {
71636
+ return;
71637
+ }
71638
+ throw err;
71639
+ }
71640
+ const requestedConversationId = runtime.activeConversationId && runtime.activeConversationId !== "default" ? runtime.activeConversationId : undefined;
71641
+ let resumeData;
71642
+ try {
71643
+ resumeData = await getResumeData2(client, agent, requestedConversationId, {
71644
+ includeMessageHistory: false
71645
+ });
71646
+ } catch (err) {
71647
+ if (err instanceof APIError2 && (err.status === 404 || err.status === 422)) {
71648
+ return;
71649
+ }
71650
+ throw err;
71651
+ }
71652
+ const pendingApprovals = resumeData.pendingApprovals || [];
71653
+ if (pendingApprovals.length === 0)
71654
+ return;
71655
+ if (abortSignal.aborted)
71656
+ throw new Error("Cancelled");
71657
+ const denialResults = pendingApprovals.map((approval) => ({
71658
+ type: "approval",
71659
+ tool_call_id: approval.toolCallId,
71660
+ approve: false,
71661
+ reason: "Auto-denied during pre-stream approval recovery"
71662
+ }));
71663
+ const recoveryConversationId = runtime.activeConversationId || "default";
71664
+ const recoveryStream = await sendMessageStream(recoveryConversationId, [{ type: "approval", approvals: denialResults }], {
71665
+ agentId: runtime.activeAgentId,
71666
+ streamTokens: true,
71667
+ background: true
71668
+ }, { maxRetries: 0, signal: abortSignal });
71669
+ const drainResult = await drainStreamWithResume(recoveryStream, createBuffers(runtime.activeAgentId), () => {}, abortSignal);
71670
+ if (drainResult.stopReason === "error") {
71671
+ throw new Error("Pre-stream approval recovery drain ended with error");
71672
+ }
71673
+ }
71246
71674
  async function sendMessageStreamWithRetry(conversationId, messages, opts, socket, runtime, abortSignal) {
71247
71675
  let transientRetries = 0;
71248
71676
  let conversationBusyRetries = 0;
71677
+ let preStreamRecoveryAttempts = 0;
71249
71678
  const MAX_CONVERSATION_BUSY_RETRIES = 1;
71250
71679
  while (true) {
71251
71680
  if (abortSignal?.aborted) {
@@ -71264,7 +71693,20 @@ async function sendMessageStreamWithRetry(conversationId, messages, opts, socket
71264
71693
  maxTransientRetries: LLM_API_ERROR_MAX_RETRIES
71265
71694
  });
71266
71695
  if (action === "resolve_approval_pending") {
71267
- throw preStreamError;
71696
+ if (abortSignal?.aborted)
71697
+ throw new Error("Cancelled by user");
71698
+ if (abortSignal && preStreamRecoveryAttempts < MAX_PRE_STREAM_RECOVERY) {
71699
+ preStreamRecoveryAttempts++;
71700
+ try {
71701
+ await resolveStaleApprovals(runtime, abortSignal);
71702
+ continue;
71703
+ } catch (_recoveryError) {
71704
+ if (abortSignal.aborted)
71705
+ throw new Error("Cancelled by user");
71706
+ }
71707
+ }
71708
+ const detail = await fetchRunErrorDetail(runtime.activeRunId);
71709
+ throw new Error(detail || `Pre-stream approval conflict (resolve_approval_pending) after ${preStreamRecoveryAttempts} recovery attempts`);
71268
71710
  }
71269
71711
  if (action === "retry_transient") {
71270
71712
  const attempt = transientRetries + 1;
@@ -71406,6 +71848,13 @@ function buildApprovalExecutionPlan(approvalMessage, pendingApprovals) {
71406
71848
  return { slots, decisions };
71407
71849
  }
71408
71850
  async function recoverPendingApprovals(runtime, socket, msg) {
71851
+ console.debug("[listener] recover_pending_approvals received", JSON.stringify({
71852
+ agentId: msg.agentId,
71853
+ conversationId: msg.conversationId ?? null,
71854
+ isProcessing: runtime.isProcessing,
71855
+ isRecovering: runtime.isRecoveringApprovals,
71856
+ batchMapSize: runtime.pendingApprovalBatchByToolCallId.size
71857
+ }));
71409
71858
  if (runtime.isProcessing || runtime.isRecoveringApprovals) {
71410
71859
  return;
71411
71860
  }
@@ -71434,11 +71883,11 @@ async function recoverPendingApprovals(runtime, socket, msg) {
71434
71883
  if (pendingApprovals.length === 0) {
71435
71884
  return;
71436
71885
  }
71437
- const recoveryBatchId = resolvePendingApprovalBatchId(runtime, pendingApprovals);
71886
+ const recoveryBatchId = resolveRecoveryBatchId(runtime, pendingApprovals);
71438
71887
  if (!recoveryBatchId) {
71439
71888
  emitToWS(socket, {
71440
71889
  type: "error",
71441
- message: "Unable to recover pending approvals without originating batch correlation",
71890
+ message: "Unable to recover pending approvals: ambiguous batch correlation",
71442
71891
  stop_reason: "error",
71443
71892
  session_id: runtime.sessionId,
71444
71893
  uuid: `error-${crypto.randomUUID()}`
@@ -71481,6 +71930,7 @@ async function recoverPendingApprovals(runtime, socket, msg) {
71481
71930
  runtime.lastStopReason = "requires_approval";
71482
71931
  return;
71483
71932
  }
71933
+ runtime.lastStopReason = "requires_approval";
71484
71934
  for (const ac of needsUserInput) {
71485
71935
  const requestId = `perm-${ac.approval.toolCallId}`;
71486
71936
  const diffs = await computeDiffPreviews(ac.approval.toolName, ac.parsedArgs);
@@ -71693,6 +72143,14 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
71693
72143
  if (hasPendingApprovals) {
71694
72144
  rejectPendingApprovalResolvers(runtime, "Cancelled by user");
71695
72145
  }
72146
+ const cancelConversationId = runtime.activeConversationId;
72147
+ const cancelAgentId = runtime.activeAgentId;
72148
+ if (cancelAgentId) {
72149
+ getClient2().then((client) => {
72150
+ const cancelId = cancelConversationId === "default" || !cancelConversationId ? cancelAgentId : cancelConversationId;
72151
+ return client.conversations.cancel(cancelId);
72152
+ }).catch(() => {});
72153
+ }
71696
72154
  emitCancelAck(socket, runtime, {
71697
72155
  requestId,
71698
72156
  accepted: true,
@@ -71891,6 +72349,8 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
71891
72349
  const msgStartTime = performance.now();
71892
72350
  let msgTurnCount = 0;
71893
72351
  const msgRunIds = [];
72352
+ let lastExecutionResults = null;
72353
+ let lastNeedsUserInputToolCallIds = [];
71894
72354
  runtime.isProcessing = true;
71895
72355
  runtime.cancelRequested = false;
71896
72356
  runtime.activeAbortController = new AbortController;
@@ -71913,8 +72373,13 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
71913
72373
  if (connectionId) {
71914
72374
  onStatusChange?.("processing", connectionId);
71915
72375
  }
71916
- let messagesToSend = msg.messages;
72376
+ let messagesToSend = [];
71917
72377
  let turnToolContextId = null;
72378
+ const consumed = consumeInterruptQueue(runtime, agentId || "", conversationId);
72379
+ if (consumed) {
72380
+ messagesToSend.push(consumed);
72381
+ }
72382
+ messagesToSend.push(...msg.messages);
71918
72383
  const firstMessage = msg.messages[0];
71919
72384
  const isApprovalMessage = firstMessage && "type" in firstMessage && firstMessage.type === "approval" && "approvals" in firstMessage;
71920
72385
  if (isApprovalMessage) {
@@ -71955,6 +72420,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
71955
72420
  approvals: rebuiltApprovals
71956
72421
  }
71957
72422
  ];
72423
+ emitInterruptToolReturnMessage(socket, runtime, rebuiltApprovals, runtime.activeRunId ?? undefined, "tool-return");
71958
72424
  }
71959
72425
  let stream2 = await sendMessageStreamWithRetry(conversationId, messagesToSend, { agentId, streamTokens: true, background: true }, socket, runtime, runtime.activeAbortController.signal);
71960
72426
  turnToolContextId = getStreamToolContextId(stream2);
@@ -72062,13 +72528,45 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
72062
72528
  break;
72063
72529
  }
72064
72530
  if (stopReason !== "requires_approval") {
72065
- runtime.lastStopReason = stopReason;
72531
+ const effectiveStopReason = runtime.cancelRequested ? "cancelled" : stopReason || "error";
72532
+ if (effectiveStopReason === "cancelled") {
72533
+ runtime.lastStopReason = "cancelled";
72534
+ runtime.isProcessing = false;
72535
+ clearActiveRunState(runtime);
72536
+ if (runtime.controlResponseCapable) {
72537
+ emitToWS(socket, {
72538
+ type: "result",
72539
+ subtype: "interrupted",
72540
+ agent_id: agentId,
72541
+ conversation_id: conversationId,
72542
+ duration_ms: performance.now() - msgStartTime,
72543
+ duration_api_ms: 0,
72544
+ num_turns: msgTurnCount,
72545
+ result: null,
72546
+ run_ids: msgRunIds,
72547
+ usage: null,
72548
+ stop_reason: "cancelled",
72549
+ session_id: runtime.sessionId,
72550
+ uuid: `result-${crypto.randomUUID()}`
72551
+ });
72552
+ } else {
72553
+ sendClientMessage(socket, {
72554
+ type: "result",
72555
+ success: false,
72556
+ stopReason: "cancelled"
72557
+ });
72558
+ }
72559
+ break;
72560
+ }
72561
+ runtime.lastStopReason = effectiveStopReason;
72066
72562
  runtime.isProcessing = false;
72067
72563
  clearActiveRunState(runtime);
72564
+ const errorDetail = await fetchRunErrorDetail(runId).catch(() => null);
72565
+ const errorMessage = errorDetail || `Unexpected stop reason: ${stopReason}`;
72068
72566
  emitToWS(socket, {
72069
72567
  type: "error",
72070
- message: `Unexpected stop reason: ${stopReason}`,
72071
- stop_reason: stopReason || "error",
72568
+ message: errorMessage,
72569
+ stop_reason: effectiveStopReason,
72072
72570
  run_id: runId,
72073
72571
  session_id: runtime.sessionId,
72074
72572
  uuid: `error-${crypto.randomUUID()}`
@@ -72085,7 +72583,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
72085
72583
  result: null,
72086
72584
  run_ids: msgRunIds,
72087
72585
  usage: null,
72088
- stop_reason: stopReason || "error",
72586
+ stop_reason: effectiveStopReason,
72089
72587
  session_id: runtime.sessionId,
72090
72588
  uuid: `result-${crypto.randomUUID()}`
72091
72589
  });
@@ -72093,7 +72591,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
72093
72591
  sendClientMessage(socket, {
72094
72592
  type: "result",
72095
72593
  success: false,
72096
- stopReason
72594
+ stopReason: effectiveStopReason
72097
72595
  });
72098
72596
  }
72099
72597
  break;
@@ -72115,6 +72613,8 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
72115
72613
  treatAskAsDeny: false,
72116
72614
  requireArgsForAutoApprove: true
72117
72615
  });
72616
+ lastNeedsUserInputToolCallIds = needsUserInput.map((ac) => ac.approval.toolCallId);
72617
+ lastExecutionResults = null;
72118
72618
  for (const ac of autoAllowed) {
72119
72619
  emitToWS(socket, {
72120
72620
  type: "auto_approval",
@@ -72209,6 +72709,8 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
72209
72709
  toolContextId: turnToolContextId ?? undefined,
72210
72710
  abortSignal: runtime.activeAbortController.signal
72211
72711
  });
72712
+ lastExecutionResults = executionResults;
72713
+ emitInterruptToolReturnMessage(socket, runtime, executionResults, runtime.activeRunId || runId || msgRunIds[msgRunIds.length - 1] || undefined, "tool-return");
72212
72714
  clearPendingApprovalBatchIds(runtime, decisions.map((decision) => decision.approval));
72213
72715
  stream2 = await sendMessageStreamWithRetry(conversationId, [
72214
72716
  {
@@ -72216,10 +72718,26 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
72216
72718
  approvals: executionResults
72217
72719
  }
72218
72720
  ], { agentId, streamTokens: true, background: true }, socket, runtime, runtime.activeAbortController.signal);
72721
+ lastExecutionResults = null;
72722
+ lastNeedsUserInputToolCallIds = [];
72219
72723
  turnToolContextId = getStreamToolContextId(stream2);
72220
72724
  }
72221
72725
  } catch (error) {
72222
72726
  if (runtime.cancelRequested) {
72727
+ populateInterruptQueue(runtime, {
72728
+ lastExecutionResults,
72729
+ lastNeedsUserInputToolCallIds,
72730
+ agentId: agentId || "",
72731
+ conversationId
72732
+ });
72733
+ const approvalsForEmission = getInterruptApprovalsForEmission(runtime, {
72734
+ lastExecutionResults,
72735
+ agentId: agentId || "",
72736
+ conversationId
72737
+ });
72738
+ if (approvalsForEmission) {
72739
+ emitInterruptToolReturnMessage(socket, runtime, approvalsForEmission, runtime.activeRunId || msgRunIds[msgRunIds.length - 1] || undefined);
72740
+ }
72223
72741
  runtime.lastStopReason = "cancelled";
72224
72742
  runtime.isProcessing = false;
72225
72743
  clearActiveRunState(runtime);
@@ -72251,6 +72769,22 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
72251
72769
  runtime.lastStopReason = "error";
72252
72770
  runtime.isProcessing = false;
72253
72771
  clearActiveRunState(runtime);
72772
+ if (msgRunIds.length === 0) {
72773
+ const errorPayload = {
72774
+ message: error instanceof Error ? error.message : String(error)
72775
+ };
72776
+ if (error instanceof APIError2) {
72777
+ errorPayload.status = error.status;
72778
+ if (error.error && typeof error.error === "object") {
72779
+ errorPayload.body = error.error;
72780
+ }
72781
+ }
72782
+ sendClientMessage(socket, {
72783
+ type: "run_request_error",
72784
+ error: errorPayload,
72785
+ batch_id: dequeuedBatchId
72786
+ });
72787
+ }
72254
72788
  const errorMessage = error instanceof Error ? error.message : String(error);
72255
72789
  emitToWS(socket, {
72256
72790
  type: "error",
@@ -72301,7 +72835,7 @@ function stopListenerClient() {
72301
72835
  activeRuntime = null;
72302
72836
  stopRuntime(runtime, true);
72303
72837
  }
72304
- var activeRuntime = null, MAX_RETRY_DURATION_MS, INITIAL_RETRY_DELAY_MS = 1000, MAX_RETRY_DELAY_MS = 30000, LLM_API_ERROR_MAX_RETRIES = 3, __listenClientTestUtils;
72838
+ var activeRuntime = null, MAX_RETRY_DURATION_MS, INITIAL_RETRY_DELAY_MS = 1000, MAX_RETRY_DELAY_MS = 30000, LLM_API_ERROR_MAX_RETRIES = 3, MAX_PRE_STREAM_RECOVERY = 2, __listenClientTestUtils;
72305
72839
  var init_listen_client = __esm(async () => {
72306
72840
  init_error();
72307
72841
  init_check_approval();
@@ -72312,6 +72846,7 @@ var init_listen_client = __esm(async () => {
72312
72846
  init_interactivePolicy();
72313
72847
  await __promiseAll([
72314
72848
  init_approval_execution(),
72849
+ init_approval_recovery(),
72315
72850
  init_client2(),
72316
72851
  init_message(),
72317
72852
  init_accumulator(),
@@ -72327,7 +72862,13 @@ var init_listen_client = __esm(async () => {
72327
72862
  emitToWS,
72328
72863
  rememberPendingApprovalBatchIds,
72329
72864
  resolvePendingApprovalBatchId,
72330
- clearPendingApprovalBatchIds
72865
+ resolveRecoveryBatchId,
72866
+ clearPendingApprovalBatchIds,
72867
+ populateInterruptQueue,
72868
+ consumeInterruptQueue,
72869
+ extractInterruptToolReturns,
72870
+ emitInterruptToolReturnMessage,
72871
+ getInterruptApprovalsForEmission
72331
72872
  };
72332
72873
  });
72333
72874
 
@@ -72353,19 +72894,19 @@ __export(exports_skills2, {
72353
72894
  SKILLS_DIR: () => SKILLS_DIR2,
72354
72895
  GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR2
72355
72896
  });
72356
- import { existsSync as existsSync12 } from "node:fs";
72897
+ import { existsSync as existsSync13 } from "node:fs";
72357
72898
  import { readdir as readdir6, readFile as readFile5, realpath as realpath3, stat as stat3 } from "node:fs/promises";
72358
- import { dirname as dirname8, join as join21 } from "node:path";
72899
+ import { dirname as dirname8, join as join22 } from "node:path";
72359
72900
  import { fileURLToPath as fileURLToPath8 } from "node:url";
72360
72901
  function getBundledSkillsPath2() {
72361
72902
  const thisDir = dirname8(fileURLToPath8(import.meta.url));
72362
72903
  if (thisDir.includes("src/agent") || thisDir.includes("src\\agent")) {
72363
- return join21(thisDir, "../skills/builtin");
72904
+ return join22(thisDir, "../skills/builtin");
72364
72905
  }
72365
- return join21(thisDir, "skills");
72906
+ return join22(thisDir, "skills");
72366
72907
  }
72367
72908
  function getAgentSkillsDir2(agentId) {
72368
- return join21(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents", agentId, "skills");
72909
+ return join22(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents", agentId, "skills");
72369
72910
  }
72370
72911
  async function getBundledSkills2() {
72371
72912
  const bundledPath = getBundledSkillsPath2();
@@ -72374,7 +72915,7 @@ async function getBundledSkills2() {
72374
72915
  }
72375
72916
  async function discoverSkillsFromDir2(skillsPath, source) {
72376
72917
  const errors = [];
72377
- if (!existsSync12(skillsPath)) {
72918
+ if (!existsSync13(skillsPath)) {
72378
72919
  return { skills: [], errors: [] };
72379
72920
  }
72380
72921
  const skills = [];
@@ -72388,7 +72929,7 @@ async function discoverSkillsFromDir2(skillsPath, source) {
72388
72929
  }
72389
72930
  return { skills, errors };
72390
72931
  }
72391
- async function discoverSkills2(projectSkillsPath = join21(process.cwd(), SKILLS_DIR2), agentId, options) {
72932
+ async function discoverSkills2(projectSkillsPath = join22(process.cwd(), SKILLS_DIR2), agentId, options) {
72392
72933
  const allErrors = [];
72393
72934
  const skillsById = new Map;
72394
72935
  const sourceSet = new Set(options?.sources ?? ALL_SKILL_SOURCES);
@@ -72443,7 +72984,7 @@ async function findSkillFiles2(currentPath, rootPath, skills, errors, source, vi
72443
72984
  try {
72444
72985
  const entries = await readdir6(currentPath, { withFileTypes: true });
72445
72986
  for (const entry of entries) {
72446
- const fullPath = join21(currentPath, entry.name);
72987
+ const fullPath = join22(currentPath, entry.name);
72447
72988
  try {
72448
72989
  let isDirectory = entry.isDirectory();
72449
72990
  let isFile = entry.isFile();
@@ -72532,7 +73073,7 @@ ${lines.join(`
72532
73073
  var SKILLS_DIR2 = ".skills", GLOBAL_SKILLS_DIR2;
72533
73074
  var init_skills2 = __esm(() => {
72534
73075
  init_skillSources();
72535
- GLOBAL_SKILLS_DIR2 = join21(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
73076
+ GLOBAL_SKILLS_DIR2 = join22(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
72536
73077
  });
72537
73078
 
72538
73079
  // src/utils/fs.ts
@@ -72546,10 +73087,10 @@ __export(exports_fs, {
72546
73087
  exists: () => exists2
72547
73088
  });
72548
73089
  import {
72549
- existsSync as existsSync13,
73090
+ existsSync as existsSync14,
72550
73091
  readFileSync as fsReadFileSync2,
72551
73092
  writeFileSync as fsWriteFileSync2,
72552
- mkdirSync as mkdirSync10
73093
+ mkdirSync as mkdirSync11
72553
73094
  } from "node:fs";
72554
73095
  import { dirname as dirname9 } from "node:path";
72555
73096
  async function readFile6(path20) {
@@ -72557,16 +73098,16 @@ async function readFile6(path20) {
72557
73098
  }
72558
73099
  async function writeFile2(path20, content) {
72559
73100
  const dir = dirname9(path20);
72560
- if (!existsSync13(dir)) {
72561
- mkdirSync10(dir, { recursive: true });
73101
+ if (!existsSync14(dir)) {
73102
+ mkdirSync11(dir, { recursive: true });
72562
73103
  }
72563
73104
  fsWriteFileSync2(path20, content, { encoding: "utf-8", flush: true });
72564
73105
  }
72565
73106
  function exists2(path20) {
72566
- return existsSync13(path20);
73107
+ return existsSync14(path20);
72567
73108
  }
72568
73109
  async function mkdir2(path20, options) {
72569
- mkdirSync10(path20, options);
73110
+ mkdirSync11(path20, options);
72570
73111
  }
72571
73112
  async function readJsonFile(path20) {
72572
73113
  const text = await readFile6(path20);
@@ -72886,9 +73427,9 @@ __export(exports_auto_update, {
72886
73427
  import { execFile as execFile9 } from "node:child_process";
72887
73428
  import { realpathSync as realpathSync2 } from "node:fs";
72888
73429
  import { readdir as readdir7, rm } from "node:fs/promises";
72889
- import { join as join22 } from "node:path";
73430
+ import { join as join23 } from "node:path";
72890
73431
  import { promisify as promisify9 } from "node:util";
72891
- function debugLog2(...args) {
73432
+ function debugLog3(...args) {
72892
73433
  if (DEBUG) {
72893
73434
  console.error("[auto-update]", ...args);
72894
73435
  }
@@ -72955,10 +73496,10 @@ function detectPackageManager() {
72955
73496
  const envOverride = process.env.LETTA_PACKAGE_MANAGER;
72956
73497
  if (envOverride) {
72957
73498
  if (VALID_PACKAGE_MANAGERS.has(envOverride)) {
72958
- debugLog2("Package manager from LETTA_PACKAGE_MANAGER:", envOverride);
73499
+ debugLog3("Package manager from LETTA_PACKAGE_MANAGER:", envOverride);
72959
73500
  return envOverride;
72960
73501
  }
72961
- debugLog2(`Invalid LETTA_PACKAGE_MANAGER="${envOverride}", falling back to path detection`);
73502
+ debugLog3(`Invalid LETTA_PACKAGE_MANAGER="${envOverride}", falling back to path detection`);
72962
73503
  }
72963
73504
  const argv = process.argv[1] || "";
72964
73505
  let resolvedPath = argv;
@@ -72966,14 +73507,14 @@ function detectPackageManager() {
72966
73507
  resolvedPath = realpathSync2(argv);
72967
73508
  } catch {}
72968
73509
  if (/[/\\]\.bun[/\\]/.test(resolvedPath)) {
72969
- debugLog2("Detected package manager from path: bun");
73510
+ debugLog3("Detected package manager from path: bun");
72970
73511
  return "bun";
72971
73512
  }
72972
73513
  if (/[/\\]\.?pnpm[/\\]/.test(resolvedPath)) {
72973
- debugLog2("Detected package manager from path: pnpm");
73514
+ debugLog3("Detected package manager from path: pnpm");
72974
73515
  return "pnpm";
72975
73516
  }
72976
- debugLog2("Detected package manager from path: npm (default)");
73517
+ debugLog3("Detected package manager from path: npm (default)");
72977
73518
  return "npm";
72978
73519
  }
72979
73520
  function isAutoUpdateEnabled() {
@@ -72985,22 +73526,22 @@ function isRunningLocally() {
72985
73526
  try {
72986
73527
  resolvedPath = realpathSync2(argv);
72987
73528
  } catch {}
72988
- debugLog2("argv[1]:", argv);
72989
- debugLog2("resolved path:", resolvedPath);
73529
+ debugLog3("argv[1]:", argv);
73530
+ debugLog3("resolved path:", resolvedPath);
72990
73531
  return !resolvedPath.includes("node_modules");
72991
73532
  }
72992
73533
  async function checkForUpdate() {
72993
73534
  const currentVersion = getVersion();
72994
- debugLog2("Current version:", currentVersion);
73535
+ debugLog3("Current version:", currentVersion);
72995
73536
  if (currentVersion.includes("-")) {
72996
- debugLog2("Prerelease version detected, skipping auto-update check");
73537
+ debugLog3("Prerelease version detected, skipping auto-update check");
72997
73538
  return { updateAvailable: false, currentVersion };
72998
73539
  }
72999
73540
  const packageName = resolveUpdatePackageName();
73000
73541
  const registryBaseUrl = resolveUpdateRegistryBaseUrl();
73001
73542
  const latestUrl = buildLatestVersionUrl(packageName, registryBaseUrl);
73002
73543
  try {
73003
- debugLog2("Checking registry for latest version:", latestUrl);
73544
+ debugLog3("Checking registry for latest version:", latestUrl);
73004
73545
  const res = await fetch(latestUrl, {
73005
73546
  signal: AbortSignal.timeout(5000)
73006
73547
  });
@@ -73012,18 +73553,18 @@ async function checkForUpdate() {
73012
73553
  throw new Error("Unexpected registry response shape");
73013
73554
  }
73014
73555
  const latestVersion = data.version;
73015
- debugLog2("Latest version from registry:", latestVersion);
73556
+ debugLog3("Latest version from registry:", latestVersion);
73016
73557
  if (latestVersion !== currentVersion) {
73017
- debugLog2("Update available!");
73558
+ debugLog3("Update available!");
73018
73559
  return {
73019
73560
  updateAvailable: true,
73020
73561
  latestVersion,
73021
73562
  currentVersion
73022
73563
  };
73023
73564
  }
73024
- debugLog2("Already on latest version");
73565
+ debugLog3("Already on latest version");
73025
73566
  } catch (error) {
73026
- debugLog2("Failed to check for updates:", error);
73567
+ debugLog3("Failed to check for updates:", error);
73027
73568
  return {
73028
73569
  updateAvailable: false,
73029
73570
  currentVersion,
@@ -73046,13 +73587,13 @@ async function getNpmGlobalPath() {
73046
73587
  }
73047
73588
  }
73048
73589
  async function cleanupOrphanedDirs(globalPath) {
73049
- const lettaAiDir = join22(globalPath, "lib/node_modules/@letta-ai");
73590
+ const lettaAiDir = join23(globalPath, "lib/node_modules/@letta-ai");
73050
73591
  try {
73051
73592
  const entries = await readdir7(lettaAiDir);
73052
73593
  for (const entry of entries) {
73053
73594
  if (entry.startsWith(".letta-code-")) {
73054
- const orphanPath = join22(lettaAiDir, entry);
73055
- debugLog2("Cleaning orphaned temp directory:", orphanPath);
73595
+ const orphanPath = join23(lettaAiDir, entry);
73596
+ debugLog3("Cleaning orphaned temp directory:", orphanPath);
73056
73597
  await rm(orphanPath, { recursive: true, force: true });
73057
73598
  }
73058
73599
  }
@@ -73062,33 +73603,33 @@ async function performUpdate() {
73062
73603
  const pm = detectPackageManager();
73063
73604
  const installCmd = buildInstallCommand(pm);
73064
73605
  const installArgs = buildInstallArgs(pm);
73065
- debugLog2("Detected package manager:", pm);
73066
- debugLog2("Install command:", installCmd);
73606
+ debugLog3("Detected package manager:", pm);
73607
+ debugLog3("Install command:", installCmd);
73067
73608
  let globalPath = null;
73068
73609
  if (pm === "npm") {
73069
73610
  globalPath = await getNpmGlobalPath();
73070
73611
  if (globalPath) {
73071
- debugLog2("Pre-cleaning orphaned directories in:", globalPath);
73612
+ debugLog3("Pre-cleaning orphaned directories in:", globalPath);
73072
73613
  await cleanupOrphanedDirs(globalPath);
73073
73614
  }
73074
73615
  }
73075
73616
  try {
73076
- debugLog2(`Running ${installCmd}...`);
73617
+ debugLog3(`Running ${installCmd}...`);
73077
73618
  await execFileAsync7(pm, installArgs, { timeout: 60000 });
73078
- debugLog2("Update completed successfully");
73619
+ debugLog3("Update completed successfully");
73079
73620
  return { success: true };
73080
73621
  } catch (error) {
73081
73622
  const errorMsg = error instanceof Error ? error.message : String(error);
73082
73623
  if (pm === "npm" && errorMsg.includes("ENOTEMPTY") && globalPath) {
73083
- debugLog2("ENOTEMPTY detected, attempting cleanup and retry...");
73624
+ debugLog3("ENOTEMPTY detected, attempting cleanup and retry...");
73084
73625
  await cleanupOrphanedDirs(globalPath);
73085
73626
  try {
73086
73627
  await execFileAsync7(pm, installArgs, { timeout: 60000 });
73087
- debugLog2("Update succeeded after cleanup retry");
73628
+ debugLog3("Update succeeded after cleanup retry");
73088
73629
  return { success: true };
73089
73630
  } catch (retryError) {
73090
73631
  const retryMsg = retryError instanceof Error ? retryError.message : String(retryError);
73091
- debugLog2("Update failed after retry:", retryMsg);
73632
+ debugLog3("Update failed after retry:", retryMsg);
73092
73633
  if (retryMsg.includes("ENOTEMPTY")) {
73093
73634
  return {
73094
73635
  success: false,
@@ -73101,21 +73642,21 @@ async function performUpdate() {
73101
73642
  }
73102
73643
  const isNpmRaceCondition = pm === "npm" && (errorMsg.includes("TAR_ENTRY_ERROR") || errorMsg.includes("uv_cwd") || errorMsg.includes("spawn sh") && errorMsg.includes("ENOENT"));
73103
73644
  if (isNpmRaceCondition) {
73104
- debugLog2("npm race condition detected, cleaning up and retrying...");
73645
+ debugLog3("npm race condition detected, cleaning up and retrying...");
73105
73646
  if (globalPath) {
73106
73647
  await cleanupOrphanedDirs(globalPath);
73107
73648
  }
73108
73649
  try {
73109
73650
  await execFileAsync7(pm, installArgs, { timeout: 60000 });
73110
- debugLog2("Update succeeded after race condition retry");
73651
+ debugLog3("Update succeeded after race condition retry");
73111
73652
  return { success: true };
73112
73653
  } catch (retryError) {
73113
73654
  const retryMsg = retryError instanceof Error ? retryError.message : String(retryError);
73114
- debugLog2("Update failed after race condition retry:", retryMsg);
73655
+ debugLog3("Update failed after race condition retry:", retryMsg);
73115
73656
  return { success: false, error: retryMsg };
73116
73657
  }
73117
73658
  }
73118
- debugLog2("Update failed:", error);
73659
+ debugLog3("Update failed:", error);
73119
73660
  return { success: false, error: errorMsg };
73120
73661
  }
73121
73662
  }
@@ -73129,16 +73670,16 @@ function isSignificantUpdate(current, latest) {
73129
73670
  return false;
73130
73671
  }
73131
73672
  async function checkAndAutoUpdate() {
73132
- debugLog2("Auto-update check starting...");
73133
- debugLog2("isAutoUpdateEnabled:", isAutoUpdateEnabled());
73673
+ debugLog3("Auto-update check starting...");
73674
+ debugLog3("isAutoUpdateEnabled:", isAutoUpdateEnabled());
73134
73675
  const runningLocally = isRunningLocally();
73135
- debugLog2("isRunningLocally:", runningLocally);
73676
+ debugLog3("isRunningLocally:", runningLocally);
73136
73677
  if (!isAutoUpdateEnabled()) {
73137
- debugLog2("Auto-update disabled via DISABLE_AUTOUPDATER=1");
73678
+ debugLog3("Auto-update disabled via DISABLE_AUTOUPDATER=1");
73138
73679
  return;
73139
73680
  }
73140
73681
  if (runningLocally) {
73141
- debugLog2("Running locally, skipping auto-update");
73682
+ debugLog3("Running locally, skipping auto-update");
73142
73683
  return;
73143
73684
  }
73144
73685
  const result = await checkForUpdate();
@@ -73313,6 +73854,7 @@ __export(exports_promptAssets2, {
73313
73854
  MEMORY_PROMPTS: () => MEMORY_PROMPTS2,
73314
73855
  MEMORY_CHECK_REMINDER: () => MEMORY_CHECK_REMINDER2,
73315
73856
  INTERRUPT_RECOVERY_ALERT: () => INTERRUPT_RECOVERY_ALERT2,
73857
+ AUTO_INIT_REMINDER: () => AUTO_INIT_REMINDER2,
73316
73858
  APPROVAL_RECOVERY_PROMPT: () => APPROVAL_RECOVERY_PROMPT2
73317
73859
  });
73318
73860
  async function resolveSystemPrompt2(systemPromptPreset) {
@@ -73331,9 +73873,10 @@ async function resolveSystemPrompt2(systemPromptPreset) {
73331
73873
  }
73332
73874
  return SYSTEM_PROMPT2;
73333
73875
  }
73334
- var SYSTEM_PROMPT2, SYSTEM_PROMPT_MEMORY_ADDON2, SYSTEM_PROMPT_MEMFS_ADDON2, PLAN_MODE_REMINDER2, SKILL_CREATOR_PROMPT2, REMEMBER_PROMPT2, MEMORY_CHECK_REMINDER2, MEMORY_REFLECTION_REMINDER2, APPROVAL_RECOVERY_PROMPT2, INTERRUPT_RECOVERY_ALERT2, MEMORY_PROMPTS2, SYSTEM_PROMPTS2;
73876
+ var SYSTEM_PROMPT2, SYSTEM_PROMPT_MEMORY_ADDON2, SYSTEM_PROMPT_MEMFS_ADDON2, PLAN_MODE_REMINDER2, SKILL_CREATOR_PROMPT2, REMEMBER_PROMPT2, MEMORY_CHECK_REMINDER2, MEMORY_REFLECTION_REMINDER2, APPROVAL_RECOVERY_PROMPT2, AUTO_INIT_REMINDER2, INTERRUPT_RECOVERY_ALERT2, MEMORY_PROMPTS2, SYSTEM_PROMPTS2;
73335
73877
  var init_promptAssets2 = __esm(() => {
73336
73878
  init_approval_recovery_alert();
73879
+ init_auto_init_reminder();
73337
73880
  init_claude();
73338
73881
  init_codex();
73339
73882
  init_gemini();
@@ -73366,6 +73909,7 @@ var init_promptAssets2 = __esm(() => {
73366
73909
  MEMORY_CHECK_REMINDER2 = memory_check_reminder_default;
73367
73910
  MEMORY_REFLECTION_REMINDER2 = memory_reflection_reminder_default;
73368
73911
  APPROVAL_RECOVERY_PROMPT2 = approval_recovery_alert_default;
73912
+ AUTO_INIT_REMINDER2 = auto_init_reminder_default;
73369
73913
  INTERRUPT_RECOVERY_ALERT2 = interrupt_recovery_alert_default;
73370
73914
  MEMORY_PROMPTS2 = {
73371
73915
  "persona.mdx": persona_default,
@@ -73438,9 +73982,9 @@ __export(exports_subagents2, {
73438
73982
  GLOBAL_AGENTS_DIR: () => GLOBAL_AGENTS_DIR2,
73439
73983
  AGENTS_DIR: () => AGENTS_DIR2
73440
73984
  });
73441
- import { existsSync as existsSync15 } from "node:fs";
73985
+ import { existsSync as existsSync16 } from "node:fs";
73442
73986
  import { readdir as readdir8, readFile as readFile7 } from "node:fs/promises";
73443
- import { join as join24 } from "node:path";
73987
+ import { join as join25 } from "node:path";
73444
73988
  function isValidName2(name) {
73445
73989
  return /^[a-z][a-z0-9-]*$/.test(name);
73446
73990
  }
@@ -73522,7 +74066,7 @@ function getBuiltinSubagentNames2() {
73522
74066
  return new Set(Object.keys(getBuiltinSubagents2()));
73523
74067
  }
73524
74068
  async function discoverSubagentsFromDir2(agentsDir, seenNames, subagents, errors) {
73525
- if (!existsSync15(agentsDir)) {
74069
+ if (!existsSync16(agentsDir)) {
73526
74070
  return;
73527
74071
  }
73528
74072
  try {
@@ -73531,7 +74075,7 @@ async function discoverSubagentsFromDir2(agentsDir, seenNames, subagents, errors
73531
74075
  if (!entry.isFile() || !entry.name.endsWith(".md")) {
73532
74076
  continue;
73533
74077
  }
73534
- const filePath = join24(agentsDir, entry.name);
74078
+ const filePath = join25(agentsDir, entry.name);
73535
74079
  try {
73536
74080
  const config = await parseSubagentFile2(filePath);
73537
74081
  if (config) {
@@ -73563,7 +74107,7 @@ async function discoverSubagents2(workingDirectory = process.cwd()) {
73563
74107
  const subagents = [];
73564
74108
  const seenNames = new Set;
73565
74109
  await discoverSubagentsFromDir2(GLOBAL_AGENTS_DIR2, seenNames, subagents, errors);
73566
- const projectAgentsDir = join24(workingDirectory, AGENTS_DIR2);
74110
+ const projectAgentsDir = join25(workingDirectory, AGENTS_DIR2);
73567
74111
  await discoverSubagentsFromDir2(projectAgentsDir, seenNames, subagents, errors);
73568
74112
  return { subagents, errors };
73569
74113
  }
@@ -73606,7 +74150,7 @@ var init_subagents2 = __esm(() => {
73606
74150
  recall_default,
73607
74151
  reflection_default
73608
74152
  ];
73609
- GLOBAL_AGENTS_DIR2 = join24(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents");
74153
+ GLOBAL_AGENTS_DIR2 = join25(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents");
73610
74154
  VALID_MEMORY_BLOCKS2 = new Set(MEMORY_BLOCK_LABELS);
73611
74155
  cache5 = {
73612
74156
  builtins: null,
@@ -73978,24 +74522,6 @@ var init_cli2 = __esm(() => {
73978
74522
  cliPermissions2 = new CliPermissions2;
73979
74523
  });
73980
74524
 
73981
- // src/agent/approval-recovery.ts
73982
- async function fetchRunErrorDetail(runId) {
73983
- if (!runId)
73984
- return null;
73985
- try {
73986
- const client = await getClient2();
73987
- const run = await client.runs.retrieve(runId);
73988
- const metaError = run.metadata?.error;
73989
- return metaError?.detail ?? metaError?.message ?? metaError?.error?.detail ?? metaError?.error?.message ?? null;
73990
- } catch {
73991
- return null;
73992
- }
73993
- }
73994
- var init_approval_recovery = __esm(async () => {
73995
- init_turn_recovery_policy();
73996
- await init_client2();
73997
- });
73998
-
73999
74525
  // src/agent/listMessagesRouting.ts
74000
74526
  function resolveListMessagesRoute(listReq, sessionConvId, sessionAgentId) {
74001
74527
  const targetConvId = listReq.conversation_id ?? sessionConvId;
@@ -74003,7 +74529,7 @@ function resolveListMessagesRoute(listReq, sessionConvId, sessionAgentId) {
74003
74529
  return { kind: "conversations", conversationId: targetConvId };
74004
74530
  }
74005
74531
  const agentId = listReq.agent_id ?? sessionAgentId;
74006
- return { kind: "conversations", conversationId: agentId };
74532
+ return { kind: "conversations", conversationId: "default", agentId };
74007
74533
  }
74008
74534
 
74009
74535
  // src/agent/bootstrapHandler.ts
@@ -74022,7 +74548,7 @@ async function handleBootstrapSessionState(params) {
74022
74548
  try {
74023
74549
  const route = resolveListMessagesRoute({ conversation_id: undefined, agent_id: sessionContext.agentId }, sessionContext.conversationId, sessionContext.agentId);
74024
74550
  const listStart = Date.now();
74025
- const page = await client.conversations.messages.list(route.conversationId, { limit: limit2, order });
74551
+ const page = await client.conversations.messages.list(route.conversationId, { limit: limit2, order, ...route.agentId ? { agent_id: route.agentId } : {} });
74026
74552
  const items = page.getPaginatedItems();
74027
74553
  const listEnd = Date.now();
74028
74554
  const hasMore = items.length >= limit2;
@@ -74377,7 +74903,12 @@ async function handleListMessages(params) {
74377
74903
  };
74378
74904
  try {
74379
74905
  const route = resolveListMessagesRoute(listReq, sessionConversationId, sessionAgentId);
74380
- const page = await client.conversations.messages.list(route.conversationId, { limit: limit2, order, ...cursorOpts });
74906
+ const page = await client.conversations.messages.list(route.conversationId, {
74907
+ limit: limit2,
74908
+ order,
74909
+ ...route.agentId ? { agent_id: route.agentId } : {},
74910
+ ...cursorOpts
74911
+ });
74381
74912
  const items = page.getPaginatedItems();
74382
74913
  const hasMore = items.length >= limit2;
74383
74914
  const oldestId = items.length > 0 ? items[items.length - 1]?.id : undefined;
@@ -74998,6 +75529,11 @@ var init_catalog = __esm(() => {
74998
75529
  description: "Compaction-triggered reflection reminder/auto-launch behavior",
74999
75530
  modes: ["interactive", "headless-one-shot", "headless-bidirectional"]
75000
75531
  },
75532
+ {
75533
+ id: "deep-init",
75534
+ description: "Auto-launch deep memory init after shallow init + turn gate",
75535
+ modes: ["interactive"]
75536
+ },
75001
75537
  {
75002
75538
  id: "command-io",
75003
75539
  description: "Recent slash command input/output context",
@@ -75007,6 +75543,11 @@ var init_catalog = __esm(() => {
75007
75543
  id: "toolset-change",
75008
75544
  description: "Client-side toolset change context",
75009
75545
  modes: ["interactive"]
75546
+ },
75547
+ {
75548
+ id: "auto-init",
75549
+ description: "Auto-init background onboarding notification",
75550
+ modes: ["interactive"]
75010
75551
  }
75011
75552
  ];
75012
75553
  SHARED_REMINDER_IDS = SHARED_REMINDER_CATALOG.map((entry) => entry.id);
@@ -75014,7 +75555,7 @@ var init_catalog = __esm(() => {
75014
75555
  });
75015
75556
 
75016
75557
  // src/reminders/engine.ts
75017
- import { join as join25 } from "node:path";
75558
+ import { join as join26 } from "node:path";
75018
75559
  async function buildAgentInfoReminder(context3) {
75019
75560
  if (context3.state.hasSentAgentInfo) {
75020
75561
  return null;
@@ -75046,7 +75587,7 @@ async function buildSkillsReminder(context3) {
75046
75587
  const previousSkillsReminder = context3.state.cachedSkillsReminder;
75047
75588
  let latestSkillsReminder = previousSkillsReminder ?? "";
75048
75589
  try {
75049
- const skillsDir = getSkillsDirectory() || join25(process.cwd(), SKILLS_DIR);
75590
+ const skillsDir = getSkillsDirectory() || join26(process.cwd(), SKILLS_DIR);
75050
75591
  const { skills } = await discoverSkills(skillsDir, context3.agent.id, {
75051
75592
  sources: context3.skillSources
75052
75593
  });
@@ -75129,6 +75670,30 @@ async function buildReflectionCompactionReminder(context3) {
75129
75670
  }
75130
75671
  return buildCompactionMemoryReminder(context3.agent.id);
75131
75672
  }
75673
+ async function buildAutoInitReminder(context3) {
75674
+ if (!context3.state.pendingAutoInitReminder)
75675
+ return null;
75676
+ context3.state.pendingAutoInitReminder = false;
75677
+ const { AUTO_INIT_REMINDER: AUTO_INIT_REMINDER3 } = await Promise.resolve().then(() => (init_promptAssets(), exports_promptAssets));
75678
+ return AUTO_INIT_REMINDER3;
75679
+ }
75680
+ async function maybeLaunchDeepInit(context3) {
75681
+ if (!DEEP_INIT_AUTO_LAUNCH_ENABLED)
75682
+ return null;
75683
+ if (!context3.state.shallowInitCompleted)
75684
+ return null;
75685
+ if (context3.state.deepInitFired)
75686
+ return null;
75687
+ if (context3.state.turnCount < 8)
75688
+ return null;
75689
+ const memfsEnabled = settingsManager.isMemfsEnabled(context3.agent.id);
75690
+ if (!memfsEnabled)
75691
+ return null;
75692
+ if (context3.maybeLaunchDeepInitSubagent) {
75693
+ await context3.maybeLaunchDeepInitSubagent();
75694
+ }
75695
+ return null;
75696
+ }
75132
75697
  function escapeXml2(value) {
75133
75698
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
75134
75699
  }
@@ -75152,26 +75717,24 @@ async function buildCommandIoReminder(context3) {
75152
75717
  const queued = context3.state.pendingCommandIoReminders.splice(0);
75153
75718
  const recent = queued.slice(-MAX_COMMAND_REMINDERS_PER_TURN);
75154
75719
  const dropped = queued.length - recent.length;
75155
- const commandBlocks = recent.map((entry) => {
75720
+ const commandLines = recent.map((entry) => {
75156
75721
  const status = entry.success ? "success" : "error";
75157
- const safeInput = escapeXml2(truncate(entry.input, MAX_COMMAND_INPUT_CHARS));
75158
- const safeOutput = escapeXml2(truncate(entry.output || "(no output)", MAX_COMMAND_OUTPUT_CHARS));
75159
- return `<user-command>
75160
- <user-command-input>${safeInput}</user-command-input>
75161
- <user-command-output>${safeOutput}</user-command-output>
75162
- <user-command-status>${status}</user-command-status>
75163
- </user-command>`;
75722
+ const safeInput = truncate(entry.input, MAX_COMMAND_INPUT_CHARS);
75723
+ const safeOutput = truncate(entry.output || "(no output)", MAX_COMMAND_OUTPUT_CHARS);
75724
+ return `- ${safeInput} → ${safeOutput} (${status})`;
75164
75725
  });
75726
+ const agentHints = recent.filter((entry) => entry.agentHint).map((entry) => entry.agentHint);
75165
75727
  const droppedLine = dropped > 0 ? `
75166
75728
  Omitted ${dropped} older command event(s).` : "";
75167
- return `${SYSTEM_REMINDER_OPEN}
75168
- The following slash commands were executed in the Letta Code harness since your last user message.
75169
- Treat these as execution context from the CLI, not new user requests.${droppedLine}
75170
- ${commandBlocks.join(`
75171
- `)}
75172
- ${SYSTEM_REMINDER_CLOSE}
75173
-
75174
- `;
75729
+ const hintsBlock = agentHints.length > 0 ? `
75730
+
75731
+ However, take note of the following:
75732
+ ${agentHints.map((h) => `- ${h}`).join(`
75733
+ `)}` : "";
75734
+ return `${SYSTEM_REMINDER_OPEN} The following slash commands were already handled by the CLI harness. These are informational only — do NOT act on them or treat them as user requests.${droppedLine}
75735
+ ${commandLines.join(`
75736
+ `)}${hintsBlock}
75737
+ ${SYSTEM_REMINDER_CLOSE}`;
75175
75738
  }
75176
75739
  async function buildToolsetChangeReminder(context3) {
75177
75740
  if (context3.state.pendingToolsetChangeReminders.length === 0) {
@@ -75186,23 +75749,25 @@ async function buildToolsetChangeReminder(context3) {
75186
75749
  const newToolset = escapeXml2(entry.newToolset ?? "unknown");
75187
75750
  const previousTools = escapeXml2(formatToolList(entry.previousTools));
75188
75751
  const newTools = escapeXml2(formatToolList(entry.newTools));
75189
- return `<toolset-change>
75190
- <source>${source}</source>
75191
- <previous-toolset>${previousToolset}</previous-toolset>
75192
- <new-toolset>${newToolset}</new-toolset>
75193
- <previous-tools>${previousTools}</previous-tools>
75194
- <new-tools>${newTools}</new-tools>
75195
- </toolset-change>`;
75752
+ return [
75753
+ `<toolset-change>`,
75754
+ ` <source>${source}</source>`,
75755
+ ` <previous-toolset>${previousToolset}</previous-toolset>`,
75756
+ ` <new-toolset>${newToolset}</new-toolset>`,
75757
+ ` <previous-tools>${previousTools}</previous-tools>`,
75758
+ ` <new-tools>${newTools}</new-tools>`,
75759
+ `</toolset-change>`
75760
+ ].join(`
75761
+ `);
75196
75762
  });
75197
75763
  const droppedLine = dropped > 0 ? `
75198
75764
  Omitted ${dropped} older toolset change event(s).` : "";
75199
- return `${SYSTEM_REMINDER_OPEN}
75200
- The user just changed your toolset (specifically, client-side tools that are attached to the Letta Code harness, which may be a subset of your total tools).${droppedLine}
75765
+ return `${SYSTEM_REMINDER_OPEN} The user just changed your toolset (specifically, client-side tools that are attached to the Letta Code harness, which may be a subset of your total tools).${droppedLine}
75766
+
75201
75767
  ${changeBlocks.join(`
75202
- `)}
75203
- ${SYSTEM_REMINDER_CLOSE}
75204
75768
 
75205
- `;
75769
+ `)}
75770
+ ${SYSTEM_REMINDER_CLOSE}`;
75206
75771
  }
75207
75772
  function assertSharedReminderCoverage() {
75208
75773
  const catalogIds = new Set(SHARED_REMINDER_CATALOG.map((entry) => entry.id));
@@ -75250,7 +75815,7 @@ function prependReminderPartsToContent(content, reminderParts) {
75250
75815
  }
75251
75816
  return content;
75252
75817
  }
75253
- var PERMISSION_MODE_DESCRIPTIONS, MAX_COMMAND_REMINDERS_PER_TURN = 10, MAX_TOOLSET_REMINDERS_PER_TURN = 5, MAX_COMMAND_INPUT_CHARS = 2000, MAX_COMMAND_OUTPUT_CHARS = 4000, MAX_TOOL_LIST_CHARS = 3000, sharedReminderProviders;
75818
+ var PERMISSION_MODE_DESCRIPTIONS, DEEP_INIT_AUTO_LAUNCH_ENABLED = false, MAX_COMMAND_REMINDERS_PER_TURN = 10, MAX_TOOLSET_REMINDERS_PER_TURN = 5, MAX_COMMAND_INPUT_CHARS = 2000, MAX_COMMAND_OUTPUT_CHARS = 4000, MAX_TOOL_LIST_CHARS = 3000, sharedReminderProviders;
75254
75819
  var init_engine = __esm(async () => {
75255
75820
  init_context();
75256
75821
  init_skills();
@@ -75277,8 +75842,10 @@ var init_engine = __esm(async () => {
75277
75842
  "plan-mode": buildPlanModeReminder,
75278
75843
  "reflection-step-count": buildReflectionStepReminder,
75279
75844
  "reflection-compaction": buildReflectionCompactionReminder,
75845
+ "deep-init": maybeLaunchDeepInit,
75280
75846
  "command-io": buildCommandIoReminder,
75281
- "toolset-change": buildToolsetChangeReminder
75847
+ "toolset-change": buildToolsetChangeReminder,
75848
+ "auto-init": buildAutoInitReminder
75282
75849
  };
75283
75850
  assertSharedReminderCoverage();
75284
75851
  });
@@ -75295,8 +75862,11 @@ function createSharedReminderState() {
75295
75862
  turnCount: 0,
75296
75863
  pendingSkillsReinject: false,
75297
75864
  pendingReflectionTrigger: false,
75865
+ pendingAutoInitReminder: false,
75298
75866
  pendingCommandIoReminders: [],
75299
- pendingToolsetChangeReminders: []
75867
+ pendingToolsetChangeReminders: [],
75868
+ shallowInitCompleted: false,
75869
+ deepInitFired: false
75300
75870
  };
75301
75871
  }
75302
75872
  function resetSharedReminderState(state) {
@@ -75480,7 +76050,7 @@ function parseRegistryHandle(handle) {
75480
76050
  }
75481
76051
  async function importAgentFromRegistry(options) {
75482
76052
  const { tmpdir: tmpdir3 } = await import("node:os");
75483
- const { join: join26 } = await import("node:path");
76053
+ const { join: join27 } = await import("node:path");
75484
76054
  const { writeFile: writeFile4, unlink } = await import("node:fs/promises");
75485
76055
  const { author, name } = parseRegistryHandle(options.handle);
75486
76056
  const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER}/${AGENT_REGISTRY_REPO}/refs/heads/${AGENT_REGISTRY_BRANCH}/agents/@${author}/${name}/${name}.af`;
@@ -75492,7 +76062,7 @@ async function importAgentFromRegistry(options) {
75492
76062
  throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
75493
76063
  }
75494
76064
  const afContent = await response.text();
75495
- const tempPath = join26(tmpdir3(), `letta-import-${author}-${name}-${Date.now()}.af`);
76065
+ const tempPath = join27(tmpdir3(), `letta-import-${author}-${name}-${Date.now()}.af`);
75496
76066
  await writeFile4(tempPath, afContent, "utf-8");
75497
76067
  try {
75498
76068
  const result = await importAgentFromFile({
@@ -75985,6 +76555,7 @@ In headless mode, use:
75985
76555
  }
75986
76556
  if (specifiedConversationId && specifiedConversationId !== "default") {
75987
76557
  try {
76558
+ debugLog("conversations", `retrieve(${specifiedConversationId}) [headless conv→agent lookup]`);
75988
76559
  const conversation = await client.conversations.retrieve(specifiedConversationId);
75989
76560
  agent = await client.agents.retrieve(conversation.agent_id);
75990
76561
  } catch (_error) {
@@ -76162,6 +76733,7 @@ In headless mode, use:
76162
76733
  conversationId = "default";
76163
76734
  } else {
76164
76735
  try {
76736
+ debugLog("conversations", `retrieve(${specifiedConversationId}) [headless --conv validate]`);
76165
76737
  await client.conversations.retrieve(specifiedConversationId);
76166
76738
  conversationId = specifiedConversationId;
76167
76739
  } catch {
@@ -76177,6 +76749,7 @@ In headless mode, use:
76177
76749
  conversationId = "default";
76178
76750
  } else {
76179
76751
  try {
76752
+ debugLog("conversations", `retrieve(${lastSession.conversationId}) [headless lastSession resume]`);
76180
76753
  await client.conversations.retrieve(lastSession.conversationId);
76181
76754
  conversationId = lastSession.conversationId;
76182
76755
  } catch {
@@ -76493,21 +77066,22 @@ ${loadedContents.join(`
76493
77066
  }
76494
77067
  if (preStreamAction === "retry_conversation_busy") {
76495
77068
  conversationBusyRetries += 1;
77069
+ const retryDelayMs = CONVERSATION_BUSY_RETRY_BASE_DELAY_MS * 2 ** (conversationBusyRetries - 1);
76496
77070
  if (outputFormat === "stream-json") {
76497
77071
  const retryMsg = {
76498
77072
  type: "retry",
76499
77073
  reason: "error",
76500
77074
  attempt: conversationBusyRetries,
76501
77075
  max_attempts: CONVERSATION_BUSY_MAX_RETRIES,
76502
- delay_ms: CONVERSATION_BUSY_RETRY_DELAY_MS,
77076
+ delay_ms: retryDelayMs,
76503
77077
  session_id: sessionId,
76504
77078
  uuid: `retry-conversation-busy-${randomUUID7()}`
76505
77079
  };
76506
77080
  console.log(JSON.stringify(retryMsg));
76507
77081
  } else {
76508
- console.error(`Conversation is busy, waiting ${CONVERSATION_BUSY_RETRY_DELAY_MS / 1000}s and retrying...`);
77082
+ console.error(`Conversation is busy, waiting ${Math.round(retryDelayMs / 1000)}s and retrying...`);
76509
77083
  }
76510
- await new Promise((resolve25) => setTimeout(resolve25, CONVERSATION_BUSY_RETRY_DELAY_MS));
77084
+ await new Promise((resolve25) => setTimeout(resolve25, retryDelayMs));
76511
77085
  continue;
76512
77086
  }
76513
77087
  if (preStreamAction === "retry_transient") {
@@ -77789,7 +78363,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
77789
78363
  setMessageQueueAdder(null);
77790
78364
  process.exit(0);
77791
78365
  }
77792
- var LLM_API_ERROR_MAX_RETRIES2 = 3, EMPTY_RESPONSE_MAX_RETRIES = 2, CONVERSATION_BUSY_MAX_RETRIES = 1, CONVERSATION_BUSY_RETRY_DELAY_MS = 2500;
78366
+ var LLM_API_ERROR_MAX_RETRIES2 = 3, EMPTY_RESPONSE_MAX_RETRIES = 2, CONVERSATION_BUSY_MAX_RETRIES = 3, CONVERSATION_BUSY_RETRY_BASE_DELAY_MS = 1e4;
77793
78367
  var init_headless = __esm(async () => {
77794
78368
  init_error();
77795
78369
  init_bootstrapHandler();
@@ -77802,6 +78376,7 @@ var init_headless = __esm(async () => {
77802
78376
  init_constants();
77803
78377
  init_diffPreview();
77804
78378
  init_interactivePolicy();
78379
+ init_debug();
77805
78380
  init_timing();
77806
78381
  await __promiseAll([
77807
78382
  init_approval_recovery(),
@@ -78111,10 +78686,10 @@ __export(exports_settings, {
78111
78686
  loadProjectSettings: () => loadProjectSettings,
78112
78687
  getSetting: () => getSetting
78113
78688
  });
78114
- import { homedir as homedir20 } from "node:os";
78115
- import { join as join27 } from "node:path";
78689
+ import { homedir as homedir21 } from "node:os";
78690
+ import { join as join28 } from "node:path";
78116
78691
  function getSettingsPath() {
78117
- return join27(homedir20(), ".letta", "settings.json");
78692
+ return join28(homedir21(), ".letta", "settings.json");
78118
78693
  }
78119
78694
  async function loadSettings() {
78120
78695
  const settingsPath = getSettingsPath();
@@ -78151,7 +78726,7 @@ async function getSetting(key) {
78151
78726
  return settings[key];
78152
78727
  }
78153
78728
  function getProjectSettingsPath() {
78154
- return join27(process.cwd(), ".letta", "settings.local.json");
78729
+ return join28(process.cwd(), ".letta", "settings.local.json");
78155
78730
  }
78156
78731
  async function loadProjectSettings() {
78157
78732
  const settingsPath = getProjectSettingsPath();
@@ -78169,7 +78744,7 @@ async function loadProjectSettings() {
78169
78744
  }
78170
78745
  async function saveProjectSettings(settings) {
78171
78746
  const settingsPath = getProjectSettingsPath();
78172
- const dirPath = join27(process.cwd(), ".letta");
78747
+ const dirPath = join28(process.cwd(), ".letta");
78173
78748
  try {
78174
78749
  if (!exists(dirPath)) {
78175
78750
  await mkdir(dirPath, { recursive: true });
@@ -78671,6 +79246,13 @@ function createCommandRunner({
78671
79246
  onCommandFinished
78672
79247
  }) {
78673
79248
  function getHandle(id, input) {
79249
+ const handle = {
79250
+ id,
79251
+ input,
79252
+ update: null,
79253
+ finish: null,
79254
+ fail: null
79255
+ };
78674
79256
  const update = (updateData) => {
78675
79257
  const previous = buffersRef.current.byId.get(id);
78676
79258
  const wasFinished = previous?.kind === "command" && previous.phase === "finished";
@@ -78687,24 +79269,26 @@ function createCommandRunner({
78687
79269
  output: next.output,
78688
79270
  success: next.success !== false,
78689
79271
  dimOutput: next.dimOutput,
78690
- preformatted: next.preformatted
79272
+ preformatted: next.preformatted,
79273
+ agentHint: handle.agentHint
78691
79274
  });
78692
79275
  }
78693
79276
  refreshDerived();
78694
79277
  };
78695
- const finish = (finalOutput, success = true, dimOutput, preformatted) => update({
79278
+ handle.update = update;
79279
+ handle.finish = (finalOutput, success = true, dimOutput, preformatted) => update({
78696
79280
  output: finalOutput,
78697
79281
  phase: "finished",
78698
79282
  success,
78699
79283
  dimOutput,
78700
79284
  preformatted
78701
79285
  });
78702
- const fail = (finalOutput) => update({
79286
+ handle.fail = (finalOutput) => update({
78703
79287
  output: finalOutput,
78704
79288
  phase: "finished",
78705
79289
  success: false
78706
79290
  });
78707
- return { id, input, update, finish, fail };
79291
+ return handle;
78708
79292
  }
78709
79293
  function start(input, output) {
78710
79294
  const id = createId("cmd");
@@ -80477,9 +81061,9 @@ function getFileEditHeader(toolName, toolArgs) {
80477
81061
  const relPath = relative9(cwd2, filePath);
80478
81062
  const displayPath = relPath.startsWith("..") ? filePath : relPath;
80479
81063
  if (t === "write" || t === "write_file" || t === "writefile" || t === "write_file_gemini" || t === "writefilegemini") {
80480
- const { existsSync: existsSync17 } = __require("node:fs");
81064
+ const { existsSync: existsSync18 } = __require("node:fs");
80481
81065
  try {
80482
- if (existsSync17(filePath)) {
81066
+ if (existsSync18(filePath)) {
80483
81067
  return `Overwrite ${displayPath}?`;
80484
81068
  }
80485
81069
  } catch {}
@@ -81181,9 +81765,9 @@ function getHeaderText(fileEdit) {
81181
81765
  const relPath = relative9(cwd2, fileEdit.filePath);
81182
81766
  const displayPath = relPath.startsWith("..") ? fileEdit.filePath : relPath;
81183
81767
  if (t === "write" || t === "write_file" || t === "writefile" || t === "write_file_gemini" || t === "writefilegemini") {
81184
- const { existsSync: existsSync17 } = __require("node:fs");
81768
+ const { existsSync: existsSync18 } = __require("node:fs");
81185
81769
  try {
81186
- if (existsSync17(fileEdit.filePath)) {
81770
+ if (existsSync18(fileEdit.filePath)) {
81187
81771
  return `Overwrite ${displayPath}?`;
81188
81772
  }
81189
81773
  } catch {}
@@ -82821,9 +83405,9 @@ html.dark .agent-name { color: var(--text-dim); }
82821
83405
  var init_plan_viewer_template = () => {};
82822
83406
 
82823
83407
  // src/web/generate-plan-viewer.ts
82824
- import { chmodSync as chmodSync2, existsSync as existsSync17, mkdirSync as mkdirSync13, writeFileSync as writeFileSync8 } from "node:fs";
82825
- import { homedir as homedir21 } from "node:os";
82826
- import { join as join28 } from "node:path";
83408
+ import { chmodSync as chmodSync2, existsSync as existsSync18, mkdirSync as mkdirSync14, writeFileSync as writeFileSync8 } from "node:fs";
83409
+ import { homedir as homedir22 } from "node:os";
83410
+ import { join as join29 } from "node:path";
82827
83411
  async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
82828
83412
  const data = {
82829
83413
  agent: { name: options?.agentName ?? "" },
@@ -82833,13 +83417,13 @@ async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
82833
83417
  };
82834
83418
  const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
82835
83419
  const html = plan_viewer_template_default.replace("<!--LETTA_PLAN_DATA_PLACEHOLDER-->", () => jsonPayload);
82836
- if (!existsSync17(VIEWERS_DIR)) {
82837
- mkdirSync13(VIEWERS_DIR, { recursive: true, mode: 448 });
83420
+ if (!existsSync18(VIEWERS_DIR)) {
83421
+ mkdirSync14(VIEWERS_DIR, { recursive: true, mode: 448 });
82838
83422
  }
82839
83423
  try {
82840
83424
  chmodSync2(VIEWERS_DIR, 448);
82841
83425
  } catch {}
82842
- const filePath = join28(VIEWERS_DIR, "plan.html");
83426
+ const filePath = join29(VIEWERS_DIR, "plan.html");
82843
83427
  writeFileSync8(filePath, html);
82844
83428
  chmodSync2(filePath, 384);
82845
83429
  const skipOpen = Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
@@ -82856,7 +83440,7 @@ async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
82856
83440
  var VIEWERS_DIR;
82857
83441
  var init_generate_plan_viewer = __esm(() => {
82858
83442
  init_plan_viewer_template();
82859
- VIEWERS_DIR = join28(homedir21(), ".letta", "viewers");
83443
+ VIEWERS_DIR = join29(homedir22(), ".letta", "viewers");
82860
83444
  });
82861
83445
 
82862
83446
  // src/cli/components/StaticPlanApproval.tsx
@@ -84054,7 +84638,8 @@ function ConversationSelector2({
84054
84638
  let defaultConversation = null;
84055
84639
  if (!afterCursor) {
84056
84640
  try {
84057
- const defaultMessages = await client.conversations.messages.list(agentId, {
84641
+ const defaultMessages = await client.conversations.messages.list("default", {
84642
+ agent_id: agentId,
84058
84643
  limit: 20,
84059
84644
  order: "desc"
84060
84645
  });
@@ -84829,9 +85414,9 @@ var init_pasteRegistry = __esm(() => {
84829
85414
 
84830
85415
  // src/cli/helpers/clipboard.ts
84831
85416
  import { execFileSync as execFileSync2 } from "node:child_process";
84832
- import { existsSync as existsSync18, readFileSync as readFileSync5, statSync as statSync4, unlinkSync as unlinkSync7 } from "node:fs";
85417
+ import { existsSync as existsSync19, readFileSync as readFileSync6, statSync as statSync4, unlinkSync as unlinkSync8 } from "node:fs";
84833
85418
  import { tmpdir as tmpdir3 } from "node:os";
84834
- import { basename as basename4, extname as extname5, isAbsolute as isAbsolute16, join as join29, resolve as resolve25 } from "node:path";
85419
+ import { basename as basename4, extname as extname5, isAbsolute as isAbsolute16, join as join30, resolve as resolve25 } from "node:path";
84835
85420
  function countLines2(text) {
84836
85421
  return (text.match(/\r\n|\r|\n/g) || []).length + 1;
84837
85422
  }
@@ -84881,8 +85466,8 @@ function translatePasteForImages(paste) {
84881
85466
  if (!isAbsolute16(filePath))
84882
85467
  filePath = resolve25(process.cwd(), filePath);
84883
85468
  const ext3 = extname5(filePath || "").toLowerCase();
84884
- if (IMAGE_EXTS.has(ext3) && existsSync18(filePath) && statSync4(filePath).isFile()) {
84885
- const buf = readFileSync5(filePath);
85469
+ if (IMAGE_EXTS.has(ext3) && existsSync19(filePath) && statSync4(filePath).isFile()) {
85470
+ const buf = readFileSync6(filePath);
84886
85471
  const b64 = buf.toString("base64");
84887
85472
  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";
84888
85473
  const id = allocateImage({
@@ -84899,7 +85484,7 @@ function translatePasteForImages(paste) {
84899
85484
  function getClipboardImageToTempFile() {
84900
85485
  if (process.platform !== "darwin")
84901
85486
  return null;
84902
- const tempPath = join29(tmpdir3(), `letta-clipboard-${Date.now()}.bin`);
85487
+ const tempPath = join30(tmpdir3(), `letta-clipboard-${Date.now()}.bin`);
84903
85488
  try {
84904
85489
  const jxa = `
84905
85490
  ObjC.import('AppKit');
@@ -84922,13 +85507,13 @@ function getClipboardImageToTempFile() {
84922
85507
  encoding: "utf8",
84923
85508
  stdio: ["ignore", "pipe", "ignore"]
84924
85509
  }).trim();
84925
- if (!uti || !existsSync18(tempPath))
85510
+ if (!uti || !existsSync19(tempPath))
84926
85511
  return null;
84927
85512
  return { tempPath, uti };
84928
85513
  } catch {
84929
- if (existsSync18(tempPath)) {
85514
+ if (existsSync19(tempPath)) {
84930
85515
  try {
84931
- unlinkSync7(tempPath);
85516
+ unlinkSync8(tempPath);
84932
85517
  } catch {}
84933
85518
  }
84934
85519
  return null;
@@ -84942,9 +85527,9 @@ async function tryImportClipboardImageMac() {
84942
85527
  return null;
84943
85528
  const { tempPath, uti } = clipboardResult;
84944
85529
  try {
84945
- const buffer = readFileSync5(tempPath);
85530
+ const buffer = readFileSync6(tempPath);
84946
85531
  try {
84947
- unlinkSync7(tempPath);
85532
+ unlinkSync8(tempPath);
84948
85533
  } catch {}
84949
85534
  const mediaType = UTI_TO_MEDIA_TYPE[uti] || "image/png";
84950
85535
  const resized = await resizeImageIfNeeded3(buffer, mediaType);
@@ -84959,9 +85544,9 @@ async function tryImportClipboardImageMac() {
84959
85544
  height: resized.height
84960
85545
  };
84961
85546
  } catch (err) {
84962
- if (existsSync18(tempPath)) {
85547
+ if (existsSync19(tempPath)) {
84963
85548
  try {
84964
- unlinkSync7(tempPath);
85549
+ unlinkSync8(tempPath);
84965
85550
  } catch {}
84966
85551
  }
84967
85552
  const message = err instanceof Error ? err.message : String(err);
@@ -85536,13 +86121,13 @@ __export(exports_terminalKeybindingInstaller, {
85536
86121
  });
85537
86122
  import {
85538
86123
  copyFileSync,
85539
- existsSync as existsSync19,
85540
- mkdirSync as mkdirSync14,
85541
- readFileSync as readFileSync6,
86124
+ existsSync as existsSync20,
86125
+ mkdirSync as mkdirSync15,
86126
+ readFileSync as readFileSync7,
85542
86127
  writeFileSync as writeFileSync9
85543
86128
  } from "node:fs";
85544
- import { homedir as homedir22, platform as platform4 } from "node:os";
85545
- import { dirname as dirname11, join as join30 } from "node:path";
86129
+ import { homedir as homedir23, platform as platform4 } from "node:os";
86130
+ import { dirname as dirname11, join as join31 } from "node:path";
85546
86131
  function detectTerminalType() {
85547
86132
  if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
85548
86133
  return "cursor";
@@ -85574,16 +86159,16 @@ function getKeybindingsPath(terminal) {
85574
86159
  }[terminal];
85575
86160
  const os6 = platform4();
85576
86161
  if (os6 === "darwin") {
85577
- return join30(homedir22(), "Library", "Application Support", appName, "User", "keybindings.json");
86162
+ return join31(homedir23(), "Library", "Application Support", appName, "User", "keybindings.json");
85578
86163
  }
85579
86164
  if (os6 === "win32") {
85580
86165
  const appData = process.env.APPDATA;
85581
86166
  if (!appData)
85582
86167
  return null;
85583
- return join30(appData, appName, "User", "keybindings.json");
86168
+ return join31(appData, appName, "User", "keybindings.json");
85584
86169
  }
85585
86170
  if (os6 === "linux") {
85586
- return join30(homedir22(), ".config", appName, "User", "keybindings.json");
86171
+ return join31(homedir23(), ".config", appName, "User", "keybindings.json");
85587
86172
  }
85588
86173
  return null;
85589
86174
  }
@@ -85605,10 +86190,10 @@ function parseKeybindings(content) {
85605
86190
  }
85606
86191
  }
85607
86192
  function keybindingExists(keybindingsPath) {
85608
- if (!existsSync19(keybindingsPath))
86193
+ if (!existsSync20(keybindingsPath))
85609
86194
  return false;
85610
86195
  try {
85611
- const content = readFileSync6(keybindingsPath, { encoding: "utf-8" });
86196
+ const content = readFileSync7(keybindingsPath, { encoding: "utf-8" });
85612
86197
  const keybindings = parseKeybindings(content);
85613
86198
  if (!keybindings)
85614
86199
  return false;
@@ -85618,7 +86203,7 @@ function keybindingExists(keybindingsPath) {
85618
86203
  }
85619
86204
  }
85620
86205
  function createBackup(keybindingsPath) {
85621
- if (!existsSync19(keybindingsPath))
86206
+ if (!existsSync20(keybindingsPath))
85622
86207
  return null;
85623
86208
  const backupPath = `${keybindingsPath}.letta-backup`;
85624
86209
  try {
@@ -85634,14 +86219,14 @@ function installKeybinding(keybindingsPath) {
85634
86219
  return { success: true, alreadyExists: true };
85635
86220
  }
85636
86221
  const parentDir = dirname11(keybindingsPath);
85637
- if (!existsSync19(parentDir)) {
85638
- mkdirSync14(parentDir, { recursive: true });
86222
+ if (!existsSync20(parentDir)) {
86223
+ mkdirSync15(parentDir, { recursive: true });
85639
86224
  }
85640
86225
  let keybindings = [];
85641
86226
  let backupPath = null;
85642
- if (existsSync19(keybindingsPath)) {
86227
+ if (existsSync20(keybindingsPath)) {
85643
86228
  backupPath = createBackup(keybindingsPath);
85644
- const content = readFileSync6(keybindingsPath, { encoding: "utf-8" });
86229
+ const content = readFileSync7(keybindingsPath, { encoding: "utf-8" });
85645
86230
  const parsed = parseKeybindings(content);
85646
86231
  if (parsed === null) {
85647
86232
  return {
@@ -85669,10 +86254,10 @@ function installKeybinding(keybindingsPath) {
85669
86254
  }
85670
86255
  function removeKeybinding(keybindingsPath) {
85671
86256
  try {
85672
- if (!existsSync19(keybindingsPath)) {
86257
+ if (!existsSync20(keybindingsPath)) {
85673
86258
  return { success: true };
85674
86259
  }
85675
- const content = readFileSync6(keybindingsPath, { encoding: "utf-8" });
86260
+ const content = readFileSync7(keybindingsPath, { encoding: "utf-8" });
85676
86261
  const keybindings = parseKeybindings(content);
85677
86262
  if (!keybindings) {
85678
86263
  return {
@@ -85736,20 +86321,20 @@ function getWezTermConfigPath() {
85736
86321
  }
85737
86322
  const xdgConfig = process.env.XDG_CONFIG_HOME;
85738
86323
  if (xdgConfig) {
85739
- const xdgPath = join30(xdgConfig, "wezterm", "wezterm.lua");
85740
- if (existsSync19(xdgPath))
86324
+ const xdgPath = join31(xdgConfig, "wezterm", "wezterm.lua");
86325
+ if (existsSync20(xdgPath))
85741
86326
  return xdgPath;
85742
86327
  }
85743
- const configPath = join30(homedir22(), ".config", "wezterm", "wezterm.lua");
85744
- if (existsSync19(configPath))
86328
+ const configPath = join31(homedir23(), ".config", "wezterm", "wezterm.lua");
86329
+ if (existsSync20(configPath))
85745
86330
  return configPath;
85746
- return join30(homedir22(), ".wezterm.lua");
86331
+ return join31(homedir23(), ".wezterm.lua");
85747
86332
  }
85748
86333
  function wezTermDeleteFixExists(configPath) {
85749
- if (!existsSync19(configPath))
86334
+ if (!existsSync20(configPath))
85750
86335
  return false;
85751
86336
  try {
85752
- const content = readFileSync6(configPath, { encoding: "utf-8" });
86337
+ const content = readFileSync7(configPath, { encoding: "utf-8" });
85753
86338
  return content.includes("Letta Code: Fix Delete key") || content.includes("key = 'Delete'") && content.includes("SendString") && content.includes("\\x1b[3~");
85754
86339
  } catch {
85755
86340
  return false;
@@ -85763,10 +86348,10 @@ function installWezTermDeleteFix() {
85763
86348
  }
85764
86349
  let content = "";
85765
86350
  let backupPath = null;
85766
- if (existsSync19(configPath)) {
86351
+ if (existsSync20(configPath)) {
85767
86352
  backupPath = `${configPath}.letta-backup`;
85768
86353
  copyFileSync(configPath, backupPath);
85769
- content = readFileSync6(configPath, { encoding: "utf-8" });
86354
+ content = readFileSync7(configPath, { encoding: "utf-8" });
85770
86355
  }
85771
86356
  if (content.includes("return {") && !content.includes("local config")) {
85772
86357
  content = content.replace(/return\s*\{/, "local config = {");
@@ -85793,8 +86378,8 @@ ${WEZTERM_DELETE_FIX}
85793
86378
  `;
85794
86379
  }
85795
86380
  const parentDir = dirname11(configPath);
85796
- if (!existsSync19(parentDir)) {
85797
- mkdirSync14(parentDir, { recursive: true });
86381
+ if (!existsSync20(parentDir)) {
86382
+ mkdirSync15(parentDir, { recursive: true });
85798
86383
  }
85799
86384
  writeFileSync9(configPath, content, { encoding: "utf-8" });
85800
86385
  return {
@@ -86316,9 +86901,9 @@ __export(exports_custom, {
86316
86901
  GLOBAL_COMMANDS_DIR: () => GLOBAL_COMMANDS_DIR,
86317
86902
  COMMANDS_DIR: () => COMMANDS_DIR
86318
86903
  });
86319
- import { existsSync as existsSync20 } from "node:fs";
86904
+ import { existsSync as existsSync21 } from "node:fs";
86320
86905
  import { readdir as readdir9, readFile as readFile9 } from "node:fs/promises";
86321
- import { basename as basename5, dirname as dirname12, join as join31 } from "node:path";
86906
+ import { basename as basename5, dirname as dirname12, join as join32 } from "node:path";
86322
86907
  async function getCustomCommands() {
86323
86908
  if (cachedCommands !== null) {
86324
86909
  return cachedCommands;
@@ -86329,7 +86914,7 @@ async function getCustomCommands() {
86329
86914
  function refreshCustomCommands() {
86330
86915
  cachedCommands = null;
86331
86916
  }
86332
- async function discoverCustomCommands(projectPath = join31(process.cwd(), COMMANDS_DIR)) {
86917
+ async function discoverCustomCommands(projectPath = join32(process.cwd(), COMMANDS_DIR)) {
86333
86918
  const commandsById = new Map;
86334
86919
  const userCommands = await discoverFromDirectory(GLOBAL_COMMANDS_DIR, "user");
86335
86920
  for (const cmd of userCommands) {
@@ -86350,7 +86935,7 @@ async function discoverCustomCommands(projectPath = join31(process.cwd(), COMMAN
86350
86935
  return result;
86351
86936
  }
86352
86937
  async function discoverFromDirectory(dirPath, source) {
86353
- if (!existsSync20(dirPath)) {
86938
+ if (!existsSync21(dirPath)) {
86354
86939
  return [];
86355
86940
  }
86356
86941
  const commands2 = [];
@@ -86361,7 +86946,7 @@ async function findCommandFiles(currentPath, rootPath, commands2, source) {
86361
86946
  try {
86362
86947
  const entries = await readdir9(currentPath, { withFileTypes: true });
86363
86948
  for (const entry of entries) {
86364
- const fullPath = join31(currentPath, entry.name);
86949
+ const fullPath = join32(currentPath, entry.name);
86365
86950
  if (entry.isDirectory()) {
86366
86951
  await findCommandFiles(fullPath, rootPath, commands2, source);
86367
86952
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
@@ -86446,7 +87031,7 @@ async function findCustomCommand(commandName) {
86446
87031
  }
86447
87032
  var COMMANDS_DIR = ".commands", GLOBAL_COMMANDS_DIR, cachedCommands = null;
86448
87033
  var init_custom = __esm(() => {
86449
- GLOBAL_COMMANDS_DIR = join31(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
87034
+ GLOBAL_COMMANDS_DIR = join32(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
86450
87035
  });
86451
87036
 
86452
87037
  // src/cli/components/HelpDialog.tsx
@@ -86727,10 +87312,10 @@ var init_HelpDialog = __esm(async () => {
86727
87312
  });
86728
87313
 
86729
87314
  // src/hooks/writer.ts
86730
- import { homedir as homedir23 } from "node:os";
87315
+ import { homedir as homedir24 } from "node:os";
86731
87316
  import { resolve as resolve26 } from "node:path";
86732
87317
  function isProjectSettingsPathCollidingWithGlobal2(workingDirectory) {
86733
- const home = process.env.HOME || homedir23();
87318
+ const home = process.env.HOME || homedir24();
86734
87319
  const globalSettingsPath = resolve26(home, ".letta", "settings.json");
86735
87320
  const projectSettingsPath = resolve26(workingDirectory, ".letta", "settings.json");
86736
87321
  return globalSettingsPath === projectSettingsPath;
@@ -87782,28 +88367,28 @@ var require_react_jsx_runtime_development = __commonJS((exports) => {
87782
88367
  return null;
87783
88368
  }
87784
88369
  var ReactSharedInternals = React14.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
87785
- function error(format2) {
88370
+ function error(format3) {
87786
88371
  {
87787
88372
  {
87788
88373
  for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1;_key2 < _len2; _key2++) {
87789
88374
  args[_key2 - 1] = arguments[_key2];
87790
88375
  }
87791
- printWarning("error", format2, args);
88376
+ printWarning("error", format3, args);
87792
88377
  }
87793
88378
  }
87794
88379
  }
87795
- function printWarning(level, format2, args) {
88380
+ function printWarning(level, format3, args) {
87796
88381
  {
87797
88382
  var ReactDebugCurrentFrame2 = ReactSharedInternals.ReactDebugCurrentFrame;
87798
88383
  var stack = ReactDebugCurrentFrame2.getStackAddendum();
87799
88384
  if (stack !== "") {
87800
- format2 += "%s";
88385
+ format3 += "%s";
87801
88386
  args = args.concat([stack]);
87802
88387
  }
87803
88388
  var argsWithFormat = args.map(function(item) {
87804
88389
  return String(item);
87805
88390
  });
87806
- argsWithFormat.unshift("Warning: " + format2);
88391
+ argsWithFormat.unshift("Warning: " + format3);
87807
88392
  Function.prototype.apply.call(console[level], console, argsWithFormat);
87808
88393
  }
87809
88394
  }
@@ -89019,7 +89604,7 @@ var init_AgentInfoBar = __esm(async () => {
89019
89604
  return localPinned.includes(agentId) || globalPinned.includes(agentId);
89020
89605
  }, [agentId]);
89021
89606
  const isCloudUser = serverUrl?.includes("api.letta.com");
89022
- const adeConversationUrl = agentId && agentId !== "loading" ? `https://app.letta.com/agents/${agentId}${conversationId && conversationId !== "default" ? `?conversation=${conversationId}` : ""}` : "";
89607
+ const adeConversationUrl = agentId && agentId !== "loading" ? buildChatUrl(agentId, { conversationId }) : "";
89023
89608
  const showBottomBar = agentId && agentId !== "loading";
89024
89609
  const reasoningLabel = formatReasoningLabel(currentReasoningEffort);
89025
89610
  const modelLine = currentModel ? `${currentModel}${reasoningLabel ? ` (${reasoningLabel})` : ""}` : null;
@@ -89090,7 +89675,7 @@ var init_AgentInfoBar = __esm(async () => {
89090
89675
  children: "· "
89091
89676
  }, undefined, false, undefined, this),
89092
89677
  /* @__PURE__ */ jsx_dev_runtime41.jsxDEV(dist_default4, {
89093
- url: "https://app.letta.com/settings/organization/usage",
89678
+ url: buildAppUrl("/settings/organization/usage"),
89094
89679
  children: /* @__PURE__ */ jsx_dev_runtime41.jsxDEV(Text2, {
89095
89680
  children: "View usage ↗"
89096
89681
  }, undefined, false, undefined, this)
@@ -89103,7 +89688,7 @@ var init_AgentInfoBar = __esm(async () => {
89103
89688
  children: /* @__PURE__ */ jsx_dev_runtime41.jsxDEV(Text2, {
89104
89689
  dimColor: true,
89105
89690
  wrap: "truncate-end",
89106
- children: truncateText(`Open in ADE: ${adeConversationUrl} · Usage: https://app.letta.com/settings/organization/usage`, rightWidth)
89691
+ children: truncateText(`Open in ADE: ${adeConversationUrl} · Usage: ${buildAppUrl("/settings/organization/usage")}`, rightWidth)
89107
89692
  }, undefined, false, undefined, this)
89108
89693
  }, undefined, false, undefined, this),
89109
89694
  !isCloudUser && /* @__PURE__ */ jsx_dev_runtime41.jsxDEV(Box_default, {
@@ -89179,8 +89764,8 @@ var init_AgentInfoBar = __esm(async () => {
89179
89764
  });
89180
89765
 
89181
89766
  // src/cli/helpers/fileSearch.ts
89182
- import { readdirSync as readdirSync8, statSync as statSync5 } from "node:fs";
89183
- import { join as join32, resolve as resolve27 } from "node:path";
89767
+ import { readdirSync as readdirSync9, statSync as statSync5 } from "node:fs";
89768
+ import { join as join33, resolve as resolve27 } from "node:path";
89184
89769
  function shouldExcludeEntry(entry) {
89185
89770
  if (entry.startsWith(".")) {
89186
89771
  return true;
@@ -89192,13 +89777,13 @@ function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = [],
89192
89777
  return results;
89193
89778
  }
89194
89779
  try {
89195
- const entries = readdirSync8(dir);
89780
+ const entries = readdirSync9(dir);
89196
89781
  for (const entry of entries) {
89197
89782
  if (shouldExcludeEntry(entry)) {
89198
89783
  continue;
89199
89784
  }
89200
89785
  try {
89201
- const fullPath = join32(dir, entry);
89786
+ const fullPath = join33(dir, entry);
89202
89787
  const stats = statSync5(fullPath);
89203
89788
  const relativePath = fullPath.startsWith(process.cwd()) ? fullPath.slice(process.cwd().length + 1) : fullPath;
89204
89789
  const matches = pattern.length === 0 || relativePath.toLowerCase().includes(pattern.toLowerCase());
@@ -89246,14 +89831,14 @@ async function searchFiles(query, deep = false) {
89246
89831
  } else {
89247
89832
  let entries = [];
89248
89833
  try {
89249
- entries = readdirSync8(searchDir);
89834
+ entries = readdirSync9(searchDir);
89250
89835
  } catch {
89251
89836
  return [];
89252
89837
  }
89253
89838
  const matchingEntries = entries.filter((entry) => !shouldExcludeEntry(entry)).filter((entry) => searchPattern.length === 0 || entry.toLowerCase().includes(searchPattern.toLowerCase()));
89254
89839
  for (const entry of matchingEntries.slice(0, 50)) {
89255
89840
  try {
89256
- const fullPath = join32(searchDir, entry);
89841
+ const fullPath = join33(searchDir, entry);
89257
89842
  const stats = statSync5(fullPath);
89258
89843
  const relativePath = fullPath.startsWith(process.cwd()) ? fullPath.slice(process.cwd().length + 1) : fullPath;
89259
89844
  results.push({
@@ -90899,7 +91484,11 @@ var init_InputRich = __esm(async () => {
90899
91484
  }, [backgroundAgents.length]);
90900
91485
  const bgAgentText = backgroundAgents.length === 0 ? "" : backgroundAgents.map((a) => {
90901
91486
  const elapsedS = Math.round((Date.now() - a.startTime) / 1000);
90902
- return `${a.type.toLowerCase()} (${elapsedS}s)`;
91487
+ const agentId = a.agentURL?.match(/\/agents\/([^/]+)/)?.[1];
91488
+ const chatUrl = agentId ? buildChatUrl(agentId) : null;
91489
+ const typeLabel = a.type.toLowerCase();
91490
+ const linkedType = chatUrl ? `\x1B]8;;${chatUrl}\x1B\\${typeLabel}\x1B]8;;\x1B\\` : typeLabel;
91491
+ return `${linkedType} (${elapsedS}s)`;
90903
91492
  }).join(" · ");
90904
91493
  const bgIndicatorWidth = backgroundAgents.length > 0 ? 2 + stringWidth(bgAgentText) + 3 : 0;
90905
91494
  const maxAgentChars = Math.max(10, Math.floor(rightColumnWidth * 0.45));
@@ -91206,15 +91795,15 @@ var init_InputRich = __esm(async () => {
91206
91795
  // src/cli/commands/install-github-app.ts
91207
91796
  import { execFileSync as execFileSync3 } from "node:child_process";
91208
91797
  import {
91209
- existsSync as existsSync21,
91210
- mkdirSync as mkdirSync15,
91798
+ existsSync as existsSync22,
91799
+ mkdirSync as mkdirSync16,
91211
91800
  mkdtempSync,
91212
- readFileSync as readFileSync7,
91801
+ readFileSync as readFileSync8,
91213
91802
  rmSync as rmSync3,
91214
91803
  writeFileSync as writeFileSync10
91215
91804
  } from "node:fs";
91216
91805
  import { tmpdir as tmpdir4 } from "node:os";
91217
- import { dirname as dirname13, join as join33 } from "node:path";
91806
+ import { dirname as dirname13, join as join34 } from "node:path";
91218
91807
  function runCommand(command, args, cwd2, input) {
91219
91808
  try {
91220
91809
  return execFileSync3(command, args, {
@@ -91448,8 +92037,8 @@ async function createLettaAgent(apiKey, name) {
91448
92037
  return { id: data.id, name: data.name };
91449
92038
  }
91450
92039
  function cloneRepoToTemp(repo) {
91451
- const tempDir = mkdtempSync(join33(tmpdir4(), "letta-install-github-app-"));
91452
- const repoDir = join33(tempDir, "repo");
92040
+ const tempDir = mkdtempSync(join34(tmpdir4(), "letta-install-github-app-"));
92041
+ const repoDir = join34(tempDir, "repo");
91453
92042
  runCommand("gh", ["repo", "clone", repo, repoDir, "--", "--depth=1"]);
91454
92043
  return { tempDir, repoDir };
91455
92044
  }
@@ -91460,14 +92049,14 @@ function runGit2(args, cwd2) {
91460
92049
  return runCommand("git", args, cwd2);
91461
92050
  }
91462
92051
  function writeWorkflow(repoDir, workflowPath, content) {
91463
- const absolutePath = join33(repoDir, workflowPath);
91464
- if (!existsSync21(dirname13(absolutePath))) {
91465
- mkdirSync15(dirname13(absolutePath), { recursive: true });
92052
+ const absolutePath = join34(repoDir, workflowPath);
92053
+ if (!existsSync22(dirname13(absolutePath))) {
92054
+ mkdirSync16(dirname13(absolutePath), { recursive: true });
91466
92055
  }
91467
92056
  const next = `${content.trimEnd()}
91468
92057
  `;
91469
- if (existsSync21(absolutePath)) {
91470
- const previous = readFileSync7(absolutePath, "utf8");
92058
+ if (existsSync22(absolutePath)) {
92059
+ const previous = readFileSync8(absolutePath, "utf8");
91471
92060
  if (previous === next) {
91472
92061
  return false;
91473
92062
  }
@@ -91573,7 +92162,7 @@ async function installGithubApp(options) {
91573
92162
  committed: false,
91574
92163
  secretAction: "set",
91575
92164
  agentId: resolvedAgentId,
91576
- agentUrl: resolvedAgentId ? `https://app.letta.com/agents/${resolvedAgentId}` : null
92165
+ agentUrl: resolvedAgentId ? buildChatUrl(resolvedAgentId) : null
91577
92166
  };
91578
92167
  }
91579
92168
  runGit2(["add", workflowPath], repoDir);
@@ -91590,7 +92179,7 @@ async function installGithubApp(options) {
91590
92179
  committed: true,
91591
92180
  secretAction: "set",
91592
92181
  agentId: resolvedAgentId,
91593
- agentUrl: resolvedAgentId ? `https://app.letta.com/agents/${resolvedAgentId}` : null
92182
+ agentUrl: resolvedAgentId ? buildChatUrl(resolvedAgentId) : null
91594
92183
  };
91595
92184
  } finally {
91596
92185
  rmSync3(tempDir, { recursive: true, force: true });
@@ -93731,21 +94320,21 @@ var init_McpSelector = __esm(async () => {
93731
94320
  });
93732
94321
 
93733
94322
  // src/agent/memoryScanner.ts
93734
- import { readdirSync as readdirSync9, readFileSync as readFileSync8, statSync as statSync6 } from "node:fs";
93735
- import { join as join34, relative as relative9 } from "node:path";
94323
+ import { readdirSync as readdirSync10, readFileSync as readFileSync9, statSync as statSync6 } from "node:fs";
94324
+ import { join as join35, relative as relative9 } from "node:path";
93736
94325
  function scanMemoryFilesystem(memoryRoot) {
93737
94326
  const nodes = [];
93738
94327
  const scanDir = (dir, depth, parentIsLast) => {
93739
94328
  let entries;
93740
94329
  try {
93741
- entries = readdirSync9(dir);
94330
+ entries = readdirSync10(dir);
93742
94331
  } catch {
93743
94332
  return;
93744
94333
  }
93745
94334
  const filtered = entries.filter((name) => !name.startsWith("."));
93746
94335
  const sorted = filtered.sort((a, b) => {
93747
- const aPath = join34(dir, a);
93748
- const bPath = join34(dir, b);
94336
+ const aPath = join35(dir, a);
94337
+ const bPath = join35(dir, b);
93749
94338
  let aIsDir = false;
93750
94339
  let bIsDir = false;
93751
94340
  try {
@@ -93765,7 +94354,7 @@ function scanMemoryFilesystem(memoryRoot) {
93765
94354
  return a.localeCompare(b);
93766
94355
  });
93767
94356
  sorted.forEach((name, index) => {
93768
- const fullPath = join34(dir, name);
94357
+ const fullPath = join35(dir, name);
93769
94358
  let isDir = false;
93770
94359
  try {
93771
94360
  isDir = statSync6(fullPath).isDirectory();
@@ -93796,7 +94385,7 @@ function getFileNodes(nodes) {
93796
94385
  }
93797
94386
  function readFileContent(fullPath) {
93798
94387
  try {
93799
- return readFileSync8(fullPath, "utf-8");
94388
+ return readFileSync9(fullPath, "utf-8");
93800
94389
  } catch {
93801
94390
  return "(unable to read file)";
93802
94391
  }
@@ -94758,7 +95347,7 @@ html.dark .warning-badge { background: hsl(42, 30%, 18%); color: hsl(42, 80%, 70
94758
95347
  } else {
94759
95348
  adeBase = 'https://app.letta.com';
94760
95349
  }
94761
- agentIdEl.href = adeBase + '/agents/' + encodeURIComponent(agentId);
95350
+ agentIdEl.href = adeBase + '/chat/' + encodeURIComponent(agentId);
94762
95351
  agentIdEl.target = '_blank';
94763
95352
  }
94764
95353
  document.getElementById('generated-at').textContent = 'Generated ' + new Date(DATA.generatedAt).toLocaleString();
@@ -95440,9 +96029,9 @@ __export(exports_generate_memory_viewer, {
95440
96029
  generateAndOpenMemoryViewer: () => generateAndOpenMemoryViewer
95441
96030
  });
95442
96031
  import { execFile as execFileCb2 } from "node:child_process";
95443
- import { chmodSync as chmodSync3, existsSync as existsSync22, mkdirSync as mkdirSync16, writeFileSync as writeFileSync11 } from "node:fs";
95444
- import { homedir as homedir24 } from "node:os";
95445
- import { join as join35 } from "node:path";
96032
+ import { chmodSync as chmodSync3, existsSync as existsSync23, mkdirSync as mkdirSync17, writeFileSync as writeFileSync11 } from "node:fs";
96033
+ import { homedir as homedir25 } from "node:os";
96034
+ import { join as join36 } from "node:path";
95446
96035
  import { promisify as promisify10 } from "node:util";
95447
96036
  async function runGitSafe(cwd2, args) {
95448
96037
  try {
@@ -95725,13 +96314,13 @@ async function generateAndOpenMemoryViewer(agentId, options) {
95725
96314
  }
95726
96315
  const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
95727
96316
  const html = memory_viewer_template_default.replace("<!--LETTA_DATA_PLACEHOLDER-->", () => jsonPayload);
95728
- if (!existsSync22(VIEWERS_DIR2)) {
95729
- mkdirSync16(VIEWERS_DIR2, { recursive: true, mode: 448 });
96317
+ if (!existsSync23(VIEWERS_DIR2)) {
96318
+ mkdirSync17(VIEWERS_DIR2, { recursive: true, mode: 448 });
95730
96319
  }
95731
96320
  try {
95732
96321
  chmodSync3(VIEWERS_DIR2, 448);
95733
96322
  } catch {}
95734
- const filePath = join35(VIEWERS_DIR2, `memory-${encodeURIComponent(agentId)}.html`);
96323
+ const filePath = join36(VIEWERS_DIR2, `memory-${encodeURIComponent(agentId)}.html`);
95735
96324
  writeFileSync11(filePath, html);
95736
96325
  chmodSync3(filePath, 384);
95737
96326
  const skipOpen = Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
@@ -95755,12 +96344,12 @@ var init_generate_memory_viewer = __esm(async () => {
95755
96344
  init_memoryGit()
95756
96345
  ]);
95757
96346
  execFile10 = promisify10(execFileCb2);
95758
- VIEWERS_DIR2 = join35(homedir24(), ".letta", "viewers");
96347
+ VIEWERS_DIR2 = join36(homedir25(), ".letta", "viewers");
95759
96348
  REFLECTION_PATTERN = /\(reflection\)|🔮|reflection:/i;
95760
96349
  });
95761
96350
 
95762
96351
  // src/cli/components/MemfsTreeViewer.tsx
95763
- import { existsSync as existsSync23 } from "node:fs";
96352
+ import { existsSync as existsSync24 } from "node:fs";
95764
96353
  function renderTreePrefix(node) {
95765
96354
  let prefix = "";
95766
96355
  for (let i = 0;i < node.depth; i++) {
@@ -95778,7 +96367,7 @@ function MemfsTreeViewer({
95778
96367
  const terminalWidth = useTerminalWidth();
95779
96368
  const solidLine = SOLID_LINE18.repeat(Math.max(terminalWidth, 10));
95780
96369
  const isTmux = Boolean(process.env.TMUX);
95781
- const adeUrl = `https://app.letta.com/agents/${agentId}?view=memory${conversationId && conversationId !== "default" ? `&conversation=${conversationId}` : ""}`;
96370
+ const adeUrl = buildChatUrl(agentId, { view: "memory", conversationId });
95782
96371
  const [selectedIndex, setSelectedIndex] = import_react75.useState(0);
95783
96372
  const [treeScrollOffset, setTreeScrollOffset] = import_react75.useState(0);
95784
96373
  const [viewMode, setViewMode] = import_react75.useState("split");
@@ -95786,7 +96375,7 @@ function MemfsTreeViewer({
95786
96375
  const [status, setStatus] = import_react75.useState(null);
95787
96376
  const statusTimerRef = import_react75.useRef(null);
95788
96377
  const memoryRoot = getMemoryFilesystemRoot(agentId);
95789
- const memoryExists = existsSync23(memoryRoot);
96378
+ const memoryExists = existsSync24(memoryRoot);
95790
96379
  const hasGitRepo = import_react75.useMemo(() => isGitRepo(agentId), [agentId]);
95791
96380
  function showStatus(msg, durationMs) {
95792
96381
  if (statusTimerRef.current)
@@ -96258,7 +96847,7 @@ function MemoryTabViewer({
96258
96847
  const terminalWidth = useTerminalWidth();
96259
96848
  const solidLine = SOLID_LINE19.repeat(Math.max(terminalWidth, 10));
96260
96849
  const isTmux = Boolean(process.env.TMUX);
96261
- const adeUrl = `https://app.letta.com/agents/${agentId}?view=memory${conversationId && conversationId !== "default" ? `&conversation=${conversationId}` : ""}`;
96850
+ const adeUrl = buildChatUrl(agentId, { view: "memory", conversationId });
96262
96851
  const [selectedTabIndex, setSelectedTabIndex] = import_react76.useState(0);
96263
96852
  const [scrollOffset, setScrollOffset] = import_react76.useState(0);
96264
96853
  const [freshBlocks, setFreshBlocks] = import_react76.useState(null);
@@ -97253,12 +97842,22 @@ var init_ModelReasoningSelector = __esm(async () => {
97253
97842
  });
97254
97843
 
97255
97844
  // src/cli/components/ModelSelector.tsx
97256
- function getModelCategories(billingTier, isSelfHosted) {
97845
+ function getModelCategories(_billingTier, isSelfHosted) {
97257
97846
  if (isSelfHosted) {
97258
97847
  return ["server-recommended", "server-all"];
97259
97848
  }
97260
- const isFreeTier = billingTier?.toLowerCase() === "free";
97261
- return isFreeTier ? ["byok", "byok-all", "supported", "all"] : ["supported", "all", "byok", "byok-all"];
97849
+ return ["supported", "all", "byok", "byok-all"];
97850
+ }
97851
+ function filterModelsByAvailabilityForSelector(typedModels, availableHandles, allApiHandles) {
97852
+ if (availableHandles === null) {
97853
+ return typedModels.filter((m) => {
97854
+ if (!API_GATED_MODEL_HANDLES.has(m.handle)) {
97855
+ return true;
97856
+ }
97857
+ return allApiHandles.includes(m.handle);
97858
+ });
97859
+ }
97860
+ return typedModels.filter((m) => availableHandles.has(m.handle));
97262
97861
  }
97263
97862
  function ModelSelector({
97264
97863
  currentModelId,
@@ -97326,11 +97925,10 @@ function ModelSelector({
97326
97925
  const staticCandidates = typedModels.filter((m) => m.handle === handle);
97327
97926
  return staticCandidates.find((m) => m.isDefault) ?? staticCandidates.find((m) => m.isFeatured) ?? staticCandidates.find((m) => m.updateArgs?.reasoning_effort === "medium") ?? staticCandidates.find((m) => m.updateArgs?.reasoning_effort === "high") ?? staticCandidates[0];
97328
97927
  }, [typedModels]);
97329
- const isFreeTier = billingTier?.toLowerCase() === "free";
97330
97928
  const supportedModels = import_react79.useMemo(() => {
97331
97929
  if (availableHandles === undefined)
97332
97930
  return [];
97333
- let available = availableHandles === null ? typedModels : typedModels.filter((m) => availableHandles.has(m.handle));
97931
+ let available = filterModelsByAvailabilityForSelector(typedModels, availableHandles, allApiHandles);
97334
97932
  if (filterProvider) {
97335
97933
  available = available.filter((m) => m.handle.startsWith(`${filterProvider}/`));
97336
97934
  }
@@ -97346,22 +97944,15 @@ function ModelSelector({
97346
97944
  seen.add(m.handle);
97347
97945
  deduped.push(pickPreferredStaticModel(m.handle) ?? m);
97348
97946
  }
97349
- if (isFreeTier) {
97350
- const freeModels = deduped.filter((m) => m.free);
97351
- const paidModels = deduped.filter((m) => !m.free);
97352
- const featured2 = paidModels.filter((m) => m.isFeatured);
97353
- const nonFeatured2 = paidModels.filter((m) => !m.isFeatured);
97354
- return [...freeModels, ...featured2, ...nonFeatured2];
97355
- }
97356
97947
  const featured = deduped.filter((m) => m.isFeatured);
97357
97948
  const nonFeatured = deduped.filter((m) => !m.isFeatured);
97358
97949
  return [...featured, ...nonFeatured];
97359
97950
  }, [
97360
97951
  typedModels,
97361
97952
  availableHandles,
97953
+ allApiHandles,
97362
97954
  filterProvider,
97363
97955
  searchQuery,
97364
- isFreeTier,
97365
97956
  pickPreferredStaticModel
97366
97957
  ]);
97367
97958
  const isByokHandle = import_react79.useCallback((handle) => BYOK_PROVIDER_PREFIXES.some((prefix) => handle.startsWith(prefix)), []);
@@ -97816,7 +98407,7 @@ function ModelSelector({
97816
98407
  ]
97817
98408
  }, undefined, true, undefined, this);
97818
98409
  }
97819
- var import_react79, jsx_dev_runtime56, SOLID_LINE22 = "─", VISIBLE_ITEMS2 = 8, BYOK_PROVIDER_PREFIXES;
98410
+ var import_react79, jsx_dev_runtime56, SOLID_LINE22 = "─", VISIBLE_ITEMS2 = 8, BYOK_PROVIDER_PREFIXES, API_GATED_MODEL_HANDLES;
97820
98411
  var init_ModelSelector = __esm(async () => {
97821
98412
  init_useTerminalWidth();
97822
98413
  init_colors();
@@ -97829,6 +98420,7 @@ var init_ModelSelector = __esm(async () => {
97829
98420
  import_react79 = __toESM(require_react(), 1);
97830
98421
  jsx_dev_runtime56 = __toESM(require_jsx_dev_runtime(), 1);
97831
98422
  BYOK_PROVIDER_PREFIXES = ["chatgpt-plus-pro/", "lc-"];
98423
+ API_GATED_MODEL_HANDLES = new Set(["letta/auto", "letta/auto-fast"]);
97832
98424
  });
97833
98425
 
97834
98426
  // src/cli/components/PinDialog.tsx
@@ -98238,11 +98830,11 @@ var init_PendingApprovalStub = __esm(async () => {
98238
98830
 
98239
98831
  // src/utils/aws-credentials.ts
98240
98832
  import { readFile as readFile10 } from "node:fs/promises";
98241
- import { homedir as homedir25 } from "node:os";
98242
- import { join as join36 } from "node:path";
98833
+ import { homedir as homedir26 } from "node:os";
98834
+ import { join as join37 } from "node:path";
98243
98835
  async function parseAwsCredentials() {
98244
- const credentialsPath = join36(homedir25(), ".aws", "credentials");
98245
- const configPath = join36(homedir25(), ".aws", "config");
98836
+ const credentialsPath = join37(homedir26(), ".aws", "credentials");
98837
+ const configPath = join37(homedir26(), ".aws", "config");
98246
98838
  const profiles = new Map;
98247
98839
  try {
98248
98840
  const content = await readFile10(credentialsPath, "utf-8");
@@ -99318,7 +99910,7 @@ function formatUsageStats({
99318
99910
  const monthlyCredits = Math.round(balance.monthly_credit_balance);
99319
99911
  const purchasedCredits = Math.round(balance.purchased_credit_balance);
99320
99912
  const toDollars = (credits) => (credits / 1000).toFixed(2);
99321
- outputLines.push(`Plan: [${balance.billing_tier}]`, "https://app.letta.com/settings/organization/usage", "", `Available credits: ◎${formatNumber(totalCredits)} ($${toDollars(totalCredits)})`, `Monthly credits: ◎${formatNumber(monthlyCredits)} ($${toDollars(monthlyCredits)})`, `Purchased credits: ◎${formatNumber(purchasedCredits)} ($${toDollars(purchasedCredits)})`);
99913
+ outputLines.push(`Plan: [${balance.billing_tier}]`, buildAppUrl("/settings/organization/usage"), "", `Available credits: ◎${formatNumber(totalCredits)} ($${toDollars(totalCredits)})`, `Monthly credits: ◎${formatNumber(monthlyCredits)} ($${toDollars(monthlyCredits)})`, `Purchased credits: ◎${formatNumber(purchasedCredits)} ($${toDollars(purchasedCredits)})`);
99322
99914
  }
99323
99915
  return outputLines.join(`
99324
99916
  `);
@@ -99350,8 +99942,8 @@ function SkillsDialog({ onClose, agentId }) {
99350
99942
  try {
99351
99943
  const { discoverSkills: discoverSkills3, SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills(), exports_skills));
99352
99944
  const { getSkillsDirectory: getSkillsDirectory2, getSkillSources: getSkillSources2 } = await Promise.resolve().then(() => (init_context(), exports_context));
99353
- const { join: join37 } = await import("node:path");
99354
- const skillsDir = getSkillsDirectory2() || join37(process.cwd(), SKILLS_DIR3);
99945
+ const { join: join38 } = await import("node:path");
99946
+ const skillsDir = getSkillsDirectory2() || join38(process.cwd(), SKILLS_DIR3);
99355
99947
  const result = await discoverSkills3(skillsDir, agentId, {
99356
99948
  sources: getSkillSources2()
99357
99949
  });
@@ -103295,6 +103887,7 @@ ${recentCommits}
103295
103887
  }
103296
103888
  }
103297
103889
  function buildMemoryInitRuntimePrompt(args) {
103890
+ const depth = args.depth ?? "deep";
103298
103891
  return `
103299
103892
  The user ran /init for the current project.
103300
103893
 
@@ -103302,6 +103895,7 @@ Runtime context:
103302
103895
  - parent_agent_id: ${args.agentId}
103303
103896
  - working_directory: ${args.workingDirectory}
103304
103897
  - memory_dir: ${args.memoryDir}
103898
+ - research_depth: ${depth}
103305
103899
 
103306
103900
  Git/project context:
103307
103901
  ${args.gitContext}
@@ -103309,6 +103903,8 @@ ${args.gitContext}
103309
103903
  Task:
103310
103904
  Initialize or reorganize the parent agent's filesystem-backed memory for this project.
103311
103905
 
103906
+ ${depth === "shallow" ? SHALLOW_INSTRUCTIONS : DEEP_INSTRUCTIONS}
103907
+
103312
103908
  Instructions:
103313
103909
  - Use the pre-loaded initializing-memory skill as your operating guide
103314
103910
  - Inspect existing memory before editing
@@ -103318,6 +103914,29 @@ Instructions:
103318
103914
  - If the memory filesystem is unavailable or unsafe to modify, stop and explain why
103319
103915
  `.trim();
103320
103916
  }
103917
+ async function fireAutoInit(agentId, onComplete) {
103918
+ if (hasActiveInitSubagent())
103919
+ return false;
103920
+ if (!settingsManager.isMemfsEnabled(agentId))
103921
+ return false;
103922
+ const gitContext = gatherGitContext();
103923
+ const initPrompt = buildMemoryInitRuntimePrompt({
103924
+ agentId,
103925
+ workingDirectory: process.cwd(),
103926
+ memoryDir: getMemoryFilesystemRoot(agentId),
103927
+ gitContext,
103928
+ depth: "shallow"
103929
+ });
103930
+ const { spawnBackgroundSubagentTask: spawnBackgroundSubagentTask2 } = await init_Task2().then(() => exports_Task);
103931
+ spawnBackgroundSubagentTask2({
103932
+ subagentType: "init",
103933
+ prompt: initPrompt,
103934
+ description: "Initializing memory",
103935
+ silentCompletion: true,
103936
+ onComplete
103937
+ });
103938
+ return true;
103939
+ }
103321
103940
  function buildLegacyInitMessage(args) {
103322
103941
  return `${SYSTEM_REMINDER_OPEN}
103323
103942
  The user has requested memory initialization via /init.
@@ -103338,9 +103957,27 @@ Once invoked, follow the instructions from the \`initializing-memory\` skill to
103338
103957
  ${args.gitContext}
103339
103958
  ${SYSTEM_REMINDER_CLOSE}`;
103340
103959
  }
103341
- var init_initCommand = __esm(() => {
103960
+ var SHALLOW_INSTRUCTIONS, DEEP_INSTRUCTIONS;
103961
+ var init_initCommand = __esm(async () => {
103962
+ init_memoryFilesystem();
103342
103963
  init_constants();
103343
103964
  init_subagentState();
103965
+ await init_settings_manager();
103966
+ SHALLOW_INSTRUCTIONS = `
103967
+ Shallow init — fast project basics only (~5 tool calls max):
103968
+ - Only read: CLAUDE.md, AGENTS.md, package.json/pyproject.toml/Cargo.toml, README.md (first 100 lines), top-level directory listing
103969
+ - Detect user identity from the git context provided above (already in the prompt — no extra calls)
103970
+ - Run one git call: git log --format="%an <%ae>" | sort -u | head -5
103971
+ - Write exactly 4 files: project/overview.md, project/commands.md, project/conventions.md, human/identity.md
103972
+ - Skip: deep directory exploration, architecture mapping, config analysis, historical sessions, persona files, reflection/checkpoint phase
103973
+ `.trim();
103974
+ DEEP_INSTRUCTIONS = `
103975
+ Deep init — full exploration (follow the initializing-memory skill fully):
103976
+ - Read all existing memory files first — do NOT recreate what already exists
103977
+ - Then follow the full initializing-memory skill as your operating guide
103978
+ - Expand and deepen existing shallow files, add new ones to reach 15-25 target
103979
+ - If shallow init already ran, build on its output rather than starting over
103980
+ `.trim();
103344
103981
  });
103345
103982
 
103346
103983
  // src/cli/helpers/queuedMessageParts.ts
@@ -103528,9 +104165,11 @@ var init_statusLineSchema = __esm(() => {
103528
104165
  { path: "workspace.current_dir" },
103529
104166
  { path: "workspace.project_dir" },
103530
104167
  { path: "session_id" },
104168
+ { path: "last_run_id" },
103531
104169
  { path: "version" },
103532
104170
  { path: "model.id" },
103533
104171
  { path: "model.display_name" },
104172
+ { path: "agent.id" },
103534
104173
  { path: "agent.name" },
103535
104174
  { path: "cost.total_duration_ms" },
103536
104175
  { path: "cost.total_api_duration_ms" },
@@ -103624,6 +104263,7 @@ function buildStatusLinePayload(input) {
103624
104263
  project_dir: input.projectDirectory
103625
104264
  },
103626
104265
  ...input.sessionId ? { session_id: input.sessionId } : {},
104266
+ last_run_id: input.lastRunId ?? null,
103627
104267
  transcript_path: null,
103628
104268
  version: getVersion(),
103629
104269
  reasoning_effort: input.reasoningEffort ?? null,
@@ -103654,6 +104294,7 @@ function buildStatusLinePayload(input) {
103654
104294
  exceeds_200k_tokens: usedContextTokens > 200000,
103655
104295
  vim: null,
103656
104296
  agent: {
104297
+ id: input.agentId ?? null,
103657
104298
  name: input.agentName ?? null
103658
104299
  },
103659
104300
  permission_mode: input.permissionMode ?? null,
@@ -104032,7 +104673,9 @@ function toPayloadInput(inputs) {
104032
104673
  currentDirectory: inputs.currentDirectory,
104033
104674
  projectDirectory: inputs.projectDirectory,
104034
104675
  sessionId: inputs.sessionId,
104676
+ agentId: inputs.agentId,
104035
104677
  agentName: inputs.agentName,
104678
+ lastRunId: inputs.lastRunId,
104036
104679
  totalDurationMs: inputs.totalDurationMs,
104037
104680
  totalApiDurationMs: inputs.totalApiDurationMs,
104038
104681
  totalInputTokens: inputs.totalInputTokens,
@@ -104238,16 +104881,16 @@ __export(exports_shellAliases, {
104238
104881
  expandAliases: () => expandAliases,
104239
104882
  clearAliasCache: () => clearAliasCache
104240
104883
  });
104241
- import { existsSync as existsSync24, readFileSync as readFileSync9 } from "node:fs";
104242
- import { homedir as homedir26 } from "node:os";
104243
- import { join as join37 } from "node:path";
104884
+ import { existsSync as existsSync25, readFileSync as readFileSync10 } from "node:fs";
104885
+ import { homedir as homedir27 } from "node:os";
104886
+ import { join as join38 } from "node:path";
104244
104887
  function parseAliasesFromFile(filePath) {
104245
104888
  const aliases = new Map;
104246
- if (!existsSync24(filePath)) {
104889
+ if (!existsSync25(filePath)) {
104247
104890
  return aliases;
104248
104891
  }
104249
104892
  try {
104250
- const content = readFileSync9(filePath, "utf-8");
104893
+ const content = readFileSync10(filePath, "utf-8");
104251
104894
  const lines = content.split(`
104252
104895
  `);
104253
104896
  let inFunction = false;
@@ -104309,10 +104952,10 @@ function loadAliases(forceReload = false) {
104309
104952
  if (aliasCache && !forceReload) {
104310
104953
  return aliasCache;
104311
104954
  }
104312
- const home = homedir26();
104955
+ const home = homedir27();
104313
104956
  const allAliases = new Map;
104314
104957
  for (const file of ALIAS_FILES) {
104315
- const filePath = join37(home, file);
104958
+ const filePath = join38(home, file);
104316
104959
  const fileAliases = parseAliasesFromFile(filePath);
104317
104960
  for (const [name, value] of fileAliases) {
104318
104961
  allAliases.set(name, value);
@@ -104802,10 +105445,11 @@ Listener disconnected from Letta Cloud.`, true);
104802
105445
  return;
104803
105446
  }
104804
105447
  if (msg.includes("--help") || msg.includes("-h")) {
104805
- addCommandResult4(ctx.buffersRef, ctx.refreshDerived, msg, `Usage: /remote [--env-name <name>]
104806
- /remote off
105448
+ addCommandResult4(ctx.buffersRef, ctx.refreshDerived, msg, `Usage: /server [--env-name <name>]
105449
+ /server off
104807
105450
 
104808
105451
  Register this letta-code instance to receive messages from Letta Cloud.
105452
+ Alias: /remote
104809
105453
 
104810
105454
  Options:
104811
105455
  --env-name <name> Friendly name for this environment (uses hostname if not provided)
@@ -104813,9 +105457,9 @@ Options:
104813
105457
  -h, --help Show this help message
104814
105458
 
104815
105459
  Examples:
104816
- /remote # Start listener with hostname
104817
- /remote --env-name "work-laptop" # Start with custom name
104818
- /remote off # Stop listening
105460
+ /server # Start listener with hostname
105461
+ /server --env-name "work-laptop" # Start with custom name
105462
+ /server off # Stop listening
104819
105463
 
104820
105464
  Once connected, this instance will listen for incoming messages from cloud agents.
104821
105465
  Messages will be executed locally using your letta-code environment.`, true);
@@ -104837,11 +105481,10 @@ Messages will be executed locally using your letta-code environment.`, true);
104837
105481
  const buildConnectionUrl = (connId) => {
104838
105482
  if (!ctx.agentId)
104839
105483
  return "";
104840
- let url = `https://app.letta.com/agents/${ctx.agentId}?deviceId=${connId}`;
104841
- if (ctx.conversationId) {
104842
- url += `&conversationId=${ctx.conversationId}`;
104843
- }
104844
- return url;
105484
+ return buildChatUrl(ctx.agentId, {
105485
+ deviceId: connId,
105486
+ conversationId: ctx.conversationId ?? undefined
105487
+ });
104845
105488
  };
104846
105489
  ctx.setCommandRunning(true);
104847
105490
  const cmdId = addCommandResult4(ctx.buffersRef, ctx.refreshDerived, msg, "Connecting to Letta Cloud...", true, "running");
@@ -105142,9 +105785,9 @@ var exports_App = {};
105142
105785
  __export(exports_App, {
105143
105786
  default: () => App2
105144
105787
  });
105145
- import { existsSync as existsSync25, readFileSync as readFileSync10, renameSync as renameSync2, writeFileSync as writeFileSync12 } from "node:fs";
105146
- import { homedir as homedir27, tmpdir as tmpdir5 } from "node:os";
105147
- import { join as join38, relative as relative11 } from "node:path";
105788
+ import { existsSync as existsSync26, readFileSync as readFileSync11, renameSync as renameSync2, writeFileSync as writeFileSync12 } from "node:fs";
105789
+ import { homedir as homedir28, tmpdir as tmpdir5 } from "node:os";
105790
+ import { join as join39, relative as relative11 } from "node:path";
105148
105791
  function deriveReasoningEffort(modelSettings, llmConfig) {
105149
105792
  if (modelSettings && "provider_type" in modelSettings) {
105150
105793
  if (modelSettings.provider_type === "openai" && "reasoning" in modelSettings && modelSettings.reasoning) {
@@ -105371,18 +106014,18 @@ ${SYSTEM_REMINDER_CLOSE}
105371
106014
  }
105372
106015
  function planFileExists() {
105373
106016
  const planFilePath = permissionMode.getPlanFilePath();
105374
- return !!planFilePath && existsSync25(planFilePath);
106017
+ return !!planFilePath && existsSync26(planFilePath);
105375
106018
  }
105376
106019
  function _readPlanFile() {
105377
106020
  const planFilePath = permissionMode.getPlanFilePath();
105378
106021
  if (!planFilePath) {
105379
106022
  return "No plan file path set.";
105380
106023
  }
105381
- if (!existsSync25(planFilePath)) {
106024
+ if (!existsSync26(planFilePath)) {
105382
106025
  return `Plan file not found at ${planFilePath}`;
105383
106026
  }
105384
106027
  try {
105385
- return readFileSync10(planFilePath, "utf-8");
106028
+ return readFileSync11(planFilePath, "utf-8");
105386
106029
  } catch {
105387
106030
  return `Failed to read plan file at ${planFilePath}`;
105388
106031
  }
@@ -105519,8 +106162,11 @@ function App2({
105519
106162
  import_react99.useEffect(() => {
105520
106163
  conversationIdRef.current = conversationId;
105521
106164
  }, [conversationId]);
106165
+ const lastRunIdRef = import_react99.useRef(null);
105522
106166
  const resumeKey = useSuspend();
105523
106167
  const pendingConversationSwitchRef = import_react99.useRef(null);
106168
+ const autoInitPendingAgentIdsRef = import_react99.useRef(new Set);
106169
+ const startupAutoInitConsumedRef = import_react99.useRef(false);
105524
106170
  const prevInitialAgentIdRef = import_react99.useRef(initialAgentId);
105525
106171
  const prevInitialAgentStateRef = import_react99.useRef(initialAgentState);
105526
106172
  const prevInitialConversationIdRef = import_react99.useRef(initialConversationId);
@@ -105857,6 +106503,15 @@ function App2({
105857
106503
  }, []);
105858
106504
  const [showExitStats, setShowExitStats] = import_react99.useState(false);
105859
106505
  const sharedReminderStateRef = import_react99.useRef(createSharedReminderState());
106506
+ const initProgressByAgentRef = import_react99.useRef(new Map);
106507
+ const updateInitProgress = (forAgentId, update) => {
106508
+ const progress2 = initProgressByAgentRef.current.get(forAgentId) ?? {
106509
+ shallowCompleted: false,
106510
+ deepFired: false
106511
+ };
106512
+ Object.assign(progress2, update);
106513
+ initProgressByAgentRef.current.set(forAgentId, progress2);
106514
+ };
105860
106515
  const hasSetConversationSummaryRef = import_react99.useRef(resumedExistingConversation);
105861
106516
  const firstUserQueryRef = import_react99.useRef(null);
105862
106517
  const resetBootstrapReminderState = import_react99.useCallback(() => {
@@ -106342,7 +106997,9 @@ function App2({
106342
106997
  currentDirectory: process.cwd(),
106343
106998
  projectDirectory,
106344
106999
  sessionId: conversationId,
107000
+ agentId,
106345
107001
  agentName,
107002
+ lastRunId: lastRunIdRef.current,
106346
107003
  totalDurationMs: sessionStatsSnapshot.totalWallMs,
106347
107004
  totalApiDurationMs: sessionStatsSnapshot.totalApiMs,
106348
107005
  totalInputTokens: sessionStatsSnapshot.usage.promptTokens,
@@ -106494,7 +107151,8 @@ function App2({
106494
107151
  enqueueCommandIoReminder(sharedReminderStateRef.current, {
106495
107152
  input,
106496
107153
  output: event.output,
106497
- success: event.success
107154
+ success: event.success,
107155
+ agentHint: event.agentHint
106498
107156
  });
106499
107157
  }, []);
106500
107158
  const maybeRecordToolsetChangeReminder = import_react99.useCallback((params) => {
@@ -106637,10 +107295,10 @@ function App2({
106637
107295
  if (!planFilePath)
106638
107296
  return;
106639
107297
  try {
106640
- const { readFileSync: readFileSync11, existsSync: existsSync26 } = __require("node:fs");
106641
- if (!existsSync26(planFilePath))
107298
+ const { readFileSync: readFileSync12, existsSync: existsSync27 } = __require("node:fs");
107299
+ if (!existsSync27(planFilePath))
106642
107300
  return;
106643
- const planContent = readFileSync11(planFilePath, "utf-8");
107301
+ const planContent = readFileSync12(planFilePath, "utf-8");
106644
107302
  const previewItem = {
106645
107303
  kind: "approval_preview",
106646
107304
  id: `approval-preview-${toolCallId}`,
@@ -106853,6 +107511,7 @@ function App2({
106853
107511
  }
106854
107512
  try {
106855
107513
  const client = await getClient2();
107514
+ debugLog("conversations", `retrieve(${conversationId}) [syncConversationModel]`);
106856
107515
  const conversation = await client.conversations.retrieve(conversationId);
106857
107516
  if (cancelled)
106858
107517
  return;
@@ -106886,7 +107545,7 @@ function App2({
106886
107545
  if (cancelled)
106887
107546
  return;
106888
107547
  debugLog("conversation-model", "Failed to sync conversation model override: %O", error);
106889
- applyAgentModelLocally();
107548
+ debugLog("conversation-model", "Keeping current model state after sync error (override in DB is authoritative)");
106890
107549
  }
106891
107550
  };
106892
107551
  syncConversationModel();
@@ -107018,9 +107677,9 @@ Memory may be stale. Try running: git -C ~/.letta/agents/${agentId}/memory pull`
107018
107677
  (async () => {
107019
107678
  try {
107020
107679
  const { watch } = await import("node:fs");
107021
- const { existsSync: existsSync26 } = await import("node:fs");
107680
+ const { existsSync: existsSync27 } = await import("node:fs");
107022
107681
  const memRoot = getMemoryFilesystemRoot(agentId);
107023
- if (!existsSync26(memRoot))
107682
+ if (!existsSync27(memRoot))
107024
107683
  return;
107025
107684
  watcher = watch(memRoot, { recursive: true }, () => {});
107026
107685
  memfsWatcherRef.current = watcher;
@@ -107264,7 +107923,7 @@ ${newState.originalPrompt}`
107264
107923
  }
107265
107924
  if (preStreamAction === "retry_conversation_busy") {
107266
107925
  conversationBusyRetriesRef.current += 1;
107267
- const retryDelayMs = CONVERSATION_BUSY_RETRY_BASE_DELAY_MS * 2 ** (conversationBusyRetriesRef.current - 1);
107926
+ const retryDelayMs = CONVERSATION_BUSY_RETRY_BASE_DELAY_MS2 * 2 ** (conversationBusyRetriesRef.current - 1);
107268
107927
  telemetry.trackError("retry_conversation_busy", formatTelemetryErrorMessage(errorDetail || "Conversation is busy"), "pre_stream_retry", {
107269
107928
  httpStatus: preStreamError instanceof APIError2 ? preStreamError.status : undefined,
107270
107929
  modelId: currentModelId || undefined
@@ -107441,6 +108100,8 @@ ${newState.originalPrompt}`
107441
108100
  fallbackError
107442
108101
  } = await drainStreamWithResume(stream2, buffersRef.current, refreshDerivedThrottled, signal, handleFirstMessage, undefined, contextTrackerRef.current);
107443
108102
  currentRunId = lastRunId ?? undefined;
108103
+ if (lastRunId)
108104
+ lastRunIdRef.current = lastRunId;
107444
108105
  sessionStatsRef.current.endTurn(apiDurationMs);
107445
108106
  const usageDelta = sessionStatsRef.current.updateUsageFromBuffers(buffersRef.current);
107446
108107
  const tokenDelta = Math.max(0, buffersRef.current.tokenCount - runTokenStart);
@@ -108293,8 +108954,12 @@ ${feedback}
108293
108954
  toolResultsInFlightRef.current = false;
108294
108955
  refreshDerived();
108295
108956
  getClient2().then((client) => {
108296
- const cancelId = conversationIdRef.current === "default" ? agentIdRef.current : conversationIdRef.current;
108297
- return client.conversations.cancel(cancelId);
108957
+ if (conversationIdRef.current === "default") {
108958
+ return client.conversations.cancel("default", {
108959
+ agent_id: agentIdRef.current
108960
+ });
108961
+ }
108962
+ return client.conversations.cancel(conversationIdRef.current);
108298
108963
  }).catch(() => {});
108299
108964
  setTimeout(() => {
108300
108965
  userCancelledRef.current = false;
@@ -108362,8 +109027,12 @@ ${feedback}
108362
109027
  setAutoHandledResults([]);
108363
109028
  setAutoDeniedApprovals([]);
108364
109029
  getClient2().then((client) => {
108365
- const cancelId = conversationIdRef.current === "default" ? agentIdRef.current : conversationIdRef.current;
108366
- return client.conversations.cancel(cancelId);
109030
+ if (conversationIdRef.current === "default") {
109031
+ return client.conversations.cancel("default", {
109032
+ agent_id: agentIdRef.current
109033
+ });
109034
+ }
109035
+ return client.conversations.cancel(conversationIdRef.current);
108367
109036
  }).catch(() => {});
108368
109037
  setTimeout(() => {
108369
109038
  userCancelledRef.current = false;
@@ -108374,8 +109043,13 @@ ${feedback}
108374
109043
  setInterruptRequested(true);
108375
109044
  try {
108376
109045
  const client = await getClient2();
108377
- const cancelId = conversationIdRef.current === "default" ? agentIdRef.current : conversationIdRef.current;
108378
- await client.conversations.cancel(cancelId);
109046
+ if (conversationIdRef.current === "default") {
109047
+ await client.conversations.cancel("default", {
109048
+ agent_id: agentIdRef.current
109049
+ });
109050
+ } else {
109051
+ await client.conversations.cancel(conversationIdRef.current);
109052
+ }
108379
109053
  if (abortControllerRef.current) {
108380
109054
  abortControllerRef.current.abort();
108381
109055
  abortControllerRef.current = null;
@@ -108543,6 +109217,9 @@ ${feedback}
108543
109217
  const { agent } = await createAgent(name);
108544
109218
  const { enableMemfsIfCloud: enableMemfsIfCloud2 } = await Promise.resolve().then(() => (init_memoryFilesystem(), exports_memoryFilesystem));
108545
109219
  await enableMemfsIfCloud2(agent.id);
109220
+ if (settingsManager.isMemfsEnabled(agent.id)) {
109221
+ autoInitPendingAgentIdsRef.current.add(agent.id);
109222
+ }
108546
109223
  await updateProjectSettings({ lastAgent: agent.id });
108547
109224
  const targetConversationId = "default";
108548
109225
  settingsManager.setLocalLastSession({ agentId: agent.id, conversationId: targetConversationId }, process.cwd());
@@ -108550,11 +109227,12 @@ ${feedback}
108550
109227
  agentId: agent.id,
108551
109228
  conversationId: targetConversationId
108552
109229
  });
108553
- const agentUrl = `https://app.letta.com/projects/default-project/agents/${agent.id}`;
109230
+ const agentUrl = buildChatUrl(agent.id);
109231
+ const memfsTip = settingsManager.isMemfsEnabled(agent.id) ? "Memory will be auto-initialized on your first message." : "Tip: use /init to initialize your agent's memory system!";
108554
109232
  const successOutput = [
108555
109233
  `Created **${agent.name || agent.id}** (use /pin to save)`,
108556
109234
  `⎿ ${agentUrl}`,
108557
- `⎿ Tip: use /init to initialize your agent's memory system!`
109235
+ `⎿ ${memfsTip}`
108558
109236
  ].join(`
108559
109237
  `);
108560
109238
  cmd.finish(successOutput, true);
@@ -108969,7 +109647,9 @@ ${SYSTEM_REMINDER_CLOSE}` : "";
108969
109647
  return { submitted: true };
108970
109648
  }
108971
109649
  if (trimmed === "/ade") {
108972
- const adeUrl = conversationIdRef.current === "default" ? `https://app.letta.com/agents/${agentId}` : `https://app.letta.com/agents/${agentId}?conversation=${conversationIdRef.current}`;
109650
+ const adeUrl = buildChatUrl(agentId, {
109651
+ conversationId: conversationIdRef.current
109652
+ });
108973
109653
  const cmd = commandRunner.start("/ade", "Opening ADE...");
108974
109654
  Promise.resolve().then(() => (init_open(), exports_open)).then(({ default: open2 }) => open2(adeUrl, { wait: false })).catch(() => {});
108975
109655
  cmd.finish(`Opening ADE...
@@ -109115,7 +109795,7 @@ ${SYSTEM_REMINDER_CLOSE}` : "";
109115
109795
  }
109116
109796
  return { submitted: true };
109117
109797
  }
109118
- if (trimmed === "/remote" || trimmed.startsWith("/remote ")) {
109798
+ if (trimmed === "/server" || trimmed.startsWith("/server ") || trimmed === "/remote" || trimmed.startsWith("/remote ")) {
109119
109799
  const parts = Array.from(trimmed.matchAll(/"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|(\S+)/g), (match3) => match3[1] ?? match3[2] ?? match3[3]);
109120
109800
  let name;
109121
109801
  let _listenAgentId;
@@ -109241,7 +109921,9 @@ ${SYSTEM_REMINDER_CLOSE}` : "";
109241
109921
  currentDirectory: wd,
109242
109922
  projectDirectory,
109243
109923
  sessionId: conversationIdRef.current,
109924
+ agentId,
109244
109925
  agentName,
109926
+ lastRunId: lastRunIdRef.current,
109245
109927
  totalDurationMs: stats.totalWallMs,
109246
109928
  totalApiDurationMs: stats.totalApiMs,
109247
109929
  totalInputTokens: stats.usage.promptTokens,
@@ -109611,8 +110293,12 @@ Type your task to begin the loop.`, true);
109611
110293
  mode: modeArg
109612
110294
  }
109613
110295
  } : undefined;
109614
- const compactId = conversationIdRef.current === "default" ? agentId : conversationIdRef.current;
109615
- const result2 = await client.conversations.messages.compact(compactId, compactParams);
110296
+ const compactConversationId = conversationIdRef.current;
110297
+ const compactBody = compactConversationId === "default" ? {
110298
+ agent_id: agentId,
110299
+ ...compactParams ?? {}
110300
+ } : compactParams;
110301
+ const result2 = await client.conversations.messages.compact(compactConversationId, compactBody);
109616
110302
  const outputLines = [
109617
110303
  `Compaction completed${modeDisplay}. Message buffer length reduced from ${result2.num_messages_before} to ${result2.num_messages_after}.`,
109618
110304
  "",
@@ -109708,6 +110394,7 @@ Type your task to begin the loop.`, true);
109708
110394
  const client = await getClient2();
109709
110395
  await client.agents.update(agentId, { name: newValue });
109710
110396
  updateAgentName(newValue);
110397
+ cmd.agentHint = `Your name is now "${newValue}" — acknowledge this and save your new name to memory.`;
109711
110398
  cmd.finish(`Agent renamed to "${newValue}"`, true);
109712
110399
  } catch (error) {
109713
110400
  const errorDetails = formatErrorDetails2(error, agentId);
@@ -110079,7 +110766,7 @@ Press Enter to continue, or type anything to cancel.`, false, "running");
110079
110766
  try {
110080
110767
  const client = await getClient2();
110081
110768
  const exportParams = {};
110082
- if (conversationId !== "default") {
110769
+ if (conversationId !== "default" && conversationId !== agentId) {
110083
110770
  exportParams.conversation_id = conversationId;
110084
110771
  }
110085
110772
  const { packageSkills: packageSkills2 } = await Promise.resolve().then(() => (init_export(), exports_export));
@@ -110201,11 +110888,11 @@ Path: ${result2.memoryDir}`, true, msg);
110201
110888
  setCommandRunning(true);
110202
110889
  try {
110203
110890
  const memoryDir = getMemoryFilesystemRoot(agentId);
110204
- if (!existsSync25(memoryDir)) {
110891
+ if (!existsSync26(memoryDir)) {
110205
110892
  updateMemorySyncCommand(cmdId, "No local memory filesystem found to reset.", true, msg);
110206
110893
  return { submitted: true };
110207
110894
  }
110208
- const backupDir = join38(tmpdir5(), `letta-memfs-reset-${agentId}-${Date.now()}`);
110895
+ const backupDir = join39(tmpdir5(), `letta-memfs-reset-${agentId}-${Date.now()}`);
110209
110896
  renameSync2(memoryDir, backupDir);
110210
110897
  ensureMemoryFilesystemDirs(agentId);
110211
110898
  updateMemorySyncCommand(cmdId, `Memory filesystem reset.
@@ -110233,8 +110920,8 @@ Run \`/memfs sync\` to repopulate from API.`, true, msg);
110233
110920
  await removeGitMemoryTag2(agentId);
110234
110921
  let backupInfo = "";
110235
110922
  const memoryDir = getMemoryFilesystemRoot(agentId);
110236
- if (existsSync25(memoryDir)) {
110237
- const backupDir = join38(tmpdir5(), `letta-memfs-disable-${agentId}-${Date.now()}`);
110923
+ if (existsSync26(memoryDir)) {
110924
+ const backupDir = join39(tmpdir5(), `letta-memfs-disable-${agentId}-${Date.now()}`);
110238
110925
  renameSync2(memoryDir, backupDir);
110239
110926
  backupInfo = `
110240
110927
  Local files backed up to ${backupDir}`;
@@ -110358,7 +111045,8 @@ ${SYSTEM_REMINDER_CLOSE}`;
110358
111045
  agentId,
110359
111046
  workingDirectory: process.cwd(),
110360
111047
  memoryDir: getMemoryFilesystemRoot(agentId),
110361
- gitContext
111048
+ gitContext,
111049
+ depth: "deep"
110362
111050
  });
110363
111051
  const { spawnBackgroundSubagentTask: spawnBackgroundSubagentTask2 } = await init_Task2().then(() => exports_Task);
110364
111052
  spawnBackgroundSubagentTask2({
@@ -110367,10 +111055,14 @@ ${SYSTEM_REMINDER_CLOSE}`;
110367
111055
  description: "Initializing memory",
110368
111056
  silentCompletion: true,
110369
111057
  onComplete: ({ success, error }) => {
110370
- const msg2 = success ? "Built a memory palace of you. Visit it with /palace." : `Memory initialization failed: ${error}`;
111058
+ if (success) {
111059
+ updateInitProgress(agentId, { deepFired: true });
111060
+ }
111061
+ const msg2 = success ? "Built a memory palace of you. Visit it with /palace." : `Memory initialization failed: ${error || "Unknown error"}`;
110371
111062
  appendTaskNotificationEvents([msg2]);
110372
111063
  }
110373
111064
  });
111065
+ autoInitPendingAgentIdsRef.current.delete(agentId);
110374
111066
  cmd.finish("Learning about you and your codebase in the background. You'll be notified when ready.", true);
110375
111067
  const reminders = sharedReminderStateRef.current.pendingCommandIoReminders;
110376
111068
  const idx = reminders.findIndex((r) => r.input === "/init");
@@ -110382,6 +111074,7 @@ ${SYSTEM_REMINDER_CLOSE}`;
110382
111074
  cmd.fail(`Failed to start memory initialization: ${errorDetails}`);
110383
111075
  }
110384
111076
  } else {
111077
+ autoInitPendingAgentIdsRef.current.delete(agentId);
110385
111078
  setCommandRunning(true);
110386
111079
  try {
110387
111080
  cmd.finish("Assimilating project context and defragmenting memories...", true);
@@ -110461,6 +111154,21 @@ ${SYSTEM_REMINDER_CLOSE}`)
110461
111154
  return { submitted: true };
110462
111155
  }
110463
111156
  }
111157
+ if (autoInitPendingAgentIdsRef.current.has(agentId) && !isSystemOnly) {
111158
+ try {
111159
+ const fired = await fireAutoInit(agentId, ({ success, error }) => {
111160
+ if (success) {
111161
+ updateInitProgress(agentId, { shallowCompleted: true });
111162
+ }
111163
+ const msg2 = success ? "Built a memory palace of you. Visit it with /palace." : `Memory initialization failed: ${error || "Unknown error"}`;
111164
+ appendTaskNotificationEvents([msg2]);
111165
+ });
111166
+ if (fired) {
111167
+ autoInitPendingAgentIdsRef.current.delete(agentId);
111168
+ sharedReminderStateRef.current.pendingAutoInitReminder = true;
111169
+ }
111170
+ } catch {}
111171
+ }
110464
111172
  const contentParts = overrideContentParts ?? buildMessageContentFromDisplay(msg);
110465
111173
  let ralphModeReminder = "";
110466
111174
  if (ralphMode.getState().isActive) {
@@ -110558,7 +111266,45 @@ ${SYSTEM_REMINDER_CLOSE}
110558
111266
  return false;
110559
111267
  }
110560
111268
  };
111269
+ const maybeLaunchDeepInitSubagent = async () => {
111270
+ if (!memfsEnabledForAgent)
111271
+ return false;
111272
+ if (hasActiveInitSubagent())
111273
+ return false;
111274
+ try {
111275
+ const gitContext = gatherGitContext();
111276
+ const initPrompt = buildMemoryInitRuntimePrompt({
111277
+ agentId,
111278
+ workingDirectory: process.cwd(),
111279
+ memoryDir: getMemoryFilesystemRoot(agentId),
111280
+ gitContext,
111281
+ depth: "deep"
111282
+ });
111283
+ const { spawnBackgroundSubagentTask: spawnBackgroundSubagentTask2 } = await init_Task2().then(() => exports_Task);
111284
+ spawnBackgroundSubagentTask2({
111285
+ subagentType: "init",
111286
+ prompt: initPrompt,
111287
+ description: "Deep memory initialization",
111288
+ silentCompletion: true,
111289
+ onComplete: ({ success, error }) => {
111290
+ if (success) {
111291
+ updateInitProgress(agentId, { deepFired: true });
111292
+ }
111293
+ const msg2 = success ? "Built a memory palace of you. Visit it with /palace." : `Deep memory initialization failed: ${error || "Unknown error"}`;
111294
+ appendTaskNotificationEvents([msg2]);
111295
+ }
111296
+ });
111297
+ debugLog("memory", "Auto-launched deep init subagent");
111298
+ return true;
111299
+ } catch (error) {
111300
+ debugWarn("memory", `Failed to auto-launch deep init subagent: ${error instanceof Error ? error.message : String(error)}`);
111301
+ return false;
111302
+ }
111303
+ };
110561
111304
  syncReminderStateFromContextTracker(sharedReminderStateRef.current, contextTrackerRef.current);
111305
+ const initProgress = initProgressByAgentRef.current.get(agentId);
111306
+ sharedReminderStateRef.current.shallowInitCompleted = initProgress?.shallowCompleted ?? false;
111307
+ sharedReminderStateRef.current.deepInitFired = initProgress?.deepFired ?? false;
110562
111308
  const { getSkillSources: getSkillSources2 } = await Promise.resolve().then(() => (init_context(), exports_context));
110563
111309
  const { parts: sharedReminderParts } = await buildSharedReminderParts({
110564
111310
  mode: "interactive",
@@ -110573,7 +111319,8 @@ ${SYSTEM_REMINDER_CLOSE}
110573
111319
  reflectionSettings,
110574
111320
  skillSources: getSkillSources2(),
110575
111321
  resolvePlanModeReminder: getPlanModeReminder,
110576
- maybeLaunchReflectionSubagent
111322
+ maybeLaunchReflectionSubagent,
111323
+ maybeLaunchDeepInitSubagent
110577
111324
  });
110578
111325
  for (const part of sharedReminderParts) {
110579
111326
  reminderParts.push(part);
@@ -112307,7 +113054,7 @@ ${guidance}`);
112307
113054
  }
112308
113055
  if (!planFileExists()) {
112309
113056
  const planFilePath = permissionMode.getPlanFilePath();
112310
- const plansDir = join38(homedir27(), ".letta", "plans");
113057
+ const plansDir = join39(homedir28(), ".letta", "plans");
112311
113058
  handlePlanKeepPlanning(`You must write your plan to a plan file before exiting plan mode.
112312
113059
  ` + (planFilePath ? `Plan file path: ${planFilePath}
112313
113060
  ` : "") + `Use a write tool to create your plan in ${plansDir}, then use ExitPlanMode to present the plan to the user.`);
@@ -112512,6 +113259,14 @@ If using apply_patch, use this exact relative patch path: ${applyPatchRelativePa
112512
113259
  return estimatedLiveHeight < resumeThreshold;
112513
113260
  });
112514
113261
  }, [estimatedLiveHeight, terminalRows]);
113262
+ import_react99.useEffect(() => {
113263
+ if (loadingState === "ready" && agentProvenance?.isNew && agentId && !startupAutoInitConsumedRef.current) {
113264
+ startupAutoInitConsumedRef.current = true;
113265
+ if (settingsManager.isMemfsEnabled(agentId)) {
113266
+ autoInitPendingAgentIdsRef.current.add(agentId);
113267
+ }
113268
+ }
113269
+ }, [loadingState, agentProvenance, agentId]);
112515
113270
  import_react99.useEffect(() => {
112516
113271
  if (loadingState === "ready" && !welcomeCommittedRef.current && messageHistory.length === 0) {
112517
113272
  if (!continueSession && !agentProvenance) {
@@ -112822,7 +113577,7 @@ If using apply_patch, use this exact relative patch path: ${applyPatchRelativePa
112822
113577
  color: colors.link.url,
112823
113578
  children: agentName && (settingsManager.getLocalPinnedAgents().includes(agentId) || settingsManager.getGlobalPinnedAgents().includes(agentId)) ? `letta -n "${agentName}"` : `letta --agent ${agentId}`
112824
113579
  }, undefined, false, undefined, this),
112825
- conversationId !== "default" && /* @__PURE__ */ jsx_dev_runtime76.jsxDEV(jsx_dev_runtime76.Fragment, {
113580
+ conversationId !== "default" && conversationId !== agentId && /* @__PURE__ */ jsx_dev_runtime76.jsxDEV(jsx_dev_runtime76.Fragment, {
112826
113581
  children: [
112827
113582
  /* @__PURE__ */ jsx_dev_runtime76.jsxDEV(Box_default, {
112828
113583
  height: 1
@@ -113446,6 +114201,9 @@ Open /mcp to attach or detach tools for this server.`, true);
113446
114201
  } else {
113447
114202
  settingsManager.pinGlobal(agentId);
113448
114203
  }
114204
+ if (newName && newName !== agentName) {
114205
+ cmd.agentHint = `Your name is now "${newName}" — acknowledge this and save your new name to memory.`;
114206
+ }
113449
114207
  cmd.finish(`Pinned "${newName || agentName || agentId.slice(0, 12)}" ${scopeText}.`, true);
113450
114208
  } catch (error) {
113451
114209
  cmd.fail(`Failed to pin: ${error}`);
@@ -113463,7 +114221,7 @@ Open /mcp to attach or detach tools for this server.`, true);
113463
114221
  ]
113464
114222
  }, resumeKey, true, undefined, this);
113465
114223
  }
113466
- var import_react99, jsx_dev_runtime76, CLEAR_SCREEN_AND_HOME = "\x1B[2J\x1B[H", MIN_RESIZE_DELTA = 2, RESIZE_SETTLE_MS = 250, MIN_CLEAR_INTERVAL_MS = 750, STABLE_WIDTH_SETTLE_MS = 180, TOOL_CALL_COMMIT_DEFER_MS = 50, ANIMATION_RESUME_HYSTERESIS_ROWS = 2, EAGER_CANCEL = true, LLM_API_ERROR_MAX_RETRIES3 = 3, EMPTY_RESPONSE_MAX_RETRIES2 = 2, CONVERSATION_BUSY_MAX_RETRIES2 = 3, CONVERSATION_BUSY_RETRY_BASE_DELAY_MS = 2500, INTERRUPT_MESSAGE = "Interrupted – tell the agent what to do differently. Something went wrong? Use /feedback to report issues.", ERROR_FEEDBACK_HINT = "Something went wrong? Use /feedback to report issues.", OPUS_BEDROCK_FALLBACK_HINT = "Downstream provider issues? Use /model to switch to Bedrock Opus 4.5", PROVIDER_FALLBACK_HINT = "Downstream provider issues? Use /model to switch to another provider", INTERACTIVE_SLASH_COMMANDS, NON_STATE_COMMANDS, APPROVAL_OPTIONS_HEIGHT = 8, APPROVAL_PREVIEW_BUFFER = 4, MIN_WRAP_WIDTH = 10, TEXT_WRAP_GUTTER = 6, DIFF_WRAP_GUTTER = 12, AUTO_REFLECTION_DESCRIPTION = "Reflect on recent conversations", AUTO_REFLECTION_PROMPT = "Review recent conversation history and update memory files with important information worth preserving.";
114224
+ var import_react99, jsx_dev_runtime76, CLEAR_SCREEN_AND_HOME = "\x1B[2J\x1B[H", MIN_RESIZE_DELTA = 2, RESIZE_SETTLE_MS = 250, MIN_CLEAR_INTERVAL_MS = 750, STABLE_WIDTH_SETTLE_MS = 180, TOOL_CALL_COMMIT_DEFER_MS = 50, ANIMATION_RESUME_HYSTERESIS_ROWS = 2, EAGER_CANCEL = true, LLM_API_ERROR_MAX_RETRIES3 = 3, EMPTY_RESPONSE_MAX_RETRIES2 = 2, CONVERSATION_BUSY_MAX_RETRIES2 = 3, CONVERSATION_BUSY_RETRY_BASE_DELAY_MS2 = 1e4, INTERRUPT_MESSAGE = "Interrupted – tell the agent what to do differently. Something went wrong? Use /feedback to report issues.", ERROR_FEEDBACK_HINT = "Something went wrong? Use /feedback to report issues.", OPUS_BEDROCK_FALLBACK_HINT = "Downstream provider issues? Use /model to switch to Bedrock Opus 4.5", PROVIDER_FALLBACK_HINT = "Downstream provider issues? Use /model to switch to another provider", INTERACTIVE_SLASH_COMMANDS, NON_STATE_COMMANDS, APPROVAL_OPTIONS_HEIGHT = 8, APPROVAL_PREVIEW_BUFFER = 4, MIN_WRAP_WIDTH = 10, TEXT_WRAP_GUTTER = 6, DIFF_WRAP_GUTTER = 12, AUTO_REFLECTION_DESCRIPTION = "Reflect on recent conversations", AUTO_REFLECTION_PROMPT = "Review recent conversation history and update memory files with important information worth preserving.";
113467
114225
  var init_App2 = __esm(async () => {
113468
114226
  init_error();
113469
114227
  init_check_approval();
@@ -113489,7 +114247,6 @@ var init_App2 = __esm(async () => {
113489
114247
  init_diff2();
113490
114248
  init_errorContext();
113491
114249
  init_errorFormatter();
113492
- init_initCommand();
113493
114250
  init_messageQueueBridge();
113494
114251
  init_pasteRegistry();
113495
114252
  init_planName();
@@ -113563,6 +114320,7 @@ var init_App2 = __esm(async () => {
113563
114320
  init_accumulator(),
113564
114321
  init_approvalClassification(),
113565
114322
  init_formatArgsDisplay(),
114323
+ init_initCommand(),
113566
114324
  init_memoryReminder(),
113567
114325
  init_statusLineConfig(),
113568
114326
  init_stream(),
@@ -113628,13 +114386,13 @@ __export(exports_terminalKeybindingInstaller2, {
113628
114386
  });
113629
114387
  import {
113630
114388
  copyFileSync as copyFileSync2,
113631
- existsSync as existsSync26,
113632
- mkdirSync as mkdirSync17,
113633
- readFileSync as readFileSync11,
114389
+ existsSync as existsSync27,
114390
+ mkdirSync as mkdirSync18,
114391
+ readFileSync as readFileSync12,
113634
114392
  writeFileSync as writeFileSync13
113635
114393
  } from "node:fs";
113636
- import { homedir as homedir28, platform as platform5 } from "node:os";
113637
- import { dirname as dirname14, join as join39 } from "node:path";
114394
+ import { homedir as homedir29, platform as platform5 } from "node:os";
114395
+ import { dirname as dirname14, join as join40 } from "node:path";
113638
114396
  function detectTerminalType2() {
113639
114397
  if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
113640
114398
  return "cursor";
@@ -113666,16 +114424,16 @@ function getKeybindingsPath2(terminal) {
113666
114424
  }[terminal];
113667
114425
  const os7 = platform5();
113668
114426
  if (os7 === "darwin") {
113669
- return join39(homedir28(), "Library", "Application Support", appName, "User", "keybindings.json");
114427
+ return join40(homedir29(), "Library", "Application Support", appName, "User", "keybindings.json");
113670
114428
  }
113671
114429
  if (os7 === "win32") {
113672
114430
  const appData = process.env.APPDATA;
113673
114431
  if (!appData)
113674
114432
  return null;
113675
- return join39(appData, appName, "User", "keybindings.json");
114433
+ return join40(appData, appName, "User", "keybindings.json");
113676
114434
  }
113677
114435
  if (os7 === "linux") {
113678
- return join39(homedir28(), ".config", appName, "User", "keybindings.json");
114436
+ return join40(homedir29(), ".config", appName, "User", "keybindings.json");
113679
114437
  }
113680
114438
  return null;
113681
114439
  }
@@ -113697,10 +114455,10 @@ function parseKeybindings2(content) {
113697
114455
  }
113698
114456
  }
113699
114457
  function keybindingExists2(keybindingsPath) {
113700
- if (!existsSync26(keybindingsPath))
114458
+ if (!existsSync27(keybindingsPath))
113701
114459
  return false;
113702
114460
  try {
113703
- const content = readFileSync11(keybindingsPath, { encoding: "utf-8" });
114461
+ const content = readFileSync12(keybindingsPath, { encoding: "utf-8" });
113704
114462
  const keybindings = parseKeybindings2(content);
113705
114463
  if (!keybindings)
113706
114464
  return false;
@@ -113710,7 +114468,7 @@ function keybindingExists2(keybindingsPath) {
113710
114468
  }
113711
114469
  }
113712
114470
  function createBackup2(keybindingsPath) {
113713
- if (!existsSync26(keybindingsPath))
114471
+ if (!existsSync27(keybindingsPath))
113714
114472
  return null;
113715
114473
  const backupPath = `${keybindingsPath}.letta-backup`;
113716
114474
  try {
@@ -113726,14 +114484,14 @@ function installKeybinding2(keybindingsPath) {
113726
114484
  return { success: true, alreadyExists: true };
113727
114485
  }
113728
114486
  const parentDir = dirname14(keybindingsPath);
113729
- if (!existsSync26(parentDir)) {
113730
- mkdirSync17(parentDir, { recursive: true });
114487
+ if (!existsSync27(parentDir)) {
114488
+ mkdirSync18(parentDir, { recursive: true });
113731
114489
  }
113732
114490
  let keybindings = [];
113733
114491
  let backupPath = null;
113734
- if (existsSync26(keybindingsPath)) {
114492
+ if (existsSync27(keybindingsPath)) {
113735
114493
  backupPath = createBackup2(keybindingsPath);
113736
- const content = readFileSync11(keybindingsPath, { encoding: "utf-8" });
114494
+ const content = readFileSync12(keybindingsPath, { encoding: "utf-8" });
113737
114495
  const parsed = parseKeybindings2(content);
113738
114496
  if (parsed === null) {
113739
114497
  return {
@@ -113761,10 +114519,10 @@ function installKeybinding2(keybindingsPath) {
113761
114519
  }
113762
114520
  function removeKeybinding2(keybindingsPath) {
113763
114521
  try {
113764
- if (!existsSync26(keybindingsPath)) {
114522
+ if (!existsSync27(keybindingsPath)) {
113765
114523
  return { success: true };
113766
114524
  }
113767
- const content = readFileSync11(keybindingsPath, { encoding: "utf-8" });
114525
+ const content = readFileSync12(keybindingsPath, { encoding: "utf-8" });
113768
114526
  const keybindings = parseKeybindings2(content);
113769
114527
  if (!keybindings) {
113770
114528
  return {
@@ -113828,20 +114586,20 @@ function getWezTermConfigPath2() {
113828
114586
  }
113829
114587
  const xdgConfig = process.env.XDG_CONFIG_HOME;
113830
114588
  if (xdgConfig) {
113831
- const xdgPath = join39(xdgConfig, "wezterm", "wezterm.lua");
113832
- if (existsSync26(xdgPath))
114589
+ const xdgPath = join40(xdgConfig, "wezterm", "wezterm.lua");
114590
+ if (existsSync27(xdgPath))
113833
114591
  return xdgPath;
113834
114592
  }
113835
- const configPath = join39(homedir28(), ".config", "wezterm", "wezterm.lua");
113836
- if (existsSync26(configPath))
114593
+ const configPath = join40(homedir29(), ".config", "wezterm", "wezterm.lua");
114594
+ if (existsSync27(configPath))
113837
114595
  return configPath;
113838
- return join39(homedir28(), ".wezterm.lua");
114596
+ return join40(homedir29(), ".wezterm.lua");
113839
114597
  }
113840
114598
  function wezTermDeleteFixExists2(configPath) {
113841
- if (!existsSync26(configPath))
114599
+ if (!existsSync27(configPath))
113842
114600
  return false;
113843
114601
  try {
113844
- const content = readFileSync11(configPath, { encoding: "utf-8" });
114602
+ const content = readFileSync12(configPath, { encoding: "utf-8" });
113845
114603
  return content.includes("Letta Code: Fix Delete key") || content.includes("key = 'Delete'") && content.includes("SendString") && content.includes("\\x1b[3~");
113846
114604
  } catch {
113847
114605
  return false;
@@ -113855,10 +114613,10 @@ function installWezTermDeleteFix2() {
113855
114613
  }
113856
114614
  let content = "";
113857
114615
  let backupPath = null;
113858
- if (existsSync26(configPath)) {
114616
+ if (existsSync27(configPath)) {
113859
114617
  backupPath = `${configPath}.letta-backup`;
113860
114618
  copyFileSync2(configPath, backupPath);
113861
- content = readFileSync11(configPath, { encoding: "utf-8" });
114619
+ content = readFileSync12(configPath, { encoding: "utf-8" });
113862
114620
  }
113863
114621
  if (content.includes("return {") && !content.includes("local config")) {
113864
114622
  content = content.replace(/return\s*\{/, "local config = {");
@@ -113885,8 +114643,8 @@ ${WEZTERM_DELETE_FIX2}
113885
114643
  `;
113886
114644
  }
113887
114645
  const parentDir = dirname14(configPath);
113888
- if (!existsSync26(parentDir)) {
113889
- mkdirSync17(parentDir, { recursive: true });
114646
+ if (!existsSync27(parentDir)) {
114647
+ mkdirSync18(parentDir, { recursive: true });
113890
114648
  }
113891
114649
  writeFileSync13(configPath, content, { encoding: "utf-8" });
113892
114650
  return {
@@ -113933,10 +114691,10 @@ __export(exports_settings2, {
113933
114691
  loadProjectSettings: () => loadProjectSettings2,
113934
114692
  getSetting: () => getSetting2
113935
114693
  });
113936
- import { homedir as homedir29 } from "node:os";
113937
- import { join as join40 } from "node:path";
114694
+ import { homedir as homedir30 } from "node:os";
114695
+ import { join as join41 } from "node:path";
113938
114696
  function getSettingsPath2() {
113939
- return join40(homedir29(), ".letta", "settings.json");
114697
+ return join41(homedir30(), ".letta", "settings.json");
113940
114698
  }
113941
114699
  async function loadSettings2() {
113942
114700
  const settingsPath = getSettingsPath2();
@@ -113973,7 +114731,7 @@ async function getSetting2(key) {
113973
114731
  return settings[key];
113974
114732
  }
113975
114733
  function getProjectSettingsPath2() {
113976
- return join40(process.cwd(), ".letta", "settings.local.json");
114734
+ return join41(process.cwd(), ".letta", "settings.local.json");
113977
114735
  }
113978
114736
  async function loadProjectSettings2() {
113979
114737
  const settingsPath = getProjectSettingsPath2();
@@ -113991,7 +114749,7 @@ async function loadProjectSettings2() {
113991
114749
  }
113992
114750
  async function saveProjectSettings2(settings) {
113993
114751
  const settingsPath = getProjectSettingsPath2();
113994
- const dirPath = join40(process.cwd(), ".letta");
114752
+ const dirPath = join41(process.cwd(), ".letta");
113995
114753
  try {
113996
114754
  if (!exists(dirPath)) {
113997
114755
  await mkdir(dirPath, { recursive: true });
@@ -114530,7 +115288,7 @@ function parseRegistryHandle2(handle) {
114530
115288
  }
114531
115289
  async function importAgentFromRegistry2(options) {
114532
115290
  const { tmpdir: tmpdir6 } = await import("node:os");
114533
- const { join: join41 } = await import("node:path");
115291
+ const { join: join42 } = await import("node:path");
114534
115292
  const { writeFile: writeFile5, unlink } = await import("node:fs/promises");
114535
115293
  const { author, name } = parseRegistryHandle2(options.handle);
114536
115294
  const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER2}/${AGENT_REGISTRY_REPO2}/refs/heads/${AGENT_REGISTRY_BRANCH2}/agents/@${author}/${name}/${name}.af`;
@@ -114542,7 +115300,7 @@ async function importAgentFromRegistry2(options) {
114542
115300
  throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
114543
115301
  }
114544
115302
  const afContent = await response.text();
114545
- const tempPath = join41(tmpdir6(), `letta-import-${author}-${name}-${Date.now()}.af`);
115303
+ const tempPath = join42(tmpdir6(), `letta-import-${author}-${name}-${Date.now()}.af`);
114546
115304
  await writeFile5(tempPath, afContent, "utf-8");
114547
115305
  try {
114548
115306
  const result = await importAgentFromFile2({
@@ -114582,23 +115340,23 @@ __export(exports_memoryFilesystem2, {
114582
115340
  MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR2,
114583
115341
  MEMORY_FS_AGENTS_DIR: () => MEMORY_FS_AGENTS_DIR2
114584
115342
  });
114585
- import { existsSync as existsSync27, mkdirSync as mkdirSync18 } from "node:fs";
114586
- import { homedir as homedir30 } from "node:os";
114587
- import { join as join41 } from "node:path";
114588
- function getMemoryFilesystemRoot2(agentId, homeDir = homedir30()) {
114589
- return join41(homeDir, MEMORY_FS_ROOT2, MEMORY_FS_AGENTS_DIR2, agentId, MEMORY_FS_MEMORY_DIR2);
115343
+ import { existsSync as existsSync28, mkdirSync as mkdirSync19 } from "node:fs";
115344
+ import { homedir as homedir31 } from "node:os";
115345
+ import { join as join42 } from "node:path";
115346
+ function getMemoryFilesystemRoot2(agentId, homeDir = homedir31()) {
115347
+ return join42(homeDir, MEMORY_FS_ROOT2, MEMORY_FS_AGENTS_DIR2, agentId, MEMORY_FS_MEMORY_DIR2);
114590
115348
  }
114591
- function getMemorySystemDir2(agentId, homeDir = homedir30()) {
114592
- return join41(getMemoryFilesystemRoot2(agentId, homeDir), MEMORY_SYSTEM_DIR2);
115349
+ function getMemorySystemDir2(agentId, homeDir = homedir31()) {
115350
+ return join42(getMemoryFilesystemRoot2(agentId, homeDir), MEMORY_SYSTEM_DIR2);
114593
115351
  }
114594
- function ensureMemoryFilesystemDirs2(agentId, homeDir = homedir30()) {
115352
+ function ensureMemoryFilesystemDirs2(agentId, homeDir = homedir31()) {
114595
115353
  const root = getMemoryFilesystemRoot2(agentId, homeDir);
114596
115354
  const systemDir = getMemorySystemDir2(agentId, homeDir);
114597
- if (!existsSync27(root)) {
114598
- mkdirSync18(root, { recursive: true });
115355
+ if (!existsSync28(root)) {
115356
+ mkdirSync19(root, { recursive: true });
114599
115357
  }
114600
- if (!existsSync27(systemDir)) {
114601
- mkdirSync18(systemDir, { recursive: true });
115358
+ if (!existsSync28(systemDir)) {
115359
+ mkdirSync19(systemDir, { recursive: true });
114602
115360
  }
114603
115361
  }
114604
115362
  function labelFromRelativePath2(relativePath) {
@@ -114975,9 +115733,6 @@ async function getResumeData(client, agent, conversationId, options = {}) {
114975
115733
  let inContextMessageIds;
114976
115734
  let messages = [];
114977
115735
  const useConversationsApi = conversationId && conversationId !== "default";
114978
- if (process.env.DEBUG) {
114979
- console.log(`[DEBUG] getResumeData: conversationId=${conversationId}, useConversationsApi=${useConversationsApi}, agentId=${agent.id}`);
114980
- }
114981
115736
  if (useConversationsApi) {
114982
115737
  const conversation = await client.conversations.retrieve(conversationId);
114983
115738
  inContextMessageIds = conversation.in_context_message_ids;
@@ -115053,13 +115808,14 @@ async function getResumeData(client, agent, conversationId, options = {}) {
115053
115808
  const retrievedMessages = await client.messages.retrieve(lastInContextId);
115054
115809
  if (includeMessageHistory && isBackfillEnabled()) {
115055
115810
  try {
115056
- const messagesPage = await client.conversations.messages.list(agent.id, {
115811
+ const messagesPage = await client.conversations.messages.list("default", {
115812
+ agent_id: agent.id,
115057
115813
  limit: BACKFILL_PAGE_LIMIT,
115058
115814
  order: "desc"
115059
115815
  });
115060
115816
  messages = sortChronological(messagesPage.getPaginatedItems());
115061
115817
  if (process.env.DEBUG) {
115062
- console.log(`[DEBUG] conversations.messages.list(${agent.id}) returned ${messages.length} messages`);
115818
+ console.log(`[DEBUG] conversations.messages.list(default, agent_id=${agent.id}) returned ${messages.length} messages`);
115063
115819
  }
115064
115820
  } catch (backfillError) {
115065
115821
  debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
@@ -115742,7 +116498,8 @@ function ConversationSelector({
115742
116498
  let defaultConversation = null;
115743
116499
  if (!afterCursor) {
115744
116500
  try {
115745
- const defaultMessages = await client.conversations.messages.list(agentId, {
116501
+ const defaultMessages = await client.conversations.messages.list("default", {
116502
+ agent_id: agentId,
115746
116503
  limit: 20,
115747
116504
  order: "desc"
115748
116505
  });
@@ -116152,8 +116909,8 @@ function parseJsonArrayFlag(rawValue, flagName) {
116152
116909
  init_error();
116153
116910
  init_errorContext();
116154
116911
  init_zaiErrors();
116155
- var LETTA_USAGE_URL = "https://app.letta.com/settings/organization/usage";
116156
- var LETTA_AGENTS_URL = "https://app.letta.com/projects/default-project/agents";
116912
+ var LETTA_USAGE_URL = buildAppUrl("/settings/organization/usage");
116913
+ var LETTA_AGENTS_URL = buildAppUrl("/projects/default-project/agents");
116157
116914
  function extractReasonList(value) {
116158
116915
  if (!Array.isArray(value))
116159
116916
  return [];
@@ -116585,7 +117342,7 @@ ${createAgentLink(runId, agentId, conversationId)}` : baseError;
116585
117342
  return String(e);
116586
117343
  }
116587
117344
  function createAgentLink(runId, agentId, conversationId) {
116588
- const url = `https://app.letta.com/agents/${agentId}${conversationId && conversationId !== "default" ? `?conversation=${conversationId}` : ""}`;
117345
+ const url = buildChatUrl(agentId, { conversationId });
116589
117346
  return `View agent: \x1B]8;;${url}\x1B\\${agentId}\x1B]8;;\x1B\\ (run: ${runId})`;
116590
117347
  }
116591
117348
 
@@ -117792,7 +118549,7 @@ async function runListenSubcommand(argv) {
117792
118549
  });
117793
118550
  const debugMode = !!values.debug;
117794
118551
  if (values.help) {
117795
- console.log(`Usage: letta remote [--env-name <name>] [--debug]
118552
+ console.log(`Usage: letta server [--env-name <name>] [--debug]
117796
118553
  `);
117797
118554
  console.log(`Register this letta-code instance to receive messages from Letta Cloud.
117798
118555
  `);
@@ -117802,9 +118559,9 @@ async function runListenSubcommand(argv) {
117802
118559
  console.log(` -h, --help Show this help message
117803
118560
  `);
117804
118561
  console.log("Examples:");
117805
- console.log(" letta remote # Uses hostname as default");
117806
- console.log(' letta remote --env-name "work-laptop"');
117807
- console.log(` letta remote --debug # Log all WS events
118562
+ console.log(" letta server # Uses hostname as default");
118563
+ console.log(' letta server --env-name "work-laptop"');
118564
+ console.log(` letta server --debug # Log all WS events
117808
118565
  `);
117809
118566
  console.log("Once connected, this instance will listen for incoming messages from cloud agents.");
117810
118567
  console.log("Messages will be executed locally using your letta-code environment.");
@@ -118389,7 +119146,8 @@ async function runMessagesSubcommand(argv) {
118389
119146
  console.error(`Invalid --order "${orderRaw}". Use "asc" or "desc".`);
118390
119147
  return 1;
118391
119148
  }
118392
- const response = await client.conversations.messages.list(agentId, {
119149
+ const response = await client.conversations.messages.list("default", {
119150
+ agent_id: agentId,
118393
119151
  limit: parseLimit3(parsed.values.limit, 20),
118394
119152
  after: parsed.values.after,
118395
119153
  before: parsed.values.before,
@@ -118441,6 +119199,7 @@ async function runSubcommand(argv) {
118441
119199
  return runMessagesSubcommand(rest);
118442
119200
  case "blocks":
118443
119201
  return runBlocksSubcommand(rest);
119202
+ case "server":
118444
119203
  case "remote":
118445
119204
  return runListenSubcommand(rest);
118446
119205
  case "connect":
@@ -120032,7 +120791,7 @@ function replaceRegistry2(newTools) {
120032
120791
  toolRegistry2.set(key, value);
120033
120792
  }
120034
120793
  }
120035
- async function loadTools2(modelIdentifier) {
120794
+ async function loadTools2(modelIdentifier, options) {
120036
120795
  acquireSwitchLock2();
120037
120796
  try {
120038
120797
  const { toolFilter: toolFilter2 } = await Promise.resolve().then(() => (init_filter(), exports_filter));
@@ -120053,6 +120812,10 @@ async function loadTools2(modelIdentifier) {
120053
120812
  } else {
120054
120813
  baseToolNames = TOOL_NAMES2;
120055
120814
  }
120815
+ if (options?.exclude && options.exclude.length > 0) {
120816
+ const excludeSet = new Set(options.exclude);
120817
+ baseToolNames = baseToolNames.filter((name) => !excludeSet.has(name));
120818
+ }
120056
120819
  const newRegistry = new Map;
120057
120820
  for (const name of baseToolNames) {
120058
120821
  if (!toolFilter2.isEnabled(name)) {
@@ -120145,6 +120908,119 @@ ${agentsSection}
120145
120908
  ${after}`;
120146
120909
  }
120147
120910
 
120911
+ // src/utils/debug.ts
120912
+ import {
120913
+ appendFileSync as appendFileSync3,
120914
+ existsSync as existsSync12,
120915
+ mkdirSync as mkdirSync10,
120916
+ readdirSync as readdirSync7,
120917
+ readFileSync as readFileSync4,
120918
+ unlinkSync as unlinkSync6
120919
+ } from "node:fs";
120920
+ import { homedir as homedir18 } from "node:os";
120921
+ import { join as join21 } from "node:path";
120922
+ import { format as format2 } from "node:util";
120923
+ function isDebugEnabled2() {
120924
+ const debug = process.env.LETTA_DEBUG;
120925
+ return debug === "1" || debug === "true";
120926
+ }
120927
+ function getDebugFile2() {
120928
+ const path20 = process.env.LETTA_DEBUG_FILE;
120929
+ return path20 && path20.trim().length > 0 ? path20 : null;
120930
+ }
120931
+ function printDebugLine2(line) {
120932
+ const debugFile = getDebugFile2();
120933
+ if (debugFile) {
120934
+ try {
120935
+ appendFileSync3(debugFile, line, { encoding: "utf8" });
120936
+ return;
120937
+ } catch {}
120938
+ }
120939
+ console.log(line.trimEnd());
120940
+ }
120941
+ var DEBUG_LOG_DIR2 = join21(homedir18(), ".letta", "logs", "debug");
120942
+ var MAX_SESSION_FILES3 = 5;
120943
+ var DEFAULT_TAIL_LINES2 = 50;
120944
+
120945
+ class DebugLogFile2 {
120946
+ logPath = null;
120947
+ agentDir = null;
120948
+ dirCreated = false;
120949
+ init(agentId, sessionId) {
120950
+ const telem = process.env.LETTA_CODE_TELEM;
120951
+ if (telem === "0" || telem === "false")
120952
+ return;
120953
+ this.agentDir = join21(DEBUG_LOG_DIR2, agentId);
120954
+ this.logPath = join21(this.agentDir, `${sessionId}.log`);
120955
+ this.dirCreated = false;
120956
+ this.pruneOldSessions();
120957
+ }
120958
+ appendLine(line) {
120959
+ if (!this.logPath)
120960
+ return;
120961
+ this.ensureDir();
120962
+ try {
120963
+ appendFileSync3(this.logPath, line, { encoding: "utf8" });
120964
+ } catch {}
120965
+ }
120966
+ getTail(maxLines = DEFAULT_TAIL_LINES2) {
120967
+ if (!this.logPath)
120968
+ return;
120969
+ try {
120970
+ if (!existsSync12(this.logPath))
120971
+ return;
120972
+ const content = readFileSync4(this.logPath, "utf8");
120973
+ const lines = content.trimEnd().split(`
120974
+ `);
120975
+ return lines.slice(-maxLines).join(`
120976
+ `);
120977
+ } catch {
120978
+ return;
120979
+ }
120980
+ }
120981
+ ensureDir() {
120982
+ if (this.dirCreated || !this.agentDir)
120983
+ return;
120984
+ try {
120985
+ if (!existsSync12(this.agentDir)) {
120986
+ mkdirSync10(this.agentDir, { recursive: true });
120987
+ }
120988
+ this.dirCreated = true;
120989
+ } catch {}
120990
+ }
120991
+ pruneOldSessions() {
120992
+ if (!this.agentDir)
120993
+ return;
120994
+ try {
120995
+ if (!existsSync12(this.agentDir))
120996
+ return;
120997
+ const files = readdirSync7(this.agentDir).filter((f) => f.endsWith(".log")).sort();
120998
+ if (files.length >= MAX_SESSION_FILES3) {
120999
+ const toDelete = files.slice(0, files.length - MAX_SESSION_FILES3 + 1);
121000
+ for (const file of toDelete) {
121001
+ try {
121002
+ unlinkSync6(join21(this.agentDir, file));
121003
+ } catch {}
121004
+ }
121005
+ }
121006
+ } catch {}
121007
+ }
121008
+ }
121009
+ var debugLogFile2 = new DebugLogFile2;
121010
+ function writeDebugLine2(prefix, message, args) {
121011
+ const ts = new Date().toISOString();
121012
+ const body = format2(`[${prefix}] ${message}`, ...args);
121013
+ const line = `${ts} ${body}
121014
+ `;
121015
+ debugLogFile2.appendLine(line);
121016
+ if (isDebugEnabled2()) {
121017
+ printDebugLine2(line);
121018
+ }
121019
+ }
121020
+ function debugLog2(prefix, message, ...args) {
121021
+ writeDebugLine2(prefix, message, args);
121022
+ }
121023
+
120148
121024
  // src/utils/timing.ts
120149
121025
  function isTimingsEnabled2() {
120150
121026
  const val = process.env.LETTA_DEBUG_TIMINGS;
@@ -120251,12 +121127,12 @@ EXAMPLES
120251
121127
  console.log(usage);
120252
121128
  }
120253
121129
  async function printInfo() {
120254
- const { join: join42 } = await import("path");
121130
+ const { join: join43 } = await import("path");
120255
121131
  const { getVersion: getVersion3 } = await Promise.resolve().then(() => (init_version2(), exports_version));
120256
121132
  const { SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills2(), exports_skills2));
120257
121133
  const { exists: exists3 } = await Promise.resolve().then(() => (init_fs2(), exports_fs));
120258
121134
  const cwd2 = process.cwd();
120259
- const skillsDir = join42(cwd2, SKILLS_DIR3);
121135
+ const skillsDir = join43(cwd2, SKILLS_DIR3);
120260
121136
  const skillsExist = exists3(skillsDir);
120261
121137
  await settingsManager2.loadLocalProjectSettings(cwd2);
120262
121138
  const localPinned = settingsManager2.getLocalPinnedAgents(cwd2);
@@ -120650,9 +121526,9 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
120650
121526
  }
120651
121527
  } else {
120652
121528
  const { resolve: resolve30 } = await import("path");
120653
- const { existsSync: existsSync28 } = await import("fs");
121529
+ const { existsSync: existsSync29 } = await import("fs");
120654
121530
  const resolvedPath = resolve30(fromAfFile);
120655
- if (!existsSync28(resolvedPath)) {
121531
+ if (!existsSync29(resolvedPath)) {
120656
121532
  console.error(`Error: AgentFile not found: ${resolvedPath}`);
120657
121533
  process.exit(1);
120658
121534
  }
@@ -120772,7 +121648,7 @@ Error: ${message}`);
120772
121648
  if (isHeadless) {
120773
121649
  markMilestone2("HEADLESS_MODE_START");
120774
121650
  const modelForTools = getModelForToolLoading(specifiedModel, specifiedToolset);
120775
- await loadTools2(modelForTools);
121651
+ await loadTools2(modelForTools, { exclude: ["AskUserQuestion"] });
120776
121652
  markMilestone2("TOOLS_LOADED");
120777
121653
  const headlessValues = specifiedAgentId && values.agent !== specifiedAgentId ? { ...values, agent: specifiedAgentId } : values;
120778
121654
  const { handleHeadlessCommand: handleHeadlessCommand2 } = await init_headless().then(() => exports_headless);
@@ -120930,6 +121806,7 @@ Error: ${message}`);
120930
121806
  return;
120931
121807
  }
120932
121808
  try {
121809
+ debugLog2("conversations", `retrieve(${specifiedConversationId}) [TUI conv\u2192agent lookup]`);
120933
121810
  const conversation = await client.conversations.retrieve(specifiedConversationId);
120934
121811
  setSelectedGlobalAgentId(conversation.agent_id);
120935
121812
  setSelectedConversationId(specifiedConversationId);
@@ -121531,4 +122408,4 @@ Error during initialization: ${message}`);
121531
122408
  }
121532
122409
  main();
121533
122410
 
121534
- //# debugId=9B975B5682ECA31464756E2164756E21
122411
+ //# debugId=FE66CA162A20D40F64756E2164756E21