@letta-ai/letta-code 0.31.9 → 0.31.11
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 +1 -1
- package/dist/mcp-client.js +2 -2
- package/dist/mcp-client.js.map +1 -1
- package/dist/types/agent/skills.d.ts.map +1 -1
- package/dist/types/backend/api/client.d.ts +0 -5
- package/dist/types/backend/api/client.d.ts.map +1 -1
- package/dist/types/backend/api/metadata.d.ts +2 -0
- package/dist/types/backend/api/metadata.d.ts.map +1 -1
- package/dist/types/backend/api/server-url.d.ts +11 -0
- package/dist/types/backend/api/server-url.d.ts.map +1 -0
- package/dist/types/backend/backend.d.ts +7 -1
- package/dist/types/backend/backend.d.ts.map +1 -1
- package/dist/types/backend/dev/fake-headless-backend.d.ts +3 -11
- package/dist/types/backend/dev/fake-headless-backend.d.ts.map +1 -1
- package/dist/types/backend/dev/headless-backend.d.ts +1 -1
- package/dist/types/backend/dev/headless-backend.d.ts.map +1 -1
- package/dist/types/backend/local/local-backend.d.ts.map +1 -1
- package/dist/types/reminders/state.d.ts +4 -0
- package/dist/types/reminders/state.d.ts.map +1 -1
- package/dist/types/tools/impl/task.d.ts.map +1 -1
- package/dist/types/tools/memory-tool-assets.d.ts.map +1 -1
- package/dist/types/tools/task-tool-assets.d.ts +14 -0
- package/dist/types/tools/task-tool-assets.d.ts.map +1 -0
- package/letta.js +1118 -1083
- package/package.json +1 -1
- package/scripts/source-file-size-baseline.json +2 -3
- package/skills/submitting-feedback/SKILL.md +13 -3
- package/skills/using-mcp-tools/SKILL.md +44 -0
- package/skills/using-cloud-mcp/SKILL.md +0 -37
package/letta.js
CHANGED
|
@@ -3757,29 +3757,6 @@ var init_oauth = __esm(() => {
|
|
|
3757
3757
|
};
|
|
3758
3758
|
});
|
|
3759
3759
|
|
|
3760
|
-
// src/auth/oauth-refresh.ts
|
|
3761
|
-
async function refreshAccessTokenSingleFlight(refreshToken2, deviceId, deviceName, refresh = refreshAccessToken2) {
|
|
3762
|
-
const refreshKey = `${refreshToken2}\x00${deviceId}`;
|
|
3763
|
-
const existing = inFlightRefreshes.get(refreshKey);
|
|
3764
|
-
if (existing) {
|
|
3765
|
-
return await existing;
|
|
3766
|
-
}
|
|
3767
|
-
const pending = refresh(refreshToken2, deviceId, deviceName);
|
|
3768
|
-
inFlightRefreshes.set(refreshKey, pending);
|
|
3769
|
-
try {
|
|
3770
|
-
return await pending;
|
|
3771
|
-
} finally {
|
|
3772
|
-
if (inFlightRefreshes.get(refreshKey) === pending) {
|
|
3773
|
-
inFlightRefreshes.delete(refreshKey);
|
|
3774
|
-
}
|
|
3775
|
-
}
|
|
3776
|
-
}
|
|
3777
|
-
var inFlightRefreshes;
|
|
3778
|
-
var init_oauth_refresh = __esm(() => {
|
|
3779
|
-
init_oauth();
|
|
3780
|
-
inFlightRefreshes = new Map;
|
|
3781
|
-
});
|
|
3782
|
-
|
|
3783
3760
|
// src/agent/agent-id.ts
|
|
3784
3761
|
function isLocalAgentId(agentId) {
|
|
3785
3762
|
return agentId.startsWith("agent-local-");
|
|
@@ -5418,98 +5395,12 @@ var init_settings_manager = __esm(() => {
|
|
|
5418
5395
|
settingsManager = globalThis.__lettaSettingsManager;
|
|
5419
5396
|
});
|
|
5420
5397
|
|
|
5421
|
-
// src/utils/timing.ts
|
|
5422
|
-
function isTimingsEnabled() {
|
|
5423
|
-
const val = process.env.LETTA_DEBUG_TIMINGS;
|
|
5424
|
-
return val === "1" || val === "true";
|
|
5425
|
-
}
|
|
5426
|
-
function formatDuration(ms) {
|
|
5427
|
-
if (ms < 1000)
|
|
5428
|
-
return `${Math.round(ms)}ms`;
|
|
5429
|
-
return `${(ms / 1000).toFixed(2)}s`;
|
|
5430
|
-
}
|
|
5431
|
-
function formatTimestamp(date) {
|
|
5432
|
-
return date.toISOString().slice(11, 23);
|
|
5433
|
-
}
|
|
5434
|
-
function logTiming(message) {
|
|
5435
|
-
if (isTimingsEnabled()) {
|
|
5436
|
-
console.error(`[timing] ${message}`);
|
|
5437
|
-
}
|
|
5438
|
-
}
|
|
5439
|
-
function markMilestone(name) {
|
|
5440
|
-
const now = performance.now();
|
|
5441
|
-
milestones.set(name, now);
|
|
5442
|
-
if (firstMilestoneTime === null) {
|
|
5443
|
-
firstMilestoneTime = now;
|
|
5444
|
-
}
|
|
5445
|
-
if (isTimingsEnabled()) {
|
|
5446
|
-
const relative = now - firstMilestoneTime;
|
|
5447
|
-
console.error(`[timing] MILESTONE ${name} at +${formatDuration(relative)} (${formatTimestamp(new Date)})`);
|
|
5448
|
-
}
|
|
5449
|
-
}
|
|
5450
|
-
function measureSinceMilestone(label, fromMilestone) {
|
|
5451
|
-
if (!isTimingsEnabled())
|
|
5452
|
-
return;
|
|
5453
|
-
const startTime = milestones.get(fromMilestone);
|
|
5454
|
-
if (startTime === undefined) {
|
|
5455
|
-
console.error(`[timing] WARNING: milestone "${fromMilestone}" not found for measurement "${label}"`);
|
|
5456
|
-
return;
|
|
5457
|
-
}
|
|
5458
|
-
const duration = performance.now() - startTime;
|
|
5459
|
-
console.error(`[timing] ${label}: ${formatDuration(duration)}`);
|
|
5460
|
-
}
|
|
5461
|
-
function reportAllMilestones() {
|
|
5462
|
-
if (!isTimingsEnabled() || milestones.size === 0)
|
|
5463
|
-
return;
|
|
5464
|
-
const first = firstMilestoneTime ?? 0;
|
|
5465
|
-
console.error(`[timing] ======== MILESTONE SUMMARY ========`);
|
|
5466
|
-
const sorted = [...milestones.entries()].sort((a, b) => a[1] - b[1]);
|
|
5467
|
-
let prevTime = first;
|
|
5468
|
-
for (const [name, time] of sorted) {
|
|
5469
|
-
const relativeToStart = time - first;
|
|
5470
|
-
const delta = time - prevTime;
|
|
5471
|
-
const deltaStr = prevTime === first ? "" : ` (+${formatDuration(delta)})`;
|
|
5472
|
-
console.error(`[timing] +${formatDuration(relativeToStart).padStart(8)} ${name}${deltaStr}`);
|
|
5473
|
-
prevTime = time;
|
|
5474
|
-
}
|
|
5475
|
-
console.error(`[timing] =====================================`);
|
|
5476
|
-
}
|
|
5477
|
-
function createTimingFetch(baseFetch) {
|
|
5478
|
-
return async (input, init) => {
|
|
5479
|
-
const start = performance.now();
|
|
5480
|
-
const startTime = formatTimestamp(new Date);
|
|
5481
|
-
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
5482
|
-
const method = init?.method || "GET";
|
|
5483
|
-
let path2;
|
|
5484
|
-
try {
|
|
5485
|
-
path2 = new URL(url).pathname;
|
|
5486
|
-
} catch {
|
|
5487
|
-
path2 = url;
|
|
5488
|
-
}
|
|
5489
|
-
logTiming(`${method} ${path2} started at ${startTime}`);
|
|
5490
|
-
try {
|
|
5491
|
-
const response = await baseFetch(input, init);
|
|
5492
|
-
const duration = performance.now() - start;
|
|
5493
|
-
logTiming(`${method} ${path2} -> ${formatDuration(duration)} (status: ${response.status})`);
|
|
5494
|
-
return response;
|
|
5495
|
-
} catch (error) {
|
|
5496
|
-
const duration = performance.now() - start;
|
|
5497
|
-
logTiming(`${method} ${path2} -> FAILED after ${formatDuration(duration)}`);
|
|
5498
|
-
throw error;
|
|
5499
|
-
}
|
|
5500
|
-
};
|
|
5501
|
-
}
|
|
5502
|
-
var milestones, firstMilestoneTime = null;
|
|
5503
|
-
var init_timing = __esm(() => {
|
|
5504
|
-
milestones = new Map;
|
|
5505
|
-
});
|
|
5506
|
-
|
|
5507
5398
|
// package.json
|
|
5508
5399
|
var package_default;
|
|
5509
5400
|
var init_package = __esm(() => {
|
|
5510
5401
|
package_default = {
|
|
5511
5402
|
name: "@letta-ai/letta-code",
|
|
5512
|
-
version: "0.31.
|
|
5403
|
+
version: "0.31.11",
|
|
5513
5404
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
5514
5405
|
type: "module",
|
|
5515
5406
|
packageManager: "bun@1.3.10",
|
|
@@ -5753,266 +5644,6 @@ var init_package = __esm(() => {
|
|
|
5753
5644
|
};
|
|
5754
5645
|
});
|
|
5755
5646
|
|
|
5756
|
-
// src/backend/api/memfs-git-proxy.ts
|
|
5757
|
-
var exports_memfs_git_proxy = {};
|
|
5758
|
-
__export(exports_memfs_git_proxy, {
|
|
5759
|
-
getMemfsServerUrl: () => getMemfsServerUrl,
|
|
5760
|
-
getMemfsGitProxyRewriteConfig: () => getMemfsGitProxyRewriteConfig,
|
|
5761
|
-
LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV: () => LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV
|
|
5762
|
-
});
|
|
5763
|
-
function isLocalhostUrl(value) {
|
|
5764
|
-
if (!value)
|
|
5765
|
-
return false;
|
|
5766
|
-
try {
|
|
5767
|
-
const parsed = new URL(value);
|
|
5768
|
-
return ["localhost", "127.0.0.1", "::1", "[::1]"].includes(parsed.hostname);
|
|
5769
|
-
} catch {
|
|
5770
|
-
return false;
|
|
5771
|
-
}
|
|
5772
|
-
}
|
|
5773
|
-
function trimBaseUrl(value) {
|
|
5774
|
-
return value.trim().replace(/\/+$/, "");
|
|
5775
|
-
}
|
|
5776
|
-
function getMemfsServerUrl() {
|
|
5777
|
-
let settings = null;
|
|
5778
|
-
try {
|
|
5779
|
-
settings = settingsManager.getSettings();
|
|
5780
|
-
} catch {}
|
|
5781
|
-
const configuredMemfsUrl = process.env.LETTA_MEMFS_BASE_URL || settings?.env?.LETTA_MEMFS_BASE_URL;
|
|
5782
|
-
if (configuredMemfsUrl) {
|
|
5783
|
-
return configuredMemfsUrl;
|
|
5784
|
-
}
|
|
5785
|
-
return LETTA_CLOUD_API_URL;
|
|
5786
|
-
}
|
|
5787
|
-
function getMemfsGitProxyRewriteConfig(env = process.env) {
|
|
5788
|
-
const rawProxyBaseUrl = env[LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV]?.trim();
|
|
5789
|
-
if (!rawProxyBaseUrl || !isLocalhostUrl(rawProxyBaseUrl)) {
|
|
5790
|
-
return null;
|
|
5791
|
-
}
|
|
5792
|
-
const memfsBaseUrl = trimBaseUrl(getMemfsServerUrl());
|
|
5793
|
-
if (!memfsBaseUrl.includes("api.letta.com")) {
|
|
5794
|
-
return null;
|
|
5795
|
-
}
|
|
5796
|
-
const proxyBaseUrl = trimBaseUrl(rawProxyBaseUrl);
|
|
5797
|
-
const proxyPrefix = `${proxyBaseUrl}/v1/git/`;
|
|
5798
|
-
const memfsPrefix = `${memfsBaseUrl}/v1/git/`;
|
|
5799
|
-
return {
|
|
5800
|
-
proxyBaseUrl,
|
|
5801
|
-
memfsBaseUrl,
|
|
5802
|
-
proxyPrefix,
|
|
5803
|
-
memfsPrefix,
|
|
5804
|
-
configKey: `url.${proxyPrefix}.insteadOf`,
|
|
5805
|
-
configValue: memfsPrefix
|
|
5806
|
-
};
|
|
5807
|
-
}
|
|
5808
|
-
var LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV = "LETTA_MEMFS_GIT_PROXY_BASE_URL";
|
|
5809
|
-
var init_memfs_git_proxy = __esm(() => {
|
|
5810
|
-
init_oauth();
|
|
5811
|
-
init_settings_manager();
|
|
5812
|
-
});
|
|
5813
|
-
|
|
5814
|
-
// src/backend/api/client.ts
|
|
5815
|
-
var exports_client = {};
|
|
5816
|
-
__export(exports_client, {
|
|
5817
|
-
getServerUrl: () => getServerUrl,
|
|
5818
|
-
getRuntimeEnvironmentDeviceId: () => getRuntimeEnvironmentDeviceId,
|
|
5819
|
-
getMemfsServerUrl: () => getMemfsServerUrl,
|
|
5820
|
-
getMemfsGitProxyRewriteConfig: () => getMemfsGitProxyRewriteConfig,
|
|
5821
|
-
getClientDefaultHeaders: () => getClientDefaultHeaders,
|
|
5822
|
-
getClient: () => getClient,
|
|
5823
|
-
consumeLastSDKDiagnostic: () => consumeLastSDKDiagnostic,
|
|
5824
|
-
clearLastSDKDiagnostic: () => clearLastSDKDiagnostic,
|
|
5825
|
-
__testOverrideGetClient: () => __testOverrideGetClient,
|
|
5826
|
-
LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV: () => LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV
|
|
5827
|
-
});
|
|
5828
|
-
import { hostname } from "node:os";
|
|
5829
|
-
function __testOverrideGetClient(factory) {
|
|
5830
|
-
_testClientOverride = factory;
|
|
5831
|
-
}
|
|
5832
|
-
function safeDiagnosticString(value) {
|
|
5833
|
-
if (value === null || value === undefined) {
|
|
5834
|
-
return "";
|
|
5835
|
-
}
|
|
5836
|
-
if (typeof value === "string") {
|
|
5837
|
-
return value;
|
|
5838
|
-
}
|
|
5839
|
-
try {
|
|
5840
|
-
return JSON.stringify(value);
|
|
5841
|
-
} catch {
|
|
5842
|
-
return String(value);
|
|
5843
|
-
}
|
|
5844
|
-
}
|
|
5845
|
-
function truncateDiagnostic(value) {
|
|
5846
|
-
const text = safeDiagnosticString(value);
|
|
5847
|
-
if (text.length <= SDK_DIAGNOSTIC_MAX_LEN) {
|
|
5848
|
-
return text;
|
|
5849
|
-
}
|
|
5850
|
-
return `${text.slice(0, SDK_DIAGNOSTIC_MAX_LEN)}...[truncated, was ${text.length}b]`;
|
|
5851
|
-
}
|
|
5852
|
-
function captureSDKErrorDiagnostic(args) {
|
|
5853
|
-
const diagnosticLine = truncateDiagnostic(args.map((arg) => safeDiagnosticString(arg)).join(" "));
|
|
5854
|
-
const previous = lastSDKDiagnostic ?? { lines: [] };
|
|
5855
|
-
lastSDKDiagnostic = {
|
|
5856
|
-
lines: [...previous.lines, diagnosticLine].slice(-SDK_DIAGNOSTIC_MAX_LINES)
|
|
5857
|
-
};
|
|
5858
|
-
}
|
|
5859
|
-
function consumeLastSDKDiagnostic() {
|
|
5860
|
-
const diag = lastSDKDiagnostic;
|
|
5861
|
-
lastSDKDiagnostic = null;
|
|
5862
|
-
if (!diag || diag.lines.length === 0) {
|
|
5863
|
-
return null;
|
|
5864
|
-
}
|
|
5865
|
-
return `sdk_error=${diag.lines.join(" || ")}`;
|
|
5866
|
-
}
|
|
5867
|
-
function clearLastSDKDiagnostic() {
|
|
5868
|
-
lastSDKDiagnostic = null;
|
|
5869
|
-
}
|
|
5870
|
-
function getServerUrl() {
|
|
5871
|
-
const settings = settingsManager.getSettings();
|
|
5872
|
-
return process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
|
|
5873
|
-
}
|
|
5874
|
-
function getNodeRoutingHeader() {
|
|
5875
|
-
const raw = process.env.LETTA_NODE;
|
|
5876
|
-
if (raw === undefined || raw.trim() === "") {
|
|
5877
|
-
return {};
|
|
5878
|
-
}
|
|
5879
|
-
const enabled = NODE_HEADER_ENABLED_VALUES.has(raw.trim().toLowerCase());
|
|
5880
|
-
return { "x-letta-node": enabled ? "1" : "0" };
|
|
5881
|
-
}
|
|
5882
|
-
function getRuntimeEnvironmentDeviceId() {
|
|
5883
|
-
return process.env[RUNTIME_ENVIRONMENT_DEVICE_ID_ENV]?.trim() || settingsManager.getOrCreateDeviceId();
|
|
5884
|
-
}
|
|
5885
|
-
function getClientDefaultHeaders() {
|
|
5886
|
-
return {
|
|
5887
|
-
"X-Letta-Source": "letta-code",
|
|
5888
|
-
"User-Agent": `letta-code/${package_default.version}`,
|
|
5889
|
-
"X-Letta-Environment-Device-Id": getRuntimeEnvironmentDeviceId(),
|
|
5890
|
-
...getNodeRoutingHeader(),
|
|
5891
|
-
...process.env.LETTA_MEMFS_BACKEND === "hosted" ? { "x-letta-memfs-backend": "hosted" } : {}
|
|
5892
|
-
};
|
|
5893
|
-
}
|
|
5894
|
-
async function getClient() {
|
|
5895
|
-
if (_testClientOverride) {
|
|
5896
|
-
return await _testClientOverride();
|
|
5897
|
-
}
|
|
5898
|
-
const baseSettings = settingsManager.getSettings();
|
|
5899
|
-
const cachedTokens = settingsManager.getCachedSecureTokens();
|
|
5900
|
-
const cachedSettings = {
|
|
5901
|
-
...baseSettings,
|
|
5902
|
-
env: {
|
|
5903
|
-
...baseSettings.env,
|
|
5904
|
-
...cachedTokens.apiKey && { LETTA_API_KEY: cachedTokens.apiKey }
|
|
5905
|
-
},
|
|
5906
|
-
refreshToken: cachedTokens.refreshToken ?? baseSettings.refreshToken
|
|
5907
|
-
};
|
|
5908
|
-
const settings = process.env.LETTA_API_KEY || cachedSettings.env?.LETTA_API_KEY || cachedSettings.refreshToken ? cachedSettings : await settingsManager.getSettingsWithSecureTokens();
|
|
5909
|
-
let apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY;
|
|
5910
|
-
if (!process.env.LETTA_API_KEY) {
|
|
5911
|
-
if (apiKey) {
|
|
5912
|
-
_cachedApiKey = apiKey;
|
|
5913
|
-
} else if (_cachedApiKey) {
|
|
5914
|
-
apiKey = _cachedApiKey;
|
|
5915
|
-
}
|
|
5916
|
-
}
|
|
5917
|
-
if (!process.env.LETTA_API_KEY && settings.tokenExpiresAt && settings.refreshToken) {
|
|
5918
|
-
const now = Date.now();
|
|
5919
|
-
const expiresAt = settings.tokenExpiresAt;
|
|
5920
|
-
if (!apiKey || expiresAt - now < 5 * 60 * 1000) {
|
|
5921
|
-
try {
|
|
5922
|
-
const deviceId = settingsManager.getOrCreateDeviceId();
|
|
5923
|
-
const deviceName = hostname();
|
|
5924
|
-
const tokens = await refreshAccessTokenSingleFlight(settings.refreshToken, deviceId, deviceName);
|
|
5925
|
-
settingsManager.updateSettings({
|
|
5926
|
-
env: { LETTA_API_KEY: tokens.access_token },
|
|
5927
|
-
refreshToken: tokens.refresh_token || settings.refreshToken,
|
|
5928
|
-
tokenExpiresAt: now + tokens.expires_in * 1000
|
|
5929
|
-
});
|
|
5930
|
-
apiKey = tokens.access_token;
|
|
5931
|
-
_cachedApiKey = tokens.access_token;
|
|
5932
|
-
} catch (error) {
|
|
5933
|
-
trackBoundaryError({
|
|
5934
|
-
errorType: "auth_token_refresh_failed",
|
|
5935
|
-
error,
|
|
5936
|
-
context: "auth_client_token_refresh"
|
|
5937
|
-
});
|
|
5938
|
-
console.error("Failed to refresh access token:", error);
|
|
5939
|
-
console.error(`
|
|
5940
|
-
If you experience this issue multiple times, move ~/.letta to ~/.letta_backup, and re-run 'letta' to re-authenticate`);
|
|
5941
|
-
throw new Error(`Failed to refresh access token: ${error instanceof Error ? error.message : String(error)}`);
|
|
5942
|
-
}
|
|
5943
|
-
}
|
|
5944
|
-
}
|
|
5945
|
-
const baseURL = process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
|
|
5946
|
-
if (!apiKey && baseURL === LETTA_CLOUD_API_URL) {
|
|
5947
|
-
console.error("Missing LETTA_API_KEY");
|
|
5948
|
-
console.error("Run 'letta' to configure authentication, or set LETTA_API_KEY to your API key");
|
|
5949
|
-
console.error(new Error("getClient() called without credentials").stack);
|
|
5950
|
-
throw new Error("Missing LETTA_API_KEY. Run 'letta' to configure authentication, or set LETTA_API_KEY to your API key.");
|
|
5951
|
-
}
|
|
5952
|
-
const client = new Letta({
|
|
5953
|
-
apiKey,
|
|
5954
|
-
baseURL,
|
|
5955
|
-
logger: sdkLogger,
|
|
5956
|
-
timeout: Number(process.env.LETTA_REQUEST_TIMEOUT_MS) || 10 * 60 * 1000,
|
|
5957
|
-
defaultHeaders: getClientDefaultHeaders(),
|
|
5958
|
-
...isTimingsEnabled() && { fetch: createTimingFetch(fetch) }
|
|
5959
|
-
});
|
|
5960
|
-
const MESSAGE_CACHE_MAX = 32;
|
|
5961
|
-
const messageCache = new Map;
|
|
5962
|
-
const origRetrieveMessage = client.messages.retrieve.bind(client.messages);
|
|
5963
|
-
client.messages.retrieve = (...args) => {
|
|
5964
|
-
const messageId = args[0];
|
|
5965
|
-
const cached = messageCache.get(messageId);
|
|
5966
|
-
if (cached) {
|
|
5967
|
-
messageCache.delete(messageId);
|
|
5968
|
-
messageCache.set(messageId, cached);
|
|
5969
|
-
return cached;
|
|
5970
|
-
}
|
|
5971
|
-
const promise = origRetrieveMessage(...args);
|
|
5972
|
-
messageCache.set(messageId, promise);
|
|
5973
|
-
if (messageCache.size > MESSAGE_CACHE_MAX) {
|
|
5974
|
-
const oldest = messageCache.keys().next().value;
|
|
5975
|
-
if (oldest !== undefined)
|
|
5976
|
-
messageCache.delete(oldest);
|
|
5977
|
-
}
|
|
5978
|
-
promise.catch(() => messageCache.delete(messageId));
|
|
5979
|
-
return promise;
|
|
5980
|
-
};
|
|
5981
|
-
return client;
|
|
5982
|
-
}
|
|
5983
|
-
var SDK_DIAGNOSTIC_MAX_LEN = 400, SDK_DIAGNOSTIC_MAX_LINES = 4, lastSDKDiagnostic = null, _cachedApiKey, _testClientOverride = null, sdkLogger, NODE_HEADER_ENABLED_VALUES, RUNTIME_ENVIRONMENT_DEVICE_ID_ENV = "LETTA_RUNTIME_ENVIRONMENT_DEVICE_ID";
|
|
5984
|
-
var init_client2 = __esm(() => {
|
|
5985
|
-
init_letta_client();
|
|
5986
|
-
init_oauth();
|
|
5987
|
-
init_oauth_refresh();
|
|
5988
|
-
init_settings_manager();
|
|
5989
|
-
init_error_reporting();
|
|
5990
|
-
init_debug();
|
|
5991
|
-
init_timing();
|
|
5992
|
-
init_package();
|
|
5993
|
-
init_memfs_git_proxy();
|
|
5994
|
-
sdkLogger = {
|
|
5995
|
-
error: (...args) => {
|
|
5996
|
-
try {
|
|
5997
|
-
captureSDKErrorDiagnostic(args);
|
|
5998
|
-
} catch {}
|
|
5999
|
-
if (isDebugEnabled()) {
|
|
6000
|
-
console.error(...args);
|
|
6001
|
-
}
|
|
6002
|
-
},
|
|
6003
|
-
warn: (...args) => {
|
|
6004
|
-
console.warn(...args);
|
|
6005
|
-
},
|
|
6006
|
-
info: (...args) => {
|
|
6007
|
-
console.info(...args);
|
|
6008
|
-
},
|
|
6009
|
-
debug: (...args) => {
|
|
6010
|
-
console.debug(...args);
|
|
6011
|
-
}
|
|
6012
|
-
};
|
|
6013
|
-
NODE_HEADER_ENABLED_VALUES = new Set(["1", "true", "yes"]);
|
|
6014
|
-
});
|
|
6015
|
-
|
|
6016
5647
|
// src/backend/api/http-headers.ts
|
|
6017
5648
|
function getLettaCodeHeaders(apiKey) {
|
|
6018
5649
|
return {
|
|
@@ -6140,8 +5771,8 @@ function parseUrl(value, options = {}) {
|
|
|
6140
5771
|
return null;
|
|
6141
5772
|
}
|
|
6142
5773
|
}
|
|
6143
|
-
function isLoopbackHostname(
|
|
6144
|
-
const normalized =
|
|
5774
|
+
function isLoopbackHostname(hostname) {
|
|
5775
|
+
const normalized = hostname.toLowerCase();
|
|
6145
5776
|
return normalized === "localhost" || normalized === "0.0.0.0" || normalized === "::1" || normalized === "[::1]" || normalized.startsWith("127.");
|
|
6146
5777
|
}
|
|
6147
5778
|
function isLoopbackUrl(value, options = {}) {
|
|
@@ -6150,6 +5781,15 @@ function isLoopbackUrl(value, options = {}) {
|
|
|
6150
5781
|
}
|
|
6151
5782
|
|
|
6152
5783
|
// src/backend/api/metadata.ts
|
|
5784
|
+
function getFeedbackClientType(env = process.env) {
|
|
5785
|
+
if (env.LETTA_DESKTOP_MODE === "1") {
|
|
5786
|
+
return "desktop";
|
|
5787
|
+
}
|
|
5788
|
+
if (env.LETTA_RUNTIME_ENVIRONMENT_DEVICE_ID) {
|
|
5789
|
+
return "chat.letta.com";
|
|
5790
|
+
}
|
|
5791
|
+
return "cli";
|
|
5792
|
+
}
|
|
6153
5793
|
async function getBalanceMetadata() {
|
|
6154
5794
|
return apiRequest("GET", "/v1/metadata/balance");
|
|
6155
5795
|
}
|
|
@@ -6198,6 +5838,38 @@ var init_metadata = __esm(() => {
|
|
|
6198
5838
|
init_request();
|
|
6199
5839
|
});
|
|
6200
5840
|
|
|
5841
|
+
// src/backend/api/server-url.ts
|
|
5842
|
+
var exports_server_url = {};
|
|
5843
|
+
__export(exports_server_url, {
|
|
5844
|
+
isCloudServerUrl: () => isCloudServerUrl,
|
|
5845
|
+
getServerUrl: () => getServerUrl
|
|
5846
|
+
});
|
|
5847
|
+
function getServerUrl() {
|
|
5848
|
+
const settings = settingsManager.getSettings();
|
|
5849
|
+
return process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
|
|
5850
|
+
}
|
|
5851
|
+
function isCloudServerUrl(serverUrl) {
|
|
5852
|
+
let resolved = serverUrl;
|
|
5853
|
+
if (resolved === undefined) {
|
|
5854
|
+
try {
|
|
5855
|
+
resolved = getServerUrl();
|
|
5856
|
+
} catch {
|
|
5857
|
+
resolved = process.env.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
|
|
5858
|
+
}
|
|
5859
|
+
}
|
|
5860
|
+
try {
|
|
5861
|
+
const parsed = new URL(resolved);
|
|
5862
|
+
const cloud = new URL(LETTA_CLOUD_API_URL);
|
|
5863
|
+
return parsed.hostname === cloud.hostname;
|
|
5864
|
+
} catch {
|
|
5865
|
+
return false;
|
|
5866
|
+
}
|
|
5867
|
+
}
|
|
5868
|
+
var init_server_url = __esm(() => {
|
|
5869
|
+
init_oauth();
|
|
5870
|
+
init_settings_manager();
|
|
5871
|
+
});
|
|
5872
|
+
|
|
6201
5873
|
// src/version.ts
|
|
6202
5874
|
var exports_version = {};
|
|
6203
5875
|
__export(exports_version, {
|
|
@@ -6725,9 +6397,9 @@ class TelemetryManager {
|
|
|
6725
6397
|
var telemetry;
|
|
6726
6398
|
var init_telemetry = __esm(() => {
|
|
6727
6399
|
init_oauth();
|
|
6728
|
-
init_client2();
|
|
6729
6400
|
init_health();
|
|
6730
6401
|
init_metadata();
|
|
6402
|
+
init_server_url();
|
|
6731
6403
|
init_paths();
|
|
6732
6404
|
init_settings_manager();
|
|
6733
6405
|
init_debug();
|
|
@@ -6776,6 +6448,370 @@ function buildCreatedAgentTags(options = {}) {
|
|
|
6776
6448
|
}
|
|
6777
6449
|
var LETTA_CODE_ORIGIN_TAG = "origin:letta-code", ONBOARDING_ORIGIN_TAG = "origin:onboarding", LETTA_CODE_SUBAGENT_TAG = "role:subagent", GIT_MEMORY_ENABLED_TAG = "git-memory-enabled";
|
|
6778
6450
|
|
|
6451
|
+
// src/auth/oauth-refresh.ts
|
|
6452
|
+
async function refreshAccessTokenSingleFlight(refreshToken2, deviceId, deviceName, refresh = refreshAccessToken2) {
|
|
6453
|
+
const refreshKey = `${refreshToken2}\x00${deviceId}`;
|
|
6454
|
+
const existing = inFlightRefreshes.get(refreshKey);
|
|
6455
|
+
if (existing) {
|
|
6456
|
+
return await existing;
|
|
6457
|
+
}
|
|
6458
|
+
const pending = refresh(refreshToken2, deviceId, deviceName);
|
|
6459
|
+
inFlightRefreshes.set(refreshKey, pending);
|
|
6460
|
+
try {
|
|
6461
|
+
return await pending;
|
|
6462
|
+
} finally {
|
|
6463
|
+
if (inFlightRefreshes.get(refreshKey) === pending) {
|
|
6464
|
+
inFlightRefreshes.delete(refreshKey);
|
|
6465
|
+
}
|
|
6466
|
+
}
|
|
6467
|
+
}
|
|
6468
|
+
var inFlightRefreshes;
|
|
6469
|
+
var init_oauth_refresh = __esm(() => {
|
|
6470
|
+
init_oauth();
|
|
6471
|
+
inFlightRefreshes = new Map;
|
|
6472
|
+
});
|
|
6473
|
+
|
|
6474
|
+
// src/utils/timing.ts
|
|
6475
|
+
function isTimingsEnabled() {
|
|
6476
|
+
const val = process.env.LETTA_DEBUG_TIMINGS;
|
|
6477
|
+
return val === "1" || val === "true";
|
|
6478
|
+
}
|
|
6479
|
+
function formatDuration(ms) {
|
|
6480
|
+
if (ms < 1000)
|
|
6481
|
+
return `${Math.round(ms)}ms`;
|
|
6482
|
+
return `${(ms / 1000).toFixed(2)}s`;
|
|
6483
|
+
}
|
|
6484
|
+
function formatTimestamp(date) {
|
|
6485
|
+
return date.toISOString().slice(11, 23);
|
|
6486
|
+
}
|
|
6487
|
+
function logTiming(message) {
|
|
6488
|
+
if (isTimingsEnabled()) {
|
|
6489
|
+
console.error(`[timing] ${message}`);
|
|
6490
|
+
}
|
|
6491
|
+
}
|
|
6492
|
+
function markMilestone(name) {
|
|
6493
|
+
const now = performance.now();
|
|
6494
|
+
milestones.set(name, now);
|
|
6495
|
+
if (firstMilestoneTime === null) {
|
|
6496
|
+
firstMilestoneTime = now;
|
|
6497
|
+
}
|
|
6498
|
+
if (isTimingsEnabled()) {
|
|
6499
|
+
const relative = now - firstMilestoneTime;
|
|
6500
|
+
console.error(`[timing] MILESTONE ${name} at +${formatDuration(relative)} (${formatTimestamp(new Date)})`);
|
|
6501
|
+
}
|
|
6502
|
+
}
|
|
6503
|
+
function measureSinceMilestone(label, fromMilestone) {
|
|
6504
|
+
if (!isTimingsEnabled())
|
|
6505
|
+
return;
|
|
6506
|
+
const startTime = milestones.get(fromMilestone);
|
|
6507
|
+
if (startTime === undefined) {
|
|
6508
|
+
console.error(`[timing] WARNING: milestone "${fromMilestone}" not found for measurement "${label}"`);
|
|
6509
|
+
return;
|
|
6510
|
+
}
|
|
6511
|
+
const duration = performance.now() - startTime;
|
|
6512
|
+
console.error(`[timing] ${label}: ${formatDuration(duration)}`);
|
|
6513
|
+
}
|
|
6514
|
+
function reportAllMilestones() {
|
|
6515
|
+
if (!isTimingsEnabled() || milestones.size === 0)
|
|
6516
|
+
return;
|
|
6517
|
+
const first = firstMilestoneTime ?? 0;
|
|
6518
|
+
console.error(`[timing] ======== MILESTONE SUMMARY ========`);
|
|
6519
|
+
const sorted = [...milestones.entries()].sort((a, b) => a[1] - b[1]);
|
|
6520
|
+
let prevTime = first;
|
|
6521
|
+
for (const [name, time] of sorted) {
|
|
6522
|
+
const relativeToStart = time - first;
|
|
6523
|
+
const delta = time - prevTime;
|
|
6524
|
+
const deltaStr = prevTime === first ? "" : ` (+${formatDuration(delta)})`;
|
|
6525
|
+
console.error(`[timing] +${formatDuration(relativeToStart).padStart(8)} ${name}${deltaStr}`);
|
|
6526
|
+
prevTime = time;
|
|
6527
|
+
}
|
|
6528
|
+
console.error(`[timing] =====================================`);
|
|
6529
|
+
}
|
|
6530
|
+
function createTimingFetch(baseFetch) {
|
|
6531
|
+
return async (input, init) => {
|
|
6532
|
+
const start = performance.now();
|
|
6533
|
+
const startTime = formatTimestamp(new Date);
|
|
6534
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
6535
|
+
const method = init?.method || "GET";
|
|
6536
|
+
let path2;
|
|
6537
|
+
try {
|
|
6538
|
+
path2 = new URL(url).pathname;
|
|
6539
|
+
} catch {
|
|
6540
|
+
path2 = url;
|
|
6541
|
+
}
|
|
6542
|
+
logTiming(`${method} ${path2} started at ${startTime}`);
|
|
6543
|
+
try {
|
|
6544
|
+
const response = await baseFetch(input, init);
|
|
6545
|
+
const duration = performance.now() - start;
|
|
6546
|
+
logTiming(`${method} ${path2} -> ${formatDuration(duration)} (status: ${response.status})`);
|
|
6547
|
+
return response;
|
|
6548
|
+
} catch (error) {
|
|
6549
|
+
const duration = performance.now() - start;
|
|
6550
|
+
logTiming(`${method} ${path2} -> FAILED after ${formatDuration(duration)}`);
|
|
6551
|
+
throw error;
|
|
6552
|
+
}
|
|
6553
|
+
};
|
|
6554
|
+
}
|
|
6555
|
+
var milestones, firstMilestoneTime = null;
|
|
6556
|
+
var init_timing = __esm(() => {
|
|
6557
|
+
milestones = new Map;
|
|
6558
|
+
});
|
|
6559
|
+
|
|
6560
|
+
// src/backend/api/memfs-git-proxy.ts
|
|
6561
|
+
var exports_memfs_git_proxy = {};
|
|
6562
|
+
__export(exports_memfs_git_proxy, {
|
|
6563
|
+
getMemfsServerUrl: () => getMemfsServerUrl,
|
|
6564
|
+
getMemfsGitProxyRewriteConfig: () => getMemfsGitProxyRewriteConfig,
|
|
6565
|
+
LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV: () => LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV
|
|
6566
|
+
});
|
|
6567
|
+
function isLocalhostUrl(value) {
|
|
6568
|
+
if (!value)
|
|
6569
|
+
return false;
|
|
6570
|
+
try {
|
|
6571
|
+
const parsed = new URL(value);
|
|
6572
|
+
return ["localhost", "127.0.0.1", "::1", "[::1]"].includes(parsed.hostname);
|
|
6573
|
+
} catch {
|
|
6574
|
+
return false;
|
|
6575
|
+
}
|
|
6576
|
+
}
|
|
6577
|
+
function trimBaseUrl(value) {
|
|
6578
|
+
return value.trim().replace(/\/+$/, "");
|
|
6579
|
+
}
|
|
6580
|
+
function getMemfsServerUrl() {
|
|
6581
|
+
let settings = null;
|
|
6582
|
+
try {
|
|
6583
|
+
settings = settingsManager.getSettings();
|
|
6584
|
+
} catch {}
|
|
6585
|
+
const configuredMemfsUrl = process.env.LETTA_MEMFS_BASE_URL || settings?.env?.LETTA_MEMFS_BASE_URL;
|
|
6586
|
+
if (configuredMemfsUrl) {
|
|
6587
|
+
return configuredMemfsUrl;
|
|
6588
|
+
}
|
|
6589
|
+
return LETTA_CLOUD_API_URL;
|
|
6590
|
+
}
|
|
6591
|
+
function getMemfsGitProxyRewriteConfig(env = process.env) {
|
|
6592
|
+
const rawProxyBaseUrl = env[LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV]?.trim();
|
|
6593
|
+
if (!rawProxyBaseUrl || !isLocalhostUrl(rawProxyBaseUrl)) {
|
|
6594
|
+
return null;
|
|
6595
|
+
}
|
|
6596
|
+
const memfsBaseUrl = trimBaseUrl(getMemfsServerUrl());
|
|
6597
|
+
if (!memfsBaseUrl.includes("api.letta.com")) {
|
|
6598
|
+
return null;
|
|
6599
|
+
}
|
|
6600
|
+
const proxyBaseUrl = trimBaseUrl(rawProxyBaseUrl);
|
|
6601
|
+
const proxyPrefix = `${proxyBaseUrl}/v1/git/`;
|
|
6602
|
+
const memfsPrefix = `${memfsBaseUrl}/v1/git/`;
|
|
6603
|
+
return {
|
|
6604
|
+
proxyBaseUrl,
|
|
6605
|
+
memfsBaseUrl,
|
|
6606
|
+
proxyPrefix,
|
|
6607
|
+
memfsPrefix,
|
|
6608
|
+
configKey: `url.${proxyPrefix}.insteadOf`,
|
|
6609
|
+
configValue: memfsPrefix
|
|
6610
|
+
};
|
|
6611
|
+
}
|
|
6612
|
+
var LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV = "LETTA_MEMFS_GIT_PROXY_BASE_URL";
|
|
6613
|
+
var init_memfs_git_proxy = __esm(() => {
|
|
6614
|
+
init_oauth();
|
|
6615
|
+
init_settings_manager();
|
|
6616
|
+
});
|
|
6617
|
+
|
|
6618
|
+
// src/backend/api/client.ts
|
|
6619
|
+
var exports_client = {};
|
|
6620
|
+
__export(exports_client, {
|
|
6621
|
+
getRuntimeEnvironmentDeviceId: () => getRuntimeEnvironmentDeviceId,
|
|
6622
|
+
getMemfsServerUrl: () => getMemfsServerUrl,
|
|
6623
|
+
getMemfsGitProxyRewriteConfig: () => getMemfsGitProxyRewriteConfig,
|
|
6624
|
+
getClientDefaultHeaders: () => getClientDefaultHeaders,
|
|
6625
|
+
getClient: () => getClient,
|
|
6626
|
+
consumeLastSDKDiagnostic: () => consumeLastSDKDiagnostic,
|
|
6627
|
+
clearLastSDKDiagnostic: () => clearLastSDKDiagnostic,
|
|
6628
|
+
__testOverrideGetClient: () => __testOverrideGetClient,
|
|
6629
|
+
LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV: () => LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV
|
|
6630
|
+
});
|
|
6631
|
+
import { hostname } from "node:os";
|
|
6632
|
+
function __testOverrideGetClient(factory) {
|
|
6633
|
+
_testClientOverride = factory;
|
|
6634
|
+
}
|
|
6635
|
+
function safeDiagnosticString(value) {
|
|
6636
|
+
if (value === null || value === undefined) {
|
|
6637
|
+
return "";
|
|
6638
|
+
}
|
|
6639
|
+
if (typeof value === "string") {
|
|
6640
|
+
return value;
|
|
6641
|
+
}
|
|
6642
|
+
try {
|
|
6643
|
+
return JSON.stringify(value);
|
|
6644
|
+
} catch {
|
|
6645
|
+
return String(value);
|
|
6646
|
+
}
|
|
6647
|
+
}
|
|
6648
|
+
function truncateDiagnostic(value) {
|
|
6649
|
+
const text = safeDiagnosticString(value);
|
|
6650
|
+
if (text.length <= SDK_DIAGNOSTIC_MAX_LEN) {
|
|
6651
|
+
return text;
|
|
6652
|
+
}
|
|
6653
|
+
return `${text.slice(0, SDK_DIAGNOSTIC_MAX_LEN)}...[truncated, was ${text.length}b]`;
|
|
6654
|
+
}
|
|
6655
|
+
function captureSDKErrorDiagnostic(args) {
|
|
6656
|
+
const diagnosticLine = truncateDiagnostic(args.map((arg) => safeDiagnosticString(arg)).join(" "));
|
|
6657
|
+
const previous = lastSDKDiagnostic ?? { lines: [] };
|
|
6658
|
+
lastSDKDiagnostic = {
|
|
6659
|
+
lines: [...previous.lines, diagnosticLine].slice(-SDK_DIAGNOSTIC_MAX_LINES)
|
|
6660
|
+
};
|
|
6661
|
+
}
|
|
6662
|
+
function consumeLastSDKDiagnostic() {
|
|
6663
|
+
const diag = lastSDKDiagnostic;
|
|
6664
|
+
lastSDKDiagnostic = null;
|
|
6665
|
+
if (!diag || diag.lines.length === 0) {
|
|
6666
|
+
return null;
|
|
6667
|
+
}
|
|
6668
|
+
return `sdk_error=${diag.lines.join(" || ")}`;
|
|
6669
|
+
}
|
|
6670
|
+
function clearLastSDKDiagnostic() {
|
|
6671
|
+
lastSDKDiagnostic = null;
|
|
6672
|
+
}
|
|
6673
|
+
function getNodeRoutingHeader() {
|
|
6674
|
+
const raw = process.env.LETTA_NODE;
|
|
6675
|
+
if (raw === undefined || raw.trim() === "") {
|
|
6676
|
+
return {};
|
|
6677
|
+
}
|
|
6678
|
+
const enabled = NODE_HEADER_ENABLED_VALUES.has(raw.trim().toLowerCase());
|
|
6679
|
+
return { "x-letta-node": enabled ? "1" : "0" };
|
|
6680
|
+
}
|
|
6681
|
+
function getRuntimeEnvironmentDeviceId() {
|
|
6682
|
+
return process.env[RUNTIME_ENVIRONMENT_DEVICE_ID_ENV]?.trim() || settingsManager.getOrCreateDeviceId();
|
|
6683
|
+
}
|
|
6684
|
+
function getClientDefaultHeaders() {
|
|
6685
|
+
return {
|
|
6686
|
+
"X-Letta-Source": "letta-code",
|
|
6687
|
+
"User-Agent": `letta-code/${package_default.version}`,
|
|
6688
|
+
"X-Letta-Environment-Device-Id": getRuntimeEnvironmentDeviceId(),
|
|
6689
|
+
...getNodeRoutingHeader(),
|
|
6690
|
+
...process.env.LETTA_MEMFS_BACKEND === "hosted" ? { "x-letta-memfs-backend": "hosted" } : {}
|
|
6691
|
+
};
|
|
6692
|
+
}
|
|
6693
|
+
async function getClient() {
|
|
6694
|
+
if (_testClientOverride) {
|
|
6695
|
+
return await _testClientOverride();
|
|
6696
|
+
}
|
|
6697
|
+
const baseSettings = settingsManager.getSettings();
|
|
6698
|
+
const cachedTokens = settingsManager.getCachedSecureTokens();
|
|
6699
|
+
const cachedSettings = {
|
|
6700
|
+
...baseSettings,
|
|
6701
|
+
env: {
|
|
6702
|
+
...baseSettings.env,
|
|
6703
|
+
...cachedTokens.apiKey && { LETTA_API_KEY: cachedTokens.apiKey }
|
|
6704
|
+
},
|
|
6705
|
+
refreshToken: cachedTokens.refreshToken ?? baseSettings.refreshToken
|
|
6706
|
+
};
|
|
6707
|
+
const settings = process.env.LETTA_API_KEY || cachedSettings.env?.LETTA_API_KEY || cachedSettings.refreshToken ? cachedSettings : await settingsManager.getSettingsWithSecureTokens();
|
|
6708
|
+
let apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY;
|
|
6709
|
+
if (!process.env.LETTA_API_KEY) {
|
|
6710
|
+
if (apiKey) {
|
|
6711
|
+
_cachedApiKey = apiKey;
|
|
6712
|
+
} else if (_cachedApiKey) {
|
|
6713
|
+
apiKey = _cachedApiKey;
|
|
6714
|
+
}
|
|
6715
|
+
}
|
|
6716
|
+
if (!process.env.LETTA_API_KEY && settings.tokenExpiresAt && settings.refreshToken) {
|
|
6717
|
+
const now = Date.now();
|
|
6718
|
+
const expiresAt = settings.tokenExpiresAt;
|
|
6719
|
+
if (!apiKey || expiresAt - now < 5 * 60 * 1000) {
|
|
6720
|
+
try {
|
|
6721
|
+
const deviceId = settingsManager.getOrCreateDeviceId();
|
|
6722
|
+
const deviceName = hostname();
|
|
6723
|
+
const tokens = await refreshAccessTokenSingleFlight(settings.refreshToken, deviceId, deviceName);
|
|
6724
|
+
settingsManager.updateSettings({
|
|
6725
|
+
env: { LETTA_API_KEY: tokens.access_token },
|
|
6726
|
+
refreshToken: tokens.refresh_token || settings.refreshToken,
|
|
6727
|
+
tokenExpiresAt: now + tokens.expires_in * 1000
|
|
6728
|
+
});
|
|
6729
|
+
apiKey = tokens.access_token;
|
|
6730
|
+
_cachedApiKey = tokens.access_token;
|
|
6731
|
+
} catch (error) {
|
|
6732
|
+
trackBoundaryError({
|
|
6733
|
+
errorType: "auth_token_refresh_failed",
|
|
6734
|
+
error,
|
|
6735
|
+
context: "auth_client_token_refresh"
|
|
6736
|
+
});
|
|
6737
|
+
console.error("Failed to refresh access token:", error);
|
|
6738
|
+
console.error(`
|
|
6739
|
+
If you experience this issue multiple times, move ~/.letta to ~/.letta_backup, and re-run 'letta' to re-authenticate`);
|
|
6740
|
+
throw new Error(`Failed to refresh access token: ${error instanceof Error ? error.message : String(error)}`);
|
|
6741
|
+
}
|
|
6742
|
+
}
|
|
6743
|
+
}
|
|
6744
|
+
const baseURL = process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
|
|
6745
|
+
if (!apiKey && baseURL === LETTA_CLOUD_API_URL) {
|
|
6746
|
+
console.error("Missing LETTA_API_KEY");
|
|
6747
|
+
console.error("Run 'letta' to configure authentication, or set LETTA_API_KEY to your API key");
|
|
6748
|
+
console.error(new Error("getClient() called without credentials").stack);
|
|
6749
|
+
throw new Error("Missing LETTA_API_KEY. Run 'letta' to configure authentication, or set LETTA_API_KEY to your API key.");
|
|
6750
|
+
}
|
|
6751
|
+
const client = new Letta({
|
|
6752
|
+
apiKey,
|
|
6753
|
+
baseURL,
|
|
6754
|
+
logger: sdkLogger,
|
|
6755
|
+
timeout: Number(process.env.LETTA_REQUEST_TIMEOUT_MS) || 10 * 60 * 1000,
|
|
6756
|
+
defaultHeaders: getClientDefaultHeaders(),
|
|
6757
|
+
...isTimingsEnabled() && { fetch: createTimingFetch(fetch) }
|
|
6758
|
+
});
|
|
6759
|
+
const MESSAGE_CACHE_MAX = 32;
|
|
6760
|
+
const messageCache = new Map;
|
|
6761
|
+
const origRetrieveMessage = client.messages.retrieve.bind(client.messages);
|
|
6762
|
+
client.messages.retrieve = (...args) => {
|
|
6763
|
+
const messageId = args[0];
|
|
6764
|
+
const cached = messageCache.get(messageId);
|
|
6765
|
+
if (cached) {
|
|
6766
|
+
messageCache.delete(messageId);
|
|
6767
|
+
messageCache.set(messageId, cached);
|
|
6768
|
+
return cached;
|
|
6769
|
+
}
|
|
6770
|
+
const promise = origRetrieveMessage(...args);
|
|
6771
|
+
messageCache.set(messageId, promise);
|
|
6772
|
+
if (messageCache.size > MESSAGE_CACHE_MAX) {
|
|
6773
|
+
const oldest = messageCache.keys().next().value;
|
|
6774
|
+
if (oldest !== undefined)
|
|
6775
|
+
messageCache.delete(oldest);
|
|
6776
|
+
}
|
|
6777
|
+
promise.catch(() => messageCache.delete(messageId));
|
|
6778
|
+
return promise;
|
|
6779
|
+
};
|
|
6780
|
+
return client;
|
|
6781
|
+
}
|
|
6782
|
+
var SDK_DIAGNOSTIC_MAX_LEN = 400, SDK_DIAGNOSTIC_MAX_LINES = 4, lastSDKDiagnostic = null, _cachedApiKey, _testClientOverride = null, sdkLogger, NODE_HEADER_ENABLED_VALUES, RUNTIME_ENVIRONMENT_DEVICE_ID_ENV = "LETTA_RUNTIME_ENVIRONMENT_DEVICE_ID";
|
|
6783
|
+
var init_client2 = __esm(() => {
|
|
6784
|
+
init_letta_client();
|
|
6785
|
+
init_oauth();
|
|
6786
|
+
init_oauth_refresh();
|
|
6787
|
+
init_settings_manager();
|
|
6788
|
+
init_error_reporting();
|
|
6789
|
+
init_debug();
|
|
6790
|
+
init_timing();
|
|
6791
|
+
init_package();
|
|
6792
|
+
init_memfs_git_proxy();
|
|
6793
|
+
sdkLogger = {
|
|
6794
|
+
error: (...args) => {
|
|
6795
|
+
try {
|
|
6796
|
+
captureSDKErrorDiagnostic(args);
|
|
6797
|
+
} catch {}
|
|
6798
|
+
if (isDebugEnabled()) {
|
|
6799
|
+
console.error(...args);
|
|
6800
|
+
}
|
|
6801
|
+
},
|
|
6802
|
+
warn: (...args) => {
|
|
6803
|
+
console.warn(...args);
|
|
6804
|
+
},
|
|
6805
|
+
info: (...args) => {
|
|
6806
|
+
console.info(...args);
|
|
6807
|
+
},
|
|
6808
|
+
debug: (...args) => {
|
|
6809
|
+
console.debug(...args);
|
|
6810
|
+
}
|
|
6811
|
+
};
|
|
6812
|
+
NODE_HEADER_ENABLED_VALUES = new Set(["1", "true", "yes"]);
|
|
6813
|
+
});
|
|
6814
|
+
|
|
6779
6815
|
// src/utils/text-files.ts
|
|
6780
6816
|
import { readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
6781
6817
|
function getUtf16Bom(bytes) {
|
|
@@ -88170,6 +88206,30 @@ var init_tool_return_clamp = __esm(() => {
|
|
|
88170
88206
|
init_truncation();
|
|
88171
88207
|
});
|
|
88172
88208
|
|
|
88209
|
+
// src/tools/task-tool-assets.ts
|
|
88210
|
+
function stripComputerFromTaskSchema(schema5) {
|
|
88211
|
+
const properties4 = schema5.properties;
|
|
88212
|
+
if (!properties4 || !Object.hasOwn(properties4, "computer")) {
|
|
88213
|
+
return schema5;
|
|
88214
|
+
}
|
|
88215
|
+
const { computer: _computer, ...rest3 } = properties4;
|
|
88216
|
+
return { ...schema5, properties: rest3 };
|
|
88217
|
+
}
|
|
88218
|
+
function stripComputerFromTaskDescription(description) {
|
|
88219
|
+
const start = description.indexOf(COMPUTER_SECTION_HEADING);
|
|
88220
|
+
if (start === -1) {
|
|
88221
|
+
return description;
|
|
88222
|
+
}
|
|
88223
|
+
const afterHeading = start + COMPUTER_SECTION_HEADING.length;
|
|
88224
|
+
const next = description.indexOf(`
|
|
88225
|
+
## `, afterHeading);
|
|
88226
|
+
const removed = next === -1 ? description.slice(0, start) : description.slice(0, start) + description.slice(next + 1);
|
|
88227
|
+
return removed.replace(/\n{3,}/g, `
|
|
88228
|
+
|
|
88229
|
+
`).trimEnd();
|
|
88230
|
+
}
|
|
88231
|
+
var COMPUTER_SECTION_HEADING = "## Running on Another Computer";
|
|
88232
|
+
|
|
88173
88233
|
// src/tools/define-tool.ts
|
|
88174
88234
|
function defineTool(input) {
|
|
88175
88235
|
return {
|
|
@@ -90810,6 +90870,9 @@ function createSharedReminderState() {
|
|
|
90810
90870
|
hasSentSecretsInfo: false,
|
|
90811
90871
|
pendingSecretsInfoRefresh: false,
|
|
90812
90872
|
lastSentSecretNamesKey: null,
|
|
90873
|
+
hasSentMcpServersInfo: false,
|
|
90874
|
+
lastSentMcpServerNamesKey: null,
|
|
90875
|
+
lastMcpServersFetchedAtMs: null,
|
|
90813
90876
|
lastNotifiedPermissionMode: null,
|
|
90814
90877
|
turnCount: 0,
|
|
90815
90878
|
pendingReflectionTrigger: false,
|
|
@@ -90826,6 +90889,8 @@ function markPostCompactionContextRemindersPending(state) {
|
|
|
90826
90889
|
state.hasSentSessionContext = false;
|
|
90827
90890
|
state.pendingSessionContextReason ??= "post_compaction";
|
|
90828
90891
|
state.hasSentSecretsInfo = false;
|
|
90892
|
+
state.hasSentMcpServersInfo = false;
|
|
90893
|
+
state.lastMcpServersFetchedAtMs = null;
|
|
90829
90894
|
state.lastNotifiedPermissionMode = null;
|
|
90830
90895
|
}
|
|
90831
90896
|
function syncReminderStateFromContextTracker(state, contextTracker) {
|
|
@@ -93661,7 +93726,7 @@ var LETTA_BIN_ARGS_ENV = "LETTA_CODE_BIN_ARGS_JSON", SHELL_SHIM_DIR_NAME = "lett
|
|
|
93661
93726
|
var init_shell_env = __esm(() => {
|
|
93662
93727
|
init_context();
|
|
93663
93728
|
init_memory_filesystem2();
|
|
93664
|
-
|
|
93729
|
+
init_server_url();
|
|
93665
93730
|
init_paths();
|
|
93666
93731
|
init_runtime_context();
|
|
93667
93732
|
init_settings_manager();
|
|
@@ -113383,8 +113448,7 @@ var init_skills3 = __esm(() => {
|
|
|
113383
113448
|
init_skill_sources();
|
|
113384
113449
|
LOCAL_AGENT_EXCLUDED_BUNDLED_SKILLS = new Set([
|
|
113385
113450
|
"image-generation",
|
|
113386
|
-
"managing-shared-memory"
|
|
113387
|
-
"using-cloud-mcp"
|
|
113451
|
+
"managing-shared-memory"
|
|
113388
113452
|
]);
|
|
113389
113453
|
PROJECT_SKILLS_DIR = join24(".agents", "skills");
|
|
113390
113454
|
GLOBAL_SKILLS_DIR = join24(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
|
|
@@ -115525,6 +115589,17 @@ async function task(args) {
|
|
|
115525
115589
|
if (!config) {
|
|
115526
115590
|
return `Error: Invalid subagent type "${subagent_type}"`;
|
|
115527
115591
|
}
|
|
115592
|
+
if (typeof args.computer === "string" && args.computer.trim()) {
|
|
115593
|
+
let environmentRouting = false;
|
|
115594
|
+
try {
|
|
115595
|
+
environmentRouting = getBackend().capabilities.environmentRouting;
|
|
115596
|
+
} catch {
|
|
115597
|
+
environmentRouting = false;
|
|
115598
|
+
}
|
|
115599
|
+
if (!environmentRouting) {
|
|
115600
|
+
return "Error: The computer option requires a Letta Cloud backend. This backend has no connected computers; omit the computer field to run the subagent on the current machine.";
|
|
115601
|
+
}
|
|
115602
|
+
}
|
|
115528
115603
|
let effectiveAgentId = args.agent_id;
|
|
115529
115604
|
let effectiveConversationId = args.conversation_id;
|
|
115530
115605
|
if (config.fork) {
|
|
@@ -118106,6 +118181,21 @@ ${WINDOWS_UNIFIED_EXEC_GUIDANCE}`;
|
|
|
118106
118181
|
|
|
118107
118182
|
// src/tools/memory-tool-assets.ts
|
|
118108
118183
|
async function resolveBackendSpecificToolAssets(name, description, inputSchema) {
|
|
118184
|
+
if (name === "Task") {
|
|
118185
|
+
let environmentRouting = false;
|
|
118186
|
+
try {
|
|
118187
|
+
environmentRouting = getBackend().capabilities.environmentRouting;
|
|
118188
|
+
} catch {
|
|
118189
|
+
environmentRouting = false;
|
|
118190
|
+
}
|
|
118191
|
+
if (!environmentRouting) {
|
|
118192
|
+
return {
|
|
118193
|
+
description: stripComputerFromTaskDescription(description),
|
|
118194
|
+
inputSchema: stripComputerFromTaskSchema(inputSchema)
|
|
118195
|
+
};
|
|
118196
|
+
}
|
|
118197
|
+
return { description, inputSchema };
|
|
118198
|
+
}
|
|
118109
118199
|
let isLocalMemfs = false;
|
|
118110
118200
|
try {
|
|
118111
118201
|
isLocalMemfs = getBackend().capabilities.localMemfs;
|
|
@@ -125779,7 +125869,7 @@ async function applyMemfsFlags(agentId, memfsFlag, options) {
|
|
|
125779
125869
|
};
|
|
125780
125870
|
}
|
|
125781
125871
|
async function isLettaCloud() {
|
|
125782
|
-
const { getServerUrl: getServerUrl2 } = await Promise.resolve().then(() => (
|
|
125872
|
+
const { getServerUrl: getServerUrl2 } = await Promise.resolve().then(() => (init_server_url(), exports_server_url));
|
|
125783
125873
|
const serverUrl = getServerUrl2();
|
|
125784
125874
|
return serverUrl.includes("api.letta.com") || process.env.LETTA_MEMFS_LOCAL === "1" || process.env.LETTA_API_KEY === "local-desktop";
|
|
125785
125875
|
}
|
|
@@ -130984,6 +131074,7 @@ var init_local_provider_errors = __esm(() => {
|
|
|
130984
131074
|
var exports_fake_headless_backend = {};
|
|
130985
131075
|
__export(exports_fake_headless_backend, {
|
|
130986
131076
|
HeadlessBackend: () => HeadlessBackend,
|
|
131077
|
+
HEADLESS_BACKEND_CAPABILITIES: () => HEADLESS_BACKEND_CAPABILITIES,
|
|
130987
131078
|
FakeHeadlessBackend: () => HeadlessBackend
|
|
130988
131079
|
});
|
|
130989
131080
|
function createPage(items3) {
|
|
@@ -131077,16 +131168,7 @@ function isTerminalRun(run) {
|
|
|
131077
131168
|
}
|
|
131078
131169
|
|
|
131079
131170
|
class HeadlessBackend {
|
|
131080
|
-
capabilities =
|
|
131081
|
-
remoteMemfs: false,
|
|
131082
|
-
serverSideToolManagement: false,
|
|
131083
|
-
serverSecrets: false,
|
|
131084
|
-
agentFileImportExport: false,
|
|
131085
|
-
promptRecompile: false,
|
|
131086
|
-
byokProviderRefresh: false,
|
|
131087
|
-
localModelCatalog: true,
|
|
131088
|
-
localMemfs: false
|
|
131089
|
-
};
|
|
131171
|
+
capabilities = HEADLESS_BACKEND_CAPABILITIES;
|
|
131090
131172
|
store;
|
|
131091
131173
|
executor;
|
|
131092
131174
|
runs = new Map;
|
|
@@ -131462,13 +131544,24 @@ class HeadlessBackend {
|
|
|
131462
131544
|
};
|
|
131463
131545
|
}
|
|
131464
131546
|
}
|
|
131465
|
-
var FAKE_HEADLESS_MODEL = "dev/fake-headless";
|
|
131547
|
+
var FAKE_HEADLESS_MODEL = "dev/fake-headless", HEADLESS_BACKEND_CAPABILITIES;
|
|
131466
131548
|
var init_fake_headless_backend = __esm(() => {
|
|
131467
131549
|
init_model_handles();
|
|
131468
131550
|
init_local_store();
|
|
131469
131551
|
init_local_stream_chunks();
|
|
131470
131552
|
init_constants2();
|
|
131471
131553
|
init_local_provider_errors();
|
|
131554
|
+
HEADLESS_BACKEND_CAPABILITIES = {
|
|
131555
|
+
remoteMemfs: false,
|
|
131556
|
+
serverSideToolManagement: false,
|
|
131557
|
+
serverSecrets: false,
|
|
131558
|
+
agentFileImportExport: false,
|
|
131559
|
+
promptRecompile: false,
|
|
131560
|
+
byokProviderRefresh: false,
|
|
131561
|
+
localModelCatalog: true,
|
|
131562
|
+
localMemfs: false,
|
|
131563
|
+
environmentRouting: false
|
|
131564
|
+
};
|
|
131472
131565
|
});
|
|
131473
131566
|
|
|
131474
131567
|
// src/backend/dev/headless-backend.ts
|
|
@@ -135121,13 +135214,8 @@ var init_local_backend = __esm(() => {
|
|
|
135121
135214
|
init_system_prompt_compilation();
|
|
135122
135215
|
LocalBackend = class LocalBackend extends HeadlessBackend {
|
|
135123
135216
|
capabilities = {
|
|
135124
|
-
|
|
135125
|
-
serverSideToolManagement: false,
|
|
135126
|
-
serverSecrets: false,
|
|
135127
|
-
agentFileImportExport: false,
|
|
135217
|
+
...HEADLESS_BACKEND_CAPABILITIES,
|
|
135128
135218
|
promptRecompile: true,
|
|
135129
|
-
byokProviderRefresh: false,
|
|
135130
|
-
localModelCatalog: true,
|
|
135131
135219
|
localMemfs: true
|
|
135132
135220
|
};
|
|
135133
135221
|
memoryDir;
|
|
@@ -135554,16 +135642,19 @@ function toApiConversationMessageListBody(body) {
|
|
|
135554
135642
|
}
|
|
135555
135643
|
|
|
135556
135644
|
class APIBackend {
|
|
135557
|
-
capabilities
|
|
135558
|
-
|
|
135559
|
-
|
|
135560
|
-
|
|
135561
|
-
|
|
135562
|
-
|
|
135563
|
-
|
|
135564
|
-
|
|
135565
|
-
|
|
135566
|
-
|
|
135645
|
+
get capabilities() {
|
|
135646
|
+
return {
|
|
135647
|
+
remoteMemfs: true,
|
|
135648
|
+
serverSideToolManagement: true,
|
|
135649
|
+
serverSecrets: true,
|
|
135650
|
+
agentFileImportExport: true,
|
|
135651
|
+
promptRecompile: true,
|
|
135652
|
+
byokProviderRefresh: true,
|
|
135653
|
+
localModelCatalog: false,
|
|
135654
|
+
localMemfs: false,
|
|
135655
|
+
environmentRouting: isCloudServerUrl()
|
|
135656
|
+
};
|
|
135657
|
+
}
|
|
135567
135658
|
getApiClientOverride;
|
|
135568
135659
|
forkConversationOverride;
|
|
135569
135660
|
constructor(deps = {}) {
|
|
@@ -135785,6 +135876,7 @@ function __testSetBackend(nextBackend) {
|
|
|
135785
135876
|
}
|
|
135786
135877
|
var DEFAULT_CONVERSATION_MESSAGE_ORDER = "desc", backend = null;
|
|
135787
135878
|
var init_backend = __esm(() => {
|
|
135879
|
+
init_server_url();
|
|
135788
135880
|
init_backend_mode();
|
|
135789
135881
|
init_local_backend();
|
|
135790
135882
|
init_paths();
|
|
@@ -185598,6 +185690,8 @@ function buildChannelFeedbackPayload(submission) {
|
|
|
185598
185690
|
return withDefinedValues2({
|
|
185599
185691
|
message: submission.message,
|
|
185600
185692
|
feature: CHANNEL_FEEDBACK_FEATURE,
|
|
185693
|
+
submission_source: "slash_command",
|
|
185694
|
+
client_type: process.env.LETTA_DESKTOP_MODE === "1" ? "desktop" : "cli",
|
|
185601
185695
|
version: getVersion(),
|
|
185602
185696
|
platform: process.platform,
|
|
185603
185697
|
channel: submission.channel,
|
|
@@ -199352,330 +199446,6 @@ var init_channels = __esm(() => {
|
|
|
199352
199446
|
};
|
|
199353
199447
|
});
|
|
199354
199448
|
|
|
199355
|
-
// src/backend/api/mcp-servers.ts
|
|
199356
|
-
function getString(record3, key2) {
|
|
199357
|
-
const value = record3[key2];
|
|
199358
|
-
return typeof value === "string" ? value : null;
|
|
199359
|
-
}
|
|
199360
|
-
function parseAgentConnectedMcpServer(value) {
|
|
199361
|
-
if (!isRecord(value)) {
|
|
199362
|
-
return null;
|
|
199363
|
-
}
|
|
199364
|
-
const id2 = getString(value, "id");
|
|
199365
|
-
const serverName = getString(value, "server_name");
|
|
199366
|
-
const serverType = getString(value, "mcp_server_type");
|
|
199367
|
-
if (!id2 || !serverName || !serverType) {
|
|
199368
|
-
return null;
|
|
199369
|
-
}
|
|
199370
|
-
const target2 = getString(value, "server_url") ?? [
|
|
199371
|
-
getString(value, "command"),
|
|
199372
|
-
...Array.isArray(value.args) ? value.args : []
|
|
199373
|
-
].filter((item) => typeof item === "string").join(" ");
|
|
199374
|
-
return { id: id2, serverName, serverType, target: target2 };
|
|
199375
|
-
}
|
|
199376
|
-
function parseAgentConnectedMcpTool(value) {
|
|
199377
|
-
if (!isRecord(value)) {
|
|
199378
|
-
return null;
|
|
199379
|
-
}
|
|
199380
|
-
const id2 = getString(value, "id");
|
|
199381
|
-
const name = getString(value, "name");
|
|
199382
|
-
if (!id2 || !name) {
|
|
199383
|
-
return null;
|
|
199384
|
-
}
|
|
199385
|
-
const description = getString(value, "description");
|
|
199386
|
-
return { id: id2, name, description };
|
|
199387
|
-
}
|
|
199388
|
-
function parseAgentMcpToolRunResult(value) {
|
|
199389
|
-
if (!isRecord(value)) {
|
|
199390
|
-
throw new Error("MCP tool run returned an invalid response");
|
|
199391
|
-
}
|
|
199392
|
-
const status = getString(value, "status") ?? "unknown";
|
|
199393
|
-
return {
|
|
199394
|
-
status,
|
|
199395
|
-
funcReturn: value.func_return,
|
|
199396
|
-
stdout: value.stdout,
|
|
199397
|
-
stderr: value.stderr
|
|
199398
|
-
};
|
|
199399
|
-
}
|
|
199400
|
-
function withTimeout(promise, timeoutMs, label) {
|
|
199401
|
-
let timer;
|
|
199402
|
-
const timeout = new Promise((_4, reject2) => {
|
|
199403
|
-
timer = setTimeout(() => reject2(new Error(`${label} timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
199404
|
-
});
|
|
199405
|
-
return Promise.race([promise, timeout]).finally(() => {
|
|
199406
|
-
if (timer !== undefined)
|
|
199407
|
-
clearTimeout(timer);
|
|
199408
|
-
});
|
|
199409
|
-
}
|
|
199410
|
-
function listServerMcpServers(client, timeoutMs = 1e4) {
|
|
199411
|
-
return withTimeout(client.mcpServers.list(), timeoutMs, "Listing server-side MCP servers");
|
|
199412
|
-
}
|
|
199413
|
-
async function listAgentConnectedMcpServers(client, agentId, timeoutMs = 1e4) {
|
|
199414
|
-
const result2 = await withTimeout(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers`), timeoutMs, "Listing agent-connected MCP servers");
|
|
199415
|
-
if (!Array.isArray(result2)) {
|
|
199416
|
-
return [];
|
|
199417
|
-
}
|
|
199418
|
-
return result2.map(parseAgentConnectedMcpServer).filter((server2) => server2 !== null);
|
|
199419
|
-
}
|
|
199420
|
-
async function listAgentConnectedMcpTools(client, agentId, mcpServerId, timeoutMs = 1e4) {
|
|
199421
|
-
const result2 = await withTimeout(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers/${encodeURIComponent(mcpServerId)}/tools`), timeoutMs, "Listing agent-connected MCP server tools");
|
|
199422
|
-
if (!Array.isArray(result2)) {
|
|
199423
|
-
return [];
|
|
199424
|
-
}
|
|
199425
|
-
return result2.map(parseAgentConnectedMcpTool).filter((tool) => tool !== null);
|
|
199426
|
-
}
|
|
199427
|
-
async function runAgentConnectedMcpTool(params) {
|
|
199428
|
-
const result2 = await withTimeout(params.client.post(`/v1/agents/${encodeURIComponent(params.agentId)}/mcp-servers/${encodeURIComponent(params.mcpServerId)}/tools/${encodeURIComponent(params.toolId)}/run`, { args: params.args }), params.timeoutMs ?? 60000, "Running agent-connected MCP tool");
|
|
199429
|
-
return parseAgentMcpToolRunResult(result2);
|
|
199430
|
-
}
|
|
199431
|
-
async function listLiveServerMcpTools(client, serverName, timeoutMs = 15000) {
|
|
199432
|
-
const result2 = await withTimeout(client.get(`/v1/tools/mcp/servers/${encodeURIComponent(serverName)}/tools`), timeoutMs, `Listing tools for MCP server "${serverName}"`);
|
|
199433
|
-
if (!Array.isArray(result2))
|
|
199434
|
-
return [];
|
|
199435
|
-
return result2.filter((tool) => typeof tool === "object" && tool !== null && typeof tool.name === "string");
|
|
199436
|
-
}
|
|
199437
|
-
async function loadServerMcpEntries(client, timeoutMs = 15000) {
|
|
199438
|
-
const servers = await listServerMcpServers(client, timeoutMs);
|
|
199439
|
-
return Promise.all(servers.map(async (server2) => {
|
|
199440
|
-
try {
|
|
199441
|
-
const tools = await listLiveServerMcpTools(client, server2.server_name, timeoutMs);
|
|
199442
|
-
return { server: server2, tools };
|
|
199443
|
-
} catch (cause) {
|
|
199444
|
-
return {
|
|
199445
|
-
server: server2,
|
|
199446
|
-
tools: [],
|
|
199447
|
-
toolsError: cause instanceof Error ? cause.message : String(cause)
|
|
199448
|
-
};
|
|
199449
|
-
}
|
|
199450
|
-
}));
|
|
199451
|
-
}
|
|
199452
|
-
function parseMcpMetadata(tool) {
|
|
199453
|
-
const metadata = tool.metadata_;
|
|
199454
|
-
const mcp = metadata?.mcp;
|
|
199455
|
-
if (typeof mcp !== "object" || mcp === null)
|
|
199456
|
-
return null;
|
|
199457
|
-
const { server_id, server_name } = mcp;
|
|
199458
|
-
return {
|
|
199459
|
-
...typeof server_id === "string" && { serverId: server_id },
|
|
199460
|
-
...typeof server_name === "string" && { serverName: server_name }
|
|
199461
|
-
};
|
|
199462
|
-
}
|
|
199463
|
-
async function listAgentMcpAttachments(client, agentId) {
|
|
199464
|
-
const attachments = [];
|
|
199465
|
-
for await (const tool of client.agents.tools.list(agentId, { limit: 100 })) {
|
|
199466
|
-
if (tool.tool_type !== "external_mcp" || !tool.id || !tool.name)
|
|
199467
|
-
continue;
|
|
199468
|
-
attachments.push({
|
|
199469
|
-
toolId: tool.id,
|
|
199470
|
-
toolName: tool.name,
|
|
199471
|
-
...parseMcpMetadata(tool)
|
|
199472
|
-
});
|
|
199473
|
-
}
|
|
199474
|
-
return attachments;
|
|
199475
|
-
}
|
|
199476
|
-
function attachmentsForEntry(entry, attachments) {
|
|
199477
|
-
return attachments.filter((attachment) => attachment.serverId && entry.server.id ? attachment.serverId === entry.server.id : attachment.serverName === entry.server.server_name);
|
|
199478
|
-
}
|
|
199479
|
-
function attachedToolNamesForEntry(entry, attachments) {
|
|
199480
|
-
return new Set(attachmentsForEntry(entry, attachments).map((attachment) => attachment.toolName));
|
|
199481
|
-
}
|
|
199482
|
-
async function registerServerMcpTool(client, serverName, toolName) {
|
|
199483
|
-
const result2 = await client.post(`/v1/tools/mcp/servers/${encodeURIComponent(serverName)}/${encodeURIComponent(toolName)}`);
|
|
199484
|
-
if (typeof result2?.id !== "string") {
|
|
199485
|
-
throw new Error(`Registering MCP tool "${toolName}" on server "${serverName}" returned no tool id`);
|
|
199486
|
-
}
|
|
199487
|
-
return { id: result2.id };
|
|
199488
|
-
}
|
|
199489
|
-
async function attachServerMcpTools(client, agentId, serverName, toolNames) {
|
|
199490
|
-
await Promise.all(toolNames.map(async (toolName) => {
|
|
199491
|
-
const { id: id2 } = await registerServerMcpTool(client, serverName, toolName);
|
|
199492
|
-
await client.agents.tools.attach(id2, { agent_id: agentId });
|
|
199493
|
-
}));
|
|
199494
|
-
}
|
|
199495
|
-
async function detachServerMcpTools(client, agentId, toolIds) {
|
|
199496
|
-
await Promise.all(toolIds.map((toolId) => client.agents.tools.detach(toolId, { agent_id: agentId })));
|
|
199497
|
-
}
|
|
199498
|
-
function refreshServerMcpServer(client, mcpServerId, agentId) {
|
|
199499
|
-
return client.mcpServers.refresh(mcpServerId, { agent_id: agentId });
|
|
199500
|
-
}
|
|
199501
|
-
function planServerMcpToggle(entry, attachments) {
|
|
199502
|
-
const attached = attachmentsForEntry(entry, attachments);
|
|
199503
|
-
if (attached.length > 0) {
|
|
199504
|
-
return {
|
|
199505
|
-
action: "detach",
|
|
199506
|
-
toolIds: attached.map((attachment) => attachment.toolId)
|
|
199507
|
-
};
|
|
199508
|
-
}
|
|
199509
|
-
return { action: "attach", toolNames: entry.tools.map((tool) => tool.name) };
|
|
199510
|
-
}
|
|
199511
|
-
function describeServerMcpTarget(server2) {
|
|
199512
|
-
if ("server_url" in server2 && server2.server_url) {
|
|
199513
|
-
return server2.server_url;
|
|
199514
|
-
}
|
|
199515
|
-
if ("command" in server2 && server2.command) {
|
|
199516
|
-
return [server2.command, ...server2.args ?? []].join(" ");
|
|
199517
|
-
}
|
|
199518
|
-
return "";
|
|
199519
|
-
}
|
|
199520
|
-
var init_mcp_servers2 = () => {};
|
|
199521
|
-
|
|
199522
|
-
// src/cli/subcommands/cloud-mcp.ts
|
|
199523
|
-
import { parseArgs as parseArgs4 } from "node:util";
|
|
199524
|
-
function printUsage4(stdout = console.log) {
|
|
199525
|
-
stdout(`
|
|
199526
|
-
Usage:
|
|
199527
|
-
letta cloud-mcp list [--agent <id>]
|
|
199528
|
-
letta cloud-mcp tools <mcp-server-id> [--agent <id>]
|
|
199529
|
-
letta cloud-mcp run <mcp-server-id> <tool-id> [--args '<json>'] [--agent <id>]
|
|
199530
|
-
|
|
199531
|
-
Actions:
|
|
199532
|
-
list List MCP servers connected to the agent
|
|
199533
|
-
tools List registered tools for one connected MCP server
|
|
199534
|
-
run Run one registered MCP tool through the agent-scoped server route
|
|
199535
|
-
|
|
199536
|
-
Aliases:
|
|
199537
|
-
list-servers, list_servers Alias for list
|
|
199538
|
-
list-tools, list_tools Alias for tools
|
|
199539
|
-
call, run-tool, run_tool Alias for run
|
|
199540
|
-
|
|
199541
|
-
Options:
|
|
199542
|
-
--agent <id> Agent ID. Defaults to LETTA_AGENT_ID or AGENT_ID
|
|
199543
|
-
--agent-id <id> Alias for --agent
|
|
199544
|
-
--args '<json>' JSON object passed as MCP tool arguments for run
|
|
199545
|
-
-h, --help Show this help
|
|
199546
|
-
|
|
199547
|
-
Notes:
|
|
199548
|
-
- Output is JSON only.
|
|
199549
|
-
- Requires a signed-in Letta Cloud agent with server-side MCP support.
|
|
199550
|
-
- Uses CLI auth; override with LETTA_API_KEY/LETTA_BASE_URL if needed.
|
|
199551
|
-
`.trim());
|
|
199552
|
-
}
|
|
199553
|
-
function parseCloudMcpArgs(argv) {
|
|
199554
|
-
return parseArgs4({
|
|
199555
|
-
args: argv,
|
|
199556
|
-
options: {
|
|
199557
|
-
help: { type: "boolean", short: "h" },
|
|
199558
|
-
agent: { type: "string" },
|
|
199559
|
-
"agent-id": { type: "string" },
|
|
199560
|
-
args: { type: "string" }
|
|
199561
|
-
},
|
|
199562
|
-
strict: true,
|
|
199563
|
-
allowPositionals: true
|
|
199564
|
-
});
|
|
199565
|
-
}
|
|
199566
|
-
function stringValue3(value) {
|
|
199567
|
-
return typeof value === "string" ? value : undefined;
|
|
199568
|
-
}
|
|
199569
|
-
function resolveCloudMcpAgentId(agent, agentId, env4 = process.env) {
|
|
199570
|
-
return (agent || agentId || env4.LETTA_AGENT_ID || env4.AGENT_ID || "").trim();
|
|
199571
|
-
}
|
|
199572
|
-
function parseToolArgs(value) {
|
|
199573
|
-
const raw2 = stringValue3(value);
|
|
199574
|
-
if (!raw2) {
|
|
199575
|
-
return {};
|
|
199576
|
-
}
|
|
199577
|
-
let parsed;
|
|
199578
|
-
try {
|
|
199579
|
-
parsed = JSON.parse(raw2);
|
|
199580
|
-
} catch (error4) {
|
|
199581
|
-
const message = error4 instanceof Error ? error4.message : String(error4);
|
|
199582
|
-
throw new Error(`Invalid --args JSON: ${message}`);
|
|
199583
|
-
}
|
|
199584
|
-
if (!isRecord(parsed)) {
|
|
199585
|
-
throw new Error("Invalid --args JSON: expected a JSON object");
|
|
199586
|
-
}
|
|
199587
|
-
return parsed;
|
|
199588
|
-
}
|
|
199589
|
-
function printJson(stdout, result2) {
|
|
199590
|
-
stdout(JSON.stringify(result2, null, 2));
|
|
199591
|
-
}
|
|
199592
|
-
async function defaultGetClient() {
|
|
199593
|
-
const client = await getClient();
|
|
199594
|
-
return client;
|
|
199595
|
-
}
|
|
199596
|
-
async function runCloudMcpSubcommand(argv, deps = {}) {
|
|
199597
|
-
const stdout = deps.stdout ?? console.log;
|
|
199598
|
-
const stderr = deps.stderr ?? console.error;
|
|
199599
|
-
let parsed;
|
|
199600
|
-
try {
|
|
199601
|
-
parsed = parseCloudMcpArgs(argv);
|
|
199602
|
-
} catch (error4) {
|
|
199603
|
-
const message = error4 instanceof Error ? error4.message : String(error4);
|
|
199604
|
-
stderr(`Error: ${message}`);
|
|
199605
|
-
printUsage4(stdout);
|
|
199606
|
-
return 1;
|
|
199607
|
-
}
|
|
199608
|
-
const [action3, mcpServerId, toolId] = parsed.positionals;
|
|
199609
|
-
if (parsed.values.help || !action3 || action3 === "help") {
|
|
199610
|
-
printUsage4(stdout);
|
|
199611
|
-
return 0;
|
|
199612
|
-
}
|
|
199613
|
-
const isAvailable = deps.isServerSideMcpAvailable ?? (() => getBackend().capabilities.serverSideToolManagement);
|
|
199614
|
-
if (!isAvailable()) {
|
|
199615
|
-
stderr("Server-side MCP requires a signed-in Letta Cloud agent; the local backend does not support it.");
|
|
199616
|
-
return 1;
|
|
199617
|
-
}
|
|
199618
|
-
const agentId = resolveCloudMcpAgentId(stringValue3(parsed.values.agent), stringValue3(parsed.values["agent-id"]));
|
|
199619
|
-
if (!agentId) {
|
|
199620
|
-
stderr("Agent id required: pass --agent <id> or set LETTA_AGENT_ID/AGENT_ID.");
|
|
199621
|
-
return 1;
|
|
199622
|
-
}
|
|
199623
|
-
await (deps.initializeSettings ?? (() => settingsManager.initialize()))();
|
|
199624
|
-
const client = await (deps.getClient ?? defaultGetClient)();
|
|
199625
|
-
try {
|
|
199626
|
-
if (action3 === "list" || action3 === "list-servers" || action3 === "list_servers") {
|
|
199627
|
-
printJson(stdout, {
|
|
199628
|
-
agent_id: agentId,
|
|
199629
|
-
servers: await listAgentConnectedMcpServers(client, agentId)
|
|
199630
|
-
});
|
|
199631
|
-
return 0;
|
|
199632
|
-
}
|
|
199633
|
-
if (action3 === "tools" || action3 === "list-tools" || action3 === "list_tools") {
|
|
199634
|
-
if (!mcpServerId) {
|
|
199635
|
-
stderr("Usage: letta cloud-mcp tools <mcp-server-id> [--agent <id>]");
|
|
199636
|
-
return 1;
|
|
199637
|
-
}
|
|
199638
|
-
printJson(stdout, {
|
|
199639
|
-
agent_id: agentId,
|
|
199640
|
-
mcp_server_id: mcpServerId,
|
|
199641
|
-
tools: await listAgentConnectedMcpTools(client, agentId, mcpServerId)
|
|
199642
|
-
});
|
|
199643
|
-
return 0;
|
|
199644
|
-
}
|
|
199645
|
-
if (action3 === "run" || action3 === "call" || action3 === "run-tool" || action3 === "run_tool") {
|
|
199646
|
-
if (!mcpServerId || !toolId) {
|
|
199647
|
-
stderr("Usage: letta cloud-mcp run <mcp-server-id> <tool-id> [--args '<json>'] [--agent <id>]");
|
|
199648
|
-
return 1;
|
|
199649
|
-
}
|
|
199650
|
-
printJson(stdout, {
|
|
199651
|
-
agent_id: agentId,
|
|
199652
|
-
mcp_server_id: mcpServerId,
|
|
199653
|
-
tool_id: toolId,
|
|
199654
|
-
result: await runAgentConnectedMcpTool({
|
|
199655
|
-
client,
|
|
199656
|
-
agentId,
|
|
199657
|
-
mcpServerId,
|
|
199658
|
-
toolId,
|
|
199659
|
-
args: parseToolArgs(parsed.values.args)
|
|
199660
|
-
})
|
|
199661
|
-
});
|
|
199662
|
-
return 0;
|
|
199663
|
-
}
|
|
199664
|
-
stderr(`Unknown cloud-mcp action: ${action3}`);
|
|
199665
|
-
printUsage4(stdout);
|
|
199666
|
-
return 1;
|
|
199667
|
-
} catch (error4) {
|
|
199668
|
-
stderr(error4 instanceof Error ? error4.message : String(error4));
|
|
199669
|
-
return 1;
|
|
199670
|
-
}
|
|
199671
|
-
}
|
|
199672
|
-
var init_cloud_mcp = __esm(() => {
|
|
199673
|
-
init_backend2();
|
|
199674
|
-
init_client2();
|
|
199675
|
-
init_mcp_servers2();
|
|
199676
|
-
init_settings_manager();
|
|
199677
|
-
});
|
|
199678
|
-
|
|
199679
199449
|
// src/auth/openai-oauth.ts
|
|
199680
199450
|
import http3 from "node:http";
|
|
199681
199451
|
function renderOAuthPage(options) {
|
|
@@ -200799,7 +200569,7 @@ var init_connect_normalize = __esm(() => {
|
|
|
200799
200569
|
// src/cli/subcommands/connect.ts
|
|
200800
200570
|
import { createInterface as createInterface6 } from "node:readline/promises";
|
|
200801
200571
|
import { Writable } from "node:stream";
|
|
200802
|
-
import { parseArgs as
|
|
200572
|
+
import { parseArgs as parseArgs4 } from "node:util";
|
|
200803
200573
|
function readStringOption(value) {
|
|
200804
200574
|
if (typeof value === "string") {
|
|
200805
200575
|
return value;
|
|
@@ -200891,7 +200661,7 @@ async function runConnectSubcommand(argv, deps = {}) {
|
|
|
200891
200661
|
const io = { ...DEFAULT_DEPS2, ...deps };
|
|
200892
200662
|
let parsed;
|
|
200893
200663
|
try {
|
|
200894
|
-
parsed =
|
|
200664
|
+
parsed = parseArgs4({
|
|
200895
200665
|
args: argv,
|
|
200896
200666
|
options: CONNECT_OPTIONS,
|
|
200897
200667
|
strict: true,
|
|
@@ -210101,8 +209871,8 @@ var init_cron_task_ref = __esm(async () => {
|
|
|
210101
209871
|
});
|
|
210102
209872
|
|
|
210103
209873
|
// src/cli/subcommands/cron.ts
|
|
210104
|
-
import { parseArgs as
|
|
210105
|
-
function
|
|
209874
|
+
import { parseArgs as parseArgs5 } from "node:util";
|
|
209875
|
+
function printUsage4() {
|
|
210106
209876
|
console.log(`
|
|
210107
209877
|
Usage:
|
|
210108
209878
|
letta cron add --prompt <text> --every <interval> [options]
|
|
@@ -210156,7 +209926,7 @@ Output is JSON.
|
|
|
210156
209926
|
`.trim());
|
|
210157
209927
|
}
|
|
210158
209928
|
function parseCronArgs(argv) {
|
|
210159
|
-
return
|
|
209929
|
+
return parseArgs5({
|
|
210160
209930
|
args: argv,
|
|
210161
209931
|
options: CRON_OPTIONS,
|
|
210162
209932
|
strict: true,
|
|
@@ -210712,12 +210482,12 @@ async function runCronSubcommand(argv) {
|
|
|
210712
210482
|
parsed = parseCronArgs(argv);
|
|
210713
210483
|
} catch (err) {
|
|
210714
210484
|
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
210715
|
-
|
|
210485
|
+
printUsage4();
|
|
210716
210486
|
return 1;
|
|
210717
210487
|
}
|
|
210718
210488
|
const [action3] = parsed.positionals;
|
|
210719
210489
|
if (parsed.values.help || !action3 || action3 === "help") {
|
|
210720
|
-
|
|
210490
|
+
printUsage4();
|
|
210721
210491
|
return 0;
|
|
210722
210492
|
}
|
|
210723
210493
|
switch (action3) {
|
|
@@ -210734,7 +210504,7 @@ async function runCronSubcommand(argv) {
|
|
|
210734
210504
|
return handleDelete(parsed.values, parsed.positionals);
|
|
210735
210505
|
default:
|
|
210736
210506
|
console.error(`Unknown action: ${action3}`);
|
|
210737
|
-
|
|
210507
|
+
printUsage4();
|
|
210738
210508
|
return 1;
|
|
210739
210509
|
}
|
|
210740
210510
|
}
|
|
@@ -210770,8 +210540,8 @@ var init_cron2 = __esm(async () => {
|
|
|
210770
210540
|
});
|
|
210771
210541
|
|
|
210772
210542
|
// src/cli/subcommands/environments.ts
|
|
210773
|
-
import { parseArgs as
|
|
210774
|
-
function
|
|
210543
|
+
import { parseArgs as parseArgs6 } from "node:util";
|
|
210544
|
+
function printUsage5() {
|
|
210775
210545
|
console.log(`
|
|
210776
210546
|
Usage:
|
|
210777
210547
|
letta environments list [options]
|
|
@@ -210839,7 +210609,7 @@ function scoreCurrentEnvironment(environment2, options) {
|
|
|
210839
210609
|
return score;
|
|
210840
210610
|
}
|
|
210841
210611
|
function parseEnvironmentsArgs(argv) {
|
|
210842
|
-
return
|
|
210612
|
+
return parseArgs6({
|
|
210843
210613
|
args: argv,
|
|
210844
210614
|
options: ENVIRONMENTS_OPTIONS,
|
|
210845
210615
|
strict: true,
|
|
@@ -210853,17 +210623,17 @@ async function runEnvironmentsSubcommand(argv, deps = {}) {
|
|
|
210853
210623
|
} catch (error4) {
|
|
210854
210624
|
const message = error4 instanceof Error ? error4.message : String(error4);
|
|
210855
210625
|
console.error(`Error: ${message}`);
|
|
210856
|
-
|
|
210626
|
+
printUsage5();
|
|
210857
210627
|
return 1;
|
|
210858
210628
|
}
|
|
210859
210629
|
const [action3] = parsed.positionals;
|
|
210860
210630
|
if (parsed.values.help || !action3 || action3 === "help") {
|
|
210861
|
-
|
|
210631
|
+
printUsage5();
|
|
210862
210632
|
return 0;
|
|
210863
210633
|
}
|
|
210864
210634
|
if (action3 !== "list" && action3 !== "current") {
|
|
210865
210635
|
console.error(`Unknown action: ${action3}`);
|
|
210866
|
-
|
|
210636
|
+
printUsage5();
|
|
210867
210637
|
return 1;
|
|
210868
210638
|
}
|
|
210869
210639
|
await (deps.initializeSettings ?? (() => settingsManager.initialize()))();
|
|
@@ -210925,8 +210695,8 @@ var init_environments3 = __esm(() => {
|
|
|
210925
210695
|
});
|
|
210926
210696
|
|
|
210927
210697
|
// src/cli/subcommands/feedback.ts
|
|
210928
|
-
import { parseArgs as
|
|
210929
|
-
function
|
|
210698
|
+
import { parseArgs as parseArgs7 } from "node:util";
|
|
210699
|
+
function printUsage6(stdout = console.log) {
|
|
210930
210700
|
stdout(`
|
|
210931
210701
|
Usage:
|
|
210932
210702
|
letta feedback --message <text>
|
|
@@ -210944,7 +210714,7 @@ async function runFeedbackSubcommand(argv, deps = {}) {
|
|
|
210944
210714
|
const stderr = deps.stderr ?? console.error;
|
|
210945
210715
|
let parsed;
|
|
210946
210716
|
try {
|
|
210947
|
-
parsed =
|
|
210717
|
+
parsed = parseArgs7({
|
|
210948
210718
|
args: argv,
|
|
210949
210719
|
options: {
|
|
210950
210720
|
help: { type: "boolean", short: "h" },
|
|
@@ -210955,11 +210725,11 @@ async function runFeedbackSubcommand(argv, deps = {}) {
|
|
|
210955
210725
|
});
|
|
210956
210726
|
} catch (error4) {
|
|
210957
210727
|
stderr(error4 instanceof Error ? error4.message : String(error4));
|
|
210958
|
-
|
|
210728
|
+
printUsage6(stdout);
|
|
210959
210729
|
return 1;
|
|
210960
210730
|
}
|
|
210961
210731
|
if (parsed.values.help) {
|
|
210962
|
-
|
|
210732
|
+
printUsage6(stdout);
|
|
210963
210733
|
return 0;
|
|
210964
210734
|
}
|
|
210965
210735
|
const message = typeof parsed.values.message === "string" ? parsed.values.message.trim() : "";
|
|
@@ -210982,6 +210752,8 @@ async function runFeedbackSubcommand(argv, deps = {}) {
|
|
|
210982
210752
|
await (deps.submitFeedback ?? submitFeedbackMetadata)(apiKey, (deps.getDeviceId ?? (() => settingsManager.getOrCreateDeviceId()))(), {
|
|
210983
210753
|
message,
|
|
210984
210754
|
feature: "letta-code-agent-feedback",
|
|
210755
|
+
submission_source: "agent_skill",
|
|
210756
|
+
client_type: (deps.getClientType ?? getFeedbackClientType)(),
|
|
210985
210757
|
version: getVersion(),
|
|
210986
210758
|
platform: process.platform,
|
|
210987
210759
|
agent_id: agentId || undefined,
|
|
@@ -238705,9 +238477,9 @@ ${lanes.join(`
|
|
|
238705
238477
|
function isJsonEqual(a2, b3) {
|
|
238706
238478
|
return a2 === b3 || typeof a2 === "object" && a2 !== null && typeof b3 === "object" && b3 !== null && equalOwnProperties(a2, b3, isJsonEqual);
|
|
238707
238479
|
}
|
|
238708
|
-
function parsePseudoBigInt(
|
|
238480
|
+
function parsePseudoBigInt(stringValue3) {
|
|
238709
238481
|
let log2Base;
|
|
238710
|
-
switch (
|
|
238482
|
+
switch (stringValue3.charCodeAt(1)) {
|
|
238711
238483
|
case 98:
|
|
238712
238484
|
case 66:
|
|
238713
238485
|
log2Base = 1;
|
|
@@ -238721,19 +238493,19 @@ ${lanes.join(`
|
|
|
238721
238493
|
log2Base = 4;
|
|
238722
238494
|
break;
|
|
238723
238495
|
default:
|
|
238724
|
-
const nIndex =
|
|
238496
|
+
const nIndex = stringValue3.length - 1;
|
|
238725
238497
|
let nonZeroStart = 0;
|
|
238726
|
-
while (
|
|
238498
|
+
while (stringValue3.charCodeAt(nonZeroStart) === 48) {
|
|
238727
238499
|
nonZeroStart++;
|
|
238728
238500
|
}
|
|
238729
|
-
return
|
|
238501
|
+
return stringValue3.slice(nonZeroStart, nIndex) || "0";
|
|
238730
238502
|
}
|
|
238731
|
-
const startIndex = 2, endIndex =
|
|
238503
|
+
const startIndex = 2, endIndex = stringValue3.length - 1;
|
|
238732
238504
|
const bitsNeeded = (endIndex - startIndex) * log2Base;
|
|
238733
238505
|
const segments = new Uint16Array((bitsNeeded >>> 4) + (bitsNeeded & 15 ? 1 : 0));
|
|
238734
238506
|
for (let i4 = endIndex - 1, bitOffset = 0;i4 >= startIndex; i4--, bitOffset += log2Base) {
|
|
238735
238507
|
const segment = bitOffset >>> 4;
|
|
238736
|
-
const digitChar =
|
|
238508
|
+
const digitChar = stringValue3.charCodeAt(i4);
|
|
238737
238509
|
const digit = digitChar <= 57 ? digitChar - 48 : 10 + digitChar - (digitChar <= 70 ? 65 : 97);
|
|
238738
238510
|
const shiftedDigit = digit << (bitOffset & 15);
|
|
238739
238511
|
segments[segment] |= shiftedDigit;
|
|
@@ -391797,7 +391569,7 @@ function toRunsArray(listResponse) {
|
|
|
391797
391569
|
}
|
|
391798
391570
|
return [];
|
|
391799
391571
|
}
|
|
391800
|
-
function
|
|
391572
|
+
function withTimeout(promise, timeoutMs, timeoutMessage) {
|
|
391801
391573
|
return new Promise((resolve34, reject2) => {
|
|
391802
391574
|
const timer = setTimeout(() => reject2(new Error(timeoutMessage)), timeoutMs);
|
|
391803
391575
|
promise.then((value) => {
|
|
@@ -391811,7 +391583,7 @@ function withTimeout2(promise, timeoutMs, timeoutMessage) {
|
|
|
391811
391583
|
}
|
|
391812
391584
|
async function discoverFallbackRunIdWithTimeout(ctx) {
|
|
391813
391585
|
const client = await getClient();
|
|
391814
|
-
return
|
|
391586
|
+
return withTimeout(discoverFallbackRunIdForResume(client, ctx), FALLBACK_RUN_DISCOVERY_TIMEOUT_MS, `Fallback run discovery timed out after ${FALLBACK_RUN_DISCOVERY_TIMEOUT_MS}ms`);
|
|
391815
391587
|
}
|
|
391816
391588
|
async function discoverFallbackRunIdForResume(client, ctx) {
|
|
391817
391589
|
const statuses = ["running"];
|
|
@@ -392548,7 +392320,7 @@ function formatMissingRequiredArgsReason(toolName, parsedArgs, missingRequiredAr
|
|
|
392548
392320
|
}
|
|
392549
392321
|
return base2;
|
|
392550
392322
|
}
|
|
392551
|
-
function
|
|
392323
|
+
function parseToolArgs(rawArgs) {
|
|
392552
392324
|
const raw2 = rawArgs ?? "";
|
|
392553
392325
|
const trimmed = raw2.trim();
|
|
392554
392326
|
if (!trimmed) {
|
|
@@ -392593,7 +392365,7 @@ async function classifyApprovals(approvals, opts = {}) {
|
|
|
392593
392365
|
});
|
|
392594
392366
|
continue;
|
|
392595
392367
|
}
|
|
392596
|
-
const argsParse =
|
|
392368
|
+
const argsParse = parseToolArgs(approval.toolArgs);
|
|
392597
392369
|
const parsedArgs = argsParse.parsedArgs;
|
|
392598
392370
|
if (argsParse.parseFailed) {
|
|
392599
392371
|
debugWarn("approval-classification", `Tool call ${approval.toolCallId} (${toolName}) had unparseable arguments ` + `(${argsParse.rawLength} chars); treating as empty`);
|
|
@@ -403485,6 +403257,16 @@ var init_catalog = __esm(() => {
|
|
|
403485
403257
|
"listen"
|
|
403486
403258
|
]
|
|
403487
403259
|
},
|
|
403260
|
+
{
|
|
403261
|
+
id: "mcp-servers-info",
|
|
403262
|
+
description: "MCP servers with tools available through letta mcp",
|
|
403263
|
+
modes: [
|
|
403264
|
+
"interactive",
|
|
403265
|
+
"headless-one-shot",
|
|
403266
|
+
"headless-bidirectional",
|
|
403267
|
+
"listen"
|
|
403268
|
+
]
|
|
403269
|
+
},
|
|
403488
403270
|
{
|
|
403489
403271
|
id: "permission-mode",
|
|
403490
403272
|
description: "Permission mode reminder",
|
|
@@ -403520,6 +403302,167 @@ var init_catalog = __esm(() => {
|
|
|
403520
403302
|
SHARED_REMINDER_BY_ID = new Map(SHARED_REMINDER_CATALOG.map((entry) => [entry.id, entry]));
|
|
403521
403303
|
});
|
|
403522
403304
|
|
|
403305
|
+
// src/backend/api/unified-mcp.ts
|
|
403306
|
+
var exports_unified_mcp = {};
|
|
403307
|
+
__export(exports_unified_mcp, {
|
|
403308
|
+
searchUnifiedMcpTools: () => searchUnifiedMcpTools,
|
|
403309
|
+
runUnifiedMcpTool: () => runUnifiedMcpTool,
|
|
403310
|
+
listUnifiedMcpTools: () => listUnifiedMcpTools,
|
|
403311
|
+
listUnifiedMcpServers: () => listUnifiedMcpServers
|
|
403312
|
+
});
|
|
403313
|
+
function stringField2(value, key2) {
|
|
403314
|
+
return typeof value[key2] === "string" ? value[key2] : null;
|
|
403315
|
+
}
|
|
403316
|
+
function recordField(value, ...names2) {
|
|
403317
|
+
for (const name of names2) {
|
|
403318
|
+
const field = value[name];
|
|
403319
|
+
if (isRecord(field))
|
|
403320
|
+
return field;
|
|
403321
|
+
}
|
|
403322
|
+
return;
|
|
403323
|
+
}
|
|
403324
|
+
function parseServer(value, registered) {
|
|
403325
|
+
if (!isRecord(value))
|
|
403326
|
+
return null;
|
|
403327
|
+
const id2 = stringField2(value, "id");
|
|
403328
|
+
const serverName = stringField2(value, "server_name") ?? (registered ? stringField2(registered, "server_name") : null);
|
|
403329
|
+
const serverType = stringField2(value, "mcp_server_type") ?? (registered ? stringField2(registered, "mcp_server_type") : null) ?? "unknown";
|
|
403330
|
+
if (!id2 || !serverName)
|
|
403331
|
+
return null;
|
|
403332
|
+
const serverUrl = stringField2(value, "server_url") ?? (registered ? stringField2(registered, "server_url") : null) ?? undefined;
|
|
403333
|
+
const command = stringField2(value, "command") ?? (registered ? stringField2(registered, "command") : null) ?? undefined;
|
|
403334
|
+
const argsValue = value.args ?? registered?.args;
|
|
403335
|
+
const args = Array.isArray(argsValue) ? argsValue.filter((item) => typeof item === "string") : [];
|
|
403336
|
+
const target2 = serverUrl ?? [command, ...args].filter(Boolean).join(" ");
|
|
403337
|
+
return {
|
|
403338
|
+
id: id2,
|
|
403339
|
+
serverName,
|
|
403340
|
+
serverType,
|
|
403341
|
+
target: target2,
|
|
403342
|
+
...serverUrl ? { serverUrl } : {},
|
|
403343
|
+
...command ? { command, args } : {}
|
|
403344
|
+
};
|
|
403345
|
+
}
|
|
403346
|
+
function parseTool(value) {
|
|
403347
|
+
if (!isRecord(value))
|
|
403348
|
+
return null;
|
|
403349
|
+
const id2 = stringField2(value, "id");
|
|
403350
|
+
const name = stringField2(value, "name");
|
|
403351
|
+
if (!id2 || !name)
|
|
403352
|
+
return null;
|
|
403353
|
+
const description = stringField2(value, "description");
|
|
403354
|
+
const jsonSchema = isRecord(value.json_schema) ? value.json_schema : {};
|
|
403355
|
+
const inputSchema = isRecord(jsonSchema.parameters) ? jsonSchema.parameters : isRecord(value.args_json_schema) ? value.args_json_schema : { type: "object", properties: {} };
|
|
403356
|
+
const title = stringField2(value, "title") ?? stringField2(jsonSchema, "title");
|
|
403357
|
+
const outputSchema = recordField(value, "outputSchema", "output_schema") ?? recordField(jsonSchema, "outputSchema", "output_schema");
|
|
403358
|
+
const annotations = recordField(value, "annotations") ?? recordField(jsonSchema, "annotations");
|
|
403359
|
+
const execution = recordField(value, "execution") ?? recordField(jsonSchema, "execution");
|
|
403360
|
+
const meta = recordField(value, "_meta") ?? recordField(jsonSchema, "_meta");
|
|
403361
|
+
const iconsValue = value.icons ?? jsonSchema.icons;
|
|
403362
|
+
const icons = Array.isArray(iconsValue) ? iconsValue.filter(isRecord) : undefined;
|
|
403363
|
+
return {
|
|
403364
|
+
id: id2,
|
|
403365
|
+
name,
|
|
403366
|
+
...title ? { title } : {},
|
|
403367
|
+
description,
|
|
403368
|
+
inputSchema,
|
|
403369
|
+
...outputSchema ? { outputSchema } : {},
|
|
403370
|
+
...annotations ? { annotations } : {},
|
|
403371
|
+
...execution ? { execution } : {},
|
|
403372
|
+
...meta ? { _meta: meta } : {},
|
|
403373
|
+
...icons ? { icons } : {}
|
|
403374
|
+
};
|
|
403375
|
+
}
|
|
403376
|
+
function parseRunResult(value) {
|
|
403377
|
+
if (!isRecord(value))
|
|
403378
|
+
throw new Error("Invalid MCP tool run response");
|
|
403379
|
+
return {
|
|
403380
|
+
status: stringField2(value, "status") ?? "unknown",
|
|
403381
|
+
funcReturn: value.func_return,
|
|
403382
|
+
stdout: value.stdout,
|
|
403383
|
+
stderr: value.stderr
|
|
403384
|
+
};
|
|
403385
|
+
}
|
|
403386
|
+
function parseSearchResult(value) {
|
|
403387
|
+
if (!isRecord(value) || !isRecord(value.tool))
|
|
403388
|
+
return null;
|
|
403389
|
+
const toolId = stringField2(value.tool, "id");
|
|
403390
|
+
const jsonSchema = value.tool.json_schema;
|
|
403391
|
+
const score = value.combined_score;
|
|
403392
|
+
if (!toolId || jsonSchema !== null && !isRecord(jsonSchema) || typeof score !== "number") {
|
|
403393
|
+
return null;
|
|
403394
|
+
}
|
|
403395
|
+
return { toolId, jsonSchema, score };
|
|
403396
|
+
}
|
|
403397
|
+
async function withTimeout2(promise, timeoutMs, operation) {
|
|
403398
|
+
let timer;
|
|
403399
|
+
try {
|
|
403400
|
+
return await Promise.race([
|
|
403401
|
+
promise,
|
|
403402
|
+
new Promise((_resolve, reject2) => {
|
|
403403
|
+
timer = setTimeout(() => reject2(new Error(`${operation} timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
403404
|
+
})
|
|
403405
|
+
]);
|
|
403406
|
+
} finally {
|
|
403407
|
+
if (timer)
|
|
403408
|
+
clearTimeout(timer);
|
|
403409
|
+
}
|
|
403410
|
+
}
|
|
403411
|
+
async function listUnifiedMcpServers(client, agentId, timeoutMs = 1e4) {
|
|
403412
|
+
const value = await withTimeout2(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers`), timeoutMs, "Listing agent MCP servers");
|
|
403413
|
+
if (!Array.isArray(value))
|
|
403414
|
+
return [];
|
|
403415
|
+
const needsEnrichment = value.some((item) => isRecord(item) && !stringField2(item, "mcp_server_type"));
|
|
403416
|
+
const registeredById = new Map;
|
|
403417
|
+
if (needsEnrichment && client.mcpServers) {
|
|
403418
|
+
try {
|
|
403419
|
+
const registered = await withTimeout2(client.mcpServers.list(), timeoutMs, "Listing registered MCP servers");
|
|
403420
|
+
for (const item of registered) {
|
|
403421
|
+
if (!isRecord(item))
|
|
403422
|
+
continue;
|
|
403423
|
+
const id2 = stringField2(item, "id");
|
|
403424
|
+
if (id2)
|
|
403425
|
+
registeredById.set(id2, item);
|
|
403426
|
+
}
|
|
403427
|
+
} catch {}
|
|
403428
|
+
}
|
|
403429
|
+
return value.map((item) => {
|
|
403430
|
+
const registered = isRecord(item) ? registeredById.get(stringField2(item, "id") ?? "") : undefined;
|
|
403431
|
+
return parseServer(item, registered);
|
|
403432
|
+
}).filter((server2) => server2 !== null);
|
|
403433
|
+
}
|
|
403434
|
+
async function listUnifiedMcpTools(client, agentId, mcpServerId, timeoutMs = 1e4) {
|
|
403435
|
+
const value = await withTimeout2(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers/${encodeURIComponent(mcpServerId)}/tools`), timeoutMs, "Listing agent MCP server tools");
|
|
403436
|
+
if (!Array.isArray(value))
|
|
403437
|
+
return [];
|
|
403438
|
+
return value.map(parseTool).filter((tool) => tool !== null);
|
|
403439
|
+
}
|
|
403440
|
+
async function searchUnifiedMcpTools(params) {
|
|
403441
|
+
const value = await withTimeout2(params.client.post(`/v1/agents/${encodeURIComponent(params.agentId)}/mcp-servers/tools/search`, {
|
|
403442
|
+
body: {
|
|
403443
|
+
query: params.query,
|
|
403444
|
+
search_mode: params.searchMode,
|
|
403445
|
+
limit: params.limit
|
|
403446
|
+
}
|
|
403447
|
+
}), params.timeoutMs ?? 60000, "Searching agent MCP tools");
|
|
403448
|
+
if (!Array.isArray(value)) {
|
|
403449
|
+
throw new Error("Invalid MCP tool search response");
|
|
403450
|
+
}
|
|
403451
|
+
const results = [];
|
|
403452
|
+
for (const item of value) {
|
|
403453
|
+
const result2 = parseSearchResult(item);
|
|
403454
|
+
if (!result2)
|
|
403455
|
+
throw new Error("Invalid MCP tool search result");
|
|
403456
|
+
results.push(result2);
|
|
403457
|
+
}
|
|
403458
|
+
return results;
|
|
403459
|
+
}
|
|
403460
|
+
async function runUnifiedMcpTool(params) {
|
|
403461
|
+
const value = await withTimeout2(params.client.post(`/v1/agents/${encodeURIComponent(params.agentId)}/mcp-servers/${encodeURIComponent(params.mcpServerId)}/tools/${encodeURIComponent(params.toolId)}/run`, { body: { args: params.args } }), params.timeoutMs ?? 60000, "Running agent MCP tool");
|
|
403462
|
+
return parseRunResult(value);
|
|
403463
|
+
}
|
|
403464
|
+
var init_unified_mcp = () => {};
|
|
403465
|
+
|
|
403523
403466
|
// src/reminders/engine.ts
|
|
403524
403467
|
async function buildAgentInfoReminder(context3) {
|
|
403525
403468
|
if (!context3.systemInfoReminderEnabled || context3.state.hasSentAgentInfo) {
|
|
@@ -403579,6 +403522,80 @@ ${SYSTEM_REMINDER_CLOSE}`;
|
|
|
403579
403522
|
return null;
|
|
403580
403523
|
}
|
|
403581
403524
|
}
|
|
403525
|
+
async function defaultListServerSideServers(agentId) {
|
|
403526
|
+
let serverSideAvailable = false;
|
|
403527
|
+
try {
|
|
403528
|
+
const { getBackend: getBackend2 } = await Promise.resolve().then(() => (init_backend2(), exports_backend));
|
|
403529
|
+
serverSideAvailable = getBackend2().capabilities.serverSideToolManagement;
|
|
403530
|
+
} catch {
|
|
403531
|
+
return null;
|
|
403532
|
+
}
|
|
403533
|
+
if (!serverSideAvailable) {
|
|
403534
|
+
return null;
|
|
403535
|
+
}
|
|
403536
|
+
const { getClient: getClient2 } = await Promise.resolve().then(() => (init_client2(), exports_client));
|
|
403537
|
+
const { getServerUrl: getServerUrl2 } = await Promise.resolve().then(() => (init_server_url(), exports_server_url));
|
|
403538
|
+
const { LETTA_CLOUD_API_URL: LETTA_CLOUD_API_URL2 } = await Promise.resolve().then(() => (init_oauth(), exports_oauth));
|
|
403539
|
+
const { listUnifiedMcpServers: listUnifiedMcpServers2, listUnifiedMcpTools: listUnifiedMcpTools2 } = await Promise.resolve().then(() => (init_unified_mcp(), exports_unified_mcp));
|
|
403540
|
+
const client = await getClient2();
|
|
403541
|
+
const allServers = await listUnifiedMcpServers2(client, agentId, 3000);
|
|
403542
|
+
const servers = getServerUrl2() === LETTA_CLOUD_API_URL2 ? allServers.filter((server2) => server2.serverType !== "stdio") : allServers;
|
|
403543
|
+
return Promise.all(servers.map(async (server2) => ({
|
|
403544
|
+
name: server2.serverName,
|
|
403545
|
+
toolCount: await listUnifiedMcpTools2(client, agentId, server2.id, 3000).then((tools) => tools.length).catch(() => null)
|
|
403546
|
+
})));
|
|
403547
|
+
}
|
|
403548
|
+
function formatMcpServerEntry(entry) {
|
|
403549
|
+
if (entry.toolCount === null) {
|
|
403550
|
+
return entry.name;
|
|
403551
|
+
}
|
|
403552
|
+
return `${entry.name} (${entry.toolCount} ${entry.toolCount === 1 ? "tool" : "tools"})`;
|
|
403553
|
+
}
|
|
403554
|
+
async function buildMcpServersInfoReminderText(context3, deps = {}) {
|
|
403555
|
+
try {
|
|
403556
|
+
const now2 = Date.now();
|
|
403557
|
+
const lastFetched = context3.state.lastMcpServersFetchedAtMs;
|
|
403558
|
+
const due = !context3.state.hasSentMcpServersInfo || lastFetched === null || now2 - lastFetched > MCP_SERVERS_REFRESH_MS;
|
|
403559
|
+
if (!due) {
|
|
403560
|
+
return null;
|
|
403561
|
+
}
|
|
403562
|
+
context3.state.lastMcpServersFetchedAtMs = now2;
|
|
403563
|
+
const localNames = (deps.getLocalServerNames ?? ((agentId) => settingsManager.getMcpServers(agentId).map((server2) => server2.name)))(context3.agent.id);
|
|
403564
|
+
const entries = localNames.map((name) => ({
|
|
403565
|
+
name,
|
|
403566
|
+
toolCount: null
|
|
403567
|
+
}));
|
|
403568
|
+
const serverSideEntries = await (deps.listServerSideServers ?? defaultListServerSideServers)(context3.agent.id);
|
|
403569
|
+
if (serverSideEntries) {
|
|
403570
|
+
entries.push(...serverSideEntries);
|
|
403571
|
+
}
|
|
403572
|
+
const uniqueEntries = [
|
|
403573
|
+
...new Map(entries.map((entry) => [entry.name, entry])).values()
|
|
403574
|
+
];
|
|
403575
|
+
const namesKey = uniqueEntries.map((entry) => `${entry.name}\x01${entry.toolCount ?? ""}`).join("\x00");
|
|
403576
|
+
if (context3.state.hasSentMcpServersInfo && context3.state.lastSentMcpServerNamesKey === namesKey) {
|
|
403577
|
+
return null;
|
|
403578
|
+
}
|
|
403579
|
+
context3.state.hasSentMcpServersInfo = true;
|
|
403580
|
+
context3.state.lastSentMcpServerNamesKey = namesKey;
|
|
403581
|
+
if (uniqueEntries.length === 0) {
|
|
403582
|
+
return `${SYSTEM_REMINDER_OPEN}
|
|
403583
|
+
MCP servers with available tools: None
|
|
403584
|
+
${SYSTEM_REMINDER_CLOSE}`;
|
|
403585
|
+
}
|
|
403586
|
+
const rendered = uniqueEntries.map(formatMcpServerEntry).join(", ");
|
|
403587
|
+
return `${SYSTEM_REMINDER_OPEN}
|
|
403588
|
+
MCP servers with available tools: ${rendered}
|
|
403589
|
+
Find tools (with schemas) with \`letta mcp search "<what you want to do>"\`, list one server's tools with \`letta mcp tools <server>\` (\`--full\` includes schemas, \`letta mcp schema <tool-name>\` fetches one), and invoke one with \`letta mcp call <tool-name> --args '{"key":"value"}'\`.
|
|
403590
|
+
${SYSTEM_REMINDER_CLOSE}`;
|
|
403591
|
+
} catch (error4) {
|
|
403592
|
+
debugLog("mcp", `Failed to build MCP servers reminder: ${error4 instanceof Error ? error4.message : String(error4)}`);
|
|
403593
|
+
return null;
|
|
403594
|
+
}
|
|
403595
|
+
}
|
|
403596
|
+
async function buildMcpServersInfoReminder(context3) {
|
|
403597
|
+
return buildMcpServersInfoReminderText(context3);
|
|
403598
|
+
}
|
|
403582
403599
|
async function buildSessionContextReminder(context3) {
|
|
403583
403600
|
if (!context3.systemInfoReminderEnabled || context3.state.hasSentSessionContext) {
|
|
403584
403601
|
return null;
|
|
@@ -403774,7 +403791,7 @@ function prependReminderPartsToContent(content, reminderParts) {
|
|
|
403774
403791
|
}
|
|
403775
403792
|
return [...reminderParts, { type: "text", text: text2 }];
|
|
403776
403793
|
}
|
|
403777
|
-
var PERMISSION_MODE_DESCRIPTIONS, MAX_COMMAND_REMINDERS_PER_TURN = 10, MAX_TOOLSET_REMINDERS_PER_TURN = 5, MAX_COMMAND_INPUT_CHARS = 2000, MAX_COMMAND_OUTPUT_CHARS = 4000, MAX_TOOL_LIST_CHARS = 3000, sharedReminderProviders;
|
|
403794
|
+
var MCP_SERVERS_REFRESH_MS = 300000, PERMISSION_MODE_DESCRIPTIONS, MAX_COMMAND_REMINDERS_PER_TURN = 10, MAX_TOOLSET_REMINDERS_PER_TURN = 5, MAX_COMMAND_INPUT_CHARS = 2000, MAX_COMMAND_OUTPUT_CHARS = 4000, MAX_TOOL_LIST_CHARS = 3000, sharedReminderProviders;
|
|
403778
403795
|
var init_engine3 = __esm(() => {
|
|
403779
403796
|
init_agent_info();
|
|
403780
403797
|
init_conversation_bootstrap();
|
|
@@ -403795,6 +403812,7 @@ var init_engine3 = __esm(() => {
|
|
|
403795
403812
|
"agent-info": buildAgentInfoReminder,
|
|
403796
403813
|
"conversation-bootstrap": buildConversationBootstrapReminderPart,
|
|
403797
403814
|
"secrets-info": buildSecretsInfoReminder,
|
|
403815
|
+
"mcp-servers-info": buildMcpServersInfoReminder,
|
|
403798
403816
|
"session-context": buildSessionContextReminder,
|
|
403799
403817
|
"permission-mode": buildPermissionModeReminder,
|
|
403800
403818
|
"memory-git-sync": buildMemoryGitSyncReminder,
|
|
@@ -408138,7 +408156,7 @@ function getNumber(record3, keys3) {
|
|
|
408138
408156
|
}
|
|
408139
408157
|
return null;
|
|
408140
408158
|
}
|
|
408141
|
-
function
|
|
408159
|
+
function getString(record3, keys3) {
|
|
408142
408160
|
const value = getValue(record3, keys3);
|
|
408143
408161
|
if (typeof value === "string" && value.trim())
|
|
408144
408162
|
return value.trim();
|
|
@@ -408224,7 +408242,7 @@ function normalizeCredits(raw2, rateLimit) {
|
|
|
408224
408242
|
const resetCredits = getRecord(raw2, ["rate_limit_reset_credits", "rateLimitResetCredits"]) ?? getRecord(rateLimit, ["rate_limit_reset_credits", "rateLimitResetCredits"]);
|
|
408225
408243
|
if (!credits && !resetCredits)
|
|
408226
408244
|
return null;
|
|
408227
|
-
const balance =
|
|
408245
|
+
const balance = getString(credits, ["balance", "credit_balance", "amount"]);
|
|
408228
408246
|
const availableCount = getNumber(credits, ["available_count", "availableCount", "count"]) ?? getNumber(resetCredits, ["available_count", "availableCount", "count"]);
|
|
408229
408247
|
const hasCredits = getBoolean(credits, ["has_credits", "hasCredits"]);
|
|
408230
408248
|
const unlimited = getBoolean(credits, ["unlimited", "is_unlimited"]);
|
|
@@ -408243,8 +408261,8 @@ function normalizeIndividualLimit(raw2, nowMs) {
|
|
|
408243
408261
|
const record3 = getRecord(raw2, ["individual_limit", "individualLimit"]) ?? getRecord(spendControl, ["individual_limit", "individualLimit"]);
|
|
408244
408262
|
if (!record3)
|
|
408245
408263
|
return null;
|
|
408246
|
-
const limit3 =
|
|
408247
|
-
const used =
|
|
408264
|
+
const limit3 = getString(record3, ["limit"]);
|
|
408265
|
+
const used = getString(record3, ["used"]);
|
|
408248
408266
|
const remainingPercent = getNumber(record3, [
|
|
408249
408267
|
"remaining_percent",
|
|
408250
408268
|
"remainingPercent"
|
|
@@ -408273,10 +408291,10 @@ function normalizeCloudUsageWindow(value, fallbackLabel, nowMs) {
|
|
|
408273
408291
|
const record3 = asRecord8(value);
|
|
408274
408292
|
if (!record3)
|
|
408275
408293
|
return null;
|
|
408276
|
-
return normalizeUsageWindow(record3,
|
|
408294
|
+
return normalizeUsageWindow(record3, getString(record3, ["label", "name"]) ?? fallbackLabel, nowMs);
|
|
408277
408295
|
}
|
|
408278
408296
|
function normalizeAdditionalRateLimit(details, index, nowMs) {
|
|
408279
|
-
const label =
|
|
408297
|
+
const label = getString(details, [
|
|
408280
408298
|
"limit_name",
|
|
408281
408299
|
"limitName",
|
|
408282
408300
|
"metered_feature",
|
|
@@ -408302,7 +408320,7 @@ function getRateLimitReachedType(raw2) {
|
|
|
408302
408320
|
if (typeof value === "string" && value.trim())
|
|
408303
408321
|
return value.trim();
|
|
408304
408322
|
const record3 = asRecord8(value);
|
|
408305
|
-
return
|
|
408323
|
+
return getString(record3, ["type", "kind"]);
|
|
408306
408324
|
}
|
|
408307
408325
|
function formatPercent(value) {
|
|
408308
408326
|
const rounded = Math.round(value);
|
|
@@ -408417,7 +408435,7 @@ function normalizeWhamUsageResponse(input) {
|
|
|
408417
408435
|
const snapshotWithoutSummary = {
|
|
408418
408436
|
providerName: input.providerName,
|
|
408419
408437
|
fetchedAt,
|
|
408420
|
-
planType:
|
|
408438
|
+
planType: getString(raw2, ["plan_type", "planType"]),
|
|
408421
408439
|
limitReached: getBoolean(rateLimit, ["limit_reached", "limitReached"]) ?? getBoolean(spendControl, ["reached"]),
|
|
408422
408440
|
rateLimitReachedType: getRateLimitReachedType(raw2),
|
|
408423
408441
|
primary,
|
|
@@ -408436,18 +408454,18 @@ function normalizeCloudChatGPTUsageResponse(input) {
|
|
|
408436
408454
|
if (!raw2)
|
|
408437
408455
|
return null;
|
|
408438
408456
|
const nowMs = input.nowMs ?? Date.now();
|
|
408439
|
-
const fetchedAt =
|
|
408457
|
+
const fetchedAt = getString(raw2, ["fetchedAt", "fetched_at"]) ?? new Date(nowMs).toISOString();
|
|
408440
408458
|
const additional = getRecordArray(raw2, [
|
|
408441
408459
|
"additional",
|
|
408442
408460
|
"additional_rate_limits",
|
|
408443
408461
|
"additionalRateLimits"
|
|
408444
408462
|
]).map((window2, index) => normalizeCloudUsageWindow(window2, `limit ${index + 1}`, nowMs)).filter((window2) => !!window2);
|
|
408445
408463
|
const snapshotWithoutSummary = {
|
|
408446
|
-
providerName:
|
|
408464
|
+
providerName: getString(raw2, ["providerName", "provider_name"]) ?? input.providerName,
|
|
408447
408465
|
fetchedAt,
|
|
408448
|
-
planType:
|
|
408466
|
+
planType: getString(raw2, ["planType", "plan_type"]),
|
|
408449
408467
|
limitReached: getBoolean(raw2, ["limitReached", "limit_reached"]),
|
|
408450
|
-
rateLimitReachedType:
|
|
408468
|
+
rateLimitReachedType: getString(raw2, [
|
|
408451
408469
|
"rateLimitReachedType",
|
|
408452
408470
|
"rate_limit_reached_type"
|
|
408453
408471
|
]),
|
|
@@ -408459,7 +408477,7 @@ function normalizeCloudChatGPTUsageResponse(input) {
|
|
|
408459
408477
|
};
|
|
408460
408478
|
return {
|
|
408461
408479
|
...snapshotWithoutSummary,
|
|
408462
|
-
summary:
|
|
408480
|
+
summary: getString(raw2, ["summary"]) ?? formatChatGPTUsageSnapshot(snapshotWithoutSummary, new Date(nowMs))
|
|
408463
408481
|
};
|
|
408464
408482
|
}
|
|
408465
408483
|
function retryAfterMs(response) {
|
|
@@ -408484,7 +408502,7 @@ async function readJsonRecord(response) {
|
|
|
408484
408502
|
}
|
|
408485
408503
|
}
|
|
408486
408504
|
function responseMessage(raw2, fallback) {
|
|
408487
|
-
return
|
|
408505
|
+
return getString(raw2 ?? undefined, ["message", "error", "detail"]) ?? fallback;
|
|
408488
408506
|
}
|
|
408489
408507
|
function chatGPTUsageError(code2, message, retryAfter) {
|
|
408490
408508
|
return {
|
|
@@ -412253,7 +412271,7 @@ var init_app_server_openai_common = __esm(() => {
|
|
|
412253
412271
|
function asRecord9(value) {
|
|
412254
412272
|
return value !== null && typeof value === "object" ? value : null;
|
|
412255
412273
|
}
|
|
412256
|
-
function
|
|
412274
|
+
function stringValue3(value) {
|
|
412257
412275
|
return typeof value === "string" ? value : undefined;
|
|
412258
412276
|
}
|
|
412259
412277
|
function extractToolCallFragments(record3) {
|
|
@@ -412267,12 +412285,12 @@ function extractToolCallFragments(record3) {
|
|
|
412267
412285
|
if (!toolCall) {
|
|
412268
412286
|
continue;
|
|
412269
412287
|
}
|
|
412270
|
-
const toolCallId =
|
|
412288
|
+
const toolCallId = stringValue3(toolCall.tool_call_id);
|
|
412271
412289
|
if (!toolCallId) {
|
|
412272
412290
|
continue;
|
|
412273
412291
|
}
|
|
412274
|
-
const name =
|
|
412275
|
-
const argumentsDelta =
|
|
412292
|
+
const name = stringValue3(toolCall.name) ?? null;
|
|
412293
|
+
const argumentsDelta = stringValue3(toolCall.arguments) ?? null;
|
|
412276
412294
|
fragments.push({ toolCallId, name, argumentsDelta });
|
|
412277
412295
|
}
|
|
412278
412296
|
return fragments;
|
|
@@ -412312,7 +412330,7 @@ function extractToolReturns(record3) {
|
|
|
412312
412330
|
if (!rec) {
|
|
412313
412331
|
continue;
|
|
412314
412332
|
}
|
|
412315
|
-
const toolCallId =
|
|
412333
|
+
const toolCallId = stringValue3(rec.tool_call_id);
|
|
412316
412334
|
const status = asToolReturnStatus2(rec.status);
|
|
412317
412335
|
if (!toolCallId || !status) {
|
|
412318
412336
|
continue;
|
|
@@ -412327,7 +412345,7 @@ function extractToolReturns(record3) {
|
|
|
412327
412345
|
return results;
|
|
412328
412346
|
}
|
|
412329
412347
|
}
|
|
412330
|
-
const topLevelToolCallId =
|
|
412348
|
+
const topLevelToolCallId = stringValue3(record3.tool_call_id);
|
|
412331
412349
|
const topLevelStatus = asToolReturnStatus2(record3.status);
|
|
412332
412350
|
if (!topLevelToolCallId || !topLevelStatus) {
|
|
412333
412351
|
return [];
|
|
@@ -412415,13 +412433,13 @@ function createToolLifecycleTracker(onEvent) {
|
|
|
412415
412433
|
return;
|
|
412416
412434
|
}
|
|
412417
412435
|
const record3 = delta2;
|
|
412418
|
-
const messageType =
|
|
412419
|
-
const toolCallId =
|
|
412436
|
+
const messageType = stringValue3(record3.message_type);
|
|
412437
|
+
const toolCallId = stringValue3(record3.tool_call_id);
|
|
412420
412438
|
if (messageType === "client_tool_start" && toolCallId) {
|
|
412421
412439
|
const state = getOrCreate(toolCallId);
|
|
412422
412440
|
state.clientManaged = true;
|
|
412423
412441
|
if (!state.name)
|
|
412424
|
-
state.name =
|
|
412442
|
+
state.name = stringValue3(record3.tool_name) ?? null;
|
|
412425
412443
|
return;
|
|
412426
412444
|
}
|
|
412427
412445
|
if (messageType === "client_tool_end" && toolCallId) {
|
|
@@ -414008,7 +414026,7 @@ var init_gateway_supervisor = __esm(() => {
|
|
|
414008
414026
|
|
|
414009
414027
|
// src/cli/subcommands/listen.tsx
|
|
414010
414028
|
import { hostname as hostname4 } from "node:os";
|
|
414011
|
-
import { parseArgs as
|
|
414029
|
+
import { parseArgs as parseArgs8 } from "node:util";
|
|
414012
414030
|
import { MessageChannel as MessageChannel2 } from "node:worker_threads";
|
|
414013
414031
|
function PromptEnvName(props) {
|
|
414014
414032
|
const [value, setValue] = import_react33.useState("");
|
|
@@ -414121,7 +414139,7 @@ function printListenUsage() {
|
|
|
414121
414139
|
async function runListenSubcommand(argv) {
|
|
414122
414140
|
let values3;
|
|
414123
414141
|
try {
|
|
414124
|
-
({ values: values3 } =
|
|
414142
|
+
({ values: values3 } = parseArgs8({
|
|
414125
414143
|
args: argv,
|
|
414126
414144
|
options: LISTEN_OPTIONS,
|
|
414127
414145
|
strict: true,
|
|
@@ -415029,15 +415047,15 @@ var init_transcript_migration = __esm(() => {
|
|
|
415029
415047
|
});
|
|
415030
415048
|
|
|
415031
415049
|
// src/cli/subcommands/local-backend.ts
|
|
415032
|
-
import { parseArgs as
|
|
415050
|
+
import { parseArgs as parseArgs9 } from "node:util";
|
|
415033
415051
|
function parseLocalBackendArgs(argv) {
|
|
415034
|
-
return
|
|
415052
|
+
return parseArgs9({
|
|
415035
415053
|
args: argv,
|
|
415036
415054
|
options: LOCAL_BACKEND_OPTIONS,
|
|
415037
415055
|
strict: true
|
|
415038
415056
|
});
|
|
415039
415057
|
}
|
|
415040
|
-
function
|
|
415058
|
+
function printUsage7() {
|
|
415041
415059
|
console.log(`
|
|
415042
415060
|
Usage:
|
|
415043
415061
|
letta local-backend migrate-transcripts [--storage-dir <path>] [--dry-run]
|
|
@@ -415050,12 +415068,12 @@ before it is replaced.
|
|
|
415050
415068
|
async function runLocalBackendSubcommand(argv) {
|
|
415051
415069
|
const [command, ...rest4] = argv;
|
|
415052
415070
|
if (!command || command === "help" || command === "--help" || command === "-h") {
|
|
415053
|
-
|
|
415071
|
+
printUsage7();
|
|
415054
415072
|
return command ? 0 : 1;
|
|
415055
415073
|
}
|
|
415056
415074
|
if (command !== "migrate-transcripts") {
|
|
415057
415075
|
console.error(`Unknown local-backend command: ${command}`);
|
|
415058
|
-
|
|
415076
|
+
printUsage7();
|
|
415059
415077
|
return 1;
|
|
415060
415078
|
}
|
|
415061
415079
|
let parsed;
|
|
@@ -415064,11 +415082,11 @@ async function runLocalBackendSubcommand(argv) {
|
|
|
415064
415082
|
} catch (error4) {
|
|
415065
415083
|
const message = error4 instanceof Error ? error4.message : String(error4);
|
|
415066
415084
|
console.error(`Error: ${message}`);
|
|
415067
|
-
|
|
415085
|
+
printUsage7();
|
|
415068
415086
|
return 1;
|
|
415069
415087
|
}
|
|
415070
415088
|
if (parsed.values.help) {
|
|
415071
|
-
|
|
415089
|
+
printUsage7();
|
|
415072
415090
|
return 0;
|
|
415073
415091
|
}
|
|
415074
415092
|
const storageDir = parsed.values["storage-dir"] ?? getLocalBackendStorageDir();
|
|
@@ -415090,160 +415108,6 @@ var init_local_backend2 = __esm(() => {
|
|
|
415090
415108
|
};
|
|
415091
415109
|
});
|
|
415092
415110
|
|
|
415093
|
-
// src/backend/api/unified-mcp.ts
|
|
415094
|
-
function stringField2(value, key2) {
|
|
415095
|
-
return typeof value[key2] === "string" ? value[key2] : null;
|
|
415096
|
-
}
|
|
415097
|
-
function recordField(value, ...names2) {
|
|
415098
|
-
for (const name of names2) {
|
|
415099
|
-
const field = value[name];
|
|
415100
|
-
if (isRecord(field))
|
|
415101
|
-
return field;
|
|
415102
|
-
}
|
|
415103
|
-
return;
|
|
415104
|
-
}
|
|
415105
|
-
function parseServer(value, registered) {
|
|
415106
|
-
if (!isRecord(value))
|
|
415107
|
-
return null;
|
|
415108
|
-
const id2 = stringField2(value, "id");
|
|
415109
|
-
const serverName = stringField2(value, "server_name") ?? (registered ? stringField2(registered, "server_name") : null);
|
|
415110
|
-
const serverType = stringField2(value, "mcp_server_type") ?? (registered ? stringField2(registered, "mcp_server_type") : null) ?? "unknown";
|
|
415111
|
-
if (!id2 || !serverName)
|
|
415112
|
-
return null;
|
|
415113
|
-
const serverUrl = stringField2(value, "server_url") ?? (registered ? stringField2(registered, "server_url") : null) ?? undefined;
|
|
415114
|
-
const command = stringField2(value, "command") ?? (registered ? stringField2(registered, "command") : null) ?? undefined;
|
|
415115
|
-
const argsValue = value.args ?? registered?.args;
|
|
415116
|
-
const args = Array.isArray(argsValue) ? argsValue.filter((item) => typeof item === "string") : [];
|
|
415117
|
-
const target2 = serverUrl ?? [command, ...args].filter(Boolean).join(" ");
|
|
415118
|
-
return {
|
|
415119
|
-
id: id2,
|
|
415120
|
-
serverName,
|
|
415121
|
-
serverType,
|
|
415122
|
-
target: target2,
|
|
415123
|
-
...serverUrl ? { serverUrl } : {},
|
|
415124
|
-
...command ? { command, args } : {}
|
|
415125
|
-
};
|
|
415126
|
-
}
|
|
415127
|
-
function parseTool(value) {
|
|
415128
|
-
if (!isRecord(value))
|
|
415129
|
-
return null;
|
|
415130
|
-
const id2 = stringField2(value, "id");
|
|
415131
|
-
const name = stringField2(value, "name");
|
|
415132
|
-
if (!id2 || !name)
|
|
415133
|
-
return null;
|
|
415134
|
-
const description = stringField2(value, "description");
|
|
415135
|
-
const jsonSchema = isRecord(value.json_schema) ? value.json_schema : {};
|
|
415136
|
-
const inputSchema = isRecord(jsonSchema.parameters) ? jsonSchema.parameters : isRecord(value.args_json_schema) ? value.args_json_schema : { type: "object", properties: {} };
|
|
415137
|
-
const title = stringField2(value, "title") ?? stringField2(jsonSchema, "title");
|
|
415138
|
-
const outputSchema = recordField(value, "outputSchema", "output_schema") ?? recordField(jsonSchema, "outputSchema", "output_schema");
|
|
415139
|
-
const annotations = recordField(value, "annotations") ?? recordField(jsonSchema, "annotations");
|
|
415140
|
-
const execution = recordField(value, "execution") ?? recordField(jsonSchema, "execution");
|
|
415141
|
-
const meta = recordField(value, "_meta") ?? recordField(jsonSchema, "_meta");
|
|
415142
|
-
const iconsValue = value.icons ?? jsonSchema.icons;
|
|
415143
|
-
const icons = Array.isArray(iconsValue) ? iconsValue.filter(isRecord) : undefined;
|
|
415144
|
-
return {
|
|
415145
|
-
id: id2,
|
|
415146
|
-
name,
|
|
415147
|
-
...title ? { title } : {},
|
|
415148
|
-
description,
|
|
415149
|
-
inputSchema,
|
|
415150
|
-
...outputSchema ? { outputSchema } : {},
|
|
415151
|
-
...annotations ? { annotations } : {},
|
|
415152
|
-
...execution ? { execution } : {},
|
|
415153
|
-
...meta ? { _meta: meta } : {},
|
|
415154
|
-
...icons ? { icons } : {}
|
|
415155
|
-
};
|
|
415156
|
-
}
|
|
415157
|
-
function parseRunResult(value) {
|
|
415158
|
-
if (!isRecord(value))
|
|
415159
|
-
throw new Error("Invalid MCP tool run response");
|
|
415160
|
-
return {
|
|
415161
|
-
status: stringField2(value, "status") ?? "unknown",
|
|
415162
|
-
funcReturn: value.func_return,
|
|
415163
|
-
stdout: value.stdout,
|
|
415164
|
-
stderr: value.stderr
|
|
415165
|
-
};
|
|
415166
|
-
}
|
|
415167
|
-
function parseSearchResult(value) {
|
|
415168
|
-
if (!isRecord(value) || !isRecord(value.tool))
|
|
415169
|
-
return null;
|
|
415170
|
-
const toolId = stringField2(value.tool, "id");
|
|
415171
|
-
const jsonSchema = value.tool.json_schema;
|
|
415172
|
-
const score = value.combined_score;
|
|
415173
|
-
if (!toolId || jsonSchema !== null && !isRecord(jsonSchema) || typeof score !== "number") {
|
|
415174
|
-
return null;
|
|
415175
|
-
}
|
|
415176
|
-
return { toolId, jsonSchema, score };
|
|
415177
|
-
}
|
|
415178
|
-
async function withTimeout3(promise, timeoutMs, operation) {
|
|
415179
|
-
let timer;
|
|
415180
|
-
try {
|
|
415181
|
-
return await Promise.race([
|
|
415182
|
-
promise,
|
|
415183
|
-
new Promise((_resolve, reject2) => {
|
|
415184
|
-
timer = setTimeout(() => reject2(new Error(`${operation} timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
415185
|
-
})
|
|
415186
|
-
]);
|
|
415187
|
-
} finally {
|
|
415188
|
-
if (timer)
|
|
415189
|
-
clearTimeout(timer);
|
|
415190
|
-
}
|
|
415191
|
-
}
|
|
415192
|
-
async function listUnifiedMcpServers(client, agentId, timeoutMs = 1e4) {
|
|
415193
|
-
const value = await withTimeout3(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers`), timeoutMs, "Listing agent MCP servers");
|
|
415194
|
-
if (!Array.isArray(value))
|
|
415195
|
-
return [];
|
|
415196
|
-
const needsEnrichment = value.some((item) => isRecord(item) && !stringField2(item, "mcp_server_type"));
|
|
415197
|
-
const registeredById = new Map;
|
|
415198
|
-
if (needsEnrichment && client.mcpServers) {
|
|
415199
|
-
try {
|
|
415200
|
-
const registered = await withTimeout3(client.mcpServers.list(), timeoutMs, "Listing registered MCP servers");
|
|
415201
|
-
for (const item of registered) {
|
|
415202
|
-
if (!isRecord(item))
|
|
415203
|
-
continue;
|
|
415204
|
-
const id2 = stringField2(item, "id");
|
|
415205
|
-
if (id2)
|
|
415206
|
-
registeredById.set(id2, item);
|
|
415207
|
-
}
|
|
415208
|
-
} catch {}
|
|
415209
|
-
}
|
|
415210
|
-
return value.map((item) => {
|
|
415211
|
-
const registered = isRecord(item) ? registeredById.get(stringField2(item, "id") ?? "") : undefined;
|
|
415212
|
-
return parseServer(item, registered);
|
|
415213
|
-
}).filter((server2) => server2 !== null);
|
|
415214
|
-
}
|
|
415215
|
-
async function listUnifiedMcpTools(client, agentId, mcpServerId, timeoutMs = 1e4) {
|
|
415216
|
-
const value = await withTimeout3(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers/${encodeURIComponent(mcpServerId)}/tools`), timeoutMs, "Listing agent MCP server tools");
|
|
415217
|
-
if (!Array.isArray(value))
|
|
415218
|
-
return [];
|
|
415219
|
-
return value.map(parseTool).filter((tool) => tool !== null);
|
|
415220
|
-
}
|
|
415221
|
-
async function searchUnifiedMcpTools(params) {
|
|
415222
|
-
const value = await withTimeout3(params.client.post(`/v1/agents/${encodeURIComponent(params.agentId)}/mcp-servers/tools/search`, {
|
|
415223
|
-
body: {
|
|
415224
|
-
query: params.query,
|
|
415225
|
-
search_mode: params.searchMode,
|
|
415226
|
-
limit: params.limit
|
|
415227
|
-
}
|
|
415228
|
-
}), params.timeoutMs ?? 60000, "Searching agent MCP tools");
|
|
415229
|
-
if (!Array.isArray(value)) {
|
|
415230
|
-
throw new Error("Invalid MCP tool search response");
|
|
415231
|
-
}
|
|
415232
|
-
const results = [];
|
|
415233
|
-
for (const item of value) {
|
|
415234
|
-
const result2 = parseSearchResult(item);
|
|
415235
|
-
if (!result2)
|
|
415236
|
-
throw new Error("Invalid MCP tool search result");
|
|
415237
|
-
results.push(result2);
|
|
415238
|
-
}
|
|
415239
|
-
return results;
|
|
415240
|
-
}
|
|
415241
|
-
async function runUnifiedMcpTool(params) {
|
|
415242
|
-
const value = await withTimeout3(params.client.post(`/v1/agents/${encodeURIComponent(params.agentId)}/mcp-servers/${encodeURIComponent(params.mcpServerId)}/tools/${encodeURIComponent(params.toolId)}/run`, { body: { args: params.args } }), params.timeoutMs ?? 60000, "Running agent MCP tool");
|
|
415243
|
-
return parseRunResult(value);
|
|
415244
|
-
}
|
|
415245
|
-
var init_unified_mcp = () => {};
|
|
415246
|
-
|
|
415247
415111
|
// node_modules/pkce-challenge/dist/index.node.js
|
|
415248
415112
|
async function getRandomValues(size2) {
|
|
415249
415113
|
return (await crypto2).getRandomValues(new Uint8Array(size2));
|
|
@@ -432086,7 +431950,7 @@ var init_mcp_client = __esm(() => {
|
|
|
432086
431950
|
init_streamableHttp();
|
|
432087
431951
|
DEFAULT_CLIENT_INFO = {
|
|
432088
431952
|
name: "letta-code",
|
|
432089
|
-
version: "0.31.
|
|
431953
|
+
version: "0.31.11"
|
|
432090
431954
|
};
|
|
432091
431955
|
});
|
|
432092
431956
|
|
|
@@ -432527,20 +432391,23 @@ function printMcpUsage(stdout) {
|
|
|
432527
432391
|
Usage:
|
|
432528
432392
|
letta mcp list [--agent <id>]
|
|
432529
432393
|
letta mcp get <server> [--agent <id>]
|
|
432530
|
-
letta mcp tools [server] [--agent <id>]
|
|
432394
|
+
letta mcp tools [server] [--full] [--agent <id>]
|
|
432395
|
+
letta mcp schema <tool-name> [--agent <id>]
|
|
432531
432396
|
letta mcp search <query> [--mode <hybrid|vector|fts>] [--limit <n>] [--agent <id>]
|
|
432532
432397
|
letta mcp call <tool-name> [--args '<json>' | --args-file <path|->] [--agent <id>]
|
|
432533
432398
|
|
|
432534
432399
|
Commands:
|
|
432535
432400
|
list List MCP servers available to the agent
|
|
432536
432401
|
get Print one server's redacted connection configuration
|
|
432537
|
-
tools
|
|
432402
|
+
tools List tool names and descriptions; names are accepted by call
|
|
432403
|
+
schema Print one tool's complete schema
|
|
432538
432404
|
search Search tools available to the agent
|
|
432539
432405
|
call Call one exact tool name and print an MCP CallToolResult
|
|
432540
432406
|
|
|
432541
432407
|
Options:
|
|
432542
432408
|
--agent <id> Agent ID. Defaults to LETTA_AGENT_ID or AGENT_ID
|
|
432543
432409
|
--agent-id <id> Alias for --agent
|
|
432410
|
+
--full Include complete schemas in tools output
|
|
432544
432411
|
--mode <mode> Search mode: hybrid (default), vector, or fts
|
|
432545
432412
|
--limit <n> Search result limit from 1 to 100 (default: 5)
|
|
432546
432413
|
--args <json> JSON object passed to a tool
|
|
@@ -432749,9 +432616,16 @@ var init_mcp_tool_names = __esm(async () => {
|
|
|
432749
432616
|
});
|
|
432750
432617
|
|
|
432751
432618
|
// src/cli/subcommands/mcp.ts
|
|
432752
|
-
import { parseArgs as
|
|
432619
|
+
import { parseArgs as parseArgs10 } from "node:util";
|
|
432620
|
+
function defaultIsHostedLettaCloud() {
|
|
432621
|
+
try {
|
|
432622
|
+
return getServerUrl() === LETTA_CLOUD_API_URL;
|
|
432623
|
+
} catch {
|
|
432624
|
+
return !process.env.LETTA_BASE_URL;
|
|
432625
|
+
}
|
|
432626
|
+
}
|
|
432753
432627
|
function parseMcpArgs(argv) {
|
|
432754
|
-
return
|
|
432628
|
+
return parseArgs10({
|
|
432755
432629
|
args: argv,
|
|
432756
432630
|
options: {
|
|
432757
432631
|
help: { type: "boolean", short: "h" },
|
|
@@ -432759,6 +432633,7 @@ function parseMcpArgs(argv) {
|
|
|
432759
432633
|
"agent-id": { type: "string" },
|
|
432760
432634
|
mode: { type: "string" },
|
|
432761
432635
|
limit: { type: "string" },
|
|
432636
|
+
full: { type: "boolean" },
|
|
432762
432637
|
args: { type: "string" },
|
|
432763
432638
|
"args-file": { type: "string" }
|
|
432764
432639
|
},
|
|
@@ -432774,7 +432649,7 @@ function parseCommandLine(argv) {
|
|
|
432774
432649
|
}
|
|
432775
432650
|
return { action: action3, target: target2, values: parsed.values };
|
|
432776
432651
|
}
|
|
432777
|
-
function
|
|
432652
|
+
function stringValue4(value) {
|
|
432778
432653
|
return typeof value === "string" ? value : undefined;
|
|
432779
432654
|
}
|
|
432780
432655
|
function getLocalServers(deps, agentId) {
|
|
@@ -432813,9 +432688,8 @@ function redactUrl(value) {
|
|
|
432813
432688
|
const url2 = new URL(value);
|
|
432814
432689
|
url2.username = "";
|
|
432815
432690
|
url2.password = "";
|
|
432816
|
-
const sensitive = /token|key|secret|password|signature|credential/i;
|
|
432817
432691
|
for (const key2 of url2.searchParams.keys()) {
|
|
432818
|
-
if (
|
|
432692
|
+
if (SENSITIVE_NAME.test(key2))
|
|
432819
432693
|
url2.searchParams.set(key2, "[REDACTED]");
|
|
432820
432694
|
}
|
|
432821
432695
|
return url2.toString();
|
|
@@ -432823,6 +432697,32 @@ function redactUrl(value) {
|
|
|
432823
432697
|
return value;
|
|
432824
432698
|
}
|
|
432825
432699
|
}
|
|
432700
|
+
function redactArgs(args) {
|
|
432701
|
+
const redacted = [];
|
|
432702
|
+
let redactNext = false;
|
|
432703
|
+
for (const arg of args) {
|
|
432704
|
+
if (redactNext) {
|
|
432705
|
+
redacted.push("[REDACTED]");
|
|
432706
|
+
redactNext = false;
|
|
432707
|
+
continue;
|
|
432708
|
+
}
|
|
432709
|
+
if (arg.startsWith("-")) {
|
|
432710
|
+
const equalsIndex = arg.indexOf("=");
|
|
432711
|
+
const flagName = equalsIndex === -1 ? arg : arg.slice(0, equalsIndex);
|
|
432712
|
+
if (SENSITIVE_NAME.test(flagName)) {
|
|
432713
|
+
if (equalsIndex === -1) {
|
|
432714
|
+
redactNext = true;
|
|
432715
|
+
redacted.push(arg);
|
|
432716
|
+
} else {
|
|
432717
|
+
redacted.push(`${flagName}=[REDACTED]`);
|
|
432718
|
+
}
|
|
432719
|
+
continue;
|
|
432720
|
+
}
|
|
432721
|
+
}
|
|
432722
|
+
redacted.push(arg);
|
|
432723
|
+
}
|
|
432724
|
+
return redacted;
|
|
432725
|
+
}
|
|
432826
432726
|
function serverDetails(target2) {
|
|
432827
432727
|
if (target2.kind === "client") {
|
|
432828
432728
|
const config2 = target2.config;
|
|
@@ -432838,7 +432738,7 @@ function serverDetails(target2) {
|
|
|
432838
432738
|
name: config2.name,
|
|
432839
432739
|
transport: "stdio",
|
|
432840
432740
|
command: config2.command,
|
|
432841
|
-
args: config2.args ?? [],
|
|
432741
|
+
args: redactArgs(config2.args ?? []),
|
|
432842
432742
|
...config2.cwd ? { cwd: config2.cwd } : {},
|
|
432843
432743
|
env: redactValues(config2.env)
|
|
432844
432744
|
};
|
|
@@ -432852,7 +432752,7 @@ function serverDetails(target2) {
|
|
|
432852
432752
|
name: server2.serverName,
|
|
432853
432753
|
transport: "stdio",
|
|
432854
432754
|
command: server2.command ?? server2.target.split(" ")[0] ?? "",
|
|
432855
|
-
args: server2.args ?? [],
|
|
432755
|
+
args: redactArgs(server2.args ?? []),
|
|
432856
432756
|
env: {}
|
|
432857
432757
|
};
|
|
432858
432758
|
}
|
|
@@ -432942,7 +432842,10 @@ async function buildToolCatalog(deps, agentId, options = {}) {
|
|
|
432942
432842
|
const connections = [];
|
|
432943
432843
|
const usedNames = new Set;
|
|
432944
432844
|
try {
|
|
432945
|
-
const
|
|
432845
|
+
const hostedLettaCloud = (deps.isHostedLettaCloud ?? defaultIsHostedLettaCloud)();
|
|
432846
|
+
const allServerTargets = activeServers.filter((target2) => target2.kind === "server");
|
|
432847
|
+
const serverTargets = hostedLettaCloud ? allServerTargets.filter(({ server: server2 }) => server2.serverType !== "stdio") : allServerTargets;
|
|
432848
|
+
const excludedHostedStdioServers = serverTargets.length !== allServerTargets.length;
|
|
432946
432849
|
if (serverTargets.length > 0) {
|
|
432947
432850
|
const client = await getServerClient(deps);
|
|
432948
432851
|
const toolLists = await Promise.all(serverTargets.map(async ({ server: server2 }) => ({
|
|
@@ -433005,6 +432908,7 @@ async function buildToolCatalog(deps, agentId, options = {}) {
|
|
|
433005
432908
|
}
|
|
433006
432909
|
return {
|
|
433007
432910
|
tools: catalog,
|
|
432911
|
+
excludedHostedStdioServers,
|
|
433008
432912
|
close: async () => {
|
|
433009
432913
|
await Promise.allSettled(connections.map((connection) => connection.close()));
|
|
433010
432914
|
}
|
|
@@ -433047,12 +432951,12 @@ function mcpToolResultFromServer(result2) {
|
|
|
433047
432951
|
isError: !success || normalized.isError === true
|
|
433048
432952
|
};
|
|
433049
432953
|
}
|
|
433050
|
-
function
|
|
432954
|
+
function printJson(stdout, value) {
|
|
433051
432955
|
stdout(JSON.stringify(value, null, 2));
|
|
433052
432956
|
}
|
|
433053
432957
|
async function runList(deps, agentId, stdout) {
|
|
433054
432958
|
const servers = await listUnifiedServers(deps, agentId);
|
|
433055
|
-
|
|
432959
|
+
printJson(stdout, servers.map(serverSummary));
|
|
433056
432960
|
return 0;
|
|
433057
432961
|
}
|
|
433058
432962
|
async function runGet(deps, agentId, selector, stdout) {
|
|
@@ -433060,25 +432964,45 @@ async function runGet(deps, agentId, selector, stdout) {
|
|
|
433060
432964
|
throw new McpCliError("invalid_arguments", "Usage: letta mcp get <server>");
|
|
433061
432965
|
}
|
|
433062
432966
|
const server2 = resolveServer(await listUnifiedServers(deps, agentId), selector);
|
|
433063
|
-
|
|
432967
|
+
printJson(stdout, serverDetails(server2));
|
|
433064
432968
|
return 0;
|
|
433065
432969
|
}
|
|
433066
|
-
async function runTools(deps, agentId, serverSelector, stdout) {
|
|
432970
|
+
async function runTools(deps, agentId, serverSelector, full, stdout) {
|
|
433067
432971
|
const catalog = await buildToolCatalog(deps, agentId, { serverSelector });
|
|
433068
432972
|
try {
|
|
433069
|
-
|
|
432973
|
+
printJson(stdout, catalog.tools.map((tool) => full ? tool.schema : {
|
|
432974
|
+
name: tool.schema.name,
|
|
432975
|
+
...tool.schema.title ? { title: tool.schema.title } : {},
|
|
432976
|
+
...tool.schema.description ? { description: tool.schema.description } : {}
|
|
432977
|
+
}));
|
|
433070
432978
|
} finally {
|
|
433071
432979
|
await catalog.close();
|
|
433072
432980
|
}
|
|
433073
432981
|
return 0;
|
|
433074
432982
|
}
|
|
432983
|
+
async function runSchema(deps, agentId, toolName, stdout) {
|
|
432984
|
+
if (!toolName) {
|
|
432985
|
+
throw new McpCliError("invalid_arguments", "Usage: letta mcp schema <tool-name>");
|
|
432986
|
+
}
|
|
432987
|
+
const catalog = await buildToolCatalog(deps, agentId, { toolName });
|
|
432988
|
+
try {
|
|
432989
|
+
const tool = catalog.tools.find((candidate) => candidate.schema.name === toolName);
|
|
432990
|
+
if (!tool) {
|
|
432991
|
+
throw new McpCliError("tool_not_found", `MCP tool '${toolName}' is not available`);
|
|
432992
|
+
}
|
|
432993
|
+
printJson(stdout, tool.schema);
|
|
432994
|
+
return 0;
|
|
432995
|
+
} finally {
|
|
432996
|
+
await catalog.close();
|
|
432997
|
+
}
|
|
432998
|
+
}
|
|
433075
432999
|
async function runSearch(parsed, deps, agentId, stdout) {
|
|
433076
433000
|
const serverSearchAvailable = serverMcpAvailable(deps);
|
|
433077
433001
|
const hasClientLocalServers = getLocalServers(deps, agentId).length > 0;
|
|
433078
433002
|
return runMcpSearch({
|
|
433079
433003
|
query: parsed.target,
|
|
433080
|
-
mode:
|
|
433081
|
-
limit:
|
|
433004
|
+
mode: stringValue4(parsed.values.mode),
|
|
433005
|
+
limit: stringValue4(parsed.values.limit),
|
|
433082
433006
|
stdout,
|
|
433083
433007
|
searchTools: async (request) => {
|
|
433084
433008
|
if (!serverSearchAvailable) {
|
|
@@ -433111,15 +433035,20 @@ async function runSearch(parsed, deps, agentId, stdout) {
|
|
|
433111
433035
|
catalogPromise
|
|
433112
433036
|
]);
|
|
433113
433037
|
catalog = resolvedCatalog;
|
|
433114
|
-
const serverResults = searchResults.
|
|
433038
|
+
const serverResults = searchResults.flatMap((result2) => {
|
|
433115
433039
|
const callable = resolvedCatalog.tools.find((tool) => tool.target.kind === "server" && tool.target.toolId === result2.toolId);
|
|
433116
433040
|
if (!callable) {
|
|
433041
|
+
if (resolvedCatalog.excludedHostedStdioServers) {
|
|
433042
|
+
return [];
|
|
433043
|
+
}
|
|
433117
433044
|
throw new Error(`MCP search returned unavailable tool '${result2.toolId}'`);
|
|
433118
433045
|
}
|
|
433119
|
-
return
|
|
433120
|
-
|
|
433121
|
-
|
|
433122
|
-
|
|
433046
|
+
return [
|
|
433047
|
+
{
|
|
433048
|
+
tool: result2.jsonSchema === null ? null : { ...result2.jsonSchema, name: callable.schema.name },
|
|
433049
|
+
score: result2.score
|
|
433050
|
+
}
|
|
433051
|
+
];
|
|
433123
433052
|
});
|
|
433124
433053
|
if (!includeLocal)
|
|
433125
433054
|
return serverResults;
|
|
@@ -433142,7 +433071,7 @@ async function runCall(parsed, deps, agentId, stdout) {
|
|
|
433142
433071
|
if (!toolName) {
|
|
433143
433072
|
throw new McpCliError("invalid_arguments", "Usage: letta mcp call <tool-name> [--args '<json>']");
|
|
433144
433073
|
}
|
|
433145
|
-
const args = await loadMcpToolArgs(
|
|
433074
|
+
const args = await loadMcpToolArgs(stringValue4(parsed.values.args), stringValue4(parsed.values["args-file"]), deps);
|
|
433146
433075
|
const catalog = await buildToolCatalog(deps, agentId, { toolName });
|
|
433147
433076
|
try {
|
|
433148
433077
|
const tool = catalog.tools.find((candidate) => candidate.schema.name === toolName);
|
|
@@ -433156,7 +433085,7 @@ async function runCall(parsed, deps, agentId, stdout) {
|
|
|
433156
433085
|
toolId: tool.target.toolId,
|
|
433157
433086
|
args
|
|
433158
433087
|
}));
|
|
433159
|
-
|
|
433088
|
+
printJson(stdout, result2);
|
|
433160
433089
|
return result2.isError === true ? 2 : 0;
|
|
433161
433090
|
} finally {
|
|
433162
433091
|
await catalog.close();
|
|
@@ -433176,7 +433105,7 @@ async function runMcpSubcommand(argv, deps = {}) {
|
|
|
433176
433105
|
printMcpUsage(stdout);
|
|
433177
433106
|
return 0;
|
|
433178
433107
|
}
|
|
433179
|
-
const agentId = resolveMcpAgentId(
|
|
433108
|
+
const agentId = resolveMcpAgentId(stringValue4(parsed.values.agent), stringValue4(parsed.values["agent-id"]), deps.env ?? process.env);
|
|
433180
433109
|
if (!agentId) {
|
|
433181
433110
|
printMcpError(stderr, new McpCliError("agent_id_required", "No agent context found", "Pass --agent <agent-id> or set LETTA_AGENT_ID."));
|
|
433182
433111
|
return 1;
|
|
@@ -433191,7 +433120,9 @@ async function runMcpSubcommand(argv, deps = {}) {
|
|
|
433191
433120
|
case "tools":
|
|
433192
433121
|
case "list-tools":
|
|
433193
433122
|
case "list_tools":
|
|
433194
|
-
return await runTools(deps, agentId, parsed.target, stdout);
|
|
433123
|
+
return await runTools(deps, agentId, parsed.target, parsed.values.full === true, stdout);
|
|
433124
|
+
case "schema":
|
|
433125
|
+
return await runSchema(deps, agentId, parsed.target, stdout);
|
|
433195
433126
|
case "search":
|
|
433196
433127
|
return await runSearch(parsed, deps, agentId, stdout);
|
|
433197
433128
|
case "call":
|
|
@@ -433207,9 +433138,12 @@ async function runMcpSubcommand(argv, deps = {}) {
|
|
|
433207
433138
|
return 1;
|
|
433208
433139
|
}
|
|
433209
433140
|
}
|
|
433141
|
+
var SENSITIVE_NAME;
|
|
433210
433142
|
var init_mcp = __esm(async () => {
|
|
433143
|
+
init_oauth();
|
|
433211
433144
|
init_backend2();
|
|
433212
433145
|
init_client2();
|
|
433146
|
+
init_server_url();
|
|
433213
433147
|
init_unified_mcp();
|
|
433214
433148
|
init_mcp_client();
|
|
433215
433149
|
init_mcp_oauth();
|
|
@@ -433220,6 +433154,7 @@ var init_mcp = __esm(async () => {
|
|
|
433220
433154
|
init_mcp_runtime(),
|
|
433221
433155
|
init_mcp_tool_names()
|
|
433222
433156
|
]);
|
|
433157
|
+
SENSITIVE_NAME = /token|key|secret|password|signature|credential|auth/i;
|
|
433223
433158
|
});
|
|
433224
433159
|
|
|
433225
433160
|
// src/cli/subcommands/memory-tokens.ts
|
|
@@ -433248,7 +433183,7 @@ function printText(total, files, top, quiet) {
|
|
|
433248
433183
|
console.log(` ${formatNumber(row.tokens).padStart(8)} ${row.path}`);
|
|
433249
433184
|
}
|
|
433250
433185
|
}
|
|
433251
|
-
function
|
|
433186
|
+
function printJson2(total, files) {
|
|
433252
433187
|
console.log(JSON.stringify({
|
|
433253
433188
|
total_tokens: total,
|
|
433254
433189
|
files
|
|
@@ -433289,7 +433224,7 @@ async function runMemoryTokensAction(options) {
|
|
|
433289
433224
|
}
|
|
433290
433225
|
const { total, files } = estimate;
|
|
433291
433226
|
if (format5 === "json") {
|
|
433292
|
-
|
|
433227
|
+
printJson2(total, files);
|
|
433293
433228
|
} else {
|
|
433294
433229
|
printText(total, files, top, options.quiet);
|
|
433295
433230
|
}
|
|
@@ -433304,8 +433239,8 @@ var init_memory_tokens = __esm(() => {
|
|
|
433304
433239
|
import { cpSync, existsSync as existsSync57, mkdirSync as mkdirSync39, rmSync as rmSync12, statSync as statSync19 } from "node:fs";
|
|
433305
433240
|
import { readdir as readdir12 } from "node:fs/promises";
|
|
433306
433241
|
import { dirname as dirname31, join as join72 } from "node:path";
|
|
433307
|
-
import { parseArgs as
|
|
433308
|
-
function
|
|
433242
|
+
import { parseArgs as parseArgs11 } from "node:util";
|
|
433243
|
+
function printUsage8() {
|
|
433309
433244
|
console.log(`
|
|
433310
433245
|
Usage:
|
|
433311
433246
|
letta memory status [--agent <id>]
|
|
@@ -433338,7 +433273,7 @@ function getAgentId3(agentFromArgs, agentIdFromArgs) {
|
|
|
433338
433273
|
return agentFromArgs || agentIdFromArgs || process.env.LETTA_AGENT_ID || "";
|
|
433339
433274
|
}
|
|
433340
433275
|
function parseMemoryArgs(argv) {
|
|
433341
|
-
return
|
|
433276
|
+
return parseArgs11({
|
|
433342
433277
|
args: argv,
|
|
433343
433278
|
options: MEMORY_OPTIONS,
|
|
433344
433279
|
strict: true,
|
|
@@ -433399,12 +433334,12 @@ async function runMemorySubcommand(argv) {
|
|
|
433399
433334
|
} catch (error5) {
|
|
433400
433335
|
const message = error5 instanceof Error ? error5.message : String(error5);
|
|
433401
433336
|
console.error(`Error: ${message}`);
|
|
433402
|
-
|
|
433337
|
+
printUsage8();
|
|
433403
433338
|
return 1;
|
|
433404
433339
|
}
|
|
433405
433340
|
const [action3] = parsed.positionals;
|
|
433406
433341
|
if (parsed.values.help || !action3 || action3 === "help") {
|
|
433407
|
-
|
|
433342
|
+
printUsage8();
|
|
433408
433343
|
return 0;
|
|
433409
433344
|
}
|
|
433410
433345
|
const agentId = getAgentId3(parsed.values.agent, parsed.values["agent-id"]);
|
|
@@ -433548,7 +433483,7 @@ async function runMemorySubcommand(argv) {
|
|
|
433548
433483
|
return 1;
|
|
433549
433484
|
}
|
|
433550
433485
|
console.error(`Unknown action: ${action3}`);
|
|
433551
|
-
|
|
433486
|
+
printUsage8();
|
|
433552
433487
|
return 1;
|
|
433553
433488
|
}
|
|
433554
433489
|
var MEMORY_OPTIONS;
|
|
@@ -433907,8 +433842,8 @@ var init_message_search = __esm(() => {
|
|
|
433907
433842
|
// src/cli/subcommands/messages.ts
|
|
433908
433843
|
import { writeFile as writeFile16 } from "node:fs/promises";
|
|
433909
433844
|
import { resolve as resolve35 } from "node:path";
|
|
433910
|
-
import { parseArgs as
|
|
433911
|
-
function
|
|
433845
|
+
import { parseArgs as parseArgs12 } from "node:util";
|
|
433846
|
+
function printUsage9() {
|
|
433912
433847
|
console.log(`
|
|
433913
433848
|
Usage:
|
|
433914
433849
|
letta messages search --query <text> [options]
|
|
@@ -433993,7 +433928,7 @@ function pageItems4(page) {
|
|
|
433993
433928
|
return [];
|
|
433994
433929
|
}
|
|
433995
433930
|
function parseMessagesArgs(argv) {
|
|
433996
|
-
return
|
|
433931
|
+
return parseArgs12({
|
|
433997
433932
|
args: argv,
|
|
433998
433933
|
options: MESSAGES_OPTIONS,
|
|
433999
433934
|
strict: true,
|
|
@@ -434007,12 +433942,12 @@ async function runMessagesSubcommand(argv, deps = {}) {
|
|
|
434007
433942
|
} catch (error5) {
|
|
434008
433943
|
const message = error5 instanceof Error ? error5.message : String(error5);
|
|
434009
433944
|
console.error(`Error: ${message}`);
|
|
434010
|
-
|
|
433945
|
+
printUsage9();
|
|
434011
433946
|
return 1;
|
|
434012
433947
|
}
|
|
434013
433948
|
const [action3] = parsed.positionals;
|
|
434014
433949
|
if (parsed.values.help || !action3 || action3 === "help") {
|
|
434015
|
-
|
|
433950
|
+
printUsage9();
|
|
434016
433951
|
return 0;
|
|
434017
433952
|
}
|
|
434018
433953
|
try {
|
|
@@ -434254,7 +434189,7 @@ async function runMessagesSubcommand(argv, deps = {}) {
|
|
|
434254
434189
|
return 1;
|
|
434255
434190
|
}
|
|
434256
434191
|
console.error(`Unknown action: ${action3}`);
|
|
434257
|
-
|
|
434192
|
+
printUsage9();
|
|
434258
434193
|
return 1;
|
|
434259
434194
|
}
|
|
434260
434195
|
var MESSAGES_OPTIONS;
|
|
@@ -435284,8 +435219,8 @@ var init_package_scaffolder = __esm(() => {
|
|
|
435284
435219
|
|
|
435285
435220
|
// src/cli/subcommands/mods.ts
|
|
435286
435221
|
import { dirname as dirname32, join as join74 } from "node:path";
|
|
435287
|
-
import { parseArgs as
|
|
435288
|
-
function
|
|
435222
|
+
import { parseArgs as parseArgs13 } from "node:util";
|
|
435223
|
+
function printUsage10() {
|
|
435289
435224
|
console.log(`
|
|
435290
435225
|
Usage:
|
|
435291
435226
|
letta mods list [--agent <id>]
|
|
@@ -435302,7 +435237,7 @@ Options:
|
|
|
435302
435237
|
`.trim());
|
|
435303
435238
|
}
|
|
435304
435239
|
function parseModsArgs(argv) {
|
|
435305
|
-
return
|
|
435240
|
+
return parseArgs13({
|
|
435306
435241
|
args: argv,
|
|
435307
435242
|
options: MODS_OPTIONS,
|
|
435308
435243
|
strict: true,
|
|
@@ -435310,7 +435245,7 @@ function parseModsArgs(argv) {
|
|
|
435310
435245
|
});
|
|
435311
435246
|
}
|
|
435312
435247
|
function parseModsPackageArgs(argv) {
|
|
435313
|
-
return
|
|
435248
|
+
return parseArgs13({
|
|
435314
435249
|
args: argv,
|
|
435315
435250
|
options: MODS_PACKAGE_OPTIONS,
|
|
435316
435251
|
strict: true,
|
|
@@ -435408,16 +435343,16 @@ async function runList2(argv, options = {}) {
|
|
|
435408
435343
|
parsed = parseModsArgs(argv);
|
|
435409
435344
|
} catch (error5) {
|
|
435410
435345
|
console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
435411
|
-
|
|
435346
|
+
printUsage10();
|
|
435412
435347
|
return 1;
|
|
435413
435348
|
}
|
|
435414
435349
|
if (parsed.values.help) {
|
|
435415
|
-
|
|
435350
|
+
printUsage10();
|
|
435416
435351
|
return 0;
|
|
435417
435352
|
}
|
|
435418
435353
|
if (parsed.positionals.length > 0) {
|
|
435419
435354
|
console.error(`Unexpected argument: ${parsed.positionals[0]}`);
|
|
435420
|
-
|
|
435355
|
+
printUsage10();
|
|
435421
435356
|
return 1;
|
|
435422
435357
|
}
|
|
435423
435358
|
const agentId = getExplicitAgentId(parsed.values);
|
|
@@ -435434,27 +435369,27 @@ async function runPackageMutation(action3, argv, options = {}) {
|
|
|
435434
435369
|
parsed = parseModsArgs(argv);
|
|
435435
435370
|
} catch (error5) {
|
|
435436
435371
|
console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
435437
|
-
|
|
435372
|
+
printUsage10();
|
|
435438
435373
|
return 1;
|
|
435439
435374
|
}
|
|
435440
435375
|
if (parsed.values.help) {
|
|
435441
|
-
|
|
435376
|
+
printUsage10();
|
|
435442
435377
|
return 0;
|
|
435443
435378
|
}
|
|
435444
435379
|
if (getExplicitAgentId(parsed.values)) {
|
|
435445
435380
|
console.error(`--agent is only supported for 'letta mods list'.`);
|
|
435446
|
-
|
|
435381
|
+
printUsage10();
|
|
435447
435382
|
return 1;
|
|
435448
435383
|
}
|
|
435449
435384
|
const [specifier, extra] = parsed.positionals;
|
|
435450
435385
|
if (!specifier) {
|
|
435451
435386
|
console.error(`Missing package specifier.`);
|
|
435452
|
-
|
|
435387
|
+
printUsage10();
|
|
435453
435388
|
return 1;
|
|
435454
435389
|
}
|
|
435455
435390
|
if (extra) {
|
|
435456
435391
|
console.error(`Unexpected argument: ${extra}`);
|
|
435457
|
-
|
|
435392
|
+
printUsage10();
|
|
435458
435393
|
return 1;
|
|
435459
435394
|
}
|
|
435460
435395
|
try {
|
|
@@ -435480,27 +435415,27 @@ async function runPackageUpdate(argv, options = {}) {
|
|
|
435480
435415
|
parsed = parseModsArgs(argv);
|
|
435481
435416
|
} catch (error5) {
|
|
435482
435417
|
console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
435483
|
-
|
|
435418
|
+
printUsage10();
|
|
435484
435419
|
return 1;
|
|
435485
435420
|
}
|
|
435486
435421
|
if (parsed.values.help) {
|
|
435487
|
-
|
|
435422
|
+
printUsage10();
|
|
435488
435423
|
return 0;
|
|
435489
435424
|
}
|
|
435490
435425
|
if (getExplicitAgentId(parsed.values)) {
|
|
435491
435426
|
console.error(`--agent is not supported for 'letta mods update'.`);
|
|
435492
|
-
|
|
435427
|
+
printUsage10();
|
|
435493
435428
|
return 1;
|
|
435494
435429
|
}
|
|
435495
435430
|
const [specifier, extra] = parsed.positionals;
|
|
435496
435431
|
if (!specifier) {
|
|
435497
435432
|
console.error(`Missing package specifier.`);
|
|
435498
|
-
|
|
435433
|
+
printUsage10();
|
|
435499
435434
|
return 1;
|
|
435500
435435
|
}
|
|
435501
435436
|
if (extra) {
|
|
435502
435437
|
console.error(`Unexpected argument: ${extra}`);
|
|
435503
|
-
|
|
435438
|
+
printUsage10();
|
|
435504
435439
|
return 1;
|
|
435505
435440
|
}
|
|
435506
435441
|
try {
|
|
@@ -435522,33 +435457,33 @@ async function runPackageScaffold(argv) {
|
|
|
435522
435457
|
parsed = parseModsPackageArgs(argv);
|
|
435523
435458
|
} catch (error5) {
|
|
435524
435459
|
console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
435525
|
-
|
|
435460
|
+
printUsage10();
|
|
435526
435461
|
return 1;
|
|
435527
435462
|
}
|
|
435528
435463
|
if (parsed.values.help) {
|
|
435529
|
-
|
|
435464
|
+
printUsage10();
|
|
435530
435465
|
return 0;
|
|
435531
435466
|
}
|
|
435532
435467
|
if (getExplicitAgentId(parsed.values)) {
|
|
435533
435468
|
console.error(`--agent is not supported for 'letta mods package'.`);
|
|
435534
|
-
|
|
435469
|
+
printUsage10();
|
|
435535
435470
|
return 1;
|
|
435536
435471
|
}
|
|
435537
435472
|
const [sourceFile, extra] = parsed.positionals;
|
|
435538
435473
|
if (!sourceFile) {
|
|
435539
435474
|
console.error(`Missing mod file.`);
|
|
435540
|
-
|
|
435475
|
+
printUsage10();
|
|
435541
435476
|
return 1;
|
|
435542
435477
|
}
|
|
435543
435478
|
if (extra) {
|
|
435544
435479
|
console.error(`Unexpected argument: ${extra}`);
|
|
435545
|
-
|
|
435480
|
+
printUsage10();
|
|
435546
435481
|
return 1;
|
|
435547
435482
|
}
|
|
435548
435483
|
const packageName = parsed.values.name;
|
|
435549
435484
|
if (typeof packageName !== "string" || !packageName.trim()) {
|
|
435550
435485
|
console.error(`Missing required --name <package-name>.`);
|
|
435551
|
-
|
|
435486
|
+
printUsage10();
|
|
435552
435487
|
return 1;
|
|
435553
435488
|
}
|
|
435554
435489
|
try {
|
|
@@ -435570,7 +435505,7 @@ async function runPackageScaffold(argv) {
|
|
|
435570
435505
|
async function runModsSubcommand(argv, options = {}) {
|
|
435571
435506
|
const [action3, ...rest4] = argv;
|
|
435572
435507
|
if (!action3 || action3 === "help" || action3 === "--help" || action3 === "-h") {
|
|
435573
|
-
|
|
435508
|
+
printUsage10();
|
|
435574
435509
|
return 0;
|
|
435575
435510
|
}
|
|
435576
435511
|
switch (action3) {
|
|
@@ -435586,7 +435521,7 @@ async function runModsSubcommand(argv, options = {}) {
|
|
|
435586
435521
|
return runPackageMutation(action3, rest4, options);
|
|
435587
435522
|
default:
|
|
435588
435523
|
console.error(`Unknown mods action: ${action3}`);
|
|
435589
|
-
|
|
435524
|
+
printUsage10();
|
|
435590
435525
|
return 1;
|
|
435591
435526
|
}
|
|
435592
435527
|
}
|
|
@@ -435666,8 +435601,8 @@ var init_sandbox_files = __esm(() => {
|
|
|
435666
435601
|
// src/cli/subcommands/sandbox.ts
|
|
435667
435602
|
import { readFile as readFile24, stat as stat16, writeFile as writeFile17 } from "node:fs/promises";
|
|
435668
435603
|
import { basename as basename26, resolve as resolve36 } from "node:path";
|
|
435669
|
-
import { parseArgs as
|
|
435670
|
-
function
|
|
435604
|
+
import { parseArgs as parseArgs14 } from "node:util";
|
|
435605
|
+
function printUsage11() {
|
|
435671
435606
|
console.log(`
|
|
435672
435607
|
Usage:
|
|
435673
435608
|
letta sandbox upload <local-path>
|
|
@@ -435681,7 +435616,7 @@ Notes:
|
|
|
435681
435616
|
`.trim());
|
|
435682
435617
|
}
|
|
435683
435618
|
function parseSandboxArgs(argv) {
|
|
435684
|
-
return
|
|
435619
|
+
return parseArgs14({
|
|
435685
435620
|
args: argv,
|
|
435686
435621
|
options: SANDBOX_OPTIONS,
|
|
435687
435622
|
strict: true,
|
|
@@ -435721,17 +435656,17 @@ async function runSandboxSubcommand(argv, deps = {}) {
|
|
|
435721
435656
|
parsed = parseSandboxArgs(argv);
|
|
435722
435657
|
} catch (error5) {
|
|
435723
435658
|
console.error(`Error: ${error5 instanceof Error ? error5.message : error5}`);
|
|
435724
|
-
|
|
435659
|
+
printUsage11();
|
|
435725
435660
|
return 1;
|
|
435726
435661
|
}
|
|
435727
435662
|
const [action3, path48] = parsed.positionals;
|
|
435728
435663
|
if (parsed.values.help || !action3 || action3 === "help") {
|
|
435729
|
-
|
|
435664
|
+
printUsage11();
|
|
435730
435665
|
return 0;
|
|
435731
435666
|
}
|
|
435732
435667
|
if (action3 !== "upload" && action3 !== "download" || !path48) {
|
|
435733
435668
|
console.error("Error: expected upload or download with a file path");
|
|
435734
|
-
|
|
435669
|
+
printUsage11();
|
|
435735
435670
|
return 1;
|
|
435736
435671
|
}
|
|
435737
435672
|
try {
|
|
@@ -435775,8 +435710,8 @@ var init_sandbox2 = __esm(() => {
|
|
|
435775
435710
|
});
|
|
435776
435711
|
|
|
435777
435712
|
// src/cli/subcommands/secret.ts
|
|
435778
|
-
import { parseArgs as
|
|
435779
|
-
function
|
|
435713
|
+
import { parseArgs as parseArgs15 } from "node:util";
|
|
435714
|
+
function printUsage12() {
|
|
435780
435715
|
console.log(`
|
|
435781
435716
|
Usage:
|
|
435782
435717
|
letta secret set KEY --env SOURCE_VAR Set KEY from environment variable SOURCE_VAR
|
|
@@ -435801,7 +435736,7 @@ Notes:
|
|
|
435801
435736
|
`.trim());
|
|
435802
435737
|
}
|
|
435803
435738
|
function parseSecretArgs(argv) {
|
|
435804
|
-
return
|
|
435739
|
+
return parseArgs15({
|
|
435805
435740
|
args: argv,
|
|
435806
435741
|
options: SECRET_OPTIONS,
|
|
435807
435742
|
strict: true,
|
|
@@ -435836,11 +435771,11 @@ async function runSecretSubcommand(argv, deps = {}) {
|
|
|
435836
435771
|
parsed = parseSecretArgs(argv);
|
|
435837
435772
|
} catch (error5) {
|
|
435838
435773
|
printError(error5);
|
|
435839
|
-
|
|
435774
|
+
printUsage12();
|
|
435840
435775
|
return 1;
|
|
435841
435776
|
}
|
|
435842
435777
|
if (parsed.values.help || parsed.positionals.length === 0) {
|
|
435843
|
-
|
|
435778
|
+
printUsage12();
|
|
435844
435779
|
return parsed.values.help ? 0 : 1;
|
|
435845
435780
|
}
|
|
435846
435781
|
const [verb, rawKey, rawValue] = parsed.positionals;
|
|
@@ -435850,7 +435785,7 @@ async function runSecretSubcommand(argv, deps = {}) {
|
|
|
435850
435785
|
}
|
|
435851
435786
|
switch (verb) {
|
|
435852
435787
|
case "help": {
|
|
435853
|
-
|
|
435788
|
+
printUsage12();
|
|
435854
435789
|
return 0;
|
|
435855
435790
|
}
|
|
435856
435791
|
case "list": {
|
|
@@ -435958,7 +435893,7 @@ async function runSecretSubcommand(argv, deps = {}) {
|
|
|
435958
435893
|
}
|
|
435959
435894
|
default: {
|
|
435960
435895
|
console.error(`Unknown subcommand '${verb ?? ""}'.`);
|
|
435961
|
-
|
|
435896
|
+
printUsage12();
|
|
435962
435897
|
return 1;
|
|
435963
435898
|
}
|
|
435964
435899
|
}
|
|
@@ -435976,7 +435911,7 @@ var init_secret = __esm(() => {
|
|
|
435976
435911
|
});
|
|
435977
435912
|
|
|
435978
435913
|
// src/cli/subcommands/app-server.ts
|
|
435979
|
-
import { parseArgs as
|
|
435914
|
+
import { parseArgs as parseArgs16 } from "node:util";
|
|
435980
435915
|
function printAppServerHelp() {
|
|
435981
435916
|
console.log(`Usage: letta server --listen [url]
|
|
435982
435917
|
|
|
@@ -436024,7 +435959,7 @@ Stopped App Server (${signal}).`);
|
|
|
436024
435959
|
async function runAppServerSubcommand(argv) {
|
|
436025
435960
|
let parsed;
|
|
436026
435961
|
try {
|
|
436027
|
-
parsed =
|
|
435962
|
+
parsed = parseArgs16({
|
|
436028
435963
|
args: argv,
|
|
436029
435964
|
allowPositionals: false,
|
|
436030
435965
|
options: {
|
|
@@ -436609,7 +436544,7 @@ var init_setup6 = __esm(async () => {
|
|
|
436609
436544
|
});
|
|
436610
436545
|
|
|
436611
436546
|
// src/cli/subcommands/setup.ts
|
|
436612
|
-
function
|
|
436547
|
+
function printUsage13() {
|
|
436613
436548
|
console.log(`
|
|
436614
436549
|
Usage:
|
|
436615
436550
|
letta setup
|
|
@@ -436620,12 +436555,12 @@ Re-run the interactive setup menu to choose local mode or sign in with Letta.
|
|
|
436620
436555
|
async function runSetupSubcommand(argv) {
|
|
436621
436556
|
const [arg, ...rest4] = argv;
|
|
436622
436557
|
if (arg === "help" || arg === "--help" || arg === "-h") {
|
|
436623
|
-
|
|
436558
|
+
printUsage13();
|
|
436624
436559
|
return 0;
|
|
436625
436560
|
}
|
|
436626
436561
|
if (arg || rest4.length > 0) {
|
|
436627
436562
|
console.error(`Unexpected arguments: ${[arg, ...rest4].filter(Boolean).join(" ")}`);
|
|
436628
|
-
|
|
436563
|
+
printUsage13();
|
|
436629
436564
|
return 1;
|
|
436630
436565
|
}
|
|
436631
436566
|
await settingsManager.initialize();
|
|
@@ -436640,8 +436575,8 @@ var init_setup7 = __esm(async () => {
|
|
|
436640
436575
|
// src/cli/subcommands/shared-memory.ts
|
|
436641
436576
|
import { existsSync as existsSync61 } from "node:fs";
|
|
436642
436577
|
import { join as join75 } from "node:path";
|
|
436643
|
-
import { parseArgs as
|
|
436644
|
-
function
|
|
436578
|
+
import { parseArgs as parseArgs17 } from "node:util";
|
|
436579
|
+
function printUsage14() {
|
|
436645
436580
|
console.log(`
|
|
436646
436581
|
Usage:
|
|
436647
436582
|
letta shared-memory list [--agent <id>]
|
|
@@ -436676,7 +436611,7 @@ Examples:
|
|
|
436676
436611
|
`.trim());
|
|
436677
436612
|
}
|
|
436678
436613
|
function parseSharedMemoryArgs(argv) {
|
|
436679
|
-
return
|
|
436614
|
+
return parseArgs17({
|
|
436680
436615
|
args: argv,
|
|
436681
436616
|
options: SHARED_MEMORY_OPTIONS,
|
|
436682
436617
|
strict: true,
|
|
@@ -436752,12 +436687,12 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
|
|
|
436752
436687
|
parsed = parseSharedMemoryArgs(argv);
|
|
436753
436688
|
} catch (error5) {
|
|
436754
436689
|
console.error(error5 instanceof Error ? error5.message : String(error5));
|
|
436755
|
-
|
|
436690
|
+
printUsage14();
|
|
436756
436691
|
return 1;
|
|
436757
436692
|
}
|
|
436758
436693
|
const [action3, reference] = parsed.positionals;
|
|
436759
436694
|
if (parsed.values.help || !action3 || action3 === "help") {
|
|
436760
|
-
|
|
436695
|
+
printUsage14();
|
|
436761
436696
|
return 0;
|
|
436762
436697
|
}
|
|
436763
436698
|
if (isLocalBackendEnvEnabled()) {
|
|
@@ -436862,7 +436797,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
|
|
|
436862
436797
|
return result2.failed > 0 ? 1 : 0;
|
|
436863
436798
|
}
|
|
436864
436799
|
console.error(`Unknown action: ${action3}`);
|
|
436865
|
-
|
|
436800
|
+
printUsage14();
|
|
436866
436801
|
return 1;
|
|
436867
436802
|
} catch (error5) {
|
|
436868
436803
|
console.error(error5 instanceof Error ? error5.message : String(error5));
|
|
@@ -438370,8 +438305,8 @@ import {
|
|
|
438370
438305
|
import { mkdir as mkdir14, readdir as readdir13 } from "node:fs/promises";
|
|
438371
438306
|
import { tmpdir as tmpdir11 } from "node:os";
|
|
438372
438307
|
import { basename as basename27, dirname as dirname33, join as join76, normalize as normalize5, resolve as resolve37, sep as sep8 } from "node:path";
|
|
438373
|
-
import { parseArgs as
|
|
438374
|
-
function
|
|
438308
|
+
import { parseArgs as parseArgs18, TextDecoder as TextDecoder2, TextEncoder as TextEncoder2 } from "node:util";
|
|
438309
|
+
function printUsage15() {
|
|
438375
438310
|
console.log(`
|
|
438376
438311
|
Usage:
|
|
438377
438312
|
letta install <thing> [--agent <id> | -n <agent name>] [--force]
|
|
@@ -438398,7 +438333,7 @@ Options:
|
|
|
438398
438333
|
`.trim());
|
|
438399
438334
|
}
|
|
438400
438335
|
function parseSkillsArgs(argv) {
|
|
438401
|
-
return
|
|
438336
|
+
return parseArgs18({
|
|
438402
438337
|
args: argv,
|
|
438403
438338
|
options: SKILLS_OPTIONS,
|
|
438404
438339
|
strict: true,
|
|
@@ -439046,17 +438981,17 @@ async function runInstall(argv, options = {}) {
|
|
|
439046
438981
|
parsed = parseSkillsArgs(argv);
|
|
439047
438982
|
} catch (error5) {
|
|
439048
438983
|
console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
439049
|
-
|
|
438984
|
+
printUsage15();
|
|
439050
438985
|
return 1;
|
|
439051
438986
|
}
|
|
439052
438987
|
const [specifier] = parsed.positionals;
|
|
439053
438988
|
if (parsed.values.help || !specifier || specifier === "help") {
|
|
439054
|
-
|
|
438989
|
+
printUsage15();
|
|
439055
438990
|
return 0;
|
|
439056
438991
|
}
|
|
439057
438992
|
if (parsed.positionals.length > 1) {
|
|
439058
438993
|
console.error(`Unexpected argument: ${parsed.positionals[1]}`);
|
|
439059
|
-
|
|
438994
|
+
printUsage15();
|
|
439060
438995
|
return 1;
|
|
439061
438996
|
}
|
|
439062
438997
|
if (specifier.startsWith("npm:")) {
|
|
@@ -439147,16 +439082,16 @@ async function runList3(argv) {
|
|
|
439147
439082
|
parsed = parseSkillsArgs(argv);
|
|
439148
439083
|
} catch (error5) {
|
|
439149
439084
|
console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
439150
|
-
|
|
439085
|
+
printUsage15();
|
|
439151
439086
|
return 1;
|
|
439152
439087
|
}
|
|
439153
439088
|
if (parsed.values.help) {
|
|
439154
|
-
|
|
439089
|
+
printUsage15();
|
|
439155
439090
|
return 0;
|
|
439156
439091
|
}
|
|
439157
439092
|
if (parsed.positionals.length > 0) {
|
|
439158
439093
|
console.error(`Unexpected argument: ${parsed.positionals[0]}`);
|
|
439159
|
-
|
|
439094
|
+
printUsage15();
|
|
439160
439095
|
return 1;
|
|
439161
439096
|
}
|
|
439162
439097
|
try {
|
|
@@ -439177,17 +439112,17 @@ async function runDelete(argv) {
|
|
|
439177
439112
|
parsed = parseSkillsArgs(argv);
|
|
439178
439113
|
} catch (error5) {
|
|
439179
439114
|
console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
439180
|
-
|
|
439115
|
+
printUsage15();
|
|
439181
439116
|
return 1;
|
|
439182
439117
|
}
|
|
439183
439118
|
const [skillName] = parsed.positionals;
|
|
439184
439119
|
if (parsed.values.help || !skillName || skillName === "help") {
|
|
439185
|
-
|
|
439120
|
+
printUsage15();
|
|
439186
439121
|
return 0;
|
|
439187
439122
|
}
|
|
439188
439123
|
if (parsed.positionals.length > 1) {
|
|
439189
439124
|
console.error(`Unexpected argument: ${parsed.positionals[1]}`);
|
|
439190
|
-
|
|
439125
|
+
printUsage15();
|
|
439191
439126
|
return 1;
|
|
439192
439127
|
}
|
|
439193
439128
|
const agentId = getExplicitAgentId2(parsed.values);
|
|
@@ -439227,11 +439162,11 @@ async function runSkillsSubcommand(argv) {
|
|
|
439227
439162
|
case "help":
|
|
439228
439163
|
case "--help":
|
|
439229
439164
|
case "-h":
|
|
439230
|
-
|
|
439165
|
+
printUsage15();
|
|
439231
439166
|
return 0;
|
|
439232
439167
|
default:
|
|
439233
439168
|
console.error(`Unknown action: ${action3}`);
|
|
439234
|
-
|
|
439169
|
+
printUsage15();
|
|
439235
439170
|
return 1;
|
|
439236
439171
|
}
|
|
439237
439172
|
}
|
|
@@ -439250,8 +439185,8 @@ var init_skills4 = __esm(() => {
|
|
|
439250
439185
|
});
|
|
439251
439186
|
|
|
439252
439187
|
// src/cli/subcommands/teleport.ts
|
|
439253
|
-
import { parseArgs as
|
|
439254
|
-
function
|
|
439188
|
+
import { parseArgs as parseArgs19 } from "node:util";
|
|
439189
|
+
function printUsage16() {
|
|
439255
439190
|
console.log(`
|
|
439256
439191
|
Usage:
|
|
439257
439192
|
letta teleport list
|
|
@@ -439274,7 +439209,7 @@ Notes:
|
|
|
439274
439209
|
`.trim());
|
|
439275
439210
|
}
|
|
439276
439211
|
function parseTeleportArgs(argv) {
|
|
439277
|
-
return
|
|
439212
|
+
return parseArgs19({
|
|
439278
439213
|
args: argv,
|
|
439279
439214
|
options: TELEPORT_OPTIONS,
|
|
439280
439215
|
strict: true,
|
|
@@ -439347,12 +439282,12 @@ async function runTeleportSubcommand(argv, deps = {}) {
|
|
|
439347
439282
|
parsed = parseTeleportArgs(argv);
|
|
439348
439283
|
} catch (error5) {
|
|
439349
439284
|
console.error(`Error: ${error5 instanceof Error ? error5.message : error5}`);
|
|
439350
|
-
|
|
439285
|
+
printUsage16();
|
|
439351
439286
|
return 1;
|
|
439352
439287
|
}
|
|
439353
439288
|
const [action3] = parsed.positionals;
|
|
439354
439289
|
if (parsed.values.help || !action3 || action3 === "help") {
|
|
439355
|
-
|
|
439290
|
+
printUsage16();
|
|
439356
439291
|
return 0;
|
|
439357
439292
|
}
|
|
439358
439293
|
try {
|
|
@@ -439788,8 +439723,8 @@ var init_review = () => {};
|
|
|
439788
439723
|
|
|
439789
439724
|
// src/cli/subcommands/trajectories.ts
|
|
439790
439725
|
import { readFile as readFile28 } from "node:fs/promises";
|
|
439791
|
-
import { parseArgs as
|
|
439792
|
-
function
|
|
439726
|
+
import { parseArgs as parseArgs20 } from "node:util";
|
|
439727
|
+
function printUsage17() {
|
|
439793
439728
|
console.log(`
|
|
439794
439729
|
Usage:
|
|
439795
439730
|
letta trajectories export [options]
|
|
@@ -439927,7 +439862,7 @@ ${results.length} session(s) matched "${keyword}"`);
|
|
|
439927
439862
|
return 0;
|
|
439928
439863
|
}
|
|
439929
439864
|
function parseTrajectoriesArgs(argv) {
|
|
439930
|
-
return
|
|
439865
|
+
return parseArgs20({
|
|
439931
439866
|
args: argv,
|
|
439932
439867
|
options: TRAJECTORIES_OPTIONS,
|
|
439933
439868
|
strict: true,
|
|
@@ -439940,12 +439875,12 @@ async function runTrajectoriesSubcommand(argv) {
|
|
|
439940
439875
|
parsed = parseTrajectoriesArgs(argv);
|
|
439941
439876
|
} catch (error5) {
|
|
439942
439877
|
console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
439943
|
-
|
|
439878
|
+
printUsage17();
|
|
439944
439879
|
return 1;
|
|
439945
439880
|
}
|
|
439946
439881
|
const [action3] = parsed.positionals;
|
|
439947
439882
|
if (parsed.values.help || action3 === "help" || !action3) {
|
|
439948
|
-
|
|
439883
|
+
printUsage17();
|
|
439949
439884
|
return parsed.values.help || action3 === "help" ? 0 : 1;
|
|
439950
439885
|
}
|
|
439951
439886
|
const asJson = Boolean(parsed.values.json);
|
|
@@ -439977,7 +439912,7 @@ async function runTrajectoriesSubcommand(argv) {
|
|
|
439977
439912
|
}
|
|
439978
439913
|
if (action3 !== "export") {
|
|
439979
439914
|
console.error(`Unknown command: ${action3}`);
|
|
439980
|
-
|
|
439915
|
+
printUsage17();
|
|
439981
439916
|
return 1;
|
|
439982
439917
|
}
|
|
439983
439918
|
const options = {
|
|
@@ -441526,9 +441461,9 @@ class ChannelRichDraftStreamerImpl {
|
|
|
441526
441461
|
return;
|
|
441527
441462
|
}
|
|
441528
441463
|
const record5 = asRecord10(chunk2);
|
|
441529
|
-
const messageType =
|
|
441464
|
+
const messageType = stringValue5(record5?.message_type);
|
|
441530
441465
|
if (messageType === "tool_return_message") {
|
|
441531
|
-
const toolCallId =
|
|
441466
|
+
const toolCallId = stringValue5(record5?.tool_call_id);
|
|
441532
441467
|
if (toolCallId) {
|
|
441533
441468
|
this.finishCall(toolCallId);
|
|
441534
441469
|
}
|
|
@@ -441821,14 +441756,14 @@ function extractToolCallFragments2(record5) {
|
|
|
441821
441756
|
const fragments = [];
|
|
441822
441757
|
for (const rawToolCall of rawToolCalls) {
|
|
441823
441758
|
const toolCall = asRecord10(rawToolCall);
|
|
441824
|
-
const toolCallId =
|
|
441759
|
+
const toolCallId = stringValue5(toolCall?.tool_call_id);
|
|
441825
441760
|
if (!toolCallId) {
|
|
441826
441761
|
continue;
|
|
441827
441762
|
}
|
|
441828
441763
|
fragments.push({
|
|
441829
441764
|
toolCallId,
|
|
441830
|
-
name:
|
|
441831
|
-
argumentsDelta:
|
|
441765
|
+
name: stringValue5(toolCall?.name),
|
|
441766
|
+
argumentsDelta: stringValue5(toolCall?.arguments)
|
|
441832
441767
|
});
|
|
441833
441768
|
}
|
|
441834
441769
|
return fragments;
|
|
@@ -441948,7 +441883,7 @@ function buildDraftId(seed) {
|
|
|
441948
441883
|
function asRecord10(value) {
|
|
441949
441884
|
return value && typeof value === "object" ? value : null;
|
|
441950
441885
|
}
|
|
441951
|
-
function
|
|
441886
|
+
function stringValue5(value) {
|
|
441952
441887
|
return typeof value === "string" ? value : undefined;
|
|
441953
441888
|
}
|
|
441954
441889
|
var MESSAGE_CHANNEL_TOOL_NAMES, DEFAULT_DRAFT_DEBOUNCE_MS = 1000, MIN_DRAFT_TEXT_LENGTH = 1;
|
|
@@ -444816,14 +444751,14 @@ var exports_channel_gateway = {};
|
|
|
444816
444751
|
__export(exports_channel_gateway, {
|
|
444817
444752
|
runChannelGatewaySubcommand: () => runChannelGatewaySubcommand
|
|
444818
444753
|
});
|
|
444819
|
-
import { parseArgs as
|
|
444754
|
+
import { parseArgs as parseArgs21 } from "node:util";
|
|
444820
444755
|
function isGatewayCommandEnvelope(value) {
|
|
444821
444756
|
return Boolean(value && typeof value === "object" && "type" in value && value.type === "command" && "requestId" in value && typeof value.requestId === "string" && "command" in value && value.command && typeof value.command === "object");
|
|
444822
444757
|
}
|
|
444823
444758
|
async function runChannelGatewaySubcommand(argv) {
|
|
444824
444759
|
let values3;
|
|
444825
444760
|
try {
|
|
444826
|
-
({ values: values3 } =
|
|
444761
|
+
({ values: values3 } = parseArgs21({
|
|
444827
444762
|
args: argv,
|
|
444828
444763
|
strict: true,
|
|
444829
444764
|
allowPositionals: false,
|
|
@@ -444963,7 +444898,6 @@ function subcommandNeedsEarlyBackendMode(command) {
|
|
|
444963
444898
|
case "sandbox":
|
|
444964
444899
|
case "secret":
|
|
444965
444900
|
case "server":
|
|
444966
|
-
case "cloud-mcp":
|
|
444967
444901
|
case "shared-memory":
|
|
444968
444902
|
case "skills":
|
|
444969
444903
|
case "teleport":
|
|
@@ -445008,8 +444942,6 @@ async function runSubcommand(argv) {
|
|
|
445008
444942
|
return runTeleportSubcommand(rest4);
|
|
445009
444943
|
case "server":
|
|
445010
444944
|
return runServerSubcommand(rest4);
|
|
445011
|
-
case "cloud-mcp":
|
|
445012
|
-
return runCloudMcpSubcommand(rest4);
|
|
445013
444945
|
case "feedback":
|
|
445014
444946
|
return runFeedbackSubcommand(rest4);
|
|
445015
444947
|
case "remote":
|
|
@@ -445047,7 +444979,6 @@ var init_router = __esm(async () => {
|
|
|
445047
444979
|
init_agents6();
|
|
445048
444980
|
init_backend3();
|
|
445049
444981
|
init_channels();
|
|
445050
|
-
init_cloud_mcp();
|
|
445051
444982
|
init_connect();
|
|
445052
444983
|
init_environments3();
|
|
445053
444984
|
init_feedback3();
|
|
@@ -445283,8 +445214,8 @@ async function startDockerVersionCheck() {
|
|
|
445283
445214
|
}
|
|
445284
445215
|
var MINIMUM_DOCKER_VERSION = "0.16.6";
|
|
445285
445216
|
var init_startup_docker_check = __esm(() => {
|
|
445286
|
-
init_client2();
|
|
445287
445217
|
init_health();
|
|
445218
|
+
init_server_url();
|
|
445288
445219
|
});
|
|
445289
445220
|
|
|
445290
445221
|
// src/agent/bootstrap-tools.ts
|
|
@@ -446917,7 +446848,7 @@ async function ensureDefaultAgents(backend3, options) {
|
|
|
446917
446848
|
}
|
|
446918
446849
|
var MEMO_TAG = "default:memo", TUTOR_TAG = "default:tutorial", MEMO_PERSONA, MEMO_HUMAN, MEMO_DESCRIPTION = "The default Letta Code agent with persistent memory", DEFAULT_AGENT_CONFIGS;
|
|
446919
446850
|
var init_defaults = __esm(() => {
|
|
446920
|
-
|
|
446851
|
+
init_server_url();
|
|
446921
446852
|
init_settings_manager();
|
|
446922
446853
|
init_create5();
|
|
446923
446854
|
init_memory();
|
|
@@ -465759,6 +465690,110 @@ var init_LettaLoginOverlay = __esm(async () => {
|
|
|
465759
465690
|
jsx_dev_runtime63 = __toESM(require_jsx_dev_runtime(), 1);
|
|
465760
465691
|
});
|
|
465761
465692
|
|
|
465693
|
+
// src/backend/api/mcp-servers.ts
|
|
465694
|
+
function withTimeout3(promise2, timeoutMs, label) {
|
|
465695
|
+
let timer;
|
|
465696
|
+
const timeout = new Promise((_4, reject2) => {
|
|
465697
|
+
timer = setTimeout(() => reject2(new Error(`${label} timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
465698
|
+
});
|
|
465699
|
+
return Promise.race([promise2, timeout]).finally(() => {
|
|
465700
|
+
if (timer !== undefined)
|
|
465701
|
+
clearTimeout(timer);
|
|
465702
|
+
});
|
|
465703
|
+
}
|
|
465704
|
+
function listServerMcpServers(client, timeoutMs = 1e4) {
|
|
465705
|
+
return withTimeout3(client.mcpServers.list(), timeoutMs, "Listing server-side MCP servers");
|
|
465706
|
+
}
|
|
465707
|
+
async function listLiveServerMcpTools(client, serverName2, timeoutMs = 15000) {
|
|
465708
|
+
const result2 = await withTimeout3(client.get(`/v1/tools/mcp/servers/${encodeURIComponent(serverName2)}/tools`), timeoutMs, `Listing tools for MCP server "${serverName2}"`);
|
|
465709
|
+
if (!Array.isArray(result2))
|
|
465710
|
+
return [];
|
|
465711
|
+
return result2.filter((tool) => typeof tool === "object" && tool !== null && typeof tool.name === "string");
|
|
465712
|
+
}
|
|
465713
|
+
async function loadServerMcpEntries(client, timeoutMs = 15000) {
|
|
465714
|
+
const servers = await listServerMcpServers(client, timeoutMs);
|
|
465715
|
+
return Promise.all(servers.map(async (server2) => {
|
|
465716
|
+
try {
|
|
465717
|
+
const tools = await listLiveServerMcpTools(client, server2.server_name, timeoutMs);
|
|
465718
|
+
return { server: server2, tools };
|
|
465719
|
+
} catch (cause) {
|
|
465720
|
+
return {
|
|
465721
|
+
server: server2,
|
|
465722
|
+
tools: [],
|
|
465723
|
+
toolsError: cause instanceof Error ? cause.message : String(cause)
|
|
465724
|
+
};
|
|
465725
|
+
}
|
|
465726
|
+
}));
|
|
465727
|
+
}
|
|
465728
|
+
function parseMcpMetadata(tool) {
|
|
465729
|
+
const metadata = tool.metadata_;
|
|
465730
|
+
const mcp = metadata?.mcp;
|
|
465731
|
+
if (typeof mcp !== "object" || mcp === null)
|
|
465732
|
+
return null;
|
|
465733
|
+
const { server_id, server_name } = mcp;
|
|
465734
|
+
return {
|
|
465735
|
+
...typeof server_id === "string" && { serverId: server_id },
|
|
465736
|
+
...typeof server_name === "string" && { serverName: server_name }
|
|
465737
|
+
};
|
|
465738
|
+
}
|
|
465739
|
+
async function listAgentMcpAttachments(client, agentId) {
|
|
465740
|
+
const attachments = [];
|
|
465741
|
+
for await (const tool of client.agents.tools.list(agentId, { limit: 100 })) {
|
|
465742
|
+
if (tool.tool_type !== "external_mcp" || !tool.id || !tool.name)
|
|
465743
|
+
continue;
|
|
465744
|
+
attachments.push({
|
|
465745
|
+
toolId: tool.id,
|
|
465746
|
+
toolName: tool.name,
|
|
465747
|
+
...parseMcpMetadata(tool)
|
|
465748
|
+
});
|
|
465749
|
+
}
|
|
465750
|
+
return attachments;
|
|
465751
|
+
}
|
|
465752
|
+
function attachmentsForEntry(entry, attachments) {
|
|
465753
|
+
return attachments.filter((attachment) => attachment.serverId && entry.server.id ? attachment.serverId === entry.server.id : attachment.serverName === entry.server.server_name);
|
|
465754
|
+
}
|
|
465755
|
+
function attachedToolNamesForEntry(entry, attachments) {
|
|
465756
|
+
return new Set(attachmentsForEntry(entry, attachments).map((attachment) => attachment.toolName));
|
|
465757
|
+
}
|
|
465758
|
+
async function registerServerMcpTool(client, serverName2, toolName) {
|
|
465759
|
+
const result2 = await client.post(`/v1/tools/mcp/servers/${encodeURIComponent(serverName2)}/${encodeURIComponent(toolName)}`);
|
|
465760
|
+
if (typeof result2?.id !== "string") {
|
|
465761
|
+
throw new Error(`Registering MCP tool "${toolName}" on server "${serverName2}" returned no tool id`);
|
|
465762
|
+
}
|
|
465763
|
+
return { id: result2.id };
|
|
465764
|
+
}
|
|
465765
|
+
async function attachServerMcpTools(client, agentId, serverName2, toolNames) {
|
|
465766
|
+
await Promise.all(toolNames.map(async (toolName) => {
|
|
465767
|
+
const { id: id2 } = await registerServerMcpTool(client, serverName2, toolName);
|
|
465768
|
+
await client.agents.tools.attach(id2, { agent_id: agentId });
|
|
465769
|
+
}));
|
|
465770
|
+
}
|
|
465771
|
+
async function detachServerMcpTools(client, agentId, toolIds) {
|
|
465772
|
+
await Promise.all(toolIds.map((toolId) => client.agents.tools.detach(toolId, { agent_id: agentId })));
|
|
465773
|
+
}
|
|
465774
|
+
function refreshServerMcpServer(client, mcpServerId, agentId) {
|
|
465775
|
+
return client.mcpServers.refresh(mcpServerId, { agent_id: agentId });
|
|
465776
|
+
}
|
|
465777
|
+
function planServerMcpToggle(entry, attachments) {
|
|
465778
|
+
const attached = attachmentsForEntry(entry, attachments);
|
|
465779
|
+
if (attached.length > 0) {
|
|
465780
|
+
return {
|
|
465781
|
+
action: "detach",
|
|
465782
|
+
toolIds: attached.map((attachment) => attachment.toolId)
|
|
465783
|
+
};
|
|
465784
|
+
}
|
|
465785
|
+
return { action: "attach", toolNames: entry.tools.map((tool) => tool.name) };
|
|
465786
|
+
}
|
|
465787
|
+
function describeServerMcpTarget(server2) {
|
|
465788
|
+
if ("server_url" in server2 && server2.server_url) {
|
|
465789
|
+
return server2.server_url;
|
|
465790
|
+
}
|
|
465791
|
+
if ("command" in server2 && server2.command) {
|
|
465792
|
+
return [server2.command, ...server2.args ?? []].join(" ");
|
|
465793
|
+
}
|
|
465794
|
+
return "";
|
|
465795
|
+
}
|
|
465796
|
+
|
|
465762
465797
|
// src/cli/components/McpSelector.tsx
|
|
465763
465798
|
function buildMcpRows(localStates, serverEntries) {
|
|
465764
465799
|
return [
|
|
@@ -465875,7 +465910,6 @@ var import_react87, jsx_dev_runtime64, SOLID_LINE12 = "─", DISPLAY_PAGE_SIZE2
|
|
|
465875
465910
|
var init_McpSelector = __esm(async () => {
|
|
465876
465911
|
init_backend2();
|
|
465877
465912
|
init_client2();
|
|
465878
|
-
init_mcp_servers2();
|
|
465879
465913
|
init_truncate_text();
|
|
465880
465914
|
init_use_terminal_width();
|
|
465881
465915
|
init_mcp_oauth();
|
|
@@ -468917,6 +468951,7 @@ var init_generate_memory_viewer = __esm(() => {
|
|
|
468917
468951
|
init_agents7();
|
|
468918
468952
|
init_client2();
|
|
468919
468953
|
init_request();
|
|
468954
|
+
init_server_url();
|
|
468920
468955
|
init_context_usage();
|
|
468921
468956
|
init_local_memory_context();
|
|
468922
468957
|
init_memory_viewer_template();
|
|
@@ -475505,7 +475540,7 @@ var init_ToolCallMessageRich = __esm(async () => {
|
|
|
475505
475540
|
let shellSemanticKind = null;
|
|
475506
475541
|
let hasShellDescription = false;
|
|
475507
475542
|
if (!isQuestionTool(rawName)) {
|
|
475508
|
-
const
|
|
475543
|
+
const parseArgs22 = () => {
|
|
475509
475544
|
if (!argsText.trim()) {
|
|
475510
475545
|
return { formatted: null, parseable: true };
|
|
475511
475546
|
}
|
|
@@ -475519,7 +475554,7 @@ var init_ToolCallMessageRich = __esm(async () => {
|
|
|
475519
475554
|
return { formatted: null, parseable: false };
|
|
475520
475555
|
}
|
|
475521
475556
|
};
|
|
475522
|
-
const { formatted, parseable } =
|
|
475557
|
+
const { formatted, parseable } = parseArgs22();
|
|
475523
475558
|
const argsComplete = parseable || line.phase === "running" || line.phase === "finished" || !isStreaming;
|
|
475524
475559
|
if (!argsComplete) {
|
|
475525
475560
|
args = "(…)";
|
|
@@ -477735,7 +477770,7 @@ function updateCommandResult(buffersRef, refreshDerived, cmdId, input, output, s
|
|
|
477735
477770
|
buffersRef.current.byId.set(cmdId, line);
|
|
477736
477771
|
refreshDerived();
|
|
477737
477772
|
}
|
|
477738
|
-
function
|
|
477773
|
+
function parseArgs22(msg) {
|
|
477739
477774
|
return msg.trim().split(/\s+/).filter(Boolean);
|
|
477740
477775
|
}
|
|
477741
477776
|
function formatConnectUsage() {
|
|
@@ -478117,7 +478152,7 @@ ${formatBedrockUsage2()}`, false);
|
|
|
478117
478152
|
}
|
|
478118
478153
|
}
|
|
478119
478154
|
async function handleConnect(ctx, msg) {
|
|
478120
|
-
const parts =
|
|
478155
|
+
const parts = parseArgs22(msg);
|
|
478121
478156
|
const providerToken = parts[1];
|
|
478122
478157
|
if (!providerToken) {
|
|
478123
478158
|
addCommandResult(ctx.buffersRef, ctx.refreshDerived, msg, formatConnectUsage(), false);
|
|
@@ -497893,7 +497928,7 @@ var init_use_conversation_switching = __esm(async () => {
|
|
|
497893
497928
|
init_create5();
|
|
497894
497929
|
init_defaults();
|
|
497895
497930
|
init_backend2();
|
|
497896
|
-
|
|
497931
|
+
init_server_url();
|
|
497897
497932
|
init_app_urls();
|
|
497898
497933
|
init_backfill();
|
|
497899
497934
|
init_error_formatter();
|
|
@@ -497946,6 +497981,8 @@ function useFeedbackHandler(ctx) {
|
|
|
497946
497981
|
await submitFeedbackMetadata(apiKey, settingsManager.getOrCreateDeviceId(), {
|
|
497947
497982
|
message: resolvedMessage,
|
|
497948
497983
|
feature: "letta-code",
|
|
497984
|
+
submission_source: "slash_command",
|
|
497985
|
+
client_type: getFeedbackClientType(),
|
|
497949
497986
|
agent_id: agentId,
|
|
497950
497987
|
session_id: telemetry.getSessionId(),
|
|
497951
497988
|
run_id: lastRunIdRef.current ?? undefined,
|
|
@@ -509060,7 +509097,6 @@ USAGE
|
|
|
509060
509097
|
letta teleport ... Move the current conversation between environments
|
|
509061
509098
|
letta messages ... Messages subcommands (JSON-only)
|
|
509062
509099
|
letta mcp ... List, search, and call MCP servers available to an agent
|
|
509063
|
-
letta cloud-mcp ... Legacy server-side MCP commands (JSON-only)
|
|
509064
509100
|
letta mods ... List and manage local mods
|
|
509065
509101
|
letta sandbox ... Transfer files to or from the current Cloud sandbox
|
|
509066
509102
|
letta server ... Run a remote environment, channels, or the App Server
|
|
@@ -509088,7 +509124,6 @@ SUBCOMMANDS
|
|
|
509088
509124
|
letta messages search --query <text> [--all-agents]
|
|
509089
509125
|
letta messages list [--agent <id>]
|
|
509090
509126
|
letta messages transcript --conversation <id> [--out <path>]
|
|
509091
|
-
letta cloud-mcp list|tools|run ... [--agent <id>]
|
|
509092
509127
|
letta mods list [--agent <id>]
|
|
509093
509128
|
letta mods package <mod-file> --name <package-name> [--out <dir>]
|
|
509094
509129
|
letta mods enable <package-spec>
|
|
@@ -512915,4 +512950,4 @@ function registerBunOAuthFlows() {
|
|
|
512915
512950
|
registerBunOAuthFlows();
|
|
512916
512951
|
await init_src5().then(() => exports_src2);
|
|
512917
512952
|
|
|
512918
|
-
//# debugId=
|
|
512953
|
+
//# debugId=A04282B12C1CC94F64756E2164756E21
|