@letta-ai/letta-agent-sdk 0.5.1 → 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 +20 -3
- 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 +3347 -641
- 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 +5 -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 +3363 -657
- 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 +12 -32
- 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 +79 -262
- 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 +2 -2
- package/src/remote.ts +18 -63
- package/src/repositories.ts +26 -99
- package/src/types.ts +12 -33
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(/\/$/, "");
|
|
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
|
+
});
|
|
68
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".`);
|
|
3007
|
+
}
|
|
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);
|
|
243
3030
|
}
|
|
244
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)
|
|
@@ -1027,31 +3816,219 @@ Strengths.
|
|
|
1027
3816
|
Blind spots.
|
|
1028
3817
|
What explanations land.
|
|
1029
3818
|
|
|
1030
|
-
Continuity is the point.
|
|
1031
|
-
Less reorientation over time.
|
|
1032
|
-
Fewer repeated mistakes.
|
|
1033
|
-
Better instinct for what matters before they spell it out again.
|
|
1034
|
-
`;
|
|
1035
|
-
var human_tutorial_default = `---
|
|
1036
|
-
label: human
|
|
1037
|
-
description: What I know about the person I am interacting with
|
|
1038
|
-
---
|
|
3819
|
+
Continuity is the point.
|
|
3820
|
+
Less reorientation over time.
|
|
3821
|
+
Fewer repeated mistakes.
|
|
3822
|
+
Better instinct for what matters before they spell it out again.
|
|
3823
|
+
`;
|
|
3824
|
+
var human_tutorial_default = `---
|
|
3825
|
+
label: human
|
|
3826
|
+
description: What I know about the person I am interacting with
|
|
3827
|
+
---
|
|
3828
|
+
|
|
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\`.
|
|
1039
4002
|
|
|
1040
|
-
|
|
1041
|
-
Occupation: ?
|
|
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.
|
|
1042
4004
|
|
|
1043
|
-
|
|
1044
|
-
?
|
|
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.
|
|
1045
4006
|
|
|
1046
|
-
##
|
|
1047
|
-
?
|
|
4007
|
+
## Hooks
|
|
1048
4008
|
|
|
1049
|
-
|
|
1050
|
-
- ?
|
|
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.
|
|
1051
4010
|
|
|
1052
|
-
|
|
4011
|
+
# Self-evolution: memory, skills, and harness
|
|
4012
|
+
|
|
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.
|
|
4014
|
+
|
|
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.
|
|
4016
|
+
|
|
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
|
|
4022
|
+
|
|
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();
|
|
@@ -6942,7 +9923,7 @@ class RemoteClientSessionCore {
|
|
|
6942
9923
|
|
|
6943
9924
|
// src/app-server-session.ts
|
|
6944
9925
|
function agentToolNames(agent) {
|
|
6945
|
-
const tools = agent
|
|
9926
|
+
const tools = agent && "tools" in agent ? agent.tools : undefined;
|
|
6946
9927
|
if (!Array.isArray(tools))
|
|
6947
9928
|
return;
|
|
6948
9929
|
return tools.flatMap((tool) => {
|
|
@@ -7171,75 +10152,21 @@ function toAppServerApprovalDecision(decision) {
|
|
|
7171
10152
|
selected_permission_suggestion_ids: selectedPermissionSuggestionIds
|
|
7172
10153
|
};
|
|
7173
10154
|
}
|
|
7174
|
-
function stringRecord2(value) {
|
|
7175
|
-
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
7176
|
-
return;
|
|
7177
|
-
const record = {};
|
|
7178
|
-
for (const [key, entry] of Object.entries(value)) {
|
|
7179
|
-
if (typeof entry === "string")
|
|
7180
|
-
record[key] = entry;
|
|
7181
|
-
}
|
|
7182
|
-
return record;
|
|
7183
|
-
}
|
|
7184
10155
|
function objectRecord(value) {
|
|
7185
10156
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
7186
10157
|
return;
|
|
7187
10158
|
return { ...value };
|
|
7188
10159
|
}
|
|
7189
|
-
function normalizeListModelsResponse(response) {
|
|
7190
|
-
if (!response.success) {
|
|
7191
|
-
throw new Error(response.error ?? "listModels failed");
|
|
7192
|
-
}
|
|
7193
|
-
const entries = Array.isArray(response.entries) ? response.entries.flatMap((entry) => {
|
|
7194
|
-
if (!entry || typeof entry !== "object")
|
|
7195
|
-
return [];
|
|
7196
|
-
const record = entry;
|
|
7197
|
-
if (typeof record.id !== "string" || typeof record.handle !== "string" || typeof record.label !== "string" || typeof record.description !== "string") {
|
|
7198
|
-
return [];
|
|
7199
|
-
}
|
|
7200
|
-
const updateArgs = objectRecord(record.updateArgs);
|
|
7201
|
-
return [
|
|
7202
|
-
{
|
|
7203
|
-
id: record.id,
|
|
7204
|
-
handle: record.handle,
|
|
7205
|
-
label: record.label,
|
|
7206
|
-
description: record.description,
|
|
7207
|
-
...typeof record.isDefault === "boolean" ? { isDefault: record.isDefault } : {},
|
|
7208
|
-
...typeof record.isFeatured === "boolean" ? { isFeatured: record.isFeatured } : {},
|
|
7209
|
-
...typeof record.free === "boolean" ? { free: record.free } : {},
|
|
7210
|
-
...updateArgs ? { updateArgs } : {}
|
|
7211
|
-
}
|
|
7212
|
-
];
|
|
7213
|
-
}) : [];
|
|
7214
|
-
const result = { entries };
|
|
7215
|
-
if (response.available_handles === null) {
|
|
7216
|
-
result.availableHandles = null;
|
|
7217
|
-
} else if (Array.isArray(response.available_handles)) {
|
|
7218
|
-
result.availableHandles = response.available_handles.filter((handle) => typeof handle === "string");
|
|
7219
|
-
}
|
|
7220
|
-
const aliases = stringRecord2(response.byok_provider_aliases);
|
|
7221
|
-
if (aliases)
|
|
7222
|
-
result.byokProviderAliases = aliases;
|
|
7223
|
-
return result;
|
|
7224
|
-
}
|
|
7225
10160
|
function normalizeUpdateModelResponse(response) {
|
|
7226
10161
|
if (!response.success) {
|
|
7227
10162
|
throw new Error(response.error ?? "Failed to update model");
|
|
7228
10163
|
}
|
|
7229
|
-
|
|
7230
|
-
|
|
7231
|
-
|
|
7232
|
-
|
|
7233
|
-
|
|
7234
|
-
|
|
7235
|
-
if (typeof response.model_handle === "string")
|
|
7236
|
-
result.modelHandle = response.model_handle;
|
|
7237
|
-
if (response.model_settings === null) {
|
|
7238
|
-
result.modelSettings = null;
|
|
7239
|
-
} else if (response.model_settings && typeof response.model_settings === "object") {
|
|
7240
|
-
result.modelSettings = { ...response.model_settings };
|
|
7241
|
-
}
|
|
7242
|
-
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
|
+
};
|
|
7243
10170
|
}
|
|
7244
10171
|
function runtimeScopeFromMessage(message) {
|
|
7245
10172
|
if (message.runtime)
|
|
@@ -7324,12 +10251,24 @@ class AppServerRuntimeController {
|
|
|
7324
10251
|
await this.client.abort({ runtime });
|
|
7325
10252
|
}
|
|
7326
10253
|
request(type, body, options = {}) {
|
|
7327
|
-
|
|
7328
|
-
|
|
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
|
+
});
|
|
7329
10268
|
}
|
|
7330
10269
|
async listModels() {
|
|
7331
10270
|
const response = await this.request("list_models", {}, { predicate: (message) => message.type === "list_models_response" });
|
|
7332
|
-
return
|
|
10271
|
+
return normalizeAppServerModels(response);
|
|
7333
10272
|
}
|
|
7334
10273
|
async updateModel(runtime, payload) {
|
|
7335
10274
|
const response = await this.request("update_model", {
|
|
@@ -7436,7 +10375,7 @@ class AppServerSession extends RemoteClientSessionCore {
|
|
|
7436
10375
|
controller: new AppServerRuntimeController(client, this.remoteOptions, this.currentOptions().allowedTools),
|
|
7437
10376
|
runtime: response.runtime,
|
|
7438
10377
|
model: typeof response.agent?.model === "string" ? response.agent.model : "",
|
|
7439
|
-
modelSettings: response.agent?.model_settings ?? null,
|
|
10378
|
+
modelSettings: objectRecord(response.agent?.model_settings) ?? null,
|
|
7440
10379
|
...tools !== undefined ? { tools } : {},
|
|
7441
10380
|
...skillSources !== undefined ? { skillSources: [...skillSources] } : {}
|
|
7442
10381
|
};
|
|
@@ -7471,8 +10410,7 @@ class AppServerSession extends RemoteClientSessionCore {
|
|
|
7471
10410
|
}
|
|
7472
10411
|
async startRuntime(client) {
|
|
7473
10412
|
const command = await this.buildRuntimeStartCommand(client);
|
|
7474
|
-
|
|
7475
|
-
return response;
|
|
10413
|
+
return client.runtimeStart(command);
|
|
7476
10414
|
}
|
|
7477
10415
|
async buildRuntimeStartCommand(client) {
|
|
7478
10416
|
const options = this.mode.options;
|
|
@@ -7523,8 +10461,13 @@ class AppServerSession extends RemoteClientSessionCore {
|
|
|
7523
10461
|
throw new Error("App-server createSession() requires an agent id. Call createAgent() first or pass an agent id.");
|
|
7524
10462
|
}
|
|
7525
10463
|
async resolveConversationAgentId(client, conversationId) {
|
|
7526
|
-
const
|
|
7527
|
-
|
|
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
|
+
});
|
|
7528
10471
|
if (!response.success || !response.conversation?.agent_id) {
|
|
7529
10472
|
throw new Error(response.error ?? `Failed to retrieve conversation ${conversationId}`);
|
|
7530
10473
|
}
|
|
@@ -7533,87 +10476,21 @@ class AppServerSession extends RemoteClientSessionCore {
|
|
|
7533
10476
|
}
|
|
7534
10477
|
|
|
7535
10478
|
// src/cloud-management.ts
|
|
7536
|
-
|
|
7537
|
-
function defaultApiKey() {
|
|
7538
|
-
const env = globalThis.process?.env;
|
|
7539
|
-
return env?.LETTA_API_KEY ?? env?.LETTA_CLOUD_API_KEY;
|
|
7540
|
-
}
|
|
7541
|
-
function bearerToken(headers) {
|
|
7542
|
-
const authorization = headers?.Authorization ?? headers?.authorization;
|
|
7543
|
-
return authorization?.match(/^Bearer\s+(.+)$/i)?.[1];
|
|
7544
|
-
}
|
|
7545
|
-
function apiBaseUrl(value) {
|
|
7546
|
-
const url = new URL(value ?? DEFAULT_CLOUD_API_BASE_URL2);
|
|
7547
|
-
url.pathname = url.pathname.replace(/\/+$/, "");
|
|
7548
|
-
url.search = "";
|
|
7549
|
-
url.hash = "";
|
|
7550
|
-
return url.toString().replace(/\/$/, "");
|
|
7551
|
-
}
|
|
7552
|
-
function requestHeaders(options) {
|
|
7553
|
-
const headers = {
|
|
7554
|
-
"Content-Type": "application/json",
|
|
7555
|
-
...options.headers ?? {}
|
|
7556
|
-
};
|
|
7557
|
-
const apiKey = options.apiKey ?? bearerToken(options.headers) ?? defaultApiKey();
|
|
7558
|
-
if (apiKey && !headers.Authorization && !headers.authorization) {
|
|
7559
|
-
headers.Authorization = `Bearer ${apiKey}`;
|
|
7560
|
-
}
|
|
7561
|
-
return headers;
|
|
7562
|
-
}
|
|
7563
|
-
function appendQuery(url, query) {
|
|
7564
|
-
for (const [key, value] of Object.entries(query)) {
|
|
7565
|
-
if (value === undefined || value === null)
|
|
7566
|
-
continue;
|
|
7567
|
-
if (Array.isArray(value)) {
|
|
7568
|
-
for (const item of value)
|
|
7569
|
-
url.searchParams.append(key, item);
|
|
7570
|
-
} else {
|
|
7571
|
-
url.searchParams.set(key, String(value));
|
|
7572
|
-
}
|
|
7573
|
-
}
|
|
7574
|
-
}
|
|
7575
|
-
async function parseResponse(response) {
|
|
7576
|
-
const text = await response.text();
|
|
7577
|
-
if (!text)
|
|
7578
|
-
return null;
|
|
7579
|
-
try {
|
|
7580
|
-
return JSON.parse(text);
|
|
7581
|
-
} catch {
|
|
7582
|
-
return text;
|
|
7583
|
-
}
|
|
7584
|
-
}
|
|
7585
|
-
function responseErrorMessage2(body, fallback) {
|
|
7586
|
-
if (body && typeof body === "object") {
|
|
7587
|
-
const record = body;
|
|
7588
|
-
const message = record.message ?? record.error ?? record.detail;
|
|
7589
|
-
if (typeof message === "string" && message.length > 0)
|
|
7590
|
-
return message;
|
|
7591
|
-
}
|
|
7592
|
-
return fallback;
|
|
7593
|
-
}
|
|
7594
|
-
function cloudRequestError(response, body, action, url, options) {
|
|
7595
|
-
const parts = [
|
|
7596
|
-
`${action} failed`,
|
|
7597
|
-
responseErrorMessage2(body, `HTTP ${response.status}`),
|
|
7598
|
-
`URL: ${url.toString()}`
|
|
7599
|
-
];
|
|
7600
|
-
if (response.status === 401 || response.status === 403) {
|
|
7601
|
-
const hasApiKey = Boolean(options.apiKey ?? bearerToken(options.headers) ?? defaultApiKey());
|
|
7602
|
-
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).");
|
|
7603
|
-
}
|
|
7604
|
-
return new Error(parts.join(" — "));
|
|
7605
|
-
}
|
|
7606
|
-
function asObject(body, action) {
|
|
10479
|
+
function asAgentRepository(body, action) {
|
|
7607
10480
|
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
7608
|
-
throw new Error(`${action} response did not include
|
|
10481
|
+
throw new Error(`${action} response did not include a repository.`);
|
|
7609
10482
|
}
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
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.`);
|
|
7615
10487
|
}
|
|
7616
|
-
return
|
|
10488
|
+
return {
|
|
10489
|
+
id: repository.id,
|
|
10490
|
+
name: repository.name,
|
|
10491
|
+
isPrimary: repository.is_primary,
|
|
10492
|
+
permissions
|
|
10493
|
+
};
|
|
7617
10494
|
}
|
|
7618
10495
|
function cloudModelEntry(raw) {
|
|
7619
10496
|
if (typeof raw.handle !== "string" || raw.handle.length === 0) {
|
|
@@ -7628,26 +10505,62 @@ function cloudModelEntry(raw) {
|
|
|
7628
10505
|
description: typeof raw.description === "string" ? raw.description : ""
|
|
7629
10506
|
};
|
|
7630
10507
|
}
|
|
10508
|
+
function isNotFound(error) {
|
|
10509
|
+
return error instanceof APIError && error.status === 404;
|
|
10510
|
+
}
|
|
7631
10511
|
|
|
7632
10512
|
class CloudManagementTransport {
|
|
7633
|
-
|
|
7634
|
-
constructor(
|
|
7635
|
-
this.
|
|
10513
|
+
client;
|
|
10514
|
+
constructor(client) {
|
|
10515
|
+
this.client = client;
|
|
7636
10516
|
}
|
|
7637
|
-
listAgents(query) {
|
|
7638
|
-
|
|
10517
|
+
async listAgents(query) {
|
|
10518
|
+
const page = await this.client.agents.list(query);
|
|
10519
|
+
return page.items;
|
|
7639
10520
|
}
|
|
7640
|
-
retrieveAgent(agentId) {
|
|
7641
|
-
return this.
|
|
10521
|
+
async retrieveAgent(agentId) {
|
|
10522
|
+
return this.client.agents.retrieve(agentId);
|
|
7642
10523
|
}
|
|
7643
|
-
updateAgent(agentId, body) {
|
|
7644
|
-
return this.
|
|
10524
|
+
async updateAgent(agentId, body) {
|
|
10525
|
+
return this.client.agents.update(agentId, body);
|
|
7645
10526
|
}
|
|
7646
10527
|
async deleteAgent(agentId) {
|
|
7647
|
-
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
|
+
});
|
|
7648
10561
|
}
|
|
7649
10562
|
async listModels() {
|
|
7650
|
-
const entries = await this.
|
|
10563
|
+
const entries = await this.client.models.list();
|
|
7651
10564
|
const normalized = entries.flatMap((entry) => {
|
|
7652
10565
|
const model = cloudModelEntry(entry);
|
|
7653
10566
|
return model ? [model] : [];
|
|
@@ -7657,65 +10570,21 @@ class CloudManagementTransport {
|
|
|
7657
10570
|
availableHandles: normalized.map((entry) => entry.handle)
|
|
7658
10571
|
};
|
|
7659
10572
|
}
|
|
7660
|
-
listConversations(query) {
|
|
7661
|
-
return this.
|
|
10573
|
+
async listConversations(query) {
|
|
10574
|
+
return this.client.conversations.list(query);
|
|
7662
10575
|
}
|
|
7663
|
-
retrieveConversation(conversationId) {
|
|
7664
|
-
return this.
|
|
10576
|
+
async retrieveConversation(conversationId) {
|
|
10577
|
+
return this.client.conversations.retrieve(conversationId);
|
|
7665
10578
|
}
|
|
7666
|
-
createConversation(body) {
|
|
7667
|
-
|
|
7668
|
-
if (typeof agentId !== "string" || agentId.length === 0) {
|
|
7669
|
-
throw new Error("createConversation() requires a non-empty agentId.");
|
|
7670
|
-
}
|
|
7671
|
-
const url = this.url("/v1/conversations/");
|
|
7672
|
-
url.searchParams.set("agent_id", agentId);
|
|
7673
|
-
return this.requestUrlObject(url, "POST", requestBody, "Cloud create conversation");
|
|
10579
|
+
async createConversation(body) {
|
|
10580
|
+
return this.client.conversations.create(body);
|
|
7674
10581
|
}
|
|
7675
|
-
updateConversation(conversationId, body) {
|
|
7676
|
-
return this.
|
|
10582
|
+
async updateConversation(conversationId, body) {
|
|
10583
|
+
return this.client.conversations.update(conversationId, body);
|
|
7677
10584
|
}
|
|
7678
10585
|
async listConversationMessages(conversationId, query) {
|
|
7679
|
-
const
|
|
7680
|
-
return { messages };
|
|
7681
|
-
}
|
|
7682
|
-
async getArray(path, query, action) {
|
|
7683
|
-
const body = await this.get(path, query, action);
|
|
7684
|
-
return asArray(body, action);
|
|
7685
|
-
}
|
|
7686
|
-
async getObject(path, query, action) {
|
|
7687
|
-
const body = await this.get(path, query, action);
|
|
7688
|
-
return asObject(body, action);
|
|
7689
|
-
}
|
|
7690
|
-
get(path, query, action) {
|
|
7691
|
-
const url = this.url(path);
|
|
7692
|
-
appendQuery(url, query);
|
|
7693
|
-
return this.requestUrl(url, "GET", undefined, action);
|
|
7694
|
-
}
|
|
7695
|
-
requestObject(path, method, body, action) {
|
|
7696
|
-
return this.requestUrlObject(this.url(path), method, body, action);
|
|
7697
|
-
}
|
|
7698
|
-
async requestUrlObject(url, method, body, action) {
|
|
7699
|
-
return asObject(await this.requestUrl(url, method, body, action), action);
|
|
7700
|
-
}
|
|
7701
|
-
async requestUrl(url, method, body, action) {
|
|
7702
|
-
const fetchImpl = (this.options.fetch ?? globalThis.fetch)?.bind(globalThis);
|
|
7703
|
-
if (!fetchImpl) {
|
|
7704
|
-
throw new Error("No fetch implementation available for cloud backend.");
|
|
7705
|
-
}
|
|
7706
|
-
const response = await fetchImpl(url, {
|
|
7707
|
-
method,
|
|
7708
|
-
headers: requestHeaders(this.options),
|
|
7709
|
-
...body !== undefined ? { body: JSON.stringify(body) } : {}
|
|
7710
|
-
});
|
|
7711
|
-
const responseBody = await parseResponse(response);
|
|
7712
|
-
if (!response.ok) {
|
|
7713
|
-
throw cloudRequestError(response, responseBody, action, url, this.options);
|
|
7714
|
-
}
|
|
7715
|
-
return responseBody;
|
|
7716
|
-
}
|
|
7717
|
-
url(path) {
|
|
7718
|
-
return new URL(`${apiBaseUrl(this.options.apiBaseUrl)}${path}`);
|
|
10586
|
+
const page = await this.client.conversations.messages.list(conversationId, query);
|
|
10587
|
+
return { messages: page.items };
|
|
7719
10588
|
}
|
|
7720
10589
|
}
|
|
7721
10590
|
|
|
@@ -7936,29 +10805,6 @@ function createCloudStatusTransportConstructor(options) {
|
|
|
7936
10805
|
}
|
|
7937
10806
|
|
|
7938
10807
|
// src/remote.ts
|
|
7939
|
-
function getDefaultApiKey2() {
|
|
7940
|
-
if (typeof process === "undefined") {
|
|
7941
|
-
return;
|
|
7942
|
-
}
|
|
7943
|
-
return process.env.LETTA_API_KEY;
|
|
7944
|
-
}
|
|
7945
|
-
function createHeaders(options) {
|
|
7946
|
-
const apiKey = options.apiKey ?? getDefaultApiKey2();
|
|
7947
|
-
return {
|
|
7948
|
-
...apiKey ? { Authorization: `Bearer ${apiKey}` } : {},
|
|
7949
|
-
...options.headers ?? {}
|
|
7950
|
-
};
|
|
7951
|
-
}
|
|
7952
|
-
function getFetch2(options) {
|
|
7953
|
-
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
7954
|
-
if (!fetchImpl) {
|
|
7955
|
-
throw new Error("Remote environments require a fetch implementation");
|
|
7956
|
-
}
|
|
7957
|
-
return fetchImpl.bind(globalThis);
|
|
7958
|
-
}
|
|
7959
|
-
function normalizeBaseUrl2(baseUrl) {
|
|
7960
|
-
return (baseUrl ?? "https://api.letta.com").replace(/\/$/, "");
|
|
7961
|
-
}
|
|
7962
10808
|
function ensureOnline(environment, target) {
|
|
7963
10809
|
if (!environment.connectionId) {
|
|
7964
10810
|
const label = "deviceId" in target ? target.deviceId : ("environmentId" in target) ? target.environmentId : ("connectionName" in target) ? target.connectionName : environment.deviceId;
|
|
@@ -7970,35 +10816,23 @@ function ensureOnline(environment, target) {
|
|
|
7970
10816
|
target
|
|
7971
10817
|
};
|
|
7972
10818
|
}
|
|
7973
|
-
async function parseJsonResponse2(response) {
|
|
7974
|
-
const text = await response.text();
|
|
7975
|
-
const body = text ? JSON.parse(text) : null;
|
|
7976
|
-
if (!response.ok) {
|
|
7977
|
-
const message = body && typeof body === "object" && "message" in body ? String(body.message) : response.statusText;
|
|
7978
|
-
throw new Error(`Letta API request failed (${response.status}): ${message}`);
|
|
7979
|
-
}
|
|
7980
|
-
return body;
|
|
7981
|
-
}
|
|
7982
10819
|
|
|
7983
10820
|
class RemoteEnvironmentClient {
|
|
7984
|
-
|
|
7985
|
-
|
|
7986
|
-
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
|
|
7990
|
-
|
|
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;
|
|
7991
10830
|
}
|
|
7992
10831
|
async listEnvironments() {
|
|
7993
|
-
|
|
7994
|
-
const response = await this.fetchImpl(url, {
|
|
7995
|
-
headers: createHeaders(this.options)
|
|
7996
|
-
});
|
|
7997
|
-
return parseJsonResponse2(response);
|
|
10832
|
+
return await this.client.environments.list();
|
|
7998
10833
|
}
|
|
7999
10834
|
async getEnvironmentByDeviceId(deviceId) {
|
|
8000
|
-
|
|
8001
|
-
return parseJsonResponse2(response);
|
|
10835
|
+
return await this.client.environments.retrieve(deviceId);
|
|
8002
10836
|
}
|
|
8003
10837
|
async resolveEnvironment(target) {
|
|
8004
10838
|
if ("connectionId" in target) {
|
|
@@ -8036,7 +10870,7 @@ var MAX_TTL_MINUTES = 60;
|
|
|
8036
10870
|
var MAX_GITHUB_REPOSITORIES = 10;
|
|
8037
10871
|
var GITHUB_OWNER_PATTERN = /^[A-Za-z0-9-]+$/;
|
|
8038
10872
|
var GITHUB_REPOSITORY_PATTERN = /^[A-Za-z0-9._-]+$/;
|
|
8039
|
-
function
|
|
10873
|
+
function validatePositiveInteger2(value, name) {
|
|
8040
10874
|
if (value !== undefined && (!Number.isInteger(value) || value <= 0)) {
|
|
8041
10875
|
throw new Error(`Invalid ${name}. Expected a positive integer.`);
|
|
8042
10876
|
}
|
|
@@ -8050,9 +10884,9 @@ function validateCloudSandboxOptions(options, name) {
|
|
|
8050
10884
|
if (options.ttlMinutes !== undefined && (!Number.isInteger(options.ttlMinutes) || options.ttlMinutes < MIN_TTL_MINUTES || options.ttlMinutes > MAX_TTL_MINUTES)) {
|
|
8051
10885
|
throw new Error(`Invalid ${name}.ttlMinutes. Expected an integer between ${MIN_TTL_MINUTES} and ${MAX_TTL_MINUTES}.`);
|
|
8052
10886
|
}
|
|
8053
|
-
|
|
8054
|
-
|
|
8055
|
-
|
|
10887
|
+
validatePositiveInteger2(options.readyTimeoutMs, `${name}.readyTimeoutMs`);
|
|
10888
|
+
validatePositiveInteger2(options.readyPollIntervalMs, `${name}.readyPollIntervalMs`);
|
|
10889
|
+
validatePositiveInteger2(options.refreshIntervalMs, `${name}.refreshIntervalMs`);
|
|
8056
10890
|
if (options.githubRepositories !== undefined) {
|
|
8057
10891
|
if (!Array.isArray(options.githubRepositories)) {
|
|
8058
10892
|
throw new Error(`Invalid ${name}.githubRepositories. Expected an array.`);
|
|
@@ -8078,7 +10912,6 @@ function validateCloudSandboxOptions(options, name) {
|
|
|
8078
10912
|
}
|
|
8079
10913
|
|
|
8080
10914
|
// src/cloud-session.ts
|
|
8081
|
-
var DEFAULT_CLOUD_API_BASE_URL3 = "https://api.letta.com";
|
|
8082
10915
|
var DEFAULT_TURN_TIMEOUT_MS = 120000;
|
|
8083
10916
|
var DEFAULT_PING_INTERVAL_MS = 30000;
|
|
8084
10917
|
var DEFAULT_SANDBOX_TTL_MINUTES = 5;
|
|
@@ -8102,27 +10935,6 @@ class CloudManagedSandboxExpiredError extends Error {
|
|
|
8102
10935
|
this.name = "CloudManagedSandboxExpiredError";
|
|
8103
10936
|
}
|
|
8104
10937
|
}
|
|
8105
|
-
function getDefaultApiKey3() {
|
|
8106
|
-
const env = globalThis.process?.env;
|
|
8107
|
-
return env?.LETTA_API_KEY ?? env?.LETTA_CLOUD_API_KEY;
|
|
8108
|
-
}
|
|
8109
|
-
function bearerTokenFromHeaders2(headers) {
|
|
8110
|
-
const authorization = headers?.Authorization ?? headers?.authorization;
|
|
8111
|
-
if (!authorization)
|
|
8112
|
-
return;
|
|
8113
|
-
const match = /^Bearer\s+(.+)$/i.exec(authorization);
|
|
8114
|
-
return match?.[1];
|
|
8115
|
-
}
|
|
8116
|
-
function getCloudApiKey2(options) {
|
|
8117
|
-
return options.apiKey ?? bearerTokenFromHeaders2(options.headers) ?? getDefaultApiKey3();
|
|
8118
|
-
}
|
|
8119
|
-
function getFetch3(fetchOverride) {
|
|
8120
|
-
const resolved = fetchOverride ?? globalThis.fetch;
|
|
8121
|
-
if (!resolved) {
|
|
8122
|
-
throw new Error("No fetch implementation available for cloud backend.");
|
|
8123
|
-
}
|
|
8124
|
-
return resolved.bind(globalThis);
|
|
8125
|
-
}
|
|
8126
10938
|
function getWebSocketConstructor(websocketOverride) {
|
|
8127
10939
|
const resolved = websocketOverride ?? globalThis.WebSocket;
|
|
8128
10940
|
if (!resolved) {
|
|
@@ -8130,75 +10942,25 @@ function getWebSocketConstructor(websocketOverride) {
|
|
|
8130
10942
|
}
|
|
8131
10943
|
return resolved;
|
|
8132
10944
|
}
|
|
8133
|
-
function normalizeCloudApiBaseUrl2(url) {
|
|
8134
|
-
const parsed = new URL(url ?? DEFAULT_CLOUD_API_BASE_URL3);
|
|
8135
|
-
parsed.pathname = parsed.pathname.replace(/\/+$/, "");
|
|
8136
|
-
parsed.search = "";
|
|
8137
|
-
parsed.hash = "";
|
|
8138
|
-
return parsed.toString().replace(/\/$/, "");
|
|
8139
|
-
}
|
|
8140
|
-
function cloudHeaders2(options) {
|
|
8141
|
-
const headers = {
|
|
8142
|
-
"Content-Type": "application/json",
|
|
8143
|
-
...options.headers ?? {}
|
|
8144
|
-
};
|
|
8145
|
-
const apiKey = getCloudApiKey2(options);
|
|
8146
|
-
if (apiKey && !headers.Authorization && !headers.authorization) {
|
|
8147
|
-
headers.Authorization = `Bearer ${apiKey}`;
|
|
8148
|
-
}
|
|
8149
|
-
return headers;
|
|
8150
|
-
}
|
|
8151
10945
|
function cloudWebSocketHeaders(options) {
|
|
8152
10946
|
const headers = { ...options.headers ?? {} };
|
|
8153
10947
|
delete headers.authorization;
|
|
8154
10948
|
delete headers.Authorization;
|
|
8155
|
-
const apiKey =
|
|
10949
|
+
const apiKey = getCloudApiKey(options);
|
|
8156
10950
|
if (apiKey)
|
|
8157
10951
|
headers.Authorization = `Bearer ${apiKey}`;
|
|
8158
10952
|
return Object.keys(headers).length > 0 ? headers : undefined;
|
|
8159
10953
|
}
|
|
8160
|
-
|
|
8161
|
-
|
|
8162
|
-
if (!text)
|
|
8163
|
-
return null;
|
|
8164
|
-
try {
|
|
8165
|
-
return JSON.parse(text);
|
|
8166
|
-
} catch {
|
|
8167
|
-
return text;
|
|
8168
|
-
}
|
|
8169
|
-
}
|
|
8170
|
-
function responseErrorMessage3(body, fallback) {
|
|
8171
|
-
if (body && typeof body === "object") {
|
|
8172
|
-
const record = body;
|
|
8173
|
-
const message = record.message ?? record.error ?? record.detail;
|
|
8174
|
-
const reasonText = record.reason_text;
|
|
8175
|
-
const pieces = [message, reasonText].filter((value) => typeof value === "string" && value.length > 0);
|
|
8176
|
-
if (pieces.length > 0)
|
|
8177
|
-
return pieces.join(": ");
|
|
8178
|
-
}
|
|
8179
|
-
return fallback;
|
|
8180
|
-
}
|
|
8181
|
-
function assertOkResponse2(response, body, action, url) {
|
|
8182
|
-
if (!response.ok) {
|
|
8183
|
-
const detail = responseErrorMessage3(body, `HTTP ${response.status}`);
|
|
8184
|
-
const parts = [`${action} failed`, detail];
|
|
8185
|
-
if (url)
|
|
8186
|
-
parts.push(`URL: ${url}`);
|
|
8187
|
-
if (response.status === 401 || response.status === 403) {
|
|
8188
|
-
const env = globalThis.process?.env;
|
|
8189
|
-
const hasKey = !!(env?.LETTA_API_KEY ?? env?.LETTA_CLOUD_API_KEY);
|
|
8190
|
-
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).");
|
|
8191
|
-
}
|
|
8192
|
-
throw new Error(parts.join(" — "));
|
|
8193
|
-
}
|
|
10954
|
+
function isNotFound2(error) {
|
|
10955
|
+
return error instanceof APIError && error.status === 404;
|
|
8194
10956
|
}
|
|
8195
|
-
function
|
|
10957
|
+
function validatePositiveInteger3(value, name) {
|
|
8196
10958
|
if (value !== undefined && (!Number.isInteger(value) || value <= 0)) {
|
|
8197
10959
|
throw new Error(`Invalid ${name}. Expected a positive integer.`);
|
|
8198
10960
|
}
|
|
8199
10961
|
}
|
|
8200
10962
|
function validateCloudClientOptions(options) {
|
|
8201
|
-
|
|
10963
|
+
validatePositiveInteger3(options.requestTimeoutMs, "requestTimeoutMs");
|
|
8202
10964
|
validateCloudSandboxOptions(options.sandbox, "sandbox");
|
|
8203
10965
|
if (options.environment !== undefined && options.sandbox !== undefined) {
|
|
8204
10966
|
throw new Error("Letta Cloud sessions cannot specify both environment and sandbox options.");
|
|
@@ -8226,7 +10988,7 @@ function environmentToRemoteTarget(environment) {
|
|
|
8226
10988
|
throw new Error("Unknown cloud environment selector.");
|
|
8227
10989
|
}
|
|
8228
10990
|
function buildCloudStatusWebSocketUrl(params) {
|
|
8229
|
-
const base = new URL(
|
|
10991
|
+
const base = new URL(normalizeCloudApiBaseUrl(params.apiBaseUrl));
|
|
8230
10992
|
if (base.protocol === "http:") {
|
|
8231
10993
|
base.protocol = "ws:";
|
|
8232
10994
|
} else if (base.protocol === "https:") {
|
|
@@ -8256,7 +11018,7 @@ function isRetryableManagedSandboxResolveError(error) {
|
|
|
8256
11018
|
const message = error instanceof Error ? error.message : String(error);
|
|
8257
11019
|
return message.includes("Remote environment is offline") || message.toLowerCase().includes("not found") || message.includes("(404)");
|
|
8258
11020
|
}
|
|
8259
|
-
function
|
|
11021
|
+
function sleep3(ms) {
|
|
8260
11022
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
8261
11023
|
}
|
|
8262
11024
|
function externalToolsByName(tools) {
|
|
@@ -8266,20 +11028,13 @@ function externalToolsByName(tools) {
|
|
|
8266
11028
|
}
|
|
8267
11029
|
return result;
|
|
8268
11030
|
}
|
|
8269
|
-
async function createCloudAgent(
|
|
11031
|
+
async function createCloudAgent(client, agentOptions) {
|
|
8270
11032
|
const body = await createAgentBody(agentOptions);
|
|
8271
|
-
const
|
|
8272
|
-
|
|
8273
|
-
headers: cloudHeaders2(clientOptions),
|
|
8274
|
-
body: JSON.stringify(body)
|
|
8275
|
-
});
|
|
8276
|
-
const responseBody = await parseJsonResponse3(response);
|
|
8277
|
-
assertOkResponse2(response, responseBody, "Cloud create agent");
|
|
8278
|
-
const agentId = responseBody && typeof responseBody === "object" ? responseBody.id : undefined;
|
|
8279
|
-
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) {
|
|
8280
11035
|
throw new Error("Cloud create agent response did not include an agent id.");
|
|
8281
11036
|
}
|
|
8282
|
-
return
|
|
11037
|
+
return agent.id;
|
|
8283
11038
|
}
|
|
8284
11039
|
function assertCloudSessionOptionsSupported(action, options) {
|
|
8285
11040
|
validateCloudSandboxOptions(options.sandbox, "sandbox");
|
|
@@ -8290,6 +11045,7 @@ function assertCloudSessionOptionsSupported(action, options) {
|
|
|
8290
11045
|
|
|
8291
11046
|
class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
8292
11047
|
cloudOptions;
|
|
11048
|
+
apiClient;
|
|
8293
11049
|
connectionId = null;
|
|
8294
11050
|
removeExternalToolHandler = null;
|
|
8295
11051
|
removeControlRequestHandler = null;
|
|
@@ -8300,14 +11056,17 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8300
11056
|
sandboxLifecycleClosing = false;
|
|
8301
11057
|
attachedRepositoryIds = new Set;
|
|
8302
11058
|
repositoryIdsRequiringCleanupRecompile = new Set;
|
|
11059
|
+
repositoryManagement;
|
|
8303
11060
|
cloudMode;
|
|
8304
|
-
constructor(cloudOptions, mode) {
|
|
11061
|
+
constructor(cloudOptions, mode, apiClient = createCloudClient(cloudOptions)) {
|
|
8305
11062
|
super(mode, {
|
|
8306
11063
|
label: "cloud",
|
|
8307
11064
|
requestTimeoutMs: cloudOptions.requestTimeoutMs ?? DEFAULT_TURN_TIMEOUT_MS
|
|
8308
11065
|
});
|
|
8309
11066
|
this.cloudOptions = cloudOptions;
|
|
11067
|
+
this.apiClient = apiClient;
|
|
8310
11068
|
this.cloudMode = mode;
|
|
11069
|
+
this.repositoryManagement = new CloudManagementTransport(apiClient);
|
|
8311
11070
|
const tools = mode.options.tools;
|
|
8312
11071
|
this.externalTools = externalToolsByName(tools);
|
|
8313
11072
|
}
|
|
@@ -8318,7 +11077,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8318
11077
|
throw error;
|
|
8319
11078
|
});
|
|
8320
11079
|
this.connectionId = connection.connectionId;
|
|
8321
|
-
const apiKey =
|
|
11080
|
+
const apiKey = getCloudApiKey(this.cloudOptions);
|
|
8322
11081
|
const url = buildCloudStatusWebSocketUrl({
|
|
8323
11082
|
apiBaseUrl: this.cloudOptions.apiBaseUrl,
|
|
8324
11083
|
connectionId: connection.connectionId,
|
|
@@ -8463,14 +11222,14 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8463
11222
|
const resources = this.repositoryResources();
|
|
8464
11223
|
if (resources.length === 0)
|
|
8465
11224
|
return false;
|
|
8466
|
-
const existing = await this.listAgentRepositories(agentId);
|
|
11225
|
+
const existing = await this.repositoryManagement.listAgentRepositories(agentId);
|
|
8467
11226
|
const existingIds = new Set(existing.map((repository) => repository.id));
|
|
8468
11227
|
try {
|
|
8469
11228
|
for (const resource of resources) {
|
|
8470
11229
|
if (existingIds.has(resource.repositoryId) || this.attachedRepositoryIds.has(resource.repositoryId)) {
|
|
8471
11230
|
continue;
|
|
8472
11231
|
}
|
|
8473
|
-
await this.
|
|
11232
|
+
await this.repositoryManagement.attachAgentRepository(agentId, resource.repositoryId, undefined);
|
|
8474
11233
|
await this.waitForAgentRepository(agentId, resource.repositoryId);
|
|
8475
11234
|
this.attachedRepositoryIds.add(resource.repositoryId);
|
|
8476
11235
|
}
|
|
@@ -8489,7 +11248,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8489
11248
|
this.repositoryIdsRequiringCleanupRecompile = new Set;
|
|
8490
11249
|
const recompileAfterDetach = await Promise.all(repositoryIds.map(async (repositoryId) => {
|
|
8491
11250
|
try {
|
|
8492
|
-
await this.
|
|
11251
|
+
await this.repositoryManagement.detachAgentRepository(agentId, repositoryId);
|
|
8493
11252
|
return repositoryIdsRequiringRecompile.has(repositoryId);
|
|
8494
11253
|
} catch {
|
|
8495
11254
|
return false;
|
|
@@ -8502,18 +11261,12 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8502
11261
|
}
|
|
8503
11262
|
}
|
|
8504
11263
|
async recompileSystemPrompt(agentId, conversationId) {
|
|
8505
|
-
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
8506
|
-
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
8507
11264
|
const usesAgentPrompt = !conversationId || conversationId === "default";
|
|
8508
|
-
|
|
8509
|
-
|
|
8510
|
-
|
|
8511
|
-
|
|
8512
|
-
|
|
8513
|
-
body: JSON.stringify(usesAgentPrompt ? {} : { agent_id: agentId })
|
|
8514
|
-
});
|
|
8515
|
-
const body = await parseJsonResponse3(response);
|
|
8516
|
-
assertOkResponse2(response, body, "Cloud recompile system prompt", url);
|
|
11265
|
+
if (usesAgentPrompt) {
|
|
11266
|
+
await this.repositoryManagement.recompileAgentSystemPrompt(agentId);
|
|
11267
|
+
return;
|
|
11268
|
+
}
|
|
11269
|
+
await this.repositoryManagement.recompileConversationSystemPrompt(agentId, conversationId);
|
|
8517
11270
|
}
|
|
8518
11271
|
repositoryResources() {
|
|
8519
11272
|
const resources = this.cloudMode.options.resources ?? [];
|
|
@@ -8533,76 +11286,33 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8533
11286
|
}
|
|
8534
11287
|
return result;
|
|
8535
11288
|
}
|
|
8536
|
-
async listAgentRepositories(agentId) {
|
|
8537
|
-
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
8538
|
-
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
8539
|
-
const response = await fetchImpl(`${baseUrl}/v1/agents/${encodeURIComponent(agentId)}/repositories`, { headers: cloudHeaders2(this.cloudOptions) });
|
|
8540
|
-
const body = await parseJsonResponse3(response);
|
|
8541
|
-
assertOkResponse2(response, body, "Cloud list agent repositories");
|
|
8542
|
-
if (!body || typeof body !== "object")
|
|
8543
|
-
return [];
|
|
8544
|
-
const repositories = body.repositories;
|
|
8545
|
-
return Array.isArray(repositories) ? repositories.filter((repository) => repository !== null && typeof repository === "object" && typeof repository.id === "string") : [];
|
|
8546
|
-
}
|
|
8547
11289
|
async waitForAgentRepository(agentId, repositoryId) {
|
|
8548
11290
|
const deadline = Date.now() + DEFAULT_REPOSITORY_ATTACH_TIMEOUT_MS;
|
|
8549
11291
|
while (true) {
|
|
8550
|
-
const repositories = await this.listAgentRepositories(agentId);
|
|
11292
|
+
const repositories = await this.repositoryManagement.listAgentRepositories(agentId);
|
|
8551
11293
|
if (repositories.some((repository) => repository.id === repositoryId))
|
|
8552
11294
|
return;
|
|
8553
11295
|
if (Date.now() >= deadline) {
|
|
8554
11296
|
throw new Error(`Cloud attach agent repository did not become visible for ${agentId}: ${repositoryId}`);
|
|
8555
11297
|
}
|
|
8556
|
-
await
|
|
11298
|
+
await sleep3(DEFAULT_REPOSITORY_ATTACH_POLL_INTERVAL_MS);
|
|
8557
11299
|
}
|
|
8558
11300
|
}
|
|
8559
|
-
async linkAgentRepository(agentId, repositoryId) {
|
|
8560
|
-
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
8561
|
-
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
8562
|
-
const response = await fetchImpl(`${baseUrl}/v1/agents/${encodeURIComponent(agentId)}/repositories`, {
|
|
8563
|
-
method: "POST",
|
|
8564
|
-
headers: cloudHeaders2(this.cloudOptions),
|
|
8565
|
-
body: JSON.stringify({ repository_id: repositoryId })
|
|
8566
|
-
});
|
|
8567
|
-
const body = await parseJsonResponse3(response);
|
|
8568
|
-
assertOkResponse2(response, body, "Cloud attach agent repository");
|
|
8569
|
-
}
|
|
8570
|
-
async unlinkAgentRepository(agentId, repositoryId) {
|
|
8571
|
-
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
8572
|
-
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
8573
|
-
const response = await fetchImpl(`${baseUrl}/v1/agents/${encodeURIComponent(agentId)}/repositories/${encodeURIComponent(repositoryId)}`, { method: "DELETE", headers: cloudHeaders2(this.cloudOptions) });
|
|
8574
|
-
const body = await parseJsonResponse3(response);
|
|
8575
|
-
if (response.status === 404)
|
|
8576
|
-
return;
|
|
8577
|
-
assertOkResponse2(response, body, "Cloud detach agent repository");
|
|
8578
|
-
}
|
|
8579
11301
|
async createConversation(agentId) {
|
|
8580
|
-
const
|
|
8581
|
-
|
|
8582
|
-
const url = new URL(`${baseUrl}/v1/conversations/`);
|
|
8583
|
-
url.searchParams.set("agent_id", agentId);
|
|
8584
|
-
const response = await fetchImpl(url, {
|
|
8585
|
-
method: "POST",
|
|
8586
|
-
headers: cloudHeaders2(this.cloudOptions),
|
|
8587
|
-
body: JSON.stringify({})
|
|
11302
|
+
const conversation = await this.apiClient.conversations.create({
|
|
11303
|
+
agent_id: agentId
|
|
8588
11304
|
});
|
|
8589
|
-
|
|
8590
|
-
assertOkResponse2(response, body, "Cloud createSession()", url.toString());
|
|
8591
|
-
if (!isCloudConversation(body)) {
|
|
11305
|
+
if (!isCloudConversation(conversation)) {
|
|
8592
11306
|
throw new Error("Cloud createSession() response did not include a conversation id.");
|
|
8593
11307
|
}
|
|
8594
|
-
return { id:
|
|
11308
|
+
return { id: conversation.id, agent_id: conversation.agent_id };
|
|
8595
11309
|
}
|
|
8596
11310
|
async retrieveConversation(conversationId) {
|
|
8597
|
-
const
|
|
8598
|
-
|
|
8599
|
-
const response = await fetchImpl(`${baseUrl}/v1/conversations/${encodeURIComponent(conversationId)}`, { headers: cloudHeaders2(this.cloudOptions) });
|
|
8600
|
-
const body = await parseJsonResponse3(response);
|
|
8601
|
-
assertOkResponse2(response, body, "Cloud resumeSession()", `${baseUrl}/v1/conversations/${encodeURIComponent(conversationId)}`);
|
|
8602
|
-
if (!isCloudConversation(body)) {
|
|
11311
|
+
const conversation = await this.apiClient.conversations.retrieve(conversationId);
|
|
11312
|
+
if (!isCloudConversation(conversation)) {
|
|
8603
11313
|
throw new Error(`Cloud resumeSession() could not retrieve conversation ${conversationId}.`);
|
|
8604
11314
|
}
|
|
8605
|
-
return { id:
|
|
11315
|
+
return { id: conversation.id, agent_id: conversation.agent_id };
|
|
8606
11316
|
}
|
|
8607
11317
|
async resolveConnectionForRuntime(runtime) {
|
|
8608
11318
|
const environment = this.effectiveEnvironment();
|
|
@@ -8639,20 +11349,14 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8639
11349
|
}
|
|
8640
11350
|
}
|
|
8641
11351
|
async createManagedSandbox(agentId, conversationId) {
|
|
8642
|
-
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
8643
|
-
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
8644
11352
|
const sandboxOptions = this.resolvedSandboxOptions();
|
|
8645
11353
|
const githubRepositories = sandboxOptions.githubRepositories;
|
|
8646
|
-
const
|
|
8647
|
-
|
|
8648
|
-
headers: cloudHeaders2(this.cloudOptions),
|
|
8649
|
-
body: JSON.stringify({
|
|
11354
|
+
const body = await this.apiClient.post(`/v1/agents/${encodeURIComponent(agentId)}/sandboxes`, {
|
|
11355
|
+
body: {
|
|
8650
11356
|
...conversationId ? { conversationId } : {},
|
|
8651
11357
|
...githubRepositories && githubRepositories.length > 0 ? { githubRepositories } : {}
|
|
8652
|
-
}
|
|
11358
|
+
}
|
|
8653
11359
|
});
|
|
8654
|
-
const body = await parseJsonResponse3(response);
|
|
8655
|
-
assertOkResponse2(response, body, "Cloud create managed sandbox", `${baseUrl}/v1/agents/${encodeURIComponent(agentId)}/sandboxes`);
|
|
8656
11360
|
if (!isCloudAgentSandbox(body)) {
|
|
8657
11361
|
throw new Error("Cloud create managed sandbox response did not include sandbox connection details.");
|
|
8658
11362
|
}
|
|
@@ -8690,32 +11394,23 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8690
11394
|
}
|
|
8691
11395
|
}
|
|
8692
11396
|
async refreshManagedSandboxOnce(sandbox) {
|
|
8693
|
-
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
8694
|
-
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
8695
11397
|
if (sandbox.conversationId) {
|
|
8696
|
-
|
|
8697
|
-
|
|
8698
|
-
|
|
8699
|
-
|
|
8700
|
-
|
|
8701
|
-
|
|
8702
|
-
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;
|
|
8703
11404
|
throw new CloudManagedSandboxExpiredError(sandbox.sandboxId, sandbox.conversationId);
|
|
8704
11405
|
}
|
|
8705
|
-
const body2 = await parseJsonResponse3(response2);
|
|
8706
|
-
assertOkResponse2(response2, body2, "Cloud refresh managed sandbox");
|
|
8707
11406
|
if (!isCloudAgentSandboxRefresh(body2) || !body2.success) {
|
|
8708
11407
|
throw new Error("Cloud refresh managed sandbox response did not confirm refresh.");
|
|
8709
11408
|
}
|
|
8710
11409
|
return;
|
|
8711
11410
|
}
|
|
8712
|
-
const
|
|
8713
|
-
|
|
8714
|
-
headers: cloudHeaders2(this.cloudOptions),
|
|
8715
|
-
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 }
|
|
8716
11413
|
});
|
|
8717
|
-
const body = await parseJsonResponse3(response);
|
|
8718
|
-
assertOkResponse2(response, body, "Cloud refresh managed sandbox", `${baseUrl}/v1/agents/${encodeURIComponent(sandbox.agentId)}/sandboxes/refresh`);
|
|
8719
11414
|
if (!isCloudAgentSandboxRefresh(body) || !body.success) {
|
|
8720
11415
|
throw new Error("Cloud refresh managed sandbox response did not confirm refresh.");
|
|
8721
11416
|
}
|
|
@@ -8724,29 +11419,22 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8724
11419
|
}
|
|
8725
11420
|
}
|
|
8726
11421
|
async terminateManagedSandbox(sandbox) {
|
|
8727
|
-
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
8728
|
-
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
8729
11422
|
if (sandbox.conversationId) {
|
|
8730
|
-
|
|
8731
|
-
|
|
8732
|
-
|
|
8733
|
-
|
|
8734
|
-
|
|
8735
|
-
|
|
8736
|
-
if (response2.status === 404)
|
|
8737
|
-
return;
|
|
8738
|
-
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
|
+
}
|
|
8739
11429
|
return;
|
|
8740
11430
|
}
|
|
8741
11431
|
await this.refreshManagedSandbox(sandbox);
|
|
8742
|
-
|
|
8743
|
-
|
|
8744
|
-
|
|
8745
|
-
|
|
8746
|
-
|
|
8747
|
-
|
|
8748
|
-
return;
|
|
8749
|
-
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
|
+
}
|
|
8750
11438
|
}
|
|
8751
11439
|
async waitForManagedSandboxConnection(sandbox) {
|
|
8752
11440
|
const deadline = Date.now() + sandbox.readyTimeoutMs;
|
|
@@ -8763,7 +11451,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8763
11451
|
break;
|
|
8764
11452
|
}
|
|
8765
11453
|
const remainingMs = Math.max(0, deadline - Date.now());
|
|
8766
|
-
await
|
|
11454
|
+
await sleep3(Math.min(sandbox.readyPollIntervalMs, remainingMs));
|
|
8767
11455
|
}
|
|
8768
11456
|
}
|
|
8769
11457
|
const detail = lastError instanceof Error ? lastError.message : String(lastError);
|
|
@@ -8801,12 +11489,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8801
11489
|
} catch {}
|
|
8802
11490
|
}
|
|
8803
11491
|
remoteEnvironmentClient() {
|
|
8804
|
-
return new RemoteEnvironmentClient({
|
|
8805
|
-
baseUrl: this.cloudOptions.apiBaseUrl,
|
|
8806
|
-
apiKey: getCloudApiKey2(this.cloudOptions),
|
|
8807
|
-
headers: this.cloudOptions.headers,
|
|
8808
|
-
fetch: this.cloudOptions.fetch
|
|
8809
|
-
});
|
|
11492
|
+
return new RemoteEnvironmentClient({}, this.apiClient);
|
|
8810
11493
|
}
|
|
8811
11494
|
effectiveEnvironment() {
|
|
8812
11495
|
const modeEnvironment = this.mode.kind === "session" ? this.mode.options.environment : undefined;
|
|
@@ -8822,16 +11505,13 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
8822
11505
|
}
|
|
8823
11506
|
|
|
8824
11507
|
// src/management.ts
|
|
8825
|
-
function
|
|
8826
|
-
return Object.fromEntries(Object.entries(values).filter(([, value]) => value !== undefined));
|
|
8827
|
-
}
|
|
8828
|
-
function assertNonEmptyId(value, name) {
|
|
11508
|
+
function assertNonEmptyId2(value, name) {
|
|
8829
11509
|
if (typeof value !== "string" || value.trim().length === 0) {
|
|
8830
11510
|
throw new Error(`Invalid ${name}. Expected a non-empty string.`);
|
|
8831
11511
|
}
|
|
8832
11512
|
}
|
|
8833
11513
|
function agentListQuery(options) {
|
|
8834
|
-
const orderBy = options.orderBy
|
|
11514
|
+
const orderBy = options.orderBy === "createdAt" ? "created_at" : options.orderBy === "lastRunCompletion" ? "last_run_completion" : undefined;
|
|
8835
11515
|
return {
|
|
8836
11516
|
before: options.before,
|
|
8837
11517
|
after: options.after,
|
|
@@ -8846,7 +11526,7 @@ function agentListQuery(options) {
|
|
|
8846
11526
|
};
|
|
8847
11527
|
}
|
|
8848
11528
|
function agentUpdateBody(options) {
|
|
8849
|
-
return
|
|
11529
|
+
return {
|
|
8850
11530
|
name: options.name,
|
|
8851
11531
|
description: options.description,
|
|
8852
11532
|
model: options.model,
|
|
@@ -8855,10 +11535,10 @@ function agentUpdateBody(options) {
|
|
|
8855
11535
|
tags: options.tags,
|
|
8856
11536
|
hidden: options.hidden,
|
|
8857
11537
|
context_window_limit: options.contextWindowLimit
|
|
8858
|
-
}
|
|
11538
|
+
};
|
|
8859
11539
|
}
|
|
8860
11540
|
function conversationListQuery(options) {
|
|
8861
|
-
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;
|
|
8862
11542
|
return {
|
|
8863
11543
|
agent_id: options.agentId,
|
|
8864
11544
|
after: options.after,
|
|
@@ -8870,7 +11550,7 @@ function conversationListQuery(options) {
|
|
|
8870
11550
|
};
|
|
8871
11551
|
}
|
|
8872
11552
|
function conversationCreateBody(options) {
|
|
8873
|
-
return
|
|
11553
|
+
return {
|
|
8874
11554
|
agent_id: options.agentId,
|
|
8875
11555
|
summary: options.summary,
|
|
8876
11556
|
description: options.description,
|
|
@@ -8878,17 +11558,17 @@ function conversationCreateBody(options) {
|
|
|
8878
11558
|
model_settings: options.modelSettings,
|
|
8879
11559
|
context_window_limit: options.contextWindowLimit,
|
|
8880
11560
|
hidden: options.hidden
|
|
8881
|
-
}
|
|
11561
|
+
};
|
|
8882
11562
|
}
|
|
8883
11563
|
function conversationUpdateBody(options) {
|
|
8884
|
-
return
|
|
11564
|
+
return {
|
|
8885
11565
|
summary: options.summary,
|
|
8886
11566
|
description: options.description,
|
|
8887
11567
|
model: options.model,
|
|
8888
11568
|
model_settings: options.modelSettings,
|
|
8889
11569
|
context_window_limit: options.contextWindowLimit,
|
|
8890
11570
|
archived: options.archived
|
|
8891
|
-
}
|
|
11571
|
+
};
|
|
8892
11572
|
}
|
|
8893
11573
|
function conversationMessagesQuery(options) {
|
|
8894
11574
|
return {
|
|
@@ -8898,13 +11578,16 @@ function conversationMessagesQuery(options) {
|
|
|
8898
11578
|
limit: options.limit
|
|
8899
11579
|
};
|
|
8900
11580
|
}
|
|
8901
|
-
function createAgentsClient(transport) {
|
|
11581
|
+
function createAgentsClient(transport, repositories) {
|
|
8902
11582
|
return {
|
|
11583
|
+
get repositories() {
|
|
11584
|
+
return repositories();
|
|
11585
|
+
},
|
|
8903
11586
|
list: (options = {}) => transport().listAgents(agentListQuery(options)),
|
|
8904
11587
|
retrieve: (agentId) => transport().retrieveAgent(agentId),
|
|
8905
11588
|
update: (agentId, options) => transport().updateAgent(agentId, agentUpdateBody(options)),
|
|
8906
11589
|
delete: async (agentId) => {
|
|
8907
|
-
|
|
11590
|
+
assertNonEmptyId2(agentId, "agent id");
|
|
8908
11591
|
await transport().deleteAgent(agentId);
|
|
8909
11592
|
}
|
|
8910
11593
|
};
|
|
@@ -9099,6 +11782,8 @@ class LettaAgentClientBase {
|
|
|
9099
11782
|
models;
|
|
9100
11783
|
options;
|
|
9101
11784
|
repositoriesClient = null;
|
|
11785
|
+
agentRepositoriesClient = null;
|
|
11786
|
+
cloudClient = null;
|
|
9102
11787
|
managementTransport = null;
|
|
9103
11788
|
constructor(options = {}) {
|
|
9104
11789
|
const backend = options.backend ?? "local";
|
|
@@ -9108,7 +11793,7 @@ class LettaAgentClientBase {
|
|
|
9108
11793
|
this.backend = backend;
|
|
9109
11794
|
this.environment = getOptionsEnvironment(options);
|
|
9110
11795
|
this.options = options;
|
|
9111
|
-
this.agents = createAgentsClient(() => this.getManagementTransport());
|
|
11796
|
+
this.agents = createAgentsClient(() => this.getManagementTransport(), () => this.getAgentRepositoriesClient());
|
|
9112
11797
|
this.conversations = createConversationsClient(() => this.getManagementTransport());
|
|
9113
11798
|
this.models = createModelsClient(() => this.getManagementTransport());
|
|
9114
11799
|
if (this.backend === "local" && this.environment !== undefined) {
|
|
@@ -9164,7 +11849,7 @@ class LettaAgentClientBase {
|
|
|
9164
11849
|
return initMsg.agentId;
|
|
9165
11850
|
}
|
|
9166
11851
|
if (this.backend === "cloud") {
|
|
9167
|
-
return createCloudAgent(this.
|
|
11852
|
+
return createCloudAgent(this.getCloudClient(), options);
|
|
9168
11853
|
}
|
|
9169
11854
|
return this.createLocalAgent(options);
|
|
9170
11855
|
}
|
|
@@ -9189,7 +11874,7 @@ class LettaAgentClientBase {
|
|
|
9189
11874
|
agentId,
|
|
9190
11875
|
newConversation: true,
|
|
9191
11876
|
options
|
|
9192
|
-
});
|
|
11877
|
+
}, this.getCloudClient());
|
|
9193
11878
|
}
|
|
9194
11879
|
return this.createLocalSession(agentId, options);
|
|
9195
11880
|
}
|
|
@@ -9218,14 +11903,14 @@ class LettaAgentClientBase {
|
|
|
9218
11903
|
kind: "session",
|
|
9219
11904
|
conversationId: id,
|
|
9220
11905
|
options
|
|
9221
|
-
});
|
|
11906
|
+
}, this.getCloudClient());
|
|
9222
11907
|
}
|
|
9223
11908
|
return new CloudEnvironmentSession(this.cloudOptions(), {
|
|
9224
11909
|
kind: "session",
|
|
9225
11910
|
agentId: id,
|
|
9226
11911
|
defaultConversation: true,
|
|
9227
11912
|
options
|
|
9228
|
-
});
|
|
11913
|
+
}, this.getCloudClient());
|
|
9229
11914
|
}
|
|
9230
11915
|
return this.resumeLocalSession(id, options);
|
|
9231
11916
|
}
|
|
@@ -9319,16 +12004,37 @@ class LettaAgentClientBase {
|
|
|
9319
12004
|
if (this.backend !== "cloud") {
|
|
9320
12005
|
throw new Error('client.repositories is only available with backend: "cloud".');
|
|
9321
12006
|
}
|
|
9322
|
-
this.repositoriesClient ??= new RepositoriesClient(this.cloudOptions());
|
|
12007
|
+
this.repositoriesClient ??= new RepositoriesClient(this.cloudOptions(), this.getCloudClient());
|
|
9323
12008
|
return this.repositoriesClient;
|
|
9324
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
|
+
}
|
|
9325
12031
|
getManagementTransport() {
|
|
9326
12032
|
if (this.managementTransport)
|
|
9327
12033
|
return this.managementTransport;
|
|
9328
12034
|
if (this.backend === "remote") {
|
|
9329
12035
|
this.managementTransport = new AppServerManagementTransport(this.remoteOptions());
|
|
9330
12036
|
} else if (this.backend === "cloud") {
|
|
9331
|
-
this.managementTransport = new CloudManagementTransport(this.
|
|
12037
|
+
this.managementTransport = new CloudManagementTransport(this.getCloudClient());
|
|
9332
12038
|
} else {
|
|
9333
12039
|
this.managementTransport = this.createLocalManagementTransport();
|
|
9334
12040
|
}
|
|
@@ -9429,4 +12135,4 @@ export {
|
|
|
9429
12135
|
CloudManagedSandboxExpiredError
|
|
9430
12136
|
};
|
|
9431
12137
|
|
|
9432
|
-
//# debugId=
|
|
12138
|
+
//# debugId=DC9188A459F6634B64756E2164756E21
|