@letta-ai/letta-code 0.24.3 → 0.24.4
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 +80 -21
- 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.24.
|
|
3272
|
+
version: "0.24.4",
|
|
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: {
|
|
@@ -87563,6 +87563,60 @@ class StreamProcessor {
|
|
|
87563
87563
|
}
|
|
87564
87564
|
|
|
87565
87565
|
// src/cli/helpers/stream.ts
|
|
87566
|
+
function summarizeStreamForDebug(stream2) {
|
|
87567
|
+
if (!stream2 || typeof stream2 !== "object") {
|
|
87568
|
+
return `type=${typeof stream2}`;
|
|
87569
|
+
}
|
|
87570
|
+
const record = stream2;
|
|
87571
|
+
const ctor = stream2.constructor?.name;
|
|
87572
|
+
const controller = record.controller && typeof record.controller === "object" ? record.controller : null;
|
|
87573
|
+
const keys = Object.keys(record).slice(0, 8);
|
|
87574
|
+
return [
|
|
87575
|
+
`ctor=${ctor ?? "unknown"}`,
|
|
87576
|
+
`asyncIterator=${typeof record[Symbol.asyncIterator]}`,
|
|
87577
|
+
`controller=${typeof record.controller}`,
|
|
87578
|
+
`controllerAbort=${typeof controller?.abort}`,
|
|
87579
|
+
`controllerSignal=${typeof controller?.signal}`,
|
|
87580
|
+
keys.length > 0 ? `keys=${keys.join(",")}` : "keys=(none)"
|
|
87581
|
+
].join(" ");
|
|
87582
|
+
}
|
|
87583
|
+
function summarizeChunkForDebug(chunk) {
|
|
87584
|
+
if (!chunk) {
|
|
87585
|
+
return "none";
|
|
87586
|
+
}
|
|
87587
|
+
const record = chunk;
|
|
87588
|
+
const parts = [`message_type=${chunk.message_type ?? "unknown"}`];
|
|
87589
|
+
for (const key of ["run_id", "seq_id", "id", "otid", "tool_call_id"]) {
|
|
87590
|
+
const value = record[key];
|
|
87591
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
87592
|
+
parts.push(`${key}=${value}`);
|
|
87593
|
+
}
|
|
87594
|
+
}
|
|
87595
|
+
if (chunk.message_type === "stop_reason") {
|
|
87596
|
+
parts.push(`stop_reason=${String(record.stop_reason ?? "unknown")}`);
|
|
87597
|
+
}
|
|
87598
|
+
const toolCalls = record.tool_calls;
|
|
87599
|
+
if (Array.isArray(toolCalls)) {
|
|
87600
|
+
parts.push(`tool_calls=${toolCalls.length}`);
|
|
87601
|
+
}
|
|
87602
|
+
return parts.join(" ");
|
|
87603
|
+
}
|
|
87604
|
+
function abortStreamController(stream2, reason) {
|
|
87605
|
+
const controller = stream2.controller;
|
|
87606
|
+
if (!controller || typeof controller !== "object") {
|
|
87607
|
+
debugWarn("drainStream", "stream.controller is unavailable during %s - cannot abort HTTP request (%s)", reason, summarizeStreamForDebug(stream2));
|
|
87608
|
+
return;
|
|
87609
|
+
}
|
|
87610
|
+
const controllerRecord = controller;
|
|
87611
|
+
if (controllerRecord.signal?.aborted) {
|
|
87612
|
+
return;
|
|
87613
|
+
}
|
|
87614
|
+
if (typeof controllerRecord.abort !== "function") {
|
|
87615
|
+
debugWarn("drainStream", "stream.controller.abort is unavailable during %s - cannot abort HTTP request (%s)", reason, summarizeStreamForDebug(stream2));
|
|
87616
|
+
return;
|
|
87617
|
+
}
|
|
87618
|
+
controllerRecord.abort();
|
|
87619
|
+
}
|
|
87566
87620
|
function hasPaginatedItems(response) {
|
|
87567
87621
|
return !Array.isArray(response) && typeof response.getPaginatedItems === "function";
|
|
87568
87622
|
}
|
|
@@ -87640,28 +87694,26 @@ async function drainStream(stream2, buffers, refresh, abortSignal, onFirstMessag
|
|
|
87640
87694
|
let stopReason = null;
|
|
87641
87695
|
let hasCalledFirstMessage = false;
|
|
87642
87696
|
let fallbackError = null;
|
|
87697
|
+
let lastChunkDebugSummary = "none";
|
|
87643
87698
|
let abortedViaListener = false;
|
|
87644
87699
|
const startAbortGen = buffers.abortGeneration || 0;
|
|
87645
87700
|
const abortHandler = () => {
|
|
87646
87701
|
abortedViaListener = true;
|
|
87647
|
-
|
|
87648
|
-
debugWarn("drainStream", "stream.controller is undefined - cannot abort HTTP request");
|
|
87649
|
-
return;
|
|
87650
|
-
}
|
|
87651
|
-
if (!stream2.controller.signal.aborted) {
|
|
87652
|
-
stream2.controller.abort();
|
|
87653
|
-
}
|
|
87702
|
+
abortStreamController(stream2, "abort_signal");
|
|
87654
87703
|
};
|
|
87655
87704
|
if (abortSignal && !abortSignal.aborted) {
|
|
87656
87705
|
abortSignal.addEventListener("abort", abortHandler, { once: true });
|
|
87657
87706
|
} else if (abortSignal?.aborted) {
|
|
87658
87707
|
abortedViaListener = true;
|
|
87659
|
-
|
|
87660
|
-
stream2.controller.abort();
|
|
87661
|
-
}
|
|
87708
|
+
abortStreamController(stream2, "pre_aborted_signal");
|
|
87662
87709
|
}
|
|
87663
87710
|
try {
|
|
87711
|
+
const asyncIterator = stream2[Symbol.asyncIterator];
|
|
87712
|
+
if (typeof asyncIterator !== "function") {
|
|
87713
|
+
throw new TypeError(`Stream is not async iterable (${summarizeStreamForDebug(stream2)})`);
|
|
87714
|
+
}
|
|
87664
87715
|
for await (const chunk of stream2) {
|
|
87716
|
+
lastChunkDebugSummary = summarizeChunkForDebug(chunk);
|
|
87665
87717
|
recordTuiJsonPayload(`stream_chunk:${chunk.message_type ?? "unknown"}`, chunk);
|
|
87666
87718
|
if ((buffers.abortGeneration || 0) !== startAbortGen) {
|
|
87667
87719
|
stopReason = "cancelled";
|
|
@@ -87730,7 +87782,10 @@ async function drainStream(stream2, buffers, refresh, abortSignal, onFirstMessag
|
|
|
87730
87782
|
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
87731
87783
|
const sdkDiagnostic = consumeLastSDKDiagnostic();
|
|
87732
87784
|
const errorMessageWithDiagnostic = sdkDiagnostic ? `${errorMessage} [${sdkDiagnostic}]` : errorMessage;
|
|
87733
|
-
debugWarn("drainStream", "Stream error caught:",
|
|
87785
|
+
debugWarn("drainStream", "Stream error caught: %s last_chunk=%s stream=%s", errorMessageWithDiagnostic, lastChunkDebugSummary, summarizeStreamForDebug(stream2));
|
|
87786
|
+
if (e instanceof Error && e.stack) {
|
|
87787
|
+
debugWarn("drainStream", "Stream error stack: %s", e.stack);
|
|
87788
|
+
}
|
|
87734
87789
|
if (!streamProcessor.lastRunId && e instanceof APIError2 && e.error) {
|
|
87735
87790
|
const errorObj = e.error;
|
|
87736
87791
|
if ("run_id" in errorObj && typeof errorObj.run_id === "string") {
|
|
@@ -95763,7 +95818,7 @@ function isSyncCommand(value) {
|
|
|
95763
95818
|
return false;
|
|
95764
95819
|
}
|
|
95765
95820
|
const candidate = value;
|
|
95766
|
-
return candidate.type === "sync" && isRuntimeScope(candidate.runtime);
|
|
95821
|
+
return candidate.type === "sync" && isRuntimeScope(candidate.runtime) && (candidate.recover_approvals === undefined || typeof candidate.recover_approvals === "boolean");
|
|
95767
95822
|
}
|
|
95768
95823
|
function isTerminalSpawnCommand(value) {
|
|
95769
95824
|
if (!value || typeof value !== "object")
|
|
@@ -96444,12 +96499,14 @@ function runDetachedListenerTask(commandName, task2) {
|
|
|
96444
96499
|
async function replaySyncStateForRuntime(listenerRuntime, socket, scope, opts) {
|
|
96445
96500
|
const syncScopedRuntime = getOrCreateScopedRuntime(listenerRuntime, scope.agent_id, scope.conversation_id);
|
|
96446
96501
|
const recoverFn = opts?.recoverApprovalStateForSync ?? recoverApprovalStateForSync;
|
|
96447
|
-
|
|
96448
|
-
|
|
96449
|
-
|
|
96450
|
-
|
|
96451
|
-
|
|
96452
|
-
|
|
96502
|
+
if (opts?.recoverApprovals ?? true) {
|
|
96503
|
+
try {
|
|
96504
|
+
await recoverFn(syncScopedRuntime, scope);
|
|
96505
|
+
} catch (error) {
|
|
96506
|
+
trackListenerError("listener_sync_recovery_failed", error, "listener_sync_recovery");
|
|
96507
|
+
if (isDebugEnabled()) {
|
|
96508
|
+
console.warn("[Listen] Sync approval recovery failed:", error);
|
|
96509
|
+
}
|
|
96453
96510
|
}
|
|
96454
96511
|
}
|
|
96455
96512
|
emitStateSync(socket, listenerRuntime, scope);
|
|
@@ -98796,7 +98853,9 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
|
|
|
98796
98853
|
console.log(`[Listen V2] Dropping sync: runtime mismatch or closed`);
|
|
98797
98854
|
return;
|
|
98798
98855
|
}
|
|
98799
|
-
await replaySyncStateForRuntime(runtime, socket, parsed.runtime
|
|
98856
|
+
await replaySyncStateForRuntime(runtime, socket, parsed.runtime, {
|
|
98857
|
+
recoverApprovals: parsed.recover_approvals !== false
|
|
98858
|
+
});
|
|
98800
98859
|
return;
|
|
98801
98860
|
}
|
|
98802
98861
|
if (parsed.type === "input") {
|
|
@@ -168653,4 +168712,4 @@ Error during initialization: ${message}`);
|
|
|
168653
168712
|
}
|
|
168654
168713
|
main();
|
|
168655
168714
|
|
|
168656
|
-
//# debugId=
|
|
168715
|
+
//# debugId=A2D8C37B0089C68564756E2164756E21
|