@letta-ai/letta-code 0.29.10 → 0.29.11
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 +148 -72
- package/package.json +1 -1
- package/scripts/source-file-size-baseline.json +3 -3
package/letta.js
CHANGED
|
@@ -5462,7 +5462,7 @@ var package_default;
|
|
|
5462
5462
|
var init_package = __esm(() => {
|
|
5463
5463
|
package_default = {
|
|
5464
5464
|
name: "@letta-ai/letta-code",
|
|
5465
|
-
version: "0.29.
|
|
5465
|
+
version: "0.29.11",
|
|
5466
5466
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
5467
5467
|
type: "module",
|
|
5468
5468
|
packageManager: "bun@1.3.0",
|
|
@@ -173413,7 +173413,7 @@ function socketForTransport(transport) {
|
|
|
173413
173413
|
function refreshLegacySingleConnection(runtime) {
|
|
173414
173414
|
const live = [...runtime.connections.values()].filter((connection) => isListenerTransportOpen(connection.writer));
|
|
173415
173415
|
const only = live.length === 1 ? live[0] : null;
|
|
173416
|
-
runtime.transport = only?.writer ??
|
|
173416
|
+
runtime.transport = runtime.processTransport ?? only?.writer ?? null;
|
|
173417
173417
|
runtime.streamTransport = only?.streamWriter ?? null;
|
|
173418
173418
|
runtime.socket = only ? socketForTransport(only.writer) : null;
|
|
173419
173419
|
runtime.streamSocket = only?.streamWriter ? socketForTransport(only.streamWriter) : null;
|
|
@@ -173617,9 +173617,7 @@ class ProcessRuntimeTransport {
|
|
|
173617
173617
|
}
|
|
173618
173618
|
function getOrCreateProcessTransport(runtime) {
|
|
173619
173619
|
runtime.processTransport ??= new ProcessRuntimeTransport(runtime);
|
|
173620
|
-
|
|
173621
|
-
refreshLegacySingleConnection(runtime);
|
|
173622
|
-
}
|
|
173620
|
+
refreshLegacySingleConnection(runtime);
|
|
173623
173621
|
return runtime.processTransport;
|
|
173624
173622
|
}
|
|
173625
173623
|
var TO_SUBSCRIBERS, BROADCAST, resumeStateByRuntime;
|
|
@@ -174044,12 +174042,6 @@ var init_channel_turn_session = __esm(() => {
|
|
|
174044
174042
|
});
|
|
174045
174043
|
|
|
174046
174044
|
// src/websocket/listener/constants.ts
|
|
174047
|
-
function isListenerPongStale(lastPongAt, now, timeoutMs) {
|
|
174048
|
-
if (lastPongAt === null) {
|
|
174049
|
-
return false;
|
|
174050
|
-
}
|
|
174051
|
-
return now - lastPongAt > timeoutMs;
|
|
174052
|
-
}
|
|
174053
174045
|
var MAX_RETRY_DURATION_MS, INITIAL_RETRY_DELAY_MS2 = 1000, MAX_RETRY_DELAY_MS = 30000, LISTENER_HEARTBEAT_INTERVAL_MS = 30000, LISTENER_PONG_TIMEOUT_MS = 90000, SYSTEM_REMINDER_RE, LLM_API_ERROR_MAX_RETRIES = 3, EMPTY_RESPONSE_MAX_RETRIES = 2, MAX_PRE_STREAM_RECOVERY = 2, MAX_POST_STOP_APPROVAL_RECOVERY = 2, PROVIDER_FALLBACK_MAP, PROVIDER_FALLBACK_NOTICE = "Anthropic API error; falling back to Bedrock...";
|
|
174054
174046
|
var init_constants3 = __esm(() => {
|
|
174055
174047
|
MAX_RETRY_DURATION_MS = 5 * 60 * 1000;
|
|
@@ -382751,6 +382743,7 @@ var init_backend2 = __esm(() => {
|
|
|
382751
382743
|
var exports_check_approval = {};
|
|
382752
382744
|
__export(exports_check_approval, {
|
|
382753
382745
|
prepareMessageHistory: () => prepareMessageHistory,
|
|
382746
|
+
isResumedConversation: () => isResumedConversation,
|
|
382754
382747
|
getResumeDataFromBackend: () => getResumeDataFromBackend,
|
|
382755
382748
|
extractApprovals: () => extractApprovals
|
|
382756
382749
|
});
|
|
@@ -382758,6 +382751,11 @@ function isBackfillEnabled() {
|
|
|
382758
382751
|
const val = process.env.LETTA_BACKFILL;
|
|
382759
382752
|
return val !== "0" && val !== "false";
|
|
382760
382753
|
}
|
|
382754
|
+
function isResumedConversation(conversation) {
|
|
382755
|
+
if (!conversation)
|
|
382756
|
+
return true;
|
|
382757
|
+
return Boolean(conversation.summary?.trim() || (conversation.in_context_message_ids?.length ?? 0) > 0);
|
|
382758
|
+
}
|
|
382761
382759
|
function approvalRequestsFromMessage(messageToCheck) {
|
|
382762
382760
|
const approvalMsg = messageToCheck;
|
|
382763
382761
|
const toolCalls = Array.isArray(approvalMsg.tool_calls) ? approvalMsg.tool_calls : approvalMsg.tool_call ? [approvalMsg.tool_call] : [];
|
|
@@ -383011,17 +383009,19 @@ async function getResumeDataFromBackend(agent2, conversationId, options3 = {}) {
|
|
|
383011
383009
|
let inContextMessageIds;
|
|
383012
383010
|
let messages = [];
|
|
383013
383011
|
if (useConversationsApi) {
|
|
383012
|
+
let conversation;
|
|
383014
383013
|
if (shouldFetchTail) {
|
|
383015
383014
|
try {
|
|
383016
383015
|
const tail = await fetchResumeTail(agent2.id, activeConversationId);
|
|
383017
383016
|
messages = tail.messages;
|
|
383018
|
-
|
|
383017
|
+
conversation = tail.conversation;
|
|
383018
|
+
inContextMessageIds = conversation?.in_context_message_ids;
|
|
383019
383019
|
} catch (backfillError) {
|
|
383020
383020
|
debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
|
|
383021
383021
|
}
|
|
383022
383022
|
}
|
|
383023
|
-
if (!
|
|
383024
|
-
|
|
383023
|
+
if (!conversation) {
|
|
383024
|
+
conversation = await getBackend().retrieveConversation(activeConversationId);
|
|
383025
383025
|
inContextMessageIds = conversation.in_context_message_ids;
|
|
383026
383026
|
}
|
|
383027
383027
|
const lastInContextId2 = inContextMessageIds?.at(-1);
|
|
@@ -383030,14 +383030,16 @@ async function getResumeDataFromBackend(agent2, conversationId, options3 = {}) {
|
|
|
383030
383030
|
return {
|
|
383031
383031
|
pendingApproval: null,
|
|
383032
383032
|
pendingApprovals: [],
|
|
383033
|
-
messageHistory: prepareMessageHistory(messages)
|
|
383033
|
+
messageHistory: prepareMessageHistory(messages),
|
|
383034
|
+
conversation
|
|
383034
383035
|
};
|
|
383035
383036
|
}
|
|
383036
383037
|
const { pendingApproval: pendingApproval2, pendingApprovals: pendingApprovals2 } = await pendingApprovalsFromTailOrRetrieve(messages, lastInContextId2);
|
|
383037
383038
|
return {
|
|
383038
383039
|
pendingApproval: pendingApproval2,
|
|
383039
383040
|
pendingApprovals: pendingApprovals2,
|
|
383040
|
-
messageHistory: prepareMessageHistory(messages)
|
|
383041
|
+
messageHistory: prepareMessageHistory(messages),
|
|
383042
|
+
conversation
|
|
383041
383043
|
};
|
|
383042
383044
|
}
|
|
383043
383045
|
inContextMessageIds = agentWithInContext.in_context_message_ids ?? agent2.message_ids;
|
|
@@ -436549,7 +436551,7 @@ function scheduleQueuePump(runtime, socket, opts, processQueuedTurn) {
|
|
|
436549
436551
|
runtime.queuePumpScheduled = true;
|
|
436550
436552
|
runtime.messageQueue = runtime.messageQueue.then(async () => {
|
|
436551
436553
|
runtime.queuePumpScheduled = false;
|
|
436552
|
-
if (runtime.listener !== getActiveRuntime() || runtime.listener.intentionallyClosed) {
|
|
436554
|
+
if (runtime.listener !== getActiveRuntime() || runtime.listener.intentionallyClosed || !isListenerTransportOpen(socket)) {
|
|
436553
436555
|
return;
|
|
436554
436556
|
}
|
|
436555
436557
|
await drainQueuedMessages(runtime, socket, opts, processQueuedTurn);
|
|
@@ -436572,6 +436574,7 @@ var init_queue = __esm(async () => {
|
|
|
436572
436574
|
init_error_reporting();
|
|
436573
436575
|
init_channel_turn_session();
|
|
436574
436576
|
init_runtime6();
|
|
436577
|
+
init_transport();
|
|
436575
436578
|
await __promiseAll([
|
|
436576
436579
|
init_image_policy(),
|
|
436577
436580
|
init_protocol_outbound()
|
|
@@ -446311,6 +446314,9 @@ function replayPendingApprovalRequestsToConnection(runtime, connectionId) {
|
|
|
446311
446314
|
}
|
|
446312
446315
|
}
|
|
446313
446316
|
function requestApprovalOverWS(runtime, socket, turnLease, requestId, controlRequest) {
|
|
446317
|
+
if (runtime.listener.intentionallyClosed) {
|
|
446318
|
+
return Promise.reject(new Error("Listener runtime stopped"));
|
|
446319
|
+
}
|
|
446314
446320
|
const scope = {
|
|
446315
446321
|
agent_id: runtime.agentId,
|
|
446316
446322
|
conversation_id: runtime.conversationId
|
|
@@ -446324,9 +446330,6 @@ function requestApprovalOverWS(runtime, socket, turnLease, requestId, controlReq
|
|
|
446324
446330
|
if (connectionIds.size === 0 && runtime.listener.connections.size === 0 && isListenerTransportOpen(socket)) {
|
|
446325
446331
|
connectionIds.add(runtime.listener.connectionId ?? "legacy");
|
|
446326
446332
|
}
|
|
446327
|
-
if (connectionIds.size === 0 && !isListenerTransportOpen(socket) && runtime.listener.connections.size === 0) {
|
|
446328
|
-
return Promise.reject(new Error("WebSocket not open"));
|
|
446329
|
-
}
|
|
446330
446333
|
const abortSignal = turnLease.signal;
|
|
446331
446334
|
const isInterrupted = () => !runtime.turnLifecycle.isCurrent(turnLease) || abortSignal.aborted;
|
|
446332
446335
|
if (isInterrupted()) {
|
|
@@ -457883,6 +457886,18 @@ function resolveChannelApprovalSource(runtime) {
|
|
|
457883
457886
|
}
|
|
457884
457887
|
return [...sourcesByScope.values()].at(-1) ?? null;
|
|
457885
457888
|
}
|
|
457889
|
+
async function waitForApprovalTransportOpen(socket, shouldInterrupt) {
|
|
457890
|
+
if (isListenerTransportOpen(socket)) {
|
|
457891
|
+
return "open";
|
|
457892
|
+
}
|
|
457893
|
+
while (!shouldInterrupt()) {
|
|
457894
|
+
await new Promise((resolve31) => setTimeout(resolve31, APPROVAL_TRANSPORT_REOPEN_POLL_MS));
|
|
457895
|
+
if (isListenerTransportOpen(socket)) {
|
|
457896
|
+
return "open";
|
|
457897
|
+
}
|
|
457898
|
+
}
|
|
457899
|
+
return "interrupted";
|
|
457900
|
+
}
|
|
457886
457901
|
async function handleApprovalStop(params) {
|
|
457887
457902
|
const {
|
|
457888
457903
|
approvals,
|
|
@@ -457906,6 +457921,8 @@ async function handleApprovalStop(params) {
|
|
|
457906
457921
|
const classifyApprovals2 = dependencies4?.classifyApprovals ?? classifyApprovalsWithSuggestions;
|
|
457907
457922
|
const executeApprovals = dependencies4?.executeApprovalBatch ?? executeApprovalBatch;
|
|
457908
457923
|
const ensureSecretsHydrated = dependencies4?.ensureSecretsHydrated ?? ensureSecretsHydratedForAgent;
|
|
457924
|
+
const sendApprovalContinuation = dependencies4?.sendApprovalContinuation ?? sendApprovalContinuationWithRetry;
|
|
457925
|
+
const waitForTransportOpen = dependencies4?.waitForApprovalTransportOpen ?? waitForApprovalTransportOpen;
|
|
457909
457926
|
if (approvals.length === 0) {
|
|
457910
457927
|
return {
|
|
457911
457928
|
kind: "error",
|
|
@@ -458077,6 +458094,17 @@ async function handleApprovalStop(params) {
|
|
|
458077
458094
|
return interruptTermination();
|
|
458078
458095
|
}
|
|
458079
458096
|
const approvedDecisions = decisions.filter((decision) => decision.type === "approve");
|
|
458097
|
+
const executionRunId = runId || runtime.activeRunId || msgRunIds[msgRunIds.length - 1];
|
|
458098
|
+
let persistedExecutionResults;
|
|
458099
|
+
if (approvedDecisions.length > 0 && !isListenerTransportOpen(socket)) {
|
|
458100
|
+
const transportOpenResult = await waitForTransportOpen(socket, shouldInterrupt);
|
|
458101
|
+
if (transportOpenResult === "interrupted") {
|
|
458102
|
+
return interruptTermination();
|
|
458103
|
+
}
|
|
458104
|
+
}
|
|
458105
|
+
if (shouldInterrupt()) {
|
|
458106
|
+
return interruptTermination();
|
|
458107
|
+
}
|
|
458080
458108
|
lastExecutingToolCallIds = approvedDecisions.map((decision) => decision.approval.toolCallId);
|
|
458081
458109
|
runtime.turnLifecycle.setExecutingToolCallIds(turnLease, lastExecutingToolCallIds);
|
|
458082
458110
|
setTurnLoopStatus(runtime, turnLease, "EXECUTING_CLIENT_SIDE_TOOL", {
|
|
@@ -458087,7 +458115,6 @@ async function handleApprovalStop(params) {
|
|
|
458087
458115
|
agent_id: agentId,
|
|
458088
458116
|
conversation_id: conversationId
|
|
458089
458117
|
});
|
|
458090
|
-
const executionRunId = runId || runtime.activeRunId || msgRunIds[msgRunIds.length - 1];
|
|
458091
458118
|
emitToolExecutionStartedEvents(socket, runtime, {
|
|
458092
458119
|
toolCalls: approvedDecisions.map((decision) => ({
|
|
458093
458120
|
toolCallId: decision.approval.toolCallId,
|
|
@@ -458156,7 +458183,7 @@ async function handleApprovalStop(params) {
|
|
|
458156
458183
|
if (!runtime.turnLifecycle.isCurrent(turnLease)) {
|
|
458157
458184
|
return interruptTermination();
|
|
458158
458185
|
}
|
|
458159
|
-
|
|
458186
|
+
persistedExecutionResults = normalizeExecutionResultsForInterruptParity(runtime, executionResults, lastExecutingToolCallIds);
|
|
458160
458187
|
validateApprovalResultIds(decisions.map((decision) => ({
|
|
458161
458188
|
approval: {
|
|
458162
458189
|
toolCallId: decision.approval.toolCallId
|
|
@@ -458201,7 +458228,7 @@ async function handleApprovalStop(params) {
|
|
|
458201
458228
|
try {
|
|
458202
458229
|
const sendOptions = buildSendOptions() ?? {};
|
|
458203
458230
|
const imageFailureModesByMessageOtid = mergeImageFailureModesByMessageOtid(sendOptions.imageFailureModesByMessageOtid, nextTurnInput.imageFailureModesByMessageOtid);
|
|
458204
|
-
sendResult = await
|
|
458231
|
+
sendResult = await sendApprovalContinuation(conversationId, nextInputWithSkillContent, {
|
|
458205
458232
|
...sendOptions,
|
|
458206
458233
|
...imageFailureModesByMessageOtid ? { imageFailureModesByMessageOtid } : {},
|
|
458207
458234
|
...continuationWasFullyAutoHandled ? { allowResponseStateReuse: true } : {}
|
|
@@ -458261,6 +458288,7 @@ async function handleApprovalStop(params) {
|
|
|
458261
458288
|
lastApprovalContinuationAccepted: true
|
|
458262
458289
|
};
|
|
458263
458290
|
}
|
|
458291
|
+
var APPROVAL_TRANSPORT_REOPEN_POLL_MS = 50;
|
|
458264
458292
|
var init_turn_approval = __esm(async () => {
|
|
458265
458293
|
init_registry();
|
|
458266
458294
|
init_diff_preview();
|
|
@@ -458269,6 +458297,7 @@ var init_turn_approval = __esm(async () => {
|
|
|
458269
458297
|
init_connection();
|
|
458270
458298
|
init_secrets_sync();
|
|
458271
458299
|
init_skill_injection();
|
|
458300
|
+
init_transport();
|
|
458272
458301
|
init_turn_input_state();
|
|
458273
458302
|
await __promiseAll([
|
|
458274
458303
|
init_approval_execution(),
|
|
@@ -462247,7 +462276,7 @@ function createConnectionTurnProcessor(runtime) {
|
|
|
462247
462276
|
if (!connection || connection.cancellation.signal.aborted) {
|
|
462248
462277
|
return;
|
|
462249
462278
|
}
|
|
462250
|
-
await handleIncomingMessage(queuedTurn,
|
|
462279
|
+
await handleIncomingMessage(queuedTurn, getOrCreateProcessTransport(runtime), scopedRuntime, connection.options.onStatusChange, connection.id, dequeuedBatch.batchId);
|
|
462251
462280
|
};
|
|
462252
462281
|
}
|
|
462253
462282
|
function cleanupListenerConnection(runtime, connectionId) {
|
|
@@ -463223,6 +463252,43 @@ var init_file_commands = __esm(async () => {
|
|
|
463223
463252
|
ignoreConfigCache = new Map;
|
|
463224
463253
|
});
|
|
463225
463254
|
|
|
463255
|
+
// src/websocket/listener/heartbeat.ts
|
|
463256
|
+
function createMissedPongWatchdog(maxUnansweredPings) {
|
|
463257
|
+
let lastPingAt = null;
|
|
463258
|
+
let unansweredPings = 0;
|
|
463259
|
+
return {
|
|
463260
|
+
shouldTerminate(lastPongAt) {
|
|
463261
|
+
if (lastPingAt !== null && lastPongAt !== null && lastPongAt >= lastPingAt) {
|
|
463262
|
+
unansweredPings = 0;
|
|
463263
|
+
}
|
|
463264
|
+
return unansweredPings >= maxUnansweredPings;
|
|
463265
|
+
},
|
|
463266
|
+
recordPing(sentAt) {
|
|
463267
|
+
lastPingAt = sentAt;
|
|
463268
|
+
unansweredPings += 1;
|
|
463269
|
+
}
|
|
463270
|
+
};
|
|
463271
|
+
}
|
|
463272
|
+
function startConnectionHeartbeat(runtime, transport, onStale, sendPing) {
|
|
463273
|
+
runtime.lastPongAt = Date.now();
|
|
463274
|
+
const maxUnansweredPings = Math.max(1, Math.ceil(LISTENER_PONG_TIMEOUT_MS / LISTENER_HEARTBEAT_INTERVAL_MS));
|
|
463275
|
+
const watchdog = createMissedPongWatchdog(maxUnansweredPings);
|
|
463276
|
+
runtime.heartbeatInterval = setInterval(() => {
|
|
463277
|
+
if (getListenerTransportKind(transport) === "websocket" && watchdog.shouldTerminate(runtime.lastPongAt)) {
|
|
463278
|
+
onStale();
|
|
463279
|
+
return;
|
|
463280
|
+
}
|
|
463281
|
+
const sentAt = Date.now();
|
|
463282
|
+
if (sendPing()) {
|
|
463283
|
+
watchdog.recordPing(sentAt);
|
|
463284
|
+
}
|
|
463285
|
+
}, LISTENER_HEARTBEAT_INTERVAL_MS);
|
|
463286
|
+
}
|
|
463287
|
+
var init_heartbeat = __esm(() => {
|
|
463288
|
+
init_constants3();
|
|
463289
|
+
init_transport();
|
|
463290
|
+
});
|
|
463291
|
+
|
|
463226
463292
|
// src/types/app-server-info.ts
|
|
463227
463293
|
var APP_SERVER_PROTOCOL_VERSION = 1;
|
|
463228
463294
|
|
|
@@ -465290,10 +465356,13 @@ function getParsedRuntimeScope(parsed) {
|
|
|
465290
465356
|
conversation_id: typeof runtime.conversation_id === "string" ? runtime.conversation_id : "default"
|
|
465291
465357
|
};
|
|
465292
465358
|
}
|
|
465293
|
-
function terminateControlAfterStreamClose(runtime, streamSocket) {
|
|
465359
|
+
function terminateControlAfterStreamClose(runtime, streamSocket, code2, reason) {
|
|
465294
465360
|
if (runtime.streamSocket !== streamSocket) {
|
|
465295
465361
|
return;
|
|
465296
465362
|
}
|
|
465363
|
+
if (code2 === 1000 && reason.toString() === "Replaced by new connection") {
|
|
465364
|
+
runtime.intentionallyClosed = true;
|
|
465365
|
+
}
|
|
465297
465366
|
runtime.streamSocket = null;
|
|
465298
465367
|
runtime.streamTransport = null;
|
|
465299
465368
|
const controlSocket = runtime.socket;
|
|
@@ -465702,6 +465771,23 @@ async function startConnectedListenerRuntime(runtime, transport, opts, processQu
|
|
|
465702
465771
|
runtime.everConnected = true;
|
|
465703
465772
|
opts.onConnected(opts.connectionId);
|
|
465704
465773
|
emitInitialConnectionState(runtime, transport, opts.connectionId, options3);
|
|
465774
|
+
for (const conversationRuntime of runtime.conversationRuntimes.values()) {
|
|
465775
|
+
replayPendingApprovalRequestsToConnection(conversationRuntime, opts.connectionId);
|
|
465776
|
+
}
|
|
465777
|
+
if (shouldStartHeartbeat) {
|
|
465778
|
+
startConnectionHeartbeat(runtime, transport, () => {
|
|
465779
|
+
trackListenerError4("listener_pong_timeout", new Error(`No relay pong within ${LISTENER_PONG_TIMEOUT_MS}ms; terminating half-open socket to force reconnect`), "listener_heartbeat");
|
|
465780
|
+
runtime.socket?.terminate();
|
|
465781
|
+
}, () => {
|
|
465782
|
+
return safeTransportSend(transport, { type: "ping" }, "listener_ping_send_failed", "listener_heartbeat");
|
|
465783
|
+
});
|
|
465784
|
+
}
|
|
465785
|
+
const processTransport = getOrCreateProcessTransport(runtime);
|
|
465786
|
+
for (const conversationRuntime of runtime.conversationRuntimes.values()) {
|
|
465787
|
+
if (conversationRuntime.queueRuntime?.isEmpty === false) {
|
|
465788
|
+
scheduleQueuePump(conversationRuntime, processTransport, opts, processQueuedTurn);
|
|
465789
|
+
}
|
|
465790
|
+
}
|
|
465705
465791
|
if (runtime.processServicesStarted) {
|
|
465706
465792
|
return;
|
|
465707
465793
|
}
|
|
@@ -465710,28 +465796,17 @@ async function startConnectedListenerRuntime(runtime, transport, opts, processQu
|
|
|
465710
465796
|
const processServicesGeneration = runtime.processServicesGeneration + 1;
|
|
465711
465797
|
runtime.processServicesGeneration = processServicesGeneration;
|
|
465712
465798
|
const processServicesReady = (async () => {
|
|
465713
|
-
const
|
|
465799
|
+
const processTransport2 = getOrCreateProcessTransport(runtime);
|
|
465714
465800
|
installProcessEventRouting({
|
|
465715
465801
|
runtime,
|
|
465716
|
-
processTransport,
|
|
465802
|
+
processTransport: processTransport2,
|
|
465717
465803
|
opts,
|
|
465718
465804
|
processQueuedTurn
|
|
465719
465805
|
});
|
|
465720
|
-
if (shouldStartHeartbeat) {
|
|
465721
|
-
runtime.lastPongAt = Date.now();
|
|
465722
|
-
runtime.heartbeatInterval = setInterval(() => {
|
|
465723
|
-
if (getListenerTransportKind(transport) === "websocket" && isListenerPongStale(runtime.lastPongAt, Date.now(), LISTENER_PONG_TIMEOUT_MS)) {
|
|
465724
|
-
trackListenerError4("listener_pong_timeout", new Error(`No relay pong within ${LISTENER_PONG_TIMEOUT_MS}ms; terminating half-open socket to force reconnect`), "listener_heartbeat");
|
|
465725
|
-
runtime.socket?.terminate();
|
|
465726
|
-
return;
|
|
465727
|
-
}
|
|
465728
|
-
safeTransportSend(transport, { type: "ping" }, "listener_ping_send_failed", "listener_heartbeat");
|
|
465729
|
-
}, LISTENER_HEARTBEAT_INTERVAL_MS);
|
|
465730
|
-
}
|
|
465731
465806
|
if (shouldStartCronScheduler) {
|
|
465732
|
-
startScheduler(
|
|
465807
|
+
startScheduler(processTransport2, opts, processQueuedTurn);
|
|
465733
465808
|
}
|
|
465734
|
-
await (options3.wireChannelIngress ?? wireChannelIngress)(runtime,
|
|
465809
|
+
await (options3.wireChannelIngress ?? wireChannelIngress)(runtime, processTransport2, opts, processQueuedTurn);
|
|
465735
465810
|
if (runtime.processServicesGeneration === processServicesGeneration) {
|
|
465736
465811
|
runtime.processServicesStarted = true;
|
|
465737
465812
|
}
|
|
@@ -465838,7 +465913,7 @@ async function attachOpenListenerSocket(runtime, socket, opts, options3 = {}) {
|
|
|
465838
465913
|
if (isDebugEnabled()) {
|
|
465839
465914
|
console.log(`[Listen] Stream WebSocket closed (code: ${code2}, reason: ${reason.toString()})`);
|
|
465840
465915
|
}
|
|
465841
|
-
terminateControlAfterStreamClose(runtime, streamSocket);
|
|
465916
|
+
terminateControlAfterStreamClose(runtime, streamSocket, code2, reason);
|
|
465842
465917
|
});
|
|
465843
465918
|
}
|
|
465844
465919
|
await options3.startupReady;
|
|
@@ -466021,20 +466096,17 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
|
|
|
466021
466096
|
reason: reason.toString()
|
|
466022
466097
|
});
|
|
466023
466098
|
fileCommandSession.dispose();
|
|
466024
|
-
|
|
466025
|
-
const
|
|
466026
|
-
|
|
466027
|
-
channelRegistry.pause();
|
|
466028
|
-
}
|
|
466029
|
-
for (const conversationRuntime of runtime.conversationRuntimes.values()) {
|
|
466030
|
-
conversationRuntime.queuedMessagesByItemId.clear();
|
|
466031
|
-
if (conversationRuntime.queueRuntime) {
|
|
466032
|
-
conversationRuntime.queueRuntime.clear("shutdown");
|
|
466033
|
-
}
|
|
466034
|
-
}
|
|
466099
|
+
const reasonText = reason.toString();
|
|
466100
|
+
const terminalClose = runtime.intentionallyClosed || code2 === 1008 || code2 === 1000 && reasonText === "Replaced by new connection";
|
|
466101
|
+
clearRuntimeTimers(runtime);
|
|
466035
466102
|
if (isDebugEnabled()) {
|
|
466036
466103
|
console.log(`[Listen] WebSocket disconnected (code: ${code2}, reason: ${reason.toString()})`);
|
|
466037
466104
|
}
|
|
466105
|
+
if (!terminalClose) {
|
|
466106
|
+
for (const conversationRuntime of runtime.conversationRuntimes.values()) {
|
|
466107
|
+
rejectPendingApprovalResolversForConnection(conversationRuntime, opts.connectionId, "Listener connection closed");
|
|
466108
|
+
}
|
|
466109
|
+
}
|
|
466038
466110
|
suspendListenerConnection(runtime, opts.connectionId);
|
|
466039
466111
|
killAllTerminals();
|
|
466040
466112
|
clearListenerWarmState(runtime);
|
|
@@ -466047,24 +466119,23 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
|
|
|
466047
466119
|
runtime.socket = null;
|
|
466048
466120
|
runtime.streamSocket = null;
|
|
466049
466121
|
runtime.streamTransport = null;
|
|
466050
|
-
|
|
466051
|
-
|
|
466052
|
-
|
|
466053
|
-
evictConversationRuntimeIfIdle(conversationRuntime);
|
|
466054
|
-
}
|
|
466055
|
-
if (runtime.intentionallyClosed) {
|
|
466056
|
-
opts.onDisconnected();
|
|
466057
|
-
return;
|
|
466058
|
-
}
|
|
466059
|
-
if (code2 === 1008) {
|
|
466060
|
-
if (isDebugEnabled()) {
|
|
466061
|
-
console.log("[Listen] Environment not found, re-registering...");
|
|
466122
|
+
if (terminalClose) {
|
|
466123
|
+
if (getActiveRuntime() === runtime) {
|
|
466124
|
+
setActiveRuntime(null);
|
|
466062
466125
|
}
|
|
466063
|
-
|
|
466064
|
-
|
|
466065
|
-
|
|
466066
|
-
|
|
466126
|
+
stopRuntime(runtime, true);
|
|
466127
|
+
if (code2 === 1008) {
|
|
466128
|
+
if (isDebugEnabled()) {
|
|
466129
|
+
console.log("[Listen] Environment not found, re-registering...");
|
|
466130
|
+
}
|
|
466131
|
+
if (opts.onNeedsReregister) {
|
|
466132
|
+
opts.onNeedsReregister();
|
|
466133
|
+
} else {
|
|
466134
|
+
opts.onDisconnected();
|
|
466135
|
+
}
|
|
466136
|
+
return;
|
|
466067
466137
|
}
|
|
466138
|
+
opts.onDisconnected();
|
|
466068
466139
|
return;
|
|
466069
466140
|
}
|
|
466070
466141
|
const nextAttempt = runtime.hasSuccessfulConnection ? 0 : attempt + 1;
|
|
@@ -466095,7 +466166,7 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
|
|
|
466095
466166
|
if (isDebugEnabled()) {
|
|
466096
466167
|
console.log(`[Listen] Stream WebSocket closed (code: ${code2}, reason: ${reason.toString()})`);
|
|
466097
466168
|
}
|
|
466098
|
-
terminateControlAfterStreamClose(runtime, streamSocket);
|
|
466169
|
+
terminateControlAfterStreamClose(runtime, streamSocket, code2, reason);
|
|
466099
466170
|
});
|
|
466100
466171
|
}
|
|
466101
466172
|
}
|
|
@@ -466128,6 +466199,7 @@ var init_lifecycle = __esm(async () => {
|
|
|
466128
466199
|
init_connection();
|
|
466129
466200
|
init_constants3();
|
|
466130
466201
|
init_cwd();
|
|
466202
|
+
init_heartbeat();
|
|
466131
466203
|
init_permission_mode();
|
|
466132
466204
|
init_runtime6();
|
|
466133
466205
|
init_transport();
|
|
@@ -536552,6 +536624,7 @@ function App2({
|
|
|
536552
536624
|
startupApprovals = [],
|
|
536553
536625
|
messageHistory = [],
|
|
536554
536626
|
resumedExistingConversation = false,
|
|
536627
|
+
startupConversationTitleEligible = false,
|
|
536555
536628
|
tokenStreaming = false,
|
|
536556
536629
|
reasoningTabCycleEnabled: initialReasoningTabCycleEnabled = false,
|
|
536557
536630
|
showCompactions = false,
|
|
@@ -537035,7 +537108,7 @@ function App2({
|
|
|
537035
537108
|
})());
|
|
537036
537109
|
const _systemPromptRecompileByConversationRef = import_react120.useRef(new Map);
|
|
537037
537110
|
const _queuedSystemPromptRecompileByConversationRef = import_react120.useRef(new Set);
|
|
537038
|
-
const shouldAutoGenerateConversationTitleRef = import_react120.useRef(!resumedExistingConversation);
|
|
537111
|
+
const shouldAutoGenerateConversationTitleRef = import_react120.useRef(!resumedExistingConversation || startupConversationTitleEligible);
|
|
537039
537112
|
const isAutoConversationTitleInFlightRef = import_react120.useRef(false);
|
|
537040
537113
|
const shouldAutoGenerateConversationDescriptionRef = import_react120.useRef(!resumedExistingConversation);
|
|
537041
537114
|
const isAutoConversationDescriptionInFlightRef = import_react120.useRef(false);
|
|
@@ -541467,11 +541540,11 @@ Error: ${message}`);
|
|
|
541467
541540
|
}
|
|
541468
541541
|
if (specifiedConversationId) {
|
|
541469
541542
|
conversationIdToUse = specifiedConversationId;
|
|
541470
|
-
setResumedExistingConversation(true);
|
|
541471
541543
|
try {
|
|
541472
541544
|
setLoadingState("checking");
|
|
541473
541545
|
const data = await getResumeDataFromBackend(agent2, specifiedConversationId);
|
|
541474
541546
|
setResumeData(data);
|
|
541547
|
+
setResumedExistingConversation(true);
|
|
541475
541548
|
} catch (error54) {
|
|
541476
541549
|
if (isBackendNotFoundError3(error54)) {
|
|
541477
541550
|
console.error(`Conversation ${specifiedConversationId} not found`);
|
|
@@ -541637,6 +541710,7 @@ Error during initialization: ${message}`);
|
|
|
541637
541710
|
});
|
|
541638
541711
|
}
|
|
541639
541712
|
const appLoadingState = loadingState;
|
|
541713
|
+
const startupConversationTitleEligible = !isResumedConversation(resumeData?.conversation);
|
|
541640
541714
|
if (!agentId || !conversationId) {
|
|
541641
541715
|
return React14.createElement(App3, {
|
|
541642
541716
|
agentId: "loading",
|
|
@@ -541647,6 +541721,7 @@ Error during initialization: ${message}`);
|
|
|
541647
541721
|
startupApprovals: resumeData?.pendingApprovals ?? EMPTY_APPROVAL_ARRAY,
|
|
541648
541722
|
messageHistory: resumeData?.messageHistory ?? EMPTY_MESSAGE_ARRAY,
|
|
541649
541723
|
resumedExistingConversation,
|
|
541724
|
+
startupConversationTitleEligible,
|
|
541650
541725
|
tokenStreaming: settings3.tokenStreaming,
|
|
541651
541726
|
reasoningTabCycleEnabled: settings3.reasoningTabCycleEnabled === true,
|
|
541652
541727
|
showCompactions: settings3.showCompactions,
|
|
@@ -541670,6 +541745,7 @@ Error during initialization: ${message}`);
|
|
|
541670
541745
|
startupApprovals: resumeData?.pendingApprovals ?? EMPTY_APPROVAL_ARRAY,
|
|
541671
541746
|
messageHistory: resumeData?.messageHistory ?? EMPTY_MESSAGE_ARRAY,
|
|
541672
541747
|
resumedExistingConversation,
|
|
541748
|
+
startupConversationTitleEligible,
|
|
541673
541749
|
tokenStreaming: settings3.tokenStreaming,
|
|
541674
541750
|
reasoningTabCycleEnabled: settings3.reasoningTabCycleEnabled === true,
|
|
541675
541751
|
showCompactions: settings3.showCompactions,
|
|
@@ -543363,4 +543439,4 @@ function registerBunOAuthFlows() {
|
|
|
543363
543439
|
registerBunOAuthFlows();
|
|
543364
543440
|
await init_src5().then(() => exports_src2);
|
|
543365
543441
|
|
|
543366
|
-
//# debugId=
|
|
543442
|
+
//# debugId=B4730B9E51AC5C6E64756E2164756E21
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"src/backend/local/local-backend.ts": 1014,
|
|
6
6
|
"src/backend/local/local-store.ts": 3594,
|
|
7
7
|
"src/backend/pi-stream-adapter.test.ts": 1304,
|
|
8
|
-
"src/cli/app/AppCoordinator.tsx":
|
|
8
|
+
"src/cli/app/AppCoordinator.tsx": 5203,
|
|
9
9
|
"src/cli/app/AppView.tsx": 1753,
|
|
10
10
|
"src/cli/app/use-approval-flow.ts": 1163,
|
|
11
11
|
"src/cli/app/use-configuration-handlers.ts": 1433,
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"src/cli/subcommands/skills.ts": 1264,
|
|
25
25
|
"src/headless.ts": 5244,
|
|
26
26
|
"src/hooks/integration.test.ts": 1147,
|
|
27
|
-
"src/index.ts":
|
|
27
|
+
"src/index.ts": 2801,
|
|
28
28
|
"src/mods/learning-harness.ts": 2434,
|
|
29
29
|
"src/mods/mod-engine.test.ts": 2153,
|
|
30
30
|
"src/mods/mod-engine.ts": 1847,
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"src/websocket/listener/commands/channels.ts": 1315,
|
|
48
48
|
"src/websocket/listener/commands/memory.ts": 1114,
|
|
49
49
|
"src/websocket/listener/file-commands.ts": 1030,
|
|
50
|
-
"src/websocket/listener/lifecycle.ts":
|
|
50
|
+
"src/websocket/listener/lifecycle.ts": 1656,
|
|
51
51
|
"src/websocket/listener/protocol-inbound.ts": 2293,
|
|
52
52
|
"src/websocket/listener/protocol-outbound.ts": 1100
|
|
53
53
|
}
|