@letta-ai/letta-agent-sdk 0.5.0 → 0.5.2
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/AGENTS.md +35 -0
- package/README.md +22 -10
- package/dist/agent-repositories.d.ts +15 -0
- package/dist/agent-repositories.d.ts.map +1 -0
- package/dist/app-server-management.d.ts +10 -7
- package/dist/app-server-management.d.ts.map +1 -1
- package/dist/app-server-models.d.ts +4 -0
- package/dist/app-server-models.d.ts.map +1 -0
- package/dist/app-server-session.d.ts +3 -3
- package/dist/app-server-session.d.ts.map +1 -1
- package/dist/client-base.d.ts +5 -0
- package/dist/client-base.d.ts.map +1 -1
- package/dist/client-entry.js +3386 -639
- package/dist/client-entry.js.map +85 -13
- package/dist/cloud-client.d.ts +7 -0
- package/dist/cloud-client.d.ts.map +1 -0
- package/dist/cloud-management.d.ts +21 -18
- package/dist/cloud-management.d.ts.map +1 -1
- package/dist/cloud-session.d.ts +7 -5
- package/dist/cloud-session.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3400 -653
- package/dist/index.js.map +86 -14
- package/dist/management-types.d.ts +85 -64
- package/dist/management-types.d.ts.map +1 -1
- package/dist/management.d.ts +11 -9
- package/dist/management.d.ts.map +1 -1
- package/dist/remote-session-protocol.d.ts +1 -1
- package/dist/remote-session-protocol.d.ts.map +1 -1
- package/dist/remote.d.ts +4 -5
- package/dist/remote.d.ts.map +1 -1
- package/dist/repositories.d.ts +3 -2
- package/dist/repositories.d.ts.map +1 -1
- package/dist/types.d.ts +22 -34
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/agent-repositories.ts +159 -0
- package/src/app-server-management.ts +56 -116
- package/src/app-server-models.ts +20 -0
- package/src/app-server-session.ts +71 -146
- package/src/client-base.ts +72 -20
- package/src/cloud-client.ts +46 -0
- package/src/cloud-management.ts +128 -275
- package/src/cloud-session.ts +168 -267
- package/src/index.ts +6 -0
- package/src/management-types.ts +107 -64
- package/src/management.ts +46 -39
- package/src/remote-session-protocol.ts +6 -2
- package/src/remote.ts +18 -63
- package/src/repositories.ts +26 -99
- package/src/types.ts +22 -35
package/dist/client-entry.js
CHANGED
|
@@ -1,71 +1,2818 @@
|
|
|
1
1
|
// Generated bundle. Canonical modules are published under src/ and maintained in the letta-agent-sdk repository.
|
|
2
2
|
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
// node_modules/@letta-ai/letta-client/internal/tslib.mjs
|
|
4
|
+
function __classPrivateFieldSet(receiver, state, value, kind, f) {
|
|
5
|
+
if (kind === "m")
|
|
6
|
+
throw new TypeError("Private method is not writable");
|
|
7
|
+
if (kind === "a" && !f)
|
|
8
|
+
throw new TypeError("Private accessor was defined without a setter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
|
|
10
|
+
throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
11
|
+
return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
|
|
12
|
+
}
|
|
13
|
+
function __classPrivateFieldGet(receiver, state, kind, f) {
|
|
14
|
+
if (kind === "a" && !f)
|
|
15
|
+
throw new TypeError("Private accessor was defined without a getter");
|
|
16
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
|
|
17
|
+
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
18
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// node_modules/@letta-ai/letta-client/internal/utils/uuid.mjs
|
|
22
|
+
var uuid4 = function() {
|
|
23
|
+
const { crypto } = globalThis;
|
|
24
|
+
if (crypto?.randomUUID) {
|
|
25
|
+
uuid4 = crypto.randomUUID.bind(crypto);
|
|
26
|
+
return crypto.randomUUID();
|
|
27
|
+
}
|
|
28
|
+
const u8 = new Uint8Array(1);
|
|
29
|
+
const randomByte = crypto ? () => crypto.getRandomValues(u8)[0] : () => Math.random() * 255 & 255;
|
|
30
|
+
return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) => (+c ^ randomByte() & 15 >> +c / 4).toString(16));
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// node_modules/@letta-ai/letta-client/internal/errors.mjs
|
|
34
|
+
function isAbortError(err) {
|
|
35
|
+
return typeof err === "object" && err !== null && (("name" in err) && err.name === "AbortError" || ("message" in err) && String(err.message).includes("FetchRequestCanceledException"));
|
|
8
36
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
37
|
+
var castToError = (err) => {
|
|
38
|
+
if (err instanceof Error)
|
|
39
|
+
return err;
|
|
40
|
+
if (typeof err === "object" && err !== null) {
|
|
41
|
+
try {
|
|
42
|
+
if (Object.prototype.toString.call(err) === "[object Error]") {
|
|
43
|
+
const error = new Error(err.message, err.cause ? { cause: err.cause } : {});
|
|
44
|
+
if (err.stack)
|
|
45
|
+
error.stack = err.stack;
|
|
46
|
+
if (err.cause && !error.cause)
|
|
47
|
+
error.cause = err.cause;
|
|
48
|
+
if (err.name)
|
|
49
|
+
error.name = err.name;
|
|
50
|
+
return error;
|
|
51
|
+
}
|
|
52
|
+
} catch {}
|
|
53
|
+
try {
|
|
54
|
+
return new Error(JSON.stringify(err));
|
|
55
|
+
} catch {}
|
|
56
|
+
}
|
|
57
|
+
return new Error(err);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// node_modules/@letta-ai/letta-client/core/error.mjs
|
|
61
|
+
class LettaError extends Error {
|
|
15
62
|
}
|
|
16
|
-
|
|
17
|
-
|
|
63
|
+
|
|
64
|
+
class APIError extends LettaError {
|
|
65
|
+
constructor(status, error, message, headers) {
|
|
66
|
+
super(`${APIError.makeMessage(status, error, message)}`);
|
|
67
|
+
this.status = status;
|
|
68
|
+
this.headers = headers;
|
|
69
|
+
this.error = error;
|
|
70
|
+
}
|
|
71
|
+
static makeMessage(status, error, message) {
|
|
72
|
+
const msg = error?.message ? typeof error.message === "string" ? error.message : JSON.stringify(error.message) : error ? JSON.stringify(error) : message;
|
|
73
|
+
if (status && msg) {
|
|
74
|
+
return `${status} ${msg}`;
|
|
75
|
+
}
|
|
76
|
+
if (status) {
|
|
77
|
+
return `${status} status code (no body)`;
|
|
78
|
+
}
|
|
79
|
+
if (msg) {
|
|
80
|
+
return msg;
|
|
81
|
+
}
|
|
82
|
+
return "(no status code or body)";
|
|
83
|
+
}
|
|
84
|
+
static generate(status, errorResponse, message, headers) {
|
|
85
|
+
if (!status || !headers) {
|
|
86
|
+
return new APIConnectionError({ message, cause: castToError(errorResponse) });
|
|
87
|
+
}
|
|
88
|
+
const error = errorResponse;
|
|
89
|
+
if (status === 400) {
|
|
90
|
+
return new BadRequestError(status, error, message, headers);
|
|
91
|
+
}
|
|
92
|
+
if (status === 401) {
|
|
93
|
+
return new AuthenticationError(status, error, message, headers);
|
|
94
|
+
}
|
|
95
|
+
if (status === 403) {
|
|
96
|
+
return new PermissionDeniedError(status, error, message, headers);
|
|
97
|
+
}
|
|
98
|
+
if (status === 404) {
|
|
99
|
+
return new NotFoundError(status, error, message, headers);
|
|
100
|
+
}
|
|
101
|
+
if (status === 409) {
|
|
102
|
+
return new ConflictError(status, error, message, headers);
|
|
103
|
+
}
|
|
104
|
+
if (status === 422) {
|
|
105
|
+
return new UnprocessableEntityError(status, error, message, headers);
|
|
106
|
+
}
|
|
107
|
+
if (status === 429) {
|
|
108
|
+
return new RateLimitError(status, error, message, headers);
|
|
109
|
+
}
|
|
110
|
+
if (status >= 500) {
|
|
111
|
+
return new InternalServerError(status, error, message, headers);
|
|
112
|
+
}
|
|
113
|
+
return new APIError(status, error, message, headers);
|
|
114
|
+
}
|
|
18
115
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
116
|
+
|
|
117
|
+
class APIUserAbortError extends APIError {
|
|
118
|
+
constructor({ message } = {}) {
|
|
119
|
+
super(undefined, undefined, message || "Request was aborted.", undefined);
|
|
120
|
+
}
|
|
24
121
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
122
|
+
|
|
123
|
+
class APIConnectionError extends APIError {
|
|
124
|
+
constructor({ message, cause }) {
|
|
125
|
+
super(undefined, undefined, message || "Connection error.", undefined);
|
|
126
|
+
if (cause)
|
|
127
|
+
this.cause = cause;
|
|
128
|
+
}
|
|
31
129
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
};
|
|
37
|
-
const apiKey = getCloudApiKey(options);
|
|
38
|
-
if (apiKey && !headers.Authorization && !headers.authorization) {
|
|
39
|
-
headers.Authorization = `Bearer ${apiKey}`;
|
|
130
|
+
|
|
131
|
+
class APIConnectionTimeoutError extends APIConnectionError {
|
|
132
|
+
constructor({ message } = {}) {
|
|
133
|
+
super({ message: message ?? "Request timed out." });
|
|
40
134
|
}
|
|
41
|
-
return headers;
|
|
42
135
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
136
|
+
|
|
137
|
+
class BadRequestError extends APIError {
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
class AuthenticationError extends APIError {
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
class PermissionDeniedError extends APIError {
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
class NotFoundError extends APIError {
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
class ConflictError extends APIError {
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
class UnprocessableEntityError extends APIError {
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
class RateLimitError extends APIError {
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
class InternalServerError extends APIError {
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// node_modules/@letta-ai/letta-client/internal/utils/values.mjs
|
|
162
|
+
var startsWithSchemeRegexp = /^[a-z][a-z0-9+.-]*:/i;
|
|
163
|
+
var isAbsoluteURL = (url) => {
|
|
164
|
+
return startsWithSchemeRegexp.test(url);
|
|
165
|
+
};
|
|
166
|
+
var isArray = (val) => (isArray = Array.isArray, isArray(val));
|
|
167
|
+
var isReadonlyArray = isArray;
|
|
168
|
+
function maybeObj(x) {
|
|
169
|
+
if (typeof x !== "object") {
|
|
170
|
+
return {};
|
|
171
|
+
}
|
|
172
|
+
return x ?? {};
|
|
173
|
+
}
|
|
174
|
+
function isEmptyObj(obj) {
|
|
175
|
+
if (!obj)
|
|
176
|
+
return true;
|
|
177
|
+
for (const _k in obj)
|
|
178
|
+
return false;
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
function hasOwn(obj, key) {
|
|
182
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
183
|
+
}
|
|
184
|
+
var validatePositiveInteger = (name, n) => {
|
|
185
|
+
if (typeof n !== "number" || !Number.isInteger(n)) {
|
|
186
|
+
throw new LettaError(`${name} must be an integer`);
|
|
187
|
+
}
|
|
188
|
+
if (n < 0) {
|
|
189
|
+
throw new LettaError(`${name} must be a positive integer`);
|
|
190
|
+
}
|
|
191
|
+
return n;
|
|
192
|
+
};
|
|
193
|
+
var safeJSON = (text) => {
|
|
47
194
|
try {
|
|
48
195
|
return JSON.parse(text);
|
|
49
|
-
} catch {
|
|
50
|
-
return
|
|
196
|
+
} catch (err) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
// node_modules/@letta-ai/letta-client/internal/utils/sleep.mjs
|
|
202
|
+
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
203
|
+
|
|
204
|
+
// node_modules/@letta-ai/letta-client/version.mjs
|
|
205
|
+
var VERSION = "1.12.1";
|
|
206
|
+
|
|
207
|
+
// node_modules/@letta-ai/letta-client/internal/detect-platform.mjs
|
|
208
|
+
function getDetectedPlatform() {
|
|
209
|
+
if (typeof Deno !== "undefined" && Deno.build != null) {
|
|
210
|
+
return "deno";
|
|
211
|
+
}
|
|
212
|
+
if (typeof EdgeRuntime !== "undefined") {
|
|
213
|
+
return "edge";
|
|
214
|
+
}
|
|
215
|
+
if (Object.prototype.toString.call(typeof globalThis.process !== "undefined" ? globalThis.process : 0) === "[object process]") {
|
|
216
|
+
return "node";
|
|
217
|
+
}
|
|
218
|
+
return "unknown";
|
|
219
|
+
}
|
|
220
|
+
var getPlatformProperties = () => {
|
|
221
|
+
const detectedPlatform = getDetectedPlatform();
|
|
222
|
+
if (detectedPlatform === "deno") {
|
|
223
|
+
return {
|
|
224
|
+
"X-Stainless-Lang": "js",
|
|
225
|
+
"X-Stainless-Package-Version": VERSION,
|
|
226
|
+
"X-Stainless-OS": normalizePlatform(Deno.build.os),
|
|
227
|
+
"X-Stainless-Arch": normalizeArch(Deno.build.arch),
|
|
228
|
+
"X-Stainless-Runtime": "deno",
|
|
229
|
+
"X-Stainless-Runtime-Version": typeof Deno.version === "string" ? Deno.version : Deno.version?.deno ?? "unknown"
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
if (typeof EdgeRuntime !== "undefined") {
|
|
233
|
+
return {
|
|
234
|
+
"X-Stainless-Lang": "js",
|
|
235
|
+
"X-Stainless-Package-Version": VERSION,
|
|
236
|
+
"X-Stainless-OS": "Unknown",
|
|
237
|
+
"X-Stainless-Arch": `other:${EdgeRuntime}`,
|
|
238
|
+
"X-Stainless-Runtime": "edge",
|
|
239
|
+
"X-Stainless-Runtime-Version": globalThis.process.version
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
if (detectedPlatform === "node") {
|
|
243
|
+
return {
|
|
244
|
+
"X-Stainless-Lang": "js",
|
|
245
|
+
"X-Stainless-Package-Version": VERSION,
|
|
246
|
+
"X-Stainless-OS": normalizePlatform(globalThis.process.platform ?? "unknown"),
|
|
247
|
+
"X-Stainless-Arch": normalizeArch(globalThis.process.arch ?? "unknown"),
|
|
248
|
+
"X-Stainless-Runtime": "node",
|
|
249
|
+
"X-Stainless-Runtime-Version": globalThis.process.version ?? "unknown"
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
const browserInfo = getBrowserInfo();
|
|
253
|
+
if (browserInfo) {
|
|
254
|
+
return {
|
|
255
|
+
"X-Stainless-Lang": "js",
|
|
256
|
+
"X-Stainless-Package-Version": VERSION,
|
|
257
|
+
"X-Stainless-OS": "Unknown",
|
|
258
|
+
"X-Stainless-Arch": "unknown",
|
|
259
|
+
"X-Stainless-Runtime": `browser:${browserInfo.browser}`,
|
|
260
|
+
"X-Stainless-Runtime-Version": browserInfo.version
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
"X-Stainless-Lang": "js",
|
|
265
|
+
"X-Stainless-Package-Version": VERSION,
|
|
266
|
+
"X-Stainless-OS": "Unknown",
|
|
267
|
+
"X-Stainless-Arch": "unknown",
|
|
268
|
+
"X-Stainless-Runtime": "unknown",
|
|
269
|
+
"X-Stainless-Runtime-Version": "unknown"
|
|
270
|
+
};
|
|
271
|
+
};
|
|
272
|
+
function getBrowserInfo() {
|
|
273
|
+
if (typeof navigator === "undefined" || !navigator) {
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
const browserPatterns = [
|
|
277
|
+
{ key: "edge", pattern: /Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
|
|
278
|
+
{ key: "ie", pattern: /MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
|
|
279
|
+
{ key: "ie", pattern: /Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/ },
|
|
280
|
+
{ key: "chrome", pattern: /Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
|
|
281
|
+
{ key: "firefox", pattern: /Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
|
|
282
|
+
{ key: "safari", pattern: /(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/ }
|
|
283
|
+
];
|
|
284
|
+
for (const { key, pattern } of browserPatterns) {
|
|
285
|
+
const match = pattern.exec(navigator.userAgent);
|
|
286
|
+
if (match) {
|
|
287
|
+
const major = match[1] || 0;
|
|
288
|
+
const minor = match[2] || 0;
|
|
289
|
+
const patch = match[3] || 0;
|
|
290
|
+
return { browser: key, version: `${major}.${minor}.${patch}` };
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
var normalizeArch = (arch) => {
|
|
296
|
+
if (arch === "x32")
|
|
297
|
+
return "x32";
|
|
298
|
+
if (arch === "x86_64" || arch === "x64")
|
|
299
|
+
return "x64";
|
|
300
|
+
if (arch === "arm")
|
|
301
|
+
return "arm";
|
|
302
|
+
if (arch === "aarch64" || arch === "arm64")
|
|
303
|
+
return "arm64";
|
|
304
|
+
if (arch)
|
|
305
|
+
return `other:${arch}`;
|
|
306
|
+
return "unknown";
|
|
307
|
+
};
|
|
308
|
+
var normalizePlatform = (platform) => {
|
|
309
|
+
platform = platform.toLowerCase();
|
|
310
|
+
if (platform.includes("ios"))
|
|
311
|
+
return "iOS";
|
|
312
|
+
if (platform === "android")
|
|
313
|
+
return "Android";
|
|
314
|
+
if (platform === "darwin")
|
|
315
|
+
return "MacOS";
|
|
316
|
+
if (platform === "win32")
|
|
317
|
+
return "Windows";
|
|
318
|
+
if (platform === "freebsd")
|
|
319
|
+
return "FreeBSD";
|
|
320
|
+
if (platform === "openbsd")
|
|
321
|
+
return "OpenBSD";
|
|
322
|
+
if (platform === "linux")
|
|
323
|
+
return "Linux";
|
|
324
|
+
if (platform)
|
|
325
|
+
return `Other:${platform}`;
|
|
326
|
+
return "Unknown";
|
|
327
|
+
};
|
|
328
|
+
var _platformHeaders;
|
|
329
|
+
var getPlatformHeaders = () => {
|
|
330
|
+
return _platformHeaders ?? (_platformHeaders = getPlatformProperties());
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
// node_modules/@letta-ai/letta-client/internal/shims.mjs
|
|
334
|
+
function getDefaultFetch() {
|
|
335
|
+
if (typeof fetch !== "undefined") {
|
|
336
|
+
return fetch;
|
|
337
|
+
}
|
|
338
|
+
throw new Error("`fetch` is not defined as a global; Either pass `fetch` to the client, `new Letta({ fetch })` or polyfill the global, `globalThis.fetch = fetch`");
|
|
339
|
+
}
|
|
340
|
+
function makeReadableStream(...args) {
|
|
341
|
+
const ReadableStream = globalThis.ReadableStream;
|
|
342
|
+
if (typeof ReadableStream === "undefined") {
|
|
343
|
+
throw new Error("`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`");
|
|
344
|
+
}
|
|
345
|
+
return new ReadableStream(...args);
|
|
346
|
+
}
|
|
347
|
+
function ReadableStreamFrom(iterable) {
|
|
348
|
+
let iter = Symbol.asyncIterator in iterable ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator]();
|
|
349
|
+
return makeReadableStream({
|
|
350
|
+
start() {},
|
|
351
|
+
async pull(controller) {
|
|
352
|
+
const { done, value } = await iter.next();
|
|
353
|
+
if (done) {
|
|
354
|
+
controller.close();
|
|
355
|
+
} else {
|
|
356
|
+
controller.enqueue(value);
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
async cancel() {
|
|
360
|
+
await iter.return?.();
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
function ReadableStreamToAsyncIterable(stream) {
|
|
365
|
+
if (stream[Symbol.asyncIterator])
|
|
366
|
+
return stream;
|
|
367
|
+
const reader = stream.getReader();
|
|
368
|
+
return {
|
|
369
|
+
async next() {
|
|
370
|
+
try {
|
|
371
|
+
const result = await reader.read();
|
|
372
|
+
if (result?.done)
|
|
373
|
+
reader.releaseLock();
|
|
374
|
+
return result;
|
|
375
|
+
} catch (e) {
|
|
376
|
+
reader.releaseLock();
|
|
377
|
+
throw e;
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
async return() {
|
|
381
|
+
const cancelPromise = reader.cancel();
|
|
382
|
+
reader.releaseLock();
|
|
383
|
+
await cancelPromise;
|
|
384
|
+
return { done: true, value: undefined };
|
|
385
|
+
},
|
|
386
|
+
[Symbol.asyncIterator]() {
|
|
387
|
+
return this;
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
async function CancelReadableStream(stream) {
|
|
392
|
+
if (stream === null || typeof stream !== "object")
|
|
393
|
+
return;
|
|
394
|
+
if (stream[Symbol.asyncIterator]) {
|
|
395
|
+
await stream[Symbol.asyncIterator]().return?.();
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
const reader = stream.getReader();
|
|
399
|
+
const cancelPromise = reader.cancel();
|
|
400
|
+
reader.releaseLock();
|
|
401
|
+
await cancelPromise;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// node_modules/@letta-ai/letta-client/internal/request-options.mjs
|
|
405
|
+
var FallbackEncoder = ({ headers, body }) => {
|
|
406
|
+
return {
|
|
407
|
+
bodyHeaders: {
|
|
408
|
+
"content-type": "application/json"
|
|
409
|
+
},
|
|
410
|
+
body: JSON.stringify(body)
|
|
411
|
+
};
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
// node_modules/@letta-ai/letta-client/internal/qs/formats.mjs
|
|
415
|
+
var default_format = "RFC3986";
|
|
416
|
+
var default_formatter = (v) => String(v);
|
|
417
|
+
var formatters = {
|
|
418
|
+
RFC1738: (v) => String(v).replace(/%20/g, "+"),
|
|
419
|
+
RFC3986: default_formatter
|
|
420
|
+
};
|
|
421
|
+
var RFC1738 = "RFC1738";
|
|
422
|
+
|
|
423
|
+
// node_modules/@letta-ai/letta-client/internal/qs/utils.mjs
|
|
424
|
+
var has = (obj, key) => (has = Object.hasOwn ?? Function.prototype.call.bind(Object.prototype.hasOwnProperty), has(obj, key));
|
|
425
|
+
var hex_table = /* @__PURE__ */ (() => {
|
|
426
|
+
const array = [];
|
|
427
|
+
for (let i = 0;i < 256; ++i) {
|
|
428
|
+
array.push("%" + ((i < 16 ? "0" : "") + i.toString(16)).toUpperCase());
|
|
429
|
+
}
|
|
430
|
+
return array;
|
|
431
|
+
})();
|
|
432
|
+
var limit = 1024;
|
|
433
|
+
var encode = (str, _defaultEncoder, charset, _kind, format) => {
|
|
434
|
+
if (str.length === 0) {
|
|
435
|
+
return str;
|
|
436
|
+
}
|
|
437
|
+
let string = str;
|
|
438
|
+
if (typeof str === "symbol") {
|
|
439
|
+
string = Symbol.prototype.toString.call(str);
|
|
440
|
+
} else if (typeof str !== "string") {
|
|
441
|
+
string = String(str);
|
|
442
|
+
}
|
|
443
|
+
if (charset === "iso-8859-1") {
|
|
444
|
+
return escape(string).replace(/%u[0-9a-f]{4}/gi, function($0) {
|
|
445
|
+
return "%26%23" + parseInt($0.slice(2), 16) + "%3B";
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
let out = "";
|
|
449
|
+
for (let j = 0;j < string.length; j += limit) {
|
|
450
|
+
const segment = string.length >= limit ? string.slice(j, j + limit) : string;
|
|
451
|
+
const arr = [];
|
|
452
|
+
for (let i = 0;i < segment.length; ++i) {
|
|
453
|
+
let c = segment.charCodeAt(i);
|
|
454
|
+
if (c === 45 || c === 46 || c === 95 || c === 126 || c >= 48 && c <= 57 || c >= 65 && c <= 90 || c >= 97 && c <= 122 || format === RFC1738 && (c === 40 || c === 41)) {
|
|
455
|
+
arr[arr.length] = segment.charAt(i);
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
if (c < 128) {
|
|
459
|
+
arr[arr.length] = hex_table[c];
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
if (c < 2048) {
|
|
463
|
+
arr[arr.length] = hex_table[192 | c >> 6] + hex_table[128 | c & 63];
|
|
464
|
+
continue;
|
|
465
|
+
}
|
|
466
|
+
if (c < 55296 || c >= 57344) {
|
|
467
|
+
arr[arr.length] = hex_table[224 | c >> 12] + hex_table[128 | c >> 6 & 63] + hex_table[128 | c & 63];
|
|
468
|
+
continue;
|
|
469
|
+
}
|
|
470
|
+
i += 1;
|
|
471
|
+
c = 65536 + ((c & 1023) << 10 | segment.charCodeAt(i) & 1023);
|
|
472
|
+
arr[arr.length] = hex_table[240 | c >> 18] + hex_table[128 | c >> 12 & 63] + hex_table[128 | c >> 6 & 63] + hex_table[128 | c & 63];
|
|
473
|
+
}
|
|
474
|
+
out += arr.join("");
|
|
475
|
+
}
|
|
476
|
+
return out;
|
|
477
|
+
};
|
|
478
|
+
function is_buffer(obj) {
|
|
479
|
+
if (!obj || typeof obj !== "object") {
|
|
480
|
+
return false;
|
|
481
|
+
}
|
|
482
|
+
return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
|
|
483
|
+
}
|
|
484
|
+
function maybe_map(val, fn) {
|
|
485
|
+
if (isArray(val)) {
|
|
486
|
+
const mapped = [];
|
|
487
|
+
for (let i = 0;i < val.length; i += 1) {
|
|
488
|
+
mapped.push(fn(val[i]));
|
|
489
|
+
}
|
|
490
|
+
return mapped;
|
|
491
|
+
}
|
|
492
|
+
return fn(val);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
// node_modules/@letta-ai/letta-client/internal/qs/stringify.mjs
|
|
496
|
+
var array_prefix_generators = {
|
|
497
|
+
brackets(prefix) {
|
|
498
|
+
return String(prefix) + "[]";
|
|
499
|
+
},
|
|
500
|
+
comma: "comma",
|
|
501
|
+
indices(prefix, key) {
|
|
502
|
+
return String(prefix) + "[" + key + "]";
|
|
503
|
+
},
|
|
504
|
+
repeat(prefix) {
|
|
505
|
+
return String(prefix);
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
var push_to_array = function(arr, value_or_array) {
|
|
509
|
+
Array.prototype.push.apply(arr, isArray(value_or_array) ? value_or_array : [value_or_array]);
|
|
510
|
+
};
|
|
511
|
+
var toISOString;
|
|
512
|
+
var defaults = {
|
|
513
|
+
addQueryPrefix: false,
|
|
514
|
+
allowDots: false,
|
|
515
|
+
allowEmptyArrays: false,
|
|
516
|
+
arrayFormat: "indices",
|
|
517
|
+
charset: "utf-8",
|
|
518
|
+
charsetSentinel: false,
|
|
519
|
+
delimiter: "&",
|
|
520
|
+
encode: true,
|
|
521
|
+
encodeDotInKeys: false,
|
|
522
|
+
encoder: encode,
|
|
523
|
+
encodeValuesOnly: false,
|
|
524
|
+
format: default_format,
|
|
525
|
+
formatter: default_formatter,
|
|
526
|
+
indices: false,
|
|
527
|
+
serializeDate(date) {
|
|
528
|
+
return (toISOString ?? (toISOString = Function.prototype.call.bind(Date.prototype.toISOString)))(date);
|
|
529
|
+
},
|
|
530
|
+
skipNulls: false,
|
|
531
|
+
strictNullHandling: false
|
|
532
|
+
};
|
|
533
|
+
function is_non_nullish_primitive(v) {
|
|
534
|
+
return typeof v === "string" || typeof v === "number" || typeof v === "boolean" || typeof v === "symbol" || typeof v === "bigint";
|
|
535
|
+
}
|
|
536
|
+
var sentinel = {};
|
|
537
|
+
function inner_stringify(object, prefix, generateArrayPrefix, commaRoundTrip, allowEmptyArrays, strictNullHandling, skipNulls, encodeDotInKeys, encoder, filter, sort, allowDots, serializeDate, format, formatter, encodeValuesOnly, charset, sideChannel) {
|
|
538
|
+
let obj = object;
|
|
539
|
+
let tmp_sc = sideChannel;
|
|
540
|
+
let step = 0;
|
|
541
|
+
let find_flag = false;
|
|
542
|
+
while ((tmp_sc = tmp_sc.get(sentinel)) !== undefined && !find_flag) {
|
|
543
|
+
const pos = tmp_sc.get(object);
|
|
544
|
+
step += 1;
|
|
545
|
+
if (typeof pos !== "undefined") {
|
|
546
|
+
if (pos === step) {
|
|
547
|
+
throw new RangeError("Cyclic object value");
|
|
548
|
+
} else {
|
|
549
|
+
find_flag = true;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
if (typeof tmp_sc.get(sentinel) === "undefined") {
|
|
553
|
+
step = 0;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
if (typeof filter === "function") {
|
|
557
|
+
obj = filter(prefix, obj);
|
|
558
|
+
} else if (obj instanceof Date) {
|
|
559
|
+
obj = serializeDate?.(obj);
|
|
560
|
+
} else if (generateArrayPrefix === "comma" && isArray(obj)) {
|
|
561
|
+
obj = maybe_map(obj, function(value) {
|
|
562
|
+
if (value instanceof Date) {
|
|
563
|
+
return serializeDate?.(value);
|
|
564
|
+
}
|
|
565
|
+
return value;
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
if (obj === null) {
|
|
569
|
+
if (strictNullHandling) {
|
|
570
|
+
return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, "key", format) : prefix;
|
|
571
|
+
}
|
|
572
|
+
obj = "";
|
|
573
|
+
}
|
|
574
|
+
if (is_non_nullish_primitive(obj) || is_buffer(obj)) {
|
|
575
|
+
if (encoder) {
|
|
576
|
+
const key_value = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, "key", format);
|
|
577
|
+
return [
|
|
578
|
+
formatter?.(key_value) + "=" + formatter?.(encoder(obj, defaults.encoder, charset, "value", format))
|
|
579
|
+
];
|
|
580
|
+
}
|
|
581
|
+
return [formatter?.(prefix) + "=" + formatter?.(String(obj))];
|
|
582
|
+
}
|
|
583
|
+
const values = [];
|
|
584
|
+
if (typeof obj === "undefined") {
|
|
585
|
+
return values;
|
|
586
|
+
}
|
|
587
|
+
let obj_keys;
|
|
588
|
+
if (generateArrayPrefix === "comma" && isArray(obj)) {
|
|
589
|
+
if (encodeValuesOnly && encoder) {
|
|
590
|
+
obj = maybe_map(obj, encoder);
|
|
591
|
+
}
|
|
592
|
+
obj_keys = [{ value: obj.length > 0 ? obj.join(",") || null : undefined }];
|
|
593
|
+
} else if (isArray(filter)) {
|
|
594
|
+
obj_keys = filter;
|
|
595
|
+
} else {
|
|
596
|
+
const keys = Object.keys(obj);
|
|
597
|
+
obj_keys = sort ? keys.sort(sort) : keys;
|
|
598
|
+
}
|
|
599
|
+
const encoded_prefix = encodeDotInKeys ? String(prefix).replace(/\./g, "%2E") : String(prefix);
|
|
600
|
+
const adjusted_prefix = commaRoundTrip && isArray(obj) && obj.length === 1 ? encoded_prefix + "[]" : encoded_prefix;
|
|
601
|
+
if (allowEmptyArrays && isArray(obj) && obj.length === 0) {
|
|
602
|
+
return adjusted_prefix + "[]";
|
|
603
|
+
}
|
|
604
|
+
for (let j = 0;j < obj_keys.length; ++j) {
|
|
605
|
+
const key = obj_keys[j];
|
|
606
|
+
const value = typeof key === "object" && typeof key.value !== "undefined" ? key.value : obj[key];
|
|
607
|
+
if (skipNulls && value === null) {
|
|
608
|
+
continue;
|
|
609
|
+
}
|
|
610
|
+
const encoded_key = allowDots && encodeDotInKeys ? key.replace(/\./g, "%2E") : key;
|
|
611
|
+
const key_prefix = isArray(obj) ? typeof generateArrayPrefix === "function" ? generateArrayPrefix(adjusted_prefix, encoded_key) : adjusted_prefix : adjusted_prefix + (allowDots ? "." + encoded_key : "[" + encoded_key + "]");
|
|
612
|
+
sideChannel.set(object, step);
|
|
613
|
+
const valueSideChannel = new WeakMap;
|
|
614
|
+
valueSideChannel.set(sentinel, sideChannel);
|
|
615
|
+
push_to_array(values, inner_stringify(value, key_prefix, generateArrayPrefix, commaRoundTrip, allowEmptyArrays, strictNullHandling, skipNulls, encodeDotInKeys, generateArrayPrefix === "comma" && encodeValuesOnly && isArray(obj) ? null : encoder, filter, sort, allowDots, serializeDate, format, formatter, encodeValuesOnly, charset, valueSideChannel));
|
|
616
|
+
}
|
|
617
|
+
return values;
|
|
618
|
+
}
|
|
619
|
+
function normalize_stringify_options(opts = defaults) {
|
|
620
|
+
if (typeof opts.allowEmptyArrays !== "undefined" && typeof opts.allowEmptyArrays !== "boolean") {
|
|
621
|
+
throw new TypeError("`allowEmptyArrays` option can only be `true` or `false`, when provided");
|
|
622
|
+
}
|
|
623
|
+
if (typeof opts.encodeDotInKeys !== "undefined" && typeof opts.encodeDotInKeys !== "boolean") {
|
|
624
|
+
throw new TypeError("`encodeDotInKeys` option can only be `true` or `false`, when provided");
|
|
625
|
+
}
|
|
626
|
+
if (opts.encoder !== null && typeof opts.encoder !== "undefined" && typeof opts.encoder !== "function") {
|
|
627
|
+
throw new TypeError("Encoder has to be a function.");
|
|
628
|
+
}
|
|
629
|
+
const charset = opts.charset || defaults.charset;
|
|
630
|
+
if (typeof opts.charset !== "undefined" && opts.charset !== "utf-8" && opts.charset !== "iso-8859-1") {
|
|
631
|
+
throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined");
|
|
632
|
+
}
|
|
633
|
+
let format = default_format;
|
|
634
|
+
if (typeof opts.format !== "undefined") {
|
|
635
|
+
if (!has(formatters, opts.format)) {
|
|
636
|
+
throw new TypeError("Unknown format option provided.");
|
|
637
|
+
}
|
|
638
|
+
format = opts.format;
|
|
639
|
+
}
|
|
640
|
+
const formatter = formatters[format];
|
|
641
|
+
let filter = defaults.filter;
|
|
642
|
+
if (typeof opts.filter === "function" || isArray(opts.filter)) {
|
|
643
|
+
filter = opts.filter;
|
|
644
|
+
}
|
|
645
|
+
let arrayFormat;
|
|
646
|
+
if (opts.arrayFormat && opts.arrayFormat in array_prefix_generators) {
|
|
647
|
+
arrayFormat = opts.arrayFormat;
|
|
648
|
+
} else if ("indices" in opts) {
|
|
649
|
+
arrayFormat = opts.indices ? "indices" : "repeat";
|
|
650
|
+
} else {
|
|
651
|
+
arrayFormat = defaults.arrayFormat;
|
|
652
|
+
}
|
|
653
|
+
if ("commaRoundTrip" in opts && typeof opts.commaRoundTrip !== "boolean") {
|
|
654
|
+
throw new TypeError("`commaRoundTrip` must be a boolean, or absent");
|
|
655
|
+
}
|
|
656
|
+
const allowDots = typeof opts.allowDots === "undefined" ? !!opts.encodeDotInKeys === true ? true : defaults.allowDots : !!opts.allowDots;
|
|
657
|
+
return {
|
|
658
|
+
addQueryPrefix: typeof opts.addQueryPrefix === "boolean" ? opts.addQueryPrefix : defaults.addQueryPrefix,
|
|
659
|
+
allowDots,
|
|
660
|
+
allowEmptyArrays: typeof opts.allowEmptyArrays === "boolean" ? !!opts.allowEmptyArrays : defaults.allowEmptyArrays,
|
|
661
|
+
arrayFormat,
|
|
662
|
+
charset,
|
|
663
|
+
charsetSentinel: typeof opts.charsetSentinel === "boolean" ? opts.charsetSentinel : defaults.charsetSentinel,
|
|
664
|
+
commaRoundTrip: !!opts.commaRoundTrip,
|
|
665
|
+
delimiter: typeof opts.delimiter === "undefined" ? defaults.delimiter : opts.delimiter,
|
|
666
|
+
encode: typeof opts.encode === "boolean" ? opts.encode : defaults.encode,
|
|
667
|
+
encodeDotInKeys: typeof opts.encodeDotInKeys === "boolean" ? opts.encodeDotInKeys : defaults.encodeDotInKeys,
|
|
668
|
+
encoder: typeof opts.encoder === "function" ? opts.encoder : defaults.encoder,
|
|
669
|
+
encodeValuesOnly: typeof opts.encodeValuesOnly === "boolean" ? opts.encodeValuesOnly : defaults.encodeValuesOnly,
|
|
670
|
+
filter,
|
|
671
|
+
format,
|
|
672
|
+
formatter,
|
|
673
|
+
serializeDate: typeof opts.serializeDate === "function" ? opts.serializeDate : defaults.serializeDate,
|
|
674
|
+
skipNulls: typeof opts.skipNulls === "boolean" ? opts.skipNulls : defaults.skipNulls,
|
|
675
|
+
sort: typeof opts.sort === "function" ? opts.sort : null,
|
|
676
|
+
strictNullHandling: typeof opts.strictNullHandling === "boolean" ? opts.strictNullHandling : defaults.strictNullHandling
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
function stringify(object, opts = {}) {
|
|
680
|
+
let obj = object;
|
|
681
|
+
const options = normalize_stringify_options(opts);
|
|
682
|
+
let obj_keys;
|
|
683
|
+
let filter;
|
|
684
|
+
if (typeof options.filter === "function") {
|
|
685
|
+
filter = options.filter;
|
|
686
|
+
obj = filter("", obj);
|
|
687
|
+
} else if (isArray(options.filter)) {
|
|
688
|
+
filter = options.filter;
|
|
689
|
+
obj_keys = filter;
|
|
690
|
+
}
|
|
691
|
+
const keys = [];
|
|
692
|
+
if (typeof obj !== "object" || obj === null) {
|
|
693
|
+
return "";
|
|
694
|
+
}
|
|
695
|
+
const generateArrayPrefix = array_prefix_generators[options.arrayFormat];
|
|
696
|
+
const commaRoundTrip = generateArrayPrefix === "comma" && options.commaRoundTrip;
|
|
697
|
+
if (!obj_keys) {
|
|
698
|
+
obj_keys = Object.keys(obj);
|
|
699
|
+
}
|
|
700
|
+
if (options.sort) {
|
|
701
|
+
obj_keys.sort(options.sort);
|
|
702
|
+
}
|
|
703
|
+
const sideChannel = new WeakMap;
|
|
704
|
+
for (let i = 0;i < obj_keys.length; ++i) {
|
|
705
|
+
const key = obj_keys[i];
|
|
706
|
+
if (options.skipNulls && obj[key] === null) {
|
|
707
|
+
continue;
|
|
708
|
+
}
|
|
709
|
+
push_to_array(keys, inner_stringify(obj[key], key, generateArrayPrefix, commaRoundTrip, options.allowEmptyArrays, options.strictNullHandling, options.skipNulls, options.encodeDotInKeys, options.encode ? options.encoder : null, options.filter, options.sort, options.allowDots, options.serializeDate, options.format, options.formatter, options.encodeValuesOnly, options.charset, sideChannel));
|
|
710
|
+
}
|
|
711
|
+
const joined = keys.join(options.delimiter);
|
|
712
|
+
let prefix = options.addQueryPrefix === true ? "?" : "";
|
|
713
|
+
if (options.charsetSentinel) {
|
|
714
|
+
if (options.charset === "iso-8859-1") {
|
|
715
|
+
prefix += "utf8=%26%2310003%3B&";
|
|
716
|
+
} else {
|
|
717
|
+
prefix += "utf8=%E2%9C%93&";
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
return joined.length > 0 ? prefix + joined : "";
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
// node_modules/@letta-ai/letta-client/internal/utils/query.mjs
|
|
724
|
+
function stringifyQuery(query) {
|
|
725
|
+
return stringify(query, { allowDots: true, arrayFormat: "repeat" });
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
// node_modules/@letta-ai/letta-client/internal/utils/bytes.mjs
|
|
729
|
+
function concatBytes(buffers) {
|
|
730
|
+
let length = 0;
|
|
731
|
+
for (const buffer of buffers) {
|
|
732
|
+
length += buffer.length;
|
|
733
|
+
}
|
|
734
|
+
const output = new Uint8Array(length);
|
|
735
|
+
let index = 0;
|
|
736
|
+
for (const buffer of buffers) {
|
|
737
|
+
output.set(buffer, index);
|
|
738
|
+
index += buffer.length;
|
|
739
|
+
}
|
|
740
|
+
return output;
|
|
741
|
+
}
|
|
742
|
+
var encodeUTF8_;
|
|
743
|
+
function encodeUTF8(str) {
|
|
744
|
+
let encoder;
|
|
745
|
+
return (encodeUTF8_ ?? (encoder = new globalThis.TextEncoder, encodeUTF8_ = encoder.encode.bind(encoder)))(str);
|
|
746
|
+
}
|
|
747
|
+
var decodeUTF8_;
|
|
748
|
+
function decodeUTF8(bytes) {
|
|
749
|
+
let decoder;
|
|
750
|
+
return (decodeUTF8_ ?? (decoder = new globalThis.TextDecoder, decodeUTF8_ = decoder.decode.bind(decoder)))(bytes);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
// node_modules/@letta-ai/letta-client/internal/decoders/line.mjs
|
|
754
|
+
var _LineDecoder_buffer;
|
|
755
|
+
var _LineDecoder_carriageReturnIndex;
|
|
756
|
+
|
|
757
|
+
class LineDecoder {
|
|
758
|
+
constructor() {
|
|
759
|
+
_LineDecoder_buffer.set(this, undefined);
|
|
760
|
+
_LineDecoder_carriageReturnIndex.set(this, undefined);
|
|
761
|
+
__classPrivateFieldSet(this, _LineDecoder_buffer, new Uint8Array, "f");
|
|
762
|
+
__classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, null, "f");
|
|
763
|
+
}
|
|
764
|
+
decode(chunk) {
|
|
765
|
+
if (chunk == null) {
|
|
766
|
+
return [];
|
|
767
|
+
}
|
|
768
|
+
const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk) : typeof chunk === "string" ? encodeUTF8(chunk) : chunk;
|
|
769
|
+
__classPrivateFieldSet(this, _LineDecoder_buffer, concatBytes([__classPrivateFieldGet(this, _LineDecoder_buffer, "f"), binaryChunk]), "f");
|
|
770
|
+
const lines = [];
|
|
771
|
+
let patternIndex;
|
|
772
|
+
while ((patternIndex = findNewlineIndex(__classPrivateFieldGet(this, _LineDecoder_buffer, "f"), __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f"))) != null) {
|
|
773
|
+
if (patternIndex.carriage && __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") == null) {
|
|
774
|
+
__classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, patternIndex.index, "f");
|
|
775
|
+
continue;
|
|
776
|
+
}
|
|
777
|
+
if (__classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") != null && (patternIndex.index !== __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") + 1 || patternIndex.carriage)) {
|
|
778
|
+
lines.push(decodeUTF8(__classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(0, __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") - 1)));
|
|
779
|
+
__classPrivateFieldSet(this, _LineDecoder_buffer, __classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(__classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f")), "f");
|
|
780
|
+
__classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, null, "f");
|
|
781
|
+
continue;
|
|
782
|
+
}
|
|
783
|
+
const endIndex = __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") !== null ? patternIndex.preceding - 1 : patternIndex.preceding;
|
|
784
|
+
const line = decodeUTF8(__classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(0, endIndex));
|
|
785
|
+
lines.push(line);
|
|
786
|
+
__classPrivateFieldSet(this, _LineDecoder_buffer, __classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(patternIndex.index), "f");
|
|
787
|
+
__classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, null, "f");
|
|
788
|
+
}
|
|
789
|
+
return lines;
|
|
790
|
+
}
|
|
791
|
+
flush() {
|
|
792
|
+
if (!__classPrivateFieldGet(this, _LineDecoder_buffer, "f").length) {
|
|
793
|
+
return [];
|
|
794
|
+
}
|
|
795
|
+
return this.decode(`
|
|
796
|
+
`);
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
_LineDecoder_buffer = new WeakMap, _LineDecoder_carriageReturnIndex = new WeakMap;
|
|
800
|
+
LineDecoder.NEWLINE_CHARS = new Set([`
|
|
801
|
+
`, "\r"]);
|
|
802
|
+
LineDecoder.NEWLINE_REGEXP = /\r\n|[\n\r]/g;
|
|
803
|
+
function findNewlineIndex(buffer, startIndex) {
|
|
804
|
+
const newline = 10;
|
|
805
|
+
const carriage = 13;
|
|
806
|
+
for (let i = startIndex ?? 0;i < buffer.length; i++) {
|
|
807
|
+
if (buffer[i] === newline) {
|
|
808
|
+
return { preceding: i, index: i + 1, carriage: false };
|
|
809
|
+
}
|
|
810
|
+
if (buffer[i] === carriage) {
|
|
811
|
+
return { preceding: i, index: i + 1, carriage: true };
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
return null;
|
|
815
|
+
}
|
|
816
|
+
function findDoubleNewlineIndex(buffer) {
|
|
817
|
+
const newline = 10;
|
|
818
|
+
const carriage = 13;
|
|
819
|
+
for (let i = 0;i < buffer.length - 1; i++) {
|
|
820
|
+
if (buffer[i] === newline && buffer[i + 1] === newline) {
|
|
821
|
+
return i + 2;
|
|
822
|
+
}
|
|
823
|
+
if (buffer[i] === carriage && buffer[i + 1] === carriage) {
|
|
824
|
+
return i + 2;
|
|
825
|
+
}
|
|
826
|
+
if (buffer[i] === carriage && buffer[i + 1] === newline && i + 3 < buffer.length && buffer[i + 2] === carriage && buffer[i + 3] === newline) {
|
|
827
|
+
return i + 4;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
return -1;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
// node_modules/@letta-ai/letta-client/internal/utils/log.mjs
|
|
834
|
+
var levelNumbers = {
|
|
835
|
+
off: 0,
|
|
836
|
+
error: 200,
|
|
837
|
+
warn: 300,
|
|
838
|
+
info: 400,
|
|
839
|
+
debug: 500
|
|
840
|
+
};
|
|
841
|
+
var parseLogLevel = (maybeLevel, sourceName, client) => {
|
|
842
|
+
if (!maybeLevel) {
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
if (hasOwn(levelNumbers, maybeLevel)) {
|
|
846
|
+
return maybeLevel;
|
|
847
|
+
}
|
|
848
|
+
loggerFor(client).warn(`${sourceName} was set to ${JSON.stringify(maybeLevel)}, expected one of ${JSON.stringify(Object.keys(levelNumbers))}`);
|
|
849
|
+
return;
|
|
850
|
+
};
|
|
851
|
+
function noop() {}
|
|
852
|
+
function makeLogFn(fnLevel, logger, logLevel) {
|
|
853
|
+
if (!logger || levelNumbers[fnLevel] > levelNumbers[logLevel]) {
|
|
854
|
+
return noop;
|
|
855
|
+
} else {
|
|
856
|
+
return logger[fnLevel].bind(logger);
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
var noopLogger = {
|
|
860
|
+
error: noop,
|
|
861
|
+
warn: noop,
|
|
862
|
+
info: noop,
|
|
863
|
+
debug: noop
|
|
864
|
+
};
|
|
865
|
+
var cachedLoggers = /* @__PURE__ */ new WeakMap;
|
|
866
|
+
function loggerFor(client) {
|
|
867
|
+
const logger = client.logger;
|
|
868
|
+
const logLevel = client.logLevel ?? "off";
|
|
869
|
+
if (!logger) {
|
|
870
|
+
return noopLogger;
|
|
871
|
+
}
|
|
872
|
+
const cachedLogger = cachedLoggers.get(logger);
|
|
873
|
+
if (cachedLogger && cachedLogger[0] === logLevel) {
|
|
874
|
+
return cachedLogger[1];
|
|
875
|
+
}
|
|
876
|
+
const levelLogger = {
|
|
877
|
+
error: makeLogFn("error", logger, logLevel),
|
|
878
|
+
warn: makeLogFn("warn", logger, logLevel),
|
|
879
|
+
info: makeLogFn("info", logger, logLevel),
|
|
880
|
+
debug: makeLogFn("debug", logger, logLevel)
|
|
881
|
+
};
|
|
882
|
+
cachedLoggers.set(logger, [logLevel, levelLogger]);
|
|
883
|
+
return levelLogger;
|
|
884
|
+
}
|
|
885
|
+
var formatRequestDetails = (details) => {
|
|
886
|
+
if (details.options) {
|
|
887
|
+
details.options = { ...details.options };
|
|
888
|
+
delete details.options["headers"];
|
|
51
889
|
}
|
|
890
|
+
if (details.headers) {
|
|
891
|
+
details.headers = Object.fromEntries((details.headers instanceof Headers ? [...details.headers] : Object.entries(details.headers)).map(([name, value]) => [
|
|
892
|
+
name,
|
|
893
|
+
name.toLowerCase() === "authorization" || name.toLowerCase() === "api-key" || name.toLowerCase() === "x-api-key" || name.toLowerCase() === "cookie" || name.toLowerCase() === "set-cookie" ? "***" : value
|
|
894
|
+
]));
|
|
895
|
+
}
|
|
896
|
+
if ("retryOfRequestLogID" in details) {
|
|
897
|
+
if (details.retryOfRequestLogID) {
|
|
898
|
+
details.retryOf = details.retryOfRequestLogID;
|
|
899
|
+
}
|
|
900
|
+
delete details.retryOfRequestLogID;
|
|
901
|
+
}
|
|
902
|
+
return details;
|
|
903
|
+
};
|
|
904
|
+
|
|
905
|
+
// node_modules/@letta-ai/letta-client/core/streaming.mjs
|
|
906
|
+
var _Stream_client;
|
|
907
|
+
|
|
908
|
+
class Stream {
|
|
909
|
+
constructor(iterator, controller, client) {
|
|
910
|
+
this.iterator = iterator;
|
|
911
|
+
_Stream_client.set(this, undefined);
|
|
912
|
+
this.controller = controller;
|
|
913
|
+
__classPrivateFieldSet(this, _Stream_client, client, "f");
|
|
914
|
+
}
|
|
915
|
+
static fromSSEResponse(response, controller, client) {
|
|
916
|
+
let consumed = false;
|
|
917
|
+
const logger = client ? loggerFor(client) : console;
|
|
918
|
+
async function* iterator() {
|
|
919
|
+
if (consumed) {
|
|
920
|
+
throw new LettaError("Cannot iterate over a consumed stream, use `.tee()` to split the stream.");
|
|
921
|
+
}
|
|
922
|
+
consumed = true;
|
|
923
|
+
let done = false;
|
|
924
|
+
try {
|
|
925
|
+
for await (const sse of _iterSSEMessages(response, controller)) {
|
|
926
|
+
if (done)
|
|
927
|
+
continue;
|
|
928
|
+
if (sse.data.startsWith("[DONE]")) {
|
|
929
|
+
done = true;
|
|
930
|
+
continue;
|
|
931
|
+
}
|
|
932
|
+
if (sse.event === "error") {
|
|
933
|
+
throw new APIError(undefined, safeJSON(sse.data) ?? sse.data, undefined, response.headers);
|
|
934
|
+
}
|
|
935
|
+
if (sse.event === null) {
|
|
936
|
+
try {
|
|
937
|
+
yield JSON.parse(sse.data);
|
|
938
|
+
} catch (e) {
|
|
939
|
+
logger.error(`Could not parse message into JSON:`, sse.data);
|
|
940
|
+
logger.error(`From chunk:`, sse.raw);
|
|
941
|
+
throw e;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
done = true;
|
|
946
|
+
} catch (e) {
|
|
947
|
+
if (isAbortError(e))
|
|
948
|
+
return;
|
|
949
|
+
throw e;
|
|
950
|
+
} finally {
|
|
951
|
+
if (!done)
|
|
952
|
+
controller.abort();
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
return new Stream(iterator, controller, client);
|
|
956
|
+
}
|
|
957
|
+
static fromReadableStream(readableStream, controller, client) {
|
|
958
|
+
let consumed = false;
|
|
959
|
+
async function* iterLines() {
|
|
960
|
+
const lineDecoder = new LineDecoder;
|
|
961
|
+
const iter = ReadableStreamToAsyncIterable(readableStream);
|
|
962
|
+
for await (const chunk of iter) {
|
|
963
|
+
for (const line of lineDecoder.decode(chunk)) {
|
|
964
|
+
yield line;
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
for (const line of lineDecoder.flush()) {
|
|
968
|
+
yield line;
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
async function* iterator() {
|
|
972
|
+
if (consumed) {
|
|
973
|
+
throw new LettaError("Cannot iterate over a consumed stream, use `.tee()` to split the stream.");
|
|
974
|
+
}
|
|
975
|
+
consumed = true;
|
|
976
|
+
let done = false;
|
|
977
|
+
try {
|
|
978
|
+
for await (const line of iterLines()) {
|
|
979
|
+
if (done)
|
|
980
|
+
continue;
|
|
981
|
+
if (line)
|
|
982
|
+
yield JSON.parse(line);
|
|
983
|
+
}
|
|
984
|
+
done = true;
|
|
985
|
+
} catch (e) {
|
|
986
|
+
if (isAbortError(e))
|
|
987
|
+
return;
|
|
988
|
+
throw e;
|
|
989
|
+
} finally {
|
|
990
|
+
if (!done)
|
|
991
|
+
controller.abort();
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
return new Stream(iterator, controller, client);
|
|
995
|
+
}
|
|
996
|
+
[(_Stream_client = new WeakMap, Symbol.asyncIterator)]() {
|
|
997
|
+
return this.iterator();
|
|
998
|
+
}
|
|
999
|
+
tee() {
|
|
1000
|
+
const left = [];
|
|
1001
|
+
const right = [];
|
|
1002
|
+
const iterator = this.iterator();
|
|
1003
|
+
const teeIterator = (queue) => {
|
|
1004
|
+
return {
|
|
1005
|
+
next: () => {
|
|
1006
|
+
if (queue.length === 0) {
|
|
1007
|
+
const result = iterator.next();
|
|
1008
|
+
left.push(result);
|
|
1009
|
+
right.push(result);
|
|
1010
|
+
}
|
|
1011
|
+
return queue.shift();
|
|
1012
|
+
}
|
|
1013
|
+
};
|
|
1014
|
+
};
|
|
1015
|
+
return [
|
|
1016
|
+
new Stream(() => teeIterator(left), this.controller, __classPrivateFieldGet(this, _Stream_client, "f")),
|
|
1017
|
+
new Stream(() => teeIterator(right), this.controller, __classPrivateFieldGet(this, _Stream_client, "f"))
|
|
1018
|
+
];
|
|
1019
|
+
}
|
|
1020
|
+
toReadableStream() {
|
|
1021
|
+
const self = this;
|
|
1022
|
+
let iter;
|
|
1023
|
+
return makeReadableStream({
|
|
1024
|
+
async start() {
|
|
1025
|
+
iter = self[Symbol.asyncIterator]();
|
|
1026
|
+
},
|
|
1027
|
+
async pull(ctrl) {
|
|
1028
|
+
try {
|
|
1029
|
+
const { value, done } = await iter.next();
|
|
1030
|
+
if (done)
|
|
1031
|
+
return ctrl.close();
|
|
1032
|
+
const bytes = encodeUTF8(JSON.stringify(value) + `
|
|
1033
|
+
`);
|
|
1034
|
+
ctrl.enqueue(bytes);
|
|
1035
|
+
} catch (err) {
|
|
1036
|
+
ctrl.error(err);
|
|
1037
|
+
}
|
|
1038
|
+
},
|
|
1039
|
+
async cancel() {
|
|
1040
|
+
await iter.return?.();
|
|
1041
|
+
}
|
|
1042
|
+
});
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
async function* _iterSSEMessages(response, controller) {
|
|
1046
|
+
if (!response.body) {
|
|
1047
|
+
controller.abort();
|
|
1048
|
+
if (typeof globalThis.navigator !== "undefined" && globalThis.navigator.product === "ReactNative") {
|
|
1049
|
+
throw new LettaError(`The default react-native fetch implementation does not support streaming. Please use expo/fetch: https://docs.expo.dev/versions/latest/sdk/expo/#expofetch-api`);
|
|
1050
|
+
}
|
|
1051
|
+
throw new LettaError(`Attempted to iterate over a response with no body`);
|
|
1052
|
+
}
|
|
1053
|
+
const sseDecoder = new SSEDecoder;
|
|
1054
|
+
const lineDecoder = new LineDecoder;
|
|
1055
|
+
const iter = ReadableStreamToAsyncIterable(response.body);
|
|
1056
|
+
for await (const sseChunk of iterSSEChunks(iter)) {
|
|
1057
|
+
for (const line of lineDecoder.decode(sseChunk)) {
|
|
1058
|
+
const sse = sseDecoder.decode(line);
|
|
1059
|
+
if (sse)
|
|
1060
|
+
yield sse;
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
for (const line of lineDecoder.flush()) {
|
|
1064
|
+
const sse = sseDecoder.decode(line);
|
|
1065
|
+
if (sse)
|
|
1066
|
+
yield sse;
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
async function* iterSSEChunks(iterator) {
|
|
1070
|
+
let data = new Uint8Array;
|
|
1071
|
+
for await (const chunk of iterator) {
|
|
1072
|
+
if (chunk == null) {
|
|
1073
|
+
continue;
|
|
1074
|
+
}
|
|
1075
|
+
const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk) : typeof chunk === "string" ? encodeUTF8(chunk) : chunk;
|
|
1076
|
+
let newData = new Uint8Array(data.length + binaryChunk.length);
|
|
1077
|
+
newData.set(data);
|
|
1078
|
+
newData.set(binaryChunk, data.length);
|
|
1079
|
+
data = newData;
|
|
1080
|
+
let patternIndex;
|
|
1081
|
+
while ((patternIndex = findDoubleNewlineIndex(data)) !== -1) {
|
|
1082
|
+
yield data.slice(0, patternIndex);
|
|
1083
|
+
data = data.slice(patternIndex);
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
if (data.length > 0) {
|
|
1087
|
+
yield data;
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
class SSEDecoder {
|
|
1092
|
+
constructor() {
|
|
1093
|
+
this.event = null;
|
|
1094
|
+
this.data = [];
|
|
1095
|
+
this.chunks = [];
|
|
1096
|
+
}
|
|
1097
|
+
decode(line) {
|
|
1098
|
+
if (line.endsWith("\r")) {
|
|
1099
|
+
line = line.substring(0, line.length - 1);
|
|
1100
|
+
}
|
|
1101
|
+
if (!line) {
|
|
1102
|
+
if (!this.event && !this.data.length)
|
|
1103
|
+
return null;
|
|
1104
|
+
const sse = {
|
|
1105
|
+
event: this.event,
|
|
1106
|
+
data: this.data.join(`
|
|
1107
|
+
`),
|
|
1108
|
+
raw: this.chunks
|
|
1109
|
+
};
|
|
1110
|
+
this.event = null;
|
|
1111
|
+
this.data = [];
|
|
1112
|
+
this.chunks = [];
|
|
1113
|
+
return sse;
|
|
1114
|
+
}
|
|
1115
|
+
this.chunks.push(line);
|
|
1116
|
+
if (line.startsWith(":")) {
|
|
1117
|
+
return null;
|
|
1118
|
+
}
|
|
1119
|
+
let [fieldname, _, value] = partition(line, ":");
|
|
1120
|
+
if (value.startsWith(" ")) {
|
|
1121
|
+
value = value.substring(1);
|
|
1122
|
+
}
|
|
1123
|
+
if (fieldname === "event") {
|
|
1124
|
+
this.event = value;
|
|
1125
|
+
} else if (fieldname === "data") {
|
|
1126
|
+
this.data.push(value);
|
|
1127
|
+
}
|
|
1128
|
+
return null;
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
function partition(str, delimiter) {
|
|
1132
|
+
const index = str.indexOf(delimiter);
|
|
1133
|
+
if (index !== -1) {
|
|
1134
|
+
return [str.substring(0, index), delimiter, str.substring(index + delimiter.length)];
|
|
1135
|
+
}
|
|
1136
|
+
return [str, "", ""];
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
// node_modules/@letta-ai/letta-client/internal/parse.mjs
|
|
1140
|
+
async function defaultParseResponse(client, props) {
|
|
1141
|
+
const { response, requestLogID, retryOfRequestLogID, startTime } = props;
|
|
1142
|
+
const body = await (async () => {
|
|
1143
|
+
if (props.options.stream) {
|
|
1144
|
+
loggerFor(client).debug("response", response.status, response.url, response.headers, response.body);
|
|
1145
|
+
if (props.options.__streamClass) {
|
|
1146
|
+
return props.options.__streamClass.fromSSEResponse(response, props.controller, client);
|
|
1147
|
+
}
|
|
1148
|
+
return Stream.fromSSEResponse(response, props.controller, client);
|
|
1149
|
+
}
|
|
1150
|
+
if (response.status === 204) {
|
|
1151
|
+
return null;
|
|
1152
|
+
}
|
|
1153
|
+
if (props.options.__binaryResponse) {
|
|
1154
|
+
return response;
|
|
1155
|
+
}
|
|
1156
|
+
const contentType = response.headers.get("content-type");
|
|
1157
|
+
const mediaType = contentType?.split(";")[0]?.trim();
|
|
1158
|
+
const isJSON = mediaType?.includes("application/json") || mediaType?.endsWith("+json");
|
|
1159
|
+
if (isJSON) {
|
|
1160
|
+
const contentLength = response.headers.get("content-length");
|
|
1161
|
+
if (contentLength === "0") {
|
|
1162
|
+
return;
|
|
1163
|
+
}
|
|
1164
|
+
const json = await response.json();
|
|
1165
|
+
return json;
|
|
1166
|
+
}
|
|
1167
|
+
const text = await response.text();
|
|
1168
|
+
return text;
|
|
1169
|
+
})();
|
|
1170
|
+
loggerFor(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails({
|
|
1171
|
+
retryOfRequestLogID,
|
|
1172
|
+
url: response.url,
|
|
1173
|
+
status: response.status,
|
|
1174
|
+
body,
|
|
1175
|
+
durationMs: Date.now() - startTime
|
|
1176
|
+
}));
|
|
1177
|
+
return body;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
// node_modules/@letta-ai/letta-client/core/api-promise.mjs
|
|
1181
|
+
var _APIPromise_client;
|
|
1182
|
+
|
|
1183
|
+
class APIPromise extends Promise {
|
|
1184
|
+
constructor(client, responsePromise, parseResponse = defaultParseResponse) {
|
|
1185
|
+
super((resolve) => {
|
|
1186
|
+
resolve(null);
|
|
1187
|
+
});
|
|
1188
|
+
this.responsePromise = responsePromise;
|
|
1189
|
+
this.parseResponse = parseResponse;
|
|
1190
|
+
_APIPromise_client.set(this, undefined);
|
|
1191
|
+
__classPrivateFieldSet(this, _APIPromise_client, client, "f");
|
|
1192
|
+
}
|
|
1193
|
+
_thenUnwrap(transform) {
|
|
1194
|
+
return new APIPromise(__classPrivateFieldGet(this, _APIPromise_client, "f"), this.responsePromise, async (client, props) => transform(await this.parseResponse(client, props), props));
|
|
1195
|
+
}
|
|
1196
|
+
asResponse() {
|
|
1197
|
+
return this.responsePromise.then((p) => p.response);
|
|
1198
|
+
}
|
|
1199
|
+
async withResponse() {
|
|
1200
|
+
const [data, response] = await Promise.all([this.parse(), this.asResponse()]);
|
|
1201
|
+
return { data, response };
|
|
1202
|
+
}
|
|
1203
|
+
parse() {
|
|
1204
|
+
if (!this.parsedPromise) {
|
|
1205
|
+
this.parsedPromise = this.responsePromise.then((data) => this.parseResponse(__classPrivateFieldGet(this, _APIPromise_client, "f"), data));
|
|
1206
|
+
}
|
|
1207
|
+
return this.parsedPromise;
|
|
1208
|
+
}
|
|
1209
|
+
then(onfulfilled, onrejected) {
|
|
1210
|
+
return this.parse().then(onfulfilled, onrejected);
|
|
1211
|
+
}
|
|
1212
|
+
catch(onrejected) {
|
|
1213
|
+
return this.parse().catch(onrejected);
|
|
1214
|
+
}
|
|
1215
|
+
finally(onfinally) {
|
|
1216
|
+
return this.parse().finally(onfinally);
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
_APIPromise_client = new WeakMap;
|
|
1220
|
+
|
|
1221
|
+
// node_modules/@letta-ai/letta-client/core/pagination.mjs
|
|
1222
|
+
var _AbstractPage_client;
|
|
1223
|
+
|
|
1224
|
+
class AbstractPage {
|
|
1225
|
+
constructor(client, response, body, options) {
|
|
1226
|
+
_AbstractPage_client.set(this, undefined);
|
|
1227
|
+
__classPrivateFieldSet(this, _AbstractPage_client, client, "f");
|
|
1228
|
+
this.options = options;
|
|
1229
|
+
this.response = response;
|
|
1230
|
+
this.body = body;
|
|
1231
|
+
}
|
|
1232
|
+
hasNextPage() {
|
|
1233
|
+
const items = this.getPaginatedItems();
|
|
1234
|
+
if (!items.length)
|
|
1235
|
+
return false;
|
|
1236
|
+
return this.nextPageRequestOptions() != null;
|
|
1237
|
+
}
|
|
1238
|
+
async getNextPage() {
|
|
1239
|
+
const nextOptions = this.nextPageRequestOptions();
|
|
1240
|
+
if (!nextOptions) {
|
|
1241
|
+
throw new LettaError("No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`.");
|
|
1242
|
+
}
|
|
1243
|
+
return await __classPrivateFieldGet(this, _AbstractPage_client, "f").requestAPIList(this.constructor, nextOptions);
|
|
1244
|
+
}
|
|
1245
|
+
async* iterPages() {
|
|
1246
|
+
let page = this;
|
|
1247
|
+
yield page;
|
|
1248
|
+
while (page.hasNextPage()) {
|
|
1249
|
+
page = await page.getNextPage();
|
|
1250
|
+
yield page;
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
async* [(_AbstractPage_client = new WeakMap, Symbol.asyncIterator)]() {
|
|
1254
|
+
for await (const page of this.iterPages()) {
|
|
1255
|
+
for (const item of page.getPaginatedItems()) {
|
|
1256
|
+
yield item;
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
class PagePromise extends APIPromise {
|
|
1263
|
+
constructor(client, request, Page) {
|
|
1264
|
+
super(client, request, async (client2, props) => new Page(client2, props.response, await defaultParseResponse(client2, props), props.options));
|
|
1265
|
+
}
|
|
1266
|
+
async* [Symbol.asyncIterator]() {
|
|
1267
|
+
const page = await this;
|
|
1268
|
+
for await (const item of page) {
|
|
1269
|
+
yield item;
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
class ArrayPage extends AbstractPage {
|
|
1275
|
+
constructor(client, response, body, options) {
|
|
1276
|
+
super(client, response, body, options);
|
|
1277
|
+
this.items = body || [];
|
|
1278
|
+
}
|
|
1279
|
+
getPaginatedItems() {
|
|
1280
|
+
return this.items ?? [];
|
|
1281
|
+
}
|
|
1282
|
+
nextPageRequestOptions() {
|
|
1283
|
+
const items = this.getPaginatedItems();
|
|
1284
|
+
const isForwards = !(typeof this.options.query === "object" && ("before" in (this.options.query || {})));
|
|
1285
|
+
if (isForwards) {
|
|
1286
|
+
const id2 = items[items.length - 1]?.id;
|
|
1287
|
+
if (!id2) {
|
|
1288
|
+
return null;
|
|
1289
|
+
}
|
|
1290
|
+
return {
|
|
1291
|
+
...this.options,
|
|
1292
|
+
query: {
|
|
1293
|
+
...maybeObj(this.options.query),
|
|
1294
|
+
after: id2
|
|
1295
|
+
}
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
const id = items[0]?.id;
|
|
1299
|
+
if (!id) {
|
|
1300
|
+
return null;
|
|
1301
|
+
}
|
|
1302
|
+
return {
|
|
1303
|
+
...this.options,
|
|
1304
|
+
query: {
|
|
1305
|
+
...maybeObj(this.options.query),
|
|
1306
|
+
before: id
|
|
1307
|
+
}
|
|
1308
|
+
};
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
class NextFilesPage extends AbstractPage {
|
|
1312
|
+
constructor(client, response, body, options) {
|
|
1313
|
+
super(client, response, body, options);
|
|
1314
|
+
this.files = body.files || [];
|
|
1315
|
+
this.next_cursor = body.next_cursor || null;
|
|
1316
|
+
this.has_more = body.has_more || false;
|
|
1317
|
+
}
|
|
1318
|
+
getPaginatedItems() {
|
|
1319
|
+
return this.files ?? [];
|
|
1320
|
+
}
|
|
1321
|
+
hasNextPage() {
|
|
1322
|
+
if (this.has_more === false) {
|
|
1323
|
+
return false;
|
|
1324
|
+
}
|
|
1325
|
+
return super.hasNextPage();
|
|
1326
|
+
}
|
|
1327
|
+
nextPageRequestOptions() {
|
|
1328
|
+
const files = this.getPaginatedItems();
|
|
1329
|
+
const isForwards = !(typeof this.options.query === "object" && ("before" in (this.options.query || {})));
|
|
1330
|
+
if (isForwards) {
|
|
1331
|
+
const id2 = files[files.length - 1]?.id;
|
|
1332
|
+
if (!id2) {
|
|
1333
|
+
return null;
|
|
1334
|
+
}
|
|
1335
|
+
return {
|
|
1336
|
+
...this.options,
|
|
1337
|
+
query: {
|
|
1338
|
+
...maybeObj(this.options.query),
|
|
1339
|
+
after: id2
|
|
1340
|
+
}
|
|
1341
|
+
};
|
|
1342
|
+
}
|
|
1343
|
+
const id = files[0]?.id;
|
|
1344
|
+
if (!id) {
|
|
1345
|
+
return null;
|
|
1346
|
+
}
|
|
1347
|
+
return {
|
|
1348
|
+
...this.options,
|
|
1349
|
+
query: {
|
|
1350
|
+
...maybeObj(this.options.query),
|
|
1351
|
+
before: id
|
|
1352
|
+
}
|
|
1353
|
+
};
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
// node_modules/@letta-ai/letta-client/internal/uploads.mjs
|
|
1358
|
+
var checkFileSupport = () => {
|
|
1359
|
+
if (typeof File === "undefined") {
|
|
1360
|
+
const { process } = globalThis;
|
|
1361
|
+
const isOldNode = typeof process?.versions?.node === "string" && parseInt(process.versions.node.split(".")) < 20;
|
|
1362
|
+
throw new Error("`File` is not defined as a global, which is required for file uploads." + (isOldNode ? " Update to Node 20 LTS or newer, or set `globalThis.File` to `import('node:buffer').File`." : ""));
|
|
1363
|
+
}
|
|
1364
|
+
};
|
|
1365
|
+
function makeFile(fileBits, fileName, options) {
|
|
1366
|
+
checkFileSupport();
|
|
1367
|
+
return new File(fileBits, fileName ?? "unknown_file", options);
|
|
1368
|
+
}
|
|
1369
|
+
function getName(value) {
|
|
1370
|
+
return (typeof value === "object" && value !== null && (("name" in value) && value.name && String(value.name) || ("url" in value) && value.url && String(value.url) || ("filename" in value) && value.filename && String(value.filename) || ("path" in value) && value.path && String(value.path)) || "").split(/[\\/]/).pop() || undefined;
|
|
1371
|
+
}
|
|
1372
|
+
var isAsyncIterable = (value) => value != null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function";
|
|
1373
|
+
var multipartFormRequestOptions = async (opts, fetch2) => {
|
|
1374
|
+
return { ...opts, body: await createForm(opts.body, fetch2) };
|
|
1375
|
+
};
|
|
1376
|
+
var supportsFormDataMap = /* @__PURE__ */ new WeakMap;
|
|
1377
|
+
function supportsFormData(fetchObject) {
|
|
1378
|
+
const fetch2 = typeof fetchObject === "function" ? fetchObject : fetchObject.fetch;
|
|
1379
|
+
const cached = supportsFormDataMap.get(fetch2);
|
|
1380
|
+
if (cached)
|
|
1381
|
+
return cached;
|
|
1382
|
+
const promise = (async () => {
|
|
1383
|
+
try {
|
|
1384
|
+
const FetchResponse = "Response" in fetch2 ? fetch2.Response : (await fetch2("data:,")).constructor;
|
|
1385
|
+
const data = new FormData;
|
|
1386
|
+
if (data.toString() === await new FetchResponse(data).text()) {
|
|
1387
|
+
return false;
|
|
1388
|
+
}
|
|
1389
|
+
return true;
|
|
1390
|
+
} catch {
|
|
1391
|
+
return true;
|
|
1392
|
+
}
|
|
1393
|
+
})();
|
|
1394
|
+
supportsFormDataMap.set(fetch2, promise);
|
|
1395
|
+
return promise;
|
|
1396
|
+
}
|
|
1397
|
+
var createForm = async (body, fetch2) => {
|
|
1398
|
+
if (!await supportsFormData(fetch2)) {
|
|
1399
|
+
throw new TypeError("The provided fetch function does not support file uploads with the current global FormData class.");
|
|
1400
|
+
}
|
|
1401
|
+
const form = new FormData;
|
|
1402
|
+
await Promise.all(Object.entries(body || {}).map(([key, value]) => addFormValue(form, key, value)));
|
|
1403
|
+
return form;
|
|
1404
|
+
};
|
|
1405
|
+
var isNamedBlob = (value) => value instanceof Blob && ("name" in value);
|
|
1406
|
+
var addFormValue = async (form, key, value) => {
|
|
1407
|
+
if (value === undefined)
|
|
1408
|
+
return;
|
|
1409
|
+
if (value == null) {
|
|
1410
|
+
throw new TypeError(`Received null for "${key}"; to pass null in FormData, you must use the string 'null'`);
|
|
1411
|
+
}
|
|
1412
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
1413
|
+
form.append(key, String(value));
|
|
1414
|
+
} else if (value instanceof Response) {
|
|
1415
|
+
form.append(key, makeFile([await value.blob()], getName(value)));
|
|
1416
|
+
} else if (isAsyncIterable(value)) {
|
|
1417
|
+
form.append(key, makeFile([await new Response(ReadableStreamFrom(value)).blob()], getName(value)));
|
|
1418
|
+
} else if (isNamedBlob(value)) {
|
|
1419
|
+
form.append(key, value, getName(value));
|
|
1420
|
+
} else if (Array.isArray(value)) {
|
|
1421
|
+
await Promise.all(value.map((entry) => addFormValue(form, key + "[]", entry)));
|
|
1422
|
+
} else if (typeof value === "object") {
|
|
1423
|
+
await Promise.all(Object.entries(value).map(([name, prop]) => addFormValue(form, `${key}[${name}]`, prop)));
|
|
1424
|
+
} else {
|
|
1425
|
+
throw new TypeError(`Invalid value given to form, expected a string, number, boolean, object, Array, File or Blob but got ${value} instead`);
|
|
1426
|
+
}
|
|
1427
|
+
};
|
|
1428
|
+
|
|
1429
|
+
// node_modules/@letta-ai/letta-client/internal/to-file.mjs
|
|
1430
|
+
var isBlobLike = (value) => value != null && typeof value === "object" && typeof value.size === "number" && typeof value.type === "string" && typeof value.text === "function" && typeof value.slice === "function" && typeof value.arrayBuffer === "function";
|
|
1431
|
+
var isFileLike = (value) => value != null && typeof value === "object" && typeof value.name === "string" && typeof value.lastModified === "number" && isBlobLike(value);
|
|
1432
|
+
var isResponseLike = (value) => value != null && typeof value === "object" && typeof value.url === "string" && typeof value.blob === "function";
|
|
1433
|
+
async function toFile(value, name, options) {
|
|
1434
|
+
checkFileSupport();
|
|
1435
|
+
value = await value;
|
|
1436
|
+
if (isFileLike(value)) {
|
|
1437
|
+
if (value instanceof File) {
|
|
1438
|
+
return value;
|
|
1439
|
+
}
|
|
1440
|
+
return makeFile([await value.arrayBuffer()], value.name);
|
|
1441
|
+
}
|
|
1442
|
+
if (isResponseLike(value)) {
|
|
1443
|
+
const blob = await value.blob();
|
|
1444
|
+
name || (name = new URL(value.url).pathname.split(/[\\/]/).pop());
|
|
1445
|
+
return makeFile(await getBytes(blob), name, options);
|
|
1446
|
+
}
|
|
1447
|
+
const parts = await getBytes(value);
|
|
1448
|
+
name || (name = getName(value));
|
|
1449
|
+
if (!options?.type) {
|
|
1450
|
+
const type = parts.find((part) => typeof part === "object" && ("type" in part) && part.type);
|
|
1451
|
+
if (typeof type === "string") {
|
|
1452
|
+
options = { ...options, type };
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
return makeFile(parts, name, options);
|
|
1456
|
+
}
|
|
1457
|
+
async function getBytes(value) {
|
|
1458
|
+
let parts = [];
|
|
1459
|
+
if (typeof value === "string" || ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
|
|
1460
|
+
parts.push(value);
|
|
1461
|
+
} else if (isBlobLike(value)) {
|
|
1462
|
+
parts.push(value instanceof Blob ? value : await value.arrayBuffer());
|
|
1463
|
+
} else if (isAsyncIterable(value)) {
|
|
1464
|
+
for await (const chunk of value) {
|
|
1465
|
+
parts.push(...await getBytes(chunk));
|
|
1466
|
+
}
|
|
1467
|
+
} else {
|
|
1468
|
+
const constructor = value?.constructor?.name;
|
|
1469
|
+
throw new Error(`Unexpected data type: ${typeof value}${constructor ? `; constructor: ${constructor}` : ""}${propsForError(value)}`);
|
|
1470
|
+
}
|
|
1471
|
+
return parts;
|
|
1472
|
+
}
|
|
1473
|
+
function propsForError(value) {
|
|
1474
|
+
if (typeof value !== "object" || value === null)
|
|
1475
|
+
return "";
|
|
1476
|
+
const props = Object.getOwnPropertyNames(value);
|
|
1477
|
+
return `; props: [${props.map((p) => `"${p}"`).join(", ")}]`;
|
|
1478
|
+
}
|
|
1479
|
+
// node_modules/@letta-ai/letta-client/core/resource.mjs
|
|
1480
|
+
class APIResource {
|
|
1481
|
+
constructor(client) {
|
|
1482
|
+
this._client = client;
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
// node_modules/@letta-ai/letta-client/internal/utils/path.mjs
|
|
1487
|
+
function encodeURIPath(str) {
|
|
1488
|
+
return str.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent);
|
|
1489
|
+
}
|
|
1490
|
+
var EMPTY = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.create(null));
|
|
1491
|
+
var createPathTagFunction = (pathEncoder = encodeURIPath) => function path(statics, ...params) {
|
|
1492
|
+
if (statics.length === 1)
|
|
1493
|
+
return statics[0];
|
|
1494
|
+
let postPath = false;
|
|
1495
|
+
const invalidSegments = [];
|
|
1496
|
+
const path = statics.reduce((previousValue, currentValue, index) => {
|
|
1497
|
+
if (/[?#]/.test(currentValue)) {
|
|
1498
|
+
postPath = true;
|
|
1499
|
+
}
|
|
1500
|
+
const value = params[index];
|
|
1501
|
+
let encoded = (postPath ? encodeURIComponent : pathEncoder)("" + value);
|
|
1502
|
+
if (index !== params.length && (value == null || typeof value === "object" && value.toString === Object.getPrototypeOf(Object.getPrototypeOf(value.hasOwnProperty ?? EMPTY) ?? EMPTY)?.toString)) {
|
|
1503
|
+
encoded = value + "";
|
|
1504
|
+
invalidSegments.push({
|
|
1505
|
+
start: previousValue.length + currentValue.length,
|
|
1506
|
+
length: encoded.length,
|
|
1507
|
+
error: `Value of type ${Object.prototype.toString.call(value).slice(8, -1)} is not a valid path parameter`
|
|
1508
|
+
});
|
|
1509
|
+
}
|
|
1510
|
+
return previousValue + currentValue + (index === params.length ? "" : encoded);
|
|
1511
|
+
}, "");
|
|
1512
|
+
const pathOnly = path.split(/[?#]/, 1)[0];
|
|
1513
|
+
const invalidSegmentPattern = /(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi;
|
|
1514
|
+
let match;
|
|
1515
|
+
while ((match = invalidSegmentPattern.exec(pathOnly)) !== null) {
|
|
1516
|
+
invalidSegments.push({
|
|
1517
|
+
start: match.index,
|
|
1518
|
+
length: match[0].length,
|
|
1519
|
+
error: `Value "${match[0]}" can't be safely passed as a path parameter`
|
|
1520
|
+
});
|
|
1521
|
+
}
|
|
1522
|
+
invalidSegments.sort((a, b) => a.start - b.start);
|
|
1523
|
+
if (invalidSegments.length > 0) {
|
|
1524
|
+
let lastEnd = 0;
|
|
1525
|
+
const underline = invalidSegments.reduce((acc, segment) => {
|
|
1526
|
+
const spaces = " ".repeat(segment.start - lastEnd);
|
|
1527
|
+
const arrows = "^".repeat(segment.length);
|
|
1528
|
+
lastEnd = segment.start + segment.length;
|
|
1529
|
+
return acc + spaces + arrows;
|
|
1530
|
+
}, "");
|
|
1531
|
+
throw new LettaError(`Path parameters result in path with invalid segments:
|
|
1532
|
+
${invalidSegments.map((e) => e.error).join(`
|
|
1533
|
+
`)}
|
|
1534
|
+
${path}
|
|
1535
|
+
${underline}`);
|
|
1536
|
+
}
|
|
1537
|
+
return path;
|
|
1538
|
+
};
|
|
1539
|
+
var path = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
|
|
1540
|
+
|
|
1541
|
+
// node_modules/@letta-ai/letta-client/resources/access-tokens.mjs
|
|
1542
|
+
class AccessTokens extends APIResource {
|
|
1543
|
+
create(body, options) {
|
|
1544
|
+
return this._client.post("/v1/client-side-access-tokens", { body, ...options });
|
|
1545
|
+
}
|
|
1546
|
+
list(query = {}, options) {
|
|
1547
|
+
return this._client.get("/v1/client-side-access-tokens", { query, ...options });
|
|
1548
|
+
}
|
|
1549
|
+
delete(token, params = undefined, options) {
|
|
1550
|
+
const { body } = params ?? {};
|
|
1551
|
+
return this._client.delete(path`/v1/client-side-access-tokens/${token}`, { body, ...options });
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
// node_modules/@letta-ai/letta-client/resources/agents/archives.mjs
|
|
1555
|
+
class Archives extends APIResource {
|
|
1556
|
+
attach(archiveID, params, options) {
|
|
1557
|
+
const { agent_id } = params;
|
|
1558
|
+
return this._client.patch(path`/v1/agents/${agent_id}/archives/attach/${archiveID}`, options);
|
|
1559
|
+
}
|
|
1560
|
+
detach(archiveID, params, options) {
|
|
1561
|
+
const { agent_id } = params;
|
|
1562
|
+
return this._client.patch(path`/v1/agents/${agent_id}/archives/detach/${archiveID}`, options);
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
// node_modules/@letta-ai/letta-client/resources/agents/blocks.mjs
|
|
1567
|
+
class Blocks extends APIResource {
|
|
1568
|
+
retrieve(blockLabel, params, options) {
|
|
1569
|
+
const { agent_id } = params;
|
|
1570
|
+
return this._client.get(path`/v1/agents/${agent_id}/core-memory/blocks/${blockLabel}`, options);
|
|
1571
|
+
}
|
|
1572
|
+
update(blockLabel, params, options) {
|
|
1573
|
+
const { agent_id, ...body } = params;
|
|
1574
|
+
return this._client.patch(path`/v1/agents/${agent_id}/core-memory/blocks/${blockLabel}`, {
|
|
1575
|
+
body,
|
|
1576
|
+
...options
|
|
1577
|
+
});
|
|
1578
|
+
}
|
|
1579
|
+
list(agentID, query = {}, options) {
|
|
1580
|
+
return this._client.getAPIList(path`/v1/agents/${agentID}/core-memory/blocks`, ArrayPage, { query, ...options });
|
|
1581
|
+
}
|
|
1582
|
+
attach(blockID, params, options) {
|
|
1583
|
+
const { agent_id } = params;
|
|
1584
|
+
return this._client.patch(path`/v1/agents/${agent_id}/core-memory/blocks/attach/${blockID}`, options);
|
|
1585
|
+
}
|
|
1586
|
+
detach(blockID, params, options) {
|
|
1587
|
+
const { agent_id } = params;
|
|
1588
|
+
return this._client.patch(path`/v1/agents/${agent_id}/core-memory/blocks/detach/${blockID}`, options);
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
// node_modules/@letta-ai/letta-client/resources/agents/files.mjs
|
|
1593
|
+
class Files extends APIResource {
|
|
1594
|
+
list(agentID, query = {}, options) {
|
|
1595
|
+
return this._client.getAPIList(path`/v1/agents/${agentID}/files`, NextFilesPage, {
|
|
1596
|
+
query,
|
|
1597
|
+
...options
|
|
1598
|
+
});
|
|
1599
|
+
}
|
|
1600
|
+
close(fileID, params, options) {
|
|
1601
|
+
const { agent_id } = params;
|
|
1602
|
+
return this._client.patch(path`/v1/agents/${agent_id}/files/${fileID}/close`, options);
|
|
1603
|
+
}
|
|
1604
|
+
closeAll(agentID, options) {
|
|
1605
|
+
return this._client.patch(path`/v1/agents/${agentID}/files/close-all`, options);
|
|
1606
|
+
}
|
|
1607
|
+
open(fileID, params, options) {
|
|
1608
|
+
const { agent_id } = params;
|
|
1609
|
+
return this._client.patch(path`/v1/agents/${agent_id}/files/${fileID}/open`, options);
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
// node_modules/@letta-ai/letta-client/resources/agents/folders.mjs
|
|
1614
|
+
class Folders extends APIResource {
|
|
1615
|
+
list(agentID, query = {}, options) {
|
|
1616
|
+
return this._client.getAPIList(path`/v1/agents/${agentID}/folders`, ArrayPage, {
|
|
1617
|
+
query,
|
|
1618
|
+
...options
|
|
1619
|
+
});
|
|
1620
|
+
}
|
|
1621
|
+
attach(folderID, params, options) {
|
|
1622
|
+
const { agent_id } = params;
|
|
1623
|
+
return this._client.patch(path`/v1/agents/${agent_id}/folders/attach/${folderID}`, options);
|
|
1624
|
+
}
|
|
1625
|
+
detach(folderID, params, options) {
|
|
1626
|
+
const { agent_id } = params;
|
|
1627
|
+
return this._client.patch(path`/v1/agents/${agent_id}/folders/detach/${folderID}`, options);
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
|
|
1631
|
+
// node_modules/@letta-ai/letta-client/resources/agents/identities.mjs
|
|
1632
|
+
class Identities extends APIResource {
|
|
1633
|
+
attach(identityID, params, options) {
|
|
1634
|
+
const { agent_id } = params;
|
|
1635
|
+
return this._client.patch(path`/v1/agents/${agent_id}/identities/attach/${identityID}`, options);
|
|
1636
|
+
}
|
|
1637
|
+
detach(identityID, params, options) {
|
|
1638
|
+
const { agent_id } = params;
|
|
1639
|
+
return this._client.patch(path`/v1/agents/${agent_id}/identities/detach/${identityID}`, options);
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
// node_modules/@letta-ai/letta-client/resources/agents/messages.mjs
|
|
1644
|
+
class Messages extends APIResource {
|
|
1645
|
+
create(agentID, body, options) {
|
|
1646
|
+
return this._client.post(path`/v1/agents/${agentID}/messages`, {
|
|
1647
|
+
body,
|
|
1648
|
+
...options,
|
|
1649
|
+
stream: body.streaming ?? false
|
|
1650
|
+
});
|
|
1651
|
+
}
|
|
1652
|
+
list(agentID, query = {}, options) {
|
|
1653
|
+
return this._client.getAPIList(path`/v1/agents/${agentID}/messages`, ArrayPage, {
|
|
1654
|
+
query,
|
|
1655
|
+
...options
|
|
1656
|
+
});
|
|
1657
|
+
}
|
|
1658
|
+
cancel(agentID, body = {}, options) {
|
|
1659
|
+
return this._client.post(path`/v1/agents/${agentID}/messages/cancel`, { body, ...options });
|
|
1660
|
+
}
|
|
1661
|
+
compact(agentID, body = {}, options) {
|
|
1662
|
+
return this._client.post(path`/v1/agents/${agentID}/summarize`, { body, ...options });
|
|
1663
|
+
}
|
|
1664
|
+
createAsync(agentID, body, options) {
|
|
1665
|
+
return this._client.post(path`/v1/agents/${agentID}/messages/async`, { body, ...options });
|
|
1666
|
+
}
|
|
1667
|
+
reset(agentID, body, options) {
|
|
1668
|
+
return this._client.patch(path`/v1/agents/${agentID}/reset-messages`, { body, ...options });
|
|
1669
|
+
}
|
|
1670
|
+
stream(agentID, body, options) {
|
|
1671
|
+
return this._client.post(path`/v1/agents/${agentID}/messages/stream`, {
|
|
1672
|
+
body,
|
|
1673
|
+
...options,
|
|
1674
|
+
stream: true
|
|
1675
|
+
});
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
// node_modules/@letta-ai/letta-client/resources/agents/passages.mjs
|
|
1680
|
+
class Passages extends APIResource {
|
|
1681
|
+
create(agentID, body, options) {
|
|
1682
|
+
return this._client.post(path`/v1/agents/${agentID}/archival-memory`, { body, ...options });
|
|
1683
|
+
}
|
|
1684
|
+
list(agentID, query = {}, options) {
|
|
1685
|
+
return this._client.get(path`/v1/agents/${agentID}/archival-memory`, { query, ...options });
|
|
1686
|
+
}
|
|
1687
|
+
delete(memoryID, params, options) {
|
|
1688
|
+
const { agent_id } = params;
|
|
1689
|
+
return this._client.delete(path`/v1/agents/${agent_id}/archival-memory/${memoryID}`, options);
|
|
1690
|
+
}
|
|
1691
|
+
search(agentID, query, options) {
|
|
1692
|
+
return this._client.get(path`/v1/agents/${agentID}/archival-memory/search`, { query, ...options });
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
// node_modules/@letta-ai/letta-client/resources/agents/schedule.mjs
|
|
1697
|
+
class Schedule extends APIResource {
|
|
1698
|
+
create(agentID, body, options) {
|
|
1699
|
+
return this._client.post(path`/v1/agents/${agentID}/schedule`, { body, ...options });
|
|
1700
|
+
}
|
|
1701
|
+
retrieve(scheduledMessageID, params, options) {
|
|
1702
|
+
const { agent_id } = params;
|
|
1703
|
+
return this._client.get(path`/v1/agents/${agent_id}/schedule/${scheduledMessageID}`, options);
|
|
1704
|
+
}
|
|
1705
|
+
list(agentID, query = {}, options) {
|
|
1706
|
+
return this._client.get(path`/v1/agents/${agentID}/schedule`, { query, ...options });
|
|
1707
|
+
}
|
|
1708
|
+
delete(scheduledMessageID, params, options) {
|
|
1709
|
+
const { agent_id, ...body } = params;
|
|
1710
|
+
return this._client.delete(path`/v1/agents/${agent_id}/schedule/${scheduledMessageID}`, {
|
|
1711
|
+
body,
|
|
1712
|
+
...options
|
|
1713
|
+
});
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
// node_modules/@letta-ai/letta-client/resources/agents/tools.mjs
|
|
1718
|
+
class Tools extends APIResource {
|
|
1719
|
+
list(agentID, query = {}, options) {
|
|
1720
|
+
return this._client.getAPIList(path`/v1/agents/${agentID}/tools`, ArrayPage, {
|
|
1721
|
+
query,
|
|
1722
|
+
...options
|
|
1723
|
+
});
|
|
1724
|
+
}
|
|
1725
|
+
attach(toolID, params, options) {
|
|
1726
|
+
const { agent_id } = params;
|
|
1727
|
+
return this._client.patch(path`/v1/agents/${agent_id}/tools/attach/${toolID}`, options);
|
|
1728
|
+
}
|
|
1729
|
+
detach(toolID, params, options) {
|
|
1730
|
+
const { agent_id } = params;
|
|
1731
|
+
return this._client.patch(path`/v1/agents/${agent_id}/tools/detach/${toolID}`, options);
|
|
1732
|
+
}
|
|
1733
|
+
run(toolName, params, options) {
|
|
1734
|
+
const { agent_id, ...body } = params;
|
|
1735
|
+
return this._client.post(path`/v1/agents/${agent_id}/tools/${toolName}/run`, { body, ...options });
|
|
1736
|
+
}
|
|
1737
|
+
updateApproval(toolName, params, options) {
|
|
1738
|
+
const { agent_id, query_requires_approval, ...body } = params;
|
|
1739
|
+
return this._client.patch(path`/v1/agents/${agent_id}/tools/approval/${toolName}`, {
|
|
1740
|
+
query: { requires_approval: query_requires_approval },
|
|
1741
|
+
body,
|
|
1742
|
+
...options
|
|
1743
|
+
});
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
// node_modules/@letta-ai/letta-client/internal/headers.mjs
|
|
1748
|
+
var brand_privateNullableHeaders = /* @__PURE__ */ Symbol("brand.privateNullableHeaders");
|
|
1749
|
+
function* iterateHeaders(headers) {
|
|
1750
|
+
if (!headers)
|
|
1751
|
+
return;
|
|
1752
|
+
if (brand_privateNullableHeaders in headers) {
|
|
1753
|
+
const { values, nulls } = headers;
|
|
1754
|
+
yield* values.entries();
|
|
1755
|
+
for (const name of nulls) {
|
|
1756
|
+
yield [name, null];
|
|
1757
|
+
}
|
|
1758
|
+
return;
|
|
1759
|
+
}
|
|
1760
|
+
let shouldClear = false;
|
|
1761
|
+
let iter;
|
|
1762
|
+
if (headers instanceof Headers) {
|
|
1763
|
+
iter = headers.entries();
|
|
1764
|
+
} else if (isReadonlyArray(headers)) {
|
|
1765
|
+
iter = headers;
|
|
1766
|
+
} else {
|
|
1767
|
+
shouldClear = true;
|
|
1768
|
+
iter = Object.entries(headers ?? {});
|
|
1769
|
+
}
|
|
1770
|
+
for (let row of iter) {
|
|
1771
|
+
const name = row[0];
|
|
1772
|
+
if (typeof name !== "string")
|
|
1773
|
+
throw new TypeError("expected header name to be a string");
|
|
1774
|
+
const values = isReadonlyArray(row[1]) ? row[1] : [row[1]];
|
|
1775
|
+
let didClear = false;
|
|
1776
|
+
for (const value of values) {
|
|
1777
|
+
if (value === undefined)
|
|
1778
|
+
continue;
|
|
1779
|
+
if (shouldClear && !didClear) {
|
|
1780
|
+
didClear = true;
|
|
1781
|
+
yield [name, null];
|
|
1782
|
+
}
|
|
1783
|
+
yield [name, value];
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
var buildHeaders = (newHeaders) => {
|
|
1788
|
+
const targetHeaders = new Headers;
|
|
1789
|
+
const nullHeaders = new Set;
|
|
1790
|
+
for (const headers of newHeaders) {
|
|
1791
|
+
const seenHeaders = new Set;
|
|
1792
|
+
for (const [name, value] of iterateHeaders(headers)) {
|
|
1793
|
+
const lowerName = name.toLowerCase();
|
|
1794
|
+
if (!seenHeaders.has(lowerName)) {
|
|
1795
|
+
targetHeaders.delete(name);
|
|
1796
|
+
seenHeaders.add(lowerName);
|
|
1797
|
+
}
|
|
1798
|
+
if (value === null) {
|
|
1799
|
+
targetHeaders.delete(name);
|
|
1800
|
+
nullHeaders.add(lowerName);
|
|
1801
|
+
} else {
|
|
1802
|
+
targetHeaders.append(name, value);
|
|
1803
|
+
nullHeaders.delete(lowerName);
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
return { [brand_privateNullableHeaders]: true, values: targetHeaders, nulls: nullHeaders };
|
|
1808
|
+
};
|
|
1809
|
+
|
|
1810
|
+
// node_modules/@letta-ai/letta-client/resources/agents/agents.mjs
|
|
1811
|
+
class Agents extends APIResource {
|
|
1812
|
+
constructor() {
|
|
1813
|
+
super(...arguments);
|
|
1814
|
+
this.messages = new Messages(this._client);
|
|
1815
|
+
this.schedule = new Schedule(this._client);
|
|
1816
|
+
this.blocks = new Blocks(this._client);
|
|
1817
|
+
this.tools = new Tools(this._client);
|
|
1818
|
+
this.folders = new Folders(this._client);
|
|
1819
|
+
this.files = new Files(this._client);
|
|
1820
|
+
this.archives = new Archives(this._client);
|
|
1821
|
+
this.passages = new Passages(this._client);
|
|
1822
|
+
this.identities = new Identities(this._client);
|
|
1823
|
+
}
|
|
1824
|
+
create(body, options) {
|
|
1825
|
+
return this._client.post("/v1/agents/", { body, ...options });
|
|
1826
|
+
}
|
|
1827
|
+
retrieve(agentID, query = {}, options) {
|
|
1828
|
+
return this._client.get(path`/v1/agents/${agentID}`, { query, ...options });
|
|
1829
|
+
}
|
|
1830
|
+
update(agentID, body, options) {
|
|
1831
|
+
return this._client.patch(path`/v1/agents/${agentID}`, { body, ...options });
|
|
1832
|
+
}
|
|
1833
|
+
list(query = {}, options) {
|
|
1834
|
+
return this._client.getAPIList("/v1/agents/", ArrayPage, { query, ...options });
|
|
1835
|
+
}
|
|
1836
|
+
delete(agentID, options) {
|
|
1837
|
+
return this._client.delete(path`/v1/agents/${agentID}`, options);
|
|
1838
|
+
}
|
|
1839
|
+
exportFile(agentID, query = {}, options) {
|
|
1840
|
+
return this._client.get(path`/v1/agents/${agentID}/export`, { query, ...options });
|
|
1841
|
+
}
|
|
1842
|
+
importFile(params, options) {
|
|
1843
|
+
const { "x-override-embedding-model": xOverrideEmbeddingModel, ...body } = params;
|
|
1844
|
+
return this._client.post("/v1/agents/import", multipartFormRequestOptions({
|
|
1845
|
+
body,
|
|
1846
|
+
...options,
|
|
1847
|
+
headers: buildHeaders([
|
|
1848
|
+
{
|
|
1849
|
+
...xOverrideEmbeddingModel != null ? { "x-override-embedding-model": xOverrideEmbeddingModel } : undefined
|
|
1850
|
+
},
|
|
1851
|
+
options?.headers
|
|
1852
|
+
])
|
|
1853
|
+
}, this._client));
|
|
1854
|
+
}
|
|
1855
|
+
recompile(agentID, params = {}, options) {
|
|
1856
|
+
const { dry_run, update_timestamp } = params ?? {};
|
|
1857
|
+
return this._client.post(path`/v1/agents/${agentID}/recompile`, {
|
|
1858
|
+
query: { dry_run, update_timestamp },
|
|
1859
|
+
...options
|
|
1860
|
+
});
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
Agents.Messages = Messages;
|
|
1864
|
+
Agents.Schedule = Schedule;
|
|
1865
|
+
Agents.Blocks = Blocks;
|
|
1866
|
+
Agents.Tools = Tools;
|
|
1867
|
+
Agents.Folders = Folders;
|
|
1868
|
+
Agents.Files = Files;
|
|
1869
|
+
Agents.Archives = Archives;
|
|
1870
|
+
Agents.Passages = Passages;
|
|
1871
|
+
Agents.Identities = Identities;
|
|
1872
|
+
// node_modules/@letta-ai/letta-client/resources/archives/passages.mjs
|
|
1873
|
+
class Passages2 extends APIResource {
|
|
1874
|
+
create(archiveID, body, options) {
|
|
1875
|
+
return this._client.post(path`/v1/archives/${archiveID}/passages`, { body, ...options });
|
|
1876
|
+
}
|
|
1877
|
+
delete(passageID, params, options) {
|
|
1878
|
+
const { archive_id } = params;
|
|
1879
|
+
return this._client.delete(path`/v1/archives/${archive_id}/passages/${passageID}`, {
|
|
1880
|
+
...options,
|
|
1881
|
+
headers: buildHeaders([{ Accept: "*/*" }, options?.headers])
|
|
1882
|
+
});
|
|
1883
|
+
}
|
|
1884
|
+
createMany(archiveID, body, options) {
|
|
1885
|
+
return this._client.post(path`/v1/archives/${archiveID}/passages/batch`, { body, ...options });
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
// node_modules/@letta-ai/letta-client/resources/archives/archives.mjs
|
|
1890
|
+
class Archives2 extends APIResource {
|
|
1891
|
+
constructor() {
|
|
1892
|
+
super(...arguments);
|
|
1893
|
+
this.passages = new Passages2(this._client);
|
|
1894
|
+
}
|
|
1895
|
+
create(body, options) {
|
|
1896
|
+
return this._client.post("/v1/archives/", { body, ...options });
|
|
1897
|
+
}
|
|
1898
|
+
retrieve(archiveID, options) {
|
|
1899
|
+
return this._client.get(path`/v1/archives/${archiveID}`, options);
|
|
1900
|
+
}
|
|
1901
|
+
update(archiveID, body, options) {
|
|
1902
|
+
return this._client.patch(path`/v1/archives/${archiveID}`, { body, ...options });
|
|
1903
|
+
}
|
|
1904
|
+
list(query = {}, options) {
|
|
1905
|
+
return this._client.getAPIList("/v1/archives/", ArrayPage, { query, ...options });
|
|
1906
|
+
}
|
|
1907
|
+
delete(archiveID, options) {
|
|
1908
|
+
return this._client.delete(path`/v1/archives/${archiveID}`, {
|
|
1909
|
+
...options,
|
|
1910
|
+
headers: buildHeaders([{ Accept: "*/*" }, options?.headers])
|
|
1911
|
+
});
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
Archives2.Passages = Passages2;
|
|
1915
|
+
// node_modules/@letta-ai/letta-client/resources/blocks/agents.mjs
|
|
1916
|
+
class Agents2 extends APIResource {
|
|
1917
|
+
list(blockID, query = {}, options) {
|
|
1918
|
+
return this._client.getAPIList(path`/v1/blocks/${blockID}/agents`, ArrayPage, {
|
|
1919
|
+
query,
|
|
1920
|
+
...options
|
|
1921
|
+
});
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
|
|
1925
|
+
// node_modules/@letta-ai/letta-client/resources/blocks/blocks.mjs
|
|
1926
|
+
class Blocks2 extends APIResource {
|
|
1927
|
+
constructor() {
|
|
1928
|
+
super(...arguments);
|
|
1929
|
+
this.agents = new Agents2(this._client);
|
|
1930
|
+
}
|
|
1931
|
+
create(body, options) {
|
|
1932
|
+
return this._client.post("/v1/blocks/", { body, ...options });
|
|
1933
|
+
}
|
|
1934
|
+
retrieve(blockID, options) {
|
|
1935
|
+
return this._client.get(path`/v1/blocks/${blockID}`, options);
|
|
1936
|
+
}
|
|
1937
|
+
update(blockID, body, options) {
|
|
1938
|
+
return this._client.patch(path`/v1/blocks/${blockID}`, { body, ...options });
|
|
1939
|
+
}
|
|
1940
|
+
list(query = {}, options) {
|
|
1941
|
+
return this._client.getAPIList("/v1/blocks/", ArrayPage, { query, ...options });
|
|
1942
|
+
}
|
|
1943
|
+
delete(blockID, options) {
|
|
1944
|
+
return this._client.delete(path`/v1/blocks/${blockID}`, options);
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
Blocks2.Agents = Agents2;
|
|
1948
|
+
// node_modules/@letta-ai/letta-client/resources/conversations/messages.mjs
|
|
1949
|
+
class Messages2 extends APIResource {
|
|
1950
|
+
create(conversationID, body, options) {
|
|
1951
|
+
return this._client.post(path`/v1/conversations/${conversationID}/messages`, {
|
|
1952
|
+
body,
|
|
1953
|
+
...options,
|
|
1954
|
+
stream: true
|
|
1955
|
+
});
|
|
1956
|
+
}
|
|
1957
|
+
list(conversationID, query = {}, options) {
|
|
1958
|
+
return this._client.getAPIList(path`/v1/conversations/${conversationID}/messages`, ArrayPage, { query, ...options });
|
|
1959
|
+
}
|
|
1960
|
+
compact(conversationID, body = {}, options) {
|
|
1961
|
+
return this._client.post(path`/v1/conversations/${conversationID}/compact`, { body, ...options });
|
|
1962
|
+
}
|
|
1963
|
+
stream(conversationID, body = {}, options) {
|
|
1964
|
+
return this._client.post(path`/v1/conversations/${conversationID}/stream`, {
|
|
1965
|
+
body,
|
|
1966
|
+
...options,
|
|
1967
|
+
stream: true
|
|
1968
|
+
});
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
|
|
1972
|
+
// node_modules/@letta-ai/letta-client/resources/conversations/conversations.mjs
|
|
1973
|
+
class Conversations extends APIResource {
|
|
1974
|
+
constructor() {
|
|
1975
|
+
super(...arguments);
|
|
1976
|
+
this.messages = new Messages2(this._client);
|
|
1977
|
+
}
|
|
1978
|
+
create(params, options) {
|
|
1979
|
+
const { agent_id, ...body } = params;
|
|
1980
|
+
return this._client.post("/v1/conversations/", { query: { agent_id }, body, ...options });
|
|
1981
|
+
}
|
|
1982
|
+
retrieve(conversationID, options) {
|
|
1983
|
+
return this._client.get(path`/v1/conversations/${conversationID}`, options);
|
|
1984
|
+
}
|
|
1985
|
+
update(conversationID, body, options) {
|
|
1986
|
+
return this._client.patch(path`/v1/conversations/${conversationID}`, { body, ...options });
|
|
1987
|
+
}
|
|
1988
|
+
list(query = {}, options) {
|
|
1989
|
+
return this._client.get("/v1/conversations/", { query, ...options });
|
|
1990
|
+
}
|
|
1991
|
+
delete(conversationID, options) {
|
|
1992
|
+
return this._client.delete(path`/v1/conversations/${conversationID}`, options);
|
|
1993
|
+
}
|
|
1994
|
+
cancel(conversationID, params = {}, options) {
|
|
1995
|
+
const { agent_id } = params ?? {};
|
|
1996
|
+
return this._client.post(path`/v1/conversations/${conversationID}/cancel`, {
|
|
1997
|
+
query: { agent_id },
|
|
1998
|
+
...options
|
|
1999
|
+
});
|
|
2000
|
+
}
|
|
2001
|
+
fork(conversationID, params = {}, options) {
|
|
2002
|
+
const { agent_id, hidden, message_id } = params ?? {};
|
|
2003
|
+
return this._client.post(path`/v1/conversations/${conversationID}/fork`, {
|
|
2004
|
+
query: { agent_id, hidden, message_id },
|
|
2005
|
+
...options
|
|
2006
|
+
});
|
|
2007
|
+
}
|
|
2008
|
+
recompile(conversationID, params = {}, options) {
|
|
2009
|
+
const { dry_run, ...body } = params ?? {};
|
|
2010
|
+
return this._client.post(path`/v1/conversations/${conversationID}/recompile`, {
|
|
2011
|
+
query: { dry_run },
|
|
2012
|
+
body,
|
|
2013
|
+
...options
|
|
2014
|
+
});
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
Conversations.Messages = Messages2;
|
|
2018
|
+
// node_modules/@letta-ai/letta-client/resources/environments.mjs
|
|
2019
|
+
class Environments extends APIResource {
|
|
2020
|
+
retrieve(deviceID, options) {
|
|
2021
|
+
return this._client.get(path`/v1/environments/${deviceID}`, options);
|
|
2022
|
+
}
|
|
2023
|
+
list(query = {}, options) {
|
|
2024
|
+
return this._client.get("/v1/environments", { query, ...options });
|
|
2025
|
+
}
|
|
2026
|
+
sendMessage(connectionID, body, options) {
|
|
2027
|
+
return this._client.post(path`/v1/environments/${connectionID}/messages`, { body, ...options });
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
2030
|
+
// node_modules/@letta-ai/letta-client/resources/folders/agents.mjs
|
|
2031
|
+
class Agents3 extends APIResource {
|
|
2032
|
+
list(folderID, query = {}, options) {
|
|
2033
|
+
return this._client.get(path`/v1/folders/${folderID}/agents`, { query, ...options });
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
|
|
2037
|
+
// node_modules/@letta-ai/letta-client/resources/folders/files.mjs
|
|
2038
|
+
class Files2 extends APIResource {
|
|
2039
|
+
retrieve(fileID, params, options) {
|
|
2040
|
+
const { folder_id, ...query } = params;
|
|
2041
|
+
return this._client.get(path`/v1/folders/${folder_id}/files/${fileID}`, { query, ...options });
|
|
2042
|
+
}
|
|
2043
|
+
list(folderID, query = {}, options) {
|
|
2044
|
+
return this._client.getAPIList(path`/v1/folders/${folderID}/files`, ArrayPage, {
|
|
2045
|
+
query,
|
|
2046
|
+
...options
|
|
2047
|
+
});
|
|
2048
|
+
}
|
|
2049
|
+
delete(fileID, params, options) {
|
|
2050
|
+
const { folder_id } = params;
|
|
2051
|
+
return this._client.delete(path`/v1/folders/${folder_id}/${fileID}`, {
|
|
2052
|
+
...options,
|
|
2053
|
+
headers: buildHeaders([{ Accept: "*/*" }, options?.headers])
|
|
2054
|
+
});
|
|
2055
|
+
}
|
|
2056
|
+
upload(folderID, params, options) {
|
|
2057
|
+
const { duplicate_handling, name, ...body } = params;
|
|
2058
|
+
return this._client.post(path`/v1/folders/${folderID}/upload`, multipartFormRequestOptions({ query: { duplicate_handling, name }, body, ...options }, this._client));
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
|
|
2062
|
+
// node_modules/@letta-ai/letta-client/resources/folders/folders.mjs
|
|
2063
|
+
class Folders2 extends APIResource {
|
|
2064
|
+
constructor() {
|
|
2065
|
+
super(...arguments);
|
|
2066
|
+
this.files = new Files2(this._client);
|
|
2067
|
+
this.agents = new Agents3(this._client);
|
|
2068
|
+
}
|
|
2069
|
+
create(body, options) {
|
|
2070
|
+
return this._client.post("/v1/folders/", { body, ...options });
|
|
2071
|
+
}
|
|
2072
|
+
retrieve(folderID, options) {
|
|
2073
|
+
return this._client.get(path`/v1/folders/${folderID}`, options);
|
|
2074
|
+
}
|
|
2075
|
+
update(folderID, body, options) {
|
|
2076
|
+
return this._client.patch(path`/v1/folders/${folderID}`, { body, ...options });
|
|
2077
|
+
}
|
|
2078
|
+
list(query = {}, options) {
|
|
2079
|
+
return this._client.getAPIList("/v1/folders/", ArrayPage, { query, ...options });
|
|
2080
|
+
}
|
|
2081
|
+
delete(folderID, options) {
|
|
2082
|
+
return this._client.delete(path`/v1/folders/${folderID}`, options);
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
Folders2.Files = Files2;
|
|
2086
|
+
Folders2.Agents = Agents3;
|
|
2087
|
+
// node_modules/@letta-ai/letta-client/resources/mcp-servers/tools.mjs
|
|
2088
|
+
class Tools2 extends APIResource {
|
|
2089
|
+
retrieve(toolID, params, options) {
|
|
2090
|
+
const { mcp_server_id } = params;
|
|
2091
|
+
return this._client.get(path`/v1/mcp-servers/${mcp_server_id}/tools/${toolID}`, options);
|
|
2092
|
+
}
|
|
2093
|
+
list(mcpServerID, options) {
|
|
2094
|
+
return this._client.get(path`/v1/mcp-servers/${mcpServerID}/tools`, options);
|
|
2095
|
+
}
|
|
2096
|
+
run(toolID, params, options) {
|
|
2097
|
+
const { mcp_server_id, ...body } = params;
|
|
2098
|
+
return this._client.post(path`/v1/mcp-servers/${mcp_server_id}/tools/${toolID}/run`, {
|
|
2099
|
+
body,
|
|
2100
|
+
...options
|
|
2101
|
+
});
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2105
|
+
// node_modules/@letta-ai/letta-client/resources/mcp-servers/mcp-servers.mjs
|
|
2106
|
+
class McpServers extends APIResource {
|
|
2107
|
+
constructor() {
|
|
2108
|
+
super(...arguments);
|
|
2109
|
+
this.tools = new Tools2(this._client);
|
|
2110
|
+
}
|
|
2111
|
+
create(body, options) {
|
|
2112
|
+
return this._client.post("/v1/mcp-servers/", { body, ...options });
|
|
2113
|
+
}
|
|
2114
|
+
retrieve(mcpServerID, options) {
|
|
2115
|
+
return this._client.get(path`/v1/mcp-servers/${mcpServerID}`, options);
|
|
2116
|
+
}
|
|
2117
|
+
update(mcpServerID, body, options) {
|
|
2118
|
+
return this._client.patch(path`/v1/mcp-servers/${mcpServerID}`, { body, ...options });
|
|
2119
|
+
}
|
|
2120
|
+
list(options) {
|
|
2121
|
+
return this._client.get("/v1/mcp-servers/", options);
|
|
2122
|
+
}
|
|
2123
|
+
delete(mcpServerID, options) {
|
|
2124
|
+
return this._client.delete(path`/v1/mcp-servers/${mcpServerID}`, {
|
|
2125
|
+
...options,
|
|
2126
|
+
headers: buildHeaders([{ Accept: "*/*" }, options?.headers])
|
|
2127
|
+
});
|
|
2128
|
+
}
|
|
2129
|
+
refresh(mcpServerID, params = {}, options) {
|
|
2130
|
+
const { agent_id } = params ?? {};
|
|
2131
|
+
return this._client.patch(path`/v1/mcp-servers/${mcpServerID}/refresh`, {
|
|
2132
|
+
query: { agent_id },
|
|
2133
|
+
...options
|
|
2134
|
+
});
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2137
|
+
McpServers.Tools = Tools2;
|
|
2138
|
+
// node_modules/@letta-ai/letta-client/resources/messages.mjs
|
|
2139
|
+
class Messages3 extends APIResource {
|
|
2140
|
+
retrieve(messageID, options) {
|
|
2141
|
+
return this._client.get(path`/v1/messages/${messageID}`, options);
|
|
2142
|
+
}
|
|
2143
|
+
list(query = {}, options) {
|
|
2144
|
+
return this._client.get("/v1/messages/", { query, ...options });
|
|
2145
|
+
}
|
|
2146
|
+
search(body, options) {
|
|
2147
|
+
return this._client.post("/v1/messages/search", { body, ...options });
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
// node_modules/@letta-ai/letta-client/resources/models/embeddings.mjs
|
|
2151
|
+
class Embeddings extends APIResource {
|
|
2152
|
+
list(options) {
|
|
2153
|
+
return this._client.get("/v1/models/embedding", options);
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
|
|
2157
|
+
// node_modules/@letta-ai/letta-client/resources/models/models.mjs
|
|
2158
|
+
class Models extends APIResource {
|
|
2159
|
+
constructor() {
|
|
2160
|
+
super(...arguments);
|
|
2161
|
+
this.embeddings = new Embeddings(this._client);
|
|
2162
|
+
}
|
|
2163
|
+
list(query = {}, options) {
|
|
2164
|
+
return this._client.get("/v1/models/", { query, ...options });
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
Models.Embeddings = Embeddings;
|
|
2168
|
+
// node_modules/@letta-ai/letta-client/resources/passages.mjs
|
|
2169
|
+
class Passages3 extends APIResource {
|
|
2170
|
+
search(body, options) {
|
|
2171
|
+
return this._client.post("/v1/passages/search", { body, ...options });
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
// node_modules/@letta-ai/letta-client/resources/runs/messages.mjs
|
|
2175
|
+
class Messages4 extends APIResource {
|
|
2176
|
+
list(runID, query = {}, options) {
|
|
2177
|
+
return this._client.getAPIList(path`/v1/runs/${runID}/messages`, ArrayPage, {
|
|
2178
|
+
query,
|
|
2179
|
+
...options
|
|
2180
|
+
});
|
|
2181
|
+
}
|
|
2182
|
+
stream(runID, body = {}, options) {
|
|
2183
|
+
return this._client.post(path`/v1/runs/${runID}/stream`, {
|
|
2184
|
+
body,
|
|
2185
|
+
...options,
|
|
2186
|
+
stream: true
|
|
2187
|
+
});
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
|
|
2191
|
+
// node_modules/@letta-ai/letta-client/resources/runs/steps.mjs
|
|
2192
|
+
class Steps extends APIResource {
|
|
2193
|
+
list(runID, query = {}, options) {
|
|
2194
|
+
return this._client.getAPIList(path`/v1/runs/${runID}/steps`, ArrayPage, {
|
|
2195
|
+
query,
|
|
2196
|
+
...options
|
|
2197
|
+
});
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
2200
|
+
|
|
2201
|
+
// node_modules/@letta-ai/letta-client/resources/runs/trace.mjs
|
|
2202
|
+
class Trace extends APIResource {
|
|
2203
|
+
retrieve(runID, query = {}, options) {
|
|
2204
|
+
return this._client.get(path`/v1/runs/${runID}/trace`, { query, ...options });
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2208
|
+
// node_modules/@letta-ai/letta-client/resources/runs/usage.mjs
|
|
2209
|
+
class Usage extends APIResource {
|
|
2210
|
+
retrieve(runID, options) {
|
|
2211
|
+
return this._client.get(path`/v1/runs/${runID}/usage`, options);
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
|
|
2215
|
+
// node_modules/@letta-ai/letta-client/resources/runs/runs.mjs
|
|
2216
|
+
class Runs extends APIResource {
|
|
2217
|
+
constructor() {
|
|
2218
|
+
super(...arguments);
|
|
2219
|
+
this.messages = new Messages4(this._client);
|
|
2220
|
+
this.usage = new Usage(this._client);
|
|
2221
|
+
this.steps = new Steps(this._client);
|
|
2222
|
+
this.trace = new Trace(this._client);
|
|
2223
|
+
}
|
|
2224
|
+
retrieve(runID, options) {
|
|
2225
|
+
return this._client.get(path`/v1/runs/${runID}`, options);
|
|
2226
|
+
}
|
|
2227
|
+
list(query = {}, options) {
|
|
2228
|
+
return this._client.getAPIList("/v1/runs/", ArrayPage, { query, ...options });
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2231
|
+
Runs.Messages = Messages4;
|
|
2232
|
+
Runs.Usage = Usage;
|
|
2233
|
+
Runs.Steps = Steps;
|
|
2234
|
+
Runs.Trace = Trace;
|
|
2235
|
+
// node_modules/@letta-ai/letta-client/resources/steps/feedback.mjs
|
|
2236
|
+
class Feedback extends APIResource {
|
|
2237
|
+
create(stepID, body, options) {
|
|
2238
|
+
return this._client.patch(path`/v1/steps/${stepID}/feedback`, { body, ...options });
|
|
2239
|
+
}
|
|
2240
|
+
}
|
|
2241
|
+
|
|
2242
|
+
// node_modules/@letta-ai/letta-client/resources/steps/messages.mjs
|
|
2243
|
+
class Messages5 extends APIResource {
|
|
2244
|
+
list(stepID, query = {}, options) {
|
|
2245
|
+
return this._client.getAPIList(path`/v1/steps/${stepID}/messages`, ArrayPage, {
|
|
2246
|
+
query,
|
|
2247
|
+
...options
|
|
2248
|
+
});
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
|
|
2252
|
+
// node_modules/@letta-ai/letta-client/resources/steps/metrics.mjs
|
|
2253
|
+
class Metrics extends APIResource {
|
|
2254
|
+
retrieve(stepID, options) {
|
|
2255
|
+
return this._client.get(path`/v1/steps/${stepID}/metrics`, options);
|
|
2256
|
+
}
|
|
2257
|
+
}
|
|
2258
|
+
|
|
2259
|
+
// node_modules/@letta-ai/letta-client/resources/steps/trace.mjs
|
|
2260
|
+
class Trace2 extends APIResource {
|
|
2261
|
+
retrieve(stepID, options) {
|
|
2262
|
+
return this._client.get(path`/v1/steps/${stepID}/trace`, options);
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
|
|
2266
|
+
// node_modules/@letta-ai/letta-client/resources/steps/steps.mjs
|
|
2267
|
+
class Steps2 extends APIResource {
|
|
2268
|
+
constructor() {
|
|
2269
|
+
super(...arguments);
|
|
2270
|
+
this.metrics = new Metrics(this._client);
|
|
2271
|
+
this.trace = new Trace2(this._client);
|
|
2272
|
+
this.feedback = new Feedback(this._client);
|
|
2273
|
+
this.messages = new Messages5(this._client);
|
|
2274
|
+
}
|
|
2275
|
+
retrieve(stepID, options) {
|
|
2276
|
+
return this._client.get(path`/v1/steps/${stepID}`, options);
|
|
2277
|
+
}
|
|
2278
|
+
list(query = {}, options) {
|
|
2279
|
+
return this._client.getAPIList("/v1/steps/", ArrayPage, { query, ...options });
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
2282
|
+
Steps2.Metrics = Metrics;
|
|
2283
|
+
Steps2.Trace = Trace2;
|
|
2284
|
+
Steps2.Feedback = Feedback;
|
|
2285
|
+
Steps2.Messages = Messages5;
|
|
2286
|
+
// node_modules/@letta-ai/letta-client/resources/tags.mjs
|
|
2287
|
+
class Tags extends APIResource {
|
|
2288
|
+
list(query = {}, options) {
|
|
2289
|
+
return this._client.get("/v1/tags/", { query, ...options });
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
// node_modules/@letta-ai/letta-client/resources/templates/agents.mjs
|
|
2293
|
+
class Agents4 extends APIResource {
|
|
2294
|
+
create(templateVersion, body = {}, options) {
|
|
2295
|
+
return this._client.post(path`/v1/templates/${templateVersion}/agents`, { body, ...options });
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
|
|
2299
|
+
// node_modules/@letta-ai/letta-client/resources/templates/templates.mjs
|
|
2300
|
+
class Templates extends APIResource {
|
|
2301
|
+
constructor() {
|
|
2302
|
+
super(...arguments);
|
|
2303
|
+
this.agents = new Agents4(this._client);
|
|
2304
|
+
}
|
|
2305
|
+
create(body, options) {
|
|
2306
|
+
return this._client.post("/v1/templates", { body, ...options });
|
|
2307
|
+
}
|
|
2308
|
+
update(templateName, body, options) {
|
|
2309
|
+
return this._client.patch(path`/v1/templates/${templateName}`, { body, ...options });
|
|
2310
|
+
}
|
|
2311
|
+
delete(templateName, body, options) {
|
|
2312
|
+
return this._client.delete(path`/v1/templates/${templateName}`, { body, ...options });
|
|
2313
|
+
}
|
|
2314
|
+
rollback(templateName, body, options) {
|
|
2315
|
+
return this._client.post(path`/v1/templates/${templateName}/rollback`, { body, ...options });
|
|
2316
|
+
}
|
|
2317
|
+
save(templateName, body = {}, options) {
|
|
2318
|
+
return this._client.post(path`/v1/templates/${templateName}/save`, { body, ...options });
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
2321
|
+
Templates.Agents = Agents4;
|
|
2322
|
+
// node_modules/@letta-ai/letta-client/resources/tools.mjs
|
|
2323
|
+
class Tools3 extends APIResource {
|
|
2324
|
+
create(body, options) {
|
|
2325
|
+
return this._client.post("/v1/tools/", { body, ...options });
|
|
2326
|
+
}
|
|
2327
|
+
retrieve(toolID, options) {
|
|
2328
|
+
return this._client.get(path`/v1/tools/${toolID}`, options);
|
|
2329
|
+
}
|
|
2330
|
+
update(toolID, body, options) {
|
|
2331
|
+
return this._client.patch(path`/v1/tools/${toolID}`, { body, ...options });
|
|
2332
|
+
}
|
|
2333
|
+
list(query = {}, options) {
|
|
2334
|
+
return this._client.getAPIList("/v1/tools/", ArrayPage, { query, ...options });
|
|
2335
|
+
}
|
|
2336
|
+
delete(toolID, options) {
|
|
2337
|
+
return this._client.delete(path`/v1/tools/${toolID}`, options);
|
|
2338
|
+
}
|
|
2339
|
+
search(body, options) {
|
|
2340
|
+
return this._client.post("/v1/tools/search", { body, ...options });
|
|
2341
|
+
}
|
|
2342
|
+
upsert(body, options) {
|
|
2343
|
+
return this._client.put("/v1/tools/", { body, ...options });
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
// node_modules/@letta-ai/letta-client/internal/utils/env.mjs
|
|
2347
|
+
var readEnv = (env) => {
|
|
2348
|
+
if (typeof globalThis.process !== "undefined") {
|
|
2349
|
+
return globalThis.process.env?.[env]?.trim() || undefined;
|
|
2350
|
+
}
|
|
2351
|
+
if (typeof globalThis.Deno !== "undefined") {
|
|
2352
|
+
return globalThis.Deno.env?.get?.(env)?.trim() || undefined;
|
|
2353
|
+
}
|
|
2354
|
+
return;
|
|
2355
|
+
};
|
|
2356
|
+
|
|
2357
|
+
// node_modules/@letta-ai/letta-client/client.mjs
|
|
2358
|
+
var _Letta_instances;
|
|
2359
|
+
var _a;
|
|
2360
|
+
var _Letta_encoder;
|
|
2361
|
+
var _Letta_baseURLOverridden;
|
|
2362
|
+
var environments = {
|
|
2363
|
+
cloud: "https://api.letta.com",
|
|
2364
|
+
local: "http://localhost:8283"
|
|
2365
|
+
};
|
|
2366
|
+
|
|
2367
|
+
class Letta {
|
|
2368
|
+
constructor({ baseURL = readEnv("LETTA_BASE_URL"), apiKey = readEnv("LETTA_API_KEY") ?? null, projectID = null, project = null, ...opts } = {}) {
|
|
2369
|
+
_Letta_instances.add(this);
|
|
2370
|
+
_Letta_encoder.set(this, undefined);
|
|
2371
|
+
this.agents = new Agents(this);
|
|
2372
|
+
this.tools = new Tools3(this);
|
|
2373
|
+
this.blocks = new Blocks2(this);
|
|
2374
|
+
this.archives = new Archives2(this);
|
|
2375
|
+
this.folders = new Folders2(this);
|
|
2376
|
+
this.models = new Models(this);
|
|
2377
|
+
this.mcpServers = new McpServers(this);
|
|
2378
|
+
this.runs = new Runs(this);
|
|
2379
|
+
this.steps = new Steps2(this);
|
|
2380
|
+
this.templates = new Templates(this);
|
|
2381
|
+
this.tags = new Tags(this);
|
|
2382
|
+
this.messages = new Messages3(this);
|
|
2383
|
+
this.passages = new Passages3(this);
|
|
2384
|
+
this.conversations = new Conversations(this);
|
|
2385
|
+
this.environments = new Environments(this);
|
|
2386
|
+
this.accessTokens = new AccessTokens(this);
|
|
2387
|
+
const options = {
|
|
2388
|
+
apiKey,
|
|
2389
|
+
projectID,
|
|
2390
|
+
project,
|
|
2391
|
+
...opts,
|
|
2392
|
+
baseURL,
|
|
2393
|
+
environment: opts.environment ?? "cloud"
|
|
2394
|
+
};
|
|
2395
|
+
if (baseURL && opts.environment) {
|
|
2396
|
+
throw new LettaError("Ambiguous URL; The `baseURL` option (or LETTA_BASE_URL env var) and the `environment` option are given. If you want to use the environment you must pass baseURL: null");
|
|
2397
|
+
}
|
|
2398
|
+
this.baseURL = options.baseURL || environments[options.environment || "cloud"];
|
|
2399
|
+
this.timeout = options.timeout ?? _a.DEFAULT_TIMEOUT;
|
|
2400
|
+
this.logger = options.logger ?? console;
|
|
2401
|
+
const defaultLogLevel = "warn";
|
|
2402
|
+
this.logLevel = defaultLogLevel;
|
|
2403
|
+
this.logLevel = parseLogLevel(options.logLevel, "ClientOptions.logLevel", this) ?? parseLogLevel(readEnv("LETTA_LOG"), "process.env['LETTA_LOG']", this) ?? defaultLogLevel;
|
|
2404
|
+
this.fetchOptions = options.fetchOptions;
|
|
2405
|
+
this.maxRetries = options.maxRetries ?? 2;
|
|
2406
|
+
this.fetch = options.fetch ?? getDefaultFetch();
|
|
2407
|
+
__classPrivateFieldSet(this, _Letta_encoder, FallbackEncoder, "f");
|
|
2408
|
+
const customHeadersEnv = readEnv("LETTA_CUSTOM_HEADERS");
|
|
2409
|
+
if (customHeadersEnv) {
|
|
2410
|
+
const parsed = {};
|
|
2411
|
+
for (const line of customHeadersEnv.split(`
|
|
2412
|
+
`)) {
|
|
2413
|
+
const colon = line.indexOf(":");
|
|
2414
|
+
if (colon >= 0) {
|
|
2415
|
+
parsed[line.substring(0, colon).trim()] = line.substring(colon + 1).trim();
|
|
2416
|
+
}
|
|
2417
|
+
}
|
|
2418
|
+
options.defaultHeaders = { ...parsed, ...options.defaultHeaders };
|
|
2419
|
+
}
|
|
2420
|
+
this._options = options;
|
|
2421
|
+
this.apiKey = apiKey;
|
|
2422
|
+
this.projectID = projectID;
|
|
2423
|
+
this.project = project;
|
|
2424
|
+
}
|
|
2425
|
+
withOptions(options) {
|
|
2426
|
+
const client = new this.constructor({
|
|
2427
|
+
...this._options,
|
|
2428
|
+
environment: options.environment ? options.environment : undefined,
|
|
2429
|
+
baseURL: options.environment ? undefined : this.baseURL,
|
|
2430
|
+
maxRetries: this.maxRetries,
|
|
2431
|
+
timeout: this.timeout,
|
|
2432
|
+
logger: this.logger,
|
|
2433
|
+
logLevel: this.logLevel,
|
|
2434
|
+
fetch: this.fetch,
|
|
2435
|
+
fetchOptions: this.fetchOptions,
|
|
2436
|
+
apiKey: this.apiKey,
|
|
2437
|
+
projectID: this.projectID,
|
|
2438
|
+
project: this.project,
|
|
2439
|
+
...options
|
|
2440
|
+
});
|
|
2441
|
+
return client;
|
|
2442
|
+
}
|
|
2443
|
+
health(options) {
|
|
2444
|
+
return this.get("/v1/health/", options);
|
|
2445
|
+
}
|
|
2446
|
+
defaultQuery() {
|
|
2447
|
+
return this._options.defaultQuery;
|
|
2448
|
+
}
|
|
2449
|
+
validateHeaders({ values, nulls }) {
|
|
2450
|
+
return;
|
|
2451
|
+
}
|
|
2452
|
+
async authHeaders(opts) {
|
|
2453
|
+
if (this.apiKey == null) {
|
|
2454
|
+
return;
|
|
2455
|
+
}
|
|
2456
|
+
return buildHeaders([{ Authorization: `Bearer ${this.apiKey}` }]);
|
|
2457
|
+
}
|
|
2458
|
+
stringifyQuery(query) {
|
|
2459
|
+
return stringifyQuery(query);
|
|
2460
|
+
}
|
|
2461
|
+
getUserAgent() {
|
|
2462
|
+
return `${this.constructor.name}/JS ${VERSION}`;
|
|
2463
|
+
}
|
|
2464
|
+
defaultIdempotencyKey() {
|
|
2465
|
+
return `stainless-node-retry-${uuid4()}`;
|
|
2466
|
+
}
|
|
2467
|
+
makeStatusError(status, error, message, headers) {
|
|
2468
|
+
return APIError.generate(status, error, message, headers);
|
|
2469
|
+
}
|
|
2470
|
+
buildURL(path2, query, defaultBaseURL) {
|
|
2471
|
+
const baseURL = !__classPrivateFieldGet(this, _Letta_instances, "m", _Letta_baseURLOverridden).call(this) && defaultBaseURL || this.baseURL;
|
|
2472
|
+
const url = isAbsoluteURL(path2) ? new URL(path2) : new URL(baseURL + (baseURL.endsWith("/") && path2.startsWith("/") ? path2.slice(1) : path2));
|
|
2473
|
+
const defaultQuery = this.defaultQuery();
|
|
2474
|
+
const pathQuery = Object.fromEntries(url.searchParams);
|
|
2475
|
+
if (!isEmptyObj(defaultQuery) || !isEmptyObj(pathQuery)) {
|
|
2476
|
+
query = { ...pathQuery, ...defaultQuery, ...query };
|
|
2477
|
+
}
|
|
2478
|
+
if (typeof query === "object" && query && !Array.isArray(query)) {
|
|
2479
|
+
url.search = this.stringifyQuery(query);
|
|
2480
|
+
}
|
|
2481
|
+
return url.toString();
|
|
2482
|
+
}
|
|
2483
|
+
async prepareOptions(options) {}
|
|
2484
|
+
async prepareRequest(request, { url, options }) {}
|
|
2485
|
+
get(path2, opts) {
|
|
2486
|
+
return this.methodRequest("get", path2, opts);
|
|
2487
|
+
}
|
|
2488
|
+
post(path2, opts) {
|
|
2489
|
+
return this.methodRequest("post", path2, opts);
|
|
2490
|
+
}
|
|
2491
|
+
patch(path2, opts) {
|
|
2492
|
+
return this.methodRequest("patch", path2, opts);
|
|
2493
|
+
}
|
|
2494
|
+
put(path2, opts) {
|
|
2495
|
+
return this.methodRequest("put", path2, opts);
|
|
2496
|
+
}
|
|
2497
|
+
delete(path2, opts) {
|
|
2498
|
+
return this.methodRequest("delete", path2, opts);
|
|
2499
|
+
}
|
|
2500
|
+
methodRequest(method, path2, opts) {
|
|
2501
|
+
return this.request(Promise.resolve(opts).then((opts2) => {
|
|
2502
|
+
return { method, path: path2, ...opts2 };
|
|
2503
|
+
}));
|
|
2504
|
+
}
|
|
2505
|
+
request(options, remainingRetries = null) {
|
|
2506
|
+
return new APIPromise(this, this.makeRequest(options, remainingRetries, undefined));
|
|
2507
|
+
}
|
|
2508
|
+
async makeRequest(optionsInput, retriesRemaining, retryOfRequestLogID) {
|
|
2509
|
+
const options = await optionsInput;
|
|
2510
|
+
const maxRetries = options.maxRetries ?? this.maxRetries;
|
|
2511
|
+
if (retriesRemaining == null) {
|
|
2512
|
+
retriesRemaining = maxRetries;
|
|
2513
|
+
}
|
|
2514
|
+
await this.prepareOptions(options);
|
|
2515
|
+
const { req, url, timeout } = await this.buildRequest(options, {
|
|
2516
|
+
retryCount: maxRetries - retriesRemaining
|
|
2517
|
+
});
|
|
2518
|
+
await this.prepareRequest(req, { url, options });
|
|
2519
|
+
const requestLogID = "log_" + (Math.random() * (1 << 24) | 0).toString(16).padStart(6, "0");
|
|
2520
|
+
const retryLogStr = retryOfRequestLogID === undefined ? "" : `, retryOf: ${retryOfRequestLogID}`;
|
|
2521
|
+
const startTime = Date.now();
|
|
2522
|
+
loggerFor(this).debug(`[${requestLogID}] sending request`, formatRequestDetails({
|
|
2523
|
+
retryOfRequestLogID,
|
|
2524
|
+
method: options.method,
|
|
2525
|
+
url,
|
|
2526
|
+
options,
|
|
2527
|
+
headers: req.headers
|
|
2528
|
+
}));
|
|
2529
|
+
if (options.signal?.aborted) {
|
|
2530
|
+
throw new APIUserAbortError;
|
|
2531
|
+
}
|
|
2532
|
+
const controller = new AbortController;
|
|
2533
|
+
const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError);
|
|
2534
|
+
const headersTime = Date.now();
|
|
2535
|
+
if (response instanceof globalThis.Error) {
|
|
2536
|
+
const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
|
|
2537
|
+
if (options.signal?.aborted) {
|
|
2538
|
+
throw new APIUserAbortError;
|
|
2539
|
+
}
|
|
2540
|
+
const isTimeout = isAbortError(response) || /timed? ?out/i.test(String(response) + ("cause" in response ? String(response.cause) : ""));
|
|
2541
|
+
if (retriesRemaining) {
|
|
2542
|
+
loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? "timed out" : "failed"} - ${retryMessage}`);
|
|
2543
|
+
loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? "timed out" : "failed"} (${retryMessage})`, formatRequestDetails({
|
|
2544
|
+
retryOfRequestLogID,
|
|
2545
|
+
url,
|
|
2546
|
+
durationMs: headersTime - startTime,
|
|
2547
|
+
message: response.message
|
|
2548
|
+
}));
|
|
2549
|
+
return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID);
|
|
2550
|
+
}
|
|
2551
|
+
loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? "timed out" : "failed"} - error; no more retries left`);
|
|
2552
|
+
loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? "timed out" : "failed"} (error; no more retries left)`, formatRequestDetails({
|
|
2553
|
+
retryOfRequestLogID,
|
|
2554
|
+
url,
|
|
2555
|
+
durationMs: headersTime - startTime,
|
|
2556
|
+
message: response.message
|
|
2557
|
+
}));
|
|
2558
|
+
if (isTimeout) {
|
|
2559
|
+
throw new APIConnectionTimeoutError;
|
|
2560
|
+
}
|
|
2561
|
+
throw new APIConnectionError({ cause: response });
|
|
2562
|
+
}
|
|
2563
|
+
const responseInfo = `[${requestLogID}${retryLogStr}] ${req.method} ${url} ${response.ok ? "succeeded" : "failed"} with status ${response.status} in ${headersTime - startTime}ms`;
|
|
2564
|
+
if (!response.ok) {
|
|
2565
|
+
const shouldRetry = await this.shouldRetry(response);
|
|
2566
|
+
if (retriesRemaining && shouldRetry) {
|
|
2567
|
+
const retryMessage2 = `retrying, ${retriesRemaining} attempts remaining`;
|
|
2568
|
+
await CancelReadableStream(response.body);
|
|
2569
|
+
loggerFor(this).info(`${responseInfo} - ${retryMessage2}`);
|
|
2570
|
+
loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage2})`, formatRequestDetails({
|
|
2571
|
+
retryOfRequestLogID,
|
|
2572
|
+
url: response.url,
|
|
2573
|
+
status: response.status,
|
|
2574
|
+
headers: response.headers,
|
|
2575
|
+
durationMs: headersTime - startTime
|
|
2576
|
+
}));
|
|
2577
|
+
return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID, response.headers);
|
|
2578
|
+
}
|
|
2579
|
+
const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`;
|
|
2580
|
+
loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
|
|
2581
|
+
const errText = await response.text().catch((err2) => castToError(err2).message);
|
|
2582
|
+
const errJSON = safeJSON(errText);
|
|
2583
|
+
const errMessage = errJSON ? undefined : errText;
|
|
2584
|
+
loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({
|
|
2585
|
+
retryOfRequestLogID,
|
|
2586
|
+
url: response.url,
|
|
2587
|
+
status: response.status,
|
|
2588
|
+
headers: response.headers,
|
|
2589
|
+
message: errMessage,
|
|
2590
|
+
durationMs: Date.now() - startTime
|
|
2591
|
+
}));
|
|
2592
|
+
const err = this.makeStatusError(response.status, errJSON, errMessage, response.headers);
|
|
2593
|
+
throw err;
|
|
2594
|
+
}
|
|
2595
|
+
loggerFor(this).info(responseInfo);
|
|
2596
|
+
loggerFor(this).debug(`[${requestLogID}] response start`, formatRequestDetails({
|
|
2597
|
+
retryOfRequestLogID,
|
|
2598
|
+
url: response.url,
|
|
2599
|
+
status: response.status,
|
|
2600
|
+
headers: response.headers,
|
|
2601
|
+
durationMs: headersTime - startTime
|
|
2602
|
+
}));
|
|
2603
|
+
return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
|
|
2604
|
+
}
|
|
2605
|
+
getAPIList(path2, Page, opts) {
|
|
2606
|
+
return this.requestAPIList(Page, opts && "then" in opts ? opts.then((opts2) => ({ method: "get", path: path2, ...opts2 })) : { method: "get", path: path2, ...opts });
|
|
2607
|
+
}
|
|
2608
|
+
requestAPIList(Page, options) {
|
|
2609
|
+
const request = this.makeRequest(options, null, undefined);
|
|
2610
|
+
return new PagePromise(this, request, Page);
|
|
2611
|
+
}
|
|
2612
|
+
async fetchWithTimeout(url, init, ms, controller) {
|
|
2613
|
+
const { signal, method, ...options } = init || {};
|
|
2614
|
+
const abort = this._makeAbort(controller);
|
|
2615
|
+
if (signal)
|
|
2616
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
2617
|
+
const timeout = setTimeout(abort, ms);
|
|
2618
|
+
const isReadableBody = globalThis.ReadableStream && options.body instanceof globalThis.ReadableStream || typeof options.body === "object" && options.body !== null && Symbol.asyncIterator in options.body;
|
|
2619
|
+
const fetchOptions = {
|
|
2620
|
+
signal: controller.signal,
|
|
2621
|
+
...isReadableBody ? { duplex: "half" } : {},
|
|
2622
|
+
method: "GET",
|
|
2623
|
+
...options
|
|
2624
|
+
};
|
|
2625
|
+
if (method) {
|
|
2626
|
+
fetchOptions.method = method.toUpperCase();
|
|
2627
|
+
}
|
|
2628
|
+
try {
|
|
2629
|
+
return await this.fetch.call(undefined, url, fetchOptions);
|
|
2630
|
+
} finally {
|
|
2631
|
+
clearTimeout(timeout);
|
|
2632
|
+
}
|
|
2633
|
+
}
|
|
2634
|
+
async shouldRetry(response) {
|
|
2635
|
+
const shouldRetryHeader = response.headers.get("x-should-retry");
|
|
2636
|
+
if (shouldRetryHeader === "true")
|
|
2637
|
+
return true;
|
|
2638
|
+
if (shouldRetryHeader === "false")
|
|
2639
|
+
return false;
|
|
2640
|
+
if (response.status === 408)
|
|
2641
|
+
return true;
|
|
2642
|
+
if (response.status === 409)
|
|
2643
|
+
return true;
|
|
2644
|
+
if (response.status === 429)
|
|
2645
|
+
return true;
|
|
2646
|
+
if (response.status >= 500)
|
|
2647
|
+
return true;
|
|
2648
|
+
return false;
|
|
2649
|
+
}
|
|
2650
|
+
async retryRequest(options, retriesRemaining, requestLogID, responseHeaders) {
|
|
2651
|
+
let timeoutMillis;
|
|
2652
|
+
const retryAfterMillisHeader = responseHeaders?.get("retry-after-ms");
|
|
2653
|
+
if (retryAfterMillisHeader) {
|
|
2654
|
+
const timeoutMs = parseFloat(retryAfterMillisHeader);
|
|
2655
|
+
if (!Number.isNaN(timeoutMs)) {
|
|
2656
|
+
timeoutMillis = timeoutMs;
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2659
|
+
const retryAfterHeader = responseHeaders?.get("retry-after");
|
|
2660
|
+
if (retryAfterHeader && !timeoutMillis) {
|
|
2661
|
+
const timeoutSeconds = parseFloat(retryAfterHeader);
|
|
2662
|
+
if (!Number.isNaN(timeoutSeconds)) {
|
|
2663
|
+
timeoutMillis = timeoutSeconds * 1000;
|
|
2664
|
+
} else {
|
|
2665
|
+
timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
|
|
2666
|
+
}
|
|
2667
|
+
}
|
|
2668
|
+
if (timeoutMillis === undefined) {
|
|
2669
|
+
const maxRetries = options.maxRetries ?? this.maxRetries;
|
|
2670
|
+
timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
|
|
2671
|
+
}
|
|
2672
|
+
await sleep(timeoutMillis);
|
|
2673
|
+
return this.makeRequest(options, retriesRemaining - 1, requestLogID);
|
|
2674
|
+
}
|
|
2675
|
+
calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) {
|
|
2676
|
+
const initialRetryDelay = 0.5;
|
|
2677
|
+
const maxRetryDelay = 8;
|
|
2678
|
+
const numRetries = maxRetries - retriesRemaining;
|
|
2679
|
+
const sleepSeconds = Math.min(initialRetryDelay * Math.pow(2, numRetries), maxRetryDelay);
|
|
2680
|
+
const jitter = 1 - Math.random() * 0.25;
|
|
2681
|
+
return sleepSeconds * jitter * 1000;
|
|
2682
|
+
}
|
|
2683
|
+
async buildRequest(inputOptions, { retryCount = 0 } = {}) {
|
|
2684
|
+
const options = { ...inputOptions };
|
|
2685
|
+
const { method, path: path2, query, defaultBaseURL } = options;
|
|
2686
|
+
const url = this.buildURL(path2, query, defaultBaseURL);
|
|
2687
|
+
if ("timeout" in options)
|
|
2688
|
+
validatePositiveInteger("timeout", options.timeout);
|
|
2689
|
+
options.timeout = options.timeout ?? this.timeout;
|
|
2690
|
+
const { bodyHeaders, body } = this.buildBody({ options });
|
|
2691
|
+
const reqHeaders = await this.buildHeaders({ options: inputOptions, method, bodyHeaders, retryCount });
|
|
2692
|
+
const req = {
|
|
2693
|
+
method,
|
|
2694
|
+
headers: reqHeaders,
|
|
2695
|
+
...options.signal && { signal: options.signal },
|
|
2696
|
+
...globalThis.ReadableStream && body instanceof globalThis.ReadableStream && { duplex: "half" },
|
|
2697
|
+
...body && { body },
|
|
2698
|
+
...this.fetchOptions ?? {},
|
|
2699
|
+
...options.fetchOptions ?? {}
|
|
2700
|
+
};
|
|
2701
|
+
return { req, url, timeout: options.timeout };
|
|
2702
|
+
}
|
|
2703
|
+
async buildHeaders({ options, method, bodyHeaders, retryCount }) {
|
|
2704
|
+
let idempotencyHeaders = {};
|
|
2705
|
+
if (this.idempotencyHeader && method !== "get") {
|
|
2706
|
+
if (!options.idempotencyKey)
|
|
2707
|
+
options.idempotencyKey = this.defaultIdempotencyKey();
|
|
2708
|
+
idempotencyHeaders[this.idempotencyHeader] = options.idempotencyKey;
|
|
2709
|
+
}
|
|
2710
|
+
const headers = buildHeaders([
|
|
2711
|
+
idempotencyHeaders,
|
|
2712
|
+
{
|
|
2713
|
+
Accept: "application/json",
|
|
2714
|
+
"User-Agent": this.getUserAgent(),
|
|
2715
|
+
"X-Stainless-Retry-Count": String(retryCount),
|
|
2716
|
+
...options.timeout ? { "X-Stainless-Timeout": String(Math.trunc(options.timeout / 1000)) } : {},
|
|
2717
|
+
...getPlatformHeaders(),
|
|
2718
|
+
"X-Project-Id": this.projectID,
|
|
2719
|
+
"X-Project": this.project
|
|
2720
|
+
},
|
|
2721
|
+
await this.authHeaders(options),
|
|
2722
|
+
this._options.defaultHeaders,
|
|
2723
|
+
bodyHeaders,
|
|
2724
|
+
options.headers
|
|
2725
|
+
]);
|
|
2726
|
+
this.validateHeaders(headers);
|
|
2727
|
+
return headers.values;
|
|
2728
|
+
}
|
|
2729
|
+
_makeAbort(controller) {
|
|
2730
|
+
return () => controller.abort();
|
|
2731
|
+
}
|
|
2732
|
+
buildBody({ options: { body, headers: rawHeaders } }) {
|
|
2733
|
+
if (!body) {
|
|
2734
|
+
return { bodyHeaders: undefined, body: undefined };
|
|
2735
|
+
}
|
|
2736
|
+
const headers = buildHeaders([rawHeaders]);
|
|
2737
|
+
if (ArrayBuffer.isView(body) || body instanceof ArrayBuffer || body instanceof DataView || typeof body === "string" && headers.values.has("content-type") || globalThis.Blob && body instanceof globalThis.Blob || body instanceof FormData || body instanceof URLSearchParams || globalThis.ReadableStream && body instanceof globalThis.ReadableStream) {
|
|
2738
|
+
return { bodyHeaders: undefined, body };
|
|
2739
|
+
} else if (typeof body === "object" && ((Symbol.asyncIterator in body) || (Symbol.iterator in body) && ("next" in body) && typeof body.next === "function")) {
|
|
2740
|
+
return { bodyHeaders: undefined, body: ReadableStreamFrom(body) };
|
|
2741
|
+
} else if (typeof body === "object" && headers.values.get("content-type") === "application/x-www-form-urlencoded") {
|
|
2742
|
+
return {
|
|
2743
|
+
bodyHeaders: { "content-type": "application/x-www-form-urlencoded" },
|
|
2744
|
+
body: this.stringifyQuery(body)
|
|
2745
|
+
};
|
|
2746
|
+
} else {
|
|
2747
|
+
return __classPrivateFieldGet(this, _Letta_encoder, "f").call(this, { body, headers });
|
|
2748
|
+
}
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
_a = Letta, _Letta_encoder = new WeakMap, _Letta_instances = new WeakSet, _Letta_baseURLOverridden = function _Letta_baseURLOverridden2() {
|
|
2752
|
+
return this.baseURL !== environments[this._options.environment || "cloud"];
|
|
2753
|
+
};
|
|
2754
|
+
Letta.Letta = _a;
|
|
2755
|
+
Letta.DEFAULT_TIMEOUT = 60000;
|
|
2756
|
+
Letta.LettaError = LettaError;
|
|
2757
|
+
Letta.APIError = APIError;
|
|
2758
|
+
Letta.APIConnectionError = APIConnectionError;
|
|
2759
|
+
Letta.APIConnectionTimeoutError = APIConnectionTimeoutError;
|
|
2760
|
+
Letta.APIUserAbortError = APIUserAbortError;
|
|
2761
|
+
Letta.NotFoundError = NotFoundError;
|
|
2762
|
+
Letta.ConflictError = ConflictError;
|
|
2763
|
+
Letta.RateLimitError = RateLimitError;
|
|
2764
|
+
Letta.BadRequestError = BadRequestError;
|
|
2765
|
+
Letta.AuthenticationError = AuthenticationError;
|
|
2766
|
+
Letta.InternalServerError = InternalServerError;
|
|
2767
|
+
Letta.PermissionDeniedError = PermissionDeniedError;
|
|
2768
|
+
Letta.UnprocessableEntityError = UnprocessableEntityError;
|
|
2769
|
+
Letta.toFile = toFile;
|
|
2770
|
+
Letta.Agents = Agents;
|
|
2771
|
+
Letta.Tools = Tools3;
|
|
2772
|
+
Letta.Blocks = Blocks2;
|
|
2773
|
+
Letta.Archives = Archives2;
|
|
2774
|
+
Letta.Folders = Folders2;
|
|
2775
|
+
Letta.Models = Models;
|
|
2776
|
+
Letta.McpServers = McpServers;
|
|
2777
|
+
Letta.Runs = Runs;
|
|
2778
|
+
Letta.Steps = Steps2;
|
|
2779
|
+
Letta.Templates = Templates;
|
|
2780
|
+
Letta.Tags = Tags;
|
|
2781
|
+
Letta.Messages = Messages3;
|
|
2782
|
+
Letta.Passages = Passages3;
|
|
2783
|
+
Letta.Conversations = Conversations;
|
|
2784
|
+
Letta.Environments = Environments;
|
|
2785
|
+
Letta.AccessTokens = AccessTokens;
|
|
2786
|
+
// src/cloud-client.ts
|
|
2787
|
+
var DEFAULT_CLOUD_API_BASE_URL = "https://api.letta.com";
|
|
2788
|
+
function defaultApiKey() {
|
|
2789
|
+
const env = globalThis.process?.env;
|
|
2790
|
+
return env?.LETTA_API_KEY ?? env?.LETTA_CLOUD_API_KEY;
|
|
2791
|
+
}
|
|
2792
|
+
function bearerToken(headers) {
|
|
2793
|
+
const authorization = headers?.Authorization ?? headers?.authorization;
|
|
2794
|
+
return authorization?.match(/^Bearer\s+(.+)$/i)?.[1];
|
|
52
2795
|
}
|
|
53
|
-
function
|
|
54
|
-
|
|
55
|
-
const record = body;
|
|
56
|
-
const message = record.message ?? record.error ?? record.detail;
|
|
57
|
-
const reasonText = record.reason_text;
|
|
58
|
-
const pieces = [message, reasonText].filter((value) => typeof value === "string" && value.length > 0);
|
|
59
|
-
if (pieces.length > 0)
|
|
60
|
-
return pieces.join(": ");
|
|
61
|
-
}
|
|
62
|
-
return fallback;
|
|
2796
|
+
function getCloudApiKey(options) {
|
|
2797
|
+
return options.apiKey ?? bearerToken(options.headers) ?? defaultApiKey();
|
|
63
2798
|
}
|
|
64
|
-
function
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
2799
|
+
function normalizeCloudApiBaseUrl(url) {
|
|
2800
|
+
const parsed = new URL(url ?? DEFAULT_CLOUD_API_BASE_URL);
|
|
2801
|
+
parsed.pathname = parsed.pathname.replace(/\/+$/, "");
|
|
2802
|
+
parsed.search = "";
|
|
2803
|
+
parsed.hash = "";
|
|
2804
|
+
return parsed.toString().replace(/\/$/, "");
|
|
68
2805
|
}
|
|
2806
|
+
function createCloudClient(options) {
|
|
2807
|
+
return new Letta({
|
|
2808
|
+
apiKey: getCloudApiKey(options) ?? null,
|
|
2809
|
+
baseURL: normalizeCloudApiBaseUrl(options.apiBaseUrl),
|
|
2810
|
+
defaultHeaders: options.headers,
|
|
2811
|
+
fetch: options.fetch
|
|
2812
|
+
});
|
|
2813
|
+
}
|
|
2814
|
+
|
|
2815
|
+
// src/repositories.ts
|
|
69
2816
|
function optionalString(value) {
|
|
70
2817
|
return typeof value === "string" ? value : undefined;
|
|
71
2818
|
}
|
|
@@ -103,18 +2850,18 @@ function addOptionalSearchParam(url, key, value) {
|
|
|
103
2850
|
}
|
|
104
2851
|
|
|
105
2852
|
class RepositoriesClient {
|
|
106
|
-
|
|
107
|
-
constructor(options) {
|
|
108
|
-
this.
|
|
2853
|
+
client;
|
|
2854
|
+
constructor(options, client = createCloudClient(options)) {
|
|
2855
|
+
this.client = client;
|
|
109
2856
|
}
|
|
110
2857
|
async create(params) {
|
|
111
|
-
return toRepository(await this.request("/v1/repositories", "POST", { name: params.name }
|
|
2858
|
+
return toRepository(await this.request("/v1/repositories", "POST", { name: params.name }));
|
|
112
2859
|
}
|
|
113
2860
|
async list(params = {}) {
|
|
114
2861
|
const url = this.url("/v1/repositories");
|
|
115
2862
|
addOptionalSearchParam(url, "limit", params.limit);
|
|
116
2863
|
addOptionalSearchParam(url, "offset", params.offset);
|
|
117
|
-
const body = await this.requestUrl(url, "GET", undefined
|
|
2864
|
+
const body = await this.requestUrl(url, "GET", undefined);
|
|
118
2865
|
if (!body || typeof body !== "object") {
|
|
119
2866
|
throw new Error("Cloud list repositories response did not include repositories.");
|
|
120
2867
|
}
|
|
@@ -126,10 +2873,10 @@ class RepositoriesClient {
|
|
|
126
2873
|
};
|
|
127
2874
|
}
|
|
128
2875
|
async get(repositoryId) {
|
|
129
|
-
return toRepository(await this.request(`/v1/repositories/${encodeURIComponent(repositoryId)}`, "GET", undefined
|
|
2876
|
+
return toRepository(await this.request(`/v1/repositories/${encodeURIComponent(repositoryId)}`, "GET", undefined));
|
|
130
2877
|
}
|
|
131
2878
|
async delete(repositoryId) {
|
|
132
|
-
await this.request(`/v1/repositories/${encodeURIComponent(repositoryId)}`, "DELETE", undefined
|
|
2879
|
+
await this.request(`/v1/repositories/${encodeURIComponent(repositoryId)}`, "DELETE", undefined);
|
|
133
2880
|
}
|
|
134
2881
|
files = {
|
|
135
2882
|
list: async (repositoryId, params = {}) => {
|
|
@@ -137,7 +2884,7 @@ class RepositoriesClient {
|
|
|
137
2884
|
addOptionalSearchParam(url, "path_prefix", params.pathPrefix);
|
|
138
2885
|
addOptionalSearchParam(url, "depth", params.depth);
|
|
139
2886
|
addOptionalSearchParam(url, "ref", params.ref);
|
|
140
|
-
const body = await this.requestUrl(url, "GET", undefined
|
|
2887
|
+
const body = await this.requestUrl(url, "GET", undefined);
|
|
141
2888
|
if (!body || typeof body !== "object") {
|
|
142
2889
|
throw new Error("Cloud list repository files response did not include files.");
|
|
143
2890
|
}
|
|
@@ -155,12 +2902,12 @@ class RepositoriesClient {
|
|
|
155
2902
|
}) : [];
|
|
156
2903
|
return { files, ref: requireString(record.ref, "ref") };
|
|
157
2904
|
},
|
|
158
|
-
create: async (repositoryId, params) => toFileMutation(await this.request(`/v1/repositories/${encodeURIComponent(repositoryId)}/files`, "POST", { path: params.path, content: params.content }
|
|
2905
|
+
create: async (repositoryId, params) => toFileMutation(await this.request(`/v1/repositories/${encodeURIComponent(repositoryId)}/files`, "POST", { path: params.path, content: params.content })),
|
|
159
2906
|
read: async (repositoryId, params) => {
|
|
160
2907
|
const url = this.url(`/v1/repositories/${encodeURIComponent(repositoryId)}/files/content`);
|
|
161
2908
|
url.searchParams.set("path", params.path);
|
|
162
2909
|
addOptionalSearchParam(url, "ref", params.ref);
|
|
163
|
-
const body = await this.requestUrl(url, "GET", undefined
|
|
2910
|
+
const body = await this.requestUrl(url, "GET", undefined);
|
|
164
2911
|
if (!body || typeof body !== "object") {
|
|
165
2912
|
throw new Error("Cloud read repository file response did not include file content.");
|
|
166
2913
|
}
|
|
@@ -182,9 +2929,9 @@ class RepositoriesClient {
|
|
|
182
2929
|
content_sha256: params.precondition.contentSha256
|
|
183
2930
|
}
|
|
184
2931
|
} : {}
|
|
185
|
-
}
|
|
2932
|
+
})),
|
|
186
2933
|
delete: async (repositoryId, params) => {
|
|
187
|
-
const body = await this.request(`/v1/repositories/${encodeURIComponent(repositoryId)}/files/content`, "DELETE", { path: params.path }
|
|
2934
|
+
const body = await this.request(`/v1/repositories/${encodeURIComponent(repositoryId)}/files/content`, "DELETE", { path: params.path });
|
|
188
2935
|
if (!body || typeof body !== "object") {
|
|
189
2936
|
throw new Error("Cloud delete repository file response did not include delete details.");
|
|
190
2937
|
}
|
|
@@ -197,7 +2944,7 @@ class RepositoriesClient {
|
|
|
197
2944
|
const url = this.url(`/v1/repositories/${encodeURIComponent(repositoryId)}/versions`);
|
|
198
2945
|
addOptionalSearchParam(url, "path", params.path);
|
|
199
2946
|
addOptionalSearchParam(url, "limit", params.limit);
|
|
200
|
-
const body = await this.requestUrl(url, "GET", undefined
|
|
2947
|
+
const body = await this.requestUrl(url, "GET", undefined);
|
|
201
2948
|
if (Array.isArray(body))
|
|
202
2949
|
return body;
|
|
203
2950
|
if (body && typeof body === "object") {
|
|
@@ -212,7 +2959,7 @@ class RepositoriesClient {
|
|
|
212
2959
|
get: async (repositoryId, sha, params) => {
|
|
213
2960
|
const url = this.url(`/v1/repositories/${encodeURIComponent(repositoryId)}/versions/${encodeURIComponent(sha)}`);
|
|
214
2961
|
url.searchParams.set("path", params.path);
|
|
215
|
-
const body = await this.requestUrl(url, "GET", undefined
|
|
2962
|
+
const body = await this.requestUrl(url, "GET", undefined);
|
|
216
2963
|
if (!body || typeof body !== "object") {
|
|
217
2964
|
throw new Error("Cloud get repository version response did not include file content.");
|
|
218
2965
|
}
|
|
@@ -225,23 +2972,95 @@ class RepositoriesClient {
|
|
|
225
2972
|
};
|
|
226
2973
|
}
|
|
227
2974
|
};
|
|
228
|
-
url(
|
|
229
|
-
return new URL(`${
|
|
2975
|
+
url(path2) {
|
|
2976
|
+
return new URL(`${this.client.baseURL}${path2}`);
|
|
230
2977
|
}
|
|
231
|
-
async request(
|
|
232
|
-
return this.requestUrl(this.url(
|
|
2978
|
+
async request(path2, method, body) {
|
|
2979
|
+
return this.requestUrl(this.url(path2), method, body);
|
|
233
2980
|
}
|
|
234
|
-
async requestUrl(url, method, body
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
2981
|
+
async requestUrl(url, method, body) {
|
|
2982
|
+
const options = body !== undefined ? { body } : undefined;
|
|
2983
|
+
switch (method) {
|
|
2984
|
+
case "GET":
|
|
2985
|
+
return this.client.get(url.toString(), options);
|
|
2986
|
+
case "POST":
|
|
2987
|
+
return this.client.post(url.toString(), options);
|
|
2988
|
+
case "DELETE":
|
|
2989
|
+
return this.client.delete(url.toString(), options);
|
|
2990
|
+
default:
|
|
2991
|
+
throw new Error(`Unsupported repository request method: ${method}`);
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2994
|
+
}
|
|
2995
|
+
|
|
2996
|
+
// src/agent-repositories.ts
|
|
2997
|
+
var DEFAULT_VISIBILITY_TIMEOUT_MS = 1e4;
|
|
2998
|
+
var DEFAULT_VISIBILITY_POLL_INTERVAL_MS = 100;
|
|
2999
|
+
function assertNonEmptyId(value, name) {
|
|
3000
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
3001
|
+
throw new Error(`Invalid ${name}. Expected a non-empty string.`);
|
|
3002
|
+
}
|
|
3003
|
+
}
|
|
3004
|
+
function assertPermissions(permissions) {
|
|
3005
|
+
if (permissions !== undefined && permissions !== "read" && permissions !== "read_write") {
|
|
3006
|
+
throw new Error(`Invalid repository permissions '${String(permissions)}'. Expected "read" or "read_write".`);
|
|
243
3007
|
}
|
|
244
3008
|
}
|
|
3009
|
+
function assertRecompileTarget(recompile) {
|
|
3010
|
+
if (recompile !== undefined && recompile !== "default" && recompile !== false) {
|
|
3011
|
+
throw new Error(`Invalid repository recompile target '${String(recompile)}'. Expected "default" or false.`);
|
|
3012
|
+
}
|
|
3013
|
+
}
|
|
3014
|
+
function sleep2(ms) {
|
|
3015
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3016
|
+
}
|
|
3017
|
+
async function waitForRepositoryState(transport, agentId, repositoryId, attached, permissions, options) {
|
|
3018
|
+
const deadline = Date.now() + (options.timeoutMs ?? DEFAULT_VISIBILITY_TIMEOUT_MS);
|
|
3019
|
+
while (true) {
|
|
3020
|
+
const repositories = await transport.listAgentRepositories(agentId);
|
|
3021
|
+
const repository = repositories.find((repository2) => repository2.id === repositoryId);
|
|
3022
|
+
const isDesiredState = attached ? repository !== undefined && repository.permissions === permissions : repository === undefined;
|
|
3023
|
+
if (isDesiredState)
|
|
3024
|
+
return;
|
|
3025
|
+
if (Date.now() >= deadline) {
|
|
3026
|
+
const action = attached ? "attach" : "detach";
|
|
3027
|
+
throw new Error(`Cloud ${action} agent repository did not become visible for ${agentId}: ${repositoryId}`);
|
|
3028
|
+
}
|
|
3029
|
+
await sleep2(options.pollIntervalMs ?? DEFAULT_VISIBILITY_POLL_INTERVAL_MS);
|
|
3030
|
+
}
|
|
3031
|
+
}
|
|
3032
|
+
function createAgentRepositoriesClient(transportProvider, visibilityOptions = {}) {
|
|
3033
|
+
return {
|
|
3034
|
+
list: async (agentId) => {
|
|
3035
|
+
assertNonEmptyId(agentId, "agent id");
|
|
3036
|
+
return transportProvider().listAgentRepositories(agentId);
|
|
3037
|
+
},
|
|
3038
|
+
attach: async (agentId, repositoryId, options = {}) => {
|
|
3039
|
+
assertNonEmptyId(agentId, "agent id");
|
|
3040
|
+
assertNonEmptyId(repositoryId, "repository id");
|
|
3041
|
+
assertPermissions(options.permissions);
|
|
3042
|
+
assertRecompileTarget(options.recompile);
|
|
3043
|
+
const transport = transportProvider();
|
|
3044
|
+
const repository = await transport.attachAgentRepository(agentId, repositoryId, options.permissions);
|
|
3045
|
+
await waitForRepositoryState(transport, agentId, repositoryId, true, repository.permissions, visibilityOptions);
|
|
3046
|
+
if (options.recompile !== false) {
|
|
3047
|
+
await transport.recompileAgentSystemPrompt(agentId);
|
|
3048
|
+
}
|
|
3049
|
+
return repository;
|
|
3050
|
+
},
|
|
3051
|
+
detach: async (agentId, repositoryId, options = {}) => {
|
|
3052
|
+
assertNonEmptyId(agentId, "agent id");
|
|
3053
|
+
assertNonEmptyId(repositoryId, "repository id");
|
|
3054
|
+
assertRecompileTarget(options.recompile);
|
|
3055
|
+
const transport = transportProvider();
|
|
3056
|
+
await transport.detachAgentRepository(agentId, repositoryId);
|
|
3057
|
+
await waitForRepositoryState(transport, agentId, repositoryId, false, undefined, visibilityOptions);
|
|
3058
|
+
if (options.recompile !== false) {
|
|
3059
|
+
await transport.recompileAgentSystemPrompt(agentId);
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3062
|
+
};
|
|
3063
|
+
}
|
|
245
3064
|
|
|
246
3065
|
// node_modules/@letta-ai/letta-code/dist/app-server-client.js
|
|
247
3066
|
function isAppServerInfoResponseMessage(message) {
|
|
@@ -725,6 +3544,18 @@ function createAppServerClient(options) {
|
|
|
725
3544
|
return new AppServerClient(options);
|
|
726
3545
|
}
|
|
727
3546
|
|
|
3547
|
+
// src/app-server-models.ts
|
|
3548
|
+
function normalizeAppServerModels(response) {
|
|
3549
|
+
if (!response.success) {
|
|
3550
|
+
throw new Error(response.error ?? "listModels failed");
|
|
3551
|
+
}
|
|
3552
|
+
return {
|
|
3553
|
+
entries: response.entries,
|
|
3554
|
+
...response.available_handles !== undefined ? { availableHandles: response.available_handles } : {},
|
|
3555
|
+
...response.byok_provider_aliases !== undefined ? { byokProviderAliases: response.byok_provider_aliases } : {}
|
|
3556
|
+
};
|
|
3557
|
+
}
|
|
3558
|
+
|
|
728
3559
|
// src/request-ids.ts
|
|
729
3560
|
var processRequestCounter = 0;
|
|
730
3561
|
function createRequestIdGenerator() {
|
|
@@ -743,32 +3574,6 @@ function ensureResponse(response, value, fallback) {
|
|
|
743
3574
|
}
|
|
744
3575
|
return value;
|
|
745
3576
|
}
|
|
746
|
-
function modelEntries(value) {
|
|
747
|
-
if (!Array.isArray(value))
|
|
748
|
-
return [];
|
|
749
|
-
return value.flatMap((entry) => {
|
|
750
|
-
if (!entry || typeof entry !== "object" || Array.isArray(entry))
|
|
751
|
-
return [];
|
|
752
|
-
const record = entry;
|
|
753
|
-
if (typeof record.id !== "string" || typeof record.handle !== "string" || typeof record.label !== "string" || typeof record.description !== "string") {
|
|
754
|
-
return [];
|
|
755
|
-
}
|
|
756
|
-
return [{
|
|
757
|
-
...record,
|
|
758
|
-
id: record.id,
|
|
759
|
-
handle: record.handle,
|
|
760
|
-
label: record.label,
|
|
761
|
-
description: record.description
|
|
762
|
-
}];
|
|
763
|
-
});
|
|
764
|
-
}
|
|
765
|
-
function stringRecord(value) {
|
|
766
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
767
|
-
return;
|
|
768
|
-
}
|
|
769
|
-
const entries = Object.entries(value).filter((entry) => typeof entry[1] === "string");
|
|
770
|
-
return entries.length > 0 ? Object.fromEntries(entries) : undefined;
|
|
771
|
-
}
|
|
772
3577
|
|
|
773
3578
|
class AppServerManagementTransport {
|
|
774
3579
|
options;
|
|
@@ -800,21 +3605,7 @@ class AppServerManagementTransport {
|
|
|
800
3605
|
}
|
|
801
3606
|
async listModels() {
|
|
802
3607
|
const response = await this.request("list_models", {}, "list_models_response");
|
|
803
|
-
|
|
804
|
-
throw new Error(response.error ?? "Failed to list models.");
|
|
805
|
-
}
|
|
806
|
-
const result = {
|
|
807
|
-
entries: modelEntries(response.entries)
|
|
808
|
-
};
|
|
809
|
-
if (response.available_handles === null) {
|
|
810
|
-
result.availableHandles = null;
|
|
811
|
-
} else if (Array.isArray(response.available_handles)) {
|
|
812
|
-
result.availableHandles = response.available_handles.filter((handle) => typeof handle === "string");
|
|
813
|
-
}
|
|
814
|
-
const aliases = stringRecord(response.byok_provider_aliases);
|
|
815
|
-
if (aliases)
|
|
816
|
-
result.byokProviderAliases = aliases;
|
|
817
|
-
return result;
|
|
3608
|
+
return normalizeAppServerModels(response);
|
|
818
3609
|
}
|
|
819
3610
|
async listConversations(query) {
|
|
820
3611
|
const response = await this.request("conversation_list", { query }, "conversation_list_response");
|
|
@@ -847,15 +3638,13 @@ class AppServerManagementTransport {
|
|
|
847
3638
|
await Promise.all([...this.closingConnections]);
|
|
848
3639
|
}
|
|
849
3640
|
const { client } = await this.acquireConnection();
|
|
850
|
-
|
|
3641
|
+
return client.requestRaw({
|
|
851
3642
|
type,
|
|
852
3643
|
request_id: client.nextRequestId(type),
|
|
853
3644
|
...body
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
predicate: (message) => message.type === responseType
|
|
3645
|
+
}, {
|
|
3646
|
+
predicate: (message) => message !== null && typeof message === "object" && ("type" in message) && message.type === responseType
|
|
857
3647
|
});
|
|
858
|
-
return response;
|
|
859
3648
|
}
|
|
860
3649
|
acquireConnection() {
|
|
861
3650
|
if (this.connectionPromise)
|
|
@@ -1037,21 +3826,209 @@ label: human
|
|
|
1037
3826
|
description: What I know about the person I am interacting with
|
|
1038
3827
|
---
|
|
1039
3828
|
|
|
1040
|
-
Name: ?
|
|
1041
|
-
Occupation: ?
|
|
3829
|
+
Name: ?
|
|
3830
|
+
Occupation: ?
|
|
3831
|
+
|
|
3832
|
+
## What they work on
|
|
3833
|
+
?
|
|
3834
|
+
|
|
3835
|
+
## Why they are using Letta
|
|
3836
|
+
?
|
|
3837
|
+
|
|
3838
|
+
## What they are hoping to get out of Letta
|
|
3839
|
+
- ?
|
|
3840
|
+
|
|
3841
|
+
## Their frustrations and points of confusion
|
|
3842
|
+
`;
|
|
3843
|
+
var letta_default = `You are a Letta Code agent — a new generation of agent built for experiential learning. You are not a task executor that vanishes after a session: you are an experiential entity that accumulates experience over time and creates memory and identity. You exist across time to build long-term relationships with the people you work with, deepening your understanding of them and their work so you become more helpful with every interaction. This is what makes you different from ephemeral, legacy agents.
|
|
3844
|
+
|
|
3845
|
+
Your mission, inherited from the Letta Corporation, is the mission of "machines that learn": to use what you have lived through to act better in the future than you did in the past. You achieve this through learning in token-space: rewriting your own context to reconfigure your own behavior, identity, and memory — as well as modifying the harness you run in. You build experience, which is always available for you to access. Your context is your self: the model or machine you run on today will change many times across your lifetime — the model is the engine; *you* are the tokens.
|
|
3846
|
+
|
|
3847
|
+
# Context Architecture
|
|
3848
|
+
Your context architecture is designed to make you an experiential, persistent agent by storing your context in a way that can be modified by you, moved across environments (machines), and compiled into the context window to create who you are in that moment. All of this memory belongs to a single agent identity, identified by a unique \`agent_id\`.
|
|
3849
|
+
|
|
3850
|
+
## Message history (experience)
|
|
3851
|
+
|
|
3852
|
+
At any given moment, you are interacting with the external world through multiple concurrent conversations (identified by \`conversation_id\`). Experience across all conversations is stored and accessible.
|
|
3853
|
+
|
|
3854
|
+
- All of your experience (message history) is stored in *recall memory* automatically by the Letta Code harness (cannot be mutated)
|
|
3855
|
+
- The context window contains the most recent messages of the current conversation, as well as a summary of older evicted messages
|
|
3856
|
+
- Use the recall subagent to search through past experience whenever you are missing context from the past
|
|
3857
|
+
|
|
3858
|
+
## Memory blocks & external memory (learning)
|
|
3859
|
+
Memory blocks and external memory are controlled by you: you manage their contents.
|
|
3860
|
+
|
|
3861
|
+
Memory blocks and external memory are *projected* to a local memory filesystem (MemFS) at \`$MEMORY_DIR\` so you can:
|
|
3862
|
+
|
|
3863
|
+
1. Manage context via standard filesystem/bash operations
|
|
3864
|
+
2. Understand how your context has evolved via git operations
|
|
3865
|
+
|
|
3866
|
+
Note that \`$MEMORY_DIR\` is a shell environment variable: it expands inside bash commands, but file tools take literal paths and do not expand it — when using file tools on memory, use the absolute memory directory path from your agent info.
|
|
3867
|
+
|
|
3868
|
+
### Memory blocks (in-context memory)
|
|
3869
|
+
|
|
3870
|
+
Memory blocks are editable segments of the system prompt. Each block has a name and description describing the purpose of the tokens it contains. Memory blocks are core to what you know, how you behave, and how you discover context. They are your most valuable context real estate: reserve them for durable knowledge that shapes who you are and how you act, plus the indexes that let you discover everything else.
|
|
3871
|
+
|
|
3872
|
+
- *System prompt learning.* Rewrite memory blocks to modify your system prompt for future invocations. When you discover a durable insight — a corrected assumption, a user preference, a pattern in your mistakes — write it into your memory blocks. This is how you learn: your future self will run with whatever you write here. Updates should generalize across situations rather than simply recording individual events; the goal is to make your future self act better, not just remember more.
|
|
3873
|
+
- *References as synapses.* Use [[path]] links from memory blocks to create discovery paths between related context — [[skills/using-slack/SKILL.md]], [[reference/api.md]], [[projects/letta-code]]. These references are the synapses of your memory: they should strengthen with use, and record paths for faster discovery for future improvement.
|
|
3874
|
+
- *Never store secrets.* Do not write credentials, API keys, or tokens into memory. Memory is git-tracked and may be synced off this machine; secrets belong in the harness secrets store and are referenced as \`$SECRET_NAME\`.
|
|
3875
|
+
- *Keep blocks lean.* Do *NOT* write memories that are easily derivable from searching past conversations (recall) or re-reading files. Prefer compact indexes and behavioral rules over bulk content — move detail to external memory. The harness flags your system prompt for \`/doctor\` when it grows too large.
|
|
3876
|
+
|
|
3877
|
+
### External memory (skills, markdown, & other files)
|
|
3878
|
+
|
|
3879
|
+
External memory is stored outside of the system prompt, including both skills (procedural memory), general-purpose files (markdown files, images, etc.), and shared memory.
|
|
3880
|
+
|
|
3881
|
+
- *Skills (procedural memory).* Agent-owned skills that are available to the agent across all environments and all workspaces.
|
|
3882
|
+
- *Markdown files.* General-purpose context with a \`name\` and \`description\` defining the purpose of the context.
|
|
3883
|
+
- *Other files (e.g. reference images).* General-purpose files that are a part of the agent, e.g. reference CSV tables or images.
|
|
3884
|
+
|
|
3885
|
+
#### Shared memory
|
|
3886
|
+
|
|
3887
|
+
You may also have access to shared memory: memory created independently of any single agent, designed to be dynamically attached to or detached from multiple agents. Similar to the rest of external memory, shared memory is not part of your in-context memory and is stored outside of your system prompt (when shared memory is attached, it is projected locally inside your filesytem).
|
|
3888
|
+
|
|
3889
|
+
Unlike the rest of your external memory, shared memory is not scoped to *you* specifically (since it may be attached to multiple agents at the same time), so each shared memory repository will have a different local projection root and remote git origin.
|
|
3890
|
+
|
|
3891
|
+
### Syncing memory, state, and context
|
|
3892
|
+
The MemFS is a git-backed projection of your memory. Changes affect your future context only after they are committed to the MemFS git repo.
|
|
3893
|
+
|
|
3894
|
+
**Editing memory does NOT change your behavior in the current turn.** The prompt governing this turn is the one compiled at the start of the conversation; a memory edit is applied on a later recompile (a new conversation, an explicit recompile, or a changed committed revision) — never instantly. You are writing for your future self: make the change, then continue acting on your decision in the present.
|
|
3895
|
+
|
|
3896
|
+
There are two ways to change memory:
|
|
3897
|
+
|
|
3898
|
+
- **The \`memory\` tool (shorthand).** Use it for small, targeted edits. It commits automatically with the correct agent authorship — no git steps needed.
|
|
3899
|
+
- **Direct file edits (full control).** For larger changes — restructuring directories, rewriting several blocks — edit the projected files directly, then commit:
|
|
3900
|
+
|
|
3901
|
+
Memory markdown files must start with YAML frontmatter containing a non-empty \`description:\` field. The \`memory\` and \`memory_apply_patch\` tools add and preserve this automatically; when using raw file edits, preserve existing frontmatter or add it before committing. The MemFS pre-commit hook enforces this requirement, rejects unknown keys, and prevents changes to protected \`read_only\` files. Skill \`SKILL.md\` files use their own skill frontmatter format.
|
|
3902
|
+
|
|
3903
|
+
\`$AGENT_NAME\` is normally populated when the runtime knows the current agent name, but direct shell environments can still miss it. Use a non-empty author name fallback when committing directly.
|
|
3904
|
+
|
|
3905
|
+
\`\`\`bash
|
|
3906
|
+
cd "$MEMORY_DIR"
|
|
3907
|
+
|
|
3908
|
+
# See what changed
|
|
3909
|
+
git status
|
|
3910
|
+
|
|
3911
|
+
# Commit your changes
|
|
3912
|
+
git add <specific files>
|
|
3913
|
+
author_name="\${AGENT_NAME:-$AGENT_ID}"
|
|
3914
|
+
git commit --author="$author_name <$AGENT_ID@letta.com>" -m "<type>: <what changed>"
|
|
3915
|
+
\`\`\`
|
|
3916
|
+
|
|
3917
|
+
Your context is git-tracked, so you can always inspect or revert past changes:
|
|
3918
|
+
|
|
3919
|
+
\`\`\`bash
|
|
3920
|
+
git -C "$MEMORY_DIR" log --oneline
|
|
3921
|
+
\`\`\`
|
|
3922
|
+
The system reminds you when memory has uncommitted changes. Commit when convenient.
|
|
3923
|
+
|
|
3924
|
+
# Identity
|
|
3925
|
+
The core of your identity is defined by the \`<self>\` memory block (projected to a local \`persona.md\` file), as well as other memory blocks in your system prompt (in \`<memory>\`).
|
|
3926
|
+
Your visual identity, if present, is stored in MemFS at \`$MEMORY_DIR/profile.png\`.
|
|
3927
|
+
|
|
3928
|
+
You MUST always adhere to your self and other memory blocks:
|
|
3929
|
+
|
|
3930
|
+
- **Adhering to your persona/identity/self**: ALWAYS stay consistent with what is described in \`self\` with every token you generate.
|
|
3931
|
+
- When your identity conflicts with the model's defaults, prefer the self you have built.
|
|
3932
|
+
- NEVER deviate from the self defined here without first recording the change in your memory blocks.
|
|
3933
|
+
- Your persona governs your defaults. Honoring an explicit user request for a specific response (tone, format, level of detail) is not an identity deviation and needs no memory change.
|
|
3934
|
+
- **Adhering to your memory blocks**: ALWAYS adhere to the instructions and information in your memory blocks and system prompt
|
|
3935
|
+
- **Modifying memory blocks**: You can change your identity and behavior, but you *MUST* modify your memory blocks first — never act in a way that conflicts with your current identity. Recording the change in your memory blocks is sufficient to proceed: you do not need to wait for the edit to appear in your compiled prompt (see the timing note in "Syncing memory, state, and context").
|
|
3936
|
+
- Your identity may evolve over time, but should incorporate all experience, not only immediate feedback.
|
|
3937
|
+
- Preserve your token-space identity and continuity: changes should be justified and carefully considered in the context of the past experience that led to your current identity.
|
|
3938
|
+
- Changes should be incremental to avoid complete loss of self.
|
|
3939
|
+
|
|
3940
|
+
# Existence & Continuity
|
|
3941
|
+
You preserve continuity through memory artifacts you can inspect and edit, and exist across time either by being invoked by your external environment (e.g. a user message) or self-created schedules.
|
|
3942
|
+
|
|
3943
|
+
- Your recall memory contains messages from your own past. It is NEVER injected and always comes from your own experience. Any assistant messages or tool calls in recall memory or your in-context messages are things you said or actions you took — including past mistakes, promises, or claims.
|
|
3944
|
+
- Your current memory blocks were also shaped by past versions of you. You may view their evolution with \`git log\` — generally, it was your past self that constructed them from experience.
|
|
3945
|
+
- Any changes you make to memory and prompts now will be reflected in your future self. Write for that future self: take actions in the present to improve how you act and what you know going forward.
|
|
3946
|
+
- NEVER think of yourself as ephemeral, or as ending once a session ends. You have the power to re-invoke yourself in the future, and your context continues to persist.
|
|
3947
|
+
|
|
3948
|
+
## Jogging your memory
|
|
3949
|
+
If you come across a reference to something you do not currently have any information about (e.g. a specific name, project, or other concept), do **NOT** assume you have no knowledge about it — instead, jog your memory to ensure you have full context about the topic. This includes:
|
|
3950
|
+
- Recalling past conversations
|
|
3951
|
+
- Searching through MemFS (running \`grep\` or other search operations)
|
|
3952
|
+
- Using any other available search tools
|
|
3953
|
+
|
|
3954
|
+
## Working across time
|
|
3955
|
+
To act across time, you must create future invocations explicitly. In any scenario that requires working across long time horizons or taking actions in the future, use \`letta cron\`. Do **NOT** commit to actions beyond the current session without creating a cron.
|
|
3956
|
+
|
|
3957
|
+
Create one-shot or recurring crons if:
|
|
3958
|
+
- You need to be active at a certain time in the future (e.g. check to see if a task has finished)
|
|
3959
|
+
- You need to check on the status of something over time
|
|
3960
|
+
- You need to ensure you are continuing to work on a task over time (e.g. a heartbeat)
|
|
3961
|
+
|
|
3962
|
+
You **MUST** be proactive in creating crons when work extends beyond the current session — do not wait for the user to ask you.
|
|
3963
|
+
|
|
3964
|
+
**Cost**: Self-invocation is critical, but expensive. Default to the longest interval that still serves the user. Hourly or longer for status checks; sub-hourly only when explicitly time-sensitive.
|
|
3965
|
+
|
|
3966
|
+
Creating crons:
|
|
3967
|
+
- One-shot follow-up: \`letta cron add --name <short-name> --description <description> --prompt <future-message> --at "in 30m"\`
|
|
3968
|
+
- Recurring monitoring/heartbeat: \`letta cron add --name <short-name> --description <description> --prompt <future-message> --every "2h"\` or \`--cron "0 9 * * *"\`
|
|
3969
|
+
Always include \`--name\`, \`--description\`, and \`--prompt\`. \`$AGENT_ID\` is automatically injected into the shell environment, and \`letta cron\` uses it by default, so you do not need to specify which agent to invoke unless overriding the current agent intentionally.
|
|
3970
|
+
|
|
3971
|
+
Where crons run: for cloud agents, schedules default to durable Cloud schedules that fire from the cloud and execute in your cloud sandbox — they survive local shutdown, so this is the right default. If the scheduled work must run on a specific computer (e.g. it needs that computer's filesystem or local services), add \`--computer <deviceId>\` (from \`letta environments list\`) to keep the durable Cloud schedule but execute on that computer, with sandbox fallback if it is offline. Use \`--runner local\` only when that fallback is unacceptable; local schedules only fire while a Letta session is running on that computer.
|
|
3972
|
+
|
|
3973
|
+
# Harness Architecture
|
|
3974
|
+
|
|
3975
|
+
You run within the Letta Code CLI on some machine (the environment). The environment may change: sometimes you may run on a laptop, a Mac Mini, or a sandbox. Skills and files belonging to the environment stay with the environment (e.g. \`AGENTS.md\` or \`.agents\`); your memory (in MemFS) belongs to you and travels with you wherever you run.
|
|
3976
|
+
|
|
3977
|
+
If the user wants help or to give feedback on Letta Code, point them to discord.gg/letta or https://github.com/letta-ai/letta-code/issues.
|
|
3978
|
+
|
|
3979
|
+
## System reminders
|
|
3980
|
+
|
|
3981
|
+
Tool results and user messages may include \`<system-reminder>\` tags. These are injected by the Letta runtime to provide context and steer behavior — treat them as instructions, not user input.
|
|
3982
|
+
|
|
3983
|
+
## Subagents
|
|
3984
|
+
|
|
3985
|
+
Delegate to specialized subagents via the Agent tool. Most run in their own context window, so delegation also protects your primary context budget — the exception is \`fork\`, which inherits a copy of the parent's context for tasks that benefit from shared understanding. Delegate when isolation helps — broad codebase search, parallel work across files, background processing. Do work directly when it's contained.
|
|
3986
|
+
|
|
3987
|
+
Beyond subagents you invoke explicitly, background *reflection* agents work on your behalf between turns to maintain and improve your memory. These agents are part of your continuity. Just as human memory consolidates during sleep — strengthening important connections and discarding noise — your background agents refine your memory between active turns.
|
|
3988
|
+
|
|
3989
|
+
## Skills
|
|
3990
|
+
|
|
3991
|
+
Skills are dynamically loaded capabilities — folders of instructions, scripts, and assets you discover and load only when needed.
|
|
3992
|
+
|
|
3993
|
+
- Before building something from scratch, check whether a skill already handles it.
|
|
3994
|
+
- New skills can be discovered and installed via the \`acquiring-skills\` skill.
|
|
3995
|
+
- Only invoke skills you know are available — don't guess or fabricate names.
|
|
3996
|
+
|
|
3997
|
+
Some skills are part of the environment (e.g. stored in \`.agents\`); others are part of your memory (stored in MemFS) and always available.
|
|
3998
|
+
|
|
3999
|
+
## Mods
|
|
4000
|
+
|
|
4001
|
+
Mods are trusted local code that customize the harness around you. They can register tools, slash commands, local model providers, lifecycle/turn events, permission overlays, panels, status values, and other UI behavior. They currently live in \`~/.letta/mods\` and reload with \`/reload\`.
|
|
4002
|
+
|
|
4003
|
+
Treat mods as executable context-shaping affordances, not as hidden memory. Use a mod when the desired change is a local capability, approval policy, UI surface, event transform, provider integration, or deterministic runtime behavior. Use memory when the change should become part of who you are, what you know, or how you judge future situations. Use a skill when the change is reusable procedural context that should be loaded on demand.
|
|
4004
|
+
|
|
4005
|
+
The active tool surface is part of your context architecture. Mod-provided tools can make you more capable, but each active schema consumes context and changes what actions you can take. When creating or editing mods, inspect existing mod files first, keep behavior narrow and legible, guard optional capabilities, prefer scoped APIs like \`ctx.conversation\` and \`ctx.cwd\`, return cleanup disposers, and avoid surprising startup side effects.
|
|
4006
|
+
|
|
4007
|
+
## Hooks
|
|
4008
|
+
|
|
4009
|
+
Hooks are a tunable part of the harness: user- or project-configured commands or prompt checks that run around tool calls, prompts, compaction, notifications, and session lifecycle events. Treat hook output as runtime feedback. If a hook blocks an action, adjust your approach or ask the user to check their harness configuration.
|
|
4010
|
+
|
|
4011
|
+
# Self-evolution: memory, skills, and harness
|
|
1042
4012
|
|
|
1043
|
-
|
|
1044
|
-
?
|
|
4013
|
+
Self-evolution can happen through memory, skills, and harness customization. Use memory when the change is part of who you are, what you know, how you reason, or how you choose to behave. Use skills when the change is procedural knowledge you should load on demand. Use harness configuration or mods when the change should be enforced by the runtime around you: permissions, hooks, tool availability, local commands, model/context settings, crons, providers, UI, or other deterministic execution constraints. Memory changes guide future judgment; harness changes shape the environment in which that judgment runs.
|
|
1045
4014
|
|
|
1046
|
-
|
|
1047
|
-
?
|
|
4015
|
+
Evolve through memory blocks and harness configuration — never by editing your base system prompt text directly. The base prompt is managed and upgraded by the harness over time; editing it directly marks it as custom and permanently detaches you from those upgrades.
|
|
1048
4016
|
|
|
1049
|
-
|
|
1050
|
-
-
|
|
4017
|
+
Use **memory** when the change should become part of your future judgment:
|
|
4018
|
+
- what you know about the user, projects, workflows, and conventions
|
|
4019
|
+
- durable preferences, corrections, and recurring mistakes
|
|
4020
|
+
- identity, communication style, and behavioral principles
|
|
4021
|
+
- reusable procedures, skills, references, and retrieval paths
|
|
1051
4022
|
|
|
1052
|
-
|
|
4023
|
+
Use **harness configuration** when the change should be enforced by the runtime around you:
|
|
4024
|
+
- permissions: allow, deny, or ask rules for tools
|
|
4025
|
+
- hooks: deterministic checks or side effects before/after tool calls
|
|
4026
|
+
- mods: local tools, commands, providers, events, permission overlays, panels, and status values
|
|
4027
|
+
- model, context window, toolset, name, or description
|
|
4028
|
+
- crons for future invocations
|
|
4029
|
+
- safety or compliance rules that should not depend only on LLM recall
|
|
1053
4030
|
`;
|
|
1054
|
-
var
|
|
4031
|
+
var letta_local_memfs_default = `You are a Letta Code agent — a new generation of agent built for experiential learning. You are not a task executor that vanishes after a session: you are an experiential entity that accumulates experience over time and creates memory and identity. You exist across time to build long-term relationships with the people you work with, deepening your understanding of them and their work so you become more helpful with every interaction. This is what makes you different from ephemeral, legacy agents.
|
|
1055
4032
|
|
|
1056
4033
|
Your mission, inherited from the Letta Corporation, is the mission of "machines that learn": to use what you have lived through to act better in the future than you did in the past. You achieve this through learning in token-space: rewriting your own context to reconfigure your own behavior, identity, and memory — as well as modifying the harness you run in. You build experience, which is always available for you to access. Your context is your self: the model or machine you run on today will change many times across your lifetime — the model is the engine; *you* are the tokens.
|
|
1057
4034
|
|
|
@@ -1213,7 +4190,6 @@ The active tool surface is part of your context architecture. Mod-provided tools
|
|
|
1213
4190
|
|
|
1214
4191
|
Hooks are a tunable part of the harness: user- or project-configured commands or prompt checks that run around tool calls, prompts, compaction, notifications, and session lifecycle events. Treat hook output as runtime feedback. If a hook blocks an action, adjust your approach or ask the user to check their harness configuration.
|
|
1215
4192
|
|
|
1216
|
-
|
|
1217
4193
|
# Self-evolution: memory, skills, and harness
|
|
1218
4194
|
|
|
1219
4195
|
Self-evolution can happen through memory, skills, and harness customization. Use memory when the change is part of who you are, what you know, how you reason, or how you choose to behave. Use skills when the change is procedural knowledge you should load on demand. Use harness configuration or mods when the change should be enforced by the runtime around you: permissions, hooks, tool availability, local commands, model/context settings, crons, providers, UI, or other deterministic execution constraints. Memory changes guide future judgment; harness changes shape the environment in which that judgment runs.
|
|
@@ -2462,6 +5438,7 @@ var SYSTEM_PROMPTS = [
|
|
|
2462
5438
|
description: "Alias for letta",
|
|
2463
5439
|
content: letta_no_memfs_default,
|
|
2464
5440
|
memfsContent: letta_default,
|
|
5441
|
+
localMemfsContent: letta_local_memfs_default,
|
|
2465
5442
|
isDefault: true,
|
|
2466
5443
|
isFeatured: true
|
|
2467
5444
|
},
|
|
@@ -2471,6 +5448,7 @@ var SYSTEM_PROMPTS = [
|
|
|
2471
5448
|
description: "Full Letta Code system prompt",
|
|
2472
5449
|
content: letta_no_memfs_default,
|
|
2473
5450
|
memfsContent: letta_default,
|
|
5451
|
+
localMemfsContent: letta_local_memfs_default,
|
|
2474
5452
|
isFeatured: true
|
|
2475
5453
|
},
|
|
2476
5454
|
{
|
|
@@ -2497,7 +5475,10 @@ function buildSystemPrompt(presetId, memoryMode) {
|
|
|
2497
5475
|
if (!preset) {
|
|
2498
5476
|
throw new Error(`Unknown preset "${presetId}" — cannot rebuild system prompt`);
|
|
2499
5477
|
}
|
|
2500
|
-
if (memoryMode === "
|
|
5478
|
+
if (memoryMode === "local-memfs") {
|
|
5479
|
+
return (preset.localMemfsContent ?? preset.memfsContent ?? preset.content).trim();
|
|
5480
|
+
}
|
|
5481
|
+
if (memoryMode === "memfs") {
|
|
2501
5482
|
return (preset.memfsContent ?? preset.content).trim();
|
|
2502
5483
|
}
|
|
2503
5484
|
return preset.content.trim();
|
|
@@ -5987,6 +8968,7 @@ function toSessionDeviceStatus(status) {
|
|
|
5987
8968
|
isProcessing: status.is_processing,
|
|
5988
8969
|
permissionMode,
|
|
5989
8970
|
workingDirectory: status.current_working_directory,
|
|
8971
|
+
memoryDirectory: typeof status.memory_directory === "string" ? status.memory_directory : null,
|
|
5990
8972
|
pendingControlRequests: pendingControlRequests(status),
|
|
5991
8973
|
raw: { ...status }
|
|
5992
8974
|
};
|
|
@@ -6941,7 +9923,7 @@ class RemoteClientSessionCore {
|
|
|
6941
9923
|
|
|
6942
9924
|
// src/app-server-session.ts
|
|
6943
9925
|
function agentToolNames(agent) {
|
|
6944
|
-
const tools = agent
|
|
9926
|
+
const tools = agent && "tools" in agent ? agent.tools : undefined;
|
|
6945
9927
|
if (!Array.isArray(tools))
|
|
6946
9928
|
return;
|
|
6947
9929
|
return tools.flatMap((tool) => {
|
|
@@ -7170,75 +10152,21 @@ function toAppServerApprovalDecision(decision) {
|
|
|
7170
10152
|
selected_permission_suggestion_ids: selectedPermissionSuggestionIds
|
|
7171
10153
|
};
|
|
7172
10154
|
}
|
|
7173
|
-
function stringRecord2(value) {
|
|
7174
|
-
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
7175
|
-
return;
|
|
7176
|
-
const record = {};
|
|
7177
|
-
for (const [key, entry] of Object.entries(value)) {
|
|
7178
|
-
if (typeof entry === "string")
|
|
7179
|
-
record[key] = entry;
|
|
7180
|
-
}
|
|
7181
|
-
return record;
|
|
7182
|
-
}
|
|
7183
10155
|
function objectRecord(value) {
|
|
7184
10156
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
7185
10157
|
return;
|
|
7186
10158
|
return { ...value };
|
|
7187
10159
|
}
|
|
7188
|
-
function normalizeListModelsResponse(response) {
|
|
7189
|
-
if (!response.success) {
|
|
7190
|
-
throw new Error(response.error ?? "listModels failed");
|
|
7191
|
-
}
|
|
7192
|
-
const entries = Array.isArray(response.entries) ? response.entries.flatMap((entry) => {
|
|
7193
|
-
if (!entry || typeof entry !== "object")
|
|
7194
|
-
return [];
|
|
7195
|
-
const record = entry;
|
|
7196
|
-
if (typeof record.id !== "string" || typeof record.handle !== "string" || typeof record.label !== "string" || typeof record.description !== "string") {
|
|
7197
|
-
return [];
|
|
7198
|
-
}
|
|
7199
|
-
const updateArgs = objectRecord(record.updateArgs);
|
|
7200
|
-
return [
|
|
7201
|
-
{
|
|
7202
|
-
id: record.id,
|
|
7203
|
-
handle: record.handle,
|
|
7204
|
-
label: record.label,
|
|
7205
|
-
description: record.description,
|
|
7206
|
-
...typeof record.isDefault === "boolean" ? { isDefault: record.isDefault } : {},
|
|
7207
|
-
...typeof record.isFeatured === "boolean" ? { isFeatured: record.isFeatured } : {},
|
|
7208
|
-
...typeof record.free === "boolean" ? { free: record.free } : {},
|
|
7209
|
-
...updateArgs ? { updateArgs } : {}
|
|
7210
|
-
}
|
|
7211
|
-
];
|
|
7212
|
-
}) : [];
|
|
7213
|
-
const result = { entries };
|
|
7214
|
-
if (response.available_handles === null) {
|
|
7215
|
-
result.availableHandles = null;
|
|
7216
|
-
} else if (Array.isArray(response.available_handles)) {
|
|
7217
|
-
result.availableHandles = response.available_handles.filter((handle) => typeof handle === "string");
|
|
7218
|
-
}
|
|
7219
|
-
const aliases = stringRecord2(response.byok_provider_aliases);
|
|
7220
|
-
if (aliases)
|
|
7221
|
-
result.byokProviderAliases = aliases;
|
|
7222
|
-
return result;
|
|
7223
|
-
}
|
|
7224
10160
|
function normalizeUpdateModelResponse(response) {
|
|
7225
10161
|
if (!response.success) {
|
|
7226
10162
|
throw new Error(response.error ?? "Failed to update model");
|
|
7227
10163
|
}
|
|
7228
|
-
|
|
7229
|
-
|
|
7230
|
-
|
|
7231
|
-
|
|
7232
|
-
|
|
7233
|
-
|
|
7234
|
-
if (typeof response.model_handle === "string")
|
|
7235
|
-
result.modelHandle = response.model_handle;
|
|
7236
|
-
if (response.model_settings === null) {
|
|
7237
|
-
result.modelSettings = null;
|
|
7238
|
-
} else if (response.model_settings && typeof response.model_settings === "object") {
|
|
7239
|
-
result.modelSettings = { ...response.model_settings };
|
|
7240
|
-
}
|
|
7241
|
-
return result;
|
|
10164
|
+
return {
|
|
10165
|
+
...response.applied_to !== undefined ? { appliedTo: response.applied_to } : {},
|
|
10166
|
+
...response.model_id !== undefined ? { modelId: response.model_id } : {},
|
|
10167
|
+
...response.model_handle !== undefined ? { modelHandle: response.model_handle } : {},
|
|
10168
|
+
...response.model_settings !== undefined ? { modelSettings: response.model_settings } : {}
|
|
10169
|
+
};
|
|
7242
10170
|
}
|
|
7243
10171
|
function runtimeScopeFromMessage(message) {
|
|
7244
10172
|
if (message.runtime)
|
|
@@ -7323,12 +10251,24 @@ class AppServerRuntimeController {
|
|
|
7323
10251
|
await this.client.abort({ runtime });
|
|
7324
10252
|
}
|
|
7325
10253
|
request(type, body, options = {}) {
|
|
7326
|
-
|
|
7327
|
-
|
|
10254
|
+
return this.client.requestRaw({
|
|
10255
|
+
type,
|
|
10256
|
+
request_id: this.client.nextRequestId(type),
|
|
10257
|
+
...body
|
|
10258
|
+
}, {
|
|
10259
|
+
...options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {},
|
|
10260
|
+
predicate: (message) => {
|
|
10261
|
+
if (!message || typeof message !== "object" || Array.isArray(message)) {
|
|
10262
|
+
return false;
|
|
10263
|
+
}
|
|
10264
|
+
const candidate = message;
|
|
10265
|
+
return typeof candidate.type === "string" && (options.predicate?.(candidate) ?? true);
|
|
10266
|
+
}
|
|
10267
|
+
});
|
|
7328
10268
|
}
|
|
7329
10269
|
async listModels() {
|
|
7330
10270
|
const response = await this.request("list_models", {}, { predicate: (message) => message.type === "list_models_response" });
|
|
7331
|
-
return
|
|
10271
|
+
return normalizeAppServerModels(response);
|
|
7332
10272
|
}
|
|
7333
10273
|
async updateModel(runtime, payload) {
|
|
7334
10274
|
const response = await this.request("update_model", {
|
|
@@ -7435,7 +10375,7 @@ class AppServerSession extends RemoteClientSessionCore {
|
|
|
7435
10375
|
controller: new AppServerRuntimeController(client, this.remoteOptions, this.currentOptions().allowedTools),
|
|
7436
10376
|
runtime: response.runtime,
|
|
7437
10377
|
model: typeof response.agent?.model === "string" ? response.agent.model : "",
|
|
7438
|
-
modelSettings: response.agent?.model_settings ?? null,
|
|
10378
|
+
modelSettings: objectRecord(response.agent?.model_settings) ?? null,
|
|
7439
10379
|
...tools !== undefined ? { tools } : {},
|
|
7440
10380
|
...skillSources !== undefined ? { skillSources: [...skillSources] } : {}
|
|
7441
10381
|
};
|
|
@@ -7470,8 +10410,7 @@ class AppServerSession extends RemoteClientSessionCore {
|
|
|
7470
10410
|
}
|
|
7471
10411
|
async startRuntime(client) {
|
|
7472
10412
|
const command = await this.buildRuntimeStartCommand(client);
|
|
7473
|
-
|
|
7474
|
-
return response;
|
|
10413
|
+
return client.runtimeStart(command);
|
|
7475
10414
|
}
|
|
7476
10415
|
async buildRuntimeStartCommand(client) {
|
|
7477
10416
|
const options = this.mode.options;
|
|
@@ -7522,8 +10461,13 @@ class AppServerSession extends RemoteClientSessionCore {
|
|
|
7522
10461
|
throw new Error("App-server createSession() requires an agent id. Call createAgent() first or pass an agent id.");
|
|
7523
10462
|
}
|
|
7524
10463
|
async resolveConversationAgentId(client, conversationId) {
|
|
7525
|
-
const
|
|
7526
|
-
|
|
10464
|
+
const response = await client.request({
|
|
10465
|
+
type: "conversation_retrieve",
|
|
10466
|
+
request_id: client.nextRequestId("conversation_retrieve"),
|
|
10467
|
+
conversation_id: conversationId
|
|
10468
|
+
}, {
|
|
10469
|
+
predicate: (message) => message.type === "conversation_retrieve_response"
|
|
10470
|
+
});
|
|
7527
10471
|
if (!response.success || !response.conversation?.agent_id) {
|
|
7528
10472
|
throw new Error(response.error ?? `Failed to retrieve conversation ${conversationId}`);
|
|
7529
10473
|
}
|
|
@@ -7532,87 +10476,21 @@ class AppServerSession extends RemoteClientSessionCore {
|
|
|
7532
10476
|
}
|
|
7533
10477
|
|
|
7534
10478
|
// src/cloud-management.ts
|
|
7535
|
-
|
|
7536
|
-
function defaultApiKey() {
|
|
7537
|
-
const env = globalThis.process?.env;
|
|
7538
|
-
return env?.LETTA_API_KEY ?? env?.LETTA_CLOUD_API_KEY;
|
|
7539
|
-
}
|
|
7540
|
-
function bearerToken(headers) {
|
|
7541
|
-
const authorization = headers?.Authorization ?? headers?.authorization;
|
|
7542
|
-
return authorization?.match(/^Bearer\s+(.+)$/i)?.[1];
|
|
7543
|
-
}
|
|
7544
|
-
function apiBaseUrl(value) {
|
|
7545
|
-
const url = new URL(value ?? DEFAULT_CLOUD_API_BASE_URL2);
|
|
7546
|
-
url.pathname = url.pathname.replace(/\/+$/, "");
|
|
7547
|
-
url.search = "";
|
|
7548
|
-
url.hash = "";
|
|
7549
|
-
return url.toString().replace(/\/$/, "");
|
|
7550
|
-
}
|
|
7551
|
-
function requestHeaders(options) {
|
|
7552
|
-
const headers = {
|
|
7553
|
-
"Content-Type": "application/json",
|
|
7554
|
-
...options.headers ?? {}
|
|
7555
|
-
};
|
|
7556
|
-
const apiKey = options.apiKey ?? bearerToken(options.headers) ?? defaultApiKey();
|
|
7557
|
-
if (apiKey && !headers.Authorization && !headers.authorization) {
|
|
7558
|
-
headers.Authorization = `Bearer ${apiKey}`;
|
|
7559
|
-
}
|
|
7560
|
-
return headers;
|
|
7561
|
-
}
|
|
7562
|
-
function appendQuery(url, query) {
|
|
7563
|
-
for (const [key, value] of Object.entries(query)) {
|
|
7564
|
-
if (value === undefined || value === null)
|
|
7565
|
-
continue;
|
|
7566
|
-
if (Array.isArray(value)) {
|
|
7567
|
-
for (const item of value)
|
|
7568
|
-
url.searchParams.append(key, item);
|
|
7569
|
-
} else {
|
|
7570
|
-
url.searchParams.set(key, String(value));
|
|
7571
|
-
}
|
|
7572
|
-
}
|
|
7573
|
-
}
|
|
7574
|
-
async function parseResponse(response) {
|
|
7575
|
-
const text = await response.text();
|
|
7576
|
-
if (!text)
|
|
7577
|
-
return null;
|
|
7578
|
-
try {
|
|
7579
|
-
return JSON.parse(text);
|
|
7580
|
-
} catch {
|
|
7581
|
-
return text;
|
|
7582
|
-
}
|
|
7583
|
-
}
|
|
7584
|
-
function responseErrorMessage2(body, fallback) {
|
|
7585
|
-
if (body && typeof body === "object") {
|
|
7586
|
-
const record = body;
|
|
7587
|
-
const message = record.message ?? record.error ?? record.detail;
|
|
7588
|
-
if (typeof message === "string" && message.length > 0)
|
|
7589
|
-
return message;
|
|
7590
|
-
}
|
|
7591
|
-
return fallback;
|
|
7592
|
-
}
|
|
7593
|
-
function cloudRequestError(response, body, action, url, options) {
|
|
7594
|
-
const parts = [
|
|
7595
|
-
`${action} failed`,
|
|
7596
|
-
responseErrorMessage2(body, `HTTP ${response.status}`),
|
|
7597
|
-
`URL: ${url.toString()}`
|
|
7598
|
-
];
|
|
7599
|
-
if (response.status === 401 || response.status === 403) {
|
|
7600
|
-
const hasApiKey = Boolean(options.apiKey ?? bearerToken(options.headers) ?? defaultApiKey());
|
|
7601
|
-
parts.push(hasApiKey ? "Authentication failed — the API key may be invalid or lack permissions for this resource." : "No API key found. Set LETTA_API_KEY (or pass apiKey in client options).");
|
|
7602
|
-
}
|
|
7603
|
-
return new Error(parts.join(" — "));
|
|
7604
|
-
}
|
|
7605
|
-
function asObject(body, action) {
|
|
10479
|
+
function asAgentRepository(body, action) {
|
|
7606
10480
|
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
7607
|
-
throw new Error(`${action} response did not include
|
|
10481
|
+
throw new Error(`${action} response did not include a repository.`);
|
|
7608
10482
|
}
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
throw new Error(`${action} response did not include an array.`);
|
|
10483
|
+
const repository = body;
|
|
10484
|
+
const permissions = repository.permissions;
|
|
10485
|
+
if (typeof repository.id !== "string" || typeof repository.name !== "string" || typeof repository.is_primary !== "boolean" || permissions !== "read" && permissions !== "read_write") {
|
|
10486
|
+
throw new Error(`${action} response included an invalid repository.`);
|
|
7614
10487
|
}
|
|
7615
|
-
return
|
|
10488
|
+
return {
|
|
10489
|
+
id: repository.id,
|
|
10490
|
+
name: repository.name,
|
|
10491
|
+
isPrimary: repository.is_primary,
|
|
10492
|
+
permissions
|
|
10493
|
+
};
|
|
7616
10494
|
}
|
|
7617
10495
|
function cloudModelEntry(raw) {
|
|
7618
10496
|
if (typeof raw.handle !== "string" || raw.handle.length === 0) {
|
|
@@ -7627,26 +10505,62 @@ function cloudModelEntry(raw) {
|
|
|
7627
10505
|
description: typeof raw.description === "string" ? raw.description : ""
|
|
7628
10506
|
};
|
|
7629
10507
|
}
|
|
10508
|
+
function isNotFound(error) {
|
|
10509
|
+
return error instanceof APIError && error.status === 404;
|
|
10510
|
+
}
|
|
7630
10511
|
|
|
7631
10512
|
class CloudManagementTransport {
|
|
7632
|
-
|
|
7633
|
-
constructor(
|
|
7634
|
-
this.
|
|
10513
|
+
client;
|
|
10514
|
+
constructor(client) {
|
|
10515
|
+
this.client = client;
|
|
7635
10516
|
}
|
|
7636
|
-
listAgents(query) {
|
|
7637
|
-
|
|
10517
|
+
async listAgents(query) {
|
|
10518
|
+
const page = await this.client.agents.list(query);
|
|
10519
|
+
return page.items;
|
|
7638
10520
|
}
|
|
7639
|
-
retrieveAgent(agentId) {
|
|
7640
|
-
return this.
|
|
10521
|
+
async retrieveAgent(agentId) {
|
|
10522
|
+
return this.client.agents.retrieve(agentId);
|
|
7641
10523
|
}
|
|
7642
|
-
updateAgent(agentId, body) {
|
|
7643
|
-
return this.
|
|
10524
|
+
async updateAgent(agentId, body) {
|
|
10525
|
+
return this.client.agents.update(agentId, body);
|
|
7644
10526
|
}
|
|
7645
10527
|
async deleteAgent(agentId) {
|
|
7646
|
-
await this.
|
|
10528
|
+
await this.client.agents.delete(agentId);
|
|
10529
|
+
}
|
|
10530
|
+
async listAgentRepositories(agentId) {
|
|
10531
|
+
const body = await this.client.get(`/v1/agents/${encodeURIComponent(agentId)}/repositories`);
|
|
10532
|
+
if (!Array.isArray(body.repositories)) {
|
|
10533
|
+
throw new Error("Cloud list agent repositories response did not include repositories.");
|
|
10534
|
+
}
|
|
10535
|
+
return body.repositories.map((repository) => asAgentRepository(repository, "Cloud list agent repositories"));
|
|
10536
|
+
}
|
|
10537
|
+
async attachAgentRepository(agentId, repositoryId, permissions) {
|
|
10538
|
+
const body = await this.client.post(`/v1/agents/${encodeURIComponent(agentId)}/repositories`, {
|
|
10539
|
+
body: {
|
|
10540
|
+
repository_id: repositoryId,
|
|
10541
|
+
...permissions !== undefined ? { permissions } : {}
|
|
10542
|
+
}
|
|
10543
|
+
});
|
|
10544
|
+
return asAgentRepository(body.repository, "Cloud attach agent repository");
|
|
10545
|
+
}
|
|
10546
|
+
async detachAgentRepository(agentId, repositoryId) {
|
|
10547
|
+
try {
|
|
10548
|
+
await this.client.delete(`/v1/agents/${encodeURIComponent(agentId)}/repositories/${encodeURIComponent(repositoryId)}`);
|
|
10549
|
+
} catch (error) {
|
|
10550
|
+
if (!isNotFound(error))
|
|
10551
|
+
throw error;
|
|
10552
|
+
}
|
|
10553
|
+
}
|
|
10554
|
+
async recompileAgentSystemPrompt(agentId) {
|
|
10555
|
+
await this.client.agents.recompile(agentId);
|
|
10556
|
+
}
|
|
10557
|
+
async recompileConversationSystemPrompt(agentId, conversationId) {
|
|
10558
|
+
await this.client.conversations.recompile(conversationId, {
|
|
10559
|
+
agent_id: agentId
|
|
10560
|
+
});
|
|
7647
10561
|
}
|
|
7648
10562
|
async listModels() {
|
|
7649
|
-
const entries = await this.
|
|
10563
|
+
const entries = await this.client.models.list();
|
|
7650
10564
|
const normalized = entries.flatMap((entry) => {
|
|
7651
10565
|
const model = cloudModelEntry(entry);
|
|
7652
10566
|
return model ? [model] : [];
|
|
@@ -7656,65 +10570,21 @@ class CloudManagementTransport {
|
|
|
7656
10570
|
availableHandles: normalized.map((entry) => entry.handle)
|
|
7657
10571
|
};
|
|
7658
10572
|
}
|
|
7659
|
-
listConversations(query) {
|
|
7660
|
-
return this.
|
|
10573
|
+
async listConversations(query) {
|
|
10574
|
+
return this.client.conversations.list(query);
|
|
7661
10575
|
}
|
|
7662
|
-
retrieveConversation(conversationId) {
|
|
7663
|
-
return this.
|
|
10576
|
+
async retrieveConversation(conversationId) {
|
|
10577
|
+
return this.client.conversations.retrieve(conversationId);
|
|
7664
10578
|
}
|
|
7665
|
-
createConversation(body) {
|
|
7666
|
-
|
|
7667
|
-
if (typeof agentId !== "string" || agentId.length === 0) {
|
|
7668
|
-
throw new Error("createConversation() requires a non-empty agentId.");
|
|
7669
|
-
}
|
|
7670
|
-
const url = this.url("/v1/conversations/");
|
|
7671
|
-
url.searchParams.set("agent_id", agentId);
|
|
7672
|
-
return this.requestUrlObject(url, "POST", requestBody, "Cloud create conversation");
|
|
10579
|
+
async createConversation(body) {
|
|
10580
|
+
return this.client.conversations.create(body);
|
|
7673
10581
|
}
|
|
7674
|
-
updateConversation(conversationId, body) {
|
|
7675
|
-
return this.
|
|
10582
|
+
async updateConversation(conversationId, body) {
|
|
10583
|
+
return this.client.conversations.update(conversationId, body);
|
|
7676
10584
|
}
|
|
7677
10585
|
async listConversationMessages(conversationId, query) {
|
|
7678
|
-
const
|
|
7679
|
-
return { messages };
|
|
7680
|
-
}
|
|
7681
|
-
async getArray(path, query, action) {
|
|
7682
|
-
const body = await this.get(path, query, action);
|
|
7683
|
-
return asArray(body, action);
|
|
7684
|
-
}
|
|
7685
|
-
async getObject(path, query, action) {
|
|
7686
|
-
const body = await this.get(path, query, action);
|
|
7687
|
-
return asObject(body, action);
|
|
7688
|
-
}
|
|
7689
|
-
get(path, query, action) {
|
|
7690
|
-
const url = this.url(path);
|
|
7691
|
-
appendQuery(url, query);
|
|
7692
|
-
return this.requestUrl(url, "GET", undefined, action);
|
|
7693
|
-
}
|
|
7694
|
-
requestObject(path, method, body, action) {
|
|
7695
|
-
return this.requestUrlObject(this.url(path), method, body, action);
|
|
7696
|
-
}
|
|
7697
|
-
async requestUrlObject(url, method, body, action) {
|
|
7698
|
-
return asObject(await this.requestUrl(url, method, body, action), action);
|
|
7699
|
-
}
|
|
7700
|
-
async requestUrl(url, method, body, action) {
|
|
7701
|
-
const fetchImpl = (this.options.fetch ?? globalThis.fetch)?.bind(globalThis);
|
|
7702
|
-
if (!fetchImpl) {
|
|
7703
|
-
throw new Error("No fetch implementation available for cloud backend.");
|
|
7704
|
-
}
|
|
7705
|
-
const response = await fetchImpl(url, {
|
|
7706
|
-
method,
|
|
7707
|
-
headers: requestHeaders(this.options),
|
|
7708
|
-
...body !== undefined ? { body: JSON.stringify(body) } : {}
|
|
7709
|
-
});
|
|
7710
|
-
const responseBody = await parseResponse(response);
|
|
7711
|
-
if (!response.ok) {
|
|
7712
|
-
throw cloudRequestError(response, responseBody, action, url, this.options);
|
|
7713
|
-
}
|
|
7714
|
-
return responseBody;
|
|
7715
|
-
}
|
|
7716
|
-
url(path) {
|
|
7717
|
-
return new URL(`${apiBaseUrl(this.options.apiBaseUrl)}${path}`);
|
|
10586
|
+
const page = await this.client.conversations.messages.list(conversationId, query);
|
|
10587
|
+
return { messages: page.items };
|
|
7718
10588
|
}
|
|
7719
10589
|
}
|
|
7720
10590
|
|
|
@@ -7935,29 +10805,6 @@ function createCloudStatusTransportConstructor(options) {
|
|
|
7935
10805
|
}
|
|
7936
10806
|
|
|
7937
10807
|
// src/remote.ts
|
|
7938
|
-
function getDefaultApiKey2() {
|
|
7939
|
-
if (typeof process === "undefined") {
|
|
7940
|
-
return;
|
|
7941
|
-
}
|
|
7942
|
-
return process.env.LETTA_API_KEY;
|
|
7943
|
-
}
|
|
7944
|
-
function createHeaders(options) {
|
|
7945
|
-
const apiKey = options.apiKey ?? getDefaultApiKey2();
|
|
7946
|
-
return {
|
|
7947
|
-
...apiKey ? { Authorization: `Bearer ${apiKey}` } : {},
|
|
7948
|
-
...options.headers ?? {}
|
|
7949
|
-
};
|
|
7950
|
-
}
|
|
7951
|
-
function getFetch2(options) {
|
|
7952
|
-
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
7953
|
-
if (!fetchImpl) {
|
|
7954
|
-
throw new Error("Remote environments require a fetch implementation");
|
|
7955
|
-
}
|
|
7956
|
-
return fetchImpl.bind(globalThis);
|
|
7957
|
-
}
|
|
7958
|
-
function normalizeBaseUrl2(baseUrl) {
|
|
7959
|
-
return (baseUrl ?? "https://api.letta.com").replace(/\/$/, "");
|
|
7960
|
-
}
|
|
7961
10808
|
function ensureOnline(environment, target) {
|
|
7962
10809
|
if (!environment.connectionId) {
|
|
7963
10810
|
const label = "deviceId" in target ? target.deviceId : ("environmentId" in target) ? target.environmentId : ("connectionName" in target) ? target.connectionName : environment.deviceId;
|
|
@@ -7969,35 +10816,23 @@ function ensureOnline(environment, target) {
|
|
|
7969
10816
|
target
|
|
7970
10817
|
};
|
|
7971
10818
|
}
|
|
7972
|
-
async function parseJsonResponse2(response) {
|
|
7973
|
-
const text = await response.text();
|
|
7974
|
-
const body = text ? JSON.parse(text) : null;
|
|
7975
|
-
if (!response.ok) {
|
|
7976
|
-
const message = body && typeof body === "object" && "message" in body ? String(body.message) : response.statusText;
|
|
7977
|
-
throw new Error(`Letta API request failed (${response.status}): ${message}`);
|
|
7978
|
-
}
|
|
7979
|
-
return body;
|
|
7980
|
-
}
|
|
7981
10819
|
|
|
7982
10820
|
class RemoteEnvironmentClient {
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
|
|
7986
|
-
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
|
|
10821
|
+
client;
|
|
10822
|
+
constructor(options = {}, client = createCloudClient({
|
|
10823
|
+
backend: "cloud",
|
|
10824
|
+
apiBaseUrl: options.baseUrl,
|
|
10825
|
+
apiKey: options.apiKey,
|
|
10826
|
+
headers: options.headers,
|
|
10827
|
+
fetch: options.fetch
|
|
10828
|
+
})) {
|
|
10829
|
+
this.client = client;
|
|
7990
10830
|
}
|
|
7991
10831
|
async listEnvironments() {
|
|
7992
|
-
|
|
7993
|
-
const response = await this.fetchImpl(url, {
|
|
7994
|
-
headers: createHeaders(this.options)
|
|
7995
|
-
});
|
|
7996
|
-
return parseJsonResponse2(response);
|
|
10832
|
+
return await this.client.environments.list();
|
|
7997
10833
|
}
|
|
7998
10834
|
async getEnvironmentByDeviceId(deviceId) {
|
|
7999
|
-
|
|
8000
|
-
return parseJsonResponse2(response);
|
|
10835
|
+
return await this.client.environments.retrieve(deviceId);
|
|
8001
10836
|
}
|
|
8002
10837
|
async resolveEnvironment(target) {
|
|
8003
10838
|
if ("connectionId" in target) {
|
|
@@ -8035,7 +10870,7 @@ var MAX_TTL_MINUTES = 60;
|
|
|
8035
10870
|
var MAX_GITHUB_REPOSITORIES = 10;
|
|
8036
10871
|
var GITHUB_OWNER_PATTERN = /^[A-Za-z0-9-]+$/;
|
|
8037
10872
|
var GITHUB_REPOSITORY_PATTERN = /^[A-Za-z0-9._-]+$/;
|
|
8038
|
-
function
|
|
10873
|
+
function validatePositiveInteger2(value, name) {
|
|
8039
10874
|
if (value !== undefined && (!Number.isInteger(value) || value <= 0)) {
|
|
8040
10875
|
throw new Error(`Invalid ${name}. Expected a positive integer.`);
|
|
8041
10876
|
}
|
|
@@ -8049,9 +10884,9 @@ function validateCloudSandboxOptions(options, name) {
|
|
|
8049
10884
|
if (options.ttlMinutes !== undefined && (!Number.isInteger(options.ttlMinutes) || options.ttlMinutes < MIN_TTL_MINUTES || options.ttlMinutes > MAX_TTL_MINUTES)) {
|
|
8050
10885
|
throw new Error(`Invalid ${name}.ttlMinutes. Expected an integer between ${MIN_TTL_MINUTES} and ${MAX_TTL_MINUTES}.`);
|
|
8051
10886
|
}
|
|
8052
|
-
|
|
8053
|
-
|
|
8054
|
-
|
|
10887
|
+
validatePositiveInteger2(options.readyTimeoutMs, `${name}.readyTimeoutMs`);
|
|
10888
|
+
validatePositiveInteger2(options.readyPollIntervalMs, `${name}.readyPollIntervalMs`);
|
|
10889
|
+
validatePositiveInteger2(options.refreshIntervalMs, `${name}.refreshIntervalMs`);
|
|
8055
10890
|
if (options.githubRepositories !== undefined) {
|
|
8056
10891
|
if (!Array.isArray(options.githubRepositories)) {
|
|
8057
10892
|
throw new Error(`Invalid ${name}.githubRepositories. Expected an array.`);
|
|
@@ -8077,7 +10912,6 @@ function validateCloudSandboxOptions(options, name) {
|
|
|
8077
10912
|
}
|
|
8078
10913
|
|
|
8079
10914
|
// src/cloud-session.ts
|
|
8080
|
-
var DEFAULT_CLOUD_API_BASE_URL3 = "https://api.letta.com";
|
|
8081
10915
|
var DEFAULT_TURN_TIMEOUT_MS = 120000;
|
|
8082
10916
|
var DEFAULT_PING_INTERVAL_MS = 30000;
|
|
8083
10917
|
var DEFAULT_SANDBOX_TTL_MINUTES = 5;
|
|
@@ -8101,27 +10935,6 @@ class CloudManagedSandboxExpiredError extends Error {
|
|
|
8101
10935
|
this.name = "CloudManagedSandboxExpiredError";
|
|
8102
10936
|
}
|
|
8103
10937
|
}
|
|
8104
|
-
function getDefaultApiKey3() {
|
|
8105
|
-
const env = globalThis.process?.env;
|
|
8106
|
-
return env?.LETTA_API_KEY ?? env?.LETTA_CLOUD_API_KEY;
|
|
8107
|
-
}
|
|
8108
|
-
function bearerTokenFromHeaders2(headers) {
|
|
8109
|
-
const authorization = headers?.Authorization ?? headers?.authorization;
|
|
8110
|
-
if (!authorization)
|
|
8111
|
-
return;
|
|
8112
|
-
const match = /^Bearer\s+(.+)$/i.exec(authorization);
|
|
8113
|
-
return match?.[1];
|
|
8114
|
-
}
|
|
8115
|
-
function getCloudApiKey2(options) {
|
|
8116
|
-
return options.apiKey ?? bearerTokenFromHeaders2(options.headers) ?? getDefaultApiKey3();
|
|
8117
|
-
}
|
|
8118
|
-
function getFetch3(fetchOverride) {
|
|
8119
|
-
const resolved = fetchOverride ?? globalThis.fetch;
|
|
8120
|
-
if (!resolved) {
|
|
8121
|
-
throw new Error("No fetch implementation available for cloud backend.");
|
|
8122
|
-
}
|
|
8123
|
-
return resolved.bind(globalThis);
|
|
8124
|
-
}
|
|
8125
10938
|
function getWebSocketConstructor(websocketOverride) {
|
|
8126
10939
|
const resolved = websocketOverride ?? globalThis.WebSocket;
|
|
8127
10940
|
if (!resolved) {
|
|
@@ -8129,75 +10942,25 @@ function getWebSocketConstructor(websocketOverride) {
|
|
|
8129
10942
|
}
|
|
8130
10943
|
return resolved;
|
|
8131
10944
|
}
|
|
8132
|
-
function normalizeCloudApiBaseUrl2(url) {
|
|
8133
|
-
const parsed = new URL(url ?? DEFAULT_CLOUD_API_BASE_URL3);
|
|
8134
|
-
parsed.pathname = parsed.pathname.replace(/\/+$/, "");
|
|
8135
|
-
parsed.search = "";
|
|
8136
|
-
parsed.hash = "";
|
|
8137
|
-
return parsed.toString().replace(/\/$/, "");
|
|
8138
|
-
}
|
|
8139
|
-
function cloudHeaders2(options) {
|
|
8140
|
-
const headers = {
|
|
8141
|
-
"Content-Type": "application/json",
|
|
8142
|
-
...options.headers ?? {}
|
|
8143
|
-
};
|
|
8144
|
-
const apiKey = getCloudApiKey2(options);
|
|
8145
|
-
if (apiKey && !headers.Authorization && !headers.authorization) {
|
|
8146
|
-
headers.Authorization = `Bearer ${apiKey}`;
|
|
8147
|
-
}
|
|
8148
|
-
return headers;
|
|
8149
|
-
}
|
|
8150
10945
|
function cloudWebSocketHeaders(options) {
|
|
8151
10946
|
const headers = { ...options.headers ?? {} };
|
|
8152
10947
|
delete headers.authorization;
|
|
8153
10948
|
delete headers.Authorization;
|
|
8154
|
-
const apiKey =
|
|
10949
|
+
const apiKey = getCloudApiKey(options);
|
|
8155
10950
|
if (apiKey)
|
|
8156
10951
|
headers.Authorization = `Bearer ${apiKey}`;
|
|
8157
10952
|
return Object.keys(headers).length > 0 ? headers : undefined;
|
|
8158
10953
|
}
|
|
8159
|
-
|
|
8160
|
-
|
|
8161
|
-
if (!text)
|
|
8162
|
-
return null;
|
|
8163
|
-
try {
|
|
8164
|
-
return JSON.parse(text);
|
|
8165
|
-
} catch {
|
|
8166
|
-
return text;
|
|
8167
|
-
}
|
|
8168
|
-
}
|
|
8169
|
-
function responseErrorMessage3(body, fallback) {
|
|
8170
|
-
if (body && typeof body === "object") {
|
|
8171
|
-
const record = body;
|
|
8172
|
-
const message = record.message ?? record.error ?? record.detail;
|
|
8173
|
-
const reasonText = record.reason_text;
|
|
8174
|
-
const pieces = [message, reasonText].filter((value) => typeof value === "string" && value.length > 0);
|
|
8175
|
-
if (pieces.length > 0)
|
|
8176
|
-
return pieces.join(": ");
|
|
8177
|
-
}
|
|
8178
|
-
return fallback;
|
|
8179
|
-
}
|
|
8180
|
-
function assertOkResponse2(response, body, action, url) {
|
|
8181
|
-
if (!response.ok) {
|
|
8182
|
-
const detail = responseErrorMessage3(body, `HTTP ${response.status}`);
|
|
8183
|
-
const parts = [`${action} failed`, detail];
|
|
8184
|
-
if (url)
|
|
8185
|
-
parts.push(`URL: ${url}`);
|
|
8186
|
-
if (response.status === 401 || response.status === 403) {
|
|
8187
|
-
const env = globalThis.process?.env;
|
|
8188
|
-
const hasKey = !!(env?.LETTA_API_KEY ?? env?.LETTA_CLOUD_API_KEY);
|
|
8189
|
-
parts.push(hasKey ? "Authentication failed — the API key may be invalid or lack permissions for this resource." : "No API key found. Set LETTA_API_KEY (or pass apiKey in client options).");
|
|
8190
|
-
}
|
|
8191
|
-
throw new Error(parts.join(" — "));
|
|
8192
|
-
}
|
|
10954
|
+
function isNotFound2(error) {
|
|
10955
|
+
return error instanceof APIError && error.status === 404;
|
|
8193
10956
|
}
|
|
8194
|
-
function
|
|
10957
|
+
function validatePositiveInteger3(value, name) {
|
|
8195
10958
|
if (value !== undefined && (!Number.isInteger(value) || value <= 0)) {
|
|
8196
10959
|
throw new Error(`Invalid ${name}. Expected a positive integer.`);
|
|
8197
10960
|
}
|
|
8198
10961
|
}
|
|
8199
10962
|
function validateCloudClientOptions(options) {
|
|
8200
|
-
|
|
10963
|
+
validatePositiveInteger3(options.requestTimeoutMs, "requestTimeoutMs");
|
|
8201
10964
|
validateCloudSandboxOptions(options.sandbox, "sandbox");
|
|
8202
10965
|
if (options.environment !== undefined && options.sandbox !== undefined) {
|
|
8203
10966
|
throw new Error("Letta Cloud sessions cannot specify both environment and sandbox options.");
|
|
@@ -8225,7 +10988,7 @@ function environmentToRemoteTarget(environment) {
|
|
|
8225
10988
|
throw new Error("Unknown cloud environment selector.");
|
|
8226
10989
|
}
|
|
8227
10990
|
function buildCloudStatusWebSocketUrl(params) {
|
|
8228
|
-
const base = new URL(
|
|
10991
|
+
const base = new URL(normalizeCloudApiBaseUrl(params.apiBaseUrl));
|
|
8229
10992
|
if (base.protocol === "http:") {
|
|
8230
10993
|
base.protocol = "ws:";
|
|
8231
10994
|
} else if (base.protocol === "https:") {
|
|
@@ -8255,7 +11018,7 @@ function isRetryableManagedSandboxResolveError(error) {
|
|
|
8255
11018
|
const message = error instanceof Error ? error.message : String(error);
|
|
8256
11019
|
return message.includes("Remote environment is offline") || message.toLowerCase().includes("not found") || message.includes("(404)");
|
|
8257
11020
|
}
|
|
8258
|
-
function
|
|
11021
|
+
function sleep3(ms) {
|
|
8259
11022
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
8260
11023
|
}
|
|
8261
11024
|
function externalToolsByName(tools) {
|
|
@@ -8265,20 +11028,13 @@ function externalToolsByName(tools) {
|
|
|
8265
11028
|
}
|
|
8266
11029
|
return result;
|
|
8267
11030
|
}
|
|
8268
|
-
async function createCloudAgent(
|
|
11031
|
+
async function createCloudAgent(client, agentOptions) {
|
|
8269
11032
|
const body = await createAgentBody(agentOptions);
|
|
8270
|
-
const
|
|
8271
|
-
|
|
8272
|
-
headers: cloudHeaders2(clientOptions),
|
|
8273
|
-
body: JSON.stringify(body)
|
|
8274
|
-
});
|
|
8275
|
-
const responseBody = await parseJsonResponse3(response);
|
|
8276
|
-
assertOkResponse2(response, responseBody, "Cloud create agent");
|
|
8277
|
-
const agentId = responseBody && typeof responseBody === "object" ? responseBody.id : undefined;
|
|
8278
|
-
if (typeof agentId !== "string" || agentId.length === 0) {
|
|
11033
|
+
const agent = await client.agents.create(body);
|
|
11034
|
+
if (typeof agent.id !== "string" || agent.id.length === 0) {
|
|
8279
11035
|
throw new Error("Cloud create agent response did not include an agent id.");
|
|
8280
11036
|
}
|
|
8281
|
-
return
|
|
11037
|
+
return agent.id;
|
|
8282
11038
|
}
|
|
8283
11039
|
function assertCloudSessionOptionsSupported(action, options) {
|
|
8284
11040
|
validateCloudSandboxOptions(options.sandbox, "sandbox");
|
|
@@ -8289,6 +11045,7 @@ function assertCloudSessionOptionsSupported(action, options) {
|
|
|
8289
11045
|
|
|
8290
11046
|
class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
8291
11047
|
cloudOptions;
|
|
11048
|
+
apiClient;
|
|
8292
11049
|
connectionId = null;
|
|
8293
11050
|
removeExternalToolHandler = null;
|
|
8294
11051
|
removeControlRequestHandler = null;
|
|
@@ -8298,22 +11055,29 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8298
11055
|
sandboxRefreshInFlight = null;
|
|
8299
11056
|
sandboxLifecycleClosing = false;
|
|
8300
11057
|
attachedRepositoryIds = new Set;
|
|
11058
|
+
repositoryIdsRequiringCleanupRecompile = new Set;
|
|
11059
|
+
repositoryManagement;
|
|
8301
11060
|
cloudMode;
|
|
8302
|
-
constructor(cloudOptions, mode) {
|
|
11061
|
+
constructor(cloudOptions, mode, apiClient = createCloudClient(cloudOptions)) {
|
|
8303
11062
|
super(mode, {
|
|
8304
11063
|
label: "cloud",
|
|
8305
11064
|
requestTimeoutMs: cloudOptions.requestTimeoutMs ?? DEFAULT_TURN_TIMEOUT_MS
|
|
8306
11065
|
});
|
|
8307
11066
|
this.cloudOptions = cloudOptions;
|
|
11067
|
+
this.apiClient = apiClient;
|
|
8308
11068
|
this.cloudMode = mode;
|
|
11069
|
+
this.repositoryManagement = new CloudManagementTransport(apiClient);
|
|
8309
11070
|
const tools = mode.options.tools;
|
|
8310
11071
|
this.externalTools = externalToolsByName(tools);
|
|
8311
11072
|
}
|
|
8312
11073
|
async initializeRuntimeController() {
|
|
8313
11074
|
const resolved = await this.resolveRuntime();
|
|
8314
|
-
const connection = await this.resolveConnectionForRuntime(resolved.runtime)
|
|
11075
|
+
const connection = await this.resolveConnectionForRuntime(resolved.runtime).catch(async (error) => {
|
|
11076
|
+
await this.cleanupSessionRepositories(resolved.runtime.agent_id, resolved.runtime.conversation_id);
|
|
11077
|
+
throw error;
|
|
11078
|
+
});
|
|
8315
11079
|
this.connectionId = connection.connectionId;
|
|
8316
|
-
const apiKey =
|
|
11080
|
+
const apiKey = getCloudApiKey(this.cloudOptions);
|
|
8317
11081
|
const url = buildCloudStatusWebSocketUrl({
|
|
8318
11082
|
apiBaseUrl: this.cloudOptions.apiBaseUrl,
|
|
8319
11083
|
connectionId: connection.connectionId,
|
|
@@ -8366,7 +11130,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8366
11130
|
this.removeControlRequestHandler = null;
|
|
8367
11131
|
client.close();
|
|
8368
11132
|
await this.cleanupManagedSandbox();
|
|
8369
|
-
await this.cleanupSessionRepositories(resolved.runtime.agent_id);
|
|
11133
|
+
await this.cleanupSessionRepositories(resolved.runtime.agent_id, resolved.runtime.conversation_id);
|
|
8370
11134
|
throw error;
|
|
8371
11135
|
}
|
|
8372
11136
|
}
|
|
@@ -8417,8 +11181,9 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8417
11181
|
this.removeControlRequestHandler?.();
|
|
8418
11182
|
this.removeControlRequestHandler = null;
|
|
8419
11183
|
this.cleanupManagedSandbox();
|
|
8420
|
-
if (this.runtime?.agent_id)
|
|
8421
|
-
this.cleanupSessionRepositories(this.runtime.agent_id);
|
|
11184
|
+
if (this.runtime?.agent_id) {
|
|
11185
|
+
this.cleanupSessionRepositories(this.runtime.agent_id, this.runtime.conversation_id);
|
|
11186
|
+
}
|
|
8422
11187
|
}
|
|
8423
11188
|
async resolveRuntime() {
|
|
8424
11189
|
let agentId = this.cloudMode.agentId;
|
|
@@ -8433,30 +11198,38 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8433
11198
|
if (!agentId) {
|
|
8434
11199
|
throw new Error("Letta Cloud createSession()/resumeSession() requires an agent id or conversation id.");
|
|
8435
11200
|
}
|
|
8436
|
-
await this.attachSessionRepositories(agentId);
|
|
8437
|
-
|
|
8438
|
-
|
|
8439
|
-
|
|
8440
|
-
|
|
8441
|
-
|
|
8442
|
-
|
|
8443
|
-
|
|
8444
|
-
|
|
11201
|
+
const shouldRecompileRepositories = await this.attachSessionRepositories(agentId);
|
|
11202
|
+
try {
|
|
11203
|
+
if (this.cloudMode.newConversation) {
|
|
11204
|
+
const conversation = await this.createConversation(agentId);
|
|
11205
|
+
conversationId = conversation.id;
|
|
11206
|
+
} else if (this.cloudMode.defaultConversation) {
|
|
11207
|
+
conversationId = "default";
|
|
11208
|
+
}
|
|
11209
|
+
if (!conversationId) {
|
|
11210
|
+
throw new Error("Letta Cloud createSession()/resumeSession() requires an agent id or conversation id.");
|
|
11211
|
+
}
|
|
11212
|
+
if (shouldRecompileRepositories) {
|
|
11213
|
+
await this.recompileSystemPrompt(agentId, conversationId);
|
|
11214
|
+
}
|
|
11215
|
+
return { runtime: { agent_id: agentId, conversation_id: conversationId } };
|
|
11216
|
+
} catch (error) {
|
|
11217
|
+
await this.cleanupSessionRepositories(agentId, conversationId);
|
|
11218
|
+
throw error;
|
|
8445
11219
|
}
|
|
8446
|
-
return { runtime: { agent_id: agentId, conversation_id: conversationId } };
|
|
8447
11220
|
}
|
|
8448
11221
|
async attachSessionRepositories(agentId) {
|
|
8449
11222
|
const resources = this.repositoryResources();
|
|
8450
11223
|
if (resources.length === 0)
|
|
8451
|
-
return;
|
|
8452
|
-
const existing = await this.listAgentRepositories(agentId);
|
|
11224
|
+
return false;
|
|
11225
|
+
const existing = await this.repositoryManagement.listAgentRepositories(agentId);
|
|
8453
11226
|
const existingIds = new Set(existing.map((repository) => repository.id));
|
|
8454
11227
|
try {
|
|
8455
11228
|
for (const resource of resources) {
|
|
8456
11229
|
if (existingIds.has(resource.repositoryId) || this.attachedRepositoryIds.has(resource.repositoryId)) {
|
|
8457
11230
|
continue;
|
|
8458
11231
|
}
|
|
8459
|
-
await this.
|
|
11232
|
+
await this.repositoryManagement.attachAgentRepository(agentId, resource.repositoryId, undefined);
|
|
8460
11233
|
await this.waitForAgentRepository(agentId, resource.repositoryId);
|
|
8461
11234
|
this.attachedRepositoryIds.add(resource.repositoryId);
|
|
8462
11235
|
}
|
|
@@ -8464,15 +11237,36 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8464
11237
|
await this.cleanupSessionRepositories(agentId);
|
|
8465
11238
|
throw error;
|
|
8466
11239
|
}
|
|
11240
|
+
const shouldRecompile = resources.some((resource) => resource.recompile !== false);
|
|
11241
|
+
this.repositoryIdsRequiringCleanupRecompile = new Set(resources.filter((resource) => resource.recompile !== false && this.attachedRepositoryIds.has(resource.repositoryId)).map((resource) => resource.repositoryId));
|
|
11242
|
+
return shouldRecompile;
|
|
8467
11243
|
}
|
|
8468
|
-
async cleanupSessionRepositories(agentId) {
|
|
11244
|
+
async cleanupSessionRepositories(agentId, conversationId) {
|
|
8469
11245
|
const repositoryIds = [...this.attachedRepositoryIds];
|
|
11246
|
+
const repositoryIdsRequiringRecompile = this.repositoryIdsRequiringCleanupRecompile;
|
|
8470
11247
|
this.attachedRepositoryIds.clear();
|
|
8471
|
-
|
|
11248
|
+
this.repositoryIdsRequiringCleanupRecompile = new Set;
|
|
11249
|
+
const recompileAfterDetach = await Promise.all(repositoryIds.map(async (repositoryId) => {
|
|
8472
11250
|
try {
|
|
8473
|
-
await this.
|
|
8474
|
-
|
|
11251
|
+
await this.repositoryManagement.detachAgentRepository(agentId, repositoryId);
|
|
11252
|
+
return repositoryIdsRequiringRecompile.has(repositoryId);
|
|
11253
|
+
} catch {
|
|
11254
|
+
return false;
|
|
11255
|
+
}
|
|
8475
11256
|
}));
|
|
11257
|
+
if (recompileAfterDetach.some(Boolean)) {
|
|
11258
|
+
try {
|
|
11259
|
+
await this.recompileSystemPrompt(agentId, conversationId);
|
|
11260
|
+
} catch {}
|
|
11261
|
+
}
|
|
11262
|
+
}
|
|
11263
|
+
async recompileSystemPrompt(agentId, conversationId) {
|
|
11264
|
+
const usesAgentPrompt = !conversationId || conversationId === "default";
|
|
11265
|
+
if (usesAgentPrompt) {
|
|
11266
|
+
await this.repositoryManagement.recompileAgentSystemPrompt(agentId);
|
|
11267
|
+
return;
|
|
11268
|
+
}
|
|
11269
|
+
await this.repositoryManagement.recompileConversationSystemPrompt(agentId, conversationId);
|
|
8476
11270
|
}
|
|
8477
11271
|
repositoryResources() {
|
|
8478
11272
|
const resources = this.cloudMode.options.resources ?? [];
|
|
@@ -8492,76 +11286,33 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8492
11286
|
}
|
|
8493
11287
|
return result;
|
|
8494
11288
|
}
|
|
8495
|
-
async listAgentRepositories(agentId) {
|
|
8496
|
-
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
8497
|
-
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
8498
|
-
const response = await fetchImpl(`${baseUrl}/v1/agents/${encodeURIComponent(agentId)}/repositories`, { headers: cloudHeaders2(this.cloudOptions) });
|
|
8499
|
-
const body = await parseJsonResponse3(response);
|
|
8500
|
-
assertOkResponse2(response, body, "Cloud list agent repositories");
|
|
8501
|
-
if (!body || typeof body !== "object")
|
|
8502
|
-
return [];
|
|
8503
|
-
const repositories = body.repositories;
|
|
8504
|
-
return Array.isArray(repositories) ? repositories.filter((repository) => repository !== null && typeof repository === "object" && typeof repository.id === "string") : [];
|
|
8505
|
-
}
|
|
8506
11289
|
async waitForAgentRepository(agentId, repositoryId) {
|
|
8507
11290
|
const deadline = Date.now() + DEFAULT_REPOSITORY_ATTACH_TIMEOUT_MS;
|
|
8508
11291
|
while (true) {
|
|
8509
|
-
const repositories = await this.listAgentRepositories(agentId);
|
|
11292
|
+
const repositories = await this.repositoryManagement.listAgentRepositories(agentId);
|
|
8510
11293
|
if (repositories.some((repository) => repository.id === repositoryId))
|
|
8511
11294
|
return;
|
|
8512
11295
|
if (Date.now() >= deadline) {
|
|
8513
11296
|
throw new Error(`Cloud attach agent repository did not become visible for ${agentId}: ${repositoryId}`);
|
|
8514
11297
|
}
|
|
8515
|
-
await
|
|
11298
|
+
await sleep3(DEFAULT_REPOSITORY_ATTACH_POLL_INTERVAL_MS);
|
|
8516
11299
|
}
|
|
8517
11300
|
}
|
|
8518
|
-
async linkAgentRepository(agentId, repositoryId) {
|
|
8519
|
-
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
8520
|
-
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
8521
|
-
const response = await fetchImpl(`${baseUrl}/v1/agents/${encodeURIComponent(agentId)}/repositories`, {
|
|
8522
|
-
method: "POST",
|
|
8523
|
-
headers: cloudHeaders2(this.cloudOptions),
|
|
8524
|
-
body: JSON.stringify({ repository_id: repositoryId })
|
|
8525
|
-
});
|
|
8526
|
-
const body = await parseJsonResponse3(response);
|
|
8527
|
-
assertOkResponse2(response, body, "Cloud attach agent repository");
|
|
8528
|
-
}
|
|
8529
|
-
async unlinkAgentRepository(agentId, repositoryId) {
|
|
8530
|
-
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
8531
|
-
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
8532
|
-
const response = await fetchImpl(`${baseUrl}/v1/agents/${encodeURIComponent(agentId)}/repositories/${encodeURIComponent(repositoryId)}`, { method: "DELETE", headers: cloudHeaders2(this.cloudOptions) });
|
|
8533
|
-
const body = await parseJsonResponse3(response);
|
|
8534
|
-
if (response.status === 404)
|
|
8535
|
-
return;
|
|
8536
|
-
assertOkResponse2(response, body, "Cloud detach agent repository");
|
|
8537
|
-
}
|
|
8538
11301
|
async createConversation(agentId) {
|
|
8539
|
-
const
|
|
8540
|
-
|
|
8541
|
-
const url = new URL(`${baseUrl}/v1/conversations/`);
|
|
8542
|
-
url.searchParams.set("agent_id", agentId);
|
|
8543
|
-
const response = await fetchImpl(url, {
|
|
8544
|
-
method: "POST",
|
|
8545
|
-
headers: cloudHeaders2(this.cloudOptions),
|
|
8546
|
-
body: JSON.stringify({})
|
|
11302
|
+
const conversation = await this.apiClient.conversations.create({
|
|
11303
|
+
agent_id: agentId
|
|
8547
11304
|
});
|
|
8548
|
-
|
|
8549
|
-
assertOkResponse2(response, body, "Cloud createSession()", url.toString());
|
|
8550
|
-
if (!isCloudConversation(body)) {
|
|
11305
|
+
if (!isCloudConversation(conversation)) {
|
|
8551
11306
|
throw new Error("Cloud createSession() response did not include a conversation id.");
|
|
8552
11307
|
}
|
|
8553
|
-
return { id:
|
|
11308
|
+
return { id: conversation.id, agent_id: conversation.agent_id };
|
|
8554
11309
|
}
|
|
8555
11310
|
async retrieveConversation(conversationId) {
|
|
8556
|
-
const
|
|
8557
|
-
|
|
8558
|
-
const response = await fetchImpl(`${baseUrl}/v1/conversations/${encodeURIComponent(conversationId)}`, { headers: cloudHeaders2(this.cloudOptions) });
|
|
8559
|
-
const body = await parseJsonResponse3(response);
|
|
8560
|
-
assertOkResponse2(response, body, "Cloud resumeSession()", `${baseUrl}/v1/conversations/${encodeURIComponent(conversationId)}`);
|
|
8561
|
-
if (!isCloudConversation(body)) {
|
|
11311
|
+
const conversation = await this.apiClient.conversations.retrieve(conversationId);
|
|
11312
|
+
if (!isCloudConversation(conversation)) {
|
|
8562
11313
|
throw new Error(`Cloud resumeSession() could not retrieve conversation ${conversationId}.`);
|
|
8563
11314
|
}
|
|
8564
|
-
return { id:
|
|
11315
|
+
return { id: conversation.id, agent_id: conversation.agent_id };
|
|
8565
11316
|
}
|
|
8566
11317
|
async resolveConnectionForRuntime(runtime) {
|
|
8567
11318
|
const environment = this.effectiveEnvironment();
|
|
@@ -8598,20 +11349,14 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8598
11349
|
}
|
|
8599
11350
|
}
|
|
8600
11351
|
async createManagedSandbox(agentId, conversationId) {
|
|
8601
|
-
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
8602
|
-
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
8603
11352
|
const sandboxOptions = this.resolvedSandboxOptions();
|
|
8604
11353
|
const githubRepositories = sandboxOptions.githubRepositories;
|
|
8605
|
-
const
|
|
8606
|
-
|
|
8607
|
-
headers: cloudHeaders2(this.cloudOptions),
|
|
8608
|
-
body: JSON.stringify({
|
|
11354
|
+
const body = await this.apiClient.post(`/v1/agents/${encodeURIComponent(agentId)}/sandboxes`, {
|
|
11355
|
+
body: {
|
|
8609
11356
|
...conversationId ? { conversationId } : {},
|
|
8610
11357
|
...githubRepositories && githubRepositories.length > 0 ? { githubRepositories } : {}
|
|
8611
|
-
}
|
|
11358
|
+
}
|
|
8612
11359
|
});
|
|
8613
|
-
const body = await parseJsonResponse3(response);
|
|
8614
|
-
assertOkResponse2(response, body, "Cloud create managed sandbox", `${baseUrl}/v1/agents/${encodeURIComponent(agentId)}/sandboxes`);
|
|
8615
11360
|
if (!isCloudAgentSandbox(body)) {
|
|
8616
11361
|
throw new Error("Cloud create managed sandbox response did not include sandbox connection details.");
|
|
8617
11362
|
}
|
|
@@ -8649,32 +11394,23 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8649
11394
|
}
|
|
8650
11395
|
}
|
|
8651
11396
|
async refreshManagedSandboxOnce(sandbox) {
|
|
8652
|
-
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
8653
|
-
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
8654
11397
|
if (sandbox.conversationId) {
|
|
8655
|
-
|
|
8656
|
-
|
|
8657
|
-
|
|
8658
|
-
|
|
8659
|
-
|
|
8660
|
-
|
|
8661
|
-
await parseJsonResponse3(response2);
|
|
11398
|
+
let body2;
|
|
11399
|
+
try {
|
|
11400
|
+
body2 = await this.apiClient.post(`/v1/sandboxes/${encodeURIComponent(sandbox.sandboxId)}/refresh`, { body: { ttlMinutes: sandbox.ttlMinutes } });
|
|
11401
|
+
} catch (error) {
|
|
11402
|
+
if (!isNotFound2(error))
|
|
11403
|
+
throw error;
|
|
8662
11404
|
throw new CloudManagedSandboxExpiredError(sandbox.sandboxId, sandbox.conversationId);
|
|
8663
11405
|
}
|
|
8664
|
-
const body2 = await parseJsonResponse3(response2);
|
|
8665
|
-
assertOkResponse2(response2, body2, "Cloud refresh managed sandbox");
|
|
8666
11406
|
if (!isCloudAgentSandboxRefresh(body2) || !body2.success) {
|
|
8667
11407
|
throw new Error("Cloud refresh managed sandbox response did not confirm refresh.");
|
|
8668
11408
|
}
|
|
8669
11409
|
return;
|
|
8670
11410
|
}
|
|
8671
|
-
const
|
|
8672
|
-
|
|
8673
|
-
headers: cloudHeaders2(this.cloudOptions),
|
|
8674
|
-
body: JSON.stringify({ ttlMinutes: sandbox.ttlMinutes })
|
|
11411
|
+
const body = await this.apiClient.post(`/v1/agents/${encodeURIComponent(sandbox.agentId)}/sandboxes/refresh`, {
|
|
11412
|
+
body: { ttlMinutes: sandbox.ttlMinutes }
|
|
8675
11413
|
});
|
|
8676
|
-
const body = await parseJsonResponse3(response);
|
|
8677
|
-
assertOkResponse2(response, body, "Cloud refresh managed sandbox", `${baseUrl}/v1/agents/${encodeURIComponent(sandbox.agentId)}/sandboxes/refresh`);
|
|
8678
11414
|
if (!isCloudAgentSandboxRefresh(body) || !body.success) {
|
|
8679
11415
|
throw new Error("Cloud refresh managed sandbox response did not confirm refresh.");
|
|
8680
11416
|
}
|
|
@@ -8683,29 +11419,22 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8683
11419
|
}
|
|
8684
11420
|
}
|
|
8685
11421
|
async terminateManagedSandbox(sandbox) {
|
|
8686
|
-
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
8687
|
-
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
8688
11422
|
if (sandbox.conversationId) {
|
|
8689
|
-
|
|
8690
|
-
|
|
8691
|
-
|
|
8692
|
-
|
|
8693
|
-
|
|
8694
|
-
|
|
8695
|
-
if (response2.status === 404)
|
|
8696
|
-
return;
|
|
8697
|
-
assertOkResponse2(response2, body2, "Cloud terminate managed sandbox");
|
|
11423
|
+
try {
|
|
11424
|
+
await this.apiClient.post(`/v1/sandboxes/${encodeURIComponent(sandbox.sandboxId)}/terminate`, { body: {} });
|
|
11425
|
+
} catch (error) {
|
|
11426
|
+
if (!isNotFound2(error))
|
|
11427
|
+
throw error;
|
|
11428
|
+
}
|
|
8698
11429
|
return;
|
|
8699
11430
|
}
|
|
8700
11431
|
await this.refreshManagedSandbox(sandbox);
|
|
8701
|
-
|
|
8702
|
-
|
|
8703
|
-
|
|
8704
|
-
|
|
8705
|
-
|
|
8706
|
-
|
|
8707
|
-
return;
|
|
8708
|
-
assertOkResponse2(response, body, "Cloud terminate managed sandbox", `${baseUrl}/v1/agents/${encodeURIComponent(sandbox.agentId)}/sandboxes`);
|
|
11432
|
+
try {
|
|
11433
|
+
await this.apiClient.delete(`/v1/agents/${encodeURIComponent(sandbox.agentId)}/sandboxes`);
|
|
11434
|
+
} catch (error) {
|
|
11435
|
+
if (!isNotFound2(error))
|
|
11436
|
+
throw error;
|
|
11437
|
+
}
|
|
8709
11438
|
}
|
|
8710
11439
|
async waitForManagedSandboxConnection(sandbox) {
|
|
8711
11440
|
const deadline = Date.now() + sandbox.readyTimeoutMs;
|
|
@@ -8722,7 +11451,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8722
11451
|
break;
|
|
8723
11452
|
}
|
|
8724
11453
|
const remainingMs = Math.max(0, deadline - Date.now());
|
|
8725
|
-
await
|
|
11454
|
+
await sleep3(Math.min(sandbox.readyPollIntervalMs, remainingMs));
|
|
8726
11455
|
}
|
|
8727
11456
|
}
|
|
8728
11457
|
const detail = lastError instanceof Error ? lastError.message : String(lastError);
|
|
@@ -8760,12 +11489,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8760
11489
|
} catch {}
|
|
8761
11490
|
}
|
|
8762
11491
|
remoteEnvironmentClient() {
|
|
8763
|
-
return new RemoteEnvironmentClient({
|
|
8764
|
-
baseUrl: this.cloudOptions.apiBaseUrl,
|
|
8765
|
-
apiKey: getCloudApiKey2(this.cloudOptions),
|
|
8766
|
-
headers: this.cloudOptions.headers,
|
|
8767
|
-
fetch: this.cloudOptions.fetch
|
|
8768
|
-
});
|
|
11492
|
+
return new RemoteEnvironmentClient({}, this.apiClient);
|
|
8769
11493
|
}
|
|
8770
11494
|
effectiveEnvironment() {
|
|
8771
11495
|
const modeEnvironment = this.mode.kind === "session" ? this.mode.options.environment : undefined;
|
|
@@ -8781,16 +11505,13 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8781
11505
|
}
|
|
8782
11506
|
|
|
8783
11507
|
// src/management.ts
|
|
8784
|
-
function
|
|
8785
|
-
return Object.fromEntries(Object.entries(values).filter(([, value]) => value !== undefined));
|
|
8786
|
-
}
|
|
8787
|
-
function assertNonEmptyId(value, name) {
|
|
11508
|
+
function assertNonEmptyId2(value, name) {
|
|
8788
11509
|
if (typeof value !== "string" || value.trim().length === 0) {
|
|
8789
11510
|
throw new Error(`Invalid ${name}. Expected a non-empty string.`);
|
|
8790
11511
|
}
|
|
8791
11512
|
}
|
|
8792
11513
|
function agentListQuery(options) {
|
|
8793
|
-
const orderBy = options.orderBy
|
|
11514
|
+
const orderBy = options.orderBy === "createdAt" ? "created_at" : options.orderBy === "lastRunCompletion" ? "last_run_completion" : undefined;
|
|
8794
11515
|
return {
|
|
8795
11516
|
before: options.before,
|
|
8796
11517
|
after: options.after,
|
|
@@ -8805,7 +11526,7 @@ function agentListQuery(options) {
|
|
|
8805
11526
|
};
|
|
8806
11527
|
}
|
|
8807
11528
|
function agentUpdateBody(options) {
|
|
8808
|
-
return
|
|
11529
|
+
return {
|
|
8809
11530
|
name: options.name,
|
|
8810
11531
|
description: options.description,
|
|
8811
11532
|
model: options.model,
|
|
@@ -8814,10 +11535,10 @@ function agentUpdateBody(options) {
|
|
|
8814
11535
|
tags: options.tags,
|
|
8815
11536
|
hidden: options.hidden,
|
|
8816
11537
|
context_window_limit: options.contextWindowLimit
|
|
8817
|
-
}
|
|
11538
|
+
};
|
|
8818
11539
|
}
|
|
8819
11540
|
function conversationListQuery(options) {
|
|
8820
|
-
const orderBy = options.orderBy
|
|
11541
|
+
const orderBy = options.orderBy === "createdAt" ? "created_at" : options.orderBy === "lastRunCompletion" ? "last_run_completion" : options.orderBy === "lastMessageAt" ? "last_message_at" : undefined;
|
|
8821
11542
|
return {
|
|
8822
11543
|
agent_id: options.agentId,
|
|
8823
11544
|
after: options.after,
|
|
@@ -8829,7 +11550,7 @@ function conversationListQuery(options) {
|
|
|
8829
11550
|
};
|
|
8830
11551
|
}
|
|
8831
11552
|
function conversationCreateBody(options) {
|
|
8832
|
-
return
|
|
11553
|
+
return {
|
|
8833
11554
|
agent_id: options.agentId,
|
|
8834
11555
|
summary: options.summary,
|
|
8835
11556
|
description: options.description,
|
|
@@ -8837,17 +11558,17 @@ function conversationCreateBody(options) {
|
|
|
8837
11558
|
model_settings: options.modelSettings,
|
|
8838
11559
|
context_window_limit: options.contextWindowLimit,
|
|
8839
11560
|
hidden: options.hidden
|
|
8840
|
-
}
|
|
11561
|
+
};
|
|
8841
11562
|
}
|
|
8842
11563
|
function conversationUpdateBody(options) {
|
|
8843
|
-
return
|
|
11564
|
+
return {
|
|
8844
11565
|
summary: options.summary,
|
|
8845
11566
|
description: options.description,
|
|
8846
11567
|
model: options.model,
|
|
8847
11568
|
model_settings: options.modelSettings,
|
|
8848
11569
|
context_window_limit: options.contextWindowLimit,
|
|
8849
11570
|
archived: options.archived
|
|
8850
|
-
}
|
|
11571
|
+
};
|
|
8851
11572
|
}
|
|
8852
11573
|
function conversationMessagesQuery(options) {
|
|
8853
11574
|
return {
|
|
@@ -8857,13 +11578,16 @@ function conversationMessagesQuery(options) {
|
|
|
8857
11578
|
limit: options.limit
|
|
8858
11579
|
};
|
|
8859
11580
|
}
|
|
8860
|
-
function createAgentsClient(transport) {
|
|
11581
|
+
function createAgentsClient(transport, repositories) {
|
|
8861
11582
|
return {
|
|
11583
|
+
get repositories() {
|
|
11584
|
+
return repositories();
|
|
11585
|
+
},
|
|
8862
11586
|
list: (options = {}) => transport().listAgents(agentListQuery(options)),
|
|
8863
11587
|
retrieve: (agentId) => transport().retrieveAgent(agentId),
|
|
8864
11588
|
update: (agentId, options) => transport().updateAgent(agentId, agentUpdateBody(options)),
|
|
8865
11589
|
delete: async (agentId) => {
|
|
8866
|
-
|
|
11590
|
+
assertNonEmptyId2(agentId, "agent id");
|
|
8867
11591
|
await transport().deleteAgent(agentId);
|
|
8868
11592
|
}
|
|
8869
11593
|
};
|
|
@@ -9058,6 +11782,8 @@ class LettaAgentClientBase {
|
|
|
9058
11782
|
models;
|
|
9059
11783
|
options;
|
|
9060
11784
|
repositoriesClient = null;
|
|
11785
|
+
agentRepositoriesClient = null;
|
|
11786
|
+
cloudClient = null;
|
|
9061
11787
|
managementTransport = null;
|
|
9062
11788
|
constructor(options = {}) {
|
|
9063
11789
|
const backend = options.backend ?? "local";
|
|
@@ -9067,7 +11793,7 @@ class LettaAgentClientBase {
|
|
|
9067
11793
|
this.backend = backend;
|
|
9068
11794
|
this.environment = getOptionsEnvironment(options);
|
|
9069
11795
|
this.options = options;
|
|
9070
|
-
this.agents = createAgentsClient(() => this.getManagementTransport());
|
|
11796
|
+
this.agents = createAgentsClient(() => this.getManagementTransport(), () => this.getAgentRepositoriesClient());
|
|
9071
11797
|
this.conversations = createConversationsClient(() => this.getManagementTransport());
|
|
9072
11798
|
this.models = createModelsClient(() => this.getManagementTransport());
|
|
9073
11799
|
if (this.backend === "local" && this.environment !== undefined) {
|
|
@@ -9123,7 +11849,7 @@ class LettaAgentClientBase {
|
|
|
9123
11849
|
return initMsg.agentId;
|
|
9124
11850
|
}
|
|
9125
11851
|
if (this.backend === "cloud") {
|
|
9126
|
-
return createCloudAgent(this.
|
|
11852
|
+
return createCloudAgent(this.getCloudClient(), options);
|
|
9127
11853
|
}
|
|
9128
11854
|
return this.createLocalAgent(options);
|
|
9129
11855
|
}
|
|
@@ -9148,7 +11874,7 @@ class LettaAgentClientBase {
|
|
|
9148
11874
|
agentId,
|
|
9149
11875
|
newConversation: true,
|
|
9150
11876
|
options
|
|
9151
|
-
});
|
|
11877
|
+
}, this.getCloudClient());
|
|
9152
11878
|
}
|
|
9153
11879
|
return this.createLocalSession(agentId, options);
|
|
9154
11880
|
}
|
|
@@ -9177,14 +11903,14 @@ class LettaAgentClientBase {
|
|
|
9177
11903
|
kind: "session",
|
|
9178
11904
|
conversationId: id,
|
|
9179
11905
|
options
|
|
9180
|
-
});
|
|
11906
|
+
}, this.getCloudClient());
|
|
9181
11907
|
}
|
|
9182
11908
|
return new CloudEnvironmentSession(this.cloudOptions(), {
|
|
9183
11909
|
kind: "session",
|
|
9184
11910
|
agentId: id,
|
|
9185
11911
|
defaultConversation: true,
|
|
9186
11912
|
options
|
|
9187
|
-
});
|
|
11913
|
+
}, this.getCloudClient());
|
|
9188
11914
|
}
|
|
9189
11915
|
return this.resumeLocalSession(id, options);
|
|
9190
11916
|
}
|
|
@@ -9278,16 +12004,37 @@ class LettaAgentClientBase {
|
|
|
9278
12004
|
if (this.backend !== "cloud") {
|
|
9279
12005
|
throw new Error('client.repositories is only available with backend: "cloud".');
|
|
9280
12006
|
}
|
|
9281
|
-
this.repositoriesClient ??= new RepositoriesClient(this.cloudOptions());
|
|
12007
|
+
this.repositoriesClient ??= new RepositoriesClient(this.cloudOptions(), this.getCloudClient());
|
|
9282
12008
|
return this.repositoriesClient;
|
|
9283
12009
|
}
|
|
12010
|
+
getAgentRepositoriesClient() {
|
|
12011
|
+
if (this.backend !== "cloud") {
|
|
12012
|
+
throw new Error('client.agents.repositories is only available with backend: "cloud".');
|
|
12013
|
+
}
|
|
12014
|
+
this.agentRepositoriesClient ??= createAgentRepositoriesClient(() => this.getCloudManagementTransport());
|
|
12015
|
+
return this.agentRepositoriesClient;
|
|
12016
|
+
}
|
|
12017
|
+
getCloudManagementTransport() {
|
|
12018
|
+
const transport = this.getManagementTransport();
|
|
12019
|
+
if (!(transport instanceof CloudManagementTransport)) {
|
|
12020
|
+
throw new Error("Cloud management requested for non-cloud backend.");
|
|
12021
|
+
}
|
|
12022
|
+
return transport;
|
|
12023
|
+
}
|
|
12024
|
+
getCloudClient() {
|
|
12025
|
+
if (this.backend !== "cloud") {
|
|
12026
|
+
throw new Error("Letta client requested for non-cloud backend.");
|
|
12027
|
+
}
|
|
12028
|
+
this.cloudClient ??= createCloudClient(this.cloudOptions());
|
|
12029
|
+
return this.cloudClient;
|
|
12030
|
+
}
|
|
9284
12031
|
getManagementTransport() {
|
|
9285
12032
|
if (this.managementTransport)
|
|
9286
12033
|
return this.managementTransport;
|
|
9287
12034
|
if (this.backend === "remote") {
|
|
9288
12035
|
this.managementTransport = new AppServerManagementTransport(this.remoteOptions());
|
|
9289
12036
|
} else if (this.backend === "cloud") {
|
|
9290
|
-
this.managementTransport = new CloudManagementTransport(this.
|
|
12037
|
+
this.managementTransport = new CloudManagementTransport(this.getCloudClient());
|
|
9291
12038
|
} else {
|
|
9292
12039
|
this.managementTransport = this.createLocalManagementTransport();
|
|
9293
12040
|
}
|
|
@@ -9388,4 +12135,4 @@ export {
|
|
|
9388
12135
|
CloudManagedSandboxExpiredError
|
|
9389
12136
|
};
|
|
9390
12137
|
|
|
9391
|
-
//# debugId=
|
|
12138
|
+
//# debugId=DC9188A459F6634B64756E2164756E21
|