@letta-ai/letta-agent-sdk 0.8.79 → 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-entry.js +85 -13
- package/dist/client-entry.js.map +7 -7
- package/dist/external-tools.d.ts +6 -2
- package/dist/external-tools.d.ts.map +1 -1
- package/dist/index.js +86 -14
- package/dist/index.js.map +8 -8
- package/package.json +3 -3
- package/src/app-server-session.ts +2 -2
- package/src/cloud-session.ts +2 -2
- package/src/external-tools.ts +58 -7
- package/src/tool-registration.ts +3 -3
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();
|
|
@@ -16272,7 +16344,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
16272
16344
|
getOptions: () => this.currentOptions()
|
|
16273
16345
|
});
|
|
16274
16346
|
if (this.externalTools.size > 0) {
|
|
16275
|
-
this.removeExternalToolHandler = client
|
|
16347
|
+
this.removeExternalToolHandler = registerExternalToolCallHandler(client, createExternalToolCallHandler(this.externalTools, () => this.runtime));
|
|
16276
16348
|
}
|
|
16277
16349
|
}
|
|
16278
16350
|
cleanupTransportHandlers() {
|
|
@@ -17030,12 +17102,12 @@ class ToolRegistry {
|
|
|
17030
17102
|
...this.options.WebSocket ? { WebSocket: this.options.WebSocket } : {},
|
|
17031
17103
|
...this.options.requestTimeoutMs !== undefined ? { requestTimeoutMs: this.options.requestTimeoutMs } : {}
|
|
17032
17104
|
}));
|
|
17033
|
-
client
|
|
17105
|
+
registerExternalToolCallHandler(client, async (request, signal) => {
|
|
17034
17106
|
const runtime = request.runtime;
|
|
17035
17107
|
const entry = runtime && [...this.entries].find((candidate) => candidate.runtimes.some((r) => runtimeKey(r) === runtimeKey(runtime)));
|
|
17036
17108
|
if (!entry)
|
|
17037
17109
|
throw new Error(`No tools registered for conversation ${runtime?.conversation_id}`);
|
|
17038
|
-
return entry.call(request);
|
|
17110
|
+
return entry.call(request, signal);
|
|
17039
17111
|
});
|
|
17040
17112
|
try {
|
|
17041
17113
|
await client.connect();
|
|
@@ -35463,7 +35535,7 @@ class StreamableHTTPClientTransport {
|
|
|
35463
35535
|
}
|
|
35464
35536
|
var DEFAULT_CLIENT_INFO = {
|
|
35465
35537
|
name: "letta-code",
|
|
35466
|
-
version: "0.34.
|
|
35538
|
+
version: "0.34.50"
|
|
35467
35539
|
};
|
|
35468
35540
|
async function connectMcpServer(config2, options = {}) {
|
|
35469
35541
|
let client = new Client(options.clientInfo ?? DEFAULT_CLIENT_INFO);
|
|
@@ -36491,4 +36563,4 @@ export {
|
|
|
36491
36563
|
CloudManagedSandboxExpiredError
|
|
36492
36564
|
};
|
|
36493
36565
|
|
|
36494
|
-
//# debugId=
|
|
36566
|
+
//# debugId=FF481D2B70CB9B5D64756E2164756E21
|