@letta-ai/letta-agent-sdk 0.8.78 → 0.8.80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.d.ts CHANGED
@@ -8,6 +8,7 @@ export declare class LettaAgentClient extends LettaAgentClientBase {
8
8
  private localClosePromise;
9
9
  private sharedLocalServer;
10
10
  close(): Promise<void>;
11
+ protected startRegisteredComputer(): Promise<void>;
11
12
  protected skillNodeSupport(): SkillNodeSupport;
12
13
  protected createLocalManagementTransport(): ManagementTransport;
13
14
  protected localAppServerConnection(): {
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAG3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,OAAO,KAAK,EACV,kBAAkB,EAClB,6BAA6B,EAE7B,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,qBAAa,gBAAiB,SAAQ,oBAAoB;IACxD,OAAO,CAAC,WAAW,CAAqC;IACxD,OAAO,CAAC,iBAAiB,CAA8B;IAEvD,OAAO,CAAC,iBAAiB;IAUhB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;cAUZ,gBAAgB,IAAI,gBAAgB;cAIpC,8BAA8B,IAAI,mBAAmB;cAIrD,wBAAwB;;;;;;;;;cAoBlB,gBAAgB,CACvC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,MAAM,CAAC;cAqBC,kBAAkB,CACnC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,6BAA6B,GACrC,gBAAgB;cAcA,uBAAuB,CACxC,YAAY,EAAE,YAAY,EAC1B,cAAc,EAAE,6BAA6B,GAC5C,gBAAgB;cAgCA,kBAAkB,CACnC,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,6BAA6B,GACrC,gBAAgB;CAwBpB"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAGxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAG3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,OAAO,KAAK,EACV,kBAAkB,EAElB,6BAA6B,EAE7B,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,qBAAa,gBAAiB,SAAQ,oBAAoB;IACxD,OAAO,CAAC,WAAW,CAAqC;IACxD,OAAO,CAAC,iBAAiB,CAA8B;IAEvD,OAAO,CAAC,iBAAiB;IAehB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;cAUN,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC;cAI9C,gBAAgB,IAAI,gBAAgB;cAIpC,8BAA8B,IAAI,mBAAmB;cAIrD,wBAAwB;;;;;;;;;cAyBlB,gBAAgB,CACvC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,MAAM,CAAC;cAqBC,kBAAkB,CACnC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,6BAA6B,GACrC,gBAAgB;cAcA,uBAAuB,CACxC,YAAY,EAAE,YAAY,EAC1B,cAAc,EAAE,6BAA6B,GAC5C,gBAAgB;cAgCA,kBAAkB,CACnC,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,6BAA6B,GACrC,gBAAgB;CAwBpB"}
@@ -3,6 +3,9 @@ import { type SkillFilesPusher } from "./skill-loading.js";
3
3
  import { RemoteClientSessionCore, type RuntimeScope, type RuntimeSessionInit, type RuntimeSessionMode } from "./remote-client-session-core.js";
4
4
  import type { CreateAgentOptions, LettaCodeClientSessionOptions, LettaCodeCloudClientOptions } from "./types.js";
5
5
  import { type SandboxFilesClient } from "./sandbox-files.js";
6
+ type ResolvedCloudConnection = {
7
+ connectionId: string;
8
+ };
6
9
  /**
7
10
  * The Cloud API reaped a conversation-scoped managed sandbox before the SDK
8
11
  * could refresh it. The failed refresh happens before the next turn is sent,
@@ -26,6 +29,8 @@ export declare function assertCloudSessionOptionsSupported(action: string, optio
26
29
  export declare class CloudEnvironmentSession extends RemoteClientSessionCore {
27
30
  private readonly cloudOptions;
28
31
  private readonly apiClient;
32
+ /** Starts and resolves the computer this client registers, when the session runs there. */
33
+ private readonly connectRegisteredComputer?;
29
34
  readonly sandbox: SandboxFilesClient | undefined;
30
35
  private connectionId;
31
36
  private removeExternalToolHandler;
@@ -41,7 +46,9 @@ export declare class CloudEnvironmentSession extends RemoteClientSessionCore {
41
46
  private repositoryIdsRequiringCleanupRecompile;
42
47
  private readonly repositoryManagement;
43
48
  private readonly cloudMode;
44
- constructor(cloudOptions: LettaCodeCloudClientOptions, mode: CloudSessionMode, apiClient?: Letta);
49
+ constructor(cloudOptions: LettaCodeCloudClientOptions, mode: CloudSessionMode, apiClient?: Letta,
50
+ /** Starts and resolves the computer this client registers, when the session runs there. */
51
+ connectRegisteredComputer?: (() => Promise<ResolvedCloudConnection>) | undefined);
45
52
  protected initializeRuntimeController(): Promise<RuntimeSessionInit>;
46
53
  private openCloudTransport;
47
54
  private createCloudTransportClient;
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-session.d.ts","sourceRoot":"","sources":["../src/cloud-session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,wBAAwB,CAAC;AAQhD,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAyB5B,OAAO,EACL,uBAAuB,EAGvB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACxB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAEV,kBAAkB,EAClB,6BAA6B,EAC7B,2BAA2B,EAI5B,MAAM,YAAY,CAAC;AAKpB,OAAO,EAIL,KAAK,kBAAkB,EAExB,MAAM,oBAAoB,CAAC;AAuE5B;;;;;GAKG;AACH,qBAAa,+BAAgC,SAAQ,KAAK;IAItD,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM;IAJjC,QAAQ,CAAC,IAAI,EAAG,yBAAyB,CAAU;gBAGxC,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM;CAOlC;AAED,KAAK,gBAAgB,GAAG,OAAO,CAC7B,kBAAkB,EAClB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,CAC/C,CAAC;AAiCF,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,2BAA2B,GAAG,IAAI,CAwBrF;AAkGD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,KAAK,EACb,YAAY,EAAE,kBAAkB,EAChC,qBAAqB,CAAC,EAAE,gBAAgB,GACvC,OAAO,CAAC,MAAM,CAAC,CAgCjB;AAED,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,6BAA6B,GACrC,IAAI,CAKN;AAED,qBAAa,uBAAwB,SAAQ,uBAAuB;IAkBhE,OAAO,CAAC,QAAQ,CAAC,YAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAnB5B,QAAQ,CAAC,OAAO,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACjD,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,yBAAyB,CAA6B;IAC9D,OAAO,CAAC,2BAA2B,CAA6B;IAChE,OAAO,CAAC,aAAa,CAAmC;IACxD,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,cAAc,CAAoC;IAC1D,OAAO,CAAC,mBAAmB,CAA+C;IAC1E,OAAO,CAAC,sBAAsB,CAA8B;IAC5D,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,qBAAqB,CAAqB;IAClD,OAAO,CAAC,sCAAsC,CAAqB;IACnE,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA2B;IAChE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;gBAG1B,YAAY,EAAE,2BAA2B,EAC1D,IAAI,EAAE,gBAAgB,EACL,SAAS,GAAE,KAAuC;cAkB5C,2BAA2B,IAAI,OAAO,CAAC,kBAAkB,CAAC;YA+CrE,kBAAkB;IAyDhC,OAAO,CAAC,0BAA0B;YA6BpB,qBAAqB;IAiDnC,OAAO,CAAC,wBAAwB;IAchC,OAAO,CAAC,wBAAwB;cAOP,oBAAoB,CAC3C,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,kBAAkB,CAAC;YAMhB,yBAAyB;cAepB,yBAAyB,IAAI,IAAI;cAIjC,6BAA6B,IAAI,IAAI;YAI1C,iBAAiB;cAwCN,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC;cAUxC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAMtC,2BAA2B;YAO3B,8BAA8B;YAK9B,oCAAoC;cAa/B,WAAW,IAAI,IAAI;cAYb,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxD,OAAO,CAAC,cAAc;YAOR,cAAc;YA0Dd,yBAAyB;YA6CzB,0BAA0B;YAgC1B,qBAAqB;IAenC,OAAO,CAAC,mBAAmB;YAkBb,sBAAsB;YActB,kBAAkB;YAUlB,oBAAoB;YAUpB,2BAA2B;YAc3B,yBAAyB;YAQzB,8BAA8B;YAsC9B,oBAAoB;YA2DpB,qBAAqB;YAcrB,yBAAyB;YA4CzB,uBAAuB;YA4BvB,+BAA+B;IA4B7C,OAAO,CAAC,0BAA0B;IAelC,OAAO,CAAC,yBAAyB;YAMnB,qBAAqB;IAuBnC,OAAO,CAAC,uBAAuB;IAI/B,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,uBAAuB;IAO/B,OAAO,CAAC,sBAAsB;CAG/B"}
1
+ {"version":3,"file":"cloud-session.d.ts","sourceRoot":"","sources":["../src/cloud-session.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { AppServerExternalToolCallHandler } from "@letta-ai/letta-code/app-server-client";
1
+ import type { AppServerClient, AppServerExternalToolCallHandler } from "@letta-ai/letta-code/app-server-client";
2
2
  import type { RuntimeScope } from "./remote-session-protocol.js";
3
3
  import type { AnyAgentTool } from "./types.js";
4
4
  /** The `external_tools` groups that advertise client tools to the runtime. */
@@ -7,5 +7,9 @@ export declare function externalToolGroups(tools: AnyAgentTool[] | undefined): A
7
7
  * Run a runtime's external tool call against the client tools by name.
8
8
  * `fallbackRuntime` covers listeners that send calls without a `runtime`.
9
9
  */
10
- export declare function createExternalToolCallHandler(externalTools: Map<string, AnyAgentTool>, fallbackRuntime?: () => RuntimeScope | null): AppServerExternalToolCallHandler;
10
+ export declare function createExternalToolCallHandler(externalTools: Map<string, AnyAgentTool>, fallbackRuntime?: () => RuntimeScope | null): CancellableToolCallHandler;
11
+ type CancellableToolCallHandler = (request: Parameters<AppServerExternalToolCallHandler>[0], signal?: AbortSignal) => ReturnType<AppServerExternalToolCallHandler>;
12
+ /** Own response arbitration so cancellation and completion cannot both reply. */
13
+ export declare function registerExternalToolCallHandler(client: AppServerClient, handler: CancellableToolCallHandler): () => void;
14
+ export {};
11
15
  //# sourceMappingURL=external-tools.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"external-tools.d.ts","sourceRoot":"","sources":["../src/external-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,wCAAwC,CAAC;AAC/F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAwB,YAAY,EAAE,MAAM,YAAY,CAAC;AAErE,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAYhH;AAID;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACxC,eAAe,CAAC,EAAE,MAAM,YAAY,GAAG,IAAI,GAC1C,gCAAgC,CAwClC"}
1
+ {"version":3,"file":"external-tools.d.ts","sourceRoot":"","sources":["../src/external-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,gCAAgC,EAAE,MAAM,wCAAwC,CAAC;AAChH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAwB,YAAY,EAAE,MAAM,YAAY,CAAC;AAErE,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAahH;AAID;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACxC,eAAe,CAAC,EAAE,MAAM,YAAY,GAAG,IAAI,GAC1C,0BAA0B,CAwC5B;AAED,KAAK,0BAA0B,GAAG,CAChC,OAAO,EAAE,UAAU,CAAC,gCAAgC,CAAC,CAAC,CAAC,CAAC,EACxD,MAAM,CAAC,EAAE,WAAW,KACjB,UAAU,CAAC,gCAAgC,CAAC,CAAC;AAElD,iFAAiF;AACjF,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,0BAA0B,GAClC,MAAM,IAAI,CAuCZ"}
package/dist/index.js CHANGED
@@ -9536,18 +9536,39 @@ function onceSocketEvent(socket, type, listener) {
9536
9536
  });
9537
9537
  return detach;
9538
9538
  }
9539
- function waitForSocketOpen(socket) {
9539
+ function waitForSocketOpen(socket, timeoutMs) {
9540
9540
  if (socket.readyState === WEBSOCKET_OPEN_STATE) {
9541
9541
  return Promise.resolve();
9542
9542
  }
9543
- return new Promise((resolve, reject) => {
9543
+ return new Promise((resolvePromise, rejectPromise) => {
9544
+ let settled = false;
9545
+ const resolve = () => {
9546
+ if (settled)
9547
+ return;
9548
+ settled = true;
9549
+ resolvePromise();
9550
+ };
9551
+ const reject = (error) => {
9552
+ if (settled)
9553
+ return;
9554
+ settled = true;
9555
+ rejectPromise(error);
9556
+ };
9544
9557
  let detachOpen = () => {};
9545
9558
  let detachError = () => {};
9559
+ let detachClose = () => {};
9546
9560
  let detachResponse = () => {};
9547
9561
  let detachBody = () => {};
9562
+ let upgradeRejected = false;
9563
+ const timer = timeoutMs > 0 ? setTimeout(() => {
9564
+ cleanup();
9565
+ reject(new Error(`App-server WebSocket failed to open: timed out after ${timeoutMs}ms`));
9566
+ }, timeoutMs) : undefined;
9548
9567
  const cleanup = () => {
9568
+ clearTimeout(timer);
9549
9569
  detachOpen();
9550
9570
  detachError();
9571
+ detachClose();
9551
9572
  detachResponse();
9552
9573
  detachBody();
9553
9574
  };
@@ -9559,6 +9580,7 @@ function waitForSocketOpen(socket) {
9559
9580
  const onResponse = (_request, response) => {
9560
9581
  if (!response)
9561
9582
  return;
9583
+ upgradeRejected = true;
9562
9584
  const request = _request;
9563
9585
  let body = Buffer.alloc(0);
9564
9586
  let finished = false;
@@ -9600,6 +9622,12 @@ function waitForSocketOpen(socket) {
9600
9622
  cleanup();
9601
9623
  reject(new Error(`App-server WebSocket failed to open: ${String(event)}`));
9602
9624
  });
9625
+ detachClose = onceSocketEvent(socket, "close", () => {
9626
+ if (upgradeRejected)
9627
+ return;
9628
+ cleanup();
9629
+ reject(new Error("App-server WebSocket failed to open: closed before opening"));
9630
+ });
9603
9631
  });
9604
9632
  }
9605
9633
  function rawEventData(event) {
@@ -9667,7 +9695,7 @@ class AppServerClient {
9667
9695
  });
9668
9696
  }
9669
9697
  async connect() {
9670
- await waitForSocketOpen(this.socket);
9698
+ await waitForSocketOpen(this.socket, this.requestTimeoutMs);
9671
9699
  return this;
9672
9700
  }
9673
9701
  close() {
@@ -13294,6 +13322,7 @@ function externalToolGroups(tools) {
13294
13322
  return;
13295
13323
  return [
13296
13324
  {
13325
+ capabilities: { external_tool_call_cancel: true },
13297
13326
  tools: tools.map((tool) => ({
13298
13327
  name: tool.name,
13299
13328
  label: tool.label,
@@ -13306,14 +13335,14 @@ function externalToolGroups(tools) {
13306
13335
  var MAX_REMEMBERED_EXTERNAL_TOOL_CALLS = 200;
13307
13336
  function createExternalToolCallHandler(externalTools, fallbackRuntime) {
13308
13337
  const calls = new Map;
13309
- const execute = async (request) => {
13338
+ const execute = async (request, signal) => {
13310
13339
  const tool = externalTools.get(request.tool_name);
13311
13340
  if (!tool) {
13312
13341
  throw new Error(`Unknown external tool: ${request.tool_name}`);
13313
13342
  }
13314
13343
  const runtime = request.runtime ?? fallbackRuntime?.() ?? null;
13315
13344
  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);
13345
+ const result = await tool.execute(request.tool_call_id, request.input, signal, undefined, context);
13317
13346
  return {
13318
13347
  content: result.content.map((part) => ({
13319
13348
  type: part.type,
@@ -13324,15 +13353,15 @@ function createExternalToolCallHandler(externalTools, fallbackRuntime) {
13324
13353
  ...result.isError === true ? { is_error: true } : {}
13325
13354
  };
13326
13355
  };
13327
- return (request) => {
13356
+ return (request, signal) => {
13328
13357
  const requestId = request.request_id;
13329
13358
  if (typeof requestId !== "string" || requestId.length === 0) {
13330
- return execute(request);
13359
+ return execute(request, signal);
13331
13360
  }
13332
13361
  const existing = calls.get(requestId);
13333
13362
  if (existing)
13334
13363
  return existing;
13335
- const call = execute(request);
13364
+ const call = execute(request, signal);
13336
13365
  calls.set(requestId, call);
13337
13366
  while (calls.size > MAX_REMEMBERED_EXTERNAL_TOOL_CALLS) {
13338
13367
  const oldest = calls.keys().next().value;
@@ -13343,6 +13372,49 @@ function createExternalToolCallHandler(externalTools, fallbackRuntime) {
13343
13372
  return call;
13344
13373
  };
13345
13374
  }
13375
+ function registerExternalToolCallHandler(client, handler) {
13376
+ const pending = new Map;
13377
+ const completed = new Set;
13378
+ const remove = client.onMessage((raw, channel) => {
13379
+ if (channel !== "control")
13380
+ return;
13381
+ const message = raw;
13382
+ const requestId = message.request_id;
13383
+ if (typeof requestId !== "string")
13384
+ return;
13385
+ if (message.type === "external_tool_call_cancel") {
13386
+ const call = pending.get(requestId);
13387
+ if (!call)
13388
+ return;
13389
+ call.finish({ error: "cancelled" });
13390
+ call.controller.abort(message.reason);
13391
+ return;
13392
+ }
13393
+ if (message.type !== "external_tool_call_request" || pending.has(requestId) || completed.has(requestId))
13394
+ return;
13395
+ const controller = new AbortController;
13396
+ const finish = (response) => {
13397
+ if (!pending.delete(requestId))
13398
+ return;
13399
+ completed.add(requestId);
13400
+ if (completed.size > MAX_REMEMBERED_EXTERNAL_TOOL_CALLS)
13401
+ completed.delete(completed.values().next().value);
13402
+ client.send({ type: "external_tool_call_response", request_id: requestId, ...response });
13403
+ };
13404
+ pending.set(requestId, { controller, finish });
13405
+ try {
13406
+ Promise.resolve(handler(raw, controller.signal)).then((result) => finish({ result }), (error) => finish({ error: error instanceof Error ? error.message : String(error) }));
13407
+ } catch (error) {
13408
+ finish({ error: error instanceof Error ? error.message : String(error) });
13409
+ }
13410
+ });
13411
+ return () => {
13412
+ remove();
13413
+ for (const call of pending.values())
13414
+ call.controller.abort();
13415
+ pending.clear();
13416
+ };
13417
+ }
13346
13418
 
13347
13419
  // src/runtime-tool-policy.ts
13348
13420
  var RUNTIME_TOOL_POLICY_CAPABILITY = "runtime_tool_policy";
@@ -15167,7 +15239,7 @@ class AppServerSession extends RemoteClientSessionCore {
15167
15239
  getOptions: () => this.currentOptions()
15168
15240
  });
15169
15241
  if (this.externalTools.size > 0 || this.inheritedTools) {
15170
- this.removeExternalToolHandler = client.onExternalToolCall(createExternalToolCallHandler(this.externalTools, () => this.runtime));
15242
+ this.removeExternalToolHandler = registerExternalToolCallHandler(client, createExternalToolCallHandler(this.externalTools, () => this.runtime));
15171
15243
  }
15172
15244
  try {
15173
15245
  await client.connect();
@@ -16007,6 +16079,19 @@ function validateCloudClientOptions(options) {
16007
16079
  const field = options.computer !== undefined ? "computer" : "environment";
16008
16080
  throw new Error(`Letta Cloud sessions cannot specify both ${field} and sandbox options.`);
16009
16081
  }
16082
+ if (options.registerComputer !== undefined) {
16083
+ const name = options.registerComputer?.name;
16084
+ if (typeof name !== "string" || !name.trim()) {
16085
+ throw new Error("Invalid registerComputer.name. Expected a non-empty string.");
16086
+ }
16087
+ if (options.computer !== undefined || options.environment !== undefined) {
16088
+ const field = options.computer !== undefined ? "computer" : "environment";
16089
+ throw new Error(`Letta Cloud clients cannot specify both ${field} and registerComputer. Use computer for a machine that is already connected, or registerComputer to connect this one.`);
16090
+ }
16091
+ if (options.sandbox !== undefined) {
16092
+ throw new Error("Letta Cloud clients cannot specify both registerComputer and sandbox options.");
16093
+ }
16094
+ }
16010
16095
  if (options.webSocketAuth !== undefined && options.webSocketAuth !== "header" && options.webSocketAuth !== "query") {
16011
16096
  throw new Error("Invalid webSocketAuth. Valid values: header, query.");
16012
16097
  }
@@ -16100,6 +16185,7 @@ function assertCloudSessionOptionsSupported(action, options) {
16100
16185
  class CloudEnvironmentSession extends RemoteClientSessionCore {
16101
16186
  cloudOptions;
16102
16187
  apiClient;
16188
+ connectRegisteredComputer;
16103
16189
  sandbox;
16104
16190
  connectionId = null;
16105
16191
  removeExternalToolHandler = null;
@@ -16115,13 +16201,14 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
16115
16201
  repositoryIdsRequiringCleanupRecompile = new Set;
16116
16202
  repositoryManagement;
16117
16203
  cloudMode;
16118
- constructor(cloudOptions, mode, apiClient = createCloudClient(cloudOptions)) {
16204
+ constructor(cloudOptions, mode, apiClient = createCloudClient(cloudOptions), connectRegisteredComputer) {
16119
16205
  super(mode, {
16120
16206
  label: "cloud",
16121
16207
  requestTimeoutMs: cloudOptions.requestTimeoutMs ?? DEFAULT_TURN_TIMEOUT_MS
16122
16208
  });
16123
16209
  this.cloudOptions = cloudOptions;
16124
16210
  this.apiClient = apiClient;
16211
+ this.connectRegisteredComputer = connectRegisteredComputer;
16125
16212
  this.cloudMode = mode;
16126
16213
  this.repositoryManagement = new CloudManagementTransport(apiClient);
16127
16214
  this.sandbox = this.effectiveEnvironment() === undefined ? {
@@ -16257,7 +16344,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
16257
16344
  getOptions: () => this.currentOptions()
16258
16345
  });
16259
16346
  if (this.externalTools.size > 0) {
16260
- this.removeExternalToolHandler = client.onExternalToolCall(createExternalToolCallHandler(this.externalTools, () => this.runtime));
16347
+ this.removeExternalToolHandler = registerExternalToolCallHandler(client, createExternalToolCallHandler(this.externalTools, () => this.runtime));
16261
16348
  }
16262
16349
  }
16263
16350
  cleanupTransportHandlers() {
@@ -16524,6 +16611,8 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
16524
16611
  return this.createManagedSandboxConnection(runtime);
16525
16612
  }
16526
16613
  async resolveExplicitConnection(environment) {
16614
+ if (this.connectRegisteredComputer)
16615
+ return this.connectRegisteredComputer();
16527
16616
  const target = environmentToRemoteTarget(environment);
16528
16617
  const resolved = await this.remoteEnvironmentClient().resolveEnvironment(target);
16529
16618
  return { connectionId: resolved.connectionId };
@@ -17013,12 +17102,12 @@ class ToolRegistry {
17013
17102
  ...this.options.WebSocket ? { WebSocket: this.options.WebSocket } : {},
17014
17103
  ...this.options.requestTimeoutMs !== undefined ? { requestTimeoutMs: this.options.requestTimeoutMs } : {}
17015
17104
  }));
17016
- client.onExternalToolCall(async (request) => {
17105
+ registerExternalToolCallHandler(client, async (request, signal) => {
17017
17106
  const runtime = request.runtime;
17018
17107
  const entry = runtime && [...this.entries].find((candidate) => candidate.runtimes.some((r) => runtimeKey(r) === runtimeKey(runtime)));
17019
17108
  if (!entry)
17020
17109
  throw new Error(`No tools registered for conversation ${runtime?.conversation_id}`);
17021
- return entry.call(request);
17110
+ return entry.call(request, signal);
17022
17111
  });
17023
17112
  try {
17024
17113
  await client.connect();
@@ -17323,6 +17412,15 @@ function stripCloudExecutionOptions(options) {
17323
17412
  delete sessionOptions.filesystemConfinement;
17324
17413
  return sessionOptions;
17325
17414
  }
17415
+ var REGISTERED_COMPUTER_READY_TIMEOUT_MS = 30000;
17416
+ var REGISTERED_COMPUTER_POLL_INTERVAL_MS = 500;
17417
+ function registeredComputerName(options) {
17418
+ return options.backend === "cloud" ? options.registerComputer?.name : undefined;
17419
+ }
17420
+ function isRegisteredComputerPending(error) {
17421
+ const message = error instanceof Error ? error.message : String(error);
17422
+ return message.startsWith("Computer not found") || message.startsWith("Computer is offline");
17423
+ }
17326
17424
  function hasRepositoryResources(options) {
17327
17425
  return options.resources !== undefined && options.resources.length > 0;
17328
17426
  }
@@ -17381,7 +17479,8 @@ class LettaAgentClientBase {
17381
17479
  throw new Error(`Invalid Letta Code backend '${String(backend)}'. Valid values: local, remote, cloud.`);
17382
17480
  }
17383
17481
  this.backend = backend;
17384
- this.computer = getOptionsComputer(options);
17482
+ const registeredName = registeredComputerName(options);
17483
+ this.computer = getOptionsComputer(options) ?? (registeredName !== undefined ? { name: registeredName } : undefined);
17385
17484
  this.environment = this.computer;
17386
17485
  this.options = options;
17387
17486
  this.agents = createAgentsClient(() => this.getManagementTransport(), () => this.getAgentRepositoriesClient());
@@ -17477,12 +17576,12 @@ class LettaAgentClientBase {
17477
17576
  });
17478
17577
  }
17479
17578
  if (this.backend === "cloud") {
17480
- return new CloudEnvironmentSession(this.cloudOptions(), {
17579
+ return this.createCloudSession({
17481
17580
  kind: "session",
17482
17581
  agentId,
17483
17582
  newConversation: true,
17484
17583
  options
17485
- }, this.getCloudClient());
17584
+ });
17486
17585
  }
17487
17586
  return this.createLocalSession(agentId, options);
17488
17587
  }
@@ -17508,19 +17607,7 @@ class LettaAgentClientBase {
17508
17607
  return session2;
17509
17608
  }
17510
17609
  if (this.backend === "cloud") {
17511
- if (looksLikeConversationId(id)) {
17512
- return new CloudEnvironmentSession(this.cloudOptions(), {
17513
- kind: "session",
17514
- conversationId: id,
17515
- options
17516
- }, this.getCloudClient());
17517
- }
17518
- return new CloudEnvironmentSession(this.cloudOptions(), {
17519
- kind: "session",
17520
- agentId: id,
17521
- defaultConversation: true,
17522
- options
17523
- }, this.getCloudClient());
17610
+ return this.createCloudSession(looksLikeConversationId(id) ? { kind: "session", conversationId: id, options } : { kind: "session", agentId: id, defaultConversation: true, options });
17524
17611
  }
17525
17612
  const session = this.resumeLocalSession(id, options);
17526
17613
  if (inherited && session instanceof AppServerSession)
@@ -17586,11 +17673,11 @@ class LettaAgentClientBase {
17586
17673
  if (!conversation || typeof conversation !== "object" || typeof conversation.id !== "string") {
17587
17674
  throw new Error("Cloud query conversation response did not include a conversation id.");
17588
17675
  }
17589
- return new CloudEnvironmentSession(this.cloudOptions(), {
17676
+ return this.createCloudSession({
17590
17677
  kind: "conversation",
17591
17678
  conversationId: conversation.id,
17592
17679
  options: sessionOptions
17593
- }, this.getCloudClient());
17680
+ });
17594
17681
  }
17595
17682
  return this.createLocalQuerySession(options, sessionOptions);
17596
17683
  }
@@ -17655,6 +17742,29 @@ class LettaAgentClientBase {
17655
17742
  }
17656
17743
  throw new Error(`LettaAgentClient backend '${this.backend}' is not implemented yet. ${action} currently supports backend 'local' only.`);
17657
17744
  }
17745
+ createCloudSession(mode) {
17746
+ const name = registeredComputerName(this.options);
17747
+ const sessionComputer = mode.options.computer ?? mode.options.environment;
17748
+ return new CloudEnvironmentSession(this.cloudOptions(), mode, this.getCloudClient(), name !== undefined && sessionComputer === undefined ? () => this.connectRegisteredComputer(name) : undefined);
17749
+ }
17750
+ async connectRegisteredComputer(name) {
17751
+ await this.startRegisteredComputer();
17752
+ const deadline = Date.now() + REGISTERED_COMPUTER_READY_TIMEOUT_MS;
17753
+ while (true) {
17754
+ try {
17755
+ const resolved = await this.getComputersClient().resolve({ name });
17756
+ return { connectionId: resolved.connectionId };
17757
+ } catch (error) {
17758
+ if (!isRegisteredComputerPending(error) || Date.now() >= deadline) {
17759
+ throw error;
17760
+ }
17761
+ await new Promise((resolve) => setTimeout(resolve, REGISTERED_COMPUTER_POLL_INTERVAL_MS));
17762
+ }
17763
+ }
17764
+ }
17765
+ startRegisteredComputer() {
17766
+ return Promise.reject(this.localBackendUnavailableError());
17767
+ }
17658
17768
  createLocalAgent(_options) {
17659
17769
  throw this.localBackendUnavailableError();
17660
17770
  }
@@ -17735,8 +17845,8 @@ class LettaAgentClientBase {
17735
17845
  }
17736
17846
  registerTools(options) {
17737
17847
  this.assertOpen();
17738
- if (this.backend === "cloud") {
17739
- return Promise.reject(new Error('registerTools() requires backend: "local" or "remote". Cloud sessions register tools through the tools session option.'));
17848
+ if (this.backend === "cloud" && registeredComputerName(this.options) === undefined) {
17849
+ return Promise.reject(new Error('registerTools() requires backend: "local" or "remote", or backend: "cloud" with registerComputer. Other Cloud sessions register tools through the tools session option.'));
17740
17850
  }
17741
17851
  this.toolRegistry ??= new ToolRegistry(this.backend === "remote" ? this.remoteOptions() : this.localAppServerConnection());
17742
17852
  return this.toolRegistry.register(options);
@@ -17767,7 +17877,8 @@ class LettaAgentClientBase {
17767
17877
  if (this.backend !== "cloud") {
17768
17878
  throw new Error('Letta Cloud options requested for non-"cloud" backend.');
17769
17879
  }
17770
- return this.options;
17880
+ const options = this.options;
17881
+ return options.registerComputer !== undefined ? { ...options, computer: { name: options.registerComputer.name } } : options;
17771
17882
  }
17772
17883
  }
17773
17884
 
@@ -18249,7 +18360,8 @@ function buildLocalAppServerArgs(cliPath, options = {}) {
18249
18360
  ...options.backend !== undefined ? ["--backend", options.backend] : [],
18250
18361
  "server",
18251
18362
  "--listen",
18252
- options.listen ?? DEFAULT_LISTEN_URL
18363
+ options.listen ?? DEFAULT_LISTEN_URL,
18364
+ ...options.computerName !== undefined ? ["--computer-name", options.computerName] : []
18253
18365
  ];
18254
18366
  }
18255
18367
  function buildLocalAppServerProcess(cliPath, options = {}, confineMemory = createMemoryConfinementLauncher) {
@@ -18516,6 +18628,9 @@ class LettaAgentClient extends LettaAgentClientBase {
18516
18628
  sharedLocalServer() {
18517
18629
  if (this.localClosePromise)
18518
18630
  throw new Error("LettaAgentClient is closed");
18631
+ if (this.backend === "cloud") {
18632
+ return this.localServer ??= registeredComputerServer(this.options);
18633
+ }
18519
18634
  const options = this.options.appServer;
18520
18635
  return this.localServer ??= new SharedLocalAppServer({
18521
18636
  listen: options?.listen,
@@ -18532,6 +18647,9 @@ class LettaAgentClient extends LettaAgentClientBase {
18532
18647
  }
18533
18648
  return this.localClosePromise;
18534
18649
  }
18650
+ async startRegisteredComputer() {
18651
+ await this.sharedLocalServer().connect();
18652
+ }
18535
18653
  skillNodeSupport() {
18536
18654
  return { loadSkillDirectory, pushSkillSupportFiles };
18537
18655
  }
@@ -18539,10 +18657,13 @@ class LettaAgentClient extends LettaAgentClientBase {
18539
18657
  return new AppServerManagementTransport(this.localAppServerConnection());
18540
18658
  }
18541
18659
  localAppServerConnection() {
18542
- const localOptions = this.options.appServer;
18660
+ const localOptions = this.backend === "cloud" ? {
18661
+ WebSocket: this.options.WebSocket,
18662
+ requestTimeoutMs: this.options.requestTimeoutMs
18663
+ } : this.options.appServer;
18543
18664
  const sharedServer = this.sharedLocalServer();
18544
18665
  return {
18545
- ...localOptions?.url !== undefined ? { url: localOptions.url } : {
18666
+ ...localOptions !== undefined && "url" in localOptions && localOptions.url !== undefined ? { url: localOptions.url } : {
18546
18667
  connect: () => sharedServer.connect()
18547
18668
  },
18548
18669
  ...localOptions?.WebSocket !== undefined ? { WebSocket: localOptions.WebSocket } : {},
@@ -18610,6 +18731,21 @@ class LettaAgentClient extends LettaAgentClientBase {
18610
18731
  }, this.sharedLocalServer());
18611
18732
  }
18612
18733
  }
18734
+ function registeredComputerServer(options) {
18735
+ const name = options.registerComputer?.name;
18736
+ if (name === undefined) {
18737
+ throw new Error('A local app-server is only available with backend: "local" or registerComputer.');
18738
+ }
18739
+ const apiKey = getCloudApiKey(options);
18740
+ return new SharedLocalAppServer({
18741
+ backend: "api",
18742
+ computerName: name,
18743
+ env: {
18744
+ ...apiKey !== undefined ? { LETTA_API_KEY: apiKey } : {},
18745
+ ...options.apiBaseUrl !== undefined ? { LETTA_BASE_URL: options.apiBaseUrl } : {}
18746
+ }
18747
+ });
18748
+ }
18613
18749
  function looksLikeConversationId2(id) {
18614
18750
  return id.startsWith("conv-") || id.startsWith("local-conv-");
18615
18751
  }
@@ -35399,7 +35535,7 @@ class StreamableHTTPClientTransport {
35399
35535
  }
35400
35536
  var DEFAULT_CLIENT_INFO = {
35401
35537
  name: "letta-code",
35402
- version: "0.34.49"
35538
+ version: "0.34.50"
35403
35539
  };
35404
35540
  async function connectMcpServer(config2, options = {}) {
35405
35541
  let client = new Client(options.clientInfo ?? DEFAULT_CLIENT_INFO);
@@ -36427,4 +36563,4 @@ export {
36427
36563
  CloudManagedSandboxExpiredError
36428
36564
  };
36429
36565
 
36430
- //# debugId=4CD40C08118B97D164756E2164756E21
36566
+ //# debugId=FF481D2B70CB9B5D64756E2164756E21