@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-base.d.ts
CHANGED
|
@@ -15,7 +15,8 @@ import type { CreateAgentOptions, LettaCodeBackend, LettaCodeClientOptions, Lett
|
|
|
15
15
|
* protocol.
|
|
16
16
|
* `remote` connects to a user-managed Letta Code app-server websocket endpoint.
|
|
17
17
|
* `cloud` uses agents hosted on Letta Cloud, with an explicit remote
|
|
18
|
-
* environment or SDK-managed sandbox.
|
|
18
|
+
* environment or SDK-managed sandbox. With `registerComputer`, the SDK also
|
|
19
|
+
* starts a local app-server that registers this machine as that computer.
|
|
19
20
|
*/
|
|
20
21
|
export declare class LettaAgentClientBase implements AsyncDisposable {
|
|
21
22
|
readonly backend: LettaCodeBackend;
|
|
@@ -72,6 +73,14 @@ export declare class LettaAgentClientBase implements AsyncDisposable {
|
|
|
72
73
|
query(params: QueryParams): Query;
|
|
73
74
|
private createQuerySession;
|
|
74
75
|
private assertSessionBackend;
|
|
76
|
+
/**
|
|
77
|
+
* Build a Cloud session. Sessions that run on the computer this client
|
|
78
|
+
* registers start the local app-server first and wait for it to come online.
|
|
79
|
+
*/
|
|
80
|
+
private createCloudSession;
|
|
81
|
+
private connectRegisteredComputer;
|
|
82
|
+
/** Start the app-server that registers this machine; overridden by the Node client. */
|
|
83
|
+
protected startRegisteredComputer(): Promise<void>;
|
|
75
84
|
protected createLocalAgent(_options: CreateAgentOptions): Promise<string>;
|
|
76
85
|
/**
|
|
77
86
|
* Node-only skill seeding support (directory loading, memory-repo git
|
|
@@ -99,7 +108,10 @@ export declare class LettaAgentClientBase implements AsyncDisposable {
|
|
|
99
108
|
* prompts, with or without an open session.
|
|
100
109
|
*/
|
|
101
110
|
registerTools(options: RegisterToolsOptions): Promise<ToolRegistration>;
|
|
102
|
-
/**
|
|
111
|
+
/**
|
|
112
|
+
* How the local backend, or a Cloud client's registered computer, reaches
|
|
113
|
+
* its App Server; overridden by the Node client.
|
|
114
|
+
*/
|
|
103
115
|
protected localAppServerConnection(): AppServerSessionOptions;
|
|
104
116
|
/**
|
|
105
117
|
* Release resources owned directly by this client, including its pooled
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-base.d.ts","sourceRoot":"","sources":["../src/client-base.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG9E,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AAOxB,OAAO,EAIL,KAAK,mBAAmB,EACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAEV,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACb,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EACV,KAAK,EACL,YAAY,EACZ,WAAW,EACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EACV,kBAAkB,EAElB,gBAAgB,EAChB,sBAAsB,EACtB,6BAA6B,EAC7B,oBAAoB,EAIpB,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACZ,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"client-base.d.ts","sourceRoot":"","sources":["../src/client-base.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG9E,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AAOxB,OAAO,EAIL,KAAK,mBAAmB,EACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAEV,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACb,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EACV,KAAK,EACL,YAAY,EACZ,WAAW,EACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EACV,kBAAkB,EAElB,gBAAgB,EAChB,sBAAsB,EACtB,6BAA6B,EAC7B,oBAAoB,EAIpB,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACZ,MAAM,YAAY,CAAC;AAuGpB;;;;;;;;;;GAUG;AACH,qBAAa,oBAAqB,YAAW,eAAe;IAC1D,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAChD,kCAAkC;IAClC,QAAQ,CAAC,WAAW,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,mBAAmB,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAC;IACnD,OAAO,CAAC,kBAAkB,CAAmC;IAC7D,OAAO,CAAC,eAAe,CAAoC;IAC3D,OAAO,CAAC,uBAAuB,CAAwC;IACvE,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,mBAAmB,CAAoC;IAC/D,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAA8B;gBAEtC,OAAO,GAAE,sBAA2B;IAmFhD;;;;;OAKG;IACH,IAAI,YAAY,IAAI,kBAAkB,CAGrC;IAED,+EAA+E;IAC/E,IAAI,SAAS,IAAI,eAAe,CAG/B;IAEK,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC;IA4CpE;;;;OAIG;IACH,aAAa,CACX,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,6BAAkC,GAC1C,gBAAgB;IA4BnB;;;;;;;;;;OAUG;IACH,aAAa,CACX,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,6BAAkC,GAC1C,gBAAgB;IAqCnB;;;OAGG;IACG,MAAM,CACV,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,gBAAgB,CAAC;IAW5B,gEAAgE;IAChE,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK;YAMnB,kBAAkB;IA4FhC,OAAO,CAAC,oBAAoB;IA6F5B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;YAaZ,yBAAyB;IAoBvC,uFAAuF;IACvF,SAAS,CAAC,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIlD,SAAS,CAAC,gBAAgB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAIzE;;;;OAIG;IACH,SAAS,CAAC,gBAAgB,IAAI,gBAAgB,GAAG,SAAS;IAI1D,SAAS,CAAC,kBAAkB,CAC1B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,6BAA6B,GACtC,gBAAgB;IAInB,SAAS,CAAC,uBAAuB,CAC/B,aAAa,EAAE,YAAY,EAC3B,eAAe,EAAE,6BAA6B,GAC7C,gBAAgB;IAInB,SAAS,CAAC,kBAAkB,CAC1B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,6BAA6B,GACtC,gBAAgB;IAInB,SAAS,CAAC,4BAA4B,IAAI,KAAK;IAM/C,SAAS,CAAC,8BAA8B,IAAI,mBAAmB;IAI/D,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,uBAAuB;IAI/B,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,qBAAqB;IAY7B,OAAO,CAAC,0BAA0B;IAYlC,OAAO,CAAC,2BAA2B;IAQnC,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,sBAAsB;IAiB9B;;;;;OAKG;IACH,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAavE;;;OAGG;IACH,SAAS,CAAC,wBAAwB,IAAI,uBAAuB;IAI7D;;;;OAIG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAYtB,wCAAwC;IAClC,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5C,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,YAAY;CAUrB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-entry.d.ts","sourceRoot":"","sources":["../src/client-entry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EACV,2BAA2B,EAC3B,4BAA4B,EAC7B,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,+BAA+B,GACvC,4BAA4B,GAC5B,2BAA2B,CAAC;AAEhC;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,oBAAoB;gBAC5C,OAAO,EAAE,+BAA+B;
|
|
1
|
+
{"version":3,"file":"client-entry.d.ts","sourceRoot":"","sources":["../src/client-entry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EACV,2BAA2B,EAC3B,4BAA4B,EAC7B,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,+BAA+B,GACvC,4BAA4B,GAC5B,2BAA2B,CAAC;AAEhC;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,oBAAoB;gBAC5C,OAAO,EAAE,+BAA+B;CAWrD;AAED,OAAO,EAAE,+BAA+B,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,8BAA8B,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,YAAY,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACrF,mBAAmB,oBAAoB,CAAC;AACxC,YAAY,EACV,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,mBAAmB,uBAAuB,CAAC;AAC3C,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAC1E,YAAY,EACV,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,aAAa,EACb,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,qCAAqC,EAAE,MAAM,gBAAgB,CAAC;AACvE,mBAAmB,YAAY,CAAC;AAChC,mBAAmB,kBAAkB,CAAC"}
|
package/dist/client-entry.js
CHANGED
|
@@ -9481,18 +9481,39 @@ function onceSocketEvent(socket, type, listener) {
|
|
|
9481
9481
|
});
|
|
9482
9482
|
return detach;
|
|
9483
9483
|
}
|
|
9484
|
-
function waitForSocketOpen(socket) {
|
|
9484
|
+
function waitForSocketOpen(socket, timeoutMs) {
|
|
9485
9485
|
if (socket.readyState === WEBSOCKET_OPEN_STATE) {
|
|
9486
9486
|
return Promise.resolve();
|
|
9487
9487
|
}
|
|
9488
|
-
return new Promise((
|
|
9488
|
+
return new Promise((resolvePromise, rejectPromise) => {
|
|
9489
|
+
let settled = false;
|
|
9490
|
+
const resolve = () => {
|
|
9491
|
+
if (settled)
|
|
9492
|
+
return;
|
|
9493
|
+
settled = true;
|
|
9494
|
+
resolvePromise();
|
|
9495
|
+
};
|
|
9496
|
+
const reject = (error) => {
|
|
9497
|
+
if (settled)
|
|
9498
|
+
return;
|
|
9499
|
+
settled = true;
|
|
9500
|
+
rejectPromise(error);
|
|
9501
|
+
};
|
|
9489
9502
|
let detachOpen = () => {};
|
|
9490
9503
|
let detachError = () => {};
|
|
9504
|
+
let detachClose = () => {};
|
|
9491
9505
|
let detachResponse = () => {};
|
|
9492
9506
|
let detachBody = () => {};
|
|
9507
|
+
let upgradeRejected = false;
|
|
9508
|
+
const timer = timeoutMs > 0 ? setTimeout(() => {
|
|
9509
|
+
cleanup();
|
|
9510
|
+
reject(new Error(`App-server WebSocket failed to open: timed out after ${timeoutMs}ms`));
|
|
9511
|
+
}, timeoutMs) : undefined;
|
|
9493
9512
|
const cleanup = () => {
|
|
9513
|
+
clearTimeout(timer);
|
|
9494
9514
|
detachOpen();
|
|
9495
9515
|
detachError();
|
|
9516
|
+
detachClose();
|
|
9496
9517
|
detachResponse();
|
|
9497
9518
|
detachBody();
|
|
9498
9519
|
};
|
|
@@ -9504,6 +9525,7 @@ function waitForSocketOpen(socket) {
|
|
|
9504
9525
|
const onResponse = (_request, response) => {
|
|
9505
9526
|
if (!response)
|
|
9506
9527
|
return;
|
|
9528
|
+
upgradeRejected = true;
|
|
9507
9529
|
const request = _request;
|
|
9508
9530
|
let body = Buffer.alloc(0);
|
|
9509
9531
|
let finished = false;
|
|
@@ -9545,6 +9567,12 @@ function waitForSocketOpen(socket) {
|
|
|
9545
9567
|
cleanup();
|
|
9546
9568
|
reject(new Error(`App-server WebSocket failed to open: ${String(event)}`));
|
|
9547
9569
|
});
|
|
9570
|
+
detachClose = onceSocketEvent(socket, "close", () => {
|
|
9571
|
+
if (upgradeRejected)
|
|
9572
|
+
return;
|
|
9573
|
+
cleanup();
|
|
9574
|
+
reject(new Error("App-server WebSocket failed to open: closed before opening"));
|
|
9575
|
+
});
|
|
9548
9576
|
});
|
|
9549
9577
|
}
|
|
9550
9578
|
function rawEventData(event) {
|
|
@@ -9612,7 +9640,7 @@ class AppServerClient {
|
|
|
9612
9640
|
});
|
|
9613
9641
|
}
|
|
9614
9642
|
async connect() {
|
|
9615
|
-
await waitForSocketOpen(this.socket);
|
|
9643
|
+
await waitForSocketOpen(this.socket, this.requestTimeoutMs);
|
|
9616
9644
|
return this;
|
|
9617
9645
|
}
|
|
9618
9646
|
close() {
|
|
@@ -13236,6 +13264,7 @@ function externalToolGroups(tools) {
|
|
|
13236
13264
|
return;
|
|
13237
13265
|
return [
|
|
13238
13266
|
{
|
|
13267
|
+
capabilities: { external_tool_call_cancel: true },
|
|
13239
13268
|
tools: tools.map((tool) => ({
|
|
13240
13269
|
name: tool.name,
|
|
13241
13270
|
label: tool.label,
|
|
@@ -13248,14 +13277,14 @@ function externalToolGroups(tools) {
|
|
|
13248
13277
|
var MAX_REMEMBERED_EXTERNAL_TOOL_CALLS = 200;
|
|
13249
13278
|
function createExternalToolCallHandler(externalTools, fallbackRuntime) {
|
|
13250
13279
|
const calls = new Map;
|
|
13251
|
-
const execute = async (request) => {
|
|
13280
|
+
const execute = async (request, signal) => {
|
|
13252
13281
|
const tool = externalTools.get(request.tool_name);
|
|
13253
13282
|
if (!tool) {
|
|
13254
13283
|
throw new Error(`Unknown external tool: ${request.tool_name}`);
|
|
13255
13284
|
}
|
|
13256
13285
|
const runtime = request.runtime ?? fallbackRuntime?.() ?? null;
|
|
13257
13286
|
const context = runtime ? { toolCallId: request.tool_call_id, agentId: runtime.agent_id, conversationId: runtime.conversation_id } : undefined;
|
|
13258
|
-
const result = await tool.execute(request.tool_call_id, request.input,
|
|
13287
|
+
const result = await tool.execute(request.tool_call_id, request.input, signal, undefined, context);
|
|
13259
13288
|
return {
|
|
13260
13289
|
content: result.content.map((part) => ({
|
|
13261
13290
|
type: part.type,
|
|
@@ -13266,15 +13295,15 @@ function createExternalToolCallHandler(externalTools, fallbackRuntime) {
|
|
|
13266
13295
|
...result.isError === true ? { is_error: true } : {}
|
|
13267
13296
|
};
|
|
13268
13297
|
};
|
|
13269
|
-
return (request) => {
|
|
13298
|
+
return (request, signal) => {
|
|
13270
13299
|
const requestId = request.request_id;
|
|
13271
13300
|
if (typeof requestId !== "string" || requestId.length === 0) {
|
|
13272
|
-
return execute(request);
|
|
13301
|
+
return execute(request, signal);
|
|
13273
13302
|
}
|
|
13274
13303
|
const existing = calls.get(requestId);
|
|
13275
13304
|
if (existing)
|
|
13276
13305
|
return existing;
|
|
13277
|
-
const call = execute(request);
|
|
13306
|
+
const call = execute(request, signal);
|
|
13278
13307
|
calls.set(requestId, call);
|
|
13279
13308
|
while (calls.size > MAX_REMEMBERED_EXTERNAL_TOOL_CALLS) {
|
|
13280
13309
|
const oldest = calls.keys().next().value;
|
|
@@ -13285,6 +13314,49 @@ function createExternalToolCallHandler(externalTools, fallbackRuntime) {
|
|
|
13285
13314
|
return call;
|
|
13286
13315
|
};
|
|
13287
13316
|
}
|
|
13317
|
+
function registerExternalToolCallHandler(client, handler) {
|
|
13318
|
+
const pending = new Map;
|
|
13319
|
+
const completed = new Set;
|
|
13320
|
+
const remove = client.onMessage((raw, channel) => {
|
|
13321
|
+
if (channel !== "control")
|
|
13322
|
+
return;
|
|
13323
|
+
const message = raw;
|
|
13324
|
+
const requestId = message.request_id;
|
|
13325
|
+
if (typeof requestId !== "string")
|
|
13326
|
+
return;
|
|
13327
|
+
if (message.type === "external_tool_call_cancel") {
|
|
13328
|
+
const call = pending.get(requestId);
|
|
13329
|
+
if (!call)
|
|
13330
|
+
return;
|
|
13331
|
+
call.finish({ error: "cancelled" });
|
|
13332
|
+
call.controller.abort(message.reason);
|
|
13333
|
+
return;
|
|
13334
|
+
}
|
|
13335
|
+
if (message.type !== "external_tool_call_request" || pending.has(requestId) || completed.has(requestId))
|
|
13336
|
+
return;
|
|
13337
|
+
const controller = new AbortController;
|
|
13338
|
+
const finish = (response) => {
|
|
13339
|
+
if (!pending.delete(requestId))
|
|
13340
|
+
return;
|
|
13341
|
+
completed.add(requestId);
|
|
13342
|
+
if (completed.size > MAX_REMEMBERED_EXTERNAL_TOOL_CALLS)
|
|
13343
|
+
completed.delete(completed.values().next().value);
|
|
13344
|
+
client.send({ type: "external_tool_call_response", request_id: requestId, ...response });
|
|
13345
|
+
};
|
|
13346
|
+
pending.set(requestId, { controller, finish });
|
|
13347
|
+
try {
|
|
13348
|
+
Promise.resolve(handler(raw, controller.signal)).then((result) => finish({ result }), (error) => finish({ error: error instanceof Error ? error.message : String(error) }));
|
|
13349
|
+
} catch (error) {
|
|
13350
|
+
finish({ error: error instanceof Error ? error.message : String(error) });
|
|
13351
|
+
}
|
|
13352
|
+
});
|
|
13353
|
+
return () => {
|
|
13354
|
+
remove();
|
|
13355
|
+
for (const call of pending.values())
|
|
13356
|
+
call.controller.abort();
|
|
13357
|
+
pending.clear();
|
|
13358
|
+
};
|
|
13359
|
+
}
|
|
13288
13360
|
|
|
13289
13361
|
// src/runtime-tool-policy.ts
|
|
13290
13362
|
var RUNTIME_TOOL_POLICY_CAPABILITY = "runtime_tool_policy";
|
|
@@ -15109,7 +15181,7 @@ class AppServerSession extends RemoteClientSessionCore {
|
|
|
15109
15181
|
getOptions: () => this.currentOptions()
|
|
15110
15182
|
});
|
|
15111
15183
|
if (this.externalTools.size > 0 || this.inheritedTools) {
|
|
15112
|
-
this.removeExternalToolHandler = client
|
|
15184
|
+
this.removeExternalToolHandler = registerExternalToolCallHandler(client, createExternalToolCallHandler(this.externalTools, () => this.runtime));
|
|
15113
15185
|
}
|
|
15114
15186
|
try {
|
|
15115
15187
|
await client.connect();
|
|
@@ -15949,6 +16021,19 @@ function validateCloudClientOptions(options) {
|
|
|
15949
16021
|
const field = options.computer !== undefined ? "computer" : "environment";
|
|
15950
16022
|
throw new Error(`Letta Cloud sessions cannot specify both ${field} and sandbox options.`);
|
|
15951
16023
|
}
|
|
16024
|
+
if (options.registerComputer !== undefined) {
|
|
16025
|
+
const name = options.registerComputer?.name;
|
|
16026
|
+
if (typeof name !== "string" || !name.trim()) {
|
|
16027
|
+
throw new Error("Invalid registerComputer.name. Expected a non-empty string.");
|
|
16028
|
+
}
|
|
16029
|
+
if (options.computer !== undefined || options.environment !== undefined) {
|
|
16030
|
+
const field = options.computer !== undefined ? "computer" : "environment";
|
|
16031
|
+
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.`);
|
|
16032
|
+
}
|
|
16033
|
+
if (options.sandbox !== undefined) {
|
|
16034
|
+
throw new Error("Letta Cloud clients cannot specify both registerComputer and sandbox options.");
|
|
16035
|
+
}
|
|
16036
|
+
}
|
|
15952
16037
|
if (options.webSocketAuth !== undefined && options.webSocketAuth !== "header" && options.webSocketAuth !== "query") {
|
|
15953
16038
|
throw new Error("Invalid webSocketAuth. Valid values: header, query.");
|
|
15954
16039
|
}
|
|
@@ -16042,6 +16127,7 @@ function assertCloudSessionOptionsSupported(action, options) {
|
|
|
16042
16127
|
class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
16043
16128
|
cloudOptions;
|
|
16044
16129
|
apiClient;
|
|
16130
|
+
connectRegisteredComputer;
|
|
16045
16131
|
sandbox;
|
|
16046
16132
|
connectionId = null;
|
|
16047
16133
|
removeExternalToolHandler = null;
|
|
@@ -16057,13 +16143,14 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
16057
16143
|
repositoryIdsRequiringCleanupRecompile = new Set;
|
|
16058
16144
|
repositoryManagement;
|
|
16059
16145
|
cloudMode;
|
|
16060
|
-
constructor(cloudOptions, mode, apiClient = createCloudClient(cloudOptions)) {
|
|
16146
|
+
constructor(cloudOptions, mode, apiClient = createCloudClient(cloudOptions), connectRegisteredComputer) {
|
|
16061
16147
|
super(mode, {
|
|
16062
16148
|
label: "cloud",
|
|
16063
16149
|
requestTimeoutMs: cloudOptions.requestTimeoutMs ?? DEFAULT_TURN_TIMEOUT_MS
|
|
16064
16150
|
});
|
|
16065
16151
|
this.cloudOptions = cloudOptions;
|
|
16066
16152
|
this.apiClient = apiClient;
|
|
16153
|
+
this.connectRegisteredComputer = connectRegisteredComputer;
|
|
16067
16154
|
this.cloudMode = mode;
|
|
16068
16155
|
this.repositoryManagement = new CloudManagementTransport(apiClient);
|
|
16069
16156
|
this.sandbox = this.effectiveEnvironment() === undefined ? {
|
|
@@ -16199,7 +16286,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
16199
16286
|
getOptions: () => this.currentOptions()
|
|
16200
16287
|
});
|
|
16201
16288
|
if (this.externalTools.size > 0) {
|
|
16202
|
-
this.removeExternalToolHandler = client
|
|
16289
|
+
this.removeExternalToolHandler = registerExternalToolCallHandler(client, createExternalToolCallHandler(this.externalTools, () => this.runtime));
|
|
16203
16290
|
}
|
|
16204
16291
|
}
|
|
16205
16292
|
cleanupTransportHandlers() {
|
|
@@ -16466,6 +16553,8 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
16466
16553
|
return this.createManagedSandboxConnection(runtime);
|
|
16467
16554
|
}
|
|
16468
16555
|
async resolveExplicitConnection(environment) {
|
|
16556
|
+
if (this.connectRegisteredComputer)
|
|
16557
|
+
return this.connectRegisteredComputer();
|
|
16469
16558
|
const target = environmentToRemoteTarget(environment);
|
|
16470
16559
|
const resolved = await this.remoteEnvironmentClient().resolveEnvironment(target);
|
|
16471
16560
|
return { connectionId: resolved.connectionId };
|
|
@@ -16955,12 +17044,12 @@ class ToolRegistry {
|
|
|
16955
17044
|
...this.options.WebSocket ? { WebSocket: this.options.WebSocket } : {},
|
|
16956
17045
|
...this.options.requestTimeoutMs !== undefined ? { requestTimeoutMs: this.options.requestTimeoutMs } : {}
|
|
16957
17046
|
}));
|
|
16958
|
-
client
|
|
17047
|
+
registerExternalToolCallHandler(client, async (request, signal) => {
|
|
16959
17048
|
const runtime = request.runtime;
|
|
16960
17049
|
const entry = runtime && [...this.entries].find((candidate) => candidate.runtimes.some((r) => runtimeKey(r) === runtimeKey(runtime)));
|
|
16961
17050
|
if (!entry)
|
|
16962
17051
|
throw new Error(`No tools registered for conversation ${runtime?.conversation_id}`);
|
|
16963
|
-
return entry.call(request);
|
|
17052
|
+
return entry.call(request, signal);
|
|
16964
17053
|
});
|
|
16965
17054
|
try {
|
|
16966
17055
|
await client.connect();
|
|
@@ -17265,6 +17354,15 @@ function stripCloudExecutionOptions(options) {
|
|
|
17265
17354
|
delete sessionOptions.filesystemConfinement;
|
|
17266
17355
|
return sessionOptions;
|
|
17267
17356
|
}
|
|
17357
|
+
var REGISTERED_COMPUTER_READY_TIMEOUT_MS = 30000;
|
|
17358
|
+
var REGISTERED_COMPUTER_POLL_INTERVAL_MS = 500;
|
|
17359
|
+
function registeredComputerName(options) {
|
|
17360
|
+
return options.backend === "cloud" ? options.registerComputer?.name : undefined;
|
|
17361
|
+
}
|
|
17362
|
+
function isRegisteredComputerPending(error) {
|
|
17363
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
17364
|
+
return message.startsWith("Computer not found") || message.startsWith("Computer is offline");
|
|
17365
|
+
}
|
|
17268
17366
|
function hasRepositoryResources(options) {
|
|
17269
17367
|
return options.resources !== undefined && options.resources.length > 0;
|
|
17270
17368
|
}
|
|
@@ -17323,7 +17421,8 @@ class LettaAgentClientBase {
|
|
|
17323
17421
|
throw new Error(`Invalid Letta Code backend '${String(backend)}'. Valid values: local, remote, cloud.`);
|
|
17324
17422
|
}
|
|
17325
17423
|
this.backend = backend;
|
|
17326
|
-
|
|
17424
|
+
const registeredName = registeredComputerName(options);
|
|
17425
|
+
this.computer = getOptionsComputer(options) ?? (registeredName !== undefined ? { name: registeredName } : undefined);
|
|
17327
17426
|
this.environment = this.computer;
|
|
17328
17427
|
this.options = options;
|
|
17329
17428
|
this.agents = createAgentsClient(() => this.getManagementTransport(), () => this.getAgentRepositoriesClient());
|
|
@@ -17419,12 +17518,12 @@ class LettaAgentClientBase {
|
|
|
17419
17518
|
});
|
|
17420
17519
|
}
|
|
17421
17520
|
if (this.backend === "cloud") {
|
|
17422
|
-
return
|
|
17521
|
+
return this.createCloudSession({
|
|
17423
17522
|
kind: "session",
|
|
17424
17523
|
agentId,
|
|
17425
17524
|
newConversation: true,
|
|
17426
17525
|
options
|
|
17427
|
-
}
|
|
17526
|
+
});
|
|
17428
17527
|
}
|
|
17429
17528
|
return this.createLocalSession(agentId, options);
|
|
17430
17529
|
}
|
|
@@ -17450,19 +17549,7 @@ class LettaAgentClientBase {
|
|
|
17450
17549
|
return session2;
|
|
17451
17550
|
}
|
|
17452
17551
|
if (this.backend === "cloud") {
|
|
17453
|
-
|
|
17454
|
-
return new CloudEnvironmentSession(this.cloudOptions(), {
|
|
17455
|
-
kind: "session",
|
|
17456
|
-
conversationId: id,
|
|
17457
|
-
options
|
|
17458
|
-
}, this.getCloudClient());
|
|
17459
|
-
}
|
|
17460
|
-
return new CloudEnvironmentSession(this.cloudOptions(), {
|
|
17461
|
-
kind: "session",
|
|
17462
|
-
agentId: id,
|
|
17463
|
-
defaultConversation: true,
|
|
17464
|
-
options
|
|
17465
|
-
}, this.getCloudClient());
|
|
17552
|
+
return this.createCloudSession(looksLikeConversationId(id) ? { kind: "session", conversationId: id, options } : { kind: "session", agentId: id, defaultConversation: true, options });
|
|
17466
17553
|
}
|
|
17467
17554
|
const session = this.resumeLocalSession(id, options);
|
|
17468
17555
|
if (inherited && session instanceof AppServerSession)
|
|
@@ -17528,11 +17615,11 @@ class LettaAgentClientBase {
|
|
|
17528
17615
|
if (!conversation || typeof conversation !== "object" || typeof conversation.id !== "string") {
|
|
17529
17616
|
throw new Error("Cloud query conversation response did not include a conversation id.");
|
|
17530
17617
|
}
|
|
17531
|
-
return
|
|
17618
|
+
return this.createCloudSession({
|
|
17532
17619
|
kind: "conversation",
|
|
17533
17620
|
conversationId: conversation.id,
|
|
17534
17621
|
options: sessionOptions
|
|
17535
|
-
}
|
|
17622
|
+
});
|
|
17536
17623
|
}
|
|
17537
17624
|
return this.createLocalQuerySession(options, sessionOptions);
|
|
17538
17625
|
}
|
|
@@ -17597,6 +17684,29 @@ class LettaAgentClientBase {
|
|
|
17597
17684
|
}
|
|
17598
17685
|
throw new Error(`LettaAgentClient backend '${this.backend}' is not implemented yet. ${action} currently supports backend 'local' only.`);
|
|
17599
17686
|
}
|
|
17687
|
+
createCloudSession(mode) {
|
|
17688
|
+
const name = registeredComputerName(this.options);
|
|
17689
|
+
const sessionComputer = mode.options.computer ?? mode.options.environment;
|
|
17690
|
+
return new CloudEnvironmentSession(this.cloudOptions(), mode, this.getCloudClient(), name !== undefined && sessionComputer === undefined ? () => this.connectRegisteredComputer(name) : undefined);
|
|
17691
|
+
}
|
|
17692
|
+
async connectRegisteredComputer(name) {
|
|
17693
|
+
await this.startRegisteredComputer();
|
|
17694
|
+
const deadline = Date.now() + REGISTERED_COMPUTER_READY_TIMEOUT_MS;
|
|
17695
|
+
while (true) {
|
|
17696
|
+
try {
|
|
17697
|
+
const resolved = await this.getComputersClient().resolve({ name });
|
|
17698
|
+
return { connectionId: resolved.connectionId };
|
|
17699
|
+
} catch (error) {
|
|
17700
|
+
if (!isRegisteredComputerPending(error) || Date.now() >= deadline) {
|
|
17701
|
+
throw error;
|
|
17702
|
+
}
|
|
17703
|
+
await new Promise((resolve) => setTimeout(resolve, REGISTERED_COMPUTER_POLL_INTERVAL_MS));
|
|
17704
|
+
}
|
|
17705
|
+
}
|
|
17706
|
+
}
|
|
17707
|
+
startRegisteredComputer() {
|
|
17708
|
+
return Promise.reject(this.localBackendUnavailableError());
|
|
17709
|
+
}
|
|
17600
17710
|
createLocalAgent(_options) {
|
|
17601
17711
|
throw this.localBackendUnavailableError();
|
|
17602
17712
|
}
|
|
@@ -17677,8 +17787,8 @@ class LettaAgentClientBase {
|
|
|
17677
17787
|
}
|
|
17678
17788
|
registerTools(options) {
|
|
17679
17789
|
this.assertOpen();
|
|
17680
|
-
if (this.backend === "cloud") {
|
|
17681
|
-
return Promise.reject(new Error('registerTools() requires backend: "local" or "remote". Cloud sessions register tools through the tools session option.'));
|
|
17790
|
+
if (this.backend === "cloud" && registeredComputerName(this.options) === undefined) {
|
|
17791
|
+
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.'));
|
|
17682
17792
|
}
|
|
17683
17793
|
this.toolRegistry ??= new ToolRegistry(this.backend === "remote" ? this.remoteOptions() : this.localAppServerConnection());
|
|
17684
17794
|
return this.toolRegistry.register(options);
|
|
@@ -17709,7 +17819,8 @@ class LettaAgentClientBase {
|
|
|
17709
17819
|
if (this.backend !== "cloud") {
|
|
17710
17820
|
throw new Error('Letta Cloud options requested for non-"cloud" backend.');
|
|
17711
17821
|
}
|
|
17712
|
-
|
|
17822
|
+
const options = this.options;
|
|
17823
|
+
return options.registerComputer !== undefined ? { ...options, computer: { name: options.registerComputer.name } } : options;
|
|
17713
17824
|
}
|
|
17714
17825
|
}
|
|
17715
17826
|
// src/stream-events.ts
|
|
@@ -18224,6 +18335,9 @@ class LettaAgentClient extends LettaAgentClientBase {
|
|
|
18224
18335
|
if (this.backend === "local") {
|
|
18225
18336
|
throw this.localBackendUnavailableError();
|
|
18226
18337
|
}
|
|
18338
|
+
if (options.backend === "cloud" && options.registerComputer !== undefined) {
|
|
18339
|
+
throw new Error('registerComputer starts a local Letta Code app-server. Import from "@letta-ai/letta-agent-sdk" in Node.js to use it.');
|
|
18340
|
+
}
|
|
18227
18341
|
}
|
|
18228
18342
|
}
|
|
18229
18343
|
export {
|
|
@@ -18236,4 +18350,4 @@ export {
|
|
|
18236
18350
|
CloudManagedSandboxExpiredError
|
|
18237
18351
|
};
|
|
18238
18352
|
|
|
18239
|
-
//# debugId=
|
|
18353
|
+
//# debugId=56DE4B3DCF03FA0964756E2164756E21
|