@letta-ai/letta-code 0.23.3 → 0.23.4

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 (2) hide show
  1. package/letta.js +90 -38
  2. package/package.json +1 -1
package/letta.js CHANGED
@@ -3269,7 +3269,7 @@ var package_default;
3269
3269
  var init_package = __esm(() => {
3270
3270
  package_default = {
3271
3271
  name: "@letta-ai/letta-code",
3272
- version: "0.23.3",
3272
+ version: "0.23.4",
3273
3273
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
3274
3274
  type: "module",
3275
3275
  bin: {
@@ -43512,15 +43512,20 @@ No external channel adapters are currently running.`;
43512
43512
 
43513
43513
  Currently active channels: ${channelList}. Available actions across the active channels: ${actionList}. The JSON schema reflects the currently active channel plugins.`;
43514
43514
  }
43515
- async function resolveMessageChannelToolDiscovery() {
43516
- const activeChannels = getActiveChannelIds();
43515
+ async function resolveMessageChannelToolDiscovery(scope) {
43516
+ const scopedChannels = scope?.channels ?? [];
43517
+ const discoveryTargets = scopedChannels.length > 0 ? scopedChannels : getActiveChannelIds().map((channelId) => ({
43518
+ channelId,
43519
+ accountId: null
43520
+ }));
43521
+ const activeChannels = Array.from(new Set(discoveryTargets.map(({ channelId }) => channelId)));
43517
43522
  const actions = new Set(["send"]);
43518
43523
  const schemaContributions = [];
43519
- for (const channelId of activeChannels) {
43524
+ for (const { channelId, accountId } of discoveryTargets) {
43520
43525
  try {
43521
43526
  const plugin = await loadChannelPlugin(channelId);
43522
43527
  const discovery = plugin.messageActions?.describeMessageTool({
43523
- accountId: null
43528
+ accountId: accountId ?? null
43524
43529
  });
43525
43530
  for (const action of collectDiscoveryActions(discovery)) {
43526
43531
  actions.add(action);
@@ -43536,16 +43541,18 @@ async function resolveMessageChannelToolDiscovery() {
43536
43541
  schemaContributions
43537
43542
  };
43538
43543
  }
43539
- async function buildDynamicMessageChannelToolDefinition(baseDescription, baseSchema) {
43540
- const discovery = await resolveMessageChannelToolDiscovery();
43544
+ async function buildDynamicMessageChannelToolDefinition(baseDescription, baseSchema, scope) {
43545
+ const discovery = await resolveMessageChannelToolDiscovery(scope);
43541
43546
  const resolved = {
43542
43547
  description: buildDynamicMessageChannelDescriptionFromDiscovery(baseDescription, discovery),
43543
43548
  schema: buildDynamicMessageChannelSchemaFromDiscovery(baseSchema, discovery)
43544
43549
  };
43545
- cachedDynamicMessageChannelTool = {
43546
- description: resolved.description,
43547
- schema: structuredClone(resolved.schema)
43548
- };
43550
+ if (!scope || scope.channels.length === 0) {
43551
+ cachedDynamicMessageChannelTool = {
43552
+ description: resolved.description,
43553
+ schema: structuredClone(resolved.schema)
43554
+ };
43555
+ }
43549
43556
  return resolved;
43550
43557
  }
43551
43558
  function getCachedDynamicMessageChannelToolDefinition() {
@@ -45239,7 +45246,7 @@ function getPreferredAgentModelHandle(agent) {
45239
45246
  }
45240
45247
  return buildModelHandleFromLlmConfig(agent.llm_config);
45241
45248
  }
45242
- function getToolNamesForToolset(toolsetName) {
45249
+ function getToolNamesForToolset(toolsetName, channelToolScope) {
45243
45250
  let tools;
45244
45251
  switch (toolsetName) {
45245
45252
  case "codex":
@@ -45260,7 +45267,8 @@ function getToolNamesForToolset(toolsetName) {
45260
45267
  tools = [...ANTHROPIC_DEFAULT_TOOLS];
45261
45268
  break;
45262
45269
  }
45263
- if (getActiveChannelIds().length > 0 && !tools.includes("MessageChannel")) {
45270
+ const hasScopedChannelTool = channelToolScope !== undefined ? (channelToolScope?.channels.length ?? 0) > 0 : (getChannelRegistry()?.getActiveChannelIds().length ?? 0) > 0;
45271
+ if (hasScopedChannelTool && !tools.includes("MessageChannel")) {
45264
45272
  tools.push("MessageChannel");
45265
45273
  }
45266
45274
  return tools;
@@ -45271,14 +45279,16 @@ async function prepareToolExecutionContextForResolvedTarget(params) {
45271
45279
  toolsetPreference,
45272
45280
  exclude,
45273
45281
  workingDirectory,
45274
- permissionModeState
45282
+ permissionModeState,
45283
+ channelToolScope
45275
45284
  } = params;
45276
45285
  const effectiveModel = modelIdentifier && modelIdentifier.length > 0 ? resolveModel2(modelIdentifier) ?? modelIdentifier : null;
45277
45286
  if (toolsetPreference === "auto") {
45278
45287
  const preparedToolContext2 = await prepareToolExecutionContextForModel(effectiveModel ?? undefined, {
45279
45288
  exclude,
45280
45289
  workingDirectory,
45281
- permissionModeState
45290
+ permissionModeState,
45291
+ channelToolScope
45282
45292
  });
45283
45293
  return {
45284
45294
  preparedToolContext: preparedToolContext2,
@@ -45287,9 +45297,10 @@ async function prepareToolExecutionContextForResolvedTarget(params) {
45287
45297
  effectiveModel
45288
45298
  };
45289
45299
  }
45290
- const preparedToolContext = await prepareToolExecutionContextForSpecificTools(getToolNamesForToolset(toolsetPreference).filter((toolName) => exclude ? !exclude.includes(toolName) : true), {
45300
+ const preparedToolContext = await prepareToolExecutionContextForSpecificTools(getToolNamesForToolset(toolsetPreference, channelToolScope).filter((toolName) => exclude ? !exclude.includes(toolName) : true), {
45291
45301
  workingDirectory,
45292
- permissionModeState
45302
+ permissionModeState,
45303
+ channelToolScope
45293
45304
  });
45294
45305
  return {
45295
45306
  preparedToolContext,
@@ -45298,6 +45309,36 @@ async function prepareToolExecutionContextForResolvedTarget(params) {
45298
45309
  effectiveModel
45299
45310
  };
45300
45311
  }
45312
+ function resolveConversationChannelToolScope(agentId, conversationId) {
45313
+ const registry = getChannelRegistry();
45314
+ if (!registry) {
45315
+ return { channels: [] };
45316
+ }
45317
+ const channels = [];
45318
+ const seen = new Set;
45319
+ for (const channelId of SUPPORTED_CHANNEL_IDS) {
45320
+ loadRoutes(channelId);
45321
+ for (const route of getRoutesForChannel(channelId)) {
45322
+ if (route.agentId !== agentId || route.conversationId !== conversationId || !route.enabled) {
45323
+ continue;
45324
+ }
45325
+ const adapter = registry.getAdapter(channelId, route.accountId);
45326
+ if (!adapter?.isRunning()) {
45327
+ continue;
45328
+ }
45329
+ const key = `${channelId}:${route.accountId ?? ""}`;
45330
+ if (seen.has(key)) {
45331
+ continue;
45332
+ }
45333
+ seen.add(key);
45334
+ channels.push({
45335
+ channelId,
45336
+ accountId: route.accountId ?? null
45337
+ });
45338
+ }
45339
+ }
45340
+ return { channels };
45341
+ }
45301
45342
  async function prepareToolExecutionContextForScope(params) {
45302
45343
  const {
45303
45344
  agentId,
@@ -45332,7 +45373,8 @@ async function prepareToolExecutionContextForScope(params) {
45332
45373
  toolsetPreference,
45333
45374
  exclude,
45334
45375
  workingDirectory,
45335
- permissionModeState
45376
+ permissionModeState,
45377
+ channelToolScope: resolveConversationChannelToolScope(agentId, conversationId ?? "default")
45336
45378
  });
45337
45379
  }
45338
45380
  async function ensureCorrectMemoryTool(agentId, modelIdentifier, useMemoryPatch) {
@@ -45489,6 +45531,8 @@ var init_toolset = __esm(async () => {
45489
45531
  init_client2();
45490
45532
  init_model2();
45491
45533
  init_registry();
45534
+ init_routing();
45535
+ init_types();
45492
45536
  init_settings_manager();
45493
45537
  init_filter();
45494
45538
  await init_manager3();
@@ -73556,20 +73600,21 @@ var init_analyzer = __esm(() => {
73556
73600
  // src/tools/manager.ts
73557
73601
  import * as nodeFs from "node:fs/promises";
73558
73602
  import * as nodePath from "node:path";
73559
- function maybeAppendChannelTools(toolNames) {
73560
- if (getActiveChannelIds().length > 0 && !toolNames.includes("MessageChannel")) {
73603
+ function maybeAppendChannelTools(toolNames, channelToolScope) {
73604
+ const hasActiveChannelTools = channelToolScope !== undefined ? (channelToolScope?.channels.length ?? 0) > 0 : getActiveChannelIds().length > 0;
73605
+ if (hasActiveChannelTools && !toolNames.includes("MessageChannel")) {
73561
73606
  return [...toolNames, "MessageChannel"];
73562
73607
  }
73563
73608
  return toolNames;
73564
73609
  }
73565
- async function maybeResolveDynamicChannelTool(name, description, schema) {
73610
+ async function maybeResolveDynamicChannelTool(name, description, schema, channelToolScope) {
73566
73611
  if (name !== "MessageChannel") {
73567
73612
  return {
73568
73613
  description,
73569
73614
  input_schema: schema
73570
73615
  };
73571
73616
  }
73572
- const resolved = await buildDynamicMessageChannelToolDefinition(description, schema);
73617
+ const resolved = await buildDynamicMessageChannelToolDefinition(description, schema, channelToolScope);
73573
73618
  return {
73574
73619
  description: resolved.description,
73575
73620
  input_schema: resolved.schema
@@ -73577,6 +73622,10 @@ async function maybeResolveDynamicChannelTool(name, description, schema) {
73577
73622
  }
73578
73623
  function withDynamicMessageChannelCache(registry) {
73579
73624
  const nextRegistry = new Map(registry);
73625
+ const existing = nextRegistry.get("MessageChannel");
73626
+ if (existing && existing.schema.description !== TOOL_DEFINITIONS.MessageChannel.description) {
73627
+ return nextRegistry;
73628
+ }
73580
73629
  if (getActiveChannelIds().length === 0) {
73581
73630
  nextRegistry.delete("MessageChannel");
73582
73631
  return nextRegistry;
@@ -73585,7 +73634,6 @@ function withDynamicMessageChannelCache(registry) {
73585
73634
  if (!cachedMessageChannel) {
73586
73635
  return nextRegistry;
73587
73636
  }
73588
- const existing = nextRegistry.get("MessageChannel");
73589
73637
  nextRegistry.set("MessageChannel", {
73590
73638
  schema: {
73591
73639
  name: "MessageChannel",
@@ -73788,7 +73836,7 @@ async function prepareCurrentToolExecutionContext(options) {
73788
73836
  }, options);
73789
73837
  }
73790
73838
  async function prepareToolExecutionContextForSpecificTools(toolNames, options) {
73791
- const toolRegistrySnapshot = await buildSpecificToolRegistry(toolNames);
73839
+ const toolRegistrySnapshot = await buildSpecificToolRegistry(toolNames, options?.channelToolScope);
73792
73840
  return capturePreparedToolExecutionContext({
73793
73841
  toolRegistry: toolRegistrySnapshot,
73794
73842
  externalTools: new Map(getExternalToolsRegistry()),
@@ -73861,7 +73909,7 @@ function maybeApplyLspReadOverride(registry) {
73861
73909
  fn: lspDefinition.impl
73862
73910
  });
73863
73911
  }
73864
- async function buildSpecificToolRegistry(toolNames) {
73912
+ async function buildSpecificToolRegistry(toolNames, channelToolScope) {
73865
73913
  const { toolFilter: toolFilter2 } = await Promise.resolve().then(() => (init_filter(), exports_filter));
73866
73914
  const newRegistry = new Map;
73867
73915
  for (const name of toolNames) {
@@ -73877,7 +73925,7 @@ async function buildSpecificToolRegistry(toolNames) {
73877
73925
  if (!definition.impl) {
73878
73926
  throw new Error(`Tool implementation not found for ${internalName}`);
73879
73927
  }
73880
- const resolvedTool = await maybeResolveDynamicChannelTool(internalName, definition.description, definition.schema);
73928
+ const resolvedTool = await maybeResolveDynamicChannelTool(internalName, definition.description, definition.schema, channelToolScope);
73881
73929
  const toolSchema = {
73882
73930
  name: internalName,
73883
73931
  description: resolvedTool.description,
@@ -73907,7 +73955,7 @@ async function resolveBaseToolNamesForModel(modelIdentifier, options) {
73907
73955
  const excludeSet = new Set(options.exclude);
73908
73956
  baseToolNames = baseToolNames.filter((name) => !excludeSet.has(name));
73909
73957
  }
73910
- baseToolNames = maybeAppendChannelTools(baseToolNames);
73958
+ baseToolNames = maybeAppendChannelTools(baseToolNames, options?.channelToolScope);
73911
73959
  return baseToolNames;
73912
73960
  }
73913
73961
  async function buildRegistryForModel(modelIdentifier, options) {
@@ -73936,7 +73984,7 @@ async function buildRegistryForModel(modelIdentifier, options) {
73936
73984
  if (name === "Task" && discoveredSubagents.length > 0) {
73937
73985
  description = injectSubagentsIntoTaskDescription(description, discoveredSubagents);
73938
73986
  }
73939
- const resolvedTool = await maybeResolveDynamicChannelTool(name, description, definition.schema);
73987
+ const resolvedTool = await maybeResolveDynamicChannelTool(name, description, definition.schema, options?.channelToolScope);
73940
73988
  const toolSchema = {
73941
73989
  name,
73942
73990
  description: resolvedTool.description,
@@ -91232,9 +91280,10 @@ async function applyModelUpdateForRuntime(params) {
91232
91280
  let toolsetError = null;
91233
91281
  try {
91234
91282
  await ensureCorrectMemoryTool(agentId, model.handle);
91235
- const preparedToolContext = await prepareToolExecutionContextForResolvedTarget({
91236
- modelIdentifier: model.handle,
91237
- toolsetPreference
91283
+ const preparedToolContext = await prepareToolExecutionContextForScope({
91284
+ agentId,
91285
+ conversationId,
91286
+ overrideModel: model.handle
91238
91287
  });
91239
91288
  nextToolset = preparedToolContext.toolset;
91240
91289
  nextLoadedTools = preparedToolContext.preparedToolContext.loadedToolNames;
@@ -161433,20 +161482,21 @@ await __promiseAll([
161433
161482
  init_toolDefinitions()
161434
161483
  ]);
161435
161484
  var TOOL_NAMES2 = Object.keys(TOOL_DEFINITIONS);
161436
- function maybeAppendChannelTools2(toolNames) {
161437
- if (getActiveChannelIds().length > 0 && !toolNames.includes("MessageChannel")) {
161485
+ function maybeAppendChannelTools2(toolNames, channelToolScope) {
161486
+ const hasActiveChannelTools = channelToolScope !== undefined ? (channelToolScope?.channels.length ?? 0) > 0 : getActiveChannelIds().length > 0;
161487
+ if (hasActiveChannelTools && !toolNames.includes("MessageChannel")) {
161438
161488
  return [...toolNames, "MessageChannel"];
161439
161489
  }
161440
161490
  return toolNames;
161441
161491
  }
161442
- async function maybeResolveDynamicChannelTool2(name, description, schema) {
161492
+ async function maybeResolveDynamicChannelTool2(name, description, schema, channelToolScope) {
161443
161493
  if (name !== "MessageChannel") {
161444
161494
  return {
161445
161495
  description,
161446
161496
  input_schema: schema
161447
161497
  };
161448
161498
  }
161449
- const resolved = await buildDynamicMessageChannelToolDefinition(description, schema);
161499
+ const resolved = await buildDynamicMessageChannelToolDefinition(description, schema, channelToolScope);
161450
161500
  return {
161451
161501
  description: resolved.description,
161452
161502
  input_schema: resolved.schema
@@ -161591,7 +161641,7 @@ async function resolveBaseToolNamesForModel2(modelIdentifier, options) {
161591
161641
  const excludeSet = new Set(options.exclude);
161592
161642
  baseToolNames = baseToolNames.filter((name) => !excludeSet.has(name));
161593
161643
  }
161594
- baseToolNames = maybeAppendChannelTools2(baseToolNames);
161644
+ baseToolNames = maybeAppendChannelTools2(baseToolNames, options?.channelToolScope);
161595
161645
  return baseToolNames;
161596
161646
  }
161597
161647
  async function buildRegistryForModel2(modelIdentifier, options) {
@@ -161620,7 +161670,7 @@ async function buildRegistryForModel2(modelIdentifier, options) {
161620
161670
  if (name === "Task" && discoveredSubagents.length > 0) {
161621
161671
  description = injectSubagentsIntoTaskDescription2(description, discoveredSubagents);
161622
161672
  }
161623
- const resolvedTool = await maybeResolveDynamicChannelTool2(name, description, definition.schema);
161673
+ const resolvedTool = await maybeResolveDynamicChannelTool2(name, description, definition.schema, options?.channelToolScope);
161624
161674
  const toolSchema = {
161625
161675
  name,
161626
161676
  description: resolvedTool.description,
@@ -161694,6 +161744,8 @@ ${after}`;
161694
161744
  init_client2();
161695
161745
  init_model2();
161696
161746
  init_registry();
161747
+ init_routing();
161748
+ init_types();
161697
161749
  init_settings_manager();
161698
161750
  init_filter();
161699
161751
  await init_manager3();
@@ -163129,4 +163181,4 @@ Error during initialization: ${message}`);
163129
163181
  }
163130
163182
  main();
163131
163183
 
163132
- //# debugId=41CC74E0316710DC64756E2164756E21
163184
+ //# debugId=29DBF7A2819CB6C064756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letta-ai/letta-code",
3
- "version": "0.23.3",
3
+ "version": "0.23.4",
4
4
  "description": "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
5
5
  "type": "module",
6
6
  "bin": {