@letta-ai/letta-code 0.34.6 → 0.34.7
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/dist/mcp-client.js +2 -2
- package/dist/mcp-client.js.map +1 -1
- package/dist/mcp-oauth.js +2 -2
- package/dist/mcp-oauth.js.map +1 -1
- package/dist/types/agent/approval-execution.d.ts.map +1 -1
- package/dist/types/permissions/checker.d.ts.map +1 -1
- package/dist/types/tools/impl/memory.d.ts +14 -0
- package/dist/types/tools/impl/memory.d.ts.map +1 -0
- package/dist/types/tools/impl/truncation.d.ts +1 -0
- package/dist/types/tools/impl/truncation.d.ts.map +1 -1
- package/dist/types/tools/manager.d.ts.map +1 -1
- package/dist/types/tools/tool-definitions.d.ts +1 -0
- package/dist/types/tools/tool-definitions.d.ts.map +1 -1
- package/dist/types/tools/toolset-catalog.d.ts +1 -1
- package/dist/types/tools/toolset-catalog.d.ts.map +1 -1
- package/letta.js +918 -568
- package/npm-shrinkwrap.json +5 -5
- package/package.json +2 -2
- package/scripts/source-file-size-baseline.json +1 -1
package/letta.js
CHANGED
|
@@ -3930,6 +3930,7 @@ var init_toolset_catalog = __esm(() => {
|
|
|
3930
3930
|
"Wake",
|
|
3931
3931
|
"TaskStop",
|
|
3932
3932
|
"Skill",
|
|
3933
|
+
"Memory",
|
|
3933
3934
|
"Workflow",
|
|
3934
3935
|
"exec_command",
|
|
3935
3936
|
"write_stdin",
|
|
@@ -3964,6 +3965,7 @@ var init_toolset_catalog = __esm(() => {
|
|
|
3964
3965
|
"TaskStop",
|
|
3965
3966
|
"Read",
|
|
3966
3967
|
"Skill",
|
|
3968
|
+
"Memory",
|
|
3967
3969
|
"Workflow",
|
|
3968
3970
|
"Task",
|
|
3969
3971
|
"SendAgentMessage",
|
|
@@ -3990,6 +3992,7 @@ var init_toolset_catalog = __esm(() => {
|
|
|
3990
3992
|
"Wake",
|
|
3991
3993
|
"TaskStop",
|
|
3992
3994
|
"Skill",
|
|
3995
|
+
"Memory",
|
|
3993
3996
|
"Workflow",
|
|
3994
3997
|
"exec_command",
|
|
3995
3998
|
"write_stdin",
|
|
@@ -5724,7 +5727,7 @@ var package_default;
|
|
|
5724
5727
|
var init_package = __esm(() => {
|
|
5725
5728
|
package_default = {
|
|
5726
5729
|
name: "@letta-ai/letta-code",
|
|
5727
|
-
version: "0.34.
|
|
5730
|
+
version: "0.34.7",
|
|
5728
5731
|
lettaStartupLogProtocol: 1,
|
|
5729
5732
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
5730
5733
|
type: "module",
|
|
@@ -5999,7 +6002,7 @@ var init_package = __esm(() => {
|
|
|
5999
6002
|
},
|
|
6000
6003
|
lettaLifecycleProtocol: 1,
|
|
6001
6004
|
lettaRuntimeGraphProtocol: 1,
|
|
6002
|
-
lettaRuntimeGraphSha512: "sha512-
|
|
6005
|
+
lettaRuntimeGraphSha512: "sha512-NkEBUY1HKUlzrKrw9Z5465jdqkp+u7tLYNly5lGlHQKUAoN/8N4gGSsIXTsc3u2Eiz9f05ryN0l5zJOf1/q1iA=="
|
|
6003
6006
|
};
|
|
6004
6007
|
});
|
|
6005
6008
|
|
|
@@ -195921,6 +195924,23 @@ Lists files and directories in a given path. The path parameter must be an absol
|
|
|
195921
195924
|
If a directory has more than 1,000 entries, only the first 1,000 will be shown.`;
|
|
195922
195925
|
var init_LS = () => {};
|
|
195923
195926
|
|
|
195927
|
+
// src/tools/descriptions/Memory.md
|
|
195928
|
+
var Memory_default = `Read deferred memory from your memory filesystem.
|
|
195929
|
+
|
|
195930
|
+
Your root memory files are already in your system prompt. Everything else is deferred: the <deferred-memory> section lists directories you have not opened. Use this tool to open them progressively instead of guessing what they contain.
|
|
195931
|
+
|
|
195932
|
+
- Memory("projects") returns projects/MEMORY.md, then the files (<memory_files>) and subdirectories (<deferred-memory>) directly beneath it, with their descriptions.
|
|
195933
|
+
- Memory("projects/code") opens a subdirectory the same way.
|
|
195934
|
+
- Memory("projects/example.md") returns that file.
|
|
195935
|
+
|
|
195936
|
+
Entries are listed most recently edited first, up to 10 per directory.
|
|
195937
|
+
|
|
195938
|
+
Paths are relative to your memory directory. Before acting on a person, project, channel, or topic that your memory index points to, open the matching memory rather than working from assumptions. Open one level at a time and only what the task needs.
|
|
195939
|
+
|
|
195940
|
+
Do not use this tool for root memory files (already loaded) or skills/ (use Skill).
|
|
195941
|
+
`;
|
|
195942
|
+
var init_Memory = () => {};
|
|
195943
|
+
|
|
195924
195944
|
// src/tools/descriptions/Monitor.md
|
|
195925
195945
|
var Monitor_default = 'Start a background monitor that streams events from a long-running script. Each stdout line is an event — you keep working and notifications arrive in the chat. Events arrive on their own schedule and are not replies from the user, even if one lands while you\'re waiting for the user to answer a question.\n\nPick by how many notifications you need:\n- **One** ("tell me when the server is ready / the build finishes") → use **Bash with `run_in_background`** and a command that exits when the condition is true, e.g. `until grep -q "Ready in" dev.log; do sleep 0.5; done`. You get a single completion notification when it exits.\n- **One per occurrence, indefinitely** ("tell me every time an ERROR line appears") → Monitor with an unbounded command (`tail -f`, `inotifywait -m`, `while true`).\n- **One per occurrence, until a known end** ("emit each CI step result, stop when the run completes") → Monitor with a command that emits lines and then exits.\n\nYour script\'s stdout is the event stream. Each line becomes a notification. Exit ends the watch.\n # Each matching log line is an event\n tail -f /var/log/app.log | grep --line-buffered "ERROR"\n # Each file change is an event\n inotifywait -m --format \'%e %f\' /watched/dir\n # Node script that emits events as they arrive (e.g. WebSocket listener)\n node watch-for-events.js\n\nFor open github.com pull requests, use WatchPR instead. It covers the whole PR surface and keeps watching after CI finishes. Use Monitor only when WatchPR does not apply.\n\n**Don\'t use an unbounded command for a single notification.** `tail -f`, `inotifywait -m`, and `while true` never exit on their own, so the monitor stays armed until timeout even after the event has fired. For "tell me when X is ready," use Bash `run_in_background` with an `until` loop instead (one notification, ends in seconds). Note that `tail -f log | grep -m 1 ...` does *not* fix this: if the log goes quiet after the match, `tail` never receives SIGPIPE and the pipeline hangs anyway.\n\n- Every pipe stage must flush per line or matches sit in its buffer unseen: `grep` needs `--line-buffered`, `awk` needs `fflush()`. `head` cannot flush at all — `| head -N` delivers nothing until N matches accumulate, then ends the stream.\n- In poll loops, handle transient failures (`curl ... || true`) — one failed request shouldn\'t kill the monitor.\n- Poll intervals: 30s+ for remote APIs (rate limits), 0.5–1s for local checks.\n- Write a specific `description` — it appears in every notification ("errors in deploy.log" not "watching logs").\n- Only stdout is the event stream. Stderr goes to the output file (readable via Read) but does not trigger notifications — for a command you run directly (e.g. `python train.py 2>&1 | grep --line-buffered ...`), merge stderr with `2>&1` so its failures reach your filter. (No effect on `tail -f` of an existing log — that file only contains what its writer redirected.)\n\n**Coverage — silence is not success.** When watching a job or process for an outcome, your filter must match every terminal state, not just the happy path. A monitor that greps only for the success marker stays silent through a crashloop, a hung process, or an unexpected exit — and silence looks identical to "still running." Before arming, ask: *if this process crashed right now, would my filter emit anything?* If not, widen it.\n # Wrong — silent on crash, hang, or any non-success exit\n tail -f run.log | grep --line-buffered "elapsed_steps="\n # Right — one alternation covering progress + the failure signatures you\'d act on\n tail -f run.log | grep -E --line-buffered "elapsed_steps=|Traceback|Error|FAILED|assert|Killed|OOM"\n\nFor poll loops checking job state, emit on every terminal status (`succeeded|failed|cancelled|timeout`), not just success. If you cannot confidently enumerate the failure signatures, broaden the grep alternation rather than narrow it — some extra noise is better than missing a crashloop.\n\n**Output volume**: Every stdout line is a conversation message, so the filter should be selective — but selective means "the lines you\'d act on," not "only good news." Never pipe raw logs; filter to exactly the success and failure signals you care about. Monitors that produce too many events are automatically stopped; restart with a tighter filter if this happens.\n\nStdout lines within 200ms are batched into a single notification, so multiline output from a single event groups naturally.\n\nThe script runs in the same shell environment as Bash. Exit ends the watch (exit code is reported). Timeout → killed. Set `persistent: true` for session-length watches (log tails, long-lived event streams) — the monitor runs until you call TaskStop or the session ends. Use TaskStop to cancel early.\n\n**ws source** — open a WebSocket and stream each incoming text frame as an event. No shell, no polling: the server pushes, you get notified.\n ws: {url: \'wss://events.example.com/stream\', protocols: [\'v1\']},\n description: \'deploy events\',\n\nEach text frame becomes one notification (multiline frames stay as one event). Binary frames are reported as `[binary frame, N bytes]` rather than passed through. Socket close ends the watch with the close code surfaced; errors are surfaced before close. Same rate limiting as bash — a firehose will be suppressed and eventually stopped, so subscribe to a filtered feed where one exists.\n\nPrefer this over `command: \'websocat wss://…\'` — it avoids the extra process and line-buffering pitfalls. Use bash when you need to transform or filter frames with shell tools before they become events.\n';
|
|
195926
195946
|
var init_Monitor = () => {};
|
|
@@ -201222,6 +201242,7 @@ var init_truncation = __esm(() => {
|
|
|
201222
201242
|
GREP_OUTPUT_CHARS: 1e4,
|
|
201223
201243
|
GLOB_MAX_FILES: 2000,
|
|
201224
201244
|
LS_MAX_ENTRIES: 1000,
|
|
201245
|
+
MEMORY_MAX_ENTRIES: 10,
|
|
201225
201246
|
TOOL_RETURN_MAX_CHARS: 32000
|
|
201226
201247
|
};
|
|
201227
201248
|
});
|
|
@@ -204618,6 +204639,7 @@ var init_approval_execution = __esm(async () => {
|
|
|
204618
204639
|
"Read",
|
|
204619
204640
|
"ViewImage",
|
|
204620
204641
|
"Grep",
|
|
204642
|
+
"Memory",
|
|
204621
204643
|
"Glob",
|
|
204622
204644
|
"conversation_search",
|
|
204623
204645
|
"web_search",
|
|
@@ -206478,6 +206500,290 @@ var init_tool_name_mapping = __esm(() => {
|
|
|
206478
206500
|
};
|
|
206479
206501
|
});
|
|
206480
206502
|
|
|
206503
|
+
// src/tools/impl/memory.ts
|
|
206504
|
+
import { execFileSync as execFileSync9 } from "node:child_process";
|
|
206505
|
+
import {
|
|
206506
|
+
closeSync as closeSync5,
|
|
206507
|
+
existsSync as existsSync39,
|
|
206508
|
+
openSync as openSync5,
|
|
206509
|
+
readdirSync as readdirSync13,
|
|
206510
|
+
readFileSync as readFileSync32,
|
|
206511
|
+
readSync as readSync3,
|
|
206512
|
+
realpathSync as realpathSync6,
|
|
206513
|
+
statSync as statSync14
|
|
206514
|
+
} from "node:fs";
|
|
206515
|
+
import { extname as extname8, join as join51, sep as sep5 } from "node:path";
|
|
206516
|
+
function resolveMemoryToolDirectory(agentId) {
|
|
206517
|
+
try {
|
|
206518
|
+
const id2 = agentId === undefined ? getCurrentAgentId() : agentId;
|
|
206519
|
+
const memoryDir = id2 ? getActiveMemoryDirectory(id2) : undefined;
|
|
206520
|
+
return memoryDir && detectMemoryFormat(memoryDir, false) === "memfs-v2" ? memoryDir : null;
|
|
206521
|
+
} catch {
|
|
206522
|
+
return null;
|
|
206523
|
+
}
|
|
206524
|
+
}
|
|
206525
|
+
function readDescription(path19) {
|
|
206526
|
+
try {
|
|
206527
|
+
const value = parseFrontmatter(readFileSync32(path19, "utf8")).frontmatter.description;
|
|
206528
|
+
return typeof value === "string" ? value.trim() || undefined : undefined;
|
|
206529
|
+
} catch {
|
|
206530
|
+
return;
|
|
206531
|
+
}
|
|
206532
|
+
}
|
|
206533
|
+
function readIndexDescription(path19) {
|
|
206534
|
+
const fromFrontmatter = readDescription(path19);
|
|
206535
|
+
if (fromFrontmatter)
|
|
206536
|
+
return fromFrontmatter;
|
|
206537
|
+
try {
|
|
206538
|
+
const { body: body3 } = parseFrontmatter(readFileSync32(path19, "utf8"));
|
|
206539
|
+
for (const block of body3.split(/\n\s*\n/)) {
|
|
206540
|
+
const text2 = block.trim();
|
|
206541
|
+
if (!text2 || /^(#|[-*+] |\d+\. |\||```|<)/.test(text2))
|
|
206542
|
+
continue;
|
|
206543
|
+
const paragraph = text2.replace(/\s*\n\s*/g, " ").replace(/\[([^\]]+)\]\([^)]*\)/g, "$1");
|
|
206544
|
+
return paragraph.length > 300 ? `${paragraph.slice(0, 297)}...` : paragraph;
|
|
206545
|
+
}
|
|
206546
|
+
} catch {}
|
|
206547
|
+
return;
|
|
206548
|
+
}
|
|
206549
|
+
function isHidden2(name) {
|
|
206550
|
+
return name.startsWith(".");
|
|
206551
|
+
}
|
|
206552
|
+
function findByBasename(dir, name, root2 = dir, found = []) {
|
|
206553
|
+
for (const entry of readdirSync13(dir, { withFileTypes: true })) {
|
|
206554
|
+
if (found.length >= 5)
|
|
206555
|
+
break;
|
|
206556
|
+
if (isHidden2(entry.name) || dir === root2 && entry.name === "skills") {
|
|
206557
|
+
continue;
|
|
206558
|
+
}
|
|
206559
|
+
const path19 = join51(dir, entry.name);
|
|
206560
|
+
if (entry.isDirectory())
|
|
206561
|
+
findByBasename(path19, name, root2, found);
|
|
206562
|
+
else if (entry.isFile() && entry.name === name && dir !== root2) {
|
|
206563
|
+
found.push(path19.slice(root2.length + 1).split(sep5).join("/"));
|
|
206564
|
+
}
|
|
206565
|
+
}
|
|
206566
|
+
return found;
|
|
206567
|
+
}
|
|
206568
|
+
function escapeXmlText2(value) {
|
|
206569
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
206570
|
+
}
|
|
206571
|
+
function descriptionAttr(description) {
|
|
206572
|
+
return description ? ` description="${escapeXmlText2(description).replace(/"/g, """)}"` : "";
|
|
206573
|
+
}
|
|
206574
|
+
function clampContent(content, fullPath, maxChars) {
|
|
206575
|
+
const lines = content.split(`
|
|
206576
|
+
`);
|
|
206577
|
+
const shown = lines.slice(0, LIMITS.READ_MAX_LINES);
|
|
206578
|
+
let longLines = false;
|
|
206579
|
+
let result2 = shown.map((line) => {
|
|
206580
|
+
if (line.length <= LIMITS.READ_MAX_CHARS_PER_LINE)
|
|
206581
|
+
return line;
|
|
206582
|
+
longLines = true;
|
|
206583
|
+
return `${line.slice(0, LIMITS.READ_MAX_CHARS_PER_LINE)}... [line truncated]`;
|
|
206584
|
+
}).join(`
|
|
206585
|
+
`);
|
|
206586
|
+
const byTotal = result2.length > maxChars;
|
|
206587
|
+
if (byTotal)
|
|
206588
|
+
result2 = truncateByChars(result2, maxChars, "Memory").content;
|
|
206589
|
+
const byLines = shown.length < lines.length;
|
|
206590
|
+
const notices = [];
|
|
206591
|
+
if (byLines) {
|
|
206592
|
+
notices.push(`[File truncated: showing lines 1-${shown.length} of ${lines.length} total lines. Use Read with offset and limit on the full file to read other sections.]`);
|
|
206593
|
+
}
|
|
206594
|
+
if (longLines) {
|
|
206595
|
+
notices.push(`[Some lines exceeded ${LIMITS.READ_MAX_CHARS_PER_LINE.toLocaleString()} characters and were truncated.]`);
|
|
206596
|
+
}
|
|
206597
|
+
if (byTotal) {
|
|
206598
|
+
notices.push("[Use Read with offset and limit on the full file to read it in smaller sections.]");
|
|
206599
|
+
}
|
|
206600
|
+
if (notices.length)
|
|
206601
|
+
notices.push(`[Full file: ${fullPath}]`);
|
|
206602
|
+
return notices.length ? `${result2}
|
|
206603
|
+
|
|
206604
|
+
${notices.join(`
|
|
206605
|
+
|
|
206606
|
+
`)}` : result2;
|
|
206607
|
+
}
|
|
206608
|
+
function lastEditedByChild(dir, names2) {
|
|
206609
|
+
const edited = new Map;
|
|
206610
|
+
const bump = (name, time) => {
|
|
206611
|
+
if (time > (edited.get(name) ?? 0))
|
|
206612
|
+
edited.set(name, time);
|
|
206613
|
+
};
|
|
206614
|
+
const git = (args) => execFileSync9("git", ["-C", dir, ...args], {
|
|
206615
|
+
encoding: "utf8",
|
|
206616
|
+
timeout: 5000,
|
|
206617
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
206618
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
206619
|
+
});
|
|
206620
|
+
const walkMtime = (path19, name) => {
|
|
206621
|
+
try {
|
|
206622
|
+
const stat6 = statSync14(path19);
|
|
206623
|
+
if (stat6.isFile())
|
|
206624
|
+
return bump(name, stat6.mtimeMs);
|
|
206625
|
+
if (!stat6.isDirectory())
|
|
206626
|
+
return;
|
|
206627
|
+
for (const entry of readdirSync13(path19, { withFileTypes: true })) {
|
|
206628
|
+
if (!isHidden2(entry.name))
|
|
206629
|
+
walkMtime(join51(path19, entry.name), name);
|
|
206630
|
+
}
|
|
206631
|
+
} catch {}
|
|
206632
|
+
};
|
|
206633
|
+
let dirty;
|
|
206634
|
+
try {
|
|
206635
|
+
let commitTime = 0;
|
|
206636
|
+
for (const line of git([
|
|
206637
|
+
"log",
|
|
206638
|
+
"--format=%x00%ct",
|
|
206639
|
+
"--name-only",
|
|
206640
|
+
"--relative",
|
|
206641
|
+
"--",
|
|
206642
|
+
"."
|
|
206643
|
+
]).split(`
|
|
206644
|
+
`)) {
|
|
206645
|
+
const child = line.split("/")[0] ?? line;
|
|
206646
|
+
if (line.startsWith("\x00"))
|
|
206647
|
+
commitTime = Number(line.slice(1)) * 1000;
|
|
206648
|
+
else if (line && !edited.has(child))
|
|
206649
|
+
edited.set(child, commitTime);
|
|
206650
|
+
}
|
|
206651
|
+
const prefix = git(["rev-parse", "--show-prefix"]).trim();
|
|
206652
|
+
dirty = git([
|
|
206653
|
+
"status",
|
|
206654
|
+
"--porcelain=v1",
|
|
206655
|
+
"-z",
|
|
206656
|
+
"--untracked-files=all",
|
|
206657
|
+
"--",
|
|
206658
|
+
"."
|
|
206659
|
+
]).split("\x00").filter((record4) => record4.length > 3).map((record4) => record4.slice(3)).filter((path19) => path19.startsWith(prefix)).map((path19) => path19.slice(prefix.length));
|
|
206660
|
+
} catch {
|
|
206661
|
+
edited.clear();
|
|
206662
|
+
dirty = names2;
|
|
206663
|
+
}
|
|
206664
|
+
for (const path19 of dirty)
|
|
206665
|
+
walkMtime(join51(dir, path19), path19.split("/")[0] ?? path19);
|
|
206666
|
+
return edited;
|
|
206667
|
+
}
|
|
206668
|
+
function renderDirectory(memoryDir, relPath, fullPath) {
|
|
206669
|
+
const entries = readdirSync13(fullPath, { withFileTypes: true }).filter((entry) => !isHidden2(entry.name) && (entry.isDirectory() || entry.isFile() && entry.name !== INDEX));
|
|
206670
|
+
const edited = lastEditedByChild(fullPath, entries.map((entry) => entry.name));
|
|
206671
|
+
const shown = entries.sort((a2, b3) => (edited.get(b3.name) ?? 0) - (edited.get(a2.name) ?? 0) || a2.name.localeCompare(b3.name)).slice(0, LIMITS.MEMORY_MAX_ENTRIES);
|
|
206672
|
+
const fileLines = shown.filter((entry) => entry.isFile()).map((entry) => {
|
|
206673
|
+
const description = extname8(entry.name) === ".md" ? readDescription(join51(fullPath, entry.name)) : undefined;
|
|
206674
|
+
return ` <file${descriptionAttr(description)}>${escapeXmlText2(`${relPath}/${entry.name}`)}</file>`;
|
|
206675
|
+
});
|
|
206676
|
+
const dirLines = shown.filter((entry) => entry.isDirectory()).map((entry) => {
|
|
206677
|
+
const description = readIndexDescription(join51(fullPath, entry.name, INDEX));
|
|
206678
|
+
return ` <directory${descriptionAttr(description)}>${escapeXmlText2(`${relPath}/${entry.name}`)}</directory>`;
|
|
206679
|
+
});
|
|
206680
|
+
const tail2 = [
|
|
206681
|
+
`Memory directory: ${memoryDir}`,
|
|
206682
|
+
"Paths in this memory are relative to the memory directory."
|
|
206683
|
+
];
|
|
206684
|
+
if (fileLines.length) {
|
|
206685
|
+
tail2.push("", "<memory_files>", ...fileLines, "</memory_files>");
|
|
206686
|
+
}
|
|
206687
|
+
if (dirLines.length) {
|
|
206688
|
+
tail2.push("", "<deferred-memory>", ...dirLines, "</deferred-memory>");
|
|
206689
|
+
}
|
|
206690
|
+
if (entries.length > LIMITS.MEMORY_MAX_ENTRIES) {
|
|
206691
|
+
tail2.push(`[Output truncated: showing ${LIMITS.MEMORY_MAX_ENTRIES.toLocaleString()} of ${entries.length.toLocaleString()} entries.]`, `[Full listing: ${fullPath}]`);
|
|
206692
|
+
}
|
|
206693
|
+
const tailText = tail2.join(`
|
|
206694
|
+
`);
|
|
206695
|
+
const indexPath = join51(fullPath, INDEX);
|
|
206696
|
+
const open4 = `<memory_content path="${escapeXmlText2(relPath).replace(/"/g, """)}">`;
|
|
206697
|
+
const close = "</memory_content>";
|
|
206698
|
+
let head4;
|
|
206699
|
+
if (existsSync39(indexPath)) {
|
|
206700
|
+
const budget = Math.max(2000, LIMITS.READ_OUTPUT_CHARS - tailText.length - open4.length - close.length - 16);
|
|
206701
|
+
head4 = clampContent(readFileSync32(indexPath, "utf8").trimEnd(), indexPath, budget);
|
|
206702
|
+
} else {
|
|
206703
|
+
head4 = `<note>No ${INDEX} index in this directory.</note>`;
|
|
206704
|
+
}
|
|
206705
|
+
return `${open4}
|
|
206706
|
+
${head4}
|
|
206707
|
+
|
|
206708
|
+
${tailText}
|
|
206709
|
+
${close}`;
|
|
206710
|
+
}
|
|
206711
|
+
function readPrefix(path19, bytes) {
|
|
206712
|
+
const fd = openSync5(path19, "r");
|
|
206713
|
+
try {
|
|
206714
|
+
const buffer = Buffer.alloc(bytes);
|
|
206715
|
+
return buffer.subarray(0, readSync3(fd, buffer, 0, bytes, 0));
|
|
206716
|
+
} finally {
|
|
206717
|
+
closeSync5(fd);
|
|
206718
|
+
}
|
|
206719
|
+
}
|
|
206720
|
+
function renderFile(relPath, fullPath) {
|
|
206721
|
+
const content = readFileSync32(fullPath, "utf8").trimEnd();
|
|
206722
|
+
const open4 = `<memory_content path="${escapeXmlText2(relPath).replace(/"/g, """)}"${descriptionAttr(readDescription(fullPath))}>`;
|
|
206723
|
+
const close = "</memory_content>";
|
|
206724
|
+
return `${open4}
|
|
206725
|
+
${clampContent(content, fullPath, LIMITS.READ_OUTPUT_CHARS - open4.length - close.length - 2)}
|
|
206726
|
+
${close}`;
|
|
206727
|
+
}
|
|
206728
|
+
async function memory2(args) {
|
|
206729
|
+
validateRequiredParams(args, ["path"], "Memory");
|
|
206730
|
+
const memoryDir = resolveMemoryToolDirectory();
|
|
206731
|
+
if (!memoryDir) {
|
|
206732
|
+
throw new Error("Memory() is only available for agents with a MemFS v2 memory directory.");
|
|
206733
|
+
}
|
|
206734
|
+
const raw2 = String(args.path).trim();
|
|
206735
|
+
const relPath = raw2.replace(/\\/g, "/").replace(/^(\.\/)+/, "").replace(/\/+$/, "");
|
|
206736
|
+
if (!relPath || relPath === "." || relPath === INDEX) {
|
|
206737
|
+
throw new Error("The memory root is already in your context. Pass a directory from <deferred-memory>.");
|
|
206738
|
+
}
|
|
206739
|
+
if (raw2.startsWith("/") || /^[A-Za-z]:/.test(raw2)) {
|
|
206740
|
+
throw new Error('Paths are relative to the memory directory, e.g. "projects".');
|
|
206741
|
+
}
|
|
206742
|
+
const segments = relPath.split("/");
|
|
206743
|
+
if (segments.some((s3) => s3 === ".." || s3 === "" || isHidden2(s3))) {
|
|
206744
|
+
throw new Error(`Invalid memory path: ${raw2}`);
|
|
206745
|
+
}
|
|
206746
|
+
if (segments[0] === "skills") {
|
|
206747
|
+
throw new Error(`skills/ is reserved for skills. Use Skill("${segments[1] ?? "<name>"}").`);
|
|
206748
|
+
}
|
|
206749
|
+
const fullPath = join51(memoryDir, ...segments);
|
|
206750
|
+
if (!existsSync39(fullPath)) {
|
|
206751
|
+
const candidates2 = !relPath.endsWith(".md") && existsSync39(`${fullPath}.md`) ? [`${relPath}.md`] : findByBasename(memoryDir, segments[segments.length - 1] ?? relPath);
|
|
206752
|
+
const hint = candidates2.length ? ` Did you mean ${candidates2.join(" or ")}? Paths are relative to the memory directory.` : "";
|
|
206753
|
+
throw new Error(`No memory at ${relPath}.${hint}`);
|
|
206754
|
+
}
|
|
206755
|
+
const realRoot = realpathSync6(memoryDir);
|
|
206756
|
+
const realTarget = realpathSync6(fullPath);
|
|
206757
|
+
if (realTarget !== realRoot && !realTarget.startsWith(realRoot + sep5)) {
|
|
206758
|
+
throw new Error(`Invalid memory path: ${raw2}`);
|
|
206759
|
+
}
|
|
206760
|
+
const stat6 = statSync14(fullPath);
|
|
206761
|
+
if (segments.length === 1 && stat6.isFile()) {
|
|
206762
|
+
throw new Error(`${relPath} is root core memory and is already in your context.`);
|
|
206763
|
+
}
|
|
206764
|
+
if (stat6.isDirectory()) {
|
|
206765
|
+
return { content: renderDirectory(memoryDir, relPath, fullPath) };
|
|
206766
|
+
}
|
|
206767
|
+
if (!stat6.isFile()) {
|
|
206768
|
+
throw new Error(`Not a memory file or directory: ${relPath}`);
|
|
206769
|
+
}
|
|
206770
|
+
if (stat6.size > MAX_FILE_BYTES) {
|
|
206771
|
+
throw new Error(`${relPath} is too large: ${stat6.size} bytes (max ${MAX_FILE_BYTES} bytes).`);
|
|
206772
|
+
}
|
|
206773
|
+
if (readPrefix(fullPath, 8000).includes(0)) {
|
|
206774
|
+
throw new Error(`${relPath} is not a text file. Use Read on ${fullPath} instead.`);
|
|
206775
|
+
}
|
|
206776
|
+
return { content: renderFile(relPath, fullPath) };
|
|
206777
|
+
}
|
|
206778
|
+
var INDEX = "MEMORY.md", MAX_FILE_BYTES;
|
|
206779
|
+
var init_memory5 = __esm(() => {
|
|
206780
|
+
init_context();
|
|
206781
|
+
init_memory_format();
|
|
206782
|
+
init_memory_runtime();
|
|
206783
|
+
init_truncation();
|
|
206784
|
+
MAX_FILE_BYTES = 10 * 1024 * 1024;
|
|
206785
|
+
});
|
|
206786
|
+
|
|
206481
206787
|
// node_modules/@isaacs/balanced-match/dist/esm/index.js
|
|
206482
206788
|
var balanced = (a2, b3, str) => {
|
|
206483
206789
|
const ma = a2 instanceof RegExp ? maybeMatch(a2, str) : a2;
|
|
@@ -207799,7 +208105,7 @@ var minimatch = (p2, pattern4, options = {}) => {
|
|
|
207799
208105
|
}, qmarksTestNoExtDot = ([$0]) => {
|
|
207800
208106
|
const len = $0.length;
|
|
207801
208107
|
return (f4) => f4.length === len && f4 !== "." && f4 !== "..";
|
|
207802
|
-
}, defaultPlatform, path19,
|
|
208108
|
+
}, defaultPlatform, path19, sep6, GLOBSTAR, qmark2 = "[^/]", star2, twoStarDot = "(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?", twoStarNoDot = "(?:(?!(?:\\/|^)\\.).)*?", filter2 = (pattern4, options = {}) => (p2) => minimatch(p2, pattern4, options), ext = (a2, b3 = {}) => Object.assign({}, a2, b3), defaults5 = (def) => {
|
|
207803
208109
|
if (!def || typeof def !== "object" || !Object.keys(def).length) {
|
|
207804
208110
|
return minimatch;
|
|
207805
208111
|
}
|
|
@@ -207861,8 +208167,8 @@ var init_esm3 = __esm(() => {
|
|
|
207861
208167
|
win32: { sep: "\\" },
|
|
207862
208168
|
posix: { sep: "/" }
|
|
207863
208169
|
};
|
|
207864
|
-
|
|
207865
|
-
minimatch.sep =
|
|
208170
|
+
sep6 = defaultPlatform === "win32" ? path19.win32.sep : path19.posix.sep;
|
|
208171
|
+
minimatch.sep = sep6;
|
|
207866
208172
|
GLOBSTAR = Symbol("globstar **");
|
|
207867
208173
|
minimatch.GLOBSTAR = GLOBSTAR;
|
|
207868
208174
|
star2 = qmark2 + "*?";
|
|
@@ -209753,6 +210059,16 @@ function checkPermissionForEngine(engine4, toolName2, toolArgs, permissions, wor
|
|
|
209753
210059
|
trace
|
|
209754
210060
|
};
|
|
209755
210061
|
}
|
|
210062
|
+
if (toolName2 === "Memory" && !isStrictMode) {
|
|
210063
|
+
traceEvent(trace, "memory-auto-allow", "Memory tool is always allowed");
|
|
210064
|
+
return {
|
|
210065
|
+
result: {
|
|
210066
|
+
decision: "allow",
|
|
210067
|
+
reason: "Memory tool is always allowed (reads own memory)"
|
|
210068
|
+
},
|
|
210069
|
+
trace
|
|
210070
|
+
};
|
|
210071
|
+
}
|
|
209756
210072
|
if (!isStrictMode && isShellToolName(canonicalTool)) {
|
|
209757
210073
|
const shellCommand = extractShellCommand(toolArgs);
|
|
209758
210074
|
if (shellCommand && isReadOnlyShellCommand(shellCommand, {
|
|
@@ -210068,15 +210384,15 @@ __export(exports_loader, {
|
|
|
210068
210384
|
getUserSettingsPaths: () => getUserSettingsPaths
|
|
210069
210385
|
});
|
|
210070
210386
|
import { createHash as createHash4 } from "node:crypto";
|
|
210071
|
-
import { readFileSync as
|
|
210387
|
+
import { readFileSync as readFileSync33, statSync as statSync15, watch } from "node:fs";
|
|
210072
210388
|
import { homedir as homedir26 } from "node:os";
|
|
210073
|
-
import { dirname as dirname21, join as
|
|
210389
|
+
import { dirname as dirname21, join as join52, resolve as resolve25 } from "node:path";
|
|
210074
210390
|
function getUserSettingsPaths(options = {}) {
|
|
210075
210391
|
const homeDir = options.homeDir || homedir26();
|
|
210076
|
-
const xdgConfigHome = options.xdgConfigHome || process.env.XDG_CONFIG_HOME ||
|
|
210392
|
+
const xdgConfigHome = options.xdgConfigHome || process.env.XDG_CONFIG_HOME || join52(homeDir, ".config");
|
|
210077
210393
|
return {
|
|
210078
|
-
canonical:
|
|
210079
|
-
legacy:
|
|
210394
|
+
canonical: join52(homeDir, ".letta", "settings.json"),
|
|
210395
|
+
legacy: join52(xdgConfigHome, "letta", "settings.json")
|
|
210080
210396
|
};
|
|
210081
210397
|
}
|
|
210082
210398
|
function getPermissionSourcePaths(workingDirectory) {
|
|
@@ -210084,13 +210400,13 @@ function getPermissionSourcePaths(workingDirectory) {
|
|
|
210084
210400
|
return [
|
|
210085
210401
|
legacyUserSettingsPath,
|
|
210086
210402
|
userSettingsPath,
|
|
210087
|
-
|
|
210088
|
-
|
|
210403
|
+
join52(workingDirectory, ".letta", "settings.json"),
|
|
210404
|
+
join52(workingDirectory, ".letta", "settings.local.json")
|
|
210089
210405
|
];
|
|
210090
210406
|
}
|
|
210091
210407
|
function getFileSignature(path20) {
|
|
210092
210408
|
try {
|
|
210093
|
-
const stat6 =
|
|
210409
|
+
const stat6 = statSync15(path20);
|
|
210094
210410
|
if (!stat6.isFile()) {
|
|
210095
210411
|
return { exists: false };
|
|
210096
210412
|
}
|
|
@@ -210098,7 +210414,7 @@ function getFileSignature(path20) {
|
|
|
210098
210414
|
exists: true,
|
|
210099
210415
|
mtimeMs: stat6.mtimeMs,
|
|
210100
210416
|
size: stat6.size,
|
|
210101
|
-
hash: createHash4("sha256").update(
|
|
210417
|
+
hash: createHash4("sha256").update(readFileSync33(path20)).digest("hex")
|
|
210102
210418
|
};
|
|
210103
210419
|
} catch {
|
|
210104
210420
|
return { exists: false };
|
|
@@ -210279,10 +210595,10 @@ async function savePermissionRule(rule, ruleType, scope, workingDirectory = proc
|
|
|
210279
210595
|
settingsPath = getUserSettingsPaths().canonical;
|
|
210280
210596
|
break;
|
|
210281
210597
|
case "project":
|
|
210282
|
-
settingsPath =
|
|
210598
|
+
settingsPath = join52(normalizedWorkingDirectory, ".letta", "settings.json");
|
|
210283
210599
|
break;
|
|
210284
210600
|
case "local":
|
|
210285
|
-
settingsPath =
|
|
210601
|
+
settingsPath = join52(normalizedWorkingDirectory, ".letta", "settings.local.json");
|
|
210286
210602
|
break;
|
|
210287
210603
|
}
|
|
210288
210604
|
let settings3 = {};
|
|
@@ -210309,7 +210625,7 @@ async function savePermissionRule(rule, ruleType, scope, workingDirectory = proc
|
|
|
210309
210625
|
}
|
|
210310
210626
|
}
|
|
210311
210627
|
async function ensureLocalSettingsIgnored(workingDirectory) {
|
|
210312
|
-
const gitignorePath =
|
|
210628
|
+
const gitignorePath = join52(workingDirectory, ".gitignore");
|
|
210313
210629
|
const pattern4 = ".letta/settings.local.json";
|
|
210314
210630
|
try {
|
|
210315
210631
|
let content = "";
|
|
@@ -211262,19 +211578,19 @@ var init_approval_result_normalization = __esm(() => {
|
|
|
211262
211578
|
|
|
211263
211579
|
// src/agent/client-skills-watcher.ts
|
|
211264
211580
|
import {
|
|
211265
|
-
existsSync as
|
|
211266
|
-
readdirSync as
|
|
211267
|
-
realpathSync as
|
|
211268
|
-
statSync as
|
|
211581
|
+
existsSync as existsSync40,
|
|
211582
|
+
readdirSync as readdirSync14,
|
|
211583
|
+
realpathSync as realpathSync7,
|
|
211584
|
+
statSync as statSync16,
|
|
211269
211585
|
watch as watch2
|
|
211270
211586
|
} from "node:fs";
|
|
211271
|
-
import { dirname as dirname23, relative as relative6, resolve as resolve27, sep as
|
|
211587
|
+
import { dirname as dirname23, relative as relative6, resolve as resolve27, sep as sep7 } from "node:path";
|
|
211272
211588
|
function defaultWatchFunction(path20, options, listener) {
|
|
211273
211589
|
return watch2(path20, options, listener);
|
|
211274
211590
|
}
|
|
211275
211591
|
function isDirectory(path20) {
|
|
211276
211592
|
try {
|
|
211277
|
-
return
|
|
211593
|
+
return statSync16(path20).isDirectory();
|
|
211278
211594
|
} catch {
|
|
211279
211595
|
return false;
|
|
211280
211596
|
}
|
|
@@ -211293,7 +211609,7 @@ function findNearestExistingDirectory(path20) {
|
|
|
211293
211609
|
function collectSymlinkDirectoryTargets(path20, targets, visited2) {
|
|
211294
211610
|
let realPath;
|
|
211295
211611
|
try {
|
|
211296
|
-
realPath =
|
|
211612
|
+
realPath = realpathSync7(path20);
|
|
211297
211613
|
} catch {
|
|
211298
211614
|
return;
|
|
211299
211615
|
}
|
|
@@ -211302,7 +211618,7 @@ function collectSymlinkDirectoryTargets(path20, targets, visited2) {
|
|
|
211302
211618
|
}
|
|
211303
211619
|
visited2.add(realPath);
|
|
211304
211620
|
try {
|
|
211305
|
-
const entries =
|
|
211621
|
+
const entries = readdirSync14(path20, {
|
|
211306
211622
|
encoding: "utf8",
|
|
211307
211623
|
withFileTypes: true
|
|
211308
211624
|
});
|
|
@@ -211313,7 +211629,7 @@ function collectSymlinkDirectoryTargets(path20, targets, visited2) {
|
|
|
211313
211629
|
continue;
|
|
211314
211630
|
}
|
|
211315
211631
|
try {
|
|
211316
|
-
targets.add(
|
|
211632
|
+
targets.add(realpathSync7(entryPath));
|
|
211317
211633
|
} catch {
|
|
211318
211634
|
continue;
|
|
211319
211635
|
}
|
|
@@ -211362,13 +211678,13 @@ class ClientSkillsWatcher {
|
|
|
211362
211678
|
const watchPaths = new Set;
|
|
211363
211679
|
let recursive = false;
|
|
211364
211680
|
let awaitedChild = null;
|
|
211365
|
-
if (
|
|
211681
|
+
if (existsSync40(root2)) {
|
|
211366
211682
|
recursive = true;
|
|
211367
211683
|
watchPaths.add(root2);
|
|
211368
211684
|
collectSymlinkDirectoryTargets(root2, watchPaths, new Set);
|
|
211369
211685
|
} else {
|
|
211370
211686
|
watchPaths.add(existingDirectory);
|
|
211371
|
-
awaitedChild = relative6(existingDirectory, root2).split(
|
|
211687
|
+
awaitedChild = relative6(existingDirectory, root2).split(sep7)[0] ?? null;
|
|
211372
211688
|
}
|
|
211373
211689
|
const watchers2 = [];
|
|
211374
211690
|
const invalidate = () => {
|
|
@@ -211415,16 +211731,16 @@ __export(exports_skills2, {
|
|
|
211415
211731
|
PROJECT_SKILLS_DIR: () => PROJECT_SKILLS_DIR,
|
|
211416
211732
|
GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR
|
|
211417
211733
|
});
|
|
211418
|
-
import { existsSync as
|
|
211734
|
+
import { existsSync as existsSync41 } from "node:fs";
|
|
211419
211735
|
import { readdir as readdir4, readFile as readFile12, realpath as realpath3, stat as stat6 } from "node:fs/promises";
|
|
211420
|
-
import { dirname as dirname24, join as
|
|
211736
|
+
import { dirname as dirname24, join as join53 } from "node:path";
|
|
211421
211737
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
211422
211738
|
function getBundledSkillsPath() {
|
|
211423
211739
|
const thisDir = dirname24(fileURLToPath6(import.meta.url));
|
|
211424
211740
|
if (thisDir.includes("src/agent") || thisDir.includes("src\\agent")) {
|
|
211425
|
-
return
|
|
211741
|
+
return join53(thisDir, "../skills/builtin");
|
|
211426
211742
|
}
|
|
211427
|
-
return
|
|
211743
|
+
return join53(thisDir, "skills");
|
|
211428
211744
|
}
|
|
211429
211745
|
function compareSkills(a2, b3) {
|
|
211430
211746
|
return a2.id.localeCompare(b3.id) || a2.source.localeCompare(b3.source) || a2.path.localeCompare(b3.path);
|
|
@@ -211471,7 +211787,7 @@ function isSkillAvailableForAgent(skill, agentId) {
|
|
|
211471
211787
|
return true;
|
|
211472
211788
|
}
|
|
211473
211789
|
function getAgentSkillsDir(agentId) {
|
|
211474
|
-
return
|
|
211790
|
+
return join53(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents", agentId, "memory/skills");
|
|
211475
211791
|
}
|
|
211476
211792
|
async function getBundledSkills() {
|
|
211477
211793
|
const bundledPath = getBundledSkillsPath();
|
|
@@ -211480,7 +211796,7 @@ async function getBundledSkills() {
|
|
|
211480
211796
|
}
|
|
211481
211797
|
async function discoverSkillsFromDir(skillsPath, source) {
|
|
211482
211798
|
const errors4 = [];
|
|
211483
|
-
if (!
|
|
211799
|
+
if (!existsSync41(skillsPath)) {
|
|
211484
211800
|
return { skills: [], errors: [] };
|
|
211485
211801
|
}
|
|
211486
211802
|
const skills = [];
|
|
@@ -211494,7 +211810,7 @@ async function discoverSkillsFromDir(skillsPath, source) {
|
|
|
211494
211810
|
}
|
|
211495
211811
|
return { skills, errors: errors4 };
|
|
211496
211812
|
}
|
|
211497
|
-
async function discoverSkills(projectSkillsPath =
|
|
211813
|
+
async function discoverSkills(projectSkillsPath = join53(process.cwd(), SKILLS_DIR), agentId, options) {
|
|
211498
211814
|
const allErrors = [];
|
|
211499
211815
|
const skillsById = new Map;
|
|
211500
211816
|
const sourceSet = new Set(options?.sources ?? ALL_SKILL_SOURCES);
|
|
@@ -211549,7 +211865,7 @@ async function findSkillFiles(currentPath, rootPath, skills, errors4, source, vi
|
|
|
211549
211865
|
try {
|
|
211550
211866
|
const entries = await readdir4(currentPath, { withFileTypes: true });
|
|
211551
211867
|
for (const entry of entries) {
|
|
211552
|
-
const fullPath =
|
|
211868
|
+
const fullPath = join53(currentPath, entry.name);
|
|
211553
211869
|
try {
|
|
211554
211870
|
let isDirectory2 = entry.isDirectory();
|
|
211555
211871
|
let isFile = entry.isFile();
|
|
@@ -211645,13 +211961,13 @@ var init_skills5 = __esm(() => {
|
|
|
211645
211961
|
"managing-shared-memory",
|
|
211646
211962
|
"working-across-computers"
|
|
211647
211963
|
]);
|
|
211648
|
-
PROJECT_SKILLS_DIR =
|
|
211649
|
-
GLOBAL_SKILLS_DIR =
|
|
211964
|
+
PROJECT_SKILLS_DIR = join53(".agents", "skills");
|
|
211965
|
+
GLOBAL_SKILLS_DIR = join53(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
|
|
211650
211966
|
});
|
|
211651
211967
|
|
|
211652
211968
|
// src/agent/shared-memory-skills.ts
|
|
211653
|
-
import { existsSync as
|
|
211654
|
-
import { dirname as dirname25, join as
|
|
211969
|
+
import { existsSync as existsSync42 } from "node:fs";
|
|
211970
|
+
import { dirname as dirname25, join as join54 } from "node:path";
|
|
211655
211971
|
function getAttachedRepositoriesCache() {
|
|
211656
211972
|
const global2 = globalThis;
|
|
211657
211973
|
if (!global2[ATTACHED_REPOSITORIES_CACHE_KEY]) {
|
|
@@ -211726,7 +212042,7 @@ async function resolveSharedMemorySkillsContext(options) {
|
|
|
211726
212042
|
for (const repository of repositories.sort((a2, b3) => a2.name.localeCompare(b3.name) || a2.id.localeCompare(b3.id))) {
|
|
211727
212043
|
try {
|
|
211728
212044
|
const repositoryName = validateAgentRepositoryName2(repository.name);
|
|
211729
|
-
skillsDirs.push(
|
|
212045
|
+
skillsDirs.push(join54(getRepositoryMountDir2(agentId, repositoryName), "skills"));
|
|
211730
212046
|
} catch (error4) {
|
|
211731
212047
|
errors4.push({
|
|
211732
212048
|
path: `shared-memory:${repository.name}`,
|
|
@@ -211743,7 +212059,7 @@ async function discoverSharedMemorySkills(skillsDirs) {
|
|
|
211743
212059
|
const repositoryMount = dirname25(dir);
|
|
211744
212060
|
if (isCheckoutPending(repositoryMount))
|
|
211745
212061
|
continue;
|
|
211746
|
-
if (!
|
|
212062
|
+
if (!existsSync42(repositoryMount)) {
|
|
211747
212063
|
errors4.push({
|
|
211748
212064
|
path: repositoryMount,
|
|
211749
212065
|
message: "Attached repository is not mounted locally"
|
|
@@ -211789,8 +212105,8 @@ __export(exports_client_skills, {
|
|
|
211789
212105
|
buildClientSkillsUpdateReminder: () => buildClientSkillsUpdateReminder,
|
|
211790
212106
|
buildClientSkillsPayload: () => buildClientSkillsPayload
|
|
211791
212107
|
});
|
|
211792
|
-
import { existsSync as
|
|
211793
|
-
import { join as
|
|
212108
|
+
import { existsSync as existsSync43 } from "node:fs";
|
|
212109
|
+
import { join as join55, resolve as resolve28 } from "node:path";
|
|
211794
212110
|
function getCache2() {
|
|
211795
212111
|
const global2 = globalThis;
|
|
211796
212112
|
if (!global2[CLIENT_SKILLS_CACHE_KEY]) {
|
|
@@ -211917,12 +212233,12 @@ function buildClientSkillsUpdateReminder(previous, current) {
|
|
|
211917
212233
|
function getMemorySkillsDirs(agentId) {
|
|
211918
212234
|
const dirs = new Set;
|
|
211919
212235
|
const scopedMemoryDir = resolveScopedMemoryDir({ agentId });
|
|
211920
|
-
if (scopedMemoryDir && scopedMemoryDir.trim().length > 0 &&
|
|
211921
|
-
dirs.add(
|
|
212236
|
+
if (scopedMemoryDir && scopedMemoryDir.trim().length > 0 && existsSync43(scopedMemoryDir)) {
|
|
212237
|
+
dirs.add(join55(scopedMemoryDir.trim(), "skills"));
|
|
211922
212238
|
} else {
|
|
211923
212239
|
const fallbackMemoryDir = (process.env.LETTA_MEMORY_DIR || process.env.MEMORY_DIR || "").trim();
|
|
211924
212240
|
if (fallbackMemoryDir) {
|
|
211925
|
-
dirs.add(
|
|
212241
|
+
dirs.add(join55(fallbackMemoryDir, "skills"));
|
|
211926
212242
|
}
|
|
211927
212243
|
}
|
|
211928
212244
|
return Array.from(dirs);
|
|
@@ -211964,8 +212280,8 @@ function toClientSkill(skill) {
|
|
|
211964
212280
|
function resolveSkillDiscoveryContext(options) {
|
|
211965
212281
|
const workingDirectory = options.workingDirectory ?? process.cwd();
|
|
211966
212282
|
const configuredSkillsDirectory = options.skillsDirectory ?? getSkillsDirectory();
|
|
211967
|
-
const legacySkillsDirectory =
|
|
211968
|
-
const primaryProjectSkillsDirectory =
|
|
212283
|
+
const legacySkillsDirectory = join55(workingDirectory, SKILLS_DIR);
|
|
212284
|
+
const primaryProjectSkillsDirectory = join55(workingDirectory, PROJECT_SKILLS_DIR);
|
|
211969
212285
|
const skillSources = options.skillSources ?? getSkillSources();
|
|
211970
212286
|
return {
|
|
211971
212287
|
workingDirectory,
|
|
@@ -212593,6 +212909,14 @@ function filterToolRegistryByClientAllowlist(registry3, clientToolAllowlist) {
|
|
|
212593
212909
|
const allowSet = new Set(clientToolAllowlist);
|
|
212594
212910
|
return new Map(Array.from(registry3.entries()).filter(([internalName]) => matchesClientToolAllowlistEntry(allowSet, getServerToolName(internalName), internalName)));
|
|
212595
212911
|
}
|
|
212912
|
+
function filterMemoryToolByMemoryFormat(registry3, agentId) {
|
|
212913
|
+
if (!registry3.has("Memory") || resolveMemoryToolDirectory(agentId)) {
|
|
212914
|
+
return registry3;
|
|
212915
|
+
}
|
|
212916
|
+
const filtered = new Map(registry3);
|
|
212917
|
+
filtered.delete("Memory");
|
|
212918
|
+
return filtered;
|
|
212919
|
+
}
|
|
212596
212920
|
function filterExternalToolsByRuntimeContext(externalTools, runtimeContext) {
|
|
212597
212921
|
return new Map(Array.from(externalTools.entries()).filter(([, tool]) => {
|
|
212598
212922
|
const matchesRuntime = !tool.runtime || (tool.runtime.agentId ?? null) === (runtimeContext.agentId ?? null) && tool.runtime.conversationId === runtimeContext.conversationId;
|
|
@@ -212809,7 +213133,7 @@ async function executeExternalTool(toolCallId, toolName2, input, executorOverrid
|
|
|
212809
213133
|
}
|
|
212810
213134
|
}
|
|
212811
213135
|
function getClientToolsFromRegistry() {
|
|
212812
|
-
return buildClientToolsFromSnapshot(toolRegistry, selectModelFacingExternalTools(filterExternalToolsByRuntimeContext(getExternalToolsRegistry(), {})), getAvailableModToolsRegistry());
|
|
213136
|
+
return buildClientToolsFromSnapshot(filterMemoryToolByMemoryFormat(toolRegistry, undefined), selectModelFacingExternalTools(filterExternalToolsByRuntimeContext(getExternalToolsRegistry(), {})), getAvailableModToolsRegistry());
|
|
212813
213137
|
}
|
|
212814
213138
|
function buildClientToolsFromSnapshot(registry3, externalTools, modTools) {
|
|
212815
213139
|
return serializeClientTools(registry3, externalTools, modTools, getServerToolName);
|
|
@@ -212817,7 +213141,7 @@ function buildClientToolsFromSnapshot(registry3, externalTools, modTools) {
|
|
|
212817
213141
|
function capturePreparedToolExecutionContext(snapshot2, options) {
|
|
212818
213142
|
const runtimeContext = buildExecutionRuntimeContextSnapshot(options);
|
|
212819
213143
|
const clientToolAllowlist = options?.clientToolAllowlist ?? toolFilter.getEnabledTools() ?? undefined;
|
|
212820
|
-
const toolRegistrySnapshot = applySubagentToolPolicy(filterToolRegistryByClientAllowlist(snapshot2.toolRegistry, clientToolAllowlist), readSubagentDepth(getRuntimeExecutionEnv(process.env, runtimeContext.executionSettings)));
|
|
213144
|
+
const toolRegistrySnapshot = filterMemoryToolByMemoryFormat(applySubagentToolPolicy(filterToolRegistryByClientAllowlist(snapshot2.toolRegistry, clientToolAllowlist), readSubagentDepth(getRuntimeExecutionEnv(process.env, runtimeContext.executionSettings))), runtimeContext.agentId);
|
|
212821
213145
|
const executionSnapshot = {
|
|
212822
213146
|
toolRegistry: toolRegistrySnapshot,
|
|
212823
213147
|
externalTools: selectModelFacingExternalTools(filterExternalToolsByClientAllowlist(filterExternalToolsByScopeIds(filterExternalToolsByRuntimeContext(snapshot2.externalTools, runtimeContext), options?.externalToolScopeIds), clientToolAllowlist), runtimeContext.connectionId),
|
|
@@ -213859,6 +214183,7 @@ var init_manager2 = __esm(async () => {
|
|
|
213859
214183
|
init_subagent_tool_policy();
|
|
213860
214184
|
init_task_tool_assets();
|
|
213861
214185
|
init_tool_name_mapping();
|
|
214186
|
+
init_memory5();
|
|
213862
214187
|
init_toolset_catalog();
|
|
213863
214188
|
await __promiseAll([
|
|
213864
214189
|
init_approval_execution(),
|
|
@@ -217290,7 +217615,7 @@ var init_LS2 = __esm(() => {
|
|
|
217290
217615
|
|
|
217291
217616
|
// src/tools/impl/ls.ts
|
|
217292
217617
|
import { readdir as readdir7, stat as stat9 } from "node:fs/promises";
|
|
217293
|
-
import { isAbsolute as isAbsolute21, join as
|
|
217618
|
+
import { isAbsolute as isAbsolute21, join as join56, resolve as resolve33 } from "node:path";
|
|
217294
217619
|
async function ls(args) {
|
|
217295
217620
|
validateRequiredParams(args, ["path"], "LS");
|
|
217296
217621
|
validateParamTypes(args, LS_default2, "LS");
|
|
@@ -217301,7 +217626,7 @@ async function ls(args) {
|
|
|
217301
217626
|
const items3 = await readdir7(dirPath);
|
|
217302
217627
|
const filteredItems = items3.filter((item) => !ignore.some((pattern4) => import_picomatch.default.isMatch(item, pattern4)));
|
|
217303
217628
|
const fileInfos = await Promise.all(filteredItems.map(async (item) => {
|
|
217304
|
-
const fullPath =
|
|
217629
|
+
const fullPath = join56(dirPath, item);
|
|
217305
217630
|
try {
|
|
217306
217631
|
const stats = await stat9(fullPath);
|
|
217307
217632
|
return {
|
|
@@ -217523,7 +217848,7 @@ var init_monitor_event_stream = __esm(() => {
|
|
|
217523
217848
|
});
|
|
217524
217849
|
|
|
217525
217850
|
// src/tools/impl/monitor.ts
|
|
217526
|
-
import { appendFileSync as appendFileSync6, readFileSync as
|
|
217851
|
+
import { appendFileSync as appendFileSync6, readFileSync as readFileSync34, writeFileSync as writeFileSync25 } from "node:fs";
|
|
217527
217852
|
import { WebSocket as WebSocket4 } from "ws";
|
|
217528
217853
|
function buildMonitorResult(taskId, timeoutMs, persistent, outputFile) {
|
|
217529
217854
|
const lifetime = persistent ? "persistent — runs until TaskStop or session end" : `timeout ${timeoutMs}ms`;
|
|
@@ -217579,7 +217904,7 @@ class MonitorOutputWriter {
|
|
|
217579
217904
|
[output truncated at ${MONITOR_OUTPUT_FILE_BYTES} bytes]
|
|
217580
217905
|
`, "utf8");
|
|
217581
217906
|
try {
|
|
217582
|
-
const content = validUtf8Prefix(Buffer.concat([
|
|
217907
|
+
const content = validUtf8Prefix(Buffer.concat([readFileSync34(this.path), chunk2]), MONITOR_OUTPUT_FILE_BYTES - marker2.length);
|
|
217583
217908
|
const truncatedOutput = Buffer.concat([content, marker2]);
|
|
217584
217909
|
writeFileSync25(this.path, truncatedOutput);
|
|
217585
217910
|
this.bytesWritten = truncatedOutput.length;
|
|
@@ -219852,7 +220177,7 @@ class CodexAppServerClient {
|
|
|
219852
220177
|
await this.request("initialize", {
|
|
219853
220178
|
clientInfo: {
|
|
219854
220179
|
name: "letta-code",
|
|
219855
|
-
version: "0.34.
|
|
220180
|
+
version: "0.34.7"
|
|
219856
220181
|
},
|
|
219857
220182
|
capabilities: null
|
|
219858
220183
|
});
|
|
@@ -221261,7 +221586,7 @@ var init_engine3 = __esm(() => {
|
|
|
221261
221586
|
|
|
221262
221587
|
// src/tools/impl/native-session-capture.ts
|
|
221263
221588
|
import { createHash as createHash5, randomUUID as randomUUID32 } from "node:crypto";
|
|
221264
|
-
import { readdirSync as
|
|
221589
|
+
import { readdirSync as readdirSync15, rmSync as rmSync14 } from "node:fs";
|
|
221265
221590
|
import {
|
|
221266
221591
|
mkdtemp as mkdtemp4,
|
|
221267
221592
|
open as open4,
|
|
@@ -221270,7 +221595,7 @@ import {
|
|
|
221270
221595
|
stat as stat10
|
|
221271
221596
|
} from "node:fs/promises";
|
|
221272
221597
|
import { homedir as homedir28, tmpdir as tmpdir12 } from "node:os";
|
|
221273
|
-
import { join as
|
|
221598
|
+
import { join as join57 } from "node:path";
|
|
221274
221599
|
async function hashNativeSessionPrefix(input, size2) {
|
|
221275
221600
|
const hash3 = createHash5("sha256");
|
|
221276
221601
|
const buffer = Buffer.allocUnsafe(NATIVE_SESSION_CAPTURE_CHUNK_BYTES);
|
|
@@ -221332,7 +221657,7 @@ function scavengeStaleSpoolDirectories() {
|
|
|
221332
221657
|
staleSpoolsScavenged = true;
|
|
221333
221658
|
let entries;
|
|
221334
221659
|
try {
|
|
221335
|
-
entries =
|
|
221660
|
+
entries = readdirSync15(tmpdir12(), { withFileTypes: true });
|
|
221336
221661
|
} catch {
|
|
221337
221662
|
return;
|
|
221338
221663
|
}
|
|
@@ -221355,7 +221680,7 @@ function scavengeStaleSpoolDirectories() {
|
|
|
221355
221680
|
}
|
|
221356
221681
|
}
|
|
221357
221682
|
if (!ownerIsAlive)
|
|
221358
|
-
cleanupSpoolDirectorySync(
|
|
221683
|
+
cleanupSpoolDirectorySync(join57(tmpdir12(), entry.name));
|
|
221359
221684
|
}
|
|
221360
221685
|
}
|
|
221361
221686
|
function key2(source, sessionId) {
|
|
@@ -221508,9 +221833,9 @@ async function findNativeSessionPath(source, sessionId, env6 = process.env) {
|
|
|
221508
221833
|
return;
|
|
221509
221834
|
const home = env6.HOME || homedir28();
|
|
221510
221835
|
if (source === "claude_code") {
|
|
221511
|
-
const projects =
|
|
221836
|
+
const projects = join57(env6.CLAUDE_CONFIG_DIR || join57(home, ".claude"), "projects");
|
|
221512
221837
|
for (const project of await entries(projects, true)) {
|
|
221513
|
-
const path29 =
|
|
221838
|
+
const path29 = join57(projects, project, `${sessionId}.jsonl`);
|
|
221514
221839
|
try {
|
|
221515
221840
|
if ((await stat10(path29)).isFile())
|
|
221516
221841
|
return path29;
|
|
@@ -221521,14 +221846,14 @@ async function findNativeSessionPath(source, sessionId, env6 = process.env) {
|
|
|
221521
221846
|
}
|
|
221522
221847
|
return;
|
|
221523
221848
|
}
|
|
221524
|
-
const root2 =
|
|
221849
|
+
const root2 = join57(env6.CODEX_HOME || join57(home, ".codex"), "sessions");
|
|
221525
221850
|
for (const year of (await entries(root2, true)).filter((name) => /^\d{4}$/.test(name)))
|
|
221526
|
-
for (const month of (await entries(
|
|
221527
|
-
for (const day of (await entries(
|
|
221528
|
-
const directory =
|
|
221851
|
+
for (const month of (await entries(join57(root2, year), true)).filter((name) => /^\d{2}$/.test(name)))
|
|
221852
|
+
for (const day of (await entries(join57(root2, year, month), true)).filter((name) => /^\d{2}$/.test(name))) {
|
|
221853
|
+
const directory = join57(root2, year, month, day);
|
|
221529
221854
|
for (const file of await entries(directory, false))
|
|
221530
221855
|
if (file.startsWith("rollout-") && file.endsWith(`-${sessionId}.jsonl`))
|
|
221531
|
-
return
|
|
221856
|
+
return join57(directory, file);
|
|
221532
221857
|
}
|
|
221533
221858
|
return;
|
|
221534
221859
|
}
|
|
@@ -221545,9 +221870,9 @@ async function seal(state2, source, sessionId, scope, env6, requestOptions) {
|
|
|
221545
221870
|
throw new Error("Native session file disappeared before EOF capture");
|
|
221546
221871
|
throw error4;
|
|
221547
221872
|
}
|
|
221548
|
-
const directory = await mkdtemp4(
|
|
221873
|
+
const directory = await mkdtemp4(join57(tmpdir12(), `letta-native-session-${process.pid}-${captureProcessInstanceId}-`));
|
|
221549
221874
|
spoolDirectories.add(directory);
|
|
221550
|
-
const spoolPath =
|
|
221875
|
+
const spoolPath = join57(directory, "segment");
|
|
221551
221876
|
let output;
|
|
221552
221877
|
let retained = false;
|
|
221553
221878
|
try {
|
|
@@ -221664,7 +221989,7 @@ async function drain(state2, source, sessionId) {
|
|
|
221664
221989
|
await spool.close();
|
|
221665
221990
|
}
|
|
221666
221991
|
state2.segments.shift();
|
|
221667
|
-
const directory =
|
|
221992
|
+
const directory = join57(segment.path, "..");
|
|
221668
221993
|
await cleanupSpoolDirectory(directory);
|
|
221669
221994
|
}
|
|
221670
221995
|
}
|
|
@@ -221696,7 +222021,7 @@ async function discardRejectedSegment(state2) {
|
|
|
221696
222021
|
const segment = state2.segments.shift();
|
|
221697
222022
|
if (!segment)
|
|
221698
222023
|
return;
|
|
221699
|
-
const directory =
|
|
222024
|
+
const directory = join57(segment.path, "..");
|
|
221700
222025
|
await cleanupSpoolDirectory(directory);
|
|
221701
222026
|
state2.ackedOffset = segment.end;
|
|
221702
222027
|
state2.retryDelayMs = INITIAL_DRAIN_RETRY_MS;
|
|
@@ -222702,20 +223027,20 @@ var init_recall_subagent_local = () => {};
|
|
|
222702
223027
|
|
|
222703
223028
|
// src/utils/transcript-paths.ts
|
|
222704
223029
|
import { homedir as homedir29 } from "node:os";
|
|
222705
|
-
import { join as
|
|
223030
|
+
import { join as join58 } from "node:path";
|
|
222706
223031
|
function getTranscriptRoot() {
|
|
222707
223032
|
const envRoot = process.env[TRANSCRIPT_ROOT_ENV]?.trim();
|
|
222708
223033
|
if (envRoot) {
|
|
222709
223034
|
return envRoot;
|
|
222710
223035
|
}
|
|
222711
|
-
return
|
|
223036
|
+
return join58(homedir29(), ".letta", "transcripts");
|
|
222712
223037
|
}
|
|
222713
223038
|
var TRANSCRIPT_ROOT_ENV = "LETTA_TRANSCRIPT_ROOT";
|
|
222714
223039
|
var init_transcript_paths = () => {};
|
|
222715
223040
|
|
|
222716
223041
|
// src/agent/subagents/sandbox.ts
|
|
222717
223042
|
import { mkdirSync as mkdirSync30 } from "node:fs";
|
|
222718
|
-
import { join as
|
|
223043
|
+
import { join as join59 } from "node:path";
|
|
222719
223044
|
function wrapSubagentLauncher(input) {
|
|
222720
223045
|
const env6 = input.env ?? process.env;
|
|
222721
223046
|
if (!isFsSandboxEnabled(env6))
|
|
@@ -222758,7 +223083,7 @@ function wrapSubagentLauncher(input) {
|
|
|
222758
223083
|
if (!wrapped || wrapped.length === 0)
|
|
222759
223084
|
return null;
|
|
222760
223085
|
const [command, ...args] = wrapped;
|
|
222761
|
-
const scratchRoot =
|
|
223086
|
+
const scratchRoot = join59(getLettaHomeRoot(), "tmp");
|
|
222762
223087
|
mkdirSync30(scratchRoot, { recursive: true });
|
|
222763
223088
|
return {
|
|
222764
223089
|
command,
|
|
@@ -224065,7 +224390,7 @@ var MEMORY_WORKER_SESSION_ENV = "LETTA_MEMORY_WORKER_SESSION";
|
|
|
224065
224390
|
|
|
224066
224391
|
// src/agent/subagents/subagent-launcher.ts
|
|
224067
224392
|
import { homedir as homedir30 } from "node:os";
|
|
224068
|
-
import { join as
|
|
224393
|
+
import { join as join60 } from "node:path";
|
|
224069
224394
|
function resolveSubagentWorkingDirectory(env6 = process.env, fallbackCwd = getCurrentWorkingDirectory(), options = {}) {
|
|
224070
224395
|
if (options.subagentType === "reflection" && options.launchProfile === "memory-subagent" && options.memoryScope) {
|
|
224071
224396
|
return env6.USER_CWD || fallbackCwd;
|
|
@@ -224123,9 +224448,9 @@ function resolveMemorySubagentScratchpad(parentProcessEnv, subagentId) {
|
|
|
224123
224448
|
return configuredScratchpad;
|
|
224124
224449
|
}
|
|
224125
224450
|
const configuredTranscriptRoot = parentProcessEnv[TRANSCRIPT_ROOT_ENV];
|
|
224126
|
-
const transcriptRoot = configuredTranscriptRoot?.trim() ||
|
|
224451
|
+
const transcriptRoot = configuredTranscriptRoot?.trim() || join60(parentProcessEnv.HOME?.trim() || homedir30(), ".letta", "transcripts");
|
|
224127
224452
|
const scope = subagentId ? encodeURIComponent(subagentId) : crypto.randomUUID();
|
|
224128
|
-
return
|
|
224453
|
+
return join60(transcriptRoot, "background", scope);
|
|
224129
224454
|
}
|
|
224130
224455
|
function composeSubagentChildEnv(options) {
|
|
224131
224456
|
const {
|
|
@@ -224695,7 +225020,7 @@ var init_manager4 = __esm(async () => {
|
|
|
224695
225020
|
import { execFile as execFile16 } from "node:child_process";
|
|
224696
225021
|
import { randomUUID as randomUUID36 } from "node:crypto";
|
|
224697
225022
|
import { readFile as readFile15, rm as rm9, writeFile as writeFile13 } from "node:fs/promises";
|
|
224698
|
-
import { join as
|
|
225023
|
+
import { join as join61 } from "node:path";
|
|
224699
225024
|
import { promisify as promisify16 } from "node:util";
|
|
224700
225025
|
async function readOptional(path29) {
|
|
224701
225026
|
try {
|
|
@@ -224716,7 +225041,7 @@ async function describeMemoryConflict(memoryDir, gitDir) {
|
|
|
224716
225041
|
]);
|
|
224717
225042
|
head4 = stdout.trim();
|
|
224718
225043
|
} catch {}
|
|
224719
|
-
const heads = await Promise.all(OPERATION_HEADS.map((name) => readOptional(
|
|
225044
|
+
const heads = await Promise.all(OPERATION_HEADS.map((name) => readOptional(join61(gitDir, name))));
|
|
224720
225045
|
return [head4, ...heads].join(`
|
|
224721
225046
|
`);
|
|
224722
225047
|
}
|
|
@@ -224736,7 +225061,7 @@ ${stdout.trim()}`;
|
|
|
224736
225061
|
}
|
|
224737
225062
|
}
|
|
224738
225063
|
async function attemptPath(memoryDir) {
|
|
224739
|
-
return
|
|
225064
|
+
return join61(await getMemoryGitDir(memoryDir), ATTEMPT_FILE);
|
|
224740
225065
|
}
|
|
224741
225066
|
async function readAttempt(path29) {
|
|
224742
225067
|
try {
|
|
@@ -224770,7 +225095,7 @@ async function claimMemoryConflictRepair(memoryDir, kind = "conflict") {
|
|
|
224770
225095
|
let signature;
|
|
224771
225096
|
try {
|
|
224772
225097
|
const gitDir = await getMemoryGitDir(memoryDir);
|
|
224773
|
-
path29 =
|
|
225098
|
+
path29 = join61(gitDir, ATTEMPT_FILE);
|
|
224774
225099
|
signature = kind === "invalid" ? await describeInvalidMemoryHistory(memoryDir) : await describeMemoryConflict(memoryDir, gitDir);
|
|
224775
225100
|
} catch {
|
|
224776
225101
|
return { status: "claimed", token: token2 };
|
|
@@ -224832,7 +225157,7 @@ var init_memory_conflict_repair = __esm(() => {
|
|
|
224832
225157
|
// src/agent/subagents/memory-handoff.ts
|
|
224833
225158
|
import { randomUUID as randomUUID37 } from "node:crypto";
|
|
224834
225159
|
import { mkdir as mkdir11, rm as rm10, writeFile as writeFile14 } from "node:fs/promises";
|
|
224835
|
-
import { join as
|
|
225160
|
+
import { join as join62 } from "node:path";
|
|
224836
225161
|
async function withMemoryHandoff(params, run) {
|
|
224837
225162
|
const handoff = await prepareMemoryHandoff(params);
|
|
224838
225163
|
try {
|
|
@@ -224867,9 +225192,9 @@ async function prepareMemoryHandoff(params) {
|
|
|
224867
225192
|
break;
|
|
224868
225193
|
after2 = cursor;
|
|
224869
225194
|
}
|
|
224870
|
-
const directory =
|
|
225195
|
+
const directory = join62(getTranscriptRoot(), params.agentId, "memory-handoffs");
|
|
224871
225196
|
await mkdir11(directory, { recursive: true, mode: 448 });
|
|
224872
|
-
transcriptPath =
|
|
225197
|
+
transcriptPath = join62(directory, `${randomUUID37()}.json`);
|
|
224873
225198
|
await writeFile14(transcriptPath, JSON.stringify(messages, null, 2), {
|
|
224874
225199
|
mode: 292,
|
|
224875
225200
|
flag: "wx"
|
|
@@ -224932,9 +225257,9 @@ var init_memory_operation = __esm(() => {
|
|
|
224932
225257
|
// src/agent/memory-worktree.ts
|
|
224933
225258
|
import { execFile as execFileCb4 } from "node:child_process";
|
|
224934
225259
|
import { randomUUID as randomUUID38 } from "node:crypto";
|
|
224935
|
-
import { existsSync as
|
|
225260
|
+
import { existsSync as existsSync44 } from "node:fs";
|
|
224936
225261
|
import { mkdir as mkdir12 } from "node:fs/promises";
|
|
224937
|
-
import { dirname as dirname26, isAbsolute as isAbsolute23, join as
|
|
225262
|
+
import { dirname as dirname26, isAbsolute as isAbsolute23, join as join63, resolve as resolve36 } from "node:path";
|
|
224938
225263
|
import { promisify as promisify17 } from "node:util";
|
|
224939
225264
|
async function runGit4(cwd2, args) {
|
|
224940
225265
|
try {
|
|
@@ -224994,9 +225319,9 @@ async function buildReflectionMergeMessage(parentMemoryDir, branchName) {
|
|
|
224994
225319
|
async function createReflectionMemoryWorktree(options) {
|
|
224995
225320
|
const parentMemoryDir = resolve36(options.parentMemoryDir);
|
|
224996
225321
|
const id2 = buildReflectionWorktreeId(options.now);
|
|
224997
|
-
const worktreeBaseDir =
|
|
225322
|
+
const worktreeBaseDir = join63(dirname26(parentMemoryDir), "memory-worktrees");
|
|
224998
225323
|
const label = options.label ?? "reflection";
|
|
224999
|
-
const worktreeDir =
|
|
225324
|
+
const worktreeDir = join63(worktreeBaseDir, `${label}-${id2}`);
|
|
225000
225325
|
const branchName = `letta/${label}/${id2}`;
|
|
225001
225326
|
await mkdir12(worktreeBaseDir, { recursive: true });
|
|
225002
225327
|
const { stdout: baseHeadOut } = await runGit4(parentMemoryDir, [
|
|
@@ -225124,7 +225449,7 @@ async function inspectReflectionMemoryWorktree(worktree) {
|
|
|
225124
225449
|
};
|
|
225125
225450
|
}
|
|
225126
225451
|
async function cleanupWorktreeAndBranch(parentMemoryDir, worktreeDir, branchName, options = {}) {
|
|
225127
|
-
const removedWorktree =
|
|
225452
|
+
const removedWorktree = existsSync44(worktreeDir);
|
|
225128
225453
|
if (removedWorktree) {
|
|
225129
225454
|
await runGit4(parentMemoryDir, [
|
|
225130
225455
|
"worktree",
|
|
@@ -225140,7 +225465,7 @@ async function cleanupWorktreeAndBranch(parentMemoryDir, worktreeDir, branchName
|
|
|
225140
225465
|
]);
|
|
225141
225466
|
}
|
|
225142
225467
|
async function finalizeReflectionMemoryWorktreeUnlocked(worktree, options) {
|
|
225143
|
-
if (!
|
|
225468
|
+
if (!existsSync44(worktree.worktreeDir) && options.knownNoChanges) {
|
|
225144
225469
|
const branchHead = (await tryRunGit(worktree.parentMemoryDir, [
|
|
225145
225470
|
"rev-parse",
|
|
225146
225471
|
"--verify",
|
|
@@ -225327,7 +225652,7 @@ async function integrateMemoryWorkerWorktree(worktree, options = {}) {
|
|
|
225327
225652
|
await cleanup(true);
|
|
225328
225653
|
return { status: "no_changes" };
|
|
225329
225654
|
}
|
|
225330
|
-
if (
|
|
225655
|
+
if (existsSync44(worktree.worktreeDir)) {
|
|
225331
225656
|
await runGit4(worktree.parentMemoryDir, [
|
|
225332
225657
|
"worktree",
|
|
225333
225658
|
"remove",
|
|
@@ -226628,9 +226953,9 @@ __export(exports_skill, {
|
|
|
226628
226953
|
loadRenderedSkillContent: () => loadRenderedSkillContent,
|
|
226629
226954
|
getResolvedSkillsDir: () => getResolvedSkillsDir
|
|
226630
226955
|
});
|
|
226631
|
-
import { existsSync as
|
|
226956
|
+
import { existsSync as existsSync45, readdirSync as readdirSync16 } from "node:fs";
|
|
226632
226957
|
import { readFile as readFile16 } from "node:fs/promises";
|
|
226633
|
-
import { dirname as dirname27, join as
|
|
226958
|
+
import { dirname as dirname27, join as join64 } from "node:path";
|
|
226634
226959
|
async function readSkillFromRoot(skillsRoot, skillId) {
|
|
226635
226960
|
const discovery = await discoverSkills(skillsRoot, undefined, {
|
|
226636
226961
|
sources: ["project"],
|
|
@@ -226650,12 +226975,12 @@ async function readSkillFromRoot(skillsRoot, skillId) {
|
|
|
226650
226975
|
function getMemorySkillsDirs2(agentId) {
|
|
226651
226976
|
const dirs = new Set;
|
|
226652
226977
|
const scopedMemoryDir = resolveScopedMemoryDir({ agentId });
|
|
226653
|
-
if (scopedMemoryDir && scopedMemoryDir.trim().length > 0 &&
|
|
226654
|
-
dirs.add(
|
|
226978
|
+
if (scopedMemoryDir && scopedMemoryDir.trim().length > 0 && existsSync45(scopedMemoryDir)) {
|
|
226979
|
+
dirs.add(join64(scopedMemoryDir.trim(), "skills"));
|
|
226655
226980
|
} else {
|
|
226656
226981
|
const fallbackMemoryDir = (process.env.LETTA_MEMORY_DIR || process.env.MEMORY_DIR || "").trim();
|
|
226657
226982
|
if (fallbackMemoryDir) {
|
|
226658
|
-
dirs.add(
|
|
226983
|
+
dirs.add(join64(fallbackMemoryDir, "skills"));
|
|
226659
226984
|
}
|
|
226660
226985
|
}
|
|
226661
226986
|
return Array.from(dirs);
|
|
@@ -226667,7 +226992,7 @@ function listSkillResources(skillMdPath) {
|
|
|
226667
226992
|
function walk3(directory, relativeDirectory) {
|
|
226668
226993
|
let entries2;
|
|
226669
226994
|
try {
|
|
226670
|
-
entries2 =
|
|
226995
|
+
entries2 = readdirSync16(directory, { withFileTypes: true });
|
|
226671
226996
|
} catch {
|
|
226672
226997
|
return;
|
|
226673
226998
|
}
|
|
@@ -226681,7 +227006,7 @@ function listSkillResources(skillMdPath) {
|
|
|
226681
227006
|
return;
|
|
226682
227007
|
}
|
|
226683
227008
|
if (entry.isDirectory()) {
|
|
226684
|
-
walk3(
|
|
227009
|
+
walk3(join64(directory, entry.name), relativePath);
|
|
226685
227010
|
if (truncated) {
|
|
226686
227011
|
return;
|
|
226687
227012
|
}
|
|
@@ -226695,7 +227020,7 @@ function listSkillResources(skillMdPath) {
|
|
|
226695
227020
|
}
|
|
226696
227021
|
async function readSkillContent(skillId, skillsDir, agentId, options = {}) {
|
|
226697
227022
|
const projectSkillsDirs = new Set([
|
|
226698
|
-
|
|
227023
|
+
join64(getCurrentWorkingDirectory(), PROJECT_SKILLS_DIR),
|
|
226699
227024
|
skillsDir
|
|
226700
227025
|
]);
|
|
226701
227026
|
for (const projectSkillsDir of projectSkillsDirs) {
|
|
@@ -226743,8 +227068,8 @@ async function readSkillContent(skillId, skillsDir, agentId, options = {}) {
|
|
|
226743
227068
|
} catch {}
|
|
226744
227069
|
}
|
|
226745
227070
|
try {
|
|
226746
|
-
const bundledSkillsDir =
|
|
226747
|
-
const bundledSkillPath =
|
|
227071
|
+
const bundledSkillsDir = join64(process.cwd(), "skills", "skills");
|
|
227072
|
+
const bundledSkillPath = join64(bundledSkillsDir, skillId, "SKILL.md");
|
|
226748
227073
|
const content = await readFile16(bundledSkillPath, "utf-8");
|
|
226749
227074
|
return { content, path: bundledSkillPath };
|
|
226750
227075
|
} catch {
|
|
@@ -226756,7 +227081,7 @@ async function getResolvedSkillsDir() {
|
|
|
226756
227081
|
if (skillsDir) {
|
|
226757
227082
|
return skillsDir;
|
|
226758
227083
|
}
|
|
226759
|
-
return
|
|
227084
|
+
return join64(getCurrentWorkingDirectory(), SKILLS_DIR);
|
|
226760
227085
|
}
|
|
226761
227086
|
function getResolvedAgentId(args) {
|
|
226762
227087
|
if (args.parentScope?.agentId) {
|
|
@@ -226776,7 +227101,7 @@ function renderSkillContent(skillName, skillContent, skillPath, options = {}) {
|
|
|
226776
227101
|
const skillDir = dirname27(skillPath);
|
|
226777
227102
|
const withSkillDir = skillContent.replace(/<SKILL_DIR>/g, skillDir).replace(/\$\{CLAUDE_SKILL_DIR\}/g, skillDir);
|
|
226778
227103
|
const resources = listSkillResources(skillPath);
|
|
226779
|
-
const resourceLines = resources.paths.map((resourcePath) => ` <file>${
|
|
227104
|
+
const resourceLines = resources.paths.map((resourcePath) => ` <file>${escapeXmlText3(resourcePath)}</file>`);
|
|
226780
227105
|
if (resources.truncated) {
|
|
226781
227106
|
resourceLines.push(" <truncated>true</truncated>");
|
|
226782
227107
|
}
|
|
@@ -226796,11 +227121,11 @@ async function loadRenderedSkillContent(skillName, options = {}) {
|
|
|
226796
227121
|
const { content: skillContent, path: skillPath } = await readSkillContent(skillName, skillsDir, options.agentId, options);
|
|
226797
227122
|
return renderSkillContent(skillName, skillContent, skillPath, options);
|
|
226798
227123
|
}
|
|
226799
|
-
function
|
|
227124
|
+
function escapeXmlText3(value) {
|
|
226800
227125
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
226801
227126
|
}
|
|
226802
227127
|
function escapeXmlAttribute3(value) {
|
|
226803
|
-
return
|
|
227128
|
+
return escapeXmlText3(value).replace(/"/g, """);
|
|
226804
227129
|
}
|
|
226805
227130
|
function wrapSkillContent(skillName, content) {
|
|
226806
227131
|
return `<skill_content name="${escapeXmlAttribute3(skillName)}">
|
|
@@ -228740,9 +229065,9 @@ function formatWorkflowSummary(stats) {
|
|
|
228740
229065
|
// src/tools/workflow/journal.ts
|
|
228741
229066
|
import { appendFileSync as appendFileSync7, mkdirSync as mkdirSync31, writeFileSync as writeFileSync26 } from "node:fs";
|
|
228742
229067
|
import { homedir as homedir32 } from "node:os";
|
|
228743
|
-
import { join as
|
|
229068
|
+
import { join as join65 } from "node:path";
|
|
228744
229069
|
function defaultExecutionsDir() {
|
|
228745
|
-
return
|
|
229070
|
+
return join65(homedir32(), ".letta", "workflows", "executions");
|
|
228746
229071
|
}
|
|
228747
229072
|
function newExecutionId() {
|
|
228748
229073
|
const alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
@@ -228753,17 +229078,17 @@ function newExecutionId() {
|
|
|
228753
229078
|
return `wf-${suffix}`;
|
|
228754
229079
|
}
|
|
228755
229080
|
function createExecutionDir(executionsDir, executionId, script4, args) {
|
|
228756
|
-
const executionDir =
|
|
229081
|
+
const executionDir = join65(executionsDir, executionId);
|
|
228757
229082
|
mkdirSync31(executionDir, { recursive: true, mode: DIR_MODE });
|
|
228758
|
-
const scriptPath =
|
|
229083
|
+
const scriptPath = join65(executionDir, "script.js");
|
|
228759
229084
|
writeFileSync26(scriptPath, script4, { mode: FILE_MODE });
|
|
228760
229085
|
if (args !== undefined) {
|
|
228761
|
-
writeFileSync26(
|
|
229086
|
+
writeFileSync26(join65(executionDir, "args.json"), JSON.stringify(args, null, 2), { mode: FILE_MODE });
|
|
228762
229087
|
}
|
|
228763
229088
|
return {
|
|
228764
229089
|
executionDir,
|
|
228765
229090
|
scriptPath,
|
|
228766
|
-
journalPath:
|
|
229091
|
+
journalPath: join65(executionDir, "journal.jsonl")
|
|
228767
229092
|
};
|
|
228768
229093
|
}
|
|
228769
229094
|
function appendJournalEntry(journalPath, entry) {
|
|
@@ -228873,9 +229198,9 @@ var init_meta3 = __esm(() => {
|
|
|
228873
229198
|
});
|
|
228874
229199
|
|
|
228875
229200
|
// src/tools/workflow/sdk-loader.ts
|
|
228876
|
-
import { existsSync as
|
|
229201
|
+
import { existsSync as existsSync46, readFileSync as readFileSync35 } from "node:fs";
|
|
228877
229202
|
import { createRequire as createRequire6 } from "node:module";
|
|
228878
|
-
import { dirname as dirname28, join as
|
|
229203
|
+
import { dirname as dirname28, join as join66 } from "node:path";
|
|
228879
229204
|
import { fileURLToPath as fileURLToPath7, pathToFileURL as pathToFileURL3 } from "node:url";
|
|
228880
229205
|
function supportsPublishedResume(version2) {
|
|
228881
229206
|
if (!version2 || !MIN_RESUME_SDK_VERSION)
|
|
@@ -228897,14 +229222,14 @@ function preferRunningCliForSubagents() {
|
|
|
228897
229222
|
if (process.env.LETTA_CLI_PATH)
|
|
228898
229223
|
return;
|
|
228899
229224
|
const entry = process.argv[1];
|
|
228900
|
-
if (entry && /(^|[\\/])letta\.js$/.test(entry) &&
|
|
229225
|
+
if (entry && /(^|[\\/])letta\.js$/.test(entry) && existsSync46(entry)) {
|
|
228901
229226
|
process.env.LETTA_CLI_PATH = entry;
|
|
228902
229227
|
}
|
|
228903
229228
|
}
|
|
228904
229229
|
function packageVersion(entry) {
|
|
228905
229230
|
for (let dir = dirname28(entry);; dir = dirname28(dir)) {
|
|
228906
229231
|
try {
|
|
228907
|
-
const manifest = JSON.parse(
|
|
229232
|
+
const manifest = JSON.parse(readFileSync35(join66(dir, "package.json"), "utf8"));
|
|
228908
229233
|
if (manifest.name === SDK_PACKAGE)
|
|
228909
229234
|
return manifest.version;
|
|
228910
229235
|
} catch {}
|
|
@@ -228914,10 +229239,10 @@ function packageVersion(entry) {
|
|
|
228914
229239
|
}
|
|
228915
229240
|
function packageEntry(packageDir) {
|
|
228916
229241
|
try {
|
|
228917
|
-
const manifest = JSON.parse(
|
|
229242
|
+
const manifest = JSON.parse(readFileSync35(join66(packageDir, "package.json"), "utf8"));
|
|
228918
229243
|
const root2 = manifest.exports?.["."];
|
|
228919
229244
|
const entry = typeof root2 === "string" ? root2 : root2?.import ?? root2?.default ?? manifest.main;
|
|
228920
|
-
return entry ?
|
|
229245
|
+
return entry ? join66(packageDir, entry) : null;
|
|
228921
229246
|
} catch {
|
|
228922
229247
|
return null;
|
|
228923
229248
|
}
|
|
@@ -228927,8 +229252,8 @@ function probeInstalledSdkDirs(startDirs) {
|
|
|
228927
229252
|
for (const start of startDirs) {
|
|
228928
229253
|
let dir = start;
|
|
228929
229254
|
while (true) {
|
|
228930
|
-
const candidate =
|
|
228931
|
-
if (
|
|
229255
|
+
const candidate = join66(dir, "node_modules", ...SDK_PACKAGE.split("/"));
|
|
229256
|
+
if (existsSync46(join66(candidate, "package.json")) && !found.includes(candidate)) {
|
|
228932
229257
|
found.push(candidate);
|
|
228933
229258
|
}
|
|
228934
229259
|
const parent = dirname28(dir);
|
|
@@ -228946,7 +229271,7 @@ async function loadAgentSdk() {
|
|
|
228946
229271
|
const specifiers = [];
|
|
228947
229272
|
if (envPath) {
|
|
228948
229273
|
try {
|
|
228949
|
-
const require2 = createRequire6(
|
|
229274
|
+
const require2 = createRequire6(join66(envPath, "noop.js"));
|
|
228950
229275
|
specifiers.push(pathToFileURL3(require2.resolve(envPath)).href);
|
|
228951
229276
|
} catch {
|
|
228952
229277
|
specifiers.push(pathToFileURL3(envPath).href);
|
|
@@ -228957,7 +229282,7 @@ async function loadAgentSdk() {
|
|
|
228957
229282
|
specifiers.push(pathToFileURL3(require2.resolve(SDK_PACKAGE)).href);
|
|
228958
229283
|
} catch {}
|
|
228959
229284
|
try {
|
|
228960
|
-
const require2 = createRequire6(
|
|
229285
|
+
const require2 = createRequire6(join66(process.cwd(), "package.json"));
|
|
228961
229286
|
specifiers.push(pathToFileURL3(require2.resolve(SDK_PACKAGE)).href);
|
|
228962
229287
|
} catch {
|
|
228963
229288
|
specifiers.push(SDK_PACKAGE);
|
|
@@ -246747,7 +247072,7 @@ var init_mcp_client = __esm(() => {
|
|
|
246747
247072
|
init_streamableHttp();
|
|
246748
247073
|
DEFAULT_CLIENT_INFO = {
|
|
246749
247074
|
name: "letta-code",
|
|
246750
|
-
version: "0.34.
|
|
247075
|
+
version: "0.34.7"
|
|
246751
247076
|
};
|
|
246752
247077
|
});
|
|
246753
247078
|
|
|
@@ -248538,8 +248863,8 @@ var init_mcp = __esm(() => {
|
|
|
248538
248863
|
});
|
|
248539
248864
|
|
|
248540
248865
|
// src/tools/impl/workflow.ts
|
|
248541
|
-
import { readFileSync as
|
|
248542
|
-
import { join as
|
|
248866
|
+
import { readFileSync as readFileSync36 } from "node:fs";
|
|
248867
|
+
import { join as join67, resolve as resolve38 } from "node:path";
|
|
248543
248868
|
function isOwningAgentId(value) {
|
|
248544
248869
|
return value?.startsWith("agent-") === true && !value.startsWith("agent-free:");
|
|
248545
248870
|
}
|
|
@@ -248696,7 +249021,7 @@ function formatCompletionResult(run, executionDir) {
|
|
|
248696
249021
|
return [
|
|
248697
249022
|
payload,
|
|
248698
249023
|
"",
|
|
248699
|
-
`Per-call results: ${
|
|
249024
|
+
`Per-call results: ${join67(executionDir, "journal.jsonl")} — one line per completed agent call with its full return value, plus one per decide() API attempt (retries included) with its model, cost, calibration, and tokens.`,
|
|
248700
249025
|
"If the result above is empty or unexpected, read that file BEFORE diagnosing — do not assume agents returned non-empty results."
|
|
248701
249026
|
].join(`
|
|
248702
249027
|
`);
|
|
@@ -248705,7 +249030,7 @@ async function workflow(args) {
|
|
|
248705
249030
|
let script4 = typeof args.script === "string" ? args.script : undefined;
|
|
248706
249031
|
if (typeof args.scriptPath === "string" && args.scriptPath) {
|
|
248707
249032
|
try {
|
|
248708
|
-
script4 =
|
|
249033
|
+
script4 = readFileSync36(resolve38(getCurrentWorkingDirectory(), args.scriptPath), "utf8");
|
|
248709
249034
|
} catch (error5) {
|
|
248710
249035
|
return {
|
|
248711
249036
|
toolReturn: `Cannot read scriptPath ${args.scriptPath}: ${String(error5)}`,
|
|
@@ -249357,6 +249682,23 @@ var init_Grep2 = __esm(() => {
|
|
|
249357
249682
|
};
|
|
249358
249683
|
});
|
|
249359
249684
|
|
|
249685
|
+
// src/tools/schemas/Memory.json
|
|
249686
|
+
var Memory_default2;
|
|
249687
|
+
var init_Memory2 = __esm(() => {
|
|
249688
|
+
Memory_default2 = {
|
|
249689
|
+
type: "object",
|
|
249690
|
+
properties: {
|
|
249691
|
+
path: {
|
|
249692
|
+
type: "string",
|
|
249693
|
+
description: 'Memory directory or file relative to the memory directory, e.g. "projects", "projects/code", or "projects/example.md".'
|
|
249694
|
+
}
|
|
249695
|
+
},
|
|
249696
|
+
required: ["path"],
|
|
249697
|
+
additionalProperties: false,
|
|
249698
|
+
$schema: "https://json-schema.org/draft/2020-12/schema"
|
|
249699
|
+
};
|
|
249700
|
+
});
|
|
249701
|
+
|
|
249360
249702
|
// src/tools/schemas/Monitor.json
|
|
249361
249703
|
var Monitor_default2;
|
|
249362
249704
|
var init_Monitor2 = __esm(() => {
|
|
@@ -249995,6 +250337,7 @@ var init_tool_definitions = __esm(async () => {
|
|
|
249995
250337
|
init_Glob();
|
|
249996
250338
|
init_Grep();
|
|
249997
250339
|
init_LS();
|
|
250340
|
+
init_Memory();
|
|
249998
250341
|
init_Monitor();
|
|
249999
250342
|
init_Read();
|
|
250000
250343
|
init_ReadArtifactFile();
|
|
@@ -250023,6 +250366,7 @@ var init_tool_definitions = __esm(async () => {
|
|
|
250023
250366
|
init_glob();
|
|
250024
250367
|
init_grep();
|
|
250025
250368
|
init_ls();
|
|
250369
|
+
init_memory5();
|
|
250026
250370
|
init_skill();
|
|
250027
250371
|
init_task_create();
|
|
250028
250372
|
init_task_get();
|
|
@@ -250041,6 +250385,7 @@ var init_tool_definitions = __esm(async () => {
|
|
|
250041
250385
|
init_Glob2();
|
|
250042
250386
|
init_Grep2();
|
|
250043
250387
|
init_LS2();
|
|
250388
|
+
init_Memory2();
|
|
250044
250389
|
init_Monitor2();
|
|
250045
250390
|
init_Read2();
|
|
250046
250391
|
init_ReadArtifactFile2();
|
|
@@ -250173,6 +250518,11 @@ ${WINDOWS_UNIFIED_EXEC_GUIDANCE}`;
|
|
|
250173
250518
|
description: SetWorkingDirectory_default.trim(),
|
|
250174
250519
|
impl: set_working_directory
|
|
250175
250520
|
}),
|
|
250521
|
+
Memory: defineTool({
|
|
250522
|
+
schema: Memory_default2,
|
|
250523
|
+
description: Memory_default.trim(),
|
|
250524
|
+
impl: memory2
|
|
250525
|
+
}),
|
|
250176
250526
|
Skill: defineTool({
|
|
250177
250527
|
schema: Skill_default2,
|
|
250178
250528
|
description: Skill_default.trim(),
|
|
@@ -250400,14 +250750,14 @@ var init_interrupted_turn_schema = __esm(async () => {
|
|
|
250400
250750
|
// src/websocket/listener/interrupted-turn-storage.ts
|
|
250401
250751
|
import { createHash as createHash7 } from "node:crypto";
|
|
250402
250752
|
import {
|
|
250403
|
-
closeSync as
|
|
250753
|
+
closeSync as closeSync6,
|
|
250404
250754
|
fsyncSync as fsyncSync3,
|
|
250405
|
-
openSync as
|
|
250755
|
+
openSync as openSync6,
|
|
250406
250756
|
renameSync as renameSync8,
|
|
250407
250757
|
writeFileSync as writeFileSync27
|
|
250408
250758
|
} from "node:fs";
|
|
250409
250759
|
import { homedir as homedir33 } from "node:os";
|
|
250410
|
-
import { join as
|
|
250760
|
+
import { join as join68 } from "node:path";
|
|
250411
250761
|
function writeInterruptedTurnRecordFile(temporary, destination, directory, record6, syncDirectory) {
|
|
250412
250762
|
writeFileSync27(temporary, JSON.stringify(record6), {
|
|
250413
250763
|
mode: 384,
|
|
@@ -250419,11 +250769,11 @@ function writeInterruptedTurnRecordFile(temporary, destination, directory, recor
|
|
|
250419
250769
|
function fsyncInterruptedTurnDirectory(directory, platform9 = process.platform) {
|
|
250420
250770
|
if (platform9 === "win32")
|
|
250421
250771
|
return;
|
|
250422
|
-
const fd =
|
|
250772
|
+
const fd = openSync6(directory, "r");
|
|
250423
250773
|
try {
|
|
250424
250774
|
fsyncSync3(fd);
|
|
250425
250775
|
} finally {
|
|
250426
|
-
|
|
250776
|
+
closeSync6(fd);
|
|
250427
250777
|
}
|
|
250428
250778
|
}
|
|
250429
250779
|
function defaultInterruptedTurnDirectory() {
|
|
@@ -250433,7 +250783,7 @@ function defaultInterruptedTurnDirectory() {
|
|
|
250433
250783
|
} catch {
|
|
250434
250784
|
serverUrl = process.env.LETTA_BASE_URL ?? "uninitialized";
|
|
250435
250785
|
}
|
|
250436
|
-
return
|
|
250786
|
+
return join68(homedir33(), ".letta", "listener-state", createHash7("sha256").update(serverUrl).digest("hex").slice(0, 24));
|
|
250437
250787
|
}
|
|
250438
250788
|
var init_interrupted_turn_storage = __esm(() => {
|
|
250439
250789
|
init_server_url();
|
|
@@ -250502,23 +250852,23 @@ function createRecoveryAuthorityGuard(dependencies4) {
|
|
|
250502
250852
|
// src/websocket/listener/recovery-lineage-sidecar.ts
|
|
250503
250853
|
import { createHash as createHash8, randomUUID as randomUUID40 } from "node:crypto";
|
|
250504
250854
|
import {
|
|
250505
|
-
existsSync as
|
|
250855
|
+
existsSync as existsSync47,
|
|
250506
250856
|
mkdirSync as mkdirSync32,
|
|
250507
|
-
readdirSync as
|
|
250508
|
-
readFileSync as
|
|
250857
|
+
readdirSync as readdirSync17,
|
|
250858
|
+
readFileSync as readFileSync37,
|
|
250509
250859
|
renameSync as renameSync9,
|
|
250510
250860
|
rmSync as rmSync17,
|
|
250511
|
-
statSync as
|
|
250861
|
+
statSync as statSync17,
|
|
250512
250862
|
writeFileSync as writeFileSync28
|
|
250513
250863
|
} from "node:fs";
|
|
250514
|
-
import { join as
|
|
250864
|
+
import { join as join69 } from "node:path";
|
|
250515
250865
|
function createRecoveryLineageSidecarAccess(params) {
|
|
250516
250866
|
const canonicalSidecarName = /\.json\.recovery-[0-9a-f]{24}$/;
|
|
250517
250867
|
const temporarySidecarName = /^(.+\.json)\.recovery-[0-9a-f]{24}\.(\d+)\.([0-9a-f-]{36})\.[0-9a-f-]{36}\.tmp$/;
|
|
250518
250868
|
const legacyTemporarySidecarName = /^(.+\.json)\.recovery-[0-9a-f]{24}\.(\d+)\.[0-9a-f-]{36}\.tmp$/;
|
|
250519
250869
|
const staleTemporaryAgeMs = 60000;
|
|
250520
250870
|
const maximumTemporaryAgeMs = 24 * 60 * 60 * 1000;
|
|
250521
|
-
const path32 = (agentId, conversationId, lineageId) =>
|
|
250871
|
+
const path32 = (agentId, conversationId, lineageId) => join69(params.directory, `${encodeURIComponent(agentId)}_${encodeURIComponent(conversationId)}.json.recovery-${createHash8("sha256").update(lineageId).digest("hex").slice(0, 24)}`);
|
|
250522
250872
|
const isSidecar = (value) => {
|
|
250523
250873
|
if (!value || typeof value !== "object")
|
|
250524
250874
|
return false;
|
|
@@ -250527,7 +250877,7 @@ function createRecoveryLineageSidecarAccess(params) {
|
|
|
250527
250877
|
};
|
|
250528
250878
|
const read2 = (agentId, conversationId, lineageId) => {
|
|
250529
250879
|
try {
|
|
250530
|
-
const parsed = JSON.parse(
|
|
250880
|
+
const parsed = JSON.parse(readFileSync37(path32(agentId, conversationId, lineageId), "utf8"));
|
|
250531
250881
|
if (!isSidecar(parsed) || parsed.agentId !== agentId || parsed.conversationId !== conversationId || parsed.lineageId !== lineageId) {
|
|
250532
250882
|
throw new Error("Invalid recovery-lineage sidecar");
|
|
250533
250883
|
}
|
|
@@ -250797,15 +251147,15 @@ function createRecoveryLineageSidecarAccess(params) {
|
|
|
250797
251147
|
const removeMalformedOrphan = (file) => {
|
|
250798
251148
|
const separator = file.indexOf(".recovery-");
|
|
250799
251149
|
const mainFile = separator >= 0 ? file.slice(0, separator) : "";
|
|
250800
|
-
if (!mainFile ||
|
|
251150
|
+
if (!mainFile || existsSync47(join69(params.directory, mainFile)))
|
|
250801
251151
|
return;
|
|
250802
251152
|
try {
|
|
250803
|
-
rmSync17(
|
|
251153
|
+
rmSync17(join69(params.directory, file), { force: true });
|
|
250804
251154
|
params.syncDirectory(params.directory);
|
|
250805
251155
|
} catch {}
|
|
250806
251156
|
};
|
|
250807
251157
|
try {
|
|
250808
|
-
const files =
|
|
251158
|
+
const files = readdirSync17(params.directory);
|
|
250809
251159
|
for (const file of files) {
|
|
250810
251160
|
const temporaryMatch = file.match(temporarySidecarName) ?? file.match(legacyTemporarySidecarName);
|
|
250811
251161
|
if (!temporaryMatch)
|
|
@@ -250827,13 +251177,13 @@ function createRecoveryLineageSidecarAccess(params) {
|
|
|
250827
251177
|
ownerIsAlive = error5.code !== "ESRCH";
|
|
250828
251178
|
}
|
|
250829
251179
|
}
|
|
250830
|
-
const ageMs = Date.now() -
|
|
251180
|
+
const ageMs = Date.now() - statSync17(join69(params.directory, file)).mtimeMs;
|
|
250831
251181
|
if (!ownerIsCurrentWriter && (!ownerIsAlive && ageMs >= staleTemporaryAgeMs || ageMs >= maximumTemporaryAgeMs)) {
|
|
250832
|
-
const release = acquireDurableFileLock(
|
|
251182
|
+
const release = acquireDurableFileLock(join69(params.directory, mainFile), { waitMs: params.lockWaitMs });
|
|
250833
251183
|
try {
|
|
250834
|
-
const currentAgeMs = Date.now() -
|
|
251184
|
+
const currentAgeMs = Date.now() - statSync17(join69(params.directory, file)).mtimeMs;
|
|
250835
251185
|
if (!ownerIsCurrentWriter && (!ownerIsAlive && currentAgeMs >= staleTemporaryAgeMs || currentAgeMs >= maximumTemporaryAgeMs)) {
|
|
250836
|
-
rmSync17(
|
|
251186
|
+
rmSync17(join69(params.directory, file), { force: true });
|
|
250837
251187
|
params.syncDirectory(params.directory);
|
|
250838
251188
|
}
|
|
250839
251189
|
} finally {
|
|
@@ -250844,8 +251194,8 @@ function createRecoveryLineageSidecarAccess(params) {
|
|
|
250844
251194
|
}
|
|
250845
251195
|
return files.filter((file) => canonicalSidecarName.test(file)).flatMap((file) => {
|
|
250846
251196
|
try {
|
|
250847
|
-
const value = JSON.parse(
|
|
250848
|
-
if (isSidecar(value) &&
|
|
251197
|
+
const value = JSON.parse(readFileSync37(join69(params.directory, file), "utf8"));
|
|
251198
|
+
if (isSidecar(value) && join69(params.directory, file) === path32(value.agentId, value.conversationId, value.lineageId)) {
|
|
250849
251199
|
return [value];
|
|
250850
251200
|
}
|
|
250851
251201
|
removeMalformedOrphan(file);
|
|
@@ -250887,14 +251237,14 @@ var init_recovery_lineage_sidecar = __esm(async () => {
|
|
|
250887
251237
|
// src/websocket/listener/interrupted-turn-record.ts
|
|
250888
251238
|
import { randomUUID as randomUUID41 } from "node:crypto";
|
|
250889
251239
|
import {
|
|
250890
|
-
existsSync as
|
|
251240
|
+
existsSync as existsSync48,
|
|
250891
251241
|
mkdirSync as mkdirSync33,
|
|
250892
|
-
readFileSync as
|
|
251242
|
+
readFileSync as readFileSync38,
|
|
250893
251243
|
rmSync as rmSync18,
|
|
250894
251244
|
unlinkSync as unlinkSync9,
|
|
250895
251245
|
writeFileSync as writeFileSync29
|
|
250896
251246
|
} from "node:fs";
|
|
250897
|
-
import { join as
|
|
251247
|
+
import { join as join70 } from "node:path";
|
|
250898
251248
|
function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(), dependencies4 = {}) {
|
|
250899
251249
|
const sync = dependencies4.fsyncDirectory ?? fsyncInterruptedTurnDirectory;
|
|
250900
251250
|
function persist(destination, record6) {
|
|
@@ -250906,11 +251256,11 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
|
|
|
250906
251256
|
}
|
|
250907
251257
|
}
|
|
250908
251258
|
function path32(agentId, conversationId) {
|
|
250909
|
-
return
|
|
251259
|
+
return join70(directory, `${encodeURIComponent(agentId)}_${encodeURIComponent(conversationId)}.json`);
|
|
250910
251260
|
}
|
|
250911
251261
|
function readRecord2(file) {
|
|
250912
251262
|
try {
|
|
250913
|
-
const value = JSON.parse(
|
|
251263
|
+
const value = JSON.parse(readFileSync38(file, "utf8"));
|
|
250914
251264
|
if (!isInterruptedTurnRecord(value, file, path32)) {
|
|
250915
251265
|
throw new Error("Invalid interrupted-turn record");
|
|
250916
251266
|
}
|
|
@@ -250944,7 +251294,7 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
|
|
|
250944
251294
|
const recoveryAuthority = createRecoveryAuthorityGuard({
|
|
250945
251295
|
path: path32,
|
|
250946
251296
|
readRecord: readRecord2,
|
|
250947
|
-
exists:
|
|
251297
|
+
exists: existsSync48,
|
|
250948
251298
|
acquire: (destination) => acquireDurableFileLock(destination, {
|
|
250949
251299
|
waitMs: dependencies4.lockWaitMs
|
|
250950
251300
|
}),
|
|
@@ -250978,7 +251328,7 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
|
|
|
250978
251328
|
});
|
|
250979
251329
|
try {
|
|
250980
251330
|
const current = readRecord2(destination);
|
|
250981
|
-
if (!
|
|
251331
|
+
if (!existsSync48(destination)) {
|
|
250982
251332
|
removeSidecar(sidecar);
|
|
250983
251333
|
} else if (current && current.recoveryClaimCompletion?.lineageId !== sidecar.lineageId) {
|
|
250984
251334
|
removeSidecar(sidecar);
|
|
@@ -251003,7 +251353,7 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
|
|
|
251003
251353
|
},
|
|
251004
251354
|
listDurableInputOwnership() {
|
|
251005
251355
|
const snapshot2 = rawSnapshot();
|
|
251006
|
-
return collectInterruptedTurnInputOwnershipWithSidecars(snapshot2.records, readMainView, listSidecars(), (agentId, conversationId) =>
|
|
251356
|
+
return collectInterruptedTurnInputOwnershipWithSidecars(snapshot2.records, readMainView, listSidecars(), (agentId, conversationId) => existsSync48(path32(agentId, conversationId)), snapshot2.unreadableScopes);
|
|
251007
251357
|
},
|
|
251008
251358
|
read(agentId, conversationId) {
|
|
251009
251359
|
const current = readRecord2(path32(agentId, conversationId));
|
|
@@ -251262,7 +251612,7 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
|
|
|
251262
251612
|
}
|
|
251263
251613
|
if (current.revision === params.pendingRevision && !marker2.independentSuccessor) {
|
|
251264
251614
|
const retiredAuthority = retireSidecar(current);
|
|
251265
|
-
const evidence =
|
|
251615
|
+
const evidence = readFileSync38(destination, "utf8");
|
|
251266
251616
|
unlinkSync9(destination);
|
|
251267
251617
|
try {
|
|
251268
251618
|
sync(directory);
|
|
@@ -251317,7 +251667,7 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
|
|
|
251317
251667
|
if (expectedRevision !== undefined && (current.revision ?? null) !== expectedRevision) {
|
|
251318
251668
|
return false;
|
|
251319
251669
|
}
|
|
251320
|
-
evidence =
|
|
251670
|
+
evidence = readFileSync38(destination, "utf8");
|
|
251321
251671
|
unlinkSync9(destination);
|
|
251322
251672
|
} catch (error5) {
|
|
251323
251673
|
if (error5.code === "ENOENT")
|
|
@@ -253305,10 +253655,10 @@ var init_input_disposition_expiry = __esm(() => {
|
|
|
253305
253655
|
// src/websocket/listener/input-disposition-path.ts
|
|
253306
253656
|
import { createHash as createHash9 } from "node:crypto";
|
|
253307
253657
|
import { homedir as homedir34 } from "node:os";
|
|
253308
|
-
import { join as
|
|
253658
|
+
import { join as join71 } from "node:path";
|
|
253309
253659
|
function inputDispositionPersistentPath(serverUrl) {
|
|
253310
253660
|
const namespace = createHash9("sha256").update(serverUrl).digest("hex").slice(0, 24);
|
|
253311
|
-
return
|
|
253661
|
+
return join71(homedir34(), ".letta", "state", namespace, "input-dispositions-v2.json");
|
|
253312
253662
|
}
|
|
253313
253663
|
var init_input_disposition_path = () => {};
|
|
253314
253664
|
|
|
@@ -253334,14 +253684,14 @@ var init_input_disposition_validation = __esm(async () => {
|
|
|
253334
253684
|
import { randomUUID as randomUUID42 } from "node:crypto";
|
|
253335
253685
|
import {
|
|
253336
253686
|
chmodSync as chmodSync7,
|
|
253337
|
-
closeSync as
|
|
253338
|
-
existsSync as
|
|
253687
|
+
closeSync as closeSync7,
|
|
253688
|
+
existsSync as existsSync49,
|
|
253339
253689
|
fsyncSync as fsyncSync4,
|
|
253340
253690
|
mkdirSync as mkdirSync34,
|
|
253341
|
-
openSync as
|
|
253342
|
-
readFileSync as
|
|
253691
|
+
openSync as openSync7,
|
|
253692
|
+
readFileSync as readFileSync39,
|
|
253343
253693
|
renameSync as renameSync10,
|
|
253344
|
-
statSync as
|
|
253694
|
+
statSync as statSync18,
|
|
253345
253695
|
unlinkSync as unlinkSync10,
|
|
253346
253696
|
writeFileSync as writeFileSync30
|
|
253347
253697
|
} from "node:fs";
|
|
@@ -253479,13 +253829,13 @@ function validateDurableStore(value) {
|
|
|
253479
253829
|
return value;
|
|
253480
253830
|
}
|
|
253481
253831
|
function readDurableStore(path32) {
|
|
253482
|
-
if (!
|
|
253832
|
+
if (!existsSync49(path32))
|
|
253483
253833
|
return emptyDurableStore();
|
|
253484
|
-
const size2 =
|
|
253834
|
+
const size2 = statSync18(path32).size;
|
|
253485
253835
|
if (size2 > MAX_INPUT_DISPOSITION_STORE_BYTES) {
|
|
253486
253836
|
throw new Error("Accepted-input disposition store exceeds its size limit");
|
|
253487
253837
|
}
|
|
253488
|
-
return validateDurableStore(JSON.parse(
|
|
253838
|
+
return validateDurableStore(JSON.parse(readFileSync39(path32, "utf8")));
|
|
253489
253839
|
}
|
|
253490
253840
|
function prepareStateDirectory(path32) {
|
|
253491
253841
|
const dir = dirname30(path32);
|
|
@@ -253501,11 +253851,11 @@ function writeDurableStore(path32, store3) {
|
|
|
253501
253851
|
const temporaryPath = `${path32}.${process.pid}.${randomUUID42()}.tmp`;
|
|
253502
253852
|
try {
|
|
253503
253853
|
writeFileSync30(temporaryPath, serialized, { mode: 384, flag: "wx" });
|
|
253504
|
-
const fd =
|
|
253854
|
+
const fd = openSync7(temporaryPath, "r+");
|
|
253505
253855
|
try {
|
|
253506
253856
|
fsyncSync4(fd);
|
|
253507
253857
|
} finally {
|
|
253508
|
-
|
|
253858
|
+
closeSync7(fd);
|
|
253509
253859
|
}
|
|
253510
253860
|
renameSync10(temporaryPath, path32);
|
|
253511
253861
|
fsyncDirectory(dirname30(path32));
|
|
@@ -253927,18 +254277,18 @@ var init_input_disposition = __esm(async () => {
|
|
|
253927
254277
|
// src/websocket/listener/turn-finished-replay.ts
|
|
253928
254278
|
import { randomUUID as randomUUID43 } from "node:crypto";
|
|
253929
254279
|
import {
|
|
253930
|
-
closeSync as
|
|
254280
|
+
closeSync as closeSync8,
|
|
253931
254281
|
fsyncSync as fsyncSync5,
|
|
253932
254282
|
mkdirSync as mkdirSync35,
|
|
253933
|
-
openSync as
|
|
253934
|
-
readdirSync as
|
|
253935
|
-
readFileSync as
|
|
254283
|
+
openSync as openSync8,
|
|
254284
|
+
readdirSync as readdirSync18,
|
|
254285
|
+
readFileSync as readFileSync40,
|
|
253936
254286
|
renameSync as renameSync11,
|
|
253937
254287
|
rmSync as rmSync19,
|
|
253938
254288
|
writeFileSync as writeFileSync31
|
|
253939
254289
|
} from "node:fs";
|
|
253940
254290
|
import { homedir as homedir35 } from "node:os";
|
|
253941
|
-
import { join as
|
|
254291
|
+
import { join as join72 } from "node:path";
|
|
253942
254292
|
function terminalAuthorityStatus(runtime, terminal, terminals, interruptedStore = createInterruptedTurnStore()) {
|
|
253943
254293
|
const { owner } = terminal;
|
|
253944
254294
|
if (!owner.recoveryLineageId)
|
|
@@ -253978,7 +254328,7 @@ function defaultDirectory() {
|
|
|
253978
254328
|
} catch {
|
|
253979
254329
|
serverUrl = process.env.LETTA_BASE_URL ?? "uninitialized";
|
|
253980
254330
|
}
|
|
253981
|
-
return
|
|
254331
|
+
return join72(homedir35(), ".letta", "listener-terminal-state", Buffer.from(serverUrl).toString("base64url"));
|
|
253982
254332
|
}
|
|
253983
254333
|
function encodeTurnFinishedScope(agentId, conversationId) {
|
|
253984
254334
|
return Buffer.from(JSON.stringify([agentId, conversationId])).toString("base64url");
|
|
@@ -253997,19 +254347,19 @@ function decodeTurnFinishedScope(encoded) {
|
|
|
253997
254347
|
function fsyncDirectory2(directory) {
|
|
253998
254348
|
if (process.platform === "win32")
|
|
253999
254349
|
return;
|
|
254000
|
-
const fd =
|
|
254350
|
+
const fd = openSync8(directory, "r");
|
|
254001
254351
|
try {
|
|
254002
254352
|
fsyncSync5(fd);
|
|
254003
254353
|
} finally {
|
|
254004
|
-
|
|
254354
|
+
closeSync8(fd);
|
|
254005
254355
|
}
|
|
254006
254356
|
}
|
|
254007
254357
|
function createTurnFinishedStore(directory = defaultDirectory(), options = {}) {
|
|
254008
254358
|
const claimantToken = randomUUID43();
|
|
254009
|
-
const path32 = (agentId, conversationId) =>
|
|
254359
|
+
const path32 = (agentId, conversationId) => join72(directory, `${encodeTurnFinishedScope(agentId, conversationId)}.json`);
|
|
254010
254360
|
const readRecord2 = (agentId, conversationId) => {
|
|
254011
254361
|
try {
|
|
254012
|
-
const record6 = JSON.parse(
|
|
254362
|
+
const record6 = JSON.parse(readFileSync40(path32(agentId, conversationId), "utf8"));
|
|
254013
254363
|
if (record6.agentId !== agentId || record6.conversationId !== conversationId || !Array.isArray(record6.terminals) || !record6.terminals.every((terminal) => typeof terminal.id === "string" && Number.isFinite(terminal.createdAt) && terminal.message?.type === "turn_finished" && typeof terminal.message.turn_id === "string" && Array.isArray(terminal.requiredConsumerIds) && terminal.requiredConsumerIds.every((id2) => typeof id2 === "string") && Array.isArray(terminal.acknowledgedConsumerIds) && terminal.acknowledgedConsumerIds.every((id2) => typeof id2 === "string") && !!terminal.owner && (terminal.owner.connectionId === null || typeof terminal.owner.connectionId === "string") && typeof terminal.owner.canRotate === "boolean" && (terminal.owner.terminalIdentity === undefined || typeof terminal.owner.terminalIdentity === "string") && (terminal.owner.interruptedRevision === undefined || typeof terminal.owner.interruptedRevision === "string") && (terminal.owner.recoveryLineageId === undefined || typeof terminal.owner.recoveryLineageId === "string") && (terminal.owner.interruptedAuthorityRevision === undefined || typeof terminal.owner.interruptedAuthorityRevision === "string") && (terminal.owner.preparationSequence === undefined || Number.isSafeInteger(terminal.owner.preparationSequence) && terminal.owner.preparationSequence >= 0))) {
|
|
254014
254364
|
throw new Error("Invalid turn-finished record");
|
|
254015
254365
|
}
|
|
@@ -254075,7 +254425,7 @@ function createTurnFinishedStore(directory = defaultDirectory(), options = {}) {
|
|
|
254075
254425
|
const sweepExpiredRecords = () => {
|
|
254076
254426
|
let entries2;
|
|
254077
254427
|
try {
|
|
254078
|
-
entries2 =
|
|
254428
|
+
entries2 = readdirSync18(directory, { withFileTypes: true });
|
|
254079
254429
|
} catch (error5) {
|
|
254080
254430
|
if (error5.code === "ENOENT")
|
|
254081
254431
|
return;
|
|
@@ -259448,13 +259798,13 @@ var init_service_protocol = __esm(() => {
|
|
|
259448
259798
|
// src/websocket/listen-log.ts
|
|
259449
259799
|
import {
|
|
259450
259800
|
appendFileSync as appendFileSync8,
|
|
259451
|
-
existsSync as
|
|
259801
|
+
existsSync as existsSync50,
|
|
259452
259802
|
mkdirSync as mkdirSync36,
|
|
259453
|
-
readdirSync as
|
|
259803
|
+
readdirSync as readdirSync19,
|
|
259454
259804
|
unlinkSync as unlinkSync11
|
|
259455
259805
|
} from "node:fs";
|
|
259456
259806
|
import { homedir as homedir36 } from "node:os";
|
|
259457
|
-
import { join as
|
|
259807
|
+
import { join as join73 } from "node:path";
|
|
259458
259808
|
function formatTimestamp2() {
|
|
259459
259809
|
const now2 = new Date;
|
|
259460
259810
|
const h3 = String(now2.getHours()).padStart(2, "0");
|
|
@@ -259468,14 +259818,14 @@ function formatFileTimestamp(now2) {
|
|
|
259468
259818
|
}
|
|
259469
259819
|
function pruneOldLogs(dir, maxFiles) {
|
|
259470
259820
|
try {
|
|
259471
|
-
if (!
|
|
259821
|
+
if (!existsSync50(dir))
|
|
259472
259822
|
return;
|
|
259473
|
-
const files =
|
|
259823
|
+
const files = readdirSync19(dir).filter((f4) => f4.endsWith(".log")).sort();
|
|
259474
259824
|
if (files.length >= maxFiles) {
|
|
259475
259825
|
const toDelete = files.slice(0, files.length - maxFiles + 1);
|
|
259476
259826
|
for (const file of toDelete) {
|
|
259477
259827
|
try {
|
|
259478
|
-
unlinkSync11(
|
|
259828
|
+
unlinkSync11(join73(dir, file));
|
|
259479
259829
|
} catch {}
|
|
259480
259830
|
}
|
|
259481
259831
|
}
|
|
@@ -259514,13 +259864,13 @@ class RemoteSessionLog {
|
|
|
259514
259864
|
freshPath() {
|
|
259515
259865
|
const stamp = formatFileTimestamp(new Date);
|
|
259516
259866
|
const suffix = this.rotation > 0 ? `.${this.rotation}` : "";
|
|
259517
|
-
return
|
|
259867
|
+
return join73(this.dir, `${stamp}${suffix}.log`);
|
|
259518
259868
|
}
|
|
259519
259869
|
rotate() {
|
|
259520
259870
|
const previous = this.path;
|
|
259521
259871
|
this.rotation += 1;
|
|
259522
259872
|
this.path = this.freshPath();
|
|
259523
|
-
while (
|
|
259873
|
+
while (existsSync50(this.path)) {
|
|
259524
259874
|
this.rotation += 1;
|
|
259525
259875
|
this.path = this.freshPath();
|
|
259526
259876
|
}
|
|
@@ -259544,7 +259894,7 @@ class RemoteSessionLog {
|
|
|
259544
259894
|
if (this.dirCreated)
|
|
259545
259895
|
return;
|
|
259546
259896
|
try {
|
|
259547
|
-
if (!
|
|
259897
|
+
if (!existsSync50(this.dir)) {
|
|
259548
259898
|
mkdirSync36(this.dir, { recursive: true });
|
|
259549
259899
|
}
|
|
259550
259900
|
this.dirCreated = true;
|
|
@@ -259553,7 +259903,7 @@ class RemoteSessionLog {
|
|
|
259553
259903
|
}
|
|
259554
259904
|
var REMOTE_LOG_DIR, MAX_LOG_FILES = 10, MAX_LOG_BYTES2;
|
|
259555
259905
|
var init_listen_log = __esm(() => {
|
|
259556
|
-
REMOTE_LOG_DIR =
|
|
259906
|
+
REMOTE_LOG_DIR = join73(homedir36(), ".letta", "logs", "remote");
|
|
259557
259907
|
MAX_LOG_BYTES2 = 10 * 1024 * 1024;
|
|
259558
259908
|
});
|
|
259559
259909
|
|
|
@@ -262296,28 +262646,28 @@ __export(exports_memory_scanner, {
|
|
|
262296
262646
|
readFileContent: () => readFileContent,
|
|
262297
262647
|
getFileNodes: () => getFileNodes
|
|
262298
262648
|
});
|
|
262299
|
-
import { readdirSync as
|
|
262300
|
-
import { join as
|
|
262649
|
+
import { readdirSync as readdirSync20, readFileSync as readFileSync41, statSync as statSync19 } from "node:fs";
|
|
262650
|
+
import { join as join74, relative as relative7 } from "node:path";
|
|
262301
262651
|
function scanMemoryFilesystem(memoryRoot) {
|
|
262302
262652
|
const nodes = [];
|
|
262303
262653
|
const scanDir = (dir, depth, parentIsLast) => {
|
|
262304
262654
|
let entries2;
|
|
262305
262655
|
try {
|
|
262306
|
-
entries2 =
|
|
262656
|
+
entries2 = readdirSync20(dir);
|
|
262307
262657
|
} catch {
|
|
262308
262658
|
return;
|
|
262309
262659
|
}
|
|
262310
262660
|
const filtered = entries2.filter((name) => !name.startsWith("."));
|
|
262311
262661
|
const sorted = filtered.sort((a2, b3) => {
|
|
262312
|
-
const aPath =
|
|
262313
|
-
const bPath =
|
|
262662
|
+
const aPath = join74(dir, a2);
|
|
262663
|
+
const bPath = join74(dir, b3);
|
|
262314
262664
|
let aIsDir = false;
|
|
262315
262665
|
let bIsDir = false;
|
|
262316
262666
|
try {
|
|
262317
|
-
aIsDir =
|
|
262667
|
+
aIsDir = statSync19(aPath).isDirectory();
|
|
262318
262668
|
} catch {}
|
|
262319
262669
|
try {
|
|
262320
|
-
bIsDir =
|
|
262670
|
+
bIsDir = statSync19(bPath).isDirectory();
|
|
262321
262671
|
} catch {}
|
|
262322
262672
|
if (aIsDir !== bIsDir)
|
|
262323
262673
|
return aIsDir ? -1 : 1;
|
|
@@ -262330,10 +262680,10 @@ function scanMemoryFilesystem(memoryRoot) {
|
|
|
262330
262680
|
return a2.localeCompare(b3);
|
|
262331
262681
|
});
|
|
262332
262682
|
sorted.forEach((name, index) => {
|
|
262333
|
-
const fullPath =
|
|
262683
|
+
const fullPath = join74(dir, name);
|
|
262334
262684
|
let isDir = false;
|
|
262335
262685
|
try {
|
|
262336
|
-
isDir =
|
|
262686
|
+
isDir = statSync19(fullPath).isDirectory();
|
|
262337
262687
|
} catch {
|
|
262338
262688
|
return;
|
|
262339
262689
|
}
|
|
@@ -262361,7 +262711,7 @@ function getFileNodes(nodes) {
|
|
|
262361
262711
|
}
|
|
262362
262712
|
function readFileContent(fullPath) {
|
|
262363
262713
|
try {
|
|
262364
|
-
return
|
|
262714
|
+
return readFileSync41(fullPath, "utf-8");
|
|
262365
262715
|
} catch {
|
|
262366
262716
|
return "(unable to read file)";
|
|
262367
262717
|
}
|
|
@@ -262432,10 +262782,10 @@ async function handleListMemoryCommand(parsed, socket, safeSocketSend, overrides
|
|
|
262432
262782
|
const isMemfsEnabledOnServer2 = overrides.isMemfsEnabledOnServer ?? actualIsMemfsEnabledOnServer;
|
|
262433
262783
|
const { scanMemoryFilesystem: scanMemoryFilesystem2, getFileNodes: getFileNodes2, readFileContent: readFileContent2 } = await Promise.resolve().then(() => (init_memory_scanner(), exports_memory_scanner));
|
|
262434
262784
|
const { parseFrontmatter: parseFrontmatter2 } = await Promise.resolve().then(() => exports_frontmatter);
|
|
262435
|
-
const { existsSync:
|
|
262436
|
-
const { join:
|
|
262785
|
+
const { existsSync: existsSync51, statSync: statSync20 } = await import("node:fs");
|
|
262786
|
+
const { join: join75, posix: posix3 } = await import("node:path");
|
|
262437
262787
|
const memoryRoot = getMemoryFilesystemRoot2(parsed.agent_id);
|
|
262438
|
-
let memfsInitialized =
|
|
262788
|
+
let memfsInitialized = existsSync51(join75(memoryRoot, ".git"));
|
|
262439
262789
|
const memfsEnabled = memfsInitialized ? true : await isMemfsEnabledOnServer2(parsed.agent_id);
|
|
262440
262790
|
if (!memfsEnabled) {
|
|
262441
262791
|
safeSocketSend(socket, {
|
|
@@ -262453,7 +262803,7 @@ async function handleListMemoryCommand(parsed, socket, safeSocketSend, overrides
|
|
|
262453
262803
|
await ensureLocalMemfsCheckout2(parsed.agent_id, {
|
|
262454
262804
|
pullOnExistingRepo: true
|
|
262455
262805
|
});
|
|
262456
|
-
memfsInitialized =
|
|
262806
|
+
memfsInitialized = existsSync51(join75(memoryRoot, ".git"));
|
|
262457
262807
|
if (!memfsInitialized) {
|
|
262458
262808
|
throw new Error("MemFS is enabled, but the local memory checkout could not be initialized.");
|
|
262459
262809
|
}
|
|
@@ -262529,7 +262879,7 @@ async function handleListMemoryCommand(parsed, socket, safeSocketSend, overrides
|
|
|
262529
262879
|
if (imageMimeType) {
|
|
262530
262880
|
let size2 = 0;
|
|
262531
262881
|
try {
|
|
262532
|
-
size2 =
|
|
262882
|
+
size2 = statSync20(node.fullPath).size;
|
|
262533
262883
|
} catch {}
|
|
262534
262884
|
return {
|
|
262535
262885
|
relative_path: node.relativePath,
|
|
@@ -262753,34 +263103,34 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
262753
263103
|
isMemfsEnabledOnServer: isMemfsEnabledOnServer2
|
|
262754
263104
|
} = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
262755
263105
|
const { readFile: readFile20 } = await import("node:fs/promises");
|
|
262756
|
-
const { existsSync:
|
|
262757
|
-
const { isAbsolute: isAbsolute25, join:
|
|
263106
|
+
const { existsSync: existsSync51 } = await import("node:fs");
|
|
263107
|
+
const { isAbsolute: isAbsolute25, join: join75, normalize: normalize4, relative: relative8, sep: sep8 } = await import("node:path");
|
|
262758
263108
|
if (isAbsolute25(parsed.path) || parsed.path.length === 0) {
|
|
262759
263109
|
sendFailure("path must be a non-empty relative path");
|
|
262760
263110
|
return;
|
|
262761
263111
|
}
|
|
262762
263112
|
const memoryRoot = getScopedMemoryFilesystemRoot2(parsed.agent_id);
|
|
262763
|
-
const absolutePath = normalize4(
|
|
263113
|
+
const absolutePath = normalize4(join75(memoryRoot, parsed.path));
|
|
262764
263114
|
const rel = relative8(memoryRoot, absolutePath);
|
|
262765
|
-
if (rel.startsWith("..") || rel === "" || isAbsolute25(rel) || rel.split(
|
|
263115
|
+
if (rel.startsWith("..") || rel === "" || isAbsolute25(rel) || rel.split(sep8).includes("..")) {
|
|
262766
263116
|
sendFailure("path must resolve inside the memory root");
|
|
262767
263117
|
return;
|
|
262768
263118
|
}
|
|
262769
|
-
if (!
|
|
263119
|
+
if (!existsSync51(join75(memoryRoot, ".git"))) {
|
|
262770
263120
|
const enabled = await isMemfsEnabledOnServer2(parsed.agent_id);
|
|
262771
263121
|
if (!enabled) {
|
|
262772
263122
|
sendFailure("memfs is not enabled for this agent");
|
|
262773
263123
|
return;
|
|
262774
263124
|
}
|
|
262775
263125
|
await ensureLocalMemfsCheckout2(parsed.agent_id);
|
|
262776
|
-
if (!
|
|
263126
|
+
if (!existsSync51(join75(memoryRoot, ".git"))) {
|
|
262777
263127
|
sendFailure("failed to initialize local memory checkout");
|
|
262778
263128
|
return;
|
|
262779
263129
|
}
|
|
262780
263130
|
}
|
|
262781
263131
|
const buffer = await readFile20(absolutePath);
|
|
262782
263132
|
const content = encoding === "base64" ? buffer.toString("base64") : buffer.toString("utf-8");
|
|
262783
|
-
const pathspec = rel.split(
|
|
263133
|
+
const pathspec = rel.split(sep8).join("/");
|
|
262784
263134
|
safeSocketSend(socket, {
|
|
262785
263135
|
type: "read_memory_file_response",
|
|
262786
263136
|
request_id: parsed.request_id,
|
|
@@ -262819,27 +263169,27 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
262819
263169
|
} = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
262820
263170
|
const { commitMemoryWrite: commitMemoryWrite2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
|
|
262821
263171
|
const { writeFile: writeFile16, mkdir: mkdir14 } = await import("node:fs/promises");
|
|
262822
|
-
const { existsSync:
|
|
262823
|
-
const { dirname: dirname31, isAbsolute: isAbsolute25, join:
|
|
263172
|
+
const { existsSync: existsSync51 } = await import("node:fs");
|
|
263173
|
+
const { dirname: dirname31, isAbsolute: isAbsolute25, join: join75, normalize: normalize4, relative: relative8, sep: sep8 } = await import("node:path");
|
|
262824
263174
|
if (isAbsolute25(parsed.path) || parsed.path.length === 0) {
|
|
262825
263175
|
sendFailure("write_memory_file: path must be a non-empty relative path");
|
|
262826
263176
|
return;
|
|
262827
263177
|
}
|
|
262828
263178
|
const memoryRoot = getScopedMemoryFilesystemRoot2(parsed.agent_id);
|
|
262829
|
-
const absolutePath = normalize4(
|
|
263179
|
+
const absolutePath = normalize4(join75(memoryRoot, parsed.path));
|
|
262830
263180
|
const rel = relative8(memoryRoot, absolutePath);
|
|
262831
|
-
if (rel.startsWith("..") || rel === "" || isAbsolute25(rel) || rel.split(
|
|
263181
|
+
if (rel.startsWith("..") || rel === "" || isAbsolute25(rel) || rel.split(sep8).includes("..")) {
|
|
262832
263182
|
sendFailure("write_memory_file: path must resolve inside the memory root");
|
|
262833
263183
|
return;
|
|
262834
263184
|
}
|
|
262835
|
-
if (!
|
|
263185
|
+
if (!existsSync51(join75(memoryRoot, ".git"))) {
|
|
262836
263186
|
const enabled = await isMemfsEnabledOnServer2(parsed.agent_id);
|
|
262837
263187
|
if (!enabled) {
|
|
262838
263188
|
sendFailure("write_memory_file: memfs is not enabled for this agent");
|
|
262839
263189
|
return;
|
|
262840
263190
|
}
|
|
262841
263191
|
await ensureLocalMemfsCheckout2(parsed.agent_id);
|
|
262842
|
-
if (!
|
|
263192
|
+
if (!existsSync51(join75(memoryRoot, ".git"))) {
|
|
262843
263193
|
sendFailure("write_memory_file: failed to initialize local memory checkout");
|
|
262844
263194
|
return;
|
|
262845
263195
|
}
|
|
@@ -262857,7 +263207,7 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
262857
263207
|
agentName = agent.name.trim();
|
|
262858
263208
|
}
|
|
262859
263209
|
} catch {}
|
|
262860
|
-
const pathspec = rel.split(
|
|
263210
|
+
const pathspec = rel.split(sep8).join("/");
|
|
262861
263211
|
const reason = parsed.commit_message?.trim() || `Update memory file ${pathspec}`;
|
|
262862
263212
|
const commitResult = await commitMemoryWrite2({
|
|
262863
263213
|
memoryDir: memoryRoot,
|
|
@@ -262917,34 +263267,34 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
262917
263267
|
} = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
262918
263268
|
const { commitMemoryWrite: commitMemoryWrite2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
|
|
262919
263269
|
const { unlink: unlink4 } = await import("node:fs/promises");
|
|
262920
|
-
const { existsSync:
|
|
262921
|
-
const { isAbsolute: isAbsolute25, join:
|
|
263270
|
+
const { existsSync: existsSync51 } = await import("node:fs");
|
|
263271
|
+
const { isAbsolute: isAbsolute25, join: join75, normalize: normalize4, relative: relative8, sep: sep8 } = await import("node:path");
|
|
262922
263272
|
if (isAbsolute25(parsed.path) || parsed.path.length === 0) {
|
|
262923
263273
|
sendFailure("delete_memory_file: path must be a non-empty relative path");
|
|
262924
263274
|
return;
|
|
262925
263275
|
}
|
|
262926
263276
|
const memoryRoot = getScopedMemoryFilesystemRoot2(parsed.agent_id);
|
|
262927
|
-
const absolutePath = normalize4(
|
|
263277
|
+
const absolutePath = normalize4(join75(memoryRoot, parsed.path));
|
|
262928
263278
|
const rel = relative8(memoryRoot, absolutePath);
|
|
262929
|
-
if (rel.startsWith("..") || rel === "" || isAbsolute25(rel) || rel.split(
|
|
263279
|
+
if (rel.startsWith("..") || rel === "" || isAbsolute25(rel) || rel.split(sep8).includes("..")) {
|
|
262930
263280
|
sendFailure("delete_memory_file: path must resolve inside the memory root");
|
|
262931
263281
|
return;
|
|
262932
263282
|
}
|
|
262933
|
-
if (!
|
|
263283
|
+
if (!existsSync51(join75(memoryRoot, ".git"))) {
|
|
262934
263284
|
const enabled = await isMemfsEnabledOnServer2(parsed.agent_id);
|
|
262935
263285
|
if (!enabled) {
|
|
262936
263286
|
sendFailure("delete_memory_file: memfs is not enabled for this agent");
|
|
262937
263287
|
return;
|
|
262938
263288
|
}
|
|
262939
263289
|
await ensureLocalMemfsCheckout2(parsed.agent_id);
|
|
262940
|
-
if (!
|
|
263290
|
+
if (!existsSync51(join75(memoryRoot, ".git"))) {
|
|
262941
263291
|
sendFailure("delete_memory_file: failed to initialize local memory checkout");
|
|
262942
263292
|
return;
|
|
262943
263293
|
}
|
|
262944
263294
|
}
|
|
262945
|
-
const pathspec = rel.split(
|
|
263295
|
+
const pathspec = rel.split(sep8).join("/");
|
|
262946
263296
|
const removeIfPresent = async () => {
|
|
262947
|
-
if (!
|
|
263297
|
+
if (!existsSync51(absolutePath))
|
|
262948
263298
|
return false;
|
|
262949
263299
|
await unlink4(absolutePath);
|
|
262950
263300
|
return true;
|
|
@@ -263013,7 +263363,7 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
263013
263363
|
return false;
|
|
263014
263364
|
}
|
|
263015
263365
|
var warnMemoryCommand, WIKI_LINK_REGEX, IMAGE_MIME_BY_EXTENSION, MEMORY_PUSH_AWAIT_CAP_MS = 8000;
|
|
263016
|
-
var
|
|
263366
|
+
var init_memory6 = __esm(async () => {
|
|
263017
263367
|
init_error_reporting();
|
|
263018
263368
|
init_debug();
|
|
263019
263369
|
await init_protocol_inbound();
|
|
@@ -263118,12 +263468,12 @@ __export(exports_remote_model_catalog, {
|
|
|
263118
263468
|
applyCatalogModels: () => applyCatalogModels,
|
|
263119
263469
|
__testResetRemoteModelCatalog: () => __testResetRemoteModelCatalog
|
|
263120
263470
|
});
|
|
263121
|
-
import { existsSync as
|
|
263471
|
+
import { existsSync as existsSync51, mkdirSync as mkdirSync37, readFileSync as readFileSync42, writeFileSync as writeFileSync32 } from "node:fs";
|
|
263122
263472
|
import { homedir as homedir38 } from "node:os";
|
|
263123
|
-
import { dirname as dirname31, join as
|
|
263473
|
+
import { dirname as dirname31, join as join75 } from "node:path";
|
|
263124
263474
|
function catalogCachePath() {
|
|
263125
|
-
const dir = process.env.LETTA_MODEL_CATALOG_CACHE_DIR ||
|
|
263126
|
-
return
|
|
263475
|
+
const dir = process.env.LETTA_MODEL_CATALOG_CACHE_DIR || join75(homedir38(), ".letta", "cache");
|
|
263476
|
+
return join75(dir, "model-catalog.json");
|
|
263127
263477
|
}
|
|
263128
263478
|
function normalizeCatalogSource(source) {
|
|
263129
263479
|
try {
|
|
@@ -263222,10 +263572,10 @@ function persistCatalogCache(entries2, source) {
|
|
|
263222
263572
|
function loadPersistedModelCatalog(source) {
|
|
263223
263573
|
try {
|
|
263224
263574
|
const path33 = catalogCachePath();
|
|
263225
|
-
if (!
|
|
263575
|
+
if (!existsSync51(path33)) {
|
|
263226
263576
|
return false;
|
|
263227
263577
|
}
|
|
263228
|
-
const parsed = JSON.parse(
|
|
263578
|
+
const parsed = JSON.parse(readFileSync42(path33, "utf-8"));
|
|
263229
263579
|
if (parsed.schemaVersion !== CACHE_SCHEMA_VERSION || parsed.source !== normalizeCatalogSource(source) || !Array.isArray(parsed.models)) {
|
|
263230
263580
|
return false;
|
|
263231
263581
|
}
|
|
@@ -263911,7 +264261,7 @@ function recordStaleHandleUse(collector, owner, capability, onDiagnostic) {
|
|
|
263911
264261
|
var MOD_DIAGNOSTICS_MAX_COUNT = 200, MOD_DIAGNOSTICS_RESET_COUNT = 50, MOD_DYNAMIC_CONTEXT_MIGRATION_HINT = "Dynamic context is now passed as ctx to commands, tools, events, permissions, and UI renderers. Use ctx.agent, ctx.cwd, ctx.conversation, ctx.model, etc.", MOD_LETTA_GET_CONTEXT_MIGRATION_HINT = "letta.getContext has been removed. Activation has no dynamic invocation context. Move dynamic work into a command, tool, event, permission, status, or statusline callback that receives ctx, or use explicit/global state such as process.cwd() for activation-time background work.", MOD_CTX_GET_CONTEXT_MIGRATION_HINT = "ctx.getContext has been removed. Use ctx directly; scoped fields are available as ctx.agent, ctx.cwd, ctx.conversation, ctx.model, etc.", MOD_GENERIC_GET_CONTEXT_MIGRATION_HINT = "getContext helpers have been removed. If this is callback ctx, use ctx directly; if activation/background code needs runtime state, move it into a callback that receives ctx or use explicit/global state such as process.cwd().";
|
|
263912
264262
|
|
|
263913
264263
|
// src/mods/paths.ts
|
|
263914
|
-
import { existsSync as
|
|
264264
|
+
import { existsSync as existsSync52 } from "node:fs";
|
|
263915
264265
|
import { homedir as homedir39 } from "node:os";
|
|
263916
264266
|
import path33 from "node:path";
|
|
263917
264267
|
function getGlobalModsDirectory(homeDirectory = homedir39()) {
|
|
@@ -263925,10 +264275,10 @@ function resolveDefaultGlobalModsDirectory(homeDirectory = homedir39(), env6 = p
|
|
|
263925
264275
|
if (environmentDirectory)
|
|
263926
264276
|
return environmentDirectory;
|
|
263927
264277
|
const modsDirectory = getGlobalModsDirectory(homeDirectory);
|
|
263928
|
-
if (
|
|
264278
|
+
if (existsSync52(modsDirectory))
|
|
263929
264279
|
return modsDirectory;
|
|
263930
264280
|
const legacyDirectory = getLegacyGlobalExtensionsDirectory(homeDirectory);
|
|
263931
|
-
if (
|
|
264281
|
+
if (existsSync52(legacyDirectory))
|
|
263932
264282
|
return legacyDirectory;
|
|
263933
264283
|
return modsDirectory;
|
|
263934
264284
|
}
|
|
@@ -272078,7 +272428,7 @@ ${lanes.join(`
|
|
|
272078
272428
|
return process.memoryUsage().heapUsed;
|
|
272079
272429
|
},
|
|
272080
272430
|
getFileSize(path35) {
|
|
272081
|
-
const stat12 =
|
|
272431
|
+
const stat12 = statSync20(path35);
|
|
272082
272432
|
if (stat12 == null ? undefined : stat12.isFile()) {
|
|
272083
272433
|
return stat12.size;
|
|
272084
272434
|
}
|
|
@@ -272121,7 +272471,7 @@ ${lanes.join(`
|
|
|
272121
272471
|
}
|
|
272122
272472
|
};
|
|
272123
272473
|
return nodeSystem;
|
|
272124
|
-
function
|
|
272474
|
+
function statSync20(path35) {
|
|
272125
272475
|
try {
|
|
272126
272476
|
return _fs.statSync(path35, statSyncOptions);
|
|
272127
272477
|
} catch {
|
|
@@ -272173,7 +272523,7 @@ ${lanes.join(`
|
|
|
272173
272523
|
activeSession.post("Profiler.stop", (err, { profile }) => {
|
|
272174
272524
|
var _a10;
|
|
272175
272525
|
if (!err) {
|
|
272176
|
-
if ((_a10 =
|
|
272526
|
+
if ((_a10 = statSync20(profilePath)) == null ? undefined : _a10.isDirectory()) {
|
|
272177
272527
|
profilePath = _path.join(profilePath, `${(/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-")}+P${process.pid}.cpuprofile`);
|
|
272178
272528
|
}
|
|
272179
272529
|
try {
|
|
@@ -272282,7 +272632,7 @@ ${lanes.join(`
|
|
|
272282
272632
|
let stat12;
|
|
272283
272633
|
if (typeof dirent === "string" || dirent.isSymbolicLink()) {
|
|
272284
272634
|
const name = combinePaths(path35, entry);
|
|
272285
|
-
stat12 =
|
|
272635
|
+
stat12 = statSync20(name);
|
|
272286
272636
|
if (!stat12) {
|
|
272287
272637
|
continue;
|
|
272288
272638
|
}
|
|
@@ -272306,7 +272656,7 @@ ${lanes.join(`
|
|
|
272306
272656
|
return matchFiles(path35, extensions, excludes, includes2, useCaseSensitiveFileNames2, process.cwd(), depth, getAccessibleFileSystemEntries, realpath6);
|
|
272307
272657
|
}
|
|
272308
272658
|
function fileSystemEntryExists(path35, entryKind) {
|
|
272309
|
-
const stat12 =
|
|
272659
|
+
const stat12 = statSync20(path35);
|
|
272310
272660
|
if (!stat12) {
|
|
272311
272661
|
return false;
|
|
272312
272662
|
}
|
|
@@ -272340,7 +272690,7 @@ ${lanes.join(`
|
|
|
272340
272690
|
}
|
|
272341
272691
|
function getModifiedTime3(path35) {
|
|
272342
272692
|
var _a10;
|
|
272343
|
-
return (_a10 =
|
|
272693
|
+
return (_a10 = statSync20(path35)) == null ? undefined : _a10.mtime;
|
|
272344
272694
|
}
|
|
272345
272695
|
function setModifiedTime(path35, time3) {
|
|
272346
272696
|
try {
|
|
@@ -305466,11 +305816,11 @@ ${lanes.join(`
|
|
|
305466
305816
|
if (i4 < rootLength) {
|
|
305467
305817
|
return;
|
|
305468
305818
|
}
|
|
305469
|
-
const
|
|
305470
|
-
if (
|
|
305819
|
+
const sep8 = directory.lastIndexOf(directorySeparator, i4 - 1);
|
|
305820
|
+
if (sep8 === -1) {
|
|
305471
305821
|
return;
|
|
305472
305822
|
}
|
|
305473
|
-
return directory.substr(0, Math.max(
|
|
305823
|
+
return directory.substr(0, Math.max(sep8, rootLength));
|
|
305474
305824
|
}
|
|
305475
305825
|
}
|
|
305476
305826
|
}
|
|
@@ -432746,7 +433096,7 @@ function createModChangeBatcher(onChange) {
|
|
|
432746
433096
|
}
|
|
432747
433097
|
|
|
432748
433098
|
// src/mods/package-manifest.ts
|
|
432749
|
-
import { readFileSync as
|
|
433099
|
+
import { readFileSync as readFileSync43 } from "node:fs";
|
|
432750
433100
|
import path35 from "node:path";
|
|
432751
433101
|
function isRecord15(value) {
|
|
432752
433102
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -432956,7 +433306,7 @@ function parseLettaPackageManifest(packageJson) {
|
|
|
432956
433306
|
}
|
|
432957
433307
|
function readLettaPackageManifest(packageJsonPath) {
|
|
432958
433308
|
try {
|
|
432959
|
-
const packageJson = JSON.parse(
|
|
433309
|
+
const packageJson = JSON.parse(readFileSync43(packageJsonPath, "utf8"));
|
|
432960
433310
|
return parseLettaPackageManifest(packageJson);
|
|
432961
433311
|
} catch (error5) {
|
|
432962
433312
|
return {
|
|
@@ -432986,9 +433336,9 @@ var init_package_manifest = __esm(() => {
|
|
|
432986
433336
|
|
|
432987
433337
|
// src/mods/package-registry.ts
|
|
432988
433338
|
import {
|
|
432989
|
-
existsSync as
|
|
433339
|
+
existsSync as existsSync53,
|
|
432990
433340
|
mkdirSync as mkdirSync39,
|
|
432991
|
-
readFileSync as
|
|
433341
|
+
readFileSync as readFileSync44,
|
|
432992
433342
|
rmSync as rmSync20,
|
|
432993
433343
|
writeFileSync as writeFileSync34
|
|
432994
433344
|
} from "node:fs";
|
|
@@ -433044,7 +433394,7 @@ function parseJsonFile(filePath) {
|
|
|
433044
433394
|
try {
|
|
433045
433395
|
return {
|
|
433046
433396
|
ok: true,
|
|
433047
|
-
value: JSON.parse(
|
|
433397
|
+
value: JSON.parse(readFileSync44(filePath, "utf8"))
|
|
433048
433398
|
};
|
|
433049
433399
|
} catch (error5) {
|
|
433050
433400
|
return {
|
|
@@ -433058,7 +433408,7 @@ function getRegistryPath(modsRoot) {
|
|
|
433058
433408
|
}
|
|
433059
433409
|
function readRegistryObject(modsRoot) {
|
|
433060
433410
|
const registryPath = getRegistryPath(modsRoot);
|
|
433061
|
-
if (!
|
|
433411
|
+
if (!existsSync53(registryPath)) {
|
|
433062
433412
|
return { diagnostics: [], ok: false, registryExists: false, registryPath };
|
|
433063
433413
|
}
|
|
433064
433414
|
const registryResult = parseJsonFile(registryPath);
|
|
@@ -433490,7 +433840,7 @@ function writePackageRegistry(registryPath, registry4) {
|
|
|
433490
433840
|
}
|
|
433491
433841
|
function validateManagedModPackageRegistryForMutation(modsRoot) {
|
|
433492
433842
|
const registryPath = getRegistryPath(modsRoot);
|
|
433493
|
-
const contents =
|
|
433843
|
+
const contents = existsSync53(registryPath) ? readFileSync44(registryPath, "utf8") : null;
|
|
433494
433844
|
const registry4 = readMutablePackageRegistry(modsRoot, {
|
|
433495
433845
|
createIfMissing: true
|
|
433496
433846
|
});
|
|
@@ -433613,12 +433963,12 @@ var init_package_registry = __esm(() => {
|
|
|
433613
433963
|
});
|
|
433614
433964
|
|
|
433615
433965
|
// src/mods/mod-sources.ts
|
|
433616
|
-
import { existsSync as
|
|
433966
|
+
import { existsSync as existsSync54, readdirSync as readdirSync21 } from "node:fs";
|
|
433617
433967
|
import path37 from "node:path";
|
|
433618
433968
|
function listModFiles(directory) {
|
|
433619
|
-
if (!
|
|
433969
|
+
if (!existsSync54(directory))
|
|
433620
433970
|
return [];
|
|
433621
|
-
return
|
|
433971
|
+
return readdirSync21(directory, { withFileTypes: true }).filter((entry) => {
|
|
433622
433972
|
if (!entry.isFile())
|
|
433623
433973
|
return false;
|
|
433624
433974
|
if (entry.name.startsWith("."))
|
|
@@ -433632,7 +433982,7 @@ function resolveLocalModSources(options = {}) {
|
|
|
433632
433982
|
const includeGlobalMods = options.includeGlobalMods !== false;
|
|
433633
433983
|
const managedPackages = includeGlobalMods ? resolveManagedModPackages(globalModsDirectory) : { diagnostics: [], files: [], packages: [] };
|
|
433634
433984
|
const sources = [];
|
|
433635
|
-
if (includeGlobalMods && legacyGlobalExtensionsDirectory && path37.resolve(legacyGlobalExtensionsDirectory) !== path37.resolve(globalModsDirectory) &&
|
|
433985
|
+
if (includeGlobalMods && legacyGlobalExtensionsDirectory && path37.resolve(legacyGlobalExtensionsDirectory) !== path37.resolve(globalModsDirectory) && existsSync54(legacyGlobalExtensionsDirectory)) {
|
|
433636
433986
|
sources.push({
|
|
433637
433987
|
files: listModFiles(legacyGlobalExtensionsDirectory),
|
|
433638
433988
|
legacyMigrationTargetRoot: globalModsDirectory,
|
|
@@ -433811,11 +434161,11 @@ function createNoopModPanelHandle() {
|
|
|
433811
434161
|
// src/mods/mod-engine.ts
|
|
433812
434162
|
import { createHash as createHash12 } from "node:crypto";
|
|
433813
434163
|
import {
|
|
433814
|
-
existsSync as
|
|
434164
|
+
existsSync as existsSync55,
|
|
433815
434165
|
mkdirSync as mkdirSync41,
|
|
433816
|
-
readdirSync as
|
|
433817
|
-
readFileSync as
|
|
433818
|
-
statSync as
|
|
434166
|
+
readdirSync as readdirSync22,
|
|
434167
|
+
readFileSync as readFileSync45,
|
|
434168
|
+
statSync as statSync20,
|
|
433819
434169
|
unlinkSync as unlinkSync13,
|
|
433820
434170
|
writeFileSync as writeFileSync35
|
|
433821
434171
|
} from "node:fs";
|
|
@@ -433990,7 +434340,7 @@ function prepareModForImport(modPath, source) {
|
|
|
433990
434340
|
}
|
|
433991
434341
|
function createImportableModPath(modPath, cacheDirectory, source) {
|
|
433992
434342
|
const importCacheDirectory = getManagedPackageImportCacheDirectory(modPath, source) ?? cacheDirectory;
|
|
433993
|
-
const sourceText =
|
|
434343
|
+
const sourceText = readFileSync45(modPath, "utf8");
|
|
433994
434344
|
const hash3 = createHash12("sha256").update(sourceText).digest("hex").slice(0, 16);
|
|
433995
434345
|
const fileExtension = path39.extname(modPath);
|
|
433996
434346
|
const importableSource = prepareModForImport(modPath, sourceText);
|
|
@@ -434001,11 +434351,11 @@ function createImportableModPath(modPath, cacheDirectory, source) {
|
|
|
434001
434351
|
}
|
|
434002
434352
|
const baseName = path39.basename(modPath, fileExtension).replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
434003
434353
|
const importPath = path39.join(importCacheDirectory, `.letta-mod-${baseName}-${hash3}.mjs`);
|
|
434004
|
-
if (!
|
|
434354
|
+
if (!existsSync55(importPath)) {
|
|
434005
434355
|
writeFileSync35(importPath, importableSource, "utf8");
|
|
434006
434356
|
}
|
|
434007
434357
|
try {
|
|
434008
|
-
for (const entry of
|
|
434358
|
+
for (const entry of readdirSync22(importCacheDirectory)) {
|
|
434009
434359
|
if (entry.startsWith(`.letta-mod-${baseName}-`) && entry !== path39.basename(importPath)) {
|
|
434010
434360
|
unlinkSync13(path39.join(importCacheDirectory, entry));
|
|
434011
434361
|
}
|
|
@@ -434644,8 +434994,8 @@ async function loadLocalMods(options) {
|
|
|
434644
434994
|
recordLegacyExtensionLoadedDiagnostic(registry4, owner, source, options.onDiagnostic);
|
|
434645
434995
|
}
|
|
434646
434996
|
try {
|
|
434647
|
-
const mtimeMs =
|
|
434648
|
-
const sourceText =
|
|
434997
|
+
const mtimeMs = statSync20(modPath).mtimeMs;
|
|
434998
|
+
const sourceText = readFileSync45(modPath, "utf8");
|
|
434649
434999
|
recordDeprecatedContextApiSourceDiagnostics(sourceText, (diagnostic) => {
|
|
434650
435000
|
recordModDiagnostic(registry4, {
|
|
434651
435001
|
...diagnostic,
|
|
@@ -435167,7 +435517,7 @@ var init_memfs_sync = __esm(() => {
|
|
|
435167
435517
|
|
|
435168
435518
|
// src/websocket/listener/mod-adapter.ts
|
|
435169
435519
|
import { createHash as createHash13 } from "node:crypto";
|
|
435170
|
-
import { join as
|
|
435520
|
+
import { join as join76 } from "node:path";
|
|
435171
435521
|
async function getUnavailableListenerClient() {
|
|
435172
435522
|
throw new Error("letta.client is not available in listener mods");
|
|
435173
435523
|
}
|
|
@@ -435243,14 +435593,14 @@ function ensureListenerModAdapter(runtime) {
|
|
|
435243
435593
|
}
|
|
435244
435594
|
function resolveListenerAgentModsDirectory(agentId) {
|
|
435245
435595
|
try {
|
|
435246
|
-
return settingsManager.isMemfsEnabled(agentId) ?
|
|
435596
|
+
return settingsManager.isMemfsEnabled(agentId) ? join76(getScopedMemoryFilesystemRoot(agentId), "mods") : null;
|
|
435247
435597
|
} catch {
|
|
435248
435598
|
return null;
|
|
435249
435599
|
}
|
|
435250
435600
|
}
|
|
435251
435601
|
function resolveListenerAgentModCacheDirectory(agentId) {
|
|
435252
435602
|
const cacheKey = createHash13("sha256").update(agentId).digest("hex");
|
|
435253
|
-
return
|
|
435603
|
+
return join76(getModCacheDirectory(), "listener-agents", cacheKey);
|
|
435254
435604
|
}
|
|
435255
435605
|
async function ensureListenerAgentModAdapter(runtime, agentId) {
|
|
435256
435606
|
runtime.agentModAdapters ??= new Map;
|
|
@@ -437407,19 +437757,19 @@ function emitSkillsUpdated(socket, safeSocketSend) {
|
|
|
437407
437757
|
}
|
|
437408
437758
|
async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
437409
437759
|
const {
|
|
437410
|
-
existsSync:
|
|
437760
|
+
existsSync: existsSync56,
|
|
437411
437761
|
lstatSync: lstatSync3,
|
|
437412
437762
|
mkdirSync: mkdirSync42,
|
|
437413
437763
|
rmdirSync: rmdirSync2,
|
|
437414
437764
|
symlinkSync: symlinkSync2,
|
|
437415
437765
|
unlinkSync: unlinkSync14
|
|
437416
437766
|
} = await import("node:fs");
|
|
437417
|
-
const { basename: basename21, join:
|
|
437418
|
-
const lettaHome = process.env.LETTA_HOME ||
|
|
437419
|
-
const globalSkillsDir =
|
|
437767
|
+
const { basename: basename21, join: join77 } = await import("node:path");
|
|
437768
|
+
const lettaHome = process.env.LETTA_HOME || join77(process.env.HOME || process.env.USERPROFILE || "~", ".letta");
|
|
437769
|
+
const globalSkillsDir = join77(lettaHome, "skills");
|
|
437420
437770
|
if (parsed.type === "skill_enable") {
|
|
437421
437771
|
try {
|
|
437422
|
-
if (!
|
|
437772
|
+
if (!existsSync56(parsed.skill_path)) {
|
|
437423
437773
|
safeSocketSend(socket, {
|
|
437424
437774
|
type: "skill_enable_response",
|
|
437425
437775
|
request_id: parsed.request_id,
|
|
@@ -437428,8 +437778,8 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
437428
437778
|
}, "listener_skill_send_failed", "listener_skill_command");
|
|
437429
437779
|
return true;
|
|
437430
437780
|
}
|
|
437431
|
-
const skillMdPath =
|
|
437432
|
-
if (!
|
|
437781
|
+
const skillMdPath = join77(parsed.skill_path, "SKILL.md");
|
|
437782
|
+
if (!existsSync56(skillMdPath)) {
|
|
437433
437783
|
safeSocketSend(socket, {
|
|
437434
437784
|
type: "skill_enable_response",
|
|
437435
437785
|
request_id: parsed.request_id,
|
|
@@ -437439,9 +437789,9 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
437439
437789
|
return true;
|
|
437440
437790
|
}
|
|
437441
437791
|
const linkName = basename21(parsed.skill_path);
|
|
437442
|
-
const linkPath =
|
|
437792
|
+
const linkPath = join77(globalSkillsDir, linkName);
|
|
437443
437793
|
mkdirSync42(globalSkillsDir, { recursive: true });
|
|
437444
|
-
if (
|
|
437794
|
+
if (existsSync56(linkPath)) {
|
|
437445
437795
|
const stat12 = lstatSync3(linkPath);
|
|
437446
437796
|
if (stat12.isSymbolicLink()) {
|
|
437447
437797
|
if (process.platform === "win32") {
|
|
@@ -437482,8 +437832,8 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
437482
437832
|
}
|
|
437483
437833
|
if (parsed.type === "skill_disable") {
|
|
437484
437834
|
try {
|
|
437485
|
-
const linkPath =
|
|
437486
|
-
if (!
|
|
437835
|
+
const linkPath = join77(globalSkillsDir, parsed.name);
|
|
437836
|
+
if (!existsSync56(linkPath)) {
|
|
437487
437837
|
safeSocketSend(socket, {
|
|
437488
437838
|
type: "skill_disable_response",
|
|
437489
437839
|
request_id: parsed.request_id,
|
|
@@ -438403,7 +438753,7 @@ var init_control_inputs = __esm(async () => {
|
|
|
438403
438753
|
});
|
|
438404
438754
|
|
|
438405
438755
|
// src/websocket/terminal-handler.ts
|
|
438406
|
-
import { existsSync as
|
|
438756
|
+
import { existsSync as existsSync56 } from "node:fs";
|
|
438407
438757
|
import * as os7 from "node:os";
|
|
438408
438758
|
import WebSocket6 from "ws";
|
|
438409
438759
|
function getTerminalKey(connectionId, terminalId) {
|
|
@@ -438419,7 +438769,7 @@ function getDefaultShell() {
|
|
|
438419
438769
|
"/bin/bash"
|
|
438420
438770
|
];
|
|
438421
438771
|
for (const candidate of candidates2) {
|
|
438422
|
-
if (candidate &&
|
|
438772
|
+
if (candidate && existsSync56(candidate)) {
|
|
438423
438773
|
return candidate;
|
|
438424
438774
|
}
|
|
438425
438775
|
}
|
|
@@ -440373,14 +440723,14 @@ var init_tui_perf = __esm(() => {
|
|
|
440373
440723
|
|
|
440374
440724
|
// src/cli/helpers/chunk-log.ts
|
|
440375
440725
|
import {
|
|
440376
|
-
existsSync as
|
|
440726
|
+
existsSync as existsSync57,
|
|
440377
440727
|
mkdirSync as mkdirSync43,
|
|
440378
|
-
readdirSync as
|
|
440728
|
+
readdirSync as readdirSync23,
|
|
440379
440729
|
unlinkSync as unlinkSync14,
|
|
440380
440730
|
writeFileSync as writeFileSync36
|
|
440381
440731
|
} from "node:fs";
|
|
440382
440732
|
import { homedir as homedir41 } from "node:os";
|
|
440383
|
-
import { join as
|
|
440733
|
+
import { join as join77 } from "node:path";
|
|
440384
440734
|
function truncateStr(value, maxLen) {
|
|
440385
440735
|
if (value === null || value === undefined)
|
|
440386
440736
|
return "";
|
|
@@ -440444,8 +440794,8 @@ class ChunkLog {
|
|
|
440444
440794
|
agentDir = null;
|
|
440445
440795
|
dirCreated = false;
|
|
440446
440796
|
init(agentId, sessionId) {
|
|
440447
|
-
this.agentDir =
|
|
440448
|
-
this.logPath =
|
|
440797
|
+
this.agentDir = join77(LOG_BASE_DIR, agentId);
|
|
440798
|
+
this.logPath = join77(this.agentDir, `${sessionId}.jsonl`);
|
|
440449
440799
|
this.buffer = [];
|
|
440450
440800
|
this.dirty = false;
|
|
440451
440801
|
this.dirCreated = false;
|
|
@@ -440474,7 +440824,7 @@ class ChunkLog {
|
|
|
440474
440824
|
if (this.dirCreated || !this.agentDir)
|
|
440475
440825
|
return;
|
|
440476
440826
|
try {
|
|
440477
|
-
if (!
|
|
440827
|
+
if (!existsSync57(this.agentDir)) {
|
|
440478
440828
|
mkdirSync43(this.agentDir, { recursive: true });
|
|
440479
440829
|
}
|
|
440480
440830
|
this.dirCreated = true;
|
|
@@ -440499,14 +440849,14 @@ class ChunkLog {
|
|
|
440499
440849
|
if (!this.agentDir)
|
|
440500
440850
|
return;
|
|
440501
440851
|
try {
|
|
440502
|
-
if (!
|
|
440852
|
+
if (!existsSync57(this.agentDir))
|
|
440503
440853
|
return;
|
|
440504
|
-
const files =
|
|
440854
|
+
const files = readdirSync23(this.agentDir).filter((f4) => f4.endsWith(".jsonl")).sort();
|
|
440505
440855
|
if (files.length >= MAX_SESSION_FILES2) {
|
|
440506
440856
|
const toDelete = files.slice(0, files.length - MAX_SESSION_FILES2 + 1);
|
|
440507
440857
|
for (const file of toDelete) {
|
|
440508
440858
|
try {
|
|
440509
|
-
unlinkSync14(
|
|
440859
|
+
unlinkSync14(join77(this.agentDir, file));
|
|
440510
440860
|
} catch (e2) {
|
|
440511
440861
|
debugWarn("chunkLog", `Failed to delete old session log ${file}: ${e2 instanceof Error ? e2.message : String(e2)}`);
|
|
440512
440862
|
}
|
|
@@ -440520,7 +440870,7 @@ class ChunkLog {
|
|
|
440520
440870
|
var MAX_ENTRIES = 100, CONTENT_TRUNCATE_LEN = 200, MAX_SESSION_FILES2 = 5, LOG_BASE_DIR, chunkLog;
|
|
440521
440871
|
var init_chunk_log = __esm(() => {
|
|
440522
440872
|
init_debug();
|
|
440523
|
-
LOG_BASE_DIR =
|
|
440873
|
+
LOG_BASE_DIR = join77(homedir41(), ".letta", "logs", "chunk-logs");
|
|
440524
440874
|
chunkLog = new ChunkLog;
|
|
440525
440875
|
});
|
|
440526
440876
|
|
|
@@ -446547,8 +446897,8 @@ var init_turn_approval = __esm(async () => {
|
|
|
446547
446897
|
});
|
|
446548
446898
|
|
|
446549
446899
|
// src/agent/attached-repository-git-sync.ts
|
|
446550
|
-
import { existsSync as
|
|
446551
|
-
import { join as
|
|
446900
|
+
import { existsSync as existsSync58 } from "node:fs";
|
|
446901
|
+
import { join as join78 } from "node:path";
|
|
446552
446902
|
async function getPendingCommitCount(path42) {
|
|
446553
446903
|
const divergence = await getMemoryAheadBehind(path42);
|
|
446554
446904
|
if (divergence) {
|
|
@@ -446578,7 +446928,7 @@ async function syncPendingAttachedRepositoryCommitsUnlocked(params) {
|
|
|
446578
446928
|
path: path42,
|
|
446579
446929
|
permissions: params.repository.permissions ?? "unknown"
|
|
446580
446930
|
};
|
|
446581
|
-
if (!
|
|
446931
|
+
if (!existsSync58(join78(path42, ".git"))) {
|
|
446582
446932
|
return {
|
|
446583
446933
|
...resultBase,
|
|
446584
446934
|
status: "skipped",
|
|
@@ -446748,8 +447098,8 @@ var init_attached_repository_git_sync = __esm(() => {
|
|
|
446748
447098
|
});
|
|
446749
447099
|
|
|
446750
447100
|
// src/reminders/memory-git-sync.ts
|
|
446751
|
-
import { existsSync as
|
|
446752
|
-
import { join as
|
|
447101
|
+
import { existsSync as existsSync59 } from "node:fs";
|
|
447102
|
+
import { join as join79 } from "node:path";
|
|
446753
447103
|
function formatMemoryRepairInProgressReminder(result3) {
|
|
446754
447104
|
return `${SYSTEM_REMINDER_OPEN}
|
|
446755
447105
|
MEMORY REPAIR RUNNING: A background worker is repairing the memory repository.
|
|
@@ -446859,7 +447209,7 @@ async function runPostTurnMemorySync(params, dependencies4 = {}) {
|
|
|
446859
447209
|
if (memorySyncEnabled) {
|
|
446860
447210
|
try {
|
|
446861
447211
|
const memoryDir = getScopedMemoryFilesystemRoot(params.agentId);
|
|
446862
|
-
const release =
|
|
447212
|
+
const release = existsSync59(join79(memoryDir, ".git")) ? await (dependencies4.claimOperation ?? claimMemoryOperation)(memoryDir) : undefined;
|
|
446863
447213
|
if (release !== null) {
|
|
446864
447214
|
try {
|
|
446865
447215
|
const result3 = await syncMemory(params.agentId);
|
|
@@ -447696,12 +448046,12 @@ function rowToolCalls(row, index, diagnostics2) {
|
|
|
447696
448046
|
}
|
|
447697
448047
|
return calls;
|
|
447698
448048
|
}
|
|
447699
|
-
function
|
|
448049
|
+
function contentText2(content) {
|
|
447700
448050
|
if (typeof content === "string") {
|
|
447701
448051
|
if (content.startsWith(CONTENT_JSON_PREFIX)) {
|
|
447702
448052
|
const encoded = content.slice(CONTENT_JSON_PREFIX.length);
|
|
447703
448053
|
try {
|
|
447704
|
-
return
|
|
448054
|
+
return contentText2(JSON.parse(encoded));
|
|
447705
448055
|
} catch {
|
|
447706
448056
|
return encoded;
|
|
447707
448057
|
}
|
|
@@ -447787,7 +448137,7 @@ var init_hermes = __esm(() => {
|
|
|
447787
448137
|
});
|
|
447788
448138
|
};
|
|
447789
448139
|
if (row.role === "user") {
|
|
447790
|
-
const content =
|
|
448140
|
+
const content = contentText2(row.content);
|
|
447791
448141
|
if (content) {
|
|
447792
448142
|
emit({
|
|
447793
448143
|
type: "message",
|
|
@@ -447807,7 +448157,7 @@ var init_hermes = __esm(() => {
|
|
|
447807
448157
|
...timestamp ? { timestamp } : {}
|
|
447808
448158
|
});
|
|
447809
448159
|
}
|
|
447810
|
-
const content =
|
|
448160
|
+
const content = contentText2(row.content);
|
|
447811
448161
|
if (content) {
|
|
447812
448162
|
emit({
|
|
447813
448163
|
type: "message",
|
|
@@ -447830,7 +448180,7 @@ var init_hermes = __esm(() => {
|
|
|
447830
448180
|
if (row.role === "tool") {
|
|
447831
448181
|
emit({
|
|
447832
448182
|
type: "tool_result",
|
|
447833
|
-
content:
|
|
448183
|
+
content: contentText2(row.content),
|
|
447834
448184
|
...typeof row.tool_call_id === "string" && row.tool_call_id ? { callId: row.tool_call_id } : {},
|
|
447835
448185
|
...timestamp ? { timestamp } : {}
|
|
447836
448186
|
});
|
|
@@ -449098,7 +449448,7 @@ var init_core5 = __esm(() => {
|
|
|
449098
449448
|
import { spawn as spawn10 } from "node:child_process";
|
|
449099
449449
|
import { accessSync as accessSync2, constants as constants6 } from "node:fs";
|
|
449100
449450
|
import { homedir as homedir42 } from "node:os";
|
|
449101
|
-
import { join as
|
|
449451
|
+
import { join as join80 } from "node:path";
|
|
449102
449452
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
449103
449453
|
async function normalizeCheckpoint(input) {
|
|
449104
449454
|
const { decoded, bounds, filters } = await decodeCheckpoint(input);
|
|
@@ -449122,7 +449472,7 @@ async function decodeCheckpoint(input) {
|
|
|
449122
449472
|
}
|
|
449123
449473
|
async function loadDeepAgentsCheckpoint(checkpoint) {
|
|
449124
449474
|
validateLocation(checkpoint);
|
|
449125
|
-
const path42 = checkpoint.path ??
|
|
449475
|
+
const path42 = checkpoint.path ?? join80(homedir42(), ".deepagents", "sessions.db");
|
|
449126
449476
|
const python = checkpoint.pythonExecutable ?? process.env.PYTHON ?? "python3";
|
|
449127
449477
|
const helper = resolveHelperPath();
|
|
449128
449478
|
return await new Promise((resolve39, reject2) => {
|
|
@@ -449341,8 +449691,8 @@ var init_deepagents = __esm(() => {
|
|
|
449341
449691
|
});
|
|
449342
449692
|
|
|
449343
449693
|
// node_modules/@letta-ai/trajectory/dist/adapters/listing-shared.js
|
|
449344
|
-
import { readdirSync as
|
|
449345
|
-
import { join as
|
|
449694
|
+
import { readdirSync as readdirSync24, statSync as statSync21 } from "node:fs";
|
|
449695
|
+
import { join as join81 } from "node:path";
|
|
449346
449696
|
function sortListings(items3) {
|
|
449347
449697
|
return items3.sort((left, right) => {
|
|
449348
449698
|
const l3 = left.updatedAt ?? "";
|
|
@@ -449354,7 +449704,7 @@ function sortListings(items3) {
|
|
|
449354
449704
|
}
|
|
449355
449705
|
function safeReadDir(path42) {
|
|
449356
449706
|
try {
|
|
449357
|
-
return
|
|
449707
|
+
return readdirSync24(path42, { withFileTypes: true }).map((entry) => ({
|
|
449358
449708
|
name: entry.name,
|
|
449359
449709
|
isDirectory: entry.isDirectory(),
|
|
449360
449710
|
isFile: entry.isFile()
|
|
@@ -449365,7 +449715,7 @@ function safeReadDir(path42) {
|
|
|
449365
449715
|
}
|
|
449366
449716
|
function safeStat(path42) {
|
|
449367
449717
|
try {
|
|
449368
|
-
const stats =
|
|
449718
|
+
const stats = statSync21(path42);
|
|
449369
449719
|
return { mtimeMs: stats.mtimeMs, sizeBytes: stats.size };
|
|
449370
449720
|
} catch {
|
|
449371
449721
|
return;
|
|
@@ -449387,7 +449737,7 @@ function collectFiles(root2, extension, depth) {
|
|
|
449387
449737
|
return [];
|
|
449388
449738
|
const collected = [];
|
|
449389
449739
|
for (const entry of safeReadDir(root2)) {
|
|
449390
|
-
const full =
|
|
449740
|
+
const full = join81(root2, entry.name);
|
|
449391
449741
|
if (entry.isFile && entry.name.endsWith(extension)) {
|
|
449392
449742
|
collected.push(full);
|
|
449393
449743
|
} else if (entry.isDirectory) {
|
|
@@ -449472,18 +449822,18 @@ var init_listing_shared = __esm(() => {
|
|
|
449472
449822
|
|
|
449473
449823
|
// node_modules/@letta-ai/trajectory/dist/adapters/claude-code/list.js
|
|
449474
449824
|
import { homedir as homedir43 } from "node:os";
|
|
449475
|
-
import { basename as basename23, join as
|
|
449825
|
+
import { basename as basename23, join as join82 } from "node:path";
|
|
449476
449826
|
async function listClaudeCodeTrajectories(root2) {
|
|
449477
|
-
const base2 = root2 ??
|
|
449827
|
+
const base2 = root2 ?? join82(homedir43(), ".claude", "projects");
|
|
449478
449828
|
const items3 = [];
|
|
449479
449829
|
for (const project of safeReadDir(base2)) {
|
|
449480
449830
|
if (!project.isDirectory)
|
|
449481
449831
|
continue;
|
|
449482
|
-
const projectPath =
|
|
449832
|
+
const projectPath = join82(base2, project.name);
|
|
449483
449833
|
for (const entry of safeReadDir(projectPath)) {
|
|
449484
449834
|
if (!entry.isFile || !entry.name.endsWith(".jsonl"))
|
|
449485
449835
|
continue;
|
|
449486
|
-
const path42 =
|
|
449836
|
+
const path42 = join82(projectPath, entry.name);
|
|
449487
449837
|
const listing = listingFromFile(basename23(entry.name, ".jsonl"), path42);
|
|
449488
449838
|
if (listing)
|
|
449489
449839
|
items3.push(listing);
|
|
@@ -449497,9 +449847,9 @@ var init_list = __esm(() => {
|
|
|
449497
449847
|
|
|
449498
449848
|
// node_modules/@letta-ai/trajectory/dist/adapters/codex/list.js
|
|
449499
449849
|
import { homedir as homedir44 } from "node:os";
|
|
449500
|
-
import { basename as basename24, join as
|
|
449850
|
+
import { basename as basename24, join as join83 } from "node:path";
|
|
449501
449851
|
async function listCodexTrajectories(root2) {
|
|
449502
|
-
const base2 = root2 ??
|
|
449852
|
+
const base2 = root2 ?? join83(homedir44(), ".codex", "sessions");
|
|
449503
449853
|
const items3 = [];
|
|
449504
449854
|
for (const path42 of collectFiles(base2, ".jsonl", 4)) {
|
|
449505
449855
|
const listing = listingFromFile(basename24(path42, ".jsonl"), path42);
|
|
@@ -449514,7 +449864,7 @@ var init_list2 = __esm(() => {
|
|
|
449514
449864
|
|
|
449515
449865
|
// node_modules/@letta-ai/trajectory/dist/adapters/deepagents/list.js
|
|
449516
449866
|
import { homedir as homedir45 } from "node:os";
|
|
449517
|
-
import { join as
|
|
449867
|
+
import { join as join84 } from "node:path";
|
|
449518
449868
|
async function listDeepAgentsTrajectories(root2) {
|
|
449519
449869
|
const path42 = resolveStorePath(root2);
|
|
449520
449870
|
if (!safeStat(path42))
|
|
@@ -449535,8 +449885,8 @@ async function listDeepAgentsTrajectories(root2) {
|
|
|
449535
449885
|
}
|
|
449536
449886
|
function resolveStorePath(root2) {
|
|
449537
449887
|
if (root2 === undefined)
|
|
449538
|
-
return
|
|
449539
|
-
return root2.endsWith(".db") ? root2 :
|
|
449888
|
+
return join84(homedir45(), ".deepagents", "sessions.db");
|
|
449889
|
+
return root2.endsWith(".db") ? root2 : join84(root2, "sessions.db");
|
|
449540
449890
|
}
|
|
449541
449891
|
var init_list3 = __esm(() => {
|
|
449542
449892
|
init_listing_shared();
|
|
@@ -449544,7 +449894,7 @@ var init_list3 = __esm(() => {
|
|
|
449544
449894
|
|
|
449545
449895
|
// node_modules/@letta-ai/trajectory/dist/adapters/hermes/list.js
|
|
449546
449896
|
import { homedir as homedir46 } from "node:os";
|
|
449547
|
-
import { join as
|
|
449897
|
+
import { join as join85 } from "node:path";
|
|
449548
449898
|
async function listHermesTrajectories(root2) {
|
|
449549
449899
|
const path42 = resolveStorePath2(root2);
|
|
449550
449900
|
if (!safeStat(path42))
|
|
@@ -449571,8 +449921,8 @@ async function listHermesTrajectories(root2) {
|
|
|
449571
449921
|
}
|
|
449572
449922
|
function resolveStorePath2(root2) {
|
|
449573
449923
|
if (root2 === undefined)
|
|
449574
|
-
return
|
|
449575
|
-
return root2.endsWith(".db") ? root2 :
|
|
449924
|
+
return join85(homedir46(), ".hermes", "state.db");
|
|
449925
|
+
return root2.endsWith(".db") ? root2 : join85(root2, "state.db");
|
|
449576
449926
|
}
|
|
449577
449927
|
function numeric2(value) {
|
|
449578
449928
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : undefined;
|
|
@@ -449583,18 +449933,18 @@ var init_list4 = __esm(() => {
|
|
|
449583
449933
|
|
|
449584
449934
|
// node_modules/@letta-ai/trajectory/dist/adapters/letta-code/list.js
|
|
449585
449935
|
import { homedir as homedir47 } from "node:os";
|
|
449586
|
-
import { join as
|
|
449936
|
+
import { join as join86 } from "node:path";
|
|
449587
449937
|
async function listLettaCodeTrajectories(root2) {
|
|
449588
|
-
const base2 = root2 ??
|
|
449938
|
+
const base2 = root2 ?? join86(homedir47(), ".letta", "transcripts");
|
|
449589
449939
|
const items3 = [];
|
|
449590
449940
|
for (const agent of safeReadDir(base2)) {
|
|
449591
449941
|
if (!agent.isDirectory)
|
|
449592
449942
|
continue;
|
|
449593
|
-
const agentPath2 =
|
|
449943
|
+
const agentPath2 = join86(base2, agent.name);
|
|
449594
449944
|
for (const conversation of safeReadDir(agentPath2)) {
|
|
449595
449945
|
if (!conversation.isDirectory)
|
|
449596
449946
|
continue;
|
|
449597
|
-
const path42 =
|
|
449947
|
+
const path42 = join86(agentPath2, conversation.name, "transcript.jsonl");
|
|
449598
449948
|
const listing = listingFromFile(`${agent.name}/${conversation.name}`, path42);
|
|
449599
449949
|
if (listing && (listing.sizeBytes ?? 0) > 0)
|
|
449600
449950
|
items3.push(listing);
|
|
@@ -449607,21 +449957,21 @@ var init_list5 = __esm(() => {
|
|
|
449607
449957
|
});
|
|
449608
449958
|
|
|
449609
449959
|
// node_modules/@letta-ai/trajectory/dist/adapters/openclaw/list.js
|
|
449610
|
-
import { existsSync as
|
|
449960
|
+
import { existsSync as existsSync60 } from "node:fs";
|
|
449611
449961
|
import { homedir as homedir48 } from "node:os";
|
|
449612
|
-
import { basename as basename25, join as
|
|
449962
|
+
import { basename as basename25, join as join87 } from "node:path";
|
|
449613
449963
|
async function listOpenClawTrajectories(root2) {
|
|
449614
449964
|
const base2 = root2 ?? defaultStateDir();
|
|
449615
449965
|
const items3 = [];
|
|
449616
|
-
const agentsPath =
|
|
449966
|
+
const agentsPath = join87(base2, "agents");
|
|
449617
449967
|
for (const agent of safeReadDir(agentsPath)) {
|
|
449618
449968
|
if (!agent.isDirectory)
|
|
449619
449969
|
continue;
|
|
449620
|
-
const sessionsPath =
|
|
449970
|
+
const sessionsPath = join87(agentsPath, agent.name, "sessions");
|
|
449621
449971
|
for (const entry of safeReadDir(sessionsPath)) {
|
|
449622
449972
|
if (!entry.isFile || !entry.name.endsWith(".jsonl"))
|
|
449623
449973
|
continue;
|
|
449624
|
-
const path42 =
|
|
449974
|
+
const path42 = join87(sessionsPath, entry.name);
|
|
449625
449975
|
const listing = listingFromFile(basename25(entry.name, ".jsonl"), path42);
|
|
449626
449976
|
if (listing)
|
|
449627
449977
|
items3.push(listing);
|
|
@@ -449633,10 +449983,10 @@ function defaultStateDir() {
|
|
|
449633
449983
|
const override = process.env.OPENCLAW_STATE_DIR?.trim() || process.env.CLAWDBOT_STATE_DIR?.trim();
|
|
449634
449984
|
if (override)
|
|
449635
449985
|
return override;
|
|
449636
|
-
const current =
|
|
449637
|
-
if (
|
|
449986
|
+
const current = join87(homedir48(), ".openclaw");
|
|
449987
|
+
if (existsSync60(current))
|
|
449638
449988
|
return current;
|
|
449639
|
-
return
|
|
449989
|
+
return join87(homedir48(), ".clawdbot");
|
|
449640
449990
|
}
|
|
449641
449991
|
var init_list6 = __esm(() => {
|
|
449642
449992
|
init_listing_shared();
|
|
@@ -449644,14 +449994,14 @@ var init_list6 = __esm(() => {
|
|
|
449644
449994
|
|
|
449645
449995
|
// node_modules/@letta-ai/trajectory/dist/adapters/openhands/list.js
|
|
449646
449996
|
import { homedir as homedir49 } from "node:os";
|
|
449647
|
-
import { join as
|
|
449997
|
+
import { join as join88 } from "node:path";
|
|
449648
449998
|
async function listOpenHandsTrajectories(root2) {
|
|
449649
|
-
const base2 = root2 ??
|
|
449999
|
+
const base2 = root2 ?? join88(homedir49(), ".openhands", "sessions");
|
|
449650
450000
|
const items3 = [];
|
|
449651
450001
|
for (const entry of safeReadDir(base2)) {
|
|
449652
450002
|
if (!entry.isDirectory)
|
|
449653
450003
|
continue;
|
|
449654
|
-
const path42 =
|
|
450004
|
+
const path42 = join88(base2, entry.name);
|
|
449655
450005
|
const facts = safeStat(path42);
|
|
449656
450006
|
items3.push({
|
|
449657
450007
|
id: entry.name,
|
|
@@ -449897,7 +450247,7 @@ import {
|
|
|
449897
450247
|
stat as stat13,
|
|
449898
450248
|
writeFile as writeFile16
|
|
449899
450249
|
} from "node:fs/promises";
|
|
449900
|
-
import { join as
|
|
450250
|
+
import { join as join89 } from "node:path";
|
|
449901
450251
|
function buildReflectionSelectorPrompt(options) {
|
|
449902
450252
|
const lines = [
|
|
449903
450253
|
'You are selecting conversation transcripts for memory reflection. The transcript candidates path is available as the `$TRANSCRIPT_PATH` env var — read it via Bash (e.g. `wc -c "$TRANSCRIPT_PATH"`). Note: `$TRANSCRIPT_PATH` only expands in shell commands; Edit file_path is literal and does NOT expand env vars.',
|
|
@@ -449931,7 +450281,7 @@ async function collectParentMemoryFiles(memoryDir) {
|
|
|
449931
450281
|
return a2.name.localeCompare(b3.name);
|
|
449932
450282
|
});
|
|
449933
450283
|
for (const entry of sortedEntries) {
|
|
449934
|
-
const entryPath =
|
|
450284
|
+
const entryPath = join89(currentDir, entry.name);
|
|
449935
450285
|
const relativePath = relativeDir ? `${relativeDir}/${entry.name}` : entry.name;
|
|
449936
450286
|
if (entry.isDirectory()) {
|
|
449937
450287
|
await walk3(entryPath, relativePath);
|
|
@@ -450347,17 +450697,17 @@ async function writeState(paths, state2) {
|
|
|
450347
450697
|
}
|
|
450348
450698
|
function buildPayloadPath(rootDir, kind) {
|
|
450349
450699
|
const nonce = Math.random().toString(36).slice(2, 8);
|
|
450350
|
-
return
|
|
450700
|
+
return join89(rootDir, `payload-${kind}-${nonce}.json`);
|
|
450351
450701
|
}
|
|
450352
450702
|
function getAgentTranscriptRoot(agentId) {
|
|
450353
|
-
return
|
|
450703
|
+
return join89(getTranscriptRoot(), sanitizePathSegment2(agentId));
|
|
450354
450704
|
}
|
|
450355
450705
|
function getReflectionTranscriptPaths(agentId, conversationId) {
|
|
450356
|
-
const rootDir =
|
|
450706
|
+
const rootDir = join89(getTranscriptRoot(), sanitizePathSegment2(agentId), sanitizePathSegment2(conversationId));
|
|
450357
450707
|
return {
|
|
450358
450708
|
rootDir,
|
|
450359
|
-
transcriptPath:
|
|
450360
|
-
statePath:
|
|
450709
|
+
transcriptPath: join89(rootDir, "transcript.jsonl"),
|
|
450710
|
+
statePath: join89(rootDir, "state.json")
|
|
450361
450711
|
};
|
|
450362
450712
|
}
|
|
450363
450713
|
async function appendTranscriptDeltaJsonl(agentId, conversationId, lines) {
|
|
@@ -450447,7 +450797,7 @@ async function getTranscriptLastUpdatedAt(paths) {
|
|
|
450447
450797
|
}
|
|
450448
450798
|
}
|
|
450449
450799
|
async function ensureAgentPayloadRoot(agentId) {
|
|
450450
|
-
const root2 =
|
|
450800
|
+
const root2 = join89(getAgentTranscriptRoot(agentId), "multi-reflection-payloads");
|
|
450451
450801
|
await mkdir14(root2, { recursive: true });
|
|
450452
450802
|
return root2;
|
|
450453
450803
|
}
|
|
@@ -455229,9 +455579,9 @@ __export(exports_custom, {
|
|
|
455229
455579
|
GLOBAL_COMMANDS_DIR: () => GLOBAL_COMMANDS_DIR,
|
|
455230
455580
|
COMMANDS_DIR: () => COMMANDS_DIR
|
|
455231
455581
|
});
|
|
455232
|
-
import { existsSync as
|
|
455582
|
+
import { existsSync as existsSync61 } from "node:fs";
|
|
455233
455583
|
import { readdir as readdir11, readFile as readFile24 } from "node:fs/promises";
|
|
455234
|
-
import { basename as basename27, dirname as dirname33, join as
|
|
455584
|
+
import { basename as basename27, dirname as dirname33, join as join90 } from "node:path";
|
|
455235
455585
|
async function getCustomCommands() {
|
|
455236
455586
|
if (cachedCommands !== null) {
|
|
455237
455587
|
return cachedCommands;
|
|
@@ -455242,7 +455592,7 @@ async function getCustomCommands() {
|
|
|
455242
455592
|
function refreshCustomCommands() {
|
|
455243
455593
|
cachedCommands = null;
|
|
455244
455594
|
}
|
|
455245
|
-
async function discoverCustomCommands(projectPath =
|
|
455595
|
+
async function discoverCustomCommands(projectPath = join90(process.cwd(), COMMANDS_DIR)) {
|
|
455246
455596
|
const commandsById = new Map;
|
|
455247
455597
|
const userCommands = await discoverFromDirectory(GLOBAL_COMMANDS_DIR, "user");
|
|
455248
455598
|
for (const cmd of userCommands) {
|
|
@@ -455263,7 +455613,7 @@ async function discoverCustomCommands(projectPath = join89(process.cwd(), COMMAN
|
|
|
455263
455613
|
return result3;
|
|
455264
455614
|
}
|
|
455265
455615
|
async function discoverFromDirectory(dirPath, source) {
|
|
455266
|
-
if (!
|
|
455616
|
+
if (!existsSync61(dirPath)) {
|
|
455267
455617
|
return [];
|
|
455268
455618
|
}
|
|
455269
455619
|
const commands = [];
|
|
@@ -455274,7 +455624,7 @@ async function findCommandFiles(currentPath, rootPath, commands, source) {
|
|
|
455274
455624
|
try {
|
|
455275
455625
|
const entries2 = await readdir11(currentPath, { withFileTypes: true });
|
|
455276
455626
|
for (const entry of entries2) {
|
|
455277
|
-
const fullPath =
|
|
455627
|
+
const fullPath = join90(currentPath, entry.name);
|
|
455278
455628
|
if (entry.isDirectory()) {
|
|
455279
455629
|
await findCommandFiles(fullPath, rootPath, commands, source);
|
|
455280
455630
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
@@ -455359,7 +455709,7 @@ async function findCustomCommand(commandName) {
|
|
|
455359
455709
|
}
|
|
455360
455710
|
var COMMANDS_DIR = ".commands", GLOBAL_COMMANDS_DIR, cachedCommands = null;
|
|
455361
455711
|
var init_custom = __esm(() => {
|
|
455362
|
-
GLOBAL_COMMANDS_DIR =
|
|
455712
|
+
GLOBAL_COMMANDS_DIR = join90(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
|
|
455363
455713
|
});
|
|
455364
455714
|
|
|
455365
455715
|
// src/cli/helpers/doctor-command.ts
|
|
@@ -457001,7 +457351,7 @@ function handleMemfsSyncedMemoryProtocolCommand(parsed, context3) {
|
|
|
457001
457351
|
}
|
|
457002
457352
|
var init_memory_command_sync = __esm(async () => {
|
|
457003
457353
|
init_memfs_sync();
|
|
457004
|
-
await
|
|
457354
|
+
await init_memory6();
|
|
457005
457355
|
});
|
|
457006
457356
|
|
|
457007
457357
|
// src/websocket/listener/commands/queue.ts
|
|
@@ -460613,7 +460963,7 @@ var init_client9 = __esm(async () => {
|
|
|
460613
460963
|
init_approval(),
|
|
460614
460964
|
init_agents_conversations(),
|
|
460615
460965
|
init_cron3(),
|
|
460616
|
-
|
|
460966
|
+
init_memory6(),
|
|
460617
460967
|
init_model_toolset(),
|
|
460618
460968
|
init_runtime_start(),
|
|
460619
460969
|
init_settings3(),
|
|
@@ -463888,17 +464238,17 @@ var init_listen = __esm(async () => {
|
|
|
463888
464238
|
import { randomUUID as randomUUID51 } from "node:crypto";
|
|
463889
464239
|
import {
|
|
463890
464240
|
copyFileSync as copyFileSync3,
|
|
463891
|
-
existsSync as
|
|
464241
|
+
existsSync as existsSync62,
|
|
463892
464242
|
mkdirSync as mkdirSync44,
|
|
463893
|
-
readdirSync as
|
|
463894
|
-
readFileSync as
|
|
464243
|
+
readdirSync as readdirSync25,
|
|
464244
|
+
readFileSync as readFileSync46,
|
|
463895
464245
|
writeFileSync as writeFileSync37
|
|
463896
464246
|
} from "node:fs";
|
|
463897
|
-
import { join as
|
|
464247
|
+
import { join as join91 } from "node:path";
|
|
463898
464248
|
function readJsonl(path45) {
|
|
463899
|
-
if (!
|
|
464249
|
+
if (!existsSync62(path45))
|
|
463900
464250
|
return [];
|
|
463901
|
-
return
|
|
464251
|
+
return readFileSync46(path45, "utf8").split(`
|
|
463902
464252
|
`).filter((line) => line.trim().length > 0).map((line) => JSON.parse(line));
|
|
463903
464253
|
}
|
|
463904
464254
|
function isLegacyUiMessage(value) {
|
|
@@ -464177,23 +464527,23 @@ function convertMessages4(messages, mode, nextId2) {
|
|
|
464177
464527
|
}
|
|
464178
464528
|
function migrateLocalBackendTranscripts(input) {
|
|
464179
464529
|
const storageDir = input.storageDir;
|
|
464180
|
-
const conversationsDir =
|
|
464530
|
+
const conversationsDir = join91(storageDir, "conversations");
|
|
464181
464531
|
const result3 = {
|
|
464182
464532
|
storageDir,
|
|
464183
464533
|
converted: [],
|
|
464184
464534
|
skipped: [],
|
|
464185
464535
|
dryRun: input.dryRun === true
|
|
464186
464536
|
};
|
|
464187
|
-
if (!
|
|
464537
|
+
if (!existsSync62(conversationsDir))
|
|
464188
464538
|
return result3;
|
|
464189
|
-
for (const name of
|
|
464190
|
-
const conversationDir =
|
|
464191
|
-
const messagesPath =
|
|
464192
|
-
const manifestPath =
|
|
464193
|
-
const hasManifest =
|
|
464539
|
+
for (const name of readdirSync25(conversationsDir)) {
|
|
464540
|
+
const conversationDir = join91(conversationsDir, name);
|
|
464541
|
+
const messagesPath = join91(conversationDir, "messages.jsonl");
|
|
464542
|
+
const manifestPath = join91(conversationDir, "manifest.json");
|
|
464543
|
+
const hasManifest = existsSync62(manifestPath);
|
|
464194
464544
|
const existingManifest = hasManifest ? (() => {
|
|
464195
464545
|
try {
|
|
464196
|
-
return JSON.parse(
|
|
464546
|
+
return JSON.parse(readFileSync46(manifestPath, "utf8"));
|
|
464197
464547
|
} catch {
|
|
464198
464548
|
return;
|
|
464199
464549
|
}
|
|
@@ -464232,11 +464582,11 @@ function migrateLocalBackendTranscripts(input) {
|
|
|
464232
464582
|
const backupPath = `${messagesPath}.pre-pi-backup-${timestampSuffix()}`;
|
|
464233
464583
|
if (!input.dryRun) {
|
|
464234
464584
|
copyFileSync3(messagesPath, backupPath);
|
|
464235
|
-
const conversationPath =
|
|
464585
|
+
const conversationPath = join91(conversationDir, "conversation.json");
|
|
464236
464586
|
let conversation;
|
|
464237
|
-
if (
|
|
464587
|
+
if (existsSync62(conversationPath)) {
|
|
464238
464588
|
try {
|
|
464239
|
-
conversation = JSON.parse(
|
|
464589
|
+
conversation = JSON.parse(readFileSync46(conversationPath, "utf8"));
|
|
464240
464590
|
} catch {
|
|
464241
464591
|
conversation = undefined;
|
|
464242
464592
|
}
|
|
@@ -464428,9 +464778,9 @@ var init_memory_tokens = __esm(() => {
|
|
|
464428
464778
|
});
|
|
464429
464779
|
|
|
464430
464780
|
// src/cli/subcommands/memory.ts
|
|
464431
|
-
import { cpSync, existsSync as
|
|
464781
|
+
import { cpSync, existsSync as existsSync63, mkdirSync as mkdirSync45, rmSync as rmSync21, statSync as statSync22 } from "node:fs";
|
|
464432
464782
|
import { readdir as readdir12 } from "node:fs/promises";
|
|
464433
|
-
import { dirname as dirname34, join as
|
|
464783
|
+
import { dirname as dirname34, join as join92 } from "node:path";
|
|
464434
464784
|
import { parseArgs as parseArgs11 } from "node:util";
|
|
464435
464785
|
function printUsage8() {
|
|
464436
464786
|
console.log(`
|
|
@@ -464490,7 +464840,7 @@ function formatBackupTimestamp(date5 = new Date) {
|
|
|
464490
464840
|
}
|
|
464491
464841
|
async function listBackups(agentId) {
|
|
464492
464842
|
const agentRoot = getAgentRoot(agentId);
|
|
464493
|
-
if (!
|
|
464843
|
+
if (!existsSync63(agentRoot)) {
|
|
464494
464844
|
return [];
|
|
464495
464845
|
}
|
|
464496
464846
|
const entries2 = await readdir12(agentRoot, { withFileTypes: true });
|
|
@@ -464500,10 +464850,10 @@ async function listBackups(agentId) {
|
|
|
464500
464850
|
continue;
|
|
464501
464851
|
if (!entry.name.startsWith("memory-backup-"))
|
|
464502
464852
|
continue;
|
|
464503
|
-
const path45 =
|
|
464853
|
+
const path45 = join92(agentRoot, entry.name);
|
|
464504
464854
|
let createdAt = null;
|
|
464505
464855
|
try {
|
|
464506
|
-
const stat15 =
|
|
464856
|
+
const stat15 = statSync22(path45);
|
|
464507
464857
|
createdAt = stat15.mtime.toISOString();
|
|
464508
464858
|
} catch {
|
|
464509
464859
|
createdAt = null;
|
|
@@ -464517,7 +464867,7 @@ function resolveBackupPath(agentId, from) {
|
|
|
464517
464867
|
if (from.startsWith("/") || /^[A-Za-z]:[/\\]/.test(from)) {
|
|
464518
464868
|
return from;
|
|
464519
464869
|
}
|
|
464520
|
-
return
|
|
464870
|
+
return join92(getAgentRoot(agentId), from);
|
|
464521
464871
|
}
|
|
464522
464872
|
async function runMemorySubcommand(argv, deps = {}) {
|
|
464523
464873
|
let parsed;
|
|
@@ -464595,14 +464945,14 @@ async function runMemorySubcommand(argv, deps = {}) {
|
|
|
464595
464945
|
}
|
|
464596
464946
|
if (action3 === "backup") {
|
|
464597
464947
|
const root2 = getMemoryRoot(agentId);
|
|
464598
|
-
if (!
|
|
464948
|
+
if (!existsSync63(root2)) {
|
|
464599
464949
|
console.error(`Memory directory not found for agent ${agentId}.`);
|
|
464600
464950
|
return 1;
|
|
464601
464951
|
}
|
|
464602
464952
|
const agentRoot = getAgentRoot(agentId);
|
|
464603
464953
|
const backupName = `memory-backup-${formatBackupTimestamp()}`;
|
|
464604
|
-
const backupPath =
|
|
464605
|
-
if (
|
|
464954
|
+
const backupPath = join92(agentRoot, backupName);
|
|
464955
|
+
if (existsSync63(backupPath)) {
|
|
464606
464956
|
console.error(`Backup already exists at ${backupPath}`);
|
|
464607
464957
|
return 1;
|
|
464608
464958
|
}
|
|
@@ -464626,11 +464976,11 @@ async function runMemorySubcommand(argv, deps = {}) {
|
|
|
464626
464976
|
return 1;
|
|
464627
464977
|
}
|
|
464628
464978
|
const backupPath = resolveBackupPath(agentId, from);
|
|
464629
|
-
if (!
|
|
464979
|
+
if (!existsSync63(backupPath)) {
|
|
464630
464980
|
console.error(`Backup not found: ${backupPath}`);
|
|
464631
464981
|
return 1;
|
|
464632
464982
|
}
|
|
464633
|
-
const stat15 =
|
|
464983
|
+
const stat15 = statSync22(backupPath);
|
|
464634
464984
|
if (!stat15.isDirectory()) {
|
|
464635
464985
|
console.error(`Backup path is not a directory: ${backupPath}`);
|
|
464636
464986
|
return 1;
|
|
@@ -464648,12 +464998,12 @@ async function runMemorySubcommand(argv, deps = {}) {
|
|
|
464648
464998
|
return 1;
|
|
464649
464999
|
}
|
|
464650
465000
|
const root2 = getMemoryRoot(agentId);
|
|
464651
|
-
if (!
|
|
465001
|
+
if (!existsSync63(root2)) {
|
|
464652
465002
|
console.error(`Memory directory not found for agent ${agentId}.`);
|
|
464653
465003
|
return 1;
|
|
464654
465004
|
}
|
|
464655
|
-
if (
|
|
464656
|
-
const stat15 =
|
|
465005
|
+
if (existsSync63(out)) {
|
|
465006
|
+
const stat15 = statSync22(out);
|
|
464657
465007
|
if (stat15.isDirectory()) {
|
|
464658
465008
|
const contents = await readdir12(out);
|
|
464659
465009
|
if (contents.length > 0) {
|
|
@@ -464680,7 +465030,7 @@ async function runMemorySubcommand(argv, deps = {}) {
|
|
|
464680
465030
|
return 1;
|
|
464681
465031
|
}
|
|
464682
465032
|
var MEMORY_OPTIONS;
|
|
464683
|
-
var
|
|
465033
|
+
var init_memory7 = __esm(() => {
|
|
464684
465034
|
init_memory_filesystem2();
|
|
464685
465035
|
init_memory_git();
|
|
464686
465036
|
init_paths();
|
|
@@ -464701,22 +465051,22 @@ var init_memory6 = __esm(() => {
|
|
|
464701
465051
|
});
|
|
464702
465052
|
|
|
464703
465053
|
// src/backend/local/transcript-search.ts
|
|
464704
|
-
import { existsSync as
|
|
464705
|
-
import { join as
|
|
465054
|
+
import { existsSync as existsSync64, readdirSync as readdirSync26, readFileSync as readFileSync47, statSync as statSync23 } from "node:fs";
|
|
465055
|
+
import { join as join93 } from "node:path";
|
|
464706
465056
|
function readJsonFile3(path45) {
|
|
464707
|
-
if (!
|
|
465057
|
+
if (!existsSync64(path45))
|
|
464708
465058
|
return;
|
|
464709
465059
|
try {
|
|
464710
|
-
return JSON.parse(
|
|
465060
|
+
return JSON.parse(readFileSync47(path45, "utf8"));
|
|
464711
465061
|
} catch {
|
|
464712
465062
|
return;
|
|
464713
465063
|
}
|
|
464714
465064
|
}
|
|
464715
465065
|
function readJsonlFile2(path45) {
|
|
464716
|
-
if (!
|
|
465066
|
+
if (!existsSync64(path45))
|
|
464717
465067
|
return [];
|
|
464718
465068
|
try {
|
|
464719
|
-
return
|
|
465069
|
+
return readFileSync47(path45, "utf8").split(`
|
|
464720
465070
|
`).filter((line) => line.trim().length > 0).map((line) => JSON.parse(line));
|
|
464721
465071
|
} catch {
|
|
464722
465072
|
return [];
|
|
@@ -464957,11 +465307,11 @@ function collectConversationMessages(input) {
|
|
|
464957
465307
|
return [];
|
|
464958
465308
|
if (input.conversationId && conversation.id !== input.conversationId)
|
|
464959
465309
|
return [];
|
|
464960
|
-
const messagesPath =
|
|
465310
|
+
const messagesPath = join93(conversationDir, "messages.jsonl");
|
|
464961
465311
|
const rows = readJsonlFile2(messagesPath);
|
|
464962
465312
|
if (rows.length === 0)
|
|
464963
465313
|
return [];
|
|
464964
|
-
const manifest2 = readJsonFile3(
|
|
465314
|
+
const manifest2 = readJsonFile3(join93(conversationDir, "manifest.json"));
|
|
464965
465315
|
const format5 = transcriptFormat(manifest2, rows);
|
|
464966
465316
|
if (!format5)
|
|
464967
465317
|
return [];
|
|
@@ -464990,11 +465340,11 @@ function collectConversationMessages(input) {
|
|
|
464990
465340
|
}).filter((record6) => record6.tokens.length > 0);
|
|
464991
465341
|
}
|
|
464992
465342
|
function conversationDirectories(storageDir) {
|
|
464993
|
-
const conversationsDir =
|
|
464994
|
-
if (!
|
|
465343
|
+
const conversationsDir = join93(storageDir, "conversations");
|
|
465344
|
+
if (!existsSync64(conversationsDir))
|
|
464995
465345
|
return [];
|
|
464996
465346
|
try {
|
|
464997
|
-
return
|
|
465347
|
+
return readdirSync26(conversationsDir).map((entry) => join93(conversationsDir, entry)).filter((entryPath) => statSync23(entryPath).isDirectory());
|
|
464998
465348
|
} catch {
|
|
464999
465349
|
return [];
|
|
465000
465350
|
}
|
|
@@ -465021,7 +465371,7 @@ function searchLocalTranscriptMessages(storageDir, body3, options = {}) {
|
|
|
465021
465371
|
const endDate = typeof body3.end_date === "string" ? body3.end_date : undefined;
|
|
465022
465372
|
const includeHidden = body3.include_hidden === true;
|
|
465023
465373
|
const records2 = conversationDirectories(storageDir).flatMap((conversationDir) => {
|
|
465024
|
-
const conversation = conversationSearchRecord(readJsonFile3(
|
|
465374
|
+
const conversation = conversationSearchRecord(readJsonFile3(join93(conversationDir, "conversation.json")));
|
|
465025
465375
|
if (!conversation)
|
|
465026
465376
|
return [];
|
|
465027
465377
|
if (conversation.hidden && !includeHidden)
|
|
@@ -465905,12 +466255,12 @@ var init_model2 = __esm(() => {
|
|
|
465905
466255
|
import { spawn as spawn13 } from "node:child_process";
|
|
465906
466256
|
import {
|
|
465907
466257
|
copyFileSync as copyFileSync4,
|
|
465908
|
-
existsSync as
|
|
466258
|
+
existsSync as existsSync65,
|
|
465909
466259
|
lstatSync as lstatSync3,
|
|
465910
466260
|
mkdirSync as mkdirSync46,
|
|
465911
466261
|
mkdtempSync as mkdtempSync5,
|
|
465912
|
-
readdirSync as
|
|
465913
|
-
readFileSync as
|
|
466262
|
+
readdirSync as readdirSync27,
|
|
466263
|
+
readFileSync as readFileSync48,
|
|
465914
466264
|
renameSync as renameSync12,
|
|
465915
466265
|
rmSync as rmSync22,
|
|
465916
466266
|
writeFileSync as writeFileSync38
|
|
@@ -465929,7 +466279,7 @@ function isPathInsideOrEqual2(childPath, parentPath) {
|
|
|
465929
466279
|
function readPackageJson(packageJsonPath) {
|
|
465930
466280
|
let parsed;
|
|
465931
466281
|
try {
|
|
465932
|
-
parsed = JSON.parse(
|
|
466282
|
+
parsed = JSON.parse(readFileSync48(packageJsonPath, "utf8"));
|
|
465933
466283
|
} catch (error5) {
|
|
465934
466284
|
throw new Error(`Could not read package.json: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
465935
466285
|
}
|
|
@@ -466050,7 +466400,7 @@ function validatePackageSource(packageDirectory) {
|
|
|
466050
466400
|
}
|
|
466051
466401
|
function copyPackageDirectory(sourceRoot, targetRoot) {
|
|
466052
466402
|
mkdirSync46(targetRoot, { recursive: true });
|
|
466053
|
-
for (const entry of
|
|
466403
|
+
for (const entry of readdirSync27(sourceRoot, { withFileTypes: true })) {
|
|
466054
466404
|
if (SKIPPED_PACKAGE_COPY_NAMES.has(entry.name))
|
|
466055
466405
|
continue;
|
|
466056
466406
|
const sourcePath = path45.join(sourceRoot, entry.name);
|
|
@@ -466082,7 +466432,7 @@ function shouldSkipDependencyPath(relativeParts, installedPackageName) {
|
|
|
466082
466432
|
function copyDependencyDirectoryFiltered(params) {
|
|
466083
466433
|
let copied = false;
|
|
466084
466434
|
const relativeParts = params.relativeParts ?? [];
|
|
466085
|
-
for (const entry of
|
|
466435
|
+
for (const entry of readdirSync27(params.sourceRoot, { withFileTypes: true })) {
|
|
466086
466436
|
const nextRelativeParts = [...relativeParts, entry.name];
|
|
466087
466437
|
if (shouldSkipDependencyPath(nextRelativeParts, params.installedPackageName)) {
|
|
466088
466438
|
continue;
|
|
@@ -466114,7 +466464,7 @@ function copyDependencyDirectoryFiltered(params) {
|
|
|
466114
466464
|
return copied;
|
|
466115
466465
|
}
|
|
466116
466466
|
function copyDependencyNodeModules(params) {
|
|
466117
|
-
if (!
|
|
466467
|
+
if (!existsSync65(params.sourceNodeModulesDirectory))
|
|
466118
466468
|
return;
|
|
466119
466469
|
copyDependencyDirectoryFiltered({
|
|
466120
466470
|
installedPackageName: params.installedPackageName,
|
|
@@ -466124,7 +466474,7 @@ function copyDependencyNodeModules(params) {
|
|
|
466124
466474
|
}
|
|
466125
466475
|
function copyPackageInternalNodeModules(params) {
|
|
466126
466476
|
const sourceNodeModulesDirectory = path45.join(params.packageDirectory, "node_modules");
|
|
466127
|
-
if (!
|
|
466477
|
+
if (!existsSync65(sourceNodeModulesDirectory))
|
|
466128
466478
|
return;
|
|
466129
466479
|
copyDependencyDirectoryFiltered({
|
|
466130
466480
|
sourceRoot: sourceNodeModulesDirectory,
|
|
@@ -466146,12 +466496,12 @@ function removeIfExists(targetPath) {
|
|
|
466146
466496
|
}
|
|
466147
466497
|
function restoreDestination(params) {
|
|
466148
466498
|
rmSync22(params.destinationRoot, { force: true, recursive: true });
|
|
466149
|
-
if (params.backupRoot &&
|
|
466499
|
+
if (params.backupRoot && existsSync65(params.backupRoot)) {
|
|
466150
466500
|
renameSync12(params.backupRoot, params.destinationRoot);
|
|
466151
466501
|
}
|
|
466152
466502
|
}
|
|
466153
466503
|
function restoreDestinationIfNeeded(params) {
|
|
466154
|
-
if (!params.backupRoot || !
|
|
466504
|
+
if (!params.backupRoot || !existsSync65(params.backupRoot)) {
|
|
466155
466505
|
rmSync22(params.destinationRoot, { force: true, recursive: true });
|
|
466156
466506
|
return;
|
|
466157
466507
|
}
|
|
@@ -466192,7 +466542,7 @@ function installPreparedManagedModPackage(params) {
|
|
|
466192
466542
|
targetPackageRoot: stagingRoot
|
|
466193
466543
|
});
|
|
466194
466544
|
}
|
|
466195
|
-
if (
|
|
466545
|
+
if (existsSync65(destinationRoot)) {
|
|
466196
466546
|
backupRoot = makeSiblingTempDirectory(destinationRoot, "backup");
|
|
466197
466547
|
rmSync22(backupRoot, { force: true, recursive: true });
|
|
466198
466548
|
renameSync12(destinationRoot, backupRoot);
|
|
@@ -466477,7 +466827,7 @@ function hasRuntimeDependencies(packageJson) {
|
|
|
466477
466827
|
}
|
|
466478
466828
|
function readPackageJsonIfExists(packageDirectory) {
|
|
466479
466829
|
const packageJsonPath = path45.join(packageDirectory, "package.json");
|
|
466480
|
-
if (!
|
|
466830
|
+
if (!existsSync65(packageJsonPath))
|
|
466481
466831
|
return null;
|
|
466482
466832
|
return readPackageJson(packageJsonPath);
|
|
466483
466833
|
}
|
|
@@ -466491,13 +466841,13 @@ function isRegularModFile(filePath) {
|
|
|
466491
466841
|
}
|
|
466492
466842
|
function inferCompatibilityModEntries(packageDirectory) {
|
|
466493
466843
|
const modsDirectory = path45.join(packageDirectory, "mods");
|
|
466494
|
-
if (
|
|
466844
|
+
if (existsSync65(modsDirectory)) {
|
|
466495
466845
|
const stats = lstatSync3(modsDirectory);
|
|
466496
466846
|
if (stats.isSymbolicLink()) {
|
|
466497
466847
|
throw new Error(`Package mods directory must not be a symlink: mods`);
|
|
466498
466848
|
}
|
|
466499
466849
|
if (stats.isDirectory()) {
|
|
466500
|
-
const entries2 =
|
|
466850
|
+
const entries2 = readdirSync27(modsDirectory, { withFileTypes: true }).filter((entry) => entry.isFile() && isModFileExtension(path45.extname(entry.name))).map((entry) => `mods/${entry.name}`).sort();
|
|
466501
466851
|
if (entries2.length > 0)
|
|
466502
466852
|
return entries2;
|
|
466503
466853
|
}
|
|
@@ -466766,7 +467116,7 @@ var init_package_installer = __esm(() => {
|
|
|
466766
467116
|
// src/mods/package-scaffolder.ts
|
|
466767
467117
|
import {
|
|
466768
467118
|
copyFileSync as copyFileSync5,
|
|
466769
|
-
existsSync as
|
|
467119
|
+
existsSync as existsSync66,
|
|
466770
467120
|
lstatSync as lstatSync4,
|
|
466771
467121
|
mkdirSync as mkdirSync47,
|
|
466772
467122
|
rmSync as rmSync23,
|
|
@@ -466859,7 +467209,7 @@ function scaffoldLocalModPackage(options) {
|
|
|
466859
467209
|
const sourceFile = readSourceFile(options.sourceFile);
|
|
466860
467210
|
const packageName = assertValidPackageName(options.packageName);
|
|
466861
467211
|
const outputDirectory = path46.resolve(options.outputDirectory ?? defaultOutputDirectory(sourceFile, packageName));
|
|
466862
|
-
if (
|
|
467212
|
+
if (existsSync66(outputDirectory)) {
|
|
466863
467213
|
throw new Error(`Output directory already exists: ${outputDirectory}`);
|
|
466864
467214
|
}
|
|
466865
467215
|
const modFileName = path46.basename(sourceFile);
|
|
@@ -466901,7 +467251,7 @@ var init_package_scaffolder = __esm(() => {
|
|
|
466901
467251
|
});
|
|
466902
467252
|
|
|
466903
467253
|
// src/cli/subcommands/mods.ts
|
|
466904
|
-
import { dirname as dirname35, join as
|
|
467254
|
+
import { dirname as dirname35, join as join94 } from "node:path";
|
|
466905
467255
|
import { parseArgs as parseArgs14 } from "node:util";
|
|
466906
467256
|
function printUsage11() {
|
|
466907
467257
|
console.log(`
|
|
@@ -466940,7 +467290,7 @@ function getExplicitAgentId(values4) {
|
|
|
466940
467290
|
return typeof explicitAgent === "string" && explicitAgent.trim() ? explicitAgent.trim() : null;
|
|
466941
467291
|
}
|
|
466942
467292
|
function getAgentModsDirectory(agentId) {
|
|
466943
|
-
return
|
|
467293
|
+
return join94(getScopedMemoryFilesystemRoot(agentId), "mods");
|
|
466944
467294
|
}
|
|
466945
467295
|
function directFilesForSource(source) {
|
|
466946
467296
|
return source.files.filter((file) => dirname35(file) === source.root);
|
|
@@ -468480,8 +468830,8 @@ var init_setup7 = __esm(async () => {
|
|
|
468480
468830
|
});
|
|
468481
468831
|
|
|
468482
468832
|
// src/cli/subcommands/shared-memory.ts
|
|
468483
|
-
import { existsSync as
|
|
468484
|
-
import { join as
|
|
468833
|
+
import { existsSync as existsSync67 } from "node:fs";
|
|
468834
|
+
import { join as join95 } from "node:path";
|
|
468485
468835
|
import { parseArgs as parseArgs19 } from "node:util";
|
|
468486
468836
|
function printUsage16() {
|
|
468487
468837
|
console.log(`
|
|
@@ -468673,7 +469023,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
|
|
|
468673
469023
|
invalidateClientSkills(agentId);
|
|
468674
469024
|
const recompileError = await recompileAndReportFailure(recompileAgent, agentId);
|
|
468675
469025
|
const mountDir = getRepositoryMountDir(agentId, repository.name);
|
|
468676
|
-
const mounted =
|
|
469026
|
+
const mounted = existsSync67(join95(mountDir, ".git"));
|
|
468677
469027
|
console.log(JSON.stringify({
|
|
468678
469028
|
attached: true,
|
|
468679
469029
|
repository: { id: repository.id, name: repository.name },
|
|
@@ -470202,16 +470552,16 @@ var init_AgentSelector = __esm(async () => {
|
|
|
470202
470552
|
// src/cli/subcommands/skills.ts
|
|
470203
470553
|
import {
|
|
470204
470554
|
cpSync as cpSync2,
|
|
470205
|
-
existsSync as
|
|
470555
|
+
existsSync as existsSync68,
|
|
470206
470556
|
mkdtempSync as mkdtempSync6,
|
|
470207
|
-
readFileSync as
|
|
470557
|
+
readFileSync as readFileSync49,
|
|
470208
470558
|
rmSync as rmSync24,
|
|
470209
|
-
statSync as
|
|
470559
|
+
statSync as statSync24,
|
|
470210
470560
|
writeFileSync as writeFileSync40
|
|
470211
470561
|
} from "node:fs";
|
|
470212
470562
|
import { mkdir as mkdir15, readdir as readdir13 } from "node:fs/promises";
|
|
470213
470563
|
import { tmpdir as tmpdir14 } from "node:os";
|
|
470214
|
-
import { basename as basename29, dirname as dirname36, join as
|
|
470564
|
+
import { basename as basename29, dirname as dirname36, join as join96, normalize as normalize4, resolve as resolve41, sep as sep8 } from "node:path";
|
|
470215
470565
|
import { parseArgs as parseArgs20, TextDecoder as TextDecoder2, TextEncoder as TextEncoder2 } from "node:util";
|
|
470216
470566
|
function printUsage17() {
|
|
470217
470567
|
console.log(`
|
|
@@ -470503,14 +470853,14 @@ async function resolveBranchAndSubdir(location) {
|
|
|
470503
470853
|
}
|
|
470504
470854
|
async function cloneSkillSource(location) {
|
|
470505
470855
|
const resolvedLocation = await resolveBranchAndSubdir(location);
|
|
470506
|
-
const tmpDir = mkdtempSync6(
|
|
470856
|
+
const tmpDir = mkdtempSync6(join96(tmpdir14(), "letta-skill-install-"));
|
|
470507
470857
|
const args = ["clone", "--depth", "1"];
|
|
470508
470858
|
if (resolvedLocation.branch) {
|
|
470509
470859
|
args.push("--branch", resolvedLocation.branch);
|
|
470510
470860
|
}
|
|
470511
470861
|
args.push(resolvedLocation.repoUrl, tmpDir);
|
|
470512
470862
|
await execFile22("git", args, { timeout: 120000 });
|
|
470513
|
-
const sourceDir = resolvedLocation.subdir ?
|
|
470863
|
+
const sourceDir = resolvedLocation.subdir ? join96(tmpDir, resolvedLocation.subdir) : tmpDir;
|
|
470514
470864
|
return { tmpDir, sourceDir };
|
|
470515
470865
|
}
|
|
470516
470866
|
function assertDirectSkillFileSize(receivedBytes, maxBytes) {
|
|
@@ -470565,11 +470915,11 @@ async function downloadDirectSkillFileSource(location, options = {}) {
|
|
|
470565
470915
|
throw new Error(`Direct skill file download failed for ${location.url}: ${response.status}`);
|
|
470566
470916
|
}
|
|
470567
470917
|
const skillText = await readResponseTextWithLimit(response, MAX_DIRECT_SKILL_FILE_BYTES);
|
|
470568
|
-
const tmpDir = mkdtempSync6(
|
|
470918
|
+
const tmpDir = mkdtempSync6(join96(tmpdir14(), "letta-direct-skill-"));
|
|
470569
470919
|
try {
|
|
470570
|
-
const sourceDir =
|
|
470920
|
+
const sourceDir = join96(tmpDir, "skill");
|
|
470571
470921
|
await mkdir15(sourceDir, { recursive: true });
|
|
470572
|
-
writeFileSync40(
|
|
470922
|
+
writeFileSync40(join96(sourceDir, "SKILL.md"), skillText, "utf8");
|
|
470573
470923
|
return { tmpDir, sourceDir };
|
|
470574
470924
|
} catch (error5) {
|
|
470575
470925
|
rmSync24(tmpDir, { recursive: true, force: true });
|
|
@@ -470610,9 +470960,9 @@ function assertSafeZipMember(name) {
|
|
|
470610
470960
|
}
|
|
470611
470961
|
async function downloadClawHubSkillSource(location) {
|
|
470612
470962
|
const version3 = await resolveClawHubVersion(location);
|
|
470613
|
-
const tmpDir = mkdtempSync6(
|
|
470614
|
-
const zipPath =
|
|
470615
|
-
const sourceDir =
|
|
470963
|
+
const tmpDir = mkdtempSync6(join96(tmpdir14(), "letta-clawhub-skill-"));
|
|
470964
|
+
const zipPath = join96(tmpDir, "skill.zip");
|
|
470965
|
+
const sourceDir = join96(tmpDir, "skill");
|
|
470616
470966
|
await mkdir15(sourceDir, { recursive: true });
|
|
470617
470967
|
const url2 = new URL(`${CLAWHUB_API_BASE_URL}/download`);
|
|
470618
470968
|
url2.searchParams.set("slug", location.slug);
|
|
@@ -470639,7 +470989,7 @@ async function downloadClawHubSkillSource(location) {
|
|
|
470639
470989
|
function assertInside(parent, child) {
|
|
470640
470990
|
const parentPath = resolve41(parent);
|
|
470641
470991
|
const childPath = resolve41(child);
|
|
470642
|
-
if (childPath !== parentPath && !childPath.startsWith(`${parentPath}${
|
|
470992
|
+
if (childPath !== parentPath && !childPath.startsWith(`${parentPath}${sep8}`)) {
|
|
470643
470993
|
throw new Error(`Resolved path is outside target directory: ${child}`);
|
|
470644
470994
|
}
|
|
470645
470995
|
}
|
|
@@ -470651,7 +471001,7 @@ function sanitizeSkillName(name) {
|
|
|
470651
471001
|
return trimmed;
|
|
470652
471002
|
}
|
|
470653
471003
|
function getSkillName(sourceDir) {
|
|
470654
|
-
const skillMd =
|
|
471004
|
+
const skillMd = readFileSync49(join96(sourceDir, "SKILL.md"), "utf8");
|
|
470655
471005
|
const { frontmatter } = parseFrontmatter(skillMd);
|
|
470656
471006
|
const frontmatterName = frontmatter.name;
|
|
470657
471007
|
const name = typeof frontmatterName === "string" && frontmatterName.trim() ? frontmatterName : basename29(sourceDir);
|
|
@@ -470660,18 +471010,18 @@ function getSkillName(sourceDir) {
|
|
|
470660
471010
|
async function installSkillDirectory(params) {
|
|
470661
471011
|
const sourceDir = resolve41(params.sourceDir);
|
|
470662
471012
|
const memoryDir = resolve41(params.memoryDir);
|
|
470663
|
-
const skillMdPath =
|
|
470664
|
-
if (!
|
|
471013
|
+
const skillMdPath = join96(sourceDir, "SKILL.md");
|
|
471014
|
+
if (!existsSync68(skillMdPath)) {
|
|
470665
471015
|
throw new Error("No SKILL.md found in the skill directory.");
|
|
470666
471016
|
}
|
|
470667
|
-
if (!
|
|
471017
|
+
if (!statSync24(sourceDir).isDirectory()) {
|
|
470668
471018
|
throw new Error(`Skill source is not a directory: ${sourceDir}`);
|
|
470669
471019
|
}
|
|
470670
471020
|
const name = getSkillName(sourceDir);
|
|
470671
|
-
const skillsDir =
|
|
470672
|
-
const targetPath =
|
|
471021
|
+
const skillsDir = join96(memoryDir, "skills");
|
|
471022
|
+
const targetPath = join96(skillsDir, name);
|
|
470673
471023
|
assertInside(skillsDir, targetPath);
|
|
470674
|
-
if (
|
|
471024
|
+
if (existsSync68(targetPath)) {
|
|
470675
471025
|
if (!params.force) {
|
|
470676
471026
|
throw new Error(`Skill "${name}" already exists at ${targetPath}. Re-run with --force to replace it.`);
|
|
470677
471027
|
}
|
|
@@ -470686,22 +471036,22 @@ async function installSkillDirectory(params) {
|
|
|
470686
471036
|
}
|
|
470687
471037
|
async function listSkillDirectories(params) {
|
|
470688
471038
|
const memoryDir = resolve41(params.memoryDir);
|
|
470689
|
-
const skillsDir =
|
|
470690
|
-
if (!
|
|
471039
|
+
const skillsDir = join96(memoryDir, "skills");
|
|
471040
|
+
if (!existsSync68(skillsDir))
|
|
470691
471041
|
return [];
|
|
470692
471042
|
const entries2 = await readdir13(skillsDir, { withFileTypes: true });
|
|
470693
471043
|
const skills = [];
|
|
470694
471044
|
for (const entry of entries2) {
|
|
470695
471045
|
if (!entry.isDirectory())
|
|
470696
471046
|
continue;
|
|
470697
|
-
const skillDir =
|
|
470698
|
-
const skillMdPath =
|
|
470699
|
-
if (!
|
|
471047
|
+
const skillDir = join96(skillsDir, entry.name);
|
|
471048
|
+
const skillMdPath = join96(skillDir, "SKILL.md");
|
|
471049
|
+
if (!existsSync68(skillMdPath))
|
|
470700
471050
|
continue;
|
|
470701
471051
|
let name = entry.name;
|
|
470702
471052
|
let description;
|
|
470703
471053
|
try {
|
|
470704
|
-
const skillMd =
|
|
471054
|
+
const skillMd = readFileSync49(skillMdPath, "utf8");
|
|
470705
471055
|
const { frontmatter } = parseFrontmatter(skillMd);
|
|
470706
471056
|
if (typeof frontmatter.name === "string" && frontmatter.name.trim()) {
|
|
470707
471057
|
name = frontmatter.name.trim();
|
|
@@ -470716,14 +471066,14 @@ async function listSkillDirectories(params) {
|
|
|
470716
471066
|
}
|
|
470717
471067
|
async function deleteSkillDirectory(params) {
|
|
470718
471068
|
const memoryDir = resolve41(params.memoryDir);
|
|
470719
|
-
const skillsDir =
|
|
471069
|
+
const skillsDir = join96(memoryDir, "skills");
|
|
470720
471070
|
const name = sanitizeSkillName(params.name);
|
|
470721
|
-
const targetPath =
|
|
471071
|
+
const targetPath = join96(skillsDir, name);
|
|
470722
471072
|
assertInside(skillsDir, targetPath);
|
|
470723
|
-
if (!
|
|
471073
|
+
if (!existsSync68(targetPath)) {
|
|
470724
471074
|
throw new Error(`Skill "${name}" is not installed at ${targetPath}.`);
|
|
470725
471075
|
}
|
|
470726
|
-
if (!
|
|
471076
|
+
if (!statSync24(targetPath).isDirectory()) {
|
|
470727
471077
|
throw new Error(`Skill path is not a directory: ${targetPath}`);
|
|
470728
471078
|
}
|
|
470729
471079
|
rmSync24(targetPath, { recursive: true, force: true });
|
|
@@ -470769,7 +471119,7 @@ async function installSkill(specifier, agentId, force) {
|
|
|
470769
471119
|
tmpDir = downloaded.tmpDir;
|
|
470770
471120
|
const sourceDir = resolve41(downloaded.sourceDir);
|
|
470771
471121
|
assertInside(tmpDir, sourceDir);
|
|
470772
|
-
if (!
|
|
471122
|
+
if (!existsSync68(sourceDir)) {
|
|
470773
471123
|
const missingPath = source.type === "git" ? source.location.subdir ?? "." : source.type === "direct-file" ? source.location.url : source.location.slug;
|
|
470774
471124
|
throw new Error(`Skill path not found: ${missingPath}`);
|
|
470775
471125
|
}
|
|
@@ -471304,7 +471654,7 @@ var init_teleport2 = __esm(() => {
|
|
|
471304
471654
|
|
|
471305
471655
|
// src/cli/subcommands/trajectories/readers.ts
|
|
471306
471656
|
import { readdir as readdir14, readFile as readFile27, stat as stat16 } from "node:fs/promises";
|
|
471307
|
-
import { join as
|
|
471657
|
+
import { join as join97 } from "node:path";
|
|
471308
471658
|
async function loadSessionTranscript(item) {
|
|
471309
471659
|
const stats = await stat16(item.path);
|
|
471310
471660
|
if (stats.isDirectory()) {
|
|
@@ -471316,13 +471666,13 @@ async function loadSessionTranscript(item) {
|
|
|
471316
471666
|
return readFile27(item.path, "utf-8");
|
|
471317
471667
|
}
|
|
471318
471668
|
async function assembleEventDirectory(sessionDir) {
|
|
471319
|
-
const eventsSubdir =
|
|
471669
|
+
const eventsSubdir = join97(sessionDir, "events");
|
|
471320
471670
|
const eventsDir = (await stat16(eventsSubdir).catch(() => null))?.isDirectory() ? eventsSubdir : sessionDir;
|
|
471321
471671
|
const names2 = (await readdir14(eventsDir, { withFileTypes: true })).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort((a2, b3) => Number.parseInt(a2, 10) - Number.parseInt(b3, 10) || a2.localeCompare(b3));
|
|
471322
471672
|
if (names2.length === 0) {
|
|
471323
471673
|
throw new Error(`No event files found in ${eventsDir}`);
|
|
471324
471674
|
}
|
|
471325
|
-
const events = await Promise.all(names2.map(async (name) => JSON.parse(await readFile27(
|
|
471675
|
+
const events = await Promise.all(names2.map(async (name) => JSON.parse(await readFile27(join97(eventsDir, name), "utf-8"))));
|
|
471326
471676
|
return JSON.stringify(events);
|
|
471327
471677
|
}
|
|
471328
471678
|
async function openReadOnlyDatabase(path47) {
|
|
@@ -471400,7 +471750,7 @@ import {
|
|
|
471400
471750
|
stat as stat17,
|
|
471401
471751
|
writeFile as writeFile19
|
|
471402
471752
|
} from "node:fs/promises";
|
|
471403
|
-
import { basename as basename30, join as
|
|
471753
|
+
import { basename as basename30, join as join98 } from "node:path";
|
|
471404
471754
|
function fileTimestamp(startedAt) {
|
|
471405
471755
|
if (!startedAt)
|
|
471406
471756
|
return "unknown-date";
|
|
@@ -471470,7 +471820,7 @@ async function prepareOutDir(outDir) {
|
|
|
471470
471820
|
throw new Error(`--out ${outDir} is not empty and has no ${MANIFEST_NAME}; refusing to overwrite a directory this tool did not create`);
|
|
471471
471821
|
}
|
|
471472
471822
|
for (const entry of entries2) {
|
|
471473
|
-
await rm12(
|
|
471823
|
+
await rm12(join98(outDir, entry), { recursive: true, force: true });
|
|
471474
471824
|
}
|
|
471475
471825
|
} catch (error5) {
|
|
471476
471826
|
if (error5.code !== "ENOENT")
|
|
@@ -471513,14 +471863,14 @@ async function runTrajectoryExport(options) {
|
|
|
471513
471863
|
}
|
|
471514
471864
|
const sessionId = sessionHash(source, id2);
|
|
471515
471865
|
const base2 = `${fileTimestamp(stats.startedAt)}_${sessionId}`;
|
|
471516
|
-
let file =
|
|
471866
|
+
let file = join98(source, `${base2}.json`);
|
|
471517
471867
|
for (let suffix = 2;usedFiles.has(file); suffix += 1) {
|
|
471518
|
-
file =
|
|
471868
|
+
file = join98(source, `${base2}-${suffix}.json`);
|
|
471519
471869
|
}
|
|
471520
471870
|
usedFiles.add(file);
|
|
471521
471871
|
const body3 = JSON.stringify(records2);
|
|
471522
|
-
await mkdir16(
|
|
471523
|
-
await writeFile19(
|
|
471872
|
+
await mkdir16(join98(options.outDir, source), { recursive: true });
|
|
471873
|
+
await writeFile19(join98(options.outDir, file), body3, "utf-8");
|
|
471524
471874
|
counts.exported += 1;
|
|
471525
471875
|
manifest2.sessions.push({
|
|
471526
471876
|
source,
|
|
@@ -471574,7 +471924,7 @@ async function runTrajectoryExport(options) {
|
|
|
471574
471924
|
await exportCheckpoint(checkpoint, `${basename30(checkpoint.path)}-${checkpoint.threadId}`);
|
|
471575
471925
|
}
|
|
471576
471926
|
manifest2.sessions.sort((a2, b3) => (a2.startedAt ?? "").localeCompare(b3.startedAt ?? ""));
|
|
471577
|
-
await writeFile19(
|
|
471927
|
+
await writeFile19(join98(options.outDir, MANIFEST_NAME), JSON.stringify(manifest2, null, 2), "utf-8");
|
|
471578
471928
|
return manifest2;
|
|
471579
471929
|
}
|
|
471580
471930
|
var MANIFEST_NAME = "manifest.json", FIRST_PROMPT_MAX_CHARS = 200, LIST_PAGE_LIMIT = 1000;
|
|
@@ -471586,13 +471936,13 @@ var init_export = __esm(() => {
|
|
|
471586
471936
|
|
|
471587
471937
|
// src/cli/subcommands/trajectories/review.ts
|
|
471588
471938
|
import { readFile as readFile29 } from "node:fs/promises";
|
|
471589
|
-
import { isAbsolute as isAbsolute26, join as
|
|
471939
|
+
import { isAbsolute as isAbsolute26, join as join99 } from "node:path";
|
|
471590
471940
|
async function readManifest(dir) {
|
|
471591
471941
|
let raw2;
|
|
471592
471942
|
try {
|
|
471593
|
-
raw2 = await readFile29(
|
|
471943
|
+
raw2 = await readFile29(join99(dir, "manifest.json"), "utf-8");
|
|
471594
471944
|
} catch {
|
|
471595
|
-
throw new Error(`No manifest at ${
|
|
471945
|
+
throw new Error(`No manifest at ${join99(dir, "manifest.json")}. Run: letta trajectories export --out ${dir}`);
|
|
471596
471946
|
}
|
|
471597
471947
|
return JSON.parse(raw2);
|
|
471598
471948
|
}
|
|
@@ -471601,7 +471951,7 @@ function filterSessions(sessions3, filter3) {
|
|
|
471601
471951
|
}
|
|
471602
471952
|
async function resolveSessionFile(dir, target2) {
|
|
471603
471953
|
if (target2.endsWith(".json")) {
|
|
471604
|
-
const direct = isAbsolute26(target2) ? target2 :
|
|
471954
|
+
const direct = isAbsolute26(target2) ? target2 : join99(dir, target2);
|
|
471605
471955
|
try {
|
|
471606
471956
|
await readFile29(direct, "utf-8");
|
|
471607
471957
|
return direct;
|
|
@@ -471612,7 +471962,7 @@ async function resolveSessionFile(dir, target2) {
|
|
|
471612
471962
|
if (!entry) {
|
|
471613
471963
|
throw new Error(`No session "${target2}" in ${dir} (pass a file path, a manifest-relative file, or a sessionId)`);
|
|
471614
471964
|
}
|
|
471615
|
-
return
|
|
471965
|
+
return join99(dir, entry.file);
|
|
471616
471966
|
}
|
|
471617
471967
|
function stamp(timestamp) {
|
|
471618
471968
|
return (timestamp ?? "").slice(0, 19);
|
|
@@ -471655,7 +472005,7 @@ async function searchSessions(dir, keyword, options = {}) {
|
|
|
471655
472005
|
for (const session2 of filterSessions(manifest2.sessions, options)) {
|
|
471656
472006
|
let records2;
|
|
471657
472007
|
try {
|
|
471658
|
-
records2 = JSON.parse(await readFile29(
|
|
472008
|
+
records2 = JSON.parse(await readFile29(join99(dir, session2.file), "utf-8"));
|
|
471659
472009
|
} catch {
|
|
471660
472010
|
continue;
|
|
471661
472011
|
}
|
|
@@ -475019,7 +475369,7 @@ var init_message_channel_gateway_tool = __esm(() => {
|
|
|
475019
475369
|
});
|
|
475020
475370
|
|
|
475021
475371
|
// src/channels/custom/scaffolding.ts
|
|
475022
|
-
import { existsSync as
|
|
475372
|
+
import { existsSync as existsSync69, mkdirSync as mkdirSync48, rmSync as rmSync25, writeFileSync as writeFileSync41 } from "node:fs";
|
|
475023
475373
|
function removeUserPlugin(channelId) {
|
|
475024
475374
|
if (FIRST_PARTY_SET.has(channelId)) {
|
|
475025
475375
|
return;
|
|
@@ -475028,7 +475378,7 @@ function removeUserPlugin(channelId) {
|
|
|
475028
475378
|
return;
|
|
475029
475379
|
}
|
|
475030
475380
|
const channelDir = getChannelDir(channelId);
|
|
475031
|
-
if (!
|
|
475381
|
+
if (!existsSync69(channelDir)) {
|
|
475032
475382
|
return;
|
|
475033
475383
|
}
|
|
475034
475384
|
try {
|
|
@@ -476770,7 +477120,7 @@ var init_router = __esm(async () => {
|
|
|
476770
477120
|
init_feedback3();
|
|
476771
477121
|
init_local_backend2();
|
|
476772
477122
|
init_mcp();
|
|
476773
|
-
|
|
477123
|
+
init_memory7();
|
|
476774
477124
|
init_messages10();
|
|
476775
477125
|
init_model2();
|
|
476776
477126
|
init_permissions2();
|
|
@@ -477908,7 +478258,7 @@ function resolveHeadlessMemfsPolicy(options) {
|
|
|
477908
478258
|
}
|
|
477909
478259
|
|
|
477910
478260
|
// src/headless-mod-adapter.ts
|
|
477911
|
-
import { join as
|
|
478261
|
+
import { join as join100 } from "node:path";
|
|
477912
478262
|
function isHeadlessMemfsEnabled(agentId) {
|
|
477913
478263
|
try {
|
|
477914
478264
|
return settingsManager.isMemfsEnabled(agentId);
|
|
@@ -477979,7 +478329,7 @@ function createHeadlessModContext(options) {
|
|
|
477979
478329
|
};
|
|
477980
478330
|
}
|
|
477981
478331
|
function createHeadlessModAdapter(options) {
|
|
477982
|
-
const agentModsDirectory = isHeadlessMemfsEnabled(options.agent.id) ?
|
|
478332
|
+
const agentModsDirectory = isHeadlessMemfsEnabled(options.agent.id) ? join100(getScopedMemoryFilesystemRoot(options.agent.id), "mods") : undefined;
|
|
477983
478333
|
return createModAdapter({
|
|
477984
478334
|
...agentModsDirectory ? { agentModsDirectory } : {},
|
|
477985
478335
|
...options.cacheDirectory ? { cacheDirectory: options.cacheDirectory } : {},
|
|
@@ -482649,10 +482999,10 @@ var init_cli_mod_context = __esm(() => {
|
|
|
482649
482999
|
|
|
482650
483000
|
// src/cli/helpers/reflection-arena-hf-upload.ts
|
|
482651
483001
|
import { execFile as execFileCb5 } from "node:child_process";
|
|
482652
|
-
import { existsSync as
|
|
483002
|
+
import { existsSync as existsSync71 } from "node:fs";
|
|
482653
483003
|
import { appendFile as appendFile2, chmod, mkdir as mkdir17, writeFile as writeFile20 } from "node:fs/promises";
|
|
482654
483004
|
import { homedir as homedir53 } from "node:os";
|
|
482655
|
-
import { join as
|
|
483005
|
+
import { join as join102 } from "node:path";
|
|
482656
483006
|
import { promisify as promisify20 } from "node:util";
|
|
482657
483007
|
function buildGitEnv(token2, askpassPath) {
|
|
482658
483008
|
return {
|
|
@@ -482688,7 +483038,7 @@ async function runGit6(cwd2, args, env6) {
|
|
|
482688
483038
|
}
|
|
482689
483039
|
}
|
|
482690
483040
|
async function writeGitAskpass(repoRoot) {
|
|
482691
|
-
const askpassPath =
|
|
483041
|
+
const askpassPath = join102(repoRoot, "hf-askpass.sh");
|
|
482692
483042
|
await writeFile20(askpassPath, [
|
|
482693
483043
|
"#!/bin/sh",
|
|
482694
483044
|
'case "$1" in',
|
|
@@ -482703,7 +483053,7 @@ async function writeGitAskpass(repoRoot) {
|
|
|
482703
483053
|
}
|
|
482704
483054
|
async function prepareHfRepo(env6) {
|
|
482705
483055
|
await mkdir17(HF_CACHE_ROOT, { recursive: true });
|
|
482706
|
-
if (!
|
|
483056
|
+
if (!existsSync71(join102(HF_REPO_DIR, ".git"))) {
|
|
482707
483057
|
await runGit6(HF_CACHE_ROOT, ["clone", "--depth", "1", HF_REPO_URL, HF_REPO_DIR], env6);
|
|
482708
483058
|
return HF_REPO_DIR;
|
|
482709
483059
|
}
|
|
@@ -482738,8 +483088,8 @@ async function maybeUploadReflectionArenaChoiceToHf(row) {
|
|
|
482738
483088
|
const env6 = buildGitEnv(token2, askpassPath);
|
|
482739
483089
|
try {
|
|
482740
483090
|
const repoDir = await prepareHfRepo(env6);
|
|
482741
|
-
await mkdir17(
|
|
482742
|
-
await appendFile2(
|
|
483091
|
+
await mkdir17(join102(repoDir, "data"), { recursive: true });
|
|
483092
|
+
await appendFile2(join102(repoDir, HF_DATASET_PATH), `${JSON.stringify(row)}
|
|
482743
483093
|
`, {
|
|
482744
483094
|
encoding: "utf-8"
|
|
482745
483095
|
});
|
|
@@ -482767,8 +483117,8 @@ var init_reflection_arena_hf_upload = __esm(() => {
|
|
|
482767
483117
|
init_version();
|
|
482768
483118
|
execFile23 = promisify20(execFileCb5);
|
|
482769
483119
|
HF_REPO_URL = `https://huggingface.co/datasets/${HF_REPO_ID}`;
|
|
482770
|
-
HF_CACHE_ROOT =
|
|
482771
|
-
HF_REPO_DIR =
|
|
483120
|
+
HF_CACHE_ROOT = join102(homedir53(), ".letta", "reflection-arena", "hf-upload");
|
|
483121
|
+
HF_REPO_DIR = join102(HF_CACHE_ROOT, "repo");
|
|
482772
483122
|
});
|
|
482773
483123
|
|
|
482774
483124
|
// src/cli/helpers/reflection-arena.ts
|
|
@@ -482776,7 +483126,7 @@ import { execFile as execFileCb6 } from "node:child_process";
|
|
|
482776
483126
|
import { randomInt as randomInt2, randomUUID as randomUUID57 } from "node:crypto";
|
|
482777
483127
|
import { appendFile as appendFile3, mkdir as mkdir18, readFile as readFile31, writeFile as writeFile21 } from "node:fs/promises";
|
|
482778
483128
|
import { homedir as homedir54 } from "node:os";
|
|
482779
|
-
import { join as
|
|
483129
|
+
import { join as join103 } from "node:path";
|
|
482780
483130
|
import { promisify as promisify21 } from "node:util";
|
|
482781
483131
|
function sampleReflectionArenaComparisonModel(excludedModels = []) {
|
|
482782
483132
|
const excluded = new Set(excludedModels);
|
|
@@ -482825,16 +483175,16 @@ function candidateIsConfirmedNoOp(candidate) {
|
|
|
482825
483175
|
return candidate.result?.success === true && candidate.result.memoryNoChanges === true && candidate.result.memoryHead === candidate.worktree.baseHead;
|
|
482826
483176
|
}
|
|
482827
483177
|
function getReflectionArenaRoot() {
|
|
482828
|
-
return
|
|
483178
|
+
return join103(homedir54(), ".letta", "reflection-arena");
|
|
482829
483179
|
}
|
|
482830
483180
|
function getReflectionArenaRunsDir() {
|
|
482831
|
-
return
|
|
483181
|
+
return join103(getReflectionArenaRoot(), "runs");
|
|
482832
483182
|
}
|
|
482833
483183
|
function getReflectionArenaChoiceLogPath() {
|
|
482834
|
-
return
|
|
483184
|
+
return join103(getReflectionArenaRoot(), "choices.jsonl");
|
|
482835
483185
|
}
|
|
482836
483186
|
function getReflectionArenaRunPath(runId) {
|
|
482837
|
-
return
|
|
483187
|
+
return join103(getReflectionArenaRunsDir(), `${runId}.json`);
|
|
482838
483188
|
}
|
|
482839
483189
|
async function saveReflectionArenaRun(run) {
|
|
482840
483190
|
await mkdir18(getReflectionArenaRunsDir(), { recursive: true });
|
|
@@ -484262,13 +484612,13 @@ __export(exports_terminal_keybinding_installer, {
|
|
|
484262
484612
|
});
|
|
484263
484613
|
import {
|
|
484264
484614
|
copyFileSync as copyFileSync6,
|
|
484265
|
-
existsSync as
|
|
484615
|
+
existsSync as existsSync72,
|
|
484266
484616
|
mkdirSync as mkdirSync50,
|
|
484267
|
-
readFileSync as
|
|
484617
|
+
readFileSync as readFileSync51,
|
|
484268
484618
|
writeFileSync as writeFileSync43
|
|
484269
484619
|
} from "node:fs";
|
|
484270
484620
|
import { homedir as homedir55, platform as platform10 } from "node:os";
|
|
484271
|
-
import { dirname as dirname37, join as
|
|
484621
|
+
import { dirname as dirname37, join as join104 } from "node:path";
|
|
484272
484622
|
function detectTerminalType() {
|
|
484273
484623
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
484274
484624
|
return "cursor";
|
|
@@ -484300,16 +484650,16 @@ function getKeybindingsPath(terminal) {
|
|
|
484300
484650
|
}[terminal];
|
|
484301
484651
|
const os9 = platform10();
|
|
484302
484652
|
if (os9 === "darwin") {
|
|
484303
|
-
return
|
|
484653
|
+
return join104(homedir55(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
484304
484654
|
}
|
|
484305
484655
|
if (os9 === "win32") {
|
|
484306
484656
|
const appData = process.env.APPDATA;
|
|
484307
484657
|
if (!appData)
|
|
484308
484658
|
return null;
|
|
484309
|
-
return
|
|
484659
|
+
return join104(appData, appName, "User", "keybindings.json");
|
|
484310
484660
|
}
|
|
484311
484661
|
if (os9 === "linux") {
|
|
484312
|
-
return
|
|
484662
|
+
return join104(homedir55(), ".config", appName, "User", "keybindings.json");
|
|
484313
484663
|
}
|
|
484314
484664
|
return null;
|
|
484315
484665
|
}
|
|
@@ -484331,10 +484681,10 @@ function parseKeybindings(content) {
|
|
|
484331
484681
|
}
|
|
484332
484682
|
}
|
|
484333
484683
|
function keybindingExists(keybindingsPath) {
|
|
484334
|
-
if (!
|
|
484684
|
+
if (!existsSync72(keybindingsPath))
|
|
484335
484685
|
return false;
|
|
484336
484686
|
try {
|
|
484337
|
-
const content =
|
|
484687
|
+
const content = readFileSync51(keybindingsPath, { encoding: "utf-8" });
|
|
484338
484688
|
const keybindings = parseKeybindings(content);
|
|
484339
484689
|
if (!keybindings)
|
|
484340
484690
|
return false;
|
|
@@ -484344,7 +484694,7 @@ function keybindingExists(keybindingsPath) {
|
|
|
484344
484694
|
}
|
|
484345
484695
|
}
|
|
484346
484696
|
function createBackup(keybindingsPath) {
|
|
484347
|
-
if (!
|
|
484697
|
+
if (!existsSync72(keybindingsPath))
|
|
484348
484698
|
return null;
|
|
484349
484699
|
const backupPath = `${keybindingsPath}.letta-backup`;
|
|
484350
484700
|
try {
|
|
@@ -484360,14 +484710,14 @@ function installKeybinding(keybindingsPath) {
|
|
|
484360
484710
|
return { success: true, alreadyExists: true };
|
|
484361
484711
|
}
|
|
484362
484712
|
const parentDir = dirname37(keybindingsPath);
|
|
484363
|
-
if (!
|
|
484713
|
+
if (!existsSync72(parentDir)) {
|
|
484364
484714
|
mkdirSync50(parentDir, { recursive: true });
|
|
484365
484715
|
}
|
|
484366
484716
|
let keybindings = [];
|
|
484367
484717
|
let backupPath = null;
|
|
484368
|
-
if (
|
|
484718
|
+
if (existsSync72(keybindingsPath)) {
|
|
484369
484719
|
backupPath = createBackup(keybindingsPath);
|
|
484370
|
-
const content =
|
|
484720
|
+
const content = readFileSync51(keybindingsPath, { encoding: "utf-8" });
|
|
484371
484721
|
const parsed = parseKeybindings(content);
|
|
484372
484722
|
if (parsed === null) {
|
|
484373
484723
|
return {
|
|
@@ -484395,10 +484745,10 @@ function installKeybinding(keybindingsPath) {
|
|
|
484395
484745
|
}
|
|
484396
484746
|
function removeKeybinding(keybindingsPath) {
|
|
484397
484747
|
try {
|
|
484398
|
-
if (!
|
|
484748
|
+
if (!existsSync72(keybindingsPath)) {
|
|
484399
484749
|
return { success: true };
|
|
484400
484750
|
}
|
|
484401
|
-
const content =
|
|
484751
|
+
const content = readFileSync51(keybindingsPath, { encoding: "utf-8" });
|
|
484402
484752
|
const keybindings = parseKeybindings(content);
|
|
484403
484753
|
if (!keybindings) {
|
|
484404
484754
|
return {
|
|
@@ -484462,14 +484812,14 @@ function getWezTermConfigPath() {
|
|
|
484462
484812
|
}
|
|
484463
484813
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
484464
484814
|
if (xdgConfig) {
|
|
484465
|
-
const xdgPath =
|
|
484466
|
-
if (
|
|
484815
|
+
const xdgPath = join104(xdgConfig, "wezterm", "wezterm.lua");
|
|
484816
|
+
if (existsSync72(xdgPath))
|
|
484467
484817
|
return xdgPath;
|
|
484468
484818
|
}
|
|
484469
|
-
const configPath =
|
|
484470
|
-
if (
|
|
484819
|
+
const configPath = join104(homedir55(), ".config", "wezterm", "wezterm.lua");
|
|
484820
|
+
if (existsSync72(configPath))
|
|
484471
484821
|
return configPath;
|
|
484472
|
-
return
|
|
484822
|
+
return join104(homedir55(), ".wezterm.lua");
|
|
484473
484823
|
}
|
|
484474
484824
|
function stripLuaCommentsFromLine(line, blockCommentEnd) {
|
|
484475
484825
|
let code2 = "";
|
|
@@ -484572,10 +484922,10 @@ ${WEZTERM_DELETE_FIX}
|
|
|
484572
484922
|
`;
|
|
484573
484923
|
}
|
|
484574
484924
|
function wezTermDeleteFixExists(configPath) {
|
|
484575
|
-
if (!
|
|
484925
|
+
if (!existsSync72(configPath))
|
|
484576
484926
|
return false;
|
|
484577
484927
|
try {
|
|
484578
|
-
const content =
|
|
484928
|
+
const content = readFileSync51(configPath, { encoding: "utf-8" });
|
|
484579
484929
|
return content.includes("Letta Code: Fix Delete key") || content.includes("key = 'Delete'") && content.includes("SendString") && content.includes("\\x1b[3~");
|
|
484580
484930
|
} catch {
|
|
484581
484931
|
return false;
|
|
@@ -484589,14 +484939,14 @@ function installWezTermDeleteFix() {
|
|
|
484589
484939
|
}
|
|
484590
484940
|
let content = "";
|
|
484591
484941
|
let backupPath = null;
|
|
484592
|
-
if (
|
|
484942
|
+
if (existsSync72(configPath)) {
|
|
484593
484943
|
backupPath = `${configPath}.letta-backup`;
|
|
484594
484944
|
copyFileSync6(configPath, backupPath);
|
|
484595
|
-
content =
|
|
484945
|
+
content = readFileSync51(configPath, { encoding: "utf-8" });
|
|
484596
484946
|
}
|
|
484597
484947
|
content = injectWezTermDeleteFix(content);
|
|
484598
484948
|
const parentDir = dirname37(configPath);
|
|
484599
|
-
if (!
|
|
484949
|
+
if (!existsSync72(parentDir)) {
|
|
484600
484950
|
mkdirSync50(parentDir, { recursive: true });
|
|
484601
484951
|
}
|
|
484602
484952
|
writeFileSync43(configPath, content, { encoding: "utf-8" });
|
|
@@ -484648,9 +484998,9 @@ __export(exports_settings2, {
|
|
|
484648
484998
|
getSetting: () => getSetting
|
|
484649
484999
|
});
|
|
484650
485000
|
import { homedir as homedir56 } from "node:os";
|
|
484651
|
-
import { join as
|
|
485001
|
+
import { join as join105 } from "node:path";
|
|
484652
485002
|
function getSettingsPath() {
|
|
484653
|
-
return
|
|
485003
|
+
return join105(homedir56(), ".letta", "settings.json");
|
|
484654
485004
|
}
|
|
484655
485005
|
async function loadSettings() {
|
|
484656
485006
|
const settingsPath = getSettingsPath();
|
|
@@ -484687,7 +485037,7 @@ async function getSetting(key3) {
|
|
|
484687
485037
|
return settings3[key3];
|
|
484688
485038
|
}
|
|
484689
485039
|
function getProjectSettingsPath() {
|
|
484690
|
-
return
|
|
485040
|
+
return join105(process.cwd(), ".letta", "settings.local.json");
|
|
484691
485041
|
}
|
|
484692
485042
|
async function loadProjectSettings() {
|
|
484693
485043
|
const settingsPath = getProjectSettingsPath();
|
|
@@ -484705,7 +485055,7 @@ async function loadProjectSettings() {
|
|
|
484705
485055
|
}
|
|
484706
485056
|
async function saveProjectSettings(settings3) {
|
|
484707
485057
|
const settingsPath = getProjectSettingsPath();
|
|
484708
|
-
const dirPath =
|
|
485058
|
+
const dirPath = join105(process.cwd(), ".letta");
|
|
484709
485059
|
try {
|
|
484710
485060
|
if (!exists(dirPath)) {
|
|
484711
485061
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -486593,9 +486943,9 @@ function getHeaderText(fileEdit) {
|
|
|
486593
486943
|
const relPath = relative13(cwd2, fileEdit.filePath);
|
|
486594
486944
|
const displayPath = relPath.startsWith("..") ? fileEdit.filePath : relPath;
|
|
486595
486945
|
if (t2 === "write") {
|
|
486596
|
-
const { existsSync:
|
|
486946
|
+
const { existsSync: existsSync73 } = __require("node:fs");
|
|
486597
486947
|
try {
|
|
486598
|
-
if (
|
|
486948
|
+
if (existsSync73(fileEdit.filePath)) {
|
|
486599
486949
|
return `Overwrite ${displayPath}?`;
|
|
486600
486950
|
}
|
|
486601
486951
|
} catch {}
|
|
@@ -495512,20 +495862,20 @@ var init_InputRich = __esm(async () => {
|
|
|
495512
495862
|
});
|
|
495513
495863
|
|
|
495514
495864
|
// src/cli/commands/install-github-app.ts
|
|
495515
|
-
import { execFileSync as
|
|
495865
|
+
import { execFileSync as execFileSync10 } from "node:child_process";
|
|
495516
495866
|
import {
|
|
495517
|
-
existsSync as
|
|
495867
|
+
existsSync as existsSync73,
|
|
495518
495868
|
mkdirSync as mkdirSync51,
|
|
495519
495869
|
mkdtempSync as mkdtempSync7,
|
|
495520
|
-
readFileSync as
|
|
495870
|
+
readFileSync as readFileSync52,
|
|
495521
495871
|
rmSync as rmSync26,
|
|
495522
495872
|
writeFileSync as writeFileSync44
|
|
495523
495873
|
} from "node:fs";
|
|
495524
495874
|
import { tmpdir as tmpdir15 } from "node:os";
|
|
495525
|
-
import { dirname as dirname38, join as
|
|
495875
|
+
import { dirname as dirname38, join as join106 } from "node:path";
|
|
495526
495876
|
function runCommand(command, args, cwd2, input) {
|
|
495527
495877
|
try {
|
|
495528
|
-
return
|
|
495878
|
+
return execFileSync10(command, args, {
|
|
495529
495879
|
cwd: cwd2,
|
|
495530
495880
|
encoding: "utf8",
|
|
495531
495881
|
stdio: [input ? "pipe" : "ignore", "pipe", "pipe"],
|
|
@@ -495743,8 +496093,8 @@ async function createLettaAgent(apiKey, name) {
|
|
|
495743
496093
|
return createMinimalAgent(apiKey, name);
|
|
495744
496094
|
}
|
|
495745
496095
|
function cloneRepoToTemp(repo) {
|
|
495746
|
-
const tempDir = mkdtempSync7(
|
|
495747
|
-
const repoDir =
|
|
496096
|
+
const tempDir = mkdtempSync7(join106(tmpdir15(), "letta-install-github-app-"));
|
|
496097
|
+
const repoDir = join106(tempDir, "repo");
|
|
495748
496098
|
runCommand("gh", ["repo", "clone", repo, repoDir, "--", "--depth=1"]);
|
|
495749
496099
|
return { tempDir, repoDir };
|
|
495750
496100
|
}
|
|
@@ -495755,14 +496105,14 @@ function runGit7(args, cwd2) {
|
|
|
495755
496105
|
return runCommand("git", args, cwd2);
|
|
495756
496106
|
}
|
|
495757
496107
|
function writeWorkflow(repoDir, workflowPath, content) {
|
|
495758
|
-
const absolutePath =
|
|
495759
|
-
if (!
|
|
496108
|
+
const absolutePath = join106(repoDir, workflowPath);
|
|
496109
|
+
if (!existsSync73(dirname38(absolutePath))) {
|
|
495760
496110
|
mkdirSync51(dirname38(absolutePath), { recursive: true });
|
|
495761
496111
|
}
|
|
495762
496112
|
const next = `${content.trimEnd()}
|
|
495763
496113
|
`;
|
|
495764
|
-
if (
|
|
495765
|
-
const previous =
|
|
496114
|
+
if (existsSync73(absolutePath)) {
|
|
496115
|
+
const previous = readFileSync52(absolutePath, "utf8");
|
|
495766
496116
|
if (previous === next) {
|
|
495767
496117
|
return false;
|
|
495768
496118
|
}
|
|
@@ -499651,9 +500001,9 @@ __export(exports_generate_memory_viewer, {
|
|
|
499651
500001
|
generateAndOpenMemoryViewer: () => generateAndOpenMemoryViewer
|
|
499652
500002
|
});
|
|
499653
500003
|
import { execFile as execFileCb7 } from "node:child_process";
|
|
499654
|
-
import { chmodSync as chmodSync8, existsSync as
|
|
500004
|
+
import { chmodSync as chmodSync8, existsSync as existsSync74, mkdirSync as mkdirSync52, writeFileSync as writeFileSync45 } from "node:fs";
|
|
499655
500005
|
import { homedir as homedir58 } from "node:os";
|
|
499656
|
-
import { join as
|
|
500006
|
+
import { join as join107 } from "node:path";
|
|
499657
500007
|
import { promisify as promisify22 } from "node:util";
|
|
499658
500008
|
function messagesFromOverview(overview) {
|
|
499659
500009
|
return overview.messages?.map((message) => ({
|
|
@@ -499962,7 +500312,7 @@ ${m4.body}` : m4.subject;
|
|
|
499962
500312
|
async function generateAndOpenMemoryViewer(agentId, options) {
|
|
499963
500313
|
const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
499964
500314
|
const repoDir = memoryRoot;
|
|
499965
|
-
if (!
|
|
500315
|
+
if (!existsSync74(join107(repoDir, ".git"))) {
|
|
499966
500316
|
throw new Error("Memory viewer requires memfs. Run /memfs enable first.");
|
|
499967
500317
|
}
|
|
499968
500318
|
const data = await collectMemoryData(agentId, repoDir, memoryRoot, options?.conversationId);
|
|
@@ -499972,13 +500322,13 @@ async function generateAndOpenMemoryViewer(agentId, options) {
|
|
|
499972
500322
|
data.context = applyContextUsageSnapshot(data.context, options?.contextUsage);
|
|
499973
500323
|
const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
|
|
499974
500324
|
const html5 = memory_viewer_template_default.replace("<!--LETTA_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
499975
|
-
if (!
|
|
500325
|
+
if (!existsSync74(VIEWERS_DIR)) {
|
|
499976
500326
|
mkdirSync52(VIEWERS_DIR, { recursive: true, mode: 448 });
|
|
499977
500327
|
}
|
|
499978
500328
|
try {
|
|
499979
500329
|
chmodSync8(VIEWERS_DIR, 448);
|
|
499980
500330
|
} catch {}
|
|
499981
|
-
const filePath =
|
|
500331
|
+
const filePath = join107(VIEWERS_DIR, `memory-${encodeURIComponent(agentId)}.html`);
|
|
499982
500332
|
writeFileSync45(filePath, html5);
|
|
499983
500333
|
chmodSync8(filePath, 384);
|
|
499984
500334
|
const skipOpen = Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
|
|
@@ -500004,13 +500354,13 @@ var init_generate_memory_viewer = __esm(() => {
|
|
|
500004
500354
|
init_local_memory_context();
|
|
500005
500355
|
init_memory_viewer_template();
|
|
500006
500356
|
execFile25 = promisify22(execFileCb7);
|
|
500007
|
-
VIEWERS_DIR =
|
|
500357
|
+
VIEWERS_DIR = join107(homedir58(), ".letta", "viewers");
|
|
500008
500358
|
REFLECTION_PATTERN = /\(reflection\)|🔮|reflection:/i;
|
|
500009
500359
|
});
|
|
500010
500360
|
|
|
500011
500361
|
// src/cli/components/MemfsTreeViewer.tsx
|
|
500012
|
-
import { existsSync as
|
|
500013
|
-
import { join as
|
|
500362
|
+
import { existsSync as existsSync75 } from "node:fs";
|
|
500363
|
+
import { join as join108 } from "node:path";
|
|
500014
500364
|
function renderTreePrefix(node) {
|
|
500015
500365
|
let prefix = "";
|
|
500016
500366
|
for (let i4 = 0;i4 < node.depth; i4++) {
|
|
@@ -500038,8 +500388,8 @@ function MemfsTreeViewer({
|
|
|
500038
500388
|
const [status, setStatus] = import_react88.useState(null);
|
|
500039
500389
|
const statusTimerRef = import_react88.useRef(null);
|
|
500040
500390
|
const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
500041
|
-
const memoryExists =
|
|
500042
|
-
const hasGitRepo = import_react88.useMemo(() =>
|
|
500391
|
+
const memoryExists = existsSync75(memoryRoot);
|
|
500392
|
+
const hasGitRepo = import_react88.useMemo(() => existsSync75(join108(memoryRoot, ".git")), [memoryRoot]);
|
|
500043
500393
|
function showStatus(msg, durationMs) {
|
|
500044
500394
|
if (statusTimerRef.current)
|
|
500045
500395
|
clearTimeout(statusTimerRef.current);
|
|
@@ -502415,10 +502765,10 @@ var init_PersonalitySelector = __esm(async () => {
|
|
|
502415
502765
|
// src/utils/aws-credentials.ts
|
|
502416
502766
|
import { readFile as readFile32 } from "node:fs/promises";
|
|
502417
502767
|
import { homedir as homedir59 } from "node:os";
|
|
502418
|
-
import { join as
|
|
502768
|
+
import { join as join109 } from "node:path";
|
|
502419
502769
|
async function parseAwsCredentials() {
|
|
502420
|
-
const credentialsPath =
|
|
502421
|
-
const configPath =
|
|
502770
|
+
const credentialsPath = join109(homedir59(), ".aws", "credentials");
|
|
502771
|
+
const configPath = join109(homedir59(), ".aws", "config");
|
|
502422
502772
|
const profiles = new Map;
|
|
502423
502773
|
try {
|
|
502424
502774
|
const content = await readFile32(credentialsPath, "utf-8");
|
|
@@ -504083,8 +504433,8 @@ function SkillsDialog({ onClose, agentId }) {
|
|
|
504083
504433
|
try {
|
|
504084
504434
|
const { discoverSkills: discoverSkills2, SKILLS_DIR: SKILLS_DIR2 } = await Promise.resolve().then(() => (init_skills5(), exports_skills2));
|
|
504085
504435
|
const { getSkillsDirectory: getSkillsDirectory2, getSkillSources: getSkillSources2 } = await Promise.resolve().then(() => (init_context(), exports_context));
|
|
504086
|
-
const { join:
|
|
504087
|
-
const skillsDir = getSkillsDirectory2() ||
|
|
504436
|
+
const { join: join110 } = await import("node:path");
|
|
504437
|
+
const skillsDir = getSkillsDirectory2() || join110(process.cwd(), SKILLS_DIR2);
|
|
504088
504438
|
const result3 = await discoverSkills2(skillsDir, agentId, {
|
|
504089
504439
|
sources: getSkillSources2()
|
|
504090
504440
|
});
|
|
@@ -508407,9 +508757,9 @@ function getFileEditHeader(toolName2, toolArgs) {
|
|
|
508407
508757
|
const relPath = relative13(cwd2, filePath);
|
|
508408
508758
|
const displayPath = relPath.startsWith("..") ? filePath : relPath;
|
|
508409
508759
|
if (t2 === "write") {
|
|
508410
|
-
const { existsSync:
|
|
508760
|
+
const { existsSync: existsSync76 } = __require("node:fs");
|
|
508411
508761
|
try {
|
|
508412
|
-
if (
|
|
508762
|
+
if (existsSync76(filePath)) {
|
|
508413
508763
|
return `Overwrite ${displayPath}?`;
|
|
508414
508764
|
}
|
|
508415
508765
|
} catch {}
|
|
@@ -510177,9 +510527,9 @@ __export(exports_generate_diff_viewer, {
|
|
|
510177
510527
|
generateAndOpenDiffViewer: () => generateAndOpenDiffViewer
|
|
510178
510528
|
});
|
|
510179
510529
|
import { execFile as execFileCb8 } from "node:child_process";
|
|
510180
|
-
import { chmodSync as chmodSync9, existsSync as
|
|
510530
|
+
import { chmodSync as chmodSync9, existsSync as existsSync76, mkdirSync as mkdirSync53, writeFileSync as writeFileSync46 } from "node:fs";
|
|
510181
510531
|
import { homedir as homedir60 } from "node:os";
|
|
510182
|
-
import { isAbsolute as isAbsolute27, join as
|
|
510532
|
+
import { isAbsolute as isAbsolute27, join as join110, resolve as resolve44 } from "node:path";
|
|
510183
510533
|
import { promisify as promisify23 } from "node:util";
|
|
510184
510534
|
async function runGit8(cwd2, args) {
|
|
510185
510535
|
try {
|
|
@@ -510402,13 +510752,13 @@ async function generateAndOpenDiffViewer(targetPath) {
|
|
|
510402
510752
|
};
|
|
510403
510753
|
const jsonPayload = JSON.stringify(payload).replace(/</g, "\\u003c");
|
|
510404
510754
|
const html5 = diff_viewer_template_default.replace("<!--LETTA_DIFF_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
510405
|
-
if (!
|
|
510755
|
+
if (!existsSync76(VIEWERS_DIR2)) {
|
|
510406
510756
|
mkdirSync53(VIEWERS_DIR2, { recursive: true, mode: 448 });
|
|
510407
510757
|
}
|
|
510408
510758
|
try {
|
|
510409
510759
|
chmodSync9(VIEWERS_DIR2, 448);
|
|
510410
510760
|
} catch {}
|
|
510411
|
-
const filePath =
|
|
510761
|
+
const filePath = join110(VIEWERS_DIR2, `diff-${encodeURIComponent(worktreePath)}.html`);
|
|
510412
510762
|
writeFileSync46(filePath, html5);
|
|
510413
510763
|
chmodSync9(filePath, 384);
|
|
510414
510764
|
const skipOpen = shouldSkipOpen();
|
|
@@ -510477,7 +510827,7 @@ var execFile26, VIEWERS_DIR2, GIT_TIMEOUT_MS3 = 60000, GIT_MAX_BUFFER, MAX_RENDE
|
|
|
510477
510827
|
var init_generate_diff_viewer = __esm(() => {
|
|
510478
510828
|
init_diff_viewer_template();
|
|
510479
510829
|
execFile26 = promisify23(execFileCb8);
|
|
510480
|
-
VIEWERS_DIR2 =
|
|
510830
|
+
VIEWERS_DIR2 = join110(homedir60(), ".letta", "viewers");
|
|
510481
510831
|
GIT_MAX_BUFFER = 50 * 1024 * 1024;
|
|
510482
510832
|
});
|
|
510483
510833
|
|
|
@@ -512422,16 +512772,16 @@ __export(exports_shell_aliases, {
|
|
|
512422
512772
|
expandAliases: () => expandAliases,
|
|
512423
512773
|
clearAliasCache: () => clearAliasCache
|
|
512424
512774
|
});
|
|
512425
|
-
import { existsSync as
|
|
512775
|
+
import { existsSync as existsSync77, readFileSync as readFileSync53 } from "node:fs";
|
|
512426
512776
|
import { homedir as homedir61 } from "node:os";
|
|
512427
|
-
import { join as
|
|
512777
|
+
import { join as join111 } from "node:path";
|
|
512428
512778
|
function parseAliasesFromFile(filePath) {
|
|
512429
512779
|
const aliases = new Map;
|
|
512430
|
-
if (!
|
|
512780
|
+
if (!existsSync77(filePath)) {
|
|
512431
512781
|
return aliases;
|
|
512432
512782
|
}
|
|
512433
512783
|
try {
|
|
512434
|
-
const content =
|
|
512784
|
+
const content = readFileSync53(filePath, "utf-8");
|
|
512435
512785
|
const lines = content.split(`
|
|
512436
512786
|
`);
|
|
512437
512787
|
let inFunction = false;
|
|
@@ -512496,7 +512846,7 @@ function loadAliases(forceReload = false) {
|
|
|
512496
512846
|
const home = homedir61();
|
|
512497
512847
|
const allAliases = new Map;
|
|
512498
512848
|
for (const file of ALIAS_FILES) {
|
|
512499
|
-
const filePath =
|
|
512849
|
+
const filePath = join111(home, file);
|
|
512500
512850
|
const fileAliases = parseAliasesFromFile(filePath);
|
|
512501
512851
|
for (const [name, value] of fileAliases) {
|
|
512502
512852
|
allAliases.set(name, value);
|
|
@@ -520696,9 +521046,9 @@ var init_conversation_switch_alert = __esm(() => {
|
|
|
520696
521046
|
|
|
520697
521047
|
// src/cli/app/use-submit-handler.ts
|
|
520698
521048
|
import { randomUUID as randomUUID62 } from "node:crypto";
|
|
520699
|
-
import { existsSync as
|
|
521049
|
+
import { existsSync as existsSync78, readFileSync as readFileSync54, renameSync as renameSync13 } from "node:fs";
|
|
520700
521050
|
import { tmpdir as tmpdir16 } from "node:os";
|
|
520701
|
-
import { join as
|
|
521051
|
+
import { join as join112 } from "node:path";
|
|
520702
521052
|
async function findCustomCommandByName(commandName) {
|
|
520703
521053
|
const { findCustomCommand: findCustomCommand2 } = await Promise.resolve().then(() => (init_custom(), exports_custom));
|
|
520704
521054
|
return findCustomCommand2(commandName);
|
|
@@ -521306,12 +521656,12 @@ ${SYSTEM_REMINDER_CLOSE}`),
|
|
|
521306
521656
|
try {
|
|
521307
521657
|
const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
521308
521658
|
const personaCandidates = [
|
|
521309
|
-
|
|
521310
|
-
|
|
521659
|
+
join112(memoryRoot, "system", "persona.md"),
|
|
521660
|
+
join112(memoryRoot, "memory", "system", "persona.md")
|
|
521311
521661
|
];
|
|
521312
|
-
const personaPath = personaCandidates.find((candidate) =>
|
|
521662
|
+
const personaPath = personaCandidates.find((candidate) => existsSync78(candidate));
|
|
521313
521663
|
if (personaPath) {
|
|
521314
|
-
const personaContent =
|
|
521664
|
+
const personaContent = readFileSync54(personaPath, "utf-8");
|
|
521315
521665
|
setCurrentPersonalityId(detectPersonalityFromPersonaFile(personaContent));
|
|
521316
521666
|
} else {
|
|
521317
521667
|
setCurrentPersonalityId(null);
|
|
@@ -522155,11 +522505,11 @@ Path: ${memoryDir}`, true);
|
|
|
522155
522505
|
setCommandRunning(true);
|
|
522156
522506
|
try {
|
|
522157
522507
|
const memoryDir = getScopedMemoryFilesystemRoot(agentId);
|
|
522158
|
-
if (!
|
|
522508
|
+
if (!existsSync78(memoryDir)) {
|
|
522159
522509
|
updateMemorySyncCommand(cmdId, "No local memory filesystem found to reset.", true, msg);
|
|
522160
522510
|
return { submitted: true };
|
|
522161
522511
|
}
|
|
522162
|
-
const backupDir =
|
|
522512
|
+
const backupDir = join112(tmpdir16(), `letta-memfs-reset-${agentId}-${Date.now()}`);
|
|
522163
522513
|
renameSync13(memoryDir, backupDir);
|
|
522164
522514
|
if (getBackend().capabilities.localMemfs) {
|
|
522165
522515
|
const { initializeLocalMemoryRepo: initializeLocalMemoryRepo2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
|
|
@@ -523074,7 +523424,7 @@ var init_use_submit_handler = __esm(async () => {
|
|
|
523074
523424
|
});
|
|
523075
523425
|
|
|
523076
523426
|
// src/cli/app/AppCoordinator.tsx
|
|
523077
|
-
import { join as
|
|
523427
|
+
import { join as join113 } from "node:path";
|
|
523078
523428
|
function buildStartupCommandHints(options) {
|
|
523079
523429
|
const {
|
|
523080
523430
|
isResumingConversation,
|
|
@@ -524356,7 +524706,7 @@ function App2({
|
|
|
524356
524706
|
agentId: a2.agentId ?? null
|
|
524357
524707
|
}))
|
|
524358
524708
|
});
|
|
524359
|
-
const agentModsDirectory = modContext.memfs.enabled && modContext.memfs.memoryDir ?
|
|
524709
|
+
const agentModsDirectory = modContext.memfs.enabled && modContext.memfs.memoryDir ? join113(modContext.memfs.memoryDir, "mods") : null;
|
|
524360
524710
|
const modAdapter = useLocalModAdapter(modContext, {
|
|
524361
524711
|
agentModsDirectory,
|
|
524362
524712
|
disabled: modsDisabled,
|
|
@@ -525112,9 +525462,9 @@ Memory may be stale. Try running: git -C ${getScopedMemoryFilesystemRoot(agentId
|
|
|
525112
525462
|
(async () => {
|
|
525113
525463
|
try {
|
|
525114
525464
|
const { watch: watch4 } = await import("node:fs");
|
|
525115
|
-
const { existsSync:
|
|
525465
|
+
const { existsSync: existsSync79 } = await import("node:fs");
|
|
525116
525466
|
const memRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
525117
|
-
if (!
|
|
525467
|
+
if (!existsSync79(memRoot))
|
|
525118
525468
|
return;
|
|
525119
525469
|
watcher2 = watch4(memRoot, { recursive: true }, () => {});
|
|
525120
525470
|
memfsWatcherRef.current = watcher2;
|
|
@@ -526684,12 +527034,12 @@ EXAMPLES
|
|
|
526684
527034
|
console.log(usage);
|
|
526685
527035
|
}
|
|
526686
527036
|
async function printInfo() {
|
|
526687
|
-
const { join:
|
|
527037
|
+
const { join: join114 } = await import("node:path");
|
|
526688
527038
|
const { getVersion: getVersion2 } = await Promise.resolve().then(() => (init_version(), exports_version));
|
|
526689
527039
|
const { SKILLS_DIR: SKILLS_DIR2 } = await Promise.resolve().then(() => (init_skills5(), exports_skills2));
|
|
526690
527040
|
const { exists: exists2 } = await Promise.resolve().then(() => (init_fs(), exports_fs));
|
|
526691
527041
|
const cwd2 = process.cwd();
|
|
526692
|
-
const skillsDir =
|
|
527042
|
+
const skillsDir = join114(cwd2, SKILLS_DIR2);
|
|
526693
527043
|
const skillsExist = exists2(skillsDir);
|
|
526694
527044
|
await settingsManager.loadLocalProjectSettings(cwd2);
|
|
526695
527045
|
const pinned = settingsManager.getPinnedAgents();
|
|
@@ -530516,4 +530866,4 @@ function registerBunOAuthFlows() {
|
|
|
530516
530866
|
registerBunOAuthFlows();
|
|
530517
530867
|
await init_src5().then(() => exports_src2);
|
|
530518
530868
|
|
|
530519
|
-
//# debugId=
|
|
530869
|
+
//# debugId=6092543575D1F9DD64756E2164756E21
|