@letta-ai/letta-code 0.30.19 → 0.30.20

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 (31) hide show
  1. package/dist/gateway-core.js +33 -1
  2. package/dist/gateway-core.js.map +3 -3
  3. package/dist/mcp-client.js +2 -2
  4. package/dist/mcp-client.js.map +1 -1
  5. package/dist/types/agent/model.d.ts.map +1 -1
  6. package/dist/types/agent/subagents/subagent-launcher.d.ts.map +1 -1
  7. package/dist/types/channels/gateway-core.d.ts +3 -0
  8. package/dist/types/channels/gateway-core.d.ts.map +1 -1
  9. package/dist/types/mods/capabilities.d.ts +4 -0
  10. package/dist/types/mods/capabilities.d.ts.map +1 -1
  11. package/dist/types/mods/mod-adapter.d.ts.map +1 -1
  12. package/dist/types/tools/impl/task-update.d.ts +1 -1
  13. package/dist/types/tools/impl/task-update.d.ts.map +1 -1
  14. package/dist/types/tools/impl/task.d.ts +1 -0
  15. package/dist/types/tools/impl/task.d.ts.map +1 -1
  16. package/dist/types/tools/impl/tasks/store.d.ts +3 -6
  17. package/dist/types/tools/impl/tasks/store.d.ts.map +1 -1
  18. package/dist/types/types/protocol_v2.d.ts +8 -10
  19. package/dist/types/types/protocol_v2.d.ts.map +1 -1
  20. package/dist/types/types/service-protocol.d.ts +11 -0
  21. package/dist/types/types/service-protocol.d.ts.map +1 -1
  22. package/dist/types/types/teleport-protocol.d.ts +54 -0
  23. package/dist/types/types/teleport-protocol.d.ts.map +1 -0
  24. package/dist/types/websocket/listener/runtime.d.ts.map +1 -1
  25. package/dist/types/websocket/listener/types.d.ts +13 -1
  26. package/dist/types/websocket/listener/types.d.ts.map +1 -1
  27. package/letta.js +1282 -553
  28. package/package.json +1 -1
  29. package/scripts/source-file-size-baseline.json +4 -4
  30. package/skills/scheduling-tasks/SKILL.md +10 -8
  31. package/skills/teleporting-between-environments/SKILL.md +100 -0
package/letta.js CHANGED
@@ -5488,7 +5488,7 @@ var package_default;
5488
5488
  var init_package = __esm(() => {
5489
5489
  package_default = {
5490
5490
  name: "@letta-ai/letta-code",
5491
- version: "0.30.19",
5491
+ version: "0.30.20",
5492
5492
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
5493
5493
  type: "module",
5494
5494
  packageManager: "bun@1.3.0",
@@ -143838,22 +143838,17 @@ function getResumeRefreshArgs(presetUpdateArgs, agent2) {
143838
143838
  const updateArgs = {};
143839
143839
  for (const field of RESUME_REFRESH_FIELDS) {
143840
143840
  const value = presetUpdateArgs[field];
143841
- if (field === "max_output_tokens" && (typeof value === "number" || value === null)) {
143842
- updateArgs[field] = value;
143843
- } else if (field === "parallel_tool_calls" && typeof value === "boolean") {
143841
+ if (typeof value === "boolean") {
143844
143842
  updateArgs[field] = value;
143845
143843
  }
143846
143844
  }
143847
143845
  if (Object.keys(updateArgs).length === 0) {
143848
143846
  return { updateArgs, needsUpdate: false };
143849
143847
  }
143850
- const currentMaxTokens = agent2.llm_config?.max_tokens;
143851
- const wantMaxTokens = updateArgs.max_output_tokens;
143852
143848
  const currentParallel = agent2.model_settings?.parallel_tool_calls;
143853
143849
  const wantParallel = updateArgs.parallel_tool_calls;
143854
- const maxTokensMatch = wantMaxTokens === undefined || currentMaxTokens === wantMaxTokens;
143855
143850
  const parallelMatch = wantParallel === undefined || currentParallel === wantParallel;
143856
- return { updateArgs, needsUpdate: !(maxTokensMatch && parallelMatch) };
143851
+ return { updateArgs, needsUpdate: !parallelMatch };
143857
143852
  }
143858
143853
  function findModelByHandle(handle) {
143859
143854
  const pickPreferred = (candidates2) => candidates2.find((m2) => m2.isDefault) ?? candidates2.find((m2) => m2.isFeatured) ?? candidates2.find((m2) => m2.updateArgs?.reasoning_effort === "medium") ?? candidates2.find((m2) => m2.updateArgs?.reasoning_effort === "high") ?? candidates2[0] ?? null;
@@ -143922,10 +143917,7 @@ var init_model = __esm(() => {
143922
143917
  "medium",
143923
143918
  "high"
143924
143919
  ];
143925
- RESUME_REFRESH_FIELDS = [
143926
- "max_output_tokens",
143927
- "parallel_tool_calls"
143928
- ];
143920
+ RESUME_REFRESH_FIELDS = ["parallel_tool_calls"];
143929
143921
  });
143930
143922
 
143931
143923
  // src/utils/error.ts
@@ -144020,7 +144012,7 @@ function generateFrontmatter(data) {
144020
144012
  var fork_default = `---
144021
144013
  name: fork
144022
144014
  description: Fork of the parent agent with full context and tools. Recommended to run in background (run_in_background: true).
144023
- tools: Bash, TaskOutput, Edit, KillBash, LS, MultiEdit, Read, TodoWrite, Write
144015
+ tools: all
144024
144016
  model: inherit
144025
144017
  fork: true
144026
144018
  background: true
@@ -144035,7 +144027,7 @@ var init_fork = () => {};
144035
144027
  var general_purpose_default = `---
144036
144028
  name: general-purpose
144037
144029
  description: Full-capability agent for research, planning, and implementation
144038
- tools: Bash, TaskOutput, Edit, KillBash, LS, MultiEdit, Read, TodoWrite, Write
144030
+ tools: Bash, TaskCreate, TaskGet, TaskList, TaskOutput, TaskUpdate, Edit, KillBash, Read, Write
144039
144031
  model: inherit
144040
144032
  ---
144041
144033
 
@@ -144051,7 +144043,7 @@ You DO have access to the full conversation history before you were launched.
144051
144043
 
144052
144044
  ## Instructions
144053
144045
 
144054
- - You have access to all tools (Read, Write, Edit, Bash, TodoWrite, etc.) — use Bash with \`rg\` / \`find\` for searching
144046
+ - You have access to all tools (Read, Write, Edit, Bash, TaskCreate/TaskUpdate, etc.) — use Bash with \`rg\` / \`find\` for searching
144055
144047
  - Break down complex tasks into steps
144056
144048
  - Search the codebase to understand existing patterns
144057
144049
  - Follow existing code conventions and style
@@ -149439,6 +149431,7 @@ var BashOutput_default = `# BashOutput
149439
149431
  - If you are repeatedly calling this tool waiting for a recurring pattern to appear ("tell me every time an ERROR line appears"), stop polling and use the Monitor tool instead: each stdout line is an event — you keep working and notifications arrive in the chat
149440
149432
  - Shell IDs can be found using the /bg command
149441
149433
  - If the accumulated output exceeds 30,000 characters, it will be truncated before being returned to you
149434
+ - Once the shell finishes you already have its output file path — it was returned when the command started, and repeated in the \`<task-notification>\` you receive on completion. For the full transcript at that point, prefer \`Read\` on that path over calling this tool again; reserve \`BashOutput\` for a shell that's still running.
149442
149435
  `;
149443
149436
  var init_BashOutput = () => {};
149444
149437
 
@@ -150199,15 +150192,15 @@ Returns the full task record including the assigned \`taskId\`.
150199
150192
  var init_TaskCreate = () => {};
150200
150193
 
150201
150194
  // src/tools/descriptions/TaskGet.md
150202
- var TaskGet_default = '# TaskGet\n\nFetch a single task by its `taskId`.\n\nReturns the full task record, including `subject`, `description`, `status`, `owner`, dependency edges (`blocks`, `blockedBy`), and `metadata`.\n\n## Notes\n\n- Works on soft-deleted tasks (`status: "deleted"`) too — `TaskGet` returns the record even though `TaskList` hides it by default.\n- Errors if the task ID doesn\'t exist.\n\n## Example\n\n```\nTaskGet({ taskId: "task_3" })\n```\n';
150195
+ var TaskGet_default = '# TaskGet\n\nFetch a single task by its `taskId`.\n\nReturns the full task record, including `subject`, `description`, `status`, `owner`, dependency edges (`blocks`, `blockedBy`), and `metadata`.\n\n## Notes\n\n- Errors if the task ID doesn\'t exist or was deleted.\n\n## Example\n\n```\nTaskGet({ taskId: "task_3" })\n```\n';
150203
150196
  var init_TaskGet = () => {};
150204
150197
 
150205
150198
  // src/tools/descriptions/TaskList.md
150206
- var TaskList_default = '# TaskList\n\nList all tasks in the current session, in creation order.\n\nSoft-deleted tasks (`status: "deleted"`) are excluded from the output. Use `TaskGet` with a specific ID to retrieve a deleted task.\n\n## When to use\n\n- Check current progress without scrolling back through the transcript\n- Verify state before committing to a sequence of `TaskUpdate` calls\n- Confirm task IDs before wiring `addBlocks` / `addBlockedBy` dependencies\n\n## Returns\n\n```\n{ "tasks": [TaskRecord, ...] }\n```\n\nEach `TaskRecord` includes `taskId`, `subject`, `description`, `activeForm`, `status`, `owner`, `blocks`, `blockedBy`, `metadata`, `createdAt`, `updatedAt`.\n';
150199
+ var TaskList_default = '# TaskList\n\nList all tasks in the current session, in creation order.\n\nTasks removed with `status: "deleted"` are excluded from the output and cannot be retrieved.\n\n## When to use\n\n- Check current progress without scrolling back through the transcript\n- Verify state before committing to a sequence of `TaskUpdate` calls\n- Confirm task IDs before wiring `addBlocks` / `addBlockedBy` dependencies\n\n## Returns\n\n```\n{ "tasks": [TaskRecord, ...] }\n```\n\nEach `TaskRecord` includes `taskId`, `subject`, `description`, `activeForm`, `status`, `owner`, `blocks`, `blockedBy`, `metadata`, `createdAt`, `updatedAt`.\n';
150207
150200
  var init_TaskList = () => {};
150208
150201
 
150209
150202
  // src/tools/descriptions/TaskOutput.md
150210
- var TaskOutput_default = "# TaskOutput\n\n- Retrieves output from a running or completed task (background shell, monitor, agent, or remote session)\n- Required: `task_id` (the task to query), `block` (whether to wait for completion), `timeout` (max wait time in ms; capped at 600000)\n- Returns the task output along with status information\n- Use `block=true` to wait until the task finishes (or `timeout` elapses)\n- Use `block=false` for an immediate, non-blocking check of current status\n- Task IDs can be found using the /tasks command\n- Works with all task types: background shells, monitors, async agents, and remote sessions\n";
150203
+ var TaskOutput_default = "# TaskOutput\n\n- Retrieves output from a running or completed task (background shell, monitor, agent, or remote session)\n- Required: `task_id` (the task to query), `block` (whether to wait for completion), `timeout` (max wait time in ms; capped at 600000)\n- Returns the task output along with status information\n- Use `block=true` to wait until the task finishes (or `timeout` elapses)\n- Use `block=false` for an immediate, non-blocking check of current status\n- Task IDs can be found using the /tasks command\n- Works with all task types: background shells, monitors, async agents, and remote sessions\n- Once a task completes you already have its output file path — it was returned when the task started, and repeated in the `<task-notification>` you receive on completion. For the full transcript at that point, prefer `Read` on that path over calling this tool again; reserve `TaskOutput` for blocking/waiting on a task that hasn't finished yet or for a quick status check.\n";
150211
150204
  var init_TaskOutput = () => {};
150212
150205
 
150213
150206
  // src/tools/descriptions/TaskStop.md
@@ -150215,7 +150208,81 @@ var TaskStop_default = "# TaskStop\n\n- Stops a running background task or monit
150215
150208
  var init_TaskStop = () => {};
150216
150209
 
150217
150210
  // src/tools/descriptions/TaskUpdate.md
150218
- var TaskUpdate_default = "# TaskUpdate\n\nPartially update a single task. Only the fields you pass will change; everything else stays intact.\n\n## Status transitions\n\nUse the `status` field to move a task through its lifecycle:\n\n- `pending` — not started\n- `in_progress` — actively being worked on (keep only ONE task in this state at a time)\n- `completed` — finished\n- `deleted` — soft-delete; excluded from `TaskList` but still fetchable via `TaskGet`\n\nMark a task `completed` **only** when it's fully done — tests pass, implementation is complete, no unresolved errors. If blocked, leave it `in_progress` and create a new task for the blocker (then wire it up via `addBlockedBy`).\n\n## Editable fields\n\n- `subject`, `description`, `activeForm` — full replacements\n- `owner` — assign a string owner (free-form)\n- `addBlocks` — append task IDs that **this task blocks** (they can't start until this one finishes)\n- `addBlockedBy` — append task IDs that **block this task** (they must finish first)\n- `metadata` — merged into existing metadata (existing keys preserved; matching keys overwritten)\n\n## Best practices\n\n- Update status in real-time as you work — don't batch status changes at the end\n- Exactly ONE task should be `in_progress` at any given time\n- Only use `status: \"deleted\"` when a task is no longer relevant; prefer completion when possible\n- When adding dependencies, call `TaskList` first to verify the referenced IDs exist\n\n## Example\n\n```\nTaskUpdate({\n taskId: \"task_3\",\n status: \"in_progress\",\n owner: \"agent-abc123\"\n})\n\nTaskUpdate({\n taskId: \"task_3\",\n addBlockedBy: [\"task_1\", \"task_2\"]\n})\n\nTaskUpdate({\n taskId: \"task_3\",\n status: \"completed\"\n})\n```\n\nReturns the updated task record.\n";
150211
+ var TaskUpdate_default = `Use this tool to update a task in the task list.
150212
+
150213
+ ## When to Use This Tool
150214
+
150215
+ **Mark tasks as resolved:**
150216
+ - When you have completed the work described in a task
150217
+ - When a task is no longer needed or has been superseded
150218
+ - IMPORTANT: Always mark your assigned tasks as resolved when you finish them
150219
+ - After resolving, call TaskList to find your next task
150220
+
150221
+ - ONLY mark a task as completed when you have FULLY accomplished it
150222
+ - If you encounter errors, blockers, or cannot finish, keep the task as in_progress
150223
+ - When blocked, create a new task describing what needs to be resolved
150224
+ - Never mark a task as completed if:
150225
+ - Tests are failing
150226
+ - Implementation is partial
150227
+ - You encountered unresolved errors
150228
+ - You couldn't find necessary files or dependencies
150229
+
150230
+ **Delete tasks:**
150231
+ - When a task is no longer relevant or was created in error
150232
+ - Setting status to \`deleted\` permanently removes the task
150233
+
150234
+ **Update task details:**
150235
+ - When requirements change or become clearer
150236
+ - When establishing dependencies between tasks
150237
+
150238
+ ## Fields You Can Update
150239
+
150240
+ - **status**: The task status (see Status Workflow below)
150241
+ - **subject**: Change the task title (imperative form, e.g., "Run tests")
150242
+ - **description**: Change the task description
150243
+ - **activeForm**: Present continuous form shown in spinner when in_progress (e.g., "Running tests")
150244
+ - **owner**: Change the task owner (agent name)
150245
+ - **metadata**: Merge metadata keys into the task (set a key to null to delete it)
150246
+ - **addBlocks**: Mark tasks that cannot start until this one completes
150247
+ - **addBlockedBy**: Mark tasks that must complete before this one can start
150248
+
150249
+ ## Status Workflow
150250
+
150251
+ Status progresses: \`pending\` → \`in_progress\` → \`completed\`
150252
+
150253
+ Use \`deleted\` to permanently remove a task.
150254
+
150255
+ ## Staleness
150256
+
150257
+ Make sure to read a task's latest state using \`TaskGet\` before updating it.
150258
+
150259
+ ## Examples
150260
+
150261
+ Mark task as in progress when starting work:
150262
+ \`\`\`json
150263
+ {"taskId": "1", "status": "in_progress"}
150264
+ \`\`\`
150265
+
150266
+ Mark task as completed after finishing work:
150267
+ \`\`\`json
150268
+ {"taskId": "1", "status": "completed"}
150269
+ \`\`\`
150270
+
150271
+ Delete a task:
150272
+ \`\`\`json
150273
+ {"taskId": "1", "status": "deleted"}
150274
+ \`\`\`
150275
+
150276
+ Claim a task by setting owner:
150277
+ \`\`\`json
150278
+ {"taskId": "1", "owner": "my-name"}
150279
+ \`\`\`
150280
+
150281
+ Set up task dependencies:
150282
+ \`\`\`json
150283
+ {"taskId": "2", "addBlockedBy": ["1"]}
150284
+ \`\`\`
150285
+ `;
150219
150286
  var init_TaskUpdate = () => {};
150220
150287
 
150221
150288
  // src/tools/descriptions/TodoWrite.md
@@ -153181,6 +153248,7 @@ function createConversationRuntime(listener, agentId, conversationId) {
153181
153248
  currentToolsetPreference: "auto",
153182
153249
  currentLoadedTools: [],
153183
153250
  currentAvailableSkills: [],
153251
+ transientChannelRuntimeTools: false,
153184
153252
  pendingApprovalBatchByToolCallId: new Map,
153185
153253
  approvalMessageIdByToolCallId: new Map,
153186
153254
  pendingInterruptedResults: null,
@@ -164072,15 +164140,12 @@ function formatWithLineNumbers(content, offset, limit3, workingDirectory) {
164072
164140
  let linesWereTruncatedInLength = false;
164073
164141
  const formattedLines = selectedLines.map((line, index) => {
164074
164142
  const lineNumber = actualStartLine + index + 1;
164075
- const maxLineNumber = actualStartLine + selectedLines.length;
164076
- const padding = Math.max(1, maxLineNumber.toString().length);
164077
- const paddedNumber = lineNumber.toString().padStart(padding);
164078
164143
  if (line.length > LIMITS.READ_MAX_CHARS_PER_LINE) {
164079
164144
  linesWereTruncatedInLength = true;
164080
164145
  const truncated = line.slice(0, LIMITS.READ_MAX_CHARS_PER_LINE);
164081
- return `${paddedNumber}→${truncated}... [line truncated]`;
164146
+ return `${lineNumber} ${truncated}... [line truncated]`;
164082
164147
  }
164083
- return `${paddedNumber}→${line}`;
164148
+ return `${lineNumber} ${line}`;
164084
164149
  });
164085
164150
  let result = formattedLines.join(`
164086
164151
  `);
@@ -173847,6 +173912,92 @@ var init_context_budget = __esm(() => {
173847
173912
  REFLECTION_STARTUP_CONTEXT_CHAR_LIMIT = REFLECTION_STARTUP_CONTEXT_TOKEN_LIMIT * STARTUP_CONTEXT_ESTIMATED_CHARS_PER_TOKEN;
173848
173913
  });
173849
173914
 
173915
+ // src/mods/capabilities.ts
173916
+ function isModCapabilityId(value) {
173917
+ return MOD_CAPABILITY_ID_SET.has(value);
173918
+ }
173919
+ function resolveProcessModCapabilities(configuredCapabilities, env3 = process.env) {
173920
+ if (env3[LETTA_MOD_CAPABILITY_PROFILE_ENV] === PROVIDERS_ONLY_MOD_CAPABILITY_PROFILE) {
173921
+ return cloneModCapabilities(PROVIDERS_ONLY_MOD_CAPABILITIES);
173922
+ }
173923
+ return resolveModCapabilities(configuredCapabilities);
173924
+ }
173925
+ function cloneModCapabilities(capabilities) {
173926
+ return {
173927
+ tools: capabilities.tools,
173928
+ commands: capabilities.commands,
173929
+ events: {
173930
+ lifecycle: capabilities.events.lifecycle,
173931
+ tools: capabilities.events.tools,
173932
+ turns: capabilities.events.turns,
173933
+ compact: capabilities.events.compact,
173934
+ llm: capabilities.events.llm
173935
+ },
173936
+ permissions: capabilities.permissions,
173937
+ providers: capabilities.providers,
173938
+ ui: {
173939
+ panels: capabilities.ui.panels
173940
+ }
173941
+ };
173942
+ }
173943
+ function resolveModCapabilities(capabilities) {
173944
+ return cloneModCapabilities(capabilities ?? DEFAULT_MOD_CAPABILITIES);
173945
+ }
173946
+ var MOD_CAPABILITY_IDS, MOD_CAPABILITY_ID_SET, DEFAULT_MOD_CAPABILITIES, DISABLED_MOD_CAPABILITIES, PROVIDERS_ONLY_MOD_CAPABILITIES, LETTA_MOD_CAPABILITY_PROFILE_ENV = "LETTA_MOD_CAPABILITY_PROFILE", PROVIDERS_ONLY_MOD_CAPABILITY_PROFILE = "providers-only";
173947
+ var init_capabilities = __esm(() => {
173948
+ MOD_CAPABILITY_IDS = [
173949
+ "tools",
173950
+ "commands",
173951
+ "providers",
173952
+ "permissions",
173953
+ "events.lifecycle",
173954
+ "events.turns",
173955
+ "events.tools",
173956
+ "events.compact",
173957
+ "events.llm",
173958
+ "ui.panels"
173959
+ ];
173960
+ MOD_CAPABILITY_ID_SET = new Set(MOD_CAPABILITY_IDS);
173961
+ DEFAULT_MOD_CAPABILITIES = {
173962
+ tools: true,
173963
+ commands: true,
173964
+ events: {
173965
+ lifecycle: true,
173966
+ tools: true,
173967
+ turns: true,
173968
+ compact: true,
173969
+ llm: true
173970
+ },
173971
+ permissions: true,
173972
+ providers: true,
173973
+ ui: {
173974
+ panels: true
173975
+ }
173976
+ };
173977
+ DISABLED_MOD_CAPABILITIES = {
173978
+ tools: false,
173979
+ commands: false,
173980
+ events: {
173981
+ lifecycle: false,
173982
+ tools: false,
173983
+ turns: false,
173984
+ compact: false,
173985
+ llm: false
173986
+ },
173987
+ permissions: false,
173988
+ providers: false,
173989
+ ui: {
173990
+ panels: false
173991
+ }
173992
+ };
173993
+ PROVIDERS_ONLY_MOD_CAPABILITIES = {
173994
+ ...DISABLED_MOD_CAPABILITIES,
173995
+ events: { ...DISABLED_MOD_CAPABILITIES.events },
173996
+ providers: true,
173997
+ ui: { ...DISABLED_MOD_CAPABILITIES.ui }
173998
+ };
173999
+ });
174000
+
173850
174001
  // src/agent/subagents/subagent-launcher.ts
173851
174002
  function resolveSubagentWorkingDirectory(env3 = process.env, fallbackCwd = getCurrentWorkingDirectory(), options3 = {}) {
173852
174003
  if (options3.subagentType === "reflection" && options3.launchProfile === "memory-subagent" && options3.memoryScope) {
@@ -173918,7 +174069,9 @@ function composeSubagentChildEnv(options3) {
173918
174069
  ...inheritedApiKey && { LETTA_API_KEY: inheritedApiKey },
173919
174070
  ...inheritedBaseUrl && { LETTA_BASE_URL: inheritedBaseUrl },
173920
174071
  LETTA_CODE_AGENT_ROLE: "subagent",
173921
- ...subagentType === "reflection" && { [LETTA_DISABLE_MODS_ENV]: "1" },
174072
+ ...subagentType === "reflection" && {
174073
+ [LETTA_MOD_CAPABILITY_PROFILE_ENV]: PROVIDERS_ONLY_MOD_CAPABILITY_PROFILE
174074
+ },
173922
174075
  ...parentAgentId && { LETTA_PARENT_AGENT_ID: parentAgentId },
173923
174076
  ...transcriptPath && { TRANSCRIPT_PATH: transcriptPath }
173924
174077
  };
@@ -173951,6 +174104,7 @@ function resolveSubagentInheritedPrimaryRoot(options3) {
173951
174104
  var init_subagent_launcher = __esm(() => {
173952
174105
  init_backend2();
173953
174106
  init_paths();
174107
+ init_capabilities();
173954
174108
  init_runtime_context();
173955
174109
  init_shell_env();
173956
174110
  });
@@ -174630,11 +174784,11 @@ ${SYSTEM_REMINDER_CLOSE}
174630
174784
  `;
174631
174785
  }
174632
174786
  return `${SYSTEM_REMINDER_OPEN}
174633
- You have been forked from the primary conversational thread to run as an independent subagent. The fork only exists so you can see the parent agent's conversation trajectory in-context as reference — you are NOT the primary agent and do not share its full toolset.
174787
+ You have been forked from the primary conversational thread to run as an independent subagent. The fork only exists so you can see the parent agent's conversation trajectory in-context as reference — you are NOT the primary agent.
174634
174788
 
174635
174789
  **Your sole task is the one described in the user message below. Ignore any existing ongoing tasks from the inherited trajectory.** Do not attempt to continue, finish, or act on anything the primary agent was in the middle of doing.
174636
174790
 
174637
- You have a scoped toolset that may differ from the primary agent's. Stay within it; don't assume you have the primary's full tool access.
174791
+ You inherit the primary agent's toolset.
174638
174792
 
174639
174793
  You CANNOT ask questions mid-execution — all instructions are provided upfront.
174640
174794
  Your final message will be returned to the caller.
@@ -174744,7 +174898,8 @@ __export(exports_task, {
174744
174898
  waitForBackgroundSubagentConversationId: () => waitForBackgroundSubagentConversationId,
174745
174899
  waitForBackgroundSubagentAgentId: () => waitForBackgroundSubagentAgentId,
174746
174900
  task: () => task,
174747
- spawnBackgroundSubagentTask: () => spawnBackgroundSubagentTask
174901
+ spawnBackgroundSubagentTask: () => spawnBackgroundSubagentTask,
174902
+ inheritForkToolset: () => inheritForkToolset
174748
174903
  });
174749
174904
  async function resolveCompletionSummary(defaultSummary, completionSummary, result) {
174750
174905
  if (!completionSummary) {
@@ -175024,6 +175179,13 @@ Error: ${errorMessage}`,
175024
175179
  });
175025
175180
  return { taskId, outputFile, subagentId };
175026
175181
  }
175182
+ async function inheritForkToolset(agentId, parentConversationId, forkConversationId) {
175183
+ const parentToolset = settingsManager.getToolsetPreference(agentId, parentConversationId);
175184
+ if (parentToolset === "auto")
175185
+ return;
175186
+ settingsManager.setToolsetPreference(agentId, parentToolset, forkConversationId);
175187
+ await settingsManager.flush();
175188
+ }
175027
175189
  async function task(args) {
175028
175190
  const { command = "run", model, toolCallId, signal } = args;
175029
175191
  if (command === "refresh") {
@@ -175074,6 +175236,7 @@ async function task(args) {
175074
175236
  ...parentConvId === "default" ? { agentId: parentAgentId } : {},
175075
175237
  hidden: true
175076
175238
  });
175239
+ await inheritForkToolset(parentAgentId, parentConvId, forkedConv.id);
175077
175240
  effectiveAgentId = parentAgentId;
175078
175241
  effectiveConversationId = forkedConv.id;
175079
175242
  } catch (error54) {
@@ -175172,6 +175335,7 @@ var init_task = __esm(() => {
175172
175335
  init_backend2();
175173
175336
  init_hooks2();
175174
175337
  init_runtime_context();
175338
+ init_settings_manager();
175175
175339
  init_message_queue_bridge();
175176
175340
  init_task_notifications();
175177
175341
  init_process_manager();
@@ -175184,15 +175348,7 @@ function nextTaskId() {
175184
175348
  return `task_${taskIdCounter2++}`;
175185
175349
  }
175186
175350
  function cloneMetadata(meta3) {
175187
- if (!meta3)
175188
- return {};
175189
- const out = {};
175190
- for (const [k, v] of Object.entries(meta3)) {
175191
- if (typeof k === "string" && typeof v === "string") {
175192
- out[k] = v;
175193
- }
175194
- }
175195
- return out;
175351
+ return meta3 ? { ...meta3 } : {};
175196
175352
  }
175197
175353
  function dedupe(values2) {
175198
175354
  return Array.from(new Set(values2));
@@ -175219,14 +175375,12 @@ function getTask(taskId) {
175219
175375
  const t2 = tasks.get(taskId);
175220
175376
  return t2 ? { ...t2 } : undefined;
175221
175377
  }
175222
- function listTasks(options3 = {}) {
175378
+ function listTasks() {
175223
175379
  const out = [];
175224
175380
  for (const id2 of insertionOrder) {
175225
175381
  const t2 = tasks.get(id2);
175226
175382
  if (!t2)
175227
175383
  continue;
175228
- if (!options3.includeDeleted && t2.status === "deleted")
175229
- continue;
175230
175384
  out.push({ ...t2 });
175231
175385
  }
175232
175386
  return out;
@@ -175253,13 +175407,23 @@ function updateTask(input) {
175253
175407
  existing.blockedBy = dedupe([...existing.blockedBy, ...input.addBlockedBy]);
175254
175408
  }
175255
175409
  if (input.metadata) {
175256
- existing.metadata = {
175257
- ...existing.metadata,
175258
- ...cloneMetadata(input.metadata)
175259
- };
175410
+ for (const [key, value] of Object.entries(input.metadata)) {
175411
+ if (value === null) {
175412
+ delete existing.metadata[key];
175413
+ } else {
175414
+ existing.metadata[key] = value;
175415
+ }
175416
+ }
175260
175417
  }
175261
175418
  existing.updatedAt = Date.now();
175262
- return { ...existing };
175419
+ const updated = { ...existing };
175420
+ if (existing.status === "deleted") {
175421
+ tasks.delete(input.taskId);
175422
+ const orderIndex = insertionOrder.indexOf(input.taskId);
175423
+ if (orderIndex !== -1)
175424
+ insertionOrder.splice(orderIndex, 1);
175425
+ }
175426
+ return updated;
175263
175427
  }
175264
175428
  var tasks, insertionOrder, taskIdCounter2 = 1, TaskNotFoundError;
175265
175429
  var init_store = __esm(() => {
@@ -175396,11 +175560,6 @@ async function task_update(args) {
175396
175560
  if (typeof args.metadata !== "object" || args.metadata === null || Array.isArray(args.metadata)) {
175397
175561
  throw new Error("TaskUpdate: 'metadata' must be an object");
175398
175562
  }
175399
- for (const [k, v] of Object.entries(args.metadata)) {
175400
- if (typeof v !== "string") {
175401
- throw new Error(`TaskUpdate: metadata['${k}'] must be a string, received ${typeof v}`);
175402
- }
175403
- }
175404
175563
  }
175405
175564
  const addBlocks = validateStringArray(args.addBlocks, "addBlocks");
175406
175565
  const addBlockedBy = validateStringArray(args.addBlockedBy, "addBlockedBy");
@@ -176829,60 +176988,55 @@ var init_TaskStop2 = __esm(() => {
176829
176988
  var TaskUpdate_default2;
176830
176989
  var init_TaskUpdate2 = __esm(() => {
176831
176990
  TaskUpdate_default2 = {
176832
- type: "object",
176991
+ $schema: "https://json-schema.org/draft/2020-12/schema",
176992
+ additionalProperties: false,
176833
176993
  properties: {
176834
- taskId: {
176835
- type: "string",
176836
- description: 'The ID of the task to update (e.g. "task_1").'
176994
+ activeForm: {
176995
+ description: 'Present continuous form shown in spinner when in_progress (e.g. "Running tests")',
176996
+ type: "string"
176837
176997
  },
176838
- status: {
176839
- anyOf: [
176840
- {
176841
- type: "string",
176842
- enum: ["pending", "in_progress", "completed"]
176843
- },
176844
- {
176845
- type: "string",
176846
- const: "deleted"
176847
- }
176848
- ],
176849
- description: "New status. Use 'deleted' to soft-delete the task (it will be excluded from TaskList but remains fetchable via TaskGet)."
176998
+ addBlockedBy: {
176999
+ description: "Task IDs that block this task",
177000
+ items: { type: "string" },
177001
+ type: "array"
176850
177002
  },
176851
- subject: {
176852
- type: "string",
176853
- description: "Replacement subject."
177003
+ addBlocks: {
177004
+ description: "Task IDs that this task blocks",
177005
+ items: { type: "string" },
177006
+ type: "array"
176854
177007
  },
176855
177008
  description: {
176856
- type: "string",
176857
- description: "Replacement description."
177009
+ description: "New description for the task",
177010
+ type: "string"
176858
177011
  },
176859
- activeForm: {
176860
- type: "string",
176861
- description: "Replacement active form."
177012
+ metadata: {
177013
+ additionalProperties: {},
177014
+ description: "Metadata keys to merge into the task. Set a key to null to delete it.",
177015
+ propertyNames: { type: "string" },
177016
+ type: "object"
176862
177017
  },
176863
177018
  owner: {
176864
- type: "string",
176865
- description: "Assign an owner (free-form string, e.g. agent id or human name)."
177019
+ description: "New owner for the task",
177020
+ type: "string"
176866
177021
  },
176867
- addBlocks: {
176868
- type: "array",
176869
- items: { type: "string" },
176870
- description: "Task IDs to append to this task's 'blocks' list (tasks that cannot start until this one finishes)."
177022
+ status: {
177023
+ anyOf: [
177024
+ { enum: ["pending", "in_progress", "completed"], type: "string" },
177025
+ { const: "deleted", type: "string" }
177026
+ ],
177027
+ description: "New status for the task"
176871
177028
  },
176872
- addBlockedBy: {
176873
- type: "array",
176874
- items: { type: "string" },
176875
- description: "Task IDs to append to this task's 'blockedBy' list (tasks that must finish before this one can start)."
177029
+ subject: {
177030
+ description: "New subject for the task",
177031
+ type: "string"
176876
177032
  },
176877
- metadata: {
176878
- type: "object",
176879
- description: "Metadata keys to merge into the existing metadata bag (existing keys are preserved; matching keys are overwritten).",
176880
- additionalProperties: { type: "string" }
177033
+ taskId: {
177034
+ description: "The ID of the task to update",
177035
+ type: "string"
176881
177036
  }
176882
177037
  },
176883
177038
  required: ["taskId"],
176884
- additionalProperties: false,
176885
- $schema: "http://json-schema.org/draft-07/schema#"
177039
+ type: "object"
176886
177040
  };
176887
177041
  });
176888
177042
 
@@ -231516,6 +231670,52 @@ var init_engine_javascript = __esm(() => {
231516
231670
  });
231517
231671
 
231518
231672
  // src/cli/components/SyntaxHighlightedCommand.tsx
231673
+ function getShikiHighlighter() {
231674
+ if (shikiHighlighter === null) {
231675
+ shikiHighlighter = createHighlighterCoreSync({
231676
+ themes: [catppuccin_mocha_default, catppuccin_latte_default],
231677
+ langs: [
231678
+ shellscript_default,
231679
+ c_default,
231680
+ cpp_default,
231681
+ csharp_default,
231682
+ css_default,
231683
+ diff_default,
231684
+ docker_default,
231685
+ go_default,
231686
+ graphql_default,
231687
+ html_default,
231688
+ ini_default,
231689
+ java_default,
231690
+ javascript_default,
231691
+ json_default,
231692
+ kotlin_default,
231693
+ less_default,
231694
+ lua_default,
231695
+ make_default,
231696
+ markdown_default,
231697
+ perl_default,
231698
+ php_default,
231699
+ python_default,
231700
+ r_default,
231701
+ ruby_default,
231702
+ rust_default,
231703
+ scala_default,
231704
+ scss_default,
231705
+ sql_default,
231706
+ swift_default,
231707
+ toml_default,
231708
+ tsx_default,
231709
+ typescript_default,
231710
+ wasm_default,
231711
+ xml_default,
231712
+ yaml_default
231713
+ ],
231714
+ engine: createJavaScriptRegexEngine()
231715
+ });
231716
+ }
231717
+ return shikiHighlighter;
231718
+ }
231519
231719
  function clipStyledSpans(spans, maxColumns) {
231520
231720
  if (maxColumns <= 0) {
231521
231721
  return { spans: [], clipped: spans.length > 0 };
@@ -231594,7 +231794,7 @@ function highlightFullBash(command) {
231594
231794
  }
231595
231795
  function highlightCode(code2, language) {
231596
231796
  try {
231597
- const result = shikiHighlighter.codeToTokens(code2, {
231797
+ const result = getShikiHighlighter().codeToTokens(code2, {
231598
231798
  lang: language,
231599
231799
  theme: colors.shellSyntax === colors.shellSyntaxLight ? "catppuccin-latte" : "catppuccin-mocha"
231600
231800
  });
@@ -231606,7 +231806,7 @@ function highlightCode(code2, language) {
231606
231806
  return;
231607
231807
  }
231608
231808
  }
231609
- var import_react23, jsx_dev_runtime4, shikiHighlighter, BASH_LANGUAGE = "bash", FIRST_LINE_PROMPT = "$", PROMPT_COLUMN_WIDTH = 2, EXT_TO_LANG, HEREDOC_RE, REDIRECT_FILE_RE, SyntaxHighlightedCommand;
231809
+ var import_react23, jsx_dev_runtime4, shikiHighlighter = null, BASH_LANGUAGE = "bash", FIRST_LINE_PROMPT = "$", PROMPT_COLUMN_WIDTH = 2, EXT_TO_LANG, HEREDOC_RE, REDIRECT_FILE_RE, SyntaxHighlightedCommand;
231610
231810
  var init_SyntaxHighlightedCommand = __esm(async () => {
231611
231811
  init_bash2();
231612
231812
  init_c();
@@ -231654,47 +231854,6 @@ var init_SyntaxHighlightedCommand = __esm(async () => {
231654
231854
  ]);
231655
231855
  import_react23 = __toESM(require_react(), 1);
231656
231856
  jsx_dev_runtime4 = __toESM(require_jsx_dev_runtime(), 1);
231657
- shikiHighlighter = createHighlighterCoreSync({
231658
- themes: [catppuccin_mocha_default, catppuccin_latte_default],
231659
- langs: [
231660
- shellscript_default,
231661
- c_default,
231662
- cpp_default,
231663
- csharp_default,
231664
- css_default,
231665
- diff_default,
231666
- docker_default,
231667
- go_default,
231668
- graphql_default,
231669
- html_default,
231670
- ini_default,
231671
- java_default,
231672
- javascript_default,
231673
- json_default,
231674
- kotlin_default,
231675
- less_default,
231676
- lua_default,
231677
- make_default,
231678
- markdown_default,
231679
- perl_default,
231680
- php_default,
231681
- python_default,
231682
- r_default,
231683
- ruby_default,
231684
- rust_default,
231685
- scala_default,
231686
- scss_default,
231687
- sql_default,
231688
- swift_default,
231689
- toml_default,
231690
- tsx_default,
231691
- typescript_default,
231692
- wasm_default,
231693
- xml_default,
231694
- yaml_default
231695
- ],
231696
- engine: createJavaScriptRegexEngine()
231697
- });
231698
231857
  EXT_TO_LANG = {
231699
231858
  ts: "typescript",
231700
231859
  tsx: "typescript",
@@ -266212,7 +266371,7 @@ function addTask(input) {
266212
266371
  return withLock(() => {
266213
266372
  const data = readCronFile();
266214
266373
  const agentId = input.agent_id;
266215
- const conversationId = input.conversation_id ?? "default";
266374
+ const conversationId = input.conversation_id ?? "new";
266216
266375
  const activeCount = data.tasks.filter((t2) => t2.agent_id === agentId && t2.status === "active").length;
266217
266376
  if (activeCount >= MAX_ACTIVE_TASKS_PER_AGENT) {
266218
266377
  throw new Error(`Agent ${agentId} has ${activeCount} active tasks (max ${MAX_ACTIVE_TASKS_PER_AGENT}). Delete some before adding more.`);
@@ -267771,6 +267930,7 @@ var init_cron = __esm(async () => {
267771
267930
  // src/backend/api/environments.ts
267772
267931
  var exports_environments2 = {};
267773
267932
  __export(exports_environments2, {
267933
+ teleportToEnvironment: () => teleportToEnvironment,
267774
267934
  sendEnvironmentMessage: () => sendEnvironmentMessage,
267775
267935
  resolveEnvironmentConnectionId: () => resolveEnvironmentConnectionId,
267776
267936
  resolveAgentSandboxConnectionId: () => resolveAgentSandboxConnectionId,
@@ -267780,6 +267940,7 @@ __export(exports_environments2, {
267780
267940
  describeEnvironment: () => describeEnvironment,
267781
267941
  createAgentSandbox: () => createAgentSandbox
267782
267942
  });
267943
+ import { randomUUID as randomUUID25 } from "node:crypto";
267783
267944
  async function listEnvironments(options3 = {}) {
267784
267945
  return apiRequest("GET", "/v1/environments", undefined, {
267785
267946
  query: {
@@ -267861,6 +268022,12 @@ async function resolveAgentSandboxConnectionId(agentId, options3 = {}) {
267861
268022
  }
267862
268023
  throw new Error(`Timed out waiting for cloud sandbox ${sandbox.connectionName} to register${lastError instanceof Error ? `: ${lastError.message}` : ""}`);
267863
268024
  }
268025
+ async function teleportToEnvironment(agentId, conversationId, targetConnectionId, request = apiRequest) {
268026
+ return request("POST", `/v1/environments/runtimes/${encodeURIComponent(agentId)}/${encodeURIComponent(conversationId)}/teleport`, {
268027
+ targetConnectionId,
268028
+ idempotencyKey: randomUUID25()
268029
+ });
268030
+ }
267864
268031
  var init_environments2 = __esm(() => {
267865
268032
  init_request();
267866
268033
  });
@@ -267984,6 +268151,27 @@ var init_cron_runner = __esm(() => {
267984
268151
  init_environments2();
267985
268152
  });
267986
268153
 
268154
+ // src/cli/subcommands/cron-scope.ts
268155
+ function resolveCronAgentId(fromArgs) {
268156
+ return fromArgs || process.env.LETTA_AGENT_ID || "";
268157
+ }
268158
+ function resolveConversationAlias(fromArgs) {
268159
+ if (fromArgs !== "self")
268160
+ return fromArgs;
268161
+ const current = process.env.LETTA_CONVERSATION_ID?.trim();
268162
+ if (current)
268163
+ return current;
268164
+ console.error("Error: --conversation self requires an active conversation (LETTA_CONVERSATION_ID is not set).");
268165
+ return null;
268166
+ }
268167
+ function resolveCronAddConversationTarget(fromArgs) {
268168
+ const resolved = resolveConversationAlias(fromArgs);
268169
+ return resolved === undefined ? "new" : resolved;
268170
+ }
268171
+ function resolveCronConversationFilter(fromArgs) {
268172
+ return resolveConversationAlias(fromArgs);
268173
+ }
268174
+
267987
268175
  // src/cli/subcommands/cron-task-ref.ts
267988
268176
  async function ensureSettingsForCloud() {
267989
268177
  const { settingsManager: settingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), exports_settings_manager));
@@ -268057,7 +268245,9 @@ Add options:
268057
268245
  --once Fire once (with --at); default for --at
268058
268246
  --cron <expr> Raw 5-field cron expression
268059
268247
  --agent <id> Agent ID (defaults to LETTA_AGENT_ID)
268060
- --conversation <id> Conversation ID (defaults to LETTA_CONVERSATION_ID or "default")
268248
+ --conversation <id> Conversation target (omit or "new" for a fresh
268249
+ conversation per fire; "self" for the current
268250
+ conversation; "default" for the agent default)
268061
268251
  --runner <runner> Where the schedule lives and fires (normally omit:
268062
268252
  the default keeps the schedule running where it was
268063
268253
  created):
@@ -268097,12 +268287,6 @@ function parseCronArgs(argv) {
268097
268287
  allowPositionals: true
268098
268288
  });
268099
268289
  }
268100
- function getAgentId3(fromArgs) {
268101
- return fromArgs || process.env.LETTA_AGENT_ID || "";
268102
- }
268103
- function getConversationId3(fromArgs) {
268104
- return fromArgs || process.env.LETTA_CONVERSATION_ID || "default";
268105
- }
268106
268290
  async function probeCloudScheduleSupport(agentId) {
268107
268291
  try {
268108
268292
  await listCloudSchedules(agentId, { limit: 1 });
@@ -268183,12 +268367,14 @@ async function handleAdd(values2) {
268183
268367
  console.error("Error: --prompt is required.");
268184
268368
  return 1;
268185
268369
  }
268186
- const agentId = getAgentId3(values2.agent);
268370
+ const agentId = resolveCronAgentId(values2.agent);
268187
268371
  if (!agentId) {
268188
268372
  console.error("Error: --agent or LETTA_AGENT_ID required.");
268189
268373
  return 1;
268190
268374
  }
268191
- const conversationId = getConversationId3(values2.conversation);
268375
+ const conversationId = resolveCronAddConversationTarget(values2.conversation);
268376
+ if (conversationId === null)
268377
+ return 1;
268192
268378
  const everyValue = values2.every;
268193
268379
  const atValue = values2.at;
268194
268380
  const cronValue = values2.cron;
@@ -268378,7 +268564,9 @@ async function handleList(values2) {
268378
268564
  return 1;
268379
268565
  }
268380
268566
  const agentId = values2.agent || process.env.LETTA_AGENT_ID || undefined;
268381
- const conversationId = values2.conversation || undefined;
268567
+ const conversationId = resolveCronConversationFilter(values2.conversation);
268568
+ if (conversationId === null)
268569
+ return 1;
268382
268570
  const includeLocal = values2.runner !== "cloud";
268383
268571
  const includeCloud = values2.runner !== "local";
268384
268572
  const output = [];
@@ -268434,7 +268622,7 @@ async function handleGet(values2, positionals) {
268434
268622
  console.error("Error: task ID or name required. Usage: letta cron get <id|name>");
268435
268623
  return 1;
268436
268624
  }
268437
- const agentId = getAgentId3(values2.agent);
268625
+ const agentId = resolveCronAgentId(values2.agent);
268438
268626
  if (values2.runner !== "cloud") {
268439
268627
  const task2 = getTask2(taskRef);
268440
268628
  if (task2) {
@@ -268516,7 +268704,7 @@ async function handleRuns(values2) {
268516
268704
  console.error(`Error: task ${id2} not found.`);
268517
268705
  return 1;
268518
268706
  }
268519
- const agentId = getAgentId3(values2.agent);
268707
+ const agentId = resolveCronAgentId(values2.agent);
268520
268708
  if (!agentId) {
268521
268709
  console.error(`Error: task ${id2} not found locally, and --agent or LETTA_AGENT_ID is required to look up Cloud schedule runs.`);
268522
268710
  return 1;
@@ -268555,7 +268743,7 @@ async function handleDelete(values2, positionals) {
268555
268743
  return 0;
268556
268744
  }
268557
268745
  }
268558
- const agentId = getAgentId3(values2.agent);
268746
+ const agentId = resolveCronAgentId(values2.agent);
268559
268747
  if (values2.runner !== "local") {
268560
268748
  if (!agentId) {
268561
268749
  console.error(`Error: task ${taskRef} not found locally, and --agent or LETTA_AGENT_ID is required to delete Cloud schedules.`);
@@ -268604,7 +268792,7 @@ async function handleDelete(values2, positionals) {
268604
268792
  return 1;
268605
268793
  }
268606
268794
  async function handleDeleteAll(values2) {
268607
- const agentId = getAgentId3(values2.agent);
268795
+ const agentId = resolveCronAgentId(values2.agent);
268608
268796
  if (!agentId) {
268609
268797
  console.error("Error: --agent or LETTA_AGENT_ID required with --all.");
268610
268798
  return 1;
@@ -273068,7 +273256,7 @@ var init_dream_targets = __esm(() => {
273068
273256
 
273069
273257
  // src/agent/memory-worktree.ts
273070
273258
  import { execFile as execFileCb4 } from "node:child_process";
273071
- import { randomUUID as randomUUID25 } from "node:crypto";
273259
+ import { randomUUID as randomUUID26 } from "node:crypto";
273072
273260
  import { existsSync as existsSync42 } from "node:fs";
273073
273261
  import { mkdir as mkdir13 } from "node:fs/promises";
273074
273262
  import { dirname as dirname26, isAbsolute as isAbsolute25, join as join60, resolve as resolve31 } from "node:path";
@@ -273112,7 +273300,7 @@ function normalizeGitPath(path32, cwd2) {
273112
273300
  }
273113
273301
  function buildReflectionWorktreeId(now = new Date) {
273114
273302
  const timestamp = now.toISOString().replace(/[^0-9]/g, "").slice(0, 14);
273115
- return `${timestamp}-${randomUUID25().slice(0, 8)}`;
273303
+ return `${timestamp}-${randomUUID26().slice(0, 8)}`;
273116
273304
  }
273117
273305
  function summarizeReflectionCommitSubject(subject) {
273118
273306
  const summary = subject.trim().replace(/^[a-z]+(?:\([^)]+\))?!?:\s*/i, "").trim();
@@ -273397,6 +273585,23 @@ var init_memory_worktree = __esm(() => {
273397
273585
  };
273398
273586
  });
273399
273587
 
273588
+ // src/backend/api/reflection.ts
273589
+ function agentPath(agentId) {
273590
+ return `/v1/agents/${encodeURIComponent(agentId)}`;
273591
+ }
273592
+ async function retrieveCloudReflectionConfig(agentId, request = apiRequest) {
273593
+ return request("GET", `${agentPath(agentId)}/reflection`);
273594
+ }
273595
+ async function updateCloudReflectionConfig(agentId, input, request = apiRequest) {
273596
+ await request("PATCH", `${agentPath(agentId)}/reflection`, { ...input });
273597
+ }
273598
+ async function updateCloudReflectionConversationProgress(agentId, conversationId, input, request = apiRequest) {
273599
+ await request("PATCH", `${agentPath(agentId)}/conversations/${encodeURIComponent(conversationId)}/reflection`, { ...input });
273600
+ }
273601
+ var init_reflection2 = __esm(() => {
273602
+ init_request();
273603
+ });
273604
+
273400
273605
  // src/cli/helpers/memory-subagent-completion.ts
273401
273606
  async function handleMemorySubagentCompletion(args, deps) {
273402
273607
  const { agentId, conversationId, subagentType, success: success2, error: error54 } = args;
@@ -273456,20 +273661,6 @@ var init_memory_subagent_completion = __esm(() => {
273456
273661
  init_system_prompt_warning();
273457
273662
  });
273458
273663
 
273459
- // src/backend/api/reflection.ts
273460
- function agentPath(agentId) {
273461
- return `/v1/agents/${encodeURIComponent(agentId)}`;
273462
- }
273463
- async function updateCloudReflectionConfig(agentId, input, request = apiRequest) {
273464
- await request("PATCH", `${agentPath(agentId)}/reflection`, { ...input });
273465
- }
273466
- async function updateCloudReflectionConversationProgress(agentId, conversationId, input, request = apiRequest) {
273467
- await request("PATCH", `${agentPath(agentId)}/conversations/${encodeURIComponent(conversationId)}/reflection`, { ...input });
273468
- }
273469
- var init_reflection2 = __esm(() => {
273470
- init_request();
273471
- });
273472
-
273473
273664
  // src/cli/helpers/reflection-completion.ts
273474
273665
  function errorMessage(error54) {
273475
273666
  return error54 instanceof Error ? error54.message : String(error54);
@@ -273587,7 +273778,7 @@ ${instructions}
273587
273778
  }
273588
273779
 
273589
273780
  // src/telemetry/reflection-threshold-feedback.ts
273590
- import { randomUUID as randomUUID26 } from "node:crypto";
273781
+ import { randomUUID as randomUUID27 } from "node:crypto";
273591
273782
  async function resolveFeedbackApiKey() {
273592
273783
  const settings3 = await settingsManager.getSettingsWithSecureTokens();
273593
273784
  return process.env.LETTA_API_KEY || settings3.env?.LETTA_API_KEY;
@@ -273599,7 +273790,7 @@ function getFeedbackDeviceId() {
273599
273790
  return deviceId;
273600
273791
  }
273601
273792
  } catch {}
273602
- return randomUUID26();
273793
+ return randomUUID27();
273603
273794
  }
273604
273795
  function getAlertDeviceType() {
273605
273796
  switch (process.platform) {
@@ -273721,6 +273912,8 @@ function getReflectionFinalizationContext(agentId) {
273721
273912
  }
273722
273913
  function getReflectionLaunchSkippedMessage(reason, surface = "cli") {
273723
273914
  switch (reason) {
273915
+ case "cutover":
273916
+ return "Reflection is managed by Letta Cloud for this agent.";
273724
273917
  case "already_active":
273725
273918
  return surface === "listener" ? "A reflection agent is already running for this conversation." : "A reflection agent is already running in the background.";
273726
273919
  case "memfs_disabled":
@@ -274008,7 +274201,18 @@ async function finalizeReflectionMemoryWorktreeLaunch(params) {
274008
274201
  integrationConversationId: integrationRun?.conversationId
274009
274202
  };
274010
274203
  }
274011
- async function launchReflectionSubagent(options3) {
274204
+ async function isReflectionCutover(agentId) {
274205
+ try {
274206
+ if (!await isLettaCloud())
274207
+ return false;
274208
+ const config3 = await retrieveCloudReflectionConfig(agentId);
274209
+ return config3.cutover === true;
274210
+ } catch (error54) {
274211
+ debugWarn("memory", `Failed to check Cloud reflection cutover: ${error54 instanceof Error ? error54.message : String(error54)}`);
274212
+ return false;
274213
+ }
274214
+ }
274215
+ async function launchReflectionSubagent(options3, dependencies4 = {}) {
274012
274216
  const {
274013
274217
  agentId,
274014
274218
  conversationId,
@@ -274023,6 +274227,10 @@ async function launchReflectionSubagent(options3) {
274023
274227
  if (!memfsEnabled) {
274024
274228
  return { launched: false, reason: "memfs_disabled" };
274025
274229
  }
274230
+ if (await (dependencies4.isCutover ?? isReflectionCutover)(agentId)) {
274231
+ debugLog("memory", `Skipping reflection launch (${triggerSource}) because server-side reflection owns this agent`);
274232
+ return { launched: false, reason: "cutover" };
274233
+ }
274026
274234
  if (!tryReserveReflectionLaunch(agentId)) {
274027
274235
  debugLog("memory", `Skipping reflection launch (${triggerSource}) because one is already active`);
274028
274236
  if (reservedReflectionAgentIds.has(agentId)) {
@@ -274160,6 +274368,7 @@ var init_reflection_launcher = __esm(() => {
274160
274368
  init_memory_worktree();
274161
274369
  init_subagent_state();
274162
274370
  init_backend2();
274371
+ init_reflection2();
274163
274372
  init_memory_reminder();
274164
274373
  init_memory_subagent_completion();
274165
274374
  init_reflection_completion();
@@ -276828,7 +277037,7 @@ var init_auth = __esm(() => {
276828
277037
  });
276829
277038
 
276830
277039
  // src/websocket/listener/manual-instance-lock.ts
276831
- import { createHash as createHash7, randomUUID as randomUUID27 } from "node:crypto";
277040
+ import { createHash as createHash7, randomUUID as randomUUID28 } from "node:crypto";
276832
277041
  import { link as link3, mkdir as mkdir14, readFile as readFile20, rm as rm9, unlink as unlink5, writeFile as writeFile15 } from "node:fs/promises";
276833
277042
  import { homedir as homedir36 } from "node:os";
276834
277043
  import path32 from "node:path";
@@ -276879,7 +277088,7 @@ function parseLockRecord(raw2, expectedScopeHash) {
276879
277088
  }
276880
277089
  }
276881
277090
  async function publishInitializedFile(targetPath, contents) {
276882
- const candidatePath = path32.join(path32.dirname(targetPath), `.manual-listener-lock-${randomUUID27()}.candidate`);
277091
+ const candidatePath = path32.join(path32.dirname(targetPath), `.manual-listener-lock-${randomUUID28()}.candidate`);
276883
277092
  let publicationError;
276884
277093
  try {
276885
277094
  await writeFile15(candidatePath, contents, { flag: "wx" });
@@ -276956,7 +277165,7 @@ async function acquireManualListenerLock(scope, overrides = {}) {
276956
277165
  const deps = {
276957
277166
  lockRoot: getDefaultLockRoot(),
276958
277167
  processId: process.pid,
276959
- ownerToken: randomUUID27(),
277168
+ ownerToken: randomUUID28(),
276960
277169
  isProcessAlive: defaultIsProcessAlive2,
276961
277170
  ...overrides
276962
277171
  };
@@ -277467,18 +277676,10 @@ function isExternalToolCallResponseCommand(value) {
277467
277676
  return Array.isArray(value.result.content) && value.result.content.every(isRecord7) && (value.result.is_error === undefined || typeof value.result.is_error === "boolean");
277468
277677
  }
277469
277678
 
277470
- // src/websocket/listener/protocol-inbound.ts
277471
- function isExperimentId(value) {
277472
- return typeof value === "string" && EXPERIMENT_IDS.has(value);
277473
- }
277679
+ // src/websocket/listener/protocol-validation.ts
277474
277680
  function isStringArray8(value) {
277475
277681
  return Array.isArray(value) && value.every((item) => typeof item === "string");
277476
277682
  }
277477
- function isClientToolsetConfig(value) {
277478
- if (!isObjectRecord2(value))
277479
- return false;
277480
- return (value.base === undefined || typeof value.base === "string" && TOOLSET_PREFERENCES.has(value.base)) && (value.include === undefined || isStringArray8(value.include));
277481
- }
277482
277683
  function isStringRecord2(value) {
277483
277684
  return !!value && typeof value === "object" && !Array.isArray(value) && Object.values(value).every((item) => typeof item === "string");
277484
277685
  }
@@ -277486,12 +277687,43 @@ function isObjectRecord2(value) {
277486
277687
  return !!value && typeof value === "object" && !Array.isArray(value);
277487
277688
  }
277488
277689
  function isRuntimeScope2(value) {
277489
- if (!value || typeof value !== "object") {
277690
+ if (!value || typeof value !== "object")
277490
277691
  return false;
277491
- }
277492
277692
  const candidate = value;
277493
277693
  return typeof candidate.agent_id === "string" && candidate.agent_id.length > 0 && typeof candidate.conversation_id === "string" && candidate.conversation_id.length > 0;
277494
277694
  }
277695
+
277696
+ // src/websocket/listener/teleport-protocol-inbound.ts
277697
+ function isTeleportContinuePayload(value) {
277698
+ if (!isObjectRecord2(value) || !isObjectRecord2(value.source))
277699
+ return false;
277700
+ return value.kind === "teleport_continue" && typeof value.teleport_id === "string" && value.teleport_id.length > 0 && typeof value.source.device_id === "string" && typeof value.source.connection_name === "string" && (value.continuation === undefined || isObjectRecord2(value.continuation) && Array.isArray(value.continuation.approvals));
277701
+ }
277702
+ function parseTeleportCommand(value) {
277703
+ if (!isObjectRecord2(value) || !isRuntimeScope2(value.runtime))
277704
+ return null;
277705
+ if (value.type === "teleport_probe" && typeof value.request_id === "string") {
277706
+ return value;
277707
+ }
277708
+ if (value.type === "teleport_request" && typeof value.request_id === "string" && typeof value.teleport_id === "string" && isObjectRecord2(value.target) && typeof value.target.connection_id === "string" && typeof value.target.device_id === "string" && typeof value.target.connection_name === "string") {
277709
+ return value;
277710
+ }
277711
+ if (value.type === "teleport_failed" && typeof value.teleport_id === "string" && typeof value.error === "string") {
277712
+ return value;
277713
+ }
277714
+ return null;
277715
+ }
277716
+ var init_teleport_protocol_inbound = () => {};
277717
+
277718
+ // src/websocket/listener/protocol-inbound.ts
277719
+ function isExperimentId(value) {
277720
+ return typeof value === "string" && EXPERIMENT_IDS.has(value);
277721
+ }
277722
+ function isClientToolsetConfig(value) {
277723
+ if (!isObjectRecord2(value))
277724
+ return false;
277725
+ return (value.base === undefined || typeof value.base === "string" && TOOLSET_PREFERENCES.has(value.base)) && (value.include === undefined || isStringArray8(value.include));
277726
+ }
277495
277727
  function isInputCommand(value) {
277496
277728
  if (!value || typeof value !== "object") {
277497
277729
  return false;
@@ -277513,6 +277745,9 @@ function isInputCommand(value) {
277513
277745
  if (payload.kind === "approval_response") {
277514
277746
  return isValidApprovalResponseBody(payload);
277515
277747
  }
277748
+ if (payload.kind === "teleport_continue") {
277749
+ return isTeleportContinuePayload(payload);
277750
+ }
277516
277751
  return false;
277517
277752
  }
277518
277753
  function legacyEnvironmentMessageToInputCommand(value) {
@@ -277602,6 +277837,15 @@ function getInvalidInputReason(value) {
277602
277837
  }
277603
277838
  return null;
277604
277839
  }
277840
+ if (payload.kind === "teleport_continue") {
277841
+ if (!isTeleportContinuePayload(payload)) {
277842
+ return {
277843
+ runtime: candidate.runtime,
277844
+ reason: "Protocol violation: input.kind=teleport_continue requires teleport_id, source, and optional continuation.approvals[]"
277845
+ };
277846
+ }
277847
+ return null;
277848
+ }
277605
277849
  return {
277606
277850
  runtime: candidate.runtime,
277607
277851
  reason: `Unsupported input payload kind: ${String(payload.kind)}`
@@ -278234,6 +278478,9 @@ function parseServerMessage(data) {
278234
278478
  if (legacyInput) {
278235
278479
  return legacyInput;
278236
278480
  }
278481
+ const teleportCommand = parseTeleportCommand(parsed);
278482
+ if (teleportCommand)
278483
+ return teleportCommand;
278237
278484
  if (isInputCommand(parsed) || isChangeDeviceStateCommand(parsed) || isAbortMessageCommand(parsed) || isSyncCommand(parsed) || isRuntimeStartCommand(parsed) || isRuntimeExternalToolsUpdateCommand(parsed) || isExternalToolCallResponseCommand(parsed) || isTerminalSpawnCommand(parsed) || isTerminalInputCommand(parsed) || isTerminalResizeCommand(parsed) || isTerminalKillCommand(parsed) || isSearchFilesCommand(parsed) || isGrepInFilesCommand(parsed) || isListInDirectoryCommand(parsed) || isGetTreeCommand(parsed) || isReadFileCommand(parsed) || isWriteFileCommand(parsed) || isWatchFileCommand(parsed) || isUnwatchFileCommand(parsed) || isEditFileCommand(parsed) || isFileOpsCommand(parsed) || isListMemoryCommand(parsed) || isMemoryHistoryCommand(parsed) || isMemoryFileAtRefCommand(parsed) || isMemoryCommitDiffCommand(parsed) || isReadMemoryFileCommand(parsed) || isWriteMemoryFileCommand(parsed) || isDeleteMemoryFileCommand(parsed) || isEnableMemfsCommand(parsed) || isListModelsCommand(parsed) || isListConnectProvidersCommand(parsed) || isConnectProviderCommand(parsed) || isDisconnectProviderCommand(parsed) || isChatGPTUsageReadCommand(parsed) || isUpdateModelCommand(parsed) || isUpdateToolsetCommand(parsed) || isCronListCommand(parsed) || isCronAddCommand(parsed) || isCronGetCommand(parsed) || isCronRunsCommand(parsed) || isCronTriggerCommand(parsed) || isCronUpdateCommand(parsed) || isCronDeleteCommand(parsed) || isCronDeleteAllCommand(parsed) || isSkillEnableCommand(parsed) || isSkillDisableCommand(parsed) || isAppServerInfoCommand(parsed) || isCreateAgentCommand(parsed) || isAgentListCommand(parsed) || isAgentRetrieveCommand(parsed) || isAgentCreateCommand(parsed) || isAgentUpdateCommand(parsed) || isAgentDeleteCommand(parsed) || isConversationListCommand(parsed) || isConversationRetrieveCommand(parsed) || isConversationCreateCommand(parsed) || isConversationUpdateCommand(parsed) || isConversationRecompileCommand(parsed) || isConversationForkCommand(parsed) || isConversationMessagesListCommand(parsed) || isConversationCompactCommand(parsed) || isGetCwdMapCommand(parsed) || isGetExperimentsCommand(parsed) || isSetExperimentCommand(parsed) || isGetReflectionSettingsCommand(parsed) || isSetReflectionSettingsCommand(parsed) || isChannelsListCommand(parsed) || isChannelAccountsListCommand(parsed) || isChannelAccountCreateCommand(parsed) || isChannelAccountUpdateCommand(parsed) || isChannelAccountBindCommand(parsed) || isChannelAccountUnbindCommand(parsed) || isChannelAccountDeleteCommand(parsed) || isChannelAccountStartCommand(parsed) || isChannelAccountStopCommand(parsed) || isChannelGetConfigCommand(parsed) || isChannelSetConfigCommand(parsed) || isChannelStartCommand(parsed) || isChannelStopCommand(parsed) || isChannelPairingsListCommand(parsed) || isChannelPairingBindCommand(parsed) || isChannelRoutesListCommand(parsed) || isChannelTargetsListCommand(parsed) || isChannelTargetBindCommand(parsed) || isChannelRouteUpdateCommand(parsed) || isChannelRouteRemoveCommand(parsed) || isExecuteCommandCommand(parsed) || isRemoveQueueItemCommand(parsed) || isSearchBranchesCommand(parsed) || isCheckoutBranchCommand(parsed) || isSecretListCommand(parsed) || isSecretApplyCommand(parsed)) {
278238
278485
  return parsed;
278239
278486
  }
@@ -278256,6 +278503,7 @@ var init_protocol_inbound = __esm(() => {
278256
278503
  init_skill_sources();
278257
278504
  init_channel_service_validation();
278258
278505
  init_approval();
278506
+ init_teleport_protocol_inbound();
278259
278507
  EXPERIMENT_IDS = new Set([
278260
278508
  "conversation_titles",
278261
278509
  "desktop_conversation_bootstrap",
@@ -279937,80 +280185,6 @@ var init_toolset_labels = __esm(() => {
279937
280185
  };
279938
280186
  });
279939
280187
 
279940
- // src/mods/capabilities.ts
279941
- function isModCapabilityId(value) {
279942
- return MOD_CAPABILITY_ID_SET.has(value);
279943
- }
279944
- function cloneModCapabilities(capabilities) {
279945
- return {
279946
- tools: capabilities.tools,
279947
- commands: capabilities.commands,
279948
- events: {
279949
- lifecycle: capabilities.events.lifecycle,
279950
- tools: capabilities.events.tools,
279951
- turns: capabilities.events.turns,
279952
- compact: capabilities.events.compact,
279953
- llm: capabilities.events.llm
279954
- },
279955
- permissions: capabilities.permissions,
279956
- providers: capabilities.providers,
279957
- ui: {
279958
- panels: capabilities.ui.panels
279959
- }
279960
- };
279961
- }
279962
- function resolveModCapabilities(capabilities) {
279963
- return cloneModCapabilities(capabilities ?? DEFAULT_MOD_CAPABILITIES);
279964
- }
279965
- var MOD_CAPABILITY_IDS, MOD_CAPABILITY_ID_SET, DEFAULT_MOD_CAPABILITIES, DISABLED_MOD_CAPABILITIES;
279966
- var init_capabilities = __esm(() => {
279967
- MOD_CAPABILITY_IDS = [
279968
- "tools",
279969
- "commands",
279970
- "providers",
279971
- "permissions",
279972
- "events.lifecycle",
279973
- "events.turns",
279974
- "events.tools",
279975
- "events.compact",
279976
- "events.llm",
279977
- "ui.panels"
279978
- ];
279979
- MOD_CAPABILITY_ID_SET = new Set(MOD_CAPABILITY_IDS);
279980
- DEFAULT_MOD_CAPABILITIES = {
279981
- tools: true,
279982
- commands: true,
279983
- events: {
279984
- lifecycle: true,
279985
- tools: true,
279986
- turns: true,
279987
- compact: true,
279988
- llm: true
279989
- },
279990
- permissions: true,
279991
- providers: true,
279992
- ui: {
279993
- panels: true
279994
- }
279995
- };
279996
- DISABLED_MOD_CAPABILITIES = {
279997
- tools: false,
279998
- commands: false,
279999
- events: {
280000
- lifecycle: false,
280001
- tools: false,
280002
- turns: false,
280003
- compact: false,
280004
- llm: false
280005
- },
280006
- permissions: false,
280007
- providers: false,
280008
- ui: {
280009
- panels: false
280010
- }
280011
- };
280012
- });
280013
-
280014
280188
  // src/mods/disabled-mod-adapter.ts
280015
280189
  function createDisabledModRegistry() {
280016
280190
  return {
@@ -451180,8 +451354,12 @@ function createModAdapter(options3) {
451180
451354
  }
451181
451355
  return createDisabledModAdapter();
451182
451356
  }
451357
+ const effectiveEngineOptions = {
451358
+ ...engineOptions,
451359
+ capabilities: resolveProcessModCapabilities(engineOptions.capabilities)
451360
+ };
451183
451361
  let disposed = false;
451184
- const initialHasModSources = hasModSources(engineOptions);
451362
+ const initialHasModSources = hasModSources(effectiveEngineOptions);
451185
451363
  let loadState = {
451186
451364
  hadModPanels: false,
451187
451365
  hasModSources: initialHasModSources,
@@ -451191,7 +451369,7 @@ function createModAdapter(options3) {
451191
451369
  let diagnosticsWriteTimer = null;
451192
451370
  const getBackend2 = () => resolveBackend?.();
451193
451371
  const engine4 = createModEngine({
451194
- ...engineOptions,
451372
+ ...effectiveEngineOptions,
451195
451373
  getBackend: getBackend2,
451196
451374
  onDiagnostic: () => scheduleDiagnosticsWrite()
451197
451375
  });
@@ -451261,7 +451439,7 @@ function createModAdapter(options3) {
451261
451439
  const previousHadModPanels = Object.keys(previousSnapshot.ui.panels).length > 0 || loadState.hadModPanels;
451262
451440
  loadState = {
451263
451441
  hadModPanels: previousHadModPanels,
451264
- hasModSources: hasModSources(engineOptions),
451442
+ hasModSources: hasModSources(effectiveEngineOptions),
451265
451443
  isLoading: true
451266
451444
  };
451267
451445
  publish();
@@ -451317,6 +451495,7 @@ function createModAdapter(options3) {
451317
451495
  }
451318
451496
  var RUNTIME_DIAGNOSTICS_WRITE_DELAY_MS = 30000;
451319
451497
  var init_mod_adapter = __esm(async () => {
451498
+ init_capabilities();
451320
451499
  init_disabled_mod_adapter();
451321
451500
  init_mod_diagnostics_file();
451322
451501
  init_permission_registry();
@@ -457300,6 +457479,151 @@ var init_send = __esm(async () => {
457300
457479
  BUSY_RUN_WAIT_TIMEOUT_MS = 5 * 60 * 1000;
457301
457480
  });
457302
457481
 
457482
+ // src/websocket/listener/teleport.ts
457483
+ function getPendingTeleports(runtime) {
457484
+ runtime.pendingTeleports ??= new Map;
457485
+ return runtime.pendingTeleports;
457486
+ }
457487
+ function findPendingTeleportForRuntime(runtime, agentId, conversationId) {
457488
+ for (const pending of getPendingTeleports(runtime).values()) {
457489
+ if (pending.agentId === agentId && pending.conversationId === conversationId && pending.readyAt === undefined) {
457490
+ return pending;
457491
+ }
457492
+ }
457493
+ return null;
457494
+ }
457495
+ function sendTeleportReady(runtime, pending, input) {
457496
+ const connection = runtime.connections.get(pending.connectionId);
457497
+ if (!connection || !isListenerTransportOpen(connection.writer))
457498
+ return false;
457499
+ const mode = getOrCreateConversationPermissionModeStateRef(runtime, pending.agentId, pending.conversationId).mode;
457500
+ const message = {
457501
+ type: "teleport_ready",
457502
+ teleport_id: pending.teleportId,
457503
+ runtime: {
457504
+ agent_id: pending.agentId,
457505
+ conversation_id: pending.conversationId
457506
+ },
457507
+ success: input.success,
457508
+ mode,
457509
+ ...pending.continuation ? { continuation: pending.continuation } : {},
457510
+ ...input.error ? { error: input.error } : {}
457511
+ };
457512
+ emitProtocolV2Message(connection.writer, runtime, message, message.runtime, toListenerConnection(pending.connectionId));
457513
+ return true;
457514
+ }
457515
+ function retainTeleportForRecovery(runtime, pending) {
457516
+ const timeout = setTimeout(() => {
457517
+ const current = runtime.pendingTeleports?.get(pending.teleportId);
457518
+ if (current === pending) {
457519
+ runtime.pendingTeleports?.delete(pending.teleportId);
457520
+ }
457521
+ }, TELEPORT_RECOVERY_TTL_MS);
457522
+ timeout.unref?.();
457523
+ }
457524
+ function handleTeleportProbe(command, socket, safeSocketSend) {
457525
+ safeSocketSend(socket, {
457526
+ type: "teleport_probe_response",
457527
+ request_id: command.request_id,
457528
+ runtime: command.runtime,
457529
+ supported: true
457530
+ }, "teleport_probe_response", "teleport_probe");
457531
+ }
457532
+ function handleTeleportRequest(params) {
457533
+ const { listener, command, connectionId } = params;
457534
+ const pendingTeleports = getPendingTeleports(listener);
457535
+ const existing = pendingTeleports.get(command.teleport_id);
457536
+ if (existing) {
457537
+ if (existing.readyAt !== undefined) {
457538
+ sendTeleportReady(listener, existing, { success: true });
457539
+ }
457540
+ return;
457541
+ }
457542
+ const pending = {
457543
+ teleportId: command.teleport_id,
457544
+ connectionId,
457545
+ agentId: command.runtime.agent_id,
457546
+ conversationId: command.runtime.conversation_id,
457547
+ requestedAt: Date.now()
457548
+ };
457549
+ const conflicting = findPendingTeleportForRuntime(listener, pending.agentId, pending.conversationId);
457550
+ if (conflicting) {
457551
+ pendingTeleports.set(pending.teleportId, pending);
457552
+ pending.readyAt = Date.now();
457553
+ sendTeleportReady(listener, pending, {
457554
+ success: false,
457555
+ error: "Conversation already has a teleport pending"
457556
+ });
457557
+ retainTeleportForRecovery(listener, pending);
457558
+ return;
457559
+ }
457560
+ pendingTeleports.set(pending.teleportId, pending);
457561
+ const conversationRuntime = getConversationRuntime(listener, pending.agentId, pending.conversationId);
457562
+ if (!conversationRuntime?.isProcessing) {
457563
+ if (sendTeleportReady(listener, pending, { success: true })) {
457564
+ pending.readyAt = Date.now();
457565
+ retainTeleportForRecovery(listener, pending);
457566
+ }
457567
+ }
457568
+ }
457569
+ function claimPendingTeleportAtBoundary(params) {
457570
+ const pending = findPendingTeleportForRuntime(params.listener, params.agentId, params.conversationId);
457571
+ if (!pending)
457572
+ return null;
457573
+ const connection = params.listener.connections.get(pending.connectionId);
457574
+ if (!connection || !isListenerTransportOpen(connection.writer))
457575
+ return null;
457576
+ pending.readyAt = Date.now();
457577
+ pending.continuation = params.continuation;
457578
+ return pending;
457579
+ }
457580
+ function emitClaimedTeleportReady(listener, pending) {
457581
+ const sent = sendTeleportReady(listener, pending, { success: true });
457582
+ if (sent) {
457583
+ retainTeleportForRecovery(listener, pending);
457584
+ }
457585
+ return sent;
457586
+ }
457587
+ function finishTeleport(runtime, lease, pending) {
457588
+ const transition = runtime.turnLifecycle.finish(lease, "cancelled");
457589
+ if (!transition.finished)
457590
+ return transition;
457591
+ emitRuntimeStateUpdates(runtime, {
457592
+ agent_id: pending.agentId,
457593
+ conversation_id: pending.conversationId
457594
+ });
457595
+ emitClaimedTeleportReady(runtime.listener, pending);
457596
+ return transition;
457597
+ }
457598
+ function finishPendingTeleport(runtime) {
457599
+ if (runtime.lastStopReason !== "end_turn" || !runtime.agentId)
457600
+ return;
457601
+ const pending = claimPendingTeleportAtBoundary({
457602
+ listener: runtime.listener,
457603
+ agentId: runtime.agentId,
457604
+ conversationId: runtime.conversationId
457605
+ });
457606
+ if (pending)
457607
+ emitClaimedTeleportReady(runtime.listener, pending);
457608
+ }
457609
+ function takeFailedTeleport(params) {
457610
+ const pending = params.listener.pendingTeleports?.get(params.teleportId);
457611
+ if (!pending || pending.agentId !== params.agentId || pending.conversationId !== params.conversationId) {
457612
+ return null;
457613
+ }
457614
+ params.listener.pendingTeleports?.delete(params.teleportId);
457615
+ return pending;
457616
+ }
457617
+ var TELEPORT_RECOVERY_TTL_MS;
457618
+ var init_teleport = __esm(() => {
457619
+ init_connection();
457620
+ init_permission_mode();
457621
+ init_protocol_outbound();
457622
+ init_runtime();
457623
+ init_transport();
457624
+ TELEPORT_RECOVERY_TTL_MS = 5 * 60000;
457625
+ });
457626
+
457303
457627
  // node_modules/diff/libesm/diff/base.js
457304
457628
  class Diff2 {
457305
457629
  diff(oldStr, newStr, options3 = {}) {
@@ -459691,6 +460015,27 @@ async function handleApprovalStop(params) {
459691
460015
  if (shouldInterrupt()) {
459692
460016
  return interruptTermination();
459693
460017
  }
460018
+ const pendingTeleport = claimPendingTeleportAtBoundary({
460019
+ listener: runtime.listener,
460020
+ agentId,
460021
+ conversationId,
460022
+ continuation: { approvals: persistedExecutionResults }
460023
+ });
460024
+ if (pendingTeleport) {
460025
+ clearPendingApprovalBatchIds(runtime, decisions.map((decision) => decision.approval));
460026
+ return {
460027
+ kind: "teleport",
460028
+ pendingTeleport,
460029
+ turnInput,
460030
+ dequeuedBatchId,
460031
+ pendingNormalizationInterruptedToolCallIds: [],
460032
+ turnToolContextId,
460033
+ lastExecutionResults,
460034
+ lastExecutingToolCallIds,
460035
+ lastNeedsUserInputToolCallIds,
460036
+ lastApprovalContinuationAccepted: false
460037
+ };
460038
+ }
459694
460039
  let nextTurnInput = createTurnInputState([
459695
460040
  {
459696
460041
  type: "approval",
@@ -459790,6 +460135,7 @@ var init_turn_approval = __esm(async () => {
459790
460135
  init_protocol_outbound();
459791
460136
  init_secrets_sync();
459792
460137
  init_skill_injection();
460138
+ init_teleport();
459793
460139
  init_transport();
459794
460140
  init_turn_input_state();
459795
460141
  init_turn_status();
@@ -459866,9 +460212,53 @@ var init_memory_git_sync = __esm(() => {
459866
460212
  init_debug();
459867
460213
  });
459868
460214
 
460215
+ // src/websocket/listener/channel-runtime-tools.ts
460216
+ async function publishChannelRuntimeToolsForTurn(listener, runtime) {
460217
+ const handler = listener.serviceCommandHandler;
460218
+ if (!handler)
460219
+ return false;
460220
+ try {
460221
+ const response = await handler({ kind: "publish_runtime_tools", runtime });
460222
+ if (response.kind === "runtime_tools_published") {
460223
+ return response.transient;
460224
+ }
460225
+ debugWarn("listen", `ChannelGateway returned an unexpected tool publication response: ${response.kind}`);
460226
+ } catch (error54) {
460227
+ debugWarn("listen", `Failed to publish channel tools for ${runtime.agent_id}/${runtime.conversation_id}: ${error54 instanceof Error ? error54.message : String(error54)}`);
460228
+ }
460229
+ return false;
460230
+ }
460231
+ async function releaseChannelRuntimeToolsForTurn(listener, runtime) {
460232
+ const handler = listener.serviceCommandHandler;
460233
+ if (!handler)
460234
+ return;
460235
+ try {
460236
+ const response = await handler({ kind: "release_runtime_tools", runtime });
460237
+ if (response.kind === "runtime_tools_released")
460238
+ return;
460239
+ debugWarn("listen", `ChannelGateway returned an unexpected tool release response: ${response.kind}`);
460240
+ } catch (error54) {
460241
+ debugWarn("listen", `Failed to release channel tools for ${runtime.agent_id}/${runtime.conversation_id}: ${error54 instanceof Error ? error54.message : String(error54)}`);
460242
+ }
460243
+ }
460244
+ var init_channel_runtime_tools = __esm(() => {
460245
+ init_debug();
460246
+ });
460247
+
459869
460248
  // src/websocket/listener/turn-cleanup.ts
459870
460249
  async function runListenerTurnCleanup(params) {
459871
- const { runtime, agentId, normalizedAgentId, conversationId } = params;
460250
+ const { runtime, agentId, normalizedAgentId, conversationId, finalized } = params;
460251
+ if (runtime.transientChannelRuntimeTools) {
460252
+ if (agentId) {
460253
+ await releaseChannelRuntimeToolsForTurn(runtime.listener, {
460254
+ agent_id: agentId,
460255
+ conversation_id: conversationId
460256
+ });
460257
+ }
460258
+ runtime.transientChannelRuntimeTools = false;
460259
+ }
460260
+ if (!finalized)
460261
+ return;
459872
460262
  pruneConversationPermissionModeStateIfDefault(runtime.listener, normalizedAgentId, conversationId);
459873
460263
  persistPermissionModeMapForRuntime(runtime.listener);
459874
460264
  emitDeviceStatusIfOpen(runtime, {
@@ -459889,6 +460279,7 @@ async function runListenerTurnCleanup(params) {
459889
460279
  var init_turn_cleanup = __esm(() => {
459890
460280
  init_memory_git_sync();
459891
460281
  init_settings_manager();
460282
+ init_channel_runtime_tools();
459892
460283
  init_permission_mode();
459893
460284
  init_protocol_outbound();
459894
460285
  });
@@ -461219,6 +461610,13 @@ async function prepareListenerTurn(params) {
461219
461610
  inboundUserTranscriptLines = buildInboundUserTranscriptLines(currentInput);
461220
461611
  }
461221
461612
  const modAdapters = await ensureListenerModAdaptersForAgent(runtime.listener, agentId);
461613
+ runtime.transientChannelRuntimeTools = await publishChannelRuntimeToolsForTurn(runtime.listener, {
461614
+ agent_id: agentId,
461615
+ conversation_id: conversationId
461616
+ });
461617
+ if (isInterrupted()) {
461618
+ return { kind: "interrupted" };
461619
+ }
461222
461620
  const listenerOptions = connectionId ? runtime.listener.connections.get(connectionId)?.options : runtime.listener.connections.values().next().value?.options;
461223
461621
  const environmentDeviceId = listenerOptions?.deviceId;
461224
461622
  const preparedToolContext = await prepareToolExecutionContextForScope({
@@ -461275,6 +461673,7 @@ var init_turn_setup = __esm(async () => {
461275
461673
  init_interactive_policy();
461276
461674
  init_debug();
461277
461675
  init_shell_context();
461676
+ init_channel_runtime_tools();
461278
461677
  init_interrupts();
461279
461678
  init_turn_input_state();
461280
461679
  init_turn_transcript();
@@ -461294,6 +461693,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
461294
461693
  await handleIncomingMessageInner(msg, socket, runtime, onStatusChange, connectionId, dequeuedBatchId, existingTurnLease);
461295
461694
  } finally {
461296
461695
  notifyTurnFinished(msg);
461696
+ finishPendingTeleport(runtime);
461297
461697
  }
461298
461698
  }
461299
461699
  async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange, connectionId, dequeuedBatchId = `batch-direct-${crypto.randomUUID()}`, existingTurnLease) {
@@ -461303,12 +461703,8 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
461303
461703
  const normalizedAgentId = normalizeCwdAgentId(agentId);
461304
461704
  const turnWorkingDirectory = getConversationWorkingDirectory(runtime.listener, normalizedAgentId, conversationId);
461305
461705
  const turnPermissionModeState = getOrCreateConversationPermissionModeStateRef(runtime.listener, normalizedAgentId, conversationId);
461706
+ let postStopApprovalRecoveryRetries = 0, llmApiErrorRetries = 0, emptyResponseRetries = 0, lastApprovalContinuationAccepted = false, activeDequeuedBatchId = dequeuedBatchId;
461306
461707
  const msgRunIds = [];
461307
- let postStopApprovalRecoveryRetries = 0;
461308
- let llmApiErrorRetries = 0;
461309
- let emptyResponseRetries = 0;
461310
- let lastApprovalContinuationAccepted = false;
461311
- let activeDequeuedBatchId = dequeuedBatchId;
461312
461708
  let lastExecutionResults = null;
461313
461709
  let lastExecutingToolCallIds = [];
461314
461710
  let lastNeedsUserInputToolCallIds = [];
@@ -461319,15 +461715,12 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
461319
461715
  if (connectionId) {
461320
461716
  runtime.activeConnectionId = connectionId;
461321
461717
  }
461322
- if (!runtime.turnLifecycle.isCurrent(turnLease)) {
461718
+ if (!runtime.turnLifecycle.isCurrent(turnLease))
461323
461719
  throw new Error("Cannot continue a turn with a stale lifecycle lease");
461324
- }
461325
461720
  const turnAbortSignal = turnLease.signal;
461326
461721
  let finalizedByThisInvocation = false;
461327
461722
  const noteFinalization = (transition) => {
461328
- if (transition.finished) {
461329
- finalizedByThisInvocation = true;
461330
- }
461723
+ finalizedByThisInvocation ||= transition.finished;
461331
461724
  return transition;
461332
461725
  };
461333
461726
  const finishTurn = (options3) => noteFinalization(finishListenerTurn(runtime, turnLease, {
@@ -461825,6 +462218,11 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
461825
462218
  lastExecutingToolCallIds = approvalResult.lastExecutingToolCallIds;
461826
462219
  lastNeedsUserInputToolCallIds = approvalResult.lastNeedsUserInputToolCallIds;
461827
462220
  lastApprovalContinuationAccepted = approvalResult.lastApprovalContinuationAccepted;
462221
+ if (approvalResult.kind === "teleport") {
462222
+ const pending = approvalResult.pendingTeleport;
462223
+ noteFinalization(finishTeleport(runtime, turnLease, pending));
462224
+ return;
462225
+ }
461828
462226
  if (approvalResult.kind === "interrupted") {
461829
462227
  if (runtime.turnLifecycle.isCurrent(turnLease)) {
461830
462228
  populateInterruptQueue(runtime, {
@@ -461948,14 +462346,13 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
461948
462346
  runtime.activeConnectionId = null;
461949
462347
  }
461950
462348
  try {
461951
- if (finalizedByThisInvocation) {
461952
- await runListenerTurnCleanup({
461953
- runtime,
461954
- agentId,
461955
- normalizedAgentId,
461956
- conversationId
461957
- });
461958
- }
462349
+ await runListenerTurnCleanup({
462350
+ runtime,
462351
+ agentId,
462352
+ normalizedAgentId,
462353
+ conversationId,
462354
+ finalized: finalizedByThisInvocation
462355
+ });
461959
462356
  } finally {
461960
462357
  releaseListenerTurnContext({ runtime, agentId, conversationId });
461961
462358
  }
@@ -461981,6 +462378,7 @@ var init_turn = __esm(async () => {
461981
462378
  init_recoverable_notices();
461982
462379
  init_runtime();
461983
462380
  init_skill_injection();
462381
+ init_teleport();
461984
462382
  init_turn_cleanup();
461985
462383
  init_turn_context();
461986
462384
  init_turn_input_state();
@@ -466494,6 +466892,46 @@ function createListenerMessageHandler(params) {
466494
466892
  })) {
466495
466893
  return;
466496
466894
  }
466895
+ if (parsed.type === "teleport_probe") {
466896
+ handleTeleportProbe(parsed, socket, safeSocketSend);
466897
+ return;
466898
+ }
466899
+ if (parsed.type === "teleport_request") {
466900
+ handleTeleportRequest({
466901
+ listener: runtime,
466902
+ command: parsed,
466903
+ connectionId
466904
+ });
466905
+ return;
466906
+ }
466907
+ if (parsed.type === "teleport_failed") {
466908
+ const pending = takeFailedTeleport({
466909
+ listener: runtime,
466910
+ teleportId: parsed.teleport_id,
466911
+ agentId: parsed.runtime.agent_id,
466912
+ conversationId: parsed.runtime.conversation_id
466913
+ });
466914
+ const approvals = pending?.continuation?.approvals;
466915
+ if (pending && approvals && approvals.length > 0) {
466916
+ const scopedRuntime = getOrCreateScopedRuntime2(runtime, pending.agentId, pending.conversationId);
466917
+ runDetachedListenerTask("teleport_failed", async () => {
466918
+ await processIncomingMessage({
466919
+ type: "message",
466920
+ connectionId: pending.connectionId,
466921
+ agentId: pending.agentId,
466922
+ conversationId: pending.conversationId,
466923
+ messages: [
466924
+ {
466925
+ type: "approval",
466926
+ approvals,
466927
+ otid: crypto.randomUUID()
466928
+ }
466929
+ ]
466930
+ }, socket, scopedRuntime, opts.onStatusChange, pending.connectionId);
466931
+ });
466932
+ }
466933
+ return;
466934
+ }
466497
466935
  if (parsed.type === "external_tool_call_response") {
466498
466936
  handleExternalToolCallResponseCommand(runtime, connectionId, parsed);
466499
466937
  return;
@@ -466575,6 +467013,42 @@ function createListenerMessageHandler(params) {
466575
467013
  acknowledgeInput(false, "Runtime is no longer active");
466576
467014
  return;
466577
467015
  }
467016
+ if (parsed.payload.kind === "teleport_continue") {
467017
+ const scopedRuntime2 = getOrCreateScopedRuntime2(runtime, parsed.runtime.agent_id, parsed.runtime.conversation_id);
467018
+ const acceptedKey = `teleport:${parsed.payload.teleport_id}`;
467019
+ const previousDisposition = scopedRuntime2.acceptedInputDispositions.get(acceptedKey);
467020
+ if (previousDisposition) {
467021
+ acknowledgeInput(true, undefined, previousDisposition);
467022
+ return;
467023
+ }
467024
+ const approvals = parsed.payload.continuation?.approvals;
467025
+ if (!approvals || approvals.length === 0) {
467026
+ acknowledgeInput(true);
467027
+ return;
467028
+ }
467029
+ if (scopedRuntime2.isProcessing) {
467030
+ acknowledgeInput(false, "Destination runtime is already processing");
467031
+ return;
467032
+ }
467033
+ scopedRuntime2.acceptedInputDispositions.set(acceptedKey, "started");
467034
+ acknowledgeInput(true, undefined, "started");
467035
+ runDetachedListenerTask("teleport_continue", async () => {
467036
+ await processIncomingMessage({
467037
+ type: "message",
467038
+ connectionId,
467039
+ agentId: parsed.runtime.agent_id,
467040
+ conversationId: parsed.runtime.conversation_id,
467041
+ messages: [
467042
+ {
467043
+ type: "approval",
467044
+ approvals,
467045
+ otid: crypto.randomUUID()
467046
+ }
467047
+ ]
467048
+ }, socket, scopedRuntime2, opts.onStatusChange, connectionId);
467049
+ });
467050
+ return;
467051
+ }
466578
467052
  if (parsed.payload.kind === "approval_response") {
466579
467053
  const handled = await handleApprovalResponseInput2(runtime, {
466580
467054
  runtime: parsed.runtime,
@@ -466930,6 +467404,7 @@ var init_message_router = __esm(async () => {
466930
467404
  init_protocol_outbound();
466931
467405
  init_recoverable_notices();
466932
467406
  init_runtime();
467407
+ init_teleport();
466933
467408
  await __promiseAll([
466934
467409
  init_commands2(),
466935
467410
  init_cron3(),
@@ -469163,7 +469638,7 @@ function createToolLifecycleTracker(onEvent) {
469163
469638
  }
469164
469639
 
469165
469640
  // src/websocket/app-server-openai-turn.ts
469166
- import { randomUUID as randomUUID28 } from "node:crypto";
469641
+ import { randomUUID as randomUUID29 } from "node:crypto";
469167
469642
  function runBridgeTurn(params) {
469168
469643
  return runTurnImpl(params);
469169
469644
  }
@@ -469182,7 +469657,7 @@ async function ensureListenerRuntime(onLog) {
469182
469657
  if (active && !active.intentionallyClosed)
469183
469658
  return active;
469184
469659
  bridgeRuntimeStart ??= startLocalChannelListener({
469185
- connectionId: `openai-api-${randomUUID28()}`,
469660
+ connectionId: `openai-api-${randomUUID29()}`,
469186
469661
  deviceId: settingsManager.getOrCreateDeviceId(),
469187
469662
  connectionName: "openai-api",
469188
469663
  onConnected: () => {},
@@ -469391,11 +469866,11 @@ var init_app_server_openai_turn = __esm(async () => {
469391
469866
  });
469392
469867
 
469393
469868
  // src/websocket/app-server-openai-responses.ts
469394
- import { randomUUID as randomUUID29 } from "node:crypto";
469869
+ import { randomUUID as randomUUID30 } from "node:crypto";
469395
469870
  function createStoredResponseId(state) {
469396
469871
  const cursor = Buffer.from(JSON.stringify({
469397
469872
  version: 1,
469398
- nonce: randomUUID29(),
469873
+ nonce: randomUUID30(),
469399
469874
  agent_id: state.agentId,
469400
469875
  conversation_id: state.conversationId
469401
469876
  })).toString("base64url");
@@ -469440,7 +469915,7 @@ function toBridgeMessages(messages, stateful) {
469440
469915
  return { messages: [], correlationOtid: null };
469441
469916
  }
469442
469917
  if (stateful) {
469443
- const otid = randomUUID29();
469918
+ const otid = randomUUID30();
469444
469919
  return {
469445
469920
  messages: [{ role: "user", content: lastUserContent, otid }],
469446
469921
  correlationOtid: otid
@@ -469462,7 +469937,7 @@ function toBridgeMessages(messages, stateful) {
469462
469937
  bridgeMessages.push({
469463
469938
  role: message.role,
469464
469939
  content,
469465
- otid: randomUUID29()
469940
+ otid: randomUUID30()
469466
469941
  });
469467
469942
  }
469468
469943
  return {
@@ -469594,7 +470069,7 @@ class ResponseOutputBuilder {
469594
470069
  this.finishText();
469595
470070
  const result = {
469596
470071
  type: "function_call_output",
469597
- id: `fco_${randomUUID29()}`,
470072
+ id: `fco_${randomUUID30()}`,
469598
470073
  call_id: event2.tool_call_id,
469599
470074
  output: [{ type: "input_text", text: event2.output }],
469600
470075
  status: event2.success ? "completed" : "incomplete"
@@ -469679,7 +470154,7 @@ class ResponseOutputBuilder {
469679
470154
  return this.message;
469680
470155
  const item = {
469681
470156
  type: "message",
469682
- id: `msg_${randomUUID29()}`,
470157
+ id: `msg_${randomUUID30()}`,
469683
470158
  status: "in_progress",
469684
470159
  role: "assistant",
469685
470160
  content: [{ type: "output_text", text: "", annotations: [] }]
@@ -469706,7 +470181,7 @@ class ResponseOutputBuilder {
469706
470181
  return this.reasoning;
469707
470182
  const item = {
469708
470183
  type: "reasoning",
469709
- id: `rs_${randomUUID29()}`,
470184
+ id: `rs_${randomUUID30()}`,
469710
470185
  status: "in_progress",
469711
470186
  summary: [{ type: "summary_text", text: "" }]
469712
470187
  };
@@ -469737,7 +470212,7 @@ class ResponseOutputBuilder {
469737
470212
  }
469738
470213
  const item = {
469739
470214
  type: "function_call",
469740
- id: `fc_${randomUUID29()}`,
470215
+ id: `fc_${randomUUID30()}`,
469741
470216
  call_id: callId,
469742
470217
  name,
469743
470218
  arguments: "",
@@ -469842,7 +470317,7 @@ async function handleResponses(request, response, options3) {
469842
470317
  sendOpenAiError(response, 500, "failed to create a conversation for this response", "server_error");
469843
470318
  return;
469844
470319
  }
469845
- const responseId = body3.store === true ? createStoredResponseId({ agentId: agent2.id, conversationId }) : `resp_${randomUUID29()}`;
470320
+ const responseId = body3.store === true ? createStoredResponseId({ agentId: agent2.id, conversationId }) : `resp_${randomUUID30()}`;
469846
470321
  const createdAt = Math.floor(Date.now() / 1000);
469847
470322
  let sequenceNumber = 0;
469848
470323
  let clientClosed = false;
@@ -469932,7 +470407,7 @@ var init_app_server_openai_responses = __esm(async () => {
469932
470407
  });
469933
470408
 
469934
470409
  // src/websocket/app-server-openai.ts
469935
- import { randomUUID as randomUUID30 } from "node:crypto";
470410
+ import { randomUUID as randomUUID31 } from "node:crypto";
469936
470411
  function isOpenAiCompatPath(pathname) {
469937
470412
  return pathname === MODELS_PATH || pathname === CHAT_COMPLETIONS_PATH || pathname === RESPONSES_PATH;
469938
470413
  }
@@ -470001,7 +470476,7 @@ async function handleChatCompletions(request, response, options3) {
470001
470476
  turnMessages.push({
470002
470477
  role: "user",
470003
470478
  content: userContent,
470004
- otid: randomUUID30()
470479
+ otid: randomUUID31()
470005
470480
  });
470006
470481
  } else {
470007
470482
  for (const message of body3.messages) {
@@ -470018,7 +470493,7 @@ async function handleChatCompletions(request, response, options3) {
470018
470493
  }
470019
470494
  if (content.length === 0)
470020
470495
  continue;
470021
- turnMessages.push({ role: message.role, content, otid: randomUUID30() });
470496
+ turnMessages.push({ role: message.role, content, otid: randomUUID31() });
470022
470497
  }
470023
470498
  }
470024
470499
  correlationOtid = turnMessages.at(-1)?.otid ?? null;
@@ -470027,7 +470502,7 @@ async function handleChatCompletions(request, response, options3) {
470027
470502
  return;
470028
470503
  }
470029
470504
  }
470030
- const completionId = `chatcmpl-${randomUUID30()}`;
470505
+ const completionId = `chatcmpl-${randomUUID31()}`;
470031
470506
  const created = Math.floor(Date.now() / 1000);
470032
470507
  const streaming3 = body3.stream === true;
470033
470508
  let clientClosed = false;
@@ -471309,7 +471784,7 @@ var init_listen = __esm(async () => {
471309
471784
  });
471310
471785
 
471311
471786
  // src/backend/local/transcript-migration.ts
471312
- import { randomUUID as randomUUID31 } from "node:crypto";
471787
+ import { randomUUID as randomUUID32 } from "node:crypto";
471313
471788
  import {
471314
471789
  copyFileSync as copyFileSync3,
471315
471790
  existsSync as existsSync52,
@@ -471349,7 +471824,7 @@ function writeSessionEntryJsonl(path44, messages, input) {
471349
471824
  ...messages.map((message) => {
471350
471825
  const entry = {
471351
471826
  type: "message",
471352
- id: randomUUID31().slice(0, 8),
471827
+ id: randomUUID32().slice(0, 8),
471353
471828
  parentId,
471354
471829
  timestamp: message.metadata?.created_at ?? new Date(message.timestamp).toISOString(),
471355
471830
  message
@@ -471885,7 +472360,7 @@ Examples:
471885
472360
  letta memory tokens --memory-dir ~/.letta/agents/agent-123/memory --format json
471886
472361
  `.trim());
471887
472362
  }
471888
- function getAgentId4(agentFromArgs, agentIdFromArgs) {
472363
+ function getAgentId3(agentFromArgs, agentIdFromArgs) {
471889
472364
  return agentFromArgs || agentIdFromArgs || process.env.LETTA_AGENT_ID || "";
471890
472365
  }
471891
472366
  function parseMemoryArgs(argv) {
@@ -471958,7 +472433,7 @@ async function runMemorySubcommand(argv) {
471958
472433
  printUsage8();
471959
472434
  return 0;
471960
472435
  }
471961
- const agentId = getAgentId4(parsed.values.agent, parsed.values["agent-id"]);
472436
+ const agentId = getAgentId3(parsed.values.agent, parsed.values["agent-id"]);
471962
472437
  if (action3 === "tokens") {
471963
472438
  return runMemoryTokensAction({
471964
472439
  memoryDir: parsed.values["memory-dir"],
@@ -472525,7 +473000,7 @@ function parseOrder(value) {
472525
473000
  }
472526
473001
  return;
472527
473002
  }
472528
- function getAgentId5(agentFromArgs, agentIdFromArgs) {
473003
+ function getAgentId4(agentFromArgs, agentIdFromArgs) {
472529
473004
  return agentFromArgs || agentIdFromArgs || process.env.LETTA_AGENT_ID || "";
472530
473005
  }
472531
473006
  function pageItems4(page) {
@@ -472686,7 +473161,7 @@ async function runMessagesSubcommand(argv, deps = {}) {
472686
473161
  }
472687
473162
  const allAgents = parsed.values["all-agents"] ?? false;
472688
473163
  const explicitAgentId = parsed.values.agent || parsed.values["agent-id"] || "";
472689
- const agentId = getAgentId5(parsed.values.agent, parsed.values["agent-id"]);
473164
+ const agentId = getAgentId4(parsed.values.agent, parsed.values["agent-id"]);
472690
473165
  const conversationId = parsed.values.conversation || parsed.values["conversation-id"];
472691
473166
  if (conversationId === "default") {
472692
473167
  if (!agentId) {
@@ -472717,7 +473192,7 @@ async function runMessagesSubcommand(argv, deps = {}) {
472717
473192
  return 0;
472718
473193
  }
472719
473194
  if (action3 === "list") {
472720
- const agentId = getAgentId5(parsed.values.agent, parsed.values["agent-id"]);
473195
+ const agentId = getAgentId4(parsed.values.agent, parsed.values["agent-id"]);
472721
473196
  const orderRaw = parsed.values.order;
472722
473197
  const order = parseOrder(orderRaw);
472723
473198
  if (orderRaw !== undefined && !order) {
@@ -472767,7 +473242,7 @@ async function runMessagesSubcommand(argv, deps = {}) {
472767
473242
  console.error("Missing conversation id. Pass --conversation <id> or --conversation-id <id>.");
472768
473243
  return 1;
472769
473244
  }
472770
- const agentId = getAgentId5(parsed.values.agent, parsed.values["agent-id"]);
473245
+ const agentId = getAgentId4(parsed.values.agent, parsed.values["agent-id"]);
472771
473246
  if (conversationId === "default" && !agentId) {
472772
473247
  console.error('Conversation "default" requires an agent id. Set LETTA_AGENT_ID or pass --agent/--agent-id.');
472773
473248
  return 1;
@@ -474261,6 +474736,10 @@ function resolveSandboxSession(env5, fallback) {
474261
474736
  }
474262
474737
  return session;
474263
474738
  }
474739
+ async function initializeSandboxSettings() {
474740
+ await settingsManager.initialize();
474741
+ await settingsManager.loadLocalProjectSettings();
474742
+ }
474264
474743
  async function runSandboxSubcommand(argv, deps = {}) {
474265
474744
  let parsed;
474266
474745
  try {
@@ -474281,7 +474760,7 @@ async function runSandboxSubcommand(argv, deps = {}) {
474281
474760
  return 1;
474282
474761
  }
474283
474762
  try {
474284
- await (deps.initializeSettings ?? (() => settingsManager.initialize()))();
474763
+ await (deps.initializeSettings ?? initializeSandboxSettings)();
474285
474764
  if (!await (deps.isCloud ?? isLettaCloud)()) {
474286
474765
  throw new Error("Sandbox file transfer is only available on Letta Cloud");
474287
474766
  }
@@ -477590,6 +478069,155 @@ var init_skills4 = __esm(() => {
477590
478069
  };
477591
478070
  });
477592
478071
 
478072
+ // src/cli/subcommands/teleport.ts
478073
+ import { parseArgs as parseArgs17 } from "node:util";
478074
+ function printUsage15() {
478075
+ console.log(`
478076
+ Usage:
478077
+ letta teleport list
478078
+ letta teleport cloud
478079
+ letta teleport <environment>
478080
+
478081
+ Notes:
478082
+ - Operates on the current agent/conversation from LETTA_AGENT_ID /
478083
+ LETTA_CONVERSATION_ID (or AGENT_ID / CONVERSATION_ID), falling back to the
478084
+ last active session.
478085
+ - Requires a Letta Cloud agent and a non-virtual conversation.
478086
+ - list: prints accessible online remote environments as JSON.
478087
+ - cloud: teleports to the agent's Cloud sandbox.
478088
+ - <environment>: teleports to a specific remote environment by name,
478089
+ device-id, connection-id, or environment id.
478090
+ - Desktop Local is not a teleport target yet. Use the Desktop environment
478091
+ picker to switch back to Local.
478092
+ - Output is JSON only.
478093
+ `.trim());
478094
+ }
478095
+ function parseTeleportArgs(argv) {
478096
+ return parseArgs17({
478097
+ args: argv,
478098
+ options: TELEPORT_OPTIONS,
478099
+ strict: true,
478100
+ allowPositionals: true
478101
+ });
478102
+ }
478103
+ function getEnvironmentSession2(env5) {
478104
+ const agentId = (env5.LETTA_AGENT_ID || env5.AGENT_ID || "").trim();
478105
+ const conversationId = (env5.LETTA_CONVERSATION_ID || env5.CONVERSATION_ID || "").trim();
478106
+ if (!agentId && !conversationId)
478107
+ return null;
478108
+ if (!agentId || !conversationId) {
478109
+ throw new Error("Both agent and conversation context are required when either is set");
478110
+ }
478111
+ return { agentId, conversationId };
478112
+ }
478113
+ function resolveTeleportSession(env5, fallback) {
478114
+ const session = getEnvironmentSession2(env5) ?? fallback;
478115
+ if (!session) {
478116
+ throw new Error("No active agent conversation found");
478117
+ }
478118
+ if (isLocalAgentId(session.agentId)) {
478119
+ throw new Error("Teleport requires a Letta Cloud agent");
478120
+ }
478121
+ if (!session.conversationId || session.conversationId === "default" || session.conversationId === "new") {
478122
+ throw new Error("Teleport requires an active conversation");
478123
+ }
478124
+ return session;
478125
+ }
478126
+ function formatTeleportApiError(error54) {
478127
+ if (error54 instanceof ApiRequestError) {
478128
+ try {
478129
+ const body3 = JSON.parse(error54.responseText);
478130
+ if (typeof body3.message === "string" && body3.message.length > 0) {
478131
+ return body3.message;
478132
+ }
478133
+ if (typeof body3.errorCode === "string" && body3.errorCode.length > 0) {
478134
+ return body3.errorCode;
478135
+ }
478136
+ } catch {}
478137
+ return `API error (${error54.status}): ${error54.responseText}`;
478138
+ }
478139
+ if (error54 instanceof Error) {
478140
+ return error54.message;
478141
+ }
478142
+ return String(error54);
478143
+ }
478144
+ function formatEnvironmentForList(environment2) {
478145
+ return {
478146
+ deviceId: environment2.deviceId,
478147
+ connectionName: environment2.connectionName,
478148
+ connectionId: environment2.connectionId ?? null
478149
+ };
478150
+ }
478151
+ function isTeleportableRemoteEnvironment(environment2) {
478152
+ return environment2.organizationId !== "local" && !environment2.connectionId?.startsWith("local-");
478153
+ }
478154
+ function assertTeleportableRemoteEnvironment(environment2) {
478155
+ if (!isTeleportableRemoteEnvironment(environment2)) {
478156
+ throw new Error("Desktop Local is not a teleport target yet. Use the Desktop environment picker to switch back to Local.");
478157
+ }
478158
+ }
478159
+ async function initializeTeleportSettings() {
478160
+ await settingsManager.initialize();
478161
+ await settingsManager.loadLocalProjectSettings();
478162
+ }
478163
+ async function runTeleportSubcommand(argv, deps = {}) {
478164
+ let parsed;
478165
+ try {
478166
+ parsed = parseTeleportArgs(argv);
478167
+ } catch (error54) {
478168
+ console.error(`Error: ${error54 instanceof Error ? error54.message : error54}`);
478169
+ printUsage15();
478170
+ return 1;
478171
+ }
478172
+ const [action3] = parsed.positionals;
478173
+ if (parsed.values.help || !action3 || action3 === "help") {
478174
+ printUsage15();
478175
+ return 0;
478176
+ }
478177
+ try {
478178
+ await (deps.initializeSettings ?? initializeTeleportSettings)();
478179
+ if (action3 === "list") {
478180
+ const list = deps.listEnvironments ?? listEnvironments;
478181
+ const result2 = await list({ limit: 100, onlineOnly: true });
478182
+ const connections = result2.connections.filter((environment2) => isEnvironmentOnline(environment2) && isTeleportableRemoteEnvironment(environment2)).map(formatEnvironmentForList);
478183
+ console.log(JSON.stringify({ ...result2, connections }, null, 2));
478184
+ return 0;
478185
+ }
478186
+ const session = resolveTeleportSession(process.env, (deps.getLastSession ?? (() => settingsManager.getEffectiveLastSession()))());
478187
+ let targetConnectionId;
478188
+ if (action3 === "cloud") {
478189
+ const resolve35 = deps.resolveAgentSandboxConnectionId ?? resolveAgentSandboxConnectionId;
478190
+ const result2 = await resolve35(session.agentId, {
478191
+ conversationId: session.conversationId
478192
+ });
478193
+ targetConnectionId = result2.connectionId;
478194
+ } else if (action3 === "back") {
478195
+ throw new Error("Teleport back is not supported yet. Use the Desktop environment picker to switch back to Local.");
478196
+ } else {
478197
+ const resolve35 = deps.resolveEnvironmentConnectionId ?? resolveEnvironmentConnectionId;
478198
+ const resolved = await resolve35(action3);
478199
+ assertTeleportableRemoteEnvironment(resolved.environment);
478200
+ targetConnectionId = resolved.connectionId;
478201
+ }
478202
+ const teleport = deps.teleportToEnvironment ?? teleportToEnvironment;
478203
+ const result = await teleport(session.agentId, session.conversationId, targetConnectionId);
478204
+ console.log(JSON.stringify(result, null, 2));
478205
+ return 0;
478206
+ } catch (error54) {
478207
+ console.error(`Error: ${formatTeleportApiError(error54)}`);
478208
+ return 1;
478209
+ }
478210
+ }
478211
+ var TELEPORT_OPTIONS;
478212
+ var init_teleport2 = __esm(() => {
478213
+ init_environments2();
478214
+ init_request();
478215
+ init_settings_manager();
478216
+ TELEPORT_OPTIONS = {
478217
+ help: { type: "boolean", short: "h" }
478218
+ };
478219
+ });
478220
+
477593
478221
  // src/cli/subcommands/trajectories/readers.ts
477594
478222
  import { readdir as readdir15, readFile as readFile26, stat as stat16 } from "node:fs/promises";
477595
478223
  import { join as join74 } from "node:path";
@@ -477975,8 +478603,8 @@ var init_review = () => {};
477975
478603
 
477976
478604
  // src/cli/subcommands/trajectories.ts
477977
478605
  import { readFile as readFile29 } from "node:fs/promises";
477978
- import { parseArgs as parseArgs17 } from "node:util";
477979
- function printUsage15() {
478606
+ import { parseArgs as parseArgs18 } from "node:util";
478607
+ function printUsage16() {
477980
478608
  console.log(`
477981
478609
  Usage:
477982
478610
  letta trajectories export [options]
@@ -478114,7 +478742,7 @@ ${results.length} session(s) matched "${keyword}"`);
478114
478742
  return 0;
478115
478743
  }
478116
478744
  function parseTrajectoriesArgs(argv) {
478117
- return parseArgs17({
478745
+ return parseArgs18({
478118
478746
  args: argv,
478119
478747
  options: TRAJECTORIES_OPTIONS,
478120
478748
  strict: true,
@@ -478127,12 +478755,12 @@ async function runTrajectoriesSubcommand(argv) {
478127
478755
  parsed = parseTrajectoriesArgs(argv);
478128
478756
  } catch (error54) {
478129
478757
  console.error(`Error: ${error54 instanceof Error ? error54.message : String(error54)}`);
478130
- printUsage15();
478758
+ printUsage16();
478131
478759
  return 1;
478132
478760
  }
478133
478761
  const [action3] = parsed.positionals;
478134
478762
  if (parsed.values.help || action3 === "help" || !action3) {
478135
- printUsage15();
478763
+ printUsage16();
478136
478764
  return parsed.values.help || action3 === "help" ? 0 : 1;
478137
478765
  }
478138
478766
  const asJson = Boolean(parsed.values.json);
@@ -478164,7 +478792,7 @@ async function runTrajectoriesSubcommand(argv) {
478164
478792
  }
478165
478793
  if (action3 !== "export") {
478166
478794
  console.error(`Unknown command: ${action3}`);
478167
- printUsage15();
478795
+ printUsage16();
478168
478796
  return 1;
478169
478797
  }
478170
478798
  const options3 = {
@@ -479457,20 +480085,9 @@ function listEligibleProactiveSlackAccounts(params) {
479457
480085
  if (!registry2) {
479458
480086
  return [];
479459
480087
  }
479460
- loadRoutes("slack");
479461
- const seen = new Set;
479462
480088
  const eligible = [];
479463
- for (const route of getRoutesForChannel("slack")) {
479464
- if (route.agentId !== params.agentId || route.conversationId !== params.conversationId || !route.enabled || route.outboundEnabled === false) {
479465
- continue;
479466
- }
479467
- const accountId = route.accountId ?? LEGACY_CHANNEL_ACCOUNT_ID;
479468
- if (seen.has(accountId)) {
479469
- continue;
479470
- }
479471
- seen.add(accountId);
479472
- const account = getChannelAccount("slack", accountId);
479473
- if (!account || !isSlackChannelAccount(account) || account.agentId !== params.agentId) {
480089
+ for (const account of listChannelAccounts("slack")) {
480090
+ if (!account.enabled || !isSlackChannelAccount(account) || account.agentId !== params.agentId) {
479474
480091
  continue;
479475
480092
  }
479476
480093
  const adapter = registry2.getAdapter("slack", account.accountId);
@@ -479486,8 +480103,7 @@ function listEligibleProactiveSlackAccounts(params) {
479486
480103
  }
479487
480104
  function resolveEligibleProactiveSlackAccount(params) {
479488
480105
  const eligible = listEligibleProactiveSlackAccounts({
479489
- agentId: params.agentId,
479490
- conversationId: params.conversationId
480106
+ agentId: params.agentId
479491
480107
  });
479492
480108
  if (params.accountId) {
479493
480109
  const matched = eligible.find(({ account }) => account.accountId === params.accountId);
@@ -479507,10 +480123,65 @@ function resolveEligibleProactiveSlackAccount(params) {
479507
480123
  var init_proactive_accounts = __esm(() => {
479508
480124
  init_accounts();
479509
480125
  init_registry();
479510
- init_routing();
479511
480126
  init_types8();
479512
480127
  });
479513
480128
 
480129
+ // src/channels/slack/proactive-route.ts
480130
+ function bindProactiveSlackThreadRoute(params) {
480131
+ loadRoutes("slack");
480132
+ const existing = getRouteRaw("slack", params.chatId, params.accountId, params.rootMessageId);
480133
+ if (existing) {
480134
+ if (existing.agentId === params.agentId && existing.conversationId === params.conversationId) {
480135
+ return;
480136
+ }
480137
+ throw new Error(`Slack thread ${params.accountId}/${params.chatId}/${params.rootMessageId} is already routed to ${existing.agentId}/${existing.conversationId}`);
480138
+ }
480139
+ const now = new Date().toISOString();
480140
+ try {
480141
+ addRoute("slack", {
480142
+ accountId: params.accountId,
480143
+ chatId: params.chatId,
480144
+ chatType: "channel",
480145
+ threadId: params.rootMessageId,
480146
+ agentId: params.agentId,
480147
+ conversationId: params.conversationId,
480148
+ enabled: true,
480149
+ outboundEnabled: true,
480150
+ createdAt: now,
480151
+ updatedAt: now
480152
+ });
480153
+ } catch (error54) {
480154
+ removeRouteInMemory("slack", params.chatId, params.accountId, params.rootMessageId);
480155
+ throw error54;
480156
+ }
480157
+ }
480158
+ function createProactiveSlackTransport(params) {
480159
+ return {
480160
+ sendMessage: async (message) => {
480161
+ const result = await params.adapter.sendMessage(message);
480162
+ const isRootChannelPost = params.target.chatType === "channel" && !message.threadId?.trim() && !message.replyToMessageId?.trim() && !message.reaction;
480163
+ if (isRootChannelPost && result.messageId.trim()) {
480164
+ try {
480165
+ bindProactiveSlackThreadRoute({
480166
+ accountId: params.accountId,
480167
+ chatId: params.target.chatId,
480168
+ rootMessageId: result.messageId,
480169
+ agentId: params.agentId,
480170
+ conversationId: params.conversationId
480171
+ });
480172
+ } catch (error54) {
480173
+ console.error(`[Channels] Failed to bind proactive Slack thread: ${error54 instanceof Error ? error54.message : String(error54)}`);
480174
+ throw new Error(`Slack accepted message ${result.messageId}, but its thread route could not be persisted: ${error54 instanceof Error ? error54.message : String(error54)}`);
480175
+ }
480176
+ }
480177
+ return result;
480178
+ }
480179
+ };
480180
+ }
480181
+ var init_proactive_route = __esm(() => {
480182
+ init_routing();
480183
+ });
480184
+
479514
480185
  // src/tools/impl/message-channel.ts
479515
480186
  function createLocalMessageChannelResolver() {
479516
480187
  return {
@@ -479546,7 +480217,6 @@ function createLocalMessageChannelResolver() {
479546
480217
  }
479547
480218
  const eligibleAccount = resolveEligibleProactiveSlackAccount({
479548
480219
  agentId: params.scope.agentId,
479549
- conversationId: params.scope.conversationId,
479550
480220
  accountId: params.accountId
479551
480221
  });
479552
480222
  if (typeof eligibleAccount === "string")
@@ -479564,7 +480234,13 @@ function createLocalMessageChannelResolver() {
479564
480234
  return {
479565
480235
  accountId: eligibleAccount.account.accountId,
479566
480236
  target: target2,
479567
- transport: eligibleAccount.adapter,
480237
+ transport: createProactiveSlackTransport({
480238
+ adapter: eligibleAccount.adapter,
480239
+ accountId: eligibleAccount.account.accountId,
480240
+ target: target2,
480241
+ agentId: params.scope.agentId,
480242
+ conversationId: params.scope.conversationId
480243
+ }),
479568
480244
  messageActions
479569
480245
  };
479570
480246
  }
@@ -479593,6 +480269,7 @@ var init_message_channel = __esm(() => {
479593
480269
  init_plugin_registry();
479594
480270
  init_registry();
479595
480271
  init_proactive_accounts();
480272
+ init_proactive_route();
479596
480273
  });
479597
480274
 
479598
480275
  // src/channels/channel-rich-draft-streamer.ts
@@ -480660,6 +481337,38 @@ class ChannelGateway {
480660
481337
  });
480661
481338
  });
480662
481339
  }
481340
+ async publishRuntimeTools(runtime, sources = []) {
481341
+ return await this.enqueueRegistration(async () => {
481342
+ if (this.states.has(runtimeKey(runtime)))
481343
+ return false;
481344
+ const tool2 = await this.hooks.buildExternalTool(runtime, sources);
481345
+ const response = await this.client.runtimeExternalToolsUpdate({
481346
+ updates: [
481347
+ {
481348
+ runtimes: [runtime],
481349
+ external_tools: tool2 ? [{ tools: [tool2] }] : []
481350
+ }
481351
+ ]
481352
+ });
481353
+ if (!response.success) {
481354
+ throw new Error(response.error ?? "Failed to publish channel runtime tools");
481355
+ }
481356
+ return tool2 !== null;
481357
+ });
481358
+ }
481359
+ async releaseRuntimeTools(runtime, routedSources = []) {
481360
+ await this.enqueueRegistration(async () => {
481361
+ if (routedSources.length > 0 || this.states.has(runtimeKey(runtime))) {
481362
+ return;
481363
+ }
481364
+ const response = await this.client.runtimeExternalToolsUpdate({
481365
+ updates: [{ runtimes: [runtime], external_tools: [] }]
481366
+ });
481367
+ if (!response.success) {
481368
+ throw new Error(response.error ?? "Failed to release channel runtime tools");
481369
+ }
481370
+ });
481371
+ }
480663
481372
  async submitApprovalResponse(runtime, response) {
480664
481373
  const result = await this.client.submitInput({
480665
481374
  runtime,
@@ -481268,29 +481977,37 @@ var init_message_tool = __esm(() => {
481268
481977
  });
481269
481978
 
481270
481979
  // src/channels/message-channel-gateway-tool.ts
481271
- async function buildGatewayMessageChannelTool(sources) {
481272
- if (sources.length === 0)
481273
- return null;
481980
+ async function buildGatewayMessageChannelTool(sources, runtime) {
481274
481981
  const seen = new Set;
481275
- const channels = sources.map((source2) => ({
481982
+ const channelScopes = (sources.length > 0 ? sources.map((source2) => ({
481276
481983
  channelId: source2.channel,
481277
481984
  accountId: source2.accountId ?? null
481278
- })).filter(({ channelId, accountId }) => {
481985
+ })) : runtime ? listEligibleProactiveSlackAccounts({
481986
+ agentId: runtime.agent_id
481987
+ }).map(({ account }) => ({
481988
+ channelId: "slack",
481989
+ accountId: account.accountId
481990
+ })) : []).filter(({ channelId, accountId }) => {
481279
481991
  const key2 = `${channelId}:${accountId ?? ""}`;
481280
481992
  if (seen.has(key2))
481281
481993
  return false;
481282
481994
  seen.add(key2);
481283
481995
  return true;
481284
481996
  });
481997
+ if (channelScopes.length === 0)
481998
+ return null;
481285
481999
  return buildMessageChannelExternalToolDefinition({
481286
- channels: await resolveLocalMessageChannelToolChannels({ channels }),
481287
- scoped: true,
482000
+ channels: await resolveLocalMessageChannelToolChannels({
482001
+ channels: channelScopes
482002
+ }),
482003
+ scoped: sources.length > 0,
481288
482004
  allowProactiveTargets: true
481289
482005
  });
481290
482006
  }
481291
482007
  var init_message_channel_gateway_tool = __esm(() => {
481292
482008
  init_message_channel_tool_definition();
481293
482009
  init_message_tool();
482010
+ init_proactive_accounts();
481294
482011
  });
481295
482012
 
481296
482013
  // src/channels/custom/scaffolding.ts
@@ -482102,7 +482819,9 @@ function groupSourcesByRuntime(sources) {
482102
482819
  }
482103
482820
  return [...sourcesByRuntime.values()];
482104
482821
  }
482105
- function toolScopeKey(sources) {
482822
+ function toolScopeKey(sources, runtime) {
482823
+ if (sources.length === 0)
482824
+ return `proactive:${runtime.agent_id}`;
482106
482825
  return JSON.stringify([
482107
482826
  ...new Set(sources.map((source2) => `${source2.channel}:${source2.accountId ?? ""}`))
482108
482827
  ].sort());
@@ -482111,13 +482830,20 @@ async function buildDesiredRegistrations(registry2, channelNames, buildTool, kno
482111
482830
  for (const channel of channelNames)
482112
482831
  loadRoutes(channel);
482113
482832
  const groupedSources = groupSourcesByRuntime(registry2.resolveRoutedTurnSources());
482833
+ const sourcesByRuntime = new Map(groupedSources.map((entry) => [runtimeKey2(entry.runtime), entry]));
482834
+ for (const runtime of knownRuntimes) {
482835
+ const key2 = runtimeKey2(runtime);
482836
+ if (!sourcesByRuntime.has(key2)) {
482837
+ sourcesByRuntime.set(key2, { runtime, sources: [] });
482838
+ }
482839
+ }
482114
482840
  const desired = new Map;
482115
482841
  const toolsByScope = new Map;
482116
- await Promise.all(groupedSources.map(async ({ runtime, sources }) => {
482117
- const scopeKey = toolScopeKey(sources);
482842
+ await Promise.all([...sourcesByRuntime.values()].map(async ({ runtime, sources }) => {
482843
+ const scopeKey = toolScopeKey(sources, runtime);
482118
482844
  let toolPromise = toolsByScope.get(scopeKey);
482119
482845
  if (!toolPromise) {
482120
- toolPromise = buildTool(sources);
482846
+ toolPromise = buildTool(sources, runtime);
482121
482847
  toolsByScope.set(scopeKey, toolPromise);
482122
482848
  }
482123
482849
  const tool2 = await toolPromise;
@@ -482129,18 +482855,6 @@ async function buildDesiredRegistrations(registry2, channelNames, buildTool, kno
482129
482855
  signature: JSON.stringify(externalTools)
482130
482856
  });
482131
482857
  }));
482132
- for (const runtime of knownRuntimes) {
482133
- const key2 = runtimeKey2(runtime);
482134
- if (desired.has(key2))
482135
- continue;
482136
- const externalTools = [];
482137
- desired.set(key2, {
482138
- runtime,
482139
- sources: [],
482140
- externalTools,
482141
- signature: JSON.stringify(externalTools)
482142
- });
482143
- }
482144
482858
  return desired;
482145
482859
  }
482146
482860
  function buildUpdateGroups(desired, publishedSignatures) {
@@ -482467,8 +483181,8 @@ async function startLocalChannelGateway(options3) {
482467
483181
  dispose: () => streamer.dispose()
482468
483182
  } : null;
482469
483183
  },
482470
- buildExternalTool: async (runtime) => {
482471
- return buildGatewayMessageChannelTool(registry2.resolveTurnSourcesForScope(runtime.agent_id, runtime.conversation_id));
483184
+ buildExternalTool: async (runtime, sources) => {
483185
+ return buildGatewayMessageChannelTool(sources, runtime);
482472
483186
  },
482473
483187
  executeExternalTool: async (request2, sources, idempotencyScope) => {
482474
483188
  if (request2.tool_name !== "MessageChannel" || !request2.runtime) {
@@ -482743,7 +483457,17 @@ async function startLocalChannelGateway(options3) {
482743
483457
  executeCommand: async (command) => {
482744
483458
  let result;
482745
483459
  try {
482746
- result = await executeGatewayServiceCommand(command);
483460
+ if (command.kind === "publish_runtime_tools") {
483461
+ const sources = registry2.resolveTurnSourcesForScope(command.runtime.agent_id, command.runtime.conversation_id);
483462
+ const transient = await gateway.publishRuntimeTools(command.runtime, sources);
483463
+ result = { kind: "runtime_tools_published", transient };
483464
+ } else if (command.kind === "release_runtime_tools") {
483465
+ const sources = registry2.resolveTurnSourcesForScope(command.runtime.agent_id, command.runtime.conversation_id);
483466
+ await gateway.releaseRuntimeTools(command.runtime, sources);
483467
+ result = { kind: "runtime_tools_released" };
483468
+ } else {
483469
+ result = await executeGatewayServiceCommand(command);
483470
+ }
482747
483471
  } catch (error54) {
482748
483472
  routedRuntimeRegistrationRefresher.requestRefresh();
482749
483473
  throw error54;
@@ -482789,14 +483513,14 @@ var exports_channel_gateway = {};
482789
483513
  __export(exports_channel_gateway, {
482790
483514
  runChannelGatewaySubcommand: () => runChannelGatewaySubcommand
482791
483515
  });
482792
- import { parseArgs as parseArgs18 } from "node:util";
483516
+ import { parseArgs as parseArgs19 } from "node:util";
482793
483517
  function isGatewayCommandEnvelope(value) {
482794
483518
  return Boolean(value && typeof value === "object" && "type" in value && value.type === "command" && "requestId" in value && typeof value.requestId === "string" && "command" in value && value.command && typeof value.command === "object");
482795
483519
  }
482796
483520
  async function runChannelGatewaySubcommand(argv) {
482797
483521
  let values2;
482798
483522
  try {
482799
- ({ values: values2 } = parseArgs18({
483523
+ ({ values: values2 } = parseArgs19({
482800
483524
  args: argv,
482801
483525
  strict: true,
482802
483526
  allowPositionals: false,
@@ -482936,6 +483660,7 @@ function subcommandNeedsEarlyBackendMode(command) {
482936
483660
  case "server":
482937
483661
  case "shared-memory":
482938
483662
  case "skills":
483663
+ case "teleport":
482939
483664
  return true;
482940
483665
  default:
482941
483666
  return false;
@@ -482969,6 +483694,8 @@ async function runSubcommand(argv) {
482969
483694
  return runModsSubcommand(rest3);
482970
483695
  case "sandbox":
482971
483696
  return runSandboxSubcommand(rest3);
483697
+ case "teleport":
483698
+ return runTeleportSubcommand(rest3);
482972
483699
  case "server":
482973
483700
  return runServerSubcommand(rest3);
482974
483701
  case "remote":
@@ -483017,6 +483744,7 @@ var init_router = __esm(async () => {
483017
483744
  init_sandbox2();
483018
483745
  init_shared_memory();
483019
483746
  init_skills4();
483747
+ init_teleport2();
483020
483748
  init_trajectories();
483021
483749
  await __promiseAll([
483022
483750
  init_cron2(),
@@ -483311,7 +484039,7 @@ function resolveListMessagesRoute(listReq, sessionConvId, sessionAgentId) {
483311
484039
  }
483312
484040
 
483313
484041
  // src/agent/bootstrap-handler.ts
483314
- import { randomUUID as randomUUID32 } from "node:crypto";
484042
+ import { randomUUID as randomUUID33 } from "node:crypto";
483315
484043
  async function handleBootstrapSessionState(params) {
483316
484044
  const {
483317
484045
  bootstrapReq,
@@ -483360,7 +484088,7 @@ async function handleBootstrapSessionState(params) {
483360
484088
  response: payload
483361
484089
  },
483362
484090
  session_id: sessionContext.sessionId,
483363
- uuid: randomUUID32()
484091
+ uuid: randomUUID33()
483364
484092
  };
483365
484093
  } catch (err) {
483366
484094
  return {
@@ -483371,14 +484099,14 @@ async function handleBootstrapSessionState(params) {
483371
484099
  error: err instanceof Error ? err.message : "bootstrap_session_state failed"
483372
484100
  },
483373
484101
  session_id: sessionContext.sessionId,
483374
- uuid: randomUUID32()
484102
+ uuid: randomUUID33()
483375
484103
  };
483376
484104
  }
483377
484105
  }
483378
484106
  var init_bootstrap_handler = () => {};
483379
484107
 
483380
484108
  // src/agent/list-messages-handler.ts
483381
- import { randomUUID as randomUUID33 } from "node:crypto";
484109
+ import { randomUUID as randomUUID34 } from "node:crypto";
483382
484110
  async function handleListMessages(params) {
483383
484111
  const {
483384
484112
  listReq,
@@ -483418,7 +484146,7 @@ async function handleListMessages(params) {
483418
484146
  response: payload
483419
484147
  },
483420
484148
  session_id: sessionId,
483421
- uuid: randomUUID33()
484149
+ uuid: randomUUID34()
483422
484150
  };
483423
484151
  } catch (err) {
483424
484152
  return {
@@ -483429,7 +484157,7 @@ async function handleListMessages(params) {
483429
484157
  error: err instanceof Error ? err.message : "list_messages failed"
483430
484158
  },
483431
484159
  session_id: sessionId,
483432
- uuid: randomUUID33()
484160
+ uuid: randomUUID34()
483433
484161
  };
483434
484162
  }
483435
484163
  }
@@ -483616,6 +484344,105 @@ var init_local_backend_mod_events = __esm(() => {
483616
484344
  init_local_backend();
483617
484345
  });
483618
484346
 
484347
+ // src/headless-environment-response.ts
484348
+ function pageItems5(page) {
484349
+ if (Array.isArray(page))
484350
+ return page;
484351
+ if (page && typeof page === "object") {
484352
+ const maybePage = page;
484353
+ if (typeof maybePage.getPaginatedItems === "function") {
484354
+ return maybePage.getPaginatedItems();
484355
+ }
484356
+ if (Array.isArray(maybePage.items)) {
484357
+ return maybePage.items;
484358
+ }
484359
+ }
484360
+ return [];
484361
+ }
484362
+ function extractMessageText(message) {
484363
+ const content = message.content;
484364
+ if (typeof content === "string")
484365
+ return content;
484366
+ if (Array.isArray(content)) {
484367
+ return content.map((part) => {
484368
+ if (part && typeof part === "object" && "type" in part && part.type === "text" && "text" in part && typeof part.text === "string") {
484369
+ return part.text;
484370
+ }
484371
+ return "";
484372
+ }).filter(Boolean).join(`
484373
+ `);
484374
+ }
484375
+ return "";
484376
+ }
484377
+ function isAssistantMessage2(message) {
484378
+ return message.message_type === "assistant_message";
484379
+ }
484380
+ function isUserMessage(message) {
484381
+ return message.message_type === "user_message";
484382
+ }
484383
+ function messageRunId(message) {
484384
+ if (!message)
484385
+ return null;
484386
+ const runId = message.run_id;
484387
+ return typeof runId === "string" && runId.length > 0 ? runId : null;
484388
+ }
484389
+ function messageSequenceId(message) {
484390
+ const sequenceId = message.seq_id;
484391
+ return typeof sequenceId === "number" ? sequenceId : null;
484392
+ }
484393
+ async function waitForEnvironmentAssistantMessage(params) {
484394
+ const timeoutMs = params.timeoutMs ?? 10 * 60000;
484395
+ const pollIntervalMs = params.pollIntervalMs ?? 1000;
484396
+ const deadline = Date.now() + timeoutMs;
484397
+ let inputSequenceId = null;
484398
+ while (Date.now() < deadline) {
484399
+ const page = params.conversationId === "default" ? await params.backend.listAgentMessages(params.agentId, {
484400
+ conversation_id: "default",
484401
+ limit: 50,
484402
+ order: "desc"
484403
+ }) : await params.backend.listConversationMessages(params.conversationId, {
484404
+ limit: 50,
484405
+ order: "desc"
484406
+ });
484407
+ const messages = pageItems5(page);
484408
+ if (inputSequenceId === null) {
484409
+ const inputMessage = messages.find((message) => isUserMessage(message) && message.otid === params.otid);
484410
+ inputSequenceId = inputMessage ? messageSequenceId(inputMessage) : null;
484411
+ }
484412
+ if (inputSequenceId !== null) {
484413
+ const anchorSequenceId = inputSequenceId;
484414
+ const newerMessages = messages.filter((message) => {
484415
+ const sequenceId = messageSequenceId(message);
484416
+ return sequenceId !== null && sequenceId > anchorSequenceId;
484417
+ });
484418
+ const nextUserSequenceId = newerMessages.reduce((closest, message) => {
484419
+ if (!isUserMessage(message))
484420
+ return closest;
484421
+ const sequenceId = messageSequenceId(message);
484422
+ if (sequenceId === null)
484423
+ return closest;
484424
+ return closest === null || sequenceId < closest ? sequenceId : closest;
484425
+ }, null);
484426
+ const assistant = newerMessages.filter((message) => {
484427
+ const sequenceId = messageSequenceId(message);
484428
+ return isAssistantMessage2(message) && sequenceId !== null && (nextUserSequenceId === null || sequenceId < nextUserSequenceId);
484429
+ }).sort((a2, b3) => (messageSequenceId(b3) ?? 0) - (messageSequenceId(a2) ?? 0))[0];
484430
+ const runId = messageRunId(assistant);
484431
+ if (runId) {
484432
+ const run = await params.backend.retrieveRun(runId);
484433
+ if ((run.status === "completed" || run.status === "failed" || run.status === "cancelled") && run.stop_reason !== "requires_approval") {
484434
+ const text2 = assistant ? extractMessageText(assistant).trim() : "";
484435
+ if (text2.length > 0) {
484436
+ return { text: text2, stopReason: run.stop_reason ?? null };
484437
+ }
484438
+ }
484439
+ }
484440
+ }
484441
+ await new Promise((resolve35) => setTimeout(resolve35, pollIntervalMs));
484442
+ }
484443
+ throw new Error("Timed out waiting for environment turn completion");
484444
+ }
484445
+
483619
484446
  // src/headless-memfs-policy.ts
483620
484447
  function resolveHeadlessMemfsPolicy(options3) {
483621
484448
  const isFreshStatelessSubagent = options3.isSubagentRole && options3.newAgentRequested;
@@ -495053,7 +495880,7 @@ var init_mcp_client = __esm(() => {
495053
495880
  init_streamableHttp();
495054
495881
  DEFAULT_CLIENT_INFO = {
495055
495882
  name: "letta-code",
495056
- version: "0.30.19"
495883
+ version: "0.30.20"
495057
495884
  };
495058
495885
  });
495059
495886
 
@@ -496092,7 +496919,7 @@ __export(exports_headless, {
496092
496919
  decideInterruptAction: () => decideInterruptAction,
496093
496920
  __headlessTestUtils: () => __headlessTestUtils
496094
496921
  });
496095
- import { randomUUID as randomUUID34 } from "node:crypto";
496922
+ import { randomUUID as randomUUID35 } from "node:crypto";
496096
496923
  function trackHeadlessBoundaryError(errorType, error54, context3) {
496097
496924
  trackBoundaryError({
496098
496925
  errorType,
@@ -496114,7 +496941,7 @@ async function reportStartupErrorAndExit(errorType, error54, context3, outputFor
496114
496941
  message,
496115
496942
  stop_reason: "error",
496116
496943
  session_id: "startup",
496117
- uuid: `startup-error-${randomUUID34()}`
496944
+ uuid: `startup-error-${randomUUID35()}`
496118
496945
  };
496119
496946
  await writeWireMessageAsync(errorMsg);
496120
496947
  } else {
@@ -496238,7 +497065,7 @@ async function emitHeadlessTurnStartCancellationOutput(options3) {
496238
497065
  message: options3.reason,
496239
497066
  stop_reason: "cancelled",
496240
497067
  session_id: options3.sessionId,
496241
- uuid: `error-turn-start-cancel-${randomUUID34()}`
497068
+ uuid: `error-turn-start-cancel-${randomUUID35()}`
496242
497069
  };
496243
497070
  await writeWireMessageAsync(errorMsg);
496244
497071
  const resultMsg = {
@@ -496253,7 +497080,7 @@ async function emitHeadlessTurnStartCancellationOutput(options3) {
496253
497080
  conversation_id: options3.conversationId,
496254
497081
  run_ids: [],
496255
497082
  usage: null,
496256
- uuid: `result-turn-start-cancel-${randomUUID34()}`,
497083
+ uuid: `result-turn-start-cancel-${randomUUID35()}`,
496257
497084
  stop_reason: "cancelled"
496258
497085
  };
496259
497086
  await writeWireMessageAsync(resultMsg);
@@ -496282,7 +497109,7 @@ function writeBidirectionalTurnStartCancellation(options3) {
496282
497109
  message: options3.reason,
496283
497110
  stop_reason: "cancelled",
496284
497111
  session_id: options3.sessionId,
496285
- uuid: `error-turn-start-cancel-${randomUUID34()}`
497112
+ uuid: `error-turn-start-cancel-${randomUUID35()}`
496286
497113
  };
496287
497114
  writeWireMessage(errorMsg);
496288
497115
  const resultMsg = {
@@ -496297,7 +497124,7 @@ function writeBidirectionalTurnStartCancellation(options3) {
496297
497124
  conversation_id: options3.conversationId,
496298
497125
  run_ids: [],
496299
497126
  usage: null,
496300
- uuid: `result-turn-start-cancel-${randomUUID34()}`,
497127
+ uuid: `result-turn-start-cancel-${randomUUID35()}`,
496301
497128
  stop_reason: "cancelled"
496302
497129
  };
496303
497130
  writeWireMessage(resultMsg);
@@ -496369,103 +497196,6 @@ async function writeFinalHeadlessStdout(text2) {
496369
497196
  process.stdout.write(text2, () => resolve37());
496370
497197
  });
496371
497198
  }
496372
- function pageItems5(page) {
496373
- if (Array.isArray(page))
496374
- return page;
496375
- if (page && typeof page === "object") {
496376
- const maybePage = page;
496377
- if (typeof maybePage.getPaginatedItems === "function") {
496378
- return maybePage.getPaginatedItems();
496379
- }
496380
- if (Array.isArray(maybePage.items)) {
496381
- return maybePage.items;
496382
- }
496383
- }
496384
- return [];
496385
- }
496386
- function extractMessageText(message) {
496387
- const content = message.content;
496388
- if (typeof content === "string")
496389
- return content;
496390
- if (Array.isArray(content)) {
496391
- return content.map((part) => {
496392
- if (part && typeof part === "object" && "type" in part && part.type === "text" && "text" in part && typeof part.text === "string") {
496393
- return part.text;
496394
- }
496395
- return "";
496396
- }).filter(Boolean).join(`
496397
- `);
496398
- }
496399
- return "";
496400
- }
496401
- function isAssistantMessage2(message) {
496402
- return message.message_type === "assistant_message";
496403
- }
496404
- function messageTime(message) {
496405
- const date6 = message.date ?? message.created_at;
496406
- return date6 ? new Date(date6).getTime() : 0;
496407
- }
496408
- function agentLastRunCompletionMs(agent2) {
496409
- const raw2 = agent2.last_run_completion;
496410
- if (typeof raw2 !== "string" || raw2.length === 0)
496411
- return null;
496412
- const ms = new Date(raw2).getTime();
496413
- return Number.isFinite(ms) ? ms : null;
496414
- }
496415
- function agentLastStopReason(agent2) {
496416
- const raw2 = agent2.last_stop_reason;
496417
- return typeof raw2 === "string" && raw2.length > 0 ? raw2 : null;
496418
- }
496419
- async function waitForEnvironmentAssistantMessage(params) {
496420
- const timeoutMs = params.timeoutMs ?? 10 * 60000;
496421
- const pollIntervalMs = params.pollIntervalMs ?? 1000;
496422
- const deadline = Date.now() + timeoutMs;
496423
- let lastText = "";
496424
- let postCompletionStableCount = 0;
496425
- let observedCompletion = false;
496426
- let observedStopReason = null;
496427
- while (Date.now() < deadline) {
496428
- const freshAgent = await params.backend.retrieveAgent(params.agentId);
496429
- const completionMs = agentLastRunCompletionMs(freshAgent);
496430
- const baselineCompletionMs = params.baselineLastRunCompletionMs ?? null;
496431
- const wasObservedCompletion = observedCompletion;
496432
- if (completionMs !== null && (baselineCompletionMs === null || completionMs > baselineCompletionMs) && completionMs >= params.startedAtMs - 5000) {
496433
- observedCompletion = true;
496434
- observedStopReason = agentLastStopReason(freshAgent);
496435
- if (!wasObservedCompletion) {
496436
- postCompletionStableCount = 0;
496437
- }
496438
- }
496439
- const page = params.conversationId === "default" ? await params.backend.listAgentMessages(params.agentId, {
496440
- conversation_id: "default",
496441
- limit: 50,
496442
- order: "desc"
496443
- }) : await params.backend.listConversationMessages(params.conversationId, {
496444
- limit: 50,
496445
- order: "desc"
496446
- });
496447
- const messages = pageItems5(page);
496448
- const assistant = messages.filter((message) => isAssistantMessage2(message) && messageTime(message) >= params.startedAtMs - 2000).sort((a2, b3) => messageTime(b3) - messageTime(a2))[0];
496449
- const text2 = assistant ? extractMessageText(assistant).trim() : "";
496450
- if (text2.length > 0) {
496451
- if (text2 === lastText) {
496452
- if (observedCompletion)
496453
- postCompletionStableCount += 1;
496454
- } else {
496455
- lastText = text2;
496456
- postCompletionStableCount = observedCompletion ? 1 : 0;
496457
- }
496458
- if (observedCompletion && postCompletionStableCount >= 2) {
496459
- return { text: text2, stopReason: observedStopReason };
496460
- }
496461
- }
496462
- await new Promise((resolve37) => setTimeout(resolve37, pollIntervalMs));
496463
- }
496464
- if (observedCompletion && lastText) {
496465
- return { text: lastText, stopReason: observedStopReason };
496466
- }
496467
- throw new Error("Timed out waiting for environment turn completion");
496468
- }
496469
497199
  function buildEnvironmentResponseMetadata(params) {
496470
497200
  return {
496471
497201
  source: params.source,
@@ -497247,7 +497977,7 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
497247
497977
  const approvalInput = {
497248
497978
  type: "approval",
497249
497979
  approvals: denialResults,
497250
- otid: randomUUID34()
497980
+ otid: randomUUID35()
497251
497981
  };
497252
497982
  const approvalMessages = [approvalInput];
497253
497983
  {
@@ -497260,7 +497990,7 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
497260
497990
  type: "text",
497261
497991
  text: sc.content
497262
497992
  })),
497263
- otid: randomUUID34()
497993
+ otid: randomUUID35()
497264
497994
  });
497265
497995
  }
497266
497996
  }
@@ -497293,7 +498023,7 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
497293
498023
  message: `Failed to resolve pending approvals on resume: ${approvalError instanceof Error ? approvalError.message : String(approvalError)}`,
497294
498024
  stop_reason: "error",
497295
498025
  session_id: sessionId,
497296
- uuid: `error-pre-loop-approval-${randomUUID34()}`
498026
+ uuid: `error-pre-loop-approval-${randomUUID35()}`
497297
498027
  };
497298
498028
  writeWireMessage(errorMsg);
497299
498029
  } else {
@@ -497432,8 +498162,7 @@ ${loadedContents.join(`
497432
498162
  }
497433
498163
  await exitHeadless(1, "headless_environment_unsupported");
497434
498164
  }
497435
- const startedAtMs = Date.now();
497436
- const baselineLastRunCompletionMs = agentLastRunCompletionMs(agent2);
498165
+ const otid = randomUUID35();
497437
498166
  await sendEnvironmentMessage(connectionId, {
497438
498167
  agentId: agent2.id,
497439
498168
  conversationId,
@@ -497441,8 +498170,8 @@ ${loadedContents.join(`
497441
498170
  {
497442
498171
  role: "user",
497443
498172
  content: contentParts,
497444
- client_message_id: randomUUID34(),
497445
- otid: randomUUID34()
498173
+ client_message_id: randomUUID35(),
498174
+ otid
497446
498175
  }
497447
498176
  ]
497448
498177
  });
@@ -497450,8 +498179,7 @@ ${loadedContents.join(`
497450
498179
  backend: backend3,
497451
498180
  agentId: agent2.id,
497452
498181
  conversationId,
497453
- startedAtMs,
497454
- baselineLastRunCompletionMs
498182
+ otid
497455
498183
  });
497456
498184
  const resultText2 = environmentResult.text;
497457
498185
  const stats2 = sessionStats.getSnapshot();
@@ -497499,7 +498227,7 @@ ${loadedContents.join(`
497499
498227
  {
497500
498228
  role: "user",
497501
498229
  content: contentParts,
497502
- otid: randomUUID34()
498230
+ otid: randomUUID35()
497503
498231
  }
497504
498232
  ];
497505
498233
  const recoveredApprovalResults = queuedRecoveredApprovalResults ?? [];
@@ -497508,7 +498236,7 @@ ${loadedContents.join(`
497508
498236
  {
497509
498237
  type: "approval",
497510
498238
  approvals: recoveredApprovalResults,
497511
- otid: randomUUID34()
498239
+ otid: randomUUID35()
497512
498240
  },
497513
498241
  ...currentInput
497514
498242
  ];
@@ -497555,7 +498283,7 @@ ${loadedContents.join(`
497555
498283
  message: `Maximum turns limit reached (${buffers.usage.stepCount}/${maxTurns} steps)`,
497556
498284
  stop_reason: "max_steps",
497557
498285
  session_id: sessionId,
497558
- uuid: `error-max-turns-${randomUUID34()}`
498286
+ uuid: `error-max-turns-${randomUUID35()}`
497559
498287
  };
497560
498288
  await writeWireMessageAsync(errorMsg);
497561
498289
  } else {
@@ -497572,7 +498300,7 @@ ${loadedContents.join(`
497572
498300
  message: "Interrupted by SIGINT",
497573
498301
  stop_reason: "cancelled",
497574
498302
  session_id: sessionId,
497575
- uuid: `error-interrupted-${randomUUID34()}`
498303
+ uuid: `error-interrupted-${randomUUID35()}`
497576
498304
  };
497577
498305
  await writeWireMessageAsync(errorMsg);
497578
498306
  } else {
@@ -497601,7 +498329,7 @@ ${loadedContents.join(`
497601
498329
  type: "text",
497602
498330
  text: sc.content
497603
498331
  })),
497604
- otid: randomUUID34()
498332
+ otid: randomUUID35()
497605
498333
  }
497606
498334
  ];
497607
498335
  }
@@ -497647,7 +498375,7 @@ ${loadedContents.join(`
497647
498375
  recovery_type: "approval_pending",
497648
498376
  message: "Detected pending approval conflict on send; resolving before retry",
497649
498377
  session_id: sessionId,
497650
- uuid: `recovery-pre-stream-${randomUUID34()}`
498378
+ uuid: `recovery-pre-stream-${randomUUID35()}`
497651
498379
  };
497652
498380
  writeWireMessage(recoveryMsg);
497653
498381
  } else {
@@ -497680,7 +498408,7 @@ ${loadedContents.join(`
497680
498408
  max_attempts: CONVERSATION_BUSY_MAX_RETRIES,
497681
498409
  delay_ms: retryDelayMs,
497682
498410
  session_id: sessionId,
497683
- uuid: `retry-conversation-busy-${randomUUID34()}`
498411
+ uuid: `retry-conversation-busy-${randomUUID35()}`
497684
498412
  };
497685
498413
  writeWireMessage(retryMsg);
497686
498414
  } else {
@@ -497704,7 +498432,7 @@ ${loadedContents.join(`
497704
498432
  type: "status",
497705
498433
  message: "Anthropic API error; falling back to Bedrock...",
497706
498434
  session_id: sessionId,
497707
- uuid: `fallback-${randomUUID34()}`
498435
+ uuid: `fallback-${randomUUID35()}`
497708
498436
  }));
497709
498437
  } else {
497710
498438
  console.error("Anthropic API error; falling back to Bedrock...");
@@ -497728,7 +498456,7 @@ ${loadedContents.join(`
497728
498456
  max_attempts: LLM_API_ERROR_MAX_RETRIES2,
497729
498457
  delay_ms: delayMs,
497730
498458
  session_id: sessionId,
497731
- uuid: `retry-pre-stream-${randomUUID34()}`
498459
+ uuid: `retry-pre-stream-${randomUUID35()}`
497732
498460
  };
497733
498461
  writeWireMessage(retryMsg);
497734
498462
  } else {
@@ -497754,7 +498482,7 @@ ${loadedContents.join(`
497754
498482
  stop_reason: "error",
497755
498483
  run_id: errorInfo.run_id,
497756
498484
  session_id: sessionId,
497757
- uuid: randomUUID34(),
498485
+ uuid: randomUUID35(),
497758
498486
  ...errorInfo.error_type && errorInfo.run_id && {
497759
498487
  api_error: {
497760
498488
  message_type: "error_message",
@@ -497776,7 +498504,7 @@ ${loadedContents.join(`
497776
498504
  message: "Detected pending approval conflict; auto-denying stale approval and retrying",
497777
498505
  run_id: recoveryRunId ?? undefined,
497778
498506
  session_id: sessionId,
497779
- uuid: `recovery-${recoveryRunId || randomUUID34()}`
498507
+ uuid: `recovery-${recoveryRunId || randomUUID35()}`
497780
498508
  };
497781
498509
  writeWireMessage(recoveryMsg);
497782
498510
  approvalPendingRecovery = true;
@@ -497794,7 +498522,7 @@ ${loadedContents.join(`
497794
498522
  type: "stream_event",
497795
498523
  event: chunk,
497796
498524
  session_id: sessionId,
497797
- uuid: uuid5 || randomUUID34()
498525
+ uuid: uuid5 || randomUUID35()
497798
498526
  };
497799
498527
  writeWireMessage(streamEvent);
497800
498528
  } else {
@@ -497802,7 +498530,7 @@ ${loadedContents.join(`
497802
498530
  type: "message",
497803
498531
  ...chunk,
497804
498532
  session_id: sessionId,
497805
- uuid: uuid5 || randomUUID34()
498533
+ uuid: uuid5 || randomUUID35()
497806
498534
  };
497807
498535
  writeWireMessage(msg);
497808
498536
  }
@@ -497845,7 +498573,7 @@ ${loadedContents.join(`
497845
498573
  {
497846
498574
  role: "user",
497847
498575
  content: continueMessage,
497848
- otid: randomUUID34()
498576
+ otid: randomUUID35()
497849
498577
  }
497850
498578
  ];
497851
498579
  const continueTurnStartEmission = await emitHeadlessTurnStart({
@@ -497917,7 +498645,7 @@ ${loadedContents.join(`
497917
498645
  const approvalInputWithOtid = {
497918
498646
  type: "approval",
497919
498647
  approvals: executedResults,
497920
- otid: randomUUID34()
498648
+ otid: randomUUID35()
497921
498649
  };
497922
498650
  currentInput = [approvalInputWithOtid];
497923
498651
  continue;
@@ -497947,7 +498675,7 @@ ${loadedContents.join(`
497947
498675
  type: "status",
497948
498676
  message: "Anthropic API error; falling back to Bedrock...",
497949
498677
  session_id: sessionId,
497950
- uuid: `fallback-${randomUUID34()}`
498678
+ uuid: `fallback-${randomUUID35()}`
497951
498679
  }));
497952
498680
  } else {
497953
498681
  console.error("Anthropic API error; falling back to Bedrock...");
@@ -497970,7 +498698,7 @@ ${loadedContents.join(`
497970
498698
  delay_ms: delayMs,
497971
498699
  run_id: lastRunId ?? undefined,
497972
498700
  session_id: sessionId,
497973
- uuid: `retry-${lastRunId || randomUUID34()}`
498701
+ uuid: `retry-${lastRunId || randomUUID35()}`
497974
498702
  };
497975
498703
  writeWireMessage(retryMsg);
497976
498704
  } else {
@@ -497991,7 +498719,7 @@ ${loadedContents.join(`
497991
498719
  message: "Tool call ID mismatch; fetching actual pending approvals and resyncing",
497992
498720
  run_id: lastRunId ?? undefined,
497993
498721
  session_id: sessionId,
497994
- uuid: `recovery-${lastRunId || randomUUID34()}`
498722
+ uuid: `recovery-${lastRunId || randomUUID35()}`
497995
498723
  };
497996
498724
  writeWireMessage(recoveryMsg);
497997
498725
  } else {
@@ -498008,7 +498736,7 @@ ${loadedContents.join(`
498008
498736
  stop_reason: stopReason,
498009
498737
  run_id: lastRunId ?? undefined,
498010
498738
  session_id: sessionId,
498011
- uuid: `error-${lastRunId || randomUUID34()}`
498739
+ uuid: `error-${lastRunId || randomUUID35()}`
498012
498740
  };
498013
498741
  await writeWireMessageAsync(errorMsg);
498014
498742
  } else {
@@ -498050,7 +498778,7 @@ ${loadedContents.join(`
498050
498778
  const nudgeMessage = {
498051
498779
  role: "system",
498052
498780
  content: `<system-reminder>The previous response was empty. Please provide a response with either text content or a tool call.</system-reminder>`,
498053
- otid: randomUUID34()
498781
+ otid: randomUUID35()
498054
498782
  };
498055
498783
  currentInput = [...currentInput, nudgeMessage];
498056
498784
  }
@@ -498063,7 +498791,7 @@ ${loadedContents.join(`
498063
498791
  delay_ms: delayMs,
498064
498792
  run_id: lastRunId ?? undefined,
498065
498793
  session_id: sessionId,
498066
- uuid: `retry-empty-${lastRunId || randomUUID34()}`
498794
+ uuid: `retry-empty-${lastRunId || randomUUID35()}`
498067
498795
  };
498068
498796
  writeWireMessage(retryMsg);
498069
498797
  } else {
@@ -498090,7 +498818,7 @@ ${loadedContents.join(`
498090
498818
  delay_ms: delayMs,
498091
498819
  run_id: lastRunId ?? undefined,
498092
498820
  session_id: sessionId,
498093
- uuid: `retry-${lastRunId || randomUUID34()}`
498821
+ uuid: `retry-${lastRunId || randomUUID35()}`
498094
498822
  };
498095
498823
  writeWireMessage(retryMsg);
498096
498824
  } else {
@@ -498120,7 +498848,7 @@ ${loadedContents.join(`
498120
498848
  delay_ms: delayMs,
498121
498849
  run_id: lastRunId ?? undefined,
498122
498850
  session_id: sessionId,
498123
- uuid: `retry-${lastRunId || randomUUID34()}`
498851
+ uuid: `retry-${lastRunId || randomUUID35()}`
498124
498852
  };
498125
498853
  writeWireMessage(retryMsg);
498126
498854
  } else {
@@ -498169,7 +498897,7 @@ ${loadedContents.join(`
498169
498897
  stop_reason: stopReason,
498170
498898
  run_id: lastRunId ?? undefined,
498171
498899
  session_id: sessionId,
498172
- uuid: `error-${lastRunId || randomUUID34()}`
498900
+ uuid: `error-${lastRunId || randomUUID35()}`
498173
498901
  };
498174
498902
  await writeWireMessageAsync(errorMsg);
498175
498903
  } else {
@@ -498188,7 +498916,7 @@ ${loadedContents.join(`
498188
498916
  stop_reason: "error",
498189
498917
  run_id: lastKnownRunId ?? undefined,
498190
498918
  session_id: sessionId,
498191
- uuid: `error-${lastKnownRunId || randomUUID34()}`
498919
+ uuid: `error-${lastKnownRunId || randomUUID35()}`
498192
498920
  };
498193
498921
  await writeWireMessageAsync(errorMsg);
498194
498922
  } else {
@@ -498385,7 +499113,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498385
499113
  const approvalInput = {
498386
499114
  type: "approval",
498387
499115
  approvals: denialResults,
498388
- otid: randomUUID34()
499116
+ otid: randomUUID35()
498389
499117
  };
498390
499118
  const approvalMessages = [approvalInput];
498391
499119
  {
@@ -498398,7 +499126,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498398
499126
  type: "text",
498399
499127
  text: sc.content
498400
499128
  })),
498401
- otid: randomUUID34()
499129
+ otid: randomUUID35()
498402
499130
  });
498403
499131
  }
498404
499132
  }
@@ -498456,7 +499184,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498456
499184
  reason,
498457
499185
  cleared_count: clearedCount,
498458
499186
  session_id: sessionId,
498459
- uuid: `q-clr-${randomUUID34()}`
499187
+ uuid: `q-clr-${randomUUID35()}`
498460
499188
  })
498461
499189
  }
498462
499190
  });
@@ -498486,7 +499214,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498486
499214
  reason: "runtime_busy",
498487
499215
  queue_len: Math.max(1, queueLen),
498488
499216
  session_id: sessionId,
498489
- uuid: `q-blk-${randomUUID34()}`
499217
+ uuid: `q-blk-${randomUUID35()}`
498490
499218
  });
498491
499219
  }
498492
499220
  function enqueueForTracking(input) {
@@ -498558,7 +499286,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498558
499286
  request_id: interruptRequestId
498559
499287
  },
498560
499288
  session_id: sessionId,
498561
- uuid: randomUUID34()
499289
+ uuid: randomUUID35()
498562
499290
  };
498563
499291
  writeWireMessage(interruptResponse);
498564
499292
  return;
@@ -498695,7 +499423,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498695
499423
  const approvalInput = {
498696
499424
  type: "approval",
498697
499425
  approvals: denialResults,
498698
- otid: randomUUID34()
499426
+ otid: randomUUID35()
498699
499427
  };
498700
499428
  const approvalStream = await sendScopedApprovalMessages({
498701
499429
  agentId: agent2.id,
@@ -498734,7 +499462,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498734
499462
  message: "Invalid JSON input",
498735
499463
  stop_reason: "error",
498736
499464
  session_id: sessionId,
498737
- uuid: randomUUID34()
499465
+ uuid: randomUUID35()
498738
499466
  };
498739
499467
  writeWireMessage(errorMsg2);
498740
499468
  continue;
@@ -498760,7 +499488,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498760
499488
  }
498761
499489
  },
498762
499490
  session_id: sessionId,
498763
- uuid: randomUUID34()
499491
+ uuid: randomUUID35()
498764
499492
  };
498765
499493
  writeWireMessage(initResponse);
498766
499494
  } else if (subtype === "interrupt") {
@@ -498777,7 +499505,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498777
499505
  request_id: requestId ?? ""
498778
499506
  },
498779
499507
  session_id: sessionId,
498780
- uuid: randomUUID34()
499508
+ uuid: randomUUID35()
498781
499509
  };
498782
499510
  writeWireMessage(interruptResponse);
498783
499511
  } else if (subtype === "register_external_tools") {
@@ -498825,7 +499553,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498825
499553
  response: { registered: tools.length }
498826
499554
  },
498827
499555
  session_id: sessionId,
498828
- uuid: randomUUID34()
499556
+ uuid: randomUUID35()
498829
499557
  };
498830
499558
  writeWireMessage(registerResponse);
498831
499559
  } else if (subtype === "bootstrap_session_state") {
@@ -498881,7 +499609,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498881
499609
  response: recovery
498882
499610
  },
498883
499611
  session_id: sessionId,
498884
- uuid: randomUUID34()
499612
+ uuid: randomUUID35()
498885
499613
  };
498886
499614
  writeWireMessage(recoveryResponse);
498887
499615
  } catch (error54) {
@@ -498893,7 +499621,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498893
499621
  error: error54 instanceof Error ? error54.message : String(error54)
498894
499622
  },
498895
499623
  session_id: sessionId,
498896
- uuid: randomUUID34()
499624
+ uuid: randomUUID35()
498897
499625
  };
498898
499626
  writeWireMessage(recoveryError);
498899
499627
  }
@@ -498906,7 +499634,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498906
499634
  error: `Unknown control request subtype: ${subtype}`
498907
499635
  },
498908
499636
  session_id: sessionId,
498909
- uuid: randomUUID34()
499637
+ uuid: randomUUID35()
498910
499638
  };
498911
499639
  writeWireMessage(errorResponse);
498912
499640
  }
@@ -498961,7 +499689,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498961
499689
  try {
498962
499690
  const buffers = createBuffers(agent2.id);
498963
499691
  const startTime = performance.now();
498964
- const userOtid = randomUUID34();
499692
+ const userOtid = randomUUID35();
498965
499693
  const userTranscriptText = extractTelemetryInputText(userContent);
498966
499694
  if (userTranscriptText.length > 0) {
498967
499695
  const userLineId = `user-${userOtid}`;
@@ -499082,7 +499810,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
499082
499810
  recovery_type: "approval_pending",
499083
499811
  message: "Detected pending approval conflict on send; resolving before retry",
499084
499812
  session_id: sessionId,
499085
- uuid: `recovery-bidir-${randomUUID34()}`
499813
+ uuid: `recovery-bidir-${randomUUID35()}`
499086
499814
  };
499087
499815
  writeWireMessage(recoveryMsg);
499088
499816
  await resolveAllPendingApprovals();
@@ -499105,7 +499833,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
499105
499833
  max_attempts: LLM_API_ERROR_MAX_RETRIES2,
499106
499834
  delay_ms: delayMs,
499107
499835
  session_id: sessionId,
499108
- uuid: `retry-bidir-${randomUUID34()}`
499836
+ uuid: `retry-bidir-${randomUUID35()}`
499109
499837
  };
499110
499838
  writeWireMessage(retryMsg);
499111
499839
  await new Promise((resolve37) => setTimeout(resolve37, delayMs));
@@ -499127,7 +499855,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
499127
499855
  stop_reason: "error",
499128
499856
  run_id: errorInfo.run_id,
499129
499857
  session_id: sessionId,
499130
- uuid: randomUUID34(),
499858
+ uuid: randomUUID35(),
499131
499859
  ...errorInfo.error_type && errorInfo.run_id && {
499132
499860
  api_error: {
499133
499861
  message_type: "error_message",
@@ -499155,7 +499883,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
499155
499883
  type: "stream_event",
499156
499884
  event: chunk,
499157
499885
  session_id: sessionId,
499158
- uuid: uuid5 || randomUUID34()
499886
+ uuid: uuid5 || randomUUID35()
499159
499887
  };
499160
499888
  writeWireMessage(streamEvent);
499161
499889
  } else {
@@ -499163,7 +499891,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
499163
499891
  type: "message",
499164
499892
  ...chunk,
499165
499893
  session_id: sessionId,
499166
- uuid: uuid5 || randomUUID34()
499894
+ uuid: uuid5 || randomUUID35()
499167
499895
  };
499168
499896
  writeWireMessage(msg);
499169
499897
  }
@@ -499229,7 +499957,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
499229
499957
  const approvalInputWithOtid = {
499230
499958
  type: "approval",
499231
499959
  approvals: executedResults,
499232
- otid: randomUUID34()
499960
+ otid: randomUUID35()
499233
499961
  };
499234
499962
  currentInput = [approvalInputWithOtid];
499235
499963
  continue;
@@ -499292,7 +500020,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
499292
500020
  message: errorDetails,
499293
500021
  stop_reason: "error",
499294
500022
  session_id: sessionId,
499295
- uuid: randomUUID34()
500023
+ uuid: randomUUID35()
499296
500024
  };
499297
500025
  writeWireMessage(errorMsg2);
499298
500026
  const errorResultMsg = {
@@ -499335,7 +500063,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
499335
500063
  message: `Unknown message type: ${message.type}`,
499336
500064
  stop_reason: "error",
499337
500065
  session_id: sessionId,
499338
- uuid: randomUUID34()
500066
+ uuid: randomUUID35()
499339
500067
  };
499340
500068
  writeWireMessage(errorMsg);
499341
500069
  }
@@ -499426,8 +500154,7 @@ var init_headless = __esm(async () => {
499426
500154
  shouldTrackTelemetryForQueuedMessage,
499427
500155
  contentToTaskNotificationText,
499428
500156
  toBidirectionalQueuedInput,
499429
- prepareHeadlessToolExecutionContext,
499430
- waitForEnvironmentAssistantMessage
500157
+ prepareHeadlessToolExecutionContext
499431
500158
  };
499432
500159
  });
499433
500160
 
@@ -500824,7 +501551,7 @@ var init_reflection_arena_hf_upload = __esm(() => {
500824
501551
 
500825
501552
  // src/cli/helpers/reflection-arena.ts
500826
501553
  import { execFile as execFileCb6 } from "node:child_process";
500827
- import { randomInt as randomInt2, randomUUID as randomUUID35 } from "node:crypto";
501554
+ import { randomInt as randomInt2, randomUUID as randomUUID36 } from "node:crypto";
500828
501555
  import { appendFile as appendFile3, mkdir as mkdir19, readFile as readFile31, writeFile as writeFile22 } from "node:fs/promises";
500829
501556
  import { homedir as homedir46 } from "node:os";
500830
501557
  import { join as join82 } from "node:path";
@@ -501198,7 +501925,7 @@ async function startReflectionArenaRun(options3) {
501198
501925
  }
501199
501926
  let releaseReservation = true;
501200
501927
  try {
501201
- const runId = randomUUID35().slice(0, 8);
501928
+ const runId = randomUUID36().slice(0, 8);
501202
501929
  const labels = shuffledLabels();
501203
501930
  const prepared = await Promise.all([
501204
501931
  prepareReflectionMemoryWorktreeLaunch({
@@ -524911,7 +525638,7 @@ var init_ToolCallMessageRich = __esm(async () => {
524911
525638
  let shellSemanticKind = null;
524912
525639
  let hasShellDescription = false;
524913
525640
  if (!isQuestionTool(rawName)) {
524914
- const parseArgs19 = () => {
525641
+ const parseArgs20 = () => {
524915
525642
  if (!argsText.trim()) {
524916
525643
  return { formatted: null, parseable: true };
524917
525644
  }
@@ -524925,7 +525652,7 @@ var init_ToolCallMessageRich = __esm(async () => {
524925
525652
  return { formatted: null, parseable: false };
524926
525653
  }
524927
525654
  };
524928
- const { formatted, parseable } = parseArgs19();
525655
+ const { formatted, parseable } = parseArgs20();
524929
525656
  const argsComplete = parseable || line.phase === "running" || line.phase === "finished" || !isStreaming;
524930
525657
  if (!argsComplete) {
524931
525658
  args = "(…)";
@@ -526396,12 +527123,12 @@ var init_ExitStats = __esm(async () => {
526396
527123
  });
526397
527124
 
526398
527125
  // src/cli/app/ids.ts
526399
- import { randomUUID as randomUUID36 } from "node:crypto";
527126
+ import { randomUUID as randomUUID37 } from "node:crypto";
526400
527127
  function uid(prefix) {
526401
527128
  return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
526402
527129
  }
526403
527130
  function createClientOtid() {
526404
- return randomUUID36();
527131
+ return randomUUID37();
526405
527132
  }
526406
527133
  function appendOptimisticUserLine(buffers, text2, otid) {
526407
527134
  if (!text2) {
@@ -527141,7 +527868,7 @@ function updateCommandResult(buffersRef, refreshDerived, cmdId, input, output, s
527141
527868
  buffersRef.current.byId.set(cmdId, line);
527142
527869
  refreshDerived();
527143
527870
  }
527144
- function parseArgs19(msg) {
527871
+ function parseArgs20(msg) {
527145
527872
  return msg.trim().split(/\s+/).filter(Boolean);
527146
527873
  }
527147
527874
  function formatConnectUsage() {
@@ -527497,7 +528224,7 @@ ${formatBedrockUsage2()}`, false);
527497
528224
  }
527498
528225
  }
527499
528226
  async function handleConnect(ctx, msg) {
527500
- const parts = parseArgs19(msg);
528227
+ const parts = parseArgs20(msg);
527501
528228
  const providerToken = parts[1];
527502
528229
  if (!providerToken) {
527503
528230
  addCommandResult(ctx.buffersRef, ctx.refreshDerived, msg, formatConnectUsage(), false);
@@ -543425,7 +544152,7 @@ var init_notifications = __esm(() => {
543425
544152
  });
543426
544153
 
543427
544154
  // src/cli/app/use-approval-flow.ts
543428
- import { randomUUID as randomUUID37 } from "node:crypto";
544155
+ import { randomUUID as randomUUID38 } from "node:crypto";
543429
544156
  function useApprovalFlow(ctx) {
543430
544157
  const {
543431
544158
  abortControllerRef,
@@ -543937,7 +544664,7 @@ function useApprovalFlow(ctx) {
543937
544664
  {
543938
544665
  type: "approval",
543939
544666
  approvals: allResults,
543940
- otid: randomUUID37()
544667
+ otid: randomUUID38()
543941
544668
  }
543942
544669
  ]);
543943
544670
  } catch (error54) {
@@ -545336,7 +546063,7 @@ var init_system_reminders = __esm(() => {
545336
546063
  });
545337
546064
 
545338
546065
  // src/cli/app/use-conversation-loop.ts
545339
- import { randomUUID as randomUUID38 } from "node:crypto";
546066
+ import { randomUUID as randomUUID39 } from "node:crypto";
545340
546067
  function sleep10(ms) {
545341
546068
  return new Promise((resolve40) => setTimeout(resolve40, ms));
545342
546069
  }
@@ -545640,16 +546367,16 @@ function useConversationLoop(ctx) {
545640
546367
  currentInput = [
545641
546368
  ...lastSentInputRef.current.map((m4) => ({
545642
546369
  ...m4,
545643
- otid: randomUUID38()
546370
+ otid: randomUUID39()
545644
546371
  })),
545645
546372
  ...currentInput.map((m4) => m4.type === "message" && m4.role === "user" ? {
545646
546373
  ...m4,
545647
- otid: randomUUID38(),
546374
+ otid: randomUUID39(),
545648
546375
  content: [
545649
546376
  { type: "text", text: INTERRUPT_RECOVERY_ALERT },
545650
546377
  ...typeof m4.content === "string" ? [{ type: "text", text: m4.content }] : Array.isArray(m4.content) ? m4.content : []
545651
546378
  ]
545652
- } : { ...m4, otid: randomUUID38() })
546379
+ } : { ...m4, otid: randomUUID39() })
545653
546380
  ];
545654
546381
  pendingInterruptRecoveryConversationIdRef.current = null;
545655
546382
  lastSentInputRef.current = [
@@ -545688,7 +546415,7 @@ function useConversationLoop(ctx) {
545688
546415
  type: "text",
545689
546416
  text: sc.content
545690
546417
  })),
545691
- otid: randomUUID38()
546418
+ otid: randomUUID39()
545692
546419
  }
545693
546420
  ];
545694
546421
  }
@@ -546068,7 +546795,7 @@ ${feedback}
546068
546795
  });
546069
546796
  buffersRef.current.order.push(statusId);
546070
546797
  refreshDerived();
546071
- const hookMessageOtid = randomUUID38();
546798
+ const hookMessageOtid = randomUUID39();
546072
546799
  setTimeout(() => {
546073
546800
  processConversation([
546074
546801
  {
@@ -546095,7 +546822,7 @@ ${feedback}
546095
546822
  turnEndContinue = undefined;
546096
546823
  }
546097
546824
  if (turnEndContinue) {
546098
- const continueOtid = randomUUID38();
546825
+ const continueOtid = randomUUID39();
546099
546826
  setTimeout(() => {
546100
546827
  processConversation([
546101
546828
  {
@@ -546449,7 +547176,7 @@ ${feedback}
546449
547176
  {
546450
547177
  type: "approval",
546451
547178
  approvals: allResults,
546452
- otid: randomUUID38()
547179
+ otid: randomUUID39()
546453
547180
  }
546454
547181
  ], {
546455
547182
  allowReentry: true,
@@ -546633,7 +547360,7 @@ ${feedback}
546633
547360
  type: "message",
546634
547361
  role: "system",
546635
547362
  content: `<system-reminder>The previous response was empty. Please provide a response with either text content or a tool call.</system-reminder>`,
546636
- otid: randomUUID38()
547363
+ otid: randomUUID39()
546637
547364
  }
546638
547365
  ];
546639
547366
  }
@@ -546927,7 +547654,7 @@ var init_use_conversation_loop = __esm(async () => {
546927
547654
  });
546928
547655
 
546929
547656
  // src/cli/app/use-conversation-switching.ts
546930
- import { randomUUID as randomUUID39 } from "node:crypto";
547657
+ import { randomUUID as randomUUID40 } from "node:crypto";
546931
547658
  function useConversationSwitching(ctx) {
546932
547659
  const {
546933
547660
  abortControllerRef,
@@ -547002,7 +547729,7 @@ function useConversationSwitching(ctx) {
547002
547729
  {
547003
547730
  role: "user",
547004
547731
  content: question,
547005
- otid: randomUUID39()
547732
+ otid: randomUUID40()
547006
547733
  }
547007
547734
  ];
547008
547735
  let approvalRecoveryRetries = 0;
@@ -552518,7 +553245,7 @@ var init_conversation_switch_alert = __esm(() => {
552518
553245
  });
552519
553246
 
552520
553247
  // src/cli/app/use-submit-handler.ts
552521
- import { randomUUID as randomUUID40 } from "node:crypto";
553248
+ import { randomUUID as randomUUID41 } from "node:crypto";
552522
553249
  import { existsSync as existsSync70, readFileSync as readFileSync45, renameSync as renameSync8, writeFileSync as writeFileSync39 } from "node:fs";
552523
553250
  import { tmpdir as tmpdir12 } from "node:os";
552524
553251
  import { join as join91 } from "node:path";
@@ -552939,7 +553666,7 @@ ${SYSTEM_REMINDER_CLOSE}` : "";
552939
553666
  content: buildTextParts(`${SYSTEM_REMINDER_OPEN}
552940
553667
  ${prompt}
552941
553668
  ${SYSTEM_REMINDER_CLOSE}`),
552942
- otid: randomUUID40()
553669
+ otid: randomUUID41()
552943
553670
  }
552944
553671
  ]);
552945
553672
  } catch (error54) {
@@ -553003,7 +553730,7 @@ ${SYSTEM_REMINDER_CLOSE}`),
553003
553730
  type: "message",
553004
553731
  role: "user",
553005
553732
  content: buildTextParts(buildModCommandPrompt(result2)),
553006
- otid: randomUUID40()
553733
+ otid: randomUUID41()
553007
553734
  }
553008
553735
  ]);
553009
553736
  } else if (result2.type === "output") {
@@ -553048,7 +553775,7 @@ ${SYSTEM_REMINDER_CLOSE}`),
553048
553775
  ${SYSTEM_REMINDER_OPEN}
553049
553776
  ${request2}
553050
553777
  ${SYSTEM_REMINDER_CLOSE}`),
553051
- otid: randomUUID40()
553778
+ otid: randomUUID41()
553052
553779
  }
553053
553780
  ]);
553054
553781
  } catch (error54) {
@@ -553317,7 +554044,7 @@ ${SYSTEM_REMINDER_CLOSE}`),
553317
554044
  ${SYSTEM_REMINDER_OPEN}
553318
554045
  ${request2}
553319
554046
  ${SYSTEM_REMINDER_CLOSE}`),
553320
- otid: randomUUID40()
554047
+ otid: randomUUID41()
553321
554048
  }
553322
554049
  ]);
553323
554050
  } catch (error54) {
@@ -554161,7 +554888,7 @@ ${SYSTEM_REMINDER_CLOSE}`;
554161
554888
  type: "message",
554162
554889
  role: "user",
554163
554890
  content: buildTextParts(skillMessage),
554164
- otid: randomUUID40()
554891
+ otid: randomUUID41()
554165
554892
  }
554166
554893
  ]);
554167
554894
  } catch (error54) {
@@ -554199,7 +554926,7 @@ ${SYSTEM_REMINDER_CLOSE}`;
554199
554926
  type: "message",
554200
554927
  role: "user",
554201
554928
  content: rememberParts,
554202
- otid: randomUUID40()
554929
+ otid: randomUUID41()
554203
554930
  }
554204
554931
  ]);
554205
554932
  } catch (error54) {
@@ -554615,7 +555342,7 @@ Resumed reflection arena choice prompt for run ${run2.runId}.`, true);
554615
555342
  type: "message",
554616
555343
  role: "user",
554617
555344
  content: buildTextParts(initMessage),
554618
- otid: randomUUID40()
555345
+ otid: randomUUID41()
554619
555346
  }
554620
555347
  ]);
554621
555348
  } catch (error54) {
@@ -554782,7 +555509,7 @@ Resumed reflection arena choice prompt for run ${run2.runId}.`, true);
554782
555509
  type: "message",
554783
555510
  role: "user",
554784
555511
  content: buildTextParts(wrapSkillPrompt2(matchedSkill.id, skillContent, userRequest)),
554785
- otid: randomUUID40()
555512
+ otid: randomUUID41()
554786
555513
  }
554787
555514
  ]);
554788
555515
  } catch (error54) {
@@ -554933,7 +555660,7 @@ ${SYSTEM_REMINDER_CLOSE}
554933
555660
  initialInput.push({
554934
555661
  type: "approval",
554935
555662
  approvals: eagerRecoveryDenials,
554936
- otid: randomUUID40()
555663
+ otid: randomUUID41()
554937
555664
  });
554938
555665
  }
554939
555666
  const queuedApprovalInput = consumeQueuedApprovalInputForCurrentConversation();
@@ -558628,6 +559355,7 @@ USAGE
558628
559355
  letta memory ... Memory filesystem subcommands
558629
559356
  letta agents ... Agents subcommands (JSON-only)
558630
559357
  letta environments ... List available remote environments (JSON-only)
559358
+ letta teleport ... Move the current conversation between environments
558631
559359
  letta messages ... Messages subcommands (JSON-only)
558632
559360
  letta mods ... List and manage local mods
558633
559361
  letta sandbox ... Transfer files to or from the current Cloud sandbox
@@ -558654,6 +559382,7 @@ SUBCOMMANDS
558654
559382
  letta agents list [--query <text> | --name <name> | --tags <tags>]
558655
559383
  letta environments list [--online-only]
558656
559384
  letta environments current
559385
+ letta teleport list|cloud|<environment>
558657
559386
  letta messages search --query <text> [--all-agents]
558658
559387
  letta messages list [--agent <id>]
558659
559388
  letta messages transcript --conversation <id> [--out <path>]
@@ -562341,4 +563070,4 @@ function registerBunOAuthFlows() {
562341
563070
  registerBunOAuthFlows();
562342
563071
  await init_src5().then(() => exports_src2);
562343
563072
 
562344
- //# debugId=447A31644C59E2F264756E2164756E21
563073
+ //# debugId=70AA6EC305780C2964756E2164756E21