@letta-ai/letta-code 0.21.12 → 0.21.14
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/letta.js +274 -39
- package/package.json +1 -1
package/letta.js
CHANGED
|
@@ -3269,7 +3269,7 @@ var package_default;
|
|
|
3269
3269
|
var init_package = __esm(() => {
|
|
3270
3270
|
package_default = {
|
|
3271
3271
|
name: "@letta-ai/letta-code",
|
|
3272
|
-
version: "0.21.
|
|
3272
|
+
version: "0.21.14",
|
|
3273
3273
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
3274
3274
|
type: "module",
|
|
3275
3275
|
bin: {
|
|
@@ -40508,7 +40508,7 @@ import {
|
|
|
40508
40508
|
mkdirSync as mkdirSync8,
|
|
40509
40509
|
readFileSync as readFileSync7,
|
|
40510
40510
|
renameSync as renameSync2,
|
|
40511
|
-
|
|
40511
|
+
rmSync as rmSync2,
|
|
40512
40512
|
statSync as statSync2,
|
|
40513
40513
|
writeFileSync as writeFileSync6
|
|
40514
40514
|
} from "node:fs";
|
|
@@ -40586,7 +40586,7 @@ function isLockStale(lockDir) {
|
|
|
40586
40586
|
}
|
|
40587
40587
|
function stealLock(lockDir) {
|
|
40588
40588
|
try {
|
|
40589
|
-
|
|
40589
|
+
rmSync2(lockDir, { recursive: true, force: true });
|
|
40590
40590
|
} catch {}
|
|
40591
40591
|
}
|
|
40592
40592
|
function acquireLock() {
|
|
@@ -40607,7 +40607,7 @@ function acquireLock() {
|
|
|
40607
40607
|
try {
|
|
40608
40608
|
const current = readLockOwner(lockDir);
|
|
40609
40609
|
if (current && current.token === token) {
|
|
40610
|
-
|
|
40610
|
+
rmSync2(lockDir, { recursive: true, force: true });
|
|
40611
40611
|
}
|
|
40612
40612
|
} catch {}
|
|
40613
40613
|
}
|
|
@@ -65411,7 +65411,7 @@ async function runProcess(context3) {
|
|
|
65411
65411
|
}
|
|
65412
65412
|
async function shell(args) {
|
|
65413
65413
|
validateRequiredParams(args, ["command"], "shell");
|
|
65414
|
-
const { command, workdir, timeout_ms, signal, onOutput } = args;
|
|
65414
|
+
const { command, workdir, timeout_ms, env_overrides, signal, onOutput } = args;
|
|
65415
65415
|
if (!Array.isArray(command) || command.length === 0) {
|
|
65416
65416
|
throw new Error("command must be a non-empty array of strings");
|
|
65417
65417
|
}
|
|
@@ -65422,7 +65422,10 @@ async function shell(args) {
|
|
|
65422
65422
|
const context3 = {
|
|
65423
65423
|
command,
|
|
65424
65424
|
cwd: cwd2,
|
|
65425
|
-
env:
|
|
65425
|
+
env: {
|
|
65426
|
+
...getShellEnv(),
|
|
65427
|
+
...env_overrides ?? {}
|
|
65428
|
+
},
|
|
65426
65429
|
timeout,
|
|
65427
65430
|
signal,
|
|
65428
65431
|
onOutput
|
|
@@ -65543,6 +65546,7 @@ async function shell_command(args) {
|
|
|
65543
65546
|
signal,
|
|
65544
65547
|
onOutput
|
|
65545
65548
|
} = args;
|
|
65549
|
+
const envOverrides = getMemoryGitIdentityEnvOverrides(command, workdir);
|
|
65546
65550
|
const launchers = buildShellLaunchers(command, { login });
|
|
65547
65551
|
if (launchers.length === 0) {
|
|
65548
65552
|
throw new Error("Command must be a non-empty string");
|
|
@@ -65554,6 +65558,7 @@ async function shell_command(args) {
|
|
|
65554
65558
|
return await shell({
|
|
65555
65559
|
command: launcher,
|
|
65556
65560
|
workdir,
|
|
65561
|
+
env_overrides: envOverrides,
|
|
65557
65562
|
timeout_ms,
|
|
65558
65563
|
justification,
|
|
65559
65564
|
signal,
|
|
@@ -65572,7 +65577,96 @@ async function shell_command(args) {
|
|
|
65572
65577
|
const reason = lastError?.message || "Shell unavailable";
|
|
65573
65578
|
throw new Error(suffix ? `${reason} (tried: ${suffix})` : reason);
|
|
65574
65579
|
}
|
|
65580
|
+
function getMemoryGitIdentityEnvOverrides(command, workdir) {
|
|
65581
|
+
const agentId = getCurrentAgentIdOrEnv();
|
|
65582
|
+
if (!agentId) {
|
|
65583
|
+
return;
|
|
65584
|
+
}
|
|
65585
|
+
if (!containsGitCommitInvocation(command)) {
|
|
65586
|
+
return;
|
|
65587
|
+
}
|
|
65588
|
+
const scopedToMemoryDir = isMemoryDirCommand(command, agentId) || (workdir ? isMemoryDirCommand(`cd ${shellQuote(workdir)} && ${command}`, agentId) : false);
|
|
65589
|
+
if (!scopedToMemoryDir) {
|
|
65590
|
+
return;
|
|
65591
|
+
}
|
|
65592
|
+
const agentName = (process.env.AGENT_NAME || "").trim() || agentId;
|
|
65593
|
+
const agentEmail = `${agentId}@letta.com`;
|
|
65594
|
+
return {
|
|
65595
|
+
GIT_AUTHOR_NAME: agentName,
|
|
65596
|
+
GIT_AUTHOR_EMAIL: agentEmail,
|
|
65597
|
+
GIT_COMMITTER_NAME: agentName,
|
|
65598
|
+
GIT_COMMITTER_EMAIL: agentEmail
|
|
65599
|
+
};
|
|
65600
|
+
}
|
|
65601
|
+
function getCurrentAgentIdOrEnv() {
|
|
65602
|
+
const envAgentId = (process.env.AGENT_ID || process.env.LETTA_AGENT_ID || "").trim();
|
|
65603
|
+
if (envAgentId) {
|
|
65604
|
+
return envAgentId;
|
|
65605
|
+
}
|
|
65606
|
+
try {
|
|
65607
|
+
const agentId = getCurrentAgentId().trim();
|
|
65608
|
+
if (agentId) {
|
|
65609
|
+
return agentId;
|
|
65610
|
+
}
|
|
65611
|
+
} catch {}
|
|
65612
|
+
return "";
|
|
65613
|
+
}
|
|
65614
|
+
function containsGitCommitInvocation(command) {
|
|
65615
|
+
const segments = command.split(/&&|\|\||;|\|/).map((segment) => segment.trim()).filter(Boolean);
|
|
65616
|
+
for (const segment of segments) {
|
|
65617
|
+
const tokens = tokenizeSegment(segment);
|
|
65618
|
+
if (tokens.length === 0) {
|
|
65619
|
+
continue;
|
|
65620
|
+
}
|
|
65621
|
+
let index = 0;
|
|
65622
|
+
while (index < tokens.length && /^[A-Za-z_][A-Za-z0-9_]*=.*/.test(tokens[index] ?? "")) {
|
|
65623
|
+
index += 1;
|
|
65624
|
+
}
|
|
65625
|
+
if (tokens[index] !== "git") {
|
|
65626
|
+
continue;
|
|
65627
|
+
}
|
|
65628
|
+
index += 1;
|
|
65629
|
+
while (index < tokens.length) {
|
|
65630
|
+
const token = tokens[index];
|
|
65631
|
+
if (!token) {
|
|
65632
|
+
index += 1;
|
|
65633
|
+
continue;
|
|
65634
|
+
}
|
|
65635
|
+
if (token === "-c" || token === "-C") {
|
|
65636
|
+
index += 2;
|
|
65637
|
+
continue;
|
|
65638
|
+
}
|
|
65639
|
+
if (token.startsWith("-")) {
|
|
65640
|
+
index += 1;
|
|
65641
|
+
continue;
|
|
65642
|
+
}
|
|
65643
|
+
if (token === "commit") {
|
|
65644
|
+
return true;
|
|
65645
|
+
}
|
|
65646
|
+
break;
|
|
65647
|
+
}
|
|
65648
|
+
}
|
|
65649
|
+
return false;
|
|
65650
|
+
}
|
|
65651
|
+
function tokenizeSegment(segment) {
|
|
65652
|
+
const matches = segment.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g);
|
|
65653
|
+
if (!matches) {
|
|
65654
|
+
return [];
|
|
65655
|
+
}
|
|
65656
|
+
return matches.map(stripWrappingQuotes);
|
|
65657
|
+
}
|
|
65658
|
+
function stripWrappingQuotes(token) {
|
|
65659
|
+
if (token.startsWith('"') && token.endsWith('"') || token.startsWith("'") && token.endsWith("'")) {
|
|
65660
|
+
return token.slice(1, -1);
|
|
65661
|
+
}
|
|
65662
|
+
return token;
|
|
65663
|
+
}
|
|
65664
|
+
function shellQuote(value) {
|
|
65665
|
+
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
65666
|
+
}
|
|
65575
65667
|
var init_ShellCommand2 = __esm(async () => {
|
|
65668
|
+
init_context();
|
|
65669
|
+
init_readOnlyShell();
|
|
65576
65670
|
init_shellRunner();
|
|
65577
65671
|
await init_Shell2();
|
|
65578
65672
|
});
|
|
@@ -65827,6 +65921,17 @@ var init_skillContentRegistry = __esm(() => {
|
|
|
65827
65921
|
import { readdirSync as readdirSync7 } from "node:fs";
|
|
65828
65922
|
import { readFile as readFile6 } from "node:fs/promises";
|
|
65829
65923
|
import { dirname as dirname10, join as join20 } from "node:path";
|
|
65924
|
+
function getMemorySkillsDirs(agentId) {
|
|
65925
|
+
const dirs = new Set;
|
|
65926
|
+
const memoryDir = process.env.MEMORY_DIR || process.env.LETTA_MEMORY_DIR;
|
|
65927
|
+
if (memoryDir && memoryDir.trim().length > 0) {
|
|
65928
|
+
dirs.add(join20(memoryDir.trim(), "skills"));
|
|
65929
|
+
}
|
|
65930
|
+
if (agentId) {
|
|
65931
|
+
dirs.add(join20(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents", agentId, "memory", "skills"));
|
|
65932
|
+
}
|
|
65933
|
+
return Array.from(dirs);
|
|
65934
|
+
}
|
|
65830
65935
|
function hasAdditionalFiles(skillMdPath) {
|
|
65831
65936
|
try {
|
|
65832
65937
|
const skillDir = dirname10(skillMdPath);
|
|
@@ -65849,6 +65954,13 @@ async function readSkillContent(skillId, skillsDir, agentId) {
|
|
|
65849
65954
|
return { content, path: agentSkillPath };
|
|
65850
65955
|
} catch {}
|
|
65851
65956
|
}
|
|
65957
|
+
for (const memorySkillsDir of getMemorySkillsDirs(agentId)) {
|
|
65958
|
+
const memorySkillPath = join20(memorySkillsDir, skillId, "SKILL.md");
|
|
65959
|
+
try {
|
|
65960
|
+
const content = await readFile6(memorySkillPath, "utf-8");
|
|
65961
|
+
return { content, path: memorySkillPath };
|
|
65962
|
+
} catch {}
|
|
65963
|
+
}
|
|
65852
65964
|
const globalSkillPath = join20(GLOBAL_SKILLS_DIR, skillId, "SKILL.md");
|
|
65853
65965
|
try {
|
|
65854
65966
|
const content = await readFile6(globalSkillPath, "utf-8");
|
|
@@ -74226,6 +74338,84 @@ var init_check_approval = __esm(() => {
|
|
|
74226
74338
|
];
|
|
74227
74339
|
});
|
|
74228
74340
|
|
|
74341
|
+
// src/utils/createRelayedAbortController.ts
|
|
74342
|
+
function createRelayedAbortController(parentSignal) {
|
|
74343
|
+
const controller = new AbortController;
|
|
74344
|
+
if (!parentSignal) {
|
|
74345
|
+
return {
|
|
74346
|
+
controller,
|
|
74347
|
+
signal: controller.signal,
|
|
74348
|
+
cleanup: () => {}
|
|
74349
|
+
};
|
|
74350
|
+
}
|
|
74351
|
+
if (parentSignal.aborted) {
|
|
74352
|
+
controller.abort(parentSignal.reason);
|
|
74353
|
+
return {
|
|
74354
|
+
controller,
|
|
74355
|
+
signal: controller.signal,
|
|
74356
|
+
cleanup: () => {}
|
|
74357
|
+
};
|
|
74358
|
+
}
|
|
74359
|
+
const relayAbort = () => {
|
|
74360
|
+
controller.abort(parentSignal.reason);
|
|
74361
|
+
};
|
|
74362
|
+
parentSignal.addEventListener("abort", relayAbort, { once: true });
|
|
74363
|
+
return {
|
|
74364
|
+
controller,
|
|
74365
|
+
signal: controller.signal,
|
|
74366
|
+
cleanup: () => {
|
|
74367
|
+
parentSignal.removeEventListener("abort", relayAbort);
|
|
74368
|
+
}
|
|
74369
|
+
};
|
|
74370
|
+
}
|
|
74371
|
+
|
|
74372
|
+
// src/utils/streamAbortRelay.ts
|
|
74373
|
+
function composeCleanups(first, second) {
|
|
74374
|
+
let cleaned = false;
|
|
74375
|
+
return () => {
|
|
74376
|
+
if (cleaned) {
|
|
74377
|
+
return;
|
|
74378
|
+
}
|
|
74379
|
+
cleaned = true;
|
|
74380
|
+
first();
|
|
74381
|
+
second();
|
|
74382
|
+
};
|
|
74383
|
+
}
|
|
74384
|
+
function createStreamAbortRelay(parentSignal) {
|
|
74385
|
+
if (!parentSignal) {
|
|
74386
|
+
return null;
|
|
74387
|
+
}
|
|
74388
|
+
const requestAbort = createRelayedAbortController(parentSignal);
|
|
74389
|
+
let cleaned = false;
|
|
74390
|
+
const cleanup = () => {
|
|
74391
|
+
if (cleaned) {
|
|
74392
|
+
return;
|
|
74393
|
+
}
|
|
74394
|
+
cleaned = true;
|
|
74395
|
+
requestAbort.cleanup();
|
|
74396
|
+
};
|
|
74397
|
+
return {
|
|
74398
|
+
signal: requestAbort.signal,
|
|
74399
|
+
attach(stream2) {
|
|
74400
|
+
const existingCleanup = streamAbortRelayCleanupByStream.get(stream2);
|
|
74401
|
+
streamAbortRelayCleanupByStream.set(stream2, existingCleanup ? composeCleanups(existingCleanup, cleanup) : cleanup);
|
|
74402
|
+
},
|
|
74403
|
+
cleanup
|
|
74404
|
+
};
|
|
74405
|
+
}
|
|
74406
|
+
function cleanupStreamAbortRelay(stream2) {
|
|
74407
|
+
const cleanup = streamAbortRelayCleanupByStream.get(stream2);
|
|
74408
|
+
if (!cleanup) {
|
|
74409
|
+
return;
|
|
74410
|
+
}
|
|
74411
|
+
streamAbortRelayCleanupByStream.delete(stream2);
|
|
74412
|
+
cleanup();
|
|
74413
|
+
}
|
|
74414
|
+
var streamAbortRelayCleanupByStream;
|
|
74415
|
+
var init_streamAbortRelay = __esm(() => {
|
|
74416
|
+
streamAbortRelayCleanupByStream = new WeakMap;
|
|
74417
|
+
});
|
|
74418
|
+
|
|
74229
74419
|
// src/agent/approval-result-normalization.ts
|
|
74230
74420
|
function normalizeToolReturnText(value) {
|
|
74231
74421
|
if (typeof value === "string")
|
|
@@ -74470,19 +74660,23 @@ async function sendMessageStream(conversationId, messages, opts = { streamTokens
|
|
|
74470
74660
|
const firstOtid = messages[0]?.otid;
|
|
74471
74661
|
debugLog("send-message-stream", "request_start conversation_id=%s agent_id=%s messages=%s otid=%s stream_tokens=%s background=%s max_retries=%s", resolvedConversationId, opts.agentId ?? "none", messageSummary || "(empty)", firstOtid ?? "none", opts.streamTokens ?? true, opts.background ?? true, requestOptions.maxRetries ?? "default");
|
|
74472
74662
|
let stream2;
|
|
74663
|
+
const abortRelay = createStreamAbortRelay(requestOptions.signal);
|
|
74473
74664
|
try {
|
|
74474
74665
|
stream2 = await client.conversations.messages.create(resolvedConversationId, requestBody, {
|
|
74475
74666
|
...requestOptions,
|
|
74667
|
+
...abortRelay ? { signal: abortRelay.signal } : {},
|
|
74476
74668
|
headers: {
|
|
74477
74669
|
...requestOptions.headers ?? {},
|
|
74478
74670
|
...extraHeaders
|
|
74479
74671
|
}
|
|
74480
74672
|
});
|
|
74481
74673
|
} catch (error) {
|
|
74674
|
+
abortRelay?.cleanup();
|
|
74482
74675
|
debugWarn("send-message-stream", "request_error conversation_id=%s otid=%s status=%s error=%s", resolvedConversationId, firstOtid ?? "none", error?.status ?? "none", error instanceof Error ? error.message : String(error));
|
|
74483
74676
|
throw error;
|
|
74484
74677
|
}
|
|
74485
74678
|
debugLog("send-message-stream", "request_ok conversation_id=%s otid=%s", resolvedConversationId, firstOtid ?? "none");
|
|
74679
|
+
abortRelay?.attach(stream2);
|
|
74486
74680
|
if (requestStartTime !== undefined) {
|
|
74487
74681
|
streamRequestStartTimes.set(stream2, requestStartTime);
|
|
74488
74682
|
}
|
|
@@ -74499,6 +74693,7 @@ async function sendMessageStream(conversationId, messages, opts = { streamTokens
|
|
|
74499
74693
|
var streamRequestStartTimes, streamToolContextIds, streamRequestContexts;
|
|
74500
74694
|
var init_message = __esm(async () => {
|
|
74501
74695
|
init_debug();
|
|
74696
|
+
init_streamAbortRelay();
|
|
74502
74697
|
init_timing();
|
|
74503
74698
|
init_approval_result_normalization();
|
|
74504
74699
|
init_clientSkills();
|
|
@@ -76589,6 +76784,7 @@ async function drainStream(stream2, buffers, refresh, abortSignal, onFirstMessag
|
|
|
76589
76784
|
if (abortSignal) {
|
|
76590
76785
|
abortSignal.removeEventListener("abort", abortHandler);
|
|
76591
76786
|
}
|
|
76787
|
+
cleanupStreamAbortRelay(stream2);
|
|
76592
76788
|
clearLastSDKDiagnostic();
|
|
76593
76789
|
}
|
|
76594
76790
|
if (!stopReason && streamProcessor.stopReason) {
|
|
@@ -76680,15 +76876,23 @@ async function drainStreamWithResume(stream2, buffers, refresh, abortSignal, onF
|
|
|
76680
76876
|
const client = await lazyClient();
|
|
76681
76877
|
buffers.commitGeneration = (buffers.commitGeneration || 0) + 1;
|
|
76682
76878
|
buffers.interrupted = false;
|
|
76683
|
-
const
|
|
76684
|
-
|
|
76685
|
-
|
|
76686
|
-
|
|
76687
|
-
|
|
76688
|
-
|
|
76689
|
-
|
|
76690
|
-
|
|
76691
|
-
|
|
76879
|
+
const resumeAbortRelay = createStreamAbortRelay(abortSignal);
|
|
76880
|
+
let resumeStream;
|
|
76881
|
+
try {
|
|
76882
|
+
resumeStream = runIdSource === "otid" && streamOtid && streamRequestContext ? await client.conversations.messages.stream(streamRequestContext.resolvedConversationId, {
|
|
76883
|
+
agent_id: streamRequestContext.conversationId === "default" ? streamRequestContext.agentId ?? undefined : undefined,
|
|
76884
|
+
otid: streamOtid,
|
|
76885
|
+
starting_after: result.lastSeqId ?? 0,
|
|
76886
|
+
batch_size: 1000
|
|
76887
|
+
}, resumeAbortRelay ? { signal: resumeAbortRelay.signal } : undefined) : await client.runs.messages.stream(runIdToResume, {
|
|
76888
|
+
starting_after: result.lastSeqId ?? 0,
|
|
76889
|
+
batch_size: 1000
|
|
76890
|
+
}, resumeAbortRelay ? { signal: resumeAbortRelay.signal } : undefined);
|
|
76891
|
+
} catch (resumeError) {
|
|
76892
|
+
resumeAbortRelay?.cleanup();
|
|
76893
|
+
throw resumeError;
|
|
76894
|
+
}
|
|
76895
|
+
resumeAbortRelay?.attach(resumeStream);
|
|
76692
76896
|
const resumeResult = await drainStream(resumeStream, buffers, refresh, abortSignal, undefined, onChunkProcessed, contextTracker, seenSeqIdThreshold, true);
|
|
76693
76897
|
if (resumeResult.stopReason !== "error") {
|
|
76694
76898
|
debugWarn("stream", "[MID-STREAM RESUME] ✅ Success (runId=%s, stopReason=%s)", runIdToResume, resumeResult.stopReason);
|
|
@@ -76753,6 +76957,7 @@ var FALLBACK_RUN_DISCOVERY_TIMEOUT_MS = 5000;
|
|
|
76753
76957
|
var init_stream = __esm(async () => {
|
|
76754
76958
|
init_error();
|
|
76755
76959
|
init_debug();
|
|
76960
|
+
init_streamAbortRelay();
|
|
76756
76961
|
init_timing();
|
|
76757
76962
|
init_chunkLog();
|
|
76758
76963
|
await __promiseAll([
|
|
@@ -80692,15 +80897,23 @@ async function sendMessageStreamWithRetry(conversationId, messages, opts, socket
|
|
|
80692
80897
|
try {
|
|
80693
80898
|
const client = await getClient();
|
|
80694
80899
|
const messageOtid = messages.map((item) => item.otid).find((value) => typeof value === "string");
|
|
80900
|
+
const resumeAbortRelay = createStreamAbortRelay(abortSignal);
|
|
80695
80901
|
if (abortSignal?.aborted) {
|
|
80696
80902
|
throw new Error("Cancelled by user");
|
|
80697
80903
|
}
|
|
80698
|
-
|
|
80699
|
-
|
|
80700
|
-
|
|
80701
|
-
|
|
80702
|
-
|
|
80703
|
-
|
|
80904
|
+
try {
|
|
80905
|
+
const resumeStream = await client.conversations.messages.stream(conversationId, {
|
|
80906
|
+
agent_id: conversationId === "default" ? runtime.agentId ?? undefined : undefined,
|
|
80907
|
+
otid: messageOtid ?? undefined,
|
|
80908
|
+
starting_after: 0,
|
|
80909
|
+
batch_size: 1000
|
|
80910
|
+
}, resumeAbortRelay ? { signal: resumeAbortRelay.signal } : undefined);
|
|
80911
|
+
resumeAbortRelay?.attach(resumeStream);
|
|
80912
|
+
return resumeStream;
|
|
80913
|
+
} catch (resumeError) {
|
|
80914
|
+
resumeAbortRelay?.cleanup();
|
|
80915
|
+
throw resumeError;
|
|
80916
|
+
}
|
|
80704
80917
|
} catch (resumeError) {
|
|
80705
80918
|
if (abortSignal?.aborted) {
|
|
80706
80919
|
throw new Error("Cancelled by user");
|
|
@@ -80815,15 +81028,23 @@ async function sendApprovalContinuationWithRetry(conversationId, messages, opts,
|
|
|
80815
81028
|
try {
|
|
80816
81029
|
const client = await getClient();
|
|
80817
81030
|
const messageOtid = messages.map((item) => item.otid).find((value) => typeof value === "string");
|
|
81031
|
+
const resumeAbortRelay = createStreamAbortRelay(abortSignal);
|
|
80818
81032
|
if (abortSignal?.aborted) {
|
|
80819
81033
|
throw new Error("Cancelled by user");
|
|
80820
81034
|
}
|
|
80821
|
-
|
|
80822
|
-
|
|
80823
|
-
|
|
80824
|
-
|
|
80825
|
-
|
|
80826
|
-
|
|
81035
|
+
try {
|
|
81036
|
+
const resumeStream = await client.conversations.messages.stream(conversationId, {
|
|
81037
|
+
agent_id: conversationId === "default" ? runtime.agentId ?? undefined : undefined,
|
|
81038
|
+
otid: messageOtid ?? undefined,
|
|
81039
|
+
starting_after: 0,
|
|
81040
|
+
batch_size: 1000
|
|
81041
|
+
}, resumeAbortRelay ? { signal: resumeAbortRelay.signal } : undefined);
|
|
81042
|
+
resumeAbortRelay?.attach(resumeStream);
|
|
81043
|
+
return resumeStream;
|
|
81044
|
+
} catch (resumeError) {
|
|
81045
|
+
resumeAbortRelay?.cleanup();
|
|
81046
|
+
throw resumeError;
|
|
81047
|
+
}
|
|
80827
81048
|
} catch (resumeError) {
|
|
80828
81049
|
if (abortSignal?.aborted) {
|
|
80829
81050
|
throw new Error("Cancelled by user");
|
|
@@ -80853,6 +81074,7 @@ var init_send = __esm(async () => {
|
|
|
80853
81074
|
init_errorFormatter();
|
|
80854
81075
|
init_diffPreview();
|
|
80855
81076
|
init_interactivePolicy();
|
|
81077
|
+
init_streamAbortRelay();
|
|
80856
81078
|
init_constants2();
|
|
80857
81079
|
init_cwd();
|
|
80858
81080
|
init_permissionMode();
|
|
@@ -83697,6 +83919,19 @@ function runDetachedListenerTask(commandName, task2) {
|
|
|
83697
83919
|
}
|
|
83698
83920
|
});
|
|
83699
83921
|
}
|
|
83922
|
+
async function replaySyncStateForRuntime(listenerRuntime, socket, scope, opts) {
|
|
83923
|
+
const syncScopedRuntime = getOrCreateScopedRuntime(listenerRuntime, scope.agent_id, scope.conversation_id);
|
|
83924
|
+
const recoverFn = opts?.recoverApprovalStateForSync ?? recoverApprovalStateForSync;
|
|
83925
|
+
try {
|
|
83926
|
+
await recoverFn(syncScopedRuntime, scope);
|
|
83927
|
+
} catch (error) {
|
|
83928
|
+
trackListenerError("listener_sync_recovery_failed", error, "listener_sync_recovery");
|
|
83929
|
+
if (isDebugEnabled()) {
|
|
83930
|
+
console.warn("[Listen] Sync approval recovery failed:", error);
|
|
83931
|
+
}
|
|
83932
|
+
}
|
|
83933
|
+
emitStateSync(socket, listenerRuntime, scope);
|
|
83934
|
+
}
|
|
83700
83935
|
function getParsedRuntimeScope(parsed) {
|
|
83701
83936
|
if (!parsed || typeof parsed !== "object" || !("runtime" in parsed)) {
|
|
83702
83937
|
return null;
|
|
@@ -83727,7 +83962,7 @@ function handleModeChange(msg, socket, runtime, scope) {
|
|
|
83727
83962
|
current.modeBeforePlan = null;
|
|
83728
83963
|
}
|
|
83729
83964
|
persistPermissionModeMapForRuntime(runtime);
|
|
83730
|
-
|
|
83965
|
+
emitRuntimeStateUpdates(runtime, scope);
|
|
83731
83966
|
if (isDebugEnabled()) {
|
|
83732
83967
|
console.log(`[Listen] Mode changed to: ${msg.mode}`);
|
|
83733
83968
|
}
|
|
@@ -84089,7 +84324,7 @@ async function handleSkillCommand(parsed, socket) {
|
|
|
84089
84324
|
existsSync: existsSync22,
|
|
84090
84325
|
lstatSync: lstatSync2,
|
|
84091
84326
|
mkdirSync: mkdirSync15,
|
|
84092
|
-
rmdirSync
|
|
84327
|
+
rmdirSync,
|
|
84093
84328
|
symlinkSync,
|
|
84094
84329
|
unlinkSync: unlinkSync8
|
|
84095
84330
|
} = await import("node:fs");
|
|
@@ -84124,7 +84359,7 @@ async function handleSkillCommand(parsed, socket) {
|
|
|
84124
84359
|
const stat6 = lstatSync2(linkPath);
|
|
84125
84360
|
if (stat6.isSymbolicLink()) {
|
|
84126
84361
|
if (process.platform === "win32") {
|
|
84127
|
-
|
|
84362
|
+
rmdirSync(linkPath);
|
|
84128
84363
|
} else {
|
|
84129
84364
|
unlinkSync8(linkPath);
|
|
84130
84365
|
}
|
|
@@ -84182,7 +84417,7 @@ async function handleSkillCommand(parsed, socket) {
|
|
|
84182
84417
|
return true;
|
|
84183
84418
|
}
|
|
84184
84419
|
if (process.platform === "win32") {
|
|
84185
|
-
|
|
84420
|
+
rmdirSync(linkPath);
|
|
84186
84421
|
} else {
|
|
84187
84422
|
unlinkSync8(linkPath);
|
|
84188
84423
|
}
|
|
@@ -84832,9 +85067,7 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
|
|
|
84832
85067
|
console.log(`[Listen V2] Dropping sync: runtime mismatch or closed`);
|
|
84833
85068
|
return;
|
|
84834
85069
|
}
|
|
84835
|
-
|
|
84836
|
-
await recoverApprovalStateForSync(syncScopedRuntime, parsed.runtime);
|
|
84837
|
-
emitStateSync(socket, runtime, parsed.runtime);
|
|
85070
|
+
await replaySyncStateForRuntime(runtime, socket, parsed.runtime);
|
|
84838
85071
|
return;
|
|
84839
85072
|
}
|
|
84840
85073
|
if (parsed.type === "input") {
|
|
@@ -85749,6 +85982,7 @@ var init_client4 = __esm(async () => {
|
|
|
85749
85982
|
__listenClientTestUtils = {
|
|
85750
85983
|
createRuntime: createLegacyTestRuntime,
|
|
85751
85984
|
createListenerRuntime: createRuntime,
|
|
85985
|
+
handleModeChange,
|
|
85752
85986
|
getOrCreateScopedRuntime,
|
|
85753
85987
|
buildListModelsEntries,
|
|
85754
85988
|
buildListModelsResponse,
|
|
@@ -85798,6 +86032,7 @@ var init_client4 = __esm(async () => {
|
|
|
85798
86032
|
handleCreateAgentCommand,
|
|
85799
86033
|
handleReflectionSettingsCommand,
|
|
85800
86034
|
scheduleQueuePump,
|
|
86035
|
+
replaySyncStateForRuntime,
|
|
85801
86036
|
recoverApprovalStateForSync,
|
|
85802
86037
|
clearRecoveredApprovalStateForScope: (runtime, scope) => clearRecoveredApprovalStateForScope(asListenerRuntimeForTests(runtime), scope),
|
|
85803
86038
|
emitStateSync
|
|
@@ -119988,7 +120223,7 @@ import {
|
|
|
119988
120223
|
mkdirSync as mkdirSync22,
|
|
119989
120224
|
mkdtempSync,
|
|
119990
120225
|
readFileSync as readFileSync18,
|
|
119991
|
-
rmSync as
|
|
120226
|
+
rmSync as rmSync4,
|
|
119992
120227
|
writeFileSync as writeFileSync16
|
|
119993
120228
|
} from "node:fs";
|
|
119994
120229
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
@@ -120371,7 +120606,7 @@ async function installGithubApp(options) {
|
|
|
120371
120606
|
agentUrl: resolvedAgentId ? buildChatUrl(resolvedAgentId) : null
|
|
120372
120607
|
};
|
|
120373
120608
|
} finally {
|
|
120374
|
-
|
|
120609
|
+
rmSync4(tempDir, { recursive: true, force: true });
|
|
120375
120610
|
}
|
|
120376
120611
|
}
|
|
120377
120612
|
var DEFAULT_WORKFLOW_PATH = ".github/workflows/letta.yml", ALTERNATE_WORKFLOW_PATH = ".github/workflows/letta-code.yml";
|
|
@@ -149303,7 +149538,7 @@ async function runListenSubcommand(argv) {
|
|
|
149303
149538
|
|
|
149304
149539
|
// src/cli/subcommands/memfs.ts
|
|
149305
149540
|
await init_memoryGit();
|
|
149306
|
-
import { cpSync, existsSync as existsSync22, mkdirSync as mkdirSync15, rmSync as
|
|
149541
|
+
import { cpSync, existsSync as existsSync22, mkdirSync as mkdirSync15, rmSync as rmSync3, statSync as statSync8 } from "node:fs";
|
|
149307
149542
|
import { readdir as readdir6 } from "node:fs/promises";
|
|
149308
149543
|
import { homedir as homedir23 } from "node:os";
|
|
149309
149544
|
import { join as join28 } from "node:path";
|
|
@@ -149496,7 +149731,7 @@ async function runMemfsSubcommand(argv) {
|
|
|
149496
149731
|
return 1;
|
|
149497
149732
|
}
|
|
149498
149733
|
const root = getMemoryRoot(agentId);
|
|
149499
|
-
|
|
149734
|
+
rmSync3(root, { recursive: true, force: true });
|
|
149500
149735
|
cpSync(backupPath, root, { recursive: true });
|
|
149501
149736
|
console.log(JSON.stringify({ restoredFrom: backupPath }, null, 2));
|
|
149502
149737
|
return 0;
|
|
@@ -153311,4 +153546,4 @@ Error during initialization: ${message}`);
|
|
|
153311
153546
|
}
|
|
153312
153547
|
main();
|
|
153313
153548
|
|
|
153314
|
-
//# debugId=
|
|
153549
|
+
//# debugId=DEDBAA251791817164756E2164756E21
|