@letta-ai/letta-code 0.31.10 → 0.31.12
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 +17 -15
- package/dist/agent-presets.js +3 -3
- package/dist/agent-presets.js.map +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/agent/subagents/manager.d.ts +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/reminders/state.d.ts +4 -0
- package/dist/types/reminders/state.d.ts.map +1 -1
- package/dist/types/tools/impl/task.d.ts +2 -2
- package/letta.js +796 -864
- package/package.json +1 -1
- package/scripts/source-file-size-baseline.json +2 -2
- package/skills/browser-use/SKILL.md +22 -61
- package/skills/messaging-agents/SKILL.md +17 -17
- package/skills/scheduling-tasks/SKILL.md +1 -1
- package/skills/submitting-feedback/SKILL.md +17 -5
- package/skills/teleporting-between-environments/SKILL.md +12 -12
- package/skills/using-mcp-tools/SKILL.md +44 -0
- package/skills/using-cloud-mcp/SKILL.md +0 -37
package/letta.js
CHANGED
|
@@ -5400,7 +5400,7 @@ var package_default;
|
|
|
5400
5400
|
var init_package = __esm(() => {
|
|
5401
5401
|
package_default = {
|
|
5402
5402
|
name: "@letta-ai/letta-code",
|
|
5403
|
-
version: "0.31.
|
|
5403
|
+
version: "0.31.12",
|
|
5404
5404
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
5405
5405
|
type: "module",
|
|
5406
5406
|
packageManager: "bun@1.3.10",
|
|
@@ -5781,6 +5781,15 @@ function isLoopbackUrl(value, options = {}) {
|
|
|
5781
5781
|
}
|
|
5782
5782
|
|
|
5783
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
|
+
}
|
|
5784
5793
|
async function getBalanceMetadata() {
|
|
5785
5794
|
return apiRequest("GET", "/v1/metadata/balance");
|
|
5786
5795
|
}
|
|
@@ -7959,7 +7968,7 @@ Other
|
|
|
7959
7968
|
- [ ] Make a permissions edit: let the user know that you can modify permissions (what commands are automatically approved/denied). Ask them if there are certain actions they would like you to avoid.
|
|
7960
7969
|
- [ ] Create a local mod: let the user know you can customize Letta Code with trusted local mods for new tools, slash commands, provider integrations, UI panels/status, events, or permission overlays. Explain that mods are for executable harness behavior, while memory and skills are for retained knowledge and reusable procedures.
|
|
7961
7970
|
- [ ] Worktrees: let the user know that you can help them orchestrate many agents in parallel, and also work in parallel to other agents. Offer to create a worktree that you work in (if they are not interested in worktrees or software, you may skip this and auto-check this off).
|
|
7962
|
-
- [ ] Moving machines: ask the user to
|
|
7971
|
+
- [ ] Moving machines: ask the user to connect another computer (they can either run another desktop instance or run \`letta server\` on another machine) and run you there instead.
|
|
7963
7972
|
`;
|
|
7964
7973
|
var init_onboarding = () => {};
|
|
7965
7974
|
|
|
@@ -8012,7 +8021,7 @@ Other
|
|
|
8012
8021
|
- [ ] Make a permissions edit: let the user know that you can modify permissions (what commands are automatically approved/denied). Ask them if there are certain actions they would like you to avoid.
|
|
8013
8022
|
- [ ] Create a local mod: let the user know you can customize Letta Code with trusted local mods for new tools, slash commands, provider integrations, UI panels/status, events, or permission overlays. Explain that mods are for executable harness behavior, while memory and skills are for retained knowledge and reusable procedures.
|
|
8014
8023
|
- [ ] Worktrees: let the user know that you can help them orchestrate many agents in parallel, and also work in parallel to other agents. Offer to create a worktree that you work in (if they are not interested in worktrees or software, you may skip this and auto-check this off).
|
|
8015
|
-
- [ ] Moving machines: ask the user to
|
|
8024
|
+
- [ ] Moving machines: ask the user to connect another computer (they can either run another desktop instance or run \`letta server\` on another machine) and run you there instead.
|
|
8016
8025
|
`;
|
|
8017
8026
|
var init_onboarding_local = () => {};
|
|
8018
8027
|
|
|
@@ -90861,6 +90870,9 @@ function createSharedReminderState() {
|
|
|
90861
90870
|
hasSentSecretsInfo: false,
|
|
90862
90871
|
pendingSecretsInfoRefresh: false,
|
|
90863
90872
|
lastSentSecretNamesKey: null,
|
|
90873
|
+
hasSentMcpServersInfo: false,
|
|
90874
|
+
lastSentMcpServerNamesKey: null,
|
|
90875
|
+
lastMcpServersFetchedAtMs: null,
|
|
90864
90876
|
lastNotifiedPermissionMode: null,
|
|
90865
90877
|
turnCount: 0,
|
|
90866
90878
|
pendingReflectionTrigger: false,
|
|
@@ -90877,6 +90889,8 @@ function markPostCompactionContextRemindersPending(state) {
|
|
|
90877
90889
|
state.hasSentSessionContext = false;
|
|
90878
90890
|
state.pendingSessionContextReason ??= "post_compaction";
|
|
90879
90891
|
state.hasSentSecretsInfo = false;
|
|
90892
|
+
state.hasSentMcpServersInfo = false;
|
|
90893
|
+
state.lastMcpServersFetchedAtMs = null;
|
|
90880
90894
|
state.lastNotifiedPermissionMode = null;
|
|
90881
90895
|
}
|
|
90882
90896
|
function syncReminderStateFromContextTracker(state, contextTracker) {
|
|
@@ -113434,8 +113448,7 @@ var init_skills3 = __esm(() => {
|
|
|
113434
113448
|
init_skill_sources();
|
|
113435
113449
|
LOCAL_AGENT_EXCLUDED_BUNDLED_SKILLS = new Set([
|
|
113436
113450
|
"image-generation",
|
|
113437
|
-
"managing-shared-memory"
|
|
113438
|
-
"using-cloud-mcp"
|
|
113451
|
+
"managing-shared-memory"
|
|
113439
113452
|
]);
|
|
113440
113453
|
PROJECT_SKILLS_DIR = join24(".agents", "skills");
|
|
113441
113454
|
GLOBAL_SKILLS_DIR = join24(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
|
|
@@ -114788,7 +114801,7 @@ function buildSubagentArgs(type3, config, model, userPrompt, existingAgentId, ex
|
|
|
114788
114801
|
args.push("--backend", options.backendMode);
|
|
114789
114802
|
}
|
|
114790
114803
|
if (options.environment) {
|
|
114791
|
-
args.push("--
|
|
114804
|
+
args.push("--computer", options.environment);
|
|
114792
114805
|
}
|
|
114793
114806
|
if (isDeployingExisting) {
|
|
114794
114807
|
if (existingConversationId) {
|
|
@@ -137011,14 +137024,15 @@ var init_args = __esm(() => {
|
|
|
137011
137024
|
description: "Inject agent-to-agent system reminder (headless mode)"
|
|
137012
137025
|
}
|
|
137013
137026
|
},
|
|
137014
|
-
|
|
137027
|
+
computer: {
|
|
137015
137028
|
parser: { type: "string" },
|
|
137016
137029
|
mode: "headless",
|
|
137017
137030
|
help: {
|
|
137018
137031
|
argLabel: "<selector>",
|
|
137019
|
-
description: "Route headless message through 'cloud'
|
|
137032
|
+
description: "Route headless message through 'cloud' or a computer by name, device ID, or connection ID"
|
|
137020
137033
|
}
|
|
137021
137034
|
},
|
|
137035
|
+
environment: { parser: { type: "string" }, mode: "headless" },
|
|
137022
137036
|
env: { parser: { type: "string" }, mode: "headless" },
|
|
137023
137037
|
skills: {
|
|
137024
137038
|
parser: { type: "string" },
|
|
@@ -185677,6 +185691,8 @@ function buildChannelFeedbackPayload(submission) {
|
|
|
185677
185691
|
return withDefinedValues2({
|
|
185678
185692
|
message: submission.message,
|
|
185679
185693
|
feature: CHANNEL_FEEDBACK_FEATURE,
|
|
185694
|
+
submission_source: "slash_command",
|
|
185695
|
+
client_type: process.env.LETTA_DESKTOP_MODE === "1" ? "desktop" : "cli",
|
|
185680
185696
|
version: getVersion(),
|
|
185681
185697
|
platform: process.platform,
|
|
185682
185698
|
channel: submission.channel,
|
|
@@ -199431,330 +199447,6 @@ var init_channels = __esm(() => {
|
|
|
199431
199447
|
};
|
|
199432
199448
|
});
|
|
199433
199449
|
|
|
199434
|
-
// src/backend/api/mcp-servers.ts
|
|
199435
|
-
function getString(record3, key2) {
|
|
199436
|
-
const value = record3[key2];
|
|
199437
|
-
return typeof value === "string" ? value : null;
|
|
199438
|
-
}
|
|
199439
|
-
function parseAgentConnectedMcpServer(value) {
|
|
199440
|
-
if (!isRecord(value)) {
|
|
199441
|
-
return null;
|
|
199442
|
-
}
|
|
199443
|
-
const id2 = getString(value, "id");
|
|
199444
|
-
const serverName = getString(value, "server_name");
|
|
199445
|
-
const serverType = getString(value, "mcp_server_type");
|
|
199446
|
-
if (!id2 || !serverName || !serverType) {
|
|
199447
|
-
return null;
|
|
199448
|
-
}
|
|
199449
|
-
const target2 = getString(value, "server_url") ?? [
|
|
199450
|
-
getString(value, "command"),
|
|
199451
|
-
...Array.isArray(value.args) ? value.args : []
|
|
199452
|
-
].filter((item) => typeof item === "string").join(" ");
|
|
199453
|
-
return { id: id2, serverName, serverType, target: target2 };
|
|
199454
|
-
}
|
|
199455
|
-
function parseAgentConnectedMcpTool(value) {
|
|
199456
|
-
if (!isRecord(value)) {
|
|
199457
|
-
return null;
|
|
199458
|
-
}
|
|
199459
|
-
const id2 = getString(value, "id");
|
|
199460
|
-
const name = getString(value, "name");
|
|
199461
|
-
if (!id2 || !name) {
|
|
199462
|
-
return null;
|
|
199463
|
-
}
|
|
199464
|
-
const description = getString(value, "description");
|
|
199465
|
-
return { id: id2, name, description };
|
|
199466
|
-
}
|
|
199467
|
-
function parseAgentMcpToolRunResult(value) {
|
|
199468
|
-
if (!isRecord(value)) {
|
|
199469
|
-
throw new Error("MCP tool run returned an invalid response");
|
|
199470
|
-
}
|
|
199471
|
-
const status = getString(value, "status") ?? "unknown";
|
|
199472
|
-
return {
|
|
199473
|
-
status,
|
|
199474
|
-
funcReturn: value.func_return,
|
|
199475
|
-
stdout: value.stdout,
|
|
199476
|
-
stderr: value.stderr
|
|
199477
|
-
};
|
|
199478
|
-
}
|
|
199479
|
-
function withTimeout(promise, timeoutMs, label) {
|
|
199480
|
-
let timer;
|
|
199481
|
-
const timeout = new Promise((_4, reject2) => {
|
|
199482
|
-
timer = setTimeout(() => reject2(new Error(`${label} timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
199483
|
-
});
|
|
199484
|
-
return Promise.race([promise, timeout]).finally(() => {
|
|
199485
|
-
if (timer !== undefined)
|
|
199486
|
-
clearTimeout(timer);
|
|
199487
|
-
});
|
|
199488
|
-
}
|
|
199489
|
-
function listServerMcpServers(client, timeoutMs = 1e4) {
|
|
199490
|
-
return withTimeout(client.mcpServers.list(), timeoutMs, "Listing server-side MCP servers");
|
|
199491
|
-
}
|
|
199492
|
-
async function listAgentConnectedMcpServers(client, agentId, timeoutMs = 1e4) {
|
|
199493
|
-
const result2 = await withTimeout(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers`), timeoutMs, "Listing agent-connected MCP servers");
|
|
199494
|
-
if (!Array.isArray(result2)) {
|
|
199495
|
-
return [];
|
|
199496
|
-
}
|
|
199497
|
-
return result2.map(parseAgentConnectedMcpServer).filter((server2) => server2 !== null);
|
|
199498
|
-
}
|
|
199499
|
-
async function listAgentConnectedMcpTools(client, agentId, mcpServerId, timeoutMs = 1e4) {
|
|
199500
|
-
const result2 = await withTimeout(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers/${encodeURIComponent(mcpServerId)}/tools`), timeoutMs, "Listing agent-connected MCP server tools");
|
|
199501
|
-
if (!Array.isArray(result2)) {
|
|
199502
|
-
return [];
|
|
199503
|
-
}
|
|
199504
|
-
return result2.map(parseAgentConnectedMcpTool).filter((tool) => tool !== null);
|
|
199505
|
-
}
|
|
199506
|
-
async function runAgentConnectedMcpTool(params) {
|
|
199507
|
-
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");
|
|
199508
|
-
return parseAgentMcpToolRunResult(result2);
|
|
199509
|
-
}
|
|
199510
|
-
async function listLiveServerMcpTools(client, serverName, timeoutMs = 15000) {
|
|
199511
|
-
const result2 = await withTimeout(client.get(`/v1/tools/mcp/servers/${encodeURIComponent(serverName)}/tools`), timeoutMs, `Listing tools for MCP server "${serverName}"`);
|
|
199512
|
-
if (!Array.isArray(result2))
|
|
199513
|
-
return [];
|
|
199514
|
-
return result2.filter((tool) => typeof tool === "object" && tool !== null && typeof tool.name === "string");
|
|
199515
|
-
}
|
|
199516
|
-
async function loadServerMcpEntries(client, timeoutMs = 15000) {
|
|
199517
|
-
const servers = await listServerMcpServers(client, timeoutMs);
|
|
199518
|
-
return Promise.all(servers.map(async (server2) => {
|
|
199519
|
-
try {
|
|
199520
|
-
const tools = await listLiveServerMcpTools(client, server2.server_name, timeoutMs);
|
|
199521
|
-
return { server: server2, tools };
|
|
199522
|
-
} catch (cause) {
|
|
199523
|
-
return {
|
|
199524
|
-
server: server2,
|
|
199525
|
-
tools: [],
|
|
199526
|
-
toolsError: cause instanceof Error ? cause.message : String(cause)
|
|
199527
|
-
};
|
|
199528
|
-
}
|
|
199529
|
-
}));
|
|
199530
|
-
}
|
|
199531
|
-
function parseMcpMetadata(tool) {
|
|
199532
|
-
const metadata = tool.metadata_;
|
|
199533
|
-
const mcp = metadata?.mcp;
|
|
199534
|
-
if (typeof mcp !== "object" || mcp === null)
|
|
199535
|
-
return null;
|
|
199536
|
-
const { server_id, server_name } = mcp;
|
|
199537
|
-
return {
|
|
199538
|
-
...typeof server_id === "string" && { serverId: server_id },
|
|
199539
|
-
...typeof server_name === "string" && { serverName: server_name }
|
|
199540
|
-
};
|
|
199541
|
-
}
|
|
199542
|
-
async function listAgentMcpAttachments(client, agentId) {
|
|
199543
|
-
const attachments = [];
|
|
199544
|
-
for await (const tool of client.agents.tools.list(agentId, { limit: 100 })) {
|
|
199545
|
-
if (tool.tool_type !== "external_mcp" || !tool.id || !tool.name)
|
|
199546
|
-
continue;
|
|
199547
|
-
attachments.push({
|
|
199548
|
-
toolId: tool.id,
|
|
199549
|
-
toolName: tool.name,
|
|
199550
|
-
...parseMcpMetadata(tool)
|
|
199551
|
-
});
|
|
199552
|
-
}
|
|
199553
|
-
return attachments;
|
|
199554
|
-
}
|
|
199555
|
-
function attachmentsForEntry(entry, attachments) {
|
|
199556
|
-
return attachments.filter((attachment) => attachment.serverId && entry.server.id ? attachment.serverId === entry.server.id : attachment.serverName === entry.server.server_name);
|
|
199557
|
-
}
|
|
199558
|
-
function attachedToolNamesForEntry(entry, attachments) {
|
|
199559
|
-
return new Set(attachmentsForEntry(entry, attachments).map((attachment) => attachment.toolName));
|
|
199560
|
-
}
|
|
199561
|
-
async function registerServerMcpTool(client, serverName, toolName) {
|
|
199562
|
-
const result2 = await client.post(`/v1/tools/mcp/servers/${encodeURIComponent(serverName)}/${encodeURIComponent(toolName)}`);
|
|
199563
|
-
if (typeof result2?.id !== "string") {
|
|
199564
|
-
throw new Error(`Registering MCP tool "${toolName}" on server "${serverName}" returned no tool id`);
|
|
199565
|
-
}
|
|
199566
|
-
return { id: result2.id };
|
|
199567
|
-
}
|
|
199568
|
-
async function attachServerMcpTools(client, agentId, serverName, toolNames) {
|
|
199569
|
-
await Promise.all(toolNames.map(async (toolName) => {
|
|
199570
|
-
const { id: id2 } = await registerServerMcpTool(client, serverName, toolName);
|
|
199571
|
-
await client.agents.tools.attach(id2, { agent_id: agentId });
|
|
199572
|
-
}));
|
|
199573
|
-
}
|
|
199574
|
-
async function detachServerMcpTools(client, agentId, toolIds) {
|
|
199575
|
-
await Promise.all(toolIds.map((toolId) => client.agents.tools.detach(toolId, { agent_id: agentId })));
|
|
199576
|
-
}
|
|
199577
|
-
function refreshServerMcpServer(client, mcpServerId, agentId) {
|
|
199578
|
-
return client.mcpServers.refresh(mcpServerId, { agent_id: agentId });
|
|
199579
|
-
}
|
|
199580
|
-
function planServerMcpToggle(entry, attachments) {
|
|
199581
|
-
const attached = attachmentsForEntry(entry, attachments);
|
|
199582
|
-
if (attached.length > 0) {
|
|
199583
|
-
return {
|
|
199584
|
-
action: "detach",
|
|
199585
|
-
toolIds: attached.map((attachment) => attachment.toolId)
|
|
199586
|
-
};
|
|
199587
|
-
}
|
|
199588
|
-
return { action: "attach", toolNames: entry.tools.map((tool) => tool.name) };
|
|
199589
|
-
}
|
|
199590
|
-
function describeServerMcpTarget(server2) {
|
|
199591
|
-
if ("server_url" in server2 && server2.server_url) {
|
|
199592
|
-
return server2.server_url;
|
|
199593
|
-
}
|
|
199594
|
-
if ("command" in server2 && server2.command) {
|
|
199595
|
-
return [server2.command, ...server2.args ?? []].join(" ");
|
|
199596
|
-
}
|
|
199597
|
-
return "";
|
|
199598
|
-
}
|
|
199599
|
-
var init_mcp_servers2 = () => {};
|
|
199600
|
-
|
|
199601
|
-
// src/cli/subcommands/cloud-mcp.ts
|
|
199602
|
-
import { parseArgs as parseArgs4 } from "node:util";
|
|
199603
|
-
function printUsage4(stdout = console.log) {
|
|
199604
|
-
stdout(`
|
|
199605
|
-
Usage:
|
|
199606
|
-
letta cloud-mcp list [--agent <id>]
|
|
199607
|
-
letta cloud-mcp tools <mcp-server-id> [--agent <id>]
|
|
199608
|
-
letta cloud-mcp run <mcp-server-id> <tool-id> [--args '<json>'] [--agent <id>]
|
|
199609
|
-
|
|
199610
|
-
Actions:
|
|
199611
|
-
list List MCP servers connected to the agent
|
|
199612
|
-
tools List registered tools for one connected MCP server
|
|
199613
|
-
run Run one registered MCP tool through the agent-scoped server route
|
|
199614
|
-
|
|
199615
|
-
Aliases:
|
|
199616
|
-
list-servers, list_servers Alias for list
|
|
199617
|
-
list-tools, list_tools Alias for tools
|
|
199618
|
-
call, run-tool, run_tool Alias for run
|
|
199619
|
-
|
|
199620
|
-
Options:
|
|
199621
|
-
--agent <id> Agent ID. Defaults to LETTA_AGENT_ID or AGENT_ID
|
|
199622
|
-
--agent-id <id> Alias for --agent
|
|
199623
|
-
--args '<json>' JSON object passed as MCP tool arguments for run
|
|
199624
|
-
-h, --help Show this help
|
|
199625
|
-
|
|
199626
|
-
Notes:
|
|
199627
|
-
- Output is JSON only.
|
|
199628
|
-
- Requires a signed-in Letta Cloud agent with server-side MCP support.
|
|
199629
|
-
- Uses CLI auth; override with LETTA_API_KEY/LETTA_BASE_URL if needed.
|
|
199630
|
-
`.trim());
|
|
199631
|
-
}
|
|
199632
|
-
function parseCloudMcpArgs(argv) {
|
|
199633
|
-
return parseArgs4({
|
|
199634
|
-
args: argv,
|
|
199635
|
-
options: {
|
|
199636
|
-
help: { type: "boolean", short: "h" },
|
|
199637
|
-
agent: { type: "string" },
|
|
199638
|
-
"agent-id": { type: "string" },
|
|
199639
|
-
args: { type: "string" }
|
|
199640
|
-
},
|
|
199641
|
-
strict: true,
|
|
199642
|
-
allowPositionals: true
|
|
199643
|
-
});
|
|
199644
|
-
}
|
|
199645
|
-
function stringValue3(value) {
|
|
199646
|
-
return typeof value === "string" ? value : undefined;
|
|
199647
|
-
}
|
|
199648
|
-
function resolveCloudMcpAgentId(agent, agentId, env4 = process.env) {
|
|
199649
|
-
return (agent || agentId || env4.LETTA_AGENT_ID || env4.AGENT_ID || "").trim();
|
|
199650
|
-
}
|
|
199651
|
-
function parseToolArgs(value) {
|
|
199652
|
-
const raw2 = stringValue3(value);
|
|
199653
|
-
if (!raw2) {
|
|
199654
|
-
return {};
|
|
199655
|
-
}
|
|
199656
|
-
let parsed;
|
|
199657
|
-
try {
|
|
199658
|
-
parsed = JSON.parse(raw2);
|
|
199659
|
-
} catch (error4) {
|
|
199660
|
-
const message = error4 instanceof Error ? error4.message : String(error4);
|
|
199661
|
-
throw new Error(`Invalid --args JSON: ${message}`);
|
|
199662
|
-
}
|
|
199663
|
-
if (!isRecord(parsed)) {
|
|
199664
|
-
throw new Error("Invalid --args JSON: expected a JSON object");
|
|
199665
|
-
}
|
|
199666
|
-
return parsed;
|
|
199667
|
-
}
|
|
199668
|
-
function printJson(stdout, result2) {
|
|
199669
|
-
stdout(JSON.stringify(result2, null, 2));
|
|
199670
|
-
}
|
|
199671
|
-
async function defaultGetClient() {
|
|
199672
|
-
const client = await getClient();
|
|
199673
|
-
return client;
|
|
199674
|
-
}
|
|
199675
|
-
async function runCloudMcpSubcommand(argv, deps = {}) {
|
|
199676
|
-
const stdout = deps.stdout ?? console.log;
|
|
199677
|
-
const stderr = deps.stderr ?? console.error;
|
|
199678
|
-
let parsed;
|
|
199679
|
-
try {
|
|
199680
|
-
parsed = parseCloudMcpArgs(argv);
|
|
199681
|
-
} catch (error4) {
|
|
199682
|
-
const message = error4 instanceof Error ? error4.message : String(error4);
|
|
199683
|
-
stderr(`Error: ${message}`);
|
|
199684
|
-
printUsage4(stdout);
|
|
199685
|
-
return 1;
|
|
199686
|
-
}
|
|
199687
|
-
const [action3, mcpServerId, toolId] = parsed.positionals;
|
|
199688
|
-
if (parsed.values.help || !action3 || action3 === "help") {
|
|
199689
|
-
printUsage4(stdout);
|
|
199690
|
-
return 0;
|
|
199691
|
-
}
|
|
199692
|
-
const isAvailable = deps.isServerSideMcpAvailable ?? (() => getBackend().capabilities.serverSideToolManagement);
|
|
199693
|
-
if (!isAvailable()) {
|
|
199694
|
-
stderr("Server-side MCP requires a signed-in Letta Cloud agent; the local backend does not support it.");
|
|
199695
|
-
return 1;
|
|
199696
|
-
}
|
|
199697
|
-
const agentId = resolveCloudMcpAgentId(stringValue3(parsed.values.agent), stringValue3(parsed.values["agent-id"]));
|
|
199698
|
-
if (!agentId) {
|
|
199699
|
-
stderr("Agent id required: pass --agent <id> or set LETTA_AGENT_ID/AGENT_ID.");
|
|
199700
|
-
return 1;
|
|
199701
|
-
}
|
|
199702
|
-
await (deps.initializeSettings ?? (() => settingsManager.initialize()))();
|
|
199703
|
-
const client = await (deps.getClient ?? defaultGetClient)();
|
|
199704
|
-
try {
|
|
199705
|
-
if (action3 === "list" || action3 === "list-servers" || action3 === "list_servers") {
|
|
199706
|
-
printJson(stdout, {
|
|
199707
|
-
agent_id: agentId,
|
|
199708
|
-
servers: await listAgentConnectedMcpServers(client, agentId)
|
|
199709
|
-
});
|
|
199710
|
-
return 0;
|
|
199711
|
-
}
|
|
199712
|
-
if (action3 === "tools" || action3 === "list-tools" || action3 === "list_tools") {
|
|
199713
|
-
if (!mcpServerId) {
|
|
199714
|
-
stderr("Usage: letta cloud-mcp tools <mcp-server-id> [--agent <id>]");
|
|
199715
|
-
return 1;
|
|
199716
|
-
}
|
|
199717
|
-
printJson(stdout, {
|
|
199718
|
-
agent_id: agentId,
|
|
199719
|
-
mcp_server_id: mcpServerId,
|
|
199720
|
-
tools: await listAgentConnectedMcpTools(client, agentId, mcpServerId)
|
|
199721
|
-
});
|
|
199722
|
-
return 0;
|
|
199723
|
-
}
|
|
199724
|
-
if (action3 === "run" || action3 === "call" || action3 === "run-tool" || action3 === "run_tool") {
|
|
199725
|
-
if (!mcpServerId || !toolId) {
|
|
199726
|
-
stderr("Usage: letta cloud-mcp run <mcp-server-id> <tool-id> [--args '<json>'] [--agent <id>]");
|
|
199727
|
-
return 1;
|
|
199728
|
-
}
|
|
199729
|
-
printJson(stdout, {
|
|
199730
|
-
agent_id: agentId,
|
|
199731
|
-
mcp_server_id: mcpServerId,
|
|
199732
|
-
tool_id: toolId,
|
|
199733
|
-
result: await runAgentConnectedMcpTool({
|
|
199734
|
-
client,
|
|
199735
|
-
agentId,
|
|
199736
|
-
mcpServerId,
|
|
199737
|
-
toolId,
|
|
199738
|
-
args: parseToolArgs(parsed.values.args)
|
|
199739
|
-
})
|
|
199740
|
-
});
|
|
199741
|
-
return 0;
|
|
199742
|
-
}
|
|
199743
|
-
stderr(`Unknown cloud-mcp action: ${action3}`);
|
|
199744
|
-
printUsage4(stdout);
|
|
199745
|
-
return 1;
|
|
199746
|
-
} catch (error4) {
|
|
199747
|
-
stderr(error4 instanceof Error ? error4.message : String(error4));
|
|
199748
|
-
return 1;
|
|
199749
|
-
}
|
|
199750
|
-
}
|
|
199751
|
-
var init_cloud_mcp = __esm(() => {
|
|
199752
|
-
init_backend2();
|
|
199753
|
-
init_client2();
|
|
199754
|
-
init_mcp_servers2();
|
|
199755
|
-
init_settings_manager();
|
|
199756
|
-
});
|
|
199757
|
-
|
|
199758
199450
|
// src/auth/openai-oauth.ts
|
|
199759
199451
|
import http3 from "node:http";
|
|
199760
199452
|
function renderOAuthPage(options) {
|
|
@@ -200878,7 +200570,7 @@ var init_connect_normalize = __esm(() => {
|
|
|
200878
200570
|
// src/cli/subcommands/connect.ts
|
|
200879
200571
|
import { createInterface as createInterface6 } from "node:readline/promises";
|
|
200880
200572
|
import { Writable } from "node:stream";
|
|
200881
|
-
import { parseArgs as
|
|
200573
|
+
import { parseArgs as parseArgs4 } from "node:util";
|
|
200882
200574
|
function readStringOption(value) {
|
|
200883
200575
|
if (typeof value === "string") {
|
|
200884
200576
|
return value;
|
|
@@ -200970,7 +200662,7 @@ async function runConnectSubcommand(argv, deps = {}) {
|
|
|
200970
200662
|
const io = { ...DEFAULT_DEPS2, ...deps };
|
|
200971
200663
|
let parsed;
|
|
200972
200664
|
try {
|
|
200973
|
-
parsed =
|
|
200665
|
+
parsed = parseArgs4({
|
|
200974
200666
|
args: argv,
|
|
200975
200667
|
options: CONNECT_OPTIONS,
|
|
200976
200668
|
strict: true,
|
|
@@ -209911,10 +209603,10 @@ async function resolveDesktopEnvironmentConnectionId(list = listEnvironments) {
|
|
|
209911
209603
|
const response = await list({ limit: 100, onlineOnly: true });
|
|
209912
209604
|
const matches3 = response.connections.filter((environment3) => environment3.listenerInstanceId?.startsWith("desktop-direct-cloud:") === true && isEnvironmentOnline(environment3));
|
|
209913
209605
|
if (matches3.length === 0) {
|
|
209914
|
-
throw new Error("Desktop Local is unavailable. Open Letta Desktop, enable Remote Access, and wait for its
|
|
209606
|
+
throw new Error("Desktop Local is unavailable. Open Letta Desktop, enable Remote Access, and wait for its computer connection to come online.");
|
|
209915
209607
|
}
|
|
209916
209608
|
if (matches3.length > 1) {
|
|
209917
|
-
throw new Error(`Multiple Desktop
|
|
209609
|
+
throw new Error(`Multiple Desktop computers are online. Run \`letta teleport list\` and choose one by name, device ID, or connection ID. Matched: ${matches3.map(describeEnvironment).join(", ")}`);
|
|
209918
209610
|
}
|
|
209919
209611
|
const environment2 = matches3[0];
|
|
209920
209612
|
if (!environment2?.connectionId) {
|
|
@@ -209925,28 +209617,28 @@ async function resolveDesktopEnvironmentConnectionId(list = listEnvironments) {
|
|
|
209925
209617
|
async function resolveEnvironmentConnectionId(selector) {
|
|
209926
209618
|
const trimmed = selector.trim();
|
|
209927
209619
|
if (!trimmed) {
|
|
209928
|
-
throw new Error("
|
|
209620
|
+
throw new Error("Computer selector must not be empty");
|
|
209929
209621
|
}
|
|
209930
209622
|
const response = await listEnvironments({ limit: 100 });
|
|
209931
209623
|
const matches3 = response.connections.filter((environment3) => {
|
|
209932
209624
|
return environment3.connectionId === trimmed || environment3.id === trimmed || environment3.deviceId === trimmed || environment3.connectionName === trimmed;
|
|
209933
209625
|
});
|
|
209934
209626
|
if (matches3.length === 0) {
|
|
209935
|
-
throw new Error(`
|
|
209627
|
+
throw new Error(`Computer "${trimmed}" not found. Run \`letta computers list\` to discover available computers.`);
|
|
209936
209628
|
}
|
|
209937
209629
|
const onlineMatches = matches3.filter(isEnvironmentOnline);
|
|
209938
209630
|
if (onlineMatches.length === 0) {
|
|
209939
|
-
throw new Error(`
|
|
209631
|
+
throw new Error(`Computer "${trimmed}" is offline. Matched: ${matches3.map(describeEnvironment).join(", ")}`);
|
|
209940
209632
|
}
|
|
209941
209633
|
if (onlineMatches.length > 1) {
|
|
209942
|
-
throw new Error(`
|
|
209634
|
+
throw new Error(`Computer "${trimmed}" is ambiguous. Matched: ${onlineMatches.map(describeEnvironment).join(", ")}`);
|
|
209943
209635
|
}
|
|
209944
209636
|
const environment2 = onlineMatches[0];
|
|
209945
209637
|
if (!environment2) {
|
|
209946
|
-
throw new Error(`
|
|
209638
|
+
throw new Error(`Computer "${trimmed}" is offline`);
|
|
209947
209639
|
}
|
|
209948
209640
|
if (!environment2.connectionId) {
|
|
209949
|
-
throw new Error(`
|
|
209641
|
+
throw new Error(`Computer "${trimmed}" has no active connection id`);
|
|
209950
209642
|
}
|
|
209951
209643
|
return { connectionId: environment2.connectionId, environment: environment2 };
|
|
209952
209644
|
}
|
|
@@ -210180,8 +209872,8 @@ var init_cron_task_ref = __esm(async () => {
|
|
|
210180
209872
|
});
|
|
210181
209873
|
|
|
210182
209874
|
// src/cli/subcommands/cron.ts
|
|
210183
|
-
import { parseArgs as
|
|
210184
|
-
function
|
|
209875
|
+
import { parseArgs as parseArgs5 } from "node:util";
|
|
209876
|
+
function printUsage4() {
|
|
210185
209877
|
console.log(`
|
|
210186
209878
|
Usage:
|
|
210187
209879
|
letta cron add --prompt <text> --every <interval> [options]
|
|
@@ -210217,8 +209909,8 @@ Add options:
|
|
|
210217
209909
|
the fallback when Cloud scheduling cannot
|
|
210218
209910
|
reach this computer)
|
|
210219
209911
|
--computer <id> (cloud runner only) Override execution with a
|
|
210220
|
-
connected external
|
|
210221
|
-
\`letta
|
|
209912
|
+
connected external computer (deviceId from
|
|
209913
|
+
\`letta computers list\`). Falls back to the Cloud
|
|
210222
209914
|
sandbox if the computer is offline at fire time.
|
|
210223
209915
|
Managed sandboxes and Desktop-local connections are
|
|
210224
209916
|
not currently valid Cloud schedule targets.
|
|
@@ -210235,7 +209927,7 @@ Output is JSON.
|
|
|
210235
209927
|
`.trim());
|
|
210236
209928
|
}
|
|
210237
209929
|
function parseCronArgs(argv) {
|
|
210238
|
-
return
|
|
209930
|
+
return parseArgs5({
|
|
210239
209931
|
args: argv,
|
|
210240
209932
|
options: CRON_OPTIONS,
|
|
210241
209933
|
strict: true,
|
|
@@ -210405,7 +210097,7 @@ async function handleAdd(values3) {
|
|
|
210405
210097
|
targetDeviceId = inferredDeviceId;
|
|
210406
210098
|
} else if (resolution.kind === "local-fallback") {
|
|
210407
210099
|
runner = "local";
|
|
210408
|
-
localFallbackNote = `This schedule is local to this computer (${resolution.reason}): it only fires while a Letta session is running here. For a schedule that fires regardless, pass --runner cloud (runs in the agent's cloud sandbox) or --computer <deviceId> (runs on a connected computer, from \`letta
|
|
210100
|
+
localFallbackNote = `This schedule is local to this computer (${resolution.reason}): it only fires while a Letta session is running here. For a schedule that fires regardless, pass --runner cloud (runs in the agent's cloud sandbox) or --computer <deviceId> (runs on a connected computer, from \`letta computers list\`).`;
|
|
210409
210101
|
}
|
|
210410
210102
|
}
|
|
210411
210103
|
if (runner === "cloud") {
|
|
@@ -210791,12 +210483,12 @@ async function runCronSubcommand(argv) {
|
|
|
210791
210483
|
parsed = parseCronArgs(argv);
|
|
210792
210484
|
} catch (err) {
|
|
210793
210485
|
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
210794
|
-
|
|
210486
|
+
printUsage4();
|
|
210795
210487
|
return 1;
|
|
210796
210488
|
}
|
|
210797
210489
|
const [action3] = parsed.positionals;
|
|
210798
210490
|
if (parsed.values.help || !action3 || action3 === "help") {
|
|
210799
|
-
|
|
210491
|
+
printUsage4();
|
|
210800
210492
|
return 0;
|
|
210801
210493
|
}
|
|
210802
210494
|
switch (action3) {
|
|
@@ -210813,7 +210505,7 @@ async function runCronSubcommand(argv) {
|
|
|
210813
210505
|
return handleDelete(parsed.values, parsed.positionals);
|
|
210814
210506
|
default:
|
|
210815
210507
|
console.error(`Unknown action: ${action3}`);
|
|
210816
|
-
|
|
210508
|
+
printUsage4();
|
|
210817
210509
|
return 1;
|
|
210818
210510
|
}
|
|
210819
210511
|
}
|
|
@@ -210849,29 +210541,31 @@ var init_cron2 = __esm(async () => {
|
|
|
210849
210541
|
});
|
|
210850
210542
|
|
|
210851
210543
|
// src/cli/subcommands/environments.ts
|
|
210852
|
-
import { parseArgs as
|
|
210853
|
-
function
|
|
210544
|
+
import { parseArgs as parseArgs6 } from "node:util";
|
|
210545
|
+
function printUsage5() {
|
|
210854
210546
|
console.log(`
|
|
210855
210547
|
Usage:
|
|
210856
|
-
letta
|
|
210857
|
-
letta
|
|
210548
|
+
letta computers list [options]
|
|
210549
|
+
letta computers current
|
|
210858
210550
|
|
|
210859
|
-
|
|
210551
|
+
Legacy aliases:
|
|
210552
|
+
letta environments list
|
|
210553
|
+
letta environments current
|
|
210860
210554
|
letta envs list
|
|
210861
210555
|
letta envs current
|
|
210862
210556
|
|
|
210863
210557
|
List options:
|
|
210864
210558
|
--limit <n> Max results (default: 50)
|
|
210865
|
-
--after <id> Pagination cursor from a previous
|
|
210866
|
-
--online-only Only include
|
|
210559
|
+
--after <id> Pagination cursor from a previous computer id
|
|
210560
|
+
--online-only Only include computers with a fresh active connection
|
|
210867
210561
|
|
|
210868
210562
|
Notes:
|
|
210869
210563
|
- Output is JSON only.
|
|
210870
210564
|
- Uses CLI auth; override with LETTA_API_KEY/LETTA_BASE_URL if needed.
|
|
210871
|
-
- Use letta
|
|
210872
|
-
- Use --
|
|
210873
|
-
- Use --
|
|
210874
|
-
to route a message through a specific registered
|
|
210565
|
+
- Use letta computers current to get this computer's connectionId.
|
|
210566
|
+
- Use --computer cloud to route through the target agent's cloud sandbox.
|
|
210567
|
+
- Use --computer <name|device-id|connection-id> with headless messaging
|
|
210568
|
+
to route a message through a specific registered computer.
|
|
210875
210569
|
`.trim());
|
|
210876
210570
|
}
|
|
210877
210571
|
function parseLimit2(value, fallback) {
|
|
@@ -210918,7 +210612,7 @@ function scoreCurrentEnvironment(environment2, options) {
|
|
|
210918
210612
|
return score;
|
|
210919
210613
|
}
|
|
210920
210614
|
function parseEnvironmentsArgs(argv) {
|
|
210921
|
-
return
|
|
210615
|
+
return parseArgs6({
|
|
210922
210616
|
args: argv,
|
|
210923
210617
|
options: ENVIRONMENTS_OPTIONS,
|
|
210924
210618
|
strict: true,
|
|
@@ -210932,17 +210626,17 @@ async function runEnvironmentsSubcommand(argv, deps = {}) {
|
|
|
210932
210626
|
} catch (error4) {
|
|
210933
210627
|
const message = error4 instanceof Error ? error4.message : String(error4);
|
|
210934
210628
|
console.error(`Error: ${message}`);
|
|
210935
|
-
|
|
210629
|
+
printUsage5();
|
|
210936
210630
|
return 1;
|
|
210937
210631
|
}
|
|
210938
210632
|
const [action3] = parsed.positionals;
|
|
210939
210633
|
if (parsed.values.help || !action3 || action3 === "help") {
|
|
210940
|
-
|
|
210634
|
+
printUsage5();
|
|
210941
210635
|
return 0;
|
|
210942
210636
|
}
|
|
210943
210637
|
if (action3 !== "list" && action3 !== "current") {
|
|
210944
210638
|
console.error(`Unknown action: ${action3}`);
|
|
210945
|
-
|
|
210639
|
+
printUsage5();
|
|
210946
210640
|
return 1;
|
|
210947
210641
|
}
|
|
210948
210642
|
await (deps.initializeSettings ?? (() => settingsManager.initialize()))();
|
|
@@ -210958,7 +210652,7 @@ async function runEnvironmentsSubcommand(argv, deps = {}) {
|
|
|
210958
210652
|
currentVersion
|
|
210959
210653
|
});
|
|
210960
210654
|
if (!current2) {
|
|
210961
|
-
console.error("No online
|
|
210655
|
+
console.error("No online computer found for this device. Start one with `letta server` and try again.");
|
|
210962
210656
|
return 1;
|
|
210963
210657
|
}
|
|
210964
210658
|
console.log(JSON.stringify(formatEnvironmentForCli(current2, {
|
|
@@ -211004,8 +210698,8 @@ var init_environments3 = __esm(() => {
|
|
|
211004
210698
|
});
|
|
211005
210699
|
|
|
211006
210700
|
// src/cli/subcommands/feedback.ts
|
|
211007
|
-
import { parseArgs as
|
|
211008
|
-
function
|
|
210701
|
+
import { parseArgs as parseArgs7 } from "node:util";
|
|
210702
|
+
function printUsage6(stdout = console.log) {
|
|
211009
210703
|
stdout(`
|
|
211010
210704
|
Usage:
|
|
211011
210705
|
letta feedback --message <text>
|
|
@@ -211023,7 +210717,7 @@ async function runFeedbackSubcommand(argv, deps = {}) {
|
|
|
211023
210717
|
const stderr = deps.stderr ?? console.error;
|
|
211024
210718
|
let parsed;
|
|
211025
210719
|
try {
|
|
211026
|
-
parsed =
|
|
210720
|
+
parsed = parseArgs7({
|
|
211027
210721
|
args: argv,
|
|
211028
210722
|
options: {
|
|
211029
210723
|
help: { type: "boolean", short: "h" },
|
|
@@ -211034,11 +210728,11 @@ async function runFeedbackSubcommand(argv, deps = {}) {
|
|
|
211034
210728
|
});
|
|
211035
210729
|
} catch (error4) {
|
|
211036
210730
|
stderr(error4 instanceof Error ? error4.message : String(error4));
|
|
211037
|
-
|
|
210731
|
+
printUsage6(stdout);
|
|
211038
210732
|
return 1;
|
|
211039
210733
|
}
|
|
211040
210734
|
if (parsed.values.help) {
|
|
211041
|
-
|
|
210735
|
+
printUsage6(stdout);
|
|
211042
210736
|
return 0;
|
|
211043
210737
|
}
|
|
211044
210738
|
const message = typeof parsed.values.message === "string" ? parsed.values.message.trim() : "";
|
|
@@ -211061,6 +210755,8 @@ async function runFeedbackSubcommand(argv, deps = {}) {
|
|
|
211061
210755
|
await (deps.submitFeedback ?? submitFeedbackMetadata)(apiKey, (deps.getDeviceId ?? (() => settingsManager.getOrCreateDeviceId()))(), {
|
|
211062
210756
|
message,
|
|
211063
210757
|
feature: "letta-code-agent-feedback",
|
|
210758
|
+
submission_source: "agent_skill",
|
|
210759
|
+
client_type: (deps.getClientType ?? getFeedbackClientType)(),
|
|
211064
210760
|
version: getVersion(),
|
|
211065
210761
|
platform: process.platform,
|
|
211066
210762
|
agent_id: agentId || undefined,
|
|
@@ -212778,7 +212474,7 @@ function ListenerStatusUI(props) {
|
|
|
212778
212474
|
bold: true,
|
|
212779
212475
|
color: "green",
|
|
212780
212476
|
children: [
|
|
212781
|
-
"The name of your
|
|
212477
|
+
"The name of your computer is: ",
|
|
212782
212478
|
envName
|
|
212783
212479
|
]
|
|
212784
212480
|
}, undefined, true, undefined, this)
|
|
@@ -212811,7 +212507,7 @@ function ListenerStatusUI(props) {
|
|
|
212811
212507
|
children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
212812
212508
|
dimColor: true,
|
|
212813
212509
|
children: [
|
|
212814
|
-
'Connect to this
|
|
212510
|
+
'Connect to this computer by visiting any agent and clicking the "cloud" button at the bottom left of the messenger input and swapping your computer to ',
|
|
212815
212511
|
envName
|
|
212816
212512
|
]
|
|
212817
212513
|
}, undefined, true, undefined, this)
|
|
@@ -238784,9 +238480,9 @@ ${lanes.join(`
|
|
|
238784
238480
|
function isJsonEqual(a2, b3) {
|
|
238785
238481
|
return a2 === b3 || typeof a2 === "object" && a2 !== null && typeof b3 === "object" && b3 !== null && equalOwnProperties(a2, b3, isJsonEqual);
|
|
238786
238482
|
}
|
|
238787
|
-
function parsePseudoBigInt(
|
|
238483
|
+
function parsePseudoBigInt(stringValue3) {
|
|
238788
238484
|
let log2Base;
|
|
238789
|
-
switch (
|
|
238485
|
+
switch (stringValue3.charCodeAt(1)) {
|
|
238790
238486
|
case 98:
|
|
238791
238487
|
case 66:
|
|
238792
238488
|
log2Base = 1;
|
|
@@ -238800,19 +238496,19 @@ ${lanes.join(`
|
|
|
238800
238496
|
log2Base = 4;
|
|
238801
238497
|
break;
|
|
238802
238498
|
default:
|
|
238803
|
-
const nIndex =
|
|
238499
|
+
const nIndex = stringValue3.length - 1;
|
|
238804
238500
|
let nonZeroStart = 0;
|
|
238805
|
-
while (
|
|
238501
|
+
while (stringValue3.charCodeAt(nonZeroStart) === 48) {
|
|
238806
238502
|
nonZeroStart++;
|
|
238807
238503
|
}
|
|
238808
|
-
return
|
|
238504
|
+
return stringValue3.slice(nonZeroStart, nIndex) || "0";
|
|
238809
238505
|
}
|
|
238810
|
-
const startIndex = 2, endIndex =
|
|
238506
|
+
const startIndex = 2, endIndex = stringValue3.length - 1;
|
|
238811
238507
|
const bitsNeeded = (endIndex - startIndex) * log2Base;
|
|
238812
238508
|
const segments = new Uint16Array((bitsNeeded >>> 4) + (bitsNeeded & 15 ? 1 : 0));
|
|
238813
238509
|
for (let i4 = endIndex - 1, bitOffset = 0;i4 >= startIndex; i4--, bitOffset += log2Base) {
|
|
238814
238510
|
const segment = bitOffset >>> 4;
|
|
238815
|
-
const digitChar =
|
|
238511
|
+
const digitChar = stringValue3.charCodeAt(i4);
|
|
238816
238512
|
const digit = digitChar <= 57 ? digitChar - 48 : 10 + digitChar - (digitChar <= 70 ? 65 : 97);
|
|
238817
238513
|
const shiftedDigit = digit << (bitOffset & 15);
|
|
238818
238514
|
segments[segment] |= shiftedDigit;
|
|
@@ -391876,7 +391572,7 @@ function toRunsArray(listResponse) {
|
|
|
391876
391572
|
}
|
|
391877
391573
|
return [];
|
|
391878
391574
|
}
|
|
391879
|
-
function
|
|
391575
|
+
function withTimeout(promise, timeoutMs, timeoutMessage) {
|
|
391880
391576
|
return new Promise((resolve34, reject2) => {
|
|
391881
391577
|
const timer = setTimeout(() => reject2(new Error(timeoutMessage)), timeoutMs);
|
|
391882
391578
|
promise.then((value) => {
|
|
@@ -391890,7 +391586,7 @@ function withTimeout2(promise, timeoutMs, timeoutMessage) {
|
|
|
391890
391586
|
}
|
|
391891
391587
|
async function discoverFallbackRunIdWithTimeout(ctx) {
|
|
391892
391588
|
const client = await getClient();
|
|
391893
|
-
return
|
|
391589
|
+
return withTimeout(discoverFallbackRunIdForResume(client, ctx), FALLBACK_RUN_DISCOVERY_TIMEOUT_MS, `Fallback run discovery timed out after ${FALLBACK_RUN_DISCOVERY_TIMEOUT_MS}ms`);
|
|
391894
391590
|
}
|
|
391895
391591
|
async function discoverFallbackRunIdForResume(client, ctx) {
|
|
391896
391592
|
const statuses = ["running"];
|
|
@@ -392627,7 +392323,7 @@ function formatMissingRequiredArgsReason(toolName, parsedArgs, missingRequiredAr
|
|
|
392627
392323
|
}
|
|
392628
392324
|
return base2;
|
|
392629
392325
|
}
|
|
392630
|
-
function
|
|
392326
|
+
function parseToolArgs(rawArgs) {
|
|
392631
392327
|
const raw2 = rawArgs ?? "";
|
|
392632
392328
|
const trimmed = raw2.trim();
|
|
392633
392329
|
if (!trimmed) {
|
|
@@ -392672,7 +392368,7 @@ async function classifyApprovals(approvals, opts = {}) {
|
|
|
392672
392368
|
});
|
|
392673
392369
|
continue;
|
|
392674
392370
|
}
|
|
392675
|
-
const argsParse =
|
|
392371
|
+
const argsParse = parseToolArgs(approval.toolArgs);
|
|
392676
392372
|
const parsedArgs = argsParse.parsedArgs;
|
|
392677
392373
|
if (argsParse.parseFailed) {
|
|
392678
392374
|
debugWarn("approval-classification", `Tool call ${approval.toolCallId} (${toolName}) had unparseable arguments ` + `(${argsParse.rawLength} chars); treating as empty`);
|
|
@@ -393592,8 +393288,15 @@ function isChatGPTByokHandleInModels(handle2, models3) {
|
|
|
393592
393288
|
const entry = models3.find((m4) => m4.handle === handle2);
|
|
393593
393289
|
return entry?.providerType === "chatgpt_oauth" && entry?.providerCategory === "byok";
|
|
393594
393290
|
}
|
|
393595
|
-
async function
|
|
393291
|
+
async function resolveScopedModelHandle(agentId, conversationId) {
|
|
393596
393292
|
try {
|
|
393293
|
+
if (conversationId !== "default") {
|
|
393294
|
+
const conversation = await getBackend().retrieveConversation(conversationId);
|
|
393295
|
+
const conversationRecord = conversation;
|
|
393296
|
+
if (typeof conversationRecord.model === "string" && conversationRecord.model.length > 0) {
|
|
393297
|
+
return conversationRecord.model;
|
|
393298
|
+
}
|
|
393299
|
+
}
|
|
393597
393300
|
const agent = await getBackend().retrieveAgent(agentId);
|
|
393598
393301
|
const record3 = agent;
|
|
393599
393302
|
if (typeof record3.model === "string" && record3.model.length > 0) {
|
|
@@ -393605,7 +393308,7 @@ async function resolveAgentModelHandle2(agentId) {
|
|
|
393605
393308
|
}
|
|
393606
393309
|
}
|
|
393607
393310
|
async function rotateChatGPTPlanOnQuotaLimit(params) {
|
|
393608
|
-
const { agentId, error: error4 } = params;
|
|
393311
|
+
const { agentId, conversationId, error: error4, exhaustedProviders } = params;
|
|
393609
393312
|
const parsedDetail = parseChatGPTUsageLimitDetail(error4);
|
|
393610
393313
|
if (!parsedDetail)
|
|
393611
393314
|
return null;
|
|
@@ -393620,9 +393323,9 @@ async function rotateChatGPTPlanOnQuotaLimit(params) {
|
|
|
393620
393323
|
}
|
|
393621
393324
|
if (!models3)
|
|
393622
393325
|
return null;
|
|
393623
|
-
let currentHandle =
|
|
393326
|
+
let currentHandle = await resolveScopedModelHandle(agentId, conversationId);
|
|
393624
393327
|
if (!currentHandle || !isChatGPTByokHandleInModels(currentHandle, models3)) {
|
|
393625
|
-
currentHandle =
|
|
393328
|
+
currentHandle = params.currentHandle;
|
|
393626
393329
|
}
|
|
393627
393330
|
if (!currentHandle || !isChatGPTByokHandleInModels(currentHandle, models3)) {
|
|
393628
393331
|
return null;
|
|
@@ -393642,9 +393345,15 @@ async function rotateChatGPTPlanOnQuotaLimit(params) {
|
|
|
393642
393345
|
if (!toProvider)
|
|
393643
393346
|
return null;
|
|
393644
393347
|
try {
|
|
393645
|
-
|
|
393646
|
-
|
|
393647
|
-
|
|
393348
|
+
if (conversationId === "default") {
|
|
393349
|
+
await updateAgentLLMConfig(agentId, toHandle, {
|
|
393350
|
+
provider_type: "chatgpt_oauth"
|
|
393351
|
+
});
|
|
393352
|
+
} else {
|
|
393353
|
+
await updateConversationLLMConfig(conversationId, toHandle, {
|
|
393354
|
+
provider_type: "chatgpt_oauth"
|
|
393355
|
+
});
|
|
393356
|
+
}
|
|
393648
393357
|
} catch {
|
|
393649
393358
|
return null;
|
|
393650
393359
|
}
|
|
@@ -393663,14 +393372,13 @@ function formatPlanRotationNotice(params) {
|
|
|
393663
393372
|
})})` : "";
|
|
393664
393373
|
return `${fromProvider} hit its usage limit${resetSuffix} — switched to ${toProvider}`;
|
|
393665
393374
|
}
|
|
393666
|
-
var CHATGPT_PLAN_ROTATION_MAX_SWAPS_PER_TURN = 3
|
|
393375
|
+
var CHATGPT_PLAN_ROTATION_MAX_SWAPS_PER_TURN = 3;
|
|
393667
393376
|
var init_chatgpt_plan_rotation = __esm(() => {
|
|
393668
393377
|
init_available_models();
|
|
393669
393378
|
init_model_handles();
|
|
393670
393379
|
init_modify();
|
|
393671
393380
|
init_turn_recovery_policy();
|
|
393672
393381
|
init_backend2();
|
|
393673
|
-
exhaustedProviders = new Set;
|
|
393674
393382
|
});
|
|
393675
393383
|
|
|
393676
393384
|
// src/websocket/listener/skill-injection.ts
|
|
@@ -403564,6 +403272,16 @@ var init_catalog = __esm(() => {
|
|
|
403564
403272
|
"listen"
|
|
403565
403273
|
]
|
|
403566
403274
|
},
|
|
403275
|
+
{
|
|
403276
|
+
id: "mcp-servers-info",
|
|
403277
|
+
description: "MCP servers with tools available through letta mcp",
|
|
403278
|
+
modes: [
|
|
403279
|
+
"interactive",
|
|
403280
|
+
"headless-one-shot",
|
|
403281
|
+
"headless-bidirectional",
|
|
403282
|
+
"listen"
|
|
403283
|
+
]
|
|
403284
|
+
},
|
|
403567
403285
|
{
|
|
403568
403286
|
id: "permission-mode",
|
|
403569
403287
|
description: "Permission mode reminder",
|
|
@@ -403599,6 +403317,167 @@ var init_catalog = __esm(() => {
|
|
|
403599
403317
|
SHARED_REMINDER_BY_ID = new Map(SHARED_REMINDER_CATALOG.map((entry) => [entry.id, entry]));
|
|
403600
403318
|
});
|
|
403601
403319
|
|
|
403320
|
+
// src/backend/api/unified-mcp.ts
|
|
403321
|
+
var exports_unified_mcp = {};
|
|
403322
|
+
__export(exports_unified_mcp, {
|
|
403323
|
+
searchUnifiedMcpTools: () => searchUnifiedMcpTools,
|
|
403324
|
+
runUnifiedMcpTool: () => runUnifiedMcpTool,
|
|
403325
|
+
listUnifiedMcpTools: () => listUnifiedMcpTools,
|
|
403326
|
+
listUnifiedMcpServers: () => listUnifiedMcpServers
|
|
403327
|
+
});
|
|
403328
|
+
function stringField2(value, key2) {
|
|
403329
|
+
return typeof value[key2] === "string" ? value[key2] : null;
|
|
403330
|
+
}
|
|
403331
|
+
function recordField(value, ...names2) {
|
|
403332
|
+
for (const name of names2) {
|
|
403333
|
+
const field = value[name];
|
|
403334
|
+
if (isRecord(field))
|
|
403335
|
+
return field;
|
|
403336
|
+
}
|
|
403337
|
+
return;
|
|
403338
|
+
}
|
|
403339
|
+
function parseServer(value, registered) {
|
|
403340
|
+
if (!isRecord(value))
|
|
403341
|
+
return null;
|
|
403342
|
+
const id2 = stringField2(value, "id");
|
|
403343
|
+
const serverName = stringField2(value, "server_name") ?? (registered ? stringField2(registered, "server_name") : null);
|
|
403344
|
+
const serverType = stringField2(value, "mcp_server_type") ?? (registered ? stringField2(registered, "mcp_server_type") : null) ?? "unknown";
|
|
403345
|
+
if (!id2 || !serverName)
|
|
403346
|
+
return null;
|
|
403347
|
+
const serverUrl = stringField2(value, "server_url") ?? (registered ? stringField2(registered, "server_url") : null) ?? undefined;
|
|
403348
|
+
const command = stringField2(value, "command") ?? (registered ? stringField2(registered, "command") : null) ?? undefined;
|
|
403349
|
+
const argsValue = value.args ?? registered?.args;
|
|
403350
|
+
const args = Array.isArray(argsValue) ? argsValue.filter((item) => typeof item === "string") : [];
|
|
403351
|
+
const target2 = serverUrl ?? [command, ...args].filter(Boolean).join(" ");
|
|
403352
|
+
return {
|
|
403353
|
+
id: id2,
|
|
403354
|
+
serverName,
|
|
403355
|
+
serverType,
|
|
403356
|
+
target: target2,
|
|
403357
|
+
...serverUrl ? { serverUrl } : {},
|
|
403358
|
+
...command ? { command, args } : {}
|
|
403359
|
+
};
|
|
403360
|
+
}
|
|
403361
|
+
function parseTool(value) {
|
|
403362
|
+
if (!isRecord(value))
|
|
403363
|
+
return null;
|
|
403364
|
+
const id2 = stringField2(value, "id");
|
|
403365
|
+
const name = stringField2(value, "name");
|
|
403366
|
+
if (!id2 || !name)
|
|
403367
|
+
return null;
|
|
403368
|
+
const description = stringField2(value, "description");
|
|
403369
|
+
const jsonSchema = isRecord(value.json_schema) ? value.json_schema : {};
|
|
403370
|
+
const inputSchema = isRecord(jsonSchema.parameters) ? jsonSchema.parameters : isRecord(value.args_json_schema) ? value.args_json_schema : { type: "object", properties: {} };
|
|
403371
|
+
const title = stringField2(value, "title") ?? stringField2(jsonSchema, "title");
|
|
403372
|
+
const outputSchema = recordField(value, "outputSchema", "output_schema") ?? recordField(jsonSchema, "outputSchema", "output_schema");
|
|
403373
|
+
const annotations = recordField(value, "annotations") ?? recordField(jsonSchema, "annotations");
|
|
403374
|
+
const execution = recordField(value, "execution") ?? recordField(jsonSchema, "execution");
|
|
403375
|
+
const meta = recordField(value, "_meta") ?? recordField(jsonSchema, "_meta");
|
|
403376
|
+
const iconsValue = value.icons ?? jsonSchema.icons;
|
|
403377
|
+
const icons = Array.isArray(iconsValue) ? iconsValue.filter(isRecord) : undefined;
|
|
403378
|
+
return {
|
|
403379
|
+
id: id2,
|
|
403380
|
+
name,
|
|
403381
|
+
...title ? { title } : {},
|
|
403382
|
+
description,
|
|
403383
|
+
inputSchema,
|
|
403384
|
+
...outputSchema ? { outputSchema } : {},
|
|
403385
|
+
...annotations ? { annotations } : {},
|
|
403386
|
+
...execution ? { execution } : {},
|
|
403387
|
+
...meta ? { _meta: meta } : {},
|
|
403388
|
+
...icons ? { icons } : {}
|
|
403389
|
+
};
|
|
403390
|
+
}
|
|
403391
|
+
function parseRunResult(value) {
|
|
403392
|
+
if (!isRecord(value))
|
|
403393
|
+
throw new Error("Invalid MCP tool run response");
|
|
403394
|
+
return {
|
|
403395
|
+
status: stringField2(value, "status") ?? "unknown",
|
|
403396
|
+
funcReturn: value.func_return,
|
|
403397
|
+
stdout: value.stdout,
|
|
403398
|
+
stderr: value.stderr
|
|
403399
|
+
};
|
|
403400
|
+
}
|
|
403401
|
+
function parseSearchResult(value) {
|
|
403402
|
+
if (!isRecord(value) || !isRecord(value.tool))
|
|
403403
|
+
return null;
|
|
403404
|
+
const toolId = stringField2(value.tool, "id");
|
|
403405
|
+
const jsonSchema = value.tool.json_schema;
|
|
403406
|
+
const score = value.combined_score;
|
|
403407
|
+
if (!toolId || jsonSchema !== null && !isRecord(jsonSchema) || typeof score !== "number") {
|
|
403408
|
+
return null;
|
|
403409
|
+
}
|
|
403410
|
+
return { toolId, jsonSchema, score };
|
|
403411
|
+
}
|
|
403412
|
+
async function withTimeout2(promise, timeoutMs, operation) {
|
|
403413
|
+
let timer;
|
|
403414
|
+
try {
|
|
403415
|
+
return await Promise.race([
|
|
403416
|
+
promise,
|
|
403417
|
+
new Promise((_resolve, reject2) => {
|
|
403418
|
+
timer = setTimeout(() => reject2(new Error(`${operation} timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
403419
|
+
})
|
|
403420
|
+
]);
|
|
403421
|
+
} finally {
|
|
403422
|
+
if (timer)
|
|
403423
|
+
clearTimeout(timer);
|
|
403424
|
+
}
|
|
403425
|
+
}
|
|
403426
|
+
async function listUnifiedMcpServers(client, agentId, timeoutMs = 1e4) {
|
|
403427
|
+
const value = await withTimeout2(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers`), timeoutMs, "Listing agent MCP servers");
|
|
403428
|
+
if (!Array.isArray(value))
|
|
403429
|
+
return [];
|
|
403430
|
+
const needsEnrichment = value.some((item) => isRecord(item) && !stringField2(item, "mcp_server_type"));
|
|
403431
|
+
const registeredById = new Map;
|
|
403432
|
+
if (needsEnrichment && client.mcpServers) {
|
|
403433
|
+
try {
|
|
403434
|
+
const registered = await withTimeout2(client.mcpServers.list(), timeoutMs, "Listing registered MCP servers");
|
|
403435
|
+
for (const item of registered) {
|
|
403436
|
+
if (!isRecord(item))
|
|
403437
|
+
continue;
|
|
403438
|
+
const id2 = stringField2(item, "id");
|
|
403439
|
+
if (id2)
|
|
403440
|
+
registeredById.set(id2, item);
|
|
403441
|
+
}
|
|
403442
|
+
} catch {}
|
|
403443
|
+
}
|
|
403444
|
+
return value.map((item) => {
|
|
403445
|
+
const registered = isRecord(item) ? registeredById.get(stringField2(item, "id") ?? "") : undefined;
|
|
403446
|
+
return parseServer(item, registered);
|
|
403447
|
+
}).filter((server2) => server2 !== null);
|
|
403448
|
+
}
|
|
403449
|
+
async function listUnifiedMcpTools(client, agentId, mcpServerId, timeoutMs = 1e4) {
|
|
403450
|
+
const value = await withTimeout2(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers/${encodeURIComponent(mcpServerId)}/tools`), timeoutMs, "Listing agent MCP server tools");
|
|
403451
|
+
if (!Array.isArray(value))
|
|
403452
|
+
return [];
|
|
403453
|
+
return value.map(parseTool).filter((tool) => tool !== null);
|
|
403454
|
+
}
|
|
403455
|
+
async function searchUnifiedMcpTools(params) {
|
|
403456
|
+
const value = await withTimeout2(params.client.post(`/v1/agents/${encodeURIComponent(params.agentId)}/mcp-servers/tools/search`, {
|
|
403457
|
+
body: {
|
|
403458
|
+
query: params.query,
|
|
403459
|
+
search_mode: params.searchMode,
|
|
403460
|
+
limit: params.limit
|
|
403461
|
+
}
|
|
403462
|
+
}), params.timeoutMs ?? 60000, "Searching agent MCP tools");
|
|
403463
|
+
if (!Array.isArray(value)) {
|
|
403464
|
+
throw new Error("Invalid MCP tool search response");
|
|
403465
|
+
}
|
|
403466
|
+
const results = [];
|
|
403467
|
+
for (const item of value) {
|
|
403468
|
+
const result2 = parseSearchResult(item);
|
|
403469
|
+
if (!result2)
|
|
403470
|
+
throw new Error("Invalid MCP tool search result");
|
|
403471
|
+
results.push(result2);
|
|
403472
|
+
}
|
|
403473
|
+
return results;
|
|
403474
|
+
}
|
|
403475
|
+
async function runUnifiedMcpTool(params) {
|
|
403476
|
+
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");
|
|
403477
|
+
return parseRunResult(value);
|
|
403478
|
+
}
|
|
403479
|
+
var init_unified_mcp = () => {};
|
|
403480
|
+
|
|
403602
403481
|
// src/reminders/engine.ts
|
|
403603
403482
|
async function buildAgentInfoReminder(context3) {
|
|
403604
403483
|
if (!context3.systemInfoReminderEnabled || context3.state.hasSentAgentInfo) {
|
|
@@ -403658,6 +403537,80 @@ ${SYSTEM_REMINDER_CLOSE}`;
|
|
|
403658
403537
|
return null;
|
|
403659
403538
|
}
|
|
403660
403539
|
}
|
|
403540
|
+
async function defaultListServerSideServers(agentId) {
|
|
403541
|
+
let serverSideAvailable = false;
|
|
403542
|
+
try {
|
|
403543
|
+
const { getBackend: getBackend2 } = await Promise.resolve().then(() => (init_backend2(), exports_backend));
|
|
403544
|
+
serverSideAvailable = getBackend2().capabilities.serverSideToolManagement;
|
|
403545
|
+
} catch {
|
|
403546
|
+
return null;
|
|
403547
|
+
}
|
|
403548
|
+
if (!serverSideAvailable) {
|
|
403549
|
+
return null;
|
|
403550
|
+
}
|
|
403551
|
+
const { getClient: getClient2 } = await Promise.resolve().then(() => (init_client2(), exports_client));
|
|
403552
|
+
const { getServerUrl: getServerUrl2 } = await Promise.resolve().then(() => (init_server_url(), exports_server_url));
|
|
403553
|
+
const { LETTA_CLOUD_API_URL: LETTA_CLOUD_API_URL2 } = await Promise.resolve().then(() => (init_oauth(), exports_oauth));
|
|
403554
|
+
const { listUnifiedMcpServers: listUnifiedMcpServers2, listUnifiedMcpTools: listUnifiedMcpTools2 } = await Promise.resolve().then(() => (init_unified_mcp(), exports_unified_mcp));
|
|
403555
|
+
const client = await getClient2();
|
|
403556
|
+
const allServers = await listUnifiedMcpServers2(client, agentId, 3000);
|
|
403557
|
+
const servers = getServerUrl2() === LETTA_CLOUD_API_URL2 ? allServers.filter((server2) => server2.serverType !== "stdio") : allServers;
|
|
403558
|
+
return Promise.all(servers.map(async (server2) => ({
|
|
403559
|
+
name: server2.serverName,
|
|
403560
|
+
toolCount: await listUnifiedMcpTools2(client, agentId, server2.id, 3000).then((tools) => tools.length).catch(() => null)
|
|
403561
|
+
})));
|
|
403562
|
+
}
|
|
403563
|
+
function formatMcpServerEntry(entry) {
|
|
403564
|
+
if (entry.toolCount === null) {
|
|
403565
|
+
return entry.name;
|
|
403566
|
+
}
|
|
403567
|
+
return `${entry.name} (${entry.toolCount} ${entry.toolCount === 1 ? "tool" : "tools"})`;
|
|
403568
|
+
}
|
|
403569
|
+
async function buildMcpServersInfoReminderText(context3, deps = {}) {
|
|
403570
|
+
try {
|
|
403571
|
+
const now2 = Date.now();
|
|
403572
|
+
const lastFetched = context3.state.lastMcpServersFetchedAtMs;
|
|
403573
|
+
const due = !context3.state.hasSentMcpServersInfo || lastFetched === null || now2 - lastFetched > MCP_SERVERS_REFRESH_MS;
|
|
403574
|
+
if (!due) {
|
|
403575
|
+
return null;
|
|
403576
|
+
}
|
|
403577
|
+
context3.state.lastMcpServersFetchedAtMs = now2;
|
|
403578
|
+
const localNames = (deps.getLocalServerNames ?? ((agentId) => settingsManager.getMcpServers(agentId).map((server2) => server2.name)))(context3.agent.id);
|
|
403579
|
+
const entries = localNames.map((name) => ({
|
|
403580
|
+
name,
|
|
403581
|
+
toolCount: null
|
|
403582
|
+
}));
|
|
403583
|
+
const serverSideEntries = await (deps.listServerSideServers ?? defaultListServerSideServers)(context3.agent.id);
|
|
403584
|
+
if (serverSideEntries) {
|
|
403585
|
+
entries.push(...serverSideEntries);
|
|
403586
|
+
}
|
|
403587
|
+
const uniqueEntries = [
|
|
403588
|
+
...new Map(entries.map((entry) => [entry.name, entry])).values()
|
|
403589
|
+
];
|
|
403590
|
+
const namesKey = uniqueEntries.map((entry) => `${entry.name}\x01${entry.toolCount ?? ""}`).join("\x00");
|
|
403591
|
+
if (context3.state.hasSentMcpServersInfo && context3.state.lastSentMcpServerNamesKey === namesKey) {
|
|
403592
|
+
return null;
|
|
403593
|
+
}
|
|
403594
|
+
context3.state.hasSentMcpServersInfo = true;
|
|
403595
|
+
context3.state.lastSentMcpServerNamesKey = namesKey;
|
|
403596
|
+
if (uniqueEntries.length === 0) {
|
|
403597
|
+
return `${SYSTEM_REMINDER_OPEN}
|
|
403598
|
+
MCP servers with available tools: None
|
|
403599
|
+
${SYSTEM_REMINDER_CLOSE}`;
|
|
403600
|
+
}
|
|
403601
|
+
const rendered = uniqueEntries.map(formatMcpServerEntry).join(", ");
|
|
403602
|
+
return `${SYSTEM_REMINDER_OPEN}
|
|
403603
|
+
MCP servers with available tools: ${rendered}
|
|
403604
|
+
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"}'\`.
|
|
403605
|
+
${SYSTEM_REMINDER_CLOSE}`;
|
|
403606
|
+
} catch (error4) {
|
|
403607
|
+
debugLog("mcp", `Failed to build MCP servers reminder: ${error4 instanceof Error ? error4.message : String(error4)}`);
|
|
403608
|
+
return null;
|
|
403609
|
+
}
|
|
403610
|
+
}
|
|
403611
|
+
async function buildMcpServersInfoReminder(context3) {
|
|
403612
|
+
return buildMcpServersInfoReminderText(context3);
|
|
403613
|
+
}
|
|
403661
403614
|
async function buildSessionContextReminder(context3) {
|
|
403662
403615
|
if (!context3.systemInfoReminderEnabled || context3.state.hasSentSessionContext) {
|
|
403663
403616
|
return null;
|
|
@@ -403853,7 +403806,7 @@ function prependReminderPartsToContent(content, reminderParts) {
|
|
|
403853
403806
|
}
|
|
403854
403807
|
return [...reminderParts, { type: "text", text: text2 }];
|
|
403855
403808
|
}
|
|
403856
|
-
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;
|
|
403809
|
+
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;
|
|
403857
403810
|
var init_engine3 = __esm(() => {
|
|
403858
403811
|
init_agent_info();
|
|
403859
403812
|
init_conversation_bootstrap();
|
|
@@ -403874,6 +403827,7 @@ var init_engine3 = __esm(() => {
|
|
|
403874
403827
|
"agent-info": buildAgentInfoReminder,
|
|
403875
403828
|
"conversation-bootstrap": buildConversationBootstrapReminderPart,
|
|
403876
403829
|
"secrets-info": buildSecretsInfoReminder,
|
|
403830
|
+
"mcp-servers-info": buildMcpServersInfoReminder,
|
|
403877
403831
|
"session-context": buildSessionContextReminder,
|
|
403878
403832
|
"permission-mode": buildPermissionModeReminder,
|
|
403879
403833
|
"memory-git-sync": buildMemoryGitSyncReminder,
|
|
@@ -404322,6 +404276,7 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
|
|
|
404322
404276
|
const turnWorkingDirectory = getConversationWorkingDirectory(runtime.listener, agentId, conversationId);
|
|
404323
404277
|
const turnPermissionModeState = getOrCreateConversationPermissionModeStateRef(runtime.listener, agentId, conversationId);
|
|
404324
404278
|
let postStopApprovalRecoveryRetries = 0, llmApiErrorRetries = 0, emptyResponseRetries = 0, chatgptPlanSwaps = 0, lastApprovalContinuationAccepted = false, activeDequeuedBatchId = dequeuedBatchId;
|
|
404279
|
+
const chatgptExhaustedProviders = new Set;
|
|
404325
404280
|
const turnCorrelation = existingTurnCorrelation ?? createTurnCorrelation(runtime, msg, activeDequeuedBatchId);
|
|
404326
404281
|
const msgRunIds = [];
|
|
404327
404282
|
let lastExecutionResults = null;
|
|
@@ -404688,8 +404643,10 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
|
|
|
404688
404643
|
if (agentId && chatgptPlanSwaps < CHATGPT_PLAN_ROTATION_MAX_SWAPS_PER_TURN) {
|
|
404689
404644
|
const rotation = await rotateChatGPTPlanOnQuotaLimit({
|
|
404690
404645
|
agentId,
|
|
404646
|
+
conversationId,
|
|
404691
404647
|
currentHandle: null,
|
|
404692
|
-
error: quotaError
|
|
404648
|
+
error: quotaError,
|
|
404649
|
+
exhaustedProviders: chatgptExhaustedProviders
|
|
404693
404650
|
});
|
|
404694
404651
|
if (rotation) {
|
|
404695
404652
|
chatgptPlanSwaps += 1;
|
|
@@ -407712,11 +407669,11 @@ function scheduleRemoteRestart(connectionName, log2) {
|
|
|
407712
407669
|
log2(`restart skipped (entrypoint=${entrypoint ?? "missing"}, connectionName=${connectionName ?? "missing"})`);
|
|
407713
407670
|
return;
|
|
407714
407671
|
}
|
|
407715
|
-
log2(`scheduling remote listener restart for
|
|
407672
|
+
log2(`scheduling remote listener restart for computer ${connectionName}`);
|
|
407716
407673
|
setTimeout(async () => {
|
|
407717
407674
|
await flushRemoteSettingsWrites();
|
|
407718
|
-
log2(`spawning replacement listener: ${process.execPath} ${entrypoint} remote --
|
|
407719
|
-
const child = spawn9(process.execPath, [entrypoint, "remote", "--
|
|
407675
|
+
log2(`spawning replacement listener: ${process.execPath} ${entrypoint} remote --computer-name ${connectionName}`);
|
|
407676
|
+
const child = spawn9(process.execPath, [entrypoint, "remote", "--computer-name", connectionName], {
|
|
407720
407677
|
cwd: process.cwd(),
|
|
407721
407678
|
detached: true,
|
|
407722
407679
|
env: process.env,
|
|
@@ -408217,7 +408174,7 @@ function getNumber(record3, keys3) {
|
|
|
408217
408174
|
}
|
|
408218
408175
|
return null;
|
|
408219
408176
|
}
|
|
408220
|
-
function
|
|
408177
|
+
function getString(record3, keys3) {
|
|
408221
408178
|
const value = getValue(record3, keys3);
|
|
408222
408179
|
if (typeof value === "string" && value.trim())
|
|
408223
408180
|
return value.trim();
|
|
@@ -408303,7 +408260,7 @@ function normalizeCredits(raw2, rateLimit) {
|
|
|
408303
408260
|
const resetCredits = getRecord(raw2, ["rate_limit_reset_credits", "rateLimitResetCredits"]) ?? getRecord(rateLimit, ["rate_limit_reset_credits", "rateLimitResetCredits"]);
|
|
408304
408261
|
if (!credits && !resetCredits)
|
|
408305
408262
|
return null;
|
|
408306
|
-
const balance =
|
|
408263
|
+
const balance = getString(credits, ["balance", "credit_balance", "amount"]);
|
|
408307
408264
|
const availableCount = getNumber(credits, ["available_count", "availableCount", "count"]) ?? getNumber(resetCredits, ["available_count", "availableCount", "count"]);
|
|
408308
408265
|
const hasCredits = getBoolean(credits, ["has_credits", "hasCredits"]);
|
|
408309
408266
|
const unlimited = getBoolean(credits, ["unlimited", "is_unlimited"]);
|
|
@@ -408322,8 +408279,8 @@ function normalizeIndividualLimit(raw2, nowMs) {
|
|
|
408322
408279
|
const record3 = getRecord(raw2, ["individual_limit", "individualLimit"]) ?? getRecord(spendControl, ["individual_limit", "individualLimit"]);
|
|
408323
408280
|
if (!record3)
|
|
408324
408281
|
return null;
|
|
408325
|
-
const limit3 =
|
|
408326
|
-
const used =
|
|
408282
|
+
const limit3 = getString(record3, ["limit"]);
|
|
408283
|
+
const used = getString(record3, ["used"]);
|
|
408327
408284
|
const remainingPercent = getNumber(record3, [
|
|
408328
408285
|
"remaining_percent",
|
|
408329
408286
|
"remainingPercent"
|
|
@@ -408352,10 +408309,10 @@ function normalizeCloudUsageWindow(value, fallbackLabel, nowMs) {
|
|
|
408352
408309
|
const record3 = asRecord8(value);
|
|
408353
408310
|
if (!record3)
|
|
408354
408311
|
return null;
|
|
408355
|
-
return normalizeUsageWindow(record3,
|
|
408312
|
+
return normalizeUsageWindow(record3, getString(record3, ["label", "name"]) ?? fallbackLabel, nowMs);
|
|
408356
408313
|
}
|
|
408357
408314
|
function normalizeAdditionalRateLimit(details, index, nowMs) {
|
|
408358
|
-
const label =
|
|
408315
|
+
const label = getString(details, [
|
|
408359
408316
|
"limit_name",
|
|
408360
408317
|
"limitName",
|
|
408361
408318
|
"metered_feature",
|
|
@@ -408381,7 +408338,7 @@ function getRateLimitReachedType(raw2) {
|
|
|
408381
408338
|
if (typeof value === "string" && value.trim())
|
|
408382
408339
|
return value.trim();
|
|
408383
408340
|
const record3 = asRecord8(value);
|
|
408384
|
-
return
|
|
408341
|
+
return getString(record3, ["type", "kind"]);
|
|
408385
408342
|
}
|
|
408386
408343
|
function formatPercent(value) {
|
|
408387
408344
|
const rounded = Math.round(value);
|
|
@@ -408496,7 +408453,7 @@ function normalizeWhamUsageResponse(input) {
|
|
|
408496
408453
|
const snapshotWithoutSummary = {
|
|
408497
408454
|
providerName: input.providerName,
|
|
408498
408455
|
fetchedAt,
|
|
408499
|
-
planType:
|
|
408456
|
+
planType: getString(raw2, ["plan_type", "planType"]),
|
|
408500
408457
|
limitReached: getBoolean(rateLimit, ["limit_reached", "limitReached"]) ?? getBoolean(spendControl, ["reached"]),
|
|
408501
408458
|
rateLimitReachedType: getRateLimitReachedType(raw2),
|
|
408502
408459
|
primary,
|
|
@@ -408515,18 +408472,18 @@ function normalizeCloudChatGPTUsageResponse(input) {
|
|
|
408515
408472
|
if (!raw2)
|
|
408516
408473
|
return null;
|
|
408517
408474
|
const nowMs = input.nowMs ?? Date.now();
|
|
408518
|
-
const fetchedAt =
|
|
408475
|
+
const fetchedAt = getString(raw2, ["fetchedAt", "fetched_at"]) ?? new Date(nowMs).toISOString();
|
|
408519
408476
|
const additional = getRecordArray(raw2, [
|
|
408520
408477
|
"additional",
|
|
408521
408478
|
"additional_rate_limits",
|
|
408522
408479
|
"additionalRateLimits"
|
|
408523
408480
|
]).map((window2, index) => normalizeCloudUsageWindow(window2, `limit ${index + 1}`, nowMs)).filter((window2) => !!window2);
|
|
408524
408481
|
const snapshotWithoutSummary = {
|
|
408525
|
-
providerName:
|
|
408482
|
+
providerName: getString(raw2, ["providerName", "provider_name"]) ?? input.providerName,
|
|
408526
408483
|
fetchedAt,
|
|
408527
|
-
planType:
|
|
408484
|
+
planType: getString(raw2, ["planType", "plan_type"]),
|
|
408528
408485
|
limitReached: getBoolean(raw2, ["limitReached", "limit_reached"]),
|
|
408529
|
-
rateLimitReachedType:
|
|
408486
|
+
rateLimitReachedType: getString(raw2, [
|
|
408530
408487
|
"rateLimitReachedType",
|
|
408531
408488
|
"rate_limit_reached_type"
|
|
408532
408489
|
]),
|
|
@@ -408538,7 +408495,7 @@ function normalizeCloudChatGPTUsageResponse(input) {
|
|
|
408538
408495
|
};
|
|
408539
408496
|
return {
|
|
408540
408497
|
...snapshotWithoutSummary,
|
|
408541
|
-
summary:
|
|
408498
|
+
summary: getString(raw2, ["summary"]) ?? formatChatGPTUsageSnapshot(snapshotWithoutSummary, new Date(nowMs))
|
|
408542
408499
|
};
|
|
408543
408500
|
}
|
|
408544
408501
|
function retryAfterMs(response) {
|
|
@@ -408563,7 +408520,7 @@ async function readJsonRecord(response) {
|
|
|
408563
408520
|
}
|
|
408564
408521
|
}
|
|
408565
408522
|
function responseMessage(raw2, fallback) {
|
|
408566
|
-
return
|
|
408523
|
+
return getString(raw2 ?? undefined, ["message", "error", "detail"]) ?? fallback;
|
|
408567
408524
|
}
|
|
408568
408525
|
function chatGPTUsageError(code2, message, retryAfter) {
|
|
408569
408526
|
return {
|
|
@@ -412332,7 +412289,7 @@ var init_app_server_openai_common = __esm(() => {
|
|
|
412332
412289
|
function asRecord9(value) {
|
|
412333
412290
|
return value !== null && typeof value === "object" ? value : null;
|
|
412334
412291
|
}
|
|
412335
|
-
function
|
|
412292
|
+
function stringValue3(value) {
|
|
412336
412293
|
return typeof value === "string" ? value : undefined;
|
|
412337
412294
|
}
|
|
412338
412295
|
function extractToolCallFragments(record3) {
|
|
@@ -412346,12 +412303,12 @@ function extractToolCallFragments(record3) {
|
|
|
412346
412303
|
if (!toolCall) {
|
|
412347
412304
|
continue;
|
|
412348
412305
|
}
|
|
412349
|
-
const toolCallId =
|
|
412306
|
+
const toolCallId = stringValue3(toolCall.tool_call_id);
|
|
412350
412307
|
if (!toolCallId) {
|
|
412351
412308
|
continue;
|
|
412352
412309
|
}
|
|
412353
|
-
const name =
|
|
412354
|
-
const argumentsDelta =
|
|
412310
|
+
const name = stringValue3(toolCall.name) ?? null;
|
|
412311
|
+
const argumentsDelta = stringValue3(toolCall.arguments) ?? null;
|
|
412355
412312
|
fragments.push({ toolCallId, name, argumentsDelta });
|
|
412356
412313
|
}
|
|
412357
412314
|
return fragments;
|
|
@@ -412391,7 +412348,7 @@ function extractToolReturns(record3) {
|
|
|
412391
412348
|
if (!rec) {
|
|
412392
412349
|
continue;
|
|
412393
412350
|
}
|
|
412394
|
-
const toolCallId =
|
|
412351
|
+
const toolCallId = stringValue3(rec.tool_call_id);
|
|
412395
412352
|
const status = asToolReturnStatus2(rec.status);
|
|
412396
412353
|
if (!toolCallId || !status) {
|
|
412397
412354
|
continue;
|
|
@@ -412406,7 +412363,7 @@ function extractToolReturns(record3) {
|
|
|
412406
412363
|
return results;
|
|
412407
412364
|
}
|
|
412408
412365
|
}
|
|
412409
|
-
const topLevelToolCallId =
|
|
412366
|
+
const topLevelToolCallId = stringValue3(record3.tool_call_id);
|
|
412410
412367
|
const topLevelStatus = asToolReturnStatus2(record3.status);
|
|
412411
412368
|
if (!topLevelToolCallId || !topLevelStatus) {
|
|
412412
412369
|
return [];
|
|
@@ -412494,13 +412451,13 @@ function createToolLifecycleTracker(onEvent) {
|
|
|
412494
412451
|
return;
|
|
412495
412452
|
}
|
|
412496
412453
|
const record3 = delta2;
|
|
412497
|
-
const messageType =
|
|
412498
|
-
const toolCallId =
|
|
412454
|
+
const messageType = stringValue3(record3.message_type);
|
|
412455
|
+
const toolCallId = stringValue3(record3.tool_call_id);
|
|
412499
412456
|
if (messageType === "client_tool_start" && toolCallId) {
|
|
412500
412457
|
const state = getOrCreate(toolCallId);
|
|
412501
412458
|
state.clientManaged = true;
|
|
412502
412459
|
if (!state.name)
|
|
412503
|
-
state.name =
|
|
412460
|
+
state.name = stringValue3(record3.tool_name) ?? null;
|
|
412504
412461
|
return;
|
|
412505
412462
|
}
|
|
412506
412463
|
if (messageType === "client_tool_end" && toolCallId) {
|
|
@@ -414087,7 +414044,7 @@ var init_gateway_supervisor = __esm(() => {
|
|
|
414087
414044
|
|
|
414088
414045
|
// src/cli/subcommands/listen.tsx
|
|
414089
414046
|
import { hostname as hostname4 } from "node:os";
|
|
414090
|
-
import { parseArgs as
|
|
414047
|
+
import { parseArgs as parseArgs8 } from "node:util";
|
|
414091
414048
|
import { MessageChannel as MessageChannel2 } from "node:worker_threads";
|
|
414092
414049
|
function PromptEnvName(props) {
|
|
414093
414050
|
const [value, setValue] = import_react33.useState("");
|
|
@@ -414095,7 +414052,7 @@ function PromptEnvName(props) {
|
|
|
414095
414052
|
flexDirection: "column",
|
|
414096
414053
|
children: [
|
|
414097
414054
|
/* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
|
|
414098
|
-
children: "Enter
|
|
414055
|
+
children: "Enter computer name (or press Enter for hostname): "
|
|
414099
414056
|
}, undefined, false, undefined, this),
|
|
414100
414057
|
/* @__PURE__ */ jsx_dev_runtime13.jsxDEV(build_default, {
|
|
414101
414058
|
value,
|
|
@@ -414172,14 +414129,14 @@ function shouldAcquireStandaloneListenerLock() {
|
|
|
414172
414129
|
return shouldAcquireManualListenerLock(getSpawnerListenerInstanceId(), process.env.LETTA_DESKTOP_MODE === "1");
|
|
414173
414130
|
}
|
|
414174
414131
|
function printListenUsage() {
|
|
414175
|
-
console.log(`Usage: letta server [--
|
|
414132
|
+
console.log(`Usage: letta server [--computer-name <name>] [--channels <list>] [--skills <path>] [--debug]
|
|
414176
414133
|
`);
|
|
414177
|
-
console.log(`Register this
|
|
414134
|
+
console.log(`Register this computer to receive messages from Letta Cloud.
|
|
414178
414135
|
`);
|
|
414179
414136
|
console.log("Options:");
|
|
414180
|
-
console.log(" --
|
|
414137
|
+
console.log(" --computer-name <name> Friendly name for this computer (uses hostname if not provided)");
|
|
414181
414138
|
console.log(" --channels <list> Comma-separated channel names to enable (e.g. telegram)");
|
|
414182
|
-
console.log(" --skills <path> Use this directory for
|
|
414139
|
+
console.log(" --skills <path> Use this directory for computer-provided skills");
|
|
414183
414140
|
console.log(" --install-channel-runtimes Install missing runtime deps for the selected channels before startup");
|
|
414184
414141
|
console.log(" --debug Plain-text mode: log all WebSocket events instead of interactive UI");
|
|
414185
414142
|
console.log(` -h, --help Show this help message
|
|
@@ -414187,20 +414144,20 @@ function printListenUsage() {
|
|
|
414187
414144
|
console.log("Examples:");
|
|
414188
414145
|
console.log(" letta channels configure telegram # Configure Telegram first");
|
|
414189
414146
|
console.log(" letta server # Uses hostname as default");
|
|
414190
|
-
console.log(' letta server --
|
|
414147
|
+
console.log(' letta server --computer-name "work-laptop"');
|
|
414191
414148
|
console.log(" letta server --channels telegram # Enable Telegram channel");
|
|
414192
414149
|
console.log(" letta server --channels telegram --install-channel-runtimes");
|
|
414193
414150
|
console.log(` letta server --debug # Log all WS events
|
|
414194
414151
|
`);
|
|
414195
414152
|
console.log("Once connected, this instance will listen for incoming messages from cloud agents.");
|
|
414196
|
-
console.log("Messages will be executed locally
|
|
414153
|
+
console.log("Messages will be executed locally on this computer.");
|
|
414197
414154
|
console.log("Telegram flow: configure the bot, start the listener with --channels telegram,");
|
|
414198
414155
|
console.log("then message the bot from Telegram and run /channels telegram pair <code> in the target conversation.");
|
|
414199
414156
|
}
|
|
414200
414157
|
async function runListenSubcommand(argv) {
|
|
414201
414158
|
let values3;
|
|
414202
414159
|
try {
|
|
414203
|
-
({ values: values3 } =
|
|
414160
|
+
({ values: values3 } = parseArgs8({
|
|
414204
414161
|
args: argv,
|
|
414205
414162
|
options: LISTEN_OPTIONS,
|
|
414206
414163
|
strict: true,
|
|
@@ -414282,8 +414239,9 @@ async function runListenSubcommand(argv) {
|
|
|
414282
414239
|
const restoreAgentScope = restoreEnabledChannels ? resolveChannelRestoreAgentScope(scopedRestoreAgentScope) : null;
|
|
414283
414240
|
const channelNames = values3.channels ? values3.channels.split(",").map((s3) => s3.trim()).filter(Boolean) : [];
|
|
414284
414241
|
let connectionName;
|
|
414285
|
-
|
|
414286
|
-
|
|
414242
|
+
const explicitComputerName = values3["computer-name"] ?? values3["env-name"];
|
|
414243
|
+
if (explicitComputerName) {
|
|
414244
|
+
connectionName = explicitComputerName;
|
|
414287
414245
|
settingsManager.setListenerEnvName(connectionName);
|
|
414288
414246
|
} else {
|
|
414289
414247
|
const savedName = settingsManager.getListenerEnvName();
|
|
@@ -414312,7 +414270,7 @@ async function runListenSubcommand(argv) {
|
|
|
414312
414270
|
const startupMode = await resolveListenerStartupMode(channelNames, channelNames.length > 0 || restoreEnabledChannels);
|
|
414313
414271
|
if (startupMode.kind === "unsupported-self-hosted") {
|
|
414314
414272
|
console.error(`Self-hosted listener registration is not available for ${startupMode.serverUrl}.`);
|
|
414315
|
-
console.error("Start with --channels to run local channel adapters, or unset LETTA_BASE_URL to use Letta API remote
|
|
414273
|
+
console.error("Start with --channels to run local channel adapters, or unset LETTA_BASE_URL to use Letta API remote computers.");
|
|
414316
414274
|
await flushListenerTelemetryEnd("listener_self_hosted_no_channels");
|
|
414317
414275
|
return 1;
|
|
414318
414276
|
}
|
|
@@ -414344,8 +414302,8 @@ async function runListenSubcommand(argv) {
|
|
|
414344
414302
|
});
|
|
414345
414303
|
} catch (lockError) {
|
|
414346
414304
|
if (lockError instanceof ManualListenerAlreadyRunningError) {
|
|
414347
|
-
console.error(`A letta server for
|
|
414348
|
-
console.error("Stop that process, or choose a different logical listener with --
|
|
414305
|
+
console.error(`A letta server for computer "${connectionName}" is already running on this machine (pid ${lockError.holderPid}).`);
|
|
414306
|
+
console.error("Stop that process, or choose a different logical listener with --computer-name.");
|
|
414349
414307
|
console.error(`Lock: ${lockError.lockPath}`);
|
|
414350
414308
|
await flushListenerTelemetryEnd("listener_already_running");
|
|
414351
414309
|
return 1;
|
|
@@ -414434,9 +414392,9 @@ async function runListenSubcommand(argv) {
|
|
|
414434
414392
|
const connectionId2 = `local-${deviceId}`;
|
|
414435
414393
|
const startupLabel = startupMode.backend === "local" ? "local backend" : `self-hosted server ${startupMode.serverUrl}`;
|
|
414436
414394
|
sessionLog.log(`Starting local channel listener for ${startupLabel}`);
|
|
414437
|
-
sessionLog.log("Skipping
|
|
414395
|
+
sessionLog.log("Skipping computer registration");
|
|
414438
414396
|
console.log(`Starting local channel listener for ${startupLabel}`);
|
|
414439
|
-
console.log(`Skipping
|
|
414397
|
+
console.log(`Skipping computer registration. Press Ctrl+C to stop.
|
|
414440
414398
|
`);
|
|
414441
414399
|
const { startLocalChannelListener: startLocalChannelListener2 } = await init_listen_client().then(() => exports_listen_client);
|
|
414442
414400
|
await startLocalChannelListener2({
|
|
@@ -414558,7 +414516,7 @@ async function runListenSubcommand(argv) {
|
|
|
414558
414516
|
console.log(`[${formatTimestamp3()}] Reconnecting (attempt ${attempt2}, retry in ${Math.round(nextRetryIn / 1000)}s)`);
|
|
414559
414517
|
},
|
|
414560
414518
|
onNeedsReregister: async () => {
|
|
414561
|
-
console.log(`[${formatTimestamp3()}]
|
|
414519
|
+
console.log(`[${formatTimestamp3()}] Computer connection expired, re-registering...`);
|
|
414562
414520
|
try {
|
|
414563
414521
|
const result2 = await reregister();
|
|
414564
414522
|
await startDebugClient(result2.connectionId, result2.wsUrl, result2.supportsSplitStatusChannels, result2.supportsPairedListenerGenerations);
|
|
@@ -414626,7 +414584,7 @@ async function runListenSubcommand(argv) {
|
|
|
414626
414584
|
updateRetryStatusCallback?.(attempt2, nextRetryIn);
|
|
414627
414585
|
},
|
|
414628
414586
|
onNeedsReregister: async () => {
|
|
414629
|
-
sessionLog.log("
|
|
414587
|
+
sessionLog.log("Computer connection expired, re-registering...");
|
|
414630
414588
|
try {
|
|
414631
414589
|
const result2 = await reregister();
|
|
414632
414590
|
await startNormalClient(result2.connectionId, result2.wsUrl, result2.supportsSplitStatusChannels, result2.supportsPairedListenerGenerations);
|
|
@@ -414695,6 +414653,7 @@ var init_listen = __esm(async () => {
|
|
|
414695
414653
|
jsx_dev_runtime13 = __toESM(require_jsx_dev_runtime(), 1);
|
|
414696
414654
|
activeListenerProcessAnchors = new Set;
|
|
414697
414655
|
LISTEN_OPTIONS = {
|
|
414656
|
+
"computer-name": { type: "string" },
|
|
414698
414657
|
"env-name": { type: "string" },
|
|
414699
414658
|
channels: { type: "string" },
|
|
414700
414659
|
skills: { type: "string" },
|
|
@@ -415108,15 +415067,15 @@ var init_transcript_migration = __esm(() => {
|
|
|
415108
415067
|
});
|
|
415109
415068
|
|
|
415110
415069
|
// src/cli/subcommands/local-backend.ts
|
|
415111
|
-
import { parseArgs as
|
|
415070
|
+
import { parseArgs as parseArgs9 } from "node:util";
|
|
415112
415071
|
function parseLocalBackendArgs(argv) {
|
|
415113
|
-
return
|
|
415072
|
+
return parseArgs9({
|
|
415114
415073
|
args: argv,
|
|
415115
415074
|
options: LOCAL_BACKEND_OPTIONS,
|
|
415116
415075
|
strict: true
|
|
415117
415076
|
});
|
|
415118
415077
|
}
|
|
415119
|
-
function
|
|
415078
|
+
function printUsage7() {
|
|
415120
415079
|
console.log(`
|
|
415121
415080
|
Usage:
|
|
415122
415081
|
letta local-backend migrate-transcripts [--storage-dir <path>] [--dry-run]
|
|
@@ -415129,12 +415088,12 @@ before it is replaced.
|
|
|
415129
415088
|
async function runLocalBackendSubcommand(argv) {
|
|
415130
415089
|
const [command, ...rest4] = argv;
|
|
415131
415090
|
if (!command || command === "help" || command === "--help" || command === "-h") {
|
|
415132
|
-
|
|
415091
|
+
printUsage7();
|
|
415133
415092
|
return command ? 0 : 1;
|
|
415134
415093
|
}
|
|
415135
415094
|
if (command !== "migrate-transcripts") {
|
|
415136
415095
|
console.error(`Unknown local-backend command: ${command}`);
|
|
415137
|
-
|
|
415096
|
+
printUsage7();
|
|
415138
415097
|
return 1;
|
|
415139
415098
|
}
|
|
415140
415099
|
let parsed;
|
|
@@ -415143,11 +415102,11 @@ async function runLocalBackendSubcommand(argv) {
|
|
|
415143
415102
|
} catch (error4) {
|
|
415144
415103
|
const message = error4 instanceof Error ? error4.message : String(error4);
|
|
415145
415104
|
console.error(`Error: ${message}`);
|
|
415146
|
-
|
|
415105
|
+
printUsage7();
|
|
415147
415106
|
return 1;
|
|
415148
415107
|
}
|
|
415149
415108
|
if (parsed.values.help) {
|
|
415150
|
-
|
|
415109
|
+
printUsage7();
|
|
415151
415110
|
return 0;
|
|
415152
415111
|
}
|
|
415153
415112
|
const storageDir = parsed.values["storage-dir"] ?? getLocalBackendStorageDir();
|
|
@@ -415169,160 +415128,6 @@ var init_local_backend2 = __esm(() => {
|
|
|
415169
415128
|
};
|
|
415170
415129
|
});
|
|
415171
415130
|
|
|
415172
|
-
// src/backend/api/unified-mcp.ts
|
|
415173
|
-
function stringField2(value, key2) {
|
|
415174
|
-
return typeof value[key2] === "string" ? value[key2] : null;
|
|
415175
|
-
}
|
|
415176
|
-
function recordField(value, ...names2) {
|
|
415177
|
-
for (const name of names2) {
|
|
415178
|
-
const field = value[name];
|
|
415179
|
-
if (isRecord(field))
|
|
415180
|
-
return field;
|
|
415181
|
-
}
|
|
415182
|
-
return;
|
|
415183
|
-
}
|
|
415184
|
-
function parseServer(value, registered) {
|
|
415185
|
-
if (!isRecord(value))
|
|
415186
|
-
return null;
|
|
415187
|
-
const id2 = stringField2(value, "id");
|
|
415188
|
-
const serverName = stringField2(value, "server_name") ?? (registered ? stringField2(registered, "server_name") : null);
|
|
415189
|
-
const serverType = stringField2(value, "mcp_server_type") ?? (registered ? stringField2(registered, "mcp_server_type") : null) ?? "unknown";
|
|
415190
|
-
if (!id2 || !serverName)
|
|
415191
|
-
return null;
|
|
415192
|
-
const serverUrl = stringField2(value, "server_url") ?? (registered ? stringField2(registered, "server_url") : null) ?? undefined;
|
|
415193
|
-
const command = stringField2(value, "command") ?? (registered ? stringField2(registered, "command") : null) ?? undefined;
|
|
415194
|
-
const argsValue = value.args ?? registered?.args;
|
|
415195
|
-
const args = Array.isArray(argsValue) ? argsValue.filter((item) => typeof item === "string") : [];
|
|
415196
|
-
const target2 = serverUrl ?? [command, ...args].filter(Boolean).join(" ");
|
|
415197
|
-
return {
|
|
415198
|
-
id: id2,
|
|
415199
|
-
serverName,
|
|
415200
|
-
serverType,
|
|
415201
|
-
target: target2,
|
|
415202
|
-
...serverUrl ? { serverUrl } : {},
|
|
415203
|
-
...command ? { command, args } : {}
|
|
415204
|
-
};
|
|
415205
|
-
}
|
|
415206
|
-
function parseTool(value) {
|
|
415207
|
-
if (!isRecord(value))
|
|
415208
|
-
return null;
|
|
415209
|
-
const id2 = stringField2(value, "id");
|
|
415210
|
-
const name = stringField2(value, "name");
|
|
415211
|
-
if (!id2 || !name)
|
|
415212
|
-
return null;
|
|
415213
|
-
const description = stringField2(value, "description");
|
|
415214
|
-
const jsonSchema = isRecord(value.json_schema) ? value.json_schema : {};
|
|
415215
|
-
const inputSchema = isRecord(jsonSchema.parameters) ? jsonSchema.parameters : isRecord(value.args_json_schema) ? value.args_json_schema : { type: "object", properties: {} };
|
|
415216
|
-
const title = stringField2(value, "title") ?? stringField2(jsonSchema, "title");
|
|
415217
|
-
const outputSchema = recordField(value, "outputSchema", "output_schema") ?? recordField(jsonSchema, "outputSchema", "output_schema");
|
|
415218
|
-
const annotations = recordField(value, "annotations") ?? recordField(jsonSchema, "annotations");
|
|
415219
|
-
const execution = recordField(value, "execution") ?? recordField(jsonSchema, "execution");
|
|
415220
|
-
const meta = recordField(value, "_meta") ?? recordField(jsonSchema, "_meta");
|
|
415221
|
-
const iconsValue = value.icons ?? jsonSchema.icons;
|
|
415222
|
-
const icons = Array.isArray(iconsValue) ? iconsValue.filter(isRecord) : undefined;
|
|
415223
|
-
return {
|
|
415224
|
-
id: id2,
|
|
415225
|
-
name,
|
|
415226
|
-
...title ? { title } : {},
|
|
415227
|
-
description,
|
|
415228
|
-
inputSchema,
|
|
415229
|
-
...outputSchema ? { outputSchema } : {},
|
|
415230
|
-
...annotations ? { annotations } : {},
|
|
415231
|
-
...execution ? { execution } : {},
|
|
415232
|
-
...meta ? { _meta: meta } : {},
|
|
415233
|
-
...icons ? { icons } : {}
|
|
415234
|
-
};
|
|
415235
|
-
}
|
|
415236
|
-
function parseRunResult(value) {
|
|
415237
|
-
if (!isRecord(value))
|
|
415238
|
-
throw new Error("Invalid MCP tool run response");
|
|
415239
|
-
return {
|
|
415240
|
-
status: stringField2(value, "status") ?? "unknown",
|
|
415241
|
-
funcReturn: value.func_return,
|
|
415242
|
-
stdout: value.stdout,
|
|
415243
|
-
stderr: value.stderr
|
|
415244
|
-
};
|
|
415245
|
-
}
|
|
415246
|
-
function parseSearchResult(value) {
|
|
415247
|
-
if (!isRecord(value) || !isRecord(value.tool))
|
|
415248
|
-
return null;
|
|
415249
|
-
const toolId = stringField2(value.tool, "id");
|
|
415250
|
-
const jsonSchema = value.tool.json_schema;
|
|
415251
|
-
const score = value.combined_score;
|
|
415252
|
-
if (!toolId || jsonSchema !== null && !isRecord(jsonSchema) || typeof score !== "number") {
|
|
415253
|
-
return null;
|
|
415254
|
-
}
|
|
415255
|
-
return { toolId, jsonSchema, score };
|
|
415256
|
-
}
|
|
415257
|
-
async function withTimeout3(promise, timeoutMs, operation) {
|
|
415258
|
-
let timer;
|
|
415259
|
-
try {
|
|
415260
|
-
return await Promise.race([
|
|
415261
|
-
promise,
|
|
415262
|
-
new Promise((_resolve, reject2) => {
|
|
415263
|
-
timer = setTimeout(() => reject2(new Error(`${operation} timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
415264
|
-
})
|
|
415265
|
-
]);
|
|
415266
|
-
} finally {
|
|
415267
|
-
if (timer)
|
|
415268
|
-
clearTimeout(timer);
|
|
415269
|
-
}
|
|
415270
|
-
}
|
|
415271
|
-
async function listUnifiedMcpServers(client, agentId, timeoutMs = 1e4) {
|
|
415272
|
-
const value = await withTimeout3(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers`), timeoutMs, "Listing agent MCP servers");
|
|
415273
|
-
if (!Array.isArray(value))
|
|
415274
|
-
return [];
|
|
415275
|
-
const needsEnrichment = value.some((item) => isRecord(item) && !stringField2(item, "mcp_server_type"));
|
|
415276
|
-
const registeredById = new Map;
|
|
415277
|
-
if (needsEnrichment && client.mcpServers) {
|
|
415278
|
-
try {
|
|
415279
|
-
const registered = await withTimeout3(client.mcpServers.list(), timeoutMs, "Listing registered MCP servers");
|
|
415280
|
-
for (const item of registered) {
|
|
415281
|
-
if (!isRecord(item))
|
|
415282
|
-
continue;
|
|
415283
|
-
const id2 = stringField2(item, "id");
|
|
415284
|
-
if (id2)
|
|
415285
|
-
registeredById.set(id2, item);
|
|
415286
|
-
}
|
|
415287
|
-
} catch {}
|
|
415288
|
-
}
|
|
415289
|
-
return value.map((item) => {
|
|
415290
|
-
const registered = isRecord(item) ? registeredById.get(stringField2(item, "id") ?? "") : undefined;
|
|
415291
|
-
return parseServer(item, registered);
|
|
415292
|
-
}).filter((server2) => server2 !== null);
|
|
415293
|
-
}
|
|
415294
|
-
async function listUnifiedMcpTools(client, agentId, mcpServerId, timeoutMs = 1e4) {
|
|
415295
|
-
const value = await withTimeout3(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers/${encodeURIComponent(mcpServerId)}/tools`), timeoutMs, "Listing agent MCP server tools");
|
|
415296
|
-
if (!Array.isArray(value))
|
|
415297
|
-
return [];
|
|
415298
|
-
return value.map(parseTool).filter((tool) => tool !== null);
|
|
415299
|
-
}
|
|
415300
|
-
async function searchUnifiedMcpTools(params) {
|
|
415301
|
-
const value = await withTimeout3(params.client.post(`/v1/agents/${encodeURIComponent(params.agentId)}/mcp-servers/tools/search`, {
|
|
415302
|
-
body: {
|
|
415303
|
-
query: params.query,
|
|
415304
|
-
search_mode: params.searchMode,
|
|
415305
|
-
limit: params.limit
|
|
415306
|
-
}
|
|
415307
|
-
}), params.timeoutMs ?? 60000, "Searching agent MCP tools");
|
|
415308
|
-
if (!Array.isArray(value)) {
|
|
415309
|
-
throw new Error("Invalid MCP tool search response");
|
|
415310
|
-
}
|
|
415311
|
-
const results = [];
|
|
415312
|
-
for (const item of value) {
|
|
415313
|
-
const result2 = parseSearchResult(item);
|
|
415314
|
-
if (!result2)
|
|
415315
|
-
throw new Error("Invalid MCP tool search result");
|
|
415316
|
-
results.push(result2);
|
|
415317
|
-
}
|
|
415318
|
-
return results;
|
|
415319
|
-
}
|
|
415320
|
-
async function runUnifiedMcpTool(params) {
|
|
415321
|
-
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");
|
|
415322
|
-
return parseRunResult(value);
|
|
415323
|
-
}
|
|
415324
|
-
var init_unified_mcp = () => {};
|
|
415325
|
-
|
|
415326
415131
|
// node_modules/pkce-challenge/dist/index.node.js
|
|
415327
415132
|
async function getRandomValues(size2) {
|
|
415328
415133
|
return (await crypto2).getRandomValues(new Uint8Array(size2));
|
|
@@ -432165,7 +431970,7 @@ var init_mcp_client = __esm(() => {
|
|
|
432165
431970
|
init_streamableHttp();
|
|
432166
431971
|
DEFAULT_CLIENT_INFO = {
|
|
432167
431972
|
name: "letta-code",
|
|
432168
|
-
version: "0.31.
|
|
431973
|
+
version: "0.31.12"
|
|
432169
431974
|
};
|
|
432170
431975
|
});
|
|
432171
431976
|
|
|
@@ -432453,7 +432258,6 @@ async function replaceClientMcpServers(agentId, configs, options = {}) {
|
|
|
432453
432258
|
const generation2 = ++runtime.generation;
|
|
432454
432259
|
await closeActiveServers(runtime);
|
|
432455
432260
|
runtime.agentId = agentId;
|
|
432456
|
-
const usedToolNames = new Set;
|
|
432457
432261
|
const states2 = await Promise.all(configs.map(async (config2) => {
|
|
432458
432262
|
let oauth;
|
|
432459
432263
|
try {
|
|
@@ -432472,20 +432276,8 @@ async function replaceClientMcpServers(agentId, configs, options = {}) {
|
|
|
432472
432276
|
await connection.close();
|
|
432473
432277
|
return { config: config2, status: "failed", tools: [], error: "Superseded" };
|
|
432474
432278
|
}
|
|
432475
|
-
|
|
432476
|
-
|
|
432477
|
-
const definition = {
|
|
432478
|
-
name,
|
|
432479
|
-
label: tool.title ?? tool.name,
|
|
432480
|
-
description: tool.description ?? `Tool ${tool.name} from MCP server ${config2.name}`,
|
|
432481
|
-
parameters: tool.inputSchema,
|
|
432482
|
-
executor: async (_toolCallId, _toolName, input) => toExternalToolResult(await connection.callTool(tool.name, input))
|
|
432483
|
-
};
|
|
432484
|
-
return definition;
|
|
432485
|
-
});
|
|
432486
|
-
registerExternalTools(tools);
|
|
432487
|
-
runtime.active.set(config2.name, { connection, tools });
|
|
432488
|
-
return { config: config2, status: "connected", tools };
|
|
432279
|
+
runtime.active.set(config2.name, { connection });
|
|
432280
|
+
return { config: config2, status: "connected", tools: connection.tools };
|
|
432489
432281
|
} catch (error5) {
|
|
432490
432282
|
return {
|
|
432491
432283
|
config: config2,
|
|
@@ -432533,23 +432325,11 @@ async function closeActiveServers(runtime) {
|
|
|
432533
432325
|
runtime.pendingOAuth.clear();
|
|
432534
432326
|
runtime.active.clear();
|
|
432535
432327
|
runtime.states = [];
|
|
432536
|
-
for (const server2 of active)
|
|
432537
|
-
unregisterExternalTools(server2.tools);
|
|
432538
432328
|
await Promise.allSettled([
|
|
432539
432329
|
...pendingOAuth.map((oauth) => oauth.close()),
|
|
432540
432330
|
...active.map((server2) => server2.connection.close())
|
|
432541
432331
|
]);
|
|
432542
432332
|
}
|
|
432543
|
-
function uniqueToolName(base2, used) {
|
|
432544
|
-
let name = base2;
|
|
432545
|
-
let suffix = 2;
|
|
432546
|
-
while (used.has(name)) {
|
|
432547
|
-
name = `${base2}_${suffix}`;
|
|
432548
|
-
suffix++;
|
|
432549
|
-
}
|
|
432550
|
-
used.add(name);
|
|
432551
|
-
return name;
|
|
432552
|
-
}
|
|
432553
432333
|
function formatClientMcpToolName(serverName, toolName) {
|
|
432554
432334
|
return `mcp__${normalizeMcpName(serverName)}__${normalizeMcpName(toolName)}`;
|
|
432555
432335
|
}
|
|
@@ -432557,35 +432337,10 @@ function normalizeMcpName(value) {
|
|
|
432557
432337
|
const normalized = value.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
432558
432338
|
return normalized || "tool";
|
|
432559
432339
|
}
|
|
432560
|
-
function toExternalToolResult(result2) {
|
|
432561
|
-
return {
|
|
432562
|
-
content: result2.content.map((item) => normalizeContent2(item)),
|
|
432563
|
-
isError: result2.isError === true
|
|
432564
|
-
};
|
|
432565
|
-
}
|
|
432566
|
-
function normalizeContent2(item) {
|
|
432567
|
-
if (isRecord17(item)) {
|
|
432568
|
-
if (item.type === "text" && typeof item.text === "string") {
|
|
432569
|
-
return { type: "text", text: item.text };
|
|
432570
|
-
}
|
|
432571
|
-
if ((item.type === "image" || item.type === "audio") && typeof item.data === "string") {
|
|
432572
|
-
return {
|
|
432573
|
-
type: item.type,
|
|
432574
|
-
data: item.data,
|
|
432575
|
-
...typeof item.mimeType === "string" ? { mimeType: item.mimeType } : {}
|
|
432576
|
-
};
|
|
432577
|
-
}
|
|
432578
|
-
}
|
|
432579
|
-
return { type: "text", text: JSON.stringify(item) };
|
|
432580
|
-
}
|
|
432581
|
-
function isRecord17(value) {
|
|
432582
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
432583
|
-
}
|
|
432584
432340
|
var CLIENT_MCP_RUNTIME_KEY;
|
|
432585
|
-
var init_mcp_runtime = __esm(
|
|
432341
|
+
var init_mcp_runtime = __esm(() => {
|
|
432586
432342
|
init_mcp_client();
|
|
432587
432343
|
init_mcp_oauth();
|
|
432588
|
-
await init_manager4();
|
|
432589
432344
|
CLIENT_MCP_RUNTIME_KEY = Symbol.for("@letta/clientMcpRuntime");
|
|
432590
432345
|
});
|
|
432591
432346
|
|
|
@@ -432606,20 +432361,23 @@ function printMcpUsage(stdout) {
|
|
|
432606
432361
|
Usage:
|
|
432607
432362
|
letta mcp list [--agent <id>]
|
|
432608
432363
|
letta mcp get <server> [--agent <id>]
|
|
432609
|
-
letta mcp tools [server] [--agent <id>]
|
|
432364
|
+
letta mcp tools [server] [--full] [--agent <id>]
|
|
432365
|
+
letta mcp schema <tool-name> [--agent <id>]
|
|
432610
432366
|
letta mcp search <query> [--mode <hybrid|vector|fts>] [--limit <n>] [--agent <id>]
|
|
432611
432367
|
letta mcp call <tool-name> [--args '<json>' | --args-file <path|->] [--agent <id>]
|
|
432612
432368
|
|
|
432613
432369
|
Commands:
|
|
432614
432370
|
list List MCP servers available to the agent
|
|
432615
432371
|
get Print one server's redacted connection configuration
|
|
432616
|
-
tools
|
|
432372
|
+
tools List tool names and descriptions; names are accepted by call
|
|
432373
|
+
schema Print one tool's complete schema
|
|
432617
432374
|
search Search tools available to the agent
|
|
432618
432375
|
call Call one exact tool name and print an MCP CallToolResult
|
|
432619
432376
|
|
|
432620
432377
|
Options:
|
|
432621
432378
|
--agent <id> Agent ID. Defaults to LETTA_AGENT_ID or AGENT_ID
|
|
432622
432379
|
--agent-id <id> Alias for --agent
|
|
432380
|
+
--full Include complete schemas in tools output
|
|
432623
432381
|
--mode <mode> Search mode: hybrid (default), vector, or fts
|
|
432624
432382
|
--limit <n> Search result limit from 1 to 100 (default: 5)
|
|
432625
432383
|
--args <json> JSON object passed to a tool
|
|
@@ -432823,14 +432581,21 @@ function formatServerMcpToolName(serverName, alias, toolName) {
|
|
|
432823
432581
|
const rawName = toolName.startsWith(sourcePrefix) ? toolName.slice(sourcePrefix.length) : toolName;
|
|
432824
432582
|
return formatClientMcpToolName(alias, rawName);
|
|
432825
432583
|
}
|
|
432826
|
-
var init_mcp_tool_names = __esm(
|
|
432827
|
-
|
|
432584
|
+
var init_mcp_tool_names = __esm(() => {
|
|
432585
|
+
init_mcp_runtime();
|
|
432828
432586
|
});
|
|
432829
432587
|
|
|
432830
432588
|
// src/cli/subcommands/mcp.ts
|
|
432831
|
-
import { parseArgs as
|
|
432589
|
+
import { parseArgs as parseArgs10 } from "node:util";
|
|
432590
|
+
function defaultIsHostedLettaCloud() {
|
|
432591
|
+
try {
|
|
432592
|
+
return getServerUrl() === LETTA_CLOUD_API_URL;
|
|
432593
|
+
} catch {
|
|
432594
|
+
return !process.env.LETTA_BASE_URL;
|
|
432595
|
+
}
|
|
432596
|
+
}
|
|
432832
432597
|
function parseMcpArgs(argv) {
|
|
432833
|
-
return
|
|
432598
|
+
return parseArgs10({
|
|
432834
432599
|
args: argv,
|
|
432835
432600
|
options: {
|
|
432836
432601
|
help: { type: "boolean", short: "h" },
|
|
@@ -432838,6 +432603,7 @@ function parseMcpArgs(argv) {
|
|
|
432838
432603
|
"agent-id": { type: "string" },
|
|
432839
432604
|
mode: { type: "string" },
|
|
432840
432605
|
limit: { type: "string" },
|
|
432606
|
+
full: { type: "boolean" },
|
|
432841
432607
|
args: { type: "string" },
|
|
432842
432608
|
"args-file": { type: "string" }
|
|
432843
432609
|
},
|
|
@@ -432853,7 +432619,7 @@ function parseCommandLine(argv) {
|
|
|
432853
432619
|
}
|
|
432854
432620
|
return { action: action3, target: target2, values: parsed.values };
|
|
432855
432621
|
}
|
|
432856
|
-
function
|
|
432622
|
+
function stringValue4(value) {
|
|
432857
432623
|
return typeof value === "string" ? value : undefined;
|
|
432858
432624
|
}
|
|
432859
432625
|
function getLocalServers(deps, agentId) {
|
|
@@ -432892,9 +432658,8 @@ function redactUrl(value) {
|
|
|
432892
432658
|
const url2 = new URL(value);
|
|
432893
432659
|
url2.username = "";
|
|
432894
432660
|
url2.password = "";
|
|
432895
|
-
const sensitive = /token|key|secret|password|signature|credential/i;
|
|
432896
432661
|
for (const key2 of url2.searchParams.keys()) {
|
|
432897
|
-
if (
|
|
432662
|
+
if (SENSITIVE_NAME.test(key2))
|
|
432898
432663
|
url2.searchParams.set(key2, "[REDACTED]");
|
|
432899
432664
|
}
|
|
432900
432665
|
return url2.toString();
|
|
@@ -432902,6 +432667,32 @@ function redactUrl(value) {
|
|
|
432902
432667
|
return value;
|
|
432903
432668
|
}
|
|
432904
432669
|
}
|
|
432670
|
+
function redactArgs(args) {
|
|
432671
|
+
const redacted = [];
|
|
432672
|
+
let redactNext = false;
|
|
432673
|
+
for (const arg of args) {
|
|
432674
|
+
if (redactNext) {
|
|
432675
|
+
redacted.push("[REDACTED]");
|
|
432676
|
+
redactNext = false;
|
|
432677
|
+
continue;
|
|
432678
|
+
}
|
|
432679
|
+
if (arg.startsWith("-")) {
|
|
432680
|
+
const equalsIndex = arg.indexOf("=");
|
|
432681
|
+
const flagName = equalsIndex === -1 ? arg : arg.slice(0, equalsIndex);
|
|
432682
|
+
if (SENSITIVE_NAME.test(flagName)) {
|
|
432683
|
+
if (equalsIndex === -1) {
|
|
432684
|
+
redactNext = true;
|
|
432685
|
+
redacted.push(arg);
|
|
432686
|
+
} else {
|
|
432687
|
+
redacted.push(`${flagName}=[REDACTED]`);
|
|
432688
|
+
}
|
|
432689
|
+
continue;
|
|
432690
|
+
}
|
|
432691
|
+
}
|
|
432692
|
+
redacted.push(arg);
|
|
432693
|
+
}
|
|
432694
|
+
return redacted;
|
|
432695
|
+
}
|
|
432905
432696
|
function serverDetails(target2) {
|
|
432906
432697
|
if (target2.kind === "client") {
|
|
432907
432698
|
const config2 = target2.config;
|
|
@@ -432917,7 +432708,7 @@ function serverDetails(target2) {
|
|
|
432917
432708
|
name: config2.name,
|
|
432918
432709
|
transport: "stdio",
|
|
432919
432710
|
command: config2.command,
|
|
432920
|
-
args: config2.args ?? [],
|
|
432711
|
+
args: redactArgs(config2.args ?? []),
|
|
432921
432712
|
...config2.cwd ? { cwd: config2.cwd } : {},
|
|
432922
432713
|
env: redactValues(config2.env)
|
|
432923
432714
|
};
|
|
@@ -432931,7 +432722,7 @@ function serverDetails(target2) {
|
|
|
432931
432722
|
name: server2.serverName,
|
|
432932
432723
|
transport: "stdio",
|
|
432933
432724
|
command: server2.command ?? server2.target.split(" ")[0] ?? "",
|
|
432934
|
-
args: server2.args ?? [],
|
|
432725
|
+
args: redactArgs(server2.args ?? []),
|
|
432935
432726
|
env: {}
|
|
432936
432727
|
};
|
|
432937
432728
|
}
|
|
@@ -433021,7 +432812,10 @@ async function buildToolCatalog(deps, agentId, options = {}) {
|
|
|
433021
432812
|
const connections = [];
|
|
433022
432813
|
const usedNames = new Set;
|
|
433023
432814
|
try {
|
|
433024
|
-
const
|
|
432815
|
+
const hostedLettaCloud = (deps.isHostedLettaCloud ?? defaultIsHostedLettaCloud)();
|
|
432816
|
+
const allServerTargets = activeServers.filter((target2) => target2.kind === "server");
|
|
432817
|
+
const serverTargets = hostedLettaCloud ? allServerTargets.filter(({ server: server2 }) => server2.serverType !== "stdio") : allServerTargets;
|
|
432818
|
+
const excludedHostedStdioServers = serverTargets.length !== allServerTargets.length;
|
|
433025
432819
|
if (serverTargets.length > 0) {
|
|
433026
432820
|
const client = await getServerClient(deps);
|
|
433027
432821
|
const toolLists = await Promise.all(serverTargets.map(async ({ server: server2 }) => ({
|
|
@@ -433084,6 +432878,7 @@ async function buildToolCatalog(deps, agentId, options = {}) {
|
|
|
433084
432878
|
}
|
|
433085
432879
|
return {
|
|
433086
432880
|
tools: catalog,
|
|
432881
|
+
excludedHostedStdioServers,
|
|
433087
432882
|
close: async () => {
|
|
433088
432883
|
await Promise.allSettled(connections.map((connection) => connection.close()));
|
|
433089
432884
|
}
|
|
@@ -433126,12 +432921,12 @@ function mcpToolResultFromServer(result2) {
|
|
|
433126
432921
|
isError: !success || normalized.isError === true
|
|
433127
432922
|
};
|
|
433128
432923
|
}
|
|
433129
|
-
function
|
|
432924
|
+
function printJson(stdout, value) {
|
|
433130
432925
|
stdout(JSON.stringify(value, null, 2));
|
|
433131
432926
|
}
|
|
433132
432927
|
async function runList(deps, agentId, stdout) {
|
|
433133
432928
|
const servers = await listUnifiedServers(deps, agentId);
|
|
433134
|
-
|
|
432929
|
+
printJson(stdout, servers.map(serverSummary));
|
|
433135
432930
|
return 0;
|
|
433136
432931
|
}
|
|
433137
432932
|
async function runGet(deps, agentId, selector, stdout) {
|
|
@@ -433139,25 +432934,45 @@ async function runGet(deps, agentId, selector, stdout) {
|
|
|
433139
432934
|
throw new McpCliError("invalid_arguments", "Usage: letta mcp get <server>");
|
|
433140
432935
|
}
|
|
433141
432936
|
const server2 = resolveServer(await listUnifiedServers(deps, agentId), selector);
|
|
433142
|
-
|
|
432937
|
+
printJson(stdout, serverDetails(server2));
|
|
433143
432938
|
return 0;
|
|
433144
432939
|
}
|
|
433145
|
-
async function runTools(deps, agentId, serverSelector, stdout) {
|
|
432940
|
+
async function runTools(deps, agentId, serverSelector, full, stdout) {
|
|
433146
432941
|
const catalog = await buildToolCatalog(deps, agentId, { serverSelector });
|
|
433147
432942
|
try {
|
|
433148
|
-
|
|
432943
|
+
printJson(stdout, catalog.tools.map((tool) => full ? tool.schema : {
|
|
432944
|
+
name: tool.schema.name,
|
|
432945
|
+
...tool.schema.title ? { title: tool.schema.title } : {},
|
|
432946
|
+
...tool.schema.description ? { description: tool.schema.description } : {}
|
|
432947
|
+
}));
|
|
433149
432948
|
} finally {
|
|
433150
432949
|
await catalog.close();
|
|
433151
432950
|
}
|
|
433152
432951
|
return 0;
|
|
433153
432952
|
}
|
|
432953
|
+
async function runSchema(deps, agentId, toolName, stdout) {
|
|
432954
|
+
if (!toolName) {
|
|
432955
|
+
throw new McpCliError("invalid_arguments", "Usage: letta mcp schema <tool-name>");
|
|
432956
|
+
}
|
|
432957
|
+
const catalog = await buildToolCatalog(deps, agentId, { toolName });
|
|
432958
|
+
try {
|
|
432959
|
+
const tool = catalog.tools.find((candidate) => candidate.schema.name === toolName);
|
|
432960
|
+
if (!tool) {
|
|
432961
|
+
throw new McpCliError("tool_not_found", `MCP tool '${toolName}' is not available`);
|
|
432962
|
+
}
|
|
432963
|
+
printJson(stdout, tool.schema);
|
|
432964
|
+
return 0;
|
|
432965
|
+
} finally {
|
|
432966
|
+
await catalog.close();
|
|
432967
|
+
}
|
|
432968
|
+
}
|
|
433154
432969
|
async function runSearch(parsed, deps, agentId, stdout) {
|
|
433155
432970
|
const serverSearchAvailable = serverMcpAvailable(deps);
|
|
433156
432971
|
const hasClientLocalServers = getLocalServers(deps, agentId).length > 0;
|
|
433157
432972
|
return runMcpSearch({
|
|
433158
432973
|
query: parsed.target,
|
|
433159
|
-
mode:
|
|
433160
|
-
limit:
|
|
432974
|
+
mode: stringValue4(parsed.values.mode),
|
|
432975
|
+
limit: stringValue4(parsed.values.limit),
|
|
433161
432976
|
stdout,
|
|
433162
432977
|
searchTools: async (request) => {
|
|
433163
432978
|
if (!serverSearchAvailable) {
|
|
@@ -433190,15 +433005,20 @@ async function runSearch(parsed, deps, agentId, stdout) {
|
|
|
433190
433005
|
catalogPromise
|
|
433191
433006
|
]);
|
|
433192
433007
|
catalog = resolvedCatalog;
|
|
433193
|
-
const serverResults = searchResults.
|
|
433008
|
+
const serverResults = searchResults.flatMap((result2) => {
|
|
433194
433009
|
const callable = resolvedCatalog.tools.find((tool) => tool.target.kind === "server" && tool.target.toolId === result2.toolId);
|
|
433195
433010
|
if (!callable) {
|
|
433011
|
+
if (resolvedCatalog.excludedHostedStdioServers) {
|
|
433012
|
+
return [];
|
|
433013
|
+
}
|
|
433196
433014
|
throw new Error(`MCP search returned unavailable tool '${result2.toolId}'`);
|
|
433197
433015
|
}
|
|
433198
|
-
return
|
|
433199
|
-
|
|
433200
|
-
|
|
433201
|
-
|
|
433016
|
+
return [
|
|
433017
|
+
{
|
|
433018
|
+
tool: result2.jsonSchema === null ? null : { ...result2.jsonSchema, name: callable.schema.name },
|
|
433019
|
+
score: result2.score
|
|
433020
|
+
}
|
|
433021
|
+
];
|
|
433202
433022
|
});
|
|
433203
433023
|
if (!includeLocal)
|
|
433204
433024
|
return serverResults;
|
|
@@ -433221,7 +433041,7 @@ async function runCall(parsed, deps, agentId, stdout) {
|
|
|
433221
433041
|
if (!toolName) {
|
|
433222
433042
|
throw new McpCliError("invalid_arguments", "Usage: letta mcp call <tool-name> [--args '<json>']");
|
|
433223
433043
|
}
|
|
433224
|
-
const args = await loadMcpToolArgs(
|
|
433044
|
+
const args = await loadMcpToolArgs(stringValue4(parsed.values.args), stringValue4(parsed.values["args-file"]), deps);
|
|
433225
433045
|
const catalog = await buildToolCatalog(deps, agentId, { toolName });
|
|
433226
433046
|
try {
|
|
433227
433047
|
const tool = catalog.tools.find((candidate) => candidate.schema.name === toolName);
|
|
@@ -433235,7 +433055,7 @@ async function runCall(parsed, deps, agentId, stdout) {
|
|
|
433235
433055
|
toolId: tool.target.toolId,
|
|
433236
433056
|
args
|
|
433237
433057
|
}));
|
|
433238
|
-
|
|
433058
|
+
printJson(stdout, result2);
|
|
433239
433059
|
return result2.isError === true ? 2 : 0;
|
|
433240
433060
|
} finally {
|
|
433241
433061
|
await catalog.close();
|
|
@@ -433255,7 +433075,7 @@ async function runMcpSubcommand(argv, deps = {}) {
|
|
|
433255
433075
|
printMcpUsage(stdout);
|
|
433256
433076
|
return 0;
|
|
433257
433077
|
}
|
|
433258
|
-
const agentId = resolveMcpAgentId(
|
|
433078
|
+
const agentId = resolveMcpAgentId(stringValue4(parsed.values.agent), stringValue4(parsed.values["agent-id"]), deps.env ?? process.env);
|
|
433259
433079
|
if (!agentId) {
|
|
433260
433080
|
printMcpError(stderr, new McpCliError("agent_id_required", "No agent context found", "Pass --agent <agent-id> or set LETTA_AGENT_ID."));
|
|
433261
433081
|
return 1;
|
|
@@ -433270,7 +433090,9 @@ async function runMcpSubcommand(argv, deps = {}) {
|
|
|
433270
433090
|
case "tools":
|
|
433271
433091
|
case "list-tools":
|
|
433272
433092
|
case "list_tools":
|
|
433273
|
-
return await runTools(deps, agentId, parsed.target, stdout);
|
|
433093
|
+
return await runTools(deps, agentId, parsed.target, parsed.values.full === true, stdout);
|
|
433094
|
+
case "schema":
|
|
433095
|
+
return await runSchema(deps, agentId, parsed.target, stdout);
|
|
433274
433096
|
case "search":
|
|
433275
433097
|
return await runSearch(parsed, deps, agentId, stdout);
|
|
433276
433098
|
case "call":
|
|
@@ -433286,19 +433108,21 @@ async function runMcpSubcommand(argv, deps = {}) {
|
|
|
433286
433108
|
return 1;
|
|
433287
433109
|
}
|
|
433288
433110
|
}
|
|
433289
|
-
var
|
|
433111
|
+
var SENSITIVE_NAME;
|
|
433112
|
+
var init_mcp = __esm(() => {
|
|
433113
|
+
init_oauth();
|
|
433290
433114
|
init_backend2();
|
|
433291
433115
|
init_client2();
|
|
433116
|
+
init_server_url();
|
|
433292
433117
|
init_unified_mcp();
|
|
433293
433118
|
init_mcp_client();
|
|
433294
433119
|
init_mcp_oauth();
|
|
433120
|
+
init_mcp_runtime();
|
|
433295
433121
|
init_settings_manager();
|
|
433296
433122
|
init_mcp_io();
|
|
433297
433123
|
init_mcp_search();
|
|
433298
|
-
|
|
433299
|
-
|
|
433300
|
-
init_mcp_tool_names()
|
|
433301
|
-
]);
|
|
433124
|
+
init_mcp_tool_names();
|
|
433125
|
+
SENSITIVE_NAME = /token|key|secret|password|signature|credential|auth/i;
|
|
433302
433126
|
});
|
|
433303
433127
|
|
|
433304
433128
|
// src/cli/subcommands/memory-tokens.ts
|
|
@@ -433327,7 +433151,7 @@ function printText(total, files, top, quiet) {
|
|
|
433327
433151
|
console.log(` ${formatNumber(row.tokens).padStart(8)} ${row.path}`);
|
|
433328
433152
|
}
|
|
433329
433153
|
}
|
|
433330
|
-
function
|
|
433154
|
+
function printJson2(total, files) {
|
|
433331
433155
|
console.log(JSON.stringify({
|
|
433332
433156
|
total_tokens: total,
|
|
433333
433157
|
files
|
|
@@ -433368,7 +433192,7 @@ async function runMemoryTokensAction(options) {
|
|
|
433368
433192
|
}
|
|
433369
433193
|
const { total, files } = estimate;
|
|
433370
433194
|
if (format5 === "json") {
|
|
433371
|
-
|
|
433195
|
+
printJson2(total, files);
|
|
433372
433196
|
} else {
|
|
433373
433197
|
printText(total, files, top, options.quiet);
|
|
433374
433198
|
}
|
|
@@ -433383,8 +433207,8 @@ var init_memory_tokens = __esm(() => {
|
|
|
433383
433207
|
import { cpSync, existsSync as existsSync57, mkdirSync as mkdirSync39, rmSync as rmSync12, statSync as statSync19 } from "node:fs";
|
|
433384
433208
|
import { readdir as readdir12 } from "node:fs/promises";
|
|
433385
433209
|
import { dirname as dirname31, join as join72 } from "node:path";
|
|
433386
|
-
import { parseArgs as
|
|
433387
|
-
function
|
|
433210
|
+
import { parseArgs as parseArgs11 } from "node:util";
|
|
433211
|
+
function printUsage8() {
|
|
433388
433212
|
console.log(`
|
|
433389
433213
|
Usage:
|
|
433390
433214
|
letta memory status [--agent <id>]
|
|
@@ -433417,7 +433241,7 @@ function getAgentId3(agentFromArgs, agentIdFromArgs) {
|
|
|
433417
433241
|
return agentFromArgs || agentIdFromArgs || process.env.LETTA_AGENT_ID || "";
|
|
433418
433242
|
}
|
|
433419
433243
|
function parseMemoryArgs(argv) {
|
|
433420
|
-
return
|
|
433244
|
+
return parseArgs11({
|
|
433421
433245
|
args: argv,
|
|
433422
433246
|
options: MEMORY_OPTIONS,
|
|
433423
433247
|
strict: true,
|
|
@@ -433478,12 +433302,12 @@ async function runMemorySubcommand(argv) {
|
|
|
433478
433302
|
} catch (error5) {
|
|
433479
433303
|
const message = error5 instanceof Error ? error5.message : String(error5);
|
|
433480
433304
|
console.error(`Error: ${message}`);
|
|
433481
|
-
|
|
433305
|
+
printUsage8();
|
|
433482
433306
|
return 1;
|
|
433483
433307
|
}
|
|
433484
433308
|
const [action3] = parsed.positionals;
|
|
433485
433309
|
if (parsed.values.help || !action3 || action3 === "help") {
|
|
433486
|
-
|
|
433310
|
+
printUsage8();
|
|
433487
433311
|
return 0;
|
|
433488
433312
|
}
|
|
433489
433313
|
const agentId = getAgentId3(parsed.values.agent, parsed.values["agent-id"]);
|
|
@@ -433627,7 +433451,7 @@ async function runMemorySubcommand(argv) {
|
|
|
433627
433451
|
return 1;
|
|
433628
433452
|
}
|
|
433629
433453
|
console.error(`Unknown action: ${action3}`);
|
|
433630
|
-
|
|
433454
|
+
printUsage8();
|
|
433631
433455
|
return 1;
|
|
433632
433456
|
}
|
|
433633
433457
|
var MEMORY_OPTIONS;
|
|
@@ -433986,8 +433810,8 @@ var init_message_search = __esm(() => {
|
|
|
433986
433810
|
// src/cli/subcommands/messages.ts
|
|
433987
433811
|
import { writeFile as writeFile16 } from "node:fs/promises";
|
|
433988
433812
|
import { resolve as resolve35 } from "node:path";
|
|
433989
|
-
import { parseArgs as
|
|
433990
|
-
function
|
|
433813
|
+
import { parseArgs as parseArgs12 } from "node:util";
|
|
433814
|
+
function printUsage9() {
|
|
433991
433815
|
console.log(`
|
|
433992
433816
|
Usage:
|
|
433993
433817
|
letta messages search --query <text> [options]
|
|
@@ -434072,7 +433896,7 @@ function pageItems4(page) {
|
|
|
434072
433896
|
return [];
|
|
434073
433897
|
}
|
|
434074
433898
|
function parseMessagesArgs(argv) {
|
|
434075
|
-
return
|
|
433899
|
+
return parseArgs12({
|
|
434076
433900
|
args: argv,
|
|
434077
433901
|
options: MESSAGES_OPTIONS,
|
|
434078
433902
|
strict: true,
|
|
@@ -434086,12 +433910,12 @@ async function runMessagesSubcommand(argv, deps = {}) {
|
|
|
434086
433910
|
} catch (error5) {
|
|
434087
433911
|
const message = error5 instanceof Error ? error5.message : String(error5);
|
|
434088
433912
|
console.error(`Error: ${message}`);
|
|
434089
|
-
|
|
433913
|
+
printUsage9();
|
|
434090
433914
|
return 1;
|
|
434091
433915
|
}
|
|
434092
433916
|
const [action3] = parsed.positionals;
|
|
434093
433917
|
if (parsed.values.help || !action3 || action3 === "help") {
|
|
434094
|
-
|
|
433918
|
+
printUsage9();
|
|
434095
433919
|
return 0;
|
|
434096
433920
|
}
|
|
434097
433921
|
try {
|
|
@@ -434333,7 +434157,7 @@ async function runMessagesSubcommand(argv, deps = {}) {
|
|
|
434333
434157
|
return 1;
|
|
434334
434158
|
}
|
|
434335
434159
|
console.error(`Unknown action: ${action3}`);
|
|
434336
|
-
|
|
434160
|
+
printUsage9();
|
|
434337
434161
|
return 1;
|
|
434338
434162
|
}
|
|
434339
434163
|
var MESSAGES_OPTIONS;
|
|
@@ -434378,7 +434202,7 @@ import {
|
|
|
434378
434202
|
} from "node:fs";
|
|
434379
434203
|
import { tmpdir as tmpdir10 } from "node:os";
|
|
434380
434204
|
import path46 from "node:path";
|
|
434381
|
-
function
|
|
434205
|
+
function isRecord17(value) {
|
|
434382
434206
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
434383
434207
|
}
|
|
434384
434208
|
function isPathInsideOrEqual2(childPath, parentPath) {
|
|
@@ -434394,7 +434218,7 @@ function readPackageJson(packageJsonPath) {
|
|
|
434394
434218
|
} catch (error5) {
|
|
434395
434219
|
throw new Error(`Could not read package.json: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
434396
434220
|
}
|
|
434397
|
-
if (!
|
|
434221
|
+
if (!isRecord17(parsed)) {
|
|
434398
434222
|
throw new Error("package.json must be an object");
|
|
434399
434223
|
}
|
|
434400
434224
|
return parsed;
|
|
@@ -434404,7 +434228,7 @@ function formatRepository(repository) {
|
|
|
434404
434228
|
const trimmed2 = repository.trim();
|
|
434405
434229
|
return trimmed2 || undefined;
|
|
434406
434230
|
}
|
|
434407
|
-
if (!
|
|
434231
|
+
if (!isRecord17(repository))
|
|
434408
434232
|
return;
|
|
434409
434233
|
const url2 = repository.url;
|
|
434410
434234
|
if (typeof url2 !== "string")
|
|
@@ -434934,7 +434758,7 @@ function hasRuntimeDependencies(packageJson) {
|
|
|
434934
434758
|
if (!packageJson)
|
|
434935
434759
|
return false;
|
|
434936
434760
|
const dependencies4 = packageJson.dependencies;
|
|
434937
|
-
return
|
|
434761
|
+
return isRecord17(dependencies4) && Object.keys(dependencies4).length > 0;
|
|
434938
434762
|
}
|
|
434939
434763
|
function readPackageJsonIfExists(packageDirectory) {
|
|
434940
434764
|
const packageJsonPath = path46.join(packageDirectory, "package.json");
|
|
@@ -435363,8 +435187,8 @@ var init_package_scaffolder = __esm(() => {
|
|
|
435363
435187
|
|
|
435364
435188
|
// src/cli/subcommands/mods.ts
|
|
435365
435189
|
import { dirname as dirname32, join as join74 } from "node:path";
|
|
435366
|
-
import { parseArgs as
|
|
435367
|
-
function
|
|
435190
|
+
import { parseArgs as parseArgs13 } from "node:util";
|
|
435191
|
+
function printUsage10() {
|
|
435368
435192
|
console.log(`
|
|
435369
435193
|
Usage:
|
|
435370
435194
|
letta mods list [--agent <id>]
|
|
@@ -435381,7 +435205,7 @@ Options:
|
|
|
435381
435205
|
`.trim());
|
|
435382
435206
|
}
|
|
435383
435207
|
function parseModsArgs(argv) {
|
|
435384
|
-
return
|
|
435208
|
+
return parseArgs13({
|
|
435385
435209
|
args: argv,
|
|
435386
435210
|
options: MODS_OPTIONS,
|
|
435387
435211
|
strict: true,
|
|
@@ -435389,7 +435213,7 @@ function parseModsArgs(argv) {
|
|
|
435389
435213
|
});
|
|
435390
435214
|
}
|
|
435391
435215
|
function parseModsPackageArgs(argv) {
|
|
435392
|
-
return
|
|
435216
|
+
return parseArgs13({
|
|
435393
435217
|
args: argv,
|
|
435394
435218
|
options: MODS_PACKAGE_OPTIONS,
|
|
435395
435219
|
strict: true,
|
|
@@ -435487,16 +435311,16 @@ async function runList2(argv, options = {}) {
|
|
|
435487
435311
|
parsed = parseModsArgs(argv);
|
|
435488
435312
|
} catch (error5) {
|
|
435489
435313
|
console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
435490
|
-
|
|
435314
|
+
printUsage10();
|
|
435491
435315
|
return 1;
|
|
435492
435316
|
}
|
|
435493
435317
|
if (parsed.values.help) {
|
|
435494
|
-
|
|
435318
|
+
printUsage10();
|
|
435495
435319
|
return 0;
|
|
435496
435320
|
}
|
|
435497
435321
|
if (parsed.positionals.length > 0) {
|
|
435498
435322
|
console.error(`Unexpected argument: ${parsed.positionals[0]}`);
|
|
435499
|
-
|
|
435323
|
+
printUsage10();
|
|
435500
435324
|
return 1;
|
|
435501
435325
|
}
|
|
435502
435326
|
const agentId = getExplicitAgentId(parsed.values);
|
|
@@ -435513,27 +435337,27 @@ async function runPackageMutation(action3, argv, options = {}) {
|
|
|
435513
435337
|
parsed = parseModsArgs(argv);
|
|
435514
435338
|
} catch (error5) {
|
|
435515
435339
|
console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
435516
|
-
|
|
435340
|
+
printUsage10();
|
|
435517
435341
|
return 1;
|
|
435518
435342
|
}
|
|
435519
435343
|
if (parsed.values.help) {
|
|
435520
|
-
|
|
435344
|
+
printUsage10();
|
|
435521
435345
|
return 0;
|
|
435522
435346
|
}
|
|
435523
435347
|
if (getExplicitAgentId(parsed.values)) {
|
|
435524
435348
|
console.error(`--agent is only supported for 'letta mods list'.`);
|
|
435525
|
-
|
|
435349
|
+
printUsage10();
|
|
435526
435350
|
return 1;
|
|
435527
435351
|
}
|
|
435528
435352
|
const [specifier, extra] = parsed.positionals;
|
|
435529
435353
|
if (!specifier) {
|
|
435530
435354
|
console.error(`Missing package specifier.`);
|
|
435531
|
-
|
|
435355
|
+
printUsage10();
|
|
435532
435356
|
return 1;
|
|
435533
435357
|
}
|
|
435534
435358
|
if (extra) {
|
|
435535
435359
|
console.error(`Unexpected argument: ${extra}`);
|
|
435536
|
-
|
|
435360
|
+
printUsage10();
|
|
435537
435361
|
return 1;
|
|
435538
435362
|
}
|
|
435539
435363
|
try {
|
|
@@ -435559,27 +435383,27 @@ async function runPackageUpdate(argv, options = {}) {
|
|
|
435559
435383
|
parsed = parseModsArgs(argv);
|
|
435560
435384
|
} catch (error5) {
|
|
435561
435385
|
console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
435562
|
-
|
|
435386
|
+
printUsage10();
|
|
435563
435387
|
return 1;
|
|
435564
435388
|
}
|
|
435565
435389
|
if (parsed.values.help) {
|
|
435566
|
-
|
|
435390
|
+
printUsage10();
|
|
435567
435391
|
return 0;
|
|
435568
435392
|
}
|
|
435569
435393
|
if (getExplicitAgentId(parsed.values)) {
|
|
435570
435394
|
console.error(`--agent is not supported for 'letta mods update'.`);
|
|
435571
|
-
|
|
435395
|
+
printUsage10();
|
|
435572
435396
|
return 1;
|
|
435573
435397
|
}
|
|
435574
435398
|
const [specifier, extra] = parsed.positionals;
|
|
435575
435399
|
if (!specifier) {
|
|
435576
435400
|
console.error(`Missing package specifier.`);
|
|
435577
|
-
|
|
435401
|
+
printUsage10();
|
|
435578
435402
|
return 1;
|
|
435579
435403
|
}
|
|
435580
435404
|
if (extra) {
|
|
435581
435405
|
console.error(`Unexpected argument: ${extra}`);
|
|
435582
|
-
|
|
435406
|
+
printUsage10();
|
|
435583
435407
|
return 1;
|
|
435584
435408
|
}
|
|
435585
435409
|
try {
|
|
@@ -435601,33 +435425,33 @@ async function runPackageScaffold(argv) {
|
|
|
435601
435425
|
parsed = parseModsPackageArgs(argv);
|
|
435602
435426
|
} catch (error5) {
|
|
435603
435427
|
console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
435604
|
-
|
|
435428
|
+
printUsage10();
|
|
435605
435429
|
return 1;
|
|
435606
435430
|
}
|
|
435607
435431
|
if (parsed.values.help) {
|
|
435608
|
-
|
|
435432
|
+
printUsage10();
|
|
435609
435433
|
return 0;
|
|
435610
435434
|
}
|
|
435611
435435
|
if (getExplicitAgentId(parsed.values)) {
|
|
435612
435436
|
console.error(`--agent is not supported for 'letta mods package'.`);
|
|
435613
|
-
|
|
435437
|
+
printUsage10();
|
|
435614
435438
|
return 1;
|
|
435615
435439
|
}
|
|
435616
435440
|
const [sourceFile, extra] = parsed.positionals;
|
|
435617
435441
|
if (!sourceFile) {
|
|
435618
435442
|
console.error(`Missing mod file.`);
|
|
435619
|
-
|
|
435443
|
+
printUsage10();
|
|
435620
435444
|
return 1;
|
|
435621
435445
|
}
|
|
435622
435446
|
if (extra) {
|
|
435623
435447
|
console.error(`Unexpected argument: ${extra}`);
|
|
435624
|
-
|
|
435448
|
+
printUsage10();
|
|
435625
435449
|
return 1;
|
|
435626
435450
|
}
|
|
435627
435451
|
const packageName = parsed.values.name;
|
|
435628
435452
|
if (typeof packageName !== "string" || !packageName.trim()) {
|
|
435629
435453
|
console.error(`Missing required --name <package-name>.`);
|
|
435630
|
-
|
|
435454
|
+
printUsage10();
|
|
435631
435455
|
return 1;
|
|
435632
435456
|
}
|
|
435633
435457
|
try {
|
|
@@ -435649,7 +435473,7 @@ async function runPackageScaffold(argv) {
|
|
|
435649
435473
|
async function runModsSubcommand(argv, options = {}) {
|
|
435650
435474
|
const [action3, ...rest4] = argv;
|
|
435651
435475
|
if (!action3 || action3 === "help" || action3 === "--help" || action3 === "-h") {
|
|
435652
|
-
|
|
435476
|
+
printUsage10();
|
|
435653
435477
|
return 0;
|
|
435654
435478
|
}
|
|
435655
435479
|
switch (action3) {
|
|
@@ -435665,7 +435489,7 @@ async function runModsSubcommand(argv, options = {}) {
|
|
|
435665
435489
|
return runPackageMutation(action3, rest4, options);
|
|
435666
435490
|
default:
|
|
435667
435491
|
console.error(`Unknown mods action: ${action3}`);
|
|
435668
|
-
|
|
435492
|
+
printUsage10();
|
|
435669
435493
|
return 1;
|
|
435670
435494
|
}
|
|
435671
435495
|
}
|
|
@@ -435745,8 +435569,8 @@ var init_sandbox_files = __esm(() => {
|
|
|
435745
435569
|
// src/cli/subcommands/sandbox.ts
|
|
435746
435570
|
import { readFile as readFile24, stat as stat16, writeFile as writeFile17 } from "node:fs/promises";
|
|
435747
435571
|
import { basename as basename26, resolve as resolve36 } from "node:path";
|
|
435748
|
-
import { parseArgs as
|
|
435749
|
-
function
|
|
435572
|
+
import { parseArgs as parseArgs14 } from "node:util";
|
|
435573
|
+
function printUsage11() {
|
|
435750
435574
|
console.log(`
|
|
435751
435575
|
Usage:
|
|
435752
435576
|
letta sandbox upload <local-path>
|
|
@@ -435760,7 +435584,7 @@ Notes:
|
|
|
435760
435584
|
`.trim());
|
|
435761
435585
|
}
|
|
435762
435586
|
function parseSandboxArgs(argv) {
|
|
435763
|
-
return
|
|
435587
|
+
return parseArgs14({
|
|
435764
435588
|
args: argv,
|
|
435765
435589
|
options: SANDBOX_OPTIONS,
|
|
435766
435590
|
strict: true,
|
|
@@ -435800,17 +435624,17 @@ async function runSandboxSubcommand(argv, deps = {}) {
|
|
|
435800
435624
|
parsed = parseSandboxArgs(argv);
|
|
435801
435625
|
} catch (error5) {
|
|
435802
435626
|
console.error(`Error: ${error5 instanceof Error ? error5.message : error5}`);
|
|
435803
|
-
|
|
435627
|
+
printUsage11();
|
|
435804
435628
|
return 1;
|
|
435805
435629
|
}
|
|
435806
435630
|
const [action3, path48] = parsed.positionals;
|
|
435807
435631
|
if (parsed.values.help || !action3 || action3 === "help") {
|
|
435808
|
-
|
|
435632
|
+
printUsage11();
|
|
435809
435633
|
return 0;
|
|
435810
435634
|
}
|
|
435811
435635
|
if (action3 !== "upload" && action3 !== "download" || !path48) {
|
|
435812
435636
|
console.error("Error: expected upload or download with a file path");
|
|
435813
|
-
|
|
435637
|
+
printUsage11();
|
|
435814
435638
|
return 1;
|
|
435815
435639
|
}
|
|
435816
435640
|
try {
|
|
@@ -435854,8 +435678,8 @@ var init_sandbox2 = __esm(() => {
|
|
|
435854
435678
|
});
|
|
435855
435679
|
|
|
435856
435680
|
// src/cli/subcommands/secret.ts
|
|
435857
|
-
import { parseArgs as
|
|
435858
|
-
function
|
|
435681
|
+
import { parseArgs as parseArgs15 } from "node:util";
|
|
435682
|
+
function printUsage12() {
|
|
435859
435683
|
console.log(`
|
|
435860
435684
|
Usage:
|
|
435861
435685
|
letta secret set KEY --env SOURCE_VAR Set KEY from environment variable SOURCE_VAR
|
|
@@ -435880,7 +435704,7 @@ Notes:
|
|
|
435880
435704
|
`.trim());
|
|
435881
435705
|
}
|
|
435882
435706
|
function parseSecretArgs(argv) {
|
|
435883
|
-
return
|
|
435707
|
+
return parseArgs15({
|
|
435884
435708
|
args: argv,
|
|
435885
435709
|
options: SECRET_OPTIONS,
|
|
435886
435710
|
strict: true,
|
|
@@ -435915,11 +435739,11 @@ async function runSecretSubcommand(argv, deps = {}) {
|
|
|
435915
435739
|
parsed = parseSecretArgs(argv);
|
|
435916
435740
|
} catch (error5) {
|
|
435917
435741
|
printError(error5);
|
|
435918
|
-
|
|
435742
|
+
printUsage12();
|
|
435919
435743
|
return 1;
|
|
435920
435744
|
}
|
|
435921
435745
|
if (parsed.values.help || parsed.positionals.length === 0) {
|
|
435922
|
-
|
|
435746
|
+
printUsage12();
|
|
435923
435747
|
return parsed.values.help ? 0 : 1;
|
|
435924
435748
|
}
|
|
435925
435749
|
const [verb, rawKey, rawValue] = parsed.positionals;
|
|
@@ -435929,7 +435753,7 @@ async function runSecretSubcommand(argv, deps = {}) {
|
|
|
435929
435753
|
}
|
|
435930
435754
|
switch (verb) {
|
|
435931
435755
|
case "help": {
|
|
435932
|
-
|
|
435756
|
+
printUsage12();
|
|
435933
435757
|
return 0;
|
|
435934
435758
|
}
|
|
435935
435759
|
case "list": {
|
|
@@ -436037,7 +435861,7 @@ async function runSecretSubcommand(argv, deps = {}) {
|
|
|
436037
435861
|
}
|
|
436038
435862
|
default: {
|
|
436039
435863
|
console.error(`Unknown subcommand '${verb ?? ""}'.`);
|
|
436040
|
-
|
|
435864
|
+
printUsage12();
|
|
436041
435865
|
return 1;
|
|
436042
435866
|
}
|
|
436043
435867
|
}
|
|
@@ -436055,7 +435879,7 @@ var init_secret = __esm(() => {
|
|
|
436055
435879
|
});
|
|
436056
435880
|
|
|
436057
435881
|
// src/cli/subcommands/app-server.ts
|
|
436058
|
-
import { parseArgs as
|
|
435882
|
+
import { parseArgs as parseArgs16 } from "node:util";
|
|
436059
435883
|
function printAppServerHelp() {
|
|
436060
435884
|
console.log(`Usage: letta server --listen [url]
|
|
436061
435885
|
|
|
@@ -436103,7 +435927,7 @@ Stopped App Server (${signal}).`);
|
|
|
436103
435927
|
async function runAppServerSubcommand(argv) {
|
|
436104
435928
|
let parsed;
|
|
436105
435929
|
try {
|
|
436106
|
-
parsed =
|
|
435930
|
+
parsed = parseArgs16({
|
|
436107
435931
|
args: argv,
|
|
436108
435932
|
allowPositionals: false,
|
|
436109
435933
|
options: {
|
|
@@ -436172,10 +435996,10 @@ function printServerHelp() {
|
|
|
436172
435996
|
letta server [remote options]
|
|
436173
435997
|
letta server --listen [url] [App Server options]
|
|
436174
435998
|
|
|
436175
|
-
Run the local agent server as a remote
|
|
435999
|
+
Run the local agent server as a remote computer, with messaging channels, or as an App Server.
|
|
436176
436000
|
|
|
436177
|
-
Remote
|
|
436178
|
-
--
|
|
436001
|
+
Remote computer options:
|
|
436002
|
+
--computer-name <name> Friendly name for this computer (uses hostname if not provided)
|
|
436179
436003
|
--channels <list> Comma-separated channel names to enable (e.g. telegram)
|
|
436180
436004
|
--install-channel-runtimes Install missing runtime dependencies for selected channels
|
|
436181
436005
|
--debug Log WebSocket events instead of showing the interactive status UI
|
|
@@ -436196,7 +436020,7 @@ Common options:
|
|
|
436196
436020
|
|
|
436197
436021
|
Examples:
|
|
436198
436022
|
letta server
|
|
436199
|
-
letta server --
|
|
436023
|
+
letta server --computer-name "work-laptop"
|
|
436200
436024
|
letta server --channels telegram
|
|
436201
436025
|
letta server --listen
|
|
436202
436026
|
letta server --listen ws://127.0.0.1:4500
|
|
@@ -436235,7 +436059,7 @@ function resolveServerCommand(argv) {
|
|
|
436235
436059
|
}
|
|
436236
436060
|
}
|
|
436237
436061
|
if (foundListen) {
|
|
436238
|
-
const conflictingOption = argv.find((arg) => arg === "--env-name" || arg.startsWith("--env-name=") || arg === "--channels" || arg.startsWith("--channels="));
|
|
436062
|
+
const conflictingOption = argv.find((arg) => arg === "--computer-name" || arg.startsWith("--computer-name=") || arg === "--env-name" || arg.startsWith("--env-name=") || arg === "--channels" || arg.startsWith("--channels="));
|
|
436239
436063
|
if (conflictingOption) {
|
|
436240
436064
|
throw new Error(`${conflictingOption.split("=")[0]} cannot be used with --listen`);
|
|
436241
436065
|
}
|
|
@@ -436688,7 +436512,7 @@ var init_setup6 = __esm(async () => {
|
|
|
436688
436512
|
});
|
|
436689
436513
|
|
|
436690
436514
|
// src/cli/subcommands/setup.ts
|
|
436691
|
-
function
|
|
436515
|
+
function printUsage13() {
|
|
436692
436516
|
console.log(`
|
|
436693
436517
|
Usage:
|
|
436694
436518
|
letta setup
|
|
@@ -436699,12 +436523,12 @@ Re-run the interactive setup menu to choose local mode or sign in with Letta.
|
|
|
436699
436523
|
async function runSetupSubcommand(argv) {
|
|
436700
436524
|
const [arg, ...rest4] = argv;
|
|
436701
436525
|
if (arg === "help" || arg === "--help" || arg === "-h") {
|
|
436702
|
-
|
|
436526
|
+
printUsage13();
|
|
436703
436527
|
return 0;
|
|
436704
436528
|
}
|
|
436705
436529
|
if (arg || rest4.length > 0) {
|
|
436706
436530
|
console.error(`Unexpected arguments: ${[arg, ...rest4].filter(Boolean).join(" ")}`);
|
|
436707
|
-
|
|
436531
|
+
printUsage13();
|
|
436708
436532
|
return 1;
|
|
436709
436533
|
}
|
|
436710
436534
|
await settingsManager.initialize();
|
|
@@ -436719,8 +436543,8 @@ var init_setup7 = __esm(async () => {
|
|
|
436719
436543
|
// src/cli/subcommands/shared-memory.ts
|
|
436720
436544
|
import { existsSync as existsSync61 } from "node:fs";
|
|
436721
436545
|
import { join as join75 } from "node:path";
|
|
436722
|
-
import { parseArgs as
|
|
436723
|
-
function
|
|
436546
|
+
import { parseArgs as parseArgs17 } from "node:util";
|
|
436547
|
+
function printUsage14() {
|
|
436724
436548
|
console.log(`
|
|
436725
436549
|
Usage:
|
|
436726
436550
|
letta shared-memory list [--agent <id>]
|
|
@@ -436755,7 +436579,7 @@ Examples:
|
|
|
436755
436579
|
`.trim());
|
|
436756
436580
|
}
|
|
436757
436581
|
function parseSharedMemoryArgs(argv) {
|
|
436758
|
-
return
|
|
436582
|
+
return parseArgs17({
|
|
436759
436583
|
args: argv,
|
|
436760
436584
|
options: SHARED_MEMORY_OPTIONS,
|
|
436761
436585
|
strict: true,
|
|
@@ -436831,12 +436655,12 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
|
|
|
436831
436655
|
parsed = parseSharedMemoryArgs(argv);
|
|
436832
436656
|
} catch (error5) {
|
|
436833
436657
|
console.error(error5 instanceof Error ? error5.message : String(error5));
|
|
436834
|
-
|
|
436658
|
+
printUsage14();
|
|
436835
436659
|
return 1;
|
|
436836
436660
|
}
|
|
436837
436661
|
const [action3, reference] = parsed.positionals;
|
|
436838
436662
|
if (parsed.values.help || !action3 || action3 === "help") {
|
|
436839
|
-
|
|
436663
|
+
printUsage14();
|
|
436840
436664
|
return 0;
|
|
436841
436665
|
}
|
|
436842
436666
|
if (isLocalBackendEnvEnabled()) {
|
|
@@ -436941,7 +436765,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
|
|
|
436941
436765
|
return result2.failed > 0 ? 1 : 0;
|
|
436942
436766
|
}
|
|
436943
436767
|
console.error(`Unknown action: ${action3}`);
|
|
436944
|
-
|
|
436768
|
+
printUsage14();
|
|
436945
436769
|
return 1;
|
|
436946
436770
|
} catch (error5) {
|
|
436947
436771
|
console.error(error5 instanceof Error ? error5.message : String(error5));
|
|
@@ -438449,8 +438273,8 @@ import {
|
|
|
438449
438273
|
import { mkdir as mkdir14, readdir as readdir13 } from "node:fs/promises";
|
|
438450
438274
|
import { tmpdir as tmpdir11 } from "node:os";
|
|
438451
438275
|
import { basename as basename27, dirname as dirname33, join as join76, normalize as normalize5, resolve as resolve37, sep as sep8 } from "node:path";
|
|
438452
|
-
import { parseArgs as
|
|
438453
|
-
function
|
|
438276
|
+
import { parseArgs as parseArgs18, TextDecoder as TextDecoder2, TextEncoder as TextEncoder2 } from "node:util";
|
|
438277
|
+
function printUsage15() {
|
|
438454
438278
|
console.log(`
|
|
438455
438279
|
Usage:
|
|
438456
438280
|
letta install <thing> [--agent <id> | -n <agent name>] [--force]
|
|
@@ -438477,7 +438301,7 @@ Options:
|
|
|
438477
438301
|
`.trim());
|
|
438478
438302
|
}
|
|
438479
438303
|
function parseSkillsArgs(argv) {
|
|
438480
|
-
return
|
|
438304
|
+
return parseArgs18({
|
|
438481
438305
|
args: argv,
|
|
438482
438306
|
options: SKILLS_OPTIONS,
|
|
438483
438307
|
strict: true,
|
|
@@ -439125,17 +438949,17 @@ async function runInstall(argv, options = {}) {
|
|
|
439125
438949
|
parsed = parseSkillsArgs(argv);
|
|
439126
438950
|
} catch (error5) {
|
|
439127
438951
|
console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
439128
|
-
|
|
438952
|
+
printUsage15();
|
|
439129
438953
|
return 1;
|
|
439130
438954
|
}
|
|
439131
438955
|
const [specifier] = parsed.positionals;
|
|
439132
438956
|
if (parsed.values.help || !specifier || specifier === "help") {
|
|
439133
|
-
|
|
438957
|
+
printUsage15();
|
|
439134
438958
|
return 0;
|
|
439135
438959
|
}
|
|
439136
438960
|
if (parsed.positionals.length > 1) {
|
|
439137
438961
|
console.error(`Unexpected argument: ${parsed.positionals[1]}`);
|
|
439138
|
-
|
|
438962
|
+
printUsage15();
|
|
439139
438963
|
return 1;
|
|
439140
438964
|
}
|
|
439141
438965
|
if (specifier.startsWith("npm:")) {
|
|
@@ -439226,16 +439050,16 @@ async function runList3(argv) {
|
|
|
439226
439050
|
parsed = parseSkillsArgs(argv);
|
|
439227
439051
|
} catch (error5) {
|
|
439228
439052
|
console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
439229
|
-
|
|
439053
|
+
printUsage15();
|
|
439230
439054
|
return 1;
|
|
439231
439055
|
}
|
|
439232
439056
|
if (parsed.values.help) {
|
|
439233
|
-
|
|
439057
|
+
printUsage15();
|
|
439234
439058
|
return 0;
|
|
439235
439059
|
}
|
|
439236
439060
|
if (parsed.positionals.length > 0) {
|
|
439237
439061
|
console.error(`Unexpected argument: ${parsed.positionals[0]}`);
|
|
439238
|
-
|
|
439062
|
+
printUsage15();
|
|
439239
439063
|
return 1;
|
|
439240
439064
|
}
|
|
439241
439065
|
try {
|
|
@@ -439256,17 +439080,17 @@ async function runDelete(argv) {
|
|
|
439256
439080
|
parsed = parseSkillsArgs(argv);
|
|
439257
439081
|
} catch (error5) {
|
|
439258
439082
|
console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
439259
|
-
|
|
439083
|
+
printUsage15();
|
|
439260
439084
|
return 1;
|
|
439261
439085
|
}
|
|
439262
439086
|
const [skillName] = parsed.positionals;
|
|
439263
439087
|
if (parsed.values.help || !skillName || skillName === "help") {
|
|
439264
|
-
|
|
439088
|
+
printUsage15();
|
|
439265
439089
|
return 0;
|
|
439266
439090
|
}
|
|
439267
439091
|
if (parsed.positionals.length > 1) {
|
|
439268
439092
|
console.error(`Unexpected argument: ${parsed.positionals[1]}`);
|
|
439269
|
-
|
|
439093
|
+
printUsage15();
|
|
439270
439094
|
return 1;
|
|
439271
439095
|
}
|
|
439272
439096
|
const agentId = getExplicitAgentId2(parsed.values);
|
|
@@ -439306,11 +439130,11 @@ async function runSkillsSubcommand(argv) {
|
|
|
439306
439130
|
case "help":
|
|
439307
439131
|
case "--help":
|
|
439308
439132
|
case "-h":
|
|
439309
|
-
|
|
439133
|
+
printUsage15();
|
|
439310
439134
|
return 0;
|
|
439311
439135
|
default:
|
|
439312
439136
|
console.error(`Unknown action: ${action3}`);
|
|
439313
|
-
|
|
439137
|
+
printUsage15();
|
|
439314
439138
|
return 1;
|
|
439315
439139
|
}
|
|
439316
439140
|
}
|
|
@@ -439329,31 +439153,31 @@ var init_skills4 = __esm(() => {
|
|
|
439329
439153
|
});
|
|
439330
439154
|
|
|
439331
439155
|
// src/cli/subcommands/teleport.ts
|
|
439332
|
-
import { parseArgs as
|
|
439333
|
-
function
|
|
439156
|
+
import { parseArgs as parseArgs19 } from "node:util";
|
|
439157
|
+
function printUsage16() {
|
|
439334
439158
|
console.log(`
|
|
439335
439159
|
Usage:
|
|
439336
439160
|
letta teleport list
|
|
439337
439161
|
letta teleport cloud
|
|
439338
439162
|
letta teleport local
|
|
439339
|
-
letta teleport <
|
|
439163
|
+
letta teleport <computer>
|
|
439340
439164
|
|
|
439341
439165
|
Notes:
|
|
439342
439166
|
- Operates on the current agent/conversation from LETTA_AGENT_ID /
|
|
439343
439167
|
LETTA_CONVERSATION_ID (or AGENT_ID / CONVERSATION_ID), falling back to the
|
|
439344
439168
|
last active session.
|
|
439345
439169
|
- Requires a Letta Cloud agent and an active conversation.
|
|
439346
|
-
- list: prints accessible online remote
|
|
439170
|
+
- list: prints accessible online remote computers as JSON.
|
|
439347
439171
|
- cloud: teleports to the agent's Cloud sandbox.
|
|
439348
|
-
- local: teleports to the one online Desktop
|
|
439172
|
+
- local: teleports to the one online Desktop computer. Desktop Remote
|
|
439349
439173
|
Access must be enabled; if several are online, choose one explicitly.
|
|
439350
|
-
- <
|
|
439351
|
-
device-id, connection-id, or
|
|
439174
|
+
- <computer>: teleports to a specific remote computer by name,
|
|
439175
|
+
device-id, connection-id, or computer id.
|
|
439352
439176
|
- Output is JSON only.
|
|
439353
439177
|
`.trim());
|
|
439354
439178
|
}
|
|
439355
439179
|
function parseTeleportArgs(argv) {
|
|
439356
|
-
return
|
|
439180
|
+
return parseArgs19({
|
|
439357
439181
|
args: argv,
|
|
439358
439182
|
options: TELEPORT_OPTIONS,
|
|
439359
439183
|
strict: true,
|
|
@@ -439413,7 +439237,7 @@ function isTeleportableRemoteEnvironment(environment2) {
|
|
|
439413
439237
|
}
|
|
439414
439238
|
function assertTeleportableRemoteEnvironment(environment2) {
|
|
439415
439239
|
if (!isTeleportableRemoteEnvironment(environment2)) {
|
|
439416
|
-
throw new Error("The Desktop-local connection is not Cloud-routable. Use `letta teleport local` to resolve its Remote Access
|
|
439240
|
+
throw new Error("The Desktop-local connection is not Cloud-routable. Use `letta teleport local` to resolve its Remote Access computer.");
|
|
439417
439241
|
}
|
|
439418
439242
|
}
|
|
439419
439243
|
async function initializeTeleportSettings() {
|
|
@@ -439426,12 +439250,12 @@ async function runTeleportSubcommand(argv, deps = {}) {
|
|
|
439426
439250
|
parsed = parseTeleportArgs(argv);
|
|
439427
439251
|
} catch (error5) {
|
|
439428
439252
|
console.error(`Error: ${error5 instanceof Error ? error5.message : error5}`);
|
|
439429
|
-
|
|
439253
|
+
printUsage16();
|
|
439430
439254
|
return 1;
|
|
439431
439255
|
}
|
|
439432
439256
|
const [action3] = parsed.positionals;
|
|
439433
439257
|
if (parsed.values.help || !action3 || action3 === "help") {
|
|
439434
|
-
|
|
439258
|
+
printUsage16();
|
|
439435
439259
|
return 0;
|
|
439436
439260
|
}
|
|
439437
439261
|
try {
|
|
@@ -439456,7 +439280,7 @@ async function runTeleportSubcommand(argv, deps = {}) {
|
|
|
439456
439280
|
const result3 = await resolve38();
|
|
439457
439281
|
targetConnectionId = result3.connectionId;
|
|
439458
439282
|
} else if (action3 === "back") {
|
|
439459
|
-
throw new Error("Teleport back is not supported. Use `letta teleport local` or choose an explicit
|
|
439283
|
+
throw new Error("Teleport back is not supported. Use `letta teleport local` or choose an explicit computer.");
|
|
439460
439284
|
} else {
|
|
439461
439285
|
const resolve38 = deps.resolveEnvironmentConnectionId ?? resolveEnvironmentConnectionId;
|
|
439462
439286
|
const resolved = await resolve38(action3);
|
|
@@ -439867,8 +439691,8 @@ var init_review = () => {};
|
|
|
439867
439691
|
|
|
439868
439692
|
// src/cli/subcommands/trajectories.ts
|
|
439869
439693
|
import { readFile as readFile28 } from "node:fs/promises";
|
|
439870
|
-
import { parseArgs as
|
|
439871
|
-
function
|
|
439694
|
+
import { parseArgs as parseArgs20 } from "node:util";
|
|
439695
|
+
function printUsage17() {
|
|
439872
439696
|
console.log(`
|
|
439873
439697
|
Usage:
|
|
439874
439698
|
letta trajectories export [options]
|
|
@@ -440006,7 +439830,7 @@ ${results.length} session(s) matched "${keyword}"`);
|
|
|
440006
439830
|
return 0;
|
|
440007
439831
|
}
|
|
440008
439832
|
function parseTrajectoriesArgs(argv) {
|
|
440009
|
-
return
|
|
439833
|
+
return parseArgs20({
|
|
440010
439834
|
args: argv,
|
|
440011
439835
|
options: TRAJECTORIES_OPTIONS,
|
|
440012
439836
|
strict: true,
|
|
@@ -440019,12 +439843,12 @@ async function runTrajectoriesSubcommand(argv) {
|
|
|
440019
439843
|
parsed = parseTrajectoriesArgs(argv);
|
|
440020
439844
|
} catch (error5) {
|
|
440021
439845
|
console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
440022
|
-
|
|
439846
|
+
printUsage17();
|
|
440023
439847
|
return 1;
|
|
440024
439848
|
}
|
|
440025
439849
|
const [action3] = parsed.positionals;
|
|
440026
439850
|
if (parsed.values.help || action3 === "help" || !action3) {
|
|
440027
|
-
|
|
439851
|
+
printUsage17();
|
|
440028
439852
|
return parsed.values.help || action3 === "help" ? 0 : 1;
|
|
440029
439853
|
}
|
|
440030
439854
|
const asJson = Boolean(parsed.values.json);
|
|
@@ -440056,7 +439880,7 @@ async function runTrajectoriesSubcommand(argv) {
|
|
|
440056
439880
|
}
|
|
440057
439881
|
if (action3 !== "export") {
|
|
440058
439882
|
console.error(`Unknown command: ${action3}`);
|
|
440059
|
-
|
|
439883
|
+
printUsage17();
|
|
440060
439884
|
return 1;
|
|
440061
439885
|
}
|
|
440062
439886
|
const options = {
|
|
@@ -441605,9 +441429,9 @@ class ChannelRichDraftStreamerImpl {
|
|
|
441605
441429
|
return;
|
|
441606
441430
|
}
|
|
441607
441431
|
const record5 = asRecord10(chunk2);
|
|
441608
|
-
const messageType =
|
|
441432
|
+
const messageType = stringValue5(record5?.message_type);
|
|
441609
441433
|
if (messageType === "tool_return_message") {
|
|
441610
|
-
const toolCallId =
|
|
441434
|
+
const toolCallId = stringValue5(record5?.tool_call_id);
|
|
441611
441435
|
if (toolCallId) {
|
|
441612
441436
|
this.finishCall(toolCallId);
|
|
441613
441437
|
}
|
|
@@ -441900,14 +441724,14 @@ function extractToolCallFragments2(record5) {
|
|
|
441900
441724
|
const fragments = [];
|
|
441901
441725
|
for (const rawToolCall of rawToolCalls) {
|
|
441902
441726
|
const toolCall = asRecord10(rawToolCall);
|
|
441903
|
-
const toolCallId =
|
|
441727
|
+
const toolCallId = stringValue5(toolCall?.tool_call_id);
|
|
441904
441728
|
if (!toolCallId) {
|
|
441905
441729
|
continue;
|
|
441906
441730
|
}
|
|
441907
441731
|
fragments.push({
|
|
441908
441732
|
toolCallId,
|
|
441909
|
-
name:
|
|
441910
|
-
argumentsDelta:
|
|
441733
|
+
name: stringValue5(toolCall?.name),
|
|
441734
|
+
argumentsDelta: stringValue5(toolCall?.arguments)
|
|
441911
441735
|
});
|
|
441912
441736
|
}
|
|
441913
441737
|
return fragments;
|
|
@@ -442027,7 +441851,7 @@ function buildDraftId(seed) {
|
|
|
442027
441851
|
function asRecord10(value) {
|
|
442028
441852
|
return value && typeof value === "object" ? value : null;
|
|
442029
441853
|
}
|
|
442030
|
-
function
|
|
441854
|
+
function stringValue5(value) {
|
|
442031
441855
|
return typeof value === "string" ? value : undefined;
|
|
442032
441856
|
}
|
|
442033
441857
|
var MESSAGE_CHANNEL_TOOL_NAMES, DEFAULT_DRAFT_DEBOUNCE_MS = 1000, MIN_DRAFT_TEXT_LENGTH = 1;
|
|
@@ -444895,14 +444719,14 @@ var exports_channel_gateway = {};
|
|
|
444895
444719
|
__export(exports_channel_gateway, {
|
|
444896
444720
|
runChannelGatewaySubcommand: () => runChannelGatewaySubcommand
|
|
444897
444721
|
});
|
|
444898
|
-
import { parseArgs as
|
|
444722
|
+
import { parseArgs as parseArgs21 } from "node:util";
|
|
444899
444723
|
function isGatewayCommandEnvelope(value) {
|
|
444900
444724
|
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");
|
|
444901
444725
|
}
|
|
444902
444726
|
async function runChannelGatewaySubcommand(argv) {
|
|
444903
444727
|
let values3;
|
|
444904
444728
|
try {
|
|
444905
|
-
({ values: values3 } =
|
|
444729
|
+
({ values: values3 } = parseArgs21({
|
|
444906
444730
|
args: argv,
|
|
444907
444731
|
strict: true,
|
|
444908
444732
|
allowPositionals: false,
|
|
@@ -445029,6 +444853,7 @@ function subcommandNeedsEarlyBackendMode(command) {
|
|
|
445029
444853
|
case "channel-gateway":
|
|
445030
444854
|
case "agents":
|
|
445031
444855
|
case "connect":
|
|
444856
|
+
case "computers":
|
|
445032
444857
|
case "environments":
|
|
445033
444858
|
case "envs":
|
|
445034
444859
|
case "feedback":
|
|
@@ -445042,7 +444867,6 @@ function subcommandNeedsEarlyBackendMode(command) {
|
|
|
445042
444867
|
case "sandbox":
|
|
445043
444868
|
case "secret":
|
|
445044
444869
|
case "server":
|
|
445045
|
-
case "cloud-mcp":
|
|
445046
444870
|
case "shared-memory":
|
|
445047
444871
|
case "skills":
|
|
445048
444872
|
case "teleport":
|
|
@@ -445074,6 +444898,7 @@ async function runSubcommand(argv) {
|
|
|
445074
444898
|
return runMessagesSubcommand(rest4);
|
|
445075
444899
|
case "mcp":
|
|
445076
444900
|
return runMcpSubcommand(rest4);
|
|
444901
|
+
case "computers":
|
|
445077
444902
|
case "environments":
|
|
445078
444903
|
case "envs":
|
|
445079
444904
|
return runEnvironmentsSubcommand(rest4);
|
|
@@ -445087,8 +444912,6 @@ async function runSubcommand(argv) {
|
|
|
445087
444912
|
return runTeleportSubcommand(rest4);
|
|
445088
444913
|
case "server":
|
|
445089
444914
|
return runServerSubcommand(rest4);
|
|
445090
|
-
case "cloud-mcp":
|
|
445091
|
-
return runCloudMcpSubcommand(rest4);
|
|
445092
444915
|
case "feedback":
|
|
445093
444916
|
return runFeedbackSubcommand(rest4);
|
|
445094
444917
|
case "remote":
|
|
@@ -445126,11 +444949,11 @@ var init_router = __esm(async () => {
|
|
|
445126
444949
|
init_agents6();
|
|
445127
444950
|
init_backend3();
|
|
445128
444951
|
init_channels();
|
|
445129
|
-
init_cloud_mcp();
|
|
445130
444952
|
init_connect();
|
|
445131
444953
|
init_environments3();
|
|
445132
444954
|
init_feedback3();
|
|
445133
444955
|
init_local_backend2();
|
|
444956
|
+
init_mcp();
|
|
445134
444957
|
init_memory7();
|
|
445135
444958
|
init_messages10();
|
|
445136
444959
|
init_sandbox2();
|
|
@@ -445142,7 +444965,6 @@ var init_router = __esm(async () => {
|
|
|
445142
444965
|
await __promiseAll([
|
|
445143
444966
|
init_cron2(),
|
|
445144
444967
|
init_listen(),
|
|
445145
|
-
init_mcp(),
|
|
445146
444968
|
init_mods(),
|
|
445147
444969
|
init_server(),
|
|
445148
444970
|
init_setup7()
|
|
@@ -447304,7 +447126,7 @@ function getEnvironmentRoutedMessagingUnsupportedReason(environment2) {
|
|
|
447304
447126
|
if (environment2.metadata?.environmentMessageProtocol === "v2-input") {
|
|
447305
447127
|
return null;
|
|
447306
447128
|
}
|
|
447307
|
-
return `
|
|
447129
|
+
return `Computer ${environment2.connectionName} (${environment2.deviceId}) is running Letta Code ${environment2.metadata?.lettaCodeVersion ?? "unknown"} and does not advertise computer-routed headless messaging support. Update that runtime or omit --computer to use same-computer messaging.`;
|
|
447308
447130
|
}
|
|
447309
447131
|
async function handleHeadlessCommand(parsedArgs, model, skillsDirectoryOverride, skillSourcesOverride, systemInfoReminderEnabledOverride, startupOptions = {}) {
|
|
447310
447132
|
const { values: values3, positionals } = parsedArgs;
|
|
@@ -447377,7 +447199,7 @@ In headless mode, use:
|
|
|
447377
447199
|
}
|
|
447378
447200
|
let forceNewConversation = values3.new ?? false;
|
|
447379
447201
|
const fromAgentId = values3["from-agent"];
|
|
447380
|
-
const explicitEnvironmentSelector = values3.environment
|
|
447202
|
+
const explicitEnvironmentSelector = values3.computer ?? values3.environment ?? values3.env;
|
|
447381
447203
|
const usesRemoteEnvironment = typeof explicitEnvironmentSelector === "string" && explicitEnvironmentSelector.trim().length > 0;
|
|
447382
447204
|
let agent = null;
|
|
447383
447205
|
let ephemeralConversationId = null;
|
|
@@ -447745,9 +447567,6 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
|
|
|
447745
447567
|
markMilestone("HEADLESS_AGENT_RESOLVED");
|
|
447746
447568
|
const publicAgentId = ephemeralFlag ? null : agent.id;
|
|
447747
447569
|
telemetry.setCurrentAgent(publicAgentId, agent.tags);
|
|
447748
|
-
if (!ephemeralFlag) {
|
|
447749
|
-
await replaceClientMcpServers(agent.id, settingsManager.getMcpServers(agent.id), { stderr: "pipe" });
|
|
447750
|
-
}
|
|
447751
447570
|
const isResumingAgent = !ephemeralFlag && !!(specifiedAgentId || !forceNew && !fromAfFile);
|
|
447752
447571
|
if (isResumingAgent) {
|
|
447753
447572
|
if (model) {
|
|
@@ -447936,7 +447755,7 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
|
|
|
447936
447755
|
process.exit(1);
|
|
447937
447756
|
}
|
|
447938
447757
|
if (usesRemoteEnvironment && isBidirectionalMode) {
|
|
447939
|
-
console.error("Error: remote
|
|
447758
|
+
console.error("Error: remote computer routing cannot be used with --input-format stream-json");
|
|
447940
447759
|
process.exit(1);
|
|
447941
447760
|
}
|
|
447942
447761
|
const sessionStats = new SessionStats;
|
|
@@ -448373,6 +448192,7 @@ ${loadedContents.join(`
|
|
|
448373
448192
|
let emptyResponseRetries = 0;
|
|
448374
448193
|
let conversationBusyRetries = 0;
|
|
448375
448194
|
let chatgptPlanSwaps = 0;
|
|
448195
|
+
const chatgptExhaustedProviders = new Set;
|
|
448376
448196
|
markMilestone("HEADLESS_FIRST_STREAM_START");
|
|
448377
448197
|
measureSinceMilestone("headless-setup-total", "HEADLESS_CLIENT_READY");
|
|
448378
448198
|
const checkMaxTurns = async () => {
|
|
@@ -448640,6 +448460,7 @@ ${loadedContents.join(`
|
|
|
448640
448460
|
emptyResponseRetries = 0;
|
|
448641
448461
|
conversationBusyRetries = 0;
|
|
448642
448462
|
chatgptPlanSwaps = 0;
|
|
448463
|
+
chatgptExhaustedProviders.clear();
|
|
448643
448464
|
const continueMessage = await emitHeadlessTurnEnd({
|
|
448644
448465
|
agent,
|
|
448645
448466
|
conversationId,
|
|
@@ -448743,8 +448564,10 @@ ${loadedContents.join(`
|
|
|
448743
448564
|
if (chatgptPlanSwaps < CHATGPT_PLAN_ROTATION_MAX_SWAPS_PER_TURN) {
|
|
448744
448565
|
const rotation = await rotateChatGPTPlanOnQuotaLimit({
|
|
448745
448566
|
agentId: agent.id,
|
|
448567
|
+
conversationId,
|
|
448746
448568
|
currentHandle: null,
|
|
448747
|
-
error: runErrorInfo2 ?? detailFromRun ?? latestErrorText
|
|
448569
|
+
error: runErrorInfo2 ?? detailFromRun ?? latestErrorText,
|
|
448570
|
+
exhaustedProviders: chatgptExhaustedProviders
|
|
448748
448571
|
});
|
|
448749
448572
|
if (rotation) {
|
|
448750
448573
|
chatgptPlanSwaps += 1;
|
|
@@ -450160,6 +449983,7 @@ var init_headless = __esm(async () => {
|
|
|
450160
449983
|
init_headless_environment_response();
|
|
450161
449984
|
init_headless_reflection_settings();
|
|
450162
449985
|
init_diff_preview();
|
|
449986
|
+
init_mcp_runtime();
|
|
450163
449987
|
init_format_denial();
|
|
450164
449988
|
init_startup();
|
|
450165
449989
|
init_queue_runtime();
|
|
@@ -450178,7 +450002,6 @@ var init_headless = __esm(async () => {
|
|
|
450178
450002
|
init_headless_ephemeral_startup(),
|
|
450179
450003
|
init_headless_mod_adapter(),
|
|
450180
450004
|
init_headless_tool_events(),
|
|
450181
|
-
init_mcp_runtime(),
|
|
450182
450005
|
init_manager4(),
|
|
450183
450006
|
init_toolset()
|
|
450184
450007
|
]);
|
|
@@ -465838,6 +465661,110 @@ var init_LettaLoginOverlay = __esm(async () => {
|
|
|
465838
465661
|
jsx_dev_runtime63 = __toESM(require_jsx_dev_runtime(), 1);
|
|
465839
465662
|
});
|
|
465840
465663
|
|
|
465664
|
+
// src/backend/api/mcp-servers.ts
|
|
465665
|
+
function withTimeout3(promise2, timeoutMs, label) {
|
|
465666
|
+
let timer;
|
|
465667
|
+
const timeout = new Promise((_4, reject2) => {
|
|
465668
|
+
timer = setTimeout(() => reject2(new Error(`${label} timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
465669
|
+
});
|
|
465670
|
+
return Promise.race([promise2, timeout]).finally(() => {
|
|
465671
|
+
if (timer !== undefined)
|
|
465672
|
+
clearTimeout(timer);
|
|
465673
|
+
});
|
|
465674
|
+
}
|
|
465675
|
+
function listServerMcpServers(client, timeoutMs = 1e4) {
|
|
465676
|
+
return withTimeout3(client.mcpServers.list(), timeoutMs, "Listing server-side MCP servers");
|
|
465677
|
+
}
|
|
465678
|
+
async function listLiveServerMcpTools(client, serverName2, timeoutMs = 15000) {
|
|
465679
|
+
const result2 = await withTimeout3(client.get(`/v1/tools/mcp/servers/${encodeURIComponent(serverName2)}/tools`), timeoutMs, `Listing tools for MCP server "${serverName2}"`);
|
|
465680
|
+
if (!Array.isArray(result2))
|
|
465681
|
+
return [];
|
|
465682
|
+
return result2.filter((tool) => typeof tool === "object" && tool !== null && typeof tool.name === "string");
|
|
465683
|
+
}
|
|
465684
|
+
async function loadServerMcpEntries(client, timeoutMs = 15000) {
|
|
465685
|
+
const servers = await listServerMcpServers(client, timeoutMs);
|
|
465686
|
+
return Promise.all(servers.map(async (server2) => {
|
|
465687
|
+
try {
|
|
465688
|
+
const tools = await listLiveServerMcpTools(client, server2.server_name, timeoutMs);
|
|
465689
|
+
return { server: server2, tools };
|
|
465690
|
+
} catch (cause) {
|
|
465691
|
+
return {
|
|
465692
|
+
server: server2,
|
|
465693
|
+
tools: [],
|
|
465694
|
+
toolsError: cause instanceof Error ? cause.message : String(cause)
|
|
465695
|
+
};
|
|
465696
|
+
}
|
|
465697
|
+
}));
|
|
465698
|
+
}
|
|
465699
|
+
function parseMcpMetadata(tool) {
|
|
465700
|
+
const metadata = tool.metadata_;
|
|
465701
|
+
const mcp = metadata?.mcp;
|
|
465702
|
+
if (typeof mcp !== "object" || mcp === null)
|
|
465703
|
+
return null;
|
|
465704
|
+
const { server_id, server_name } = mcp;
|
|
465705
|
+
return {
|
|
465706
|
+
...typeof server_id === "string" && { serverId: server_id },
|
|
465707
|
+
...typeof server_name === "string" && { serverName: server_name }
|
|
465708
|
+
};
|
|
465709
|
+
}
|
|
465710
|
+
async function listAgentMcpAttachments(client, agentId) {
|
|
465711
|
+
const attachments = [];
|
|
465712
|
+
for await (const tool of client.agents.tools.list(agentId, { limit: 100 })) {
|
|
465713
|
+
if (tool.tool_type !== "external_mcp" || !tool.id || !tool.name)
|
|
465714
|
+
continue;
|
|
465715
|
+
attachments.push({
|
|
465716
|
+
toolId: tool.id,
|
|
465717
|
+
toolName: tool.name,
|
|
465718
|
+
...parseMcpMetadata(tool)
|
|
465719
|
+
});
|
|
465720
|
+
}
|
|
465721
|
+
return attachments;
|
|
465722
|
+
}
|
|
465723
|
+
function attachmentsForEntry(entry, attachments) {
|
|
465724
|
+
return attachments.filter((attachment) => attachment.serverId && entry.server.id ? attachment.serverId === entry.server.id : attachment.serverName === entry.server.server_name);
|
|
465725
|
+
}
|
|
465726
|
+
function attachedToolNamesForEntry(entry, attachments) {
|
|
465727
|
+
return new Set(attachmentsForEntry(entry, attachments).map((attachment) => attachment.toolName));
|
|
465728
|
+
}
|
|
465729
|
+
async function registerServerMcpTool(client, serverName2, toolName) {
|
|
465730
|
+
const result2 = await client.post(`/v1/tools/mcp/servers/${encodeURIComponent(serverName2)}/${encodeURIComponent(toolName)}`);
|
|
465731
|
+
if (typeof result2?.id !== "string") {
|
|
465732
|
+
throw new Error(`Registering MCP tool "${toolName}" on server "${serverName2}" returned no tool id`);
|
|
465733
|
+
}
|
|
465734
|
+
return { id: result2.id };
|
|
465735
|
+
}
|
|
465736
|
+
async function attachServerMcpTools(client, agentId, serverName2, toolNames) {
|
|
465737
|
+
await Promise.all(toolNames.map(async (toolName) => {
|
|
465738
|
+
const { id: id2 } = await registerServerMcpTool(client, serverName2, toolName);
|
|
465739
|
+
await client.agents.tools.attach(id2, { agent_id: agentId });
|
|
465740
|
+
}));
|
|
465741
|
+
}
|
|
465742
|
+
async function detachServerMcpTools(client, agentId, toolIds) {
|
|
465743
|
+
await Promise.all(toolIds.map((toolId) => client.agents.tools.detach(toolId, { agent_id: agentId })));
|
|
465744
|
+
}
|
|
465745
|
+
function refreshServerMcpServer(client, mcpServerId, agentId) {
|
|
465746
|
+
return client.mcpServers.refresh(mcpServerId, { agent_id: agentId });
|
|
465747
|
+
}
|
|
465748
|
+
function planServerMcpToggle(entry, attachments) {
|
|
465749
|
+
const attached = attachmentsForEntry(entry, attachments);
|
|
465750
|
+
if (attached.length > 0) {
|
|
465751
|
+
return {
|
|
465752
|
+
action: "detach",
|
|
465753
|
+
toolIds: attached.map((attachment) => attachment.toolId)
|
|
465754
|
+
};
|
|
465755
|
+
}
|
|
465756
|
+
return { action: "attach", toolNames: entry.tools.map((tool) => tool.name) };
|
|
465757
|
+
}
|
|
465758
|
+
function describeServerMcpTarget(server2) {
|
|
465759
|
+
if ("server_url" in server2 && server2.server_url) {
|
|
465760
|
+
return server2.server_url;
|
|
465761
|
+
}
|
|
465762
|
+
if ("command" in server2 && server2.command) {
|
|
465763
|
+
return [server2.command, ...server2.args ?? []].join(" ");
|
|
465764
|
+
}
|
|
465765
|
+
return "";
|
|
465766
|
+
}
|
|
465767
|
+
|
|
465841
465768
|
// src/cli/components/McpSelector.tsx
|
|
465842
465769
|
function buildMcpRows(localStates, serverEntries) {
|
|
465843
465770
|
return [
|
|
@@ -465954,15 +465881,14 @@ var import_react87, jsx_dev_runtime64, SOLID_LINE12 = "─", DISPLAY_PAGE_SIZE2
|
|
|
465954
465881
|
var init_McpSelector = __esm(async () => {
|
|
465955
465882
|
init_backend2();
|
|
465956
465883
|
init_client2();
|
|
465957
|
-
init_mcp_servers2();
|
|
465958
465884
|
init_truncate_text();
|
|
465959
465885
|
init_use_terminal_width();
|
|
465960
465886
|
init_mcp_oauth();
|
|
465887
|
+
init_mcp_runtime();
|
|
465961
465888
|
init_settings_manager();
|
|
465962
465889
|
init_colors();
|
|
465963
465890
|
await __promiseAll([
|
|
465964
465891
|
init_build4(),
|
|
465965
|
-
init_mcp_runtime(),
|
|
465966
465892
|
init_Text2()
|
|
465967
465893
|
]);
|
|
465968
465894
|
import_react87 = __toESM(require_react(), 1);
|
|
@@ -466264,7 +466190,7 @@ var init_McpSelector = __esm(async () => {
|
|
|
466264
466190
|
flexDirection: "column",
|
|
466265
466191
|
children: [
|
|
466266
466192
|
/* @__PURE__ */ jsx_dev_runtime64.jsxDEV(Text2, {
|
|
466267
|
-
children: tool.
|
|
466193
|
+
children: tool.title ?? tool.name
|
|
466268
466194
|
}, undefined, false, undefined, this),
|
|
466269
466195
|
/* @__PURE__ */ jsx_dev_runtime64.jsxDEV(Text2, {
|
|
466270
466196
|
dimColor: true,
|
|
@@ -466274,7 +466200,7 @@ var init_McpSelector = __esm(async () => {
|
|
|
466274
466200
|
]
|
|
466275
466201
|
}, undefined, true, undefined, this)
|
|
466276
466202
|
]
|
|
466277
|
-
}, tool.
|
|
466203
|
+
}, tool.name, true, undefined, this)),
|
|
466278
466204
|
/* @__PURE__ */ jsx_dev_runtime64.jsxDEV(Box_default, {
|
|
466279
466205
|
marginTop: 1,
|
|
466280
466206
|
children: /* @__PURE__ */ jsx_dev_runtime64.jsxDEV(Text2, {
|
|
@@ -475585,7 +475511,7 @@ var init_ToolCallMessageRich = __esm(async () => {
|
|
|
475585
475511
|
let shellSemanticKind = null;
|
|
475586
475512
|
let hasShellDescription = false;
|
|
475587
475513
|
if (!isQuestionTool(rawName)) {
|
|
475588
|
-
const
|
|
475514
|
+
const parseArgs22 = () => {
|
|
475589
475515
|
if (!argsText.trim()) {
|
|
475590
475516
|
return { formatted: null, parseable: true };
|
|
475591
475517
|
}
|
|
@@ -475599,7 +475525,7 @@ var init_ToolCallMessageRich = __esm(async () => {
|
|
|
475599
475525
|
return { formatted: null, parseable: false };
|
|
475600
475526
|
}
|
|
475601
475527
|
};
|
|
475602
|
-
const { formatted, parseable } =
|
|
475528
|
+
const { formatted, parseable } = parseArgs22();
|
|
475603
475529
|
const argsComplete = parseable || line.phase === "running" || line.phase === "finished" || !isStreaming;
|
|
475604
475530
|
if (!argsComplete) {
|
|
475605
475531
|
args = "(…)";
|
|
@@ -477815,7 +477741,7 @@ function updateCommandResult(buffersRef, refreshDerived, cmdId, input, output, s
|
|
|
477815
477741
|
buffersRef.current.byId.set(cmdId, line);
|
|
477816
477742
|
refreshDerived();
|
|
477817
477743
|
}
|
|
477818
|
-
function
|
|
477744
|
+
function parseArgs22(msg) {
|
|
477819
477745
|
return msg.trim().split(/\s+/).filter(Boolean);
|
|
477820
477746
|
}
|
|
477821
477747
|
function formatConnectUsage() {
|
|
@@ -478197,7 +478123,7 @@ ${formatBedrockUsage2()}`, false);
|
|
|
478197
478123
|
}
|
|
478198
478124
|
}
|
|
478199
478125
|
async function handleConnect(ctx, msg) {
|
|
478200
|
-
const parts =
|
|
478126
|
+
const parts = parseArgs22(msg);
|
|
478201
478127
|
const providerToken = parts[1];
|
|
478202
478128
|
if (!providerToken) {
|
|
478203
478129
|
addCommandResult(ctx.buffersRef, ctx.refreshDerived, msg, formatConnectUsage(), false);
|
|
@@ -493905,20 +493831,20 @@ var init_session3 = __esm(() => {
|
|
|
493905
493831
|
});
|
|
493906
493832
|
|
|
493907
493833
|
// src/cli/app/use-agent-mcp-servers.ts
|
|
493908
|
-
function
|
|
493834
|
+
function useMcpCleanup(agentId) {
|
|
493835
|
+
const previousAgentId = import_react110.useRef(agentId);
|
|
493909
493836
|
import_react110.useEffect(() => {
|
|
493910
|
-
|
|
493911
|
-
|
|
493837
|
+
if (previousAgentId.current === agentId)
|
|
493838
|
+
return;
|
|
493839
|
+
previousAgentId.current = agentId;
|
|
493840
|
+
closeClientMcpServers().catch((error5) => debugWarn("mcp", `Failed to close client MCP servers: ${String(error5)}`));
|
|
493912
493841
|
}, [agentId]);
|
|
493913
493842
|
}
|
|
493914
493843
|
var import_react110;
|
|
493915
|
-
var init_use_agent_mcp_servers = __esm(
|
|
493916
|
-
|
|
493844
|
+
var init_use_agent_mcp_servers = __esm(() => {
|
|
493845
|
+
init_mcp_runtime();
|
|
493846
|
+
init_mcp_runtime();
|
|
493917
493847
|
init_debug();
|
|
493918
|
-
await __promiseAll([
|
|
493919
|
-
init_mcp_runtime(),
|
|
493920
|
-
init_mcp_runtime()
|
|
493921
|
-
]);
|
|
493922
493848
|
import_react110 = __toESM(require_react(), 1);
|
|
493923
493849
|
});
|
|
493924
493850
|
|
|
@@ -495908,6 +495834,7 @@ function useConversationLoop(ctx) {
|
|
|
495908
495834
|
clearApprovalToolContext,
|
|
495909
495835
|
closeTrajectorySegment,
|
|
495910
495836
|
chatgptPlanSwapsRef,
|
|
495837
|
+
chatgptExhaustedProvidersRef,
|
|
495911
495838
|
consumeQueuedMessages,
|
|
495912
495839
|
queueModeRef,
|
|
495913
495840
|
contextTrackerRef,
|
|
@@ -496140,6 +496067,7 @@ function useConversationLoop(ctx) {
|
|
|
496140
496067
|
conversationBusyRetriesRef.current = 0;
|
|
496141
496068
|
quotaAutoSwapAttemptedRef.current = false;
|
|
496142
496069
|
chatgptPlanSwapsRef.current = 0;
|
|
496070
|
+
chatgptExhaustedProvidersRef.current.clear();
|
|
496143
496071
|
}
|
|
496144
496072
|
let currentRunId;
|
|
496145
496073
|
let preserveTranscriptStartForApproval = false;
|
|
@@ -497107,8 +497035,10 @@ ${feedback}
|
|
|
497107
497035
|
if (chatgptPlanSwapsRef.current < CHATGPT_PLAN_ROTATION_MAX_SWAPS_PER_TURN) {
|
|
497108
497036
|
const rotation = await rotateChatGPTPlanOnQuotaLimit({
|
|
497109
497037
|
agentId: agentIdRef.current,
|
|
497038
|
+
conversationId: conversationIdRef.current,
|
|
497110
497039
|
currentHandle: currentModelId,
|
|
497111
|
-
error: runErrorInfo2 ?? detailFromRun ?? fallbackError
|
|
497040
|
+
error: runErrorInfo2 ?? detailFromRun ?? fallbackError,
|
|
497041
|
+
exhaustedProviders: chatgptExhaustedProvidersRef.current
|
|
497112
497042
|
});
|
|
497113
497043
|
if (rotation) {
|
|
497114
497044
|
chatgptPlanSwapsRef.current += 1;
|
|
@@ -498026,6 +497956,8 @@ function useFeedbackHandler(ctx) {
|
|
|
498026
497956
|
await submitFeedbackMetadata(apiKey, settingsManager.getOrCreateDeviceId(), {
|
|
498027
497957
|
message: resolvedMessage,
|
|
498028
497958
|
feature: "letta-code",
|
|
497959
|
+
submission_source: "slash_command",
|
|
497960
|
+
client_type: getFeedbackClientType(),
|
|
498029
497961
|
agent_id: agentId,
|
|
498030
497962
|
session_id: telemetry.getSessionId(),
|
|
498031
497963
|
run_id: lastRunIdRef.current ?? undefined,
|
|
@@ -501442,10 +501374,10 @@ function mcpHelpText() {
|
|
|
501442
501374
|
`);
|
|
501443
501375
|
}
|
|
501444
501376
|
var activeCommandId2 = null;
|
|
501445
|
-
var init_mcp2 = __esm(
|
|
501377
|
+
var init_mcp2 = __esm(() => {
|
|
501446
501378
|
init_error_formatter();
|
|
501379
|
+
init_mcp_runtime();
|
|
501447
501380
|
init_settings_manager();
|
|
501448
|
-
await init_mcp_runtime();
|
|
501449
501381
|
});
|
|
501450
501382
|
|
|
501451
501383
|
// src/cli/commands/listen.ts
|
|
@@ -501508,24 +501440,24 @@ Listener disconnected from Letta Cloud.`, true);
|
|
|
501508
501440
|
return;
|
|
501509
501441
|
}
|
|
501510
501442
|
if (msg.includes("--help") || msg.includes("-h")) {
|
|
501511
|
-
addCommandResult3(ctx.buffersRef, ctx.refreshDerived, msg, `Usage: /server [--
|
|
501443
|
+
addCommandResult3(ctx.buffersRef, ctx.refreshDerived, msg, `Usage: /server [--computer-name <name>]
|
|
501512
501444
|
/server off
|
|
501513
501445
|
|
|
501514
|
-
Register this
|
|
501446
|
+
Register this computer to receive messages from Letta Cloud.
|
|
501515
501447
|
Alias: /remote
|
|
501516
501448
|
|
|
501517
501449
|
Options:
|
|
501518
|
-
--
|
|
501450
|
+
--computer-name <name> Friendly name for this computer (uses hostname if not provided)
|
|
501519
501451
|
off Stop the active listener connection
|
|
501520
501452
|
-h, --help Show this help message
|
|
501521
501453
|
|
|
501522
501454
|
Examples:
|
|
501523
501455
|
/server # Start listener with hostname
|
|
501524
|
-
/server --
|
|
501456
|
+
/server --computer-name "work-laptop" # Start with custom name
|
|
501525
501457
|
/server off # Stop listening
|
|
501526
501458
|
|
|
501527
501459
|
Once connected, this instance will listen for incoming messages from cloud agents.
|
|
501528
|
-
Messages will be executed locally
|
|
501460
|
+
Messages will be executed locally on this computer.`, true);
|
|
501529
501461
|
return;
|
|
501530
501462
|
}
|
|
501531
501463
|
let connectionName;
|
|
@@ -501575,7 +501507,7 @@ Retry ${attempt2} in ${Math.round(delayMs / 1000)}s: ${error5.message}`, true, "
|
|
|
501575
501507
|
updateCommandResult3(ctx.buffersRef, ctx.refreshDerived, cmdId, msg, `✓ Registered successfully!
|
|
501576
501508
|
|
|
501577
501509
|
` + `Connection ID: ${connectionId}
|
|
501578
|
-
|
|
501510
|
+
Computer: "${connectionName}"
|
|
501579
501511
|
WebSocket: ${wsUrl}
|
|
501580
501512
|
|
|
501581
501513
|
Starting WebSocket connection...`, true, "running");
|
|
@@ -501593,18 +501525,18 @@ Starting WebSocket connection...`, true, "running");
|
|
|
501593
501525
|
const url2 = buildConnectionUrl(id2);
|
|
501594
501526
|
const urlText = url2 ? `
|
|
501595
501527
|
|
|
501596
|
-
Connect to this
|
|
501528
|
+
Connect to this computer:
|
|
501597
501529
|
${url2}` : "";
|
|
501598
|
-
updateCommandResult3(ctx.buffersRef, ctx.refreshDerived, cmdId, msg, `
|
|
501530
|
+
updateCommandResult3(ctx.buffersRef, ctx.refreshDerived, cmdId, msg, `Computer initialized: ${connectionName}
|
|
501599
501531
|
${statusText}${urlText}`, true, "finished");
|
|
501600
501532
|
},
|
|
501601
501533
|
onRetrying: (attempt2, _maxAttempts, nextRetryIn, id2) => {
|
|
501602
501534
|
const url2 = buildConnectionUrl(id2);
|
|
501603
501535
|
const urlText = url2 ? `
|
|
501604
501536
|
|
|
501605
|
-
Connect to this
|
|
501537
|
+
Connect to this computer:
|
|
501606
501538
|
${url2}` : "";
|
|
501607
|
-
updateCommandResult3(ctx.buffersRef, ctx.refreshDerived, cmdId, msg, `
|
|
501539
|
+
updateCommandResult3(ctx.buffersRef, ctx.refreshDerived, cmdId, msg, `Computer initialized: ${connectionName}
|
|
501608
501540
|
Reconnecting to Letta Cloud...
|
|
501609
501541
|
Attempt ${attempt2}, retrying in ${Math.round(nextRetryIn / 1000)}s${urlText}`, true, "running");
|
|
501610
501542
|
},
|
|
@@ -501612,14 +501544,14 @@ Attempt ${attempt2}, retrying in ${Math.round(nextRetryIn / 1000)}s${urlText}`,
|
|
|
501612
501544
|
const url2 = buildConnectionUrl(id2);
|
|
501613
501545
|
const urlText = url2 ? `
|
|
501614
501546
|
|
|
501615
|
-
Connect to this
|
|
501547
|
+
Connect to this computer:
|
|
501616
501548
|
${url2}` : "";
|
|
501617
|
-
updateCommandResult3(ctx.buffersRef, ctx.refreshDerived, cmdId, msg, `
|
|
501549
|
+
updateCommandResult3(ctx.buffersRef, ctx.refreshDerived, cmdId, msg, `Computer initialized: ${connectionName}
|
|
501618
501550
|
Awaiting instructions${urlText}`, true, "finished");
|
|
501619
501551
|
ctx.setCommandRunning(false);
|
|
501620
501552
|
},
|
|
501621
501553
|
onNeedsReregister: async () => {
|
|
501622
|
-
updateCommandResult3(ctx.buffersRef, ctx.refreshDerived, cmdId, msg, `
|
|
501554
|
+
updateCommandResult3(ctx.buffersRef, ctx.refreshDerived, cmdId, msg, `Computer connection expired, re-registering "${connectionName}"...`, true, "running");
|
|
501623
501555
|
try {
|
|
501624
501556
|
const nextRegisterOptions = await resolveRegisterOptions();
|
|
501625
501557
|
const reregisterResult = await registerWithCloudRetry(nextRegisterOptions, {
|
|
@@ -501745,7 +501677,7 @@ async function handleConnectionCommand(msg, trimmed, ctx) {
|
|
|
501745
501677
|
for (let i4 = 1;i4 < parts.length; i4++) {
|
|
501746
501678
|
const part = parts[i4];
|
|
501747
501679
|
const nextPart = parts[i4 + 1];
|
|
501748
|
-
if (part === "--env-name" && nextPart) {
|
|
501680
|
+
if ((part === "--computer-name" || part === "--env-name") && nextPart) {
|
|
501749
501681
|
name = nextPart;
|
|
501750
501682
|
i4++;
|
|
501751
501683
|
}
|
|
@@ -501768,8 +501700,8 @@ async function handleConnectionCommand(msg, trimmed, ctx) {
|
|
|
501768
501700
|
}
|
|
501769
501701
|
return null;
|
|
501770
501702
|
}
|
|
501771
|
-
var init_submit_connection_commands = __esm(
|
|
501772
|
-
|
|
501703
|
+
var init_submit_connection_commands = __esm(() => {
|
|
501704
|
+
init_mcp2();
|
|
501773
501705
|
});
|
|
501774
501706
|
|
|
501775
501707
|
// src/cli/helpers/context-chart.ts
|
|
@@ -505551,6 +505483,7 @@ var init_use_submit_handler = __esm(async () => {
|
|
|
505551
505483
|
init_command_routing();
|
|
505552
505484
|
init_ids();
|
|
505553
505485
|
init_session3();
|
|
505486
|
+
init_submit_connection_commands();
|
|
505554
505487
|
init_submit_diagnostics_commands();
|
|
505555
505488
|
init_submit_profile_commands();
|
|
505556
505489
|
await __promiseAll([
|
|
@@ -505558,7 +505491,6 @@ var init_use_submit_handler = __esm(async () => {
|
|
|
505558
505491
|
init_mods2(),
|
|
505559
505492
|
init_PinDialog(),
|
|
505560
505493
|
init_accumulator(),
|
|
505561
|
-
init_submit_connection_commands(),
|
|
505562
505494
|
init_submit_navigation_commands()
|
|
505563
505495
|
]);
|
|
505564
505496
|
import_react120 = __toESM(require_react(), 1);
|
|
@@ -506254,6 +506186,7 @@ function App2({
|
|
|
506254
506186
|
const quotaAutoSwapAttemptedRef = import_react121.useRef(false);
|
|
506255
506187
|
const emptyResponseRetriesRef = import_react121.useRef(0);
|
|
506256
506188
|
const chatgptPlanSwapsRef = import_react121.useRef(0);
|
|
506189
|
+
const chatgptExhaustedProvidersRef = import_react121.useRef(new Set);
|
|
506257
506190
|
const conversationBusyRetriesRef = import_react121.useRef(0);
|
|
506258
506191
|
const [queueDisplay, setQueueDisplay] = import_react121.useState([]);
|
|
506259
506192
|
const tuiQueueRef = import_react121.useRef(null);
|
|
@@ -506910,7 +506843,7 @@ function App2({
|
|
|
506910
506843
|
import_react121.useEffect(() => {
|
|
506911
506844
|
buffersRef.current.agentId = agentState?.id;
|
|
506912
506845
|
}, [agentState?.id]);
|
|
506913
|
-
|
|
506846
|
+
useMcpCleanup(agentState?.id);
|
|
506914
506847
|
const precomputedDiffsRef = import_react121.useRef(new Map);
|
|
506915
506848
|
const eagerCommittedPreviewsRef = import_react121.useRef(new Set);
|
|
506916
506849
|
const estimateApprovalPreviewLines = import_react121.useCallback((approval) => {
|
|
@@ -507743,6 +507676,7 @@ Memory may be stale. Try running: git -C ${getScopedMemoryFilesystemRoot(agentId
|
|
|
507743
507676
|
buffersRef,
|
|
507744
507677
|
clearApprovalToolContext,
|
|
507745
507678
|
chatgptPlanSwapsRef,
|
|
507679
|
+
chatgptExhaustedProvidersRef,
|
|
507746
507680
|
closeTrajectorySegment,
|
|
507747
507681
|
consumeQueuedMessages,
|
|
507748
507682
|
queueModeRef,
|
|
@@ -508904,6 +508838,7 @@ var init_AppCoordinator = __esm(async () => {
|
|
|
508904
508838
|
init_ids();
|
|
508905
508839
|
init_model_config();
|
|
508906
508840
|
init_session3();
|
|
508841
|
+
init_use_agent_mcp_servers();
|
|
508907
508842
|
init_use_feedback_handler();
|
|
508908
508843
|
init_use_queued_approval_submit();
|
|
508909
508844
|
init_use_reasoning_cycle();
|
|
@@ -508919,7 +508854,6 @@ var init_AppCoordinator = __esm(async () => {
|
|
|
508919
508854
|
init_manager4(),
|
|
508920
508855
|
init_toolset(),
|
|
508921
508856
|
init_AppView(),
|
|
508922
|
-
init_use_agent_mcp_servers(),
|
|
508923
508857
|
init_use_approval_flow(),
|
|
508924
508858
|
init_use_bash_handlers(),
|
|
508925
508859
|
init_use_configuration_handlers(),
|
|
@@ -509136,14 +509070,13 @@ USAGE
|
|
|
509136
509070
|
letta update Check for updates and install (aliases: upgrade, --update, --upgrade)
|
|
509137
509071
|
letta memory ... Memory filesystem subcommands
|
|
509138
509072
|
letta agents ... Agents subcommands (JSON-only)
|
|
509139
|
-
letta
|
|
509140
|
-
letta teleport ... Move the current conversation between
|
|
509073
|
+
letta computers ... List available remote computers (JSON-only)
|
|
509074
|
+
letta teleport ... Move the current conversation between computers
|
|
509141
509075
|
letta messages ... Messages subcommands (JSON-only)
|
|
509142
509076
|
letta mcp ... List, search, and call MCP servers available to an agent
|
|
509143
|
-
letta cloud-mcp ... Legacy server-side MCP commands (JSON-only)
|
|
509144
509077
|
letta mods ... List and manage local mods
|
|
509145
509078
|
letta sandbox ... Transfer files to or from the current Cloud sandbox
|
|
509146
|
-
letta server ... Run a remote
|
|
509079
|
+
letta server ... Run a remote computer, channels, or the App Server
|
|
509147
509080
|
letta connect ... Connect providers from terminal
|
|
509148
509081
|
letta backend ... Show or set the default backend
|
|
509149
509082
|
letta setup Re-run first-run setup
|
|
@@ -509162,20 +509095,19 @@ SUBCOMMANDS
|
|
|
509162
509095
|
letta memory pull --agent <id>
|
|
509163
509096
|
letta memory tokens [--memory-dir <path>] [--agent <id>] [--format text|json]
|
|
509164
509097
|
letta agents list [--query <text> | --name <name> | --tags <tags>]
|
|
509165
|
-
letta
|
|
509166
|
-
letta
|
|
509167
|
-
letta teleport list|cloud|local|<
|
|
509098
|
+
letta computers list [--online-only]
|
|
509099
|
+
letta computers current
|
|
509100
|
+
letta teleport list|cloud|local|<computer>
|
|
509168
509101
|
letta messages search --query <text> [--all-agents]
|
|
509169
509102
|
letta messages list [--agent <id>]
|
|
509170
509103
|
letta messages transcript --conversation <id> [--out <path>]
|
|
509171
|
-
letta cloud-mcp list|tools|run ... [--agent <id>]
|
|
509172
509104
|
letta mods list [--agent <id>]
|
|
509173
509105
|
letta mods package <mod-file> --name <package-name> [--out <dir>]
|
|
509174
509106
|
letta mods enable <package-spec>
|
|
509175
509107
|
letta mods disable <package-spec>
|
|
509176
509108
|
letta mods remove <package-spec>
|
|
509177
509109
|
letta mcp list|get|tools|search|call ... [--agent <id>]
|
|
509178
|
-
letta server [--
|
|
509110
|
+
letta server [--computer-name <name> | --listen [url]] [options]
|
|
509179
509111
|
letta connect <provider> [options]
|
|
509180
509112
|
letta install <thing> [--agent <id> | -n <name>]
|
|
509181
509113
|
letta skills list [--agent <id> | -n <name>]
|
|
@@ -509936,7 +509868,7 @@ Error: ${message}`);
|
|
|
509936
509868
|
markMilestone("REACT_IMPORT_DONE");
|
|
509937
509869
|
await terminalPreflightPromise;
|
|
509938
509870
|
markMilestone("TERMINAL_PREFLIGHT_DONE");
|
|
509939
|
-
const { useState: useState56, useEffect: useEffect50, useRef:
|
|
509871
|
+
const { useState: useState56, useEffect: useEffect50, useRef: useRef21 } = React14;
|
|
509940
509872
|
const App3 = AppModule.App;
|
|
509941
509873
|
function LoadingApp({
|
|
509942
509874
|
forceNew: forceNew2,
|
|
@@ -509960,7 +509892,7 @@ Error: ${message}`);
|
|
|
509960
509892
|
const [resumedExistingConversation, setResumedExistingConversation] = useState56(false);
|
|
509961
509893
|
const [agentProvenance, setAgentProvenance] = useState56(null);
|
|
509962
509894
|
const [selectedGlobalAgentId, setSelectedGlobalAgentId] = useState56(null);
|
|
509963
|
-
const startupCreatedAgentRef =
|
|
509895
|
+
const startupCreatedAgentRef = useRef21(null);
|
|
509964
509896
|
const [startupHasCloudCredentials, setStartupHasCloudCredentials] = useState56(Boolean(settings3.refreshToken || apiKey));
|
|
509965
509897
|
const [fileAutocompleteFdPath, setFileAutocompleteFdPath] = useState56(() => resolveFdPath());
|
|
509966
509898
|
const [startupHasAvailableLocalModels, setStartupHasAvailableLocalModels] = useState56(true);
|
|
@@ -512995,4 +512927,4 @@ function registerBunOAuthFlows() {
|
|
|
512995
512927
|
registerBunOAuthFlows();
|
|
512996
512928
|
await init_src5().then(() => exports_src2);
|
|
512997
512929
|
|
|
512998
|
-
//# debugId=
|
|
512930
|
+
//# debugId=D6C12B8170F7A1C664756E2164756E21
|