@letta-ai/letta-agent-sdk 0.8.72 → 0.8.74

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 (47) hide show
  1. package/README.md +69 -0
  2. package/dist/app-server-session.d.ts +28 -7
  3. package/dist/app-server-session.d.ts.map +1 -1
  4. package/dist/client-base.d.ts +17 -0
  5. package/dist/client-base.d.ts.map +1 -1
  6. package/dist/client-entry.d.ts +1 -0
  7. package/dist/client-entry.d.ts.map +1 -1
  8. package/dist/client-entry.js +480 -77
  9. package/dist/client-entry.js.map +15 -12
  10. package/dist/client.d.ts +9 -0
  11. package/dist/client.d.ts.map +1 -1
  12. package/dist/cloud-session.d.ts.map +1 -1
  13. package/dist/cloud-status-transport.d.ts.map +1 -1
  14. package/dist/external-tools.d.ts +11 -0
  15. package/dist/external-tools.d.ts.map +1 -0
  16. package/dist/index.d.ts +2 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +509 -103
  19. package/dist/index.js.map +17 -14
  20. package/dist/remote-client-session-core.d.ts.map +1 -1
  21. package/dist/remote-session-protocol.d.ts +3 -1
  22. package/dist/remote-session-protocol.d.ts.map +1 -1
  23. package/dist/remote-turn-coordinator.d.ts +14 -0
  24. package/dist/remote-turn-coordinator.d.ts.map +1 -1
  25. package/dist/runtime-tool-policy.d.ts +57 -0
  26. package/dist/runtime-tool-policy.d.ts.map +1 -0
  27. package/dist/structured-output-session.d.ts.map +1 -1
  28. package/dist/tool-registration.d.ts +67 -0
  29. package/dist/tool-registration.d.ts.map +1 -0
  30. package/dist/types.d.ts +30 -2
  31. package/dist/types.d.ts.map +1 -1
  32. package/package.json +3 -3
  33. package/src/app-server-session.ts +104 -60
  34. package/src/client-base.ts +57 -14
  35. package/src/client-entry.ts +1 -0
  36. package/src/client.ts +6 -2
  37. package/src/cloud-session.ts +12 -3
  38. package/src/cloud-status-transport.ts +4 -0
  39. package/src/external-tools.ts +69 -0
  40. package/src/index.ts +3 -0
  41. package/src/remote-client-session-core.ts +4 -4
  42. package/src/remote-session-protocol.ts +3 -0
  43. package/src/remote-turn-coordinator.ts +80 -15
  44. package/src/runtime-tool-policy.ts +114 -0
  45. package/src/structured-output-session.ts +2 -1
  46. package/src/tool-registration.ts +311 -0
  47. package/src/types.ts +39 -1
package/dist/index.js CHANGED
@@ -13183,7 +13183,7 @@ async function* streamStructuredTurns(config) {
13183
13183
  return;
13184
13184
  });
13185
13185
  }
13186
- if (msg.type !== "result") {
13186
+ if (msg.type !== "result" || msg.origin !== undefined) {
13187
13187
  yield msg;
13188
13188
  continue;
13189
13189
  }
@@ -13303,9 +13303,115 @@ function expandMcpToolWildcards(allowedTools, mcpTools) {
13303
13303
  return [...new Set(expanded)];
13304
13304
  }
13305
13305
 
13306
+ // src/external-tools.ts
13307
+ function externalToolGroups(tools) {
13308
+ if (!tools || tools.length === 0)
13309
+ return;
13310
+ return [
13311
+ {
13312
+ tools: tools.map((tool) => ({
13313
+ name: tool.name,
13314
+ label: tool.label,
13315
+ description: tool.description,
13316
+ parameters: tool.parameters
13317
+ }))
13318
+ }
13319
+ ];
13320
+ }
13321
+ var MAX_REMEMBERED_EXTERNAL_TOOL_CALLS = 200;
13322
+ function createExternalToolCallHandler(externalTools, fallbackRuntime) {
13323
+ const calls = new Map;
13324
+ const execute = async (request) => {
13325
+ const tool = externalTools.get(request.tool_name);
13326
+ if (!tool) {
13327
+ throw new Error(`Unknown external tool: ${request.tool_name}`);
13328
+ }
13329
+ const runtime = request.runtime ?? fallbackRuntime?.() ?? null;
13330
+ const context = runtime ? { toolCallId: request.tool_call_id, agentId: runtime.agent_id, conversationId: runtime.conversation_id } : undefined;
13331
+ const result = await tool.execute(request.tool_call_id, request.input, undefined, undefined, context);
13332
+ return {
13333
+ content: result.content.map((part) => ({
13334
+ type: part.type,
13335
+ ...part.text !== undefined ? { text: part.text } : {},
13336
+ ...part.data !== undefined ? { data: part.data } : {},
13337
+ ...part.mimeType !== undefined ? { mimeType: part.mimeType } : {}
13338
+ })),
13339
+ ...result.isError === true ? { is_error: true } : {}
13340
+ };
13341
+ };
13342
+ return (request) => {
13343
+ const requestId = request.request_id;
13344
+ if (typeof requestId !== "string" || requestId.length === 0) {
13345
+ return execute(request);
13346
+ }
13347
+ const existing = calls.get(requestId);
13348
+ if (existing)
13349
+ return existing;
13350
+ const call = execute(request);
13351
+ calls.set(requestId, call);
13352
+ while (calls.size > MAX_REMEMBERED_EXTERNAL_TOOL_CALLS) {
13353
+ const oldest = calls.keys().next().value;
13354
+ if (oldest === undefined)
13355
+ break;
13356
+ calls.delete(oldest);
13357
+ }
13358
+ return call;
13359
+ };
13360
+ }
13361
+
13362
+ // src/runtime-tool-policy.ts
13363
+ var RUNTIME_TOOL_POLICY_CAPABILITY = "runtime_tool_policy";
13364
+ var CAPABILITY_PROBE_TIMEOUT_MS = 5000;
13365
+ function clientToolsetPayload(toolset) {
13366
+ return {
13367
+ ...toolset.base !== undefined ? { base: toolset.base } : {},
13368
+ ...toolset.include !== undefined ? { include: [...new Set(toolset.include)] } : {}
13369
+ };
13370
+ }
13371
+ function runtimeToolPolicy(allowedTools, toolset) {
13372
+ return {
13373
+ ...toolset !== undefined ? { toolset: clientToolsetPayload(toolset) } : {},
13374
+ ...allowedTools !== undefined ? { allowlist: [...new Set(allowedTools)] } : {},
13375
+ exclude_interactive: true
13376
+ };
13377
+ }
13378
+ async function supportsRuntimeToolPolicy(client) {
13379
+ try {
13380
+ const info = await client.info({ timeoutMs: CAPABILITY_PROBE_TIMEOUT_MS });
13381
+ const capabilities = info.capabilities;
13382
+ return capabilities?.[RUNTIME_TOOL_POLICY_CAPABILITY] === true;
13383
+ } catch {
13384
+ return false;
13385
+ }
13386
+ }
13387
+ function mergeInheritedTools(inherited, own) {
13388
+ if (!inherited)
13389
+ return own;
13390
+ const tools = new Map(inherited.tools.map((tool) => [tool.name, tool]));
13391
+ for (const tool of own.tools)
13392
+ tools.set(tool.name, tool);
13393
+ const ownNames = new Set(own.tools.map((tool) => tool.name));
13394
+ const registered = inherited.allowedTools;
13395
+ const allowedTools = registered === undefined ? own.allowedTools : own.allowedTools === undefined ? [...new Set([...registered, ...ownNames])] : own.allowedTools.filter((name) => registered.includes(name) || ownNames.has(name));
13396
+ const toolset = own.toolset ?? inherited.toolset;
13397
+ return {
13398
+ tools: [...tools.values()],
13399
+ ...allowedTools !== undefined ? { allowedTools } : {},
13400
+ ...toolset !== undefined ? { toolset } : {}
13401
+ };
13402
+ }
13403
+
13306
13404
  // src/remote-turn-coordinator.ts
13307
13405
  var MAX_RECENTLY_SETTLED_RUN_IDS = 256;
13308
13406
  var TRAILING_USAGE_GRACE_MS = 100;
13407
+ var TURN_ORIGINS = new Set([
13408
+ "task_notification",
13409
+ "cron",
13410
+ "subagent",
13411
+ "system",
13412
+ "channel",
13413
+ "user"
13414
+ ]);
13309
13415
 
13310
13416
  class RemoteTurnCoordinator {
13311
13417
  label;
@@ -13317,6 +13423,8 @@ class RemoteTurnCoordinator {
13317
13423
  activeTurn = null;
13318
13424
  pendingTurns = [];
13319
13425
  settledRunIds = new Set;
13426
+ queueOrigins = new Map;
13427
+ nextServerOrigin = "unknown";
13320
13428
  nextTurnId = 0;
13321
13429
  messageCounter = 0;
13322
13430
  clientMessageCounter = 0;
@@ -13332,16 +13440,27 @@ class RemoteTurnCoordinator {
13332
13440
  return this._activeTurnStartedAt;
13333
13441
  }
13334
13442
  hasInFlightTurn() {
13335
- return this.activeTurn !== null || this.pendingTurns.length > 0;
13443
+ return this.activeTurn !== null && this.activeTurn.origin === undefined || this.pendingTurns.length > 0;
13336
13444
  }
13337
13445
  trackSentTurn(runtime, callerOtid, outputFormat) {
13338
13446
  const otid = normalizeCallerOtid(callerOtid);
13339
- const turn = {
13340
- id: ++this.nextTurnId,
13341
- runtime,
13447
+ const turn = this.newTracker(runtime, {
13342
13448
  ...otid !== undefined ? { otid } : {},
13343
13449
  ...outputFormat !== undefined ? { outputFormat } : {},
13344
- clientMessageId: otid ?? `sdk-message-${Date.now()}-${++this.clientMessageCounter}`,
13450
+ clientMessageId: otid ?? `sdk-message-${Date.now()}-${++this.clientMessageCounter}`
13451
+ });
13452
+ if (this.activeTurn) {
13453
+ this.pendingTurns.push(turn);
13454
+ } else {
13455
+ this.activateTurn(turn);
13456
+ }
13457
+ return turn;
13458
+ }
13459
+ newTracker(runtime, identity) {
13460
+ return {
13461
+ id: ++this.nextTurnId,
13462
+ runtime,
13463
+ ...identity,
13345
13464
  queuedAt: Date.now(),
13346
13465
  startedAt: 0,
13347
13466
  assistantText: "",
@@ -13358,13 +13477,32 @@ class RemoteTurnCoordinator {
13358
13477
  abortRequested: false,
13359
13478
  timeout: null
13360
13479
  };
13361
- if (this.activeTurn) {
13362
- this.pendingTurns.push(turn);
13363
- } else {
13364
- this.activateTurn(turn);
13365
- }
13480
+ }
13481
+ startServerTurn(runtime) {
13482
+ const turn = this.newTracker(runtime, { clientMessageId: "", origin: this.nextServerOrigin });
13483
+ this.nextServerOrigin = "unknown";
13484
+ this.activateTurn(turn);
13366
13485
  return turn;
13367
13486
  }
13487
+ observeQueueOrigins(message, queue) {
13488
+ for (const item of queue) {
13489
+ if (!item.clientMessageId)
13490
+ continue;
13491
+ this.queueOrigins.set(item.clientMessageId, TURN_ORIGINS.has(item.source) ? item.source : "unknown");
13492
+ if (this.queueOrigins.size > MAX_RECENTLY_SETTLED_RUN_IDS) {
13493
+ this.queueOrigins.delete(this.queueOrigins.keys().next().value);
13494
+ }
13495
+ }
13496
+ for (const removed of Array.isArray(message.removed) ? message.removed : []) {
13497
+ const { client_message_id: id, disposition, source } = removed;
13498
+ if (disposition !== "dequeued" || typeof id !== "string")
13499
+ continue;
13500
+ const own = [this.activeTurn, ...this.pendingTurns].some((turn) => turn?.clientMessageId === id);
13501
+ if (own)
13502
+ continue;
13503
+ this.nextServerOrigin = typeof source === "string" && TURN_ORIGINS.has(source) ? source : this.queueOrigins.get(id) ?? "unknown";
13504
+ }
13505
+ }
13368
13506
  removeTrackedTurn(turn) {
13369
13507
  if (turn.timeout)
13370
13508
  clearTimeout(turn.timeout);
@@ -13378,6 +13516,12 @@ class RemoteTurnCoordinator {
13378
13516
  if (index !== -1)
13379
13517
  this.pendingTurns.splice(index, 1);
13380
13518
  }
13519
+ failServerTurn(detail) {
13520
+ const active = this.activeTurn;
13521
+ if (active?.origin === undefined)
13522
+ return;
13523
+ this.failTurn(active, detail, { errorCode: "stream_closed", recoverable: true });
13524
+ }
13381
13525
  markAbortRequested() {
13382
13526
  if (this.activeTurn)
13383
13527
  this.activeTurn.abortRequested = true;
@@ -13397,6 +13541,7 @@ class RemoteTurnCoordinator {
13397
13541
  type: "queue_update",
13398
13542
  queue: queueItems(message)
13399
13543
  };
13544
+ this.observeQueueOrigins(message, sdkMessage2.queue);
13400
13545
  this.enqueue(sdkMessage2);
13401
13546
  return;
13402
13547
  }
@@ -13439,9 +13584,9 @@ class RemoteTurnCoordinator {
13439
13584
  if (!delta)
13440
13585
  return;
13441
13586
  const messageType = streamDeltaMessageType(delta);
13442
- const active = messageType === "usage_statistics" || messageType === "stop_reason" ? this.activeTurn : this.activateNextTurnFromProtocol();
13443
13587
  const runId = streamDeltaRunId(delta);
13444
13588
  const isTurnEvidence = messageType === "assistant_message" || messageType === "reasoning_message" || messageType === "tool_call_message" || messageType === "approval_request_message" || messageType === "tool_return_message" || messageType === "error_message" || messageType === "loop_error" || runId !== undefined && (messageType === "usage_statistics" || messageType === "stop_reason");
13589
+ const active = messageType === "usage_statistics" || messageType === "stop_reason" ? this.activeTurn : this.activateNextTurnFromProtocol() ?? (isTurnEvidence && runId !== undefined ? this.startServerTurn(runtime) : null);
13445
13590
  if (active && isTurnEvidence) {
13446
13591
  active.observedTurnEvidence = true;
13447
13592
  if (runId)
@@ -13899,7 +14044,8 @@ class RemoteTurnCoordinator {
13899
14044
  stopReason,
13900
14045
  durationMs: Date.now() - (tracker?.startedAt || this._activeTurnStartedAt),
13901
14046
  conversationId: turn.runtime.conversation_id,
13902
- runIds: turn.runIds.length > 0 ? turn.runIds : undefined
14047
+ runIds: turn.runIds.length > 0 ? turn.runIds : undefined,
14048
+ ...tracker?.origin !== undefined ? { origin: tracker.origin } : {}
13903
14049
  };
13904
14050
  }
13905
14051
  enqueue(message) {
@@ -14141,9 +14287,8 @@ class RemoteClientSessionCore {
14141
14287
  }
14142
14288
  await this.send(message);
14143
14289
  for await (const msg of this.stream()) {
14144
- if (msg.type === "result") {
14290
+ if (msg.type === "result" && msg.origin === undefined)
14145
14291
  return msg;
14146
- }
14147
14292
  }
14148
14293
  return {
14149
14294
  type: "result",
@@ -14179,7 +14324,7 @@ class RemoteClientSessionCore {
14179
14324
  if (!msg)
14180
14325
  break;
14181
14326
  yield msg;
14182
- if (msg.type === "result")
14327
+ if (msg.type === "result" && msg.origin === undefined)
14183
14328
  break;
14184
14329
  }
14185
14330
  }
@@ -14489,6 +14634,7 @@ class RemoteClientSessionCore {
14489
14634
  this.controller?.close();
14490
14635
  this.controller = null;
14491
14636
  const error = new Error(`${this.label} connection closed before send`);
14637
+ this.turns.failServerTurn(error.message);
14492
14638
  for (const cancel of [...this.deviceStatusRefreshCancels])
14493
14639
  cancel(error);
14494
14640
  this.deviceStatusRefreshCancels.clear();
@@ -14629,38 +14775,6 @@ function agentToolNames(agent) {
14629
14775
  return typeof name === "string" && name.length > 0 ? [name] : [];
14630
14776
  });
14631
14777
  }
14632
- function externalToolGroups(tools) {
14633
- if (!tools || tools.length === 0)
14634
- return;
14635
- return [
14636
- {
14637
- tools: tools.map((tool) => ({
14638
- name: tool.name,
14639
- label: tool.label,
14640
- description: tool.description,
14641
- parameters: tool.parameters
14642
- }))
14643
- }
14644
- ];
14645
- }
14646
- function createExternalToolCallHandler(externalTools) {
14647
- return async (request) => {
14648
- const tool = externalTools.get(request.tool_name);
14649
- if (!tool) {
14650
- throw new Error(`Unknown external tool: ${request.tool_name}`);
14651
- }
14652
- const result = await tool.execute(request.tool_call_id, request.input);
14653
- return {
14654
- content: result.content.map((part) => ({
14655
- type: part.type,
14656
- ...part.text !== undefined ? { text: part.text } : {},
14657
- ...part.data !== undefined ? { data: part.data } : {},
14658
- ...part.mimeType !== undefined ? { mimeType: part.mimeType } : {}
14659
- })),
14660
- ...result.isError === true ? { is_error: true } : {}
14661
- };
14662
- };
14663
- }
14664
14778
  async function resolveAppServerToolApproval(options, toolName, toolInput, context) {
14665
14779
  if ("outputFormat" in options && options.outputFormat !== undefined && toolName === STRUCTURED_OUTPUT_TOOL) {
14666
14780
  return { behavior: "allow", updatedInput: null, updatedPermissions: [] };
@@ -14837,11 +14951,26 @@ class AppServerRuntimeController {
14837
14951
  options;
14838
14952
  clientToolAllowlist;
14839
14953
  clientToolset;
14840
- constructor(client, options, clientToolAllowlist, clientToolset) {
14954
+ toolPolicyApplied;
14955
+ constructor(client, options, clientToolAllowlist, clientToolset, toolPolicyApplied = false) {
14841
14956
  this.client = client;
14842
14957
  this.options = options;
14843
14958
  this.clientToolAllowlist = clientToolAllowlist;
14844
14959
  this.clientToolset = clientToolset;
14960
+ this.toolPolicyApplied = toolPolicyApplied;
14961
+ }
14962
+ async updateToolSelection(runtime, selection) {
14963
+ this.clientToolAllowlist = selection.allowedTools;
14964
+ this.clientToolset = selection.toolset;
14965
+ const response = await this.client.runtimeExternalToolsUpdate({
14966
+ updates: [{
14967
+ runtimes: [runtime],
14968
+ external_tools: externalToolGroups(selection.tools) ?? [],
14969
+ ...this.toolPolicyApplied ? { tool_policy: runtimeToolPolicy(selection.allowedTools, selection.toolset) } : {}
14970
+ }]
14971
+ });
14972
+ if (!response.success)
14973
+ throw new Error(response.error ?? "Failed to update session tools");
14845
14974
  }
14846
14975
  onMessage(handler) {
14847
14976
  return this.client.onMessage((message, channel) => {
@@ -14863,14 +14992,11 @@ class AppServerRuntimeController {
14863
14992
  }
14864
14993
  ]
14865
14994
  };
14866
- if (this.clientToolAllowlist !== undefined) {
14995
+ if (!this.toolPolicyApplied && this.clientToolAllowlist !== undefined) {
14867
14996
  payload.client_tool_allowlist = [...new Set(this.clientToolAllowlist)];
14868
14997
  }
14869
- if (this.clientToolset !== undefined) {
14870
- payload.client_toolset = {
14871
- ...this.clientToolset.base !== undefined ? { base: this.clientToolset.base } : {},
14872
- ...this.clientToolset.include !== undefined ? { include: [...new Set(this.clientToolset.include)] } : {}
14873
- };
14998
+ if (!this.toolPolicyApplied && this.clientToolset !== undefined) {
14999
+ payload.client_toolset = clientToolsetPayload(this.clientToolset);
14874
15000
  }
14875
15001
  if (options.outputFormat !== undefined) {
14876
15002
  payload.response_format = {
@@ -14882,7 +15008,8 @@ class AppServerRuntimeController {
14882
15008
  }
14883
15009
  };
14884
15010
  }
14885
- payload.exclude_interactive_tools = true;
15011
+ if (!this.toolPolicyApplied)
15012
+ payload.exclude_interactive_tools = true;
14886
15013
  this.client.input({
14887
15014
  runtime,
14888
15015
  payload
@@ -14974,6 +15101,9 @@ class AppServerSession extends RemoteClientSessionCore {
14974
15101
  mcpCleanup = Promise.resolve();
14975
15102
  removeExternalToolHandler = null;
14976
15103
  removeControlRequestHandler = null;
15104
+ inheritedTools = null;
15105
+ removeInheritedListener = null;
15106
+ ownSelection = null;
14977
15107
  constructor(remoteOptions, mode) {
14978
15108
  super(mode, {
14979
15109
  label: "app-server",
@@ -14985,6 +15115,27 @@ class AppServerSession extends RemoteClientSessionCore {
14985
15115
  this.externalTools.set(tool.name, tool);
14986
15116
  }
14987
15117
  }
15118
+ inheritTools(source) {
15119
+ this.inheritedTools = source;
15120
+ this.removeInheritedListener = source.onChange(() => {
15121
+ this.refreshInheritedTools().catch(() => {
15122
+ return;
15123
+ });
15124
+ });
15125
+ }
15126
+ applyToolSelection() {
15127
+ const selection = mergeInheritedTools(this.inheritedTools?.current() ?? null, this.ownSelection ?? { tools: [] });
15128
+ this.externalTools.clear();
15129
+ for (const tool of selection.tools)
15130
+ this.externalTools.set(tool.name, tool);
15131
+ return selection;
15132
+ }
15133
+ async refreshInheritedTools() {
15134
+ if (!this.ownSelection || !this.runtime || !(this.controller instanceof AppServerRuntimeController))
15135
+ return;
15136
+ const selection = this.applyToolSelection();
15137
+ await this.controller.updateToolSelection(this.runtime, selection);
15138
+ }
14988
15139
  shouldEnableMemfs(options) {
14989
15140
  if (this.mode.kind !== "create-agent")
14990
15141
  return false;
@@ -15000,6 +15151,9 @@ class AppServerSession extends RemoteClientSessionCore {
15000
15151
  ...this.remoteOptions.requestTimeoutMs !== undefined ? { requestTimeoutMs: this.remoteOptions.requestTimeoutMs } : {}
15001
15152
  }));
15002
15153
  const options = this.currentOptions();
15154
+ this.externalTools.clear();
15155
+ for (const tool of this.mode.options.tools ?? [])
15156
+ this.externalTools.set(tool.name, tool);
15003
15157
  this.mcpBridge = await connectMcpServers("mcpServers" in options ? options.mcpServers : undefined, {
15004
15158
  cwd: options.cwd,
15005
15159
  reservedToolNames: this.externalTools.keys()
@@ -15007,13 +15161,22 @@ class AppServerSession extends RemoteClientSessionCore {
15007
15161
  for (const tool of this.mcpBridge.tools) {
15008
15162
  this.externalTools.set(tool.name, tool);
15009
15163
  }
15164
+ const mcpToolNames = this.mcpBridge.tools.map((tool) => tool.name);
15165
+ const ownToolset = "toolset" in options ? options.toolset : undefined;
15166
+ const ownAllowedTools = expandMcpToolWildcards(options.allowedTools, mcpToolNames);
15167
+ this.ownSelection = {
15168
+ tools: [...this.externalTools.values()],
15169
+ ...ownAllowedTools !== undefined ? { allowedTools: ownAllowedTools } : {},
15170
+ ...ownToolset !== undefined ? { toolset: ownToolset } : {}
15171
+ };
15172
+ const { allowedTools, toolset: clientToolset } = this.applyToolSelection();
15010
15173
  this.removeControlRequestHandler = registerAppServerControlRequestHandler({
15011
15174
  client,
15012
15175
  getRuntime: () => this.runtime,
15013
15176
  getOptions: () => this.currentOptions()
15014
15177
  });
15015
- if (this.externalTools.size > 0) {
15016
- this.removeExternalToolHandler = client.onExternalToolCall(createExternalToolCallHandler(this.externalTools));
15178
+ if (this.externalTools.size > 0 || this.inheritedTools) {
15179
+ this.removeExternalToolHandler = client.onExternalToolCall(createExternalToolCallHandler(this.externalTools, () => this.runtime));
15017
15180
  }
15018
15181
  try {
15019
15182
  await client.connect();
@@ -15024,19 +15187,17 @@ class AppServerSession extends RemoteClientSessionCore {
15024
15187
  throw new Error(`Local query() requires a Letta Code app-server with local conversation support (connected version: ${info.letta_code_version}). Upgrade @letta-ai/letta-code.`);
15025
15188
  }
15026
15189
  }
15027
- const response = await this.startRuntime(client);
15190
+ const response = await this.startRuntime(client, runtimeToolPolicy(allowedTools, clientToolset));
15028
15191
  if (!response.success || !response.runtime) {
15029
15192
  throw new Error(response.error ?? "Failed to start app-server runtime");
15030
15193
  }
15031
15194
  this.watchTransportDisconnect(client);
15195
+ const toolPolicyApplied = await supportsRuntimeToolPolicy(client);
15032
15196
  const tools = agentToolNames(response.agent);
15033
15197
  const skillSources = options.skillSources;
15034
- const clientToolset = "toolset" in options ? options.toolset : undefined;
15035
- const mcpToolNames = this.mcpBridge?.tools.map((tool) => tool.name) ?? [];
15036
- const allowedTools = expandMcpToolWildcards(options.allowedTools, mcpToolNames);
15037
15198
  const availableTools = tools === undefined && mcpToolNames.length === 0 ? undefined : [...tools ?? [], ...mcpToolNames];
15038
15199
  return {
15039
- controller: new AppServerRuntimeController(client, this.remoteOptions, allowedTools, clientToolset),
15200
+ controller: new AppServerRuntimeController(client, this.remoteOptions, allowedTools, clientToolset, toolPolicyApplied),
15040
15201
  runtime: response.runtime,
15041
15202
  model: typeof response.agent?.model === "string" ? response.agent.model : typeof response.conversation?.model === "string" ? response.conversation.model : "",
15042
15203
  modelSettings: objectRecord(response.agent?.model_settings) ?? objectRecord(response.conversation?.model_settings) ?? null,
@@ -15054,6 +15215,10 @@ class AppServerSession extends RemoteClientSessionCore {
15054
15215
  }
15055
15216
  }
15056
15217
  onCoreClose() {
15218
+ if (this.closed) {
15219
+ this.removeInheritedListener?.();
15220
+ this.removeInheritedListener = null;
15221
+ }
15057
15222
  this.removeExternalToolHandler?.();
15058
15223
  this.removeExternalToolHandler = null;
15059
15224
  this.removeControlRequestHandler?.();
@@ -15084,11 +15249,11 @@ class AppServerSession extends RemoteClientSessionCore {
15084
15249
  this.ownedConnection = connection;
15085
15250
  return connection.url;
15086
15251
  }
15087
- async startRuntime(client) {
15088
- const command = await this.buildRuntimeStartCommand(client);
15252
+ async startRuntime(client, toolPolicy) {
15253
+ const command = await this.buildRuntimeStartCommand(client, toolPolicy);
15089
15254
  return client.runtimeStart(command);
15090
15255
  }
15091
- async buildRuntimeStartCommand(client) {
15256
+ async buildRuntimeStartCommand(client, toolPolicy) {
15092
15257
  const options = this.mode.options;
15093
15258
  const command = {
15094
15259
  client_info: {
@@ -15119,6 +15284,7 @@ class AppServerSession extends RemoteClientSessionCore {
15119
15284
  const groups = externalToolGroups([...this.externalTools.values()]);
15120
15285
  if (groups)
15121
15286
  command.external_tools = groups;
15287
+ command.tool_policy = toolPolicy;
15122
15288
  if (this.mode.kind === "create-agent") {
15123
15289
  command.create_agent = {
15124
15290
  body: await createAgentBody(this.mode.options),
@@ -15601,6 +15767,9 @@ class CloudStatusTransport {
15601
15767
  if (channel === "control" && message.type === "stream_delta") {
15602
15768
  return false;
15603
15769
  }
15770
+ if (channel === "stream" && message.type === "external_tool_call_request") {
15771
+ return false;
15772
+ }
15604
15773
  if (this.isDuplicate(message))
15605
15774
  return false;
15606
15775
  this.trackEventSequence(message);
@@ -16097,7 +16266,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
16097
16266
  getOptions: () => this.currentOptions()
16098
16267
  });
16099
16268
  if (this.externalTools.size > 0) {
16100
- this.removeExternalToolHandler = client.onExternalToolCall(createExternalToolCallHandler(this.externalTools));
16269
+ this.removeExternalToolHandler = client.onExternalToolCall(createExternalToolCallHandler(this.externalTools, () => this.runtime));
16101
16270
  }
16102
16271
  }
16103
16272
  cleanupTransportHandlers() {
@@ -16155,6 +16324,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
16155
16324
  const groups = externalToolGroups([...this.externalTools.values()]);
16156
16325
  if (groups)
16157
16326
  command.external_tools = groups;
16327
+ command.tool_policy = runtimeToolPolicy(expandMcpToolWildcards(options.allowedTools, this.mcpBridge?.tools.map((tool) => tool.name) ?? []), "toolset" in options ? options.toolset : undefined);
16158
16328
  return await client.runtimeStart(command);
16159
16329
  }
16160
16330
  async afterRuntimeInitialized() {
@@ -16720,6 +16890,221 @@ function createQuery(createSession, params) {
16720
16890
  });
16721
16891
  }
16722
16892
 
16893
+ // src/tool-registration.ts
16894
+ var RECONNECT_DELAYS_MS = [250, 1000, 5000, 15000];
16895
+ var runtimeKey = (runtime) => `${runtime.agent_id}:${runtime.conversation_id}`;
16896
+
16897
+ class ToolRegistry {
16898
+ options;
16899
+ connection = null;
16900
+ entries = new Set;
16901
+ listeners = new Set;
16902
+ reconnectAttempt = 0;
16903
+ reconnectTimer = null;
16904
+ closed = false;
16905
+ constructor(options) {
16906
+ this.options = options;
16907
+ }
16908
+ async register(options) {
16909
+ if (this.closed)
16910
+ throw new Error("LettaAgentClient is closed");
16911
+ const entry = { options, runtimes: [], call: createExternalToolCallHandler(new Map) };
16912
+ await this.apply(entry, options);
16913
+ const registry = this;
16914
+ return {
16915
+ get conversations() {
16916
+ return [...entry.options.conversations];
16917
+ },
16918
+ update: async (next) => {
16919
+ if (!registry.entries.has(entry))
16920
+ throw new Error("This tool registration is closed.");
16921
+ await registry.apply(entry, { ...entry.options, ...next });
16922
+ },
16923
+ close: () => registry.remove(entry),
16924
+ [Symbol.asyncDispose]: () => registry.remove(entry)
16925
+ };
16926
+ }
16927
+ close() {
16928
+ this.closed = true;
16929
+ this.entries.clear();
16930
+ this.disconnect();
16931
+ this.notify();
16932
+ }
16933
+ inheritFor(id, own) {
16934
+ const covering = this.covering(id);
16935
+ if (!covering)
16936
+ return null;
16937
+ const registered = new Set(covering.options.tools.map((tool) => tool.name));
16938
+ const clash = own.tools?.find((tool) => registered.has(tool.name));
16939
+ if (clash) {
16940
+ throw new Error(`Tool ${clash.name} is already registered for ${id} with registerTools(); don't pass it to the session again.`);
16941
+ }
16942
+ if (own.toolset !== undefined && covering.options.toolset !== undefined && JSON.stringify(own.toolset) !== JSON.stringify(covering.options.toolset)) {
16943
+ throw new Error(`${id} already has a toolset from registerTools(); narrow it with the session's allowedTools instead.`);
16944
+ }
16945
+ return {
16946
+ current: () => this.covering(id)?.options ?? null,
16947
+ onChange: (listener) => {
16948
+ this.listeners.add(listener);
16949
+ return () => this.listeners.delete(listener);
16950
+ }
16951
+ };
16952
+ }
16953
+ covering(id) {
16954
+ return [...this.entries].find((entry) => entry.options.conversations.includes(id) || entry.runtimes.some((runtime) => runtime.conversation_id === id || runtime.conversation_id === "default" && runtime.agent_id === id));
16955
+ }
16956
+ notify() {
16957
+ for (const listener of [...this.listeners])
16958
+ listener();
16959
+ }
16960
+ async apply(entry, options) {
16961
+ if (!Array.isArray(options.conversations) || options.conversations.length === 0) {
16962
+ throw new Error("registerTools() requires at least one conversation.");
16963
+ }
16964
+ if (!Array.isArray(options.tools))
16965
+ throw new Error("registerTools() requires a tools array.");
16966
+ const connection = await this.connect();
16967
+ if (!connection.toolPolicy && (options.allowedTools || options.toolset)) {
16968
+ throw new Error("registerTools() allowedTools and toolset require a Letta Code app server that supports runtime tool policies. Upgrade @letta-ai/letta-code.");
16969
+ }
16970
+ const runtimes = await Promise.all(options.conversations.map((id) => resolveRuntime(connection.client, id)));
16971
+ const taken = new Set([...this.entries].filter((other) => other !== entry).flatMap((other) => other.runtimes.map(runtimeKey)));
16972
+ const overlap = options.conversations.find((_, index) => taken.has(runtimeKey(runtimes[index])));
16973
+ if (overlap)
16974
+ throw new Error(`Tools are already registered for ${overlap}.`);
16975
+ const keys = new Set(runtimes.map(runtimeKey));
16976
+ const dropped = entry.runtimes.filter((runtime) => !keys.has(runtimeKey(runtime)));
16977
+ const previous = { ...entry };
16978
+ const isNew = !this.entries.has(entry);
16979
+ entry.options = options;
16980
+ entry.runtimes = runtimes;
16981
+ entry.call = createExternalToolCallHandler(new Map(options.tools.map((tool) => [tool.name, tool])));
16982
+ this.entries.add(entry);
16983
+ try {
16984
+ await publish(connection.client, [
16985
+ group(runtimes, options, connection.toolPolicy),
16986
+ ...dropped.length > 0 ? [{ runtimes: dropped, external_tools: [] }] : []
16987
+ ]);
16988
+ } catch (error) {
16989
+ Object.assign(entry, previous);
16990
+ if (isNew)
16991
+ this.entries.delete(entry);
16992
+ throw error;
16993
+ }
16994
+ this.notify();
16995
+ }
16996
+ async remove(entry) {
16997
+ if (!this.entries.delete(entry))
16998
+ return;
16999
+ this.notify();
17000
+ if (this.entries.size === 0) {
17001
+ this.disconnect();
17002
+ return;
17003
+ }
17004
+ const connection = await this.connect();
17005
+ await publish(connection.client, [{ runtimes: entry.runtimes, external_tools: [] }]);
17006
+ }
17007
+ connect() {
17008
+ this.connection ??= this.open().catch((error) => {
17009
+ this.connection = null;
17010
+ throw error;
17011
+ });
17012
+ return this.connection;
17013
+ }
17014
+ async open() {
17015
+ const owned = this.options.url ? null : await this.options.connect?.();
17016
+ const url = this.options.url ?? owned?.url;
17017
+ if (!url)
17018
+ throw new Error("registerTools() requires an app-server url.");
17019
+ const client = applyUniqueRequestIds(createAppServerClient({
17020
+ url,
17021
+ ...this.options.authToken !== undefined ? { authToken: this.options.authToken } : {},
17022
+ ...this.options.WebSocket ? { WebSocket: this.options.WebSocket } : {},
17023
+ ...this.options.requestTimeoutMs !== undefined ? { requestTimeoutMs: this.options.requestTimeoutMs } : {}
17024
+ }));
17025
+ client.onExternalToolCall(async (request) => {
17026
+ const runtime = request.runtime;
17027
+ const entry = runtime && [...this.entries].find((candidate) => candidate.runtimes.some((r) => runtimeKey(r) === runtimeKey(runtime)));
17028
+ if (!entry)
17029
+ throw new Error(`No tools registered for conversation ${runtime?.conversation_id}`);
17030
+ return entry.call(request);
17031
+ });
17032
+ try {
17033
+ await client.connect();
17034
+ } catch (error) {
17035
+ client.close();
17036
+ owned?.close();
17037
+ throw error;
17038
+ }
17039
+ client.onDisconnect(() => this.onDisconnect(client));
17040
+ return { client, owned: owned ?? null, toolPolicy: await supportsRuntimeToolPolicy(client) };
17041
+ }
17042
+ disconnect() {
17043
+ if (this.reconnectTimer)
17044
+ clearTimeout(this.reconnectTimer);
17045
+ this.reconnectTimer = null;
17046
+ const connection = this.connection;
17047
+ this.connection = null;
17048
+ connection?.then(({ client, owned }) => {
17049
+ client.close();
17050
+ owned?.close();
17051
+ }, () => {
17052
+ return;
17053
+ });
17054
+ }
17055
+ onDisconnect(client) {
17056
+ this.connection?.then((current) => {
17057
+ if (current.client !== client)
17058
+ return;
17059
+ current.owned?.close();
17060
+ this.connection = null;
17061
+ this.scheduleReconnect();
17062
+ }, () => {
17063
+ return;
17064
+ });
17065
+ }
17066
+ scheduleReconnect() {
17067
+ if (this.closed || this.entries.size === 0 || this.reconnectTimer)
17068
+ return;
17069
+ const delay = RECONNECT_DELAYS_MS[Math.min(this.reconnectAttempt, RECONNECT_DELAYS_MS.length - 1)];
17070
+ this.reconnectAttempt += 1;
17071
+ this.reconnectTimer = setTimeout(() => {
17072
+ this.reconnectTimer = null;
17073
+ this.republish().catch(() => this.scheduleReconnect());
17074
+ }, delay);
17075
+ this.reconnectTimer.unref?.();
17076
+ }
17077
+ async republish() {
17078
+ const connection = await this.connect();
17079
+ await publish(connection.client, [...this.entries].map((entry) => group(entry.runtimes, entry.options, connection.toolPolicy)));
17080
+ this.reconnectAttempt = 0;
17081
+ }
17082
+ }
17083
+ function group(runtimes, options, toolPolicy) {
17084
+ return {
17085
+ runtimes,
17086
+ external_tools: externalToolGroups(options.tools) ?? [],
17087
+ ...toolPolicy ? { tool_policy: runtimeToolPolicy(options.allowedTools, options.toolset) } : {}
17088
+ };
17089
+ }
17090
+ async function publish(client, updates) {
17091
+ const response = await client.runtimeExternalToolsUpdate({ updates });
17092
+ if (!response.success)
17093
+ throw new Error(response.error ?? "Failed to register tools");
17094
+ }
17095
+ async function resolveRuntime(client, id) {
17096
+ if (!id.startsWith("conv-") && !id.startsWith("local-conv-")) {
17097
+ return { agent_id: id, conversation_id: "default" };
17098
+ }
17099
+ const response = await client.request({ type: "conversation_retrieve", request_id: client.nextRequestId("conversation_retrieve"), conversation_id: id }, {
17100
+ predicate: (message) => message.type === "conversation_retrieve_response"
17101
+ });
17102
+ if (!response.success || !response.conversation) {
17103
+ throw new Error(response.error ?? `Failed to retrieve conversation ${id}`);
17104
+ }
17105
+ return { agent_id: response.conversation.agent_id ?? null, conversation_id: id };
17106
+ }
17107
+
16723
17108
  // src/validation.ts
16724
17109
  var VALID_SKILL_SOURCES = [
16725
17110
  "bundled",
@@ -16996,6 +17381,7 @@ class LettaAgentClientBase {
16996
17381
  agentRepositoriesClient = null;
16997
17382
  cloudClient = null;
16998
17383
  managementTransport = null;
17384
+ toolRegistry = null;
16999
17385
  closed = false;
17000
17386
  closePromise = null;
17001
17387
  constructor(options = {}) {
@@ -17114,20 +17500,21 @@ class LettaAgentClientBase {
17114
17500
  const sessionOptions = stripCloudExecutionOptions(options);
17115
17501
  validateCreateSessionOptions(sessionOptions);
17116
17502
  this.assertSessionBackend("resumeSession", options);
17503
+ const inherited = this.backend === "cloud" ? null : this.toolRegistry?.inheritFor(id, sessionOptions) ?? null;
17117
17504
  if (this.backend === "remote") {
17118
- if (looksLikeConversationId(id)) {
17119
- return new AppServerSession(this.appServerSessionOptions(), {
17120
- kind: "session",
17121
- conversationId: id,
17122
- options
17123
- });
17124
- }
17125
- return new AppServerSession(this.appServerSessionOptions(), {
17505
+ const session2 = looksLikeConversationId(id) ? new AppServerSession(this.appServerSessionOptions(), {
17506
+ kind: "session",
17507
+ conversationId: id,
17508
+ options
17509
+ }) : new AppServerSession(this.appServerSessionOptions(), {
17126
17510
  kind: "session",
17127
17511
  agentId: id,
17128
17512
  defaultConversation: true,
17129
17513
  options
17130
17514
  });
17515
+ if (inherited)
17516
+ session2.inheritTools(inherited);
17517
+ return session2;
17131
17518
  }
17132
17519
  if (this.backend === "cloud") {
17133
17520
  if (looksLikeConversationId(id)) {
@@ -17144,7 +17531,10 @@ class LettaAgentClientBase {
17144
17531
  options
17145
17532
  }, this.getCloudClient());
17146
17533
  }
17147
- return this.resumeLocalSession(id, options);
17534
+ const session = this.resumeLocalSession(id, options);
17535
+ if (inherited && session instanceof AppServerSession)
17536
+ session.inheritTools(inherited);
17537
+ return session;
17148
17538
  }
17149
17539
  async prompt(message, agentId, options = {}) {
17150
17540
  this.assertOpen();
@@ -17352,10 +17742,23 @@ class LettaAgentClientBase {
17352
17742
  }
17353
17743
  return this.managementTransport;
17354
17744
  }
17745
+ registerTools(options) {
17746
+ this.assertOpen();
17747
+ if (this.backend === "cloud") {
17748
+ return Promise.reject(new Error('registerTools() requires backend: "local" or "remote". Cloud sessions register tools through the tools session option.'));
17749
+ }
17750
+ this.toolRegistry ??= new ToolRegistry(this.backend === "remote" ? this.remoteOptions() : this.localAppServerConnection());
17751
+ return this.toolRegistry.register(options);
17752
+ }
17753
+ localAppServerConnection() {
17754
+ throw this.localBackendUnavailableError();
17755
+ }
17355
17756
  close() {
17356
17757
  if (this.closePromise)
17357
17758
  return this.closePromise;
17358
17759
  this.closed = true;
17760
+ this.toolRegistry?.close();
17761
+ this.toolRegistry = null;
17359
17762
  const transport = this.managementTransport;
17360
17763
  this.managementTransport = null;
17361
17764
  const close = transport?.close() ?? Promise.resolve();
@@ -18142,15 +18545,18 @@ class LettaAgentClient extends LettaAgentClientBase {
18142
18545
  return { loadSkillDirectory, pushSkillSupportFiles };
18143
18546
  }
18144
18547
  createLocalManagementTransport() {
18548
+ return new AppServerManagementTransport(this.localAppServerConnection());
18549
+ }
18550
+ localAppServerConnection() {
18145
18551
  const localOptions = this.options.appServer;
18146
18552
  const sharedServer = this.sharedLocalServer();
18147
- return new AppServerManagementTransport({
18553
+ return {
18148
18554
  ...localOptions?.url !== undefined ? { url: localOptions.url } : {
18149
18555
  connect: () => sharedServer.connect()
18150
18556
  },
18151
18557
  ...localOptions?.WebSocket !== undefined ? { WebSocket: localOptions.WebSocket } : {},
18152
18558
  ...localOptions?.requestTimeoutMs !== undefined ? { requestTimeoutMs: localOptions.requestTimeoutMs } : {}
18153
- });
18559
+ };
18154
18560
  }
18155
18561
  async createLocalAgent(options) {
18156
18562
  const localOptions = this.options;
@@ -19647,12 +20053,12 @@ var require_applicability2 = __commonJS2((exports) => {
19647
20053
  Object.defineProperty(exports, "__esModule", { value: true });
19648
20054
  exports.shouldUseRule = exports.shouldUseGroup = exports.schemaHasRulesForType = undefined;
19649
20055
  function schemaHasRulesForType({ schema, self }, type) {
19650
- const group = self.RULES.types[type];
19651
- return group && group !== true && shouldUseGroup(schema, group);
20056
+ const group2 = self.RULES.types[type];
20057
+ return group2 && group2 !== true && shouldUseGroup(schema, group2);
19652
20058
  }
19653
20059
  exports.schemaHasRulesForType = schemaHasRulesForType;
19654
- function shouldUseGroup(schema, group) {
19655
- return group.rules.some((rule) => shouldUseRule(schema, rule));
20060
+ function shouldUseGroup(schema, group2) {
20061
+ return group2.rules.some((rule) => shouldUseRule(schema, rule));
19656
20062
  }
19657
20063
  exports.shouldUseGroup = shouldUseGroup;
19658
20064
  function shouldUseRule(schema, rule) {
@@ -20644,36 +21050,36 @@ var require_validate2 = __commonJS2((exports) => {
20644
21050
  if (!opts.jtd)
20645
21051
  checkStrictTypes(it, types);
20646
21052
  gen.block(() => {
20647
- for (const group of RULES.rules)
20648
- groupKeywords(group);
21053
+ for (const group2 of RULES.rules)
21054
+ groupKeywords(group2);
20649
21055
  groupKeywords(RULES.post);
20650
21056
  });
20651
- function groupKeywords(group) {
20652
- if (!(0, applicability_1.shouldUseGroup)(schema, group))
21057
+ function groupKeywords(group2) {
21058
+ if (!(0, applicability_1.shouldUseGroup)(schema, group2))
20653
21059
  return;
20654
- if (group.type) {
20655
- gen.if((0, dataType_2.checkDataType)(group.type, data, opts.strictNumbers));
20656
- iterateKeywords(it, group);
20657
- if (types.length === 1 && types[0] === group.type && typeErrors) {
21060
+ if (group2.type) {
21061
+ gen.if((0, dataType_2.checkDataType)(group2.type, data, opts.strictNumbers));
21062
+ iterateKeywords(it, group2);
21063
+ if (types.length === 1 && types[0] === group2.type && typeErrors) {
20658
21064
  gen.else();
20659
21065
  (0, dataType_2.reportTypeError)(it);
20660
21066
  }
20661
21067
  gen.endIf();
20662
21068
  } else {
20663
- iterateKeywords(it, group);
21069
+ iterateKeywords(it, group2);
20664
21070
  }
20665
21071
  if (!allErrors)
20666
21072
  gen.if((0, codegen_1._)`${names_1.default.errors} === ${errsCount || 0}`);
20667
21073
  }
20668
21074
  }
20669
- function iterateKeywords(it, group) {
21075
+ function iterateKeywords(it, group2) {
20670
21076
  const { gen, schema, opts: { useDefaults } } = it;
20671
21077
  if (useDefaults)
20672
- (0, defaults_1.assignDefaults)(it, group.type);
21078
+ (0, defaults_1.assignDefaults)(it, group2.type);
20673
21079
  gen.block(() => {
20674
- for (const rule of group.rules) {
21080
+ for (const rule of group2.rules) {
20675
21081
  if ((0, applicability_1.shouldUseRule)(schema, rule)) {
20676
- keywordCode(it, rule.keyword, rule.definition, group.type);
21082
+ keywordCode(it, rule.keyword, rule.definition, group2.type);
20677
21083
  }
20678
21084
  }
20679
21085
  });
@@ -22358,10 +22764,10 @@ var require_core3 = __commonJS2((exports) => {
22358
22764
  const { RULES } = this;
22359
22765
  delete RULES.keywords[keyword];
22360
22766
  delete RULES.all[keyword];
22361
- for (const group of RULES.rules) {
22362
- const i = group.rules.findIndex((rule) => rule.keyword === keyword);
22767
+ for (const group2 of RULES.rules) {
22768
+ const i = group2.rules.findIndex((rule) => rule.keyword === keyword);
22363
22769
  if (i >= 0)
22364
- group.rules.splice(i, 1);
22770
+ group2.rules.splice(i, 1);
22365
22771
  }
22366
22772
  return this;
22367
22773
  }
@@ -29615,16 +30021,16 @@ var safeDecode = /* @__PURE__ */ _safeDecode(ZodRealError);
29615
30021
  var safeEncodeAsync = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
29616
30022
  var safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
29617
30023
  var _installedGroups = /* @__PURE__ */ new WeakMap;
29618
- function _installLazyMethods(inst, group, methods) {
30024
+ function _installLazyMethods(inst, group2, methods) {
29619
30025
  const proto = Object.getPrototypeOf(inst);
29620
30026
  let installed = _installedGroups.get(proto);
29621
30027
  if (!installed) {
29622
30028
  installed = new Set;
29623
30029
  _installedGroups.set(proto, installed);
29624
30030
  }
29625
- if (installed.has(group))
30031
+ if (installed.has(group2))
29626
30032
  return;
29627
- installed.add(group);
30033
+ installed.add(group2);
29628
30034
  for (const key in methods) {
29629
30035
  const fn = methods[key];
29630
30036
  Object.defineProperty(proto, key, {
@@ -35002,7 +35408,7 @@ class StreamableHTTPClientTransport {
35002
35408
  }
35003
35409
  var DEFAULT_CLIENT_INFO = {
35004
35410
  name: "letta-code",
35005
- version: "0.34.43"
35411
+ version: "0.34.44"
35006
35412
  };
35007
35413
  async function connectMcpServer(config2, options = {}) {
35008
35414
  let client = new Client(options.clientInfo ?? DEFAULT_CLIENT_INFO);
@@ -36030,4 +36436,4 @@ export {
36030
36436
  CloudManagedSandboxExpiredError
36031
36437
  };
36032
36438
 
36033
- //# debugId=F5582294ADA61D1064756E2164756E21
36439
+ //# debugId=6E9CA934B8E5A10D64756E2164756E21