@letta-ai/letta-code 0.34.27 → 0.34.29
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/channels-slack.js +2 -2
- package/dist/channels-slack.js.map +3 -3
- 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/memory-git-process.d.ts +10 -0
- package/dist/types/agent/memory-git-process.d.ts.map +1 -0
- package/dist/types/agent/memory-git.d.ts.map +1 -1
- package/dist/types/channels/slack/attachment-primitives.d.ts.map +1 -1
- package/dist/types/tools/impl/monitor-script.d.ts +38 -0
- package/dist/types/tools/impl/monitor-script.d.ts.map +1 -0
- package/dist/types/tools/impl/monitor-timeout.d.ts +3 -0
- package/dist/types/tools/impl/monitor-timeout.d.ts.map +1 -0
- package/dist/types/tools/impl/monitor.d.ts +3 -2
- package/dist/types/tools/impl/monitor.d.ts.map +1 -1
- package/dist/types/tools/impl/process_manager.d.ts +1 -1
- package/dist/types/tools/impl/process_manager.d.ts.map +1 -1
- package/dist/types/tools/impl/shell-runner.d.ts.map +1 -1
- package/dist/types/tools/impl/watch-pr.d.ts.map +1 -1
- package/dist/types/tools/impl/workflow.d.ts +1 -0
- package/dist/types/tools/impl/workflow.d.ts.map +1 -1
- package/dist/types/tools/manager.d.ts.map +1 -1
- package/dist/types/tools/script-tool-scope.d.ts +2 -0
- package/dist/types/tools/script-tool-scope.d.ts.map +1 -1
- package/dist/types/tools/tool-context-retention.d.ts +7 -0
- package/dist/types/tools/tool-context-retention.d.ts.map +1 -0
- package/dist/types/tools/workflow/types.d.ts +2 -0
- package/dist/types/tools/workflow/types.d.ts.map +1 -1
- package/dist/types/tools/workflow/workflow-engine.d.ts +4 -1
- package/dist/types/tools/workflow/workflow-engine.d.ts.map +1 -1
- package/dist/types/types/background-process-protocol.d.ts +1 -1
- package/dist/types/types/background-process-protocol.d.ts.map +1 -1
- package/dist/types/websocket/listener/durable-file-lock.d.ts +2 -0
- package/dist/types/websocket/listener/durable-file-lock.d.ts.map +1 -1
- package/dist/types/websocket/listener/queue.d.ts +0 -1
- package/dist/types/websocket/listener/queue.d.ts.map +1 -1
- package/dist/types/websocket/listener/types.d.ts +6 -0
- package/dist/types/websocket/listener/types.d.ts.map +1 -1
- package/letta.js +765 -270
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/scripts/run-api-integration-tests.ts +55 -0
- package/scripts/source-file-size-baseline.json +3 -3
package/letta.js
CHANGED
|
@@ -6044,7 +6044,7 @@ var package_default;
|
|
|
6044
6044
|
var init_package = __esm(() => {
|
|
6045
6045
|
package_default = {
|
|
6046
6046
|
name: "@letta-ai/letta-code",
|
|
6047
|
-
version: "0.34.
|
|
6047
|
+
version: "0.34.29",
|
|
6048
6048
|
lettaStartupLogProtocol: 1,
|
|
6049
6049
|
lettaConfigDirProtocol: 1,
|
|
6050
6050
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
@@ -102800,6 +102800,83 @@ async function getMemoryGitDir(memoryDir) {
|
|
|
102800
102800
|
}
|
|
102801
102801
|
var init_memory_git_dir = () => {};
|
|
102802
102802
|
|
|
102803
|
+
// src/agent/memory-git-process.ts
|
|
102804
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
102805
|
+
async function execGit(args, options) {
|
|
102806
|
+
let termination = Promise.resolve();
|
|
102807
|
+
let timedOut = false;
|
|
102808
|
+
const child = spawn2("git", args, {
|
|
102809
|
+
cwd: options.cwd,
|
|
102810
|
+
env: options.env,
|
|
102811
|
+
detached: process.platform !== "win32",
|
|
102812
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
102813
|
+
windowsHide: true
|
|
102814
|
+
});
|
|
102815
|
+
let stdout = "";
|
|
102816
|
+
let stderr = "";
|
|
102817
|
+
let bufferError;
|
|
102818
|
+
const collect = (stream11, data) => {
|
|
102819
|
+
if (bufferError)
|
|
102820
|
+
return;
|
|
102821
|
+
if (stream11 === "stdout")
|
|
102822
|
+
stdout += data;
|
|
102823
|
+
else
|
|
102824
|
+
stderr += data;
|
|
102825
|
+
if (Buffer.byteLength(stream11 === "stdout" ? stdout : stderr) > 10 * 1024 * 1024) {
|
|
102826
|
+
bufferError = new Error(`git ${stream11} exceeded maxBuffer`);
|
|
102827
|
+
terminate();
|
|
102828
|
+
}
|
|
102829
|
+
};
|
|
102830
|
+
child.stdout.setEncoding("utf8").on("data", (data) => collect("stdout", data));
|
|
102831
|
+
child.stderr.setEncoding("utf8").on("data", (data) => collect("stderr", data));
|
|
102832
|
+
const closed = new Promise((resolve7) => child.once("close", resolve7));
|
|
102833
|
+
const result = new Promise((resolve7, reject) => {
|
|
102834
|
+
child.once("error", reject);
|
|
102835
|
+
child.once("close", (code2, signal) => {
|
|
102836
|
+
if (timedOut || bufferError || code2 !== 0) {
|
|
102837
|
+
reject(Object.assign(bufferError ?? new Error(`git ${args.join(" ")} failed${timedOut ? " (ETIMEDOUT)" : ""}: ${stderr}`), { code: timedOut ? "ETIMEDOUT" : code2, signal, stdout, stderr }));
|
|
102838
|
+
} else
|
|
102839
|
+
resolve7({ stdout, stderr });
|
|
102840
|
+
});
|
|
102841
|
+
});
|
|
102842
|
+
function terminate() {
|
|
102843
|
+
if (!child.pid)
|
|
102844
|
+
return;
|
|
102845
|
+
if (process.platform === "win32") {
|
|
102846
|
+
termination = new Promise((resolve7) => {
|
|
102847
|
+
const killer = spawn2("taskkill.exe", ["/pid", String(child.pid), "/t", "/f"], { stdio: "ignore", windowsHide: true });
|
|
102848
|
+
killer.once("error", () => {
|
|
102849
|
+
child.kill("SIGKILL");
|
|
102850
|
+
resolve7();
|
|
102851
|
+
});
|
|
102852
|
+
killer.once("close", (code2) => {
|
|
102853
|
+
if (code2 !== 0)
|
|
102854
|
+
child.kill("SIGKILL");
|
|
102855
|
+
resolve7();
|
|
102856
|
+
});
|
|
102857
|
+
});
|
|
102858
|
+
} else {
|
|
102859
|
+
try {
|
|
102860
|
+
process.kill(-child.pid, "SIGKILL");
|
|
102861
|
+
} catch {
|
|
102862
|
+
child.kill("SIGKILL");
|
|
102863
|
+
}
|
|
102864
|
+
}
|
|
102865
|
+
}
|
|
102866
|
+
const timer = options.timeoutMs > 0 ? setTimeout(() => {
|
|
102867
|
+
timedOut = true;
|
|
102868
|
+
terminate();
|
|
102869
|
+
}, options.timeoutMs) : undefined;
|
|
102870
|
+
try {
|
|
102871
|
+
return await result;
|
|
102872
|
+
} finally {
|
|
102873
|
+
clearTimeout(timer);
|
|
102874
|
+
await termination;
|
|
102875
|
+
await closed;
|
|
102876
|
+
}
|
|
102877
|
+
}
|
|
102878
|
+
var init_memory_git_process = () => {};
|
|
102879
|
+
|
|
102803
102880
|
// src/backend/api/memfs-git-proxy.ts
|
|
102804
102881
|
var exports_memfs_git_proxy = {};
|
|
102805
102882
|
__export(exports_memfs_git_proxy, {
|
|
@@ -103472,7 +103549,6 @@ __export(exports_memory_git, {
|
|
|
103472
103549
|
buildGitAuthArgs: () => buildGitAuthArgs,
|
|
103473
103550
|
addGitMemoryTag: () => addGitMemoryTag
|
|
103474
103551
|
});
|
|
103475
|
-
import { execFile as execFileCb } from "node:child_process";
|
|
103476
103552
|
import {
|
|
103477
103553
|
existsSync as existsSync8,
|
|
103478
103554
|
mkdirSync as mkdirSync6,
|
|
@@ -103483,7 +103559,6 @@ import {
|
|
|
103483
103559
|
} from "node:fs";
|
|
103484
103560
|
import { platform } from "node:os";
|
|
103485
103561
|
import { dirname as dirname8, join as join14 } from "node:path";
|
|
103486
|
-
import { promisify as promisify4 } from "node:util";
|
|
103487
103562
|
function getAgentRootDir(agentId) {
|
|
103488
103563
|
return join14(resolveGlobalConfigDir(), "agents", agentId);
|
|
103489
103564
|
}
|
|
@@ -103746,11 +103821,10 @@ async function runGit(cwd, args, token, options) {
|
|
|
103746
103821
|
const timeoutMs = options?.timeoutMs ?? GIT_DEFAULT_TIMEOUT_MS;
|
|
103747
103822
|
let result;
|
|
103748
103823
|
try {
|
|
103749
|
-
result = await
|
|
103824
|
+
result = await execGit(allArgs, {
|
|
103750
103825
|
cwd,
|
|
103751
103826
|
env: buildNonInteractiveGitEnv(),
|
|
103752
|
-
|
|
103753
|
-
timeout: timeoutMs
|
|
103827
|
+
timeoutMs
|
|
103754
103828
|
});
|
|
103755
103829
|
} catch (error4) {
|
|
103756
103830
|
throw redactGitAuthError(error4);
|
|
@@ -104622,10 +104696,11 @@ async function addGitMemoryTag(agentId, prefetchedAgent) {
|
|
|
104622
104696
|
debugWarn("memfs-git", `Failed to add git-memory tag: ${err instanceof Error ? err.message : String(err)}`);
|
|
104623
104697
|
}
|
|
104624
104698
|
}
|
|
104625
|
-
var
|
|
104699
|
+
var RETRYABLE_GIT_HTTP_ERROR_RE, RETRYABLE_GIT_NETWORK_ERROR_RE, MISSING_CWD_GIT_ERROR_RE, NON_FAST_FORWARD_PUSH_ERROR_RE, UNRELATED_HISTORY_PULL_ERROR_RE, NO_UPSTREAM_PULL_ERROR_RE, AGENT_DISPLAY_NAME_TIMEOUT_MS = 3000, HOSTED_BACKEND_HEADER = "x-letta-memfs-backend", HOSTED_BACKEND_VALUE = "hosted", GIT_DEFAULT_TIMEOUT_MS = 60000, GIT_CLONE_TIMEOUT_MS = 180000, gitConfig = (dir, args) => withSerializedGitConfigMutation(dir, () => runGit(dir, args)), MEMORY_REPOSITORY_CONFIG_KEY = "letta.memoryRepository.url", MEMORY_REPOSITORY_PUSH_LOG = "memory-repository-push.log";
|
|
104626
104700
|
var init_memory_git = __esm(() => {
|
|
104627
104701
|
init_memory_constraints_audit();
|
|
104628
104702
|
init_memory_git_dir();
|
|
104703
|
+
init_memory_git_process();
|
|
104629
104704
|
init_memfs_git_proxy();
|
|
104630
104705
|
init_checkout_readiness();
|
|
104631
104706
|
init_debug();
|
|
@@ -104638,7 +104713,6 @@ var init_memory_git = __esm(() => {
|
|
|
104638
104713
|
init_memory_git_hooks();
|
|
104639
104714
|
init_memory_git_signing();
|
|
104640
104715
|
init_memory_git_windows_credentials();
|
|
104641
|
-
execFile3 = promisify4(execFileCb);
|
|
104642
104716
|
RETRYABLE_GIT_HTTP_ERROR_RE = /(?:\bHTTP\s+(?:503|520|521|522|523|524)\b|The requested URL returned error:\s*(?:503|520|521|522|523|524))/i;
|
|
104643
104717
|
RETRYABLE_GIT_NETWORK_ERROR_RE = /(remote end hung up unexpectedly|connection reset by peer|operation timed out|timed out|SIGTERM|ETIMEDOUT)/i;
|
|
104644
104718
|
MISSING_CWD_GIT_ERROR_RE = /(Unable to read current working directory: No such file or directory|\buv_cwd\b|\bcwd\b.*\bENOENT\b)/i;
|
|
@@ -104654,7 +104728,7 @@ __export(exports_personality_default_files, {
|
|
|
104654
104728
|
seedPersonalityDefaultMemoryFiles: () => seedPersonalityDefaultMemoryFiles,
|
|
104655
104729
|
getPersonalityAssetPath: () => getPersonalityAssetPath
|
|
104656
104730
|
});
|
|
104657
|
-
import { execFile as
|
|
104731
|
+
import { execFile as execFileCb } from "node:child_process";
|
|
104658
104732
|
import {
|
|
104659
104733
|
constants as constants2,
|
|
104660
104734
|
copyFileSync,
|
|
@@ -104664,7 +104738,7 @@ import {
|
|
|
104664
104738
|
} from "node:fs";
|
|
104665
104739
|
import { dirname as dirname9, isAbsolute as isAbsolute4, join as join15, relative } from "node:path";
|
|
104666
104740
|
import { fileURLToPath } from "node:url";
|
|
104667
|
-
import { promisify as
|
|
104741
|
+
import { promisify as promisify4 } from "node:util";
|
|
104668
104742
|
function getBundledPersonalityAssetsPath() {
|
|
104669
104743
|
const thisDir = dirname9(fileURLToPath(import.meta.url));
|
|
104670
104744
|
if (thisDir.replaceAll("\\", "/").endsWith("/src/agent")) {
|
|
@@ -104705,7 +104779,7 @@ function resolveMemoryPath(memoryDir, path8) {
|
|
|
104705
104779
|
}
|
|
104706
104780
|
async function hasMemoryFileHistory(memoryDir, relativePath) {
|
|
104707
104781
|
try {
|
|
104708
|
-
const { stdout } = await
|
|
104782
|
+
const { stdout } = await execFile3("git", ["log", "-1", "--format=%H", "--all", "--", relativePath], { cwd: memoryDir, timeout: 1e4 });
|
|
104709
104783
|
return stdout.trim().length > 0;
|
|
104710
104784
|
} catch {
|
|
104711
104785
|
return false;
|
|
@@ -104716,7 +104790,7 @@ async function discardUncommittedFile(memoryDir, relativePath, absolutePath) {
|
|
|
104716
104790
|
unlinkSync3(absolutePath);
|
|
104717
104791
|
} catch {}
|
|
104718
104792
|
try {
|
|
104719
|
-
await
|
|
104793
|
+
await execFile3("git", ["reset", "--quiet", "--", relativePath], {
|
|
104720
104794
|
cwd: memoryDir,
|
|
104721
104795
|
timeout: 1e4
|
|
104722
104796
|
});
|
|
@@ -104811,13 +104885,13 @@ async function seedPersonalityDefaultMemoryFilesBestEffort(params) {
|
|
|
104811
104885
|
};
|
|
104812
104886
|
}
|
|
104813
104887
|
}
|
|
104814
|
-
var
|
|
104888
|
+
var execFile3;
|
|
104815
104889
|
var init_personality_default_files = __esm(() => {
|
|
104816
104890
|
init_backend2();
|
|
104817
104891
|
init_debug();
|
|
104818
104892
|
init_memory_git();
|
|
104819
104893
|
init_personality_presets();
|
|
104820
|
-
|
|
104894
|
+
execFile3 = promisify4(execFileCb);
|
|
104821
104895
|
});
|
|
104822
104896
|
|
|
104823
104897
|
// src/backend/api/providers.ts
|
|
@@ -120370,10 +120444,10 @@ __export(exports_personality, {
|
|
|
120370
120444
|
buildCreateAgentOptionsForPersonality: () => buildCreateAgentOptionsForPersonality,
|
|
120371
120445
|
applyPersonalityToMemory: () => applyPersonalityToMemory
|
|
120372
120446
|
});
|
|
120373
|
-
import { execFile as
|
|
120447
|
+
import { execFile as execFileCb2 } from "node:child_process";
|
|
120374
120448
|
import { existsSync as existsSync17, mkdirSync as mkdirSync11, readFileSync as readFileSync10, writeFileSync as writeFileSync10 } from "node:fs";
|
|
120375
120449
|
import { dirname as dirname11, join as join24 } from "node:path";
|
|
120376
|
-
import { promisify as
|
|
120450
|
+
import { promisify as promisify5 } from "node:util";
|
|
120377
120451
|
function ensureTrailingNewline2(content) {
|
|
120378
120452
|
return `${content.trimEnd()}
|
|
120379
120453
|
`;
|
|
@@ -120532,7 +120606,7 @@ async function applyPersonalityToMemory(params) {
|
|
|
120532
120606
|
const isLocalMemfs = getBackend().capabilities.localMemfs;
|
|
120533
120607
|
const blockDefinitions = getPersonalityBlockDefinitions(params.personalityId, isLocalMemfs ? "local" : "cloud");
|
|
120534
120608
|
const repoDir = isLocalMemfs ? getScopedMemoryFilesystemRoot(params.agentId) : getMemoryRepoDir(params.agentId);
|
|
120535
|
-
const statusResult = await
|
|
120609
|
+
const statusResult = await execFile4("git", ["status", "--porcelain"], {
|
|
120536
120610
|
cwd: repoDir,
|
|
120537
120611
|
timeout: 1e4
|
|
120538
120612
|
});
|
|
@@ -120596,7 +120670,7 @@ async function applyPersonalityToMemory(params) {
|
|
|
120596
120670
|
commitMessage
|
|
120597
120671
|
};
|
|
120598
120672
|
}
|
|
120599
|
-
var
|
|
120673
|
+
var execFile4, PRIMARY_PERSONA_RELATIVE_PATH = "system/persona.md", LEGACY_PERSONA_RELATIVE_PATH = "memory/system/persona.md", PRIMARY_HUMAN_RELATIVE_PATH = "system/human.md", LEGACY_HUMAN_RELATIVE_PATH = "memory/system/human.md";
|
|
120600
120674
|
var init_personality = __esm(() => {
|
|
120601
120675
|
init_backend2();
|
|
120602
120676
|
init_server_url();
|
|
@@ -120605,7 +120679,7 @@ var init_personality = __esm(() => {
|
|
|
120605
120679
|
init_memory_filesystem2();
|
|
120606
120680
|
init_memory_git();
|
|
120607
120681
|
init_personality_presets();
|
|
120608
|
-
|
|
120682
|
+
execFile4 = promisify5(execFileCb2);
|
|
120609
120683
|
});
|
|
120610
120684
|
|
|
120611
120685
|
// src/browser-discovery-server.ts
|
|
@@ -157665,13 +157739,13 @@ var exports_image_resize_sips = {};
|
|
|
157665
157739
|
__export(exports_image_resize_sips, {
|
|
157666
157740
|
convertHeicToJpegWithSips: () => convertHeicToJpegWithSips
|
|
157667
157741
|
});
|
|
157668
|
-
import { execFile as
|
|
157742
|
+
import { execFile as execFile5 } from "node:child_process";
|
|
157669
157743
|
import { mkdtemp as mkdtemp2, readFile as readFile5, rm as rm2, writeFile as writeFile4 } from "node:fs/promises";
|
|
157670
157744
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
157671
157745
|
import { join as join27 } from "node:path";
|
|
157672
157746
|
function execFileAsync2(file, args) {
|
|
157673
157747
|
return new Promise((resolve11, reject2) => {
|
|
157674
|
-
|
|
157748
|
+
execFile5(file, args, (error4) => {
|
|
157675
157749
|
if (error4) {
|
|
157676
157750
|
reject2(error4);
|
|
157677
157751
|
return;
|
|
@@ -157705,7 +157779,7 @@ async function convertHeicToJpegWithSips(buffer) {
|
|
|
157705
157779
|
var init_image_resize_sips = () => {};
|
|
157706
157780
|
|
|
157707
157781
|
// src/utils/image-resize.ts
|
|
157708
|
-
import { spawn as
|
|
157782
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
157709
157783
|
import { existsSync as existsSync19 } from "node:fs";
|
|
157710
157784
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
157711
157785
|
function resolveImageWorkerPath() {
|
|
@@ -157722,7 +157796,7 @@ function resolveImageWorkerPath() {
|
|
|
157722
157796
|
function resizeWithSharpWorker(buffer, inputMediaType) {
|
|
157723
157797
|
return new Promise((resolve11, reject2) => {
|
|
157724
157798
|
const workerPath = resolveImageWorkerPath();
|
|
157725
|
-
const child =
|
|
157799
|
+
const child = spawn3(process.execPath, [workerPath, inputMediaType], {
|
|
157726
157800
|
shell: false,
|
|
157727
157801
|
stdio: ["pipe", "pipe", "pipe"],
|
|
157728
157802
|
windowsHide: true
|
|
@@ -159325,7 +159399,7 @@ function parsePositiveIntFlag(options) {
|
|
|
159325
159399
|
}
|
|
159326
159400
|
|
|
159327
159401
|
// src/cli/helpers/file-autocomplete.ts
|
|
159328
|
-
import { spawn as
|
|
159402
|
+
import { spawn as spawn4, spawnSync as spawnSync3 } from "node:child_process";
|
|
159329
159403
|
import {
|
|
159330
159404
|
chmodSync as chmodSync4,
|
|
159331
159405
|
createWriteStream as createWriteStream2,
|
|
@@ -159471,7 +159545,7 @@ async function walkDirectoryWithFd(baseDir, fdPath, query3, maxResults, signal)
|
|
|
159471
159545
|
resolve12([]);
|
|
159472
159546
|
return;
|
|
159473
159547
|
}
|
|
159474
|
-
const child =
|
|
159548
|
+
const child = spawn4(fdPath, args, {
|
|
159475
159549
|
stdio: ["ignore", "pipe", "pipe"]
|
|
159476
159550
|
});
|
|
159477
159551
|
let stdout = "";
|
|
@@ -163489,7 +163563,7 @@ __export(exports_auto_update, {
|
|
|
163489
163563
|
acquireUpdateLock: () => acquireUpdateLock
|
|
163490
163564
|
});
|
|
163491
163565
|
import {
|
|
163492
|
-
execFile as
|
|
163566
|
+
execFile as execFile6
|
|
163493
163567
|
} from "node:child_process";
|
|
163494
163568
|
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
163495
163569
|
import {
|
|
@@ -163509,7 +163583,7 @@ import {
|
|
|
163509
163583
|
import { readdir as readdir3, rm as rm3 } from "node:fs/promises";
|
|
163510
163584
|
import { homedir as homedir8 } from "node:os";
|
|
163511
163585
|
import { dirname as dirname12, join as join32 } from "node:path";
|
|
163512
|
-
import { promisify as
|
|
163586
|
+
import { promisify as promisify6 } from "node:util";
|
|
163513
163587
|
function debugLog2(...args) {
|
|
163514
163588
|
if (DEBUG) {
|
|
163515
163589
|
console.error("[auto-update]", ...args);
|
|
@@ -164041,7 +164115,7 @@ var init_auto_update = __esm(() => {
|
|
|
164041
164115
|
init_error_reporting();
|
|
164042
164116
|
init_process_liveness();
|
|
164043
164117
|
init_version();
|
|
164044
|
-
execFileAsync3 =
|
|
164118
|
+
execFileAsync3 = promisify6(execFile6);
|
|
164045
164119
|
DEBUG = process.env.LETTA_DEBUG_AUTOUPDATE === "1";
|
|
164046
164120
|
INSTALL_ARG_PREFIX = {
|
|
164047
164121
|
npm: ["install", "-g"],
|
|
@@ -164489,7 +164563,7 @@ var require_cross_spawn = __commonJS((exports, module3) => {
|
|
|
164489
164563
|
var cp3 = __require("child_process");
|
|
164490
164564
|
var parse4 = require_parse2();
|
|
164491
164565
|
var enoent = require_enoent();
|
|
164492
|
-
function
|
|
164566
|
+
function spawn5(command, args, options) {
|
|
164493
164567
|
const parsed = parse4(command, args, options);
|
|
164494
164568
|
const spawned = cp3.spawn(parsed.command, parsed.args, parsed.options);
|
|
164495
164569
|
enoent.hookChildProcess(spawned, parsed);
|
|
@@ -164501,8 +164575,8 @@ var require_cross_spawn = __commonJS((exports, module3) => {
|
|
|
164501
164575
|
result2.error = result2.error || enoent.verifyENOENTSync(result2.status, parsed);
|
|
164502
164576
|
return result2;
|
|
164503
164577
|
}
|
|
164504
|
-
module3.exports =
|
|
164505
|
-
module3.exports.spawn =
|
|
164578
|
+
module3.exports = spawn5;
|
|
164579
|
+
module3.exports.spawn = spawn5;
|
|
164506
164580
|
module3.exports.sync = spawnSync4;
|
|
164507
164581
|
module3.exports._parse = parse4;
|
|
164508
164582
|
module3.exports._enoent = enoent;
|
|
@@ -164510,13 +164584,13 @@ var require_cross_spawn = __commonJS((exports, module3) => {
|
|
|
164510
164584
|
|
|
164511
164585
|
// src/utils/package-manager-spawn.ts
|
|
164512
164586
|
import {
|
|
164513
|
-
spawn as
|
|
164587
|
+
spawn as spawn5
|
|
164514
164588
|
} from "node:child_process";
|
|
164515
164589
|
function isWindowsCommandShim(command) {
|
|
164516
164590
|
return /\.(?:cmd|bat)$/i.test(command);
|
|
164517
164591
|
}
|
|
164518
164592
|
function getPackageManagerProcessFactory({
|
|
164519
|
-
nativeSpawn =
|
|
164593
|
+
nativeSpawn = spawn5,
|
|
164520
164594
|
platform: platform4 = process.platform,
|
|
164521
164595
|
windowsSpawn = import_cross_spawn.default
|
|
164522
164596
|
} = {}) {
|
|
@@ -168979,7 +169053,7 @@ async function resolveSlackMessageFiles(params) {
|
|
|
168979
169053
|
oldest: params.messageTs,
|
|
168980
169054
|
latest: params.messageTs,
|
|
168981
169055
|
inclusive: true,
|
|
168982
|
-
limit:
|
|
169056
|
+
limit: 2
|
|
168983
169057
|
}));
|
|
168984
169058
|
const message2 = messages2.find((entry) => entry.ts === params.messageTs);
|
|
168985
169059
|
return message2 ? collectSlackFiles(message2) : null;
|
|
@@ -179295,7 +179369,7 @@ var init_runtime5 = __esm(() => {
|
|
|
179295
179369
|
});
|
|
179296
179370
|
|
|
179297
179371
|
// src/channels/signal/setup-runtime.ts
|
|
179298
|
-
import { execFileSync as execFileSync6, spawn as
|
|
179372
|
+
import { execFileSync as execFileSync6, spawn as spawn6 } from "node:child_process";
|
|
179299
179373
|
import { existsSync as existsSync28 } from "node:fs";
|
|
179300
179374
|
function getSignalDockerRunCommand() {
|
|
179301
179375
|
return [
|
|
@@ -179357,7 +179431,7 @@ function runNativeSignalCli(args) {
|
|
|
179357
179431
|
}
|
|
179358
179432
|
function runNativeSignalCliInteractive(args, onOutput) {
|
|
179359
179433
|
return new Promise((resolve13) => {
|
|
179360
|
-
const child =
|
|
179434
|
+
const child = spawn6("signal-cli", args, {
|
|
179361
179435
|
stdio: ["ignore", "pipe", "pipe"]
|
|
179362
179436
|
});
|
|
179363
179437
|
let output = "";
|
|
@@ -185691,9 +185765,9 @@ function defineLazyProperty(object3, propertyName, valueGetter) {
|
|
|
185691
185765
|
}
|
|
185692
185766
|
|
|
185693
185767
|
// node_modules/default-browser-id/index.js
|
|
185694
|
-
import { promisify as
|
|
185768
|
+
import { promisify as promisify7 } from "node:util";
|
|
185695
185769
|
import process15 from "node:process";
|
|
185696
|
-
import { execFile as
|
|
185770
|
+
import { execFile as execFile7 } from "node:child_process";
|
|
185697
185771
|
async function defaultBrowserId() {
|
|
185698
185772
|
if (process15.platform !== "darwin") {
|
|
185699
185773
|
throw new Error("macOS only");
|
|
@@ -185704,13 +185778,13 @@ async function defaultBrowserId() {
|
|
|
185704
185778
|
}
|
|
185705
185779
|
var execFileAsync4;
|
|
185706
185780
|
var init_default_browser_id = __esm(() => {
|
|
185707
|
-
execFileAsync4 =
|
|
185781
|
+
execFileAsync4 = promisify7(execFile7);
|
|
185708
185782
|
});
|
|
185709
185783
|
|
|
185710
185784
|
// node_modules/run-applescript/index.js
|
|
185711
185785
|
import process16 from "node:process";
|
|
185712
|
-
import { promisify as
|
|
185713
|
-
import { execFile as
|
|
185786
|
+
import { promisify as promisify8 } from "node:util";
|
|
185787
|
+
import { execFile as execFile8, execFileSync as execFileSync7 } from "node:child_process";
|
|
185714
185788
|
async function runAppleScript(script4, { humanReadableOutput = true, signal } = {}) {
|
|
185715
185789
|
if (process16.platform !== "darwin") {
|
|
185716
185790
|
throw new Error("macOS only");
|
|
@@ -185725,7 +185799,7 @@ async function runAppleScript(script4, { humanReadableOutput = true, signal } =
|
|
|
185725
185799
|
}
|
|
185726
185800
|
var execFileAsync5;
|
|
185727
185801
|
var init_run_applescript = __esm(() => {
|
|
185728
|
-
execFileAsync5 =
|
|
185802
|
+
execFileAsync5 = promisify8(execFile8);
|
|
185729
185803
|
});
|
|
185730
185804
|
|
|
185731
185805
|
// node_modules/bundle-name/index.js
|
|
@@ -185738,8 +185812,8 @@ var init_bundle_name = __esm(() => {
|
|
|
185738
185812
|
});
|
|
185739
185813
|
|
|
185740
185814
|
// node_modules/default-browser/windows.js
|
|
185741
|
-
import { promisify as
|
|
185742
|
-
import { execFile as
|
|
185815
|
+
import { promisify as promisify9 } from "node:util";
|
|
185816
|
+
import { execFile as execFile9 } from "node:child_process";
|
|
185743
185817
|
async function defaultBrowser(_execFileAsync = execFileAsync6) {
|
|
185744
185818
|
const { stdout } = await _execFileAsync("reg", [
|
|
185745
185819
|
"QUERY",
|
|
@@ -185760,7 +185834,7 @@ async function defaultBrowser(_execFileAsync = execFileAsync6) {
|
|
|
185760
185834
|
}
|
|
185761
185835
|
var execFileAsync6, windowsBrowserProgIds, UnknownBrowserError;
|
|
185762
185836
|
var init_windows = __esm(() => {
|
|
185763
|
-
execFileAsync6 =
|
|
185837
|
+
execFileAsync6 = promisify9(execFile9);
|
|
185764
185838
|
windowsBrowserProgIds = {
|
|
185765
185839
|
AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
|
|
185766
185840
|
MSEdgeDHTML: { name: "Edge", id: "com.microsoft.edge" },
|
|
@@ -185777,9 +185851,9 @@ var init_windows = __esm(() => {
|
|
|
185777
185851
|
});
|
|
185778
185852
|
|
|
185779
185853
|
// node_modules/default-browser/index.js
|
|
185780
|
-
import { promisify as
|
|
185854
|
+
import { promisify as promisify10 } from "node:util";
|
|
185781
185855
|
import process17 from "node:process";
|
|
185782
|
-
import { execFile as
|
|
185856
|
+
import { execFile as execFile10 } from "node:child_process";
|
|
185783
185857
|
async function defaultBrowser2() {
|
|
185784
185858
|
if (process17.platform === "darwin") {
|
|
185785
185859
|
const id2 = await defaultBrowserId();
|
|
@@ -185802,7 +185876,7 @@ var init_default_browser = __esm(() => {
|
|
|
185802
185876
|
init_default_browser_id();
|
|
185803
185877
|
init_bundle_name();
|
|
185804
185878
|
init_windows();
|
|
185805
|
-
execFileAsync7 =
|
|
185879
|
+
execFileAsync7 = promisify10(execFile10);
|
|
185806
185880
|
});
|
|
185807
185881
|
|
|
185808
185882
|
// node_modules/open/index.js
|
|
@@ -185816,14 +185890,14 @@ import process18 from "node:process";
|
|
|
185816
185890
|
import { Buffer as Buffer5 } from "node:buffer";
|
|
185817
185891
|
import path8 from "node:path";
|
|
185818
185892
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
185819
|
-
import { promisify as
|
|
185893
|
+
import { promisify as promisify11 } from "node:util";
|
|
185820
185894
|
import childProcess from "node:child_process";
|
|
185821
185895
|
import fs13, { constants as fsConstants2 } from "node:fs/promises";
|
|
185822
185896
|
async function getWindowsDefaultBrowserFromWsl() {
|
|
185823
185897
|
const powershellPath = await powerShellPath();
|
|
185824
185898
|
const rawCommand = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
|
|
185825
185899
|
const encodedCommand = Buffer5.from(rawCommand, "utf16le").toString("base64");
|
|
185826
|
-
const { stdout } = await
|
|
185900
|
+
const { stdout } = await execFile11(powershellPath, [
|
|
185827
185901
|
"-NoProfile",
|
|
185828
185902
|
"-NonInteractive",
|
|
185829
185903
|
"-ExecutionPolicy",
|
|
@@ -185859,7 +185933,7 @@ function detectPlatformBinary({ [platform4]: platformBinary }, { wsl }) {
|
|
|
185859
185933
|
}
|
|
185860
185934
|
return detectArchBinary(platformBinary);
|
|
185861
185935
|
}
|
|
185862
|
-
var
|
|
185936
|
+
var execFile11, __dirname2, localXdgOpenPath, platform4, arch2, pTryEach = async (array2, mapper) => {
|
|
185863
185937
|
let latestError;
|
|
185864
185938
|
for (const item of array2) {
|
|
185865
185939
|
try {
|
|
@@ -186038,7 +186112,7 @@ var init_open = __esm(() => {
|
|
|
186038
186112
|
init_wsl_utils();
|
|
186039
186113
|
init_default_browser();
|
|
186040
186114
|
init_is_inside_container();
|
|
186041
|
-
|
|
186115
|
+
execFile11 = promisify11(childProcess.execFile);
|
|
186042
186116
|
__dirname2 = path8.dirname(fileURLToPath3(import.meta.url));
|
|
186043
186117
|
localXdgOpenPath = path8.join(__dirname2, "xdg-open");
|
|
186044
186118
|
({ platform: platform4, arch: arch2 } = process18);
|
|
@@ -211476,7 +211550,7 @@ var init_mcp_client = __esm(() => {
|
|
|
211476
211550
|
init_streamableHttp();
|
|
211477
211551
|
DEFAULT_CLIENT_INFO = {
|
|
211478
211552
|
name: "letta-code",
|
|
211479
|
-
version: "0.34.
|
|
211553
|
+
version: "0.34.29"
|
|
211480
211554
|
};
|
|
211481
211555
|
});
|
|
211482
211556
|
|
|
@@ -214704,19 +214778,27 @@ function getProcessStart(pid, platform5 = process.platform, run = (executable, a
|
|
|
214704
214778
|
return null;
|
|
214705
214779
|
}
|
|
214706
214780
|
}
|
|
214707
|
-
function
|
|
214708
|
-
let
|
|
214709
|
-
|
|
214710
|
-
|
|
214711
|
-
if (
|
|
214712
|
-
|
|
214713
|
-
|
|
214714
|
-
|
|
214715
|
-
|
|
214716
|
-
|
|
214717
|
-
|
|
214781
|
+
function createCurrentDurableLockOwner(readStart = (timeoutMs) => getProcessStart(process.pid, process.platform, undefined, timeoutMs), now2 = () => performance.now()) {
|
|
214782
|
+
let cachedProcessStart;
|
|
214783
|
+
let retryAt = -Infinity;
|
|
214784
|
+
return (processStartTimeoutMs = PROCESS_START_PROBE_TIMEOUT_MS) => {
|
|
214785
|
+
if (cachedProcessStart === undefined && now2() >= retryAt) {
|
|
214786
|
+
const processStart = readStart(processStartTimeoutMs);
|
|
214787
|
+
if (processStart === null)
|
|
214788
|
+
retryAt = now2() + PROCESS_START_RETRY_DELAY_MS;
|
|
214789
|
+
else
|
|
214790
|
+
cachedProcessStart = processStart;
|
|
214791
|
+
}
|
|
214792
|
+
return {
|
|
214793
|
+
token: randomUUID30(),
|
|
214794
|
+
pid: process.pid,
|
|
214795
|
+
processStart: cachedProcessStart ?? null
|
|
214796
|
+
};
|
|
214718
214797
|
};
|
|
214719
214798
|
}
|
|
214799
|
+
function currentDurableLockOwner(processStartTimeoutMs = PROCESS_START_PROBE_TIMEOUT_MS) {
|
|
214800
|
+
return readCurrentDurableLockOwner(processStartTimeoutMs);
|
|
214801
|
+
}
|
|
214720
214802
|
function durableLockOwnerIsAlive(owner, readStart = getProcessStart, probe = (pid) => process.kill(pid, 0)) {
|
|
214721
214803
|
if (!Number.isSafeInteger(owner.pid) || owner.pid <= 0)
|
|
214722
214804
|
return false;
|
|
@@ -215132,8 +215214,10 @@ function acquireDurableFileLock(path12, options = {}) {
|
|
|
215132
215214
|
released = true;
|
|
215133
215215
|
};
|
|
215134
215216
|
}
|
|
215135
|
-
var MAX_OWNER_BYTES = 4096, WAIT_SLICE_MS = 5, PROCESS_START_PROBE_TIMEOUT_MS = 250, MAX_CANDIDATE_SWEEP = 128, INSTALLING_OWNER_NAME = ".installing",
|
|
215136
|
-
var init_durable_file_lock = () => {
|
|
215217
|
+
var MAX_OWNER_BYTES = 4096, WAIT_SLICE_MS = 5, PROCESS_START_PROBE_TIMEOUT_MS = 250, MAX_CANDIDATE_SWEEP = 128, INSTALLING_OWNER_NAME = ".installing", PROCESS_START_RETRY_DELAY_MS = 5000, readCurrentDurableLockOwner;
|
|
215218
|
+
var init_durable_file_lock = __esm(() => {
|
|
215219
|
+
readCurrentDurableLockOwner = createCurrentDurableLockOwner();
|
|
215220
|
+
});
|
|
215137
215221
|
|
|
215138
215222
|
// src/websocket/listener/interrupted-turn-input-ownership.ts
|
|
215139
215223
|
import { readdirSync as readdirSync10 } from "node:fs";
|
|
@@ -215530,7 +215614,7 @@ Important:
|
|
|
215530
215614
|
var init_Bash = () => {};
|
|
215531
215615
|
|
|
215532
215616
|
// src/tools/descriptions/CodeMode.md
|
|
215533
|
-
var CodeMode_default = "Run a JavaScript async function body that calls tools and returns only the results you need.\n\nCall built-in tools with `await tools.<name>(args)` and MCP tools with `await tools.mcp__server__tool(args)`; `listTools()` and `describeTool(name)` list tools and their schemas. Failed calls throw. `args` holds optional input, and `console.log()` output is captured.\n\nReturns `{ result, output }`. Like Bash, a script still running after a brief wait continues in the background and its result arrives as a task notification; `run_in_background: true` returns the task ID immediately. TaskStop aborts it.\n\nNested calls follow permission rules; calls that need approval fail, so call those tools directly. This is not a security sandbox.\n\nExample:\n\n const texts = await Promise.all(args.paths.map(file_path => tools.Read({ file_path })));\n return texts.map((text, i) => ({ path: args.paths[i], lines: text.split('\\n').length }));\n";
|
|
215617
|
+
var CodeMode_default = "Run a JavaScript async function body that calls tools and returns only the results you need.\n\nCall built-in and server-side tools with `await tools.<name>(args)` and MCP tools with `await tools.mcp__server__tool(args)`; `listTools()` and `describeTool(name)` list tools and their schemas. Failed calls throw. `args` holds optional input, `process.env` holds the variables a Bash command sees plus the agent's secrets, and `console.log()` output is captured.\n\nReturns `{ result, output }`. Like Bash, a script still running after a brief wait continues in the background and its result arrives as a task notification; `run_in_background: true` returns the task ID immediately. TaskStop aborts it.\n\nNested calls follow permission rules; calls that need approval fail, so call those tools directly. This is not a security sandbox.\n\nExample:\n\n const texts = await Promise.all(args.paths.map(file_path => tools.Read({ file_path })));\n return texts.map((text, i) => ({ path: args.paths[i], lines: text.split('\\n').length }));\n";
|
|
215534
215618
|
var init_CodeMode = () => {};
|
|
215535
215619
|
|
|
215536
215620
|
// src/tools/descriptions/Edit.md
|
|
@@ -215634,7 +215718,7 @@ Do not use this tool for root memory files (already loaded) or skills/ (use Skil
|
|
|
215634
215718
|
var init_Memory = () => {};
|
|
215635
215719
|
|
|
215636
215720
|
// src/tools/descriptions/Monitor.md
|
|
215637
|
-
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). In managed Cloud sandboxes, every monitor stops
|
|
215721
|
+
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). In managed Cloud sandboxes, every monitor stops at the per-sandbox cap configured by LETTA_MONITOR_MAX_TIMEOUT_MS (default 1 hour, clamped to 1 hour through 7 days), including persistent monitors; elsewhere persistent monitors run until TaskStop or session end. Call Monitor again to re-arm it if you still need to watch. For much longer Cloud waits, schedule a Wake or cron (which does not keep the sandbox running between turns) and combine it with shorter monitors. Use TaskStop to cancel early.\n\nWhen someone is waiting on the result, set `backup_after_seconds` (e.g. 900). If the monitor goes that long without an event, a durable Wake brings you back to check the real state, so a queued, hung, or dead watch can\'t leave them waiting in silence.\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\n**script source** — a JavaScript watch loop with the same globals as CodeMode, plus `emit(text)` (one event) and `sleep(ms)`. Returning or throwing ends the watch.\n';
|
|
215638
215722
|
var init_Monitor = () => {};
|
|
215639
215723
|
|
|
215640
215724
|
// src/tools/descriptions/Read.md
|
|
@@ -216156,7 +216240,7 @@ var init_Wake = () => {};
|
|
|
216156
216240
|
// src/tools/descriptions/WatchPR.md
|
|
216157
216241
|
var WatchPR_default = `Watch one open github.com pull request until it merges, closes, is stopped with TaskStop, or the session ends.
|
|
216158
216242
|
|
|
216159
|
-
In managed Cloud sandboxes, WatchPR also stops after
|
|
216243
|
+
In managed Cloud sandboxes, WatchPR also stops after the per-sandbox cap configured by LETTA_MONITOR_MAX_TIMEOUT_MS (default 1 hour, clamped to 1 hour through 7 days) and sends a timeout notification. Call WatchPR again to re-arm it if you still need to watch. For much longer waits, use Wake or cron (which does not keep the sandbox running between turns) and combine it with shorter watches. Local watches have no duration limit.
|
|
216160
216244
|
|
|
216161
216245
|
Use WatchPR instead of writing a Monitor or shell polling loop when you need ongoing notifications about a PR. Start at most one watch per PR. It reports:
|
|
216162
216246
|
|
|
@@ -216173,7 +216257,7 @@ Pass a URL ending at the PR number, such as \`https://github.com/owner/repo/pull
|
|
|
216173
216257
|
var init_WatchPR = () => {};
|
|
216174
216258
|
|
|
216175
216259
|
// src/tools/descriptions/Workflow.md
|
|
216176
|
-
var Workflow_default = "Execute a workflow script that orchestrates multiple subagents deterministically (loops, conditionals, fan-out) rather than model-driven.\n\nWorkflows run in the background: this tool returns immediately with a task ID, and a <task-notification> carrying the script's return value arrives when the workflow completes. Do not poll or sleep for it, and never fabricate the result before it arrives. TaskStop aborts the run. With `wait: true`, the workflow runs in the foreground instead and this tool returns the script's value directly.\n\nScripts that call `agent()` or `decide()` spend money on subagents and model calls. Run one only when the user explicitly asked for a workflow or multi-agent orchestration (\"use a workflow\", \"fan out agents\") or a skill's instructions call this tool; otherwise describe the workflow and ask first. For scripts that only call tools, use CodeMode instead.\n\nScripts can call tools directly: `await tools.<name>(args)` for this turn's built-in tools and `await tools.mcp__server__tool(args)` for the agent's MCP tools, subject to the user's permission rules. `await listTools()` returns `[{ name, description }]`; `await describeTool(name)` returns `{ name, description, inputSchema }`, or `undefined` for an unknown tool.\n\nScripts are plain JavaScript and must begin with `export const meta = {...}`, a pure literal (no variables, calls, or interpolation). Pass the work list via `args`. Prefer `pipeline()` so each item moves to its next stage as soon as it is ready. Await `agent()` calls: failures reject with the cause, `callIndex`, and `conversationId` when available. `parallel()` and `pipeline()` let siblings finish, then reject if any callback failed; a failed pipeline item skips its remaining stages. Catch errors explicitly inside callbacks for best-effort processing.\n\n export const meta = {\n name: 'review-files',\n description: 'Review each file for bugs, verify each finding',\n phases: [{ title: 'Review' }, { title: 'Verify' }],\n }\n const findings = {type: 'object', properties: {bugs: {type: 'array', items: {type: 'string'}}}, required: ['bugs']}\n const verdict = {type: 'object', properties: {real: {type: 'boolean'}}, required: ['real']}\n const results = await pipeline(\n args.files,\n f => agent(`Review ${f} for bugs.`, { phase: 'Review', schema: findings }),\n (review, f) => parallel(review.bugs.map(bug => () =>\n agent(`Is this a real bug in ${f}? ${bug}`, { phase: 'Verify', schema: verdict })\n .then(v => v.real ? { file: f, bug } : null))),\n )\n return results.flat().filter(Boolean)\n\nBefore authoring a script, load the `workflow-authoring` skill — the script API, pipeline-vs-barrier rules, quality patterns, worked examples, and how to diagnose a run.\n";
|
|
216260
|
+
var Workflow_default = "Execute a workflow script that orchestrates multiple subagents deterministically (loops, conditionals, fan-out) rather than model-driven.\n\nWorkflows run in the background: this tool returns immediately with a task ID, and a <task-notification> carrying the script's return value arrives when the workflow completes. Do not poll or sleep for it, and never fabricate the result before it arrives. TaskStop aborts the run. With `wait: true`, the workflow runs in the foreground instead and this tool returns the script's value directly.\n\nScripts that call `agent()` or `decide()` spend money on subagents and model calls. Run one only when the user explicitly asked for a workflow or multi-agent orchestration (\"use a workflow\", \"fan out agents\") or a skill's instructions call this tool; otherwise describe the workflow and ask first. For scripts that only call tools, use CodeMode instead.\n\nScripts can call tools directly: `await tools.<name>(args)` for this turn's built-in tools and `await tools.mcp__server__tool(args)` for the agent's MCP tools, subject to the user's permission rules. `await listTools()` returns `[{ name, description }]`; `await describeTool(name)` returns `{ name, description, inputSchema }`, or `undefined` for an unknown tool.\n\nScripts are plain JavaScript and must begin with `export const meta = {...}`, a pure literal (no variables, calls, or interpolation). Pass the work list via `args`. `process.env` holds the variables a Bash command sees plus the agent's secrets. Prefer `pipeline()` so each item moves to its next stage as soon as it is ready. Await `agent()` calls: failures reject with the cause, `callIndex`, and `conversationId` when available. `parallel()` and `pipeline()` let siblings finish, then reject if any callback failed; a failed pipeline item skips its remaining stages. Catch errors explicitly inside callbacks for best-effort processing.\n\n export const meta = {\n name: 'review-files',\n description: 'Review each file for bugs, verify each finding',\n phases: [{ title: 'Review' }, { title: 'Verify' }],\n }\n const findings = {type: 'object', properties: {bugs: {type: 'array', items: {type: 'string'}}}, required: ['bugs']}\n const verdict = {type: 'object', properties: {real: {type: 'boolean'}}, required: ['real']}\n const results = await pipeline(\n args.files,\n f => agent(`Review ${f} for bugs.`, { phase: 'Review', schema: findings }),\n (review, f) => parallel(review.bugs.map(bug => () =>\n agent(`Is this a real bug in ${f}? ${bug}`, { phase: 'Verify', schema: verdict })\n .then(v => v.real ? { file: f, bug } : null))),\n )\n return results.flat().filter(Boolean)\n\nBefore authoring a script, load the `workflow-authoring` skill — the script API, pipeline-vs-barrier rules, quality patterns, worked examples, and how to diagnose a run.\n";
|
|
216177
216261
|
var init_Workflow = () => {};
|
|
216178
216262
|
|
|
216179
216263
|
// src/tools/descriptions/Write.md
|
|
@@ -219263,7 +219347,7 @@ var init_github_pull_request_tracker = __esm(() => {
|
|
|
219263
219347
|
});
|
|
219264
219348
|
|
|
219265
219349
|
// src/tools/impl/shell-runner.ts
|
|
219266
|
-
import { spawn as
|
|
219350
|
+
import { spawn as spawn8 } from "node:child_process";
|
|
219267
219351
|
import { StringDecoder } from "node:string_decoder";
|
|
219268
219352
|
function buildSpawnError(err, executable, cwd2) {
|
|
219269
219353
|
let message = `Failed to execute command: ${err?.message || "unknown error"}`;
|
|
@@ -219317,7 +219401,7 @@ function killChildProcessTree(childProcess2, signal = "SIGTERM") {
|
|
|
219317
219401
|
return;
|
|
219318
219402
|
}
|
|
219319
219403
|
if (process.platform === "win32") {
|
|
219320
|
-
const taskkill =
|
|
219404
|
+
const taskkill = spawn8("taskkill.exe", ["/pid", String(childProcess2.pid), "/t", "/f"], {
|
|
219321
219405
|
stdio: "ignore",
|
|
219322
219406
|
windowsHide: true
|
|
219323
219407
|
});
|
|
@@ -219349,12 +219433,36 @@ function interruptChildProcessTree(childProcess2) {
|
|
|
219349
219433
|
}
|
|
219350
219434
|
killChildProcessTree(childProcess2, "SIGINT");
|
|
219351
219435
|
}
|
|
219436
|
+
function createPipeProcessKiller(childProcess2) {
|
|
219437
|
+
let exited = false;
|
|
219438
|
+
let forced = false;
|
|
219439
|
+
let drainTimer;
|
|
219440
|
+
childProcess2.once("close", () => clearTimeout(drainTimer));
|
|
219441
|
+
const closePipes = () => {
|
|
219442
|
+
if (!exited || !forced || drainTimer)
|
|
219443
|
+
return;
|
|
219444
|
+
drainTimer = setTimeout(() => {
|
|
219445
|
+
childProcess2.stdin?.destroy();
|
|
219446
|
+
childProcess2.stdout?.destroy();
|
|
219447
|
+
childProcess2.stderr?.destroy();
|
|
219448
|
+
}, 100);
|
|
219449
|
+
};
|
|
219450
|
+
childProcess2.once("exit", () => {
|
|
219451
|
+
exited = true;
|
|
219452
|
+
closePipes();
|
|
219453
|
+
});
|
|
219454
|
+
return (signal) => {
|
|
219455
|
+
forced ||= process.platform === "win32" || signal === "SIGKILL" || signal === 9;
|
|
219456
|
+
killChildProcessTree(childProcess2, signal);
|
|
219457
|
+
closePipes();
|
|
219458
|
+
};
|
|
219459
|
+
}
|
|
219352
219460
|
function spawnPipeProcess(launcher, options, events) {
|
|
219353
219461
|
const [executable, ...args] = launcher;
|
|
219354
219462
|
if (!executable) {
|
|
219355
219463
|
throw new ShellExecutionError("Executable is required");
|
|
219356
219464
|
}
|
|
219357
|
-
const childProcess2 =
|
|
219465
|
+
const childProcess2 = spawn8(executable, args, {
|
|
219358
219466
|
cwd: options.cwd,
|
|
219359
219467
|
env: options.env,
|
|
219360
219468
|
shell: false,
|
|
@@ -219370,9 +219478,7 @@ function spawnPipeProcess(launcher, options, events) {
|
|
|
219370
219478
|
childProcess2.on("error", events.error);
|
|
219371
219479
|
childProcess2.on("close", events.close);
|
|
219372
219480
|
return {
|
|
219373
|
-
kill(
|
|
219374
|
-
killChildProcessTree(childProcess2, signal);
|
|
219375
|
-
},
|
|
219481
|
+
kill: createPipeProcessKiller(childProcess2),
|
|
219376
219482
|
interrupt() {
|
|
219377
219483
|
interruptChildProcessTree(childProcess2);
|
|
219378
219484
|
},
|
|
@@ -219384,7 +219490,7 @@ function spawnPtyBridgeProcess(launcher, options, events) {
|
|
|
219384
219490
|
if (!executable) {
|
|
219385
219491
|
throw new ShellExecutionError("Executable is required");
|
|
219386
219492
|
}
|
|
219387
|
-
const childProcess2 =
|
|
219493
|
+
const childProcess2 = spawn8("node", [
|
|
219388
219494
|
"-e",
|
|
219389
219495
|
NODE_PTY_BRIDGE_SCRIPT,
|
|
219390
219496
|
JSON.stringify({ executable, args, cwd: options.cwd })
|
|
@@ -219404,9 +219510,7 @@ function spawnPtyBridgeProcess(launcher, options, events) {
|
|
|
219404
219510
|
childProcess2.on("error", events.error);
|
|
219405
219511
|
childProcess2.on("close", events.close);
|
|
219406
219512
|
return {
|
|
219407
|
-
kill(
|
|
219408
|
-
killChildProcessTree(childProcess2, signal);
|
|
219409
|
-
},
|
|
219513
|
+
kill: createPipeProcessKiller(childProcess2),
|
|
219410
219514
|
interrupt() {
|
|
219411
219515
|
interruptChildProcessTree(childProcess2);
|
|
219412
219516
|
},
|
|
@@ -222499,7 +222603,7 @@ var init_prompt_executor = __esm(() => {
|
|
|
222499
222603
|
});
|
|
222500
222604
|
|
|
222501
222605
|
// src/hooks/executor.ts
|
|
222502
|
-
import { spawn as
|
|
222606
|
+
import { spawn as spawn9 } from "node:child_process";
|
|
222503
222607
|
function truncateHookFeedback(text2, workingDirectory) {
|
|
222504
222608
|
return truncateByChars(scrubAmbientSecrets(text2), LIMITS.HOOK_OUTPUT_CHARS, "Hook", {
|
|
222505
222609
|
workingDirectory,
|
|
@@ -222532,7 +222636,7 @@ function trySpawnWithLauncher(launcher, workingDirectory, input) {
|
|
|
222532
222636
|
LETTA_WORKING_DIR: _lettaWorkingDir,
|
|
222533
222637
|
...parentEnv
|
|
222534
222638
|
} = process.env;
|
|
222535
|
-
return
|
|
222639
|
+
return spawn9(executable, args, {
|
|
222536
222640
|
cwd: workingDirectory,
|
|
222537
222641
|
env: {
|
|
222538
222642
|
...parentEnv,
|
|
@@ -224201,6 +224305,34 @@ var init_external_tool_background_eligibility = __esm(() => {
|
|
|
224201
224305
|
listenerRegistrations = new WeakMap;
|
|
224202
224306
|
});
|
|
224203
224307
|
|
|
224308
|
+
// src/tools/tool-context-retention.ts
|
|
224309
|
+
function retainToolContext(contextId) {
|
|
224310
|
+
holders.set(contextId, (holders.get(contextId) ?? 0) + 1);
|
|
224311
|
+
}
|
|
224312
|
+
function releaseRetainedToolContext(contextId) {
|
|
224313
|
+
const count = (holders.get(contextId) ?? 0) - 1;
|
|
224314
|
+
if (count > 0) {
|
|
224315
|
+
holders.set(contextId, count);
|
|
224316
|
+
return false;
|
|
224317
|
+
}
|
|
224318
|
+
holders.delete(contextId);
|
|
224319
|
+
return deferredReleases.delete(contextId);
|
|
224320
|
+
}
|
|
224321
|
+
function isToolContextRetained(contextId) {
|
|
224322
|
+
return holders.has(contextId);
|
|
224323
|
+
}
|
|
224324
|
+
function deferToolContextRelease(contextId) {
|
|
224325
|
+
if (!holders.has(contextId))
|
|
224326
|
+
return false;
|
|
224327
|
+
deferredReleases.add(contextId);
|
|
224328
|
+
return true;
|
|
224329
|
+
}
|
|
224330
|
+
var holders, deferredReleases;
|
|
224331
|
+
var init_tool_context_retention = __esm(() => {
|
|
224332
|
+
holders = new Map;
|
|
224333
|
+
deferredReleases = new Set;
|
|
224334
|
+
});
|
|
224335
|
+
|
|
224204
224336
|
// src/tools/external-tool-content.ts
|
|
224205
224337
|
function normalizeExternalToolResultContent(content) {
|
|
224206
224338
|
const normalized = content.flatMap((part) => {
|
|
@@ -231005,12 +231137,11 @@ function saveExecutionContext(snapshot) {
|
|
|
231005
231137
|
const contexts = getExecutionContexts();
|
|
231006
231138
|
const contextId = `ctx-${Date.now()}-${toolExecutionContextCounter++}`;
|
|
231007
231139
|
contexts.set(contextId, snapshot);
|
|
231008
|
-
const
|
|
231009
|
-
|
|
231010
|
-
|
|
231011
|
-
if (
|
|
231012
|
-
contexts.delete(
|
|
231013
|
-
}
|
|
231140
|
+
for (const id2 of contexts.keys()) {
|
|
231141
|
+
if (contexts.size <= 4096)
|
|
231142
|
+
break;
|
|
231143
|
+
if (!isToolContextRetained(id2))
|
|
231144
|
+
contexts.delete(id2);
|
|
231014
231145
|
}
|
|
231015
231146
|
return contextId;
|
|
231016
231147
|
}
|
|
@@ -231056,7 +231187,8 @@ function clearCapturedToolExecutionContexts() {
|
|
|
231056
231187
|
getExecutionContexts().clear();
|
|
231057
231188
|
}
|
|
231058
231189
|
function releaseToolExecutionContext(contextId) {
|
|
231059
|
-
|
|
231190
|
+
if (!deferToolContextRelease(contextId))
|
|
231191
|
+
getExecutionContexts().delete(contextId);
|
|
231060
231192
|
}
|
|
231061
231193
|
function acquireSwitchLock() {
|
|
231062
231194
|
const lock = getSwitchLock();
|
|
@@ -232208,6 +232340,7 @@ var init_manager2 = __esm(async () => {
|
|
|
232208
232340
|
init_telemetry();
|
|
232209
232341
|
init_external_tool_background();
|
|
232210
232342
|
init_external_tool_background_eligibility();
|
|
232343
|
+
init_tool_context_retention();
|
|
232211
232344
|
init_checkout_readiness();
|
|
232212
232345
|
init_debug();
|
|
232213
232346
|
init_secrets_store();
|
|
@@ -234219,6 +234352,51 @@ var init_mcp = __esm(() => {
|
|
|
234219
234352
|
|
|
234220
234353
|
// src/tools/script-tool-scope.ts
|
|
234221
234354
|
import { randomUUID as randomUUID33 } from "node:crypto";
|
|
234355
|
+
async function loadServerTools(agentId, builtins) {
|
|
234356
|
+
const tools = new Map;
|
|
234357
|
+
if (!agentId || !getBackend().capabilities.serverSideToolManagement) {
|
|
234358
|
+
return tools;
|
|
234359
|
+
}
|
|
234360
|
+
try {
|
|
234361
|
+
const agent = await (await getClient()).agents.retrieve(agentId, {
|
|
234362
|
+
include: ["agent.tools"]
|
|
234363
|
+
});
|
|
234364
|
+
const approvalRules = new Set((agent.tool_rules ?? []).filter((rule) => rule.type === "requires_approval").map((rule) => rule.tool_name));
|
|
234365
|
+
for (const tool of agent.tools ?? []) {
|
|
234366
|
+
const name = tool.name;
|
|
234367
|
+
if (!name || tool.tool_type === "external_mcp")
|
|
234368
|
+
continue;
|
|
234369
|
+
if (builtins.has(name) || SCRIPT_EXCLUDED_TOOLS.has(name))
|
|
234370
|
+
continue;
|
|
234371
|
+
tools.set(name, {
|
|
234372
|
+
name,
|
|
234373
|
+
description: tool.description ?? "",
|
|
234374
|
+
inputSchema: tool.json_schema?.parameters ?? {},
|
|
234375
|
+
requiresApproval: tool.default_requires_approval === true || approvalRules.has(name)
|
|
234376
|
+
});
|
|
234377
|
+
}
|
|
234378
|
+
} catch {}
|
|
234379
|
+
return tools;
|
|
234380
|
+
}
|
|
234381
|
+
async function callServerTool(agentId, tool, args, signal) {
|
|
234382
|
+
if (!agentId)
|
|
234383
|
+
throw new Error(`${tool.name} requires an invoking agent.`);
|
|
234384
|
+
if (tool.requiresApproval) {
|
|
234385
|
+
throw new Error(`${tool.name} needs approval, which a script cannot request; call it directly.`);
|
|
234386
|
+
}
|
|
234387
|
+
const result2 = await (await getClient()).agents.tools.run(tool.name, { agent_id: agentId, args }, signal ? { signal } : {});
|
|
234388
|
+
const value = result2.status === "success" ? result2.func_return : result2.stderr?.join(`
|
|
234389
|
+
`) ?? result2.func_return;
|
|
234390
|
+
return {
|
|
234391
|
+
content: [
|
|
234392
|
+
{
|
|
234393
|
+
type: "text",
|
|
234394
|
+
text: typeof value === "string" ? value : JSON.stringify(value ?? null)
|
|
234395
|
+
}
|
|
234396
|
+
],
|
|
234397
|
+
isError: result2.status !== "success"
|
|
234398
|
+
};
|
|
234399
|
+
}
|
|
234222
234400
|
function isOwningAgentId(value) {
|
|
234223
234401
|
return value?.startsWith("agent-") === true && !value.startsWith("agent-free:");
|
|
234224
234402
|
}
|
|
@@ -234245,8 +234423,9 @@ async function createScriptToolScope(parentAgentId, signal) {
|
|
|
234245
234423
|
const permissionCwd = getCurrentWorkingDirectory();
|
|
234246
234424
|
const context3 = toolContextId ? manager.getExecutionContextById(toolContextId) : undefined;
|
|
234247
234425
|
const builtinSchemas = (context3 ? serializeClientTools(context3.toolRegistry, context3.externalTools, context3.modTools, manager.getServerToolName) : []).filter((schema5) => !SCRIPT_EXCLUDED_TOOLS.has(schema5.name));
|
|
234248
|
-
const
|
|
234249
|
-
const
|
|
234426
|
+
const builtins = new Set(builtinSchemas.map((schema5) => schema5.name));
|
|
234427
|
+
const serverTools = await loadServerTools(parentAgentId, builtins);
|
|
234428
|
+
const builtinToolNames = [...builtins, ...serverTools.keys()];
|
|
234250
234429
|
let mcpSession;
|
|
234251
234430
|
const mcp = () => {
|
|
234252
234431
|
if (!parentAgentId)
|
|
@@ -234254,8 +234433,22 @@ async function createScriptToolScope(parentAgentId, signal) {
|
|
|
234254
234433
|
mcpSession ??= Promise.resolve().then(() => (init_mcp(), exports_mcp)).then((module3) => module3.createAgentMcpSession(parentAgentId));
|
|
234255
234434
|
return mcpSession;
|
|
234256
234435
|
};
|
|
234436
|
+
const { getShellEnv: getShellEnv2 } = await Promise.resolve().then(() => (init_shell_env(), exports_shell_env));
|
|
234437
|
+
const secrets2 = await Promise.resolve().then(() => (init_secrets_store(), exports_secrets_store));
|
|
234438
|
+
if (parentAgentId)
|
|
234439
|
+
await secrets2.ensureSecretsLoaded(parentAgentId).catch(() => {
|
|
234440
|
+
return;
|
|
234441
|
+
});
|
|
234442
|
+
const env6 = {};
|
|
234443
|
+
for (const [key2, value] of Object.entries(getShellEnv2())) {
|
|
234444
|
+
if (typeof value === "string")
|
|
234445
|
+
env6[key2] = value;
|
|
234446
|
+
}
|
|
234447
|
+
if (parentAgentId)
|
|
234448
|
+
Object.assign(env6, secrets2.loadSecrets(parentAgentId));
|
|
234257
234449
|
return {
|
|
234258
234450
|
builtinToolNames,
|
|
234451
|
+
env: env6,
|
|
234259
234452
|
listTools: async () => {
|
|
234260
234453
|
const mcpTools = parentAgentId ? await (await mcp()).listTools().catch(() => []) : [];
|
|
234261
234454
|
return [
|
|
@@ -234264,6 +234457,7 @@ async function createScriptToolScope(parentAgentId, signal) {
|
|
|
234264
234457
|
description: schema5.description,
|
|
234265
234458
|
inputSchema: schema5.parameters
|
|
234266
234459
|
})),
|
|
234460
|
+
...serverTools.values(),
|
|
234267
234461
|
...mcpTools.map((tool) => ({
|
|
234268
234462
|
name: tool.name,
|
|
234269
234463
|
description: tool.description ?? "",
|
|
@@ -234273,6 +234467,10 @@ async function createScriptToolScope(parentAgentId, signal) {
|
|
|
234273
234467
|
},
|
|
234274
234468
|
callTool: async (toolName2, toolArgs) => {
|
|
234275
234469
|
signal?.throwIfAborted();
|
|
234470
|
+
const serverTool = serverTools.get(toolName2);
|
|
234471
|
+
if (serverTool) {
|
|
234472
|
+
return callServerTool(parentAgentId, serverTool, toolArgs, signal);
|
|
234473
|
+
}
|
|
234276
234474
|
const toolCallId = `script-${randomUUID33()}`;
|
|
234277
234475
|
const { decision } = await manager.checkToolPermission(toolName2, toolArgs, permissionCwd, permissionModeState && { ...permissionModeState }, parentAgentId ?? undefined, toolContextId, toolCallId);
|
|
234278
234476
|
if (decision !== "allow") {
|
|
@@ -234303,12 +234501,14 @@ var SCRIPT_EXCLUDED_TOOLS;
|
|
|
234303
234501
|
var init_script_tool_scope = __esm(() => {
|
|
234304
234502
|
init_context();
|
|
234305
234503
|
init_backend2();
|
|
234504
|
+
init_client4();
|
|
234306
234505
|
init_runtime_context();
|
|
234307
234506
|
init_client_tool_serialization();
|
|
234308
234507
|
SCRIPT_EXCLUDED_TOOLS = new Set([
|
|
234309
234508
|
"AskUserQuestion",
|
|
234310
234509
|
"Workflow",
|
|
234311
|
-
"CodeMode"
|
|
234510
|
+
"CodeMode",
|
|
234511
|
+
"Monitor"
|
|
234312
234512
|
]);
|
|
234313
234513
|
});
|
|
234314
234514
|
|
|
@@ -234670,13 +234870,10 @@ async function executeWorkflow(spawner, options) {
|
|
|
234670
234870
|
return executeScript(spawner, options, meta2);
|
|
234671
234871
|
}
|
|
234672
234872
|
async function executeToolScript(options) {
|
|
234673
|
-
const run = await executeScript(undefined, options, {
|
|
234674
|
-
name: "code-mode",
|
|
234675
|
-
description: "Combine tools with JavaScript"
|
|
234676
|
-
});
|
|
234873
|
+
const run = await executeScript(undefined, options, { name: "code-mode", description: "Combine tools with JavaScript" }, options.globals);
|
|
234677
234874
|
return run.result;
|
|
234678
234875
|
}
|
|
234679
|
-
async function executeScript(spawner, options, meta2) {
|
|
234876
|
+
async function executeScript(spawner, options, meta2, extraGlobals) {
|
|
234680
234877
|
const signal = options.signal ?? new AbortController().signal;
|
|
234681
234878
|
let settled = false;
|
|
234682
234879
|
const emit = (event) => {
|
|
@@ -234952,7 +235149,9 @@ async function executeScript(spawner, options, meta2) {
|
|
|
234952
235149
|
describeTool,
|
|
234953
235150
|
...spawner ? { agent, decide, parallel, pipeline: pipeline7, phase, log: log3 } : {},
|
|
234954
235151
|
args: options.args,
|
|
234955
|
-
console: { log: log3, warn: log3, error: log3, info: log3 }
|
|
235152
|
+
console: { log: log3, warn: log3, error: log3, info: log3 },
|
|
235153
|
+
process: Object.freeze({ env: Object.freeze({ ...options.env }) }),
|
|
235154
|
+
...extraGlobals
|
|
234956
235155
|
});
|
|
234957
235156
|
const wrapped = `(async () => { "use strict";
|
|
234958
235157
|
${spawner ? stripMetaExport(options.script) : options.script}
|
|
@@ -236025,8 +236224,8 @@ var init_constants3 = __esm(() => {
|
|
|
236025
236224
|
});
|
|
236026
236225
|
|
|
236027
236226
|
// src/cli/helpers/git-context.ts
|
|
236028
|
-
import { execFile as
|
|
236029
|
-
import { promisify as
|
|
236227
|
+
import { execFile as execFile12, execFileSync as execFileSync10 } from "node:child_process";
|
|
236228
|
+
import { promisify as promisify12 } from "node:util";
|
|
236030
236229
|
function runGit2(args, cwd2) {
|
|
236031
236230
|
try {
|
|
236032
236231
|
return execFileSync10("git", args, {
|
|
@@ -236135,7 +236334,7 @@ async function getGitContextAsync(cwd2, options = {}) {
|
|
|
236135
236334
|
}
|
|
236136
236335
|
var execFileAsync8, GIT_ASYNC_TIMEOUT_MS = 1e4;
|
|
236137
236336
|
var init_git_context = __esm(() => {
|
|
236138
|
-
execFileAsync8 =
|
|
236337
|
+
execFileAsync8 = promisify12(execFile12);
|
|
236139
236338
|
});
|
|
236140
236339
|
|
|
236141
236340
|
// src/websocket/listener/device-git-context.ts
|
|
@@ -238959,9 +239158,9 @@ var init_exit_worktree = __esm(async () => {
|
|
|
238959
239158
|
});
|
|
238960
239159
|
|
|
238961
239160
|
// src/tools/impl/glob.ts
|
|
238962
|
-
import { execFile as
|
|
239161
|
+
import { execFile as execFile13 } from "node:child_process";
|
|
238963
239162
|
import * as path25 from "node:path";
|
|
238964
|
-
import { promisify as
|
|
239163
|
+
import { promisify as promisify13 } from "node:util";
|
|
238965
239164
|
function applyFileLimit(files, workingDirectory) {
|
|
238966
239165
|
const totalFiles = files.length;
|
|
238967
239166
|
if (totalFiles <= LIMITS.GLOB_MAX_FILES) {
|
|
@@ -239028,13 +239227,13 @@ var init_glob = __esm(() => {
|
|
|
239028
239227
|
init_runtime_context();
|
|
239029
239228
|
init_ripgrep_manager();
|
|
239030
239229
|
init_truncation();
|
|
239031
|
-
execFileAsync9 =
|
|
239230
|
+
execFileAsync9 = promisify13(execFile13);
|
|
239032
239231
|
});
|
|
239033
239232
|
|
|
239034
239233
|
// src/tools/impl/grep.ts
|
|
239035
|
-
import { execFile as
|
|
239234
|
+
import { execFile as execFile14 } from "node:child_process";
|
|
239036
239235
|
import * as path26 from "node:path";
|
|
239037
|
-
import { promisify as
|
|
239236
|
+
import { promisify as promisify14 } from "node:util";
|
|
239038
239237
|
function applyOffsetAndLimit(items3, offset, limit4) {
|
|
239039
239238
|
const sliced = items3.slice(offset);
|
|
239040
239239
|
if (limit4 > 0) {
|
|
@@ -239196,7 +239395,7 @@ var init_grep = __esm(() => {
|
|
|
239196
239395
|
init_runtime_context();
|
|
239197
239396
|
init_ripgrep_manager();
|
|
239198
239397
|
init_truncation();
|
|
239199
|
-
execFileAsync10 =
|
|
239398
|
+
execFileAsync10 = promisify14(execFile14);
|
|
239200
239399
|
});
|
|
239201
239400
|
|
|
239202
239401
|
// node_modules/picomatch/lib/constants.js
|
|
@@ -241570,11 +241769,243 @@ var init_monitor_event_stream = __esm(() => {
|
|
|
241570
241769
|
MONITOR_EVENT_BUFFER_CHARS = 1024 * 1024;
|
|
241571
241770
|
});
|
|
241572
241771
|
|
|
241772
|
+
// src/tools/impl/monitor-script.ts
|
|
241773
|
+
function rateLimitToolCalls(call2, signal) {
|
|
241774
|
+
let tokens = TOOL_CALL_BURST;
|
|
241775
|
+
let refilledAt = Date.now();
|
|
241776
|
+
return (toolName2, toolArgs) => {
|
|
241777
|
+
if (signal.aborted)
|
|
241778
|
+
return new Promise(() => {});
|
|
241779
|
+
const now2 = Date.now();
|
|
241780
|
+
const refill = Math.floor((now2 - refilledAt) / TOOL_CALL_REFILL_MS);
|
|
241781
|
+
if (refill > 0) {
|
|
241782
|
+
tokens = Math.min(TOOL_CALL_BURST, tokens + refill);
|
|
241783
|
+
refilledAt += refill * TOOL_CALL_REFILL_MS;
|
|
241784
|
+
}
|
|
241785
|
+
if (tokens === 0) {
|
|
241786
|
+
throw new Error(`Monitor script exceeded ${1000 / TOOL_CALL_REFILL_MS} tool calls per second; add sleep() between polls.`);
|
|
241787
|
+
}
|
|
241788
|
+
tokens -= 1;
|
|
241789
|
+
return call2(toolName2, toolArgs);
|
|
241790
|
+
};
|
|
241791
|
+
}
|
|
241792
|
+
function abortableSleep3(ms, signal) {
|
|
241793
|
+
const delay3 = Number(ms);
|
|
241794
|
+
if (!Number.isFinite(delay3) || delay3 < 0) {
|
|
241795
|
+
return Promise.reject(new Error("sleep(ms) needs a non-negative number."));
|
|
241796
|
+
}
|
|
241797
|
+
return new Promise((resolve34) => {
|
|
241798
|
+
if (signal.aborted)
|
|
241799
|
+
return;
|
|
241800
|
+
const onAbort = () => clearTimeout(timer);
|
|
241801
|
+
const timer = setTimeout(() => {
|
|
241802
|
+
signal.removeEventListener("abort", onAbort);
|
|
241803
|
+
resolve34();
|
|
241804
|
+
}, delay3);
|
|
241805
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
241806
|
+
});
|
|
241807
|
+
}
|
|
241808
|
+
function formatReturnValue(value) {
|
|
241809
|
+
if (value === undefined)
|
|
241810
|
+
return "The script returned without a value.";
|
|
241811
|
+
let text2;
|
|
241812
|
+
try {
|
|
241813
|
+
text2 = typeof value === "string" ? value : JSON.stringify(value);
|
|
241814
|
+
} catch (error5) {
|
|
241815
|
+
return `The script returned a value that is not JSON-serializable: ${String(error5)}`;
|
|
241816
|
+
}
|
|
241817
|
+
return text2.length <= MAX_RESULT_CHARS ? text2 : `${text2.slice(0, MAX_RESULT_CHARS)}
|
|
241818
|
+
[truncated; see the output file]`;
|
|
241819
|
+
}
|
|
241820
|
+
async function releaseToolContext(contextId) {
|
|
241821
|
+
if (!contextId || !releaseRetainedToolContext(contextId))
|
|
241822
|
+
return;
|
|
241823
|
+
const manager = await init_manager2().then(() => exports_manager);
|
|
241824
|
+
manager.releaseToolExecutionContext(contextId);
|
|
241825
|
+
}
|
|
241826
|
+
async function startScriptMonitor(args, hooks) {
|
|
241827
|
+
assertBackgroundProcessCapacity();
|
|
241828
|
+
const toolContextId = getRuntimeContext()?.toolContextId ?? null;
|
|
241829
|
+
if (toolContextId)
|
|
241830
|
+
retainToolContext(toolContextId);
|
|
241831
|
+
const controller = new AbortController;
|
|
241832
|
+
const parentAgentId = await resolveScriptParentAgentId(args).catch(async (error5) => {
|
|
241833
|
+
await releaseToolContext(toolContextId);
|
|
241834
|
+
throw error5;
|
|
241835
|
+
});
|
|
241836
|
+
const toolScope = await createScriptToolScope(parentAgentId, controller.signal).catch(async (error5) => {
|
|
241837
|
+
await releaseToolContext(toolContextId);
|
|
241838
|
+
throw error5;
|
|
241839
|
+
});
|
|
241840
|
+
const taskId = getNextMonitorId();
|
|
241841
|
+
const outputFile = createBackgroundOutputFile(taskId);
|
|
241842
|
+
const output = hooks.createOutput(outputFile);
|
|
241843
|
+
const scope = resolveNotificationScope(args.parentScope);
|
|
241844
|
+
const actingUserId = getRuntimeActingUserAttribution();
|
|
241845
|
+
const secrets2 = captureSecretRedactions(parentAgentId ?? undefined);
|
|
241846
|
+
const scrub = (text2) => scrubSecretsFromString(text2, secrets2);
|
|
241847
|
+
let timeout;
|
|
241848
|
+
const stop = (reason, note) => {
|
|
241849
|
+
if (processState.status !== "running")
|
|
241850
|
+
return;
|
|
241851
|
+
processState.completionNotificationSuppressed = true;
|
|
241852
|
+
if (note)
|
|
241853
|
+
output.append(note);
|
|
241854
|
+
hooks.markFinished(taskId, processState, "failed", null);
|
|
241855
|
+
controller.abort(new Error(reason));
|
|
241856
|
+
};
|
|
241857
|
+
const events = createMonitorEventStream({
|
|
241858
|
+
emit(event) {
|
|
241859
|
+
hooks.queueEvent({ taskId, event, scope, actingUserId, secrets: secrets2 });
|
|
241860
|
+
},
|
|
241861
|
+
stopSource() {
|
|
241862
|
+
stop("output rate too high", `
|
|
241863
|
+
[stopped: output rate too high]
|
|
241864
|
+
`);
|
|
241865
|
+
}
|
|
241866
|
+
});
|
|
241867
|
+
const firstLine = args.script.trim().split(`
|
|
241868
|
+
`)[0] ?? "";
|
|
241869
|
+
const processState = {
|
|
241870
|
+
process: {
|
|
241871
|
+
kill() {
|
|
241872
|
+
events.cancel();
|
|
241873
|
+
controller.abort(new Error("Monitor stopped via TaskStop"));
|
|
241874
|
+
}
|
|
241875
|
+
},
|
|
241876
|
+
command: `script: ${firstLine.slice(0, 80)}`,
|
|
241877
|
+
status: "running",
|
|
241878
|
+
exitCode: null,
|
|
241879
|
+
startTime: new Date,
|
|
241880
|
+
outputFile,
|
|
241881
|
+
runtimeScope: scope,
|
|
241882
|
+
actingUserId,
|
|
241883
|
+
kind: "monitor",
|
|
241884
|
+
description: args.description,
|
|
241885
|
+
monitorSource: "script",
|
|
241886
|
+
persistent: args.persistent,
|
|
241887
|
+
secrets: secrets2
|
|
241888
|
+
};
|
|
241889
|
+
backgroundProcesses.set(taskId, processState);
|
|
241890
|
+
notifyBackgroundProcessStateChanged(scope);
|
|
241891
|
+
const emit = (value) => {
|
|
241892
|
+
if (processState.status !== "running")
|
|
241893
|
+
return;
|
|
241894
|
+
const text2 = scrub(typeof value === "string" ? value : String(value));
|
|
241895
|
+
if (!text2.trim())
|
|
241896
|
+
return;
|
|
241897
|
+
const line = text2.endsWith(`
|
|
241898
|
+
`) ? text2 : `${text2}
|
|
241899
|
+
`;
|
|
241900
|
+
if (!output.append(line)) {
|
|
241901
|
+
stop("output file write failed");
|
|
241902
|
+
return;
|
|
241903
|
+
}
|
|
241904
|
+
events.onData(line);
|
|
241905
|
+
};
|
|
241906
|
+
const finish = (status, detail) => {
|
|
241907
|
+
events.finish();
|
|
241908
|
+
output.append(`
|
|
241909
|
+
[${status === "completed" ? "result" : "error"}] ${detail}
|
|
241910
|
+
`);
|
|
241911
|
+
if (processState.status !== "running")
|
|
241912
|
+
return;
|
|
241913
|
+
hooks.markFinished(taskId, processState, status, status === "completed" ? 0 : 1);
|
|
241914
|
+
const durationMs = Date.now() - (processState.startTime?.getTime() ?? 0);
|
|
241915
|
+
addToMessageQueue({
|
|
241916
|
+
kind: "task_notification",
|
|
241917
|
+
text: formatTaskNotification({
|
|
241918
|
+
taskId,
|
|
241919
|
+
status,
|
|
241920
|
+
summary: status === "completed" ? `Monitor "${args.description}" script returned` : `Monitor "${args.description}" script failed`,
|
|
241921
|
+
result: detail,
|
|
241922
|
+
outputFile,
|
|
241923
|
+
usage: { durationMs }
|
|
241924
|
+
}),
|
|
241925
|
+
...scope,
|
|
241926
|
+
...actingUserId !== undefined ? { actingUserId } : {}
|
|
241927
|
+
});
|
|
241928
|
+
};
|
|
241929
|
+
const stopped = new Promise((_resolve, reject2) => {
|
|
241930
|
+
controller.signal.addEventListener("abort", () => reject2(controller.signal.reason), { once: true });
|
|
241931
|
+
});
|
|
241932
|
+
const run = executeToolScript({
|
|
241933
|
+
...toolScope,
|
|
241934
|
+
callTool: rateLimitToolCalls(toolScope.callTool, controller.signal),
|
|
241935
|
+
maxTotalToolCalls: Number.POSITIVE_INFINITY,
|
|
241936
|
+
script: args.script,
|
|
241937
|
+
args: args.args,
|
|
241938
|
+
signal: new AbortController().signal,
|
|
241939
|
+
globals: {
|
|
241940
|
+
emit,
|
|
241941
|
+
sleep: (ms) => abortableSleep3(ms, controller.signal)
|
|
241942
|
+
},
|
|
241943
|
+
onProgress: (event) => {
|
|
241944
|
+
if (event.kind === "log")
|
|
241945
|
+
output.append(`${scrub(event.message)}
|
|
241946
|
+
`);
|
|
241947
|
+
}
|
|
241948
|
+
});
|
|
241949
|
+
run.catch(() => {});
|
|
241950
|
+
Promise.race([run, stopped]).then((value) => finish("completed", scrub(formatReturnValue(value))), (error5) => finish("failed", scrub(error5 instanceof Error ? error5.message : String(error5)))).finally(async () => {
|
|
241951
|
+
if (timeout)
|
|
241952
|
+
clearTimeout(timeout);
|
|
241953
|
+
await toolScope.cleanup();
|
|
241954
|
+
await releaseToolContext(toolContextId);
|
|
241955
|
+
});
|
|
241956
|
+
if (!args.persistent) {
|
|
241957
|
+
timeout = setTimeout(() => {
|
|
241958
|
+
if (processState.status !== "running")
|
|
241959
|
+
return;
|
|
241960
|
+
events.finish();
|
|
241961
|
+
hooks.queueEvent({
|
|
241962
|
+
taskId,
|
|
241963
|
+
event: hooks.timeoutEvent(args.timeout_ms),
|
|
241964
|
+
scope,
|
|
241965
|
+
actingUserId,
|
|
241966
|
+
secrets: secrets2
|
|
241967
|
+
});
|
|
241968
|
+
stop("timeout", `
|
|
241969
|
+
[timeout after ${args.timeout_ms}ms]
|
|
241970
|
+
`);
|
|
241971
|
+
}, args.timeout_ms);
|
|
241972
|
+
unrefTimer(timeout);
|
|
241973
|
+
}
|
|
241974
|
+
return { taskId, outputFile };
|
|
241975
|
+
}
|
|
241976
|
+
var TOOL_CALL_BURST = 120, TOOL_CALL_REFILL_MS = 500, MAX_RESULT_CHARS = 30000;
|
|
241977
|
+
var init_monitor_script = __esm(() => {
|
|
241978
|
+
init_runtime_context();
|
|
241979
|
+
init_script_tool_scope();
|
|
241980
|
+
init_secret_substitution();
|
|
241981
|
+
init_tool_context_retention();
|
|
241982
|
+
init_workflow_engine();
|
|
241983
|
+
init_message_queue_bridge();
|
|
241984
|
+
init_task_notifications();
|
|
241985
|
+
init_monitor_event_stream();
|
|
241986
|
+
init_process_manager();
|
|
241987
|
+
});
|
|
241988
|
+
|
|
241989
|
+
// src/tools/impl/monitor-timeout.ts
|
|
241990
|
+
function getMonitorMaxTimeoutMs() {
|
|
241991
|
+
const value = process.env.LETTA_MONITOR_MAX_TIMEOUT_MS;
|
|
241992
|
+
if (!value || !/^\d+$/.test(value))
|
|
241993
|
+
return DEFAULT_MAX_TIMEOUT_MS;
|
|
241994
|
+
const parsed = Number(value);
|
|
241995
|
+
if (!Number.isInteger(parsed) || parsed <= 0)
|
|
241996
|
+
return DEFAULT_MAX_TIMEOUT_MS;
|
|
241997
|
+
return Math.min(SEVEN_DAYS_MS, Math.max(DEFAULT_MAX_TIMEOUT_MS, parsed));
|
|
241998
|
+
}
|
|
241999
|
+
var DEFAULT_MAX_TIMEOUT_MS = 3600000, SEVEN_DAYS_MS;
|
|
242000
|
+
var init_monitor_timeout = __esm(() => {
|
|
242001
|
+
SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;
|
|
242002
|
+
});
|
|
242003
|
+
|
|
241573
242004
|
// src/tools/impl/monitor.ts
|
|
241574
242005
|
import { appendFileSync as appendFileSync7, readFileSync as readFileSync37, writeFileSync as writeFileSync28 } from "node:fs";
|
|
241575
242006
|
import { WebSocket as WebSocket4 } from "ws";
|
|
241576
|
-
function getMonitorTimeoutEvent(timeoutMs) {
|
|
241577
|
-
return isManagedCloudRuntime() && timeoutMs ===
|
|
242007
|
+
function getMonitorTimeoutEvent(timeoutMs, tool = "Monitor") {
|
|
242008
|
+
return isManagedCloudRuntime() && timeoutMs === getMonitorMaxTimeoutMs() ? `${tool} stopped at the ${timeoutMs / 3600000}-hour Cloud sandbox limit. If you still need to watch, simply re-arm it by calling ${tool} again. For much longer waits, schedule a Wake or cron, which does not keep the sandbox running between turns.` : "[Monitor timed out — re-arm if needed.]";
|
|
241578
242009
|
}
|
|
241579
242010
|
function buildMonitorResult(taskId, timeoutMs, persistent, outputFile) {
|
|
241580
242011
|
const lifetime = persistent ? "persistent — runs until TaskStop or session end" : `timeout ${timeoutMs}ms`;
|
|
@@ -241685,8 +242116,8 @@ function normalizeMonitorArgs(args) {
|
|
|
241685
242116
|
if (typeof normalized.description !== "string") {
|
|
241686
242117
|
throw new Error("Monitor description is required");
|
|
241687
242118
|
}
|
|
241688
|
-
if (typeof normalized.timeout_ms !== "number" || !Number.isFinite(normalized.timeout_ms) || normalized.timeout_ms < MIN_TIMEOUT_MS || !normalized.persistent && normalized.timeout_ms >
|
|
241689
|
-
throw new Error(`Monitor timeout_ms must be between ${MIN_TIMEOUT_MS} and ${
|
|
242119
|
+
if (typeof normalized.timeout_ms !== "number" || !Number.isFinite(normalized.timeout_ms) || normalized.timeout_ms < MIN_TIMEOUT_MS || !normalized.persistent && normalized.timeout_ms > getMonitorMaxTimeoutMs()) {
|
|
242120
|
+
throw new Error(`Monitor timeout_ms must be between ${MIN_TIMEOUT_MS} and ${getMonitorMaxTimeoutMs()}`);
|
|
241690
242121
|
}
|
|
241691
242122
|
if (typeof normalized.persistent !== "boolean") {
|
|
241692
242123
|
throw new Error("Monitor persistent must be a boolean");
|
|
@@ -241698,10 +242129,18 @@ function normalizeMonitorArgs(args) {
|
|
|
241698
242129
|
if (normalized.command !== undefined && typeof normalized.command !== "string") {
|
|
241699
242130
|
throw new Error("Monitor command must be a string");
|
|
241700
242131
|
}
|
|
242132
|
+
if (normalized.script !== undefined && typeof normalized.script !== "string") {
|
|
242133
|
+
throw new Error("Monitor script must be a string");
|
|
242134
|
+
}
|
|
242135
|
+
const hasScript = typeof normalized.script === "string" && normalized.script.trim() !== "";
|
|
241701
242136
|
const hasCommand = typeof normalized.command === "string" && normalized.command.length > 0;
|
|
241702
242137
|
const hasWebSocket = normalized.ws !== undefined && !(typeof normalized.ws === "object" && normalized.ws !== null && normalized.ws.url === "");
|
|
241703
|
-
if (Number(hasCommand) + Number(hasWebSocket) !== 1) {
|
|
241704
|
-
throw new Error("Monitor requires exactly one of command or
|
|
242138
|
+
if (Number(hasCommand) + Number(hasWebSocket) + Number(hasScript) !== 1) {
|
|
242139
|
+
throw new Error("Monitor requires exactly one of command, ws, or script");
|
|
242140
|
+
}
|
|
242141
|
+
if (!hasScript) {
|
|
242142
|
+
delete normalized.script;
|
|
242143
|
+
delete normalized.args;
|
|
241705
242144
|
}
|
|
241706
242145
|
if (!hasCommand) {
|
|
241707
242146
|
delete normalized.command;
|
|
@@ -241720,7 +242159,7 @@ function normalizeMonitorArgs(args) {
|
|
|
241720
242159
|
}
|
|
241721
242160
|
if (isManagedCloudRuntime() && normalized.persistent) {
|
|
241722
242161
|
normalized.persistent = false;
|
|
241723
|
-
normalized.timeout_ms =
|
|
242162
|
+
normalized.timeout_ms = getMonitorMaxTimeoutMs();
|
|
241724
242163
|
}
|
|
241725
242164
|
return normalized;
|
|
241726
242165
|
}
|
|
@@ -242152,6 +242591,22 @@ function startWebSocketMonitor(args) {
|
|
|
242152
242591
|
}
|
|
242153
242592
|
return buildMonitorResult(taskId, args.persistent ? 0 : args.timeout_ms, args.persistent, outputFile);
|
|
242154
242593
|
}
|
|
242594
|
+
async function startScriptSource(args) {
|
|
242595
|
+
const { taskId, outputFile } = await startScriptMonitor({
|
|
242596
|
+
description: args.description,
|
|
242597
|
+
script: args.script,
|
|
242598
|
+
args: args.args,
|
|
242599
|
+
timeout_ms: args.timeout_ms,
|
|
242600
|
+
persistent: args.persistent,
|
|
242601
|
+
parentScope: args.parentScope
|
|
242602
|
+
}, {
|
|
242603
|
+
createOutput: (path27) => new MonitorOutputWriter(path27),
|
|
242604
|
+
queueEvent: queueMonitorEvent,
|
|
242605
|
+
markFinished: markMonitorFinished,
|
|
242606
|
+
timeoutEvent: getMonitorTimeoutEvent
|
|
242607
|
+
});
|
|
242608
|
+
return buildMonitorResult(taskId, args.persistent ? 0 : args.timeout_ms, args.persistent, outputFile);
|
|
242609
|
+
}
|
|
242155
242610
|
function backupScopeFor(taskId) {
|
|
242156
242611
|
const processState = backgroundProcesses.get(taskId);
|
|
242157
242612
|
const runtimeScope = processState?.runtimeScope;
|
|
@@ -242163,7 +242618,7 @@ async function monitor(args) {
|
|
|
242163
242618
|
args.signal?.throwIfAborted();
|
|
242164
242619
|
const normalized = normalizeMonitorArgs(args);
|
|
242165
242620
|
installMonitorProcessExitCleanup();
|
|
242166
|
-
const result3 = normalized.command !== undefined ? startCommandMonitor(normalized) : startWebSocketMonitor(normalized);
|
|
242621
|
+
const result3 = normalized.script !== undefined ? await startScriptSource(normalized) : normalized.command !== undefined ? startCommandMonitor(normalized) : startWebSocketMonitor(normalized);
|
|
242167
242622
|
if (normalized.backup_after_seconds === undefined)
|
|
242168
242623
|
return result3;
|
|
242169
242624
|
const note = await armMonitorBackup({
|
|
@@ -242199,7 +242654,7 @@ function installMonitorProcessExitCleanup() {
|
|
|
242199
242654
|
monitorProcessExitCleanupInstalled = true;
|
|
242200
242655
|
process.once("exit", stopMonitorsForProcessExit);
|
|
242201
242656
|
}
|
|
242202
|
-
var MIN_TIMEOUT_MS = 1000,
|
|
242657
|
+
var MIN_TIMEOUT_MS = 1000, DEFAULT_TIMEOUT_MS3 = 300000, MONITOR_OUTPUT_FILE_BYTES, WEBSOCKET_MAX_PAYLOAD_BYTES, WEBSOCKET_PROTOCOL_PATTERN, monitorProcessExitCleanupInstalled = false;
|
|
242203
242658
|
var init_monitor = __esm(async () => {
|
|
242204
242659
|
init_strip_ansi();
|
|
242205
242660
|
init_runtime_context();
|
|
@@ -242207,6 +242662,8 @@ var init_monitor = __esm(async () => {
|
|
|
242207
242662
|
init_message_queue_bridge();
|
|
242208
242663
|
init_task_notifications();
|
|
242209
242664
|
init_monitor_event_stream();
|
|
242665
|
+
init_monitor_script();
|
|
242666
|
+
init_monitor_timeout();
|
|
242210
242667
|
init_process_manager();
|
|
242211
242668
|
init_shell_env();
|
|
242212
242669
|
init_shell_launchers();
|
|
@@ -242702,9 +243159,9 @@ var init_typescript = __esm(() => {
|
|
|
242702
243159
|
throw new Error("LSP auto-download is disabled. Please install typescript-language-server manually: npm install -g typescript-language-server typescript");
|
|
242703
243160
|
}
|
|
242704
243161
|
console.log("[LSP] Installing typescript-language-server and typescript...");
|
|
242705
|
-
const { spawn:
|
|
243162
|
+
const { spawn: spawn10 } = await import("node:child_process");
|
|
242706
243163
|
return new Promise((resolve34, reject2) => {
|
|
242707
|
-
const proc =
|
|
243164
|
+
const proc = spawn10("npm", ["install", "-g", "typescript-language-server", "typescript"], {
|
|
242708
243165
|
stdio: "inherit"
|
|
242709
243166
|
});
|
|
242710
243167
|
proc.on("exit", (code2) => {
|
|
@@ -242777,7 +243234,7 @@ class LSPManager {
|
|
|
242777
243234
|
return existing.client;
|
|
242778
243235
|
}
|
|
242779
243236
|
try {
|
|
242780
|
-
const { spawn:
|
|
243237
|
+
const { spawn: spawn10 } = await import("node:child_process");
|
|
242781
243238
|
const rootUri = process.cwd();
|
|
242782
243239
|
if (serverDef.autoInstall) {
|
|
242783
243240
|
const isAvailable = await serverDef.autoInstall.check();
|
|
@@ -242791,7 +243248,7 @@ class LSPManager {
|
|
|
242791
243248
|
console.error(`[LSP] ${serverDef.id} has no command configured`);
|
|
242792
243249
|
return null;
|
|
242793
243250
|
}
|
|
242794
|
-
const proc =
|
|
243251
|
+
const proc = spawn10(command, serverDef.command.slice(1), {
|
|
242795
243252
|
cwd: rootUri,
|
|
242796
243253
|
env: {
|
|
242797
243254
|
...process.env,
|
|
@@ -243312,7 +243769,7 @@ async function resolveAgentMessageDestination(input, backend3, signal) {
|
|
|
243312
243769
|
var init_agent_message = () => {};
|
|
243313
243770
|
|
|
243314
243771
|
// src/agent/subagents/subagent-process.ts
|
|
243315
|
-
import { spawn as
|
|
243772
|
+
import { spawn as spawn10 } from "node:child_process";
|
|
243316
243773
|
function signalProcessGroup(childProcess2, signal) {
|
|
243317
243774
|
if (!childProcess2.pid)
|
|
243318
243775
|
return;
|
|
@@ -243345,7 +243802,7 @@ async function killWindowsProcessTree(childProcess2) {
|
|
|
243345
243802
|
if (!childProcess2.pid)
|
|
243346
243803
|
return;
|
|
243347
243804
|
await new Promise((resolve35) => {
|
|
243348
|
-
const taskkill =
|
|
243805
|
+
const taskkill = spawn10("taskkill.exe", ["/pid", String(childProcess2.pid), "/t", "/f"], { stdio: "ignore", windowsHide: true });
|
|
243349
243806
|
let settled = false;
|
|
243350
243807
|
const finish = (succeeded) => {
|
|
243351
243808
|
if (settled)
|
|
@@ -243377,7 +243834,7 @@ async function terminateSubagentProcessTree(childProcess2, forceKillGraceMs) {
|
|
|
243377
243834
|
await waitForProcessGroupExit(pid, FORCE_KILL_SETTLE_MS);
|
|
243378
243835
|
}
|
|
243379
243836
|
function spawnSubagentProcess(command, args, options) {
|
|
243380
|
-
const childProcess2 =
|
|
243837
|
+
const childProcess2 = spawn10(command, args, {
|
|
243381
243838
|
cwd: options.cwd,
|
|
243382
243839
|
env: options.env,
|
|
243383
243840
|
detached: process.platform !== "win32"
|
|
@@ -244042,7 +244499,7 @@ class CodexAppServerClient {
|
|
|
244042
244499
|
await this.request("initialize", {
|
|
244043
244500
|
clientInfo: {
|
|
244044
244501
|
name: "letta-code",
|
|
244045
|
-
version: "0.34.
|
|
244502
|
+
version: "0.34.29"
|
|
244046
244503
|
},
|
|
244047
244504
|
capabilities: null
|
|
244048
244505
|
});
|
|
@@ -249565,11 +250022,11 @@ var init_manager4 = __esm(async () => {
|
|
|
249565
250022
|
});
|
|
249566
250023
|
|
|
249567
250024
|
// src/agent/memory-conflict-repair.ts
|
|
249568
|
-
import { execFile as
|
|
250025
|
+
import { execFile as execFile15 } from "node:child_process";
|
|
249569
250026
|
import { randomUUID as randomUUID42 } from "node:crypto";
|
|
249570
250027
|
import { readFile as readFile16, rm as rm9, writeFile as writeFile13 } from "node:fs/promises";
|
|
249571
250028
|
import { join as join68 } from "node:path";
|
|
249572
|
-
import { promisify as
|
|
250029
|
+
import { promisify as promisify15 } from "node:util";
|
|
249573
250030
|
async function readOptional(path29) {
|
|
249574
250031
|
try {
|
|
249575
250032
|
return (await readFile16(path29, "utf8")).trim();
|
|
@@ -249580,7 +250037,7 @@ async function readOptional(path29) {
|
|
|
249580
250037
|
async function describeMemoryConflict(memoryDir, gitDir) {
|
|
249581
250038
|
let head4 = "";
|
|
249582
250039
|
try {
|
|
249583
|
-
const { stdout } = await
|
|
250040
|
+
const { stdout } = await promisify15(execFile15)("git", [
|
|
249584
250041
|
"-C",
|
|
249585
250042
|
memoryDir,
|
|
249586
250043
|
"rev-parse",
|
|
@@ -249595,7 +250052,7 @@ async function describeMemoryConflict(memoryDir, gitDir) {
|
|
|
249595
250052
|
}
|
|
249596
250053
|
async function describeInvalidMemoryHistory(memoryDir) {
|
|
249597
250054
|
try {
|
|
249598
|
-
const { stdout } = await
|
|
250055
|
+
const { stdout } = await promisify15(execFile15)("git", [
|
|
249599
250056
|
"-C",
|
|
249600
250057
|
memoryDir,
|
|
249601
250058
|
"rev-parse",
|
|
@@ -249939,7 +250396,7 @@ ${result3.report}
|
|
|
249939
250396
|
});
|
|
249940
250397
|
return { execution, unsubscribe };
|
|
249941
250398
|
}
|
|
249942
|
-
async function ensureMemoryRepair(params,
|
|
250399
|
+
async function ensureMemoryRepair(params, spawn11, claimRepair = claimMemoryConflictRepair) {
|
|
249943
250400
|
let claim;
|
|
249944
250401
|
try {
|
|
249945
250402
|
const kind = params.result.status === "invalid" ? "invalid" : "conflict";
|
|
@@ -249947,7 +250404,7 @@ async function ensureMemoryRepair(params, spawn10, claimRepair = claimMemoryConf
|
|
|
249947
250404
|
if (claim.status !== "claimed")
|
|
249948
250405
|
return claim.status === "in_progress";
|
|
249949
250406
|
const invalid2 = params.result.status === "invalid";
|
|
249950
|
-
|
|
250407
|
+
spawn11({
|
|
249951
250408
|
subagentType: "memory",
|
|
249952
250409
|
description: invalid2 ? "Repair invalid committed memory" : "Repair memory Git conflict",
|
|
249953
250410
|
prompt: invalid2 ? `The committed memory tree fails the repository's validation, usually because concurrent memory updates were combined. Make one new commit that brings the current memory within the limits while preserving its information: move detail out of oversized files and behind indexes instead of deleting it. Do not change or disable the limits, rewrite history, or perform unrelated edits. If the committed memory already passes validation, stop.
|
|
@@ -252633,8 +253090,8 @@ query($id: ID!, $before: String) {
|
|
|
252633
253090
|
}`;
|
|
252634
253091
|
|
|
252635
253092
|
// src/tools/impl/github-pull-request-watch.ts
|
|
252636
|
-
import { execFile as
|
|
252637
|
-
import { promisify as
|
|
253093
|
+
import { execFile as execFile16 } from "node:child_process";
|
|
253094
|
+
import { promisify as promisify16 } from "node:util";
|
|
252638
253095
|
function authorLogin(author) {
|
|
252639
253096
|
return author?.login || "unknown";
|
|
252640
253097
|
}
|
|
@@ -253163,7 +253620,7 @@ async function fetchGitHubPullRequestSnapshot(ref5, options) {
|
|
|
253163
253620
|
}
|
|
253164
253621
|
var execFileAsync11, MAX_CONSISTENCY_READ_ATTEMPTS = 3, PullRequestChangedDuringReadError;
|
|
253165
253622
|
var init_github_pull_request_watch = __esm(() => {
|
|
253166
|
-
execFileAsync11 =
|
|
253623
|
+
execFileAsync11 = promisify16(execFile16);
|
|
253167
253624
|
PullRequestChangedDuringReadError = class PullRequestChangedDuringReadError extends Error {
|
|
253168
253625
|
};
|
|
253169
253626
|
});
|
|
@@ -253217,6 +253674,7 @@ ${describeGitHubPullRequestSnapshot(initial2)}
|
|
|
253217
253674
|
const secrets2 = {};
|
|
253218
253675
|
let processState;
|
|
253219
253676
|
const persistent = !isManagedCloudRuntime();
|
|
253677
|
+
const maxTimeoutMs = getMonitorMaxTimeoutMs();
|
|
253220
253678
|
let timeout;
|
|
253221
253679
|
const events = createMonitorEventStream({
|
|
253222
253680
|
emit(event) {
|
|
@@ -253283,7 +253741,7 @@ ${describeGitHubPullRequestSnapshot(initial2)}
|
|
|
253283
253741
|
events.finish();
|
|
253284
253742
|
if (processState.status !== "running")
|
|
253285
253743
|
return;
|
|
253286
|
-
const event = getMonitorTimeoutEvent(
|
|
253744
|
+
const event = getMonitorTimeoutEvent(maxTimeoutMs, "WatchPR");
|
|
253287
253745
|
output.append(`
|
|
253288
253746
|
${event}
|
|
253289
253747
|
`);
|
|
@@ -253291,7 +253749,7 @@ ${event}
|
|
|
253291
253749
|
processState.completionNotificationSuppressed = true;
|
|
253292
253750
|
markMonitorFinished(taskId, processState, "failed", null);
|
|
253293
253751
|
processState.process.kill();
|
|
253294
|
-
},
|
|
253752
|
+
}, maxTimeoutMs);
|
|
253295
253753
|
unrefTimer(timeout);
|
|
253296
253754
|
}
|
|
253297
253755
|
const wait = deps.wait ?? defaultWait;
|
|
@@ -253362,7 +253820,7 @@ ${event}
|
|
|
253362
253820
|
content: [
|
|
253363
253821
|
{
|
|
253364
253822
|
type: "text",
|
|
253365
|
-
text: `WatchPR started (task ${taskId}). It will keep watching after CI finishes and report new failures, reviews, comments, conflicts, head changes, merge-state changes, and watcher errors. It stops when the PR merges/closes, on TaskStop, or when this session ends.${persistent ? "" :
|
|
253823
|
+
text: `WatchPR started (task ${taskId}). It will keep watching after CI finishes and report new failures, reviews, comments, conflicts, head changes, merge-state changes, and watcher errors. It stops when the PR merges/closes, on TaskStop, or when this session ends.${persistent ? "" : ` A hard ${maxTimeoutMs / 3600000}-hour limit applies in this Cloud sandbox; call WatchPR again to re-arm it, or use Wake or cron for much longer waits.`}
|
|
253366
253824
|
|
|
253367
253825
|
Current state:
|
|
253368
253826
|
${describeGitHubPullRequestSnapshot(initial2)}
|
|
@@ -253384,6 +253842,7 @@ var init_watch_pr = __esm(async () => {
|
|
|
253384
253842
|
init_github_pull_request_diff();
|
|
253385
253843
|
init_github_pull_request_watch();
|
|
253386
253844
|
init_monitor_event_stream();
|
|
253845
|
+
init_monitor_timeout();
|
|
253387
253846
|
init_process_manager();
|
|
253388
253847
|
await init_monitor();
|
|
253389
253848
|
WATCH_MAX_POLL_MS = 5 * 60000;
|
|
@@ -254049,7 +254508,8 @@ function toolOptions(handle2) {
|
|
|
254049
254508
|
return {
|
|
254050
254509
|
...handle2.callTool ? { callTool: handle2.callTool } : {},
|
|
254051
254510
|
...handle2.builtinToolNames ? { builtinToolNames: handle2.builtinToolNames } : {},
|
|
254052
|
-
...handle2.listTools ? { listTools: handle2.listTools } : {}
|
|
254511
|
+
...handle2.listTools ? { listTools: handle2.listTools } : {},
|
|
254512
|
+
...handle2.env ? { env: handle2.env } : {}
|
|
254053
254513
|
};
|
|
254054
254514
|
}
|
|
254055
254515
|
function formatWorkflowProgressLine(event) {
|
|
@@ -254853,12 +255313,12 @@ var init_Monitor2 = __esm(() => {
|
|
|
254853
255313
|
type: "number",
|
|
254854
255314
|
minimum: 1000,
|
|
254855
255315
|
default: 300000,
|
|
254856
|
-
description: "Kill the monitor after this deadline. Default 300000ms,
|
|
255316
|
+
description: "Kill the monitor after this deadline. Default 300000ms. Maximum is LETTA_MONITOR_MAX_TIMEOUT_MS (default 3600000ms, clamped to 1 hour through 7 days). Ignored when persistent is true."
|
|
254857
255317
|
},
|
|
254858
255318
|
persistent: {
|
|
254859
255319
|
type: "boolean",
|
|
254860
255320
|
default: false,
|
|
254861
|
-
description: "Run until TaskStop or session end. In managed Cloud sandboxes,
|
|
255321
|
+
description: "Run until TaskStop or session end. In managed Cloud sandboxes, the configured monitor cap still applies (default 1 hour); elsewhere there is no timeout. Call Monitor again to re-arm it. For much longer waits in Cloud, use Wake/cron."
|
|
254862
255322
|
},
|
|
254863
255323
|
backup_after_seconds: {
|
|
254864
255324
|
type: "integer",
|
|
@@ -254891,7 +255351,14 @@ var init_Monitor2 = __esm(() => {
|
|
|
254891
255351
|
},
|
|
254892
255352
|
required: ["url"],
|
|
254893
255353
|
additionalProperties: false,
|
|
254894
|
-
description: "WebSocket to open. Each text frame is an event; binary frames are reported as a placeholder line. Socket close ends the watch. Cannot be combined with command."
|
|
255354
|
+
description: "WebSocket to open. Each text frame is an event; binary frames are reported as a placeholder line. Socket close ends the watch. Cannot be combined with command or script."
|
|
255355
|
+
},
|
|
255356
|
+
script: {
|
|
255357
|
+
type: "string",
|
|
255358
|
+
description: "JavaScript watch loop with CodeMode's globals plus emit(text) and sleep(ms). Cannot be combined with command or ws."
|
|
255359
|
+
},
|
|
255360
|
+
args: {
|
|
255361
|
+
description: "Optional input exposed to script as args."
|
|
254895
255362
|
}
|
|
254896
255363
|
},
|
|
254897
255364
|
required: ["description"],
|
|
@@ -260680,19 +261147,6 @@ function getDequeuedClientMessageIds(runtime, batch) {
|
|
|
260680
261147
|
function shouldQueueInboundMessage(parsed) {
|
|
260681
261148
|
return parsed.messages.some((payload) => ("content" in payload));
|
|
260682
261149
|
}
|
|
260683
|
-
function shouldProcessInboundMessageDirectly(runtime, parsed) {
|
|
260684
|
-
if (!shouldQueueInboundMessage(parsed)) {
|
|
260685
|
-
return false;
|
|
260686
|
-
}
|
|
260687
|
-
if (runtime.queueRuntime.length > 0 || runtime.queuePumpActive || runtime.queuePumpScheduled || runtime.pendingTurns > 0 || runtime.queuedMessagesByItemId.size > 0 || runtime.turnLifecycle.kind !== "idle" || runtime.pendingApprovalResolvers.size > 0 || runtime.pendingApprovalBatchByToolCallId.size > 0 || runtime.recoveredApprovalState !== null || runtime.pendingInterruptedResults !== null || runtime.pendingInterruptedContext !== null || (runtime.pendingInterruptedToolCallIds?.length ?? 0) > 0) {
|
|
260688
|
-
return false;
|
|
260689
|
-
}
|
|
260690
|
-
const activeScope = resolveRuntimeScope(runtime.listener, {
|
|
260691
|
-
agent_id: runtime.agentId,
|
|
260692
|
-
conversation_id: runtime.conversationId
|
|
260693
|
-
});
|
|
260694
|
-
return getListenerBlockedReason(runtime.turnLifecycle.snapshot(), activeScope ? getPendingControlRequestCount(runtime.listener, activeScope) : 0) === null;
|
|
260695
|
-
}
|
|
260696
261150
|
function consumeQueuedTurn(runtime) {
|
|
260697
261151
|
const queuedItems = runtime.queueRuntime.peekReady();
|
|
260698
261152
|
const firstQueuedItem = queuedItems[0];
|
|
@@ -260838,6 +261292,10 @@ function emitQueuePumpBoundary(operation) {
|
|
|
260838
261292
|
}
|
|
260839
261293
|
}
|
|
260840
261294
|
function resolveQueuePumpTransport(runtime, socket) {
|
|
261295
|
+
const first = runtime.queueRuntime.peekReady()[0];
|
|
261296
|
+
if (first?.kind === "message" && first.noCoalesce === true && runtime.queuedMessagesByItemId.get(first.id)?.processOwnedTurn === true) {
|
|
261297
|
+
return getOrCreateProcessTransport(runtime.listener);
|
|
261298
|
+
}
|
|
260841
261299
|
if (runtime.listener.connections.size > 0 || runtime.listener.processTransport !== null) {
|
|
260842
261300
|
const transport3 = getOrCreateProcessTransport(runtime.listener);
|
|
260843
261301
|
if (!isListenerTransportOpen(transport3))
|
|
@@ -265226,7 +265684,7 @@ var init_listen_log = __esm(() => {
|
|
|
265226
265684
|
});
|
|
265227
265685
|
|
|
265228
265686
|
// src/utils/machine-metadata.ts
|
|
265229
|
-
import { execFile as
|
|
265687
|
+
import { execFile as execFile17 } from "node:child_process";
|
|
265230
265688
|
import { readFile as readFile20 } from "node:fs/promises";
|
|
265231
265689
|
import { cpus, totalmem } from "node:os";
|
|
265232
265690
|
function getMachineMetadata() {
|
|
@@ -265244,7 +265702,7 @@ function localSources() {
|
|
|
265244
265702
|
memoryBytes: Math.min(totalmem(), limit4 || Number.POSITIVE_INFINITY),
|
|
265245
265703
|
read: (path32, signal) => readFile20(path32, { encoding: "utf8", signal }),
|
|
265246
265704
|
run: (command, args, signal) => new Promise((resolve38, reject2) => {
|
|
265247
|
-
|
|
265705
|
+
execFile17(command, args, {
|
|
265248
265706
|
encoding: "utf8",
|
|
265249
265707
|
signal,
|
|
265250
265708
|
killSignal: "SIGKILL",
|
|
@@ -268472,9 +268930,9 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
268472
268930
|
if (isMemoryHistoryCommand(parsed)) {
|
|
268473
268931
|
runDetachedListenerTask("memory_history", async () => {
|
|
268474
268932
|
const { getScopedMemoryFilesystemRoot: getScopedMemoryFilesystemRoot2 } = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
268475
|
-
const { execFile:
|
|
268476
|
-
const { promisify:
|
|
268477
|
-
const execFileAsync12 =
|
|
268933
|
+
const { execFile: execFileCb3 } = await import("node:child_process");
|
|
268934
|
+
const { promisify: promisify17 } = await import("node:util");
|
|
268935
|
+
const execFileAsync12 = promisify17(execFileCb3);
|
|
268478
268936
|
const memoryRoot = getScopedMemoryFilesystemRoot2(parsed.agent_id);
|
|
268479
268937
|
const limit4 = parsed.limit ?? 50;
|
|
268480
268938
|
const gitArgs = ["log", `--max-count=${limit4}`, "--format=%H|%s|%aI|%an"];
|
|
@@ -268508,9 +268966,9 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
268508
268966
|
if (isMemoryFileAtRefCommand(parsed)) {
|
|
268509
268967
|
runDetachedListenerTask("memory_file_at_ref", async () => {
|
|
268510
268968
|
const { getScopedMemoryFilesystemRoot: getScopedMemoryFilesystemRoot2 } = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
268511
|
-
const { execFile:
|
|
268512
|
-
const { promisify:
|
|
268513
|
-
const execFileAsync12 =
|
|
268969
|
+
const { execFile: execFileCb3 } = await import("node:child_process");
|
|
268970
|
+
const { promisify: promisify17 } = await import("node:util");
|
|
268971
|
+
const execFileAsync12 = promisify17(execFileCb3);
|
|
268514
268972
|
const memoryRoot = getScopedMemoryFilesystemRoot2(parsed.agent_id);
|
|
268515
268973
|
try {
|
|
268516
268974
|
const { stdout } = await execFileAsync12("git", ["show", `${parsed.ref}:${parsed.file_path}`], { cwd: memoryRoot, timeout: 1e4 });
|
|
@@ -268539,9 +268997,9 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
268539
268997
|
if (isMemoryCommitDiffCommand(parsed)) {
|
|
268540
268998
|
runDetachedListenerTask("memory_commit_diff", async () => {
|
|
268541
268999
|
const { getScopedMemoryFilesystemRoot: getScopedMemoryFilesystemRoot2 } = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
268542
|
-
const { execFile:
|
|
268543
|
-
const { promisify:
|
|
268544
|
-
const execFileAsync12 =
|
|
269000
|
+
const { execFile: execFileCb3 } = await import("node:child_process");
|
|
269001
|
+
const { promisify: promisify17 } = await import("node:util");
|
|
269002
|
+
const execFileAsync12 = promisify17(execFileCb3);
|
|
268545
269003
|
const memoryRoot = getScopedMemoryFilesystemRoot2(parsed.agent_id);
|
|
268546
269004
|
try {
|
|
268547
269005
|
const { stdout } = await execFileAsync12("git", ["show", parsed.sha, "--format=", "--no-color"], { cwd: memoryRoot, timeout: 1e4 });
|
|
@@ -441825,7 +442283,7 @@ function installExternalToolBridge(runtime) {
|
|
|
441825
442283
|
const connectionId = registrationKey ? getConnectionIdsByRegistrationKey(runtime).get(registrationKey) : undefined;
|
|
441826
442284
|
const connection = connectionId ? runtime.connections.get(connectionId) : undefined;
|
|
441827
442285
|
if (!connection || !isListenerTransportOpen(connection.writer) || runtime.intentionallyClosed) {
|
|
441828
|
-
throw new Error("External tool controller is not connected");
|
|
442286
|
+
throw new Error("External tool controller is not connected; the tool call was not sent and is safe to retry.");
|
|
441829
442287
|
}
|
|
441830
442288
|
const writer = connection.writer;
|
|
441831
442289
|
const requestId = `external-tool-${crypto.randomUUID()}`;
|
|
@@ -441835,6 +442293,9 @@ function installExternalToolBridge(runtime) {
|
|
|
441835
442293
|
agent_id: toolRuntime.agentId ?? null,
|
|
441836
442294
|
conversation_id: toolRuntime.conversationId
|
|
441837
442295
|
} : undefined;
|
|
442296
|
+
const conversation = requestRuntime ? runtime.conversationRuntimes?.get(getConversationRuntimeKey(requestRuntime.agent_id, requestRuntime.conversation_id)) : null;
|
|
442297
|
+
const lease = conversation?.turnLifecycle.currentLease;
|
|
442298
|
+
const isOwningTurnCurrent = conversation && lease ? () => conversation.turnLifecycle.isCurrent(lease) && !lease.signal.aborted : undefined;
|
|
441838
442299
|
const request2 = {
|
|
441839
442300
|
type: "external_tool_call_request",
|
|
441840
442301
|
request_id: requestId,
|
|
@@ -441844,6 +442305,7 @@ function installExternalToolBridge(runtime) {
|
|
|
441844
442305
|
tool_name: toolName2,
|
|
441845
442306
|
input
|
|
441846
442307
|
};
|
|
442308
|
+
const requestFrame = JSON.stringify(request2);
|
|
441847
442309
|
const timeoutMs = context3?.tool.timeoutMs ?? EXTERNAL_TOOL_CALL_TIMEOUT_MS;
|
|
441848
442310
|
const result3 = await new Promise((resolve38, reject2) => {
|
|
441849
442311
|
const timeout = setTimeout(() => {
|
|
@@ -441852,6 +442314,9 @@ function installExternalToolBridge(runtime) {
|
|
|
441852
442314
|
}, timeoutMs);
|
|
441853
442315
|
getPendingExternalToolCalls(runtime).set(requestKey, {
|
|
441854
442316
|
connectionId: connection.id,
|
|
442317
|
+
isOwningTurnCurrent,
|
|
442318
|
+
requestFrame,
|
|
442319
|
+
sentOn: writer,
|
|
441855
442320
|
resolve: (response) => {
|
|
441856
442321
|
resolve38({
|
|
441857
442322
|
content: [...response.content],
|
|
@@ -441862,7 +442327,7 @@ function installExternalToolBridge(runtime) {
|
|
|
441862
442327
|
timeout
|
|
441863
442328
|
});
|
|
441864
442329
|
try {
|
|
441865
|
-
writer.send(
|
|
442330
|
+
writer.send(requestFrame);
|
|
441866
442331
|
} catch (error5) {
|
|
441867
442332
|
clearTimeout(timeout);
|
|
441868
442333
|
getPendingExternalToolCalls(runtime).delete(requestKey);
|
|
@@ -441923,6 +442388,25 @@ function handleExternalToolCallResponseCommand(runtime, connectionId, command) {
|
|
|
441923
442388
|
pending2.resolve(command.result);
|
|
441924
442389
|
return true;
|
|
441925
442390
|
}
|
|
442391
|
+
function resendPendingExternalToolCallsForConnection(runtime, connection) {
|
|
442392
|
+
const pendingExternalToolCalls = getPendingExternalToolCalls(runtime);
|
|
442393
|
+
for (const [requestKey, pending2] of pendingExternalToolCalls) {
|
|
442394
|
+
if (pending2.connectionId !== connection.id || pending2.sentOn === connection.writer) {
|
|
442395
|
+
continue;
|
|
442396
|
+
}
|
|
442397
|
+
try {
|
|
442398
|
+
if (pending2.isOwningTurnCurrent && !pending2.isOwningTurnCurrent()) {
|
|
442399
|
+
throw new Error("External tool call was not resent because its owning turn is no longer active.");
|
|
442400
|
+
}
|
|
442401
|
+
connection.writer.send(pending2.requestFrame);
|
|
442402
|
+
pending2.sentOn = connection.writer;
|
|
442403
|
+
} catch (error5) {
|
|
442404
|
+
clearTimeout(pending2.timeout);
|
|
442405
|
+
pendingExternalToolCalls.delete(requestKey);
|
|
442406
|
+
pending2.reject(error5 instanceof Error ? error5 : new Error(String(error5)));
|
|
442407
|
+
}
|
|
442408
|
+
}
|
|
442409
|
+
}
|
|
441926
442410
|
function rejectPendingExternalToolCallsForConnection(runtime, connectionId, reason) {
|
|
441927
442411
|
const pendingExternalToolCalls = getPendingExternalToolCalls(runtime);
|
|
441928
442412
|
for (const [requestKey, pending2] of pendingExternalToolCalls) {
|
|
@@ -443833,6 +444317,19 @@ function getInterruptApprovalsForEmission(runtime, params) {
|
|
|
443833
444317
|
}
|
|
443834
444318
|
return runtime.pendingInterruptedResults;
|
|
443835
444319
|
}
|
|
444320
|
+
function emitInterruptApprovals(socket, runtime, params) {
|
|
444321
|
+
const approvals = getInterruptApprovalsForEmission(runtime, params);
|
|
444322
|
+
if (!approvals)
|
|
444323
|
+
return;
|
|
444324
|
+
const { runId, agentId, conversationId } = params;
|
|
444325
|
+
emitToolExecutionFinishedEvents(socket, runtime, {
|
|
444326
|
+
approvals,
|
|
444327
|
+
runId,
|
|
444328
|
+
agentId,
|
|
444329
|
+
conversationId
|
|
444330
|
+
});
|
|
444331
|
+
emitInterruptToolReturnMessage(socket, runtime, approvals, runId || undefined);
|
|
444332
|
+
}
|
|
443836
444333
|
function populateInterruptQueue(runtime, input) {
|
|
443837
444334
|
const shouldPopulate = !runtime.pendingInterruptedResults || runtime.pendingInterruptedResults.length === 0 || !runtime.pendingInterruptedContext;
|
|
443838
444335
|
if (!shouldPopulate)
|
|
@@ -449194,7 +449691,8 @@ async function resolveStaleApprovals(runtime, socket, turnLease, deps = {}) {
|
|
|
449194
449691
|
runtime.currentToolset = preparedToolContext.toolset;
|
|
449195
449692
|
runtime.currentToolsetPreference = preparedToolContext.toolsetPreference;
|
|
449196
449693
|
runtime.currentLoadedTools = preparedToolContext.preparedToolContext.loadedToolNames;
|
|
449197
|
-
const
|
|
449694
|
+
const recoveryRecord = (deps.readInterruptedTurn ?? readInterruptedTurn)(runtime);
|
|
449695
|
+
const recoveryActingUserId = recoveryRecord?.actingUserId;
|
|
449198
449696
|
pendingApprovals = await filterStillPending(pendingApprovals);
|
|
449199
449697
|
while (pendingApprovals.length > 0) {
|
|
449200
449698
|
assertCurrentTurnLease();
|
|
@@ -449203,10 +449701,16 @@ async function resolveStaleApprovals(runtime, socket, turnLease, deps = {}) {
|
|
|
449203
449701
|
throw new Error("Ambiguous pending approval batch mapping during recovery");
|
|
449204
449702
|
}
|
|
449205
449703
|
rememberPendingApprovalBatchIds(runtime, pendingApprovals, recoveryBatchId);
|
|
449206
|
-
const
|
|
449704
|
+
const pendingToolCallIds = pendingApprovals.map((approval) => approval.toolCallId);
|
|
449705
|
+
const approvalResults = recoveryRecord ? recordedToolResults(recoveryRecord, pendingToolCallIds) : buildFreshDenialApprovals(pendingApprovals, STALE_APPROVAL_RECOVERY_DENIAL_REASON);
|
|
449207
449706
|
if (approvalResults.length === 0) {
|
|
449208
449707
|
return null;
|
|
449209
449708
|
}
|
|
449709
|
+
if (recoveryRecord && allRecordedResults(recoveryRecord).some((result3) => pendingToolCallIds.includes(result3.tool_call_id))) {
|
|
449710
|
+
runtime.pendingInterruptedResults = null;
|
|
449711
|
+
runtime.pendingInterruptedContext = null;
|
|
449712
|
+
runtime.pendingInterruptedToolCallIds = null;
|
|
449713
|
+
}
|
|
449210
449714
|
try {
|
|
449211
449715
|
const continuationInput = createTurnInputState([
|
|
449212
449716
|
{
|
|
@@ -449591,6 +450095,7 @@ var init_send = __esm(async () => {
|
|
|
449591
450095
|
init_constants3();
|
|
449592
450096
|
init_cwd();
|
|
449593
450097
|
init_permission_mode();
|
|
450098
|
+
init_recorded_tool_results();
|
|
449594
450099
|
init_turn_input_state();
|
|
449595
450100
|
await __promiseAll([
|
|
449596
450101
|
init_message(),
|
|
@@ -452448,6 +452953,7 @@ async function handleApprovalStop(params) {
|
|
|
452448
452953
|
if (shouldInterrupt()) {
|
|
452449
452954
|
return interruptTermination(nextTurnInput, continuationBatchId);
|
|
452450
452955
|
}
|
|
452956
|
+
params.onContinuationSendError?.(interruptTermination());
|
|
452451
452957
|
throw error5;
|
|
452452
452958
|
}
|
|
452453
452959
|
if (sendResult.kind === "terminal") {
|
|
@@ -455077,7 +455583,7 @@ var init_core5 = __esm(() => {
|
|
|
455077
455583
|
});
|
|
455078
455584
|
|
|
455079
455585
|
// node_modules/@letta-ai/trajectory/dist/adapters/deepagents/index.js
|
|
455080
|
-
import { spawn as
|
|
455586
|
+
import { spawn as spawn11 } from "node:child_process";
|
|
455081
455587
|
import { accessSync as accessSync2, constants as constants6 } from "node:fs";
|
|
455082
455588
|
import { homedir as homedir22 } from "node:os";
|
|
455083
455589
|
import { join as join85 } from "node:path";
|
|
@@ -455108,7 +455614,7 @@ async function loadDeepAgentsCheckpoint(checkpoint) {
|
|
|
455108
455614
|
const python = checkpoint.pythonExecutable ?? process.env.PYTHON ?? "python3";
|
|
455109
455615
|
const helper = resolveHelperPath();
|
|
455110
455616
|
return await new Promise((resolve38, reject2) => {
|
|
455111
|
-
const child =
|
|
455617
|
+
const child = spawn11(python, [helper], {
|
|
455112
455618
|
stdio: ["pipe", "pipe", "pipe"],
|
|
455113
455619
|
windowsHide: true
|
|
455114
455620
|
});
|
|
@@ -456989,16 +457495,16 @@ var init_post_turn_reflection = __esm(() => {
|
|
|
456989
457495
|
});
|
|
456990
457496
|
|
|
456991
457497
|
// src/agent/memory-worktree.ts
|
|
456992
|
-
import { execFile as
|
|
457498
|
+
import { execFile as execFileCb3 } from "node:child_process";
|
|
456993
457499
|
import { randomUUID as randomUUID52 } from "node:crypto";
|
|
456994
457500
|
import { existsSync as existsSync62 } from "node:fs";
|
|
456995
457501
|
import { mkdir as mkdir14 } from "node:fs/promises";
|
|
456996
457502
|
import { dirname as dirname36, isAbsolute as isAbsolute25, join as join95, resolve as resolve38 } from "node:path";
|
|
456997
|
-
import { promisify as
|
|
457503
|
+
import { promisify as promisify17 } from "node:util";
|
|
456998
457504
|
async function runGit4(cwd2, args) {
|
|
456999
457505
|
try {
|
|
457000
457506
|
const allArgs = [...GIT_DISABLE_COMMIT_SIGNING_ARGS, ...args];
|
|
457001
|
-
const { stdout, stderr } = await
|
|
457507
|
+
const { stdout, stderr } = await execFile18("git", allArgs, {
|
|
457002
457508
|
cwd: cwd2,
|
|
457003
457509
|
env: {
|
|
457004
457510
|
...process.env,
|
|
@@ -457367,7 +457873,7 @@ async function finalizeReflectionMemoryWorktreeUnlocked(worktree, options) {
|
|
|
457367
457873
|
async function finalizeReflectionMemoryWorktree(worktree, options) {
|
|
457368
457874
|
return withMemoryOperation(worktree.parentMemoryDir, () => finalizeReflectionMemoryWorktreeUnlocked(worktree, options));
|
|
457369
457875
|
}
|
|
457370
|
-
var
|
|
457876
|
+
var execFile18, GIT_TIMEOUT_MS = 30000, HARNESS_GIT_ENV;
|
|
457371
457877
|
var init_memory_worktree = __esm(() => {
|
|
457372
457878
|
init_memory_auth();
|
|
457373
457879
|
init_memory_git();
|
|
@@ -457375,7 +457881,7 @@ var init_memory_worktree = __esm(() => {
|
|
|
457375
457881
|
init_memory_operation();
|
|
457376
457882
|
init_memfs_git_proxy();
|
|
457377
457883
|
init_debug();
|
|
457378
|
-
|
|
457884
|
+
execFile18 = promisify17(execFileCb3);
|
|
457379
457885
|
HARNESS_GIT_ENV = {
|
|
457380
457886
|
GIT_AUTHOR_NAME: "Letta Code",
|
|
457381
457887
|
GIT_AUTHOR_EMAIL: "noreply@letta.com",
|
|
@@ -459384,7 +459890,7 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
|
|
|
459384
459890
|
const conversationId = requestedConversationId ?? "default";
|
|
459385
459891
|
const turnWorkingDirectory = getConversationWorkingDirectory(runtime.listener, agentId, conversationId);
|
|
459386
459892
|
const turnPermissionModeState = getOrCreateConversationPermissionModeStateRef(runtime.listener, agentId, conversationId);
|
|
459387
|
-
let postStopApprovalRecoveryRetries = 0, deploymentRecoveryAttempts = 0, llmApiErrorRetries = 0, emptyResponseRetries = 0, chatgptPlanSwaps = 0, lastApprovalContinuationAccepted = false, activeDequeuedBatchId = dequeuedBatchId;
|
|
459893
|
+
let postStopApprovalRecoveryRetries = 0, deploymentRecoveryAttempts = 0, llmApiErrorRetries = 0, emptyResponseRetries = 0, chatgptPlanSwaps = 0, lastApprovalContinuationAccepted = false, continuationSendFailed = false, activeDequeuedBatchId = dequeuedBatchId;
|
|
459388
459894
|
const chatgptExhaustedProviders = new Set;
|
|
459389
459895
|
const turnCorrelation = existingTurnCorrelation ?? createTurnCorrelation(runtime, msg, activeDequeuedBatchId);
|
|
459390
459896
|
const msgRunIds = [];
|
|
@@ -459392,6 +459898,13 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
|
|
|
459392
459898
|
let lastExecutingToolCallIds = [];
|
|
459393
459899
|
let lastNeedsUserInputToolCallIds = [];
|
|
459394
459900
|
const durabilityOwnership = createTurnDurabilityOwnership();
|
|
459901
|
+
const recordApprovalProgress = (progress) => {
|
|
459902
|
+
({
|
|
459903
|
+
lastExecutionResults,
|
|
459904
|
+
lastExecutingToolCallIds,
|
|
459905
|
+
lastNeedsUserInputToolCallIds
|
|
459906
|
+
} = durabilityOwnership.record(progress));
|
|
459907
|
+
};
|
|
459395
459908
|
const interruptedRevisionRef = { current: initialInterruptedRevision };
|
|
459396
459909
|
durabilityOwnership.recordInput(msg);
|
|
459397
459910
|
const turnLease = existingTurnLease ?? runtime.turnLifecycle.begin({
|
|
@@ -459891,6 +460404,10 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
|
|
|
459891
460404
|
recoveryLineageId,
|
|
459892
460405
|
recoveryAuthorityStore,
|
|
459893
460406
|
buildSendOptions,
|
|
460407
|
+
onContinuationSendError: (progress) => {
|
|
460408
|
+
continuationSendFailed = true;
|
|
460409
|
+
recordApprovalProgress(progress);
|
|
460410
|
+
},
|
|
459894
460411
|
dependencies: recoveryEvidenceWriter ? { recordListenerWork: recoveryEvidenceWriter } : undefined
|
|
459895
460412
|
});
|
|
459896
460413
|
if (approvalResult.kind === "error") {
|
|
@@ -459911,11 +460428,7 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
|
|
|
459911
460428
|
activeDequeuedBatchId = approvalResult.dequeuedBatchId;
|
|
459912
460429
|
pendingNormalizationInterruptedToolCallIds = approvalResult.pendingNormalizationInterruptedToolCallIds;
|
|
459913
460430
|
turnToolContextId = approvalResult.turnToolContextId;
|
|
459914
|
-
(
|
|
459915
|
-
lastExecutionResults,
|
|
459916
|
-
lastExecutingToolCallIds,
|
|
459917
|
-
lastNeedsUserInputToolCallIds
|
|
459918
|
-
} = durabilityOwnership.record(approvalResult));
|
|
460431
|
+
recordApprovalProgress(approvalResult);
|
|
459919
460432
|
lastApprovalContinuationAccepted = approvalResult.lastApprovalContinuationAccepted;
|
|
459920
460433
|
if (approvalResult.kind === "teleport") {
|
|
459921
460434
|
const pending2 = approvalResult.pendingTeleport;
|
|
@@ -459963,29 +460476,24 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
|
|
|
459963
460476
|
context: "listener_turn_processing",
|
|
459964
460477
|
runId: runtime.activeRunId || msgRunIds[msgRunIds.length - 1]
|
|
459965
460478
|
});
|
|
460479
|
+
const canParkUnsentResults = runtime.turnLifecycle.isCurrent(turnLease) && !lastApprovalContinuationAccepted;
|
|
460480
|
+
if (canParkUnsentResults && (turnAbortSignal.aborted || continuationSendFailed)) {
|
|
460481
|
+
populateInterruptQueue(runtime, {
|
|
460482
|
+
lastExecutionResults,
|
|
460483
|
+
lastExecutingToolCallIds,
|
|
460484
|
+
lastNeedsUserInputToolCallIds,
|
|
460485
|
+
agentId,
|
|
460486
|
+
conversationId
|
|
460487
|
+
});
|
|
460488
|
+
}
|
|
459966
460489
|
if (turnAbortSignal.aborted) {
|
|
459967
|
-
if (
|
|
459968
|
-
|
|
460490
|
+
if (canParkUnsentResults) {
|
|
460491
|
+
emitInterruptApprovals(socket, runtime, {
|
|
459969
460492
|
lastExecutionResults,
|
|
459970
|
-
|
|
459971
|
-
lastNeedsUserInputToolCallIds,
|
|
460493
|
+
runId: runtime.activeRunId || msgRunIds[msgRunIds.length - 1],
|
|
459972
460494
|
agentId,
|
|
459973
460495
|
conversationId
|
|
459974
460496
|
});
|
|
459975
|
-
const approvalsForEmission = getInterruptApprovalsForEmission(runtime, {
|
|
459976
|
-
lastExecutionResults,
|
|
459977
|
-
agentId,
|
|
459978
|
-
conversationId
|
|
459979
|
-
});
|
|
459980
|
-
if (approvalsForEmission) {
|
|
459981
|
-
emitToolExecutionFinishedEvents(socket, runtime, {
|
|
459982
|
-
approvals: approvalsForEmission,
|
|
459983
|
-
runId: runtime.activeRunId || msgRunIds[msgRunIds.length - 1],
|
|
459984
|
-
agentId,
|
|
459985
|
-
conversationId
|
|
459986
|
-
});
|
|
459987
|
-
emitInterruptToolReturnMessage(socket, runtime, approvalsForEmission, runtime.activeRunId || msgRunIds[msgRunIds.length - 1] || undefined);
|
|
459988
|
-
}
|
|
459989
460497
|
}
|
|
459990
460498
|
finishTurn({
|
|
459991
460499
|
stopReason: "cancelled",
|
|
@@ -460320,7 +460828,7 @@ var init_connection_state_sync = __esm(async () => {
|
|
|
460320
460828
|
});
|
|
460321
460829
|
|
|
460322
460830
|
// src/websocket/listener/grep-in-files.ts
|
|
460323
|
-
import { execFile as
|
|
460831
|
+
import { execFile as execFile19 } from "node:child_process";
|
|
460324
460832
|
import { createRequire as createRequire8 } from "node:module";
|
|
460325
460833
|
import * as path42 from "node:path";
|
|
460326
460834
|
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
@@ -460376,7 +460884,7 @@ async function runGrepInFiles(args) {
|
|
|
460376
460884
|
}
|
|
460377
460885
|
function runRipgrep2(rgArgs) {
|
|
460378
460886
|
return new Promise((resolve39, reject2) => {
|
|
460379
|
-
const child =
|
|
460887
|
+
const child = execFile19(rgPath, rgArgs, {
|
|
460380
460888
|
maxBuffer: 50 * 1024 * 1024
|
|
460381
460889
|
}, (error5, stdout, _stderr) => {
|
|
460382
460890
|
if (error5 && error5.code !== 1) {
|
|
@@ -462301,7 +462809,7 @@ var init_mod_commands = __esm(async () => {
|
|
|
462301
462809
|
});
|
|
462302
462810
|
|
|
462303
462811
|
// src/websocket/listener/commands.ts
|
|
462304
|
-
import { spawn as
|
|
462812
|
+
import { spawn as spawn12 } from "node:child_process";
|
|
462305
462813
|
async function handleExecuteCommand(command, socket, conversationRuntime, opts) {
|
|
462306
462814
|
const scope = {
|
|
462307
462815
|
agent_id: conversationRuntime.agentId,
|
|
@@ -462538,7 +463046,7 @@ function scheduleRemoteRestart(connectionName, log3) {
|
|
|
462538
463046
|
setTimeout(async () => {
|
|
462539
463047
|
await flushRemoteSettingsWrites();
|
|
462540
463048
|
log3(`spawning replacement listener: ${process.execPath} ${entrypoint} remote --computer-name ${connectionName}`);
|
|
462541
|
-
const child =
|
|
463049
|
+
const child = spawn12(process.execPath, [entrypoint, "remote", "--computer-name", connectionName], {
|
|
462542
463050
|
cwd: process.cwd(),
|
|
462543
463051
|
detached: true,
|
|
462544
463052
|
env: process.env,
|
|
@@ -463721,8 +464229,8 @@ var init_connect_providers = __esm(async () => {
|
|
|
463721
464229
|
});
|
|
463722
464230
|
|
|
463723
464231
|
// src/websocket/listener/commands/git-branches.ts
|
|
463724
|
-
import { execFile as
|
|
463725
|
-
import { promisify as
|
|
464232
|
+
import { execFile as execFile20 } from "node:child_process";
|
|
464233
|
+
import { promisify as promisify18 } from "node:util";
|
|
463726
464234
|
function handleGitBranchCommand(parsed, context3) {
|
|
463727
464235
|
const { socket, runtime, safeSocketSend, runDetachedListenerTask: runDetachedListenerTask2 } = context3;
|
|
463728
464236
|
if (isSearchBranchesCommand(parsed)) {
|
|
@@ -463730,7 +464238,7 @@ function handleGitBranchCommand(parsed, context3) {
|
|
|
463730
464238
|
try {
|
|
463731
464239
|
const cwd2 = parsed.cwd ?? getBootWorkingDirectory(runtime);
|
|
463732
464240
|
const maxResults = parsed.max_results ?? 20;
|
|
463733
|
-
const execFileAsync12 =
|
|
464241
|
+
const execFileAsync12 = promisify18(execFile20);
|
|
463734
464242
|
const { stdout } = await execFileAsync12("git", ["branch", "-a", "--format=%(refname:short)\t%(HEAD)"], {
|
|
463735
464243
|
cwd: cwd2,
|
|
463736
464244
|
encoding: "utf-8",
|
|
@@ -463770,7 +464278,7 @@ function handleGitBranchCommand(parsed, context3) {
|
|
|
463770
464278
|
runDetachedListenerTask2("checkout_branch", async () => {
|
|
463771
464279
|
try {
|
|
463772
464280
|
const cwd2 = parsed.cwd ?? getBootWorkingDirectory(runtime);
|
|
463773
|
-
const execFileAsync12 =
|
|
464281
|
+
const execFileAsync12 = promisify18(execFile20);
|
|
463774
464282
|
const args = parsed.create ? ["checkout", "-b", parsed.branch] : ["checkout", parsed.branch];
|
|
463775
464283
|
await execFileAsync12("git", args, {
|
|
463776
464284
|
cwd: cwd2,
|
|
@@ -464007,7 +464515,7 @@ function dispatchInboundMessageWhenReady(params) {
|
|
|
464007
464515
|
acknowledgeInput({ accepted: false });
|
|
464008
464516
|
return;
|
|
464009
464517
|
}
|
|
464010
|
-
if (shouldQueueInboundMessage(incoming)
|
|
464518
|
+
if (shouldQueueInboundMessage(incoming)) {
|
|
464011
464519
|
const committed = commitInputDisposition(runtime, reservation, "queued", { incoming: attributedIncoming, actingUserId });
|
|
464012
464520
|
let accepted = false;
|
|
464013
464521
|
try {
|
|
@@ -464050,18 +464558,8 @@ function dispatchInboundMessageWhenReady(params) {
|
|
|
464050
464558
|
acknowledgeInput({ accepted: false });
|
|
464051
464559
|
return;
|
|
464052
464560
|
}
|
|
464053
|
-
const directBatchId = `batch-direct-${crypto.randomUUID()}`;
|
|
464054
|
-
if (identity2) {
|
|
464055
|
-
runtime.dequeuedInputIdentitiesByBatchId.set(directBatchId, [
|
|
464056
|
-
identity2
|
|
464057
|
-
]);
|
|
464058
|
-
}
|
|
464059
464561
|
acknowledgeInput({ accepted: true, disposition: "started" });
|
|
464060
|
-
|
|
464061
|
-
await processIncomingMessage(attributedIncoming, getOrCreateProcessTransport(listener), runtime, options.onStatusChange, options.connectionId, directBatchId);
|
|
464062
|
-
} finally {
|
|
464063
|
-
runtime.dequeuedInputIdentitiesByBatchId.delete(directBatchId);
|
|
464064
|
-
}
|
|
464562
|
+
await processIncomingMessage(attributedIncoming, getOrCreateProcessTransport(listener), runtime, options.onStatusChange, options.connectionId);
|
|
464065
464563
|
emitListenerStatus(listener, options.onStatusChange, options.connectionId);
|
|
464066
464564
|
if (runtime.queueRuntime.length > 0 || runtime.queuePumpScheduled || runtime.queuePumpActive) {
|
|
464067
464565
|
scheduleQueuePump(runtime, socket, options, processQueuedTurn);
|
|
@@ -464551,11 +465049,11 @@ async function routeInputFrame(deps) {
|
|
|
464551
465049
|
return;
|
|
464552
465050
|
}
|
|
464553
465051
|
const scopedRuntime = getOrCreateScopedRuntime2(runtime, incoming.agentId, incoming.conversationId);
|
|
464554
|
-
const
|
|
465052
|
+
const dispatchNonContentMessage = (nonContentIncoming) => {
|
|
464555
465053
|
dispatchInboundMessageWhenReady({
|
|
464556
465054
|
listener: runtime,
|
|
464557
465055
|
runtime: scopedRuntime,
|
|
464558
|
-
incoming:
|
|
465056
|
+
incoming: nonContentIncoming,
|
|
464559
465057
|
socket,
|
|
464560
465058
|
options: opts,
|
|
464561
465059
|
processQueuedTurn,
|
|
@@ -464578,10 +465076,6 @@ async function routeInputFrame(deps) {
|
|
|
464578
465076
|
if (!gateInputOriginatorAdmission()) {
|
|
464579
465077
|
return;
|
|
464580
465078
|
}
|
|
464581
|
-
if (shouldProcessInboundMessageDirectly(scopedRuntime, stampedIncoming)) {
|
|
464582
|
-
processIncomingMessageDirectly(stampedIncoming);
|
|
464583
|
-
return;
|
|
464584
|
-
}
|
|
464585
465079
|
const admission = reserveInputDisposition(scopedRuntime, identity2);
|
|
464586
465080
|
if (admission.kind === "duplicate") {
|
|
464587
465081
|
acknowledgeAdmissionDuplicate(ackTransport, scopedRuntime, identity2, admission.disposition);
|
|
@@ -464624,7 +465118,7 @@ async function routeInputFrame(deps) {
|
|
|
464624
465118
|
if (!gateInputOriginatorAdmission()) {
|
|
464625
465119
|
return;
|
|
464626
465120
|
}
|
|
464627
|
-
|
|
465121
|
+
dispatchNonContentMessage(incoming);
|
|
464628
465122
|
return;
|
|
464629
465123
|
}
|
|
464630
465124
|
var init_input_frame_router = __esm(async () => {
|
|
@@ -467062,6 +467556,7 @@ async function startConnectedListenerRuntime(runtime, transport3, opts, processQ
|
|
|
467062
467556
|
await opts.onConnectionReady?.(startupConnection);
|
|
467063
467557
|
if (!isExactOpenConnection() || !startupConnection.ingressReady)
|
|
467064
467558
|
return;
|
|
467559
|
+
resendPendingExternalToolCallsForConnection(runtime, startupConnection);
|
|
467065
467560
|
startupComplete = true;
|
|
467066
467561
|
} finally {
|
|
467067
467562
|
clearStartupDeadline();
|
|
@@ -470195,7 +470690,7 @@ __export(exports_gateway_supervisor, {
|
|
|
470195
470690
|
startChannelGatewaySupervisor: () => startChannelGatewaySupervisor,
|
|
470196
470691
|
CHANNEL_GATEWAY_READY_SIGNAL: () => CHANNEL_GATEWAY_READY_SIGNAL
|
|
470197
470692
|
});
|
|
470198
|
-
import { spawn as
|
|
470693
|
+
import { spawn as spawn13 } from "node:child_process";
|
|
470199
470694
|
function resolveLauncher(cwd2) {
|
|
470200
470695
|
const invocation = resolveLettaInvocation(process.env, process.argv, process.execPath, cwd2);
|
|
470201
470696
|
if (invocation)
|
|
@@ -470296,7 +470791,7 @@ async function startChannelGatewaySupervisor(options) {
|
|
|
470296
470791
|
function launch() {
|
|
470297
470792
|
if (stopping)
|
|
470298
470793
|
return;
|
|
470299
|
-
child = (options.spawnProcess ??
|
|
470794
|
+
child = (options.spawnProcess ?? spawn13)(launcher.command, childArgs, {
|
|
470300
470795
|
cwd: cwd2,
|
|
470301
470796
|
env: options.env ?? process.env,
|
|
470302
470797
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -471894,11 +472389,11 @@ async function runMemorySubcommand(argv, deps = {}) {
|
|
|
471894
472389
|
console.error("Not a git repo. Enable git-backed memory first.");
|
|
471895
472390
|
return 1;
|
|
471896
472391
|
}
|
|
471897
|
-
const { execFile:
|
|
471898
|
-
const { promisify:
|
|
471899
|
-
const
|
|
472392
|
+
const { execFile: execFileCb4 } = await import("node:child_process");
|
|
472393
|
+
const { promisify: promisify19 } = await import("node:util");
|
|
472394
|
+
const execFile21 = promisify19(execFileCb4);
|
|
471900
472395
|
const dir = getScopedMemoryFilesystemRoot(agentId);
|
|
471901
|
-
const { stdout } = await
|
|
472396
|
+
const { stdout } = await execFile21("git", ["diff"], { cwd: dir });
|
|
471902
472397
|
if (stdout.trim()) {
|
|
471903
472398
|
console.log(stdout);
|
|
471904
472399
|
return 2;
|
|
@@ -473427,7 +473922,7 @@ var init_model2 = __esm(() => {
|
|
|
473427
473922
|
});
|
|
473428
473923
|
|
|
473429
473924
|
// src/mods/package-installer.ts
|
|
473430
|
-
import { spawn as
|
|
473925
|
+
import { spawn as spawn14 } from "node:child_process";
|
|
473431
473926
|
import {
|
|
473432
473927
|
copyFileSync as copyFileSync4,
|
|
473433
473928
|
existsSync as existsSync67,
|
|
@@ -474285,7 +474780,7 @@ var init_package_installer = __esm(() => {
|
|
|
474285
474780
|
init_package_registry();
|
|
474286
474781
|
init_package_manager_spawn();
|
|
474287
474782
|
SKIPPED_PACKAGE_COPY_NAMES = new Set([".git", "node_modules"]);
|
|
474288
|
-
spawnGitInstallProcess =
|
|
474783
|
+
spawnGitInstallProcess = spawn14;
|
|
474289
474784
|
});
|
|
474290
474785
|
|
|
474291
474786
|
// src/mods/package-scaffolder.ts
|
|
@@ -478049,15 +478544,15 @@ function resolveSkillSourceSpecifier(input) {
|
|
|
478049
478544
|
}
|
|
478050
478545
|
return null;
|
|
478051
478546
|
}
|
|
478052
|
-
async function
|
|
478053
|
-
const { execFile:
|
|
478054
|
-
const { promisify:
|
|
478055
|
-
return
|
|
478547
|
+
async function execFile21(command, args, options = {}) {
|
|
478548
|
+
const { execFile: execFileCb4 } = await import("node:child_process");
|
|
478549
|
+
const { promisify: promisify19 } = await import("node:util");
|
|
478550
|
+
return promisify19(execFileCb4)(command, args, options);
|
|
478056
478551
|
}
|
|
478057
478552
|
async function resolveBranchAndSubdir(location) {
|
|
478058
478553
|
if (!location.subdir)
|
|
478059
478554
|
return location;
|
|
478060
|
-
const { stdout } = await
|
|
478555
|
+
const { stdout } = await execFile21("git", ["ls-remote", "--heads", location.repoUrl], {
|
|
478061
478556
|
timeout: 60000
|
|
478062
478557
|
});
|
|
478063
478558
|
const branches = stdout.split(`
|
|
@@ -478084,7 +478579,7 @@ async function cloneSkillSource(location) {
|
|
|
478084
478579
|
args.push("--branch", resolvedLocation.branch);
|
|
478085
478580
|
}
|
|
478086
478581
|
args.push(resolvedLocation.repoUrl, tmpDir);
|
|
478087
|
-
await
|
|
478582
|
+
await execFile21("git", args, { timeout: 120000 });
|
|
478088
478583
|
const sourceDir = resolvedLocation.subdir ? join102(tmpDir, resolvedLocation.subdir) : tmpDir;
|
|
478089
478584
|
return { tmpDir, sourceDir };
|
|
478090
478585
|
}
|
|
@@ -478197,7 +478692,7 @@ async function downloadClawHubSkillSource(location) {
|
|
|
478197
478692
|
throw new Error(`ClawHub download failed for ${location.slug}@${version3}: ${response.status}`);
|
|
478198
478693
|
}
|
|
478199
478694
|
writeFileSync42(zipPath, Buffer.from(await response.arrayBuffer()));
|
|
478200
|
-
const { stdout } = await
|
|
478695
|
+
const { stdout } = await execFile21("unzip", ["-Z1", zipPath], {
|
|
478201
478696
|
timeout: 30000
|
|
478202
478697
|
});
|
|
478203
478698
|
const members = stdout.split(`
|
|
@@ -478206,7 +478701,7 @@ async function downloadClawHubSkillSource(location) {
|
|
|
478206
478701
|
throw new Error(`ClawHub download was empty for ${location.slug}@${version3}`);
|
|
478207
478702
|
}
|
|
478208
478703
|
members.forEach(assertSafeZipMember);
|
|
478209
|
-
await
|
|
478704
|
+
await execFile21("unzip", ["-q", zipPath, "-d", sourceDir], {
|
|
478210
478705
|
timeout: 30000
|
|
478211
478706
|
});
|
|
478212
478707
|
return { tmpDir, sourceDir };
|
|
@@ -490216,12 +490711,12 @@ var init_cli_mod_context = __esm(() => {
|
|
|
490216
490711
|
});
|
|
490217
490712
|
|
|
490218
490713
|
// src/cli/helpers/reflection-arena-hf-upload.ts
|
|
490219
|
-
import { execFile as
|
|
490714
|
+
import { execFile as execFileCb4 } from "node:child_process";
|
|
490220
490715
|
import { existsSync as existsSync73 } from "node:fs";
|
|
490221
490716
|
import { appendFile as appendFile3, chmod, mkdir as mkdir18, writeFile as writeFile21 } from "node:fs/promises";
|
|
490222
490717
|
import { homedir as homedir33 } from "node:os";
|
|
490223
490718
|
import { join as join108 } from "node:path";
|
|
490224
|
-
import { promisify as
|
|
490719
|
+
import { promisify as promisify19 } from "node:util";
|
|
490225
490720
|
function getReflectionArenaHfCacheRoot(env6 = process.env, fallbackHome = homedir33()) {
|
|
490226
490721
|
return join108(resolveGlobalConfigDir(env6, fallbackHome), "reflection-arena", "hf-upload");
|
|
490227
490722
|
}
|
|
@@ -490247,7 +490742,7 @@ function formatTokenStatus(token2) {
|
|
|
490247
490742
|
}
|
|
490248
490743
|
async function runGit6(cwd2, args, env6) {
|
|
490249
490744
|
try {
|
|
490250
|
-
await
|
|
490745
|
+
await execFile22("git", args, {
|
|
490251
490746
|
cwd: cwd2,
|
|
490252
490747
|
env: env6,
|
|
490253
490748
|
encoding: "utf-8",
|
|
@@ -490332,23 +490827,23 @@ async function maybeUploadReflectionArenaChoiceToHf(row) {
|
|
|
490332
490827
|
};
|
|
490333
490828
|
}
|
|
490334
490829
|
}
|
|
490335
|
-
var
|
|
490830
|
+
var execFile22, HF_REPO_ID = "letta-ai/reflection-arena", HF_REPO_URL, GIT_TIMEOUT_MS2 = 60000, HF_CACHE_ROOT, HF_REPO_DIR, HF_DATASET_PATH = "data/choices.jsonl";
|
|
490336
490831
|
var init_reflection_arena_hf_upload = __esm(() => {
|
|
490337
490832
|
init_secrets_store();
|
|
490338
490833
|
init_settings_path();
|
|
490339
490834
|
init_version();
|
|
490340
|
-
|
|
490835
|
+
execFile22 = promisify19(execFileCb4);
|
|
490341
490836
|
HF_REPO_URL = `https://huggingface.co/datasets/${HF_REPO_ID}`;
|
|
490342
490837
|
HF_CACHE_ROOT = getReflectionArenaHfCacheRoot();
|
|
490343
490838
|
HF_REPO_DIR = join108(HF_CACHE_ROOT, "repo");
|
|
490344
490839
|
});
|
|
490345
490840
|
|
|
490346
490841
|
// src/cli/helpers/reflection-arena.ts
|
|
490347
|
-
import { execFile as
|
|
490842
|
+
import { execFile as execFileCb5 } from "node:child_process";
|
|
490348
490843
|
import { randomInt as randomInt2, randomUUID as randomUUID64 } from "node:crypto";
|
|
490349
490844
|
import { appendFile as appendFile4, mkdir as mkdir19, readFile as readFile32, writeFile as writeFile22 } from "node:fs/promises";
|
|
490350
490845
|
import { join as join109 } from "node:path";
|
|
490351
|
-
import { promisify as
|
|
490846
|
+
import { promisify as promisify20 } from "node:util";
|
|
490352
490847
|
function sampleReflectionArenaComparisonModel(excludedModels = []) {
|
|
490353
490848
|
const excluded = new Set(excludedModels);
|
|
490354
490849
|
const candidates2 = REFLECTION_ARENA_COMPARISON_MODEL_POOL.filter((entry) => !excluded.has(entry.model));
|
|
@@ -490365,7 +490860,7 @@ function sampleReflectionArenaComparisonModel(excludedModels = []) {
|
|
|
490365
490860
|
}
|
|
490366
490861
|
async function getGitOutput(cwd2, args) {
|
|
490367
490862
|
try {
|
|
490368
|
-
const { stdout } = await
|
|
490863
|
+
const { stdout } = await execFile23("git", args, {
|
|
490369
490864
|
cwd: cwd2,
|
|
490370
490865
|
encoding: "utf-8",
|
|
490371
490866
|
timeout: 30000,
|
|
@@ -490921,7 +491416,7 @@ async function finalizeReflectionArenaChoice(options) {
|
|
|
490921
491416
|
run: completedRun
|
|
490922
491417
|
};
|
|
490923
491418
|
}
|
|
490924
|
-
var
|
|
491419
|
+
var execFile23, REFLECTION_ARENA_TELEMETRY_TRANSCRIPT_MAX_CHARS = 1e6, REFLECTION_ARENA_MODEL_A_DEFAULT = "letta/auto-memory", REFLECTION_ARENA_COMPARISON_MODEL_POOL, ANSI_BOLD = "\x1B[1m", ANSI_CYAN = "\x1B[36m", ANSI_MAGENTA = "\x1B[35m", ANSI_RESET_BOLD = "\x1B[22m", ANSI_RESET_FOREGROUND = "\x1B[39m", REFLECTION_ARENA_CANDIDATE_COUNT = 2, REFLECTION_ARENA_CHOICE_QUESTION = "Which reflection should be merged?", REFLECTION_ARENA_NOTES_QUESTION = "Optional feedback for this choice?", updateLocks;
|
|
490925
491420
|
var init_reflection_arena = __esm(() => {
|
|
490926
491421
|
init_memory_worktree();
|
|
490927
491422
|
init_app_urls();
|
|
@@ -490932,7 +491427,7 @@ var init_reflection_arena = __esm(() => {
|
|
|
490932
491427
|
init_telemetry();
|
|
490933
491428
|
init_debug();
|
|
490934
491429
|
init_settings_path();
|
|
490935
|
-
|
|
491430
|
+
execFile23 = promisify20(execFileCb5);
|
|
490936
491431
|
REFLECTION_ARENA_COMPARISON_MODEL_POOL = [
|
|
490937
491432
|
{ model: "lc-anthropic/claude-sonnet-5", weight: 1 },
|
|
490938
491433
|
{ model: "lc-anthropic/claude-opus-4-8", weight: 3 },
|
|
@@ -507225,10 +507720,10 @@ var exports_generate_memory_viewer = {};
|
|
|
507225
507720
|
__export(exports_generate_memory_viewer, {
|
|
507226
507721
|
generateAndOpenMemoryViewer: () => generateAndOpenMemoryViewer
|
|
507227
507722
|
});
|
|
507228
|
-
import { execFile as
|
|
507723
|
+
import { execFile as execFileCb6 } from "node:child_process";
|
|
507229
507724
|
import { chmodSync as chmodSync10, existsSync as existsSync76, mkdirSync as mkdirSync56, writeFileSync as writeFileSync47 } from "node:fs";
|
|
507230
507725
|
import { join as join113 } from "node:path";
|
|
507231
|
-
import { promisify as
|
|
507726
|
+
import { promisify as promisify21 } from "node:util";
|
|
507232
507727
|
function messagesFromOverview(overview) {
|
|
507233
507728
|
return overview.messages?.map((message2) => ({
|
|
507234
507729
|
id: message2.id,
|
|
@@ -507255,7 +507750,7 @@ function contextFromOverview(overview, model, contextWindow) {
|
|
|
507255
507750
|
}
|
|
507256
507751
|
async function runGitSafe(cwd2, args) {
|
|
507257
507752
|
try {
|
|
507258
|
-
const { stdout } = await
|
|
507753
|
+
const { stdout } = await execFile24("git", args, {
|
|
507259
507754
|
cwd: cwd2,
|
|
507260
507755
|
maxBuffer: 10 * 1024 * 1024,
|
|
507261
507756
|
timeout: 60000
|
|
@@ -507566,7 +508061,7 @@ async function generateAndOpenMemoryViewer(agentId, options) {
|
|
|
507566
508061
|
}
|
|
507567
508062
|
return { filePath, opened: !skipOpen };
|
|
507568
508063
|
}
|
|
507569
|
-
var
|
|
508064
|
+
var execFile24, VIEWERS_DIR, MAX_COMMITS = 500, RECENT_DIFF_COUNT = 50, PER_DIFF_CAP = 1e5, TOTAL_PAYLOAD_CAP = 5000000, RECORD_SEP = "\x1E", REFLECTION_PATTERN;
|
|
507570
508065
|
var init_generate_memory_viewer = __esm(() => {
|
|
507571
508066
|
init_memory_filesystem2();
|
|
507572
508067
|
init_memory_scanner();
|
|
@@ -507578,7 +508073,7 @@ var init_generate_memory_viewer = __esm(() => {
|
|
|
507578
508073
|
init_context_usage();
|
|
507579
508074
|
init_local_memory_context();
|
|
507580
508075
|
init_memory_viewer_template();
|
|
507581
|
-
|
|
508076
|
+
execFile24 = promisify21(execFileCb6);
|
|
507582
508077
|
VIEWERS_DIR = join113(resolveGlobalConfigDir(), "viewers");
|
|
507583
508078
|
REFLECTION_PATTERN = /\(reflection\)|🔮|reflection:/i;
|
|
507584
508079
|
});
|
|
@@ -518247,13 +518742,13 @@ var exports_generate_diff_viewer = {};
|
|
|
518247
518742
|
__export(exports_generate_diff_viewer, {
|
|
518248
518743
|
generateAndOpenDiffViewer: () => generateAndOpenDiffViewer
|
|
518249
518744
|
});
|
|
518250
|
-
import { execFile as
|
|
518745
|
+
import { execFile as execFileCb7 } from "node:child_process";
|
|
518251
518746
|
import { chmodSync as chmodSync11, existsSync as existsSync78, mkdirSync as mkdirSync57, writeFileSync as writeFileSync48 } from "node:fs";
|
|
518252
518747
|
import { isAbsolute as isAbsolute28, join as join117, resolve as resolve43 } from "node:path";
|
|
518253
|
-
import { promisify as
|
|
518748
|
+
import { promisify as promisify22 } from "node:util";
|
|
518254
518749
|
async function runGit8(cwd2, args) {
|
|
518255
518750
|
try {
|
|
518256
|
-
const { stdout } = await
|
|
518751
|
+
const { stdout } = await execFile25("git", args, {
|
|
518257
518752
|
cwd: cwd2,
|
|
518258
518753
|
maxBuffer: GIT_MAX_BUFFER,
|
|
518259
518754
|
timeout: GIT_TIMEOUT_MS3
|
|
@@ -518492,7 +518987,7 @@ async function generateAndOpenDiffViewer(targetPath) {
|
|
|
518492
518987
|
}
|
|
518493
518988
|
return { filePath, opened: !skipOpen, fileCount: rendered.files.length };
|
|
518494
518989
|
}
|
|
518495
|
-
var
|
|
518990
|
+
var execFile25, VIEWERS_DIR2, GIT_TIMEOUT_MS3 = 60000, GIT_MAX_BUFFER, MAX_RENDERED_FILES = 100, DIFF_UNSAFE_CSS = `
|
|
518496
518991
|
:host {
|
|
518497
518992
|
--diffs-addition-color-override: #15803d;
|
|
518498
518993
|
--diffs-deletion-color-override: #b91c1c;
|
|
@@ -518547,7 +519042,7 @@ var execFile26, VIEWERS_DIR2, GIT_TIMEOUT_MS3 = 60000, GIT_MAX_BUFFER, MAX_RENDE
|
|
|
518547
519042
|
var init_generate_diff_viewer = __esm(() => {
|
|
518548
519043
|
init_settings_path();
|
|
518549
519044
|
init_diff_viewer_template();
|
|
518550
|
-
|
|
519045
|
+
execFile25 = promisify22(execFileCb7);
|
|
518551
519046
|
VIEWERS_DIR2 = join117(resolveGlobalConfigDir(), "viewers");
|
|
518552
519047
|
GIT_MAX_BUFFER = 50 * 1024 * 1024;
|
|
518553
519048
|
});
|
|
@@ -524862,7 +525357,7 @@ The deployment target for this project is CITATION-DOGFOOD-OK.
|
|
|
524862
525357
|
});
|
|
524863
525358
|
|
|
524864
525359
|
// src/mods/learning-harness.ts
|
|
524865
|
-
import { spawn as
|
|
525360
|
+
import { spawn as spawn15 } from "node:child_process";
|
|
524866
525361
|
import { access as access2, copyFile as copyFile2, mkdir as mkdir20, readFile as readFile34, writeFile as writeFile23 } from "node:fs/promises";
|
|
524867
525362
|
import path49 from "node:path";
|
|
524868
525363
|
function slugify2(value) {
|
|
@@ -525802,7 +526297,7 @@ async function writeHistoryArtifacts(params) {
|
|
|
525802
526297
|
async function defaultCommandRunner(command, args, options) {
|
|
525803
526298
|
const startedAt = Date.now();
|
|
525804
526299
|
return new Promise((resolve44) => {
|
|
525805
|
-
const child =
|
|
526300
|
+
const child = spawn15(command, args, {
|
|
525806
526301
|
cwd: options.cwd,
|
|
525807
526302
|
env: options.env,
|
|
525808
526303
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -528614,12 +529109,12 @@ var exports_worktree_diff_list = {};
|
|
|
528614
529109
|
__export(exports_worktree_diff_list, {
|
|
528615
529110
|
listWorktreeDiffOptions: () => listWorktreeDiffOptions
|
|
528616
529111
|
});
|
|
528617
|
-
import { execFile as
|
|
529112
|
+
import { execFile as execFileCb8 } from "node:child_process";
|
|
528618
529113
|
import { basename as basename33 } from "node:path";
|
|
528619
|
-
import { promisify as
|
|
529114
|
+
import { promisify as promisify23 } from "node:util";
|
|
528620
529115
|
async function runGit9(cwd2, args) {
|
|
528621
529116
|
try {
|
|
528622
|
-
const { stdout } = await
|
|
529117
|
+
const { stdout } = await execFile26("git", args, {
|
|
528623
529118
|
cwd: cwd2,
|
|
528624
529119
|
maxBuffer: GIT_MAX_BUFFER2,
|
|
528625
529120
|
timeout: GIT_TIMEOUT_MS4
|
|
@@ -528748,9 +529243,9 @@ async function listWorktreeDiffOptions(cwd2 = process.cwd()) {
|
|
|
528748
529243
|
const worktrees = parseWorktreeList(output, currentPath);
|
|
528749
529244
|
return Promise.all(worktrees.map((worktree) => summarizeWorktree(worktree)));
|
|
528750
529245
|
}
|
|
528751
|
-
var
|
|
529246
|
+
var execFile26, GIT_TIMEOUT_MS4 = 60000, GIT_MAX_BUFFER2;
|
|
528752
529247
|
var init_worktree_diff_list = __esm(() => {
|
|
528753
|
-
|
|
529248
|
+
execFile26 = promisify23(execFileCb8);
|
|
528754
529249
|
GIT_MAX_BUFFER2 = 10 * 1024 * 1024;
|
|
528755
529250
|
});
|
|
528756
529251
|
|
|
@@ -538684,4 +539179,4 @@ function registerBunOAuthFlows() {
|
|
|
538684
539179
|
registerBunOAuthFlows();
|
|
538685
539180
|
await init_src5().then(() => exports_src2);
|
|
538686
539181
|
|
|
538687
|
-
//# debugId=
|
|
539182
|
+
//# debugId=395DF1A0E3F5616F64756E2164756E21
|