@letta-ai/letta-agent-sdk 0.2.4 → 0.2.5
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/README.md +31 -0
- package/dist/client.d.ts +4 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/cloud-session.d.ts +8 -0
- package/dist/cloud-session.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +426 -62
- package/dist/index.js.map +7 -6
- package/dist/repositories.d.ts +32 -0
- package/dist/repositories.d.ts.map +1 -0
- package/dist/types.d.ts +79 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1354,6 +1354,249 @@ ${stderr}` : "";
|
|
|
1354
1354
|
}
|
|
1355
1355
|
}
|
|
1356
1356
|
|
|
1357
|
+
// src/repositories.ts
|
|
1358
|
+
var DEFAULT_CLOUD_API_BASE_URL = "https://api.letta.com";
|
|
1359
|
+
function getDefaultApiKey() {
|
|
1360
|
+
const env = globalThis.process?.env;
|
|
1361
|
+
return env?.LETTA_API_KEY ?? env?.LETTA_CLOUD_API_KEY;
|
|
1362
|
+
}
|
|
1363
|
+
function bearerTokenFromHeaders(headers) {
|
|
1364
|
+
const authorization = headers?.Authorization ?? headers?.authorization;
|
|
1365
|
+
if (!authorization)
|
|
1366
|
+
return;
|
|
1367
|
+
const match = /^Bearer\s+(.+)$/i.exec(authorization);
|
|
1368
|
+
return match?.[1];
|
|
1369
|
+
}
|
|
1370
|
+
function getCloudApiKey(options) {
|
|
1371
|
+
return options.apiKey ?? bearerTokenFromHeaders(options.headers) ?? getDefaultApiKey();
|
|
1372
|
+
}
|
|
1373
|
+
function getFetch(fetchOverride) {
|
|
1374
|
+
const resolved = fetchOverride ?? globalThis.fetch;
|
|
1375
|
+
if (!resolved)
|
|
1376
|
+
throw new Error("No fetch implementation available for cloud backend.");
|
|
1377
|
+
return resolved.bind(globalThis);
|
|
1378
|
+
}
|
|
1379
|
+
function normalizeCloudApiBaseUrl(url) {
|
|
1380
|
+
const parsed = new URL(url ?? DEFAULT_CLOUD_API_BASE_URL);
|
|
1381
|
+
parsed.pathname = parsed.pathname.replace(/\/+$/, "");
|
|
1382
|
+
parsed.search = "";
|
|
1383
|
+
parsed.hash = "";
|
|
1384
|
+
return parsed.toString().replace(/\/$/, "");
|
|
1385
|
+
}
|
|
1386
|
+
function cloudHeaders(options) {
|
|
1387
|
+
const headers = {
|
|
1388
|
+
"Content-Type": "application/json",
|
|
1389
|
+
...options.headers ?? {}
|
|
1390
|
+
};
|
|
1391
|
+
const apiKey = getCloudApiKey(options);
|
|
1392
|
+
if (apiKey && !headers.Authorization && !headers.authorization) {
|
|
1393
|
+
headers.Authorization = `Bearer ${apiKey}`;
|
|
1394
|
+
}
|
|
1395
|
+
return headers;
|
|
1396
|
+
}
|
|
1397
|
+
async function parseJsonResponse(response) {
|
|
1398
|
+
const text = await response.text();
|
|
1399
|
+
if (!text)
|
|
1400
|
+
return null;
|
|
1401
|
+
try {
|
|
1402
|
+
return JSON.parse(text);
|
|
1403
|
+
} catch {
|
|
1404
|
+
return text;
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
function responseErrorMessage(body, fallback) {
|
|
1408
|
+
if (body && typeof body === "object") {
|
|
1409
|
+
const record = body;
|
|
1410
|
+
const message = record.message ?? record.error ?? record.detail;
|
|
1411
|
+
const reasonText = record.reason_text;
|
|
1412
|
+
const pieces = [message, reasonText].filter((value) => typeof value === "string" && value.length > 0);
|
|
1413
|
+
if (pieces.length > 0)
|
|
1414
|
+
return pieces.join(": ");
|
|
1415
|
+
}
|
|
1416
|
+
return fallback;
|
|
1417
|
+
}
|
|
1418
|
+
function assertOkResponse(response, body, action) {
|
|
1419
|
+
if (!response.ok) {
|
|
1420
|
+
throw new Error(responseErrorMessage(body, `${action} failed with HTTP ${response.status}`));
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
function optionalString(value) {
|
|
1424
|
+
return typeof value === "string" ? value : undefined;
|
|
1425
|
+
}
|
|
1426
|
+
function requireString(value, name) {
|
|
1427
|
+
if (typeof value !== "string")
|
|
1428
|
+
throw new Error(`Cloud repositories response missing ${name}.`);
|
|
1429
|
+
return value;
|
|
1430
|
+
}
|
|
1431
|
+
function toRepository(body) {
|
|
1432
|
+
if (!body || typeof body !== "object") {
|
|
1433
|
+
throw new Error("Cloud repositories response did not include a repository.");
|
|
1434
|
+
}
|
|
1435
|
+
const record = body;
|
|
1436
|
+
return {
|
|
1437
|
+
id: requireString(record.id, "id"),
|
|
1438
|
+
name: requireString(record.name, "name"),
|
|
1439
|
+
createdAt: requireString(record.created_at, "created_at"),
|
|
1440
|
+
updatedAt: requireString(record.updated_at, "updated_at")
|
|
1441
|
+
};
|
|
1442
|
+
}
|
|
1443
|
+
function toFileMutation(body) {
|
|
1444
|
+
if (!body || typeof body !== "object") {
|
|
1445
|
+
throw new Error("Cloud repositories file response did not include file details.");
|
|
1446
|
+
}
|
|
1447
|
+
const record = body;
|
|
1448
|
+
return {
|
|
1449
|
+
path: requireString(record.path, "path"),
|
|
1450
|
+
contentSha256: requireString(record.content_sha256, "content_sha256"),
|
|
1451
|
+
commitSha: requireString(record.commit_sha, "commit_sha")
|
|
1452
|
+
};
|
|
1453
|
+
}
|
|
1454
|
+
function addOptionalSearchParam(url, key, value) {
|
|
1455
|
+
if (value !== undefined)
|
|
1456
|
+
url.searchParams.set(key, String(value));
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
class RepositoriesClient {
|
|
1460
|
+
options;
|
|
1461
|
+
constructor(options) {
|
|
1462
|
+
this.options = options;
|
|
1463
|
+
}
|
|
1464
|
+
async create(params) {
|
|
1465
|
+
return toRepository(await this.request("/v1/repositories", "POST", { name: params.name }, "Cloud create repository"));
|
|
1466
|
+
}
|
|
1467
|
+
async list(params = {}) {
|
|
1468
|
+
const url = this.url("/v1/repositories");
|
|
1469
|
+
addOptionalSearchParam(url, "limit", params.limit);
|
|
1470
|
+
addOptionalSearchParam(url, "offset", params.offset);
|
|
1471
|
+
const body = await this.requestUrl(url, "GET", undefined, "Cloud list repositories");
|
|
1472
|
+
if (!body || typeof body !== "object") {
|
|
1473
|
+
throw new Error("Cloud list repositories response did not include repositories.");
|
|
1474
|
+
}
|
|
1475
|
+
const record = body;
|
|
1476
|
+
const repositories = Array.isArray(record.repositories) ? record.repositories.map(toRepository) : [];
|
|
1477
|
+
return {
|
|
1478
|
+
repositories,
|
|
1479
|
+
hasNextPage: record.has_next_page === true
|
|
1480
|
+
};
|
|
1481
|
+
}
|
|
1482
|
+
async get(repositoryId) {
|
|
1483
|
+
return toRepository(await this.request(`/v1/repositories/${encodeURIComponent(repositoryId)}`, "GET", undefined, "Cloud get repository"));
|
|
1484
|
+
}
|
|
1485
|
+
async delete(repositoryId) {
|
|
1486
|
+
await this.request(`/v1/repositories/${encodeURIComponent(repositoryId)}`, "DELETE", undefined, "Cloud delete repository");
|
|
1487
|
+
}
|
|
1488
|
+
files = {
|
|
1489
|
+
list: async (repositoryId, params = {}) => {
|
|
1490
|
+
const url = this.url(`/v1/repositories/${encodeURIComponent(repositoryId)}/files`);
|
|
1491
|
+
addOptionalSearchParam(url, "path_prefix", params.pathPrefix);
|
|
1492
|
+
addOptionalSearchParam(url, "depth", params.depth);
|
|
1493
|
+
addOptionalSearchParam(url, "ref", params.ref);
|
|
1494
|
+
const body = await this.requestUrl(url, "GET", undefined, "Cloud list repository files");
|
|
1495
|
+
if (!body || typeof body !== "object") {
|
|
1496
|
+
throw new Error("Cloud list repository files response did not include files.");
|
|
1497
|
+
}
|
|
1498
|
+
const record = body;
|
|
1499
|
+
const files = Array.isArray(record.files) ? record.files.map((entry) => {
|
|
1500
|
+
if (!entry || typeof entry !== "object") {
|
|
1501
|
+
throw new Error("Cloud list repository files response included an invalid file entry.");
|
|
1502
|
+
}
|
|
1503
|
+
const file = entry;
|
|
1504
|
+
const type = file.type;
|
|
1505
|
+
if (type !== "file" && type !== "directory") {
|
|
1506
|
+
throw new Error("Cloud list repository files response included an invalid file type.");
|
|
1507
|
+
}
|
|
1508
|
+
return { path: requireString(file.path, "path"), type };
|
|
1509
|
+
}) : [];
|
|
1510
|
+
return { files, ref: requireString(record.ref, "ref") };
|
|
1511
|
+
},
|
|
1512
|
+
create: async (repositoryId, params) => toFileMutation(await this.request(`/v1/repositories/${encodeURIComponent(repositoryId)}/files`, "POST", { path: params.path, content: params.content }, "Cloud create repository file")),
|
|
1513
|
+
read: async (repositoryId, params) => {
|
|
1514
|
+
const url = this.url(`/v1/repositories/${encodeURIComponent(repositoryId)}/files/content`);
|
|
1515
|
+
url.searchParams.set("path", params.path);
|
|
1516
|
+
addOptionalSearchParam(url, "ref", params.ref);
|
|
1517
|
+
const body = await this.requestUrl(url, "GET", undefined, "Cloud read repository file");
|
|
1518
|
+
if (!body || typeof body !== "object") {
|
|
1519
|
+
throw new Error("Cloud read repository file response did not include file content.");
|
|
1520
|
+
}
|
|
1521
|
+
const record = body;
|
|
1522
|
+
return {
|
|
1523
|
+
path: requireString(record.path, "path"),
|
|
1524
|
+
content: requireString(record.content, "content"),
|
|
1525
|
+
contentSha256: requireString(record.content_sha256, "content_sha256"),
|
|
1526
|
+
ref: optionalString(record.ref)
|
|
1527
|
+
};
|
|
1528
|
+
},
|
|
1529
|
+
update: async (repositoryId, params) => toFileMutation(await this.request(`/v1/repositories/${encodeURIComponent(repositoryId)}/files/content`, "POST", {
|
|
1530
|
+
path: params.path,
|
|
1531
|
+
...params.content !== undefined ? { content: params.content } : {},
|
|
1532
|
+
...params.newPath !== undefined ? { new_path: params.newPath } : {},
|
|
1533
|
+
...params.precondition !== undefined ? {
|
|
1534
|
+
precondition: {
|
|
1535
|
+
type: "content_sha256",
|
|
1536
|
+
content_sha256: params.precondition.contentSha256
|
|
1537
|
+
}
|
|
1538
|
+
} : {}
|
|
1539
|
+
}, "Cloud update repository file")),
|
|
1540
|
+
delete: async (repositoryId, params) => {
|
|
1541
|
+
const body = await this.request(`/v1/repositories/${encodeURIComponent(repositoryId)}/files/content`, "DELETE", { path: params.path }, "Cloud delete repository file");
|
|
1542
|
+
if (!body || typeof body !== "object") {
|
|
1543
|
+
throw new Error("Cloud delete repository file response did not include delete details.");
|
|
1544
|
+
}
|
|
1545
|
+
const record = body;
|
|
1546
|
+
return { success: record.success === true, commitSha: requireString(record.commit_sha, "commit_sha") };
|
|
1547
|
+
}
|
|
1548
|
+
};
|
|
1549
|
+
versions = {
|
|
1550
|
+
list: async (repositoryId, params = {}) => {
|
|
1551
|
+
const url = this.url(`/v1/repositories/${encodeURIComponent(repositoryId)}/versions`);
|
|
1552
|
+
addOptionalSearchParam(url, "path", params.path);
|
|
1553
|
+
addOptionalSearchParam(url, "limit", params.limit);
|
|
1554
|
+
const body = await this.requestUrl(url, "GET", undefined, "Cloud list repository versions");
|
|
1555
|
+
if (Array.isArray(body))
|
|
1556
|
+
return body;
|
|
1557
|
+
if (body && typeof body === "object") {
|
|
1558
|
+
const record = body;
|
|
1559
|
+
if (Array.isArray(record.commits))
|
|
1560
|
+
return record.commits;
|
|
1561
|
+
if (Array.isArray(record.versions))
|
|
1562
|
+
return record.versions;
|
|
1563
|
+
}
|
|
1564
|
+
return [];
|
|
1565
|
+
},
|
|
1566
|
+
get: async (repositoryId, sha, params) => {
|
|
1567
|
+
const url = this.url(`/v1/repositories/${encodeURIComponent(repositoryId)}/versions/${encodeURIComponent(sha)}`);
|
|
1568
|
+
url.searchParams.set("path", params.path);
|
|
1569
|
+
const body = await this.requestUrl(url, "GET", undefined, "Cloud get repository version");
|
|
1570
|
+
if (!body || typeof body !== "object") {
|
|
1571
|
+
throw new Error("Cloud get repository version response did not include file content.");
|
|
1572
|
+
}
|
|
1573
|
+
const record = body;
|
|
1574
|
+
return {
|
|
1575
|
+
path: requireString(record.path, "path"),
|
|
1576
|
+
content: requireString(record.content, "content"),
|
|
1577
|
+
contentSha256: requireString(record.content_sha256, "content_sha256"),
|
|
1578
|
+
ref: requireString(record.sha, "sha")
|
|
1579
|
+
};
|
|
1580
|
+
}
|
|
1581
|
+
};
|
|
1582
|
+
url(path) {
|
|
1583
|
+
return new URL(`${normalizeCloudApiBaseUrl(this.options.apiBaseUrl)}${path}`);
|
|
1584
|
+
}
|
|
1585
|
+
async request(path, method, body, action) {
|
|
1586
|
+
return this.requestUrl(this.url(path), method, body, action);
|
|
1587
|
+
}
|
|
1588
|
+
async requestUrl(url, method, body, action) {
|
|
1589
|
+
const response = await getFetch(this.options.fetch)(url, {
|
|
1590
|
+
method,
|
|
1591
|
+
headers: cloudHeaders(this.options),
|
|
1592
|
+
...body !== undefined ? { body: JSON.stringify(body) } : {}
|
|
1593
|
+
});
|
|
1594
|
+
const parsed = await parseJsonResponse(response);
|
|
1595
|
+
assertOkResponse(response, parsed, action);
|
|
1596
|
+
return parsed;
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1357
1600
|
// node_modules/@letta-ai/letta-code/dist/app-server-client.js
|
|
1358
1601
|
var DEFAULT_REQUEST_TIMEOUT_MS = 30000;
|
|
1359
1602
|
var WEBSOCKET_OPEN_STATE = 1;
|
|
@@ -3479,20 +3722,20 @@ class AppServerSession extends RemoteClientSessionCore {
|
|
|
3479
3722
|
}
|
|
3480
3723
|
|
|
3481
3724
|
// src/remote.ts
|
|
3482
|
-
function
|
|
3725
|
+
function getDefaultApiKey2() {
|
|
3483
3726
|
if (typeof process === "undefined") {
|
|
3484
3727
|
return;
|
|
3485
3728
|
}
|
|
3486
3729
|
return process.env.LETTA_API_KEY;
|
|
3487
3730
|
}
|
|
3488
3731
|
function createHeaders(options) {
|
|
3489
|
-
const apiKey = options.apiKey ??
|
|
3732
|
+
const apiKey = options.apiKey ?? getDefaultApiKey2();
|
|
3490
3733
|
return {
|
|
3491
3734
|
...apiKey ? { Authorization: `Bearer ${apiKey}` } : {},
|
|
3492
3735
|
...options.headers ?? {}
|
|
3493
3736
|
};
|
|
3494
3737
|
}
|
|
3495
|
-
function
|
|
3738
|
+
function getFetch2(options) {
|
|
3496
3739
|
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
3497
3740
|
if (!fetchImpl) {
|
|
3498
3741
|
throw new Error("Remote environments require a fetch implementation");
|
|
@@ -3513,7 +3756,7 @@ function ensureOnline(environment, target) {
|
|
|
3513
3756
|
target
|
|
3514
3757
|
};
|
|
3515
3758
|
}
|
|
3516
|
-
async function
|
|
3759
|
+
async function parseJsonResponse2(response) {
|
|
3517
3760
|
const text = await response.text();
|
|
3518
3761
|
const body = text ? JSON.parse(text) : null;
|
|
3519
3762
|
if (!response.ok) {
|
|
@@ -3530,18 +3773,18 @@ class RemoteEnvironmentClient {
|
|
|
3530
3773
|
constructor(options = {}) {
|
|
3531
3774
|
this.options = options;
|
|
3532
3775
|
this.baseUrl = normalizeBaseUrl2(options.baseUrl);
|
|
3533
|
-
this.fetchImpl =
|
|
3776
|
+
this.fetchImpl = getFetch2(options);
|
|
3534
3777
|
}
|
|
3535
3778
|
async listEnvironments() {
|
|
3536
3779
|
const url = new URL(`${this.baseUrl}/v1/environments`);
|
|
3537
3780
|
const response = await this.fetchImpl(url, {
|
|
3538
3781
|
headers: createHeaders(this.options)
|
|
3539
3782
|
});
|
|
3540
|
-
return
|
|
3783
|
+
return parseJsonResponse2(response);
|
|
3541
3784
|
}
|
|
3542
3785
|
async getEnvironmentByDeviceId(deviceId) {
|
|
3543
3786
|
const response = await this.fetchImpl(`${this.baseUrl}/v1/environments/${encodeURIComponent(deviceId)}`, { headers: createHeaders(this.options) });
|
|
3544
|
-
return
|
|
3787
|
+
return parseJsonResponse2(response);
|
|
3545
3788
|
}
|
|
3546
3789
|
async resolveEnvironment(target) {
|
|
3547
3790
|
if ("connectionId" in target) {
|
|
@@ -3574,7 +3817,7 @@ class RemoteEnvironmentClient {
|
|
|
3574
3817
|
}
|
|
3575
3818
|
|
|
3576
3819
|
// src/cloud-session.ts
|
|
3577
|
-
var
|
|
3820
|
+
var DEFAULT_CLOUD_API_BASE_URL2 = "https://api.letta.com";
|
|
3578
3821
|
var DEFAULT_TURN_TIMEOUT_MS = 120000;
|
|
3579
3822
|
var DEFAULT_PING_INTERVAL_MS = 30000;
|
|
3580
3823
|
var DEFAULT_SANDBOX_TTL_MINUTES = 5;
|
|
@@ -3582,25 +3825,27 @@ var MIN_SANDBOX_TTL_MINUTES = 1;
|
|
|
3582
3825
|
var MAX_SANDBOX_TTL_MINUTES = 60;
|
|
3583
3826
|
var DEFAULT_SANDBOX_READY_TIMEOUT_MS = 120000;
|
|
3584
3827
|
var DEFAULT_SANDBOX_READY_POLL_INTERVAL_MS = 1000;
|
|
3828
|
+
var DEFAULT_REPOSITORY_ATTACH_TIMEOUT_MS = 1e4;
|
|
3829
|
+
var DEFAULT_REPOSITORY_ATTACH_POLL_INTERVAL_MS = 250;
|
|
3585
3830
|
var SDK_AGENT_ORIGIN = "@letta-ai/letta-agent-sdk";
|
|
3586
3831
|
|
|
3587
3832
|
class CloudManagedSandboxOwnershipError extends Error {
|
|
3588
3833
|
}
|
|
3589
|
-
function
|
|
3834
|
+
function getDefaultApiKey3() {
|
|
3590
3835
|
const env = globalThis.process?.env;
|
|
3591
3836
|
return env?.LETTA_API_KEY ?? env?.LETTA_CLOUD_API_KEY;
|
|
3592
3837
|
}
|
|
3593
|
-
function
|
|
3838
|
+
function bearerTokenFromHeaders2(headers) {
|
|
3594
3839
|
const authorization = headers?.Authorization ?? headers?.authorization;
|
|
3595
3840
|
if (!authorization)
|
|
3596
3841
|
return;
|
|
3597
3842
|
const match = /^Bearer\s+(.+)$/i.exec(authorization);
|
|
3598
3843
|
return match?.[1];
|
|
3599
3844
|
}
|
|
3600
|
-
function
|
|
3601
|
-
return options.apiKey ??
|
|
3845
|
+
function getCloudApiKey2(options) {
|
|
3846
|
+
return options.apiKey ?? bearerTokenFromHeaders2(options.headers) ?? getDefaultApiKey3();
|
|
3602
3847
|
}
|
|
3603
|
-
function
|
|
3848
|
+
function getFetch3(fetchOverride) {
|
|
3604
3849
|
const resolved = fetchOverride ?? globalThis.fetch;
|
|
3605
3850
|
if (!resolved) {
|
|
3606
3851
|
throw new Error("No fetch implementation available for cloud backend.");
|
|
@@ -3614,19 +3859,19 @@ function getWebSocketConstructor(websocketOverride) {
|
|
|
3614
3859
|
}
|
|
3615
3860
|
return resolved;
|
|
3616
3861
|
}
|
|
3617
|
-
function
|
|
3618
|
-
const parsed = new URL(url ??
|
|
3862
|
+
function normalizeCloudApiBaseUrl2(url) {
|
|
3863
|
+
const parsed = new URL(url ?? DEFAULT_CLOUD_API_BASE_URL2);
|
|
3619
3864
|
parsed.pathname = parsed.pathname.replace(/\/+$/, "");
|
|
3620
3865
|
parsed.search = "";
|
|
3621
3866
|
parsed.hash = "";
|
|
3622
3867
|
return parsed.toString().replace(/\/$/, "");
|
|
3623
3868
|
}
|
|
3624
|
-
function
|
|
3869
|
+
function cloudHeaders2(options) {
|
|
3625
3870
|
const headers = {
|
|
3626
3871
|
"Content-Type": "application/json",
|
|
3627
3872
|
...options.headers ?? {}
|
|
3628
3873
|
};
|
|
3629
|
-
const apiKey =
|
|
3874
|
+
const apiKey = getCloudApiKey2(options);
|
|
3630
3875
|
if (apiKey && !headers.Authorization && !headers.authorization) {
|
|
3631
3876
|
headers.Authorization = `Bearer ${apiKey}`;
|
|
3632
3877
|
}
|
|
@@ -3636,12 +3881,12 @@ function cloudWebSocketHeaders(options) {
|
|
|
3636
3881
|
const headers = { ...options.headers ?? {} };
|
|
3637
3882
|
delete headers.authorization;
|
|
3638
3883
|
delete headers.Authorization;
|
|
3639
|
-
const apiKey =
|
|
3884
|
+
const apiKey = getCloudApiKey2(options);
|
|
3640
3885
|
if (apiKey)
|
|
3641
3886
|
headers.Authorization = `Bearer ${apiKey}`;
|
|
3642
3887
|
return Object.keys(headers).length > 0 ? headers : undefined;
|
|
3643
3888
|
}
|
|
3644
|
-
async function
|
|
3889
|
+
async function parseJsonResponse3(response) {
|
|
3645
3890
|
const text = await response.text();
|
|
3646
3891
|
if (!text)
|
|
3647
3892
|
return null;
|
|
@@ -3651,7 +3896,7 @@ async function parseJsonResponse2(response) {
|
|
|
3651
3896
|
return text;
|
|
3652
3897
|
}
|
|
3653
3898
|
}
|
|
3654
|
-
function
|
|
3899
|
+
function responseErrorMessage2(body, fallback) {
|
|
3655
3900
|
if (body && typeof body === "object") {
|
|
3656
3901
|
const record = body;
|
|
3657
3902
|
const message = record.message ?? record.error ?? record.detail;
|
|
@@ -3662,9 +3907,9 @@ function responseErrorMessage(body, fallback) {
|
|
|
3662
3907
|
}
|
|
3663
3908
|
return fallback;
|
|
3664
3909
|
}
|
|
3665
|
-
function
|
|
3910
|
+
function assertOkResponse2(response, body, action) {
|
|
3666
3911
|
if (!response.ok) {
|
|
3667
|
-
throw new Error(
|
|
3912
|
+
throw new Error(responseErrorMessage2(body, `${action} failed with HTTP ${response.status}`));
|
|
3668
3913
|
}
|
|
3669
3914
|
}
|
|
3670
3915
|
function validatePositiveInteger(value, name) {
|
|
@@ -3724,7 +3969,7 @@ function environmentToRemoteTarget(environment) {
|
|
|
3724
3969
|
throw new Error("Unknown cloud environment selector.");
|
|
3725
3970
|
}
|
|
3726
3971
|
function buildCloudStatusWebSocketUrl(params) {
|
|
3727
|
-
const base = new URL(
|
|
3972
|
+
const base = new URL(normalizeCloudApiBaseUrl2(params.apiBaseUrl));
|
|
3728
3973
|
if (base.protocol === "http:") {
|
|
3729
3974
|
base.protocol = "ws:";
|
|
3730
3975
|
} else if (base.protocol === "https:") {
|
|
@@ -3771,7 +4016,7 @@ function messageEventData(event) {
|
|
|
3771
4016
|
function createCloudStatusWebSocketConstructor(params) {
|
|
3772
4017
|
const WebSocketCtor = getWebSocketConstructor(params.cloudOptions.WebSocket);
|
|
3773
4018
|
const authMode = params.cloudOptions.webSocketAuth ?? "header";
|
|
3774
|
-
const
|
|
4019
|
+
const cloudHeaders3 = authMode === "header" ? cloudWebSocketHeaders(params.cloudOptions) : undefined;
|
|
3775
4020
|
const pingIntervalMs = params.cloudOptions.pingIntervalMs ?? DEFAULT_PING_INTERVAL_MS;
|
|
3776
4021
|
const state = {
|
|
3777
4022
|
runtime: params.runtime,
|
|
@@ -3791,7 +4036,7 @@ function createCloudStatusWebSocketConstructor(params) {
|
|
|
3791
4036
|
this.channel = new URL(url).searchParams.get("channel");
|
|
3792
4037
|
const mergedHeaders = authMode === "header" ? {
|
|
3793
4038
|
...options?.headers ?? {},
|
|
3794
|
-
...
|
|
4039
|
+
...cloudHeaders3 ?? {}
|
|
3795
4040
|
} : undefined;
|
|
3796
4041
|
const socketOptions = mergedHeaders && Object.keys(mergedHeaders).length > 0 ? { headers: mergedHeaders } : undefined;
|
|
3797
4042
|
this.socket = new WebSocketCtor(url, socketOptions);
|
|
@@ -3951,10 +4196,10 @@ function externalToolsByName(tools) {
|
|
|
3951
4196
|
}
|
|
3952
4197
|
function cloudHarnessAppServerOptions(clientOptions) {
|
|
3953
4198
|
const appServer = clientOptions.appServer;
|
|
3954
|
-
const apiKey =
|
|
4199
|
+
const apiKey = getCloudApiKey2(clientOptions);
|
|
3955
4200
|
const localEnv = {
|
|
3956
4201
|
...apiKey ? { LETTA_API_KEY: apiKey } : {},
|
|
3957
|
-
...clientOptions.apiBaseUrl ? { LETTA_BASE_URL:
|
|
4202
|
+
...clientOptions.apiBaseUrl ? { LETTA_BASE_URL: normalizeCloudApiBaseUrl2(clientOptions.apiBaseUrl) } : {}
|
|
3958
4203
|
};
|
|
3959
4204
|
return {
|
|
3960
4205
|
local: appServer?.url === undefined,
|
|
@@ -4013,6 +4258,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
4013
4258
|
managedSandbox = null;
|
|
4014
4259
|
sandboxRefreshTimer = null;
|
|
4015
4260
|
sandboxRefreshInFlight = null;
|
|
4261
|
+
attachedRepositoryIds = new Set;
|
|
4016
4262
|
cloudMode;
|
|
4017
4263
|
constructor(cloudOptions, mode) {
|
|
4018
4264
|
super(mode, {
|
|
@@ -4028,7 +4274,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
4028
4274
|
const resolved = await this.resolveRuntime();
|
|
4029
4275
|
const connection = await this.resolveConnectionForRuntime(resolved.runtime);
|
|
4030
4276
|
this.connectionId = connection.connectionId;
|
|
4031
|
-
const apiKey =
|
|
4277
|
+
const apiKey = getCloudApiKey2(this.cloudOptions);
|
|
4032
4278
|
const url = buildCloudStatusWebSocketUrl({
|
|
4033
4279
|
apiBaseUrl: this.cloudOptions.apiBaseUrl,
|
|
4034
4280
|
connectionId: connection.connectionId,
|
|
@@ -4076,6 +4322,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
4076
4322
|
this.removeControlRequestHandler = null;
|
|
4077
4323
|
client.close();
|
|
4078
4324
|
await this.cleanupManagedSandbox();
|
|
4325
|
+
await this.cleanupSessionRepositories(resolved.runtime.agent_id);
|
|
4079
4326
|
throw error;
|
|
4080
4327
|
}
|
|
4081
4328
|
}
|
|
@@ -4123,16 +4370,12 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
4123
4370
|
this.removeControlRequestHandler?.();
|
|
4124
4371
|
this.removeControlRequestHandler = null;
|
|
4125
4372
|
this.cleanupManagedSandbox();
|
|
4373
|
+
if (this.runtime?.agent_id)
|
|
4374
|
+
this.cleanupSessionRepositories(this.runtime.agent_id);
|
|
4126
4375
|
}
|
|
4127
4376
|
async resolveRuntime() {
|
|
4128
4377
|
let agentId = this.cloudMode.agentId;
|
|
4129
4378
|
let conversationId = this.cloudMode.conversationId;
|
|
4130
|
-
if (agentId && this.cloudMode.newConversation) {
|
|
4131
|
-
const conversation = await this.createConversation(agentId);
|
|
4132
|
-
conversationId = conversation.id;
|
|
4133
|
-
} else if (agentId && this.cloudMode.defaultConversation) {
|
|
4134
|
-
conversationId = "default";
|
|
4135
|
-
}
|
|
4136
4379
|
if (!agentId && conversationId) {
|
|
4137
4380
|
const conversation = await this.retrieveConversation(conversationId);
|
|
4138
4381
|
if (!conversation.agent_id) {
|
|
@@ -4140,34 +4383,134 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
4140
4383
|
}
|
|
4141
4384
|
agentId = conversation.agent_id;
|
|
4142
4385
|
}
|
|
4143
|
-
if (!agentId
|
|
4386
|
+
if (!agentId) {
|
|
4387
|
+
throw new Error("Constellation createSession()/resumeSession() requires an agent id or conversation id.");
|
|
4388
|
+
}
|
|
4389
|
+
await this.attachSessionRepositories(agentId);
|
|
4390
|
+
if (this.cloudMode.newConversation) {
|
|
4391
|
+
const conversation = await this.createConversation(agentId);
|
|
4392
|
+
conversationId = conversation.id;
|
|
4393
|
+
} else if (this.cloudMode.defaultConversation) {
|
|
4394
|
+
conversationId = "default";
|
|
4395
|
+
}
|
|
4396
|
+
if (!conversationId) {
|
|
4144
4397
|
throw new Error("Constellation createSession()/resumeSession() requires an agent id or conversation id.");
|
|
4145
4398
|
}
|
|
4146
4399
|
return { runtime: { agent_id: agentId, conversation_id: conversationId } };
|
|
4147
4400
|
}
|
|
4401
|
+
async attachSessionRepositories(agentId) {
|
|
4402
|
+
const resources = this.repositoryResources();
|
|
4403
|
+
if (resources.length === 0)
|
|
4404
|
+
return;
|
|
4405
|
+
const existing = await this.listAgentRepositories(agentId);
|
|
4406
|
+
const existingIds = new Set(existing.map((repository) => repository.id));
|
|
4407
|
+
try {
|
|
4408
|
+
for (const resource of resources) {
|
|
4409
|
+
if (existingIds.has(resource.repositoryId) || this.attachedRepositoryIds.has(resource.repositoryId)) {
|
|
4410
|
+
continue;
|
|
4411
|
+
}
|
|
4412
|
+
await this.linkAgentRepository(agentId, resource.repositoryId);
|
|
4413
|
+
await this.waitForAgentRepository(agentId, resource.repositoryId);
|
|
4414
|
+
this.attachedRepositoryIds.add(resource.repositoryId);
|
|
4415
|
+
}
|
|
4416
|
+
} catch (error) {
|
|
4417
|
+
await this.cleanupSessionRepositories(agentId);
|
|
4418
|
+
throw error;
|
|
4419
|
+
}
|
|
4420
|
+
}
|
|
4421
|
+
async cleanupSessionRepositories(agentId) {
|
|
4422
|
+
const repositoryIds = [...this.attachedRepositoryIds];
|
|
4423
|
+
this.attachedRepositoryIds.clear();
|
|
4424
|
+
await Promise.all(repositoryIds.map(async (repositoryId) => {
|
|
4425
|
+
try {
|
|
4426
|
+
await this.unlinkAgentRepository(agentId, repositoryId);
|
|
4427
|
+
} catch {}
|
|
4428
|
+
}));
|
|
4429
|
+
}
|
|
4430
|
+
repositoryResources() {
|
|
4431
|
+
const resources = this.cloudMode.options.resources ?? [];
|
|
4432
|
+
const seen = new Set;
|
|
4433
|
+
const result = [];
|
|
4434
|
+
for (const resource of resources) {
|
|
4435
|
+
if (resource.type !== "repository") {
|
|
4436
|
+
throw new Error(`Unsupported Cloud session resource type: ${String(resource.type)}`);
|
|
4437
|
+
}
|
|
4438
|
+
if (typeof resource.repositoryId !== "string" || resource.repositoryId.length === 0) {
|
|
4439
|
+
throw new Error("Cloud session repository resources require repositoryId.");
|
|
4440
|
+
}
|
|
4441
|
+
if (seen.has(resource.repositoryId))
|
|
4442
|
+
continue;
|
|
4443
|
+
seen.add(resource.repositoryId);
|
|
4444
|
+
result.push(resource);
|
|
4445
|
+
}
|
|
4446
|
+
return result;
|
|
4447
|
+
}
|
|
4448
|
+
async listAgentRepositories(agentId) {
|
|
4449
|
+
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
4450
|
+
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
4451
|
+
const response = await fetchImpl(`${baseUrl}/v1/agents/${encodeURIComponent(agentId)}/repositories`, { headers: cloudHeaders2(this.cloudOptions) });
|
|
4452
|
+
const body = await parseJsonResponse3(response);
|
|
4453
|
+
assertOkResponse2(response, body, "Cloud list agent repositories");
|
|
4454
|
+
if (!body || typeof body !== "object")
|
|
4455
|
+
return [];
|
|
4456
|
+
const repositories = body.repositories;
|
|
4457
|
+
return Array.isArray(repositories) ? repositories.filter((repository) => repository !== null && typeof repository === "object" && typeof repository.id === "string") : [];
|
|
4458
|
+
}
|
|
4459
|
+
async waitForAgentRepository(agentId, repositoryId) {
|
|
4460
|
+
const deadline = Date.now() + DEFAULT_REPOSITORY_ATTACH_TIMEOUT_MS;
|
|
4461
|
+
while (true) {
|
|
4462
|
+
const repositories = await this.listAgentRepositories(agentId);
|
|
4463
|
+
if (repositories.some((repository) => repository.id === repositoryId))
|
|
4464
|
+
return;
|
|
4465
|
+
if (Date.now() >= deadline) {
|
|
4466
|
+
throw new Error(`Cloud attach agent repository did not become visible for ${agentId}: ${repositoryId}`);
|
|
4467
|
+
}
|
|
4468
|
+
await sleep(DEFAULT_REPOSITORY_ATTACH_POLL_INTERVAL_MS);
|
|
4469
|
+
}
|
|
4470
|
+
}
|
|
4471
|
+
async linkAgentRepository(agentId, repositoryId) {
|
|
4472
|
+
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
4473
|
+
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
4474
|
+
const response = await fetchImpl(`${baseUrl}/v1/agents/${encodeURIComponent(agentId)}/repositories`, {
|
|
4475
|
+
method: "POST",
|
|
4476
|
+
headers: cloudHeaders2(this.cloudOptions),
|
|
4477
|
+
body: JSON.stringify({ repository_id: repositoryId })
|
|
4478
|
+
});
|
|
4479
|
+
const body = await parseJsonResponse3(response);
|
|
4480
|
+
assertOkResponse2(response, body, "Cloud attach agent repository");
|
|
4481
|
+
}
|
|
4482
|
+
async unlinkAgentRepository(agentId, repositoryId) {
|
|
4483
|
+
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
4484
|
+
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
4485
|
+
const response = await fetchImpl(`${baseUrl}/v1/agents/${encodeURIComponent(agentId)}/repositories/${encodeURIComponent(repositoryId)}`, { method: "DELETE", headers: cloudHeaders2(this.cloudOptions) });
|
|
4486
|
+
const body = await parseJsonResponse3(response);
|
|
4487
|
+
if (response.status === 404)
|
|
4488
|
+
return;
|
|
4489
|
+
assertOkResponse2(response, body, "Cloud detach agent repository");
|
|
4490
|
+
}
|
|
4148
4491
|
async createConversation(agentId) {
|
|
4149
|
-
const fetchImpl =
|
|
4150
|
-
const baseUrl =
|
|
4492
|
+
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
4493
|
+
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
4151
4494
|
const url = new URL(`${baseUrl}/v1/conversations/`);
|
|
4152
4495
|
url.searchParams.set("agent_id", agentId);
|
|
4153
4496
|
const response = await fetchImpl(url, {
|
|
4154
4497
|
method: "POST",
|
|
4155
|
-
headers:
|
|
4498
|
+
headers: cloudHeaders2(this.cloudOptions),
|
|
4156
4499
|
body: JSON.stringify({})
|
|
4157
4500
|
});
|
|
4158
|
-
const body = await
|
|
4159
|
-
|
|
4501
|
+
const body = await parseJsonResponse3(response);
|
|
4502
|
+
assertOkResponse2(response, body, "Cloud createSession()");
|
|
4160
4503
|
if (!isCloudConversation(body)) {
|
|
4161
4504
|
throw new Error("Cloud createSession() response did not include a conversation id.");
|
|
4162
4505
|
}
|
|
4163
4506
|
return { id: body.id, agent_id: body.agent_id };
|
|
4164
4507
|
}
|
|
4165
4508
|
async retrieveConversation(conversationId) {
|
|
4166
|
-
const fetchImpl =
|
|
4167
|
-
const baseUrl =
|
|
4168
|
-
const response = await fetchImpl(`${baseUrl}/v1/conversations/${encodeURIComponent(conversationId)}`, { headers:
|
|
4169
|
-
const body = await
|
|
4170
|
-
|
|
4509
|
+
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
4510
|
+
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
4511
|
+
const response = await fetchImpl(`${baseUrl}/v1/conversations/${encodeURIComponent(conversationId)}`, { headers: cloudHeaders2(this.cloudOptions) });
|
|
4512
|
+
const body = await parseJsonResponse3(response);
|
|
4513
|
+
assertOkResponse2(response, body, "Cloud resumeSession()");
|
|
4171
4514
|
if (!isCloudConversation(body)) {
|
|
4172
4515
|
throw new Error(`Cloud resumeSession() could not retrieve conversation ${conversationId}.`);
|
|
4173
4516
|
}
|
|
@@ -4203,15 +4546,15 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
4203
4546
|
}
|
|
4204
4547
|
}
|
|
4205
4548
|
async createManagedSandbox(agentId) {
|
|
4206
|
-
const fetchImpl =
|
|
4207
|
-
const baseUrl =
|
|
4549
|
+
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
4550
|
+
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
4208
4551
|
const response = await fetchImpl(`${baseUrl}/v1/agents/${encodeURIComponent(agentId)}/sandboxes`, {
|
|
4209
4552
|
method: "POST",
|
|
4210
|
-
headers:
|
|
4553
|
+
headers: cloudHeaders2(this.cloudOptions),
|
|
4211
4554
|
body: JSON.stringify({})
|
|
4212
4555
|
});
|
|
4213
|
-
const body = await
|
|
4214
|
-
|
|
4556
|
+
const body = await parseJsonResponse3(response);
|
|
4557
|
+
assertOkResponse2(response, body, "Cloud create managed sandbox");
|
|
4215
4558
|
if (!isCloudAgentSandbox(body)) {
|
|
4216
4559
|
throw new Error("Cloud create managed sandbox response did not include sandbox connection details.");
|
|
4217
4560
|
}
|
|
@@ -4245,15 +4588,15 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
4245
4588
|
}
|
|
4246
4589
|
}
|
|
4247
4590
|
async refreshManagedSandboxOnce(sandbox) {
|
|
4248
|
-
const fetchImpl =
|
|
4249
|
-
const baseUrl =
|
|
4591
|
+
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
4592
|
+
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
4250
4593
|
const response = await fetchImpl(`${baseUrl}/v1/agents/${encodeURIComponent(sandbox.agentId)}/sandboxes/refresh`, {
|
|
4251
4594
|
method: "POST",
|
|
4252
|
-
headers:
|
|
4595
|
+
headers: cloudHeaders2(this.cloudOptions),
|
|
4253
4596
|
body: JSON.stringify({ ttlMinutes: sandbox.ttlMinutes })
|
|
4254
4597
|
});
|
|
4255
|
-
const body = await
|
|
4256
|
-
|
|
4598
|
+
const body = await parseJsonResponse3(response);
|
|
4599
|
+
assertOkResponse2(response, body, "Cloud refresh managed sandbox");
|
|
4257
4600
|
if (!isCloudAgentSandboxRefresh(body) || !body.success) {
|
|
4258
4601
|
throw new Error("Cloud refresh managed sandbox response did not confirm refresh.");
|
|
4259
4602
|
}
|
|
@@ -4263,16 +4606,16 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
4263
4606
|
}
|
|
4264
4607
|
async terminateManagedSandbox(sandbox) {
|
|
4265
4608
|
await this.refreshManagedSandbox(sandbox);
|
|
4266
|
-
const fetchImpl =
|
|
4267
|
-
const baseUrl =
|
|
4609
|
+
const fetchImpl = getFetch3(this.cloudOptions.fetch);
|
|
4610
|
+
const baseUrl = normalizeCloudApiBaseUrl2(this.cloudOptions.apiBaseUrl);
|
|
4268
4611
|
const response = await fetchImpl(`${baseUrl}/v1/agents/${encodeURIComponent(sandbox.agentId)}/sandboxes`, {
|
|
4269
4612
|
method: "DELETE",
|
|
4270
|
-
headers:
|
|
4613
|
+
headers: cloudHeaders2(this.cloudOptions)
|
|
4271
4614
|
});
|
|
4272
|
-
const body = await
|
|
4615
|
+
const body = await parseJsonResponse3(response);
|
|
4273
4616
|
if (response.status === 404)
|
|
4274
4617
|
return;
|
|
4275
|
-
|
|
4618
|
+
assertOkResponse2(response, body, "Cloud terminate managed sandbox");
|
|
4276
4619
|
}
|
|
4277
4620
|
async waitForManagedSandboxConnection(sandbox) {
|
|
4278
4621
|
const deadline = Date.now() + sandbox.readyTimeoutMs;
|
|
@@ -4325,7 +4668,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
4325
4668
|
remoteEnvironmentClient() {
|
|
4326
4669
|
return new RemoteEnvironmentClient({
|
|
4327
4670
|
baseUrl: this.cloudOptions.apiBaseUrl,
|
|
4328
|
-
apiKey:
|
|
4671
|
+
apiKey: getCloudApiKey2(this.cloudOptions),
|
|
4329
4672
|
headers: this.cloudOptions.headers,
|
|
4330
4673
|
fetch: this.cloudOptions.fetch
|
|
4331
4674
|
});
|
|
@@ -4486,6 +4829,9 @@ function stripCloudExecutionOptions(options) {
|
|
|
4486
4829
|
delete sessionOptions.sandbox;
|
|
4487
4830
|
return sessionOptions;
|
|
4488
4831
|
}
|
|
4832
|
+
function hasRepositoryResources(options) {
|
|
4833
|
+
return options.resources !== undefined && options.resources.length > 0;
|
|
4834
|
+
}
|
|
4489
4835
|
function hasCreateAgentEnvironment(options) {
|
|
4490
4836
|
return "environment" in options;
|
|
4491
4837
|
}
|
|
@@ -4500,6 +4846,7 @@ class LettaAgentClient {
|
|
|
4500
4846
|
backend;
|
|
4501
4847
|
environment;
|
|
4502
4848
|
options;
|
|
4849
|
+
repositoriesClient = null;
|
|
4503
4850
|
constructor(options = {}) {
|
|
4504
4851
|
const backend = options.backend ?? "local";
|
|
4505
4852
|
if (!isLettaCodeBackend(backend)) {
|
|
@@ -4543,6 +4890,9 @@ class LettaAgentClient {
|
|
|
4543
4890
|
validateCloudClientOptions(options);
|
|
4544
4891
|
}
|
|
4545
4892
|
}
|
|
4893
|
+
get repositories() {
|
|
4894
|
+
return this.getRepositoriesClient();
|
|
4895
|
+
}
|
|
4546
4896
|
async createAgent(options = {}) {
|
|
4547
4897
|
if (hasCreateAgentEnvironment(options)) {
|
|
4548
4898
|
throw new Error("createAgent() does not accept environment. Set a client default or pass environment to resumeSession()/createSession().");
|
|
@@ -4700,6 +5050,9 @@ class LettaAgentClient {
|
|
|
4700
5050
|
if (options.sandbox !== undefined) {
|
|
4701
5051
|
throw new Error(`${action}() sandbox options are only valid with backend: "cloud".`);
|
|
4702
5052
|
}
|
|
5053
|
+
if (hasRepositoryResources(options)) {
|
|
5054
|
+
throw new Error(`${action}() repository resources are only valid with backend: "cloud".`);
|
|
5055
|
+
}
|
|
4703
5056
|
if (!this.useLegacyLocalStdio()) {
|
|
4704
5057
|
assertRemoteSessionOptionsSupported(action, options);
|
|
4705
5058
|
}
|
|
@@ -4712,6 +5065,9 @@ class LettaAgentClient {
|
|
|
4712
5065
|
if (options.sandbox !== undefined) {
|
|
4713
5066
|
throw new Error(`${action}() sandbox options are only valid with backend: "cloud"; remote url selects the app-server runtime.`);
|
|
4714
5067
|
}
|
|
5068
|
+
if (hasRepositoryResources(options)) {
|
|
5069
|
+
throw new Error(`${action}() repository resources are only valid with backend: "cloud".`);
|
|
5070
|
+
}
|
|
4715
5071
|
assertRemoteSessionOptionsSupported(action, options);
|
|
4716
5072
|
return;
|
|
4717
5073
|
}
|
|
@@ -4750,6 +5106,13 @@ class LettaAgentClient {
|
|
|
4750
5106
|
}
|
|
4751
5107
|
return this.options;
|
|
4752
5108
|
}
|
|
5109
|
+
getRepositoriesClient() {
|
|
5110
|
+
if (this.backend !== "cloud") {
|
|
5111
|
+
throw new Error('client.repositories is only available with backend: "cloud".');
|
|
5112
|
+
}
|
|
5113
|
+
this.repositoriesClient ??= new RepositoriesClient(this.cloudOptions());
|
|
5114
|
+
return this.repositoriesClient;
|
|
5115
|
+
}
|
|
4753
5116
|
cloudOptions() {
|
|
4754
5117
|
if (this.backend !== "cloud") {
|
|
4755
5118
|
throw new Error('Constellation options requested for non-"cloud" backend.');
|
|
@@ -4995,7 +5358,8 @@ export {
|
|
|
4995
5358
|
createSession,
|
|
4996
5359
|
createAgent,
|
|
4997
5360
|
Session,
|
|
5361
|
+
RepositoriesClient,
|
|
4998
5362
|
LettaAgentClient
|
|
4999
5363
|
};
|
|
5000
5364
|
|
|
5001
|
-
//# debugId=
|
|
5365
|
+
//# debugId=7B3400A69740F48F64756E2164756E21
|