@letta-ai/letta-agent-sdk 0.8.73 → 0.8.75

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 +488 -100
  9. package/dist/client-entry.js.map +16 -13
  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 +517 -126
  19. package/dist/index.js.map +18 -15
  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
@@ -10198,14 +10198,6 @@ function buildCreatedAgentTags(options = {}) {
10198
10198
  }
10199
10199
  return Array.from(new Set(tags));
10200
10200
  }
10201
- var DEFAULT_SUMMARIZATION_MODEL = "letta/auto";
10202
- var SYSTEM_REMINDER_TAG = "system-reminder";
10203
- var SYSTEM_REMINDER_OPEN = `<${SYSTEM_REMINDER_TAG}>`;
10204
- var SYSTEM_REMINDER_CLOSE = `</${SYSTEM_REMINDER_TAG}>`;
10205
- var SYSTEM_ALERT_TAG = "system-alert";
10206
- var SYSTEM_ALERT_OPEN = `<${SYSTEM_ALERT_TAG}>`;
10207
- var SYSTEM_ALERT_CLOSE = `</${SYSTEM_ALERT_TAG}>`;
10208
- var ELAPSED_DISPLAY_THRESHOLD_MS = 60 * 1000;
10209
10201
  var READ_ONLY_BLOCK_LABELS = ["memory_filesystem"];
10210
10202
  var human_default = `---
10211
10203
  label: human
@@ -12245,7 +12237,6 @@ async function getDefaultMemoryBlocks() {
12245
12237
  }
12246
12238
  var models = [];
12247
12239
  var BUILTIN_MODEL_ALIASES = new Map([
12248
- ["auto", "letta/auto"],
12249
12240
  ["auto-chat", "letta/auto-chat"],
12250
12241
  ["auto-fast", "letta/auto-fast"]
12251
12242
  ]);
@@ -12294,20 +12285,14 @@ function resolveModel(modelIdentifier) {
12294
12285
  return builtinHandle;
12295
12286
  return modelIdentifier.includes("/") ? modelIdentifier : null;
12296
12287
  }
12288
+ var UNSELECTED_MODEL_HANDLE = "local/default";
12289
+ function isLettaHostedModelHandle(handle) {
12290
+ return handle.startsWith("letta/");
12291
+ }
12297
12292
  function getDefaultModel() {
12298
- if (models.length === 0)
12299
- return "letta/auto";
12300
- const autoModel = models.find((model) => model.id === "auto");
12301
- if (autoModel)
12302
- return autoModel.handle;
12303
- const defaultModel = models.find((model) => model.isDefault);
12304
- if (defaultModel)
12305
- return defaultModel.handle;
12306
- const firstModel = models[0];
12307
- if (!firstModel) {
12308
- throw new Error("Model catalog is unavailable.");
12309
- }
12310
- return firstModel.handle;
12293
+ const candidates = models.filter((model) => !isLettaHostedModelHandle(model.handle));
12294
+ const defaultModel = candidates.find((model) => model.isDefault) ?? candidates[0];
12295
+ return defaultModel?.handle ?? UNSELECTED_MODEL_HANDLE;
12311
12296
  }
12312
12297
  var PERSONALITY_OPTIONS = [
12313
12298
  {
@@ -12569,7 +12554,7 @@ async function buildCreateAgentRequest(options = {}) {
12569
12554
  initial_message_sequence: [],
12570
12555
  parallel_tool_calls: options.parallelToolCalls ?? true,
12571
12556
  compaction_settings: {
12572
- model: options.compactionModel ?? DEFAULT_SUMMARIZATION_MODEL
12557
+ model: options.compactionModel ?? modelHandle
12573
12558
  },
12574
12559
  ...options.embedding !== undefined ? { embedding: options.embedding } : {},
12575
12560
  ...options.isSubagent ? { hidden: true } : options.hidden !== undefined ? { hidden: options.hidden } : {}
@@ -13183,7 +13168,7 @@ async function* streamStructuredTurns(config) {
13183
13168
  return;
13184
13169
  });
13185
13170
  }
13186
- if (msg.type !== "result") {
13171
+ if (msg.type !== "result" || msg.origin !== undefined) {
13187
13172
  yield msg;
13188
13173
  continue;
13189
13174
  }
@@ -13303,9 +13288,115 @@ function expandMcpToolWildcards(allowedTools, mcpTools) {
13303
13288
  return [...new Set(expanded)];
13304
13289
  }
13305
13290
 
13291
+ // src/external-tools.ts
13292
+ function externalToolGroups(tools) {
13293
+ if (!tools || tools.length === 0)
13294
+ return;
13295
+ return [
13296
+ {
13297
+ tools: tools.map((tool) => ({
13298
+ name: tool.name,
13299
+ label: tool.label,
13300
+ description: tool.description,
13301
+ parameters: tool.parameters
13302
+ }))
13303
+ }
13304
+ ];
13305
+ }
13306
+ var MAX_REMEMBERED_EXTERNAL_TOOL_CALLS = 200;
13307
+ function createExternalToolCallHandler(externalTools, fallbackRuntime) {
13308
+ const calls = new Map;
13309
+ const execute = async (request) => {
13310
+ const tool = externalTools.get(request.tool_name);
13311
+ if (!tool) {
13312
+ throw new Error(`Unknown external tool: ${request.tool_name}`);
13313
+ }
13314
+ const runtime = request.runtime ?? fallbackRuntime?.() ?? null;
13315
+ const context = runtime ? { toolCallId: request.tool_call_id, agentId: runtime.agent_id, conversationId: runtime.conversation_id } : undefined;
13316
+ const result = await tool.execute(request.tool_call_id, request.input, undefined, undefined, context);
13317
+ return {
13318
+ content: result.content.map((part) => ({
13319
+ type: part.type,
13320
+ ...part.text !== undefined ? { text: part.text } : {},
13321
+ ...part.data !== undefined ? { data: part.data } : {},
13322
+ ...part.mimeType !== undefined ? { mimeType: part.mimeType } : {}
13323
+ })),
13324
+ ...result.isError === true ? { is_error: true } : {}
13325
+ };
13326
+ };
13327
+ return (request) => {
13328
+ const requestId = request.request_id;
13329
+ if (typeof requestId !== "string" || requestId.length === 0) {
13330
+ return execute(request);
13331
+ }
13332
+ const existing = calls.get(requestId);
13333
+ if (existing)
13334
+ return existing;
13335
+ const call = execute(request);
13336
+ calls.set(requestId, call);
13337
+ while (calls.size > MAX_REMEMBERED_EXTERNAL_TOOL_CALLS) {
13338
+ const oldest = calls.keys().next().value;
13339
+ if (oldest === undefined)
13340
+ break;
13341
+ calls.delete(oldest);
13342
+ }
13343
+ return call;
13344
+ };
13345
+ }
13346
+
13347
+ // src/runtime-tool-policy.ts
13348
+ var RUNTIME_TOOL_POLICY_CAPABILITY = "runtime_tool_policy";
13349
+ var CAPABILITY_PROBE_TIMEOUT_MS = 5000;
13350
+ function clientToolsetPayload(toolset) {
13351
+ return {
13352
+ ...toolset.base !== undefined ? { base: toolset.base } : {},
13353
+ ...toolset.include !== undefined ? { include: [...new Set(toolset.include)] } : {}
13354
+ };
13355
+ }
13356
+ function runtimeToolPolicy(allowedTools, toolset) {
13357
+ return {
13358
+ ...toolset !== undefined ? { toolset: clientToolsetPayload(toolset) } : {},
13359
+ ...allowedTools !== undefined ? { allowlist: [...new Set(allowedTools)] } : {},
13360
+ exclude_interactive: true
13361
+ };
13362
+ }
13363
+ async function supportsRuntimeToolPolicy(client) {
13364
+ try {
13365
+ const info = await client.info({ timeoutMs: CAPABILITY_PROBE_TIMEOUT_MS });
13366
+ const capabilities = info.capabilities;
13367
+ return capabilities?.[RUNTIME_TOOL_POLICY_CAPABILITY] === true;
13368
+ } catch {
13369
+ return false;
13370
+ }
13371
+ }
13372
+ function mergeInheritedTools(inherited, own) {
13373
+ if (!inherited)
13374
+ return own;
13375
+ const tools = new Map(inherited.tools.map((tool) => [tool.name, tool]));
13376
+ for (const tool of own.tools)
13377
+ tools.set(tool.name, tool);
13378
+ const ownNames = new Set(own.tools.map((tool) => tool.name));
13379
+ const registered = inherited.allowedTools;
13380
+ const allowedTools = registered === undefined ? own.allowedTools : own.allowedTools === undefined ? [...new Set([...registered, ...ownNames])] : own.allowedTools.filter((name) => registered.includes(name) || ownNames.has(name));
13381
+ const toolset = own.toolset ?? inherited.toolset;
13382
+ return {
13383
+ tools: [...tools.values()],
13384
+ ...allowedTools !== undefined ? { allowedTools } : {},
13385
+ ...toolset !== undefined ? { toolset } : {}
13386
+ };
13387
+ }
13388
+
13306
13389
  // src/remote-turn-coordinator.ts
13307
13390
  var MAX_RECENTLY_SETTLED_RUN_IDS = 256;
13308
13391
  var TRAILING_USAGE_GRACE_MS = 100;
13392
+ var TURN_ORIGINS = new Set([
13393
+ "task_notification",
13394
+ "cron",
13395
+ "subagent",
13396
+ "system",
13397
+ "channel",
13398
+ "user"
13399
+ ]);
13309
13400
 
13310
13401
  class RemoteTurnCoordinator {
13311
13402
  label;
@@ -13317,6 +13408,8 @@ class RemoteTurnCoordinator {
13317
13408
  activeTurn = null;
13318
13409
  pendingTurns = [];
13319
13410
  settledRunIds = new Set;
13411
+ queueOrigins = new Map;
13412
+ nextServerOrigin = "unknown";
13320
13413
  nextTurnId = 0;
13321
13414
  messageCounter = 0;
13322
13415
  clientMessageCounter = 0;
@@ -13332,16 +13425,27 @@ class RemoteTurnCoordinator {
13332
13425
  return this._activeTurnStartedAt;
13333
13426
  }
13334
13427
  hasInFlightTurn() {
13335
- return this.activeTurn !== null || this.pendingTurns.length > 0;
13428
+ return this.activeTurn !== null && this.activeTurn.origin === undefined || this.pendingTurns.length > 0;
13336
13429
  }
13337
13430
  trackSentTurn(runtime, callerOtid, outputFormat) {
13338
13431
  const otid = normalizeCallerOtid(callerOtid);
13339
- const turn = {
13340
- id: ++this.nextTurnId,
13341
- runtime,
13432
+ const turn = this.newTracker(runtime, {
13342
13433
  ...otid !== undefined ? { otid } : {},
13343
13434
  ...outputFormat !== undefined ? { outputFormat } : {},
13344
- clientMessageId: otid ?? `sdk-message-${Date.now()}-${++this.clientMessageCounter}`,
13435
+ clientMessageId: otid ?? `sdk-message-${Date.now()}-${++this.clientMessageCounter}`
13436
+ });
13437
+ if (this.activeTurn) {
13438
+ this.pendingTurns.push(turn);
13439
+ } else {
13440
+ this.activateTurn(turn);
13441
+ }
13442
+ return turn;
13443
+ }
13444
+ newTracker(runtime, identity) {
13445
+ return {
13446
+ id: ++this.nextTurnId,
13447
+ runtime,
13448
+ ...identity,
13345
13449
  queuedAt: Date.now(),
13346
13450
  startedAt: 0,
13347
13451
  assistantText: "",
@@ -13358,13 +13462,32 @@ class RemoteTurnCoordinator {
13358
13462
  abortRequested: false,
13359
13463
  timeout: null
13360
13464
  };
13361
- if (this.activeTurn) {
13362
- this.pendingTurns.push(turn);
13363
- } else {
13364
- this.activateTurn(turn);
13365
- }
13465
+ }
13466
+ startServerTurn(runtime) {
13467
+ const turn = this.newTracker(runtime, { clientMessageId: "", origin: this.nextServerOrigin });
13468
+ this.nextServerOrigin = "unknown";
13469
+ this.activateTurn(turn);
13366
13470
  return turn;
13367
13471
  }
13472
+ observeQueueOrigins(message, queue) {
13473
+ for (const item of queue) {
13474
+ if (!item.clientMessageId)
13475
+ continue;
13476
+ this.queueOrigins.set(item.clientMessageId, TURN_ORIGINS.has(item.source) ? item.source : "unknown");
13477
+ if (this.queueOrigins.size > MAX_RECENTLY_SETTLED_RUN_IDS) {
13478
+ this.queueOrigins.delete(this.queueOrigins.keys().next().value);
13479
+ }
13480
+ }
13481
+ for (const removed of Array.isArray(message.removed) ? message.removed : []) {
13482
+ const { client_message_id: id, disposition, source } = removed;
13483
+ if (disposition !== "dequeued" || typeof id !== "string")
13484
+ continue;
13485
+ const own = [this.activeTurn, ...this.pendingTurns].some((turn) => turn?.clientMessageId === id);
13486
+ if (own)
13487
+ continue;
13488
+ this.nextServerOrigin = typeof source === "string" && TURN_ORIGINS.has(source) ? source : this.queueOrigins.get(id) ?? "unknown";
13489
+ }
13490
+ }
13368
13491
  removeTrackedTurn(turn) {
13369
13492
  if (turn.timeout)
13370
13493
  clearTimeout(turn.timeout);
@@ -13378,6 +13501,12 @@ class RemoteTurnCoordinator {
13378
13501
  if (index !== -1)
13379
13502
  this.pendingTurns.splice(index, 1);
13380
13503
  }
13504
+ failServerTurn(detail) {
13505
+ const active = this.activeTurn;
13506
+ if (active?.origin === undefined)
13507
+ return;
13508
+ this.failTurn(active, detail, { errorCode: "stream_closed", recoverable: true });
13509
+ }
13381
13510
  markAbortRequested() {
13382
13511
  if (this.activeTurn)
13383
13512
  this.activeTurn.abortRequested = true;
@@ -13397,6 +13526,7 @@ class RemoteTurnCoordinator {
13397
13526
  type: "queue_update",
13398
13527
  queue: queueItems(message)
13399
13528
  };
13529
+ this.observeQueueOrigins(message, sdkMessage2.queue);
13400
13530
  this.enqueue(sdkMessage2);
13401
13531
  return;
13402
13532
  }
@@ -13439,9 +13569,9 @@ class RemoteTurnCoordinator {
13439
13569
  if (!delta)
13440
13570
  return;
13441
13571
  const messageType = streamDeltaMessageType(delta);
13442
- const active = messageType === "usage_statistics" || messageType === "stop_reason" ? this.activeTurn : this.activateNextTurnFromProtocol();
13443
13572
  const runId = streamDeltaRunId(delta);
13444
13573
  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");
13574
+ const active = messageType === "usage_statistics" || messageType === "stop_reason" ? this.activeTurn : this.activateNextTurnFromProtocol() ?? (isTurnEvidence && runId !== undefined ? this.startServerTurn(runtime) : null);
13445
13575
  if (active && isTurnEvidence) {
13446
13576
  active.observedTurnEvidence = true;
13447
13577
  if (runId)
@@ -13899,7 +14029,8 @@ class RemoteTurnCoordinator {
13899
14029
  stopReason,
13900
14030
  durationMs: Date.now() - (tracker?.startedAt || this._activeTurnStartedAt),
13901
14031
  conversationId: turn.runtime.conversation_id,
13902
- runIds: turn.runIds.length > 0 ? turn.runIds : undefined
14032
+ runIds: turn.runIds.length > 0 ? turn.runIds : undefined,
14033
+ ...tracker?.origin !== undefined ? { origin: tracker.origin } : {}
13903
14034
  };
13904
14035
  }
13905
14036
  enqueue(message) {
@@ -14141,9 +14272,8 @@ class RemoteClientSessionCore {
14141
14272
  }
14142
14273
  await this.send(message);
14143
14274
  for await (const msg of this.stream()) {
14144
- if (msg.type === "result") {
14275
+ if (msg.type === "result" && msg.origin === undefined)
14145
14276
  return msg;
14146
- }
14147
14277
  }
14148
14278
  return {
14149
14279
  type: "result",
@@ -14179,7 +14309,7 @@ class RemoteClientSessionCore {
14179
14309
  if (!msg)
14180
14310
  break;
14181
14311
  yield msg;
14182
- if (msg.type === "result")
14312
+ if (msg.type === "result" && msg.origin === undefined)
14183
14313
  break;
14184
14314
  }
14185
14315
  }
@@ -14489,6 +14619,7 @@ class RemoteClientSessionCore {
14489
14619
  this.controller?.close();
14490
14620
  this.controller = null;
14491
14621
  const error = new Error(`${this.label} connection closed before send`);
14622
+ this.turns.failServerTurn(error.message);
14492
14623
  for (const cancel of [...this.deviceStatusRefreshCancels])
14493
14624
  cancel(error);
14494
14625
  this.deviceStatusRefreshCancels.clear();
@@ -14629,38 +14760,6 @@ function agentToolNames(agent) {
14629
14760
  return typeof name === "string" && name.length > 0 ? [name] : [];
14630
14761
  });
14631
14762
  }
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
14763
  async function resolveAppServerToolApproval(options, toolName, toolInput, context) {
14665
14764
  if ("outputFormat" in options && options.outputFormat !== undefined && toolName === STRUCTURED_OUTPUT_TOOL) {
14666
14765
  return { behavior: "allow", updatedInput: null, updatedPermissions: [] };
@@ -14837,11 +14936,26 @@ class AppServerRuntimeController {
14837
14936
  options;
14838
14937
  clientToolAllowlist;
14839
14938
  clientToolset;
14840
- constructor(client, options, clientToolAllowlist, clientToolset) {
14939
+ toolPolicyApplied;
14940
+ constructor(client, options, clientToolAllowlist, clientToolset, toolPolicyApplied = false) {
14841
14941
  this.client = client;
14842
14942
  this.options = options;
14843
14943
  this.clientToolAllowlist = clientToolAllowlist;
14844
14944
  this.clientToolset = clientToolset;
14945
+ this.toolPolicyApplied = toolPolicyApplied;
14946
+ }
14947
+ async updateToolSelection(runtime, selection) {
14948
+ this.clientToolAllowlist = selection.allowedTools;
14949
+ this.clientToolset = selection.toolset;
14950
+ const response = await this.client.runtimeExternalToolsUpdate({
14951
+ updates: [{
14952
+ runtimes: [runtime],
14953
+ external_tools: externalToolGroups(selection.tools) ?? [],
14954
+ ...this.toolPolicyApplied ? { tool_policy: runtimeToolPolicy(selection.allowedTools, selection.toolset) } : {}
14955
+ }]
14956
+ });
14957
+ if (!response.success)
14958
+ throw new Error(response.error ?? "Failed to update session tools");
14845
14959
  }
14846
14960
  onMessage(handler) {
14847
14961
  return this.client.onMessage((message, channel) => {
@@ -14863,14 +14977,11 @@ class AppServerRuntimeController {
14863
14977
  }
14864
14978
  ]
14865
14979
  };
14866
- if (this.clientToolAllowlist !== undefined) {
14980
+ if (!this.toolPolicyApplied && this.clientToolAllowlist !== undefined) {
14867
14981
  payload.client_tool_allowlist = [...new Set(this.clientToolAllowlist)];
14868
14982
  }
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
- };
14983
+ if (!this.toolPolicyApplied && this.clientToolset !== undefined) {
14984
+ payload.client_toolset = clientToolsetPayload(this.clientToolset);
14874
14985
  }
14875
14986
  if (options.outputFormat !== undefined) {
14876
14987
  payload.response_format = {
@@ -14882,7 +14993,8 @@ class AppServerRuntimeController {
14882
14993
  }
14883
14994
  };
14884
14995
  }
14885
- payload.exclude_interactive_tools = true;
14996
+ if (!this.toolPolicyApplied)
14997
+ payload.exclude_interactive_tools = true;
14886
14998
  this.client.input({
14887
14999
  runtime,
14888
15000
  payload
@@ -14974,6 +15086,9 @@ class AppServerSession extends RemoteClientSessionCore {
14974
15086
  mcpCleanup = Promise.resolve();
14975
15087
  removeExternalToolHandler = null;
14976
15088
  removeControlRequestHandler = null;
15089
+ inheritedTools = null;
15090
+ removeInheritedListener = null;
15091
+ ownSelection = null;
14977
15092
  constructor(remoteOptions, mode) {
14978
15093
  super(mode, {
14979
15094
  label: "app-server",
@@ -14985,6 +15100,27 @@ class AppServerSession extends RemoteClientSessionCore {
14985
15100
  this.externalTools.set(tool.name, tool);
14986
15101
  }
14987
15102
  }
15103
+ inheritTools(source) {
15104
+ this.inheritedTools = source;
15105
+ this.removeInheritedListener = source.onChange(() => {
15106
+ this.refreshInheritedTools().catch(() => {
15107
+ return;
15108
+ });
15109
+ });
15110
+ }
15111
+ applyToolSelection() {
15112
+ const selection = mergeInheritedTools(this.inheritedTools?.current() ?? null, this.ownSelection ?? { tools: [] });
15113
+ this.externalTools.clear();
15114
+ for (const tool of selection.tools)
15115
+ this.externalTools.set(tool.name, tool);
15116
+ return selection;
15117
+ }
15118
+ async refreshInheritedTools() {
15119
+ if (!this.ownSelection || !this.runtime || !(this.controller instanceof AppServerRuntimeController))
15120
+ return;
15121
+ const selection = this.applyToolSelection();
15122
+ await this.controller.updateToolSelection(this.runtime, selection);
15123
+ }
14988
15124
  shouldEnableMemfs(options) {
14989
15125
  if (this.mode.kind !== "create-agent")
14990
15126
  return false;
@@ -15000,6 +15136,9 @@ class AppServerSession extends RemoteClientSessionCore {
15000
15136
  ...this.remoteOptions.requestTimeoutMs !== undefined ? { requestTimeoutMs: this.remoteOptions.requestTimeoutMs } : {}
15001
15137
  }));
15002
15138
  const options = this.currentOptions();
15139
+ this.externalTools.clear();
15140
+ for (const tool of this.mode.options.tools ?? [])
15141
+ this.externalTools.set(tool.name, tool);
15003
15142
  this.mcpBridge = await connectMcpServers("mcpServers" in options ? options.mcpServers : undefined, {
15004
15143
  cwd: options.cwd,
15005
15144
  reservedToolNames: this.externalTools.keys()
@@ -15007,13 +15146,22 @@ class AppServerSession extends RemoteClientSessionCore {
15007
15146
  for (const tool of this.mcpBridge.tools) {
15008
15147
  this.externalTools.set(tool.name, tool);
15009
15148
  }
15149
+ const mcpToolNames = this.mcpBridge.tools.map((tool) => tool.name);
15150
+ const ownToolset = "toolset" in options ? options.toolset : undefined;
15151
+ const ownAllowedTools = expandMcpToolWildcards(options.allowedTools, mcpToolNames);
15152
+ this.ownSelection = {
15153
+ tools: [...this.externalTools.values()],
15154
+ ...ownAllowedTools !== undefined ? { allowedTools: ownAllowedTools } : {},
15155
+ ...ownToolset !== undefined ? { toolset: ownToolset } : {}
15156
+ };
15157
+ const { allowedTools, toolset: clientToolset } = this.applyToolSelection();
15010
15158
  this.removeControlRequestHandler = registerAppServerControlRequestHandler({
15011
15159
  client,
15012
15160
  getRuntime: () => this.runtime,
15013
15161
  getOptions: () => this.currentOptions()
15014
15162
  });
15015
- if (this.externalTools.size > 0) {
15016
- this.removeExternalToolHandler = client.onExternalToolCall(createExternalToolCallHandler(this.externalTools));
15163
+ if (this.externalTools.size > 0 || this.inheritedTools) {
15164
+ this.removeExternalToolHandler = client.onExternalToolCall(createExternalToolCallHandler(this.externalTools, () => this.runtime));
15017
15165
  }
15018
15166
  try {
15019
15167
  await client.connect();
@@ -15024,19 +15172,17 @@ class AppServerSession extends RemoteClientSessionCore {
15024
15172
  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
15173
  }
15026
15174
  }
15027
- const response = await this.startRuntime(client);
15175
+ const response = await this.startRuntime(client, runtimeToolPolicy(allowedTools, clientToolset));
15028
15176
  if (!response.success || !response.runtime) {
15029
15177
  throw new Error(response.error ?? "Failed to start app-server runtime");
15030
15178
  }
15031
15179
  this.watchTransportDisconnect(client);
15180
+ const toolPolicyApplied = await supportsRuntimeToolPolicy(client);
15032
15181
  const tools = agentToolNames(response.agent);
15033
15182
  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
15183
  const availableTools = tools === undefined && mcpToolNames.length === 0 ? undefined : [...tools ?? [], ...mcpToolNames];
15038
15184
  return {
15039
- controller: new AppServerRuntimeController(client, this.remoteOptions, allowedTools, clientToolset),
15185
+ controller: new AppServerRuntimeController(client, this.remoteOptions, allowedTools, clientToolset, toolPolicyApplied),
15040
15186
  runtime: response.runtime,
15041
15187
  model: typeof response.agent?.model === "string" ? response.agent.model : typeof response.conversation?.model === "string" ? response.conversation.model : "",
15042
15188
  modelSettings: objectRecord(response.agent?.model_settings) ?? objectRecord(response.conversation?.model_settings) ?? null,
@@ -15054,6 +15200,10 @@ class AppServerSession extends RemoteClientSessionCore {
15054
15200
  }
15055
15201
  }
15056
15202
  onCoreClose() {
15203
+ if (this.closed) {
15204
+ this.removeInheritedListener?.();
15205
+ this.removeInheritedListener = null;
15206
+ }
15057
15207
  this.removeExternalToolHandler?.();
15058
15208
  this.removeExternalToolHandler = null;
15059
15209
  this.removeControlRequestHandler?.();
@@ -15084,11 +15234,11 @@ class AppServerSession extends RemoteClientSessionCore {
15084
15234
  this.ownedConnection = connection;
15085
15235
  return connection.url;
15086
15236
  }
15087
- async startRuntime(client) {
15088
- const command = await this.buildRuntimeStartCommand(client);
15237
+ async startRuntime(client, toolPolicy) {
15238
+ const command = await this.buildRuntimeStartCommand(client, toolPolicy);
15089
15239
  return client.runtimeStart(command);
15090
15240
  }
15091
- async buildRuntimeStartCommand(client) {
15241
+ async buildRuntimeStartCommand(client, toolPolicy) {
15092
15242
  const options = this.mode.options;
15093
15243
  const command = {
15094
15244
  client_info: {
@@ -15119,6 +15269,7 @@ class AppServerSession extends RemoteClientSessionCore {
15119
15269
  const groups = externalToolGroups([...this.externalTools.values()]);
15120
15270
  if (groups)
15121
15271
  command.external_tools = groups;
15272
+ command.tool_policy = toolPolicy;
15122
15273
  if (this.mode.kind === "create-agent") {
15123
15274
  command.create_agent = {
15124
15275
  body: await createAgentBody(this.mode.options),
@@ -15601,6 +15752,9 @@ class CloudStatusTransport {
15601
15752
  if (channel === "control" && message.type === "stream_delta") {
15602
15753
  return false;
15603
15754
  }
15755
+ if (channel === "stream" && message.type === "external_tool_call_request") {
15756
+ return false;
15757
+ }
15604
15758
  if (this.isDuplicate(message))
15605
15759
  return false;
15606
15760
  this.trackEventSequence(message);
@@ -16097,7 +16251,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
16097
16251
  getOptions: () => this.currentOptions()
16098
16252
  });
16099
16253
  if (this.externalTools.size > 0) {
16100
- this.removeExternalToolHandler = client.onExternalToolCall(createExternalToolCallHandler(this.externalTools));
16254
+ this.removeExternalToolHandler = client.onExternalToolCall(createExternalToolCallHandler(this.externalTools, () => this.runtime));
16101
16255
  }
16102
16256
  }
16103
16257
  cleanupTransportHandlers() {
@@ -16155,6 +16309,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
16155
16309
  const groups = externalToolGroups([...this.externalTools.values()]);
16156
16310
  if (groups)
16157
16311
  command.external_tools = groups;
16312
+ command.tool_policy = runtimeToolPolicy(expandMcpToolWildcards(options.allowedTools, this.mcpBridge?.tools.map((tool) => tool.name) ?? []), "toolset" in options ? options.toolset : undefined);
16158
16313
  return await client.runtimeStart(command);
16159
16314
  }
16160
16315
  async afterRuntimeInitialized() {
@@ -16720,6 +16875,221 @@ function createQuery(createSession, params) {
16720
16875
  });
16721
16876
  }
16722
16877
 
16878
+ // src/tool-registration.ts
16879
+ var RECONNECT_DELAYS_MS = [250, 1000, 5000, 15000];
16880
+ var runtimeKey = (runtime) => `${runtime.agent_id}:${runtime.conversation_id}`;
16881
+
16882
+ class ToolRegistry {
16883
+ options;
16884
+ connection = null;
16885
+ entries = new Set;
16886
+ listeners = new Set;
16887
+ reconnectAttempt = 0;
16888
+ reconnectTimer = null;
16889
+ closed = false;
16890
+ constructor(options) {
16891
+ this.options = options;
16892
+ }
16893
+ async register(options) {
16894
+ if (this.closed)
16895
+ throw new Error("LettaAgentClient is closed");
16896
+ const entry = { options, runtimes: [], call: createExternalToolCallHandler(new Map) };
16897
+ await this.apply(entry, options);
16898
+ const registry = this;
16899
+ return {
16900
+ get conversations() {
16901
+ return [...entry.options.conversations];
16902
+ },
16903
+ update: async (next) => {
16904
+ if (!registry.entries.has(entry))
16905
+ throw new Error("This tool registration is closed.");
16906
+ await registry.apply(entry, { ...entry.options, ...next });
16907
+ },
16908
+ close: () => registry.remove(entry),
16909
+ [Symbol.asyncDispose]: () => registry.remove(entry)
16910
+ };
16911
+ }
16912
+ close() {
16913
+ this.closed = true;
16914
+ this.entries.clear();
16915
+ this.disconnect();
16916
+ this.notify();
16917
+ }
16918
+ inheritFor(id, own) {
16919
+ const covering = this.covering(id);
16920
+ if (!covering)
16921
+ return null;
16922
+ const registered = new Set(covering.options.tools.map((tool) => tool.name));
16923
+ const clash = own.tools?.find((tool) => registered.has(tool.name));
16924
+ if (clash) {
16925
+ throw new Error(`Tool ${clash.name} is already registered for ${id} with registerTools(); don't pass it to the session again.`);
16926
+ }
16927
+ if (own.toolset !== undefined && covering.options.toolset !== undefined && JSON.stringify(own.toolset) !== JSON.stringify(covering.options.toolset)) {
16928
+ throw new Error(`${id} already has a toolset from registerTools(); narrow it with the session's allowedTools instead.`);
16929
+ }
16930
+ return {
16931
+ current: () => this.covering(id)?.options ?? null,
16932
+ onChange: (listener) => {
16933
+ this.listeners.add(listener);
16934
+ return () => this.listeners.delete(listener);
16935
+ }
16936
+ };
16937
+ }
16938
+ covering(id) {
16939
+ 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));
16940
+ }
16941
+ notify() {
16942
+ for (const listener of [...this.listeners])
16943
+ listener();
16944
+ }
16945
+ async apply(entry, options) {
16946
+ if (!Array.isArray(options.conversations) || options.conversations.length === 0) {
16947
+ throw new Error("registerTools() requires at least one conversation.");
16948
+ }
16949
+ if (!Array.isArray(options.tools))
16950
+ throw new Error("registerTools() requires a tools array.");
16951
+ const connection = await this.connect();
16952
+ if (!connection.toolPolicy && (options.allowedTools || options.toolset)) {
16953
+ throw new Error("registerTools() allowedTools and toolset require a Letta Code app server that supports runtime tool policies. Upgrade @letta-ai/letta-code.");
16954
+ }
16955
+ const runtimes = await Promise.all(options.conversations.map((id) => resolveRuntime(connection.client, id)));
16956
+ const taken = new Set([...this.entries].filter((other) => other !== entry).flatMap((other) => other.runtimes.map(runtimeKey)));
16957
+ const overlap = options.conversations.find((_, index) => taken.has(runtimeKey(runtimes[index])));
16958
+ if (overlap)
16959
+ throw new Error(`Tools are already registered for ${overlap}.`);
16960
+ const keys = new Set(runtimes.map(runtimeKey));
16961
+ const dropped = entry.runtimes.filter((runtime) => !keys.has(runtimeKey(runtime)));
16962
+ const previous = { ...entry };
16963
+ const isNew = !this.entries.has(entry);
16964
+ entry.options = options;
16965
+ entry.runtimes = runtimes;
16966
+ entry.call = createExternalToolCallHandler(new Map(options.tools.map((tool) => [tool.name, tool])));
16967
+ this.entries.add(entry);
16968
+ try {
16969
+ await publish(connection.client, [
16970
+ group(runtimes, options, connection.toolPolicy),
16971
+ ...dropped.length > 0 ? [{ runtimes: dropped, external_tools: [] }] : []
16972
+ ]);
16973
+ } catch (error) {
16974
+ Object.assign(entry, previous);
16975
+ if (isNew)
16976
+ this.entries.delete(entry);
16977
+ throw error;
16978
+ }
16979
+ this.notify();
16980
+ }
16981
+ async remove(entry) {
16982
+ if (!this.entries.delete(entry))
16983
+ return;
16984
+ this.notify();
16985
+ if (this.entries.size === 0) {
16986
+ this.disconnect();
16987
+ return;
16988
+ }
16989
+ const connection = await this.connect();
16990
+ await publish(connection.client, [{ runtimes: entry.runtimes, external_tools: [] }]);
16991
+ }
16992
+ connect() {
16993
+ this.connection ??= this.open().catch((error) => {
16994
+ this.connection = null;
16995
+ throw error;
16996
+ });
16997
+ return this.connection;
16998
+ }
16999
+ async open() {
17000
+ const owned = this.options.url ? null : await this.options.connect?.();
17001
+ const url = this.options.url ?? owned?.url;
17002
+ if (!url)
17003
+ throw new Error("registerTools() requires an app-server url.");
17004
+ const client = applyUniqueRequestIds(createAppServerClient({
17005
+ url,
17006
+ ...this.options.authToken !== undefined ? { authToken: this.options.authToken } : {},
17007
+ ...this.options.WebSocket ? { WebSocket: this.options.WebSocket } : {},
17008
+ ...this.options.requestTimeoutMs !== undefined ? { requestTimeoutMs: this.options.requestTimeoutMs } : {}
17009
+ }));
17010
+ client.onExternalToolCall(async (request) => {
17011
+ const runtime = request.runtime;
17012
+ const entry = runtime && [...this.entries].find((candidate) => candidate.runtimes.some((r) => runtimeKey(r) === runtimeKey(runtime)));
17013
+ if (!entry)
17014
+ throw new Error(`No tools registered for conversation ${runtime?.conversation_id}`);
17015
+ return entry.call(request);
17016
+ });
17017
+ try {
17018
+ await client.connect();
17019
+ } catch (error) {
17020
+ client.close();
17021
+ owned?.close();
17022
+ throw error;
17023
+ }
17024
+ client.onDisconnect(() => this.onDisconnect(client));
17025
+ return { client, owned: owned ?? null, toolPolicy: await supportsRuntimeToolPolicy(client) };
17026
+ }
17027
+ disconnect() {
17028
+ if (this.reconnectTimer)
17029
+ clearTimeout(this.reconnectTimer);
17030
+ this.reconnectTimer = null;
17031
+ const connection = this.connection;
17032
+ this.connection = null;
17033
+ connection?.then(({ client, owned }) => {
17034
+ client.close();
17035
+ owned?.close();
17036
+ }, () => {
17037
+ return;
17038
+ });
17039
+ }
17040
+ onDisconnect(client) {
17041
+ this.connection?.then((current) => {
17042
+ if (current.client !== client)
17043
+ return;
17044
+ current.owned?.close();
17045
+ this.connection = null;
17046
+ this.scheduleReconnect();
17047
+ }, () => {
17048
+ return;
17049
+ });
17050
+ }
17051
+ scheduleReconnect() {
17052
+ if (this.closed || this.entries.size === 0 || this.reconnectTimer)
17053
+ return;
17054
+ const delay = RECONNECT_DELAYS_MS[Math.min(this.reconnectAttempt, RECONNECT_DELAYS_MS.length - 1)];
17055
+ this.reconnectAttempt += 1;
17056
+ this.reconnectTimer = setTimeout(() => {
17057
+ this.reconnectTimer = null;
17058
+ this.republish().catch(() => this.scheduleReconnect());
17059
+ }, delay);
17060
+ this.reconnectTimer.unref?.();
17061
+ }
17062
+ async republish() {
17063
+ const connection = await this.connect();
17064
+ await publish(connection.client, [...this.entries].map((entry) => group(entry.runtimes, entry.options, connection.toolPolicy)));
17065
+ this.reconnectAttempt = 0;
17066
+ }
17067
+ }
17068
+ function group(runtimes, options, toolPolicy) {
17069
+ return {
17070
+ runtimes,
17071
+ external_tools: externalToolGroups(options.tools) ?? [],
17072
+ ...toolPolicy ? { tool_policy: runtimeToolPolicy(options.allowedTools, options.toolset) } : {}
17073
+ };
17074
+ }
17075
+ async function publish(client, updates) {
17076
+ const response = await client.runtimeExternalToolsUpdate({ updates });
17077
+ if (!response.success)
17078
+ throw new Error(response.error ?? "Failed to register tools");
17079
+ }
17080
+ async function resolveRuntime(client, id) {
17081
+ if (!id.startsWith("conv-") && !id.startsWith("local-conv-")) {
17082
+ return { agent_id: id, conversation_id: "default" };
17083
+ }
17084
+ const response = await client.request({ type: "conversation_retrieve", request_id: client.nextRequestId("conversation_retrieve"), conversation_id: id }, {
17085
+ predicate: (message) => message.type === "conversation_retrieve_response"
17086
+ });
17087
+ if (!response.success || !response.conversation) {
17088
+ throw new Error(response.error ?? `Failed to retrieve conversation ${id}`);
17089
+ }
17090
+ return { agent_id: response.conversation.agent_id ?? null, conversation_id: id };
17091
+ }
17092
+
16723
17093
  // src/validation.ts
16724
17094
  var VALID_SKILL_SOURCES = [
16725
17095
  "bundled",
@@ -16996,6 +17366,7 @@ class LettaAgentClientBase {
16996
17366
  agentRepositoriesClient = null;
16997
17367
  cloudClient = null;
16998
17368
  managementTransport = null;
17369
+ toolRegistry = null;
16999
17370
  closed = false;
17000
17371
  closePromise = null;
17001
17372
  constructor(options = {}) {
@@ -17114,20 +17485,21 @@ class LettaAgentClientBase {
17114
17485
  const sessionOptions = stripCloudExecutionOptions(options);
17115
17486
  validateCreateSessionOptions(sessionOptions);
17116
17487
  this.assertSessionBackend("resumeSession", options);
17488
+ const inherited = this.backend === "cloud" ? null : this.toolRegistry?.inheritFor(id, sessionOptions) ?? null;
17117
17489
  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(), {
17490
+ const session2 = looksLikeConversationId(id) ? new AppServerSession(this.appServerSessionOptions(), {
17491
+ kind: "session",
17492
+ conversationId: id,
17493
+ options
17494
+ }) : new AppServerSession(this.appServerSessionOptions(), {
17126
17495
  kind: "session",
17127
17496
  agentId: id,
17128
17497
  defaultConversation: true,
17129
17498
  options
17130
17499
  });
17500
+ if (inherited)
17501
+ session2.inheritTools(inherited);
17502
+ return session2;
17131
17503
  }
17132
17504
  if (this.backend === "cloud") {
17133
17505
  if (looksLikeConversationId(id)) {
@@ -17144,7 +17516,10 @@ class LettaAgentClientBase {
17144
17516
  options
17145
17517
  }, this.getCloudClient());
17146
17518
  }
17147
- return this.resumeLocalSession(id, options);
17519
+ const session = this.resumeLocalSession(id, options);
17520
+ if (inherited && session instanceof AppServerSession)
17521
+ session.inheritTools(inherited);
17522
+ return session;
17148
17523
  }
17149
17524
  async prompt(message, agentId, options = {}) {
17150
17525
  this.assertOpen();
@@ -17352,10 +17727,23 @@ class LettaAgentClientBase {
17352
17727
  }
17353
17728
  return this.managementTransport;
17354
17729
  }
17730
+ registerTools(options) {
17731
+ this.assertOpen();
17732
+ if (this.backend === "cloud") {
17733
+ return Promise.reject(new Error('registerTools() requires backend: "local" or "remote". Cloud sessions register tools through the tools session option.'));
17734
+ }
17735
+ this.toolRegistry ??= new ToolRegistry(this.backend === "remote" ? this.remoteOptions() : this.localAppServerConnection());
17736
+ return this.toolRegistry.register(options);
17737
+ }
17738
+ localAppServerConnection() {
17739
+ throw this.localBackendUnavailableError();
17740
+ }
17355
17741
  close() {
17356
17742
  if (this.closePromise)
17357
17743
  return this.closePromise;
17358
17744
  this.closed = true;
17745
+ this.toolRegistry?.close();
17746
+ this.toolRegistry = null;
17359
17747
  const transport = this.managementTransport;
17360
17748
  this.managementTransport = null;
17361
17749
  const close = transport?.close() ?? Promise.resolve();
@@ -18142,15 +18530,18 @@ class LettaAgentClient extends LettaAgentClientBase {
18142
18530
  return { loadSkillDirectory, pushSkillSupportFiles };
18143
18531
  }
18144
18532
  createLocalManagementTransport() {
18533
+ return new AppServerManagementTransport(this.localAppServerConnection());
18534
+ }
18535
+ localAppServerConnection() {
18145
18536
  const localOptions = this.options.appServer;
18146
18537
  const sharedServer = this.sharedLocalServer();
18147
- return new AppServerManagementTransport({
18538
+ return {
18148
18539
  ...localOptions?.url !== undefined ? { url: localOptions.url } : {
18149
18540
  connect: () => sharedServer.connect()
18150
18541
  },
18151
18542
  ...localOptions?.WebSocket !== undefined ? { WebSocket: localOptions.WebSocket } : {},
18152
18543
  ...localOptions?.requestTimeoutMs !== undefined ? { requestTimeoutMs: localOptions.requestTimeoutMs } : {}
18153
- });
18544
+ };
18154
18545
  }
18155
18546
  async createLocalAgent(options) {
18156
18547
  const localOptions = this.options;
@@ -19647,12 +20038,12 @@ var require_applicability2 = __commonJS2((exports) => {
19647
20038
  Object.defineProperty(exports, "__esModule", { value: true });
19648
20039
  exports.shouldUseRule = exports.shouldUseGroup = exports.schemaHasRulesForType = undefined;
19649
20040
  function schemaHasRulesForType({ schema, self }, type) {
19650
- const group = self.RULES.types[type];
19651
- return group && group !== true && shouldUseGroup(schema, group);
20041
+ const group2 = self.RULES.types[type];
20042
+ return group2 && group2 !== true && shouldUseGroup(schema, group2);
19652
20043
  }
19653
20044
  exports.schemaHasRulesForType = schemaHasRulesForType;
19654
- function shouldUseGroup(schema, group) {
19655
- return group.rules.some((rule) => shouldUseRule(schema, rule));
20045
+ function shouldUseGroup(schema, group2) {
20046
+ return group2.rules.some((rule) => shouldUseRule(schema, rule));
19656
20047
  }
19657
20048
  exports.shouldUseGroup = shouldUseGroup;
19658
20049
  function shouldUseRule(schema, rule) {
@@ -20644,36 +21035,36 @@ var require_validate2 = __commonJS2((exports) => {
20644
21035
  if (!opts.jtd)
20645
21036
  checkStrictTypes(it, types);
20646
21037
  gen.block(() => {
20647
- for (const group of RULES.rules)
20648
- groupKeywords(group);
21038
+ for (const group2 of RULES.rules)
21039
+ groupKeywords(group2);
20649
21040
  groupKeywords(RULES.post);
20650
21041
  });
20651
- function groupKeywords(group) {
20652
- if (!(0, applicability_1.shouldUseGroup)(schema, group))
21042
+ function groupKeywords(group2) {
21043
+ if (!(0, applicability_1.shouldUseGroup)(schema, group2))
20653
21044
  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) {
21045
+ if (group2.type) {
21046
+ gen.if((0, dataType_2.checkDataType)(group2.type, data, opts.strictNumbers));
21047
+ iterateKeywords(it, group2);
21048
+ if (types.length === 1 && types[0] === group2.type && typeErrors) {
20658
21049
  gen.else();
20659
21050
  (0, dataType_2.reportTypeError)(it);
20660
21051
  }
20661
21052
  gen.endIf();
20662
21053
  } else {
20663
- iterateKeywords(it, group);
21054
+ iterateKeywords(it, group2);
20664
21055
  }
20665
21056
  if (!allErrors)
20666
21057
  gen.if((0, codegen_1._)`${names_1.default.errors} === ${errsCount || 0}`);
20667
21058
  }
20668
21059
  }
20669
- function iterateKeywords(it, group) {
21060
+ function iterateKeywords(it, group2) {
20670
21061
  const { gen, schema, opts: { useDefaults } } = it;
20671
21062
  if (useDefaults)
20672
- (0, defaults_1.assignDefaults)(it, group.type);
21063
+ (0, defaults_1.assignDefaults)(it, group2.type);
20673
21064
  gen.block(() => {
20674
- for (const rule of group.rules) {
21065
+ for (const rule of group2.rules) {
20675
21066
  if ((0, applicability_1.shouldUseRule)(schema, rule)) {
20676
- keywordCode(it, rule.keyword, rule.definition, group.type);
21067
+ keywordCode(it, rule.keyword, rule.definition, group2.type);
20677
21068
  }
20678
21069
  }
20679
21070
  });
@@ -22358,10 +22749,10 @@ var require_core3 = __commonJS2((exports) => {
22358
22749
  const { RULES } = this;
22359
22750
  delete RULES.keywords[keyword];
22360
22751
  delete RULES.all[keyword];
22361
- for (const group of RULES.rules) {
22362
- const i = group.rules.findIndex((rule) => rule.keyword === keyword);
22752
+ for (const group2 of RULES.rules) {
22753
+ const i = group2.rules.findIndex((rule) => rule.keyword === keyword);
22363
22754
  if (i >= 0)
22364
- group.rules.splice(i, 1);
22755
+ group2.rules.splice(i, 1);
22365
22756
  }
22366
22757
  return this;
22367
22758
  }
@@ -29615,16 +30006,16 @@ var safeDecode = /* @__PURE__ */ _safeDecode(ZodRealError);
29615
30006
  var safeEncodeAsync = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
29616
30007
  var safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
29617
30008
  var _installedGroups = /* @__PURE__ */ new WeakMap;
29618
- function _installLazyMethods(inst, group, methods) {
30009
+ function _installLazyMethods(inst, group2, methods) {
29619
30010
  const proto = Object.getPrototypeOf(inst);
29620
30011
  let installed = _installedGroups.get(proto);
29621
30012
  if (!installed) {
29622
30013
  installed = new Set;
29623
30014
  _installedGroups.set(proto, installed);
29624
30015
  }
29625
- if (installed.has(group))
30016
+ if (installed.has(group2))
29626
30017
  return;
29627
- installed.add(group);
30018
+ installed.add(group2);
29628
30019
  for (const key in methods) {
29629
30020
  const fn = methods[key];
29630
30021
  Object.defineProperty(proto, key, {
@@ -35002,7 +35393,7 @@ class StreamableHTTPClientTransport {
35002
35393
  }
35003
35394
  var DEFAULT_CLIENT_INFO = {
35004
35395
  name: "letta-code",
35005
- version: "0.34.44"
35396
+ version: "0.34.46"
35006
35397
  };
35007
35398
  async function connectMcpServer(config2, options = {}) {
35008
35399
  let client = new Client(options.clientInfo ?? DEFAULT_CLIENT_INFO);
@@ -36030,4 +36421,4 @@ export {
36030
36421
  CloudManagedSandboxExpiredError
36031
36422
  };
36032
36423
 
36033
- //# debugId=B1D81F173658DB9E64756E2164756E21
36424
+ //# debugId=7BDBF5BF72C0151764756E2164756E21