@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-base.d.ts +14 -2
- package/dist/client-base.d.ts.map +1 -1
- package/dist/client-entry.d.ts.map +1 -1
- package/dist/client-entry.js +149 -35
- package/dist/client-entry.js.map +9 -9
- package/dist/client.d.ts +1 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/cloud-session.d.ts +8 -1
- package/dist/cloud-session.d.ts.map +1 -1
- package/dist/external-tools.d.ts +6 -2
- package/dist/external-tools.d.ts.map +1 -1
- package/dist/index.js +175 -39
- package/dist/index.js.map +11 -11
- package/dist/local-app-server.d.ts +3 -1
- package/dist/local-app-server.d.ts.map +1 -1
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/app-server-session.ts +2 -2
- package/src/client-base.ts +90 -45
- package/src/client-entry.ts +5 -0
- package/src/client.ts +45 -4
- package/src/cloud-session.ts +22 -2
- package/src/external-tools.ts +58 -7
- package/src/local-app-server.ts +9 -1
- package/src/tool-registration.ts +3 -3
- package/src/types.ts +7 -0
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(): {
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;
|
|
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"}
|
package/dist/cloud-session.d.ts
CHANGED
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"cloud-session.d.ts","sourceRoot":"","sources":["../src/cloud-session.ts"],"names":[],"mappings":"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"}
|
package/dist/external-tools.d.ts
CHANGED
|
@@ -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):
|
|
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;
|
|
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((
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
17579
|
+
return this.createCloudSession({
|
|
17481
17580
|
kind: "session",
|
|
17482
17581
|
agentId,
|
|
17483
17582
|
newConversation: true,
|
|
17484
17583
|
options
|
|
17485
|
-
}
|
|
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
|
-
|
|
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
|
|
17676
|
+
return this.createCloudSession({
|
|
17590
17677
|
kind: "conversation",
|
|
17591
17678
|
conversationId: conversation.id,
|
|
17592
17679
|
options: sessionOptions
|
|
17593
|
-
}
|
|
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
|
-
|
|
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.
|
|
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
|
|
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.
|
|
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=
|
|
36566
|
+
//# debugId=FF481D2B70CB9B5D64756E2164756E21
|