@letta-ai/letta-code 0.34.20 → 0.34.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/letta.js CHANGED
@@ -5967,7 +5967,7 @@ var package_default;
5967
5967
  var init_package = __esm(() => {
5968
5968
  package_default = {
5969
5969
  name: "@letta-ai/letta-code",
5970
- version: "0.34.20",
5970
+ version: "0.34.21",
5971
5971
  lettaStartupLogProtocol: 1,
5972
5972
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
5973
5973
  type: "module",
@@ -6242,7 +6242,7 @@ var init_package = __esm(() => {
6242
6242
  },
6243
6243
  lettaLifecycleProtocol: 1,
6244
6244
  lettaRuntimeGraphProtocol: 1,
6245
- lettaRuntimeGraphSha512: "sha512-RWgzMK/RLJluHmJEAXwWV7NZe1gpOgg3BYpp8+G8QfqsXUUmzZgQpQz5E9CHogeIwfcGzCaHAUIdboH6Ir7KyA=="
6245
+ lettaRuntimeGraphSha512: "sha512-xHwgmxBsCCiYY3o9bJl2DPx84chNPq1OsLFGac23DBEoU+h6hGCcX7rZezQxutCYhG/yFzjQ65L3pZ5j6BzNbg=="
6246
6246
  };
6247
6247
  });
6248
6248
 
@@ -100099,7 +100099,7 @@ Other
100099
100099
  - [ ] Make a permissions edit: let the user know that you can modify permissions (what commands are automatically approved/denied). Ask them if there are certain actions they would like you to avoid.
100100
100100
  - [ ] Create a local mod: let the user know you can customize Letta Code with trusted local mods for new tools, slash commands, provider integrations, UI panels/status, events, or permission overlays. Explain that mods are for executable harness behavior, while memory and skills are for retained knowledge and reusable procedures.
100101
100101
  - [ ] Worktrees: let the user know that you can help them orchestrate many agents in parallel, and also work in parallel to other agents. Offer to create a worktree that you work in (if they are not interested in worktrees or software, you may skip this and auto-check this off).
100102
- - [ ] Moving machines: ask the user to connect another computer (they can either run another desktop instance or run \`letta server\` on another machine) and run you there instead.
100102
+ - [ ] Moving machines: ask the user to connect another computer by running \`letta server\` on it, then run you there instead.
100103
100103
  `;
100104
100104
  var init_onboarding = () => {};
100105
100105
 
@@ -100152,7 +100152,7 @@ Other
100152
100152
  - [ ] Make a permissions edit: let the user know that you can modify permissions (what commands are automatically approved/denied). Ask them if there are certain actions they would like you to avoid.
100153
100153
  - [ ] Create a local mod: let the user know you can customize Letta Code with trusted local mods for new tools, slash commands, provider integrations, UI panels/status, events, or permission overlays. Explain that mods are for executable harness behavior, while memory and skills are for retained knowledge and reusable procedures.
100154
100154
  - [ ] Worktrees: let the user know that you can help them orchestrate many agents in parallel, and also work in parallel to other agents. Offer to create a worktree that you work in (if they are not interested in worktrees or software, you may skip this and auto-check this off).
100155
- - [ ] Moving machines: ask the user to connect another computer (they can either run another desktop instance or run \`letta server\` on another machine) and run you there instead.
100155
+ - [ ] Moving machines: ask the user to connect another computer by running \`letta server\` on it, then run you there instead.
100156
100156
  `;
100157
100157
  var init_onboarding_local = () => {};
100158
100158
 
@@ -210910,7 +210910,7 @@ var init_mcp_client = __esm(() => {
210910
210910
  init_streamableHttp();
210911
210911
  DEFAULT_CLIENT_INFO = {
210912
210912
  name: "letta-code",
210913
- version: "0.34.20"
210913
+ version: "0.34.21"
210914
210914
  };
210915
210915
  });
210916
210916
 
@@ -232387,13 +232387,14 @@ async function runUnifiedMcpTool(params) {
232387
232387
  body: { args: params.args },
232388
232388
  ...params.originatorToken ? {
232389
232389
  headers: {
232390
- [MCP_ORIGINATOR_TOKEN_HEADER]: params.originatorToken
232390
+ [MCP_ORIGINATOR_TOKEN_HEADER]: params.originatorToken,
232391
+ [MCP_ORIGINATOR_ISOLATION_HEADER]: "1"
232391
232392
  }
232392
232393
  } : {}
232393
232394
  }), params.timeoutMs ?? 60000, "Running agent MCP tool");
232394
232395
  return parseRunResult(value);
232395
232396
  }
232396
- var MCP_ORIGINATOR_TOKEN_HEADER = "x-letta-mcp-originator-token";
232397
+ var MCP_ORIGINATOR_TOKEN_HEADER = "x-letta-mcp-originator-token", MCP_ORIGINATOR_ISOLATION_HEADER = "x-letta-mcp-originator-isolation";
232397
232398
  var init_unified_mcp = () => {};
232398
232399
 
232399
232400
  // src/mcp-runtime.ts
@@ -240080,7 +240081,7 @@ async function resolveDesktopEnvironmentConnectionId(list = listEnvironments) {
240080
240081
  const response = await list({ limit: 100, onlineOnly: true });
240081
240082
  const matches3 = response.connections.filter((environment3) => (environment3.deviceId.startsWith("desktop:") && environment3.listenerInstanceId?.startsWith("desktop-primary:") === true || environment3.listenerInstanceId?.startsWith("desktop-direct-cloud:") === true) && environment3.organizationId !== "local" && isEnvironmentOnline(environment3));
240082
240083
  if (matches3.length === 0) {
240083
- throw new Error("Desktop Local is unavailable. Open Letta Desktop and wait for its computer connection to come online.");
240084
+ throw new Error("No Desktop Local computer is online. Run `letta teleport list` and choose a connected computer by name, device ID, or connection ID. To connect a computer, run `letta server` on it.");
240084
240085
  }
240085
240086
  if (matches3.length > 1) {
240086
240087
  throw new Error(`Multiple Desktop computers are online. Run \`letta teleport list\` and choose one by name, device ID, or connection ID. Matched: ${matches3.map(describeEnvironment).join(", ")}`);
@@ -240227,7 +240228,7 @@ function validateTargetDevice(deviceId, environment2) {
240227
240228
  if (environment2?.organizationId === "local") {
240228
240229
  return {
240229
240230
  ok: false,
240230
- error: `Device ${deviceId} is this computer's local desktop connection, not a computer connected to your Letta account. Cloud schedules can only target connected computers — run \`letta server\` on that machine (or enable remote access in the desktop app) to connect it.`
240231
+ error: `Device ${deviceId} is this computer's local desktop connection, not a computer connected to your Letta account. Cloud schedules can only target connected computers — run \`letta server\` on that machine to connect it.`
240231
240232
  };
240232
240233
  }
240233
240234
  return { ok: true };
@@ -243271,7 +243272,7 @@ class CodexAppServerClient {
243271
243272
  await this.request("initialize", {
243272
243273
  clientInfo: {
243273
243274
  name: "letta-code",
243274
- version: "0.34.20"
243275
+ version: "0.34.21"
243275
243276
  },
243276
243277
  capabilities: null
243277
243278
  });
@@ -244353,11 +244354,13 @@ function buildMcpServersReminderText(entries) {
244353
244354
  if (entries.length === 0) {
244354
244355
  return `${SYSTEM_REMINDER_OPEN}
244355
244356
  MCP servers with available tools: None
244357
+ Do not automatically store results of principal-restricted operations in shared memory.
244356
244358
  ${SYSTEM_REMINDER_CLOSE}`;
244357
244359
  }
244358
244360
  const rendered = entries.map(formatMcpServerEntry).join(", ");
244359
244361
  return `${SYSTEM_REMINDER_OPEN}
244360
244362
  MCP servers with available tools: ${rendered}
244363
+ Do not automatically store results of principal-restricted operations in shared memory.
244361
244364
  Find tools (with schemas) with \`letta mcp search "<what you want to do>"\`, list one server's tools with \`letta mcp tools <server>\` (\`--full\` includes schemas, \`letta mcp schema <tool-name>\` fetches one), and invoke one with \`letta mcp call <tool-name> --args '{"key":"value"}'\`.
244362
244365
  ${SYSTEM_REMINDER_CLOSE}`;
244363
244366
  }
@@ -246733,7 +246736,7 @@ function isAppServerInfoResponseMessage(message2) {
246733
246736
  return false;
246734
246737
  }
246735
246738
  const capabilityRecord = capabilities;
246736
- return candidate.type === "app_server_info_response" && typeof candidate.request_id === "string" && candidate.request_id.length > 0 && candidate.success === true && (candidate.backend === "local" || candidate.backend === "api") && typeof candidate.letta_code_version === "string" && typeof candidate.protocol_version === "number" && Number.isInteger(candidate.protocol_version) && typeof capabilityRecord.agent_management === "boolean" && typeof capabilityRecord.conversation_management === "boolean" && typeof capabilityRecord.memory_management === "boolean" && typeof capabilityRecord.runtime_start === "boolean" && (capabilityRecord.agent_free_conversations === undefined || typeof capabilityRecord.agent_free_conversations === "boolean") && (capabilityRecord.launch_subagent === undefined || typeof capabilityRecord.launch_subagent === "boolean") && (capabilityRecord.launch_subagent_notify_caller === undefined || typeof capabilityRecord.launch_subagent_notify_caller === "boolean") && (capabilityRecord.subagent_message === undefined || typeof capabilityRecord.subagent_message === "boolean") && (capabilityRecord.runtime_workspace_sandbox === undefined || typeof capabilityRecord.runtime_workspace_sandbox === "boolean") && (capabilityRecord.runtime_external_tools_update === undefined || typeof capabilityRecord.runtime_external_tools_update === "boolean") && (capabilityRecord.structured_outputs === undefined || typeof capabilityRecord.structured_outputs === "boolean") && (capabilityRecord.write_file_base64 === undefined || typeof capabilityRecord.write_file_base64 === "boolean") && typeof capabilityRecord.split_channels === "boolean";
246739
+ return candidate.type === "app_server_info_response" && typeof candidate.request_id === "string" && candidate.request_id.length > 0 && candidate.success === true && (candidate.backend === "local" || candidate.backend === "api") && typeof candidate.letta_code_version === "string" && typeof candidate.protocol_version === "number" && Number.isInteger(candidate.protocol_version) && typeof capabilityRecord.agent_management === "boolean" && typeof capabilityRecord.conversation_management === "boolean" && typeof capabilityRecord.memory_management === "boolean" && typeof capabilityRecord.runtime_start === "boolean" && (capabilityRecord.agent_free_conversations === undefined || typeof capabilityRecord.agent_free_conversations === "boolean") && (capabilityRecord.launch_subagent === undefined || typeof capabilityRecord.launch_subagent === "boolean") && (capabilityRecord.launch_subagent_notify_caller === undefined || typeof capabilityRecord.launch_subagent_notify_caller === "boolean") && (capabilityRecord.subagent_message === undefined || typeof capabilityRecord.subagent_message === "boolean") && (capabilityRecord.runtime_workspace_sandbox === undefined || typeof capabilityRecord.runtime_workspace_sandbox === "boolean") && (capabilityRecord.runtime_external_tools_update === undefined || typeof capabilityRecord.runtime_external_tools_update === "boolean") && (capabilityRecord.structured_outputs === undefined || typeof capabilityRecord.structured_outputs === "boolean") && (capabilityRecord.write_file_base64 === undefined || typeof capabilityRecord.write_file_base64 === "boolean") && (capabilityRecord.mcp_originator_queue_isolation === undefined || typeof capabilityRecord.mcp_originator_queue_isolation === "boolean") && typeof capabilityRecord.split_channels === "boolean";
246737
246740
  }
246738
246741
  var APP_SERVER_PROTOCOL_VERSION = 1;
246739
246742
 
@@ -259917,6 +259920,20 @@ var init_image_policy = __esm(async () => {
259917
259920
  await init_message_image_normalization();
259918
259921
  });
259919
259922
 
259923
+ // src/websocket/listener/mcp-originator-scope.ts
259924
+ function getMcpOriginatorScope(message2) {
259925
+ return message2?.mcpOriginatorSuperRunId ? {
259926
+ superRunId: message2.mcpOriginatorSuperRunId,
259927
+ tokenPresent: message2.mcpOriginatorTokenPresent === true
259928
+ } : null;
259929
+ }
259930
+ function sameMcpOriginatorScope(a2, b3) {
259931
+ return a2 === null || b3 === null ? a2 === b3 : a2.superRunId === b3.superRunId && a2.tokenPresent === b3.tokenPresent;
259932
+ }
259933
+ function getEffectiveMcpOriginatorId(message2) {
259934
+ return message2.mcpOriginatorTokenPresent === true ? message2.mcpOriginatorSuperRunId : undefined;
259935
+ }
259936
+
259920
259937
  // src/websocket/listener/queue.ts
259921
259938
  function getQueueItemScope(item) {
259922
259939
  if (!item) {
@@ -260040,12 +260057,15 @@ function shouldProcessInboundMessageDirectly(runtime, parsed) {
260040
260057
  });
260041
260058
  return getListenerBlockedReason(runtime.turnLifecycle.snapshot(), activeScope ? getPendingControlRequestCount(runtime.listener, activeScope) : 0) === null;
260042
260059
  }
260043
- function consumeQueuedTurn(runtime) {
260060
+ function consumeQueuedTurn(runtime, activeScope) {
260044
260061
  const queuedItems = runtime.queueRuntime.peekReady();
260045
260062
  const firstQueuedItem = queuedItems[0];
260046
260063
  if (!firstQueuedItem || !isCoalescable(firstQueuedItem.kind)) {
260047
260064
  return null;
260048
260065
  }
260066
+ const firstScope = getMcpOriginatorScope(firstQueuedItem.kind === "message" ? runtime.queuedMessagesByItemId.get(firstQueuedItem.id) : undefined);
260067
+ if (activeScope !== undefined && !sameMcpOriginatorScope(firstScope, activeScope))
260068
+ return null;
260049
260069
  let queueLen = 0;
260050
260070
  let hasMessage = false;
260051
260071
  let hasTaskNotification = false;
@@ -260056,7 +260076,7 @@ function consumeQueuedTurn(runtime) {
260056
260076
  let batchPreferences = JSON.stringify(getStoredClientPreferences(runtime.agentId, runtime.conversationId));
260057
260077
  const isNoCoalesce = (candidate) => candidate.kind === "message" && candidate.noCoalesce === true;
260058
260078
  for (const item of queuedItems) {
260059
- if (!isCoalescable(item.kind) || !hasSameQueueScope(firstQueuedItem, item)) {
260079
+ if (!isCoalescable(item.kind) || !hasSameQueueScope(firstQueuedItem, item) || !sameMcpOriginatorScope(firstScope, getMcpOriginatorScope(item.kind === "message" ? runtime.queuedMessagesByItemId.get(item.id) : undefined))) {
260060
260080
  break;
260061
260081
  }
260062
260082
  const incoming = runtime.queuedMessagesByItemId.get(item.id);
@@ -262118,11 +262138,12 @@ Legacy aliases:
262118
262138
 
262119
262139
  List options:
262120
262140
  --limit <n> Max results (default: 50)
262121
- --after <id> Pagination cursor from a previous computer id
262141
+ --after <id> The id of the last record from the previous page
262122
262142
  --online-only Only include computers with a fresh active connection
262123
262143
 
262124
262144
  Notes:
262125
262145
  - Output is JSON only.
262146
+ - Pass nextCursor to --after to advance, including with --online-only.
262126
262147
  - Uses CLI auth; override with LETTA_API_KEY/LETTA_BASE_URL if needed.
262127
262148
  - Use letta computers current to get this computer's stable deviceId.
262128
262149
  - Prefer deviceId or connectionName for --computer and Agent(computer=...).
@@ -262143,6 +262164,7 @@ function isOnline(environment2) {
262143
262164
  }
262144
262165
  function formatEnvironmentForCli(environment2, options) {
262145
262166
  const formatted = {
262167
+ id: environment2.id,
262146
262168
  deviceId: environment2.deviceId,
262147
262169
  connectionName: environment2.connectionName,
262148
262170
  connectionId: environment2.connectionId ?? null,
@@ -262244,6 +262266,7 @@ async function runEnvironmentsSubcommand(argv, deps = {}) {
262244
262266
  })).filter((environment2) => !onlineOnly || environment2.isOnline).slice(0, limit4).map((environment2) => formatEnvironmentForCli(environment2, { onlineOnly, currentConnectionId }));
262245
262267
  console.log(JSON.stringify({
262246
262268
  ...result3,
262269
+ nextCursor: result3.hasNextPage ? result3.connections.at(-1)?.id ?? null : null,
262247
262270
  connections
262248
262271
  }, null, 2));
262249
262272
  return 0;
@@ -268195,7 +268218,28 @@ function buildListModelsEntries(availableModels = [], options = {}) {
268195
268218
  nativeHandles.add(model.handle);
268196
268219
  return [buildNativeModelEntry(model)];
268197
268220
  });
268198
- return [...presetEntries, ...nativeEntries];
268221
+ const byokHandles = new Set(availableModels.filter((model) => model.providerCategory === "byok").map((model) => model.handle));
268222
+ return disambiguateByokLabels([...presetEntries, ...nativeEntries], byokHandles);
268223
+ }
268224
+ function providerNameFromHandle(handle2) {
268225
+ const slashIndex = handle2.indexOf("/");
268226
+ return slashIndex > 0 ? handle2.slice(0, slashIndex) : undefined;
268227
+ }
268228
+ function disambiguateByokLabels(entries2, byokHandles) {
268229
+ const labelCounts = new Map;
268230
+ for (const entry of entries2) {
268231
+ if (!byokHandles.has(entry.handle))
268232
+ continue;
268233
+ labelCounts.set(entry.label, (labelCounts.get(entry.label) ?? 0) + 1);
268234
+ }
268235
+ return entries2.map((entry) => {
268236
+ const isByokRow = byokHandles.has(entry.handle);
268237
+ const providerName = providerNameFromHandle(entry.handle);
268238
+ if (!isByokRow || !providerName || (labelCounts.get(entry.label) ?? 0) < 2) {
268239
+ return entry;
268240
+ }
268241
+ return { ...entry, label: `${entry.label} · ${providerName}` };
268242
+ });
268199
268243
  }
268200
268244
  var init_model_catalog2 = __esm(() => {
268201
268245
  init_model();
@@ -268744,7 +268788,7 @@ async function prepareToolExecutionContextForScope(params) {
268744
268788
  conversationId: scopedConversationId,
268745
268789
  ...actingUserId ? { actingUserId } : {},
268746
268790
  ...suppressActingUserFallback ? { suppressActingUserFallback: true } : {},
268747
- ...mcpOriginatorSuperRunId ? { mcpOriginatorSuperRunId } : {},
268791
+ mcpOriginatorSuperRunId: mcpOriginatorSuperRunId ?? null,
268748
268792
  workingDirectory,
268749
268793
  ...skillsDirectory !== undefined ? { skillsDirectory } : {},
268750
268794
  ...skillSources !== undefined ? { skillSources } : {},
@@ -446669,98 +446713,6 @@ var init_cloud_retry_message = __esm(async () => {
446669
446713
  await init_protocol_outbound();
446670
446714
  });
446671
446715
 
446672
- // src/websocket/listener/turn-input-state.ts
446673
- function ensureTurnInputMessageOtids(messages) {
446674
- let didChange = false;
446675
- const messagesWithOtids = messages.map((message2) => {
446676
- if (!("content" in message2) || message2.otid) {
446677
- return message2;
446678
- }
446679
- didChange = true;
446680
- return {
446681
- ...message2,
446682
- otid: "client_message_id" in message2 && typeof message2.client_message_id === "string" ? message2.client_message_id : crypto.randomUUID()
446683
- };
446684
- });
446685
- return didChange ? messagesWithOtids : messages;
446686
- }
446687
- function createTurnInputState(messages, imageFailureModesByMessageOtid) {
446688
- return {
446689
- messages,
446690
- ...imageFailureModesByMessageOtid ? { imageFailureModesByMessageOtid } : {}
446691
- };
446692
- }
446693
- function createDeploymentRecoveryTurnInput() {
446694
- return createTurnInputState([
446695
- {
446696
- type: "message",
446697
- role: "user",
446698
- content: [{ type: "text", text: APPROVAL_RECOVERY_PROMPT }],
446699
- otid: crypto.randomUUID()
446700
- }
446701
- ]);
446702
- }
446703
- function updateTurnInputMessagesPreservingOtids(state2, messages) {
446704
- if (state2.imageFailureModesByMessageOtid) {
446705
- const nextOtids = new Set(messages.map((message2) => message2.otid));
446706
- for (const otid of Object.keys(state2.imageFailureModesByMessageOtid)) {
446707
- if (!nextOtids.has(otid)) {
446708
- throw new Error(`Cannot preserve image failure policy for missing message OTID: ${otid}`);
446709
- }
446710
- }
446711
- }
446712
- return createTurnInputState(messages, state2.imageFailureModesByMessageOtid);
446713
- }
446714
- function refreshTurnInputOtidsForNewRequest(state2) {
446715
- const refreshedMessages = refreshInputOtidsForNewRequest(state2.messages);
446716
- return createTurnInputState(refreshedMessages, remapImageFailureModesByPosition(state2.messages, refreshedMessages, state2.imageFailureModesByMessageOtid));
446717
- }
446718
- function rebuildTurnInputWithFreshDenials(state2, serverApprovals, denialReason, preserveMessageOtids = false) {
446719
- const rebuiltMessages = rebuildInputWithFreshDenials(state2.messages, serverApprovals, denialReason, preserveMessageOtids);
446720
- return createTurnInputState(rebuiltMessages, remapImageFailureModesByPosition(getContentMessages(state2.messages), getContentMessages(rebuiltMessages), state2.imageFailureModesByMessageOtid));
446721
- }
446722
- function getContentMessages(messages) {
446723
- return messages.filter((message2) => ("content" in message2));
446724
- }
446725
- function remapImageFailureModesByPosition(previousMessages, nextMessages, previousModes) {
446726
- if (!previousModes) {
446727
- return;
446728
- }
446729
- if (previousMessages.length !== nextMessages.length) {
446730
- throw new Error("Cannot remap image failure policy across non-corresponding message lists");
446731
- }
446732
- const remappedEntries = [];
446733
- for (const [index, previousMessage] of previousMessages.entries()) {
446734
- const nextMessage = nextMessages[index];
446735
- const previousOtid = previousMessage?.otid;
446736
- const nextOtid = nextMessage?.otid;
446737
- if (typeof previousOtid !== "string" || typeof nextOtid !== "string") {
446738
- continue;
446739
- }
446740
- const previousMode = previousModes[previousOtid];
446741
- if (previousMode) {
446742
- remappedEntries.push([nextOtid, previousMode]);
446743
- }
446744
- }
446745
- return remappedEntries.length > 0 ? Object.fromEntries(remappedEntries) : undefined;
446746
- }
446747
- var init_turn_input_state = __esm(() => {
446748
- init_prompt_assets();
446749
- init_turn_recovery_policy();
446750
- });
446751
-
446752
- // src/websocket/listener/continuation-input.ts
446753
- function appendQueuedTurnToInput(state2, queuedTurn) {
446754
- return createTurnInputState([...state2.messages, ...queuedTurn.messages], mergeImageFailureModesByMessageOtid(state2.imageFailureModesByMessageOtid, getInboundImageFailureModes(queuedTurn)));
446755
- }
446756
- var init_continuation_input = __esm(async () => {
446757
- init_turn_input_state();
446758
- await __promiseAll([
446759
- init_message_image_normalization(),
446760
- init_image_policy()
446761
- ]);
446762
- });
446763
-
446764
446716
  // src/websocket/listener/recovered-approval-checkpoint.ts
446765
446717
  function denialResult(decision) {
446766
446718
  return {
@@ -447041,26 +446993,6 @@ var init_recovered_approval_retry = __esm(() => {
447041
446993
  retryStates = new WeakMap;
447042
446994
  });
447043
446995
 
447044
- // src/websocket/listener/recovered-queue-rehydration.ts
447045
- function rehydrateClaimLostQueuedTurn(runtime, socket, queuedTurn, opts, processTurn) {
447046
- if (!requeueStartedInputDispositions(runtime, queuedTurn.durableInputIdentities ?? [])) {
447047
- scheduleDurableQueueRestore(runtime.listener, false);
447048
- throw new Error("Failed to requeue claim-lost durable continuation");
447049
- }
447050
- if (!enqueueInboundUserMessage(runtime, queuedTurn, queuedTurn.actingUserId)) {
447051
- scheduleDurableQueueRestore(runtime.listener, false);
447052
- throw new Error("Failed to rehydrate claim-lost queued continuation");
447053
- }
447054
- scheduleQueuePump(runtime, socket, opts ?? {}, (queued, batch) => processTurn(queued, socket, runtime, opts?.onStatusChange, queued.connectionId ?? opts?.connectionId, batch.batchId));
447055
- }
447056
- var init_recovered_queue_rehydration = __esm(async () => {
447057
- await __promiseAll([
447058
- init_conversation_runtime(),
447059
- init_input_disposition(),
447060
- init_queue()
447061
- ]);
447062
- });
447063
-
447064
446996
  // src/websocket/listener/interrupted-turn-read.ts
447065
446997
  function readInterruptedTurn(runtime, recoveryLineageId) {
447066
446998
  if (!runtime.agentId || !runtime.listener.connectionId?.startsWith("conn-"))
@@ -447586,6 +447518,86 @@ var init_turn_durability_ownership = __esm(async () => {
447586
447518
  await init_interrupted_turn_record();
447587
447519
  });
447588
447520
 
447521
+ // src/websocket/listener/turn-input-state.ts
447522
+ function ensureTurnInputMessageOtids(messages) {
447523
+ let didChange = false;
447524
+ const messagesWithOtids = messages.map((message2) => {
447525
+ if (!("content" in message2) || message2.otid) {
447526
+ return message2;
447527
+ }
447528
+ didChange = true;
447529
+ return {
447530
+ ...message2,
447531
+ otid: "client_message_id" in message2 && typeof message2.client_message_id === "string" ? message2.client_message_id : crypto.randomUUID()
447532
+ };
447533
+ });
447534
+ return didChange ? messagesWithOtids : messages;
447535
+ }
447536
+ function createTurnInputState(messages, imageFailureModesByMessageOtid) {
447537
+ return {
447538
+ messages,
447539
+ ...imageFailureModesByMessageOtid ? { imageFailureModesByMessageOtid } : {}
447540
+ };
447541
+ }
447542
+ function createDeploymentRecoveryTurnInput() {
447543
+ return createTurnInputState([
447544
+ {
447545
+ type: "message",
447546
+ role: "user",
447547
+ content: [{ type: "text", text: APPROVAL_RECOVERY_PROMPT }],
447548
+ otid: crypto.randomUUID()
447549
+ }
447550
+ ]);
447551
+ }
447552
+ function updateTurnInputMessagesPreservingOtids(state2, messages) {
447553
+ if (state2.imageFailureModesByMessageOtid) {
447554
+ const nextOtids = new Set(messages.map((message2) => message2.otid));
447555
+ for (const otid of Object.keys(state2.imageFailureModesByMessageOtid)) {
447556
+ if (!nextOtids.has(otid)) {
447557
+ throw new Error(`Cannot preserve image failure policy for missing message OTID: ${otid}`);
447558
+ }
447559
+ }
447560
+ }
447561
+ return createTurnInputState(messages, state2.imageFailureModesByMessageOtid);
447562
+ }
447563
+ function refreshTurnInputOtidsForNewRequest(state2) {
447564
+ const refreshedMessages = refreshInputOtidsForNewRequest(state2.messages);
447565
+ return createTurnInputState(refreshedMessages, remapImageFailureModesByPosition(state2.messages, refreshedMessages, state2.imageFailureModesByMessageOtid));
447566
+ }
447567
+ function rebuildTurnInputWithFreshDenials(state2, serverApprovals, denialReason, preserveMessageOtids = false) {
447568
+ const rebuiltMessages = rebuildInputWithFreshDenials(state2.messages, serverApprovals, denialReason, preserveMessageOtids);
447569
+ return createTurnInputState(rebuiltMessages, remapImageFailureModesByPosition(getContentMessages(state2.messages), getContentMessages(rebuiltMessages), state2.imageFailureModesByMessageOtid));
447570
+ }
447571
+ function getContentMessages(messages) {
447572
+ return messages.filter((message2) => ("content" in message2));
447573
+ }
447574
+ function remapImageFailureModesByPosition(previousMessages, nextMessages, previousModes) {
447575
+ if (!previousModes) {
447576
+ return;
447577
+ }
447578
+ if (previousMessages.length !== nextMessages.length) {
447579
+ throw new Error("Cannot remap image failure policy across non-corresponding message lists");
447580
+ }
447581
+ const remappedEntries = [];
447582
+ for (const [index, previousMessage] of previousMessages.entries()) {
447583
+ const nextMessage = nextMessages[index];
447584
+ const previousOtid = previousMessage?.otid;
447585
+ const nextOtid = nextMessage?.otid;
447586
+ if (typeof previousOtid !== "string" || typeof nextOtid !== "string") {
447587
+ continue;
447588
+ }
447589
+ const previousMode = previousModes[previousOtid];
447590
+ if (previousMode) {
447591
+ remappedEntries.push([nextOtid, previousMode]);
447592
+ }
447593
+ }
447594
+ return remappedEntries.length > 0 ? Object.fromEntries(remappedEntries) : undefined;
447595
+ }
447596
+ var init_turn_input_state = __esm(() => {
447597
+ init_prompt_assets();
447598
+ init_turn_recovery_policy();
447599
+ });
447600
+
447589
447601
  // src/websocket/listener/recovery-debug.ts
447590
447602
  async function debugLogApprovalResumeState(runtime, params) {
447591
447603
  if (!isDebugEnabled())
@@ -448043,52 +448055,24 @@ async function executeRecoveredApprovalContinuation(params) {
448043
448055
  return;
448044
448056
  }
448045
448057
  emitRuntimeStateUpdates(runtime, scope);
448046
- let continuationInput = createTurnInputState([
448058
+ const continuationInput = createTurnInputState([
448047
448059
  {
448048
448060
  type: "approval",
448049
448061
  approvals: approvalResults,
448050
448062
  otid: continuationOtid
448051
448063
  }
448052
448064
  ]);
448053
- let continuationBatchId = `batch-recovered-${crypto.randomUUID()}`;
448054
- let continuationCorrelation;
448065
+ const continuationBatchId = `batch-recovered-${crypto.randomUUID()}`;
448066
+ const continuationCorrelation = undefined;
448055
448067
  const continuationOwnership = createTurnDurabilityOwnership();
448056
448068
  continuationOwnership.recordInput(recovered);
448057
- const consumedQueuedTurn = consumeQueuedTurn(runtime);
448058
- if (consumedQueuedTurn) {
448059
- const { dequeuedBatch, queuedTurn } = consumedQueuedTurn;
448060
- continuationOwnership.recordInput(queuedTurn);
448061
- try {
448062
- await evidence.checkpointOwnership(continuationOwnership, queuedTurn.actingUserId);
448063
- } catch (error5) {
448064
- runtime.dequeuedClientMessageIdsByBatchId.delete(dequeuedBatch.batchId);
448065
- runtime.dequeuedInputIdentitiesByBatchId.delete(dequeuedBatch.batchId);
448066
- rehydrateClaimLostQueuedTurn(runtime, socket, queuedTurn, opts, processTurn);
448067
- throw error5;
448068
- }
448069
- continuationBatchId = dequeuedBatch.batchId;
448070
- continuationInput = appendQueuedTurnToInput(continuationInput, queuedTurn);
448071
- continuationCorrelation = createTurnCorrelation(runtime, {
448072
- type: "message",
448073
- agentId: recovered.agentId,
448074
- conversationId: recovered.conversationId,
448075
- durableInputIdentities: continuationOwnership.durableInputIdentities,
448076
- terminalConsumerIds: continuationOwnership.terminalConsumerIds,
448077
- messages: continuationInput.messages
448078
- }, continuationBatchId);
448079
- emitDequeuedUserMessage(socket, runtime, queuedTurn, dequeuedBatch);
448080
- }
448081
448069
  if (!hasRecoveryOwnership()) {
448082
448070
  runtime.dequeuedClientMessageIdsByBatchId.delete(continuationBatchId);
448083
448071
  runtime.dequeuedInputIdentitiesByBatchId.delete(continuationBatchId);
448084
- if (consumedQueuedTurn) {
448085
- const { queuedTurn } = consumedQueuedTurn;
448086
- rehydrateClaimLostQueuedTurn(runtime, socket, queuedTurn, opts, processTurn);
448087
- }
448088
448072
  return;
448089
448073
  }
448090
448074
  const continuationConnectionId = selectedDeliveryOwnerId ?? opts?.connectionId;
448091
- const continuationActingUserId = consumedQueuedTurn ? consumedQueuedTurn.queuedTurn.actingUserId : recovered.actingUserId;
448075
+ const continuationActingUserId = recovered.actingUserId;
448092
448076
  await processTurn({
448093
448077
  type: "message",
448094
448078
  agentId: recovered.agentId,
@@ -448146,6 +448130,7 @@ async function executeRecoveredApprovalContinuation(params) {
448146
448130
  if (runtime.recoveredApprovalState === recovered) {
448147
448131
  clearRecoveredApprovalState(runtime);
448148
448132
  }
448133
+ scheduleQueuePump(runtime, socket, opts ?? {}, (queued, batch) => processTurn(queued, socket, runtime, opts?.onStatusChange, queued.connectionId ?? opts?.connectionId, batch.batchId));
448149
448134
  return;
448150
448135
  } catch (error5) {
448151
448136
  if (continuationFinalized) {
@@ -448199,20 +448184,17 @@ var init_recovery = __esm(async () => {
448199
448184
  init_toolset(),
448200
448185
  init_cloud_retry_message(),
448201
448186
  init_connection(),
448202
- init_continuation_input(),
448203
448187
  init_conversation_runtime(),
448204
448188
  init_interrupted_turn_record(),
448205
448189
  init_interrupts(),
448206
448190
  init_mod_adapter2(),
448207
448191
  init_protocol_outbound(),
448208
- init_queue(),
448209
448192
  init_recoverable_notices(),
448210
- init_recovered_queue_rehydration(),
448193
+ init_queue(),
448211
448194
  init_recovered_turn_finalizer(),
448212
448195
  init_recovery_evidence(),
448213
448196
  init_recovery_ownership(),
448214
448197
  init_runtime6(),
448215
- init_turn_correlation(),
448216
448198
  init_turn_durability_ownership(),
448217
448199
  init_turn_finished_replay(),
448218
448200
  init_turn_status()
@@ -448448,7 +448430,7 @@ async function resolveStaleApprovals(runtime, socket, turnLease, deps = {}) {
448448
448430
  runtime.currentToolset = preparedToolContext.toolset;
448449
448431
  runtime.currentToolsetPreference = preparedToolContext.toolsetPreference;
448450
448432
  runtime.currentLoadedTools = preparedToolContext.preparedToolContext.loadedToolNames;
448451
- let recoveryActingUserId = readInterruptedTurn(runtime)?.actingUserId;
448433
+ const recoveryActingUserId = readInterruptedTurn(runtime)?.actingUserId;
448452
448434
  while (pendingApprovals.length > 0) {
448453
448435
  assertCurrentTurnLease();
448454
448436
  const recoveryBatchId = resolveRecoveryBatchId(runtime, pendingApprovals);
@@ -448461,7 +448443,7 @@ async function resolveStaleApprovals(runtime, socket, turnLease, deps = {}) {
448461
448443
  return null;
448462
448444
  }
448463
448445
  try {
448464
- let continuationInput = createTurnInputState([
448446
+ const continuationInput = createTurnInputState([
448465
448447
  {
448466
448448
  type: "approval",
448467
448449
  approvals: approvalResults,
@@ -448469,14 +448451,6 @@ async function resolveStaleApprovals(runtime, socket, turnLease, deps = {}) {
448469
448451
  }
448470
448452
  ]);
448471
448453
  let recoveryTurnCorrelation;
448472
- const consumedQueuedTurn = consumeQueuedTurn(runtime);
448473
- if (consumedQueuedTurn) {
448474
- const { dequeuedBatch, queuedTurn } = consumedQueuedTurn;
448475
- recoveryActingUserId = queuedTurn.actingUserId;
448476
- recoveryTurnCorrelation = createTurnCorrelation(runtime, queuedTurn, dequeuedBatch.batchId);
448477
- continuationInput = appendQueuedTurnToInput(continuationInput, queuedTurn);
448478
- emitDequeuedUserMessage(socket, runtime, queuedTurn, dequeuedBatch);
448479
- }
448480
448454
  const continuationMessagesWithSkillContent = injectQueuedSkillContent(continuationInput.messages, {
448481
448455
  socket,
448482
448456
  runtime,
@@ -448848,14 +448822,11 @@ var init_send = __esm(async () => {
448848
448822
  init_toolset(),
448849
448823
  init_approval(),
448850
448824
  init_connection(),
448851
- init_continuation_input(),
448852
448825
  init_interrupted_turn_read(),
448853
448826
  init_mod_adapter2(),
448854
448827
  init_protocol_outbound(),
448855
- init_queue(),
448856
448828
  init_recovery(),
448857
448829
  init_skill_injection(),
448858
- init_turn_correlation(),
448859
448830
  init_turn_status()
448860
448831
  ]);
448861
448832
  ACTIVE_BLOCKING_RUN_STATUSES = new Set(["created", "running"]);
@@ -451162,6 +451133,18 @@ async function waitForApprovalTransportOpen(isDeliveryReady, shouldInterrupt) {
451162
451133
  }
451163
451134
  var APPROVAL_TRANSPORT_REOPEN_POLL_MS = 50;
451164
451135
 
451136
+ // src/websocket/listener/continuation-input.ts
451137
+ function appendQueuedTurnToInput(state2, queuedTurn) {
451138
+ return createTurnInputState([...state2.messages, ...queuedTurn.messages], mergeImageFailureModesByMessageOtid(state2.imageFailureModesByMessageOtid, getInboundImageFailureModes(queuedTurn)));
451139
+ }
451140
+ var init_continuation_input = __esm(async () => {
451141
+ init_turn_input_state();
451142
+ await __promiseAll([
451143
+ init_message_image_normalization(),
451144
+ init_image_policy()
451145
+ ]);
451146
+ });
451147
+
451165
451148
  // src/websocket/listener/turn-approval.ts
451166
451149
  async function handleApprovalStop(params) {
451167
451150
  const {
@@ -451638,7 +451621,7 @@ async function handleApprovalStop(params) {
451638
451621
  const sendOptions = buildSendOptions() ?? {};
451639
451622
  if (shouldInterrupt())
451640
451623
  return interruptTermination();
451641
- const consumedQueuedTurn = consumeQueuedTurn(runtime);
451624
+ const consumedQueuedTurn = params.allowQueuedContinuation === false ? null : consumeQueuedTurn(runtime, params.activeOriginatorScope ?? null);
451642
451625
  if (consumedQueuedTurn) {
451643
451626
  const { dequeuedBatch, queuedTurn } = consumedQueuedTurn;
451644
451627
  await params.onConsumeQueuedTurn?.(queuedTurn);
@@ -457346,13 +457329,17 @@ var init_execution_context_mcp_originator = __esm(async () => {
457346
457329
  // src/websocket/listener/turn-finalizer.ts
457347
457330
  function applyTurnOriginSwap(parkedInput, consumedTurn, turnToolContextId) {
457348
457331
  retireMcpOriginatorTokensOnOriginSwap(parkedInput.mcpOriginatorSuperRunId, consumedTurn.mcpOriginatorSuperRunId);
457349
- rebindTurnToolContextMcpOriginator(turnToolContextId, consumedTurn.mcpOriginatorSuperRunId);
457332
+ rebindTurnToolContextMcpOriginator(turnToolContextId, getEffectiveMcpOriginatorId(consumedTurn));
457350
457333
  }
457351
457334
  function createQueuedTurnConsumer(params) {
457352
- return async (queuedTurn) => {
457353
- applyTurnOriginSwap(params.parkedInput, queuedTurn, params.turnToolContextId);
457354
- params.ownership.recordInput(queuedTurn);
457355
- params.interruptedRevisionRef.current = await checkpointTurnInputOwnership(params.runtime, params.ownership, params.interruptedRevisionRef.current, queuedTurn.actingUserId, params.recoveryLineageId, params.recoveryEvidenceWriter);
457335
+ return {
457336
+ activeOriginatorScope: getMcpOriginatorScope(params.parkedInput),
457337
+ allowQueuedContinuation: params.parkedInput.messages.some((message2) => ("content" in message2)),
457338
+ onConsumeQueuedTurn: async (queuedTurn) => {
457339
+ applyTurnOriginSwap(params.parkedInput, queuedTurn, params.turnToolContextId);
457340
+ params.ownership.recordInput(queuedTurn);
457341
+ params.interruptedRevisionRef.current = await checkpointTurnInputOwnership(params.runtime, params.ownership, params.interruptedRevisionRef.current, queuedTurn.actingUserId, params.recoveryLineageId, params.recoveryEvidenceWriter);
457342
+ }
457356
457343
  };
457357
457344
  }
457358
457345
  function createTurnFinalizer(params) {
@@ -457947,7 +457934,7 @@ async function prepareListenerTurn(params) {
457947
457934
  conversationId,
457948
457935
  actingUserId: msg.actingUserId,
457949
457936
  suppressActingUserFallback: msg.suppressActingUserFallback,
457950
- mcpOriginatorSuperRunId: msg.mcpOriginatorSuperRunId,
457937
+ mcpOriginatorSuperRunId: getEffectiveMcpOriginatorId(msg),
457951
457938
  clientToolset: msg.clientToolset,
457952
457939
  clientToolAllowlist: msg.clientToolAllowlist,
457953
457940
  ...msg.excludeInteractiveTools ? { exclude: [...INTERACTIVE_USER_INPUT_TOOL_NAMES] } : {},
@@ -458657,7 +458644,7 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
458657
458644
  turnToolContextId,
458658
458645
  turnLease,
458659
458646
  turnCorrelation,
458660
- onConsumeQueuedTurn: createQueuedTurnConsumer({
458647
+ ...createQueuedTurnConsumer({
458661
458648
  parkedInput: msg,
458662
458649
  turnToolContextId,
458663
458650
  runtime,
@@ -461606,6 +461593,7 @@ function buildAppServerInfoResponse(command, options) {
461606
461593
  runtime_external_tools_update: true,
461607
461594
  structured_outputs: options.backend === "api",
461608
461595
  write_file_base64: true,
461596
+ mcp_originator_queue_isolation: true,
461609
461597
  split_channels: false
461610
461598
  }
461611
461599
  };
@@ -536241,4 +536229,4 @@ function registerBunOAuthFlows() {
536241
536229
  registerBunOAuthFlows();
536242
536230
  await init_src5().then(() => exports_src2);
536243
536231
 
536244
- //# debugId=9C7F976A516FF7CA64756E2164756E21
536232
+ //# debugId=13209D1BDC471C9864756E2164756E21