@letta-ai/letta-code 0.34.36 → 0.34.37
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/app-server-client.cjs +46 -1
- package/dist/app-server-client.cjs.map +3 -3
- package/dist/app-server-client.js +46 -1
- package/dist/app-server-client.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-hooks.d.ts +2 -0
- package/dist/types/agent/memory-git-hooks.d.ts.map +1 -1
- package/dist/types/agent/subagent-state.d.ts +32 -0
- package/dist/types/agent/subagent-state.d.ts.map +1 -1
- package/dist/types/app-server-client.d.ts.map +1 -1
- package/dist/types/backend/api/environments.d.ts +2 -0
- package/dist/types/backend/api/environments.d.ts.map +1 -1
- package/dist/types/backend/local/initial-memory.d.ts +1 -0
- package/dist/types/backend/local/initial-memory.d.ts.map +1 -1
- package/dist/types/cron/runner.d.ts.map +1 -1
- package/dist/types/headless-super-run-wait.d.ts +2 -0
- package/dist/types/headless-super-run-wait.d.ts.map +1 -1
- package/dist/types/queue/queue-runtime.d.ts +2 -0
- package/dist/types/queue/queue-runtime.d.ts.map +1 -1
- package/dist/types/reminders/disk-space.d.ts +12 -0
- package/dist/types/reminders/disk-space.d.ts.map +1 -1
- package/dist/types/runtime-context.d.ts +6 -0
- package/dist/types/runtime-context.d.ts.map +1 -1
- package/dist/types/tools/impl/claude-stream-session.d.ts +18 -1
- package/dist/types/tools/impl/claude-stream-session.d.ts.map +1 -1
- package/dist/types/tools/impl/codex-app-server-payloads.d.ts +19 -0
- package/dist/types/tools/impl/codex-app-server-payloads.d.ts.map +1 -0
- package/dist/types/tools/impl/codex-app-server.d.ts +7 -3
- package/dist/types/tools/impl/codex-app-server.d.ts.map +1 -1
- package/dist/types/tools/impl/external-coding-agent-task.d.ts.map +1 -1
- package/dist/types/tools/impl/external-coding-agent.d.ts +26 -1
- package/dist/types/tools/impl/external-coding-agent.d.ts.map +1 -1
- package/dist/types/tools/impl/external-tool-call.d.ts +2 -0
- package/dist/types/tools/impl/external-tool-call.d.ts.map +1 -1
- package/dist/types/tools/impl/monitor-timeout.d.ts +13 -1
- package/dist/types/tools/impl/monitor-timeout.d.ts.map +1 -1
- package/dist/types/tools/impl/native-session-capture.d.ts +1 -0
- package/dist/types/tools/impl/native-session-capture.d.ts.map +1 -1
- package/dist/types/tools/impl/remote-external-coding-agent.d.ts.map +1 -1
- package/dist/types/tools/impl/send-agent-message.d.ts +2 -0
- package/dist/types/tools/impl/send-agent-message.d.ts.map +1 -1
- package/dist/types/tools/impl/task-transcript.d.ts +33 -0
- package/dist/types/tools/impl/task-transcript.d.ts.map +1 -1
- package/dist/types/tools/impl/task.d.ts.map +1 -1
- package/dist/types/tools/impl/workflow.d.ts.map +1 -1
- package/dist/types/tools/tool-definitions.d.ts.map +1 -1
- package/dist/types/tools/toolset.d.ts +2 -0
- package/dist/types/tools/toolset.d.ts.map +1 -1
- package/dist/types/types/protocol_v2.d.ts +5 -1
- package/dist/types/types/protocol_v2.d.ts.map +1 -1
- package/dist/types/utils/message-queue-bridge.d.ts +2 -0
- package/dist/types/utils/message-queue-bridge.d.ts.map +1 -1
- package/dist/types/utils/process-liveness.d.ts.map +1 -1
- package/dist/types/utils/task-notifications.d.ts +2 -0
- package/dist/types/utils/task-notifications.d.ts.map +1 -1
- package/dist/types/websocket/listener/protocol-outbound.d.ts +2 -4
- package/dist/types/websocket/listener/protocol-outbound.d.ts.map +1 -1
- package/dist/types/websocket/listener/queue.d.ts.map +1 -1
- package/dist/types/websocket/listener/subagent-state-cache.d.ts +16 -0
- package/dist/types/websocket/listener/subagent-state-cache.d.ts.map +1 -0
- package/dist/types/websocket/listener/types.d.ts +2 -0
- package/dist/types/websocket/listener/types.d.ts.map +1 -1
- package/letta.js +1355 -578
- package/npm-shrinkwrap.json +14 -14
- package/package.json +2 -2
- package/scripts/isolated-unit-tests.json +6 -0
- package/scripts/source-file-size-baseline.json +1 -2
package/letta.js
CHANGED
|
@@ -6077,7 +6077,7 @@ var package_default;
|
|
|
6077
6077
|
var init_package = __esm(() => {
|
|
6078
6078
|
package_default = {
|
|
6079
6079
|
name: "@letta-ai/letta-code",
|
|
6080
|
-
version: "0.34.
|
|
6080
|
+
version: "0.34.37",
|
|
6081
6081
|
lettaStartupLogProtocol: 1,
|
|
6082
6082
|
lettaConfigDirProtocol: 1,
|
|
6083
6083
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
@@ -6355,7 +6355,7 @@ var init_package = __esm(() => {
|
|
|
6355
6355
|
},
|
|
6356
6356
|
lettaLifecycleProtocol: 1,
|
|
6357
6357
|
lettaRuntimeGraphProtocol: 1,
|
|
6358
|
-
lettaRuntimeGraphSha512: "sha512-
|
|
6358
|
+
lettaRuntimeGraphSha512: "sha512-WqLO/tmUfIp8hKqBdQE1lQtkR5VxOaoI/Ajy8QoRz3N1f0x2/gRcyGbTKlonrJrkKMNXyKJMWYtqAbudmdmrog==",
|
|
6359
6359
|
patchedDependencies: {
|
|
6360
6360
|
"@earendil-works/pi-ai@0.99.1": "patches/@earendil-works%2Fpi-ai@0.99.1.patch"
|
|
6361
6361
|
}
|
|
@@ -97760,7 +97760,10 @@ async function getProcessStartTime(pid) {
|
|
|
97760
97760
|
"-NoProfile",
|
|
97761
97761
|
"-Command",
|
|
97762
97762
|
`(Get-Process -Id ${pid}).StartTime.ToFileTimeUtc()`
|
|
97763
|
-
]) : await promisify2(execFile)("ps", ["-o", "lstart=", "-p", String(pid)], {
|
|
97763
|
+
], { timeout: PROCESS_START_LOOKUP_TIMEOUT_MS, windowsHide: true }) : await promisify2(execFile)("ps", ["-o", "lstart=", "-p", String(pid)], {
|
|
97764
|
+
env: { ...process.env, TZ: "UTC", LC_ALL: "C" },
|
|
97765
|
+
timeout: PROCESS_START_LOOKUP_TIMEOUT_MS
|
|
97766
|
+
});
|
|
97764
97767
|
const started = stdout.trim();
|
|
97765
97768
|
return started.length > 0 ? started : null;
|
|
97766
97769
|
} catch {
|
|
@@ -97802,7 +97805,7 @@ function isPidReusedByNonLetta(pid, getCommand = getProcessCommand) {
|
|
|
97802
97805
|
const argv0 = command.split(/\s+/)[0] ?? "";
|
|
97803
97806
|
return basename4(argv0) !== basename4(process.execPath);
|
|
97804
97807
|
}
|
|
97805
|
-
var ownStartTime;
|
|
97808
|
+
var PROCESS_START_LOOKUP_TIMEOUT_MS = 5000, ownStartTime;
|
|
97806
97809
|
var init_process_liveness = () => {};
|
|
97807
97810
|
|
|
97808
97811
|
// src/utils/sleep.ts
|
|
@@ -102660,12 +102663,14 @@ function installPreCommitHookWithPolicy(dir, policy) {
|
|
|
102660
102663
|
function installPreCommitHook(dir, allowRootMemoryLayout = false) {
|
|
102661
102664
|
installPreCommitHookWithPolicy(dir, allowRootMemoryLayout ? "root-marker" : "legacy-only");
|
|
102662
102665
|
}
|
|
102663
|
-
function
|
|
102664
|
-
|
|
102666
|
+
function hasRootMemoryMarker(dir) {
|
|
102667
|
+
return existsSync5(join9(dir, "MEMORY.md")) || spawnSync("git", ["cat-file", "-e", "HEAD:MEMORY.md"], {
|
|
102665
102668
|
cwd: dir,
|
|
102666
102669
|
stdio: "ignore"
|
|
102667
102670
|
}).status === 0;
|
|
102668
|
-
|
|
102671
|
+
}
|
|
102672
|
+
function installLocalMemoryPreCommitHook(dir) {
|
|
102673
|
+
installPreCommitHookWithPolicy(dir, hasRootMemoryMarker(dir) ? "root-marker" : "legacy-only");
|
|
102669
102674
|
}
|
|
102670
102675
|
function installSharedMemoryPreCommitHook(dir) {
|
|
102671
102676
|
installPreCommitHookWithPolicy(dir, "shared-memory");
|
|
@@ -120521,14 +120526,25 @@ __export(exports_personality, {
|
|
|
120521
120526
|
applyPersonalityToMemory: () => applyPersonalityToMemory
|
|
120522
120527
|
});
|
|
120523
120528
|
import { execFile as execFileCb2 } from "node:child_process";
|
|
120524
|
-
import {
|
|
120525
|
-
|
|
120529
|
+
import {
|
|
120530
|
+
existsSync as existsSync17,
|
|
120531
|
+
mkdirSync as mkdirSync11,
|
|
120532
|
+
readdirSync as readdirSync4,
|
|
120533
|
+
readFileSync as readFileSync10,
|
|
120534
|
+
rmdirSync,
|
|
120535
|
+
rmSync as rmSync5,
|
|
120536
|
+
writeFileSync as writeFileSync10
|
|
120537
|
+
} from "node:fs";
|
|
120538
|
+
import { basename as basename6, dirname as dirname11, join as join24 } from "node:path";
|
|
120526
120539
|
import { promisify as promisify5 } from "node:util";
|
|
120527
120540
|
function ensureTrailingNewline2(content) {
|
|
120528
120541
|
return `${content.trimEnd()}
|
|
120529
120542
|
`;
|
|
120530
120543
|
}
|
|
120531
|
-
function getMemoryFileRelativePathForRepo(repoDir, primaryRelativePath, legacyRelativePath) {
|
|
120544
|
+
function getMemoryFileRelativePathForRepo(repoDir, rootRelativePath, primaryRelativePath, legacyRelativePath) {
|
|
120545
|
+
if (existsSync17(join24(repoDir, rootRelativePath)) || hasRootMemoryMarker(repoDir)) {
|
|
120546
|
+
return rootRelativePath;
|
|
120547
|
+
}
|
|
120532
120548
|
const primaryPath = join24(repoDir, primaryRelativePath);
|
|
120533
120549
|
if (existsSync17(primaryPath)) {
|
|
120534
120550
|
return primaryRelativePath;
|
|
@@ -120543,10 +120559,10 @@ function getMemoryFileRelativePathForRepo(repoDir, primaryRelativePath, legacyRe
|
|
|
120543
120559
|
return primaryRelativePath;
|
|
120544
120560
|
}
|
|
120545
120561
|
function getPersonaRelativePathForRepo(repoDir) {
|
|
120546
|
-
return getMemoryFileRelativePathForRepo(repoDir, PRIMARY_PERSONA_RELATIVE_PATH, LEGACY_PERSONA_RELATIVE_PATH);
|
|
120562
|
+
return getMemoryFileRelativePathForRepo(repoDir, ROOT_PERSONA_RELATIVE_PATH, PRIMARY_PERSONA_RELATIVE_PATH, LEGACY_PERSONA_RELATIVE_PATH);
|
|
120547
120563
|
}
|
|
120548
120564
|
function getHumanRelativePathForRepo(repoDir) {
|
|
120549
|
-
return getMemoryFileRelativePathForRepo(repoDir, PRIMARY_HUMAN_RELATIVE_PATH, LEGACY_HUMAN_RELATIVE_PATH);
|
|
120565
|
+
return getMemoryFileRelativePathForRepo(repoDir, ROOT_HUMAN_RELATIVE_PATH, PRIMARY_HUMAN_RELATIVE_PATH, LEGACY_HUMAN_RELATIVE_PATH);
|
|
120550
120566
|
}
|
|
120551
120567
|
async function resolvePersonalityMemoryPromptMode(environment2) {
|
|
120552
120568
|
if (environment2 === "local")
|
|
@@ -120661,22 +120677,64 @@ async function getMemoryCommitAuthor(agentId) {
|
|
|
120661
120677
|
authorEmail: `${agentId}@letta.com`
|
|
120662
120678
|
};
|
|
120663
120679
|
}
|
|
120664
|
-
function
|
|
120680
|
+
function buildRootMemoryFile(relativePath, templatePromptAssetName, body, description) {
|
|
120681
|
+
const { frontmatter, body: normalizedBody } = parseMdxFrontmatter(buildDefaultMemoryFile(templatePromptAssetName, body, description));
|
|
120682
|
+
const name = memoryNameFromPath(basename6(relativePath));
|
|
120683
|
+
return `${serializeFrontmatter({
|
|
120684
|
+
name,
|
|
120685
|
+
description: frontmatter.description?.trim() || name
|
|
120686
|
+
})}
|
|
120687
|
+
|
|
120688
|
+
${ensureTrailingNewline2(normalizedBody.trim())}`;
|
|
120689
|
+
}
|
|
120690
|
+
function applyPersonalityFiles(filesToUpdate, undoLog) {
|
|
120665
120691
|
const changedPaths = [];
|
|
120666
120692
|
for (const file of filesToUpdate) {
|
|
120667
120693
|
const existingContent = existsSync17(file.absolutePath) ? readFileSync10(file.absolutePath, "utf-8") : null;
|
|
120694
|
+
if (file.onlyIfBlank && existingContent !== null && existingContent.replace(FRONTMATTER_REGEX, "").trim()) {
|
|
120695
|
+
continue;
|
|
120696
|
+
}
|
|
120668
120697
|
const nextContent = existingContent ? replaceBodyPreservingFrontmatter(existingContent, file.content, {
|
|
120669
120698
|
description: file.description
|
|
120670
|
-
}) : buildDefaultMemoryFile(file.templatePromptAssetName, file.content, file.description);
|
|
120699
|
+
}) : file.relativePath.includes("/") ? buildDefaultMemoryFile(file.templatePromptAssetName, file.content, file.description) : buildRootMemoryFile(file.relativePath, file.templatePromptAssetName, file.content, file.description);
|
|
120671
120700
|
if (existingContent !== null && normalizeComparableContent(existingContent) === normalizeComparableContent(nextContent)) {
|
|
120672
120701
|
continue;
|
|
120673
120702
|
}
|
|
120703
|
+
const createdDirs = [];
|
|
120704
|
+
for (let dir = dirname11(file.absolutePath);!existsSync17(dir); dir = dirname11(dir)) {
|
|
120705
|
+
createdDirs.push(dir);
|
|
120706
|
+
}
|
|
120707
|
+
undoLog.push({
|
|
120708
|
+
absolutePath: file.absolutePath,
|
|
120709
|
+
previousContent: existingContent,
|
|
120710
|
+
createdDirs
|
|
120711
|
+
});
|
|
120674
120712
|
mkdirSync11(dirname11(file.absolutePath), { recursive: true });
|
|
120675
120713
|
writeFileSync10(file.absolutePath, nextContent, "utf-8");
|
|
120676
120714
|
changedPaths.push(file.relativePath);
|
|
120677
120715
|
}
|
|
120678
120716
|
return changedPaths;
|
|
120679
120717
|
}
|
|
120718
|
+
async function undoPersonalityFiles(repoDir, undoLog) {
|
|
120719
|
+
if (undoLog.length === 0)
|
|
120720
|
+
return;
|
|
120721
|
+
for (const entry of [...undoLog].reverse()) {
|
|
120722
|
+
try {
|
|
120723
|
+
if (entry.previousContent === null) {
|
|
120724
|
+
rmSync5(entry.absolutePath, { force: true });
|
|
120725
|
+
} else {
|
|
120726
|
+
writeFileSync10(entry.absolutePath, entry.previousContent, "utf-8");
|
|
120727
|
+
}
|
|
120728
|
+
for (const dir of entry.createdDirs) {
|
|
120729
|
+
if (existsSync17(dir) && readdirSync4(dir).length === 0)
|
|
120730
|
+
rmdirSync(dir);
|
|
120731
|
+
}
|
|
120732
|
+
} catch {}
|
|
120733
|
+
}
|
|
120734
|
+
try {
|
|
120735
|
+
await execFile4("git", ["reset", "-q", "--", ...undoLog.map((entry) => entry.absolutePath)], { cwd: repoDir, timeout: 1e4 });
|
|
120736
|
+
} catch {}
|
|
120737
|
+
}
|
|
120680
120738
|
async function applyPersonalityToMemory(params) {
|
|
120681
120739
|
const personality = getPersonalityOption(params.personalityId);
|
|
120682
120740
|
const isLocalMemfs = getBackend().capabilities.localMemfs;
|
|
@@ -120709,11 +120767,30 @@ async function applyPersonalityToMemory(params) {
|
|
|
120709
120767
|
absolutePath: humanPath,
|
|
120710
120768
|
templatePromptAssetName: blockDefinitions.human.templatePromptAssetName,
|
|
120711
120769
|
content: blockDefinitions.human.value,
|
|
120712
|
-
description: blockDefinitions.human.description
|
|
120770
|
+
description: blockDefinitions.human.description,
|
|
120771
|
+
onlyIfBlank: true
|
|
120713
120772
|
}
|
|
120714
120773
|
];
|
|
120715
|
-
const
|
|
120716
|
-
|
|
120774
|
+
const commitMessage = params.commitMessage ?? `chore(personality): switch to ${personality.label}`;
|
|
120775
|
+
const undoLog = [];
|
|
120776
|
+
let commitResult = null;
|
|
120777
|
+
try {
|
|
120778
|
+
const changedPaths = applyPersonalityFiles(filesToUpdate, undoLog);
|
|
120779
|
+
if (changedPaths.length > 0) {
|
|
120780
|
+
const author = await getMemoryCommitAuthor(params.agentId);
|
|
120781
|
+
commitResult = await commitMemoryWrite({
|
|
120782
|
+
memoryDir: repoDir,
|
|
120783
|
+
pathspecs: changedPaths,
|
|
120784
|
+
reason: commitMessage,
|
|
120785
|
+
author,
|
|
120786
|
+
syncMode: isLocalMemfs ? "local" : "remote"
|
|
120787
|
+
});
|
|
120788
|
+
}
|
|
120789
|
+
} catch (error4) {
|
|
120790
|
+
await undoPersonalityFiles(repoDir, undoLog);
|
|
120791
|
+
throw error4;
|
|
120792
|
+
}
|
|
120793
|
+
if (!commitResult) {
|
|
120717
120794
|
return {
|
|
120718
120795
|
changed: false,
|
|
120719
120796
|
personality,
|
|
@@ -120721,16 +120798,8 @@ async function applyPersonalityToMemory(params) {
|
|
|
120721
120798
|
humanRelativePath
|
|
120722
120799
|
};
|
|
120723
120800
|
}
|
|
120724
|
-
const commitMessage = params.commitMessage ?? `chore(personality): switch to ${personality.label}`;
|
|
120725
|
-
const author = await getMemoryCommitAuthor(params.agentId);
|
|
120726
|
-
const commitResult = await commitMemoryWrite({
|
|
120727
|
-
memoryDir: repoDir,
|
|
120728
|
-
pathspecs: changedPaths,
|
|
120729
|
-
reason: commitMessage,
|
|
120730
|
-
author,
|
|
120731
|
-
syncMode: isLocalMemfs ? "local" : "remote"
|
|
120732
|
-
});
|
|
120733
120801
|
if (!commitResult.committed) {
|
|
120802
|
+
await undoPersonalityFiles(repoDir, undoLog);
|
|
120734
120803
|
return {
|
|
120735
120804
|
changed: false,
|
|
120736
120805
|
personality,
|
|
@@ -120746,14 +120815,16 @@ async function applyPersonalityToMemory(params) {
|
|
|
120746
120815
|
commitMessage
|
|
120747
120816
|
};
|
|
120748
120817
|
}
|
|
120749
|
-
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";
|
|
120818
|
+
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", ROOT_PERSONA_RELATIVE_PATH = "persona.md", ROOT_HUMAN_RELATIVE_PATH = "human.md";
|
|
120750
120819
|
var init_personality = __esm(() => {
|
|
120751
120820
|
init_backend2();
|
|
120752
120821
|
init_server_url();
|
|
120822
|
+
init_initial_memory();
|
|
120753
120823
|
init_settings_manager();
|
|
120754
120824
|
init_memory3();
|
|
120755
120825
|
init_memory_filesystem2();
|
|
120756
120826
|
init_memory_git();
|
|
120827
|
+
init_memory_git_hooks();
|
|
120757
120828
|
init_personality_presets();
|
|
120758
120829
|
execFile4 = promisify5(execFileCb2);
|
|
120759
120830
|
});
|
|
@@ -147019,12 +147090,12 @@ function mergeObjects(target2, ...sources) {
|
|
|
147019
147090
|
});
|
|
147020
147091
|
return target2;
|
|
147021
147092
|
}
|
|
147022
|
-
function
|
|
147093
|
+
function basename7(path8) {
|
|
147023
147094
|
const idx = ~path8.lastIndexOf("/") || ~path8.lastIndexOf("\\");
|
|
147024
147095
|
if (idx === 0) {
|
|
147025
147096
|
return path8;
|
|
147026
147097
|
} else if (~idx === path8.length - 1) {
|
|
147027
|
-
return
|
|
147098
|
+
return basename7(path8.substring(0, path8.length - 1));
|
|
147028
147099
|
} else {
|
|
147029
147100
|
return path8.substr(~idx + 1);
|
|
147030
147101
|
}
|
|
@@ -148267,7 +148338,7 @@ var CAPTURING_REGEX_SOURCE, RegexSource = class {
|
|
|
148267
148338
|
this._contentNameIsCapturing = RegexSource.hasCaptures(this._contentName);
|
|
148268
148339
|
}
|
|
148269
148340
|
get debugName() {
|
|
148270
|
-
const location = this.$location ? `${
|
|
148341
|
+
const location = this.$location ? `${basename7(this.$location.filename)}:${this.$location.line}` : "unknown";
|
|
148271
148342
|
return `${this.constructor.name}#${this.id} @ ${location}`;
|
|
148272
148343
|
}
|
|
148273
148344
|
getName(lineText, captureIndices) {
|
|
@@ -156956,16 +157027,16 @@ function clipStyledSpans(spans, maxColumns) {
|
|
|
156956
157027
|
return { spans: clipped, clipped: false };
|
|
156957
157028
|
}
|
|
156958
157029
|
function languageFromPath(filePath) {
|
|
156959
|
-
const
|
|
156960
|
-
const lower2 =
|
|
157030
|
+
const basename8 = filePath.split("/").pop() ?? filePath;
|
|
157031
|
+
const lower2 = basename8.toLowerCase();
|
|
156961
157032
|
if (lower2 === "makefile")
|
|
156962
157033
|
return "makefile";
|
|
156963
157034
|
if (lower2 === "dockerfile")
|
|
156964
157035
|
return "dockerfile";
|
|
156965
|
-
const dotIdx =
|
|
157036
|
+
const dotIdx = basename8.lastIndexOf(".");
|
|
156966
157037
|
if (dotIdx < 0)
|
|
156967
157038
|
return;
|
|
156968
|
-
const ext =
|
|
157039
|
+
const ext = basename8.slice(dotIdx + 1).toLowerCase();
|
|
156969
157040
|
return Object.hasOwn(EXT_TO_LANG, ext) ? EXT_TO_LANG[ext] : undefined;
|
|
156970
157041
|
}
|
|
156971
157042
|
function highlightCommand(command) {
|
|
@@ -158097,7 +158168,7 @@ var init_paste_registry = __esm(() => {
|
|
|
158097
158168
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
158098
158169
|
import { existsSync as existsSync20, readFileSync as readFileSync13, statSync as statSync6, unlinkSync as unlinkSync5 } from "node:fs";
|
|
158099
158170
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
158100
|
-
import { basename as
|
|
158171
|
+
import { basename as basename8, extname, isAbsolute as isAbsolute5, join as join28, resolve as resolve11 } from "node:path";
|
|
158101
158172
|
function countLines(text2) {
|
|
158102
158173
|
return (text2.match(/\r\n|\r|\n/g) || []).length + 1;
|
|
158103
158174
|
}
|
|
@@ -158175,7 +158246,7 @@ function translatePasteForImages(paste) {
|
|
|
158175
158246
|
const id2 = allocateImage({
|
|
158176
158247
|
data: b64,
|
|
158177
158248
|
mediaType: mt,
|
|
158178
|
-
filename:
|
|
158249
|
+
filename: basename8(filePath)
|
|
158179
158250
|
});
|
|
158180
158251
|
s3 = `[Image #${id2}]`;
|
|
158181
158252
|
}
|
|
@@ -159481,13 +159552,13 @@ import {
|
|
|
159481
159552
|
createWriteStream as createWriteStream2,
|
|
159482
159553
|
existsSync as existsSync21,
|
|
159483
159554
|
mkdirSync as mkdirSync12,
|
|
159484
|
-
readdirSync as
|
|
159555
|
+
readdirSync as readdirSync5,
|
|
159485
159556
|
renameSync as renameSync4,
|
|
159486
|
-
rmSync as
|
|
159557
|
+
rmSync as rmSync6,
|
|
159487
159558
|
statSync as statSync7
|
|
159488
159559
|
} from "node:fs";
|
|
159489
159560
|
import { arch, homedir as homedir6, platform as platform3 } from "node:os";
|
|
159490
|
-
import { basename as
|
|
159561
|
+
import { basename as basename9, join as join29 } from "node:path";
|
|
159491
159562
|
import { Readable as Readable2 } from "node:stream";
|
|
159492
159563
|
import { pipeline as pipeline4 } from "node:stream/promises";
|
|
159493
159564
|
function toDisplayPath(value) {
|
|
@@ -159817,7 +159888,7 @@ function findBinaryRecursively(rootDir, binaryName) {
|
|
|
159817
159888
|
const currentDir = stack.pop();
|
|
159818
159889
|
if (!currentDir)
|
|
159819
159890
|
continue;
|
|
159820
|
-
for (const entry of
|
|
159891
|
+
for (const entry of readdirSync5(currentDir, { withFileTypes: true })) {
|
|
159821
159892
|
const fullPath = join29(currentDir, entry.name);
|
|
159822
159893
|
if (entry.isFile() && entry.name === binaryName) {
|
|
159823
159894
|
return fullPath;
|
|
@@ -159860,8 +159931,8 @@ async function downloadFd() {
|
|
|
159860
159931
|
chmodSync4(FD_LOCAL_PATH, 493);
|
|
159861
159932
|
}
|
|
159862
159933
|
} finally {
|
|
159863
|
-
|
|
159864
|
-
|
|
159934
|
+
rmSync6(archivePath, { force: true });
|
|
159935
|
+
rmSync6(extractDir, { recursive: true, force: true });
|
|
159865
159936
|
}
|
|
159866
159937
|
return FD_LOCAL_PATH;
|
|
159867
159938
|
}
|
|
@@ -159998,7 +160069,7 @@ class FileAutocompleteProvider {
|
|
|
159998
160069
|
return `${toDisplayPath(displayBase)}${normalizedRelativePath}`;
|
|
159999
160070
|
}
|
|
160000
160071
|
scoreEntry(filePath, query3, isDirectory) {
|
|
160001
|
-
const fileName =
|
|
160072
|
+
const fileName = basename9(filePath);
|
|
160002
160073
|
const lowerFileName = fileName.toLowerCase();
|
|
160003
160074
|
const lowerQuery = query3.toLowerCase();
|
|
160004
160075
|
let score = 0;
|
|
@@ -160036,7 +160107,7 @@ class FileAutocompleteProvider {
|
|
|
160036
160107
|
for (const { path: entryPath, isDirectory } of topEntries) {
|
|
160037
160108
|
const pathWithoutSlash = isDirectory ? entryPath.slice(0, -1) : entryPath;
|
|
160038
160109
|
const displayPath = scopedQuery ? this.scopedPathForDisplay(scopedQuery.displayBase, pathWithoutSlash) : pathWithoutSlash;
|
|
160039
|
-
const entryName =
|
|
160110
|
+
const entryName = basename9(pathWithoutSlash);
|
|
160040
160111
|
const completionPath = isDirectory ? `${displayPath}/` : displayPath;
|
|
160041
160112
|
const value = buildCompletionValue(completionPath, {
|
|
160042
160113
|
isDirectory,
|
|
@@ -160186,14 +160257,14 @@ var init_local = __esm(() => {
|
|
|
160186
160257
|
});
|
|
160187
160258
|
|
|
160188
160259
|
// src/cli/helpers/local-agent-listing.ts
|
|
160189
|
-
import { existsSync as existsSync22, readdirSync as
|
|
160260
|
+
import { existsSync as existsSync22, readdirSync as readdirSync6, readFileSync as readFileSync14, statSync as statSync8 } from "node:fs";
|
|
160190
160261
|
import { join as join30 } from "node:path";
|
|
160191
160262
|
function listLocalAgentsFromDisk() {
|
|
160192
160263
|
const storageDir = getLocalBackendStorageDir();
|
|
160193
160264
|
const agentsDir = join30(storageDir, "agents");
|
|
160194
160265
|
if (!existsSync22(agentsDir))
|
|
160195
160266
|
return [];
|
|
160196
|
-
const files =
|
|
160267
|
+
const files = readdirSync6(agentsDir).filter((f4) => f4.endsWith(".json"));
|
|
160197
160268
|
const agents = [];
|
|
160198
160269
|
for (const file of files) {
|
|
160199
160270
|
try {
|
|
@@ -164766,7 +164837,7 @@ __export(exports_runtime_deps, {
|
|
|
164766
164837
|
import { existsSync as existsSync26 } from "node:fs";
|
|
164767
164838
|
import { mkdir as mkdir4, symlink, writeFile as writeFile5 } from "node:fs/promises";
|
|
164768
164839
|
import { createRequire as createRequire3 } from "node:module";
|
|
164769
|
-
import { basename as
|
|
164840
|
+
import { basename as basename10, join as join33 } from "node:path";
|
|
164770
164841
|
import { pathToFileURL } from "node:url";
|
|
164771
164842
|
function getPackageDisplayName(packageSpec) {
|
|
164772
164843
|
if (!packageSpec.startsWith("@")) {
|
|
@@ -164917,7 +164988,7 @@ async function ensureChannelRuntimeInstalled(channelId) {
|
|
|
164917
164988
|
return false;
|
|
164918
164989
|
}
|
|
164919
164990
|
const spec = getChannelPluginMetadata(channelId);
|
|
164920
|
-
const packageLabels = spec.runtimePackages.map((pkg) =>
|
|
164991
|
+
const packageLabels = spec.runtimePackages.map((pkg) => basename10(getPackageDisplayName(pkg)));
|
|
164921
164992
|
console.log(`[Channels] Installing ${spec.displayName} runtime dependencies (${packageLabels.join(", ")})...`);
|
|
164922
164993
|
await installChannelRuntime(channelId);
|
|
164923
164994
|
console.log(`[Channels] ${spec.displayName} runtime dependencies installed.`);
|
|
@@ -166112,9 +166183,9 @@ __export(exports_transcription, {
|
|
|
166112
166183
|
isTranscriptionConfigured: () => isTranscriptionConfigured
|
|
166113
166184
|
});
|
|
166114
166185
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
166115
|
-
import { mkdtempSync as mkdtempSync3, readFileSync as readFileSync19, rmSync as
|
|
166186
|
+
import { mkdtempSync as mkdtempSync3, readFileSync as readFileSync19, rmSync as rmSync7 } from "node:fs";
|
|
166116
166187
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
166117
|
-
import { basename as
|
|
166188
|
+
import { basename as basename11, extname as extname2, join as join34 } from "node:path";
|
|
166118
166189
|
function audioMimeTypeForPath(localPath) {
|
|
166119
166190
|
switch (extname2(localPath).toLowerCase()) {
|
|
166120
166191
|
case ".flac":
|
|
@@ -166143,7 +166214,7 @@ function prepareOpenAiTranscriptionFile(localPath) {
|
|
|
166143
166214
|
return { localPath };
|
|
166144
166215
|
}
|
|
166145
166216
|
const tempDir = mkdtempSync3(join34(tmpdir7(), "letta-transcription-"));
|
|
166146
|
-
const convertedPath = join34(tempDir, `${
|
|
166217
|
+
const convertedPath = join34(tempDir, `${basename11(localPath)}.m4a`);
|
|
166147
166218
|
try {
|
|
166148
166219
|
execFileSync5("ffmpeg", [
|
|
166149
166220
|
"-y",
|
|
@@ -166157,12 +166228,12 @@ function prepareOpenAiTranscriptionFile(localPath) {
|
|
|
166157
166228
|
convertedPath
|
|
166158
166229
|
], { stdio: "ignore", timeout: TRANSCRIPTION_TIMEOUT_MS });
|
|
166159
166230
|
} catch (error4) {
|
|
166160
|
-
|
|
166231
|
+
rmSync7(tempDir, { recursive: true, force: true });
|
|
166161
166232
|
throw new Error(`Unsupported audio format ${extname2(localPath).replace(/^\./, "") || "unknown"}; ffmpeg conversion failed. ffmpeg is required to transcribe this audio format; install ffmpeg on the channel listener machine. ${error4 instanceof Error ? error4.message : String(error4)}`);
|
|
166162
166233
|
}
|
|
166163
166234
|
return {
|
|
166164
166235
|
localPath: convertedPath,
|
|
166165
|
-
cleanup: () =>
|
|
166236
|
+
cleanup: () => rmSync7(tempDir, { recursive: true, force: true })
|
|
166166
166237
|
};
|
|
166167
166238
|
}
|
|
166168
166239
|
function isTranscriptionConfigured() {
|
|
@@ -166180,7 +166251,7 @@ async function transcribeAudioFile(localPath) {
|
|
|
166180
166251
|
const prepared = prepareOpenAiTranscriptionFile(localPath);
|
|
166181
166252
|
try {
|
|
166182
166253
|
const buffer = readFileSync19(prepared.localPath);
|
|
166183
|
-
const filename =
|
|
166254
|
+
const filename = basename11(prepared.localPath);
|
|
166184
166255
|
const formData = new FormData;
|
|
166185
166256
|
const blob = new Blob([buffer], {
|
|
166186
166257
|
type: audioMimeTypeForPath(prepared.localPath)
|
|
@@ -166237,7 +166308,7 @@ var init_transcription = __esm(() => {
|
|
|
166237
166308
|
// src/channels/telegram/media.ts
|
|
166238
166309
|
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
166239
166310
|
import { mkdir as mkdir5, writeFile as writeFile6 } from "node:fs/promises";
|
|
166240
|
-
import { basename as
|
|
166311
|
+
import { basename as basename12, extname as extname3, join as join35 } from "node:path";
|
|
166241
166312
|
function normalizeTelegramMimeType(mimeType) {
|
|
166242
166313
|
const normalized = mimeType?.split(";")[0]?.trim().toLowerCase();
|
|
166243
166314
|
return normalized || undefined;
|
|
@@ -166395,7 +166466,7 @@ function inferUploadMethodFromMimeType(mimeType) {
|
|
|
166395
166466
|
return null;
|
|
166396
166467
|
}
|
|
166397
166468
|
function detectTelegramUploadMethod(filePath, fileName) {
|
|
166398
|
-
const inferredName = (fileName ??
|
|
166469
|
+
const inferredName = (fileName ?? basename12(filePath)).toLowerCase();
|
|
166399
166470
|
const extension = extname3(inferredName);
|
|
166400
166471
|
const mimeType = inferMimeTypeFromName(inferredName);
|
|
166401
166472
|
const byMimeType = inferUploadMethodFromMimeType(mimeType);
|
|
@@ -166506,7 +166577,7 @@ function buildTelegramFileUrl(token2, filePath) {
|
|
|
166506
166577
|
return `https://api.telegram.org/file/bot${token2}/${filePath}`;
|
|
166507
166578
|
}
|
|
166508
166579
|
function inferAttachmentFileName(params) {
|
|
166509
|
-
const hintedName = params.candidate.name?.trim() ||
|
|
166580
|
+
const hintedName = params.candidate.name?.trim() || basename12(params.remotePath) || "attachment";
|
|
166510
166581
|
if (extname3(hintedName)) {
|
|
166511
166582
|
return hintedName;
|
|
166512
166583
|
}
|
|
@@ -169896,7 +169967,7 @@ var init_attachment_download = __esm(() => {
|
|
|
169896
169967
|
|
|
169897
169968
|
// src/channels/slack/file-upload.ts
|
|
169898
169969
|
import { readFile as readFile7 } from "node:fs/promises";
|
|
169899
|
-
import { basename as
|
|
169970
|
+
import { basename as basename13, extname as extname4 } from "node:path";
|
|
169900
169971
|
function resolveUploadMimeType(filePath) {
|
|
169901
169972
|
switch (extname4(filePath).toLowerCase()) {
|
|
169902
169973
|
case ".png":
|
|
@@ -169923,7 +169994,7 @@ async function uploadSlackFile(slackClient, msg) {
|
|
|
169923
169994
|
throw new Error("mediaPath is required for Slack file uploads.");
|
|
169924
169995
|
}
|
|
169925
169996
|
const buffer = await readFile7(msg.mediaPath);
|
|
169926
|
-
const uploadFileName = msg.fileName ??
|
|
169997
|
+
const uploadFileName = msg.fileName ?? basename13(msg.mediaPath);
|
|
169927
169998
|
const uploadTitle = msg.title ?? uploadFileName;
|
|
169928
169999
|
const uploadMimeType = resolveUploadMimeType(uploadFileName);
|
|
169929
170000
|
const uploadUrlResp = await slackClient.files.getUploadURLExternal({
|
|
@@ -173198,18 +173269,22 @@ function unescapeXml(str) {
|
|
|
173198
173269
|
function resolveNotificationScope(parentScope) {
|
|
173199
173270
|
const runtime = getRuntimeContext();
|
|
173200
173271
|
const actingUserId = runtime?.suppressActingUserFallback ? null : runtime?.actingUserId;
|
|
173272
|
+
const clientMessageIds = runtime?.resolveClientMessageIds?.() ?? [];
|
|
173273
|
+
const correlation = clientMessageIds.length > 0 ? { clientMessageIds } : {};
|
|
173201
173274
|
if (parentScope?.agentId) {
|
|
173202
173275
|
return {
|
|
173203
173276
|
agentId: parentScope.agentId,
|
|
173204
173277
|
conversationId: parentScope.conversationId || "default",
|
|
173205
|
-
actingUserId
|
|
173278
|
+
actingUserId,
|
|
173279
|
+
...correlation
|
|
173206
173280
|
};
|
|
173207
173281
|
}
|
|
173208
173282
|
try {
|
|
173209
173283
|
return {
|
|
173210
173284
|
agentId: getCurrentAgentId(),
|
|
173211
173285
|
conversationId: getConversationId() ?? "default",
|
|
173212
|
-
actingUserId
|
|
173286
|
+
actingUserId,
|
|
173287
|
+
...correlation
|
|
173213
173288
|
};
|
|
173214
173289
|
} catch {
|
|
173215
173290
|
return;
|
|
@@ -174664,7 +174739,7 @@ var init_typing_controller2 = __esm(() => {
|
|
|
174664
174739
|
});
|
|
174665
174740
|
|
|
174666
174741
|
// src/channels/discord/adapter.ts
|
|
174667
|
-
import { basename as
|
|
174742
|
+
import { basename as basename14 } from "node:path";
|
|
174668
174743
|
function createDiscordAdapter(config) {
|
|
174669
174744
|
let client = null;
|
|
174670
174745
|
let running = false;
|
|
@@ -175210,7 +175285,7 @@ function createDiscordAdapter(config) {
|
|
|
175210
175285
|
files: [
|
|
175211
175286
|
{
|
|
175212
175287
|
attachment: msg.mediaPath,
|
|
175213
|
-
name: msg.fileName ??
|
|
175288
|
+
name: msg.fileName ?? basename14(msg.mediaPath)
|
|
175214
175289
|
}
|
|
175215
175290
|
]
|
|
175216
175291
|
});
|
|
@@ -175729,7 +175804,7 @@ var init_attachment_policy = __esm(() => {
|
|
|
175729
175804
|
// src/channels/whatsapp/media.ts
|
|
175730
175805
|
import { randomUUID as randomUUID20 } from "node:crypto";
|
|
175731
175806
|
import { mkdir as mkdir7, writeFile as writeFile8 } from "node:fs/promises";
|
|
175732
|
-
import { basename as
|
|
175807
|
+
import { basename as basename15, extname as extname6, join as join39 } from "node:path";
|
|
175733
175808
|
function unwrapWhatsAppMessageContent(message) {
|
|
175734
175809
|
if (!message || typeof message !== "object")
|
|
175735
175810
|
return null;
|
|
@@ -175932,7 +176007,7 @@ function buildWhatsAppOutboundPayload(msg, resolvedMedia) {
|
|
|
175932
176007
|
return { text: msg.text };
|
|
175933
176008
|
}
|
|
175934
176009
|
const mediaPath = resolvedMedia?.mediaPath ?? msg.mediaPath;
|
|
175935
|
-
const fileName = resolvedMedia ?
|
|
176010
|
+
const fileName = resolvedMedia ? basename15(mediaPath) : msg.fileName || basename15(mediaPath);
|
|
175936
176011
|
const extension = resolvedMedia ? extname6(mediaPath).toLowerCase() : getWhatsAppOutboundMediaExtension(msg);
|
|
175937
176012
|
const caption = msg.text?.trim() || msg.title?.trim() || undefined;
|
|
175938
176013
|
if (WHATSAPP_IMAGE_EXTENSIONS.has(extension)) {
|
|
@@ -176834,7 +176909,7 @@ var init_state = __esm(() => {
|
|
|
176834
176909
|
});
|
|
176835
176910
|
|
|
176836
176911
|
// src/channels/whatsapp/session.ts
|
|
176837
|
-
import { mkdirSync as mkdirSync20, readFileSync as readFileSync23, rmSync as
|
|
176912
|
+
import { mkdirSync as mkdirSync20, readFileSync as readFileSync23, rmSync as rmSync8, writeFileSync as writeFileSync17 } from "node:fs";
|
|
176838
176913
|
import { join as join40 } from "node:path";
|
|
176839
176914
|
function shouldDropLine(line) {
|
|
176840
176915
|
if (typeof line !== "string")
|
|
@@ -176945,7 +177020,7 @@ function acquireWhatsAppSessionLease(accountId, options = {}) {
|
|
|
176945
177020
|
if (activeSessionLeases.get(accountId) === lockDir) {
|
|
176946
177021
|
activeSessionLeases.delete(accountId);
|
|
176947
177022
|
}
|
|
176948
|
-
|
|
177023
|
+
rmSync8(lockDir, { recursive: true, force: true });
|
|
176949
177024
|
}
|
|
176950
177025
|
};
|
|
176951
177026
|
} catch (error4) {
|
|
@@ -176954,7 +177029,7 @@ function acquireWhatsAppSessionLease(accountId, options = {}) {
|
|
|
176954
177029
|
}
|
|
176955
177030
|
const owner = readLeaseOwner(lockDir);
|
|
176956
177031
|
if (owner.pid && !isProcessAlive2(owner.pid)) {
|
|
176957
|
-
|
|
177032
|
+
rmSync8(lockDir, { recursive: true, force: true });
|
|
176958
177033
|
continue;
|
|
176959
177034
|
}
|
|
176960
177035
|
const ownerLabel = owner.pid ? `PID ${owner.pid}${owner.command ? ` (${owner.command})` : ""}` : "an unknown live process";
|
|
@@ -178531,14 +178606,14 @@ import { randomUUID as randomUUID24 } from "node:crypto";
|
|
|
178531
178606
|
import {
|
|
178532
178607
|
copyFileSync as copyFileSync2,
|
|
178533
178608
|
mkdirSync as mkdirSync21,
|
|
178534
|
-
readdirSync as
|
|
178609
|
+
readdirSync as readdirSync7,
|
|
178535
178610
|
readFileSync as readFileSync24,
|
|
178536
178611
|
realpathSync as realpathSync5,
|
|
178537
178612
|
statSync as statSync11
|
|
178538
178613
|
} from "node:fs";
|
|
178539
178614
|
import { homedir as homedir9 } from "node:os";
|
|
178540
178615
|
import {
|
|
178541
|
-
basename as
|
|
178616
|
+
basename as basename16,
|
|
178542
178617
|
extname as extname7,
|
|
178543
178618
|
isAbsolute as isAbsolute8,
|
|
178544
178619
|
join as join42,
|
|
@@ -178654,7 +178729,7 @@ function getSignalAttachmentSearchDirs() {
|
|
|
178654
178729
|
const dirs = [];
|
|
178655
178730
|
const localShare = join42(homedir9(), ".local", "share");
|
|
178656
178731
|
try {
|
|
178657
|
-
for (const entry of
|
|
178732
|
+
for (const entry of readdirSync7(localShare, { withFileTypes: true })) {
|
|
178658
178733
|
if (!entry.isDirectory() || !entry.name.startsWith("signal-cli")) {
|
|
178659
178734
|
continue;
|
|
178660
178735
|
}
|
|
@@ -178757,7 +178832,7 @@ function resolveRecentSignalAttachmentPath(params) {
|
|
|
178757
178832
|
for (const baseDir of getSignalAttachmentSearchDirs()) {
|
|
178758
178833
|
let entries;
|
|
178759
178834
|
try {
|
|
178760
|
-
entries =
|
|
178835
|
+
entries = readdirSync7(baseDir, { withFileTypes: true });
|
|
178761
178836
|
} catch {
|
|
178762
178837
|
continue;
|
|
178763
178838
|
}
|
|
@@ -178797,13 +178872,13 @@ function resolveSignalAttachmentFileName(attachment, sourcePath) {
|
|
|
178797
178872
|
if (hintedName && !hintedName.includes("/") && !hintedName.includes("\\")) {
|
|
178798
178873
|
return hintedName;
|
|
178799
178874
|
}
|
|
178800
|
-
return
|
|
178875
|
+
return basename16(sourcePath) || "attachment";
|
|
178801
178876
|
}
|
|
178802
178877
|
function copySignalAttachment(params) {
|
|
178803
178878
|
const sourceStat = statSync11(params.sourcePath);
|
|
178804
178879
|
const sizeBytes = typeof params.attachment.size === "number" && params.attachment.size >= 0 ? params.attachment.size : sourceStat.size;
|
|
178805
178880
|
if (sizeBytes > params.maxBytes || sourceStat.size > params.maxBytes) {
|
|
178806
|
-
console.warn(`[Signal] Skipping attachment ${params.attachment.filename ?? params.attachment.id ??
|
|
178881
|
+
console.warn(`[Signal] Skipping attachment ${params.attachment.filename ?? params.attachment.id ?? basename16(params.sourcePath)}: ${Math.max(sizeBytes, sourceStat.size)} bytes exceeds Signal download limit (${params.maxBytes} bytes).`);
|
|
178807
178882
|
return null;
|
|
178808
178883
|
}
|
|
178809
178884
|
const fileName = resolveSignalAttachmentFileName(params.attachment, params.sourcePath);
|
|
@@ -180319,7 +180394,7 @@ __export(exports_plugin_registry, {
|
|
|
180319
180394
|
getChannelDisplayName: () => getChannelDisplayName,
|
|
180320
180395
|
__testClearUserChannelPluginCache: () => __testClearUserChannelPluginCache
|
|
180321
180396
|
});
|
|
180322
|
-
import { existsSync as existsSync29, readdirSync as
|
|
180397
|
+
import { existsSync as existsSync29, readdirSync as readdirSync8, readFileSync as readFileSync25 } from "node:fs";
|
|
180323
180398
|
import { resolve as resolve13, sep as sep3 } from "node:path";
|
|
180324
180399
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
180325
180400
|
function isValidChannelId(value) {
|
|
@@ -180415,7 +180490,7 @@ function discoverUserChannelRegistrations() {
|
|
|
180415
180490
|
}
|
|
180416
180491
|
let entries;
|
|
180417
180492
|
try {
|
|
180418
|
-
entries =
|
|
180493
|
+
entries = readdirSync8(channelsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
180419
180494
|
} catch {
|
|
180420
180495
|
return registrations;
|
|
180421
180496
|
}
|
|
@@ -193926,7 +194001,7 @@ import {
|
|
|
193926
194001
|
mkdirSync as mkdirSync23,
|
|
193927
194002
|
readFileSync as readFileSync28,
|
|
193928
194003
|
renameSync as renameSync7,
|
|
193929
|
-
rmSync as
|
|
194004
|
+
rmSync as rmSync9,
|
|
193930
194005
|
statSync as statSync12,
|
|
193931
194006
|
writeFileSync as writeFileSync19
|
|
193932
194007
|
} from "node:fs";
|
|
@@ -194019,7 +194094,7 @@ function isLockStale(lockDir) {
|
|
|
194019
194094
|
}
|
|
194020
194095
|
function stealLock(lockDir) {
|
|
194021
194096
|
try {
|
|
194022
|
-
|
|
194097
|
+
rmSync9(lockDir, { recursive: true, force: true });
|
|
194023
194098
|
} catch {}
|
|
194024
194099
|
}
|
|
194025
194100
|
function acquireLock() {
|
|
@@ -194041,7 +194116,7 @@ function acquireLock() {
|
|
|
194041
194116
|
try {
|
|
194042
194117
|
const current = readLockOwner(lockDir);
|
|
194043
194118
|
if (current && current.token === token2) {
|
|
194044
|
-
|
|
194119
|
+
rmSync9(lockDir, { recursive: true, force: true });
|
|
194045
194120
|
}
|
|
194046
194121
|
} catch {}
|
|
194047
194122
|
}
|
|
@@ -211690,7 +211765,7 @@ var init_mcp_client = __esm(() => {
|
|
|
211690
211765
|
init_streamableHttp();
|
|
211691
211766
|
DEFAULT_CLIENT_INFO = {
|
|
211692
211767
|
name: "letta-code",
|
|
211693
|
-
version: "0.34.
|
|
211768
|
+
version: "0.34.37"
|
|
211694
211769
|
};
|
|
211695
211770
|
});
|
|
211696
211771
|
|
|
@@ -213803,7 +213878,7 @@ import {
|
|
|
213803
213878
|
linkSync as linkSync2,
|
|
213804
213879
|
mkdirSync as mkdirSync26,
|
|
213805
213880
|
readFileSync as readFileSync30,
|
|
213806
|
-
rmSync as
|
|
213881
|
+
rmSync as rmSync10,
|
|
213807
213882
|
writeFileSync as writeFileSync21
|
|
213808
213883
|
} from "node:fs";
|
|
213809
213884
|
import { link as link3, mkdir as mkdir8, readFile as readFile8, rm as rm5, writeFile as writeFile9 } from "node:fs/promises";
|
|
@@ -213859,7 +213934,7 @@ function createInitializedTokenLinkSync(targetPath, ownerToken) {
|
|
|
213859
213934
|
acquisitionError = error5;
|
|
213860
213935
|
}
|
|
213861
213936
|
try {
|
|
213862
|
-
|
|
213937
|
+
rmSync10(candidatePath, { force: true });
|
|
213863
213938
|
} catch {}
|
|
213864
213939
|
return acquisitionError;
|
|
213865
213940
|
}
|
|
@@ -213878,7 +213953,7 @@ async function createInitializedTokenLink(targetPath, ownerToken) {
|
|
|
213878
213953
|
function cleanupRecoveryClaimsSync(lockPath, staleToken, deepestClaim) {
|
|
213879
213954
|
for (let depth = deepestClaim;depth >= 0; depth--) {
|
|
213880
213955
|
try {
|
|
213881
|
-
|
|
213956
|
+
rmSync10(getRecoveryClaimPath(lockPath, staleToken, depth), {
|
|
213882
213957
|
force: true
|
|
213883
213958
|
});
|
|
213884
213959
|
} catch {}
|
|
@@ -213924,7 +213999,7 @@ function recoverStaleLockSync(lockPath, staleToken, recoveryOwner) {
|
|
|
213924
213999
|
}
|
|
213925
214000
|
if (readFileSync30(lockPath, "utf-8") !== staleToken)
|
|
213926
214001
|
return false;
|
|
213927
|
-
|
|
214002
|
+
rmSync10(lockPath, { force: true });
|
|
213928
214003
|
return true;
|
|
213929
214004
|
} catch {
|
|
213930
214005
|
return false;
|
|
@@ -213988,7 +214063,7 @@ function reclaimAbandonedLockSync(lockPath, allowDuringAcquisition = false) {
|
|
|
213988
214063
|
abandonedLock = null;
|
|
213989
214064
|
return false;
|
|
213990
214065
|
}
|
|
213991
|
-
|
|
214066
|
+
rmSync10(handle2.lockPath, { force: true });
|
|
213992
214067
|
abandonedLock = null;
|
|
213993
214068
|
return true;
|
|
213994
214069
|
} catch (error5) {
|
|
@@ -214121,7 +214196,7 @@ function releaseRemoteSettingsLockSync(handle2) {
|
|
|
214121
214196
|
if (readFileSync30(handle2.lockPath, "utf-8") !== handle2.ownerToken) {
|
|
214122
214197
|
released = true;
|
|
214123
214198
|
} else {
|
|
214124
|
-
|
|
214199
|
+
rmSync10(handle2.lockPath, { force: true });
|
|
214125
214200
|
released = true;
|
|
214126
214201
|
}
|
|
214127
214202
|
} catch (error5) {
|
|
@@ -214182,10 +214257,10 @@ import { randomUUID as randomUUID29 } from "node:crypto";
|
|
|
214182
214257
|
import {
|
|
214183
214258
|
existsSync as existsSync33,
|
|
214184
214259
|
mkdirSync as mkdirSync27,
|
|
214185
|
-
readdirSync as
|
|
214260
|
+
readdirSync as readdirSync9,
|
|
214186
214261
|
readFileSync as readFileSync31,
|
|
214187
214262
|
renameSync as renameSync8,
|
|
214188
|
-
rmSync as
|
|
214263
|
+
rmSync as rmSync11,
|
|
214189
214264
|
writeFileSync as writeFileSync22
|
|
214190
214265
|
} from "node:fs";
|
|
214191
214266
|
import { readFile as readFile9, rm as rm6, writeFile as writeFile10 } from "node:fs/promises";
|
|
@@ -214255,7 +214330,7 @@ function readCwdRepairJournals(settingsPath) {
|
|
|
214255
214330
|
const prefix = getCwdRepairJournalPrefix(settingsPath);
|
|
214256
214331
|
let names2;
|
|
214257
214332
|
try {
|
|
214258
|
-
names2 =
|
|
214333
|
+
names2 = readdirSync9(directory).filter((name) => name.startsWith(prefix) && (name.endsWith(".json") || name.endsWith(".tmp")));
|
|
214259
214334
|
} catch {
|
|
214260
214335
|
return [];
|
|
214261
214336
|
}
|
|
@@ -214320,14 +214395,14 @@ function writeCwdRepairJournal(settingsPath, patch2) {
|
|
|
214320
214395
|
return null;
|
|
214321
214396
|
} finally {
|
|
214322
214397
|
try {
|
|
214323
|
-
|
|
214398
|
+
rmSync11(tempPath, { force: true });
|
|
214324
214399
|
} catch {}
|
|
214325
214400
|
}
|
|
214326
214401
|
}
|
|
214327
214402
|
function cleanupCwdRepairJournals(journals) {
|
|
214328
214403
|
for (const journal of journals) {
|
|
214329
214404
|
try {
|
|
214330
|
-
|
|
214405
|
+
rmSync11(journal.path, { force: true });
|
|
214331
214406
|
} catch {}
|
|
214332
214407
|
}
|
|
214333
214408
|
}
|
|
@@ -214472,7 +214547,7 @@ function persistRemoteSettingsSync(generation3) {
|
|
|
214472
214547
|
return false;
|
|
214473
214548
|
} finally {
|
|
214474
214549
|
try {
|
|
214475
|
-
|
|
214550
|
+
rmSync11(tempPath, { force: true });
|
|
214476
214551
|
} catch {}
|
|
214477
214552
|
releaseRemoteSettingsLockSync(lock);
|
|
214478
214553
|
}
|
|
@@ -214827,21 +214902,21 @@ import {
|
|
|
214827
214902
|
lstatSync,
|
|
214828
214903
|
mkdirSync as mkdirSync28,
|
|
214829
214904
|
openSync as openSync5,
|
|
214830
|
-
readdirSync as
|
|
214905
|
+
readdirSync as readdirSync10,
|
|
214831
214906
|
readFileSync as readFileSync32,
|
|
214832
214907
|
readSync as readSync2,
|
|
214833
|
-
rmdirSync,
|
|
214834
|
-
rmSync as
|
|
214908
|
+
rmdirSync as rmdirSync2,
|
|
214909
|
+
rmSync as rmSync12,
|
|
214835
214910
|
unlinkSync as unlinkSync8,
|
|
214836
214911
|
writeFileSync as writeFileSync23
|
|
214837
214912
|
} from "node:fs";
|
|
214838
|
-
import { basename as
|
|
214913
|
+
import { basename as basename17, dirname as dirname16, join as join44 } from "node:path";
|
|
214839
214914
|
function installCandidateDirectory(candidatePath, lockPath, hooks) {
|
|
214840
214915
|
mkdirSync28(lockPath, { mode: 448 });
|
|
214841
214916
|
const directoryIdentity = pathIdentity(lockPath);
|
|
214842
214917
|
if (!directoryIdentity)
|
|
214843
214918
|
return false;
|
|
214844
|
-
const names2 =
|
|
214919
|
+
const names2 = readdirSync10(candidatePath);
|
|
214845
214920
|
if (names2.length !== 1)
|
|
214846
214921
|
throw new Error("Invalid durable lock candidate");
|
|
214847
214922
|
const candidateOwnerPath = join44(candidatePath, names2[0]);
|
|
@@ -214856,7 +214931,7 @@ function installCandidateDirectory(candidatePath, lockPath, hooks) {
|
|
|
214856
214931
|
return false;
|
|
214857
214932
|
throw error5;
|
|
214858
214933
|
}
|
|
214859
|
-
const installingNames =
|
|
214934
|
+
const installingNames = readdirSync10(lockPath);
|
|
214860
214935
|
if (!hasPathIdentity(lockPath, directoryIdentity) || installingNames.length !== 1 || installingNames[0] !== INSTALLING_OWNER_NAME) {
|
|
214861
214936
|
if (sameFile(candidateOwnerPath, installingOwnerPath)) {
|
|
214862
214937
|
unlinkSync8(installingOwnerPath);
|
|
@@ -214872,7 +214947,7 @@ function installCandidateDirectory(candidatePath, lockPath, hooks) {
|
|
|
214872
214947
|
hooks.afterInstallingOwnerUnlink?.(lockPath);
|
|
214873
214948
|
fsyncDirectory(lockPath);
|
|
214874
214949
|
unlinkSync8(candidateOwnerPath);
|
|
214875
|
-
|
|
214950
|
+
rmdirSync2(candidatePath);
|
|
214876
214951
|
return true;
|
|
214877
214952
|
}
|
|
214878
214953
|
function fsyncDirectory(path12, platform5 = process.platform) {
|
|
@@ -214957,7 +215032,7 @@ function ownerFileName(owner) {
|
|
|
214957
215032
|
return `${owner.pid}-${owner.token}.json`;
|
|
214958
215033
|
}
|
|
214959
215034
|
function readOwnerDirectory(lockPath, afterRead) {
|
|
214960
|
-
const names2 =
|
|
215035
|
+
const names2 = readdirSync10(lockPath);
|
|
214961
215036
|
if (names2.length === 0)
|
|
214962
215037
|
return null;
|
|
214963
215038
|
if (names2.length > 2) {
|
|
@@ -215040,7 +215115,7 @@ function removeDirectoryIfEmpty(path12, parent, expectedIdentity) {
|
|
|
215040
215115
|
if (expectedIdentity && !hasPathIdentity(path12, expectedIdentity))
|
|
215041
215116
|
return false;
|
|
215042
215117
|
try {
|
|
215043
|
-
|
|
215118
|
+
rmdirSync2(path12);
|
|
215044
215119
|
fsyncDirectory(parent);
|
|
215045
215120
|
return true;
|
|
215046
215121
|
} catch (error5) {
|
|
@@ -215070,8 +215145,8 @@ function removeDeadOwner(lockPath, parent, ownerPath, afterOwnerUnlink) {
|
|
|
215070
215145
|
return true;
|
|
215071
215146
|
}
|
|
215072
215147
|
function sweepDeadCandidates(lockPath, parent, isOwnerAlive, ignoredPath) {
|
|
215073
|
-
const prefix = `${
|
|
215074
|
-
const allCandidates =
|
|
215148
|
+
const prefix = `${basename17(lockPath)}.candidate-`;
|
|
215149
|
+
const allCandidates = readdirSync10(parent, { withFileTypes: true }).filter((entry) => entry.name.startsWith(prefix) && entry.isDirectory());
|
|
215075
215150
|
let hasUnresolvedCandidate = allCandidates.length > MAX_CANDIDATE_SWEEP;
|
|
215076
215151
|
const candidates2 = allCandidates.slice(0, MAX_CANDIDATE_SWEEP);
|
|
215077
215152
|
for (const entry of candidates2) {
|
|
@@ -215100,7 +215175,7 @@ function sweepDeadCandidates(lockPath, parent, isOwnerAlive, ignoredPath) {
|
|
|
215100
215175
|
hasUnresolvedCandidate = true;
|
|
215101
215176
|
continue;
|
|
215102
215177
|
}
|
|
215103
|
-
|
|
215178
|
+
rmSync12(candidatePath, { recursive: true, force: true });
|
|
215104
215179
|
fsyncDirectory(parent);
|
|
215105
215180
|
continue;
|
|
215106
215181
|
}
|
|
@@ -215119,7 +215194,7 @@ function sweepDeadCandidates(lockPath, parent, isOwnerAlive, ignoredPath) {
|
|
|
215119
215194
|
hasUnresolvedCandidate = true;
|
|
215120
215195
|
continue;
|
|
215121
215196
|
}
|
|
215122
|
-
|
|
215197
|
+
rmSync12(candidatePath, { recursive: true, force: true });
|
|
215123
215198
|
fsyncDirectory(parent);
|
|
215124
215199
|
continue;
|
|
215125
215200
|
}
|
|
@@ -215157,7 +215232,7 @@ function prepareCandidate(lockPath, parent, owner) {
|
|
|
215157
215232
|
return candidatePath;
|
|
215158
215233
|
} catch (error5) {
|
|
215159
215234
|
try {
|
|
215160
|
-
|
|
215235
|
+
rmSync12(candidatePath, { recursive: true, force: true });
|
|
215161
215236
|
fsyncDirectory(parent);
|
|
215162
215237
|
} catch {}
|
|
215163
215238
|
throw error5;
|
|
@@ -215322,7 +215397,7 @@ function acquireDurableFileLock(path12, options = {}) {
|
|
|
215322
215397
|
removeDeadOwner(lockPath, parent, join44(lockPath, ownerFileName(owner)));
|
|
215323
215398
|
} catch {}
|
|
215324
215399
|
try {
|
|
215325
|
-
|
|
215400
|
+
rmSync12(candidatePath, { recursive: true, force: true });
|
|
215326
215401
|
fsyncDirectory(parent);
|
|
215327
215402
|
} catch {}
|
|
215328
215403
|
throw error5;
|
|
@@ -215356,7 +215431,7 @@ var init_durable_file_lock = __esm(() => {
|
|
|
215356
215431
|
});
|
|
215357
215432
|
|
|
215358
215433
|
// src/websocket/listener/interrupted-turn-input-ownership.ts
|
|
215359
|
-
import { readdirSync as
|
|
215434
|
+
import { readdirSync as readdirSync11 } from "node:fs";
|
|
215360
215435
|
import { join as join45 } from "node:path";
|
|
215361
215436
|
function decodeMainFilenameScopes(file) {
|
|
215362
215437
|
if (!file.endsWith(".json"))
|
|
@@ -215378,7 +215453,7 @@ function listInterruptedTurnMainSnapshot(directory, readRecord) {
|
|
|
215378
215453
|
try {
|
|
215379
215454
|
const records = [];
|
|
215380
215455
|
const unreadableScopes = new Map;
|
|
215381
|
-
for (const file of
|
|
215456
|
+
for (const file of readdirSync11(directory).filter((entry) => entry.endsWith(".json"))) {
|
|
215382
215457
|
const record6 = readRecord(join45(directory, file));
|
|
215383
215458
|
if (record6) {
|
|
215384
215459
|
records.push(record6);
|
|
@@ -215854,7 +215929,7 @@ Do not use this tool for root memory files (already loaded) or skills/ (use Skil
|
|
|
215854
215929
|
var init_Memory = () => {};
|
|
215855
215930
|
|
|
215856
215931
|
// src/tools/descriptions/Monitor.md
|
|
215857
|
-
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
|
|
215932
|
+
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, including persistent ones, stops after {{MONITOR_MAX_TIMEOUT}} (this sandbox\'s monitor cap); 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 (including `decide()`), plus `emit(text)` (one event) and `sleep(ms)`. Tool calls and `decide()` share one rate limit; `decide()` spends money on every call, so call it only when an observed change needs judgment, not on every poll. Returning or throwing ends the watch.\n';
|
|
215858
215933
|
var init_Monitor = () => {};
|
|
215859
215934
|
|
|
215860
215935
|
// src/tools/descriptions/Read.md
|
|
@@ -216370,13 +216445,13 @@ var ViewImage_default = `View a local image file from the filesystem when visual
|
|
|
216370
216445
|
var init_ViewImage = () => {};
|
|
216371
216446
|
|
|
216372
216447
|
// src/tools/descriptions/Wake.md
|
|
216373
|
-
var Wake_default = "Schedule a future turn for the current conversation. Wake is the durable, time-based counterpart to Monitor: use Monitor when ongoing work can emit an event, and Wake when you need to act at a future time even if nothing emits one.\n\nWake is always self-bound. It cannot target another agent, conversation, or computer.\n\n- `create`: provide `name`, `prompt`, and exactly one of `after_seconds`, `scheduled_at`, or `cron`.\n- `list`: list active and paused wakes for this conversation.\n- `cancel`: provide the `id` returned by create or list.\n\nUse `after_seconds` for ordinary follow-ups such as checking again in five minutes. `scheduled_at` must be RFC 3339 with `Z` or an explicit UTC offset. `cron` is a recurring five-field UTC expression and cannot run more often than hourly.\n\nFor calendar requests such as “tomorrow at 9am,” resolve the date in the user's timezone and pass `scheduled_at` with an explicit offset. Infer a reasonable timezone from available context instead of asking a redundant follow-up. State the timezone you used in the confirmation (for example, “Scheduled for 9:00 AM PT”) so the user can correct the assumption.\n\nWakes created in a managed Cloud sandbox survive sandbox shutdown. Wakes created on a user-managed computer or self-hosted runtime use its local scheduler and only fire while a listener is active. List and cancel include both local and Cloud wakes already bound to this conversation, so older wakes remain manageable. The create result warns when no listener currently owns local schedules.\n\nFor advanced scheduling, load the `scheduling-tasks` skill and use `letta cron`. The CLI can target fresh, default, or other conversations and, from managed Cloud, connected computers; it can also inspect run history and manage schedules outside the current conversation.\n";
|
|
216448
|
+
var Wake_default = "Schedule a future turn for the current conversation. Wake is the durable, time-based counterpart to Monitor: use Monitor when ongoing work can emit an event, and Wake when you need to act at a future time even if nothing emits one.\n\nWake is always self-bound. It cannot target another agent, conversation, or computer.\n\n- `create`: provide `name`, `prompt`, and exactly one of `after_seconds`, `scheduled_at`, or `cron`.\n- `list`: list active and paused wakes for this conversation.\n- `cancel`: provide the `id` returned by create or list.\n\nWrite `prompt` as a note to your future self, not a script: what you are waiting on, what you planned and why, and what to check before acting. When the wake fires, the situation or people's wishes may have changed since you wrote it.\n\nUse `after_seconds` for ordinary follow-ups such as checking again in five minutes. `scheduled_at` must be RFC 3339 with `Z` or an explicit UTC offset. `cron` is a recurring five-field UTC expression and cannot run more often than hourly.\n\nFor calendar requests such as “tomorrow at 9am,” resolve the date in the user's timezone and pass `scheduled_at` with an explicit offset. Infer a reasonable timezone from available context instead of asking a redundant follow-up. State the timezone you used in the confirmation (for example, “Scheduled for 9:00 AM PT”) so the user can correct the assumption.\n\nWakes created in a managed Cloud sandbox survive sandbox shutdown. Wakes created on a user-managed computer or self-hosted runtime use its local scheduler and only fire while a listener is active. List and cancel include both local and Cloud wakes already bound to this conversation, so older wakes remain manageable. The create result warns when no listener currently owns local schedules.\n\nFor advanced scheduling, load the `scheduling-tasks` skill and use `letta cron`. The CLI can target fresh, default, or other conversations and, from managed Cloud, connected computers; it can also inspect run history and manage schedules outside the current conversation.\n";
|
|
216374
216449
|
var init_Wake = () => {};
|
|
216375
216450
|
|
|
216376
216451
|
// src/tools/descriptions/WatchPR.md
|
|
216377
216452
|
var WatchPR_default = `Watch one open github.com pull request until it merges, closes, is stopped with TaskStop, or the session ends.
|
|
216378
216453
|
|
|
216379
|
-
In managed Cloud sandboxes, WatchPR also stops after
|
|
216454
|
+
In managed Cloud sandboxes, WatchPR also stops after {{MONITOR_MAX_TIMEOUT}} (this sandbox's monitor cap) 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.
|
|
216380
216455
|
|
|
216381
216456
|
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:
|
|
216382
216457
|
|
|
@@ -217845,8 +217920,8 @@ function isGitExecutable(command) {
|
|
|
217845
217920
|
}
|
|
217846
217921
|
function isShellExecutable(command) {
|
|
217847
217922
|
const normalized = command.replace(/\\/g, "/").toLowerCase();
|
|
217848
|
-
const
|
|
217849
|
-
return
|
|
217923
|
+
const basename18 = path13.basename(normalized);
|
|
217924
|
+
return basename18 === "bash" || basename18 === "sh" || basename18 === "zsh" || basename18 === "ash" || basename18 === "cmd.exe" || basename18.includes("powershell") || basename18.includes("pwsh");
|
|
217850
217925
|
}
|
|
217851
217926
|
function extractShellCommandArgument(launcher, startIndex) {
|
|
217852
217927
|
const argIndex = launcher.findIndex((token2, index) => {
|
|
@@ -218220,9 +218295,9 @@ import {
|
|
|
218220
218295
|
createWriteStream as createWriteStream3,
|
|
218221
218296
|
existsSync as existsSync34,
|
|
218222
218297
|
mkdirSync as mkdirSync29,
|
|
218223
|
-
readdirSync as
|
|
218298
|
+
readdirSync as readdirSync12,
|
|
218224
218299
|
renameSync as renameSync9,
|
|
218225
|
-
rmSync as
|
|
218300
|
+
rmSync as rmSync13
|
|
218226
218301
|
} from "node:fs";
|
|
218227
218302
|
import { createRequire as createRequire4 } from "node:module";
|
|
218228
218303
|
import { arch as arch3, platform as platform5 } from "node:os";
|
|
@@ -218309,7 +218384,7 @@ function findBinaryRecursively2(rootDir, binaryFileName) {
|
|
|
218309
218384
|
const currentDir = stack.pop();
|
|
218310
218385
|
if (!currentDir)
|
|
218311
218386
|
continue;
|
|
218312
|
-
const entries =
|
|
218387
|
+
const entries = readdirSync12(currentDir, { withFileTypes: true });
|
|
218313
218388
|
for (const entry of entries) {
|
|
218314
218389
|
const fullPath = join47(currentDir, entry.name);
|
|
218315
218390
|
if (entry.isFile() && entry.name === binaryFileName) {
|
|
@@ -218456,8 +218531,8 @@ async function downloadRipgrep() {
|
|
|
218456
218531
|
chmodSync8(binaryPath, 493);
|
|
218457
218532
|
}
|
|
218458
218533
|
} finally {
|
|
218459
|
-
|
|
218460
|
-
|
|
218534
|
+
rmSync13(archivePath, { force: true });
|
|
218535
|
+
rmSync13(extractDir, { recursive: true, force: true });
|
|
218461
218536
|
}
|
|
218462
218537
|
if (!commandWorks(binaryPath)) {
|
|
218463
218538
|
throw new Error(`${config2.name} installed to ${binaryPath} but failed --version validation`);
|
|
@@ -219044,8 +219119,8 @@ function hasPathSeparator(executable) {
|
|
|
219044
219119
|
return executable.includes("/") || executable.includes("\\");
|
|
219045
219120
|
}
|
|
219046
219121
|
function hasFileExtension(executable) {
|
|
219047
|
-
const
|
|
219048
|
-
return /\.[^.]+$/.test(
|
|
219122
|
+
const basename19 = executable.split(/[\\/]/).pop() ?? executable;
|
|
219123
|
+
return /\.[^.]+$/.test(basename19);
|
|
219049
219124
|
}
|
|
219050
219125
|
function shellCandidateExists(candidate) {
|
|
219051
219126
|
try {
|
|
@@ -220446,7 +220521,7 @@ var init_availability = __esm(() => {
|
|
|
220446
220521
|
|
|
220447
220522
|
// src/permissions/memory-paths.ts
|
|
220448
220523
|
import { homedir as homedir10 } from "node:os";
|
|
220449
|
-
import { basename as
|
|
220524
|
+
import { basename as basename19, dirname as dirname21, isAbsolute as isAbsolute14, resolve as resolve17 } from "node:path";
|
|
220450
220525
|
function normalizeMemoryPath(path16) {
|
|
220451
220526
|
const resolvedPath = resolve17(expandHomePath(path16));
|
|
220452
220527
|
const normalized = resolvedPath.replace(/\\/g, "/");
|
|
@@ -220491,7 +220566,7 @@ function addRootAndSiblingWorktree(root2, acc) {
|
|
|
220491
220566
|
return;
|
|
220492
220567
|
}
|
|
220493
220568
|
acc.add(normalizedRoot);
|
|
220494
|
-
const leaf =
|
|
220569
|
+
const leaf = basename19(normalizedRoot);
|
|
220495
220570
|
if (leaf === "memory") {
|
|
220496
220571
|
acc.add(normalizeMemoryPath(resolve17(dirname21(normalizedRoot), "memory-worktrees")));
|
|
220497
220572
|
}
|
|
@@ -220574,7 +220649,7 @@ var init_memory_paths = __esm(() => {
|
|
|
220574
220649
|
// src/permissions/sandbox-policy.ts
|
|
220575
220650
|
import { existsSync as existsSync37, realpathSync as realpathSync6 } from "node:fs";
|
|
220576
220651
|
import { homedir as homedir11 } from "node:os";
|
|
220577
|
-
import { basename as
|
|
220652
|
+
import { basename as basename20, dirname as dirname22, isAbsolute as isAbsolute15, join as join51, resolve as resolve18 } from "node:path";
|
|
220578
220653
|
function getCrossBackendAgentsTreeRoots(options = {}) {
|
|
220579
220654
|
const homeDir = options.homeDir;
|
|
220580
220655
|
const env6 = options.env ?? process.env;
|
|
@@ -220603,7 +220678,7 @@ function canonicalizeRoot(input) {
|
|
|
220603
220678
|
let dir = abs;
|
|
220604
220679
|
const tail2 = [];
|
|
220605
220680
|
while (!existsSync37(dir)) {
|
|
220606
|
-
tail2.unshift(
|
|
220681
|
+
tail2.unshift(basename20(dir));
|
|
220607
220682
|
const parent = dirname22(dir);
|
|
220608
220683
|
if (parent === dir) {
|
|
220609
220684
|
return normalizeSandboxPath(abs);
|
|
@@ -220637,8 +220712,8 @@ function deriveSelfAgentRootsForTrees(memoryRoots, agentsTreeRoots = getCrossBac
|
|
|
220637
220712
|
const canon = canonicalizeRoot(root2);
|
|
220638
220713
|
const containingTree = canonicalTrees.find((tree) => canon !== tree && isWithinRoot(canon, tree));
|
|
220639
220714
|
if (containingTree) {
|
|
220640
|
-
const leaf =
|
|
220641
|
-
const parentLeaf =
|
|
220715
|
+
const leaf = basename20(canon);
|
|
220716
|
+
const parentLeaf = basename20(dirname22(canon));
|
|
220642
220717
|
out.add(leaf === "memory" || leaf === "memory-worktrees" ? dirname22(canon) : parentLeaf === "memory-worktrees" || parentLeaf === "memory" && leaf === ".git" ? dirname22(dirname22(canon)) : canon);
|
|
220643
220718
|
continue;
|
|
220644
220719
|
}
|
|
@@ -221855,8 +221930,8 @@ function resolveRemovalTarget(rawTarget, cwd2, env6) {
|
|
|
221855
221930
|
let target2 = expandEnvironment(rawTarget, env6).replace(/[),]+$/g, "").replace(/(?<=[\\/:])\$(?:env:)?[A-Za-z_][A-Za-z0-9_]*/gi, "").replaceAll("/", "\\");
|
|
221856
221931
|
if (!target2 || target2 === "*")
|
|
221857
221932
|
return null;
|
|
221858
|
-
const
|
|
221859
|
-
if (
|
|
221933
|
+
const basename21 = win323.basename(target2);
|
|
221934
|
+
if (basename21.includes("*") || basename21.includes("?")) {
|
|
221860
221935
|
target2 = win323.dirname(target2);
|
|
221861
221936
|
}
|
|
221862
221937
|
return win323.normalize(win323.resolve(cwd2, target2));
|
|
@@ -221939,7 +222014,7 @@ __export(exports_bash, {
|
|
|
221939
222014
|
bash: () => bash,
|
|
221940
222015
|
__setShellProcessStarterForTests: () => __setShellProcessStarterForTests
|
|
221941
222016
|
});
|
|
221942
|
-
import { rmSync as
|
|
222017
|
+
import { rmSync as rmSync14 } from "node:fs";
|
|
221943
222018
|
function __setShellProcessStarterForTests(starter) {
|
|
221944
222019
|
shellProcessStarter = starter ?? startShellProcess;
|
|
221945
222020
|
}
|
|
@@ -222280,7 +222355,7 @@ async function bash(args) {
|
|
|
222280
222355
|
]) : await settledOutcome;
|
|
222281
222356
|
if (outcome.type === "settled") {
|
|
222282
222357
|
backgroundProcesses.delete(bashId);
|
|
222283
|
-
|
|
222358
|
+
rmSync14(outputFile, { force: true });
|
|
222284
222359
|
const { result: result2 } = outcome;
|
|
222285
222360
|
const output = [foregroundOutput.stdout, foregroundOutput.stderr].filter(Boolean).join(`
|
|
222286
222361
|
`);
|
|
@@ -222478,7 +222553,7 @@ async function checkDiskSpaceNow(path17, options = {}) {
|
|
|
222478
222553
|
}
|
|
222479
222554
|
}
|
|
222480
222555
|
async function watchDiskSpaceDuring(path17, deliver, work, options = {}) {
|
|
222481
|
-
if (!isManagedCloudRuntime(options.env))
|
|
222556
|
+
if (!isManagedCloudRuntime(options.env) || sandboxPollTimer)
|
|
222482
222557
|
return work();
|
|
222483
222558
|
const check5 = () => void checkDiskSpaceNow(path17, options).then((text2) => {
|
|
222484
222559
|
if (text2)
|
|
@@ -222493,6 +222568,31 @@ async function watchDiskSpaceDuring(path17, deliver, work, options = {}) {
|
|
|
222493
222568
|
check5();
|
|
222494
222569
|
}
|
|
222495
222570
|
}
|
|
222571
|
+
function watchSandboxDiskSpace(getPath, deliver, options = {}) {
|
|
222572
|
+
try {
|
|
222573
|
+
if (!isManagedCloudRuntime(options.env))
|
|
222574
|
+
return () => {};
|
|
222575
|
+
if (sandboxPollTimer)
|
|
222576
|
+
clearInterval(sandboxPollTimer);
|
|
222577
|
+
const timer = setInterval(() => {
|
|
222578
|
+
try {
|
|
222579
|
+
checkDiskSpaceNow(getPath(), options).then((text2) => {
|
|
222580
|
+
if (text2)
|
|
222581
|
+
deliver(text2);
|
|
222582
|
+
}).catch(() => {});
|
|
222583
|
+
} catch {}
|
|
222584
|
+
}, options.intervalMs ?? DISK_SPACE_POLL_INTERVAL_MS);
|
|
222585
|
+
timer.unref?.();
|
|
222586
|
+
sandboxPollTimer = timer;
|
|
222587
|
+
return () => {
|
|
222588
|
+
clearInterval(timer);
|
|
222589
|
+
if (sandboxPollTimer === timer)
|
|
222590
|
+
sandboxPollTimer = null;
|
|
222591
|
+
};
|
|
222592
|
+
} catch {
|
|
222593
|
+
return () => {};
|
|
222594
|
+
}
|
|
222595
|
+
}
|
|
222496
222596
|
function deliverDiskSpaceReminder(text2, parentScope) {
|
|
222497
222597
|
if (!isQueueBridgeConnected()) {
|
|
222498
222598
|
pendingRequestReminder = text2;
|
|
@@ -222530,7 +222630,7 @@ function evaluateDiskSpaceReminder(input) {
|
|
|
222530
222630
|
return { text: null, notified: input.notified };
|
|
222531
222631
|
}
|
|
222532
222632
|
}
|
|
222533
|
-
var LOW_DISK_USED_FRACTION = 0.9, LOW_DISK_AVAILABLE_BYTES, DISK_SPACE_CHECK_INTERVAL_MS = 60000, cache5, CRITICAL_DISK_USED_FRACTION = 0.95, DISK_SPACE_POLL_INTERVAL_MS = 30000, pushedLevel = 0, pendingRequestReminder = null;
|
|
222633
|
+
var LOW_DISK_USED_FRACTION = 0.9, LOW_DISK_AVAILABLE_BYTES, DISK_SPACE_CHECK_INTERVAL_MS = 60000, cache5, CRITICAL_DISK_USED_FRACTION = 0.95, DISK_SPACE_POLL_INTERVAL_MS = 30000, pushedLevel = 0, sandboxPollTimer = null, pendingRequestReminder = null;
|
|
222534
222634
|
var init_disk_space = __esm(() => {
|
|
222535
222635
|
init_constants2();
|
|
222536
222636
|
init_message_queue_bridge();
|
|
@@ -223857,6 +223957,10 @@ var init_hooks = __esm(() => {
|
|
|
223857
223957
|
});
|
|
223858
223958
|
|
|
223859
223959
|
// src/agent/subagent-state.ts
|
|
223960
|
+
function excerptProgressText(value, max2) {
|
|
223961
|
+
const line = value.replace(/\s+/g, " ").trim();
|
|
223962
|
+
return line.length > max2 ? `${line.slice(0, max2)}…` : line;
|
|
223963
|
+
}
|
|
223860
223964
|
function updateSnapshot() {
|
|
223861
223965
|
const agents = Array.from(store2.agents.values());
|
|
223862
223966
|
const now2 = Date.now();
|
|
@@ -223885,6 +223989,9 @@ function unrefTimer2(timer) {
|
|
|
223885
223989
|
timer.unref();
|
|
223886
223990
|
}
|
|
223887
223991
|
}
|
|
223992
|
+
function isPublished(agent) {
|
|
223993
|
+
return agent.published === true || agent.result !== undefined;
|
|
223994
|
+
}
|
|
223888
223995
|
function scheduleCompletedSubagentCleanup(id2) {
|
|
223889
223996
|
const agent = store2.agents.get(id2);
|
|
223890
223997
|
if (!agent || agent.status !== "completed" && agent.status !== "error") {
|
|
@@ -223909,7 +224016,7 @@ function armCompletedSubagentCleanup(id2) {
|
|
|
223909
224016
|
}
|
|
223910
224017
|
store2.agents.delete(id2);
|
|
223911
224018
|
notifyListeners();
|
|
223912
|
-
}, agent
|
|
224019
|
+
}, isPublished(agent) ? publishedResultRetentionMs : completedSubagentRetentionMs);
|
|
223913
224020
|
unrefTimer2(timer);
|
|
223914
224021
|
completedSubagentCleanupTimers.set(id2, timer);
|
|
223915
224022
|
}
|
|
@@ -223989,6 +224096,25 @@ function addToolCall(subagentId, toolCallId, toolName2, toolArgs) {
|
|
|
223989
224096
|
store2.agents.set(subagentId, updatedAgent);
|
|
223990
224097
|
notifyListeners();
|
|
223991
224098
|
}
|
|
224099
|
+
function addProgressText(subagentId, text2, now2 = () => new Date) {
|
|
224100
|
+
const agent = store2.agents.get(subagentId);
|
|
224101
|
+
if (!agent)
|
|
224102
|
+
return;
|
|
224103
|
+
const excerpt = excerptProgressText(text2, PROGRESS_TEXT_CHARS);
|
|
224104
|
+
const previous = agent.progressTexts?.at(-1);
|
|
224105
|
+
if (!excerpt || previous?.text === excerpt)
|
|
224106
|
+
return;
|
|
224107
|
+
const count = (agent.progressTextCount ?? 0) + 1;
|
|
224108
|
+
store2.agents.set(subagentId, {
|
|
224109
|
+
...agent,
|
|
224110
|
+
progressTexts: [
|
|
224111
|
+
...agent.progressTexts ?? [],
|
|
224112
|
+
{ id: `text-${count}`, at: now2().toISOString(), text: excerpt }
|
|
224113
|
+
].slice(-MAX_PROGRESS_TEXTS),
|
|
224114
|
+
progressTextCount: count
|
|
224115
|
+
});
|
|
224116
|
+
notifyListeners();
|
|
224117
|
+
}
|
|
223992
224118
|
function completeSubagent(id2, result2) {
|
|
223993
224119
|
const agent = store2.agents.get(id2);
|
|
223994
224120
|
if (!agent)
|
|
@@ -223999,6 +224125,7 @@ function completeSubagent(id2, result2) {
|
|
|
223999
224125
|
error: result2.error,
|
|
224000
224126
|
stopFailed: undefined,
|
|
224001
224127
|
...result2.result !== undefined ? { result: result2.result } : {},
|
|
224128
|
+
...result2.published ? { published: true } : {},
|
|
224002
224129
|
durationMs: Date.now() - agent.startTime,
|
|
224003
224130
|
totalTokens: result2.totalTokens ?? agent.totalTokens,
|
|
224004
224131
|
maxToolCallsSeen: Math.max(agent.maxToolCallsSeen, agent.toolCalls.length)
|
|
@@ -224052,7 +224179,7 @@ function subscribeToSubagentLifecycle(listener) {
|
|
|
224052
224179
|
function clearCompletedSubagents() {
|
|
224053
224180
|
let removedAny = false;
|
|
224054
224181
|
for (const [id2, agent] of store2.agents.entries()) {
|
|
224055
|
-
if (agent
|
|
224182
|
+
if (isPublished(agent))
|
|
224056
224183
|
continue;
|
|
224057
224184
|
if (agent.cancelPending)
|
|
224058
224185
|
continue;
|
|
@@ -224185,7 +224312,7 @@ function emitStreamEvent(subagentId, event) {
|
|
|
224185
224312
|
listener(subagentId, event);
|
|
224186
224313
|
}
|
|
224187
224314
|
}
|
|
224188
|
-
var store2, cachedSnapshot, cachedLifecycleItems, DEFAULT_COMPLETED_SUBAGENT_RETENTION_MS = 30000, completedSubagentRetentionMs, DEFAULT_PUBLISHED_RESULT_RETENTION_MS, publishedResultRetentionMs, completedSubagentCleanupTimers, subagentCounter = 0, subagentAbortHooks, streamEventListeners;
|
|
224315
|
+
var PROGRESS_TEXT_CHARS = 300, MAX_PROGRESS_TEXTS = 20, store2, cachedSnapshot, cachedLifecycleItems, DEFAULT_COMPLETED_SUBAGENT_RETENTION_MS = 30000, completedSubagentRetentionMs, DEFAULT_PUBLISHED_RESULT_RETENTION_MS, publishedResultRetentionMs, completedSubagentCleanupTimers, subagentCounter = 0, subagentAbortHooks, streamEventListeners;
|
|
224189
224316
|
var init_subagent_state = __esm(() => {
|
|
224190
224317
|
store2 = {
|
|
224191
224318
|
agents: new Map,
|
|
@@ -225172,7 +225299,7 @@ import {
|
|
|
225172
225299
|
closeSync as closeSync6,
|
|
225173
225300
|
existsSync as existsSync39,
|
|
225174
225301
|
openSync as openSync6,
|
|
225175
|
-
readdirSync as
|
|
225302
|
+
readdirSync as readdirSync14,
|
|
225176
225303
|
readFileSync as readFileSync33,
|
|
225177
225304
|
readSync as readSync3,
|
|
225178
225305
|
realpathSync as realpathSync7,
|
|
@@ -225216,7 +225343,7 @@ function isHidden2(name) {
|
|
|
225216
225343
|
return name.startsWith(".");
|
|
225217
225344
|
}
|
|
225218
225345
|
function findByBasename(dir, name, root2 = dir, found = []) {
|
|
225219
|
-
for (const entry of
|
|
225346
|
+
for (const entry of readdirSync14(dir, { withFileTypes: true })) {
|
|
225220
225347
|
if (found.length >= 5)
|
|
225221
225348
|
break;
|
|
225222
225349
|
if (isHidden2(entry.name) || dir === root2 && entry.name === "skills") {
|
|
@@ -225290,7 +225417,7 @@ function lastEditedByChild(dir, names2) {
|
|
|
225290
225417
|
return bump(name, stat6.mtimeMs);
|
|
225291
225418
|
if (!stat6.isDirectory())
|
|
225292
225419
|
return;
|
|
225293
|
-
for (const entry of
|
|
225420
|
+
for (const entry of readdirSync14(path18, { withFileTypes: true })) {
|
|
225294
225421
|
if (!isHidden2(entry.name))
|
|
225295
225422
|
walkMtime(join53(path18, entry.name), name);
|
|
225296
225423
|
}
|
|
@@ -225332,7 +225459,7 @@ function lastEditedByChild(dir, names2) {
|
|
|
225332
225459
|
return edited;
|
|
225333
225460
|
}
|
|
225334
225461
|
function renderDirectory(memoryDir, relPath, fullPath) {
|
|
225335
|
-
const entries =
|
|
225462
|
+
const entries = readdirSync14(fullPath, { withFileTypes: true }).filter((entry) => !isHidden2(entry.name) && (entry.isDirectory() || entry.isFile() && entry.name !== INDEX));
|
|
225336
225463
|
const edited = lastEditedByChild(fullPath, entries.map((entry) => entry.name));
|
|
225337
225464
|
const shown = entries.sort((a2, b3) => (edited.get(b3.name) ?? 0) - (edited.get(a2.name) ?? 0) || a2.name.localeCompare(b3.name)).slice(0, LIMITS.MEMORY_MAX_ENTRIES);
|
|
225338
225465
|
const fileLines = shown.filter((entry) => entry.isFile()).map((entry) => {
|
|
@@ -230936,7 +231063,7 @@ var init_approval_result_normalization = __esm(() => {
|
|
|
230936
231063
|
// src/agent/client-skills-watcher.ts
|
|
230937
231064
|
import {
|
|
230938
231065
|
existsSync as existsSync41,
|
|
230939
|
-
readdirSync as
|
|
231066
|
+
readdirSync as readdirSync15,
|
|
230940
231067
|
realpathSync as realpathSync8,
|
|
230941
231068
|
statSync as statSync18,
|
|
230942
231069
|
watch as watch2
|
|
@@ -230975,7 +231102,7 @@ function collectSymlinkDirectoryTargets(path19, targets, visited2) {
|
|
|
230975
231102
|
}
|
|
230976
231103
|
visited2.add(realPath);
|
|
230977
231104
|
try {
|
|
230978
|
-
const entries =
|
|
231105
|
+
const entries = readdirSync15(path19, {
|
|
230979
231106
|
encoding: "utf8",
|
|
230980
231107
|
withFileTypes: true
|
|
230981
231108
|
});
|
|
@@ -235751,7 +235878,7 @@ var init_workflow_engine = __esm(() => {
|
|
|
235751
235878
|
});
|
|
235752
235879
|
|
|
235753
235880
|
// src/tools/impl/code-mode.ts
|
|
235754
|
-
import { rmSync as
|
|
235881
|
+
import { rmSync as rmSync15 } from "node:fs";
|
|
235755
235882
|
function truncateResult(text2) {
|
|
235756
235883
|
if (text2.length <= MAX_NOTIFICATION_RESULT_CHARS)
|
|
235757
235884
|
return text2;
|
|
@@ -235881,7 +236008,7 @@ ${outcome.text}
|
|
|
235881
236008
|
signal?.removeEventListener("abort", forwardAbort);
|
|
235882
236009
|
if (first !== "yield") {
|
|
235883
236010
|
backgroundProcesses.delete(taskId);
|
|
235884
|
-
|
|
236011
|
+
rmSync15(outputFile, { force: true });
|
|
235885
236012
|
if (first.ok)
|
|
235886
236013
|
return { content: first.text, status: "success" };
|
|
235887
236014
|
return {
|
|
@@ -236411,7 +236538,7 @@ var init_memory_reminder = __esm(() => {
|
|
|
236411
236538
|
});
|
|
236412
236539
|
|
|
236413
236540
|
// src/agent/system-prompt-size.ts
|
|
236414
|
-
import { existsSync as existsSync45, readdirSync as
|
|
236541
|
+
import { existsSync as existsSync45, readdirSync as readdirSync16, readFileSync as readFileSync36 } from "node:fs";
|
|
236415
236542
|
import { join as join60 } from "node:path";
|
|
236416
236543
|
function estimateSystemTokens(text2) {
|
|
236417
236544
|
return Math.ceil(Buffer.byteLength(text2, "utf8") / SYSTEM_PROMPT_BYTES_PER_TOKEN);
|
|
@@ -236424,7 +236551,7 @@ function walkMarkdownFiles(dir) {
|
|
|
236424
236551
|
return [];
|
|
236425
236552
|
}
|
|
236426
236553
|
const out = [];
|
|
236427
|
-
const entries =
|
|
236554
|
+
const entries = readdirSync16(dir, { withFileTypes: true });
|
|
236428
236555
|
for (const entry of entries) {
|
|
236429
236556
|
if (entry.name.startsWith(".")) {
|
|
236430
236557
|
continue;
|
|
@@ -236445,7 +236572,7 @@ function estimateSystemPromptSize(memoryDir, localMemfs = false) {
|
|
|
236445
236572
|
return { total: 0, files: [] };
|
|
236446
236573
|
}
|
|
236447
236574
|
const memoryFormat = detectMemoryFormat(memoryDir, localMemfs);
|
|
236448
|
-
const files = memoryFormat === "memfs-v2" ?
|
|
236575
|
+
const files = memoryFormat === "memfs-v2" ? readdirSync16(memoryDir, { withFileTypes: true }).filter((entry) => !entry.name.startsWith(".") && entry.isFile() && entry.name.endsWith(".md")).map((entry) => join60(memoryDir, entry.name)).sort() : walkMarkdownFiles(join60(memoryDir, "system")).sort();
|
|
236449
236576
|
const rows = [];
|
|
236450
236577
|
for (const filePath of files) {
|
|
236451
236578
|
const text2 = readFileSync36(filePath, "utf8");
|
|
@@ -237325,6 +237452,30 @@ var init_stream_observers = __esm(() => {
|
|
|
237325
237452
|
init_debug();
|
|
237326
237453
|
});
|
|
237327
237454
|
|
|
237455
|
+
// src/websocket/listener/subagent-state-cache.ts
|
|
237456
|
+
function clearSubagentSnapshotCache(owner) {
|
|
237457
|
+
lastSubagentSnapshotByOwner.delete(owner);
|
|
237458
|
+
}
|
|
237459
|
+
function shouldEmitSubagentSnapshot(owner, scope, snapshot2, options) {
|
|
237460
|
+
const snapshotJson = JSON.stringify(snapshot2);
|
|
237461
|
+
const cacheKey = `${scope?.agent_id ?? ""}:${scope?.conversation_id ?? ""}`;
|
|
237462
|
+
let scopeCache = lastSubagentSnapshotByOwner.get(owner);
|
|
237463
|
+
if (!scopeCache) {
|
|
237464
|
+
scopeCache = new Map;
|
|
237465
|
+
lastSubagentSnapshotByOwner.set(owner, scopeCache);
|
|
237466
|
+
}
|
|
237467
|
+
const previousJson = scopeCache.get(cacheKey) ?? EMPTY_SNAPSHOT_JSON;
|
|
237468
|
+
if (options?.onlyIfChanged && previousJson === snapshotJson) {
|
|
237469
|
+
return false;
|
|
237470
|
+
}
|
|
237471
|
+
scopeCache.set(cacheKey, snapshotJson);
|
|
237472
|
+
return true;
|
|
237473
|
+
}
|
|
237474
|
+
var EMPTY_SNAPSHOT_JSON = "[]", lastSubagentSnapshotByOwner;
|
|
237475
|
+
var init_subagent_state_cache = __esm(() => {
|
|
237476
|
+
lastSubagentSnapshotByOwner = new WeakMap;
|
|
237477
|
+
});
|
|
237478
|
+
|
|
237328
237479
|
// src/websocket/listener/inbound-queue.ts
|
|
237329
237480
|
function getInboundClientMessageId(incoming) {
|
|
237330
237481
|
return getInboundClientMessageIds(incoming)[0];
|
|
@@ -237437,7 +237588,6 @@ __export(exports_protocol_outbound, {
|
|
|
237437
237588
|
refreshDeviceGitContext: () => refreshDeviceGitContext,
|
|
237438
237589
|
isSystemReminderPart: () => isSystemReminderPart,
|
|
237439
237590
|
emitSubagentStateUpdate: () => emitSubagentStateUpdate,
|
|
237440
|
-
emitSubagentStateIfOpen: () => emitSubagentStateIfOpen,
|
|
237441
237591
|
emitStreamDelta: () => emitStreamDelta,
|
|
237442
237592
|
emitStatusDelta: () => emitStatusDelta,
|
|
237443
237593
|
emitStateSync: () => emitStateSync,
|
|
@@ -237909,26 +238059,22 @@ function buildSubagentSnapshot(runtime, scope) {
|
|
|
237909
238059
|
parent_conversation_id: a2.parentConversationId,
|
|
237910
238060
|
start_time: a2.startTime,
|
|
237911
238061
|
tool_calls: a2.toolCalls,
|
|
238062
|
+
...a2.progressTexts?.length ? { progress_texts: a2.progressTexts } : {},
|
|
237912
238063
|
total_tokens: a2.totalTokens,
|
|
237913
238064
|
duration_ms: a2.durationMs,
|
|
237914
238065
|
error: a2.error,
|
|
237915
238066
|
...a2.result !== undefined ? { result: a2.result } : {}
|
|
237916
238067
|
}));
|
|
237917
238068
|
}
|
|
237918
|
-
function emitSubagentStateUpdate(socket, runtime, scope, routing = TO_SUBSCRIBERS) {
|
|
237919
|
-
const
|
|
237920
|
-
|
|
237921
|
-
|
|
237922
|
-
|
|
238069
|
+
function emitSubagentStateUpdate(socket, runtime, scope, routing = TO_SUBSCRIBERS, options) {
|
|
238070
|
+
const subagents = buildSubagentSnapshot(runtime, scope);
|
|
238071
|
+
const cacheScope = resolveSubagentScopeForSnapshot(runtime, scope);
|
|
238072
|
+
const cacheOwner = getListenerRuntime(runtime) ?? socket;
|
|
238073
|
+
if (!shouldEmitSubagentSnapshot(cacheOwner, cacheScope, subagents, options))
|
|
238074
|
+
return;
|
|
238075
|
+
const message = { type: "update_subagent_state", subagents };
|
|
237923
238076
|
emitProtocolV2Message(socket, runtime, message, scope, routing);
|
|
237924
238077
|
}
|
|
237925
|
-
function emitSubagentStateIfOpen(runtime, scope) {
|
|
237926
|
-
const listener = getListenerRuntime(runtime);
|
|
237927
|
-
const transport3 = listener?.transport ?? listener?.socket;
|
|
237928
|
-
if (transport3 && isListenerTransportOpen(transport3)) {
|
|
237929
|
-
emitSubagentStateUpdate(transport3, runtime, scope);
|
|
237930
|
-
}
|
|
237931
|
-
}
|
|
237932
238078
|
function emitCanonicalMessageDelta(socket, runtime, delta2, scope, routing = TO_SUBSCRIBERS) {
|
|
237933
238079
|
return emitStreamDelta(socket, runtime, delta2, scope, undefined, routing);
|
|
237934
238080
|
}
|
|
@@ -237996,6 +238142,7 @@ var init_protocol_outbound = __esm(async () => {
|
|
|
237996
238142
|
init_permission_mode();
|
|
237997
238143
|
init_protocol_outbound_routing();
|
|
237998
238144
|
init_stream_observers();
|
|
238145
|
+
init_subagent_state_cache();
|
|
237999
238146
|
init_transport2();
|
|
238000
238147
|
await __promiseAll([
|
|
238001
238148
|
init_connection(),
|
|
@@ -241497,6 +241644,7 @@ __export(exports_environments3, {
|
|
|
241497
241644
|
isEnvironmentOnline: () => isEnvironmentOnline,
|
|
241498
241645
|
getTeleportStatus: () => getTeleportStatus,
|
|
241499
241646
|
getEnvironmentConnection: () => getEnvironmentConnection,
|
|
241647
|
+
environmentMatchesSelector: () => environmentMatchesSelector,
|
|
241500
241648
|
describeEnvironment: () => describeEnvironment,
|
|
241501
241649
|
createAgentSandbox: () => createAgentSandbox
|
|
241502
241650
|
});
|
|
@@ -241542,15 +241690,16 @@ async function resolveDesktopEnvironmentConnectionId(list = listEnvironments) {
|
|
|
241542
241690
|
}
|
|
241543
241691
|
return { connectionId: environment2.connectionId, environment: environment2 };
|
|
241544
241692
|
}
|
|
241693
|
+
function environmentMatchesSelector(environment2, selector) {
|
|
241694
|
+
return environment2.connectionId === selector || environment2.id === selector || environment2.deviceId === selector || environment2.connectionName === selector;
|
|
241695
|
+
}
|
|
241545
241696
|
async function resolveEnvironmentConnectionId(selector, list = listEnvironments) {
|
|
241546
241697
|
const trimmed = selector.trim();
|
|
241547
241698
|
if (!trimmed) {
|
|
241548
241699
|
throw new Error("Computer selector must not be empty");
|
|
241549
241700
|
}
|
|
241550
241701
|
const response = await list({ limit: 100 });
|
|
241551
|
-
const matches3 = response.connections.filter((environment3) =>
|
|
241552
|
-
return environment3.connectionId === trimmed || environment3.id === trimmed || environment3.deviceId === trimmed || environment3.connectionName === trimmed;
|
|
241553
|
-
});
|
|
241702
|
+
const matches3 = response.connections.filter((environment3) => environmentMatchesSelector(environment3, trimmed));
|
|
241554
241703
|
if (matches3.length === 0) {
|
|
241555
241704
|
throw new Error(`Computer "${trimmed}" not found. Run \`letta computers list\` to discover available computers.`);
|
|
241556
241705
|
}
|
|
@@ -241691,6 +241840,34 @@ async function lookupEnvironmentForTarget(deviceId) {
|
|
|
241691
241840
|
return null;
|
|
241692
241841
|
}
|
|
241693
241842
|
}
|
|
241843
|
+
async function resolveTargetDeviceSelector(selector) {
|
|
241844
|
+
let environments2;
|
|
241845
|
+
let response;
|
|
241846
|
+
try {
|
|
241847
|
+
environments2 = await Promise.resolve().then(() => (init_environments3(), exports_environments3));
|
|
241848
|
+
response = await environments2.listEnvironments({ limit: 100 });
|
|
241849
|
+
} catch {
|
|
241850
|
+
return null;
|
|
241851
|
+
}
|
|
241852
|
+
const matches3 = response.connections.filter((environment3) => environments2.environmentMatchesSelector(environment3, selector));
|
|
241853
|
+
if (matches3.length === 0) {
|
|
241854
|
+
if (response.hasNextPage)
|
|
241855
|
+
return null;
|
|
241856
|
+
return {
|
|
241857
|
+
error: `Computer "${selector}" not found. Run \`letta computers list\` and pass its deviceId (or name).`
|
|
241858
|
+
};
|
|
241859
|
+
}
|
|
241860
|
+
if (new Set(matches3.map((environment3) => environment3.deviceId)).size > 1) {
|
|
241861
|
+
return {
|
|
241862
|
+
error: `Computer "${selector}" is ambiguous. Matched: ${matches3.map(environments2.describeEnvironment).join(", ")}. Pass a deviceId instead.`
|
|
241863
|
+
};
|
|
241864
|
+
}
|
|
241865
|
+
matches3.sort((a2, b3) => Math.max(b3.lastHeartbeat ?? 0, b3.lastSeenAt) - Math.max(a2.lastHeartbeat ?? 0, a2.lastSeenAt));
|
|
241866
|
+
const environment2 = matches3[0];
|
|
241867
|
+
if (!environment2)
|
|
241868
|
+
return null;
|
|
241869
|
+
return { deviceId: environment2.deviceId, environment: environment2 };
|
|
241870
|
+
}
|
|
241694
241871
|
async function resolveCronCreatePlacement(params) {
|
|
241695
241872
|
const resolved2 = await resolveCronRunnerForAgent(params.agentId);
|
|
241696
241873
|
if ("error" in resolved2)
|
|
@@ -241701,12 +241878,24 @@ async function resolveCronCreatePlacement(params) {
|
|
|
241701
241878
|
error: "--computer is only available from a managed Cloud sandbox. Run the schedule on this computer instead."
|
|
241702
241879
|
};
|
|
241703
241880
|
}
|
|
241704
|
-
if (targetDeviceId)
|
|
241705
|
-
|
|
241706
|
-
|
|
241707
|
-
|
|
241708
|
-
|
|
241709
|
-
|
|
241881
|
+
if (!targetDeviceId)
|
|
241882
|
+
return { runner: resolved2.runner };
|
|
241883
|
+
const selectorValidity = validateTargetDevice(targetDeviceId, null);
|
|
241884
|
+
if (!selectorValidity.ok)
|
|
241885
|
+
return selectorValidity;
|
|
241886
|
+
const resolution = await resolveTargetDeviceSelector(targetDeviceId);
|
|
241887
|
+
if (!resolution) {
|
|
241888
|
+
const validity2 = validateTargetDevice(targetDeviceId, await lookupEnvironmentForTarget(targetDeviceId));
|
|
241889
|
+
if (!validity2.ok)
|
|
241890
|
+
return validity2;
|
|
241891
|
+
return { runner: resolved2.runner, targetDeviceId };
|
|
241892
|
+
}
|
|
241893
|
+
if ("error" in resolution)
|
|
241894
|
+
return resolution;
|
|
241895
|
+
const validity = validateTargetDevice(resolution.deviceId, resolution.environment);
|
|
241896
|
+
if (!validity.ok)
|
|
241897
|
+
return validity;
|
|
241898
|
+
return { runner: resolved2.runner, targetDeviceId: resolution.deviceId };
|
|
241710
241899
|
}
|
|
241711
241900
|
function buildCloudScheduleInput(params) {
|
|
241712
241901
|
const notes = [];
|
|
@@ -242548,17 +242737,30 @@ var init_monitor_script = __esm(() => {
|
|
|
242548
242737
|
|
|
242549
242738
|
// src/tools/impl/monitor-timeout.ts
|
|
242550
242739
|
function getMonitorMaxTimeoutMs() {
|
|
242551
|
-
const
|
|
242740
|
+
const seconds = process.env.LETTA_MONITOR_MAX_TIMEOUT_SECONDS;
|
|
242741
|
+
const value = seconds || process.env.LETTA_MONITOR_MAX_TIMEOUT_MS;
|
|
242552
242742
|
if (!value || !/^\d+$/.test(value))
|
|
242553
242743
|
return DEFAULT_MAX_TIMEOUT_MS;
|
|
242554
|
-
const parsed = Number(value);
|
|
242555
|
-
if (!Number.
|
|
242744
|
+
const parsed = seconds ? Number(value) * 1000 : Number(value);
|
|
242745
|
+
if (!Number.isSafeInteger(parsed) || parsed <= 0) {
|
|
242556
242746
|
return DEFAULT_MAX_TIMEOUT_MS;
|
|
242747
|
+
}
|
|
242557
242748
|
return Math.min(SEVEN_DAYS_MS, Math.max(DEFAULT_MAX_TIMEOUT_MS, parsed));
|
|
242558
242749
|
}
|
|
242559
|
-
|
|
242750
|
+
function formatMonitorMaxTimeout(timeoutMs = getMonitorMaxTimeoutMs()) {
|
|
242751
|
+
const days = timeoutMs >= 2 * DAY_MS && timeoutMs % DAY_MS === 0;
|
|
242752
|
+
const value = days ? timeoutMs / DAY_MS : Math.round(timeoutMs / HOUR_MS * 100) / 100;
|
|
242753
|
+
const unit = days ? "day" : "hour";
|
|
242754
|
+
return `${value} ${unit}${value === 1 ? "" : "s"}`;
|
|
242755
|
+
}
|
|
242756
|
+
function applyMonitorMaxTimeout(text2, timeoutMs = getMonitorMaxTimeoutMs()) {
|
|
242757
|
+
return text2.replaceAll("{{MONITOR_MAX_TIMEOUT}}", formatMonitorMaxTimeout(timeoutMs));
|
|
242758
|
+
}
|
|
242759
|
+
var HOUR_MS = 3600000, DAY_MS, DEFAULT_MAX_TIMEOUT_MS, SEVEN_DAYS_MS;
|
|
242560
242760
|
var init_monitor_timeout = __esm(() => {
|
|
242561
|
-
|
|
242761
|
+
DAY_MS = 24 * HOUR_MS;
|
|
242762
|
+
DEFAULT_MAX_TIMEOUT_MS = HOUR_MS;
|
|
242763
|
+
SEVEN_DAYS_MS = 7 * DAY_MS;
|
|
242562
242764
|
});
|
|
242563
242765
|
|
|
242564
242766
|
// src/tools/impl/monitor.ts
|
|
@@ -244149,6 +244351,8 @@ function noReplyMessage(receipt) {
|
|
|
244149
244351
|
}
|
|
244150
244352
|
async function waitForAcceptedSuperRun(receipt, signal, deps) {
|
|
244151
244353
|
const pollMs = deps.pollMs ?? 1000;
|
|
244354
|
+
const runLinkGraceMs = deps.runLinkGraceMs ?? DEFAULT_RUN_LINK_GRACE_MS;
|
|
244355
|
+
let completedWithoutRunSince;
|
|
244152
244356
|
const sleep11 = deps.sleep ?? ((ms, waitSignal) => delay3(ms, undefined, { signal: waitSignal }));
|
|
244153
244357
|
while (true) {
|
|
244154
244358
|
signal.throwIfAborted();
|
|
@@ -244164,6 +244368,11 @@ async function waitForAcceptedSuperRun(receipt, signal, deps) {
|
|
|
244164
244368
|
}
|
|
244165
244369
|
const runId = exact.run_ids[0];
|
|
244166
244370
|
if (!runId) {
|
|
244371
|
+
completedWithoutRunSince ??= Date.now();
|
|
244372
|
+
if (Date.now() - completedWithoutRunSince < runLinkGraceMs) {
|
|
244373
|
+
await sleep11(pollMs, signal);
|
|
244374
|
+
continue;
|
|
244375
|
+
}
|
|
244167
244376
|
throw new RemoteExecutionFailed(`Remote Super Run ${exact.id} completed without a correlated child run.`);
|
|
244168
244377
|
}
|
|
244169
244378
|
const run = await retryRead(() => deps.run(runId, AbortSignal.any([signal, AbortSignal.timeout(30000)])), signal, sleep11, `Remote child run read for ${runId} failed`);
|
|
@@ -244187,7 +244396,7 @@ async function waitForAcceptedSuperRun(receipt, signal, deps) {
|
|
|
244187
244396
|
};
|
|
244188
244397
|
}
|
|
244189
244398
|
}
|
|
244190
|
-
var RemoteExecutionFailed;
|
|
244399
|
+
var RemoteExecutionFailed, DEFAULT_RUN_LINK_GRACE_MS = 60000;
|
|
244191
244400
|
var init_headless_super_run_wait = __esm(() => {
|
|
244192
244401
|
init_letta_client();
|
|
244193
244402
|
init_conversation_enqueue();
|
|
@@ -244475,9 +244684,10 @@ import { createInterface as createInterface8 } from "node:readline";
|
|
|
244475
244684
|
function errorMessage2(error5) {
|
|
244476
244685
|
return error5 instanceof Error ? error5.message : String(error5);
|
|
244477
244686
|
}
|
|
244478
|
-
function userInput(prompt) {
|
|
244687
|
+
function userInput(prompt, uuid5) {
|
|
244479
244688
|
return `${JSON.stringify({
|
|
244480
244689
|
type: "user",
|
|
244690
|
+
uuid: uuid5,
|
|
244481
244691
|
message: {
|
|
244482
244692
|
role: "user",
|
|
244483
244693
|
content: [{ type: "text", text: prompt }]
|
|
@@ -244502,6 +244712,7 @@ function buildClaudeStreamArgs(options) {
|
|
|
244502
244712
|
"--output-format",
|
|
244503
244713
|
"stream-json",
|
|
244504
244714
|
"--include-partial-messages",
|
|
244715
|
+
"--replay-user-messages",
|
|
244505
244716
|
"--permission-mode",
|
|
244506
244717
|
"bypassPermissions"
|
|
244507
244718
|
];
|
|
@@ -244549,19 +244760,29 @@ function rejectTurnWaiters(session3, error5) {
|
|
|
244549
244760
|
waiter.reject(error5);
|
|
244550
244761
|
session3.turnWaiters.clear();
|
|
244551
244762
|
}
|
|
244763
|
+
function clearBackgroundCap(session3) {
|
|
244764
|
+
if (session3.backgroundCapTimer)
|
|
244765
|
+
clearTimeout(session3.backgroundCapTimer);
|
|
244766
|
+
session3.backgroundCapTimer = undefined;
|
|
244767
|
+
}
|
|
244552
244768
|
function markTurnStarted(session3) {
|
|
244553
244769
|
session3.interruptible = true;
|
|
244770
|
+
session3.idleOnBackgroundTasks = false;
|
|
244771
|
+
clearBackgroundCap(session3);
|
|
244554
244772
|
if (session3.awaitingReplacementStart) {
|
|
244555
244773
|
session3.awaitingReplacementStart = false;
|
|
244556
244774
|
session3.pendingSteers = 0;
|
|
244557
244775
|
session3.suppressedResult = undefined;
|
|
244558
244776
|
}
|
|
244777
|
+
resolveTurnWaiters(session3);
|
|
244778
|
+
}
|
|
244779
|
+
function resolveTurnWaiters(session3) {
|
|
244559
244780
|
for (const waiter of session3.turnWaiters)
|
|
244560
244781
|
waiter.resolve();
|
|
244561
244782
|
session3.turnWaiters.clear();
|
|
244562
244783
|
}
|
|
244563
244784
|
function waitForTurnStart(session3, signal) {
|
|
244564
|
-
if (session3.interruptible)
|
|
244785
|
+
if (session3.interruptible || session3.idleOnBackgroundTasks)
|
|
244565
244786
|
return Promise.resolve();
|
|
244566
244787
|
if (session3.settled) {
|
|
244567
244788
|
return Promise.reject(new Error("Claude Code session is no longer active"));
|
|
@@ -244594,9 +244815,8 @@ function settle(session3, result3) {
|
|
|
244594
244815
|
if (session3.settled)
|
|
244595
244816
|
return;
|
|
244596
244817
|
session3.settled = true;
|
|
244597
|
-
session3.
|
|
244598
|
-
|
|
244599
|
-
sessions.delete(session3.sessionId);
|
|
244818
|
+
session3.idleOnBackgroundTasks = false;
|
|
244819
|
+
clearBackgroundCap(session3);
|
|
244600
244820
|
const completedError = new Error("Claude Code session completed");
|
|
244601
244821
|
rejectControls(session3, completedError);
|
|
244602
244822
|
rejectTurnWaiters(session3, completedError);
|
|
@@ -244614,8 +244834,21 @@ function writeRaw(stdin, data) {
|
|
|
244614
244834
|
});
|
|
244615
244835
|
});
|
|
244616
244836
|
}
|
|
244617
|
-
function writeInput(
|
|
244618
|
-
|
|
244837
|
+
function writeInput(session3, prompt) {
|
|
244838
|
+
const uuid5 = randomUUID36();
|
|
244839
|
+
session3.latestInputUuid = uuid5;
|
|
244840
|
+
session3.latestInputStarted = false;
|
|
244841
|
+
return writeRaw(session3.transport.process.stdin, userInput(prompt, uuid5));
|
|
244842
|
+
}
|
|
244843
|
+
function acknowledgeInput(session3, uuid5) {
|
|
244844
|
+
if (typeof uuid5 !== "string" || !session3.latestInputUuid)
|
|
244845
|
+
return;
|
|
244846
|
+
session3.acknowledgesInputs = true;
|
|
244847
|
+
if (uuid5 === session3.latestInputUuid)
|
|
244848
|
+
session3.latestInputStarted = true;
|
|
244849
|
+
}
|
|
244850
|
+
function isStaleResult(session3) {
|
|
244851
|
+
return session3.acknowledgesInputs && !session3.latestInputStarted;
|
|
244619
244852
|
}
|
|
244620
244853
|
function closeInput(session3) {
|
|
244621
244854
|
if (!session3.transport.process.stdin.destroyed && !session3.transport.process.stdin.writableEnded) {
|
|
@@ -244656,15 +244889,31 @@ function handleControlResponse(session3, value) {
|
|
|
244656
244889
|
pending2.reject(new Error(detail));
|
|
244657
244890
|
}
|
|
244658
244891
|
}
|
|
244892
|
+
function reportText(session3, messageId, text2) {
|
|
244893
|
+
if (!session3.onText || typeof text2 !== "string" || !text2.trim())
|
|
244894
|
+
return;
|
|
244895
|
+
const key2 = `${typeof messageId === "string" ? messageId : ""}\x00${text2.slice(0, 1000)}`;
|
|
244896
|
+
if (session3.seenTextBlocks.has(key2))
|
|
244897
|
+
return;
|
|
244898
|
+
session3.seenTextBlocks.add(key2);
|
|
244899
|
+
try {
|
|
244900
|
+
session3.onText(text2);
|
|
244901
|
+
} catch {}
|
|
244902
|
+
}
|
|
244659
244903
|
function handleAssistant(session3, value) {
|
|
244660
|
-
if (!session3.onToolCall)
|
|
244904
|
+
if (!session3.onToolCall && !session3.onText)
|
|
244661
244905
|
return;
|
|
244662
|
-
const
|
|
244906
|
+
const message = readRecord(value.message);
|
|
244907
|
+
const content = message?.content;
|
|
244663
244908
|
if (!Array.isArray(content))
|
|
244664
244909
|
return;
|
|
244665
244910
|
for (const entry of content) {
|
|
244666
244911
|
const block = readRecord(entry);
|
|
244667
|
-
if (block?.type
|
|
244912
|
+
if (block?.type === "text") {
|
|
244913
|
+
reportText(session3, message?.id, block.text);
|
|
244914
|
+
continue;
|
|
244915
|
+
}
|
|
244916
|
+
if (!session3.onToolCall || block?.type !== "tool_use" || typeof block.id !== "string" || typeof block.name !== "string" || session3.seenToolCallIds.has(block.id))
|
|
244668
244917
|
continue;
|
|
244669
244918
|
session3.seenToolCallIds.add(block.id);
|
|
244670
244919
|
try {
|
|
@@ -244677,6 +244926,8 @@ function handleAssistant(session3, value) {
|
|
|
244677
244926
|
}
|
|
244678
244927
|
}
|
|
244679
244928
|
function settleResult(session3, value) {
|
|
244929
|
+
if (session3.settled)
|
|
244930
|
+
return;
|
|
244680
244931
|
if (typeof value.result === "string")
|
|
244681
244932
|
session3.report = value.result;
|
|
244682
244933
|
closeInput(session3);
|
|
@@ -244686,6 +244937,41 @@ function settleResult(session3, value) {
|
|
|
244686
244937
|
settle(session3, successResult(session3));
|
|
244687
244938
|
}
|
|
244688
244939
|
}
|
|
244940
|
+
function handleBackgroundTasksChanged(session3, value) {
|
|
244941
|
+
if (Array.isArray(value.tasks))
|
|
244942
|
+
session3.backgroundTasks = value.tasks;
|
|
244943
|
+
}
|
|
244944
|
+
function holdResult(session3, value) {
|
|
244945
|
+
if (session3.settled)
|
|
244946
|
+
return;
|
|
244947
|
+
const capMs = session3.backgroundCapMs;
|
|
244948
|
+
if (typeof value.result === "string")
|
|
244949
|
+
session3.report = value.result;
|
|
244950
|
+
session3.provisionalResult = value;
|
|
244951
|
+
session3.idleOnBackgroundTasks = true;
|
|
244952
|
+
resolveTurnWaiters(session3);
|
|
244953
|
+
clearBackgroundCap(session3);
|
|
244954
|
+
session3.backgroundCapTimer = setTimeout(() => {
|
|
244955
|
+
session3.backgroundCapTimer = undefined;
|
|
244956
|
+
if (session3.settled)
|
|
244957
|
+
return;
|
|
244958
|
+
const minutes = Math.round(capMs / 60000);
|
|
244959
|
+
const note = `[Claude Code background tasks were still running ${minutes} minute(s) after its last result; reporting that result.]`;
|
|
244960
|
+
const text2 = typeof value.result === "string" ? value.result : session3.report;
|
|
244961
|
+
settleResult(session3, {
|
|
244962
|
+
...value,
|
|
244963
|
+
result: text2 ? `${text2}
|
|
244964
|
+
|
|
244965
|
+
${note}` : note
|
|
244966
|
+
});
|
|
244967
|
+
}, capMs);
|
|
244968
|
+
}
|
|
244969
|
+
function finishResult(session3, value) {
|
|
244970
|
+
if (session3.backgroundTasks.length > 0)
|
|
244971
|
+
holdResult(session3, value);
|
|
244972
|
+
else
|
|
244973
|
+
settleResult(session3, value);
|
|
244974
|
+
}
|
|
244689
244975
|
function handleResult(session3, value) {
|
|
244690
244976
|
session3.interruptible = false;
|
|
244691
244977
|
session3.resultCount++;
|
|
@@ -244694,7 +244980,9 @@ function handleResult(session3, value) {
|
|
|
244694
244980
|
session3.suppressedResult = value;
|
|
244695
244981
|
return;
|
|
244696
244982
|
}
|
|
244697
|
-
|
|
244983
|
+
if (isStaleResult(session3))
|
|
244984
|
+
return;
|
|
244985
|
+
finishResult(session3, value);
|
|
244698
244986
|
}
|
|
244699
244987
|
async function launchSession(options, deps) {
|
|
244700
244988
|
const sessionId = options.resumeSessionId ?? options.sessionId ?? deps.createSessionId?.() ?? randomUUID36();
|
|
@@ -244731,6 +245019,10 @@ async function launchSession(options, deps) {
|
|
|
244731
245019
|
const completion = new Promise((done) => {
|
|
244732
245020
|
resolve35 = done;
|
|
244733
245021
|
});
|
|
245022
|
+
let resolveExit;
|
|
245023
|
+
const exit = new Promise((done) => {
|
|
245024
|
+
resolveExit = done;
|
|
245025
|
+
});
|
|
244734
245026
|
const session3 = {
|
|
244735
245027
|
sessionId,
|
|
244736
245028
|
transport: transport3,
|
|
@@ -244740,11 +245032,21 @@ async function launchSession(options, deps) {
|
|
|
244740
245032
|
report: "",
|
|
244741
245033
|
protocolError: undefined,
|
|
244742
245034
|
settled: false,
|
|
245035
|
+
exited: false,
|
|
245036
|
+
exit,
|
|
245037
|
+
latestInputUuid: undefined,
|
|
245038
|
+
latestInputStarted: false,
|
|
245039
|
+
acknowledgesInputs: false,
|
|
244743
245040
|
pendingSteers: 0,
|
|
244744
245041
|
interruptible: false,
|
|
244745
245042
|
awaitingReplacementStart: false,
|
|
244746
245043
|
suppressedResult: undefined,
|
|
244747
245044
|
resultCount: 0,
|
|
245045
|
+
backgroundTasks: [],
|
|
245046
|
+
provisionalResult: undefined,
|
|
245047
|
+
idleOnBackgroundTasks: false,
|
|
245048
|
+
backgroundCapMs: deps.backgroundTaskWaitCapMs ?? BACKGROUND_TASK_WAIT_CAP_MS,
|
|
245049
|
+
backgroundCapTimer: undefined,
|
|
244748
245050
|
turnWaiters: new Set,
|
|
244749
245051
|
writeLock: Promise.resolve(),
|
|
244750
245052
|
completion,
|
|
@@ -244753,7 +245055,9 @@ async function launchSession(options, deps) {
|
|
|
244753
245055
|
abortController,
|
|
244754
245056
|
removeUpstreamAbort,
|
|
244755
245057
|
onToolCall: options.onToolCall,
|
|
244756
|
-
seenToolCallIds: new Set
|
|
245058
|
+
seenToolCallIds: new Set,
|
|
245059
|
+
onText: options.onText,
|
|
245060
|
+
seenTextBlocks: new Set
|
|
244757
245061
|
};
|
|
244758
245062
|
sessions.set(sessionId, session3);
|
|
244759
245063
|
transport3.process.stderr.setEncoding("utf8");
|
|
@@ -244768,8 +245072,14 @@ async function launchSession(options, deps) {
|
|
|
244768
245072
|
const value = JSON.parse(line);
|
|
244769
245073
|
if (value.type === "control_response") {
|
|
244770
245074
|
handleControlResponse(session3, value);
|
|
245075
|
+
} else if (value.type === "user" && value.isReplay === true) {
|
|
245076
|
+
acknowledgeInput(session3, value.uuid);
|
|
245077
|
+
} else if (value.type === "command_lifecycle" && (value.state === "started" || value.state === "completed")) {
|
|
245078
|
+
acknowledgeInput(session3, value.command_uuid);
|
|
244771
245079
|
} else if (value.type === "result") {
|
|
244772
245080
|
handleResult(session3, value);
|
|
245081
|
+
} else if (value.type === "system" && value.subtype === "background_tasks_changed") {
|
|
245082
|
+
handleBackgroundTasksChanged(session3, value);
|
|
244773
245083
|
} else if (value.type === "assistant") {
|
|
244774
245084
|
handleAssistant(session3, value);
|
|
244775
245085
|
} else if (value.type === "stream_event" && readRecord(value.event)?.type === "message_start") {
|
|
@@ -244782,6 +245092,10 @@ async function launchSession(options, deps) {
|
|
|
244782
245092
|
transport3.completion.then(({ exitCode, exitSignal }) => {
|
|
244783
245093
|
if (session3.settled)
|
|
244784
245094
|
return;
|
|
245095
|
+
if (session3.provisionalResult && exitCode === 0 && !transport3.wasAborted()) {
|
|
245096
|
+
settleResult(session3, session3.provisionalResult);
|
|
245097
|
+
return;
|
|
245098
|
+
}
|
|
244785
245099
|
const detail = session3.stderr.trim();
|
|
244786
245100
|
const protocolDetail = session3.protocolError ? `; protocol error: ${session3.protocolError}` : "";
|
|
244787
245101
|
const oomDetail = exitCode === 143 || exitSignal === "SIGTERM" || exitSignal === "SIGKILL" ? "; possibly out of memory" : "";
|
|
@@ -244791,9 +245105,15 @@ async function launchSession(options, deps) {
|
|
|
244791
245105
|
}).catch((error5) => {
|
|
244792
245106
|
rejectControls(session3, new Error(errorMessage2(error5)));
|
|
244793
245107
|
settle(session3, failResult(session3, error5));
|
|
245108
|
+
}).finally(() => {
|
|
245109
|
+
session3.exited = true;
|
|
245110
|
+
removeUpstreamAbort();
|
|
245111
|
+
if (sessions.get(sessionId) === session3)
|
|
245112
|
+
sessions.delete(sessionId);
|
|
245113
|
+
resolveExit();
|
|
244794
245114
|
});
|
|
244795
245115
|
try {
|
|
244796
|
-
await writeInput(
|
|
245116
|
+
await writeInput(session3, options.prompt);
|
|
244797
245117
|
} catch (error5) {
|
|
244798
245118
|
settle(session3, failResult(session3, error5));
|
|
244799
245119
|
abortController.abort(error5);
|
|
@@ -244805,12 +245125,51 @@ async function launchSession(options, deps) {
|
|
|
244805
245125
|
options.onStarted?.(sessionId);
|
|
244806
245126
|
return session3;
|
|
244807
245127
|
}
|
|
245128
|
+
async function waitForSettledExit(session3, deps, signal) {
|
|
245129
|
+
if (session3.exited)
|
|
245130
|
+
return;
|
|
245131
|
+
const graceMs = deps.settledExitGraceMs ?? SETTLED_EXIT_GRACE_MS;
|
|
245132
|
+
let timer;
|
|
245133
|
+
let onAbort;
|
|
245134
|
+
const cancelled = new Promise((_4, reject2) => {
|
|
245135
|
+
onAbort = () => reject2(signal?.reason instanceof Error ? signal.reason : new Error("Claude Code turn cancelled"));
|
|
245136
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
245137
|
+
if (signal?.aborted)
|
|
245138
|
+
onAbort();
|
|
245139
|
+
});
|
|
245140
|
+
cancelled.catch(() => {
|
|
245141
|
+
return;
|
|
245142
|
+
});
|
|
245143
|
+
try {
|
|
245144
|
+
const exitedInTime = await Promise.race([
|
|
245145
|
+
session3.exit.then(() => true),
|
|
245146
|
+
new Promise((resolve35) => {
|
|
245147
|
+
timer = setTimeout(() => resolve35(false), graceMs);
|
|
245148
|
+
}),
|
|
245149
|
+
cancelled
|
|
245150
|
+
]);
|
|
245151
|
+
if (!exitedInTime) {
|
|
245152
|
+
session3.abortController.abort(new Error("Claude Code process replaced by a new turn"));
|
|
245153
|
+
await Promise.race([session3.exit, cancelled]);
|
|
245154
|
+
}
|
|
245155
|
+
} finally {
|
|
245156
|
+
if (timer)
|
|
245157
|
+
clearTimeout(timer);
|
|
245158
|
+
if (onAbort)
|
|
245159
|
+
signal?.removeEventListener("abort", onAbort);
|
|
245160
|
+
}
|
|
245161
|
+
}
|
|
244808
245162
|
async function startSession(options, deps) {
|
|
244809
245163
|
const key2 = options.resumeSessionId ?? options.sessionId;
|
|
244810
245164
|
if (key2) {
|
|
244811
|
-
|
|
244812
|
-
|
|
244813
|
-
|
|
245165
|
+
for (;; ) {
|
|
245166
|
+
const existing = sessions.get(key2);
|
|
245167
|
+
if (!existing)
|
|
245168
|
+
break;
|
|
245169
|
+
if (!existing.settled)
|
|
245170
|
+
return existing;
|
|
245171
|
+
await waitForSettledExit(existing, deps, options.signal);
|
|
245172
|
+
}
|
|
244814
245173
|
}
|
|
244815
245174
|
return launchSession(options, deps);
|
|
244816
245175
|
}
|
|
@@ -244835,6 +245194,14 @@ async function steerSession(session3, prompt, signal) {
|
|
|
244835
245194
|
await withWriteLock(session3, async () => {
|
|
244836
245195
|
signal?.throwIfAborted();
|
|
244837
245196
|
await waitForTurnStart(session3, signal);
|
|
245197
|
+
if (session3.idleOnBackgroundTasks) {
|
|
245198
|
+
if (session3.settled || sessions.get(session3.sessionId) !== session3) {
|
|
245199
|
+
throw new Error("Claude Code session is no longer active");
|
|
245200
|
+
}
|
|
245201
|
+
session3.idleOnBackgroundTasks = false;
|
|
245202
|
+
await writeInput(session3, prompt);
|
|
245203
|
+
return;
|
|
245204
|
+
}
|
|
244838
245205
|
if (session3.settled || sessions.get(session3.sessionId) !== session3) {
|
|
244839
245206
|
throw new Error("Claude Code session is no longer active");
|
|
244840
245207
|
}
|
|
@@ -244859,7 +245226,7 @@ async function steerSession(session3, prompt, signal) {
|
|
|
244859
245226
|
await response;
|
|
244860
245227
|
interruptAcknowledged = true;
|
|
244861
245228
|
signal?.throwIfAborted();
|
|
244862
|
-
await writeInput(session3
|
|
245229
|
+
await writeInput(session3, prompt);
|
|
244863
245230
|
session3.awaitingReplacementStart = true;
|
|
244864
245231
|
session3.suppressedResult = undefined;
|
|
244865
245232
|
} catch (error5) {
|
|
@@ -244872,7 +245239,7 @@ async function steerSession(session3, prompt, signal) {
|
|
|
244872
245239
|
} else if (session3.suppressedResult) {
|
|
244873
245240
|
const suppressed = session3.suppressedResult;
|
|
244874
245241
|
session3.suppressedResult = undefined;
|
|
244875
|
-
|
|
245242
|
+
finishResult(session3, suppressed);
|
|
244876
245243
|
} else if (session3.resultCount === resultCount && !session3.settled && sessions.get(session3.sessionId) === session3) {
|
|
244877
245244
|
markTurnStarted(session3);
|
|
244878
245245
|
}
|
|
@@ -244884,42 +245251,144 @@ async function steerSession(session3, prompt, signal) {
|
|
|
244884
245251
|
}
|
|
244885
245252
|
});
|
|
244886
245253
|
}
|
|
244887
|
-
async function
|
|
244888
|
-
|
|
244889
|
-
|
|
244890
|
-
|
|
245254
|
+
async function deliverClaudeMessage(options, deps, launch) {
|
|
245255
|
+
for (;; ) {
|
|
245256
|
+
const existing = sessions.get(options.sessionId);
|
|
245257
|
+
if (!existing)
|
|
245258
|
+
break;
|
|
245259
|
+
if (existing.settled) {
|
|
245260
|
+
await waitForSettledExit(existing, deps, options.signal);
|
|
245261
|
+
continue;
|
|
245262
|
+
}
|
|
244891
245263
|
try {
|
|
244892
|
-
await steerSession(
|
|
244893
|
-
return { mode: "steered",
|
|
245264
|
+
await steerSession(existing, options.prompt, options.signal);
|
|
245265
|
+
return { mode: "steered", session: existing };
|
|
244894
245266
|
} catch (error5) {
|
|
244895
|
-
if (sessions.get(options.sessionId) ===
|
|
245267
|
+
if (sessions.get(options.sessionId) === existing && !existing.settled)
|
|
244896
245268
|
throw error5;
|
|
244897
245269
|
}
|
|
244898
245270
|
}
|
|
244899
|
-
if (
|
|
244900
|
-
|
|
244901
|
-
const session3 = await
|
|
245271
|
+
if (!launch)
|
|
245272
|
+
return;
|
|
245273
|
+
const session3 = await launch();
|
|
244902
245274
|
if (session3.sessionId !== options.sessionId) {
|
|
244903
245275
|
throw new Error("Claude Code resumed with an unexpected session ID");
|
|
244904
245276
|
}
|
|
245277
|
+
return { mode: "resumed", session: session3 };
|
|
245278
|
+
}
|
|
245279
|
+
function trackedReceipt(session3) {
|
|
244905
245280
|
return {
|
|
244906
245281
|
mode: "resumed",
|
|
244907
|
-
sessionId:
|
|
245282
|
+
sessionId: session3.sessionId,
|
|
244908
245283
|
completion: session3.completion,
|
|
244909
245284
|
interrupt: async () => {
|
|
244910
245285
|
session3.abortController.abort(new Error("Claude Code turn cancelled"));
|
|
244911
245286
|
}
|
|
244912
245287
|
};
|
|
244913
245288
|
}
|
|
244914
|
-
|
|
245289
|
+
async function sendClaudeMessage(options, deps = {}) {
|
|
245290
|
+
options.signal?.throwIfAborted();
|
|
245291
|
+
const steered = await deliverClaudeMessage(options, deps);
|
|
245292
|
+
if (steered)
|
|
245293
|
+
return { mode: "steered", sessionId: options.sessionId };
|
|
245294
|
+
if (options.beforeStart)
|
|
245295
|
+
await options.beforeStart();
|
|
245296
|
+
const delivered = await deliverClaudeMessage(options, deps, () => launchSession({ ...options, resumeSessionId: options.sessionId }, deps));
|
|
245297
|
+
if (!delivered)
|
|
245298
|
+
throw new Error("Claude Code session did not start");
|
|
245299
|
+
if (delivered.mode === "steered" && !options.beforeStart)
|
|
245300
|
+
return { mode: "steered", sessionId: options.sessionId };
|
|
245301
|
+
return trackedReceipt(delivered.session);
|
|
245302
|
+
}
|
|
245303
|
+
var sessions, CONTROL_RESPONSE_TIMEOUT_MS = 30000, TURN_START_TIMEOUT_MS = 60000, BACKGROUND_TASK_WAIT_CAP_MS, SETTLED_EXIT_GRACE_MS = 1e4;
|
|
244915
245304
|
var init_claude_stream_session = __esm(() => {
|
|
244916
245305
|
init_subagent_process();
|
|
244917
245306
|
init_native_cli_env();
|
|
244918
245307
|
sessions = new Map;
|
|
245308
|
+
BACKGROUND_TASK_WAIT_CAP_MS = 35 * 60000;
|
|
245309
|
+
});
|
|
245310
|
+
|
|
245311
|
+
// src/tools/impl/codex-app-server-payloads.ts
|
|
245312
|
+
function asRecord9(value) {
|
|
245313
|
+
return value && typeof value === "object" ? value : undefined;
|
|
245314
|
+
}
|
|
245315
|
+
function readString3(value, key2) {
|
|
245316
|
+
const record6 = asRecord9(value);
|
|
245317
|
+
return typeof record6?.[key2] === "string" ? record6[key2] : undefined;
|
|
245318
|
+
}
|
|
245319
|
+
function isCapacityError(error5) {
|
|
245320
|
+
const info = asRecord9(error5.codexErrorInfo);
|
|
245321
|
+
if (info && Object.values(info).some((detail) => asRecord9(detail)?.httpStatusCode === 409)) {
|
|
245322
|
+
return true;
|
|
245323
|
+
}
|
|
245324
|
+
return /\b409 Conflict\b/i.test(readString3(error5, "message") ?? "");
|
|
245325
|
+
}
|
|
245326
|
+
function turnFailureMessage(turnError, notifications) {
|
|
245327
|
+
const messages = [turnError, ...notifications].map((error5) => readString3(error5, "message")?.trim()).filter((message) => Boolean(message));
|
|
245328
|
+
return messages.length ? [...new Set(messages)].join("; ") : undefined;
|
|
245329
|
+
}
|
|
245330
|
+
function turnReport(params) {
|
|
245331
|
+
const turn = asRecord9(params.turn);
|
|
245332
|
+
const items3 = Array.isArray(turn?.items) ? turn.items : [];
|
|
245333
|
+
for (let index = items3.length - 1;index >= 0; index--) {
|
|
245334
|
+
const item = asRecord9(items3[index]);
|
|
245335
|
+
if (item?.type === "agentMessage" && typeof item.text === "string") {
|
|
245336
|
+
return item.text;
|
|
245337
|
+
}
|
|
245338
|
+
}
|
|
245339
|
+
return "";
|
|
245340
|
+
}
|
|
245341
|
+
function describeCodexToolItem(item) {
|
|
245342
|
+
const id2 = readString3(item, "id");
|
|
245343
|
+
if (!item || !id2)
|
|
245344
|
+
return;
|
|
245345
|
+
const call2 = (name, args) => ({
|
|
245346
|
+
id: id2,
|
|
245347
|
+
name,
|
|
245348
|
+
args: formatExternalToolCallArgs(args)
|
|
245349
|
+
});
|
|
245350
|
+
switch (item.type) {
|
|
245351
|
+
case "commandExecution":
|
|
245352
|
+
return call2("Bash", { command: item.command });
|
|
245353
|
+
case "fileChange": {
|
|
245354
|
+
const changes = Array.isArray(item.changes) ? item.changes : [];
|
|
245355
|
+
return call2("Edit", {
|
|
245356
|
+
files: changes.map((change) => readString3(change, "path"))
|
|
245357
|
+
});
|
|
245358
|
+
}
|
|
245359
|
+
case "mcpToolCall":
|
|
245360
|
+
return call2(`${readString3(item, "server") ?? "mcp"}/${readString3(item, "tool") ?? "tool"}`, item.arguments);
|
|
245361
|
+
case "dynamicToolCall":
|
|
245362
|
+
return call2(readString3(item, "tool") ?? "tool", item.arguments);
|
|
245363
|
+
case "webSearch": {
|
|
245364
|
+
const query3 = readString3(item, "query");
|
|
245365
|
+
return query3 ? call2("WebSearch", { query: query3 }) : undefined;
|
|
245366
|
+
}
|
|
245367
|
+
default:
|
|
245368
|
+
return;
|
|
245369
|
+
}
|
|
245370
|
+
}
|
|
245371
|
+
function capacityResult(result3) {
|
|
245372
|
+
return {
|
|
245373
|
+
...result3,
|
|
245374
|
+
error: `${CODEX_CAPACITY_ERROR}. Last error: ${result3.error ?? "unknown"}`
|
|
245375
|
+
};
|
|
245376
|
+
}
|
|
245377
|
+
var CAPACITY_RETRY_DELAYS_MS, CODEX_CAPACITY_ERROR = "Codex is out of capacity for this session; start a new codex session or use claude-code", TOOL_ITEM_TYPES;
|
|
245378
|
+
var init_codex_app_server_payloads = __esm(() => {
|
|
245379
|
+
CAPACITY_RETRY_DELAYS_MS = [1000, 2000];
|
|
245380
|
+
TOOL_ITEM_TYPES = new Set([
|
|
245381
|
+
"commandExecution",
|
|
245382
|
+
"fileChange",
|
|
245383
|
+
"mcpToolCall",
|
|
245384
|
+
"dynamicToolCall",
|
|
245385
|
+
"webSearch"
|
|
245386
|
+
]);
|
|
244919
245387
|
});
|
|
244920
245388
|
|
|
244921
245389
|
// src/tools/impl/codex-app-server.ts
|
|
244922
245390
|
import { createInterface as createInterface9 } from "node:readline";
|
|
245391
|
+
import { setTimeout as sleep11 } from "node:timers/promises";
|
|
244923
245392
|
async function listCodexModels(cwd2, env6) {
|
|
244924
245393
|
const controller = new AbortController;
|
|
244925
245394
|
const running = spawnManagedWorkloadProcess("codex", ["app-server", "--stdio"], {
|
|
@@ -244996,29 +245465,6 @@ function spawnTransport(options) {
|
|
|
244996
245465
|
})
|
|
244997
245466
|
};
|
|
244998
245467
|
}
|
|
244999
|
-
function asRecord9(value) {
|
|
245000
|
-
return value && typeof value === "object" ? value : undefined;
|
|
245001
|
-
}
|
|
245002
|
-
function readString3(value, key2) {
|
|
245003
|
-
const record6 = asRecord9(value);
|
|
245004
|
-
return typeof record6?.[key2] === "string" ? record6[key2] : undefined;
|
|
245005
|
-
}
|
|
245006
|
-
function turnError(params) {
|
|
245007
|
-
const turn = asRecord9(params.turn);
|
|
245008
|
-
const error5 = asRecord9(turn?.error);
|
|
245009
|
-
return typeof error5?.message === "string" ? error5.message : undefined;
|
|
245010
|
-
}
|
|
245011
|
-
function turnReport(params) {
|
|
245012
|
-
const turn = asRecord9(params.turn);
|
|
245013
|
-
const items3 = Array.isArray(turn?.items) ? turn.items : [];
|
|
245014
|
-
for (let index = items3.length - 1;index >= 0; index--) {
|
|
245015
|
-
const item = asRecord9(items3[index]);
|
|
245016
|
-
if (item?.type === "agentMessage" && typeof item.text === "string") {
|
|
245017
|
-
return item.text;
|
|
245018
|
-
}
|
|
245019
|
-
}
|
|
245020
|
-
return "";
|
|
245021
|
-
}
|
|
245022
245468
|
|
|
245023
245469
|
class CodexAppServerClient {
|
|
245024
245470
|
transport;
|
|
@@ -245070,7 +245516,7 @@ class CodexAppServerClient {
|
|
|
245070
245516
|
await this.request("initialize", {
|
|
245071
245517
|
clientInfo: {
|
|
245072
245518
|
name: "letta-code",
|
|
245073
|
-
version: "0.34.
|
|
245519
|
+
version: "0.34.37"
|
|
245074
245520
|
},
|
|
245075
245521
|
capabilities: null
|
|
245076
245522
|
});
|
|
@@ -245131,46 +245577,24 @@ function failSession(session3, error5) {
|
|
|
245131
245577
|
if (!waiter)
|
|
245132
245578
|
return;
|
|
245133
245579
|
waiter.resolve({
|
|
245134
|
-
|
|
245135
|
-
|
|
245136
|
-
|
|
245137
|
-
|
|
245138
|
-
|
|
245139
|
-
|
|
245140
|
-
|
|
245580
|
+
result: {
|
|
245581
|
+
agentId: `codex_${session3.threadId}`,
|
|
245582
|
+
runtimeSessionId: session3.threadId,
|
|
245583
|
+
model: waiter.model,
|
|
245584
|
+
report: waiter.latestAgentMessage ?? "",
|
|
245585
|
+
success: false,
|
|
245586
|
+
error: error5.message,
|
|
245587
|
+
durationMs: Date.now() - waiter.startedAt
|
|
245588
|
+
},
|
|
245589
|
+
capacityFailure: false,
|
|
245590
|
+
ranTool: waiter.ranTool,
|
|
245591
|
+
steered: waiter.steered
|
|
245141
245592
|
});
|
|
245142
245593
|
}
|
|
245143
|
-
function describeCodexToolItem(item) {
|
|
245144
|
-
const id2 = readString3(item, "id");
|
|
245145
|
-
if (!item || !id2)
|
|
245146
|
-
return;
|
|
245147
|
-
const call2 = (name, args) => ({
|
|
245148
|
-
id: id2,
|
|
245149
|
-
name,
|
|
245150
|
-
args: formatExternalToolCallArgs(args)
|
|
245151
|
-
});
|
|
245152
|
-
switch (item.type) {
|
|
245153
|
-
case "commandExecution":
|
|
245154
|
-
return call2("Bash", { command: item.command });
|
|
245155
|
-
case "fileChange": {
|
|
245156
|
-
const changes = Array.isArray(item.changes) ? item.changes : [];
|
|
245157
|
-
return call2("Edit", {
|
|
245158
|
-
files: changes.map((change) => readString3(change, "path"))
|
|
245159
|
-
});
|
|
245160
|
-
}
|
|
245161
|
-
case "mcpToolCall":
|
|
245162
|
-
return call2(`${readString3(item, "server") ?? "mcp"}/${readString3(item, "tool") ?? "tool"}`, item.arguments);
|
|
245163
|
-
case "dynamicToolCall":
|
|
245164
|
-
return call2(readString3(item, "tool") ?? "tool", item.arguments);
|
|
245165
|
-
case "webSearch": {
|
|
245166
|
-
const query3 = readString3(item, "query");
|
|
245167
|
-
return query3 ? call2("WebSearch", { query: query3 }) : undefined;
|
|
245168
|
-
}
|
|
245169
|
-
default:
|
|
245170
|
-
return;
|
|
245171
|
-
}
|
|
245172
|
-
}
|
|
245173
245594
|
function recordToolItem(waiter, item) {
|
|
245595
|
+
if (typeof item.type === "string" && TOOL_ITEM_TYPES.has(item.type)) {
|
|
245596
|
+
waiter.ranTool = true;
|
|
245597
|
+
}
|
|
245174
245598
|
if (!waiter.onToolCall)
|
|
245175
245599
|
return;
|
|
245176
245600
|
const call2 = describeCodexToolItem(item);
|
|
@@ -245181,6 +245605,18 @@ function recordToolItem(waiter, item) {
|
|
|
245181
245605
|
waiter.onToolCall(call2);
|
|
245182
245606
|
} catch {}
|
|
245183
245607
|
}
|
|
245608
|
+
function recordTextItem(waiter, item) {
|
|
245609
|
+
const id2 = readString3(item, "id");
|
|
245610
|
+
const { reportedText } = waiter;
|
|
245611
|
+
if (!waiter.onText || typeof item.text !== "string" || !item.text.trim() || id2 && reportedText.itemIds.has(id2) || waiter.textFromEarlierAttempts.has(item.text.trim()))
|
|
245612
|
+
return;
|
|
245613
|
+
if (id2)
|
|
245614
|
+
reportedText.itemIds.add(id2);
|
|
245615
|
+
reportedText.texts.add(item.text.trim());
|
|
245616
|
+
try {
|
|
245617
|
+
waiter.onText(item.text);
|
|
245618
|
+
} catch {}
|
|
245619
|
+
}
|
|
245184
245620
|
function recordItem(session3, params, completed) {
|
|
245185
245621
|
const turnId = readString3(params, "turnId");
|
|
245186
245622
|
if (turnId !== session3.activeTurnId || !session3.activeWaiter)
|
|
@@ -245191,6 +245627,7 @@ function recordItem(session3, params, completed) {
|
|
|
245191
245627
|
recordToolItem(session3.activeWaiter, item);
|
|
245192
245628
|
if (completed && item.type === "agentMessage" && typeof item.text === "string") {
|
|
245193
245629
|
session3.activeWaiter.latestAgentMessage = item.text;
|
|
245630
|
+
recordTextItem(session3.activeWaiter, item);
|
|
245194
245631
|
}
|
|
245195
245632
|
return true;
|
|
245196
245633
|
}
|
|
@@ -245204,19 +245641,36 @@ function settleTurn(session3, params) {
|
|
|
245204
245641
|
session3.activeTurnId = undefined;
|
|
245205
245642
|
session3.activeWaiter = undefined;
|
|
245206
245643
|
const status = readString3(turn, "status");
|
|
245207
|
-
const
|
|
245644
|
+
const completed = status === "completed";
|
|
245645
|
+
const turnError = asRecord9(turn?.error);
|
|
245646
|
+
const failure2 = turnFailureMessage(turnError, waiter.errors);
|
|
245208
245647
|
waiter.resolve({
|
|
245209
|
-
|
|
245210
|
-
|
|
245211
|
-
|
|
245212
|
-
|
|
245213
|
-
|
|
245214
|
-
|
|
245215
|
-
|
|
245648
|
+
result: {
|
|
245649
|
+
agentId: `codex_${session3.threadId}`,
|
|
245650
|
+
runtimeSessionId: session3.threadId,
|
|
245651
|
+
model: waiter.model,
|
|
245652
|
+
report: turnReport(params) || waiter.latestAgentMessage || "",
|
|
245653
|
+
success: completed,
|
|
245654
|
+
...completed ? {} : { error: failure2 ?? `Codex turn ${status ?? "failed"}` },
|
|
245655
|
+
durationMs: Date.now() - waiter.startedAt
|
|
245656
|
+
},
|
|
245657
|
+
capacityFailure: !completed && [turnError, ...waiter.errors].some((error5) => error5 !== undefined && isCapacityError(error5)),
|
|
245658
|
+
ranTool: waiter.ranTool,
|
|
245659
|
+
steered: waiter.steered
|
|
245216
245660
|
});
|
|
245217
245661
|
scheduleIdleSessionCleanup(session3);
|
|
245218
245662
|
return true;
|
|
245219
245663
|
}
|
|
245664
|
+
function recordError(session3, params) {
|
|
245665
|
+
const turnId = readString3(params, "turnId");
|
|
245666
|
+
if (turnId !== session3.activeTurnId || !session3.activeWaiter)
|
|
245667
|
+
return false;
|
|
245668
|
+
const error5 = asRecord9(params.error);
|
|
245669
|
+
if (error5 && params.willRetry !== true) {
|
|
245670
|
+
session3.activeWaiter.errors.push(error5);
|
|
245671
|
+
}
|
|
245672
|
+
return true;
|
|
245673
|
+
}
|
|
245220
245674
|
function handleNotification(session3, message) {
|
|
245221
245675
|
if (!message.params)
|
|
245222
245676
|
return true;
|
|
@@ -245229,6 +245683,9 @@ function handleNotification(session3, message) {
|
|
|
245229
245683
|
if (message.method === "turn/completed") {
|
|
245230
245684
|
return settleTurn(session3, message.params);
|
|
245231
245685
|
}
|
|
245686
|
+
if (message.method === "error") {
|
|
245687
|
+
return recordError(session3, message.params);
|
|
245688
|
+
}
|
|
245232
245689
|
return true;
|
|
245233
245690
|
}
|
|
245234
245691
|
function replayPendingNotifications(session3) {
|
|
@@ -245287,8 +245744,10 @@ async function createSession(options, deps) {
|
|
|
245287
245744
|
let session3;
|
|
245288
245745
|
const pendingNotifications = [];
|
|
245289
245746
|
const client = new CodexAppServerClient(transport3, (message) => {
|
|
245290
|
-
if (!session3
|
|
245747
|
+
if (!session3)
|
|
245291
245748
|
pendingNotifications.push(message);
|
|
245749
|
+
else if (!handleNotification(session3, message)) {
|
|
245750
|
+
session3.pendingNotifications.push(message);
|
|
245292
245751
|
}
|
|
245293
245752
|
}, (error5) => {
|
|
245294
245753
|
if (session3)
|
|
@@ -245328,7 +245787,8 @@ async function createSession(options, deps) {
|
|
|
245328
245787
|
model: options.model,
|
|
245329
245788
|
startLock: Promise.resolve(),
|
|
245330
245789
|
pendingNotifications,
|
|
245331
|
-
idleTimeoutMs: deps.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS
|
|
245790
|
+
idleTimeoutMs: deps.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS,
|
|
245791
|
+
sleep: deps.sleep ?? sleep11
|
|
245332
245792
|
};
|
|
245333
245793
|
sessions2.set(threadId, session3);
|
|
245334
245794
|
return session3;
|
|
@@ -245346,7 +245806,7 @@ async function withSessionLock(session3, operation) {
|
|
|
245346
245806
|
release();
|
|
245347
245807
|
}
|
|
245348
245808
|
}
|
|
245349
|
-
async function
|
|
245809
|
+
async function startTurnAttempt(session3, prompt, startedAt, listeners5) {
|
|
245350
245810
|
if (session3.activeTurnId) {
|
|
245351
245811
|
throw new Error("Codex thread already has an active turn");
|
|
245352
245812
|
}
|
|
@@ -245363,34 +245823,90 @@ async function startTurnUnlocked(session3, prompt, signal, onStarted, onToolCall
|
|
|
245363
245823
|
const turnId = readString3(turn, "id");
|
|
245364
245824
|
if (!turnId)
|
|
245365
245825
|
throw new Error("Codex app-server returned no native turn ID");
|
|
245366
|
-
const
|
|
245826
|
+
const outcome = new Promise((resolve35) => {
|
|
245367
245827
|
session3.activeTurnId = turnId;
|
|
245368
245828
|
session3.activeWaiter = {
|
|
245369
245829
|
turnId,
|
|
245370
245830
|
resolve: resolve35,
|
|
245371
|
-
startedAt
|
|
245831
|
+
startedAt,
|
|
245372
245832
|
model: session3.model,
|
|
245373
|
-
onToolCall,
|
|
245374
|
-
seenToolCallIds: new Set
|
|
245833
|
+
onToolCall: listeners5.onToolCall,
|
|
245834
|
+
seenToolCallIds: new Set,
|
|
245835
|
+
onText: listeners5.onText,
|
|
245836
|
+
reportedText: listeners5.reportedText,
|
|
245837
|
+
textFromEarlierAttempts: new Set(listeners5.reportedText.texts),
|
|
245838
|
+
ranTool: false,
|
|
245839
|
+
steered: false,
|
|
245840
|
+
errors: []
|
|
245375
245841
|
};
|
|
245376
245842
|
});
|
|
245377
|
-
|
|
245843
|
+
return { turnId, outcome };
|
|
245844
|
+
}
|
|
245845
|
+
async function startTurnUnlocked(session3, prompt, signal, onStarted, { onToolCall, onText } = {}) {
|
|
245846
|
+
const startedAt = Date.now();
|
|
245847
|
+
const listeners5 = {
|
|
245848
|
+
onToolCall,
|
|
245849
|
+
onText,
|
|
245850
|
+
reportedText: { itemIds: new Set, texts: new Set }
|
|
245851
|
+
};
|
|
245852
|
+
const first = await startTurnAttempt(session3, prompt, startedAt, listeners5);
|
|
245853
|
+
let currentTurnId = first.turnId;
|
|
245854
|
+
let interrupted = false;
|
|
245855
|
+
onStarted?.(session3.threadId, first.turnId);
|
|
245378
245856
|
replayPendingNotifications(session3);
|
|
245379
|
-
const
|
|
245380
|
-
|
|
245381
|
-
|
|
245857
|
+
const interrupt = async () => {
|
|
245858
|
+
interrupted = true;
|
|
245859
|
+
await session3.client.request("turn/interrupt", {
|
|
245860
|
+
threadId: session3.threadId,
|
|
245861
|
+
turnId: currentTurnId
|
|
245382
245862
|
});
|
|
245383
245863
|
};
|
|
245864
|
+
const abort = () => void interrupt().catch(() => {
|
|
245865
|
+
return;
|
|
245866
|
+
});
|
|
245384
245867
|
signal?.addEventListener("abort", abort, { once: true });
|
|
245385
245868
|
if (signal?.aborted)
|
|
245386
245869
|
abort();
|
|
245870
|
+
const completion = (async () => {
|
|
245871
|
+
let attempt2 = first;
|
|
245872
|
+
for (let retry3 = 0;; retry3++) {
|
|
245873
|
+
const outcome = await attempt2.outcome;
|
|
245874
|
+
if (!outcome.capacityFailure)
|
|
245875
|
+
return outcome.result;
|
|
245876
|
+
const delay4 = CAPACITY_RETRY_DELAYS_MS[retry3];
|
|
245877
|
+
const canRetry = () => !interrupted && !signal?.aborted && !outcome.ranTool && !outcome.steered;
|
|
245878
|
+
if (delay4 === undefined || !canRetry()) {
|
|
245879
|
+
return capacityResult(outcome.result);
|
|
245880
|
+
}
|
|
245881
|
+
await session3.sleep(delay4);
|
|
245882
|
+
if (!canRetry())
|
|
245883
|
+
return capacityResult(outcome.result);
|
|
245884
|
+
try {
|
|
245885
|
+
attempt2 = await withSessionLock(session3, async () => {
|
|
245886
|
+
const next = await startTurnAttempt(session3, prompt, startedAt, listeners5);
|
|
245887
|
+
currentTurnId = next.turnId;
|
|
245888
|
+
replayPendingNotifications(session3);
|
|
245889
|
+
return next;
|
|
245890
|
+
});
|
|
245891
|
+
} catch {
|
|
245892
|
+
return capacityResult(outcome.result);
|
|
245893
|
+
}
|
|
245894
|
+
if (interrupted || signal?.aborted)
|
|
245895
|
+
abort();
|
|
245896
|
+
}
|
|
245897
|
+
})();
|
|
245387
245898
|
completion.finally(() => signal?.removeEventListener("abort", abort));
|
|
245388
|
-
return {
|
|
245899
|
+
return {
|
|
245900
|
+
threadId: session3.threadId,
|
|
245901
|
+
turnId: first.turnId,
|
|
245902
|
+
completion,
|
|
245903
|
+
interrupt
|
|
245904
|
+
};
|
|
245389
245905
|
}
|
|
245390
245906
|
function startTurn(session3, options) {
|
|
245391
245907
|
return withSessionLock(session3, async () => {
|
|
245392
245908
|
await options.beforeStart?.(session3.threadId);
|
|
245393
|
-
return startTurnUnlocked(session3, options.prompt, options.signal, options.onStarted, options
|
|
245909
|
+
return startTurnUnlocked(session3, options.prompt, options.signal, options.onStarted, options);
|
|
245394
245910
|
});
|
|
245395
245911
|
}
|
|
245396
245912
|
async function startCodexTurn(options, deps = {}) {
|
|
@@ -245428,6 +245944,9 @@ async function sendCodexMessage(options, deps = {}) {
|
|
|
245428
245944
|
expectedTurnId: activeTurnId,
|
|
245429
245945
|
input: textInput(options.prompt)
|
|
245430
245946
|
});
|
|
245947
|
+
if (session3.activeWaiter?.turnId === activeTurnId) {
|
|
245948
|
+
session3.activeWaiter.steered = true;
|
|
245949
|
+
}
|
|
245431
245950
|
return {
|
|
245432
245951
|
mode: "steered",
|
|
245433
245952
|
threadId: session3.threadId,
|
|
@@ -245440,12 +245959,9 @@ async function sendCodexMessage(options, deps = {}) {
|
|
|
245440
245959
|
}
|
|
245441
245960
|
options.signal?.throwIfAborted();
|
|
245442
245961
|
await options.beforeStart?.(session3.threadId);
|
|
245443
|
-
const handle2 = await startTurnUnlocked(session3, options.prompt, undefined, options.onStarted, options
|
|
245962
|
+
const handle2 = await startTurnUnlocked(session3, options.prompt, undefined, options.onStarted, options);
|
|
245444
245963
|
if (options.signal?.aborted) {
|
|
245445
|
-
await
|
|
245446
|
-
threadId: handle2.threadId,
|
|
245447
|
-
turnId: handle2.turnId
|
|
245448
|
-
});
|
|
245964
|
+
await handle2.interrupt();
|
|
245449
245965
|
options.signal.throwIfAborted();
|
|
245450
245966
|
}
|
|
245451
245967
|
return {
|
|
@@ -245453,12 +245969,7 @@ async function sendCodexMessage(options, deps = {}) {
|
|
|
245453
245969
|
threadId: handle2.threadId,
|
|
245454
245970
|
turnId: handle2.turnId,
|
|
245455
245971
|
completion: handle2.completion,
|
|
245456
|
-
interrupt:
|
|
245457
|
-
await session3.client.request("turn/interrupt", {
|
|
245458
|
-
threadId: handle2.threadId,
|
|
245459
|
-
turnId: handle2.turnId
|
|
245460
|
-
});
|
|
245461
|
-
}
|
|
245972
|
+
interrupt: handle2.interrupt
|
|
245462
245973
|
};
|
|
245463
245974
|
});
|
|
245464
245975
|
} catch (error5) {
|
|
@@ -245487,6 +245998,7 @@ var init_codex_app_server = __esm(() => {
|
|
|
245487
245998
|
init_subagent_process();
|
|
245488
245999
|
init_native_cli_env();
|
|
245489
246000
|
init_package_manager_spawn();
|
|
246001
|
+
init_codex_app_server_payloads();
|
|
245490
246002
|
sessions2 = new Map;
|
|
245491
246003
|
sessionCreations = new Map;
|
|
245492
246004
|
DEFAULT_IDLE_TIMEOUT_MS = 5 * 60000;
|
|
@@ -246069,7 +246581,7 @@ var init_conversation_bootstrap = __esm(() => {
|
|
|
246069
246581
|
|
|
246070
246582
|
// src/cli/helpers/session-context.ts
|
|
246071
246583
|
import { platform as platform7 } from "node:os";
|
|
246072
|
-
import { basename as
|
|
246584
|
+
import { basename as basename22 } from "node:path";
|
|
246073
246585
|
function getLocalTime() {
|
|
246074
246586
|
const now2 = new Date;
|
|
246075
246587
|
return now2.toLocaleString(undefined, {
|
|
@@ -246113,7 +246625,7 @@ function getGitInfo(cwd2) {
|
|
|
246113
246625
|
};
|
|
246114
246626
|
}
|
|
246115
246627
|
function buildUnixShellLine(shellContext) {
|
|
246116
|
-
const shellName =
|
|
246628
|
+
const shellName = basename22(shellContext.displayName) || shellContext.displayName;
|
|
246117
246629
|
return `- **Shell**: ${shellName}
|
|
246118
246630
|
`;
|
|
246119
246631
|
}
|
|
@@ -246700,7 +247212,7 @@ var init_engine3 = __esm(() => {
|
|
|
246700
247212
|
|
|
246701
247213
|
// src/tools/impl/native-session-capture.ts
|
|
246702
247214
|
import { createHash as createHash10, randomUUID as randomUUID38 } from "node:crypto";
|
|
246703
|
-
import { readdirSync as
|
|
247215
|
+
import { readdirSync as readdirSync17, rmSync as rmSync16 } from "node:fs";
|
|
246704
247216
|
import {
|
|
246705
247217
|
mkdtemp as mkdtemp4,
|
|
246706
247218
|
open as open4,
|
|
@@ -246754,7 +247266,7 @@ async function snapshotStableNativeSession(input) {
|
|
|
246754
247266
|
throw new NativeSessionSourceGrowthError;
|
|
246755
247267
|
}
|
|
246756
247268
|
function cleanupSpoolDirectorySync(directory) {
|
|
246757
|
-
|
|
247269
|
+
rmSync16(directory, { recursive: true, force: true });
|
|
246758
247270
|
spoolDirectories.delete(directory);
|
|
246759
247271
|
}
|
|
246760
247272
|
async function cleanupSpoolDirectory(directory) {
|
|
@@ -246771,7 +247283,7 @@ function scavengeStaleSpoolDirectories() {
|
|
|
246771
247283
|
staleSpoolsScavenged = true;
|
|
246772
247284
|
let entries;
|
|
246773
247285
|
try {
|
|
246774
|
-
entries =
|
|
247286
|
+
entries = readdirSync17(tmpdir13(), { withFileTypes: true });
|
|
246775
247287
|
} catch {
|
|
246776
247288
|
return;
|
|
246777
247289
|
}
|
|
@@ -247207,9 +247719,20 @@ function captureNativeSession(source, sessionId, scope, env6 = process.env, requ
|
|
|
247207
247719
|
});
|
|
247208
247720
|
return sealing.then(() => startDrain(state2, source, sessionId));
|
|
247209
247721
|
}
|
|
247722
|
+
function getNativeSessionOwner(source, sessionId) {
|
|
247723
|
+
return owners.get(key3(source, sessionId));
|
|
247724
|
+
}
|
|
247210
247725
|
function rememberNativeSession(source, sessionId, scope, cloudUrl = getServerUrl()) {
|
|
247211
247726
|
scavengeStaleSpoolDirectories();
|
|
247212
247727
|
const id2 = key3(source, sessionId);
|
|
247728
|
+
if (!owners.has(id2)) {
|
|
247729
|
+
owners.set(id2, { ...scope });
|
|
247730
|
+
if (owners.size > MAX_NATIVE_SESSION_OWNERS) {
|
|
247731
|
+
const oldest = owners.keys().next().value;
|
|
247732
|
+
if (oldest !== undefined)
|
|
247733
|
+
owners.delete(oldest);
|
|
247734
|
+
}
|
|
247735
|
+
}
|
|
247213
247736
|
if (!states2.has(id2) && UUID2.test(sessionId) && isCloudServerUrl(cloudUrl))
|
|
247214
247737
|
states2.set(id2, {
|
|
247215
247738
|
scope: { ...scope },
|
|
@@ -247227,7 +247750,7 @@ function reportNativeSessionCaptureFailure(source, sessionId, error5) {
|
|
|
247227
247750
|
const reason = error5 instanceof ApiRequestError ? `HTTP ${error5.status}` : error5 instanceof Error ? error5.name : "unknown error";
|
|
247228
247751
|
debugWarn("native-session", `${source} ${sessionId}: upload failed (${reason})`);
|
|
247229
247752
|
}
|
|
247230
|
-
var NativeChunkAcknowledgmentError, NativeSessionSourceGrowthError, states2, admissions, spoolDirectories, captureProcessInstanceId, activeInstanceRegistryKey, activeCaptureInstances, spoolDirectoryName, staleSpoolsScavenged = false, sealHookForTests, prefixVerificationHookForTests, drainHookForTests, NATIVE_SESSION_CAPTURE_CHUNK_BYTES, INITIAL_DRAIN_RETRY_MS = 250, MAX_DRAIN_RETRY_MS = 30000, SEAL_RETRY_DELAYS_MS, UUID2;
|
|
247753
|
+
var NativeChunkAcknowledgmentError, NativeSessionSourceGrowthError, states2, admissions, spoolDirectories, captureProcessInstanceId, activeInstanceRegistryKey, activeCaptureInstances, spoolDirectoryName, staleSpoolsScavenged = false, sealHookForTests, prefixVerificationHookForTests, drainHookForTests, NATIVE_SESSION_CAPTURE_CHUNK_BYTES, INITIAL_DRAIN_RETRY_MS = 250, MAX_DRAIN_RETRY_MS = 30000, SEAL_RETRY_DELAYS_MS, UUID2, MAX_NATIVE_SESSION_OWNERS = 1024, owners;
|
|
247231
247754
|
var init_native_session_capture = __esm(() => {
|
|
247232
247755
|
init_request();
|
|
247233
247756
|
init_server_url();
|
|
@@ -247265,6 +247788,7 @@ var init_native_session_capture = __esm(() => {
|
|
|
247265
247788
|
cleanupSpoolDirectorySync(directory);
|
|
247266
247789
|
}
|
|
247267
247790
|
});
|
|
247791
|
+
owners = new Map;
|
|
247268
247792
|
});
|
|
247269
247793
|
|
|
247270
247794
|
// src/tools/impl/opencode-server.ts
|
|
@@ -247920,20 +248444,16 @@ async function resolveExternalCodingAgentSecretEnv(parentAgentId, lookupParent)
|
|
|
247920
248444
|
} catch {}
|
|
247921
248445
|
return { ...inherited, ...loadSecrets2(parentAgentId) };
|
|
247922
248446
|
}
|
|
247923
|
-
async function
|
|
248447
|
+
async function buildExternalWorkerLaunchEnv(options, deps = {}) {
|
|
247924
248448
|
const parentMemoryNote = buildParentMemoryNote(options.parentAgentId);
|
|
247925
|
-
|
|
247926
|
-
|
|
247927
|
-
mcpReminder: [
|
|
247928
|
-
parentMemoryNote ? `${SYSTEM_REMINDER_OPEN}
|
|
248449
|
+
const mcpReminder = [
|
|
248450
|
+
parentMemoryNote ? `${SYSTEM_REMINDER_OPEN}
|
|
247929
248451
|
${parentMemoryNote}
|
|
247930
248452
|
${SYSTEM_REMINDER_CLOSE}` : undefined,
|
|
247931
|
-
|
|
247932
|
-
|
|
248453
|
+
options.mcpReminder
|
|
248454
|
+
].filter(Boolean).join(`
|
|
247933
248455
|
|
|
247934
|
-
`) || undefined
|
|
247935
|
-
};
|
|
247936
|
-
const startedAt = Date.now();
|
|
248456
|
+
`) || undefined;
|
|
247937
248457
|
const secretEnv = await (deps.resolveSecretEnv ?? resolveExternalCodingAgentSecretEnv)(options.parentAgentId);
|
|
247938
248458
|
const env6 = withNativeCliPath({
|
|
247939
248459
|
...deps.env ?? process.env,
|
|
@@ -247949,6 +248469,27 @@ ${SYSTEM_REMINDER_CLOSE}` : undefined,
|
|
|
247949
248469
|
} else if (options.actingUserId === null || getRuntimeContext()?.suppressActingUserFallback) {
|
|
247950
248470
|
delete env6[ACTING_USER_ID_ENV];
|
|
247951
248471
|
}
|
|
248472
|
+
return { env: env6, secretEnv, mcpReminder };
|
|
248473
|
+
}
|
|
248474
|
+
async function buildExternalWorkerResumeEnv(options, deps = {}) {
|
|
248475
|
+
const mcpReminder = await (deps.resolveMcpReminder ?? ((parentAgentId) => resolveExternalCodingAgentMcpReminder(parentAgentId, undefined)))(options.parentAgentId).catch(() => {
|
|
248476
|
+
return;
|
|
248477
|
+
});
|
|
248478
|
+
return buildExternalWorkerLaunchEnv({ ...options, mcpReminder }, deps);
|
|
248479
|
+
}
|
|
248480
|
+
function scrubExternalWorkerResult(result3, secretEnv) {
|
|
248481
|
+
return {
|
|
248482
|
+
...result3,
|
|
248483
|
+
report: scrubSecretsFromString(result3.report, secretEnv),
|
|
248484
|
+
...result3.error !== undefined && {
|
|
248485
|
+
error: scrubSecretsFromString(result3.error, secretEnv)
|
|
248486
|
+
}
|
|
248487
|
+
};
|
|
248488
|
+
}
|
|
248489
|
+
async function runExternalCodingAgent(options, deps = {}) {
|
|
248490
|
+
const startedAt = Date.now();
|
|
248491
|
+
const { env: env6, secretEnv, mcpReminder } = await buildExternalWorkerLaunchEnv(options, deps);
|
|
248492
|
+
options = { ...options, mcpReminder };
|
|
247952
248493
|
const cwd2 = options.cwd ?? getCurrentWorkingDirectory();
|
|
247953
248494
|
const captureActingUserId = options.actingUserId !== undefined ? options.actingUserId : getRuntimeActingUserAttribution();
|
|
247954
248495
|
const scope = options.parentConversationId ? {
|
|
@@ -247965,13 +248506,7 @@ ${SYSTEM_REMINDER_CLOSE}` : undefined,
|
|
|
247965
248506
|
return captureReservation;
|
|
247966
248507
|
};
|
|
247967
248508
|
const capture = async (rawResult) => {
|
|
247968
|
-
const result3 =
|
|
247969
|
-
...rawResult,
|
|
247970
|
-
report: scrubSecretsFromString(rawResult.report, secretEnv),
|
|
247971
|
-
...rawResult.error !== undefined && {
|
|
247972
|
-
error: scrubSecretsFromString(rawResult.error, secretEnv)
|
|
247973
|
-
}
|
|
247974
|
-
};
|
|
248509
|
+
const result3 = scrubExternalWorkerResult(rawResult, secretEnv);
|
|
247975
248510
|
const sessionId = result3.runtimeSessionId ?? captureSessionId;
|
|
247976
248511
|
if (scope && sessionId) {
|
|
247977
248512
|
try {
|
|
@@ -248029,6 +248564,7 @@ ${SYSTEM_REMINDER_CLOSE}` : undefined,
|
|
|
248029
248564
|
signal: options.signal,
|
|
248030
248565
|
resumeThreadId: options.resumeSessionId,
|
|
248031
248566
|
onToolCall: options.onToolCall,
|
|
248567
|
+
onText: options.onText,
|
|
248032
248568
|
beforeStart: async (threadId) => {
|
|
248033
248569
|
if (scope && !captureReservation) {
|
|
248034
248570
|
if (!options.resumeSessionId) {
|
|
@@ -248071,7 +248607,8 @@ ${SYSTEM_REMINDER_CLOSE}` : undefined,
|
|
|
248071
248607
|
signal: options.signal,
|
|
248072
248608
|
resumeSessionId: options.resumeSessionId,
|
|
248073
248609
|
sessionId,
|
|
248074
|
-
onToolCall: options.onToolCall
|
|
248610
|
+
onToolCall: options.onToolCall,
|
|
248611
|
+
onText: options.onText
|
|
248075
248612
|
}, { env: env6 }));
|
|
248076
248613
|
}
|
|
248077
248614
|
const result3 = await (deps.runProcess ?? runProcess)(buildExternalCodingAgentCommand({ ...options, cwd: cwd2 }), { cwd: cwd2, env: env6, signal: options.signal });
|
|
@@ -248874,14 +249411,59 @@ function waitForSocketOpen(socket) {
|
|
|
248874
249411
|
return new Promise((resolve35, reject2) => {
|
|
248875
249412
|
let detachOpen = () => {};
|
|
248876
249413
|
let detachError = () => {};
|
|
249414
|
+
let detachResponse = () => {};
|
|
249415
|
+
let detachBody = () => {};
|
|
248877
249416
|
const cleanup = () => {
|
|
248878
249417
|
detachOpen();
|
|
248879
249418
|
detachError();
|
|
249419
|
+
detachResponse();
|
|
249420
|
+
detachBody();
|
|
248880
249421
|
};
|
|
248881
249422
|
detachOpen = onceSocketEvent(socket, "open", () => {
|
|
248882
249423
|
cleanup();
|
|
248883
249424
|
resolve35();
|
|
248884
249425
|
});
|
|
249426
|
+
if (socket.on) {
|
|
249427
|
+
const onResponse = (_request, response) => {
|
|
249428
|
+
if (!response)
|
|
249429
|
+
return;
|
|
249430
|
+
const request2 = _request;
|
|
249431
|
+
let body3 = Buffer.alloc(0);
|
|
249432
|
+
let finished2 = false;
|
|
249433
|
+
const finish2 = () => {
|
|
249434
|
+
if (finished2)
|
|
249435
|
+
return;
|
|
249436
|
+
detachBody();
|
|
249437
|
+
const detail = body3.toString("utf8").trim();
|
|
249438
|
+
reject2(new Error(`App-server WebSocket failed to open: HTTP ${response.statusCode}${detail ? `: ${detail}` : ""}`));
|
|
249439
|
+
detachOpen();
|
|
249440
|
+
detachResponse();
|
|
249441
|
+
request2.once("close", cleanup);
|
|
249442
|
+
request2.abort();
|
|
249443
|
+
};
|
|
249444
|
+
const onData = (chunk2) => {
|
|
249445
|
+
const bytes = Buffer.isBuffer(chunk2) ? chunk2 : Buffer.from(chunk2);
|
|
249446
|
+
body3 = Buffer.concat([body3, bytes.subarray(0, 2048 - body3.length)]);
|
|
249447
|
+
if (body3.length >= 2048)
|
|
249448
|
+
finish2();
|
|
249449
|
+
};
|
|
249450
|
+
const timeout = setTimeout(finish2, 1000);
|
|
249451
|
+
detachBody = () => {
|
|
249452
|
+
finished2 = true;
|
|
249453
|
+
clearTimeout(timeout);
|
|
249454
|
+
response.off("data", onData);
|
|
249455
|
+
response.off("end", finish2);
|
|
249456
|
+
response.off("error", finish2);
|
|
249457
|
+
response.off("close", finish2);
|
|
249458
|
+
};
|
|
249459
|
+
response.on("data", onData);
|
|
249460
|
+
response.on("end", finish2);
|
|
249461
|
+
response.on("error", finish2);
|
|
249462
|
+
response.on("close", finish2);
|
|
249463
|
+
};
|
|
249464
|
+
socket.on("unexpected-response", onResponse);
|
|
249465
|
+
detachResponse = () => socket.off?.("unexpected-response", onResponse);
|
|
249466
|
+
}
|
|
248885
249467
|
detachError = onceSocketEvent(socket, "error", (event) => {
|
|
248886
249468
|
cleanup();
|
|
248887
249469
|
reject2(new Error(`App-server WebSocket failed to open: ${String(event)}`));
|
|
@@ -250116,7 +250698,7 @@ var init_subagent_launcher = __esm(async () => {
|
|
|
250116
250698
|
});
|
|
250117
250699
|
|
|
250118
250700
|
// src/agent/subagents/manager.ts
|
|
250119
|
-
import { rmSync as
|
|
250701
|
+
import { rmSync as rmSync17 } from "node:fs";
|
|
250120
250702
|
import { platform as platform8 } from "node:os";
|
|
250121
250703
|
function isProviderNotSupportedError(errorOutput) {
|
|
250122
250704
|
return errorOutput.includes("Provider") && errorOutput.includes("is not supported") && errorOutput.includes("supported providers:");
|
|
@@ -250333,7 +250915,7 @@ async function executeSubagent(type3, config2, model, userPrompt, subagentId, is
|
|
|
250333
250915
|
const { exitCode, exitSignal } = await runningProcess.completion;
|
|
250334
250916
|
if (effectiveLaunchProfile === "memory-subagent" && !parentProcessEnv.LETTA_SCRATCHPAD?.trim() && childEnv.LETTA_SCRATCHPAD) {
|
|
250335
250917
|
try {
|
|
250336
|
-
|
|
250918
|
+
rmSync17(childEnv.LETTA_SCRATCHPAD, { recursive: true, force: true });
|
|
250337
250919
|
} catch (error5) {
|
|
250338
250920
|
debugWarn("subagent", `Failed to clean up memory-subagent scratchpad: ${getErrorMessage2(error5)}`);
|
|
250339
250921
|
}
|
|
@@ -251029,6 +251611,112 @@ var init_memory_task_lifecycle = __esm(() => {
|
|
|
251029
251611
|
init_process_manager();
|
|
251030
251612
|
});
|
|
251031
251613
|
|
|
251614
|
+
// src/tools/impl/task-transcript.ts
|
|
251615
|
+
function buildTaskResultHeader(subagentType, subagentId, result3, status) {
|
|
251616
|
+
return [
|
|
251617
|
+
`subagent_type=${subagentType}`,
|
|
251618
|
+
`subagent_id=${subagentId}`,
|
|
251619
|
+
status ? `subagent_status=${status}` : undefined,
|
|
251620
|
+
result3?.agentId ? `agent_id=${result3.agentId}` : undefined,
|
|
251621
|
+
result3?.conversationId ? `conversation_id=${result3.conversationId}` : undefined,
|
|
251622
|
+
result3?.runtimeSessionId ? `runtime_session_id=${result3.runtimeSessionId}` : undefined
|
|
251623
|
+
].filter(Boolean).join(" ");
|
|
251624
|
+
}
|
|
251625
|
+
function writeTaskTranscriptStart(outputFile, description, subagentType) {
|
|
251626
|
+
appendToOutputFile(outputFile, `[Task started: ${description}]
|
|
251627
|
+
[subagent_type: ${subagentType}]
|
|
251628
|
+
|
|
251629
|
+
`);
|
|
251630
|
+
}
|
|
251631
|
+
function writeTaskTranscriptResult(outputFile, result3, header, reportAlreadyWritten = false) {
|
|
251632
|
+
if (result3.success) {
|
|
251633
|
+
const report = reportAlreadyWritten ? "" : `${result3.report}
|
|
251634
|
+
|
|
251635
|
+
`;
|
|
251636
|
+
appendToOutputFile(outputFile, `${header}
|
|
251637
|
+
|
|
251638
|
+
${report}[Task completed]
|
|
251639
|
+
`);
|
|
251640
|
+
return;
|
|
251641
|
+
}
|
|
251642
|
+
appendToOutputFile(outputFile, `${header ? `${header}
|
|
251643
|
+
|
|
251644
|
+
` : ""}[error] ${result3.error || "Subagent execution failed"}
|
|
251645
|
+
|
|
251646
|
+
[Task failed]
|
|
251647
|
+
`);
|
|
251648
|
+
}
|
|
251649
|
+
function appendProgress(log3, entry, at2) {
|
|
251650
|
+
if (log3.lines >= TASK_PROGRESS_MAX_LINES)
|
|
251651
|
+
return;
|
|
251652
|
+
log3.lines++;
|
|
251653
|
+
const line = log3.lines === TASK_PROGRESS_MAX_LINES ? `[progress log reached ${TASK_PROGRESS_MAX_LINES} lines; further progress omitted]` : `[${at2 ?? log3.now().toISOString()}] ${entry}`;
|
|
251654
|
+
appendToOutputFile(log3.outputFile, `${line}
|
|
251655
|
+
`);
|
|
251656
|
+
}
|
|
251657
|
+
function openTaskProgressLog(subagentId, outputFile, now2 = () => new Date) {
|
|
251658
|
+
progressLogs.set(subagentId, {
|
|
251659
|
+
outputFile,
|
|
251660
|
+
lines: 0,
|
|
251661
|
+
seenToolCallIds: new Set,
|
|
251662
|
+
seenTextIds: new Set,
|
|
251663
|
+
now: now2
|
|
251664
|
+
});
|
|
251665
|
+
}
|
|
251666
|
+
function closeTaskProgressLog(subagentId) {
|
|
251667
|
+
progressLogs.delete(subagentId);
|
|
251668
|
+
}
|
|
251669
|
+
function recordTaskProgressToolCall(subagentId, call2) {
|
|
251670
|
+
const log3 = progressLogs.get(subagentId);
|
|
251671
|
+
if (!log3 || log3.seenToolCallIds.has(call2.id))
|
|
251672
|
+
return;
|
|
251673
|
+
log3.seenToolCallIds.add(call2.id);
|
|
251674
|
+
log3.lastText = undefined;
|
|
251675
|
+
const args = excerptProgressText(call2.args, TASK_PROGRESS_ARGS_CHARS);
|
|
251676
|
+
appendProgress(log3, `tool: ${call2.name}${args ? ` ${args}` : ""}`);
|
|
251677
|
+
}
|
|
251678
|
+
function recordTaskProgressText(subagentId, text2) {
|
|
251679
|
+
const log3 = progressLogs.get(subagentId);
|
|
251680
|
+
if (!log3)
|
|
251681
|
+
return;
|
|
251682
|
+
const line = excerptProgressText(text2, TASK_PROGRESS_TEXT_CHARS);
|
|
251683
|
+
if (!line || line === log3.lastText)
|
|
251684
|
+
return;
|
|
251685
|
+
log3.lastText = line;
|
|
251686
|
+
appendProgress(log3, `text: ${line}`);
|
|
251687
|
+
}
|
|
251688
|
+
function recordTaskProgressRemoteText(subagentId, entry) {
|
|
251689
|
+
const log3 = progressLogs.get(subagentId);
|
|
251690
|
+
if (!log3 || log3.seenTextIds.has(entry.id))
|
|
251691
|
+
return;
|
|
251692
|
+
log3.seenTextIds.add(entry.id);
|
|
251693
|
+
const line = excerptProgressText(entry.text, TASK_PROGRESS_TEXT_CHARS);
|
|
251694
|
+
if (!line)
|
|
251695
|
+
return;
|
|
251696
|
+
log3.lastText = line;
|
|
251697
|
+
const at2 = Number.isNaN(Date.parse(entry.at)) ? undefined : new Date(entry.at).toISOString();
|
|
251698
|
+
appendProgress(log3, `text: ${line}`, at2);
|
|
251699
|
+
}
|
|
251700
|
+
function externalWorkerProgressListeners(subagentId) {
|
|
251701
|
+
return {
|
|
251702
|
+
onToolCall: (call2) => {
|
|
251703
|
+
addToolCall(subagentId, call2.id, call2.name, call2.args);
|
|
251704
|
+
recordTaskProgressToolCall(subagentId, call2);
|
|
251705
|
+
},
|
|
251706
|
+
onText: (text2) => {
|
|
251707
|
+
addProgressText(subagentId, text2);
|
|
251708
|
+
recordTaskProgressText(subagentId, text2);
|
|
251709
|
+
}
|
|
251710
|
+
};
|
|
251711
|
+
}
|
|
251712
|
+
var TASK_PROGRESS_TEXT_CHARS, TASK_PROGRESS_ARGS_CHARS = 200, TASK_PROGRESS_MAX_LINES = 1000, progressLogs;
|
|
251713
|
+
var init_task_transcript = __esm(() => {
|
|
251714
|
+
init_subagent_state();
|
|
251715
|
+
init_process_manager();
|
|
251716
|
+
TASK_PROGRESS_TEXT_CHARS = PROGRESS_TEXT_CHARS;
|
|
251717
|
+
progressLogs = new Map;
|
|
251718
|
+
});
|
|
251719
|
+
|
|
251032
251720
|
// src/tools/impl/remote-external-coding-agent.ts
|
|
251033
251721
|
import { randomUUID as randomUUID44 } from "node:crypto";
|
|
251034
251722
|
import WebSocket6 from "ws";
|
|
@@ -251134,6 +251822,9 @@ class RemoteSubagentFollower {
|
|
|
251134
251822
|
markLaunched() {
|
|
251135
251823
|
this.launched = true;
|
|
251136
251824
|
}
|
|
251825
|
+
latestAgentId() {
|
|
251826
|
+
return this.latest?.agent_id ?? undefined;
|
|
251827
|
+
}
|
|
251137
251828
|
async waitForAgentId(timeoutMs) {
|
|
251138
251829
|
const deadline = Date.now() + timeoutMs;
|
|
251139
251830
|
while (Date.now() < deadline) {
|
|
@@ -251160,6 +251851,7 @@ class RemoteSubagentFollower {
|
|
|
251160
251851
|
const onAbort = () => this.wake.resolve();
|
|
251161
251852
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
251162
251853
|
let failedReconnects = 0;
|
|
251854
|
+
let disconnectedSince;
|
|
251163
251855
|
try {
|
|
251164
251856
|
while (true) {
|
|
251165
251857
|
signal?.throwIfAborted();
|
|
@@ -251173,8 +251865,20 @@ class RemoteSubagentFollower {
|
|
|
251173
251865
|
if (latest)
|
|
251174
251866
|
onProgress(latest);
|
|
251175
251867
|
if (this.disconnected) {
|
|
251176
|
-
|
|
251868
|
+
disconnectedSince ??= Date.now();
|
|
251869
|
+
const offlineSince = disconnectedSince;
|
|
251870
|
+
this.wake = Promise.withResolvers();
|
|
251871
|
+
let timer;
|
|
251872
|
+
await Promise.race([
|
|
251873
|
+
this.wake.promise,
|
|
251874
|
+
new Promise((resolve36) => {
|
|
251875
|
+
timer = setTimeout(resolve36, Math.min(this.reconnectDelayMs * (failedReconnects + 1), MAX_RECONNECT_DELAY_MS));
|
|
251876
|
+
})
|
|
251877
|
+
]);
|
|
251878
|
+
clearTimeout(timer);
|
|
251177
251879
|
signal?.throwIfAborted();
|
|
251880
|
+
if (this.closed)
|
|
251881
|
+
throw new Error("Stopped following the subagent");
|
|
251178
251882
|
try {
|
|
251179
251883
|
const client = await this.connect();
|
|
251180
251884
|
this.attach(client);
|
|
@@ -251186,8 +251890,10 @@ class RemoteSubagentFollower {
|
|
|
251186
251890
|
recover_approvals: false
|
|
251187
251891
|
});
|
|
251188
251892
|
failedReconnects = 0;
|
|
251893
|
+
disconnectedSince = undefined;
|
|
251189
251894
|
} catch (error5) {
|
|
251190
|
-
|
|
251895
|
+
failedReconnects++;
|
|
251896
|
+
if (Date.now() - offlineSince >= DEFAULT_PUBLISHED_RESULT_RETENTION_MS)
|
|
251191
251897
|
throw new Error(`Lost connection: ${errorMessage4(error5)}`);
|
|
251192
251898
|
}
|
|
251193
251899
|
continue;
|
|
@@ -251266,9 +251972,13 @@ async function launchRemoteExternalCodingAgent(params, deps) {
|
|
|
251266
251972
|
};
|
|
251267
251973
|
}
|
|
251268
251974
|
follower.markLaunched();
|
|
251269
|
-
const
|
|
251270
|
-
|
|
251271
|
-
|
|
251975
|
+
const qualify = (nativeAgentId) => {
|
|
251976
|
+
const parsed = nativeAgentId ? parseExternalCodingAgentId(nativeAgentId) : null;
|
|
251977
|
+
return parsed && !parsed.computer ? formatExternalCodingAgentId(parsed.type, parsed.sessionId, deviceId) : null;
|
|
251978
|
+
};
|
|
251979
|
+
const launchedAgentId = qualify(launched.agent_id);
|
|
251980
|
+
const qualifiedAgentId = supportsSteering ? launchedAgentId ?? qualify(await follower.waitForAgentId(deps.agentIdWaitMs ?? 2000)) : null;
|
|
251981
|
+
const workerAgentId = () => qualify(follower.latestAgentId()) ?? qualifiedAgentId ?? launchedAgentId ?? "";
|
|
251272
251982
|
const { taskId, outputFile, subagentId } = deps.spawn({
|
|
251273
251983
|
subagentType: type3,
|
|
251274
251984
|
config: createExternalCodingAgentConfig(type3),
|
|
@@ -251281,13 +251991,30 @@ async function launchRemoteExternalCodingAgent(params, deps) {
|
|
|
251281
251991
|
spawnSubagentImpl: async (_type, _prompt, model, subagentId2, signal) => {
|
|
251282
251992
|
const startedAt = Date.now();
|
|
251283
251993
|
updateSubagent(subagentId2, { status: "running" });
|
|
251994
|
+
const recordProgress = (snapshot2) => {
|
|
251995
|
+
for (const call2 of snapshot2.tool_calls ?? [])
|
|
251996
|
+
recordTaskProgressToolCall(subagentId2, call2);
|
|
251997
|
+
const texts = Array.isArray(snapshot2.progress_texts) ? snapshot2.progress_texts : [];
|
|
251998
|
+
for (const entry of texts) {
|
|
251999
|
+
if (typeof entry?.id === "string" && typeof entry.text === "string")
|
|
252000
|
+
recordTaskProgressRemoteText(subagentId2, {
|
|
252001
|
+
id: entry.id,
|
|
252002
|
+
at: typeof entry.at === "string" ? entry.at : "",
|
|
252003
|
+
text: entry.text
|
|
252004
|
+
});
|
|
252005
|
+
}
|
|
252006
|
+
};
|
|
251284
252007
|
try {
|
|
251285
|
-
const final = await follower.waitForTerminal(signal, (snapshot2) =>
|
|
251286
|
-
|
|
251287
|
-
|
|
251288
|
-
|
|
252008
|
+
const final = await follower.waitForTerminal(signal, (snapshot2) => {
|
|
252009
|
+
updateSubagent(subagentId2, {
|
|
252010
|
+
toolCalls: snapshot2.tool_calls,
|
|
252011
|
+
totalTokens: snapshot2.total_tokens
|
|
252012
|
+
});
|
|
252013
|
+
recordProgress(snapshot2);
|
|
252014
|
+
});
|
|
252015
|
+
recordProgress(final);
|
|
251289
252016
|
return {
|
|
251290
|
-
agentId:
|
|
252017
|
+
agentId: workerAgentId(),
|
|
251291
252018
|
model: final.model ?? model,
|
|
251292
252019
|
report: final.result ?? "",
|
|
251293
252020
|
success: final.status === "completed",
|
|
@@ -251298,7 +252025,7 @@ async function launchRemoteExternalCodingAgent(params, deps) {
|
|
|
251298
252025
|
} catch (error5) {
|
|
251299
252026
|
const remoteWorkerStopped = signal?.reason === REMOTE_EXTERNAL_WORKER_STOPPED;
|
|
251300
252027
|
return {
|
|
251301
|
-
agentId:
|
|
252028
|
+
agentId: workerAgentId(),
|
|
251302
252029
|
model,
|
|
251303
252030
|
report: "",
|
|
251304
252031
|
success: false,
|
|
@@ -251447,7 +252174,7 @@ async function sendRemoteExternalCodingAgentMessage(params, deps = {}) {
|
|
|
251447
252174
|
outputFile: tracked.outputFile
|
|
251448
252175
|
};
|
|
251449
252176
|
}
|
|
251450
|
-
var REMOTE_EXTERNAL_WORKER_STOPPED, DISPLAY_NAMES, RemoteWorkerLostError;
|
|
252177
|
+
var REMOTE_EXTERNAL_WORKER_STOPPED, DISPLAY_NAMES, RemoteWorkerLostError, MAX_RECONNECT_DELAY_MS = 30000;
|
|
251451
252178
|
var init_remote_external_coding_agent = __esm(() => {
|
|
251452
252179
|
init_subagent_state();
|
|
251453
252180
|
init_app_server_client();
|
|
@@ -251457,6 +252184,7 @@ var init_remote_external_coding_agent = __esm(() => {
|
|
|
251457
252184
|
init_headless_environment_response();
|
|
251458
252185
|
init_headless_listener_launch();
|
|
251459
252186
|
init_external_coding_agent();
|
|
252187
|
+
init_task_transcript();
|
|
251460
252188
|
REMOTE_EXTERNAL_WORKER_STOPPED = Symbol("remote external worker stopped");
|
|
251461
252189
|
DISPLAY_NAMES = {
|
|
251462
252190
|
"claude-code": "Claude Code",
|
|
@@ -251695,45 +252423,6 @@ var init_task_abort_hook = __esm(() => {
|
|
|
251695
252423
|
init_process_manager();
|
|
251696
252424
|
});
|
|
251697
252425
|
|
|
251698
|
-
// src/tools/impl/task-transcript.ts
|
|
251699
|
-
function buildTaskResultHeader(subagentType, subagentId, result3, status) {
|
|
251700
|
-
return [
|
|
251701
|
-
`subagent_type=${subagentType}`,
|
|
251702
|
-
`subagent_id=${subagentId}`,
|
|
251703
|
-
status ? `subagent_status=${status}` : undefined,
|
|
251704
|
-
result3?.agentId ? `agent_id=${result3.agentId}` : undefined,
|
|
251705
|
-
result3?.conversationId ? `conversation_id=${result3.conversationId}` : undefined,
|
|
251706
|
-
result3?.runtimeSessionId ? `runtime_session_id=${result3.runtimeSessionId}` : undefined
|
|
251707
|
-
].filter(Boolean).join(" ");
|
|
251708
|
-
}
|
|
251709
|
-
function writeTaskTranscriptStart(outputFile, description, subagentType) {
|
|
251710
|
-
appendToOutputFile(outputFile, `[Task started: ${description}]
|
|
251711
|
-
[subagent_type: ${subagentType}]
|
|
251712
|
-
|
|
251713
|
-
`);
|
|
251714
|
-
}
|
|
251715
|
-
function writeTaskTranscriptResult(outputFile, result3, header, reportAlreadyWritten = false) {
|
|
251716
|
-
if (result3.success) {
|
|
251717
|
-
const report = reportAlreadyWritten ? "" : `${result3.report}
|
|
251718
|
-
|
|
251719
|
-
`;
|
|
251720
|
-
appendToOutputFile(outputFile, `${header}
|
|
251721
|
-
|
|
251722
|
-
${report}[Task completed]
|
|
251723
|
-
`);
|
|
251724
|
-
return;
|
|
251725
|
-
}
|
|
251726
|
-
appendToOutputFile(outputFile, `${header ? `${header}
|
|
251727
|
-
|
|
251728
|
-
` : ""}[error] ${result3.error || "Subagent execution failed"}
|
|
251729
|
-
|
|
251730
|
-
[Task failed]
|
|
251731
|
-
`);
|
|
251732
|
-
}
|
|
251733
|
-
var init_task_transcript = __esm(() => {
|
|
251734
|
-
init_process_manager();
|
|
251735
|
-
});
|
|
251736
|
-
|
|
251737
252426
|
// src/tools/impl/task.ts
|
|
251738
252427
|
var exports_task = {};
|
|
251739
252428
|
__export(exports_task, {
|
|
@@ -251819,6 +252508,7 @@ function spawnBackgroundSubagentTask(args) {
|
|
|
251819
252508
|
backgroundTasks.set(taskId, bgTask);
|
|
251820
252509
|
registerSubagentAbortHook(subagentId, buildBackgroundTaskAbortHook(taskId, abortController));
|
|
251821
252510
|
writeTaskTranscriptStart(outputFile, description, subagentType);
|
|
252511
|
+
openTaskProgressLog(subagentId, outputFile);
|
|
251822
252512
|
const parentAgentIdForSpawn = resolvedParentScope?.agentId;
|
|
251823
252513
|
const workerMemoryDir = subagentType === "memory" && resolvedParentScope ? memoryScope?.primaryRoot ?? getScopedMemoryFilesystemRoot(resolvedParentScope.agentId) : undefined;
|
|
251824
252514
|
const effectiveMemoryScope = memoryScope ?? (workerMemoryDir ? { primaryRoot: workerMemoryDir, writableRoots: [workerMemoryDir] } : undefined);
|
|
@@ -251841,6 +252531,7 @@ function spawnBackgroundSubagentTask(args) {
|
|
|
251841
252531
|
const unsubscribe = memoryTask?.unsubscribe ?? (() => {});
|
|
251842
252532
|
const subagentExecution = memoryTask?.execution ?? (subagentType === "memory" ? Promise.reject(new Error("Memory tasks require a parent conversation scope")) : execute());
|
|
251843
252533
|
const taskLifecycle = subagentExecution.then(async (result3) => {
|
|
252534
|
+
closeTaskProgressLog(subagentId);
|
|
251844
252535
|
await copyGitHubPullRequestTagsFn(result3.conversationId, resolvedParentScope?.conversationId);
|
|
251845
252536
|
bgTask.status = result3.success ? "completed" : "failed";
|
|
251846
252537
|
if (result3.error) {
|
|
@@ -251854,6 +252545,7 @@ function spawnBackgroundSubagentTask(args) {
|
|
|
251854
252545
|
success: result3.success,
|
|
251855
252546
|
error: result3.error,
|
|
251856
252547
|
totalTokens: result3.totalTokens,
|
|
252548
|
+
...publishResult ? { published: true } : {},
|
|
251857
252549
|
...publishResult && result3.success ? {
|
|
251858
252550
|
result: truncateByChars(result3.report || "", LIMITS.TASK_OUTPUT_CHARS, "Task", { workingDirectory: getCurrentWorkingDirectory() }).content
|
|
251859
252551
|
} : {}
|
|
@@ -251904,11 +252596,13 @@ Error: ${result3.error || "Subagent execution failed"}`;
|
|
|
251904
252596
|
text: notificationXml,
|
|
251905
252597
|
agentId: resolvedParentScope?.agentId,
|
|
251906
252598
|
conversationId: resolvedParentScope?.conversationId,
|
|
251907
|
-
actingUserId: bgTask.actingUserId
|
|
252599
|
+
actingUserId: bgTask.actingUserId,
|
|
252600
|
+
clientMessageIds: resolvedParentScope?.clientMessageIds
|
|
251908
252601
|
});
|
|
251909
252602
|
}
|
|
251910
252603
|
runSubagentStopHooksFn(subagentType, subagentId, result3.success, result3.error, result3.agentId, result3.conversationId).catch(() => {});
|
|
251911
252604
|
}).catch(async (error5) => {
|
|
252605
|
+
closeTaskProgressLog(subagentId);
|
|
251912
252606
|
const errorMessage5 = error5 instanceof Error ? error5.message : String(error5);
|
|
251913
252607
|
bgTask.status = "failed";
|
|
251914
252608
|
bgTask.error = errorMessage5;
|
|
@@ -251918,7 +252612,11 @@ Error: ${result3.error || "Subagent execution failed"}`;
|
|
|
251918
252612
|
`);
|
|
251919
252613
|
scheduleBackgroundTaskCleanup(taskId);
|
|
251920
252614
|
clearSubagentAbortHook(subagentId);
|
|
251921
|
-
completeSubagentFn(subagentId, {
|
|
252615
|
+
completeSubagentFn(subagentId, {
|
|
252616
|
+
success: false,
|
|
252617
|
+
error: errorMessage5,
|
|
252618
|
+
...publishResult ? { published: true } : {}
|
|
252619
|
+
});
|
|
251922
252620
|
try {
|
|
251923
252621
|
await onComplete?.({
|
|
251924
252622
|
success: false,
|
|
@@ -251959,7 +252657,8 @@ Error: ${errorMessage5}`,
|
|
|
251959
252657
|
text: notificationXml,
|
|
251960
252658
|
agentId: resolvedParentScope?.agentId,
|
|
251961
252659
|
conversationId: resolvedParentScope?.conversationId,
|
|
251962
|
-
actingUserId: bgTask.actingUserId
|
|
252660
|
+
actingUserId: bgTask.actingUserId,
|
|
252661
|
+
clientMessageIds: resolvedParentScope?.clientMessageIds
|
|
251963
252662
|
});
|
|
251964
252663
|
}
|
|
251965
252664
|
runSubagentStopHooksFn(subagentType, subagentId, false, errorMessage5, existingAgentId, existingConversationId).catch(() => {});
|
|
@@ -252103,7 +252802,7 @@ async function launchSubagent(args) {
|
|
|
252103
252802
|
parentScope: resolvedParentScope,
|
|
252104
252803
|
...callerNotification,
|
|
252105
252804
|
deps: {
|
|
252106
|
-
spawnSubagentImpl: async (_type, prompt2, model2,
|
|
252805
|
+
spawnSubagentImpl: async (_type, prompt2, model2, workerSubagentId, childSignal) => runExternalCodingAgent({
|
|
252107
252806
|
type: externalCodingAgentType,
|
|
252108
252807
|
prompt: prompt2,
|
|
252109
252808
|
model: model2,
|
|
@@ -252114,7 +252813,7 @@ async function launchSubagent(args) {
|
|
|
252114
252813
|
mcpReminder,
|
|
252115
252814
|
signal: childSignal,
|
|
252116
252815
|
onStarted: (agentId2) => updateSubagent(subagentId2, { agentId: agentId2, status: "running" }),
|
|
252117
|
-
|
|
252816
|
+
...externalWorkerProgressListeners(workerSubagentId)
|
|
252118
252817
|
})
|
|
252119
252818
|
}
|
|
252120
252819
|
});
|
|
@@ -252338,10 +253037,10 @@ function trackExternalFollowupCompletion(args) {
|
|
|
252338
253037
|
});
|
|
252339
253038
|
}
|
|
252340
253039
|
var init_external_coding_agent_task = __esm(async () => {
|
|
252341
|
-
init_subagent_state();
|
|
252342
253040
|
init_runtime_context();
|
|
252343
253041
|
init_external_coding_agent();
|
|
252344
253042
|
init_native_session_capture();
|
|
253043
|
+
init_task_transcript();
|
|
252345
253044
|
await init_task();
|
|
252346
253045
|
});
|
|
252347
253046
|
|
|
@@ -252478,6 +253177,10 @@ async function send_agent_message(args, deps = {}) {
|
|
|
252478
253177
|
throw error5;
|
|
252479
253178
|
}
|
|
252480
253179
|
}
|
|
253180
|
+
const worker = await buildExternalWorkerResumeEnv({
|
|
253181
|
+
parentAgentId: parentScope.agentId,
|
|
253182
|
+
actingUserId: getRuntimeActingUserAttribution()
|
|
253183
|
+
}, deps.workerEnv);
|
|
252481
253184
|
if (externalTarget.type === "codex") {
|
|
252482
253185
|
let captureReservation2;
|
|
252483
253186
|
let receipt3;
|
|
@@ -252487,6 +253190,7 @@ async function send_agent_message(args, deps = {}) {
|
|
|
252487
253190
|
prompt: args.message,
|
|
252488
253191
|
parentAgentId: parentScope.agentId,
|
|
252489
253192
|
cwd: getCurrentWorkingDirectory(),
|
|
253193
|
+
mcpReminder: worker.mcpReminder,
|
|
252490
253194
|
signal: args.signal,
|
|
252491
253195
|
beforeStart: async () => {
|
|
252492
253196
|
captureReservation2 = await reserveNativeSessionCapture("codex", externalTarget.sessionId, {
|
|
@@ -252494,7 +253198,7 @@ async function send_agent_message(args, deps = {}) {
|
|
|
252494
253198
|
actingUserId: getRuntimeActingUserAttribution()
|
|
252495
253199
|
});
|
|
252496
253200
|
}
|
|
252497
|
-
});
|
|
253201
|
+
}, { env: worker.env });
|
|
252498
253202
|
} catch (error5) {
|
|
252499
253203
|
await finishFailedNativeStartCapture(captureReservation2, "codex", externalTarget.sessionId);
|
|
252500
253204
|
throw error5;
|
|
@@ -252513,6 +253217,7 @@ async function send_agent_message(args, deps = {}) {
|
|
|
252513
253217
|
if (!receipt3.completion || !receipt3.interrupt) {
|
|
252514
253218
|
throw new Error("Codex turn/start returned an incomplete background-task receipt");
|
|
252515
253219
|
}
|
|
253220
|
+
const completion2 = receipt3.completion.then((result3) => scrubExternalWorkerResult(result3, worker.secretEnv));
|
|
252516
253221
|
let taskReceipt2;
|
|
252517
253222
|
try {
|
|
252518
253223
|
taskReceipt2 = (deps.trackExternalFollowup ?? trackExternalFollowupCompletion)({
|
|
@@ -252523,7 +253228,7 @@ async function send_agent_message(args, deps = {}) {
|
|
|
252523
253228
|
...parentScope,
|
|
252524
253229
|
actingUserId: getRuntimeActingUserAttribution()
|
|
252525
253230
|
},
|
|
252526
|
-
completion:
|
|
253231
|
+
completion: completion2,
|
|
252527
253232
|
interrupt: receipt3.interrupt,
|
|
252528
253233
|
captureReservation: captureReservation2
|
|
252529
253234
|
});
|
|
@@ -252531,7 +253236,7 @@ async function send_agent_message(args, deps = {}) {
|
|
|
252531
253236
|
await receipt3.interrupt().catch(() => {
|
|
252532
253237
|
return;
|
|
252533
253238
|
});
|
|
252534
|
-
finishUntrackedNativeCapture(
|
|
253239
|
+
finishUntrackedNativeCapture(completion2, captureReservation2, "codex", externalTarget.sessionId);
|
|
252535
253240
|
throw error5;
|
|
252536
253241
|
}
|
|
252537
253242
|
return {
|
|
@@ -252554,6 +253259,7 @@ async function send_agent_message(args, deps = {}) {
|
|
|
252554
253259
|
prompt: args.message,
|
|
252555
253260
|
parentAgentId: parentScope.agentId,
|
|
252556
253261
|
cwd: getCurrentWorkingDirectory(),
|
|
253262
|
+
mcpReminder: worker.mcpReminder,
|
|
252557
253263
|
signal: args.signal,
|
|
252558
253264
|
beforeStart: async () => {
|
|
252559
253265
|
captureReservation = await reserveNativeSessionCapture("claude_code", externalTarget.sessionId, {
|
|
@@ -252561,7 +253267,7 @@ async function send_agent_message(args, deps = {}) {
|
|
|
252561
253267
|
actingUserId: getRuntimeActingUserAttribution()
|
|
252562
253268
|
});
|
|
252563
253269
|
}
|
|
252564
|
-
});
|
|
253270
|
+
}, { env: worker.env });
|
|
252565
253271
|
} catch (error5) {
|
|
252566
253272
|
await finishFailedNativeStartCapture(captureReservation, "claude_code", externalTarget.sessionId);
|
|
252567
253273
|
throw error5;
|
|
@@ -252579,6 +253285,7 @@ async function send_agent_message(args, deps = {}) {
|
|
|
252579
253285
|
if (!receipt2.completion || !receipt2.interrupt) {
|
|
252580
253286
|
throw new Error("Claude resume returned an incomplete background-task receipt");
|
|
252581
253287
|
}
|
|
253288
|
+
const completion = receipt2.completion.then((result3) => scrubExternalWorkerResult(result3, worker.secretEnv));
|
|
252582
253289
|
let taskReceipt;
|
|
252583
253290
|
try {
|
|
252584
253291
|
taskReceipt = (deps.trackExternalFollowup ?? trackExternalFollowupCompletion)({
|
|
@@ -252589,7 +253296,7 @@ async function send_agent_message(args, deps = {}) {
|
|
|
252589
253296
|
...parentScope,
|
|
252590
253297
|
actingUserId: getRuntimeActingUserAttribution()
|
|
252591
253298
|
},
|
|
252592
|
-
completion
|
|
253299
|
+
completion,
|
|
252593
253300
|
interrupt: receipt2.interrupt,
|
|
252594
253301
|
captureReservation
|
|
252595
253302
|
});
|
|
@@ -252597,7 +253304,7 @@ async function send_agent_message(args, deps = {}) {
|
|
|
252597
253304
|
await receipt2.interrupt().catch(() => {
|
|
252598
253305
|
return;
|
|
252599
253306
|
});
|
|
252600
|
-
finishUntrackedNativeCapture(
|
|
253307
|
+
finishUntrackedNativeCapture(completion, captureReservation, "claude_code", externalTarget.sessionId);
|
|
252601
253308
|
throw error5;
|
|
252602
253309
|
}
|
|
252603
253310
|
return {
|
|
@@ -252801,7 +253508,7 @@ __export(exports_skill, {
|
|
|
252801
253508
|
loadRenderedSkillContent: () => loadRenderedSkillContent,
|
|
252802
253509
|
getResolvedSkillsDir: () => getResolvedSkillsDir
|
|
252803
253510
|
});
|
|
252804
|
-
import { existsSync as existsSync47, readdirSync as
|
|
253511
|
+
import { existsSync as existsSync47, readdirSync as readdirSync18 } from "node:fs";
|
|
252805
253512
|
import { readFile as readFile19 } from "node:fs/promises";
|
|
252806
253513
|
import { dirname as dirname30, join as join70 } from "node:path";
|
|
252807
253514
|
async function readSkillFromRoot(skillsRoot, skillId) {
|
|
@@ -252840,7 +253547,7 @@ function listSkillResources(skillMdPath) {
|
|
|
252840
253547
|
function walk3(directory, relativeDirectory) {
|
|
252841
253548
|
let entries2;
|
|
252842
253549
|
try {
|
|
252843
|
-
entries2 =
|
|
253550
|
+
entries2 = readdirSync18(directory, { withFileTypes: true });
|
|
252844
253551
|
} catch {
|
|
252845
253552
|
return;
|
|
252846
253553
|
}
|
|
@@ -254179,7 +254886,7 @@ var init_github_pull_request_watch = __esm(() => {
|
|
|
254179
254886
|
});
|
|
254180
254887
|
|
|
254181
254888
|
// src/tools/impl/watch-pr.ts
|
|
254182
|
-
import { rmSync as
|
|
254889
|
+
import { rmSync as rmSync18 } from "node:fs";
|
|
254183
254890
|
import { setTimeout as delay5 } from "node:timers/promises";
|
|
254184
254891
|
function errorText(error5) {
|
|
254185
254892
|
const message2 = error5 instanceof Error ? error5.message : String(error5);
|
|
@@ -254212,7 +254919,7 @@ async function watch_pr(args, deps = {}) {
|
|
|
254212
254919
|
if (!output.append(`[initial snapshot]
|
|
254213
254920
|
${describeGitHubPullRequestSnapshot(initial2)}
|
|
254214
254921
|
`)) {
|
|
254215
|
-
|
|
254922
|
+
rmSync18(outputFile, { force: true });
|
|
254216
254923
|
throw new Error(`WatchPR could not write its output file: ${outputFile}`);
|
|
254217
254924
|
}
|
|
254218
254925
|
const runtimeContext = getRuntimeContext();
|
|
@@ -255345,7 +256052,8 @@ ${result3}
|
|
|
255345
256052
|
}),
|
|
255346
256053
|
agentId: scope?.agentId,
|
|
255347
256054
|
conversationId: scope?.conversationId,
|
|
255348
|
-
actingUserId: scope?.actingUserId
|
|
256055
|
+
actingUserId: scope?.actingUserId,
|
|
256056
|
+
clientMessageIds: scope?.clientMessageIds
|
|
255349
256057
|
});
|
|
255350
256058
|
};
|
|
255351
256059
|
executeWorkflow(handle2.spawner, {
|
|
@@ -255866,12 +256574,12 @@ var init_Monitor2 = __esm(() => {
|
|
|
255866
256574
|
type: "number",
|
|
255867
256575
|
minimum: 1000,
|
|
255868
256576
|
default: 300000,
|
|
255869
|
-
description: "Kill the monitor after this deadline. Default 300000ms. Maximum
|
|
256577
|
+
description: "Kill the monitor after this deadline. Default 300000ms. Maximum {{MONITOR_MAX_TIMEOUT}}. Ignored when persistent is true."
|
|
255870
256578
|
},
|
|
255871
256579
|
persistent: {
|
|
255872
256580
|
type: "boolean",
|
|
255873
256581
|
default: false,
|
|
255874
|
-
description: "Run until TaskStop or session end. In managed Cloud sandboxes,
|
|
256582
|
+
description: "Run until TaskStop or session end. In managed Cloud sandboxes, it still stops after {{MONITOR_MAX_TIMEOUT}} (this sandbox's monitor cap); elsewhere there is no timeout. Call Monitor again to re-arm it. For much longer waits in Cloud, use Wake/cron."
|
|
255875
256583
|
},
|
|
255876
256584
|
backup_after_seconds: {
|
|
255877
256585
|
type: "integer",
|
|
@@ -256322,7 +257030,7 @@ var init_Wake2 = __esm(() => {
|
|
|
256322
257030
|
prompt: {
|
|
256323
257031
|
type: "string",
|
|
256324
257032
|
maxLength: 4000,
|
|
256325
|
-
description: "
|
|
257033
|
+
description: "Note to your future self: what you are waiting on, what you planned and why, and what to check before acting. Required for create."
|
|
256326
257034
|
},
|
|
256327
257035
|
after_seconds: {
|
|
256328
257036
|
type: "integer",
|
|
@@ -256544,6 +257252,7 @@ var init_tool_definitions = __esm(async () => {
|
|
|
256544
257252
|
init_grep();
|
|
256545
257253
|
init_ls();
|
|
256546
257254
|
init_memory5();
|
|
257255
|
+
init_monitor_timeout();
|
|
256547
257256
|
init_skill();
|
|
256548
257257
|
init_task_create();
|
|
256549
257258
|
init_task_get();
|
|
@@ -256652,13 +257361,13 @@ ${WINDOWS_UNIFIED_EXEC_GUIDANCE}`;
|
|
|
256652
257361
|
impl: task_stop
|
|
256653
257362
|
}),
|
|
256654
257363
|
Monitor: defineTool({
|
|
256655
|
-
schema: Monitor_default2,
|
|
256656
|
-
description: Monitor_default.trim(),
|
|
257364
|
+
schema: JSON.parse(applyMonitorMaxTimeout(JSON.stringify(Monitor_default2))),
|
|
257365
|
+
description: applyMonitorMaxTimeout(Monitor_default.trim()),
|
|
256657
257366
|
impl: monitor
|
|
256658
257367
|
}),
|
|
256659
257368
|
WatchPR: defineTool({
|
|
256660
257369
|
schema: WatchPR_default2,
|
|
256661
|
-
description: WatchPR_default.trim(),
|
|
257370
|
+
description: applyMonitorMaxTimeout(WatchPR_default.trim()),
|
|
256662
257371
|
impl: watch_pr
|
|
256663
257372
|
}),
|
|
256664
257373
|
Read: defineTool({
|
|
@@ -257051,9 +257760,9 @@ import { createHash as createHash12, randomUUID as randomUUID46 } from "node:cry
|
|
|
257051
257760
|
import {
|
|
257052
257761
|
existsSync as existsSync49,
|
|
257053
257762
|
mkdirSync as mkdirSync36,
|
|
257054
|
-
readdirSync as
|
|
257763
|
+
readdirSync as readdirSync19,
|
|
257055
257764
|
readFileSync as readFileSync40,
|
|
257056
|
-
rmSync as
|
|
257765
|
+
rmSync as rmSync19,
|
|
257057
257766
|
statSync as statSync20,
|
|
257058
257767
|
writeFileSync as writeFileSync31
|
|
257059
257768
|
} from "node:fs";
|
|
@@ -257096,7 +257805,7 @@ function createRecoveryLineageSidecarAccess(params) {
|
|
|
257096
257805
|
renameSyncWithRetry(temporary, destination);
|
|
257097
257806
|
params.syncDirectory(params.directory);
|
|
257098
257807
|
} finally {
|
|
257099
|
-
|
|
257808
|
+
rmSync19(temporary, { force: true });
|
|
257100
257809
|
}
|
|
257101
257810
|
};
|
|
257102
257811
|
const retire = (current, existing) => {
|
|
@@ -257314,7 +258023,7 @@ function createRecoveryLineageSidecarAccess(params) {
|
|
|
257314
258023
|
};
|
|
257315
258024
|
};
|
|
257316
258025
|
const remove2 = (sidecar) => {
|
|
257317
|
-
|
|
258026
|
+
rmSync19(path33(sidecar.agentId, sidecar.conversationId, sidecar.lineageId), {
|
|
257318
258027
|
force: true
|
|
257319
258028
|
});
|
|
257320
258029
|
params.syncDirectory(params.directory);
|
|
@@ -257346,12 +258055,12 @@ function createRecoveryLineageSidecarAccess(params) {
|
|
|
257346
258055
|
if (!mainFile || existsSync49(join74(params.directory, mainFile)))
|
|
257347
258056
|
return;
|
|
257348
258057
|
try {
|
|
257349
|
-
|
|
258058
|
+
rmSync19(join74(params.directory, file), { force: true });
|
|
257350
258059
|
params.syncDirectory(params.directory);
|
|
257351
258060
|
} catch {}
|
|
257352
258061
|
};
|
|
257353
258062
|
try {
|
|
257354
|
-
const files =
|
|
258063
|
+
const files = readdirSync19(params.directory);
|
|
257355
258064
|
for (const file of files) {
|
|
257356
258065
|
const temporaryMatch = file.match(temporarySidecarName) ?? file.match(legacyTemporarySidecarName);
|
|
257357
258066
|
if (!temporaryMatch)
|
|
@@ -257379,7 +258088,7 @@ function createRecoveryLineageSidecarAccess(params) {
|
|
|
257379
258088
|
try {
|
|
257380
258089
|
const currentAgeMs = Date.now() - statSync20(join74(params.directory, file)).mtimeMs;
|
|
257381
258090
|
if (!ownerIsCurrentWriter && (!ownerIsAlive && currentAgeMs >= staleTemporaryAgeMs || currentAgeMs >= maximumTemporaryAgeMs)) {
|
|
257382
|
-
|
|
258091
|
+
rmSync19(join74(params.directory, file), { force: true });
|
|
257383
258092
|
params.syncDirectory(params.directory);
|
|
257384
258093
|
}
|
|
257385
258094
|
} finally {
|
|
@@ -257437,7 +258146,7 @@ import {
|
|
|
257437
258146
|
existsSync as existsSync50,
|
|
257438
258147
|
mkdirSync as mkdirSync37,
|
|
257439
258148
|
readFileSync as readFileSync41,
|
|
257440
|
-
rmSync as
|
|
258149
|
+
rmSync as rmSync20,
|
|
257441
258150
|
unlinkSync as unlinkSync12,
|
|
257442
258151
|
writeFileSync as writeFileSync32
|
|
257443
258152
|
} from "node:fs";
|
|
@@ -257449,7 +258158,7 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
|
|
|
257449
258158
|
try {
|
|
257450
258159
|
writeInterruptedTurnRecordFile(temporary, destination, directory, record6, sync);
|
|
257451
258160
|
} finally {
|
|
257452
|
-
|
|
258161
|
+
rmSync20(temporary, { force: true });
|
|
257453
258162
|
}
|
|
257454
258163
|
}
|
|
257455
258164
|
function path33(agentId, conversationId) {
|
|
@@ -260480,9 +261189,9 @@ import {
|
|
|
260480
261189
|
fsyncSync as fsyncSync6,
|
|
260481
261190
|
mkdirSync as mkdirSync39,
|
|
260482
261191
|
openSync as openSync10,
|
|
260483
|
-
readdirSync as
|
|
261192
|
+
readdirSync as readdirSync20,
|
|
260484
261193
|
readFileSync as readFileSync43,
|
|
260485
|
-
rmSync as
|
|
261194
|
+
rmSync as rmSync21,
|
|
260486
261195
|
writeFileSync as writeFileSync34
|
|
260487
261196
|
} from "node:fs";
|
|
260488
261197
|
import { join as join77 } from "node:path";
|
|
@@ -260579,11 +261288,11 @@ function createTurnFinishedStore(directory = defaultTurnFinishedDirectory(), opt
|
|
|
260579
261288
|
renameSyncWithRetry(temporary, destination);
|
|
260580
261289
|
fsyncDirectory2(directory);
|
|
260581
261290
|
} finally {
|
|
260582
|
-
|
|
261291
|
+
rmSync21(temporary, { force: true });
|
|
260583
261292
|
}
|
|
260584
261293
|
};
|
|
260585
261294
|
const removeRecordFile = (recordPath) => {
|
|
260586
|
-
|
|
261295
|
+
rmSync21(recordPath, { force: true });
|
|
260587
261296
|
fsyncDirectory2(directory);
|
|
260588
261297
|
};
|
|
260589
261298
|
const withRecordLock = (agentId, conversationId, operation) => {
|
|
@@ -260622,7 +261331,7 @@ function createTurnFinishedStore(directory = defaultTurnFinishedDirectory(), opt
|
|
|
260622
261331
|
const sweepExpiredRecords = () => {
|
|
260623
261332
|
let entries2;
|
|
260624
261333
|
try {
|
|
260625
|
-
entries2 =
|
|
261334
|
+
entries2 = readdirSync20(directory, { withFileTypes: true });
|
|
260626
261335
|
} catch (error5) {
|
|
260627
261336
|
if (error5.code === "ENOENT")
|
|
260628
261337
|
return;
|
|
@@ -261698,6 +262407,11 @@ function getDequeuedClientMessageIds(runtime, batch) {
|
|
|
261698
262407
|
for (const clientMessageId of inboundClientMessageIds.length > 0 ? inboundClientMessageIds : item.clientMessageId ? [item.clientMessageId] : []) {
|
|
261699
262408
|
clientMessageIds.add(clientMessageId);
|
|
261700
262409
|
}
|
|
262410
|
+
if (item.kind === "task_notification") {
|
|
262411
|
+
for (const clientMessageId of item.clientMessageIds ?? []) {
|
|
262412
|
+
clientMessageIds.add(clientMessageId);
|
|
262413
|
+
}
|
|
262414
|
+
}
|
|
261701
262415
|
}
|
|
261702
262416
|
return [...clientMessageIds];
|
|
261703
262417
|
}
|
|
@@ -263310,8 +264024,8 @@ Add options:
|
|
|
263310
264024
|
conversation per fire; "self" for the current
|
|
263311
264025
|
conversation; "default" for the agent default)
|
|
263312
264026
|
--computer <id> (managed Cloud sandbox only) Run on a connected
|
|
263313
|
-
external computer (deviceId
|
|
263314
|
-
list\`). If
|
|
264027
|
+
external computer (deviceId, id, or name from
|
|
264028
|
+
\`letta computers list\`). If it is offline at fire
|
|
263315
264029
|
time, that run fails (no Cloud sandbox fallback);
|
|
263316
264030
|
omit --computer to run in the Cloud sandbox.
|
|
263317
264031
|
|
|
@@ -266135,7 +266849,7 @@ import {
|
|
|
266135
266849
|
appendFileSync as appendFileSync8,
|
|
266136
266850
|
existsSync as existsSync52,
|
|
266137
266851
|
mkdirSync as mkdirSync40,
|
|
266138
|
-
readdirSync as
|
|
266852
|
+
readdirSync as readdirSync21,
|
|
266139
266853
|
unlinkSync as unlinkSync14
|
|
266140
266854
|
} from "node:fs";
|
|
266141
266855
|
import { join as join78 } from "node:path";
|
|
@@ -266154,7 +266868,7 @@ function pruneOldLogs(dir, maxFiles) {
|
|
|
266154
266868
|
try {
|
|
266155
266869
|
if (!existsSync52(dir))
|
|
266156
266870
|
return;
|
|
266157
|
-
const files =
|
|
266871
|
+
const files = readdirSync21(dir).filter((f4) => f4.endsWith(".log")).sort();
|
|
266158
266872
|
if (files.length >= maxFiles) {
|
|
266159
266873
|
const toDelete = files.slice(0, files.length - maxFiles + 1);
|
|
266160
266874
|
for (const file of toDelete) {
|
|
@@ -266510,7 +267224,7 @@ async function registerWithCloud(opts, fetchImpl = fetch) {
|
|
|
266510
267224
|
async function registerWithCloudRetry(opts, callbacks) {
|
|
266511
267225
|
const startTime = Date.now();
|
|
266512
267226
|
const maxDurationMs = callbacks?.maxDurationMs ?? REGISTER_MAX_DURATION_MS;
|
|
266513
|
-
const
|
|
267227
|
+
const sleep12 = callbacks?.sleep ?? ((delayMs) => new Promise((resolve38) => setTimeout(resolve38, delayMs)));
|
|
266514
267228
|
let attempt2 = 0;
|
|
266515
267229
|
for (;; ) {
|
|
266516
267230
|
try {
|
|
@@ -266529,7 +267243,7 @@ async function registerWithCloudRetry(opts, callbacks) {
|
|
|
266529
267243
|
if (error5 instanceof Error) {
|
|
266530
267244
|
callbacks?.onRetry?.(attempt2, retryDelay, error5);
|
|
266531
267245
|
}
|
|
266532
|
-
await
|
|
267246
|
+
await sleep12(retryDelay);
|
|
266533
267247
|
}
|
|
266534
267248
|
}
|
|
266535
267249
|
}
|
|
@@ -269148,14 +269862,14 @@ __export(exports_memory_scanner, {
|
|
|
269148
269862
|
readFileContent: () => readFileContent,
|
|
269149
269863
|
getFileNodes: () => getFileNodes
|
|
269150
269864
|
});
|
|
269151
|
-
import { readdirSync as
|
|
269865
|
+
import { readdirSync as readdirSync22, readFileSync as readFileSync44, statSync as statSync22 } from "node:fs";
|
|
269152
269866
|
import { join as join79, relative as relative7 } from "node:path";
|
|
269153
269867
|
function scanMemoryFilesystem(memoryRoot) {
|
|
269154
269868
|
const nodes = [];
|
|
269155
269869
|
const scanDir = (dir, depth, parentIsLast) => {
|
|
269156
269870
|
let entries2;
|
|
269157
269871
|
try {
|
|
269158
|
-
entries2 =
|
|
269872
|
+
entries2 = readdirSync22(dir);
|
|
269159
269873
|
} catch {
|
|
269160
269874
|
return;
|
|
269161
269875
|
}
|
|
@@ -270453,6 +271167,7 @@ async function prepareToolExecutionContextForScope(params) {
|
|
|
270453
271167
|
actingUserId,
|
|
270454
271168
|
suppressActingUserFallback,
|
|
270455
271169
|
mcpOriginatorSuperRunId,
|
|
271170
|
+
resolveClientMessageIds,
|
|
270456
271171
|
overrideModel,
|
|
270457
271172
|
overrideProviderType,
|
|
270458
271173
|
cachedEffectiveModel,
|
|
@@ -270522,6 +271237,7 @@ async function prepareToolExecutionContextForScope(params) {
|
|
|
270522
271237
|
...actingUserId ? { actingUserId } : {},
|
|
270523
271238
|
...suppressActingUserFallback ? { suppressActingUserFallback: true } : {},
|
|
270524
271239
|
mcpOriginatorSuperRunId: mcpOriginatorSuperRunId ?? null,
|
|
271240
|
+
resolveClientMessageIds,
|
|
270525
271241
|
workingDirectory,
|
|
270526
271242
|
...skillsDirectory !== undefined ? { skillsDirectory } : {},
|
|
270527
271243
|
...skillSources !== undefined ? { skillSources } : {},
|
|
@@ -378816,10 +379532,10 @@ ${lanes.join(`
|
|
|
378816
379532
|
}
|
|
378817
379533
|
function getDefaultLibFilePriority(a2) {
|
|
378818
379534
|
if (containsPath(defaultLibraryPath, a2.fileName, false)) {
|
|
378819
|
-
const
|
|
378820
|
-
if (
|
|
379535
|
+
const basename23 = getBaseFileName(a2.fileName);
|
|
379536
|
+
if (basename23 === "lib.d.ts" || basename23 === "lib.es6.d.ts")
|
|
378821
379537
|
return 0;
|
|
378822
|
-
const name = removeSuffix(removePrefix(
|
|
379538
|
+
const name = removeSuffix(removePrefix(basename23, "lib."), ".d.ts");
|
|
378823
379539
|
const index = libs.indexOf(name);
|
|
378824
379540
|
if (index !== -1)
|
|
378825
379541
|
return index + 1;
|
|
@@ -431382,8 +432098,8 @@ ${options.prefix}` : `
|
|
|
431382
432098
|
}
|
|
431383
432099
|
};
|
|
431384
432100
|
for (const file of files) {
|
|
431385
|
-
const
|
|
431386
|
-
if (
|
|
432101
|
+
const basename23 = getBaseFileName(file);
|
|
432102
|
+
if (basename23 === "package.json" || basename23 === "bower.json") {
|
|
431387
432103
|
createProjectWatcher(file, "FileWatcher");
|
|
431388
432104
|
continue;
|
|
431389
432105
|
}
|
|
@@ -434260,8 +434976,8 @@ All files are: ${JSON.stringify(names2)}`, "Err");
|
|
|
434260
434976
|
const fileOrDirectoryPath = removeIgnoredPath(this.toPath(fileOrDirectory));
|
|
434261
434977
|
if (!fileOrDirectoryPath)
|
|
434262
434978
|
return;
|
|
434263
|
-
const
|
|
434264
|
-
if (((_a10 = result3.affectedModuleSpecifierCacheProjects) == null ? undefined : _a10.size) && (
|
|
434979
|
+
const basename23 = getBaseFileName(fileOrDirectoryPath);
|
|
434980
|
+
if (((_a10 = result3.affectedModuleSpecifierCacheProjects) == null ? undefined : _a10.size) && (basename23 === "package.json" || basename23 === "node_modules")) {
|
|
434265
434981
|
result3.affectedModuleSpecifierCacheProjects.forEach((project) => {
|
|
434266
434982
|
var _a22;
|
|
434267
434983
|
(_a22 = project.getModuleSpecifierCache()) == null || _a22.clear();
|
|
@@ -439870,7 +440586,7 @@ import {
|
|
|
439870
440586
|
existsSync as existsSync55,
|
|
439871
440587
|
mkdirSync as mkdirSync43,
|
|
439872
440588
|
readFileSync as readFileSync47,
|
|
439873
|
-
rmSync as
|
|
440589
|
+
rmSync as rmSync22,
|
|
439874
440590
|
writeFileSync as writeFileSync37
|
|
439875
440591
|
} from "node:fs";
|
|
439876
440592
|
import path37 from "node:path";
|
|
@@ -440473,7 +441189,7 @@ function removeManagedModPackage(params) {
|
|
|
440473
441189
|
assertSafePackageRemovalRoot(match3.metadata);
|
|
440474
441190
|
registry4.packagesValue.splice(match3.index, 1);
|
|
440475
441191
|
writePackageRegistry(registry4.registryPath, registry4.registry);
|
|
440476
|
-
|
|
441192
|
+
rmSync22(match3.metadata.packageRoot, { force: true, recursive: true });
|
|
440477
441193
|
return {
|
|
440478
441194
|
package: mutationItem(match3.metadata, match3.index, match3.metadata.enabled),
|
|
440479
441195
|
registryPath: registry4.registryPath,
|
|
@@ -440494,12 +441210,12 @@ var init_package_registry = __esm(() => {
|
|
|
440494
441210
|
});
|
|
440495
441211
|
|
|
440496
441212
|
// src/mods/mod-sources.ts
|
|
440497
|
-
import { existsSync as existsSync56, readdirSync as
|
|
441213
|
+
import { existsSync as existsSync56, readdirSync as readdirSync23 } from "node:fs";
|
|
440498
441214
|
import path38 from "node:path";
|
|
440499
441215
|
function listModFiles(directory) {
|
|
440500
441216
|
if (!existsSync56(directory))
|
|
440501
441217
|
return [];
|
|
440502
|
-
return
|
|
441218
|
+
return readdirSync23(directory, { withFileTypes: true }).filter((entry) => {
|
|
440503
441219
|
if (!entry.isFile())
|
|
440504
441220
|
return false;
|
|
440505
441221
|
if (entry.name.startsWith("."))
|
|
@@ -440694,7 +441410,7 @@ import { createHash as createHash16 } from "node:crypto";
|
|
|
440694
441410
|
import {
|
|
440695
441411
|
existsSync as existsSync57,
|
|
440696
441412
|
mkdirSync as mkdirSync45,
|
|
440697
|
-
readdirSync as
|
|
441413
|
+
readdirSync as readdirSync24,
|
|
440698
441414
|
readFileSync as readFileSync48,
|
|
440699
441415
|
statSync as statSync23,
|
|
440700
441416
|
unlinkSync as unlinkSync16,
|
|
@@ -440886,7 +441602,7 @@ function createImportableModPath(modPath, cacheDirectory, source) {
|
|
|
440886
441602
|
writeFileSync38(importPath, importableSource, "utf8");
|
|
440887
441603
|
}
|
|
440888
441604
|
try {
|
|
440889
|
-
for (const entry of
|
|
441605
|
+
for (const entry of readdirSync24(importCacheDirectory)) {
|
|
440890
441606
|
if (entry.startsWith(`.letta-mod-${baseName}-`) && entry !== path40.basename(importPath)) {
|
|
440891
441607
|
unlinkSync16(path40.join(importCacheDirectory, entry));
|
|
440892
441608
|
}
|
|
@@ -444338,11 +445054,11 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
444338
445054
|
existsSync: existsSync58,
|
|
444339
445055
|
lstatSync: lstatSync4,
|
|
444340
445056
|
mkdirSync: mkdirSync46,
|
|
444341
|
-
rmdirSync:
|
|
445057
|
+
rmdirSync: rmdirSync3,
|
|
444342
445058
|
symlinkSync: symlinkSync2,
|
|
444343
445059
|
unlinkSync: unlinkSync17
|
|
444344
445060
|
} = await import("node:fs");
|
|
444345
|
-
const { basename:
|
|
445061
|
+
const { basename: basename23, join: join82 } = await import("node:path");
|
|
444346
445062
|
const globalSkillsDir = getGlobalSkillsDir();
|
|
444347
445063
|
if (parsed.type === "skill_enable") {
|
|
444348
445064
|
try {
|
|
@@ -444365,14 +445081,14 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
444365
445081
|
}, "listener_skill_send_failed", "listener_skill_command");
|
|
444366
445082
|
return true;
|
|
444367
445083
|
}
|
|
444368
|
-
const linkName =
|
|
445084
|
+
const linkName = basename23(parsed.skill_path);
|
|
444369
445085
|
const linkPath = join82(globalSkillsDir, linkName);
|
|
444370
445086
|
mkdirSync46(globalSkillsDir, { recursive: true });
|
|
444371
445087
|
if (existsSync58(linkPath)) {
|
|
444372
445088
|
const stat12 = lstatSync4(linkPath);
|
|
444373
445089
|
if (stat12.isSymbolicLink()) {
|
|
444374
445090
|
if (process.platform === "win32") {
|
|
444375
|
-
|
|
445091
|
+
rmdirSync3(linkPath);
|
|
444376
445092
|
} else {
|
|
444377
445093
|
unlinkSync17(linkPath);
|
|
444378
445094
|
}
|
|
@@ -444430,7 +445146,7 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
444430
445146
|
return true;
|
|
444431
445147
|
}
|
|
444432
445148
|
if (process.platform === "win32") {
|
|
444433
|
-
|
|
445149
|
+
rmdirSync3(linkPath);
|
|
444434
445150
|
} else {
|
|
444435
445151
|
unlinkSync17(linkPath);
|
|
444436
445152
|
}
|
|
@@ -447428,7 +448144,7 @@ var init_tui_perf = __esm(() => {
|
|
|
447428
448144
|
import {
|
|
447429
448145
|
existsSync as existsSync59,
|
|
447430
448146
|
mkdirSync as mkdirSync47,
|
|
447431
|
-
readdirSync as
|
|
448147
|
+
readdirSync as readdirSync25,
|
|
447432
448148
|
unlinkSync as unlinkSync17,
|
|
447433
448149
|
writeFileSync as writeFileSync39
|
|
447434
448150
|
} from "node:fs";
|
|
@@ -447553,7 +448269,7 @@ class ChunkLog {
|
|
|
447553
448269
|
try {
|
|
447554
448270
|
if (!existsSync59(this.agentDir))
|
|
447555
448271
|
return;
|
|
447556
|
-
const files =
|
|
448272
|
+
const files = readdirSync25(this.agentDir).filter((f4) => f4.endsWith(".jsonl")).sort();
|
|
447557
448273
|
if (files.length >= MAX_SESSION_FILES2) {
|
|
447558
448274
|
const toDelete = files.slice(0, files.length - MAX_SESSION_FILES2 + 1);
|
|
447559
448275
|
for (const file of toDelete) {
|
|
@@ -451483,7 +452199,7 @@ __export(exports_diff, {
|
|
|
451483
452199
|
ADV_DIFF_IGNORE_WHITESPACE: () => ADV_DIFF_IGNORE_WHITESPACE,
|
|
451484
452200
|
ADV_DIFF_CONTEXT_LINES: () => ADV_DIFF_CONTEXT_LINES
|
|
451485
452201
|
});
|
|
451486
|
-
import { basename as
|
|
452202
|
+
import { basename as basename23 } from "node:path";
|
|
451487
452203
|
function readFileOrNull(p2) {
|
|
451488
452204
|
try {
|
|
451489
452205
|
return __require("node:fs").readFileSync(p2, "utf-8");
|
|
@@ -451507,7 +452223,7 @@ function applyAllOccurrences(content, oldStr, newStr) {
|
|
|
451507
452223
|
return { ok: true, out: content.split(oldStr).join(newStr) };
|
|
451508
452224
|
}
|
|
451509
452225
|
function computeAdvancedDiff(input, opts) {
|
|
451510
|
-
const fileName =
|
|
452226
|
+
const fileName = basename23(input.filePath || "");
|
|
451511
452227
|
const fileContent = opts?.oldStrOverride !== undefined ? opts.oldStrOverride : readFileOrNull(input.filePath);
|
|
451512
452228
|
if (fileContent === null && input.kind !== "write") {
|
|
451513
452229
|
return { mode: "fallback", reason: "File not readable" };
|
|
@@ -451539,7 +452255,7 @@ function computeAdvancedDiff(input, opts) {
|
|
|
451539
452255
|
return { mode: "advanced", fileName, oldStr, newStr, hunks };
|
|
451540
452256
|
}
|
|
451541
452257
|
function parsePatchToAdvancedDiff(patchLines, filePath) {
|
|
451542
|
-
const fileName =
|
|
452258
|
+
const fileName = basename23(filePath);
|
|
451543
452259
|
const hunks = [];
|
|
451544
452260
|
let currentHunk = null;
|
|
451545
452261
|
let oldLine = 1;
|
|
@@ -451817,8 +452533,8 @@ function isFormatterSegment(tokens) {
|
|
|
451817
452533
|
}
|
|
451818
452534
|
}
|
|
451819
452535
|
function isShellExecutor2(token2) {
|
|
451820
|
-
const
|
|
451821
|
-
return ["bash", "sh", "zsh", "dash", "ksh"].includes(
|
|
452536
|
+
const basename24 = token2.split("/").pop() ?? token2;
|
|
452537
|
+
return ["bash", "sh", "zsh", "dash", "ksh"].includes(basename24.toLowerCase());
|
|
451822
452538
|
}
|
|
451823
452539
|
function normalizeRawCommand(command) {
|
|
451824
452540
|
if (Array.isArray(command)) {
|
|
@@ -452605,7 +453321,7 @@ var init_format_args_display = __esm(() => {
|
|
|
452605
453321
|
});
|
|
452606
453322
|
|
|
452607
453323
|
// src/helpers/diff-preview.ts
|
|
452608
|
-
import path42, { basename as
|
|
453324
|
+
import path42, { basename as basename24 } from "node:path";
|
|
452609
453325
|
function parseHunkLinePrefix(raw2) {
|
|
452610
453326
|
if (raw2.length === 0) {
|
|
452611
453327
|
return { type: "context", content: "" };
|
|
@@ -452711,7 +453427,7 @@ async function computeDiffPreviews(toolName2, toolArgs, workingDirectory = getCu
|
|
|
452711
453427
|
filePath: resolvedFilePath,
|
|
452712
453428
|
content: toolArgs.content || ""
|
|
452713
453429
|
});
|
|
452714
|
-
previews.push(toDiffPreview(result3,
|
|
453430
|
+
previews.push(toDiffPreview(result3, basename24(filePath)));
|
|
452715
453431
|
}
|
|
452716
453432
|
} else if (isFileEditTool3(toolName2)) {
|
|
452717
453433
|
const filePath = toolArgs.file_path;
|
|
@@ -452724,7 +453440,7 @@ async function computeDiffPreviews(toolName2, toolArgs, workingDirectory = getCu
|
|
|
452724
453440
|
newString: toolArgs.new_string || "",
|
|
452725
453441
|
replaceAll: toolArgs.replace_all
|
|
452726
453442
|
});
|
|
452727
|
-
previews.push(toDiffPreview(result3,
|
|
453443
|
+
previews.push(toDiffPreview(result3, basename24(filePath)));
|
|
452728
453444
|
}
|
|
452729
453445
|
} else if (isPatchTool2(toolName2) && toolArgs.input) {
|
|
452730
453446
|
const operations2 = parsePatchOperations2(toolArgs.input);
|
|
@@ -452732,7 +453448,7 @@ async function computeDiffPreviews(toolName2, toolArgs, workingDirectory = getCu
|
|
|
452732
453448
|
if (op.kind === "add" || op.kind === "update") {
|
|
452733
453449
|
const result3 = parsePatchToAdvancedDiff2(op.patchLines, op.path);
|
|
452734
453450
|
if (result3) {
|
|
452735
|
-
previews.push(toDiffPreview(result3,
|
|
453451
|
+
previews.push(toDiffPreview(result3, basename24(op.path)));
|
|
452736
453452
|
}
|
|
452737
453453
|
}
|
|
452738
453454
|
}
|
|
@@ -456390,7 +457106,7 @@ var init_deepagents = __esm(() => {
|
|
|
456390
457106
|
});
|
|
456391
457107
|
|
|
456392
457108
|
// node_modules/@letta-ai/trajectory/dist/adapters/listing-shared.js
|
|
456393
|
-
import { readdirSync as
|
|
457109
|
+
import { readdirSync as readdirSync26, statSync as statSync24 } from "node:fs";
|
|
456394
457110
|
import { join as join86 } from "node:path";
|
|
456395
457111
|
function sortListings(items3) {
|
|
456396
457112
|
return items3.sort((left, right) => {
|
|
@@ -456403,7 +457119,7 @@ function sortListings(items3) {
|
|
|
456403
457119
|
}
|
|
456404
457120
|
function safeReadDir(path43) {
|
|
456405
457121
|
try {
|
|
456406
|
-
return
|
|
457122
|
+
return readdirSync26(path43, { withFileTypes: true }).map((entry) => ({
|
|
456407
457123
|
name: entry.name,
|
|
456408
457124
|
isDirectory: entry.isDirectory(),
|
|
456409
457125
|
isFile: entry.isFile()
|
|
@@ -456521,7 +457237,7 @@ var init_listing_shared = __esm(() => {
|
|
|
456521
457237
|
|
|
456522
457238
|
// node_modules/@letta-ai/trajectory/dist/adapters/claude-code/list.js
|
|
456523
457239
|
import { homedir as homedir23 } from "node:os";
|
|
456524
|
-
import { basename as
|
|
457240
|
+
import { basename as basename25, join as join87 } from "node:path";
|
|
456525
457241
|
async function listClaudeCodeTrajectories(root2) {
|
|
456526
457242
|
const base2 = root2 ?? join87(homedir23(), ".claude", "projects");
|
|
456527
457243
|
const items3 = [];
|
|
@@ -456533,7 +457249,7 @@ async function listClaudeCodeTrajectories(root2) {
|
|
|
456533
457249
|
if (!entry.isFile || !entry.name.endsWith(".jsonl"))
|
|
456534
457250
|
continue;
|
|
456535
457251
|
const path43 = join87(projectPath, entry.name);
|
|
456536
|
-
const listing = listingFromFile(
|
|
457252
|
+
const listing = listingFromFile(basename25(entry.name, ".jsonl"), path43);
|
|
456537
457253
|
if (listing)
|
|
456538
457254
|
items3.push(listing);
|
|
456539
457255
|
}
|
|
@@ -456546,12 +457262,12 @@ var init_list = __esm(() => {
|
|
|
456546
457262
|
|
|
456547
457263
|
// node_modules/@letta-ai/trajectory/dist/adapters/codex/list.js
|
|
456548
457264
|
import { homedir as homedir24 } from "node:os";
|
|
456549
|
-
import { basename as
|
|
457265
|
+
import { basename as basename26, join as join88 } from "node:path";
|
|
456550
457266
|
async function listCodexTrajectories(root2) {
|
|
456551
457267
|
const base2 = root2 ?? join88(homedir24(), ".codex", "sessions");
|
|
456552
457268
|
const items3 = [];
|
|
456553
457269
|
for (const path43 of collectFiles(base2, ".jsonl", 4)) {
|
|
456554
|
-
const listing = listingFromFile(
|
|
457270
|
+
const listing = listingFromFile(basename26(path43, ".jsonl"), path43);
|
|
456555
457271
|
if (listing)
|
|
456556
457272
|
items3.push(listing);
|
|
456557
457273
|
}
|
|
@@ -456658,7 +457374,7 @@ var init_list5 = __esm(() => {
|
|
|
456658
457374
|
// node_modules/@letta-ai/trajectory/dist/adapters/openclaw/list.js
|
|
456659
457375
|
import { existsSync as existsSync62 } from "node:fs";
|
|
456660
457376
|
import { homedir as homedir28 } from "node:os";
|
|
456661
|
-
import { basename as
|
|
457377
|
+
import { basename as basename27, join as join92 } from "node:path";
|
|
456662
457378
|
async function listOpenClawTrajectories(root2) {
|
|
456663
457379
|
const base2 = root2 ?? defaultStateDir();
|
|
456664
457380
|
const items3 = [];
|
|
@@ -456671,7 +457387,7 @@ async function listOpenClawTrajectories(root2) {
|
|
|
456671
457387
|
if (!entry.isFile || !entry.name.endsWith(".jsonl"))
|
|
456672
457388
|
continue;
|
|
456673
457389
|
const path43 = join92(sessionsPath, entry.name);
|
|
456674
|
-
const listing = listingFromFile(
|
|
457390
|
+
const listing = listingFromFile(basename27(entry.name, ".jsonl"), path43);
|
|
456675
457391
|
if (listing)
|
|
456676
457392
|
items3.push(listing);
|
|
456677
457393
|
}
|
|
@@ -460062,7 +460778,8 @@ async function prepareListenerTurn(params) {
|
|
|
460062
460778
|
permissionModeState,
|
|
460063
460779
|
turnLease,
|
|
460064
460780
|
onStatusChange,
|
|
460065
|
-
connectionId
|
|
460781
|
+
connectionId,
|
|
460782
|
+
resolveClientMessageIds
|
|
460066
460783
|
} = params;
|
|
460067
460784
|
const isInterrupted = () => turnLease.signal.aborted || !runtime.turnLifecycle.isCurrent(turnLease);
|
|
460068
460785
|
let listenAgentMetadata = await ensureListenerWarmStateForTurn(runtime.listener, { agentId, conversationId });
|
|
@@ -460229,6 +460946,7 @@ async function prepareListenerTurn(params) {
|
|
|
460229
460946
|
actingUserId: msg.actingUserId,
|
|
460230
460947
|
suppressActingUserFallback: msg.suppressActingUserFallback,
|
|
460231
460948
|
mcpOriginatorSuperRunId: getEffectiveMcpOriginatorId(msg),
|
|
460949
|
+
resolveClientMessageIds,
|
|
460232
460950
|
clientToolset: msg.clientToolset,
|
|
460233
460951
|
clientToolAllowlist: msg.clientToolAllowlist,
|
|
460234
460952
|
...msg.excludeInteractiveTools ? { exclude: [...INTERACTIVE_USER_INPUT_TOOL_NAMES] } : {},
|
|
@@ -460528,7 +461246,8 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
|
|
|
460528
461246
|
permissionModeState: turnPermissionModeState,
|
|
460529
461247
|
turnLease,
|
|
460530
461248
|
onStatusChange,
|
|
460531
|
-
connectionId
|
|
461249
|
+
connectionId,
|
|
461250
|
+
resolveClientMessageIds: () => turnCorrelation.clientMessageIds
|
|
460532
461251
|
});
|
|
460533
461252
|
if (setup.kind === "interrupted") {
|
|
460534
461253
|
finishTurn({
|
|
@@ -462802,7 +463521,7 @@ __export(exports_custom, {
|
|
|
462802
463521
|
});
|
|
462803
463522
|
import { existsSync as existsSync64 } from "node:fs";
|
|
462804
463523
|
import { readdir as readdir11, readFile as readFile27 } from "node:fs/promises";
|
|
462805
|
-
import { basename as
|
|
463524
|
+
import { basename as basename29, dirname as dirname37, join as join96 } from "node:path";
|
|
462806
463525
|
function getGlobalCommandsDir() {
|
|
462807
463526
|
return join96(resolveGlobalConfigDir(), "commands");
|
|
462808
463527
|
}
|
|
@@ -462865,7 +463584,7 @@ async function findCommandFiles(currentPath, rootPath, commands, source) {
|
|
|
462865
463584
|
async function parseCommandFile(filePath, rootPath, source) {
|
|
462866
463585
|
const content = await readFile27(filePath, "utf-8");
|
|
462867
463586
|
const { frontmatter, body: body3 } = parseFrontmatter(content);
|
|
462868
|
-
const id2 =
|
|
463587
|
+
const id2 = basename29(filePath, ".md");
|
|
462869
463588
|
const relativePath = dirname37(filePath).slice(rootPath.length);
|
|
462870
463589
|
const namespace = relativePath.replace(/^[/\\]/, "") || undefined;
|
|
462871
463590
|
let description = getStringField(frontmatter, "description");
|
|
@@ -465028,7 +465747,7 @@ function dispatchInboundMessageWhenReady(params) {
|
|
|
465028
465747
|
} = params;
|
|
465029
465748
|
const identity2 = ordinaryInputIdentity(getInboundClientMessageId(incoming));
|
|
465030
465749
|
let inputAcknowledged = false;
|
|
465031
|
-
const
|
|
465750
|
+
const acknowledgeInput2 = (result3) => {
|
|
465032
465751
|
if (inputAcknowledged)
|
|
465033
465752
|
return;
|
|
465034
465753
|
inputAcknowledged = true;
|
|
@@ -465051,12 +465770,12 @@ function dispatchInboundMessageWhenReady(params) {
|
|
|
465051
465770
|
runtime.pendingInboundDispatches += 1;
|
|
465052
465771
|
runtime.messageQueue = runtime.messageQueue.then(async () => {
|
|
465053
465772
|
if (listener !== getActiveRuntime() || listener.intentionallyClosed) {
|
|
465054
|
-
|
|
465773
|
+
acknowledgeInput2({ accepted: false });
|
|
465055
465774
|
return;
|
|
465056
465775
|
}
|
|
465057
465776
|
const admission = reserveInputDisposition(runtime, identity2);
|
|
465058
465777
|
if (admission.kind === "duplicate") {
|
|
465059
|
-
|
|
465778
|
+
acknowledgeInput2({
|
|
465060
465779
|
accepted: true,
|
|
465061
465780
|
disposition: admission.disposition,
|
|
465062
465781
|
duplicate: true,
|
|
@@ -465065,7 +465784,7 @@ function dispatchInboundMessageWhenReady(params) {
|
|
|
465065
465784
|
return;
|
|
465066
465785
|
}
|
|
465067
465786
|
if (admission.kind === "full") {
|
|
465068
|
-
|
|
465787
|
+
acknowledgeInput2({ accepted: false });
|
|
465069
465788
|
return;
|
|
465070
465789
|
}
|
|
465071
465790
|
const reservation = admission.kind === "reserved" ? admission.reservation : undefined;
|
|
@@ -465077,7 +465796,7 @@ function dispatchInboundMessageWhenReady(params) {
|
|
|
465077
465796
|
try {
|
|
465078
465797
|
if (isRuntimeTeleportPending(listener, runtime.agentId, runtime.conversationId)) {
|
|
465079
465798
|
rollbackInputDisposition(runtime, reservation);
|
|
465080
|
-
|
|
465799
|
+
acknowledgeInput2({ accepted: false });
|
|
465081
465800
|
return;
|
|
465082
465801
|
}
|
|
465083
465802
|
if (shouldQueueInboundMessage(incoming)) {
|
|
@@ -465088,7 +465807,7 @@ function dispatchInboundMessageWhenReady(params) {
|
|
|
465088
465807
|
} catch (error5) {
|
|
465089
465808
|
if (committed && !forgetQueuedInput(runtime, identity2)) {
|
|
465090
465809
|
recoverRetainedQueuedInput();
|
|
465091
|
-
|
|
465810
|
+
acknowledgeInput2({ accepted: true, disposition: "queued" });
|
|
465092
465811
|
return;
|
|
465093
465812
|
}
|
|
465094
465813
|
throw error5;
|
|
@@ -465098,14 +465817,14 @@ function dispatchInboundMessageWhenReady(params) {
|
|
|
465098
465817
|
if (committed) {
|
|
465099
465818
|
if (!forgetQueuedInput(runtime, identity2)) {
|
|
465100
465819
|
recoverRetainedQueuedInput();
|
|
465101
|
-
|
|
465820
|
+
acknowledgeInput2({ accepted: true, disposition: "queued" });
|
|
465102
465821
|
return;
|
|
465103
465822
|
}
|
|
465104
465823
|
} else {
|
|
465105
465824
|
rollbackInputDisposition(runtime, reservation);
|
|
465106
465825
|
}
|
|
465107
465826
|
}
|
|
465108
|
-
|
|
465827
|
+
acknowledgeInput2({
|
|
465109
465828
|
accepted: durablyAccepted,
|
|
465110
465829
|
...durablyAccepted ? { disposition: "queued" } : {}
|
|
465111
465830
|
});
|
|
@@ -465120,10 +465839,10 @@ function dispatchInboundMessageWhenReady(params) {
|
|
|
465120
465839
|
actingUserId
|
|
465121
465840
|
})) {
|
|
465122
465841
|
rollbackInputDisposition(runtime, reservation);
|
|
465123
|
-
|
|
465842
|
+
acknowledgeInput2({ accepted: false });
|
|
465124
465843
|
return;
|
|
465125
465844
|
}
|
|
465126
|
-
|
|
465845
|
+
acknowledgeInput2({ accepted: true, disposition: "started" });
|
|
465127
465846
|
await processIncomingMessage(attributedIncoming, getOrCreateProcessTransport(listener), runtime, options.onStatusChange, options.connectionId);
|
|
465128
465847
|
emitListenerStatus(listener, options.onStatusChange, options.connectionId);
|
|
465129
465848
|
if (runtime.queueRuntime.length > 0 || runtime.queuePumpScheduled || runtime.queuePumpActive) {
|
|
@@ -465135,7 +465854,7 @@ function dispatchInboundMessageWhenReady(params) {
|
|
|
465135
465854
|
}
|
|
465136
465855
|
}).catch((error5) => {
|
|
465137
465856
|
try {
|
|
465138
|
-
|
|
465857
|
+
acknowledgeInput2({ accepted: false });
|
|
465139
465858
|
} catch (acknowledgementError) {
|
|
465140
465859
|
trackListenerError5("listener_input_acknowledgement_failed", acknowledgementError, "listener_message_queue");
|
|
465141
465860
|
}
|
|
@@ -465432,27 +466151,27 @@ function admitTeleportContinueInput(params) {
|
|
|
465432
466151
|
agentId,
|
|
465433
466152
|
conversationId,
|
|
465434
466153
|
payload,
|
|
465435
|
-
acknowledgeInput
|
|
466154
|
+
acknowledgeInput: acknowledgeInput2
|
|
465436
466155
|
} = params;
|
|
465437
466156
|
const teleportId = payload.teleport_id;
|
|
465438
466157
|
if (isInboundTeleportExpected(scopedRuntime) && scopedRuntime.expectedTeleportId !== teleportId) {
|
|
465439
|
-
|
|
466158
|
+
acknowledgeInput2(false, "Teleport continuation does not match the expected handoff");
|
|
465440
466159
|
return;
|
|
465441
466160
|
}
|
|
465442
466161
|
const admission = reserveInputDisposition(scopedRuntime, teleportInputIdentity(teleportId));
|
|
465443
466162
|
if (admission.kind === "duplicate") {
|
|
465444
|
-
|
|
466163
|
+
acknowledgeInput2(true, undefined, admission.disposition, "refresh", () => hasLiveAcceptedInputOwnerWithOriginatorRetirement(scopedRuntime, teleportInputIdentity(teleportId)));
|
|
465445
466164
|
return;
|
|
465446
466165
|
}
|
|
465447
466166
|
if (admission.kind === "full") {
|
|
465448
|
-
|
|
466167
|
+
acknowledgeInput2(false, "Stable input ledger is at capacity");
|
|
465449
466168
|
return;
|
|
465450
466169
|
}
|
|
465451
466170
|
const reservation = admission.kind === "reserved" ? admission.reservation : undefined;
|
|
465452
466171
|
try {
|
|
465453
466172
|
if (scopedRuntime.isProcessing) {
|
|
465454
466173
|
rollbackInputDisposition(scopedRuntime, reservation);
|
|
465455
|
-
|
|
466174
|
+
acknowledgeInput2(false, "Destination runtime is already processing");
|
|
465456
466175
|
return;
|
|
465457
466176
|
}
|
|
465458
466177
|
clearPriorReadyTeleports({
|
|
@@ -465479,11 +466198,11 @@ function admitTeleportContinueInput(params) {
|
|
|
465479
466198
|
incoming: continuationInput
|
|
465480
466199
|
})) {
|
|
465481
466200
|
rollbackInputDisposition(scopedRuntime, reservation);
|
|
465482
|
-
|
|
466201
|
+
acknowledgeInput2(false, "Stable input disposition could not be persisted");
|
|
465483
466202
|
return;
|
|
465484
466203
|
}
|
|
465485
466204
|
clearExpectedInboundTeleport(scopedRuntime);
|
|
465486
|
-
|
|
466205
|
+
acknowledgeInput2(true, undefined, "started", "refresh");
|
|
465487
466206
|
params.runDetachedListenerTask("teleport_continue", async () => {
|
|
465488
466207
|
await params.processIncomingMessage(continuationInput, getOrCreateProcessTransport(listener), scopedRuntime, params.onStatusChange, connectionId);
|
|
465489
466208
|
});
|
|
@@ -465520,11 +466239,11 @@ async function routeInputFrame(deps) {
|
|
|
465520
466239
|
processIncomingMessage
|
|
465521
466240
|
} = deps;
|
|
465522
466241
|
let ackExtras;
|
|
465523
|
-
const
|
|
466242
|
+
const acknowledgeInput2 = (...args) => acknowledgeInputFrame(safeSocketSend, socket, parsed, args[0], args[1], args[2], args[3], args[4], ackExtras);
|
|
465524
466243
|
const ackTransport = { safeSocketSend, socket, frame: parsed };
|
|
465525
466244
|
if (runtime !== getActiveRuntime() || runtime.intentionallyClosed) {
|
|
465526
466245
|
logV2Command(opts, "Dropping input: runtime mismatch or closed");
|
|
465527
|
-
|
|
466246
|
+
acknowledgeInput2(false, "Runtime is no longer active");
|
|
465528
466247
|
return;
|
|
465529
466248
|
}
|
|
465530
466249
|
const gateInputOriginatorAdmission = () => {
|
|
@@ -465538,7 +466257,7 @@ async function routeInputFrame(deps) {
|
|
|
465538
466257
|
abortReason: MCP_ORIGINATOR_DENIED_PERMANENT_ABORT_REASON
|
|
465539
466258
|
};
|
|
465540
466259
|
console.error("[message-router] originator admission is permanently denied; rejecting the input without committing work");
|
|
465541
|
-
|
|
466260
|
+
acknowledgeInput2(false, "Originator authority for this input was permanently rejected");
|
|
465542
466261
|
return false;
|
|
465543
466262
|
}
|
|
465544
466263
|
ackExtras = { preGated: gate.delivery ?? null };
|
|
@@ -465547,7 +466266,7 @@ async function routeInputFrame(deps) {
|
|
|
465547
466266
|
if (parsed.payload.kind === "teleport_continue") {
|
|
465548
466267
|
const teleportAgentId = parsed.runtime.agent_id;
|
|
465549
466268
|
if (!teleportAgentId) {
|
|
465550
|
-
|
|
466269
|
+
acknowledgeInput2(false, "Teleport requires an agent-backed runtime");
|
|
465551
466270
|
return;
|
|
465552
466271
|
}
|
|
465553
466272
|
if (!gateInputOriginatorAdmission()) {
|
|
@@ -465562,7 +466281,7 @@ async function routeInputFrame(deps) {
|
|
|
465562
466281
|
payload: parsed.payload,
|
|
465563
466282
|
originatorSuperRunId: parsed.super_run_id,
|
|
465564
466283
|
onStatusChange: opts.onStatusChange,
|
|
465565
|
-
acknowledgeInput,
|
|
466284
|
+
acknowledgeInput: acknowledgeInput2,
|
|
465566
466285
|
runDetachedListenerTask: runDetachedListenerTask2,
|
|
465567
466286
|
processIncomingMessage
|
|
465568
466287
|
});
|
|
@@ -465580,7 +466299,7 @@ async function routeInputFrame(deps) {
|
|
|
465580
466299
|
},
|
|
465581
466300
|
processQueuedTurn
|
|
465582
466301
|
});
|
|
465583
|
-
|
|
466302
|
+
acknowledgeInput2(handled, handled ? undefined : "Approval request is no longer pending");
|
|
465584
466303
|
return;
|
|
465585
466304
|
}
|
|
465586
466305
|
const inputPayload = parsed.payload;
|
|
@@ -465592,12 +466311,12 @@ async function routeInputFrame(deps) {
|
|
|
465592
466311
|
agentId: parsed.runtime.agent_id,
|
|
465593
466312
|
conversationId: parsed.runtime.conversation_id
|
|
465594
466313
|
});
|
|
465595
|
-
|
|
466314
|
+
acknowledgeInput2(false, "Unsupported input payload kind");
|
|
465596
466315
|
return;
|
|
465597
466316
|
}
|
|
465598
466317
|
const error5 = validateResponseFormat(inputPayload.response_format);
|
|
465599
466318
|
if (error5) {
|
|
465600
|
-
|
|
466319
|
+
acknowledgeInput2(false, error5);
|
|
465601
466320
|
return;
|
|
465602
466321
|
}
|
|
465603
466322
|
const incoming = createIncomingMessage(parsed.runtime, inputPayload, connectionId, parsed);
|
|
@@ -465610,7 +466329,7 @@ async function routeInputFrame(deps) {
|
|
|
465610
466329
|
agentId: parsed.runtime.agent_id,
|
|
465611
466330
|
conversationId: parsed.runtime.conversation_id
|
|
465612
466331
|
});
|
|
465613
|
-
|
|
466332
|
+
acknowledgeInput2(false, "Approval payloads require approval_response");
|
|
465614
466333
|
return;
|
|
465615
466334
|
}
|
|
465616
466335
|
const scopedRuntime = getOrCreateScopedRuntime2(runtime, incoming.agentId, incoming.conversationId);
|
|
@@ -465625,7 +466344,7 @@ async function routeInputFrame(deps) {
|
|
|
465625
466344
|
processIncomingMessage,
|
|
465626
466345
|
actingUserId: parsed.runtime.acting_user_id,
|
|
465627
466346
|
trackListenerError: trackListenerError5,
|
|
465628
|
-
onInputAccepted: (result3) =>
|
|
466347
|
+
onInputAccepted: (result3) => acknowledgeInput2(result3.accepted, result3.accepted ? undefined : "Input was rejected by the queue", result3.disposition, result3.duplicate ? "refresh" : undefined, result3.mayRecreateOwner)
|
|
465629
466348
|
});
|
|
465630
466349
|
};
|
|
465631
466350
|
if (shouldQueueInboundMessage(incoming)) {
|
|
@@ -465635,7 +466354,7 @@ async function routeInputFrame(deps) {
|
|
|
465635
466354
|
return;
|
|
465636
466355
|
}
|
|
465637
466356
|
if (isRuntimeTeleportPending(runtime, scopedRuntime.agentId, scopedRuntime.conversationId)) {
|
|
465638
|
-
|
|
466357
|
+
acknowledgeInput2(false, "Conversation is switching computers");
|
|
465639
466358
|
return;
|
|
465640
466359
|
}
|
|
465641
466360
|
if (!gateInputOriginatorAdmission()) {
|
|
@@ -465647,7 +466366,7 @@ async function routeInputFrame(deps) {
|
|
|
465647
466366
|
return;
|
|
465648
466367
|
}
|
|
465649
466368
|
if (admission.kind === "full") {
|
|
465650
|
-
|
|
466369
|
+
acknowledgeInput2(false, "Stable input ledger is at capacity");
|
|
465651
466370
|
return;
|
|
465652
466371
|
}
|
|
465653
466372
|
const reservation = admission.kind === "reserved" ? admission.reservation : undefined;
|
|
@@ -465673,7 +466392,7 @@ async function routeInputFrame(deps) {
|
|
|
465673
466392
|
} else {
|
|
465674
466393
|
rollbackInputDisposition(scopedRuntime, reservation);
|
|
465675
466394
|
}
|
|
465676
|
-
|
|
466395
|
+
acknowledgeInput2(durablyAccepted, durablyAccepted ? undefined : "Input was rejected by the queue or durable ledger", durablyAccepted ? "queued" : undefined);
|
|
465677
466396
|
} catch (error6) {
|
|
465678
466397
|
rollbackInputDisposition(scopedRuntime, reservation);
|
|
465679
466398
|
throw error6;
|
|
@@ -466079,6 +466798,15 @@ function findOwnedTask(runtime, agentId) {
|
|
|
466079
466798
|
return;
|
|
466080
466799
|
return [...backgroundTasks.entries()].find(([, task2]) => task2.subagentId === subagent.id);
|
|
466081
466800
|
}
|
|
466801
|
+
function ownsNativeSession(runtime, agentId) {
|
|
466802
|
+
const target2 = parseExternalCodingAgentId(agentId);
|
|
466803
|
+
if (!target2 || target2.computer)
|
|
466804
|
+
return false;
|
|
466805
|
+
if (target2.type !== "claude-code" && target2.type !== "codex")
|
|
466806
|
+
return false;
|
|
466807
|
+
const owner = getNativeSessionOwner(target2.type === "claude-code" ? "claude_code" : "codex", target2.sessionId);
|
|
466808
|
+
return owner?.agentId === runtime.agentId && owner.conversationId === runtime.conversationId;
|
|
466809
|
+
}
|
|
466082
466810
|
function runtimeContext(parent, command) {
|
|
466083
466811
|
return {
|
|
466084
466812
|
agentId: parent.agentId,
|
|
@@ -466110,7 +466838,7 @@ async function handleSubagentMessageCommand(command, parent, deps = {}) {
|
|
|
466110
466838
|
try {
|
|
466111
466839
|
if (parent.agentId !== command.runtime.agent_id || parent.conversationId !== command.runtime.conversation_id)
|
|
466112
466840
|
throw new Error("Parent runtime does not match the message request");
|
|
466113
|
-
if (!findOwnedTask(parent, command.agent_id))
|
|
466841
|
+
if (!findOwnedTask(parent, command.agent_id) && !ownsNativeSession(parent, command.agent_id))
|
|
466114
466842
|
throw new Error("Subagent does not belong to this conversation");
|
|
466115
466843
|
const target2 = parseExternalCodingAgentId(command.agent_id);
|
|
466116
466844
|
if (!target2 || target2.computer || !isExternalCodingAgentType(target2.type))
|
|
@@ -466123,40 +466851,52 @@ async function handleSubagentMessageCommand(command, parent, deps = {}) {
|
|
|
466123
466851
|
let captureReservation;
|
|
466124
466852
|
const source = target2.type === "claude-code" ? "claude_code" : "codex";
|
|
466125
466853
|
const secrets2 = target2.type === "cursor" ? await resolveExternalCodingAgentSecretEnv(parent.agentId) : {};
|
|
466126
|
-
|
|
466127
|
-
|
|
466128
|
-
|
|
466129
|
-
|
|
466130
|
-
|
|
466131
|
-
}, { ...process.env, ...secrets2 }, secrets2) : target2.type === "claude-code" ? (deps.sendClaude ?? sendClaudeMessage)({
|
|
466132
|
-
sessionId: target2.sessionId,
|
|
466133
|
-
prompt: command.message,
|
|
466134
|
-
parentAgentId: command.runtime.agent_id,
|
|
466135
|
-
cwd: getCurrentWorkingDirectory(),
|
|
466136
|
-
beforeStart: async () => {
|
|
466137
|
-
captureReservation = await (deps.reserveCapture ?? reserveNativeSessionCapture)(source, sessionId, {
|
|
466138
|
-
agentId: command.runtime.agent_id,
|
|
466139
|
-
conversationId: command.runtime.conversation_id,
|
|
466854
|
+
let worker;
|
|
466855
|
+
const receipt = await runOutsideRuntimeContext(() => runWithRuntimeContext(runtimeContext(parent, command), async () => {
|
|
466856
|
+
if (target2.type !== "cursor")
|
|
466857
|
+
worker = await buildExternalWorkerResumeEnv({
|
|
466858
|
+
parentAgentId: command.runtime.agent_id,
|
|
466140
466859
|
actingUserId: command.runtime.acting_user_id
|
|
466141
|
-
});
|
|
466142
|
-
|
|
466143
|
-
|
|
466144
|
-
|
|
466145
|
-
|
|
466146
|
-
|
|
466147
|
-
|
|
466148
|
-
|
|
466149
|
-
|
|
466150
|
-
|
|
466151
|
-
|
|
466152
|
-
|
|
466153
|
-
|
|
466154
|
-
|
|
466155
|
-
|
|
466860
|
+
}, deps.workerEnv);
|
|
466861
|
+
return target2.type === "cursor" ? sendCursorMessage({
|
|
466862
|
+
sessionId,
|
|
466863
|
+
prompt: command.message,
|
|
466864
|
+
parentAgentId: command.runtime.agent_id,
|
|
466865
|
+
cwd: getCurrentWorkingDirectory()
|
|
466866
|
+
}, { ...process.env, ...secrets2 }, secrets2) : target2.type === "claude-code" ? (deps.sendClaude ?? sendClaudeMessage)({
|
|
466867
|
+
sessionId: target2.sessionId,
|
|
466868
|
+
prompt: command.message,
|
|
466869
|
+
parentAgentId: command.runtime.agent_id,
|
|
466870
|
+
cwd: getCurrentWorkingDirectory(),
|
|
466871
|
+
mcpReminder: worker?.mcpReminder,
|
|
466872
|
+
beforeStart: async () => {
|
|
466873
|
+
captureReservation = await (deps.reserveCapture ?? reserveNativeSessionCapture)(source, sessionId, {
|
|
466874
|
+
agentId: command.runtime.agent_id,
|
|
466875
|
+
conversationId: command.runtime.conversation_id,
|
|
466876
|
+
actingUserId: command.runtime.acting_user_id
|
|
466877
|
+
});
|
|
466878
|
+
}
|
|
466879
|
+
}, { env: worker?.env }) : (deps.sendCodex ?? sendCodexMessage)({
|
|
466880
|
+
threadId: target2.sessionId,
|
|
466881
|
+
prompt: command.message,
|
|
466882
|
+
parentAgentId: command.runtime.agent_id,
|
|
466883
|
+
cwd: getCurrentWorkingDirectory(),
|
|
466884
|
+
mcpReminder: worker?.mcpReminder,
|
|
466885
|
+
beforeStart: async () => {
|
|
466886
|
+
captureReservation = await (deps.reserveCapture ?? reserveNativeSessionCapture)(source, sessionId, {
|
|
466887
|
+
agentId: command.runtime.agent_id,
|
|
466888
|
+
conversationId: command.runtime.conversation_id,
|
|
466889
|
+
actingUserId: command.runtime.acting_user_id
|
|
466890
|
+
});
|
|
466891
|
+
}
|
|
466892
|
+
}, { env: worker?.env });
|
|
466893
|
+
}));
|
|
466156
466894
|
if (receipt.mode === "steered")
|
|
466157
466895
|
return { ...base2, success: true, delivery: "steered" };
|
|
466158
466896
|
if (!receipt.completion || !receipt.interrupt)
|
|
466159
466897
|
throw new Error("External coding agent returned an incomplete receipt");
|
|
466898
|
+
const secretEnv = worker?.secretEnv;
|
|
466899
|
+
const completion = secretEnv ? receipt.completion.then((result4) => scrubExternalWorkerResult(result4, secretEnv)) : receipt.completion;
|
|
466160
466900
|
try {
|
|
466161
466901
|
(deps.track ?? trackExternalFollowupCompletion)({
|
|
466162
466902
|
type: target2.type,
|
|
@@ -466167,7 +466907,7 @@ async function handleSubagentMessageCommand(command, parent, deps = {}) {
|
|
|
466167
466907
|
conversationId: parent.conversationId,
|
|
466168
466908
|
actingUserId: command.runtime.acting_user_id
|
|
466169
466909
|
},
|
|
466170
|
-
completion
|
|
466910
|
+
completion,
|
|
466171
466911
|
interrupt: receipt.interrupt,
|
|
466172
466912
|
captureReservation,
|
|
466173
466913
|
toolCallId: command.tool_call_id,
|
|
@@ -466179,7 +466919,7 @@ async function handleSubagentMessageCommand(command, parent, deps = {}) {
|
|
|
466179
466919
|
await receipt.interrupt().catch(() => {
|
|
466180
466920
|
return;
|
|
466181
466921
|
});
|
|
466182
|
-
finishUntrackedNativeCapture2(
|
|
466922
|
+
finishUntrackedNativeCapture2(completion, captureReservation, source, sessionId);
|
|
466183
466923
|
throw error5;
|
|
466184
466924
|
}
|
|
466185
466925
|
return { ...base2, success: true, delivery: "resumed" };
|
|
@@ -466212,8 +466952,11 @@ async function handleSubagentStopCommand(command, parent) {
|
|
|
466212
466952
|
if (parent.agentId !== command.runtime.agent_id || parent.conversationId !== command.runtime.conversation_id)
|
|
466213
466953
|
return { ...base2, error: "Parent runtime does not match the stop request" };
|
|
466214
466954
|
const owned = findOwnedTask(parent, command.agent_id);
|
|
466215
|
-
if (!owned)
|
|
466955
|
+
if (!owned) {
|
|
466956
|
+
if (ownsNativeSession(parent, command.agent_id))
|
|
466957
|
+
return { ...base2, success: true };
|
|
466216
466958
|
return { ...base2, error: "Subagent does not belong to this conversation" };
|
|
466959
|
+
}
|
|
466217
466960
|
const [, task2] = owned;
|
|
466218
466961
|
if (task2.status !== "running")
|
|
466219
466962
|
return { ...base2, success: true };
|
|
@@ -466846,16 +467589,24 @@ var init_message_router = __esm(async () => {
|
|
|
466846
467589
|
function installProcessEventRouting(params) {
|
|
466847
467590
|
const { runtime, processTransport, opts, processQueuedTurn } = params;
|
|
466848
467591
|
runtime._unsubscribeSubagentState?.();
|
|
467592
|
+
const emitSubagentState = (scope, options) => {
|
|
467593
|
+
const transport3 = runtime.transport ?? runtime.socket;
|
|
467594
|
+
if (!transport3 || !isListenerTransportOpen(transport3)) {
|
|
467595
|
+
clearSubagentSnapshotCache(runtime);
|
|
467596
|
+
return;
|
|
467597
|
+
}
|
|
467598
|
+
emitSubagentStateUpdate(transport3, runtime, scope, TO_SUBSCRIBERS, options);
|
|
467599
|
+
};
|
|
466849
467600
|
runtime._unsubscribeSubagentState = subscribe2(() => {
|
|
466850
467601
|
if (runtime.conversationRuntimes.size === 0) {
|
|
466851
|
-
|
|
467602
|
+
emitSubagentState();
|
|
466852
467603
|
return;
|
|
466853
467604
|
}
|
|
466854
467605
|
for (const conversationRuntime of runtime.conversationRuntimes.values()) {
|
|
466855
|
-
|
|
467606
|
+
emitSubagentState({
|
|
466856
467607
|
agent_id: conversationRuntime.agentId,
|
|
466857
467608
|
conversation_id: conversationRuntime.conversationId
|
|
466858
|
-
});
|
|
467609
|
+
}, { onlyIfChanged: true });
|
|
466859
467610
|
}
|
|
466860
467611
|
});
|
|
466861
467612
|
runtime._unsubscribeSubagentStreamEvents?.();
|
|
@@ -466911,11 +467662,32 @@ function installProcessEventRouting(params) {
|
|
|
466911
467662
|
text: queuedMessage.text,
|
|
466912
467663
|
content: queuedMessage.content,
|
|
466913
467664
|
actingUserId: queuedMessage.actingUserId,
|
|
467665
|
+
clientMessageIds: queuedMessage.clientMessageIds,
|
|
466914
467666
|
agentId: queuedMessage.agentId ?? targetRuntime.agentId ?? undefined,
|
|
466915
467667
|
conversationId: queuedMessage.conversationId ?? targetRuntime.conversationId
|
|
466916
467668
|
});
|
|
466917
467669
|
scheduleQueuePump(targetRuntime, processTransport, opts, processQueuedTurn);
|
|
466918
467670
|
});
|
|
467671
|
+
runtime._stopDiskSpaceWatch?.();
|
|
467672
|
+
runtime._stopDiskSpaceWatch = watchSandboxDiskSpace(getCurrentWorkingDirectory, (text3) => deliverSandboxDiskAlert(runtime, text3));
|
|
467673
|
+
}
|
|
467674
|
+
function deliverSandboxDiskAlert(runtime, text3) {
|
|
467675
|
+
const target2 = getMostRecentlyActiveConversation(runtime);
|
|
467676
|
+
deliverDiskSpaceReminder(text3, target2?.agentId ? { agentId: target2.agentId, conversationId: target2.conversationId } : undefined);
|
|
467677
|
+
}
|
|
467678
|
+
function getMostRecentlyActiveConversation(runtime) {
|
|
467679
|
+
let latest = null;
|
|
467680
|
+
let latestAt = -1;
|
|
467681
|
+
for (const conversationRuntime of runtime.conversationRuntimes.values()) {
|
|
467682
|
+
if (!conversationRuntime.agentId)
|
|
467683
|
+
continue;
|
|
467684
|
+
const activeAt = conversationRuntime.isProcessing ? Number.POSITIVE_INFINITY : conversationRuntime.contextTracker.contextTokensHistory.at(-1)?.timestamp ?? 0;
|
|
467685
|
+
if (activeAt > latestAt) {
|
|
467686
|
+
latest = conversationRuntime;
|
|
467687
|
+
latestAt = activeAt;
|
|
467688
|
+
}
|
|
467689
|
+
}
|
|
467690
|
+
return latest;
|
|
466919
467691
|
}
|
|
466920
467692
|
function clearProcessServices(runtime) {
|
|
466921
467693
|
runtime._unsubscribeSubagentState?.();
|
|
@@ -466924,6 +467696,8 @@ function clearProcessServices(runtime) {
|
|
|
466924
467696
|
runtime._unsubscribeSubagentStreamEvents = undefined;
|
|
466925
467697
|
runtime._unsubscribeBackgroundProcessState?.();
|
|
466926
467698
|
runtime._unsubscribeBackgroundProcessState = undefined;
|
|
467699
|
+
runtime._stopDiskSpaceWatch?.();
|
|
467700
|
+
runtime._stopDiskSpaceWatch = undefined;
|
|
466927
467701
|
setMessageQueueAdder(null);
|
|
466928
467702
|
stopScheduler();
|
|
466929
467703
|
clearRuntimeTimers(runtime);
|
|
@@ -466955,8 +467729,11 @@ async function waitForProcessServicesSlot(runtime, connectionId) {
|
|
|
466955
467729
|
}
|
|
466956
467730
|
var init_process_services = __esm(async () => {
|
|
466957
467731
|
init_subagent_state();
|
|
467732
|
+
init_disk_space();
|
|
467733
|
+
init_runtime_context();
|
|
466958
467734
|
init_process_manager();
|
|
466959
467735
|
init_message_queue_bridge();
|
|
467736
|
+
init_subagent_state_cache();
|
|
466960
467737
|
init_transport2();
|
|
466961
467738
|
await __promiseAll([
|
|
466962
467739
|
init_scheduler(),
|
|
@@ -472289,7 +473066,7 @@ import {
|
|
|
472289
473066
|
copyFileSync as copyFileSync3,
|
|
472290
473067
|
existsSync as existsSync65,
|
|
472291
473068
|
mkdirSync as mkdirSync48,
|
|
472292
|
-
readdirSync as
|
|
473069
|
+
readdirSync as readdirSync27,
|
|
472293
473070
|
readFileSync as readFileSync49,
|
|
472294
473071
|
writeFileSync as writeFileSync40
|
|
472295
473072
|
} from "node:fs";
|
|
@@ -472585,7 +473362,7 @@ function migrateLocalBackendTranscripts(input) {
|
|
|
472585
473362
|
};
|
|
472586
473363
|
if (!existsSync65(conversationsDir))
|
|
472587
473364
|
return result3;
|
|
472588
|
-
for (const name of
|
|
473365
|
+
for (const name of readdirSync27(conversationsDir)) {
|
|
472589
473366
|
const conversationDir = join97(conversationsDir, name);
|
|
472590
473367
|
const messagesPath = join97(conversationDir, "messages.jsonl");
|
|
472591
473368
|
const manifestPath = join97(conversationDir, "manifest.json");
|
|
@@ -472827,7 +473604,7 @@ var init_memory_tokens = __esm(() => {
|
|
|
472827
473604
|
});
|
|
472828
473605
|
|
|
472829
473606
|
// src/cli/subcommands/memory.ts
|
|
472830
|
-
import { cpSync, existsSync as existsSync66, mkdirSync as mkdirSync49, rmSync as
|
|
473607
|
+
import { cpSync, existsSync as existsSync66, mkdirSync as mkdirSync49, rmSync as rmSync23, statSync as statSync25 } from "node:fs";
|
|
472831
473608
|
import { readdir as readdir12 } from "node:fs/promises";
|
|
472832
473609
|
import { dirname as dirname38, join as join98 } from "node:path";
|
|
472833
473610
|
import { parseArgs as parseArgs11 } from "node:util";
|
|
@@ -473035,7 +473812,7 @@ async function runMemorySubcommand(argv, deps = {}) {
|
|
|
473035
473812
|
return 1;
|
|
473036
473813
|
}
|
|
473037
473814
|
const root2 = getMemoryRoot(agentId);
|
|
473038
|
-
|
|
473815
|
+
rmSync23(root2, { recursive: true, force: true });
|
|
473039
473816
|
cpSync(backupPath, root2, { recursive: true });
|
|
473040
473817
|
console.log(JSON.stringify({ restoredFrom: backupPath }, null, 2));
|
|
473041
473818
|
return 0;
|
|
@@ -473100,7 +473877,7 @@ var init_memory7 = __esm(() => {
|
|
|
473100
473877
|
});
|
|
473101
473878
|
|
|
473102
473879
|
// src/backend/local/transcript-search.ts
|
|
473103
|
-
import { existsSync as existsSync67, readdirSync as
|
|
473880
|
+
import { existsSync as existsSync67, readdirSync as readdirSync28, readFileSync as readFileSync50, statSync as statSync26 } from "node:fs";
|
|
473104
473881
|
import { join as join99 } from "node:path";
|
|
473105
473882
|
function readJsonFile3(path47) {
|
|
473106
473883
|
if (!existsSync67(path47))
|
|
@@ -473439,7 +474216,7 @@ function conversationDirectories(storageDir) {
|
|
|
473439
474216
|
if (!existsSync67(conversationsDir))
|
|
473440
474217
|
return [];
|
|
473441
474218
|
try {
|
|
473442
|
-
return
|
|
474219
|
+
return readdirSync28(conversationsDir).map((entry) => join99(conversationsDir, entry)).filter((entryPath) => statSync26(entryPath).isDirectory());
|
|
473443
474220
|
} catch {
|
|
473444
474221
|
return [];
|
|
473445
474222
|
}
|
|
@@ -474503,10 +475280,10 @@ import {
|
|
|
474503
475280
|
lstatSync as lstatSync4,
|
|
474504
475281
|
mkdirSync as mkdirSync50,
|
|
474505
475282
|
mkdtempSync as mkdtempSync5,
|
|
474506
|
-
readdirSync as
|
|
475283
|
+
readdirSync as readdirSync29,
|
|
474507
475284
|
readFileSync as readFileSync51,
|
|
474508
475285
|
renameSync as renameSync12,
|
|
474509
|
-
rmSync as
|
|
475286
|
+
rmSync as rmSync24,
|
|
474510
475287
|
writeFileSync as writeFileSync41
|
|
474511
475288
|
} from "node:fs";
|
|
474512
475289
|
import { tmpdir as tmpdir14 } from "node:os";
|
|
@@ -474644,7 +475421,7 @@ function validatePackageSource(packageDirectory) {
|
|
|
474644
475421
|
}
|
|
474645
475422
|
function copyPackageDirectory(sourceRoot, targetRoot) {
|
|
474646
475423
|
mkdirSync50(targetRoot, { recursive: true });
|
|
474647
|
-
for (const entry of
|
|
475424
|
+
for (const entry of readdirSync29(sourceRoot, { withFileTypes: true })) {
|
|
474648
475425
|
if (SKIPPED_PACKAGE_COPY_NAMES.has(entry.name))
|
|
474649
475426
|
continue;
|
|
474650
475427
|
const sourcePath = path47.join(sourceRoot, entry.name);
|
|
@@ -474676,7 +475453,7 @@ function shouldSkipDependencyPath(relativeParts, installedPackageName) {
|
|
|
474676
475453
|
function copyDependencyDirectoryFiltered(params) {
|
|
474677
475454
|
let copied = false;
|
|
474678
475455
|
const relativeParts = params.relativeParts ?? [];
|
|
474679
|
-
for (const entry of
|
|
475456
|
+
for (const entry of readdirSync29(params.sourceRoot, { withFileTypes: true })) {
|
|
474680
475457
|
const nextRelativeParts = [...relativeParts, entry.name];
|
|
474681
475458
|
if (shouldSkipDependencyPath(nextRelativeParts, params.installedPackageName)) {
|
|
474682
475459
|
continue;
|
|
@@ -474727,7 +475504,7 @@ function copyPackageInternalNodeModules(params) {
|
|
|
474727
475504
|
}
|
|
474728
475505
|
function restoreRegistry(registryPath, previousContents) {
|
|
474729
475506
|
if (previousContents === null) {
|
|
474730
|
-
|
|
475507
|
+
rmSync24(registryPath, { force: true });
|
|
474731
475508
|
return;
|
|
474732
475509
|
}
|
|
474733
475510
|
mkdirSync50(path47.dirname(registryPath), { recursive: true });
|
|
@@ -474736,17 +475513,17 @@ function restoreRegistry(registryPath, previousContents) {
|
|
|
474736
475513
|
function removeIfExists(targetPath) {
|
|
474737
475514
|
if (!targetPath)
|
|
474738
475515
|
return;
|
|
474739
|
-
|
|
475516
|
+
rmSync24(targetPath, { force: true, recursive: true });
|
|
474740
475517
|
}
|
|
474741
475518
|
function restoreDestination(params) {
|
|
474742
|
-
|
|
475519
|
+
rmSync24(params.destinationRoot, { force: true, recursive: true });
|
|
474743
475520
|
if (params.backupRoot && existsSync68(params.backupRoot)) {
|
|
474744
475521
|
renameSync12(params.backupRoot, params.destinationRoot);
|
|
474745
475522
|
}
|
|
474746
475523
|
}
|
|
474747
475524
|
function restoreDestinationIfNeeded(params) {
|
|
474748
475525
|
if (!params.backupRoot || !existsSync68(params.backupRoot)) {
|
|
474749
|
-
|
|
475526
|
+
rmSync24(params.destinationRoot, { force: true, recursive: true });
|
|
474750
475527
|
return;
|
|
474751
475528
|
}
|
|
474752
475529
|
restoreDestination(params);
|
|
@@ -474788,7 +475565,7 @@ function installPreparedManagedModPackage(params) {
|
|
|
474788
475565
|
}
|
|
474789
475566
|
if (existsSync68(destinationRoot)) {
|
|
474790
475567
|
backupRoot = makeSiblingTempDirectory(destinationRoot, "backup");
|
|
474791
|
-
|
|
475568
|
+
rmSync24(backupRoot, { force: true, recursive: true });
|
|
474792
475569
|
renameSync12(destinationRoot, backupRoot);
|
|
474793
475570
|
destinationNeedsRollback = true;
|
|
474794
475571
|
}
|
|
@@ -475091,7 +475868,7 @@ function inferCompatibilityModEntries(packageDirectory) {
|
|
|
475091
475868
|
throw new Error(`Package mods directory must not be a symlink: mods`);
|
|
475092
475869
|
}
|
|
475093
475870
|
if (stats.isDirectory()) {
|
|
475094
|
-
const entries2 =
|
|
475871
|
+
const entries2 = readdirSync29(modsDirectory, { withFileTypes: true }).filter((entry) => entry.isFile() && isModFileExtension(path47.extname(entry.name))).map((entry) => `mods/${entry.name}`).sort();
|
|
475095
475872
|
if (entries2.length > 0)
|
|
475096
475873
|
return entries2;
|
|
475097
475874
|
}
|
|
@@ -475239,7 +476016,7 @@ async function installNpmManagedModPackage(params) {
|
|
|
475239
476016
|
packageDirectory
|
|
475240
476017
|
});
|
|
475241
476018
|
} finally {
|
|
475242
|
-
|
|
476019
|
+
rmSync24(tempRoot, { force: true, recursive: true });
|
|
475243
476020
|
}
|
|
475244
476021
|
}
|
|
475245
476022
|
async function installGitManagedModPackage(params) {
|
|
@@ -475271,7 +476048,7 @@ async function installGitManagedModPackage(params) {
|
|
|
475271
476048
|
packageInfo
|
|
475272
476049
|
});
|
|
475273
476050
|
} finally {
|
|
475274
|
-
|
|
476051
|
+
rmSync24(tempRoot, { force: true, recursive: true });
|
|
475275
476052
|
}
|
|
475276
476053
|
}
|
|
475277
476054
|
async function updateNpmManagedModPackage(params) {
|
|
@@ -475302,7 +476079,7 @@ async function updateNpmManagedModPackage(params) {
|
|
|
475302
476079
|
previousVersion: existing.version
|
|
475303
476080
|
};
|
|
475304
476081
|
} finally {
|
|
475305
|
-
|
|
476082
|
+
rmSync24(tempRoot, { force: true, recursive: true });
|
|
475306
476083
|
}
|
|
475307
476084
|
}
|
|
475308
476085
|
async function updateGitManagedModPackage(params) {
|
|
@@ -475344,7 +476121,7 @@ async function updateGitManagedModPackage(params) {
|
|
|
475344
476121
|
previousVersion: existing.version
|
|
475345
476122
|
};
|
|
475346
476123
|
} finally {
|
|
475347
|
-
|
|
476124
|
+
rmSync24(tempRoot, { force: true, recursive: true });
|
|
475348
476125
|
}
|
|
475349
476126
|
}
|
|
475350
476127
|
var SKIPPED_PACKAGE_COPY_NAMES, spawnNpmInstallProcessOverride = null, spawnGitInstallProcess, platformOverride2 = null;
|
|
@@ -475363,7 +476140,7 @@ import {
|
|
|
475363
476140
|
existsSync as existsSync69,
|
|
475364
476141
|
lstatSync as lstatSync5,
|
|
475365
476142
|
mkdirSync as mkdirSync51,
|
|
475366
|
-
rmSync as
|
|
476143
|
+
rmSync as rmSync25,
|
|
475367
476144
|
writeFileSync as writeFileSync42
|
|
475368
476145
|
} from "node:fs";
|
|
475369
476146
|
import path48 from "node:path";
|
|
@@ -475472,7 +476249,7 @@ function scaffoldLocalModPackage(options) {
|
|
|
475472
476249
|
writeFileSync42(readmePath, createReadme(packageName));
|
|
475473
476250
|
writeFileSync42(modGuidePath, createModGuide(packageName, manifestEntry));
|
|
475474
476251
|
} catch (error5) {
|
|
475475
|
-
|
|
476252
|
+
rmSync25(outputDirectory, { force: true, recursive: true });
|
|
475476
476253
|
throw error5;
|
|
475477
476254
|
}
|
|
475478
476255
|
return {
|
|
@@ -476009,7 +476786,7 @@ var init_sandbox_files = __esm(() => {
|
|
|
476009
476786
|
|
|
476010
476787
|
// src/cli/subcommands/sandbox.ts
|
|
476011
476788
|
import { readFile as readFile29, stat as stat15, writeFile as writeFile19 } from "node:fs/promises";
|
|
476012
|
-
import { basename as
|
|
476789
|
+
import { basename as basename30, resolve as resolve40 } from "node:path";
|
|
476013
476790
|
import { parseArgs as parseArgs16 } from "node:util";
|
|
476014
476791
|
function printUsage13() {
|
|
476015
476792
|
console.log(`
|
|
@@ -476160,13 +476937,13 @@ async function runSandboxSubcommand(argv, deps = {}) {
|
|
|
476160
476937
|
throw new Error(`${localPath2} is not a file`);
|
|
476161
476938
|
const data2 = await (deps.readLocalFile ?? readFile29)(localPath2);
|
|
476162
476939
|
const sandbox2 = await ensureSandbox();
|
|
476163
|
-
const result3 = await (deps.uploadFile ?? uploadFileToSandbox)(sandbox2.sandboxId, { blob: new Blob([data2]), name:
|
|
476940
|
+
const result3 = await (deps.uploadFile ?? uploadFileToSandbox)(sandbox2.sandboxId, { blob: new Blob([data2]), name: basename30(localPath2) });
|
|
476164
476941
|
console.log(JSON.stringify({ ...result3, ...targetOutput }, null, 2));
|
|
476165
476942
|
return 0;
|
|
476166
476943
|
}
|
|
476167
476944
|
const sandbox = await ensureSandbox();
|
|
476168
476945
|
const data = await (deps.downloadFile ?? downloadFileFromSandbox)(sandbox.sandboxId, path49);
|
|
476169
|
-
const localPath = resolve40(parsed.values.to ??
|
|
476946
|
+
const localPath = resolve40(parsed.values.to ?? basename30(path49));
|
|
476170
476947
|
await (deps.writeLocalFile ?? writeFile19)(localPath, data);
|
|
476171
476948
|
console.log(JSON.stringify({
|
|
476172
476949
|
path: localPath,
|
|
@@ -478859,13 +479636,13 @@ import {
|
|
|
478859
479636
|
existsSync as existsSync71,
|
|
478860
479637
|
mkdtempSync as mkdtempSync6,
|
|
478861
479638
|
readFileSync as readFileSync52,
|
|
478862
|
-
rmSync as
|
|
479639
|
+
rmSync as rmSync26,
|
|
478863
479640
|
statSync as statSync27,
|
|
478864
479641
|
writeFileSync as writeFileSync43
|
|
478865
479642
|
} from "node:fs";
|
|
478866
479643
|
import { mkdir as mkdir16, readdir as readdir13 } from "node:fs/promises";
|
|
478867
479644
|
import { tmpdir as tmpdir15 } from "node:os";
|
|
478868
|
-
import { basename as
|
|
479645
|
+
import { basename as basename31, dirname as dirname40, join as join102, normalize as normalize5, resolve as resolve41, sep as sep8 } from "node:path";
|
|
478869
479646
|
import { parseArgs as parseArgs20, TextDecoder as TextDecoder2, TextEncoder as TextEncoder2 } from "node:util";
|
|
478870
479647
|
function printUsage17() {
|
|
478871
479648
|
console.log(`
|
|
@@ -479039,7 +479816,7 @@ function parseDirectSkillFileUrlSpecifier(input) {
|
|
|
479039
479816
|
if (url2.protocol !== "https:" && !(url2.protocol === "http:" && isLocalhostHostname(url2.hostname))) {
|
|
479040
479817
|
return null;
|
|
479041
479818
|
}
|
|
479042
|
-
if (
|
|
479819
|
+
if (basename31(url2.pathname).toLowerCase() !== "skill.md")
|
|
479043
479820
|
return null;
|
|
479044
479821
|
return { url: url2.toString() };
|
|
479045
479822
|
}
|
|
@@ -479205,7 +479982,7 @@ async function downloadDirectSkillFileSource(location, options = {}) {
|
|
|
479205
479982
|
writeFileSync43(join102(sourceDir, "SKILL.md"), skillText, "utf8");
|
|
479206
479983
|
return { tmpDir, sourceDir };
|
|
479207
479984
|
} catch (error5) {
|
|
479208
|
-
|
|
479985
|
+
rmSync26(tmpDir, { recursive: true, force: true });
|
|
479209
479986
|
throw error5;
|
|
479210
479987
|
}
|
|
479211
479988
|
}
|
|
@@ -479287,7 +480064,7 @@ function getSkillName(sourceDir) {
|
|
|
479287
480064
|
const skillMd = readFileSync52(join102(sourceDir, "SKILL.md"), "utf8");
|
|
479288
480065
|
const { frontmatter } = parseFrontmatter(skillMd);
|
|
479289
480066
|
const frontmatterName = frontmatter.name;
|
|
479290
|
-
const name = typeof frontmatterName === "string" && frontmatterName.trim() ? frontmatterName :
|
|
480067
|
+
const name = typeof frontmatterName === "string" && frontmatterName.trim() ? frontmatterName : basename31(sourceDir);
|
|
479291
480068
|
return sanitizeSkillName(name);
|
|
479292
480069
|
}
|
|
479293
480070
|
async function installSkillDirectory(params) {
|
|
@@ -479308,12 +480085,12 @@ async function installSkillDirectory(params) {
|
|
|
479308
480085
|
if (!params.force) {
|
|
479309
480086
|
throw new Error(`Skill "${name}" already exists at ${targetPath}. Re-run with --force to replace it.`);
|
|
479310
480087
|
}
|
|
479311
|
-
|
|
480088
|
+
rmSync26(targetPath, { recursive: true, force: true });
|
|
479312
480089
|
}
|
|
479313
480090
|
await mkdir16(skillsDir, { recursive: true });
|
|
479314
480091
|
cpSync2(sourceDir, targetPath, {
|
|
479315
480092
|
recursive: true,
|
|
479316
|
-
filter: (source) =>
|
|
480093
|
+
filter: (source) => basename31(source) !== ".git"
|
|
479317
480094
|
});
|
|
479318
480095
|
return { name, path: normalize5(targetPath) };
|
|
479319
480096
|
}
|
|
@@ -479359,7 +480136,7 @@ async function deleteSkillDirectory(params) {
|
|
|
479359
480136
|
if (!statSync27(targetPath).isDirectory()) {
|
|
479360
480137
|
throw new Error(`Skill path is not a directory: ${targetPath}`);
|
|
479361
480138
|
}
|
|
479362
|
-
|
|
480139
|
+
rmSync26(targetPath, { recursive: true, force: true });
|
|
479363
480140
|
return { name, path: normalize5(targetPath) };
|
|
479364
480141
|
}
|
|
479365
480142
|
async function loadSkillMemorySyncFn() {
|
|
@@ -479423,7 +480200,7 @@ async function installSkill(specifier, agentId, force) {
|
|
|
479423
480200
|
};
|
|
479424
480201
|
} finally {
|
|
479425
480202
|
if (tmpDir)
|
|
479426
|
-
|
|
480203
|
+
rmSync26(tmpDir, { recursive: true, force: true });
|
|
479427
480204
|
}
|
|
479428
480205
|
}
|
|
479429
480206
|
async function getAgentMemoryDir(agentId) {
|
|
@@ -480033,7 +480810,7 @@ import {
|
|
|
480033
480810
|
stat as stat17,
|
|
480034
480811
|
writeFile as writeFile20
|
|
480035
480812
|
} from "node:fs/promises";
|
|
480036
|
-
import { basename as
|
|
480813
|
+
import { basename as basename32, join as join104 } from "node:path";
|
|
480037
480814
|
function fileTimestamp(startedAt) {
|
|
480038
480815
|
if (!startedAt)
|
|
480039
480816
|
return "unknown-date";
|
|
@@ -480201,10 +480978,10 @@ async function runTrajectoryExport(options) {
|
|
|
480201
480978
|
if (!supported.includes(explicit.source)) {
|
|
480202
480979
|
throw new Error(`Unknown source "${explicit.source}" in --transcript. The installed trajectory package supports: ${supported.join(", ")}.`);
|
|
480203
480980
|
}
|
|
480204
|
-
await exportTranscript(explicit.source,
|
|
480981
|
+
await exportTranscript(explicit.source, basename32(explicit.path).replace(/\.[^.]+$/, ""), explicit.path, () => readFile31(explicit.path, "utf-8"));
|
|
480205
480982
|
}
|
|
480206
480983
|
for (const checkpoint of options.deepagents ?? []) {
|
|
480207
|
-
await exportCheckpoint(checkpoint, `${
|
|
480984
|
+
await exportCheckpoint(checkpoint, `${basename32(checkpoint.path)}-${checkpoint.threadId}`);
|
|
480208
480985
|
}
|
|
480209
480986
|
manifest2.sessions.sort((a2, b3) => (a2.startedAt ?? "").localeCompare(b3.startedAt ?? ""));
|
|
480210
480987
|
await writeFile20(join104(options.outDir, MANIFEST_NAME), JSON.stringify(manifest2, null, 2), "utf-8");
|
|
@@ -483652,7 +484429,7 @@ var init_message_channel_gateway_tool = __esm(() => {
|
|
|
483652
484429
|
});
|
|
483653
484430
|
|
|
483654
484431
|
// src/channels/custom/scaffolding.ts
|
|
483655
|
-
import { existsSync as existsSync72, mkdirSync as mkdirSync52, rmSync as
|
|
484432
|
+
import { existsSync as existsSync72, mkdirSync as mkdirSync52, rmSync as rmSync27, writeFileSync as writeFileSync44 } from "node:fs";
|
|
483656
484433
|
function removeUserPlugin(channelId) {
|
|
483657
484434
|
if (FIRST_PARTY_SET.has(channelId)) {
|
|
483658
484435
|
return;
|
|
@@ -483665,7 +484442,7 @@ function removeUserPlugin(channelId) {
|
|
|
483665
484442
|
return;
|
|
483666
484443
|
}
|
|
483667
484444
|
try {
|
|
483668
|
-
|
|
484445
|
+
rmSync27(channelDir, { recursive: true, force: true });
|
|
483669
484446
|
} catch (err) {
|
|
483670
484447
|
console.error(`[channels] Failed to remove plugin folder ${channelDir}:`, err);
|
|
483671
484448
|
}
|
|
@@ -490432,7 +491209,7 @@ var BYTES_PER_TOKEN = 4;
|
|
|
490432
491209
|
|
|
490433
491210
|
// src/cli/helpers/window-title-config.ts
|
|
490434
491211
|
import { homedir as homedir32 } from "node:os";
|
|
490435
|
-
import { basename as
|
|
491212
|
+
import { basename as basename33, resolve as resolve42 } from "node:path";
|
|
490436
491213
|
function isWindowTitleField(value) {
|
|
490437
491214
|
return WINDOW_TITLE_FIELDS.includes(value);
|
|
490438
491215
|
}
|
|
@@ -490591,7 +491368,7 @@ function terminalTitleProjectName(data) {
|
|
|
490591
491368
|
if (!directory)
|
|
490592
491369
|
return null;
|
|
490593
491370
|
const resolved2 = resolve42(directory);
|
|
490594
|
-
const name =
|
|
491371
|
+
const name = basename33(resolved2) || formatDirectoryDisplay(resolved2) || resolved2;
|
|
490595
491372
|
return truncateTerminalTitlePart(name, 24);
|
|
490596
491373
|
}
|
|
490597
491374
|
function titleDirectory(data) {
|
|
@@ -504149,7 +504926,7 @@ import {
|
|
|
504149
504926
|
mkdirSync as mkdirSync55,
|
|
504150
504927
|
mkdtempSync as mkdtempSync7,
|
|
504151
504928
|
readFileSync as readFileSync55,
|
|
504152
|
-
rmSync as
|
|
504929
|
+
rmSync as rmSync28,
|
|
504153
504930
|
writeFileSync as writeFileSync47
|
|
504154
504931
|
} from "node:fs";
|
|
504155
504932
|
import { tmpdir as tmpdir16 } from "node:os";
|
|
@@ -504519,7 +505296,7 @@ async function installGithubApp(options) {
|
|
|
504519
505296
|
agentUrl: resolvedAgentId ? buildAgentReference(resolvedAgentId) : null
|
|
504520
505297
|
};
|
|
504521
505298
|
} finally {
|
|
504522
|
-
|
|
505299
|
+
rmSync28(tempDir, { recursive: true, force: true });
|
|
504523
505300
|
}
|
|
504524
505301
|
}
|
|
504525
505302
|
var DEFAULT_WORKFLOW_PATH = ".github/workflows/letta.yml", ALTERNATE_WORKFLOW_PATH = ".github/workflows/letta-code.yml";
|
|
@@ -522801,7 +523578,7 @@ var init_system_reminders2 = __esm(() => {
|
|
|
522801
523578
|
|
|
522802
523579
|
// src/cli/app/use-conversation-loop.ts
|
|
522803
523580
|
import { randomUUID as randomUUID68 } from "node:crypto";
|
|
522804
|
-
function
|
|
523581
|
+
function sleep12(ms) {
|
|
522805
523582
|
return new Promise((resolve44) => setTimeout(resolve44, ms));
|
|
522806
523583
|
}
|
|
522807
523584
|
function makeExecutionPhaseHook(setExecutionPhase) {
|
|
@@ -522932,7 +523709,7 @@ function useConversationLoop(ctx) {
|
|
|
522932
523709
|
const currentSettings = await settingsManager.getSettingsWithSecureTokens();
|
|
522933
523710
|
const hasCloudAuth = Boolean(process.env.LETTA_API_KEY || currentSettings.refreshToken || currentSettings.env?.LETTA_API_KEY);
|
|
522934
523711
|
setThinkingMessage(getRandomThinkingVerb());
|
|
522935
|
-
await
|
|
523712
|
+
await sleep12(250);
|
|
522936
523713
|
const lineId = uid("assistant");
|
|
522937
523714
|
buffersRef.current.byId.set(lineId, {
|
|
522938
523715
|
kind: "assistant",
|
|
@@ -522957,7 +523734,7 @@ function useConversationLoop(ctx) {
|
|
|
522957
523734
|
});
|
|
522958
523735
|
buffersRef.current.tokenCount += Buffer.byteLength(chunk2, "utf8");
|
|
522959
523736
|
refreshDerived();
|
|
522960
|
-
await
|
|
523737
|
+
await sleep12(chunk2 === `
|
|
522961
523738
|
` ? 70 : 120);
|
|
522962
523739
|
}
|
|
522963
523740
|
const finalLine = buffersRef.current.byId.get(lineId);
|
|
@@ -529671,7 +530448,7 @@ __export(exports_worktree_diff_list, {
|
|
|
529671
530448
|
listWorktreeDiffOptions: () => listWorktreeDiffOptions
|
|
529672
530449
|
});
|
|
529673
530450
|
import { execFile as execFileCb8 } from "node:child_process";
|
|
529674
|
-
import { basename as
|
|
530451
|
+
import { basename as basename34 } from "node:path";
|
|
529675
530452
|
import { promisify as promisify23 } from "node:util";
|
|
529676
530453
|
async function runGit9(cwd2, args) {
|
|
529677
530454
|
try {
|
|
@@ -529720,7 +530497,7 @@ function parseWorktreeList(output, currentPath) {
|
|
|
529720
530497
|
if (current?.path) {
|
|
529721
530498
|
worktrees.push({
|
|
529722
530499
|
path: current.path,
|
|
529723
|
-
name:
|
|
530500
|
+
name: basename34(current.path),
|
|
529724
530501
|
branch: current.branch ?? "detached",
|
|
529725
530502
|
head: current.head ?? "",
|
|
529726
530503
|
isCurrent: current.path === currentPath,
|
|
@@ -529746,7 +530523,7 @@ function parseWorktreeList(output, currentPath) {
|
|
|
529746
530523
|
if (current?.path) {
|
|
529747
530524
|
worktrees.push({
|
|
529748
530525
|
path: current.path,
|
|
529749
|
-
name:
|
|
530526
|
+
name: basename34(current.path),
|
|
529750
530527
|
branch: current.branch ?? "detached",
|
|
529751
530528
|
head: current.head ?? "",
|
|
529752
530529
|
isCurrent: current.path === currentPath,
|
|
@@ -539736,4 +540513,4 @@ function registerBunOAuthFlows() {
|
|
|
539736
540513
|
registerBunOAuthFlows();
|
|
539737
540514
|
await init_src5().then(() => exports_src2);
|
|
539738
540515
|
|
|
539739
|
-
//# debugId=
|
|
540516
|
+
//# debugId=23162BCF185F91F064756E2164756E21
|