@letta-ai/letta-code 0.34.22 → 0.34.24
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 +2 -2
- package/dist/app-server-client.cjs.map +3 -3
- package/dist/app-server-client.js +2 -2
- package/dist/app-server-client.js.map +3 -3
- package/dist/gateway-core.js +7 -4
- package/dist/gateway-core.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-constraints.d.ts +1 -1
- package/dist/types/agent/turn-recovery-policy.d.ts +3 -3
- package/dist/types/agent/turn-recovery-policy.d.ts.map +1 -1
- package/dist/types/backend/api/schedules.d.ts +4 -3
- package/dist/types/backend/api/schedules.d.ts.map +1 -1
- package/dist/types/backend/api/unified-mcp.d.ts.map +1 -1
- package/dist/types/backend/dev/fake-headless-backend.d.ts +1 -0
- package/dist/types/backend/dev/fake-headless-backend.d.ts.map +1 -1
- package/dist/types/backend/dev/provider-turn-executor.d.ts.map +1 -1
- package/dist/types/backend/local/local-conversation-key.d.ts +6 -0
- package/dist/types/backend/local/local-conversation-key.d.ts.map +1 -0
- package/dist/types/backend/local/local-store.d.ts.map +1 -1
- package/dist/types/channels/control-request-coordinator.d.ts.map +1 -1
- package/dist/types/cli/helpers/git-context.d.ts +5 -2
- package/dist/types/cli/helpers/git-context.d.ts.map +1 -1
- package/dist/types/cron/cron-file.d.ts +2 -3
- package/dist/types/cron/cron-file.d.ts.map +1 -1
- package/dist/types/cron/process-identity.d.ts +9 -0
- package/dist/types/cron/process-identity.d.ts.map +1 -1
- package/dist/types/cron/runner.d.ts +2 -2
- package/dist/types/cron/runner.d.ts.map +1 -1
- package/dist/types/cron/scheduler.d.ts +3 -2
- package/dist/types/cron/scheduler.d.ts.map +1 -1
- package/dist/types/permissions/checker.d.ts +8 -0
- package/dist/types/permissions/checker.d.ts.map +1 -1
- package/dist/types/queue/queue-runtime.d.ts +7 -19
- package/dist/types/queue/queue-runtime.d.ts.map +1 -1
- package/dist/types/tools/impl/external-coding-agent-task.d.ts +9 -0
- package/dist/types/tools/impl/external-coding-agent-task.d.ts.map +1 -1
- package/dist/types/tools/impl/shell-launchers.d.ts.map +1 -1
- package/dist/types/types/app-server-info.d.ts +0 -2
- package/dist/types/types/app-server-info.d.ts.map +1 -1
- package/dist/types/types/protocol.d.ts +2 -3
- package/dist/types/types/protocol.d.ts.map +1 -1
- package/dist/types/types/protocol_v2.d.ts +1 -1
- package/dist/types/types/protocol_v2.d.ts.map +1 -1
- package/dist/types/types/schedule-protocol.d.ts +2 -2
- package/dist/types/types/schedule-protocol.d.ts.map +1 -1
- package/dist/types/utils/rename-sync-with-retry.d.ts +3 -0
- package/dist/types/utils/rename-sync-with-retry.d.ts.map +1 -0
- package/dist/types/websocket/listener/connection.d.ts +2 -0
- package/dist/types/websocket/listener/connection.d.ts.map +1 -1
- package/dist/types/websocket/listener/constants.d.ts +1 -0
- package/dist/types/websocket/listener/constants.d.ts.map +1 -1
- package/dist/types/websocket/listener/device-git-context.d.ts.map +1 -1
- package/dist/types/websocket/listener/interrupted-turn-record.d.ts.map +1 -1
- package/dist/types/websocket/listener/interrupted-turn-storage.d.ts.map +1 -1
- package/dist/types/websocket/listener/queue.d.ts +1 -2
- package/dist/types/websocket/listener/queue.d.ts.map +1 -1
- package/dist/types/websocket/listener/recovery-lineage-sidecar.d.ts.map +1 -1
- package/dist/types/websocket/listener/turn-correlation.d.ts +0 -8
- package/dist/types/websocket/listener/turn-correlation.d.ts.map +1 -1
- package/dist/types/websocket/listener/turn-finished-replay.d.ts.map +1 -1
- package/dist/types/websocket/listener/types.d.ts +14 -1
- package/dist/types/websocket/listener/types.d.ts.map +1 -1
- package/letta.js +840 -598
- package/npm-shrinkwrap.json +2 -2
- package/package.json +7 -4
- package/scripts/build-pypi.py +6 -6
- package/scripts/claude-watch/runtime-probe.test.ts +1 -1
- package/scripts/claude-watch/runtime-sandbox.ts +1 -1
- package/scripts/source-file-size-baseline.json +3 -3
- package/skills/scheduling-tasks/SKILL.md +1 -1
- package/skills/working-across-computers/references/connect-a-computer-for-remote-access.md +2 -2
- package/dist/types/websocket/listener/mcp-originator-scope.d.ts +0 -9
- package/dist/types/websocket/listener/mcp-originator-scope.d.ts.map +0 -1
package/letta.js
CHANGED
|
@@ -5967,7 +5967,7 @@ var package_default;
|
|
|
5967
5967
|
var init_package = __esm(() => {
|
|
5968
5968
|
package_default = {
|
|
5969
5969
|
name: "@letta-ai/letta-code",
|
|
5970
|
-
version: "0.34.
|
|
5970
|
+
version: "0.34.24",
|
|
5971
5971
|
lettaStartupLogProtocol: 1,
|
|
5972
5972
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
5973
5973
|
type: "module",
|
|
@@ -6110,7 +6110,7 @@ var init_package = __esm(() => {
|
|
|
6110
6110
|
license: "Apache-2.0",
|
|
6111
6111
|
engines: {
|
|
6112
6112
|
bun: ">=1.3.2",
|
|
6113
|
-
node: "
|
|
6113
|
+
node: "^22.23.4 || ^24.22.1 || ^26.12.1"
|
|
6114
6114
|
},
|
|
6115
6115
|
publishConfig: {
|
|
6116
6116
|
access: "public"
|
|
@@ -6187,7 +6187,7 @@ var init_package = __esm(() => {
|
|
|
6187
6187
|
prepublishOnly: "bun run runtime-graph:verify && bun run build",
|
|
6188
6188
|
postinstall: `node scripts/postinstall-patches.js || echo letta: vendor patches skipped && node -e "try{require('fs').chmodSync(require('path').join(require.resolve('node-pty/package.json'),'../prebuilds/darwin-arm64/spawn-helper'),0o755)}catch(e){}" || true`,
|
|
6189
6189
|
"mod-learning:memory-citations": "bun scripts/mod-learning/learn-mod.ts --env docs/examples/mods/learning/memory-citations.env.json",
|
|
6190
|
-
"test:built-entrypoints": 'LETTA_TEST_CLI_BUNDLE="$PWD/letta.js" LETTA_TEST_BUILT_ARTIFACT=1 bun test src/cli/subcommands/lifecycle-output.test.ts src/websocket/app-server-dream.test.ts --timeout 60000'
|
|
6190
|
+
"test:built-entrypoints": 'LETTA_TEST_CLI_BUNDLE="$PWD/letta.js" LETTA_TEST_BUILT_ARTIFACT=1 bun test src/subcommand-exit.test.ts src/cli/subcommands/lifecycle-output.test.ts src/websocket/app-server-dream.test.ts --timeout 60000'
|
|
6191
6191
|
},
|
|
6192
6192
|
"lint-staged": {
|
|
6193
6193
|
"*.{ts,tsx,js,jsx,json}": [
|
|
@@ -6242,7 +6242,10 @@ var init_package = __esm(() => {
|
|
|
6242
6242
|
},
|
|
6243
6243
|
lettaLifecycleProtocol: 1,
|
|
6244
6244
|
lettaRuntimeGraphProtocol: 1,
|
|
6245
|
-
lettaRuntimeGraphSha512: "sha512-xHwgmxBsCCiYY3o9bJl2DPx84chNPq1OsLFGac23DBEoU+h6hGCcX7rZezQxutCYhG/yFzjQ65L3pZ5j6BzNbg=="
|
|
6245
|
+
lettaRuntimeGraphSha512: "sha512-xHwgmxBsCCiYY3o9bJl2DPx84chNPq1OsLFGac23DBEoU+h6hGCcX7rZezQxutCYhG/yFzjQ65L3pZ5j6BzNbg==",
|
|
6246
|
+
patchedDependencies: {
|
|
6247
|
+
"@earendil-works/pi-ai@0.99.1": "patches/@earendil-works%2Fpi-ai@0.99.1.patch"
|
|
6248
|
+
}
|
|
6246
6249
|
};
|
|
6247
6250
|
});
|
|
6248
6251
|
|
|
@@ -26753,6 +26756,16 @@ function addCacheControlToTextContent(message, cacheControl) {
|
|
|
26753
26756
|
}
|
|
26754
26757
|
return false;
|
|
26755
26758
|
}
|
|
26759
|
+
function isOpenAIHost(baseUrl) {
|
|
26760
|
+
if (!baseUrl)
|
|
26761
|
+
return true;
|
|
26762
|
+
try {
|
|
26763
|
+
const host = new URL(baseUrl).hostname.toLowerCase();
|
|
26764
|
+
return host === "api.openai.com" || host.endsWith(".azure.com");
|
|
26765
|
+
} catch {
|
|
26766
|
+
return true;
|
|
26767
|
+
}
|
|
26768
|
+
}
|
|
26756
26769
|
function convertMessages(model, context, compat, options) {
|
|
26757
26770
|
const normalizedContext = resolveTranscript(context, compat.supportsMidConvoSystemMessages);
|
|
26758
26771
|
const params = [];
|
|
@@ -26769,7 +26782,7 @@ function convertMessages(model, context, compat, options) {
|
|
|
26769
26782
|
const prefix = callId.slice(0, Math.max(1, 40 - hash.length - 1));
|
|
26770
26783
|
return `${prefix}_${hash}`;
|
|
26771
26784
|
}
|
|
26772
|
-
if (model.provider === "openai")
|
|
26785
|
+
if (model.provider === "openai" && isOpenAIHost(model.baseUrl))
|
|
26773
26786
|
return id.length > 40 ? id.slice(0, 40) : id;
|
|
26774
26787
|
return id;
|
|
26775
26788
|
};
|
|
@@ -109083,6 +109096,11 @@ var init_memory_filesystem2 = __esm(() => {
|
|
|
109083
109096
|
MEMORY_TREE_MAX_CHILDREN_PER_DIR = DIRECTORY_LIMIT_DEFAULTS.memfsTreeMaxChildrenPerDir;
|
|
109084
109097
|
});
|
|
109085
109098
|
|
|
109099
|
+
// src/backend/local/local-conversation-key.ts
|
|
109100
|
+
function localConversationKey(conversationId, agentId) {
|
|
109101
|
+
return conversationId === "default" ? `default:${agentId}` : `conversation:${conversationId}`;
|
|
109102
|
+
}
|
|
109103
|
+
|
|
109086
109104
|
// src/backend/local/local-model-normalization.ts
|
|
109087
109105
|
function supportedModelSettingsFromBody(bodyRecord) {
|
|
109088
109106
|
const modelSettings = isRecord2(bodyRecord.model_settings) ? { ...bodyRecord.model_settings } : {};
|
|
@@ -112419,7 +112437,7 @@ class LocalStore {
|
|
|
112419
112437
|
return conversation.agent_free ? this.executionAgentIdForConversation(conversationId) : conversation.agent_id;
|
|
112420
112438
|
}
|
|
112421
112439
|
conversationKey(conversationId, agentId) {
|
|
112422
|
-
return conversationId
|
|
112440
|
+
return localConversationKey(conversationId, agentId);
|
|
112423
112441
|
}
|
|
112424
112442
|
}
|
|
112425
112443
|
var DEFAULT_LOCAL_AGENT_NAME = "Letta Code", DEFAULT_LOCAL_MODEL = "local/default", LEGACY_LOCAL_CONTEXT_WINDOW_LIMIT2 = 128000, DEFAULT_LOCAL_CONVERSATION_ID_PREFIX = "local-conv-", DEFAULT_LOCAL_STORED_MESSAGE_ID_PREFIX = "letta-msg-", DEFAULT_LOCAL_UI_MESSAGE_ID_PREFIX = "ui-msg-", DEFAULT_RESIDENT_MESSAGE_TAIL_LIMIT = 100, LocalBackendNotFoundError;
|
|
@@ -113576,12 +113594,22 @@ function refreshInputOtidsForNewRequest(currentInput) {
|
|
|
113576
113594
|
}));
|
|
113577
113595
|
}
|
|
113578
113596
|
function rebuildInputWithFreshDenials(currentInput, serverApprovals, denialReason, preserveMessageOtids = false) {
|
|
113597
|
+
const localResults = new Map;
|
|
113598
|
+
for (const item of currentInput) {
|
|
113599
|
+
if (item?.type === "approval") {
|
|
113600
|
+
for (const result of item.approvals ?? []) {
|
|
113601
|
+
if (result.tool_call_id) {
|
|
113602
|
+
localResults.set(result.tool_call_id, result);
|
|
113603
|
+
}
|
|
113604
|
+
}
|
|
113605
|
+
}
|
|
113606
|
+
}
|
|
113579
113607
|
const content = currentInput.filter((item) => item?.type !== "approval");
|
|
113580
113608
|
const stripped = preserveMessageOtids ? content : refreshInputOtidsForNewRequest(content);
|
|
113581
113609
|
if (serverApprovals.length > 0) {
|
|
113582
113610
|
const denials = {
|
|
113583
113611
|
type: "approval",
|
|
113584
|
-
approvals: buildFreshDenialApprovals(serverApprovals, denialReason),
|
|
113612
|
+
approvals: buildFreshDenialApprovals(serverApprovals, denialReason).map((denial) => localResults.get(denial.tool_call_id) ?? denial),
|
|
113585
113613
|
otid: randomUUID9()
|
|
113586
113614
|
};
|
|
113587
113615
|
return [denials, ...stripped];
|
|
@@ -113684,7 +113712,7 @@ function selectChatGPTQuotaFailoverHandle(params) {
|
|
|
113684
113712
|
const index = Math.min(Math.floor(random() * candidates2.length), candidates2.length - 1);
|
|
113685
113713
|
return candidates2[index]?.handle ?? null;
|
|
113686
113714
|
}
|
|
113687
|
-
var INVALID_TOOL_CALL_IDS_FRAGMENT = "invalid tool call ids", APPROVAL_PENDING_DETAIL_FRAGMENT = "waiting for approval", CONVERSATION_BUSY_DETAIL_FRAGMENTS, CONVERSATION_BUSY_RUN_ID_PATTERN, EMPTY_RESPONSE_DETAIL_FRAGMENT = "empty content in", RETRYABLE_PROVIDER_DETAIL_PATTERNS, NON_RETRYABLE_PROVIDER_DETAIL_PATTERNS, NON_RETRYABLE_RUN_ERROR_TYPES, NON_RETRYABLE_429_REASONS, NON_RETRYABLE_QUOTA_DETAIL_PATTERNS, NON_RETRYABLE_4XX_PATTERN, RETRYABLE_429_PATTERN, DEFAULT_TRANSIENT_RETRY_BASE_DELAY_MS = 1000, CLOUDFLARE_EDGE_52X_RETRY_BASE_DELAY_MS = 5000, CONVERSATION_BUSY_RETRY_BASE_DELAY_MS = 1e4, EMPTY_RESPONSE_RETRY_BASE_DELAY_MS = 500, STALE_APPROVAL_RECOVERY_DENIAL_REASON = "The agent harness automatically closed this stale pending tool call to recover from a client/server state desync: the server was still waiting on a result for it, but the harness had no matching tool execution in flight and no result was ever recorded. It was not denied by the user or a permissions policy.
|
|
113715
|
+
var INVALID_TOOL_CALL_IDS_FRAGMENT = "invalid tool call ids", APPROVAL_PENDING_DETAIL_FRAGMENT = "waiting for approval", CONVERSATION_BUSY_DETAIL_FRAGMENTS, CONVERSATION_BUSY_RUN_ID_PATTERN, EMPTY_RESPONSE_DETAIL_FRAGMENT = "empty content in", RETRYABLE_PROVIDER_DETAIL_PATTERNS, NON_RETRYABLE_PROVIDER_DETAIL_PATTERNS, NON_RETRYABLE_RUN_ERROR_TYPES, NON_RETRYABLE_429_REASONS, NON_RETRYABLE_QUOTA_DETAIL_PATTERNS, NON_RETRYABLE_4XX_PATTERN, RETRYABLE_429_PATTERN, DEFAULT_TRANSIENT_RETRY_BASE_DELAY_MS = 1000, CLOUDFLARE_EDGE_52X_RETRY_BASE_DELAY_MS = 5000, CONVERSATION_BUSY_RETRY_BASE_DELAY_MS = 1e4, EMPTY_RESPONSE_RETRY_BASE_DELAY_MS = 500, STALE_APPROVAL_RECOVERY_DENIAL_REASON = "The agent harness automatically closed this stale pending tool call to recover from a client/server state desync: the server was still waiting on a result for it, but the harness had no matching tool execution in flight and no result was ever recorded. It was not denied by the user or a permissions policy. The harness can't tell whether it ran, so check whether its effect already happened before running it again.", STARTED_TOOL_CALL_RECOVERY_DENIAL_REASON = "The agent harness closed this pending tool call while recovering from an interrupted turn. The call had started, but its result was not recorded, so it may or may not have run. Check whether its effect already happened before running it again.", CHATGPT_USAGE_LIMIT_FRAGMENT = "usage_limit_reached", CHATGPT_OAUTH_PROVIDER_TYPE2 = "chatgpt_oauth", BYOK_PROVIDER_CATEGORY = "byok";
|
|
113688
113716
|
var init_turn_recovery_policy = __esm(() => {
|
|
113689
113717
|
init_error_formatter();
|
|
113690
113718
|
init_zai_errors();
|
|
@@ -114248,7 +114276,7 @@ class HeadlessBackend {
|
|
|
114248
114276
|
}
|
|
114249
114277
|
async cancelConversation(...args) {
|
|
114250
114278
|
const [conversationIdOrAgentId] = args;
|
|
114251
|
-
const runId = this.activeRunByConversation.get(conversationIdOrAgentId) ?? this.findActiveRunByAgentId(conversationIdOrAgentId);
|
|
114279
|
+
const runId = this.activeRunByConversation.get(localConversationKey(conversationIdOrAgentId, this.store.resolveAgentIdForConversation(conversationIdOrAgentId))) ?? this.activeRunByConversation.get(localConversationKey("default", conversationIdOrAgentId)) ?? this.findActiveRunByAgentId(conversationIdOrAgentId);
|
|
114252
114280
|
const run = runId ? this.runs.get(runId) : undefined;
|
|
114253
114281
|
if (run?.conversation_id && run.agent_id) {
|
|
114254
114282
|
this.store.settleInterruptedToolCalls(run.conversation_id, {
|
|
@@ -114303,7 +114331,7 @@ class HeadlessBackend {
|
|
|
114303
114331
|
}
|
|
114304
114332
|
async cancelConversationRun(...args) {
|
|
114305
114333
|
const [conversationId, requestedRunId] = args;
|
|
114306
|
-
const runId = requestedRunId ?? this.activeRunByConversation.get(conversationId);
|
|
114334
|
+
const runId = requestedRunId ?? this.activeRunByConversation.get(localConversationKey(conversationId, this.store.resolveAgentIdForConversation(conversationId)));
|
|
114307
114335
|
if (!runId)
|
|
114308
114336
|
return {};
|
|
114309
114337
|
const run = this.runs.get(runId);
|
|
@@ -114338,7 +114366,8 @@ class HeadlessBackend {
|
|
|
114338
114366
|
if (options?.signal?.aborted) {
|
|
114339
114367
|
throw new APIUserAbortError;
|
|
114340
114368
|
}
|
|
114341
|
-
const
|
|
114369
|
+
const turnAgentId = body.agent_id ?? this.store.resolveAgentIdForConversation(conversationId);
|
|
114370
|
+
const activeRunId = this.activeRunByConversation.get(localConversationKey(conversationId, turnAgentId));
|
|
114342
114371
|
const activeRun = activeRunId ? this.runs.get(activeRunId) : undefined;
|
|
114343
114372
|
if (activeRun && !isTerminalRun(activeRun)) {
|
|
114344
114373
|
throw new Error(`Conversation ${conversationId} already has an active run (${activeRun.id})`);
|
|
@@ -114447,7 +114476,7 @@ class HeadlessBackend {
|
|
|
114447
114476
|
}
|
|
114448
114477
|
};
|
|
114449
114478
|
this.runs.set(run.id, run);
|
|
114450
|
-
this.activeRunByConversation.set(conversationId, run.id);
|
|
114479
|
+
this.activeRunByConversation.set(localConversationKey(conversationId, agentId), run.id);
|
|
114451
114480
|
return run;
|
|
114452
114481
|
}
|
|
114453
114482
|
completeRun(runId, stopReason, errorInfo) {
|
|
@@ -114471,9 +114500,7 @@ class HeadlessBackend {
|
|
|
114471
114500
|
}
|
|
114472
114501
|
} : run.metadata
|
|
114473
114502
|
});
|
|
114474
|
-
|
|
114475
|
-
this.activeRunByConversation.delete(run.conversation_id);
|
|
114476
|
-
}
|
|
114503
|
+
this.releaseActiveRun(run);
|
|
114477
114504
|
this.runControllerByRunId.delete(runId);
|
|
114478
114505
|
this.runStartupPreemptByRunId.delete(runId);
|
|
114479
114506
|
}
|
|
@@ -114500,9 +114527,7 @@ class HeadlessBackend {
|
|
|
114500
114527
|
}
|
|
114501
114528
|
}
|
|
114502
114529
|
});
|
|
114503
|
-
|
|
114504
|
-
this.activeRunByConversation.delete(run.conversation_id);
|
|
114505
|
-
}
|
|
114530
|
+
this.releaseActiveRun(run);
|
|
114506
114531
|
this.runControllerByRunId.delete(runId);
|
|
114507
114532
|
this.runStartupPreemptByRunId.delete(runId);
|
|
114508
114533
|
}
|
|
@@ -114522,6 +114547,14 @@ class HeadlessBackend {
|
|
|
114522
114547
|
const run = this.runs.get(runId);
|
|
114523
114548
|
return run ? isTerminalRun(run) : false;
|
|
114524
114549
|
}
|
|
114550
|
+
releaseActiveRun(run) {
|
|
114551
|
+
if (!run.conversation_id)
|
|
114552
|
+
return;
|
|
114553
|
+
const key = localConversationKey(run.conversation_id, run.agent_id);
|
|
114554
|
+
if (this.activeRunByConversation.get(key) === run.id) {
|
|
114555
|
+
this.activeRunByConversation.delete(key);
|
|
114556
|
+
}
|
|
114557
|
+
}
|
|
114525
114558
|
findActiveRunByAgentId(agentId) {
|
|
114526
114559
|
for (const [runId, run] of this.runs.entries()) {
|
|
114527
114560
|
if (run.agent_id === agentId && !isTerminalRun(run))
|
|
@@ -117167,11 +117200,9 @@ function createUsageStatisticsChunk(usage, contextTokensEstimate) {
|
|
|
117167
117200
|
const cachedInputTokens = usage?.cacheRead;
|
|
117168
117201
|
const cacheWriteTokens = usage?.cacheWrite;
|
|
117169
117202
|
const reasoningTokens = usage?.reasoning;
|
|
117170
|
-
if (promptTokens === undefined && completionTokens === undefined && totalTokens === undefined && cachedInputTokens === undefined && cacheWriteTokens === undefined && reasoningTokens === undefined && contextTokens === undefined) {
|
|
117171
|
-
return;
|
|
117172
|
-
}
|
|
117173
117203
|
return {
|
|
117174
117204
|
message_type: "usage_statistics",
|
|
117205
|
+
step_count: 1,
|
|
117175
117206
|
...promptTokens !== undefined ? { prompt_tokens: promptTokens } : {},
|
|
117176
117207
|
...completionTokens !== undefined ? { completion_tokens: completionTokens } : {},
|
|
117177
117208
|
...totalTokens !== undefined ? { total_tokens: totalTokens } : {},
|
|
@@ -117284,11 +117315,8 @@ function createProviderLettaStream(events, contextTokensEstimate) {
|
|
|
117284
117315
|
}
|
|
117285
117316
|
if (part.type === "done") {
|
|
117286
117317
|
if (!sawUsageStatistics) {
|
|
117287
|
-
|
|
117288
|
-
|
|
117289
|
-
sawUsageStatistics = true;
|
|
117290
|
-
yield usageChunk;
|
|
117291
|
-
}
|
|
117318
|
+
sawUsageStatistics = true;
|
|
117319
|
+
yield createUsageStatisticsChunk(part.message.usage, contextTokensEstimate);
|
|
117292
117320
|
}
|
|
117293
117321
|
pendingStopReason = {
|
|
117294
117322
|
message_type: "stop_reason",
|
|
@@ -163406,14 +163434,14 @@ function buildLatestVersionUrl(packageName, registryBaseUrl) {
|
|
|
163406
163434
|
function buildInstallCommand(pm, env6 = process.env) {
|
|
163407
163435
|
return `${pm} ${buildInstallArgs(pm, env6).join(" ")}`;
|
|
163408
163436
|
}
|
|
163409
|
-
function buildUpdateExecOptions(timeout, platform4 = process.platform) {
|
|
163437
|
+
function buildUpdateExecOptions(timeout = 0, platform4 = process.platform) {
|
|
163410
163438
|
return {
|
|
163411
163439
|
timeout,
|
|
163412
163440
|
encoding: "utf8",
|
|
163413
163441
|
shell: platform4 === "win32"
|
|
163414
163442
|
};
|
|
163415
163443
|
}
|
|
163416
|
-
async function runUpdateCommand(command, args, timeout) {
|
|
163444
|
+
async function runUpdateCommand(command, args, timeout = 0) {
|
|
163417
163445
|
return execFileAsync3(command, args, buildUpdateExecOptions(timeout));
|
|
163418
163446
|
}
|
|
163419
163447
|
function getResolvedEntrypoint() {
|
|
@@ -163616,7 +163644,7 @@ async function performUpdate(progressLog) {
|
|
|
163616
163644
|
try {
|
|
163617
163645
|
debugLog2(`Running ${installCmd}...`);
|
|
163618
163646
|
progressLog?.(`Running update command: ${installCmd}`);
|
|
163619
|
-
await runUpdateCommand(pm, installArgs
|
|
163647
|
+
await runUpdateCommand(pm, installArgs);
|
|
163620
163648
|
debugLog2("Update completed successfully");
|
|
163621
163649
|
progressLog?.("Update command completed successfully.");
|
|
163622
163650
|
return { success: true };
|
|
@@ -163633,7 +163661,7 @@ async function performUpdate(progressLog) {
|
|
|
163633
163661
|
debugLog2("ENOTEMPTY detected, attempting cleanup and retry...");
|
|
163634
163662
|
await cleanupOrphanedDirs(globalPath);
|
|
163635
163663
|
try {
|
|
163636
|
-
await runUpdateCommand(pm, installArgs
|
|
163664
|
+
await runUpdateCommand(pm, installArgs);
|
|
163637
163665
|
debugLog2("Update succeeded after cleanup retry");
|
|
163638
163666
|
return { success: true };
|
|
163639
163667
|
} catch (retryError) {
|
|
@@ -163661,7 +163689,7 @@ async function performUpdate(progressLog) {
|
|
|
163661
163689
|
await cleanupOrphanedDirs(globalPath);
|
|
163662
163690
|
}
|
|
163663
163691
|
try {
|
|
163664
|
-
await runUpdateCommand(pm, installArgs
|
|
163692
|
+
await runUpdateCommand(pm, installArgs);
|
|
163665
163693
|
debugLog2("Update succeeded after race condition retry");
|
|
163666
163694
|
return { success: true };
|
|
163667
163695
|
} catch (retryError) {
|
|
@@ -163755,7 +163783,7 @@ async function manualUpdate(options) {
|
|
|
163755
163783
|
To update manually: ${installCmd}`
|
|
163756
163784
|
};
|
|
163757
163785
|
}
|
|
163758
|
-
var execFileAsync3, DEBUG, DEFAULT_UPDATE_PACKAGE_NAME = "@letta-ai/letta-code", DEFAULT_UPDATE_REGISTRY_BASE_URL = "https://registry.npmjs.org", UPDATE_PACKAGE_NAME_ENV = "LETTA_UPDATE_PACKAGE_NAME", UPDATE_REGISTRY_BASE_URL_ENV = "LETTA_UPDATE_REGISTRY_BASE_URL", UPDATE_INSTALL_REGISTRY_URL_ENV = "LETTA_UPDATE_INSTALL_REGISTRY_URL", DESKTOP_MANAGED_ENV = "LETTA_CODE_DESKTOP_MANAGED", INSTALL_ARG_PREFIX, VALID_PACKAGE_MANAGERS, NPM_PREFIX_TIMEOUT_MS = 5000,
|
|
163786
|
+
var execFileAsync3, DEBUG, DEFAULT_UPDATE_PACKAGE_NAME = "@letta-ai/letta-code", DEFAULT_UPDATE_REGISTRY_BASE_URL = "https://registry.npmjs.org", UPDATE_PACKAGE_NAME_ENV = "LETTA_UPDATE_PACKAGE_NAME", UPDATE_REGISTRY_BASE_URL_ENV = "LETTA_UPDATE_REGISTRY_BASE_URL", UPDATE_INSTALL_REGISTRY_URL_ENV = "LETTA_UPDATE_INSTALL_REGISTRY_URL", DESKTOP_MANAGED_ENV = "LETTA_CODE_DESKTOP_MANAGED", INSTALL_ARG_PREFIX, VALID_PACKAGE_MANAGERS, NPM_PREFIX_TIMEOUT_MS = 5000, PYTHON_UPDATE_COMMAND = "Upgrade with your installer: uv tool upgrade letta, pipx upgrade letta, or python -m pip install --upgrade letta";
|
|
163759
163787
|
var init_auto_update = __esm(() => {
|
|
163760
163788
|
init_error_reporting();
|
|
163761
163789
|
init_version();
|
|
@@ -180737,9 +180765,12 @@ class ChannelControlRequestCoordinator {
|
|
|
180737
180765
|
return true;
|
|
180738
180766
|
}
|
|
180739
180767
|
await this.clear(requestId);
|
|
180740
|
-
if (result2
|
|
180741
|
-
|
|
180742
|
-
|
|
180768
|
+
if (result2 !== "expired")
|
|
180769
|
+
return true;
|
|
180770
|
+
const wasApproval = "decision" in parsed.response && parsed.response.decision?.behavior === "allow";
|
|
180771
|
+
if (!wasApproval)
|
|
180772
|
+
return false;
|
|
180773
|
+
await this.options.deliverReprompt(cloneEvent(pending.event), input, "That approval prompt expired before I could use your reply. Please ask the agent to try again.");
|
|
180743
180774
|
return true;
|
|
180744
180775
|
}
|
|
180745
180776
|
async clear(requestId) {
|
|
@@ -181380,7 +181411,8 @@ function createChannelInboundRouter(deps) {
|
|
|
181380
181411
|
content: formatChannelNotification(preparedMessage2),
|
|
181381
181412
|
turnSources: [
|
|
181382
181413
|
buildChannelTurnSource(discordResult.route, preparedMessage2)
|
|
181383
|
-
]
|
|
181414
|
+
],
|
|
181415
|
+
defaultPermissionMode: config.defaultPermissionMode
|
|
181384
181416
|
});
|
|
181385
181417
|
return;
|
|
181386
181418
|
}
|
|
@@ -181445,7 +181477,8 @@ function createChannelInboundRouter(deps) {
|
|
|
181445
181477
|
deps.deliver({
|
|
181446
181478
|
route,
|
|
181447
181479
|
content,
|
|
181448
|
-
turnSources: [buildChannelTurnSource(route, preparedMessage)]
|
|
181480
|
+
turnSources: [buildChannelTurnSource(route, preparedMessage)],
|
|
181481
|
+
...isDiscordChannelAccount(config) || isSlackChannelAccount(config) ? { defaultPermissionMode: config.defaultPermissionMode } : {}
|
|
181449
181482
|
});
|
|
181450
181483
|
}
|
|
181451
181484
|
return { handleInboundMessage };
|
|
@@ -193257,7 +193290,10 @@ var init_parse_interval = __esm(() => {
|
|
|
193257
193290
|
});
|
|
193258
193291
|
|
|
193259
193292
|
// src/cron/process-identity.ts
|
|
193293
|
+
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
193260
193294
|
import { readFileSync as readFileSync26 } from "node:fs";
|
|
193295
|
+
import { uptime } from "node:os";
|
|
193296
|
+
import { basename as basename15 } from "node:path";
|
|
193261
193297
|
function readLinuxProcessIdentity(pid) {
|
|
193262
193298
|
try {
|
|
193263
193299
|
const stat5 = readFileSync26(`/proc/${pid}/stat`, "utf8");
|
|
@@ -193309,10 +193345,51 @@ function isProcessAlive2(pid, owner) {
|
|
|
193309
193345
|
}
|
|
193310
193346
|
}
|
|
193311
193347
|
}
|
|
193348
|
+
if (pid === process.pid)
|
|
193349
|
+
return true;
|
|
193350
|
+
if (owner && pidReuseProbe.platform !== "linux") {
|
|
193351
|
+
return !isPidReusedSinceBoot(pid, owner.started_at);
|
|
193352
|
+
}
|
|
193312
193353
|
return true;
|
|
193313
193354
|
}
|
|
193314
|
-
|
|
193315
|
-
|
|
193355
|
+
function isPidReusedSinceBoot(pid, startedAt) {
|
|
193356
|
+
const startedAtMs = startedAt ? Date.parse(startedAt) : Number.NaN;
|
|
193357
|
+
if (!Number.isFinite(startedAtMs) || startedAtMs >= pidReuseProbe.bootTimeMs() - BOOT_TIME_SLACK_MS) {
|
|
193358
|
+
return false;
|
|
193359
|
+
}
|
|
193360
|
+
const command = pidReuseProbe.getProcessCommand(pid);
|
|
193361
|
+
return Boolean(command) && !isLettaCommand(command ?? "");
|
|
193362
|
+
}
|
|
193363
|
+
function isLettaCommand(command) {
|
|
193364
|
+
if (/letta/i.test(command))
|
|
193365
|
+
return true;
|
|
193366
|
+
const script4 = process.argv[1];
|
|
193367
|
+
if (script4 && command.includes(script4))
|
|
193368
|
+
return true;
|
|
193369
|
+
const argv0 = command.split(/\s+/)[0] ?? "";
|
|
193370
|
+
return argv0 === process.execPath || basename15(argv0) === basename15(process.execPath);
|
|
193371
|
+
}
|
|
193372
|
+
var BOOT_TIME_SLACK_MS = 60000, defaultPidReuseProbe, pidReuseProbe, readProcessIdentityOverride = null;
|
|
193373
|
+
var init_process_identity = __esm(() => {
|
|
193374
|
+
defaultPidReuseProbe = {
|
|
193375
|
+
platform: process.platform,
|
|
193376
|
+
bootTimeMs: () => Date.now() - uptime() * 1000,
|
|
193377
|
+
getProcessCommand: (pid) => {
|
|
193378
|
+
if (process.platform === "win32")
|
|
193379
|
+
return null;
|
|
193380
|
+
try {
|
|
193381
|
+
return execFileSync7("ps", ["-p", String(pid), "-o", "command="], {
|
|
193382
|
+
encoding: "utf-8",
|
|
193383
|
+
timeout: 1000,
|
|
193384
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
193385
|
+
}).trim();
|
|
193386
|
+
} catch {
|
|
193387
|
+
return null;
|
|
193388
|
+
}
|
|
193389
|
+
}
|
|
193390
|
+
};
|
|
193391
|
+
pidReuseProbe = defaultPidReuseProbe;
|
|
193392
|
+
});
|
|
193316
193393
|
|
|
193317
193394
|
// src/cron/cron-file.ts
|
|
193318
193395
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
@@ -210919,7 +210996,7 @@ var init_mcp_client = __esm(() => {
|
|
|
210919
210996
|
init_streamableHttp();
|
|
210920
210997
|
DEFAULT_CLIENT_INFO = {
|
|
210921
210998
|
name: "letta-code",
|
|
210922
|
-
version: "0.34.
|
|
210999
|
+
version: "0.34.24"
|
|
210923
211000
|
};
|
|
210924
211001
|
});
|
|
210925
211002
|
|
|
@@ -214052,7 +214129,7 @@ var init_cwd = __esm(() => {
|
|
|
214052
214129
|
});
|
|
214053
214130
|
|
|
214054
214131
|
// src/websocket/listener/durable-file-lock.ts
|
|
214055
|
-
import { execFileSync as
|
|
214132
|
+
import { execFileSync as execFileSync8 } from "node:child_process";
|
|
214056
214133
|
import { randomUUID as randomUUID29 } from "node:crypto";
|
|
214057
214134
|
import {
|
|
214058
214135
|
chmodSync as chmodSync5,
|
|
@@ -214071,7 +214148,7 @@ import {
|
|
|
214071
214148
|
unlinkSync as unlinkSync7,
|
|
214072
214149
|
writeFileSync as writeFileSync23
|
|
214073
214150
|
} from "node:fs";
|
|
214074
|
-
import { basename as
|
|
214151
|
+
import { basename as basename16, dirname as dirname15, join as join43 } from "node:path";
|
|
214075
214152
|
function installCandidateDirectory(candidatePath, lockPath, hooks) {
|
|
214076
214153
|
mkdirSync27(lockPath, { mode: 448 });
|
|
214077
214154
|
const directoryIdentity = pathIdentity(lockPath);
|
|
@@ -214121,7 +214198,7 @@ function fsyncDirectory(path12, platform5 = process.platform) {
|
|
|
214121
214198
|
closeSync4(fd);
|
|
214122
214199
|
}
|
|
214123
214200
|
}
|
|
214124
|
-
function getProcessStart(pid, platform5 = process.platform, run = (executable, args, options) =>
|
|
214201
|
+
function getProcessStart(pid, platform5 = process.platform, run = (executable, args, options) => execFileSync8(executable, args, {
|
|
214125
214202
|
...options,
|
|
214126
214203
|
encoding: "utf8",
|
|
214127
214204
|
windowsHide: true
|
|
@@ -214298,7 +214375,7 @@ function removeDeadOwner(lockPath, parent, ownerPath, afterOwnerUnlink) {
|
|
|
214298
214375
|
return true;
|
|
214299
214376
|
}
|
|
214300
214377
|
function sweepDeadCandidates(lockPath, parent, isOwnerAlive, ignoredPath) {
|
|
214301
|
-
const prefix = `${
|
|
214378
|
+
const prefix = `${basename16(lockPath)}.candidate-`;
|
|
214302
214379
|
const allCandidates = readdirSync9(parent, { withFileTypes: true }).filter((entry) => entry.name.startsWith(prefix) && entry.isDirectory());
|
|
214303
214380
|
let hasUnresolvedCandidate = allCandidates.length > MAX_CANDIDATE_SWEEP;
|
|
214304
214381
|
const candidates2 = allCandidates.slice(0, MAX_CANDIDATE_SWEEP);
|
|
@@ -217047,8 +217124,8 @@ function isGitExecutable(command) {
|
|
|
217047
217124
|
}
|
|
217048
217125
|
function isShellExecutable(command) {
|
|
217049
217126
|
const normalized = command.replace(/\\/g, "/").toLowerCase();
|
|
217050
|
-
const
|
|
217051
|
-
return
|
|
217127
|
+
const basename17 = path13.basename(normalized);
|
|
217128
|
+
return basename17 === "bash" || basename17 === "sh" || basename17 === "zsh" || basename17 === "ash" || basename17 === "cmd.exe" || basename17.includes("powershell") || basename17.includes("pwsh");
|
|
217052
217129
|
}
|
|
217053
217130
|
function extractShellCommandArgument(launcher, startIndex) {
|
|
217054
217131
|
const argIndex = launcher.findIndex((token2, index) => {
|
|
@@ -218133,7 +218210,7 @@ function detectShellContext(env6 = process.env, currentPlatform = platform6()) {
|
|
|
218133
218210
|
var init_shell_context = () => {};
|
|
218134
218211
|
|
|
218135
218212
|
// src/tools/impl/shell-launchers.ts
|
|
218136
|
-
import {
|
|
218213
|
+
import { lstatSync as lstatSync2 } from "node:fs";
|
|
218137
218214
|
import { delimiter as delimiter3, isAbsolute as isAbsolute11, join as join48 } from "node:path";
|
|
218138
218215
|
function isValidEnvAlias(name) {
|
|
218139
218216
|
return /^[A-Za-z_][A-Za-z0-9_]*$/.test(name);
|
|
@@ -218244,12 +218321,20 @@ function hasPathSeparator(executable) {
|
|
|
218244
218321
|
return executable.includes("/") || executable.includes("\\");
|
|
218245
218322
|
}
|
|
218246
218323
|
function hasFileExtension(executable) {
|
|
218247
|
-
const
|
|
218248
|
-
return /\.[^.]+$/.test(
|
|
218324
|
+
const basename18 = executable.split(/[\\/]/).pop() ?? executable;
|
|
218325
|
+
return /\.[^.]+$/.test(basename18);
|
|
218326
|
+
}
|
|
218327
|
+
function shellCandidateExists(candidate) {
|
|
218328
|
+
try {
|
|
218329
|
+
lstatSync2(candidate);
|
|
218330
|
+
return true;
|
|
218331
|
+
} catch {
|
|
218332
|
+
return false;
|
|
218333
|
+
}
|
|
218249
218334
|
}
|
|
218250
218335
|
function resolveExecutablePath(executable, env6) {
|
|
218251
218336
|
if (isAbsolute11(executable) || hasPathSeparator(executable)) {
|
|
218252
|
-
return
|
|
218337
|
+
return shellCandidateExists(executable) ? executable : null;
|
|
218253
218338
|
}
|
|
218254
218339
|
const pathDelimiter = process.platform === "win32" ? ";" : delimiter3;
|
|
218255
218340
|
const pathEntries = pathEnvValue(env6).split(pathDelimiter).filter(Boolean);
|
|
@@ -218262,7 +218347,7 @@ function resolveExecutablePath(executable, env6) {
|
|
|
218262
218347
|
for (const entry of pathEntries) {
|
|
218263
218348
|
for (const name of executableNames) {
|
|
218264
218349
|
const candidate = join48(entry, name);
|
|
218265
|
-
if (
|
|
218350
|
+
if (shellCandidateExists(candidate)) {
|
|
218266
218351
|
return candidate;
|
|
218267
218352
|
}
|
|
218268
218353
|
}
|
|
@@ -219069,7 +219154,7 @@ var SANDBOX_EXEC_PATH = "/usr/bin/sandbox-exec";
|
|
|
219069
219154
|
|
|
219070
219155
|
// src/sandbox/availability.ts
|
|
219071
219156
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
219072
|
-
import { existsSync as
|
|
219157
|
+
import { existsSync as existsSync35 } from "node:fs";
|
|
219073
219158
|
import { delimiter as delimiter4, isAbsolute as isAbsolute12, join as join49 } from "node:path";
|
|
219074
219159
|
function detectSandboxBackend(options = {}) {
|
|
219075
219160
|
const platform7 = options.platform ?? process.platform;
|
|
@@ -219101,7 +219186,7 @@ function warnSandboxBackendUnavailable(availability, context3) {
|
|
|
219101
219186
|
}
|
|
219102
219187
|
function probe(platform7) {
|
|
219103
219188
|
if (platform7 === "darwin") {
|
|
219104
|
-
if (
|
|
219189
|
+
if (existsSync35(SANDBOX_EXEC_PATH)) {
|
|
219105
219190
|
return { backend: "seatbelt", reason: "sandbox-exec available" };
|
|
219106
219191
|
}
|
|
219107
219192
|
return {
|
|
@@ -219136,13 +219221,13 @@ function probeBwrap() {
|
|
|
219136
219221
|
return { backend: "bwrap", bwrapPath, reason: "bwrap available" };
|
|
219137
219222
|
}
|
|
219138
219223
|
function resolveExecutableOnPath(executable, envPath = process.env.PATH) {
|
|
219139
|
-
if (isAbsolute12(executable) &&
|
|
219224
|
+
if (isAbsolute12(executable) && existsSync35(executable))
|
|
219140
219225
|
return executable;
|
|
219141
219226
|
for (const dir of (envPath ?? "").split(delimiter4)) {
|
|
219142
219227
|
if (!dir)
|
|
219143
219228
|
continue;
|
|
219144
219229
|
const candidate = join49(dir, executable);
|
|
219145
|
-
if (
|
|
219230
|
+
if (existsSync35(candidate))
|
|
219146
219231
|
return candidate;
|
|
219147
219232
|
}
|
|
219148
219233
|
return null;
|
|
@@ -219183,7 +219268,7 @@ var init_policy = () => {};
|
|
|
219183
219268
|
|
|
219184
219269
|
// src/permissions/memory-paths.ts
|
|
219185
219270
|
import { homedir as homedir19 } from "node:os";
|
|
219186
|
-
import { basename as
|
|
219271
|
+
import { basename as basename18, dirname as dirname20, isAbsolute as isAbsolute13, resolve as resolve16 } from "node:path";
|
|
219187
219272
|
function normalizeMemoryPath(path15) {
|
|
219188
219273
|
const resolvedPath = resolve16(expandHomePath(path15));
|
|
219189
219274
|
const normalized = resolvedPath.replace(/\\/g, "/");
|
|
@@ -219228,7 +219313,7 @@ function addRootAndSiblingWorktree(root2, acc) {
|
|
|
219228
219313
|
return;
|
|
219229
219314
|
}
|
|
219230
219315
|
acc.add(normalizedRoot);
|
|
219231
|
-
const leaf =
|
|
219316
|
+
const leaf = basename18(normalizedRoot);
|
|
219232
219317
|
if (leaf === "memory") {
|
|
219233
219318
|
acc.add(normalizeMemoryPath(resolve16(dirname20(normalizedRoot), "memory-worktrees")));
|
|
219234
219319
|
}
|
|
@@ -219309,9 +219394,9 @@ var init_memory_paths = __esm(() => {
|
|
|
219309
219394
|
});
|
|
219310
219395
|
|
|
219311
219396
|
// src/permissions/sandbox-policy.ts
|
|
219312
|
-
import { existsSync as
|
|
219397
|
+
import { existsSync as existsSync36, realpathSync as realpathSync5 } from "node:fs";
|
|
219313
219398
|
import { homedir as homedir20 } from "node:os";
|
|
219314
|
-
import { basename as
|
|
219399
|
+
import { basename as basename19, dirname as dirname21, isAbsolute as isAbsolute14, join as join50, resolve as resolve17 } from "node:path";
|
|
219315
219400
|
function getDefaultAgentsTreeRoot(homeDir = homedir20()) {
|
|
219316
219401
|
return canonicalizeRoot(join50(homeDir, ".letta", "agents"));
|
|
219317
219402
|
}
|
|
@@ -219330,8 +219415,8 @@ function canonicalizeRoot(input) {
|
|
|
219330
219415
|
const abs = isAbsolute14(input) ? input : resolve17(input);
|
|
219331
219416
|
let dir = abs;
|
|
219332
219417
|
const tail2 = [];
|
|
219333
|
-
while (!
|
|
219334
|
-
tail2.unshift(
|
|
219418
|
+
while (!existsSync36(dir)) {
|
|
219419
|
+
tail2.unshift(basename19(dir));
|
|
219335
219420
|
const parent = dirname21(dir);
|
|
219336
219421
|
if (parent === dir) {
|
|
219337
219422
|
return normalizeSandboxPath(abs);
|
|
@@ -219365,8 +219450,8 @@ function deriveSelfAgentRootsForTrees(memoryRoots, agentsTreeRoots = getCrossBac
|
|
|
219365
219450
|
const canon = canonicalizeRoot(root2);
|
|
219366
219451
|
const containingTree = canonicalTrees.find((tree) => canon !== tree && isWithinRoot(canon, tree));
|
|
219367
219452
|
if (containingTree) {
|
|
219368
|
-
const leaf =
|
|
219369
|
-
const parentLeaf =
|
|
219453
|
+
const leaf = basename19(canon);
|
|
219454
|
+
const parentLeaf = basename19(dirname21(canon));
|
|
219370
219455
|
out.add(leaf === "memory" || leaf === "memory-worktrees" ? dirname21(canon) : parentLeaf === "memory-worktrees" || parentLeaf === "memory" && leaf === ".git" ? dirname21(dirname21(canon)) : canon);
|
|
219371
219456
|
continue;
|
|
219372
219457
|
}
|
|
@@ -220579,8 +220664,8 @@ function resolveRemovalTarget(rawTarget, cwd2, env6) {
|
|
|
220579
220664
|
let target2 = expandEnvironment(rawTarget, env6).replace(/[),]+$/g, "").replace(/(?<=[\\/:])\$(?:env:)?[A-Za-z_][A-Za-z0-9_]*/gi, "").replaceAll("/", "\\");
|
|
220580
220665
|
if (!target2 || target2 === "*")
|
|
220581
220666
|
return null;
|
|
220582
|
-
const
|
|
220583
|
-
if (
|
|
220667
|
+
const basename20 = win323.basename(target2);
|
|
220668
|
+
if (basename20.includes("*") || basename20.includes("?")) {
|
|
220584
220669
|
target2 = win323.dirname(target2);
|
|
220585
220670
|
}
|
|
220586
220671
|
return win323.normalize(win323.resolve(cwd2, target2));
|
|
@@ -223861,10 +223946,10 @@ var init_memory_runtime = __esm(() => {
|
|
|
223861
223946
|
});
|
|
223862
223947
|
|
|
223863
223948
|
// src/tools/impl/memory.ts
|
|
223864
|
-
import { execFileSync as
|
|
223949
|
+
import { execFileSync as execFileSync9 } from "node:child_process";
|
|
223865
223950
|
import {
|
|
223866
223951
|
closeSync as closeSync5,
|
|
223867
|
-
existsSync as
|
|
223952
|
+
existsSync as existsSync38,
|
|
223868
223953
|
openSync as openSync5,
|
|
223869
223954
|
readdirSync as readdirSync13,
|
|
223870
223955
|
readFileSync as readFileSync32,
|
|
@@ -223971,7 +224056,7 @@ function lastEditedByChild(dir, names2) {
|
|
|
223971
224056
|
if (time3 > (edited.get(name) ?? 0))
|
|
223972
224057
|
edited.set(name, time3);
|
|
223973
224058
|
};
|
|
223974
|
-
const git = (args) =>
|
|
224059
|
+
const git = (args) => execFileSync9("git", ["-C", dir, ...args], {
|
|
223975
224060
|
encoding: "utf8",
|
|
223976
224061
|
timeout: 5000,
|
|
223977
224062
|
maxBuffer: 64 * 1024 * 1024,
|
|
@@ -224056,7 +224141,7 @@ function renderDirectory(memoryDir, relPath, fullPath) {
|
|
|
224056
224141
|
const open4 = `<memory_content path="${escapeXmlText2(relPath).replace(/"/g, """)}">`;
|
|
224057
224142
|
const close = "</memory_content>";
|
|
224058
224143
|
let head4;
|
|
224059
|
-
if (
|
|
224144
|
+
if (existsSync38(indexPath)) {
|
|
224060
224145
|
const budget = Math.max(2000, LIMITS.READ_OUTPUT_CHARS - tailText.length - open4.length - close.length - 16);
|
|
224061
224146
|
head4 = clampContent(readFileSync32(indexPath, "utf8").trimEnd(), indexPath, budget);
|
|
224062
224147
|
} else {
|
|
@@ -224107,8 +224192,8 @@ async function memory2(args) {
|
|
|
224107
224192
|
throw new Error(`skills/ is reserved for skills. Use Skill("${segments[1] ?? "<name>"}").`);
|
|
224108
224193
|
}
|
|
224109
224194
|
const fullPath = join52(memoryDir, ...segments);
|
|
224110
|
-
if (!
|
|
224111
|
-
const candidates2 = !relPath.endsWith(".md") &&
|
|
224195
|
+
if (!existsSync38(fullPath)) {
|
|
224196
|
+
const candidates2 = !relPath.endsWith(".md") && existsSync38(`${fullPath}.md`) ? [`${relPath}.md`] : findByBasename(memoryDir, segments[segments.length - 1] ?? relPath);
|
|
224112
224197
|
const hint = candidates2.length ? ` Did you mean ${candidates2.join(" or ")}? Paths are relative to the memory directory.` : "";
|
|
224113
224198
|
throw new Error(`No memory at ${relPath}.${hint}`);
|
|
224114
224199
|
}
|
|
@@ -227176,10 +227261,11 @@ var init_read_only_shell = __esm(() => {
|
|
|
227176
227261
|
// src/permissions/checker.ts
|
|
227177
227262
|
var exports_checker = {};
|
|
227178
227263
|
__export(exports_checker, {
|
|
227264
|
+
isPathWithin: () => isPathWithin,
|
|
227179
227265
|
checkPermissionWithHooks: () => checkPermissionWithHooks,
|
|
227180
227266
|
checkPermission: () => checkPermission
|
|
227181
227267
|
});
|
|
227182
|
-
import { resolve as resolve24 } from "node:path";
|
|
227268
|
+
import { posix as posix3, resolve as resolve24, win32 as win324 } from "node:path";
|
|
227183
227269
|
function envFlagEnabled(name) {
|
|
227184
227270
|
const value = process.env[name];
|
|
227185
227271
|
if (!value)
|
|
@@ -227542,15 +227628,25 @@ function checkPermissionForEngine(engine4, toolName2, toolArgs, permissions, wor
|
|
|
227542
227628
|
trace
|
|
227543
227629
|
};
|
|
227544
227630
|
}
|
|
227631
|
+
function isPathWithin(child, root2, pathImpl = process.platform === "win32" ? win324 : posix3) {
|
|
227632
|
+
const caseInsensitive = pathImpl === win324;
|
|
227633
|
+
const normalizedChild = caseInsensitive ? child.toLowerCase() : child;
|
|
227634
|
+
const normalizedRoot = caseInsensitive ? root2.toLowerCase() : root2;
|
|
227635
|
+
const rel = pathImpl.relative(normalizedRoot, normalizedChild);
|
|
227636
|
+
if (rel === "") {
|
|
227637
|
+
return true;
|
|
227638
|
+
}
|
|
227639
|
+
return rel !== ".." && !rel.startsWith(`..${pathImpl.sep}`) && !pathImpl.isAbsolute(rel);
|
|
227640
|
+
}
|
|
227545
227641
|
function isWithinAllowedDirectories(filePath, permissions, workingDirectory) {
|
|
227546
227642
|
const absolutePath = resolve24(workingDirectory, filePath);
|
|
227547
|
-
if (absolutePath
|
|
227643
|
+
if (isPathWithin(absolutePath, resolve24(workingDirectory))) {
|
|
227548
227644
|
return true;
|
|
227549
227645
|
}
|
|
227550
227646
|
if (permissions.additionalDirectories) {
|
|
227551
227647
|
for (const dir of permissions.additionalDirectories) {
|
|
227552
227648
|
const resolvedDir = resolve24(workingDirectory, dir);
|
|
227553
|
-
if (absolutePath
|
|
227649
|
+
if (isPathWithin(absolutePath, resolvedDir)) {
|
|
227554
227650
|
return true;
|
|
227555
227651
|
}
|
|
227556
227652
|
}
|
|
@@ -228016,7 +228112,7 @@ __export(exports_analyzer, {
|
|
|
228016
228112
|
analyzeApprovalContext: () => analyzeApprovalContext
|
|
228017
228113
|
});
|
|
228018
228114
|
import { homedir as homedir28 } from "node:os";
|
|
228019
|
-
import { dirname as dirname23, relative as relative5, resolve as resolve26, win32 as
|
|
228115
|
+
import { dirname as dirname23, relative as relative5, resolve as resolve26, win32 as win325 } from "node:path";
|
|
228020
228116
|
function normalizeOsPath(path18) {
|
|
228021
228117
|
return path18.replace(/\\/g, "/");
|
|
228022
228118
|
}
|
|
@@ -228025,24 +228121,24 @@ function isWindowsPath(path18) {
|
|
|
228025
228121
|
}
|
|
228026
228122
|
function resolvePathForContext(basePath, targetPath) {
|
|
228027
228123
|
const windows = isWindowsPath(basePath) || isWindowsPath(targetPath);
|
|
228028
|
-
return windows ?
|
|
228124
|
+
return windows ? win325.resolve(basePath, targetPath) : resolve26(basePath, targetPath);
|
|
228029
228125
|
}
|
|
228030
228126
|
function relativePathForContext(basePath, targetPath) {
|
|
228031
228127
|
const windows = isWindowsPath(basePath) || isWindowsPath(targetPath);
|
|
228032
|
-
return windows ?
|
|
228128
|
+
return windows ? win325.relative(basePath, targetPath) : relative5(basePath, targetPath);
|
|
228033
228129
|
}
|
|
228034
228130
|
function isPathWithinDirectory(path18, directory) {
|
|
228035
228131
|
const windows = isWindowsPath(path18) || isWindowsPath(directory);
|
|
228036
228132
|
const normalizedPath = normalizeOsPath(path18);
|
|
228037
228133
|
const normalizedDirectory = normalizeOsPath(directory);
|
|
228038
|
-
const relativePath = normalizeOsPath(windows ?
|
|
228134
|
+
const relativePath = normalizeOsPath(windows ? win325.relative(normalizedDirectory.toLowerCase(), normalizedPath.toLowerCase()) : relativePathForContext(normalizedDirectory, normalizedPath));
|
|
228039
228135
|
if (relativePath === "") {
|
|
228040
228136
|
return true;
|
|
228041
228137
|
}
|
|
228042
228138
|
return !relativePath.startsWith("../") && relativePath !== ".." && !relativePath.startsWith("/") && !/^[a-zA-Z]:\//.test(relativePath);
|
|
228043
228139
|
}
|
|
228044
228140
|
function dirnameForContext(path18) {
|
|
228045
|
-
return isWindowsPath(path18) ?
|
|
228141
|
+
return isWindowsPath(path18) ? win325.dirname(path18) : dirname23(path18);
|
|
228046
228142
|
}
|
|
228047
228143
|
function formatAbsoluteRulePath(path18) {
|
|
228048
228144
|
const normalized = normalizeOsPath(path18).replace(/\/+$/, "");
|
|
@@ -228938,7 +229034,7 @@ var init_approval_result_normalization = __esm(() => {
|
|
|
228938
229034
|
|
|
228939
229035
|
// src/agent/client-skills-watcher.ts
|
|
228940
229036
|
import {
|
|
228941
|
-
existsSync as
|
|
229037
|
+
existsSync as existsSync39,
|
|
228942
229038
|
readdirSync as readdirSync14,
|
|
228943
229039
|
realpathSync as realpathSync7,
|
|
228944
229040
|
statSync as statSync17,
|
|
@@ -229038,7 +229134,7 @@ class ClientSkillsWatcher {
|
|
|
229038
229134
|
const watchPaths = new Set;
|
|
229039
229135
|
let recursive = false;
|
|
229040
229136
|
let awaitedChild = null;
|
|
229041
|
-
if (
|
|
229137
|
+
if (existsSync39(root2)) {
|
|
229042
229138
|
recursive = true;
|
|
229043
229139
|
watchPaths.add(root2);
|
|
229044
229140
|
collectSymlinkDirectoryTargets(root2, watchPaths, new Set);
|
|
@@ -229091,7 +229187,7 @@ __export(exports_skills2, {
|
|
|
229091
229187
|
PROJECT_SKILLS_DIR: () => PROJECT_SKILLS_DIR,
|
|
229092
229188
|
GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR
|
|
229093
229189
|
});
|
|
229094
|
-
import { existsSync as
|
|
229190
|
+
import { existsSync as existsSync40 } from "node:fs";
|
|
229095
229191
|
import { readdir as readdir4, readFile as readFile11, realpath as realpath3, stat as stat6 } from "node:fs/promises";
|
|
229096
229192
|
import { dirname as dirname25, join as join54 } from "node:path";
|
|
229097
229193
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
@@ -229156,7 +229252,7 @@ async function getBundledSkills() {
|
|
|
229156
229252
|
}
|
|
229157
229253
|
async function discoverSkillsFromDir(skillsPath, source) {
|
|
229158
229254
|
const errors6 = [];
|
|
229159
|
-
if (!
|
|
229255
|
+
if (!existsSync40(skillsPath)) {
|
|
229160
229256
|
return { skills: [], errors: [] };
|
|
229161
229257
|
}
|
|
229162
229258
|
const skills = [];
|
|
@@ -229328,7 +229424,7 @@ var init_skills5 = __esm(() => {
|
|
|
229328
229424
|
});
|
|
229329
229425
|
|
|
229330
229426
|
// src/agent/shared-memory-skills.ts
|
|
229331
|
-
import { existsSync as
|
|
229427
|
+
import { existsSync as existsSync41 } from "node:fs";
|
|
229332
229428
|
import { dirname as dirname26, join as join55 } from "node:path";
|
|
229333
229429
|
function getAttachedRepositoriesCache() {
|
|
229334
229430
|
const global2 = globalThis;
|
|
@@ -229421,7 +229517,7 @@ async function discoverSharedMemorySkills(skillsDirs) {
|
|
|
229421
229517
|
const repositoryMount = dirname26(dir);
|
|
229422
229518
|
if (isCheckoutPending(repositoryMount))
|
|
229423
229519
|
continue;
|
|
229424
|
-
if (!
|
|
229520
|
+
if (!existsSync41(repositoryMount)) {
|
|
229425
229521
|
errors6.push({
|
|
229426
229522
|
path: repositoryMount,
|
|
229427
229523
|
message: "Attached repository is not mounted locally"
|
|
@@ -229467,7 +229563,7 @@ __export(exports_client_skills, {
|
|
|
229467
229563
|
buildClientSkillsUpdateReminder: () => buildClientSkillsUpdateReminder,
|
|
229468
229564
|
buildClientSkillsPayload: () => buildClientSkillsPayload
|
|
229469
229565
|
});
|
|
229470
|
-
import { existsSync as
|
|
229566
|
+
import { existsSync as existsSync42 } from "node:fs";
|
|
229471
229567
|
import { join as join56, resolve as resolve28 } from "node:path";
|
|
229472
229568
|
function getCache2() {
|
|
229473
229569
|
const global2 = globalThis;
|
|
@@ -229596,7 +229692,7 @@ function buildClientSkillsUpdateReminder(previous, current) {
|
|
|
229596
229692
|
function getMemorySkillsDirs(agentId) {
|
|
229597
229693
|
const dirs = new Set;
|
|
229598
229694
|
const scopedMemoryDir = resolveScopedMemoryDir({ agentId });
|
|
229599
|
-
if (scopedMemoryDir && scopedMemoryDir.trim().length > 0 &&
|
|
229695
|
+
if (scopedMemoryDir && scopedMemoryDir.trim().length > 0 && existsSync42(scopedMemoryDir)) {
|
|
229600
229696
|
dirs.add(join56(scopedMemoryDir.trim(), "skills"));
|
|
229601
229697
|
} else {
|
|
229602
229698
|
const fallbackMemoryDir = (process.env.LETTA_MEMORY_DIR || process.env.MEMORY_DIR || "").trim();
|
|
@@ -231602,7 +231698,7 @@ var init_manager2 = __esm(async () => {
|
|
|
231602
231698
|
import { createHash as createHash9, randomUUID as randomUUID31 } from "node:crypto";
|
|
231603
231699
|
import {
|
|
231604
231700
|
closeSync as closeSync6,
|
|
231605
|
-
existsSync as
|
|
231701
|
+
existsSync as existsSync43,
|
|
231606
231702
|
fsyncSync as fsyncSync3,
|
|
231607
231703
|
mkdirSync as mkdirSync31,
|
|
231608
231704
|
openSync as openSync6,
|
|
@@ -231655,7 +231751,7 @@ function mergeRecords(a2, b3) {
|
|
|
231655
231751
|
}
|
|
231656
231752
|
function readAuthorityRecords(path18) {
|
|
231657
231753
|
const records = new Map;
|
|
231658
|
-
if (!
|
|
231754
|
+
if (!existsSync43(path18))
|
|
231659
231755
|
return { records, degraded: false };
|
|
231660
231756
|
try {
|
|
231661
231757
|
const parsed = JSON.parse(readFileSync34(path18, "utf8"));
|
|
@@ -234976,7 +235072,7 @@ var init_memory_reminder = __esm(() => {
|
|
|
234976
235072
|
});
|
|
234977
235073
|
|
|
234978
235074
|
// src/agent/system-prompt-size.ts
|
|
234979
|
-
import { existsSync as
|
|
235075
|
+
import { existsSync as existsSync44, readdirSync as readdirSync15, readFileSync as readFileSync35 } from "node:fs";
|
|
234980
235076
|
import { join as join59 } from "node:path";
|
|
234981
235077
|
function estimateSystemTokens(text2) {
|
|
234982
235078
|
return Math.ceil(Buffer.byteLength(text2, "utf8") / SYSTEM_PROMPT_BYTES_PER_TOKEN);
|
|
@@ -234985,7 +235081,7 @@ function normalizePath3(value) {
|
|
|
234985
235081
|
return value.replaceAll("\\", "/");
|
|
234986
235082
|
}
|
|
234987
235083
|
function walkMarkdownFiles(dir) {
|
|
234988
|
-
if (!
|
|
235084
|
+
if (!existsSync44(dir)) {
|
|
234989
235085
|
return [];
|
|
234990
235086
|
}
|
|
234991
235087
|
const out = [];
|
|
@@ -235006,7 +235102,7 @@ function walkMarkdownFiles(dir) {
|
|
|
235006
235102
|
return out;
|
|
235007
235103
|
}
|
|
235008
235104
|
function estimateSystemPromptSize(memoryDir, localMemfs = false) {
|
|
235009
|
-
if (!
|
|
235105
|
+
if (!existsSync44(memoryDir)) {
|
|
235010
235106
|
return { total: 0, files: [] };
|
|
235011
235107
|
}
|
|
235012
235108
|
const memoryFormat = detectMemoryFormat(memoryDir, localMemfs);
|
|
@@ -235319,7 +235415,7 @@ var init_background_process_snapshot = __esm(() => {
|
|
|
235319
235415
|
});
|
|
235320
235416
|
|
|
235321
235417
|
// src/websocket/listener/constants.ts
|
|
235322
|
-
var MAX_RETRY_DURATION_MS, INITIAL_RETRY_DELAY_MS2 = 1000, MAX_RETRY_DELAY_MS = 30000, MAX_RETRY_ATTEMPTS, LISTENER_STREAM_OPEN_TIMEOUT_MS = 30000, LISTENER_HEARTBEAT_INTERVAL_MS = 30000, LISTENER_PONG_TIMEOUT_MS = 90000, SYSTEM_REMINDER_RE, LISTENER_STREAM_RESUME_POLICY, LLM_API_ERROR_MAX_RETRIES = 3, CLOUD_API_DEPLOYMENT_RECOVERY_MAX_ATTEMPTS = 3, EMPTY_RESPONSE_MAX_RETRIES = 2, MAX_PRE_STREAM_RECOVERY = 2, MAX_POST_STOP_APPROVAL_RECOVERY = 2;
|
|
235418
|
+
var CLOUD_ENVIRONMENT_NOT_FOUND_CLOSE_REASON = "Environment not found", MAX_RETRY_DURATION_MS, INITIAL_RETRY_DELAY_MS2 = 1000, MAX_RETRY_DELAY_MS = 30000, MAX_RETRY_ATTEMPTS, LISTENER_STREAM_OPEN_TIMEOUT_MS = 30000, LISTENER_HEARTBEAT_INTERVAL_MS = 30000, LISTENER_PONG_TIMEOUT_MS = 90000, SYSTEM_REMINDER_RE, LISTENER_STREAM_RESUME_POLICY, LLM_API_ERROR_MAX_RETRIES = 3, CLOUD_API_DEPLOYMENT_RECOVERY_MAX_ATTEMPTS = 3, EMPTY_RESPONSE_MAX_RETRIES = 2, MAX_PRE_STREAM_RECOVERY = 2, MAX_POST_STOP_APPROVAL_RECOVERY = 2;
|
|
235323
235419
|
var init_constants3 = __esm(() => {
|
|
235324
235420
|
MAX_RETRY_DURATION_MS = 5 * 60 * 1000;
|
|
235325
235421
|
MAX_RETRY_ATTEMPTS = Math.ceil(Math.log2(MAX_RETRY_DURATION_MS / INITIAL_RETRY_DELAY_MS2));
|
|
@@ -235332,11 +235428,11 @@ var init_constants3 = __esm(() => {
|
|
|
235332
235428
|
});
|
|
235333
235429
|
|
|
235334
235430
|
// src/cli/helpers/git-context.ts
|
|
235335
|
-
import { execFile as execFile13, execFileSync as
|
|
235431
|
+
import { execFile as execFile13, execFileSync as execFileSync10 } from "node:child_process";
|
|
235336
235432
|
import { promisify as promisify13 } from "node:util";
|
|
235337
235433
|
function runGit2(args, cwd2) {
|
|
235338
235434
|
try {
|
|
235339
|
-
return
|
|
235435
|
+
return execFileSync10("git", args, {
|
|
235340
235436
|
cwd: cwd2,
|
|
235341
235437
|
encoding: "utf-8",
|
|
235342
235438
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -235346,15 +235442,20 @@ function runGit2(args, cwd2) {
|
|
|
235346
235442
|
return null;
|
|
235347
235443
|
}
|
|
235348
235444
|
}
|
|
235349
|
-
async function runGitAsync(args, cwd2) {
|
|
235445
|
+
async function runGitAsync(args, cwd2, timeoutMs) {
|
|
235350
235446
|
try {
|
|
235351
235447
|
const { stdout } = await execFileAsync8("git", args, {
|
|
235352
235448
|
cwd: cwd2,
|
|
235353
235449
|
encoding: "utf-8",
|
|
235354
|
-
windowsHide: true
|
|
235450
|
+
windowsHide: true,
|
|
235451
|
+
timeout: timeoutMs,
|
|
235452
|
+
killSignal: "SIGKILL"
|
|
235355
235453
|
});
|
|
235356
235454
|
return stdout.trim();
|
|
235357
|
-
} catch {
|
|
235455
|
+
} catch (error5) {
|
|
235456
|
+
if (error5?.killed) {
|
|
235457
|
+
throw new Error(`git ${args[0] ?? ""} timed out after ${timeoutMs}ms`);
|
|
235458
|
+
}
|
|
235358
235459
|
return null;
|
|
235359
235460
|
}
|
|
235360
235461
|
}
|
|
@@ -235419,22 +235520,23 @@ function gatherGitContextSnapshot(options = {}) {
|
|
|
235419
235520
|
gitUser
|
|
235420
235521
|
};
|
|
235421
235522
|
}
|
|
235422
|
-
async function getGitContextAsync(cwd2) {
|
|
235423
|
-
|
|
235523
|
+
async function getGitContextAsync(cwd2, options = {}) {
|
|
235524
|
+
const timeoutMs = options.timeoutMs ?? GIT_ASYNC_TIMEOUT_MS;
|
|
235525
|
+
if (!await runGitAsync(["rev-parse", "--git-dir"], cwd2, timeoutMs)) {
|
|
235424
235526
|
return null;
|
|
235425
235527
|
}
|
|
235426
|
-
const branch = await runGitAsync(["branch", "--show-current"], cwd2);
|
|
235528
|
+
const branch = await runGitAsync(["branch", "--show-current"], cwd2, timeoutMs);
|
|
235427
235529
|
const branchList = await runGitAsync([
|
|
235428
235530
|
"branch",
|
|
235429
235531
|
"--sort=-committerdate",
|
|
235430
235532
|
"--format=%(refname:short)",
|
|
235431
235533
|
"--no-color"
|
|
235432
|
-
], cwd2);
|
|
235534
|
+
], cwd2, timeoutMs);
|
|
235433
235535
|
const recentBranches = branchList ? branchList.split(`
|
|
235434
235536
|
`).map((b3) => b3.trim()).filter((b3) => b3.length > 0 && b3 !== branch).slice(0, 10) : [];
|
|
235435
235537
|
return { branch, recent_branches: recentBranches };
|
|
235436
235538
|
}
|
|
235437
|
-
var execFileAsync8;
|
|
235539
|
+
var execFileAsync8, GIT_ASYNC_TIMEOUT_MS = 1e4;
|
|
235438
235540
|
var init_git_context = __esm(() => {
|
|
235439
235541
|
execFileAsync8 = promisify13(execFile13);
|
|
235440
235542
|
});
|
|
@@ -235472,7 +235574,7 @@ class DeviceGitContextCache {
|
|
|
235472
235574
|
});
|
|
235473
235575
|
this.prune();
|
|
235474
235576
|
return value;
|
|
235475
|
-
}).finally(() => {
|
|
235577
|
+
}, () => this.entries.get(cwd2)?.value ?? null).finally(() => {
|
|
235476
235578
|
this.pending.delete(cwd2);
|
|
235477
235579
|
});
|
|
235478
235580
|
this.pending.set(cwd2, load);
|
|
@@ -235914,39 +236016,6 @@ function enqueueInboundUserMessage(runtime, incoming, actingUserId, options = {}
|
|
|
235914
236016
|
}
|
|
235915
236017
|
|
|
235916
236018
|
// src/websocket/listener/turn-correlation.ts
|
|
235917
|
-
function mergeTurnCorrelationIndexes(...sources) {
|
|
235918
|
-
const merged = new Map;
|
|
235919
|
-
for (const source of sources) {
|
|
235920
|
-
for (const [conversationKey, runs2] of source ?? []) {
|
|
235921
|
-
const mergedRuns = merged.get(conversationKey) ?? new Map;
|
|
235922
|
-
for (const [runId, clientMessageIds] of runs2) {
|
|
235923
|
-
const mergedClientMessageIds = [
|
|
235924
|
-
...new Set([...mergedRuns.get(runId) ?? [], ...clientMessageIds])
|
|
235925
|
-
].slice(-MAX_CLIENT_MESSAGE_IDS_PER_RUN);
|
|
235926
|
-
mergedRuns.delete(runId);
|
|
235927
|
-
mergedRuns.set(runId, mergedClientMessageIds);
|
|
235928
|
-
while (mergedRuns.size > MAX_RECENT_RUN_CORRELATIONS) {
|
|
235929
|
-
const oldestRunId = mergedRuns.keys().next().value;
|
|
235930
|
-
if (!oldestRunId)
|
|
235931
|
-
break;
|
|
235932
|
-
mergedRuns.delete(oldestRunId);
|
|
235933
|
-
}
|
|
235934
|
-
}
|
|
235935
|
-
merged.delete(conversationKey);
|
|
235936
|
-
merged.set(conversationKey, mergedRuns);
|
|
235937
|
-
while (merged.size > MAX_RECENT_CONVERSATIONS) {
|
|
235938
|
-
const oldestConversationKey = merged.keys().next().value;
|
|
235939
|
-
if (!oldestConversationKey)
|
|
235940
|
-
break;
|
|
235941
|
-
merged.delete(oldestConversationKey);
|
|
235942
|
-
}
|
|
235943
|
-
}
|
|
235944
|
-
}
|
|
235945
|
-
return merged;
|
|
235946
|
-
}
|
|
235947
|
-
function cloneTurnCorrelationIndex(source) {
|
|
235948
|
-
return mergeTurnCorrelationIndexes(source);
|
|
235949
|
-
}
|
|
235950
236019
|
function takeDequeuedClientMessageIds(runtime, batchId) {
|
|
235951
236020
|
const clientMessageIds = runtime.dequeuedClientMessageIdsByBatchId.get(batchId) ?? [];
|
|
235952
236021
|
runtime.dequeuedClientMessageIdsByBatchId.delete(batchId);
|
|
@@ -237007,7 +237076,7 @@ async function resolveDefaultBaseRef(repoRoot) {
|
|
|
237007
237076
|
const branch = currentBranch.stdout.trim();
|
|
237008
237077
|
return currentBranch.exitCode === 0 && branch && branch !== "HEAD" ? branch : "HEAD";
|
|
237009
237078
|
}
|
|
237010
|
-
function
|
|
237079
|
+
function isPathWithin2(child, parent) {
|
|
237011
237080
|
const resolvedChild = path21.resolve(child);
|
|
237012
237081
|
const resolvedParent = path21.resolve(parent);
|
|
237013
237082
|
return resolvedChild === resolvedParent || resolvedChild.startsWith(resolvedParent + path21.sep);
|
|
@@ -237368,7 +237437,7 @@ async function claimWorktreeLock(params) {
|
|
|
237368
237437
|
if (result2.outcome === "conflict") {
|
|
237369
237438
|
throw new Error(formatLockConflict(result2.heldBy, params.worktreePath));
|
|
237370
237439
|
}
|
|
237371
|
-
if (
|
|
237440
|
+
if (isPathWithin2(params.previousCwd, params.managedDir)) {
|
|
237372
237441
|
const previousGitDir = await resolveWorktreeGitDir(params.previousCwd);
|
|
237373
237442
|
if (previousGitDir && previousGitDir !== targetGitDir) {
|
|
237374
237443
|
await releaseWorktreeLock({ worktreeGitDir: previousGitDir, owner });
|
|
@@ -238210,7 +238279,7 @@ No worktree session to exit.`, "success");
|
|
|
238210
238279
|
}
|
|
238211
238280
|
const primaryRoot = await resolvePrimaryWorktreeRoot(repoRoot);
|
|
238212
238281
|
const managedDir = path24.join(primaryRoot, ".letta", "worktrees");
|
|
238213
|
-
if (!
|
|
238282
|
+
if (!isPathWithin2(currentCwd, managedDir)) {
|
|
238214
238283
|
return textResult([
|
|
238215
238284
|
`Not in a managed worktree (current directory: ${currentCwd}).`,
|
|
238216
238285
|
"ExitWorktree only applies to worktrees under .letta/worktrees/; nothing to do."
|
|
@@ -238667,8 +238736,8 @@ var require_constants2 = __commonJS((exports, module3) => {
|
|
|
238667
238736
|
"@": { type: "at", open: "(?:", close: ")" }
|
|
238668
238737
|
};
|
|
238669
238738
|
},
|
|
238670
|
-
globChars(
|
|
238671
|
-
return
|
|
238739
|
+
globChars(win326) {
|
|
238740
|
+
return win326 === true ? WINDOWS_CHARS : POSIX_CHARS;
|
|
238672
238741
|
}
|
|
238673
238742
|
};
|
|
238674
238743
|
});
|
|
@@ -238676,7 +238745,7 @@ var require_constants2 = __commonJS((exports, module3) => {
|
|
|
238676
238745
|
// node_modules/picomatch/lib/utils.js
|
|
238677
238746
|
var require_utils2 = __commonJS((exports) => {
|
|
238678
238747
|
var path27 = __require("path");
|
|
238679
|
-
var
|
|
238748
|
+
var win326 = process.platform === "win32";
|
|
238680
238749
|
var {
|
|
238681
238750
|
REGEX_BACKSLASH,
|
|
238682
238751
|
REGEX_REMOVE_BACKSLASH,
|
|
@@ -238704,7 +238773,7 @@ var require_utils2 = __commonJS((exports) => {
|
|
|
238704
238773
|
if (options && typeof options.windows === "boolean") {
|
|
238705
238774
|
return options.windows;
|
|
238706
238775
|
}
|
|
238707
|
-
return
|
|
238776
|
+
return win326 === true || path27.sep === "\\";
|
|
238708
238777
|
};
|
|
238709
238778
|
exports.escapeLast = (input, char, lastIdx) => {
|
|
238710
238779
|
const idx = input.lastIndexOf(char, lastIdx);
|
|
@@ -239089,8 +239158,8 @@ var require_parse3 = __commonJS((exports, module3) => {
|
|
|
239089
239158
|
const bos = { type: "bos", value: "", output: opts.prepend || "" };
|
|
239090
239159
|
const tokens = [bos];
|
|
239091
239160
|
const capture = opts.capture ? "" : "?:";
|
|
239092
|
-
const
|
|
239093
|
-
const PLATFORM_CHARS = constants6.globChars(
|
|
239161
|
+
const win326 = utils.isWindows(options);
|
|
239162
|
+
const PLATFORM_CHARS = constants6.globChars(win326);
|
|
239094
239163
|
const EXTGLOB_CHARS = constants6.extglobChars(PLATFORM_CHARS);
|
|
239095
239164
|
const {
|
|
239096
239165
|
DOT_LITERAL,
|
|
@@ -239324,9 +239393,9 @@ var require_parse3 = __commonJS((exports, module3) => {
|
|
|
239324
239393
|
const idx = prev.value.lastIndexOf("[");
|
|
239325
239394
|
const pre = prev.value.slice(0, idx);
|
|
239326
239395
|
const rest5 = prev.value.slice(idx + 2);
|
|
239327
|
-
const
|
|
239328
|
-
if (
|
|
239329
|
-
prev.value = pre +
|
|
239396
|
+
const posix4 = POSIX_REGEX_SOURCE[rest5];
|
|
239397
|
+
if (posix4) {
|
|
239398
|
+
prev.value = pre + posix4;
|
|
239330
239399
|
state2.backtrack = true;
|
|
239331
239400
|
advance();
|
|
239332
239401
|
if (!bos.output && tokens.indexOf(prev) === 1) {
|
|
@@ -239762,7 +239831,7 @@ var require_parse3 = __commonJS((exports, module3) => {
|
|
|
239762
239831
|
throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max2}`);
|
|
239763
239832
|
}
|
|
239764
239833
|
input = REPLACEMENTS[input] || input;
|
|
239765
|
-
const
|
|
239834
|
+
const win326 = utils.isWindows(options);
|
|
239766
239835
|
const {
|
|
239767
239836
|
DOT_LITERAL,
|
|
239768
239837
|
SLASH_LITERAL,
|
|
@@ -239773,7 +239842,7 @@ var require_parse3 = __commonJS((exports, module3) => {
|
|
|
239773
239842
|
NO_DOTS_SLASH,
|
|
239774
239843
|
STAR,
|
|
239775
239844
|
START_ANCHOR
|
|
239776
|
-
} = constants6.globChars(
|
|
239845
|
+
} = constants6.globChars(win326);
|
|
239777
239846
|
const nodot = opts.dot ? NO_DOTS : NO_DOT;
|
|
239778
239847
|
const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
|
|
239779
239848
|
const capture = opts.capture ? "" : "?:";
|
|
@@ -239852,7 +239921,7 @@ var require_picomatch = __commonJS((exports, module3) => {
|
|
|
239852
239921
|
throw new TypeError("Expected pattern to be a non-empty string");
|
|
239853
239922
|
}
|
|
239854
239923
|
const opts = options || {};
|
|
239855
|
-
const
|
|
239924
|
+
const posix4 = utils.isWindows(options);
|
|
239856
239925
|
const regex4 = isState ? picomatch.compileRe(glob3, options) : picomatch.makeRe(glob3, options, false, true);
|
|
239857
239926
|
const state2 = regex4.state;
|
|
239858
239927
|
delete regex4.state;
|
|
@@ -239862,8 +239931,8 @@ var require_picomatch = __commonJS((exports, module3) => {
|
|
|
239862
239931
|
isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);
|
|
239863
239932
|
}
|
|
239864
239933
|
const matcher = (input, returnObject = false) => {
|
|
239865
|
-
const { isMatch: isMatch2, match: match3, output } = picomatch.test(input, regex4, options, { glob: glob3, posix:
|
|
239866
|
-
const result2 = { glob: glob3, state: state2, regex: regex4, posix:
|
|
239934
|
+
const { isMatch: isMatch2, match: match3, output } = picomatch.test(input, regex4, options, { glob: glob3, posix: posix4 });
|
|
239935
|
+
const result2 = { glob: glob3, state: state2, regex: regex4, posix: posix4, input, output, match: match3, isMatch: isMatch2 };
|
|
239867
239936
|
if (typeof opts.onResult === "function") {
|
|
239868
239937
|
opts.onResult(result2);
|
|
239869
239938
|
}
|
|
@@ -239888,7 +239957,7 @@ var require_picomatch = __commonJS((exports, module3) => {
|
|
|
239888
239957
|
}
|
|
239889
239958
|
return matcher;
|
|
239890
239959
|
};
|
|
239891
|
-
picomatch.test = (input, regex4, options, { glob: glob3, posix:
|
|
239960
|
+
picomatch.test = (input, regex4, options, { glob: glob3, posix: posix4 } = {}) => {
|
|
239892
239961
|
if (typeof input !== "string") {
|
|
239893
239962
|
throw new TypeError("Expected input to be a string");
|
|
239894
239963
|
}
|
|
@@ -239896,7 +239965,7 @@ var require_picomatch = __commonJS((exports, module3) => {
|
|
|
239896
239965
|
return { isMatch: false, output: "" };
|
|
239897
239966
|
}
|
|
239898
239967
|
const opts = options || {};
|
|
239899
|
-
const format6 = opts.format || (
|
|
239968
|
+
const format6 = opts.format || (posix4 ? utils.toPosixSlashes : null);
|
|
239900
239969
|
let match3 = input === glob3;
|
|
239901
239970
|
let output = match3 && format6 ? format6(input) : input;
|
|
239902
239971
|
if (match3 === false) {
|
|
@@ -239905,14 +239974,14 @@ var require_picomatch = __commonJS((exports, module3) => {
|
|
|
239905
239974
|
}
|
|
239906
239975
|
if (match3 === false || opts.capture === true) {
|
|
239907
239976
|
if (opts.matchBase === true || opts.basename === true) {
|
|
239908
|
-
match3 = picomatch.matchBase(input, regex4, options,
|
|
239977
|
+
match3 = picomatch.matchBase(input, regex4, options, posix4);
|
|
239909
239978
|
} else {
|
|
239910
239979
|
match3 = regex4.exec(output);
|
|
239911
239980
|
}
|
|
239912
239981
|
}
|
|
239913
239982
|
return { isMatch: Boolean(match3), match: match3, output };
|
|
239914
239983
|
};
|
|
239915
|
-
picomatch.matchBase = (input, glob3, options,
|
|
239984
|
+
picomatch.matchBase = (input, glob3, options, posix4 = utils.isWindows(options)) => {
|
|
239916
239985
|
const regex4 = glob3 instanceof RegExp ? glob3 : picomatch.makeRe(glob3, options);
|
|
239917
239986
|
return regex4.test(path27.basename(input));
|
|
239918
239987
|
};
|
|
@@ -240308,7 +240377,7 @@ function buildCloudScheduleInput(params) {
|
|
|
240308
240377
|
}
|
|
240309
240378
|
const targetDeviceId = params.targetDeviceId?.trim();
|
|
240310
240379
|
if (targetDeviceId) {
|
|
240311
|
-
notes.push(
|
|
240380
|
+
notes.push(CLOUD_DEVICE_OFFLINE_NOTE);
|
|
240312
240381
|
}
|
|
240313
240382
|
return {
|
|
240314
240383
|
input: {
|
|
@@ -240322,7 +240391,7 @@ function buildCloudScheduleInput(params) {
|
|
|
240322
240391
|
notes
|
|
240323
240392
|
};
|
|
240324
240393
|
}
|
|
240325
|
-
var CLOUD_EXECUTION_TARGET = "cloud-sandbox", SYNTHETIC_CLOUD_DEVICE_ID = "__letta_cloud__", SYNTHETIC_LOCAL_PLACEHOLDER_ID = "local", CLOUD_CRON_UTC_NOTE = "Recurring Cloud schedules currently interpret cron expressions in UTC (timezone support is tracked in LET-9815).",
|
|
240394
|
+
var CLOUD_EXECUTION_TARGET = "cloud-sandbox", SYNTHETIC_CLOUD_DEVICE_ID = "__letta_cloud__", SYNTHETIC_LOCAL_PLACEHOLDER_ID = "local", CLOUD_CRON_UTC_NOTE = "Recurring Cloud schedules currently interpret cron expressions in UTC (timezone support is tracked in LET-9815).", CLOUD_DEVICE_OFFLINE_NOTE = "If the target computer is offline when the schedule fires, that occurrence fails (TARGET_DEVICE_UNAVAILABLE) and does not run; omit --computer to run in the Cloud sandbox.";
|
|
240326
240395
|
var init_runner = __esm(() => {
|
|
240327
240396
|
init_request();
|
|
240328
240397
|
init_schedules();
|
|
@@ -243307,7 +243376,7 @@ class CodexAppServerClient {
|
|
|
243307
243376
|
await this.request("initialize", {
|
|
243308
243377
|
clientInfo: {
|
|
243309
243378
|
name: "letta-code",
|
|
243310
|
-
version: "0.34.
|
|
243379
|
+
version: "0.34.24"
|
|
243311
243380
|
},
|
|
243312
243381
|
capabilities: null
|
|
243313
243382
|
});
|
|
@@ -244017,7 +244086,7 @@ var init_conversation_bootstrap = __esm(() => {
|
|
|
244017
244086
|
|
|
244018
244087
|
// src/cli/helpers/session-context.ts
|
|
244019
244088
|
import { platform as platform7 } from "node:os";
|
|
244020
|
-
import { basename as
|
|
244089
|
+
import { basename as basename21 } from "node:path";
|
|
244021
244090
|
function getLocalTime() {
|
|
244022
244091
|
const now2 = new Date;
|
|
244023
244092
|
return now2.toLocaleString(undefined, {
|
|
@@ -244061,7 +244130,7 @@ function getGitInfo(cwd2) {
|
|
|
244061
244130
|
};
|
|
244062
244131
|
}
|
|
244063
244132
|
function buildUnixShellLine(shellContext) {
|
|
244064
|
-
const shellName =
|
|
244133
|
+
const shellName = basename21(shellContext.displayName) || shellContext.displayName;
|
|
244065
244134
|
return `- **Shell**: ${shellName}
|
|
244066
244135
|
`;
|
|
244067
244136
|
}
|
|
@@ -246771,7 +246840,7 @@ function isAppServerInfoResponseMessage(message2) {
|
|
|
246771
246840
|
return false;
|
|
246772
246841
|
}
|
|
246773
246842
|
const capabilityRecord = capabilities;
|
|
246774
|
-
return candidate.type === "app_server_info_response" && typeof candidate.request_id === "string" && candidate.request_id.length > 0 && candidate.success === true && (candidate.backend === "local" || candidate.backend === "api") && typeof candidate.letta_code_version === "string" && typeof candidate.protocol_version === "number" && Number.isInteger(candidate.protocol_version) && typeof capabilityRecord.agent_management === "boolean" && typeof capabilityRecord.conversation_management === "boolean" && typeof capabilityRecord.memory_management === "boolean" && typeof capabilityRecord.runtime_start === "boolean" && (capabilityRecord.agent_free_conversations === undefined || typeof capabilityRecord.agent_free_conversations === "boolean") && (capabilityRecord.launch_subagent === undefined || typeof capabilityRecord.launch_subagent === "boolean") && (capabilityRecord.launch_subagent_notify_caller === undefined || typeof capabilityRecord.launch_subagent_notify_caller === "boolean") && (capabilityRecord.subagent_message === undefined || typeof capabilityRecord.subagent_message === "boolean") && (capabilityRecord.runtime_workspace_sandbox === undefined || typeof capabilityRecord.runtime_workspace_sandbox === "boolean") && (capabilityRecord.runtime_external_tools_update === undefined || typeof capabilityRecord.runtime_external_tools_update === "boolean") && (capabilityRecord.structured_outputs === undefined || typeof capabilityRecord.structured_outputs === "boolean") && (capabilityRecord.write_file_base64 === undefined || typeof capabilityRecord.write_file_base64 === "boolean") &&
|
|
246843
|
+
return candidate.type === "app_server_info_response" && typeof candidate.request_id === "string" && candidate.request_id.length > 0 && candidate.success === true && (candidate.backend === "local" || candidate.backend === "api") && typeof candidate.letta_code_version === "string" && typeof candidate.protocol_version === "number" && Number.isInteger(candidate.protocol_version) && typeof capabilityRecord.agent_management === "boolean" && typeof capabilityRecord.conversation_management === "boolean" && typeof capabilityRecord.memory_management === "boolean" && typeof capabilityRecord.runtime_start === "boolean" && (capabilityRecord.agent_free_conversations === undefined || typeof capabilityRecord.agent_free_conversations === "boolean") && (capabilityRecord.launch_subagent === undefined || typeof capabilityRecord.launch_subagent === "boolean") && (capabilityRecord.launch_subagent_notify_caller === undefined || typeof capabilityRecord.launch_subagent_notify_caller === "boolean") && (capabilityRecord.subagent_message === undefined || typeof capabilityRecord.subagent_message === "boolean") && (capabilityRecord.runtime_workspace_sandbox === undefined || typeof capabilityRecord.runtime_workspace_sandbox === "boolean") && (capabilityRecord.runtime_external_tools_update === undefined || typeof capabilityRecord.runtime_external_tools_update === "boolean") && (capabilityRecord.structured_outputs === undefined || typeof capabilityRecord.structured_outputs === "boolean") && (capabilityRecord.write_file_base64 === undefined || typeof capabilityRecord.write_file_base64 === "boolean") && typeof capabilityRecord.split_channels === "boolean";
|
|
246775
246844
|
}
|
|
246776
246845
|
var APP_SERVER_PROTOCOL_VERSION = 1;
|
|
246777
246846
|
|
|
@@ -248740,7 +248809,7 @@ var init_memory_operation = __esm(() => {
|
|
|
248740
248809
|
// src/agent/memory-worktree.ts
|
|
248741
248810
|
import { execFile as execFileCb4 } from "node:child_process";
|
|
248742
248811
|
import { randomUUID as randomUUID41 } from "node:crypto";
|
|
248743
|
-
import { existsSync as
|
|
248812
|
+
import { existsSync as existsSync45 } from "node:fs";
|
|
248744
248813
|
import { mkdir as mkdir12 } from "node:fs/promises";
|
|
248745
248814
|
import { dirname as dirname29, isAbsolute as isAbsolute23, join as join67, resolve as resolve36 } from "node:path";
|
|
248746
248815
|
import { promisify as promisify17 } from "node:util";
|
|
@@ -248932,7 +249001,7 @@ async function inspectReflectionMemoryWorktree(worktree) {
|
|
|
248932
249001
|
};
|
|
248933
249002
|
}
|
|
248934
249003
|
async function cleanupWorktreeAndBranch(parentMemoryDir, worktreeDir, branchName, options = {}) {
|
|
248935
|
-
const removedWorktree =
|
|
249004
|
+
const removedWorktree = existsSync45(worktreeDir);
|
|
248936
249005
|
if (removedWorktree) {
|
|
248937
249006
|
await runGit4(parentMemoryDir, [
|
|
248938
249007
|
"worktree",
|
|
@@ -248948,7 +249017,7 @@ async function cleanupWorktreeAndBranch(parentMemoryDir, worktreeDir, branchName
|
|
|
248948
249017
|
]);
|
|
248949
249018
|
}
|
|
248950
249019
|
async function finalizeReflectionMemoryWorktreeUnlocked(worktree, options) {
|
|
248951
|
-
if (!
|
|
249020
|
+
if (!existsSync45(worktree.worktreeDir) && options.knownNoChanges) {
|
|
248952
249021
|
const branchHead = (await tryRunGit(worktree.parentMemoryDir, [
|
|
248953
249022
|
"rev-parse",
|
|
248954
249023
|
"--verify",
|
|
@@ -249135,7 +249204,7 @@ async function integrateMemoryWorkerWorktree(worktree, options = {}) {
|
|
|
249135
249204
|
await cleanup(true);
|
|
249136
249205
|
return { status: "no_changes" };
|
|
249137
249206
|
}
|
|
249138
|
-
if (
|
|
249207
|
+
if (existsSync45(worktree.worktreeDir)) {
|
|
249139
249208
|
await runGit4(worktree.parentMemoryDir, [
|
|
249140
249209
|
"worktree",
|
|
249141
249210
|
"remove",
|
|
@@ -250694,6 +250763,8 @@ function trackExternalFollowupCompletion(args) {
|
|
|
250694
250763
|
existingAgentId: args.agentId,
|
|
250695
250764
|
toolCallId: args.toolCallId,
|
|
250696
250765
|
publishResult: args.publishResult,
|
|
250766
|
+
emitCompletionNotification: args.emitCompletionNotification,
|
|
250767
|
+
claimsParentRuntime: args.claimsParentRuntime,
|
|
250697
250768
|
parentScope: args.parentScope,
|
|
250698
250769
|
actingUserId: args.parentScope.actingUserId,
|
|
250699
250770
|
deps: {
|
|
@@ -251198,7 +251269,7 @@ __export(exports_skill, {
|
|
|
251198
251269
|
loadRenderedSkillContent: () => loadRenderedSkillContent,
|
|
251199
251270
|
getResolvedSkillsDir: () => getResolvedSkillsDir
|
|
251200
251271
|
});
|
|
251201
|
-
import { existsSync as
|
|
251272
|
+
import { existsSync as existsSync46, readdirSync as readdirSync17 } from "node:fs";
|
|
251202
251273
|
import { readFile as readFile17 } from "node:fs/promises";
|
|
251203
251274
|
import { dirname as dirname30, join as join68 } from "node:path";
|
|
251204
251275
|
async function readSkillFromRoot(skillsRoot, skillId) {
|
|
@@ -251220,7 +251291,7 @@ async function readSkillFromRoot(skillsRoot, skillId) {
|
|
|
251220
251291
|
function getMemorySkillsDirs2(agentId) {
|
|
251221
251292
|
const dirs = new Set;
|
|
251222
251293
|
const scopedMemoryDir = resolveScopedMemoryDir({ agentId });
|
|
251223
|
-
if (scopedMemoryDir && scopedMemoryDir.trim().length > 0 &&
|
|
251294
|
+
if (scopedMemoryDir && scopedMemoryDir.trim().length > 0 && existsSync46(scopedMemoryDir)) {
|
|
251224
251295
|
dirs.add(join68(scopedMemoryDir.trim(), "skills"));
|
|
251225
251296
|
} else {
|
|
251226
251297
|
const fallbackMemoryDir = (process.env.LETTA_MEMORY_DIR || process.env.MEMORY_DIR || "").trim();
|
|
@@ -252797,7 +252868,7 @@ var init_watch_pr = __esm(async () => {
|
|
|
252797
252868
|
});
|
|
252798
252869
|
|
|
252799
252870
|
// src/tools/workflow/sdk-loader.ts
|
|
252800
|
-
import { existsSync as
|
|
252871
|
+
import { existsSync as existsSync47, readFileSync as readFileSync37 } from "node:fs";
|
|
252801
252872
|
import { createRequire as createRequire6 } from "node:module";
|
|
252802
252873
|
import { dirname as dirname31, join as join69 } from "node:path";
|
|
252803
252874
|
import { fileURLToPath as fileURLToPath7, pathToFileURL as pathToFileURL3 } from "node:url";
|
|
@@ -252821,7 +252892,7 @@ function preferRunningCliForSubagents() {
|
|
|
252821
252892
|
if (process.env.LETTA_CLI_PATH)
|
|
252822
252893
|
return;
|
|
252823
252894
|
const entry = process.argv[1];
|
|
252824
|
-
if (entry && /(^|[\\/])letta\.js$/.test(entry) &&
|
|
252895
|
+
if (entry && /(^|[\\/])letta\.js$/.test(entry) && existsSync47(entry)) {
|
|
252825
252896
|
process.env.LETTA_CLI_PATH = entry;
|
|
252826
252897
|
}
|
|
252827
252898
|
}
|
|
@@ -252852,7 +252923,7 @@ function probeInstalledSdkDirs(startDirs) {
|
|
|
252852
252923
|
let dir = start2;
|
|
252853
252924
|
while (true) {
|
|
252854
252925
|
const candidate = join69(dir, "node_modules", ...SDK_PACKAGE.split("/"));
|
|
252855
|
-
if (
|
|
252926
|
+
if (existsSync47(join69(candidate, "package.json")) && !found.includes(candidate)) {
|
|
252856
252927
|
found.push(candidate);
|
|
252857
252928
|
}
|
|
252858
252929
|
const parent = dirname31(dir);
|
|
@@ -255325,15 +255396,28 @@ var init_interrupted_turn_schema = __esm(async () => {
|
|
|
255325
255396
|
await init_teleport_protocol_inbound();
|
|
255326
255397
|
});
|
|
255327
255398
|
|
|
255399
|
+
// src/utils/rename-sync-with-retry.ts
|
|
255400
|
+
import { renameSync as renameSync10 } from "node:fs";
|
|
255401
|
+
function renameSyncWithRetry(source, destination, platform9 = process.platform, rename3 = renameSync10) {
|
|
255402
|
+
const sleeper = new Int32Array(new SharedArrayBuffer(4));
|
|
255403
|
+
for (let attempt2 = 0;; attempt2++) {
|
|
255404
|
+
try {
|
|
255405
|
+
rename3(source, destination);
|
|
255406
|
+
return;
|
|
255407
|
+
} catch (error5) {
|
|
255408
|
+
const code2 = error5.code;
|
|
255409
|
+
if (platform9 !== "win32" || attempt2 >= 9 || !["EPERM", "EACCES", "EBUSY"].includes(code2 ?? "")) {
|
|
255410
|
+
throw error5;
|
|
255411
|
+
}
|
|
255412
|
+
Atomics.wait(sleeper, 0, 0, 10 * (attempt2 + 1));
|
|
255413
|
+
}
|
|
255414
|
+
}
|
|
255415
|
+
}
|
|
255416
|
+
var init_rename_sync_with_retry = () => {};
|
|
255417
|
+
|
|
255328
255418
|
// src/websocket/listener/interrupted-turn-storage.ts
|
|
255329
255419
|
import { createHash as createHash11 } from "node:crypto";
|
|
255330
|
-
import {
|
|
255331
|
-
closeSync as closeSync7,
|
|
255332
|
-
fsyncSync as fsyncSync4,
|
|
255333
|
-
openSync as openSync7,
|
|
255334
|
-
renameSync as renameSync10,
|
|
255335
|
-
writeFileSync as writeFileSync29
|
|
255336
|
-
} from "node:fs";
|
|
255420
|
+
import { closeSync as closeSync7, fsyncSync as fsyncSync4, openSync as openSync7, writeFileSync as writeFileSync29 } from "node:fs";
|
|
255337
255421
|
import { homedir as homedir35 } from "node:os";
|
|
255338
255422
|
import { join as join71 } from "node:path";
|
|
255339
255423
|
function writeInterruptedTurnRecordFile(temporary, destination, directory, record6, syncDirectory) {
|
|
@@ -255341,7 +255425,7 @@ function writeInterruptedTurnRecordFile(temporary, destination, directory, recor
|
|
|
255341
255425
|
mode: 384,
|
|
255342
255426
|
flush: true
|
|
255343
255427
|
});
|
|
255344
|
-
|
|
255428
|
+
renameSyncWithRetry(temporary, destination);
|
|
255345
255429
|
syncDirectory(directory);
|
|
255346
255430
|
}
|
|
255347
255431
|
function fsyncInterruptedTurnDirectory(directory, platform9 = process.platform) {
|
|
@@ -255365,6 +255449,7 @@ function defaultInterruptedTurnDirectory() {
|
|
|
255365
255449
|
}
|
|
255366
255450
|
var init_interrupted_turn_storage = __esm(() => {
|
|
255367
255451
|
init_server_url();
|
|
255452
|
+
init_rename_sync_with_retry();
|
|
255368
255453
|
});
|
|
255369
255454
|
|
|
255370
255455
|
// src/websocket/listener/recorded-tool-results.ts
|
|
@@ -255430,11 +255515,10 @@ function createRecoveryAuthorityGuard(dependencies4) {
|
|
|
255430
255515
|
// src/websocket/listener/recovery-lineage-sidecar.ts
|
|
255431
255516
|
import { createHash as createHash12, randomUUID as randomUUID44 } from "node:crypto";
|
|
255432
255517
|
import {
|
|
255433
|
-
existsSync as
|
|
255518
|
+
existsSync as existsSync48,
|
|
255434
255519
|
mkdirSync as mkdirSync35,
|
|
255435
255520
|
readdirSync as readdirSync18,
|
|
255436
255521
|
readFileSync as readFileSync39,
|
|
255437
|
-
renameSync as renameSync11,
|
|
255438
255522
|
rmSync as rmSync18,
|
|
255439
255523
|
statSync as statSync19,
|
|
255440
255524
|
writeFileSync as writeFileSync30
|
|
@@ -255475,7 +255559,7 @@ function createRecoveryLineageSidecarAccess(params) {
|
|
|
255475
255559
|
mode: 384,
|
|
255476
255560
|
flush: true
|
|
255477
255561
|
});
|
|
255478
|
-
|
|
255562
|
+
renameSyncWithRetry(temporary, destination);
|
|
255479
255563
|
params.syncDirectory(params.directory);
|
|
255480
255564
|
} finally {
|
|
255481
255565
|
rmSync18(temporary, { force: true });
|
|
@@ -255725,7 +255809,7 @@ function createRecoveryLineageSidecarAccess(params) {
|
|
|
255725
255809
|
const removeMalformedOrphan = (file) => {
|
|
255726
255810
|
const separator = file.indexOf(".recovery-");
|
|
255727
255811
|
const mainFile = separator >= 0 ? file.slice(0, separator) : "";
|
|
255728
|
-
if (!mainFile ||
|
|
255812
|
+
if (!mainFile || existsSync48(join72(params.directory, mainFile)))
|
|
255729
255813
|
return;
|
|
255730
255814
|
try {
|
|
255731
255815
|
rmSync18(join72(params.directory, file), { force: true });
|
|
@@ -255807,6 +255891,7 @@ function createRecoveryLineageSidecarAccess(params) {
|
|
|
255807
255891
|
}
|
|
255808
255892
|
var sidecarWriterInstanceId;
|
|
255809
255893
|
var init_recovery_lineage_sidecar = __esm(async () => {
|
|
255894
|
+
init_rename_sync_with_retry();
|
|
255810
255895
|
init_durable_file_lock();
|
|
255811
255896
|
await init_interrupted_turn_schema();
|
|
255812
255897
|
sidecarWriterInstanceId = randomUUID44();
|
|
@@ -255815,7 +255900,7 @@ var init_recovery_lineage_sidecar = __esm(async () => {
|
|
|
255815
255900
|
// src/websocket/listener/interrupted-turn-record.ts
|
|
255816
255901
|
import { randomUUID as randomUUID45 } from "node:crypto";
|
|
255817
255902
|
import {
|
|
255818
|
-
existsSync as
|
|
255903
|
+
existsSync as existsSync49,
|
|
255819
255904
|
mkdirSync as mkdirSync36,
|
|
255820
255905
|
readFileSync as readFileSync40,
|
|
255821
255906
|
rmSync as rmSync19,
|
|
@@ -255872,7 +255957,7 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
|
|
|
255872
255957
|
const recoveryAuthority = createRecoveryAuthorityGuard({
|
|
255873
255958
|
path: path32,
|
|
255874
255959
|
readRecord: readRecord2,
|
|
255875
|
-
exists:
|
|
255960
|
+
exists: existsSync49,
|
|
255876
255961
|
acquire: (destination) => acquireDurableFileLock(destination, {
|
|
255877
255962
|
waitMs: dependencies4.lockWaitMs
|
|
255878
255963
|
}),
|
|
@@ -255906,7 +255991,7 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
|
|
|
255906
255991
|
});
|
|
255907
255992
|
try {
|
|
255908
255993
|
const current = readRecord2(destination);
|
|
255909
|
-
if (!
|
|
255994
|
+
if (!existsSync49(destination)) {
|
|
255910
255995
|
removeSidecar(sidecar);
|
|
255911
255996
|
} else if (current && current.recoveryClaimCompletion?.lineageId !== sidecar.lineageId) {
|
|
255912
255997
|
removeSidecar(sidecar);
|
|
@@ -255931,7 +256016,7 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
|
|
|
255931
256016
|
},
|
|
255932
256017
|
listDurableInputOwnership() {
|
|
255933
256018
|
const snapshot2 = rawSnapshot();
|
|
255934
|
-
return collectInterruptedTurnInputOwnershipWithSidecars(snapshot2.records, readMainView, listSidecars(), (agentId, conversationId) =>
|
|
256019
|
+
return collectInterruptedTurnInputOwnershipWithSidecars(snapshot2.records, readMainView, listSidecars(), (agentId, conversationId) => existsSync49(path32(agentId, conversationId)), snapshot2.unreadableScopes);
|
|
255935
256020
|
},
|
|
255936
256021
|
read(agentId, conversationId) {
|
|
255937
256022
|
const current = readRecord2(path32(agentId, conversationId));
|
|
@@ -257490,7 +257575,7 @@ function socketForTransport(transport3) {
|
|
|
257490
257575
|
}
|
|
257491
257576
|
function refreshLegacySingleConnection(runtime) {
|
|
257492
257577
|
const live = [...runtime.connections.values()].filter((connection) => isListenerTransportOpen(connection.writer));
|
|
257493
|
-
const only = live.length === 1 ? live[0] : null;
|
|
257578
|
+
const only = live.find(({ id: id2 }) => id2 === runtime.connectionId) ?? (live.length === 1 ? live[0] : null);
|
|
257494
257579
|
runtime.transport = runtime.processTransport ?? only?.writer ?? null;
|
|
257495
257580
|
runtime.streamTransport = only?.streamWriter ?? null;
|
|
257496
257581
|
runtime.socket = only ? socketForTransport(only.writer) : null;
|
|
@@ -257716,6 +257801,26 @@ function suspendListenerConnection(runtime, connectionId) {
|
|
|
257716
257801
|
getResumeStates(runtime).set(connectionId, resumeState);
|
|
257717
257802
|
return closed;
|
|
257718
257803
|
}
|
|
257804
|
+
function resumeListenerConnectionIdentity(runtime, previousId, nextId2) {
|
|
257805
|
+
const states3 = getResumeStates(runtime);
|
|
257806
|
+
const previous = states3.get(previousId);
|
|
257807
|
+
states3.delete(previousId);
|
|
257808
|
+
if (previous)
|
|
257809
|
+
states3.set(nextId2, previous);
|
|
257810
|
+
for (const conversation of runtime.conversationRuntimes.values()) {
|
|
257811
|
+
for (const [itemId, message2] of conversation.queuedMessagesByItemId) {
|
|
257812
|
+
if (message2.connectionId === previousId) {
|
|
257813
|
+
conversation.queuedMessagesByItemId.set(itemId, {
|
|
257814
|
+
...message2,
|
|
257815
|
+
connectionId: nextId2
|
|
257816
|
+
});
|
|
257817
|
+
}
|
|
257818
|
+
}
|
|
257819
|
+
if (conversation.activeConnectionId === previousId) {
|
|
257820
|
+
conversation.activeConnectionId = nextId2;
|
|
257821
|
+
}
|
|
257822
|
+
}
|
|
257823
|
+
}
|
|
257719
257824
|
|
|
257720
257825
|
class ProcessRuntimeTransport {
|
|
257721
257826
|
runtime;
|
|
@@ -257761,9 +257866,6 @@ var init_connection = __esm(async () => {
|
|
|
257761
257866
|
});
|
|
257762
257867
|
|
|
257763
257868
|
// src/queue/queue-runtime.ts
|
|
257764
|
-
function isCoalescable(kind) {
|
|
257765
|
-
return kind === "message" || kind === "task_notification" || kind === "cron_prompt" || kind === "mod_continue";
|
|
257766
|
-
}
|
|
257767
257869
|
function hasSameScope(a2, b3) {
|
|
257768
257870
|
return (a2.agentId ?? null) === (b3.agentId ?? null) && (a2.conversationId ?? null) === (b3.conversationId ?? null);
|
|
257769
257871
|
}
|
|
@@ -257785,7 +257887,7 @@ class QueueRuntime {
|
|
|
257785
257887
|
this.callbacks = options.callbacks ?? {};
|
|
257786
257888
|
}
|
|
257787
257889
|
enqueue(input, options = {}) {
|
|
257788
|
-
if (options.preserveExisting && (this.store.length >= this.hardMaxItems || this.store.length >= this.maxItems
|
|
257890
|
+
if (options.preserveExisting && (this.store.length >= this.hardMaxItems || this.store.length >= this.maxItems)) {
|
|
257789
257891
|
return null;
|
|
257790
257892
|
}
|
|
257791
257893
|
if (this.store.length >= this.hardMaxItems) {
|
|
@@ -257795,9 +257897,8 @@ class QueueRuntime {
|
|
|
257795
257897
|
this.safeCallback("onDropped", phantom, "buffer_limit", this.store.length);
|
|
257796
257898
|
return null;
|
|
257797
257899
|
}
|
|
257798
|
-
if (this.store.length >= this.maxItems
|
|
257799
|
-
const
|
|
257800
|
-
const dropped = dropIdx !== -1 ? this.store[dropIdx] : undefined;
|
|
257900
|
+
if (this.store.length >= this.maxItems) {
|
|
257901
|
+
const dropped = this.store[0];
|
|
257801
257902
|
if (dropped !== undefined) {
|
|
257802
257903
|
if (!this.mutationAllowed("beforeDropped", dropped)) {
|
|
257803
257904
|
const rejected = this.makeItem(input);
|
|
@@ -257806,7 +257907,7 @@ class QueueRuntime {
|
|
|
257806
257907
|
this.safeCallback("onDropped", rejected, "buffer_limit", this.store.length);
|
|
257807
257908
|
return null;
|
|
257808
257909
|
}
|
|
257809
|
-
this.store.
|
|
257910
|
+
this.store.shift();
|
|
257810
257911
|
const item2 = this.makeItem(input);
|
|
257811
257912
|
this.store.push(item2);
|
|
257812
257913
|
this.safeCallback("onDropped", dropped, "buffer_limit", this.store.length);
|
|
@@ -257844,16 +257945,14 @@ class QueueRuntime {
|
|
|
257844
257945
|
}
|
|
257845
257946
|
const batch = [];
|
|
257846
257947
|
const first = this.store.find((item) => !item.paused);
|
|
257847
|
-
if (first
|
|
257948
|
+
if (first) {
|
|
257848
257949
|
for (const item of this.store) {
|
|
257849
257950
|
if (item.paused)
|
|
257850
257951
|
continue;
|
|
257851
|
-
if (!
|
|
257952
|
+
if (!hasSameScope(first, item))
|
|
257852
257953
|
break;
|
|
257853
257954
|
batch.push(item);
|
|
257854
257955
|
}
|
|
257855
|
-
} else if (first) {
|
|
257856
|
-
batch.push(first);
|
|
257857
257956
|
}
|
|
257858
257957
|
if (batch.length === 0) {
|
|
257859
257958
|
return null;
|
|
@@ -258246,12 +258345,11 @@ import { randomUUID as randomUUID46 } from "node:crypto";
|
|
|
258246
258345
|
import {
|
|
258247
258346
|
chmodSync as chmodSync7,
|
|
258248
258347
|
closeSync as closeSync8,
|
|
258249
|
-
existsSync as
|
|
258348
|
+
existsSync as existsSync50,
|
|
258250
258349
|
fsyncSync as fsyncSync5,
|
|
258251
258350
|
mkdirSync as mkdirSync37,
|
|
258252
258351
|
openSync as openSync8,
|
|
258253
258352
|
readFileSync as readFileSync41,
|
|
258254
|
-
renameSync as renameSync12,
|
|
258255
258353
|
statSync as statSync20,
|
|
258256
258354
|
unlinkSync as unlinkSync11,
|
|
258257
258355
|
writeFileSync as writeFileSync32
|
|
@@ -258390,7 +258488,7 @@ function validateDurableStore(value) {
|
|
|
258390
258488
|
return value;
|
|
258391
258489
|
}
|
|
258392
258490
|
function readDurableStore(path32) {
|
|
258393
|
-
if (!
|
|
258491
|
+
if (!existsSync50(path32))
|
|
258394
258492
|
return emptyDurableStore();
|
|
258395
258493
|
const size2 = statSync20(path32).size;
|
|
258396
258494
|
if (size2 > MAX_INPUT_DISPOSITION_STORE_BYTES) {
|
|
@@ -258418,7 +258516,7 @@ function writeDurableStore(path32, store3) {
|
|
|
258418
258516
|
} finally {
|
|
258419
258517
|
closeSync8(fd);
|
|
258420
258518
|
}
|
|
258421
|
-
|
|
258519
|
+
renameSyncWithRetry(temporaryPath, path32);
|
|
258422
258520
|
fsyncDirectory(dirname33(path32));
|
|
258423
258521
|
} catch (error5) {
|
|
258424
258522
|
try {
|
|
@@ -258820,6 +258918,7 @@ function loadDurableQueuedInputEntries(listener) {
|
|
|
258820
258918
|
var ACCEPTED_INPUT_DISPOSITION_TTL_MS, MAX_ACCEPTED_INPUT_DISPOSITIONS_PER_SCOPE = 4096, MAX_ACCEPTED_INPUT_DISPOSITIONS = 65536, MAX_DURABLE_QUEUED_INPUT_BYTES, MAX_INPUT_DISPOSITION_STORE_BYTES, LOCK_WAIT_MS = 2000;
|
|
258821
258919
|
var init_input_disposition = __esm(async () => {
|
|
258822
258920
|
init_server_url();
|
|
258921
|
+
init_rename_sync_with_retry();
|
|
258823
258922
|
init_durable_file_lock();
|
|
258824
258923
|
init_input_disposition_capacity();
|
|
258825
258924
|
init_input_disposition_expiry();
|
|
@@ -258844,7 +258943,6 @@ import {
|
|
|
258844
258943
|
openSync as openSync9,
|
|
258845
258944
|
readdirSync as readdirSync19,
|
|
258846
258945
|
readFileSync as readFileSync42,
|
|
258847
|
-
renameSync as renameSync13,
|
|
258848
258946
|
rmSync as rmSync20,
|
|
258849
258947
|
writeFileSync as writeFileSync33
|
|
258850
258948
|
} from "node:fs";
|
|
@@ -258940,7 +259038,7 @@ function createTurnFinishedStore(directory = defaultDirectory(), options = {}) {
|
|
|
258940
259038
|
mode: 384,
|
|
258941
259039
|
flush: true
|
|
258942
259040
|
});
|
|
258943
|
-
|
|
259041
|
+
renameSyncWithRetry(temporary, destination);
|
|
258944
259042
|
fsyncDirectory2(directory);
|
|
258945
259043
|
} finally {
|
|
258946
259044
|
rmSync20(temporary, { force: true });
|
|
@@ -259292,6 +259390,7 @@ var TurnFinishedCapacityError, MAX_PENDING_TERMINALS_PER_CONVERSATION = 64, DELI
|
|
|
259292
259390
|
var init_turn_finished_replay = __esm(async () => {
|
|
259293
259391
|
init_server_url();
|
|
259294
259392
|
init_debug();
|
|
259393
|
+
init_rename_sync_with_retry();
|
|
259295
259394
|
init_durable_file_lock();
|
|
259296
259395
|
await __promiseAll([
|
|
259297
259396
|
init_connection(),
|
|
@@ -259956,20 +260055,6 @@ var init_image_policy = __esm(async () => {
|
|
|
259956
260055
|
await init_message_image_normalization();
|
|
259957
260056
|
});
|
|
259958
260057
|
|
|
259959
|
-
// src/websocket/listener/mcp-originator-scope.ts
|
|
259960
|
-
function getMcpOriginatorScope(message2) {
|
|
259961
|
-
return message2?.mcpOriginatorSuperRunId ? {
|
|
259962
|
-
superRunId: message2.mcpOriginatorSuperRunId,
|
|
259963
|
-
tokenPresent: message2.mcpOriginatorTokenPresent === true
|
|
259964
|
-
} : null;
|
|
259965
|
-
}
|
|
259966
|
-
function sameMcpOriginatorScope(a2, b3) {
|
|
259967
|
-
return a2 === null || b3 === null ? a2 === b3 : a2.superRunId === b3.superRunId && a2.tokenPresent === b3.tokenPresent;
|
|
259968
|
-
}
|
|
259969
|
-
function getEffectiveMcpOriginatorId(message2) {
|
|
259970
|
-
return message2.mcpOriginatorTokenPresent === true ? message2.mcpOriginatorSuperRunId : undefined;
|
|
259971
|
-
}
|
|
259972
|
-
|
|
259973
260058
|
// src/websocket/listener/queue.ts
|
|
259974
260059
|
function getQueueItemScope(item) {
|
|
259975
260060
|
if (!item) {
|
|
@@ -260028,7 +260113,7 @@ function buildQueuedTurnMessage(runtime, batch) {
|
|
|
260028
260113
|
messageOriginatorIds.push(undefined);
|
|
260029
260114
|
originatorVotes.push(null);
|
|
260030
260115
|
messages.push(withMessageAttribution({ role: "user", content: item.content }, item.actingUserId ?? undefined));
|
|
260031
|
-
} else
|
|
260116
|
+
} else {
|
|
260032
260117
|
messageOriginatorIds.push(undefined);
|
|
260033
260118
|
originatorVotes.push(null);
|
|
260034
260119
|
messages.push({
|
|
@@ -260093,15 +260178,12 @@ function shouldProcessInboundMessageDirectly(runtime, parsed) {
|
|
|
260093
260178
|
});
|
|
260094
260179
|
return getListenerBlockedReason(runtime.turnLifecycle.snapshot(), activeScope ? getPendingControlRequestCount(runtime.listener, activeScope) : 0) === null;
|
|
260095
260180
|
}
|
|
260096
|
-
function consumeQueuedTurn(runtime
|
|
260181
|
+
function consumeQueuedTurn(runtime) {
|
|
260097
260182
|
const queuedItems = runtime.queueRuntime.peekReady();
|
|
260098
260183
|
const firstQueuedItem = queuedItems[0];
|
|
260099
|
-
if (!firstQueuedItem
|
|
260184
|
+
if (!firstQueuedItem) {
|
|
260100
260185
|
return null;
|
|
260101
260186
|
}
|
|
260102
|
-
const firstScope = getMcpOriginatorScope(firstQueuedItem.kind === "message" ? runtime.queuedMessagesByItemId.get(firstQueuedItem.id) : undefined);
|
|
260103
|
-
if (activeScope !== undefined && !sameMcpOriginatorScope(firstScope, activeScope))
|
|
260104
|
-
return null;
|
|
260105
260187
|
let queueLen = 0;
|
|
260106
260188
|
let hasMessage = false;
|
|
260107
260189
|
let hasTaskNotification = false;
|
|
@@ -260112,7 +260194,7 @@ function consumeQueuedTurn(runtime, activeScope) {
|
|
|
260112
260194
|
let batchPreferences = JSON.stringify(getStoredClientPreferences(runtime.agentId, runtime.conversationId));
|
|
260113
260195
|
const isNoCoalesce = (candidate) => candidate.kind === "message" && candidate.noCoalesce === true;
|
|
260114
260196
|
for (const item of queuedItems) {
|
|
260115
|
-
if (!
|
|
260197
|
+
if (!hasSameQueueScope(firstQueuedItem, item)) {
|
|
260116
260198
|
break;
|
|
260117
260199
|
}
|
|
260118
260200
|
const incoming = runtime.queuedMessagesByItemId.get(item.id);
|
|
@@ -260158,6 +260240,25 @@ function consumeQueuedTurn(runtime, activeScope) {
|
|
|
260158
260240
|
if (!dequeuedBatch) {
|
|
260159
260241
|
return null;
|
|
260160
260242
|
}
|
|
260243
|
+
for (const item of dequeuedBatch.items) {
|
|
260244
|
+
if (item.kind !== "cron_prompt")
|
|
260245
|
+
continue;
|
|
260246
|
+
try {
|
|
260247
|
+
const task2 = getTask(item.cronTaskId);
|
|
260248
|
+
if (task2 && task2.agent_id === item.agentId) {
|
|
260249
|
+
safeAppendCronRunLogForTask(task2, {
|
|
260250
|
+
status: "ok",
|
|
260251
|
+
outcome: "delivered",
|
|
260252
|
+
reason: "dequeued",
|
|
260253
|
+
queueItemId: item.id,
|
|
260254
|
+
conversationId: item.conversationId,
|
|
260255
|
+
runAtMs: Date.now()
|
|
260256
|
+
});
|
|
260257
|
+
}
|
|
260258
|
+
} catch (error5) {
|
|
260259
|
+
debugWarn("Cron", "Error reading task for dequeued cron prompt:", error5);
|
|
260260
|
+
}
|
|
260261
|
+
}
|
|
260161
260262
|
const clientMessageIds = getDequeuedClientMessageIds(runtime, dequeuedBatch);
|
|
260162
260263
|
const queuedTurn = buildQueuedTurnMessage(runtime, dequeuedBatch);
|
|
260163
260264
|
if (!queuedTurn) {
|
|
@@ -260316,7 +260417,8 @@ function scheduleQueuePump(runtime, socket, opts, processQueuedTurn) {
|
|
|
260316
260417
|
}
|
|
260317
260418
|
var init_queue = __esm(async () => {
|
|
260318
260419
|
init_mcp_originator_tokens();
|
|
260319
|
-
|
|
260420
|
+
init_cron_file();
|
|
260421
|
+
init_run_log();
|
|
260320
260422
|
init_error_reporting();
|
|
260321
260423
|
init_debug();
|
|
260322
260424
|
init_transport();
|
|
@@ -261074,6 +261176,11 @@ function taskMatchesCronSchedulerScope(task2, scope) {
|
|
|
261074
261176
|
return true;
|
|
261075
261177
|
return scope === "local" ? isLocalAgentId(task2.agent_id) : !isLocalAgentId(task2.agent_id);
|
|
261076
261178
|
}
|
|
261179
|
+
function clearSlowLeaseRetry() {
|
|
261180
|
+
if (slowLeaseRetryTimer)
|
|
261181
|
+
clearInterval(slowLeaseRetryTimer);
|
|
261182
|
+
slowLeaseRetryTimer = null;
|
|
261183
|
+
}
|
|
261077
261184
|
function logScheduler(opts, message2) {
|
|
261078
261185
|
if (opts.onLog) {
|
|
261079
261186
|
opts.onLog(`[Cron] ${message2}`);
|
|
@@ -261464,16 +261571,31 @@ function startScheduler(socket, opts, processQueuedTurn, _retryCount = 0) {
|
|
|
261464
261571
|
try {
|
|
261465
261572
|
token2 = claimSchedulerLease(scope);
|
|
261466
261573
|
} catch (err) {
|
|
261574
|
+
if (slowLeaseRetryTimer)
|
|
261575
|
+
return;
|
|
261467
261576
|
if (_retryCount < MAX_LEASE_RETRIES) {
|
|
261468
261577
|
logScheduler(opts, `Could not claim scheduler lease (attempt ${_retryCount + 1}/${MAX_LEASE_RETRIES + 1}): ${err instanceof Error ? err.message : err}`);
|
|
261469
261578
|
logScheduler(opts, "Cron tasks will not fire until the scheduler starts. Retrying...");
|
|
261470
261579
|
setTimeout(() => startScheduler(socket, opts, processQueuedTurn, _retryCount + 1), LEASE_RETRY_MS);
|
|
261471
261580
|
} else {
|
|
261472
261581
|
logScheduler(opts, `Failed to claim scheduler lease after ${MAX_LEASE_RETRIES + 1} attempts. Cron tasks will not fire.`);
|
|
261473
|
-
logScheduler(opts,
|
|
261582
|
+
logScheduler(opts, `Another process may hold the lease. Retrying every ${SLOW_LEASE_RETRY_MS / 60000} minutes.`);
|
|
261583
|
+
slowLeaseRetryTimer = setInterval(() => {
|
|
261584
|
+
const ctx = listenerFireContext;
|
|
261585
|
+
if (!ctx || schedulerState) {
|
|
261586
|
+
clearSlowLeaseRetry();
|
|
261587
|
+
return;
|
|
261588
|
+
}
|
|
261589
|
+
startScheduler(ctx.socket, ctx.opts, ctx.processQueuedTurn, _retryCount);
|
|
261590
|
+
}, SLOW_LEASE_RETRY_MS);
|
|
261591
|
+
slowLeaseRetryTimer.unref?.();
|
|
261474
261592
|
}
|
|
261475
261593
|
return;
|
|
261476
261594
|
}
|
|
261595
|
+
if (slowLeaseRetryTimer) {
|
|
261596
|
+
clearSlowLeaseRetry();
|
|
261597
|
+
logScheduler(opts, "Claimed scheduler lease on slow retry.");
|
|
261598
|
+
}
|
|
261477
261599
|
const now2 = new Date;
|
|
261478
261600
|
const state2 = {
|
|
261479
261601
|
token: token2,
|
|
@@ -261521,6 +261643,7 @@ function startScheduler(socket, opts, processQueuedTurn, _retryCount = 0) {
|
|
|
261521
261643
|
}
|
|
261522
261644
|
function stopScheduler() {
|
|
261523
261645
|
listenerFireContext = null;
|
|
261646
|
+
clearSlowLeaseRetry();
|
|
261524
261647
|
if (!schedulerState)
|
|
261525
261648
|
return;
|
|
261526
261649
|
clearInterval(schedulerState.tickInterval);
|
|
@@ -261534,7 +261657,7 @@ function stopScheduler() {
|
|
|
261534
261657
|
} catch {}
|
|
261535
261658
|
schedulerState = null;
|
|
261536
261659
|
}
|
|
261537
|
-
var schedulerState = null, CRON_SCHEDULER_SCOPE_ENV = "LETTA_CRON_SCHEDULER_SCOPE", listenerFireContext = null, TICK_INTERVAL_MS = 60000, GC_INTERVAL_MS, TOMBSTONE_HEARTBEAT_MS = 1000, LEASE_RETRY_MS = 30000, MAX_LEASE_RETRIES = 3, NEW_CONVERSATION_TARGET = "new";
|
|
261660
|
+
var schedulerState = null, CRON_SCHEDULER_SCOPE_ENV = "LETTA_CRON_SCHEDULER_SCOPE", listenerFireContext = null, TICK_INTERVAL_MS = 60000, GC_INTERVAL_MS, TOMBSTONE_HEARTBEAT_MS = 1000, LEASE_RETRY_MS = 30000, MAX_LEASE_RETRIES = 3, SLOW_LEASE_RETRY_MS, slowLeaseRetryTimer = null, NEW_CONVERSATION_TARGET = "new";
|
|
261538
261661
|
var init_scheduler = __esm(async () => {
|
|
261539
261662
|
init_backend2();
|
|
261540
261663
|
init_debug();
|
|
@@ -261552,6 +261675,7 @@ var init_scheduler = __esm(async () => {
|
|
|
261552
261675
|
init_runtime6()
|
|
261553
261676
|
]);
|
|
261554
261677
|
GC_INTERVAL_MS = 60 * 60000;
|
|
261678
|
+
SLOW_LEASE_RETRY_MS = 5 * 60000;
|
|
261555
261679
|
});
|
|
261556
261680
|
|
|
261557
261681
|
// src/cron/index.ts
|
|
@@ -261654,8 +261778,9 @@ Add options:
|
|
|
261654
261778
|
conversation; "default" for the agent default)
|
|
261655
261779
|
--computer <id> (managed Cloud sandbox only) Run on a connected
|
|
261656
261780
|
external computer (deviceId from \`letta computers
|
|
261657
|
-
list\`).
|
|
261658
|
-
|
|
261781
|
+
list\`). If that computer is offline at fire
|
|
261782
|
+
time, that run fails (no Cloud sandbox fallback);
|
|
261783
|
+
omit --computer to run in the Cloud sandbox.
|
|
261659
261784
|
|
|
261660
261785
|
List/filter options:
|
|
261661
261786
|
--agent <id> Filter by agent ID
|
|
@@ -261880,7 +262005,7 @@ async function handleCloudAdd(params) {
|
|
|
261880
262005
|
output.notes = notes;
|
|
261881
262006
|
}
|
|
261882
262007
|
console.log(JSON.stringify(output, null, 2));
|
|
261883
|
-
console.error(targetDeviceId ? `Created Cloud schedule: it fires from the cloud and runs on computer "${targetDeviceId}" (
|
|
262008
|
+
console.error(targetDeviceId ? `Created Cloud schedule: it fires from the cloud and runs on computer "${targetDeviceId}" (if it is offline at fire time, that run fails; no sandbox fallback).` : "Created Cloud schedule: it fires from the cloud and runs in this agent's managed cloud sandbox (survives local shutdown).");
|
|
261884
262009
|
return 0;
|
|
261885
262010
|
} catch (err) {
|
|
261886
262011
|
console.error(`Error: failed to create Cloud schedule: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -264248,6 +264373,11 @@ var init_listen_first_run_welcome = __esm(async () => {
|
|
|
264248
264373
|
await init_AnimatedLogo();
|
|
264249
264374
|
});
|
|
264250
264375
|
|
|
264376
|
+
// src/cli/subcommands/listen-output-mode.ts
|
|
264377
|
+
function shouldUseNonInteractiveListenerOutput(debugMode, lifecycleOutput, stdoutIsTTY = process.stdout.isTTY) {
|
|
264378
|
+
return debugMode || lifecycleOutput || !stdoutIsTTY;
|
|
264379
|
+
}
|
|
264380
|
+
|
|
264251
264381
|
// src/cli/subcommands/listen-process-anchor.ts
|
|
264252
264382
|
import { MessageChannel as MessageChannel2 } from "node:worker_threads";
|
|
264253
264383
|
function createMessageChannelProcessAnchor() {
|
|
@@ -264305,7 +264435,7 @@ function printListenUsage() {
|
|
|
264305
264435
|
}
|
|
264306
264436
|
|
|
264307
264437
|
// src/cli/subcommands/listener-readiness.ts
|
|
264308
|
-
async function completeListenerConnectionStartup(expectedConnection, readiness, startGateway = async () => {}) {
|
|
264438
|
+
async function completeListenerConnectionStartup(expectedConnection, readiness, startGateway = async () => {}, onGatewayError = console.error) {
|
|
264309
264439
|
const { getActiveRuntime: getActiveRuntime2 } = await init_runtime6().then(() => exports_runtime);
|
|
264310
264440
|
const runtime = getActiveRuntime2();
|
|
264311
264441
|
const connection = runtime?.connections.get(expectedConnection.id);
|
|
@@ -264315,12 +264445,12 @@ async function completeListenerConnectionStartup(expectedConnection, readiness,
|
|
|
264315
264445
|
const { isListenerTransportOpen: isListenerTransportOpen2 } = await Promise.resolve().then(() => (init_transport(), exports_transport));
|
|
264316
264446
|
if (!isListenerTransportOpen2(connection.writer))
|
|
264317
264447
|
return false;
|
|
264318
|
-
await startGateway();
|
|
264319
264448
|
if (getActiveRuntime2()?.connections.get(connection.id) !== connection)
|
|
264320
264449
|
return false;
|
|
264321
264450
|
if (!connection.initialized || !connection.ingressReady || connection.cancellation.signal.aborted || !isListenerTransportOpen2(connection.writer))
|
|
264322
264451
|
return false;
|
|
264323
264452
|
readiness.completeCloudStartup(epoch);
|
|
264453
|
+
Promise.resolve().then(startGateway).catch(onGatewayError);
|
|
264324
264454
|
return true;
|
|
264325
264455
|
}
|
|
264326
264456
|
function applyGatewayLifecycleReadiness(readiness, event) {
|
|
@@ -264473,7 +264603,7 @@ var init_service_protocol = __esm(() => {
|
|
|
264473
264603
|
// src/websocket/listen-log.ts
|
|
264474
264604
|
import {
|
|
264475
264605
|
appendFileSync as appendFileSync8,
|
|
264476
|
-
existsSync as
|
|
264606
|
+
existsSync as existsSync51,
|
|
264477
264607
|
mkdirSync as mkdirSync39,
|
|
264478
264608
|
readdirSync as readdirSync20,
|
|
264479
264609
|
unlinkSync as unlinkSync12
|
|
@@ -264493,7 +264623,7 @@ function formatFileTimestamp(now2) {
|
|
|
264493
264623
|
}
|
|
264494
264624
|
function pruneOldLogs(dir, maxFiles) {
|
|
264495
264625
|
try {
|
|
264496
|
-
if (!
|
|
264626
|
+
if (!existsSync51(dir))
|
|
264497
264627
|
return;
|
|
264498
264628
|
const files = readdirSync20(dir).filter((f4) => f4.endsWith(".log")).sort();
|
|
264499
264629
|
if (files.length >= maxFiles) {
|
|
@@ -264545,7 +264675,7 @@ class RemoteSessionLog {
|
|
|
264545
264675
|
const previous = this.path;
|
|
264546
264676
|
this.rotation += 1;
|
|
264547
264677
|
this.path = this.freshPath();
|
|
264548
|
-
while (
|
|
264678
|
+
while (existsSync51(this.path)) {
|
|
264549
264679
|
this.rotation += 1;
|
|
264550
264680
|
this.path = this.freshPath();
|
|
264551
264681
|
}
|
|
@@ -264569,7 +264699,7 @@ class RemoteSessionLog {
|
|
|
264569
264699
|
if (this.dirCreated)
|
|
264570
264700
|
return;
|
|
264571
264701
|
try {
|
|
264572
|
-
if (!
|
|
264702
|
+
if (!existsSync51(this.dir)) {
|
|
264573
264703
|
mkdirSync39(this.dir, { recursive: true });
|
|
264574
264704
|
}
|
|
264575
264705
|
this.dirCreated = true;
|
|
@@ -265178,9 +265308,10 @@ var init_auth3 = __esm(() => {
|
|
|
265178
265308
|
});
|
|
265179
265309
|
|
|
265180
265310
|
// src/websocket/listener/manual-instance-lock.ts
|
|
265311
|
+
import { execFileSync as execFileSync11 } from "node:child_process";
|
|
265181
265312
|
import { createHash as createHash15, randomUUID as randomUUID48 } from "node:crypto";
|
|
265182
265313
|
import { link as link4, mkdir as mkdir13, readFile as readFile21, rm as rm11, unlink as unlink3, writeFile as writeFile15 } from "node:fs/promises";
|
|
265183
|
-
import { homedir as homedir39 } from "node:os";
|
|
265314
|
+
import { homedir as homedir39, uptime as uptime2 } from "node:os";
|
|
265184
265315
|
import path32 from "node:path";
|
|
265185
265316
|
function hasErrorCode3(error5, code2) {
|
|
265186
265317
|
return typeof error5 === "object" && error5 !== null && "code" in error5 && error5.code === code2;
|
|
@@ -265193,6 +265324,32 @@ function defaultIsProcessAlive2(pid) {
|
|
|
265193
265324
|
return !hasErrorCode3(error5, "ESRCH");
|
|
265194
265325
|
}
|
|
265195
265326
|
}
|
|
265327
|
+
function getDefaultBootTimeMs() {
|
|
265328
|
+
return Date.now() - uptime2() * 1000;
|
|
265329
|
+
}
|
|
265330
|
+
function defaultGetProcessCommand(pid) {
|
|
265331
|
+
if (process.platform === "win32")
|
|
265332
|
+
return null;
|
|
265333
|
+
try {
|
|
265334
|
+
return execFileSync11("ps", ["-p", String(pid), "-o", "command="], {
|
|
265335
|
+
encoding: "utf-8",
|
|
265336
|
+
timeout: 1000,
|
|
265337
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
265338
|
+
}).trim();
|
|
265339
|
+
} catch {
|
|
265340
|
+
return null;
|
|
265341
|
+
}
|
|
265342
|
+
}
|
|
265343
|
+
function isOwnerAlive2(record6, deps) {
|
|
265344
|
+
if (!deps.isProcessAlive(record6.pid))
|
|
265345
|
+
return false;
|
|
265346
|
+
const acquiredAtMs = Date.parse(record6.acquiredAt);
|
|
265347
|
+
if (!Number.isFinite(acquiredAtMs) || acquiredAtMs >= deps.bootTimeMs - BOOT_TIME_SLACK_MS2) {
|
|
265348
|
+
return true;
|
|
265349
|
+
}
|
|
265350
|
+
const command = deps.getProcessCommand(record6.pid);
|
|
265351
|
+
return !command || /letta/i.test(command);
|
|
265352
|
+
}
|
|
265196
265353
|
function getDefaultLockRoot() {
|
|
265197
265354
|
return path32.join(process.env.HOME || homedir39(), ".letta");
|
|
265198
265355
|
}
|
|
@@ -265277,7 +265434,7 @@ async function recoverDeadOwner(lockPath, staleContents, recoveryOwnerContents,
|
|
|
265277
265434
|
if (!claimOwner) {
|
|
265278
265435
|
throw new ManualListenerLockUnavailableError(`Listener lock recovery record is invalid: ${claimPath}`, lockPath);
|
|
265279
265436
|
}
|
|
265280
|
-
if (
|
|
265437
|
+
if (isOwnerAlive2(claimOwner, deps)) {
|
|
265281
265438
|
return false;
|
|
265282
265439
|
}
|
|
265283
265440
|
}
|
|
@@ -265308,6 +265465,8 @@ async function acquireManualListenerLock(scope, overrides = {}) {
|
|
|
265308
265465
|
processId: process.pid,
|
|
265309
265466
|
ownerToken: randomUUID48(),
|
|
265310
265467
|
isProcessAlive: defaultIsProcessAlive2,
|
|
265468
|
+
bootTimeMs: getDefaultBootTimeMs(),
|
|
265469
|
+
getProcessCommand: defaultGetProcessCommand,
|
|
265311
265470
|
...overrides
|
|
265312
265471
|
};
|
|
265313
265472
|
const listenerLockDir = path32.join(deps.lockRoot, "listeners");
|
|
@@ -265367,7 +265526,7 @@ async function acquireManualListenerLock(scope, overrides = {}) {
|
|
|
265367
265526
|
if (!incumbent) {
|
|
265368
265527
|
throw new ManualListenerLockUnavailableError(`Listener lock is corrupt or belongs to an incompatible version: ${lockPath}`, lockPath);
|
|
265369
265528
|
}
|
|
265370
|
-
if (
|
|
265529
|
+
if (isOwnerAlive2(incumbent, deps)) {
|
|
265371
265530
|
throw new ManualListenerAlreadyRunningError(incumbent.pid, lockPath);
|
|
265372
265531
|
}
|
|
265373
265532
|
const recovered = await recoverDeadOwner(lockPath, incumbentContents, ownerContents, scopeHash, deps);
|
|
@@ -265376,7 +265535,7 @@ async function acquireManualListenerLock(scope, overrides = {}) {
|
|
|
265376
265535
|
}
|
|
265377
265536
|
}
|
|
265378
265537
|
}
|
|
265379
|
-
var RECOVERY_MAX_DEPTH2 = 64, ManualListenerAlreadyRunningError, ManualListenerLockUnavailableError;
|
|
265538
|
+
var RECOVERY_MAX_DEPTH2 = 64, BOOT_TIME_SLACK_MS2 = 60000, ManualListenerAlreadyRunningError, ManualListenerLockUnavailableError;
|
|
265380
265539
|
var init_manual_instance_lock = __esm(() => {
|
|
265381
265540
|
ManualListenerAlreadyRunningError = class ManualListenerAlreadyRunningError extends Error {
|
|
265382
265541
|
holderPid;
|
|
@@ -267608,10 +267767,10 @@ async function handleListMemoryCommand(parsed, socket, safeSocketSend, overrides
|
|
|
267608
267767
|
const isMemfsEnabledOnServer2 = overrides.isMemfsEnabledOnServer ?? actualIsMemfsEnabledOnServer;
|
|
267609
267768
|
const { scanMemoryFilesystem: scanMemoryFilesystem2, getFileNodes: getFileNodes2, readFileContent: readFileContent2 } = await Promise.resolve().then(() => (init_memory_scanner(), exports_memory_scanner));
|
|
267610
267769
|
const { parseFrontmatter: parseFrontmatter2 } = await Promise.resolve().then(() => exports_frontmatter);
|
|
267611
|
-
const { existsSync:
|
|
267612
|
-
const { join: join78, posix:
|
|
267770
|
+
const { existsSync: existsSync52, statSync: statSync22 } = await import("node:fs");
|
|
267771
|
+
const { join: join78, posix: posix4 } = await import("node:path");
|
|
267613
267772
|
const memoryRoot = getMemoryFilesystemRoot2(parsed.agent_id);
|
|
267614
|
-
let memfsInitialized =
|
|
267773
|
+
let memfsInitialized = existsSync52(join78(memoryRoot, ".git"));
|
|
267615
267774
|
const memfsEnabled = memfsInitialized ? true : await isMemfsEnabledOnServer2(parsed.agent_id);
|
|
267616
267775
|
if (!memfsEnabled) {
|
|
267617
267776
|
safeSocketSend(socket, {
|
|
@@ -267629,7 +267788,7 @@ async function handleListMemoryCommand(parsed, socket, safeSocketSend, overrides
|
|
|
267629
267788
|
await ensureLocalMemfsCheckout2(parsed.agent_id, {
|
|
267630
267789
|
pullOnExistingRepo: true
|
|
267631
267790
|
});
|
|
267632
|
-
memfsInitialized =
|
|
267791
|
+
memfsInitialized = existsSync52(join78(memoryRoot, ".git"));
|
|
267633
267792
|
if (!memfsInitialized) {
|
|
267634
267793
|
throw new Error("MemFS is enabled, but the local memory checkout could not be initialized.");
|
|
267635
267794
|
}
|
|
@@ -267658,8 +267817,8 @@ async function handleListMemoryCommand(parsed, socket, safeSocketSend, overrides
|
|
|
267658
267817
|
if (!target2) {
|
|
267659
267818
|
return null;
|
|
267660
267819
|
}
|
|
267661
|
-
const sourceDir =
|
|
267662
|
-
const candidate = target2.startsWith("./") || target2.startsWith("../") ?
|
|
267820
|
+
const sourceDir = posix4.dirname(sourcePath.replace(/\\/g, "/"));
|
|
267821
|
+
const candidate = target2.startsWith("./") || target2.startsWith("../") ? posix4.normalize(posix4.join(sourceDir, target2)) : posix4.normalize(target2.startsWith("/") ? target2.slice(1) : target2);
|
|
267663
267822
|
if (!candidate || candidate.startsWith("../") || candidate === "." || candidate === "..") {
|
|
267664
267823
|
return null;
|
|
267665
267824
|
}
|
|
@@ -267667,10 +267826,10 @@ async function handleListMemoryCommand(parsed, socket, safeSocketSend, overrides
|
|
|
267667
267826
|
const candidates2 = new Set([withExtension]);
|
|
267668
267827
|
const isExplicitRelative = target2.startsWith("./") || target2.startsWith("../");
|
|
267669
267828
|
if (!isExplicitRelative && !target2.startsWith("/") && sourceDir && sourceDir !== ".") {
|
|
267670
|
-
candidates2.add(
|
|
267829
|
+
candidates2.add(posix4.normalize(posix4.join(sourceDir, withExtension)));
|
|
267671
267830
|
}
|
|
267672
267831
|
if (!withExtension.startsWith("system/")) {
|
|
267673
|
-
candidates2.add(
|
|
267832
|
+
candidates2.add(posix4.normalize(`system/${withExtension}`));
|
|
267674
267833
|
}
|
|
267675
267834
|
for (const resolved2 of candidates2) {
|
|
267676
267835
|
if (allPaths.has(resolved2)) {
|
|
@@ -267929,7 +268088,7 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
267929
268088
|
isMemfsEnabledOnServer: isMemfsEnabledOnServer2
|
|
267930
268089
|
} = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
267931
268090
|
const { readFile: readFile22 } = await import("node:fs/promises");
|
|
267932
|
-
const { existsSync:
|
|
268091
|
+
const { existsSync: existsSync52 } = await import("node:fs");
|
|
267933
268092
|
const { isAbsolute: isAbsolute25, join: join78, normalize: normalize4, relative: relative8, sep: sep8 } = await import("node:path");
|
|
267934
268093
|
if (isAbsolute25(parsed.path) || parsed.path.length === 0) {
|
|
267935
268094
|
sendFailure("path must be a non-empty relative path");
|
|
@@ -267942,14 +268101,14 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
267942
268101
|
sendFailure("path must resolve inside the memory root");
|
|
267943
268102
|
return;
|
|
267944
268103
|
}
|
|
267945
|
-
if (!
|
|
268104
|
+
if (!existsSync52(join78(memoryRoot, ".git"))) {
|
|
267946
268105
|
const enabled = await isMemfsEnabledOnServer2(parsed.agent_id);
|
|
267947
268106
|
if (!enabled) {
|
|
267948
268107
|
sendFailure("memfs is not enabled for this agent");
|
|
267949
268108
|
return;
|
|
267950
268109
|
}
|
|
267951
268110
|
await ensureLocalMemfsCheckout2(parsed.agent_id);
|
|
267952
|
-
if (!
|
|
268111
|
+
if (!existsSync52(join78(memoryRoot, ".git"))) {
|
|
267953
268112
|
sendFailure("failed to initialize local memory checkout");
|
|
267954
268113
|
return;
|
|
267955
268114
|
}
|
|
@@ -267995,7 +268154,7 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
267995
268154
|
} = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
267996
268155
|
const { commitMemoryWrite: commitMemoryWrite2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
|
|
267997
268156
|
const { writeFile: writeFile16, mkdir: mkdir14 } = await import("node:fs/promises");
|
|
267998
|
-
const { existsSync:
|
|
268157
|
+
const { existsSync: existsSync52 } = await import("node:fs");
|
|
267999
268158
|
const { dirname: dirname34, isAbsolute: isAbsolute25, join: join78, normalize: normalize4, relative: relative8, sep: sep8 } = await import("node:path");
|
|
268000
268159
|
if (isAbsolute25(parsed.path) || parsed.path.length === 0) {
|
|
268001
268160
|
sendFailure("write_memory_file: path must be a non-empty relative path");
|
|
@@ -268008,14 +268167,14 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
268008
268167
|
sendFailure("write_memory_file: path must resolve inside the memory root");
|
|
268009
268168
|
return;
|
|
268010
268169
|
}
|
|
268011
|
-
if (!
|
|
268170
|
+
if (!existsSync52(join78(memoryRoot, ".git"))) {
|
|
268012
268171
|
const enabled = await isMemfsEnabledOnServer2(parsed.agent_id);
|
|
268013
268172
|
if (!enabled) {
|
|
268014
268173
|
sendFailure("write_memory_file: memfs is not enabled for this agent");
|
|
268015
268174
|
return;
|
|
268016
268175
|
}
|
|
268017
268176
|
await ensureLocalMemfsCheckout2(parsed.agent_id);
|
|
268018
|
-
if (!
|
|
268177
|
+
if (!existsSync52(join78(memoryRoot, ".git"))) {
|
|
268019
268178
|
sendFailure("write_memory_file: failed to initialize local memory checkout");
|
|
268020
268179
|
return;
|
|
268021
268180
|
}
|
|
@@ -268093,7 +268252,7 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
268093
268252
|
} = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
268094
268253
|
const { commitMemoryWrite: commitMemoryWrite2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
|
|
268095
268254
|
const { unlink: unlink4 } = await import("node:fs/promises");
|
|
268096
|
-
const { existsSync:
|
|
268255
|
+
const { existsSync: existsSync52 } = await import("node:fs");
|
|
268097
268256
|
const { isAbsolute: isAbsolute25, join: join78, normalize: normalize4, relative: relative8, sep: sep8 } = await import("node:path");
|
|
268098
268257
|
if (isAbsolute25(parsed.path) || parsed.path.length === 0) {
|
|
268099
268258
|
sendFailure("delete_memory_file: path must be a non-empty relative path");
|
|
@@ -268106,21 +268265,21 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
268106
268265
|
sendFailure("delete_memory_file: path must resolve inside the memory root");
|
|
268107
268266
|
return;
|
|
268108
268267
|
}
|
|
268109
|
-
if (!
|
|
268268
|
+
if (!existsSync52(join78(memoryRoot, ".git"))) {
|
|
268110
268269
|
const enabled = await isMemfsEnabledOnServer2(parsed.agent_id);
|
|
268111
268270
|
if (!enabled) {
|
|
268112
268271
|
sendFailure("delete_memory_file: memfs is not enabled for this agent");
|
|
268113
268272
|
return;
|
|
268114
268273
|
}
|
|
268115
268274
|
await ensureLocalMemfsCheckout2(parsed.agent_id);
|
|
268116
|
-
if (!
|
|
268275
|
+
if (!existsSync52(join78(memoryRoot, ".git"))) {
|
|
268117
268276
|
sendFailure("delete_memory_file: failed to initialize local memory checkout");
|
|
268118
268277
|
return;
|
|
268119
268278
|
}
|
|
268120
268279
|
}
|
|
268121
268280
|
const pathspec = rel.split(sep8).join("/");
|
|
268122
268281
|
const removeIfPresent = async () => {
|
|
268123
|
-
if (!
|
|
268282
|
+
if (!existsSync52(absolutePath))
|
|
268124
268283
|
return false;
|
|
268125
268284
|
await unlink4(absolutePath);
|
|
268126
268285
|
return true;
|
|
@@ -268315,7 +268474,7 @@ __export(exports_remote_model_catalog, {
|
|
|
268315
268474
|
applyCatalogModels: () => applyCatalogModels,
|
|
268316
268475
|
__testResetRemoteModelCatalog: () => __testResetRemoteModelCatalog
|
|
268317
268476
|
});
|
|
268318
|
-
import { existsSync as
|
|
268477
|
+
import { existsSync as existsSync52, mkdirSync as mkdirSync40, readFileSync as readFileSync44, writeFileSync as writeFileSync34 } from "node:fs";
|
|
268319
268478
|
import { homedir as homedir40 } from "node:os";
|
|
268320
268479
|
import { dirname as dirname34, join as join78 } from "node:path";
|
|
268321
268480
|
function catalogCachePath() {
|
|
@@ -268419,7 +268578,7 @@ function persistCatalogCache(entries2, source) {
|
|
|
268419
268578
|
function loadPersistedModelCatalog(source) {
|
|
268420
268579
|
try {
|
|
268421
268580
|
const path33 = catalogCachePath();
|
|
268422
|
-
if (!
|
|
268581
|
+
if (!existsSync52(path33)) {
|
|
268423
268582
|
return false;
|
|
268424
268583
|
}
|
|
268425
268584
|
const parsed = JSON.parse(readFileSync44(path33, "utf-8"));
|
|
@@ -269112,7 +269271,7 @@ function recordStaleHandleUse(collector, owner, capability, onDiagnostic) {
|
|
|
269112
269271
|
var MOD_DIAGNOSTICS_MAX_COUNT = 200, MOD_DIAGNOSTICS_RESET_COUNT = 50, MOD_DYNAMIC_CONTEXT_MIGRATION_HINT = "Dynamic context is now passed as ctx to commands, tools, events, permissions, and UI renderers. Use ctx.agent, ctx.cwd, ctx.conversation, ctx.model, etc.", MOD_LETTA_GET_CONTEXT_MIGRATION_HINT = "letta.getContext has been removed. Activation has no dynamic invocation context. Move dynamic work into a command, tool, event, permission, status, or statusline callback that receives ctx, or use explicit/global state such as process.cwd() for activation-time background work.", MOD_CTX_GET_CONTEXT_MIGRATION_HINT = "ctx.getContext has been removed. Use ctx directly; scoped fields are available as ctx.agent, ctx.cwd, ctx.conversation, ctx.model, etc.", MOD_GENERIC_GET_CONTEXT_MIGRATION_HINT = "getContext helpers have been removed. If this is callback ctx, use ctx directly; if activation/background code needs runtime state, move it into a callback that receives ctx or use explicit/global state such as process.cwd().";
|
|
269113
269272
|
|
|
269114
269273
|
// src/mods/paths.ts
|
|
269115
|
-
import { existsSync as
|
|
269274
|
+
import { existsSync as existsSync53 } from "node:fs";
|
|
269116
269275
|
import { homedir as homedir41 } from "node:os";
|
|
269117
269276
|
import path33 from "node:path";
|
|
269118
269277
|
function getGlobalModsDirectory(homeDirectory = homedir41()) {
|
|
@@ -269126,10 +269285,10 @@ function resolveDefaultGlobalModsDirectory(homeDirectory = homedir41(), env6 = p
|
|
|
269126
269285
|
if (environmentDirectory)
|
|
269127
269286
|
return environmentDirectory;
|
|
269128
269287
|
const modsDirectory = getGlobalModsDirectory(homeDirectory);
|
|
269129
|
-
if (
|
|
269288
|
+
if (existsSync53(modsDirectory))
|
|
269130
269289
|
return modsDirectory;
|
|
269131
269290
|
const legacyDirectory = getLegacyGlobalExtensionsDirectory(homeDirectory);
|
|
269132
|
-
if (
|
|
269291
|
+
if (existsSync53(legacyDirectory))
|
|
269133
269292
|
return legacyDirectory;
|
|
269134
269293
|
return modsDirectory;
|
|
269135
269294
|
}
|
|
@@ -377136,10 +377295,10 @@ ${lanes.join(`
|
|
|
377136
377295
|
}
|
|
377137
377296
|
function getDefaultLibFilePriority(a2) {
|
|
377138
377297
|
if (containsPath(defaultLibraryPath, a2.fileName, false)) {
|
|
377139
|
-
const
|
|
377140
|
-
if (
|
|
377298
|
+
const basename22 = getBaseFileName(a2.fileName);
|
|
377299
|
+
if (basename22 === "lib.d.ts" || basename22 === "lib.es6.d.ts")
|
|
377141
377300
|
return 0;
|
|
377142
|
-
const name = removeSuffix(removePrefix(
|
|
377301
|
+
const name = removeSuffix(removePrefix(basename22, "lib."), ".d.ts");
|
|
377143
377302
|
const index = libs.indexOf(name);
|
|
377144
377303
|
if (index !== -1)
|
|
377145
377304
|
return index + 1;
|
|
@@ -429702,8 +429861,8 @@ ${options.prefix}` : `
|
|
|
429702
429861
|
}
|
|
429703
429862
|
};
|
|
429704
429863
|
for (const file of files) {
|
|
429705
|
-
const
|
|
429706
|
-
if (
|
|
429864
|
+
const basename22 = getBaseFileName(file);
|
|
429865
|
+
if (basename22 === "package.json" || basename22 === "bower.json") {
|
|
429707
429866
|
createProjectWatcher(file, "FileWatcher");
|
|
429708
429867
|
continue;
|
|
429709
429868
|
}
|
|
@@ -432580,8 +432739,8 @@ All files are: ${JSON.stringify(names2)}`, "Err");
|
|
|
432580
432739
|
const fileOrDirectoryPath = removeIgnoredPath(this.toPath(fileOrDirectory));
|
|
432581
432740
|
if (!fileOrDirectoryPath)
|
|
432582
432741
|
return;
|
|
432583
|
-
const
|
|
432584
|
-
if (((_a10 = result3.affectedModuleSpecifierCacheProjects) == null ? undefined : _a10.size) && (
|
|
432742
|
+
const basename22 = getBaseFileName(fileOrDirectoryPath);
|
|
432743
|
+
if (((_a10 = result3.affectedModuleSpecifierCacheProjects) == null ? undefined : _a10.size) && (basename22 === "package.json" || basename22 === "node_modules")) {
|
|
432585
432744
|
result3.affectedModuleSpecifierCacheProjects.forEach((project) => {
|
|
432586
432745
|
var _a22;
|
|
432587
432746
|
(_a22 = project.getModuleSpecifierCache()) == null || _a22.clear();
|
|
@@ -438187,7 +438346,7 @@ var init_package_manifest = __esm(() => {
|
|
|
438187
438346
|
|
|
438188
438347
|
// src/mods/package-registry.ts
|
|
438189
438348
|
import {
|
|
438190
|
-
existsSync as
|
|
438349
|
+
existsSync as existsSync54,
|
|
438191
438350
|
mkdirSync as mkdirSync42,
|
|
438192
438351
|
readFileSync as readFileSync46,
|
|
438193
438352
|
rmSync as rmSync21,
|
|
@@ -438259,7 +438418,7 @@ function getRegistryPath(modsRoot) {
|
|
|
438259
438418
|
}
|
|
438260
438419
|
function readRegistryObject(modsRoot) {
|
|
438261
438420
|
const registryPath = getRegistryPath(modsRoot);
|
|
438262
|
-
if (!
|
|
438421
|
+
if (!existsSync54(registryPath)) {
|
|
438263
438422
|
return { diagnostics: [], ok: false, registryExists: false, registryPath };
|
|
438264
438423
|
}
|
|
438265
438424
|
const registryResult = parseJsonFile(registryPath);
|
|
@@ -438691,7 +438850,7 @@ function writePackageRegistry(registryPath, registry4) {
|
|
|
438691
438850
|
}
|
|
438692
438851
|
function validateManagedModPackageRegistryForMutation(modsRoot) {
|
|
438693
438852
|
const registryPath = getRegistryPath(modsRoot);
|
|
438694
|
-
const contents =
|
|
438853
|
+
const contents = existsSync54(registryPath) ? readFileSync46(registryPath, "utf8") : null;
|
|
438695
438854
|
const registry4 = readMutablePackageRegistry(modsRoot, {
|
|
438696
438855
|
createIfMissing: true
|
|
438697
438856
|
});
|
|
@@ -438814,10 +438973,10 @@ var init_package_registry = __esm(() => {
|
|
|
438814
438973
|
});
|
|
438815
438974
|
|
|
438816
438975
|
// src/mods/mod-sources.ts
|
|
438817
|
-
import { existsSync as
|
|
438976
|
+
import { existsSync as existsSync55, readdirSync as readdirSync22 } from "node:fs";
|
|
438818
438977
|
import path37 from "node:path";
|
|
438819
438978
|
function listModFiles(directory) {
|
|
438820
|
-
if (!
|
|
438979
|
+
if (!existsSync55(directory))
|
|
438821
438980
|
return [];
|
|
438822
438981
|
return readdirSync22(directory, { withFileTypes: true }).filter((entry) => {
|
|
438823
438982
|
if (!entry.isFile())
|
|
@@ -438833,7 +438992,7 @@ function resolveLocalModSources(options = {}) {
|
|
|
438833
438992
|
const includeGlobalMods = options.includeGlobalMods !== false;
|
|
438834
438993
|
const managedPackages = includeGlobalMods ? resolveManagedModPackages(globalModsDirectory) : { diagnostics: [], files: [], packages: [] };
|
|
438835
438994
|
const sources = [];
|
|
438836
|
-
if (includeGlobalMods && legacyGlobalExtensionsDirectory && path37.resolve(legacyGlobalExtensionsDirectory) !== path37.resolve(globalModsDirectory) &&
|
|
438995
|
+
if (includeGlobalMods && legacyGlobalExtensionsDirectory && path37.resolve(legacyGlobalExtensionsDirectory) !== path37.resolve(globalModsDirectory) && existsSync55(legacyGlobalExtensionsDirectory)) {
|
|
438837
438996
|
sources.push({
|
|
438838
438997
|
files: listModFiles(legacyGlobalExtensionsDirectory),
|
|
438839
438998
|
legacyMigrationTargetRoot: globalModsDirectory,
|
|
@@ -438872,7 +439031,7 @@ var init_mod_sources = __esm(() => {
|
|
|
438872
439031
|
|
|
438873
439032
|
// src/mods/runtime-dependencies.ts
|
|
438874
439033
|
import {
|
|
438875
|
-
lstatSync as
|
|
439034
|
+
lstatSync as lstatSync3,
|
|
438876
439035
|
mkdirSync as mkdirSync43,
|
|
438877
439036
|
readlinkSync,
|
|
438878
439037
|
symlinkSync,
|
|
@@ -438893,7 +439052,7 @@ function ensureRuntimeDependencySymlink(cacheDirectory, packageName, resolveRunt
|
|
|
438893
439052
|
const packageDirectory = path38.resolve(resolveRuntimePackageDirectory(packageName));
|
|
438894
439053
|
mkdirSync43(nodeModulesDirectory, { recursive: true });
|
|
438895
439054
|
try {
|
|
438896
|
-
const stats =
|
|
439055
|
+
const stats = lstatSync3(linkPath);
|
|
438897
439056
|
if (!stats.isSymbolicLink())
|
|
438898
439057
|
return;
|
|
438899
439058
|
const existingTarget = readlinkSync(linkPath);
|
|
@@ -439012,7 +439171,7 @@ function createNoopModPanelHandle() {
|
|
|
439012
439171
|
// src/mods/mod-engine.ts
|
|
439013
439172
|
import { createHash as createHash16 } from "node:crypto";
|
|
439014
439173
|
import {
|
|
439015
|
-
existsSync as
|
|
439174
|
+
existsSync as existsSync56,
|
|
439016
439175
|
mkdirSync as mkdirSync44,
|
|
439017
439176
|
readdirSync as readdirSync23,
|
|
439018
439177
|
readFileSync as readFileSync47,
|
|
@@ -439202,7 +439361,7 @@ function createImportableModPath(modPath, cacheDirectory, source) {
|
|
|
439202
439361
|
}
|
|
439203
439362
|
const baseName = path39.basename(modPath, fileExtension).replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
439204
439363
|
const importPath = path39.join(importCacheDirectory, `.letta-mod-${baseName}-${hash3}.mjs`);
|
|
439205
|
-
if (!
|
|
439364
|
+
if (!existsSync56(importPath)) {
|
|
439206
439365
|
writeFileSync37(importPath, importableSource, "utf8");
|
|
439207
439366
|
}
|
|
439208
439367
|
try {
|
|
@@ -442625,19 +442784,19 @@ function emitSkillsUpdated(socket, safeSocketSend) {
|
|
|
442625
442784
|
}
|
|
442626
442785
|
async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
442627
442786
|
const {
|
|
442628
|
-
existsSync:
|
|
442629
|
-
lstatSync:
|
|
442787
|
+
existsSync: existsSync57,
|
|
442788
|
+
lstatSync: lstatSync4,
|
|
442630
442789
|
mkdirSync: mkdirSync45,
|
|
442631
442790
|
rmdirSync: rmdirSync2,
|
|
442632
442791
|
symlinkSync: symlinkSync2,
|
|
442633
442792
|
unlinkSync: unlinkSync15
|
|
442634
442793
|
} = await import("node:fs");
|
|
442635
|
-
const { basename:
|
|
442794
|
+
const { basename: basename22, join: join80 } = await import("node:path");
|
|
442636
442795
|
const lettaHome = process.env.LETTA_HOME || join80(process.env.HOME || process.env.USERPROFILE || "~", ".letta");
|
|
442637
442796
|
const globalSkillsDir = join80(lettaHome, "skills");
|
|
442638
442797
|
if (parsed.type === "skill_enable") {
|
|
442639
442798
|
try {
|
|
442640
|
-
if (!
|
|
442799
|
+
if (!existsSync57(parsed.skill_path)) {
|
|
442641
442800
|
safeSocketSend(socket, {
|
|
442642
442801
|
type: "skill_enable_response",
|
|
442643
442802
|
request_id: parsed.request_id,
|
|
@@ -442647,7 +442806,7 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
442647
442806
|
return true;
|
|
442648
442807
|
}
|
|
442649
442808
|
const skillMdPath = join80(parsed.skill_path, "SKILL.md");
|
|
442650
|
-
if (!
|
|
442809
|
+
if (!existsSync57(skillMdPath)) {
|
|
442651
442810
|
safeSocketSend(socket, {
|
|
442652
442811
|
type: "skill_enable_response",
|
|
442653
442812
|
request_id: parsed.request_id,
|
|
@@ -442656,11 +442815,11 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
442656
442815
|
}, "listener_skill_send_failed", "listener_skill_command");
|
|
442657
442816
|
return true;
|
|
442658
442817
|
}
|
|
442659
|
-
const linkName =
|
|
442818
|
+
const linkName = basename22(parsed.skill_path);
|
|
442660
442819
|
const linkPath = join80(globalSkillsDir, linkName);
|
|
442661
442820
|
mkdirSync45(globalSkillsDir, { recursive: true });
|
|
442662
|
-
if (
|
|
442663
|
-
const stat12 =
|
|
442821
|
+
if (existsSync57(linkPath)) {
|
|
442822
|
+
const stat12 = lstatSync4(linkPath);
|
|
442664
442823
|
if (stat12.isSymbolicLink()) {
|
|
442665
442824
|
if (process.platform === "win32") {
|
|
442666
442825
|
rmdirSync2(linkPath);
|
|
@@ -442701,7 +442860,7 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
442701
442860
|
if (parsed.type === "skill_disable") {
|
|
442702
442861
|
try {
|
|
442703
442862
|
const linkPath = join80(globalSkillsDir, parsed.name);
|
|
442704
|
-
if (!
|
|
442863
|
+
if (!existsSync57(linkPath)) {
|
|
442705
442864
|
safeSocketSend(socket, {
|
|
442706
442865
|
type: "skill_disable_response",
|
|
442707
442866
|
request_id: parsed.request_id,
|
|
@@ -442710,7 +442869,7 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
442710
442869
|
}, "listener_skill_send_failed", "listener_skill_command");
|
|
442711
442870
|
return true;
|
|
442712
442871
|
}
|
|
442713
|
-
const stat12 =
|
|
442872
|
+
const stat12 = lstatSync4(linkPath);
|
|
442714
442873
|
if (!stat12.isSymbolicLink()) {
|
|
442715
442874
|
safeSocketSend(socket, {
|
|
442716
442875
|
type: "skill_disable_response",
|
|
@@ -443209,7 +443368,7 @@ function populateInterruptQueue(runtime, input) {
|
|
|
443209
443368
|
type: "approval",
|
|
443210
443369
|
tool_call_id: toolCallId,
|
|
443211
443370
|
approve: false,
|
|
443212
|
-
reason: "User interrupted the stream"
|
|
443371
|
+
reason: input.denialReason ?? "User interrupted the stream"
|
|
443213
443372
|
}));
|
|
443214
443373
|
runtime.pendingInterruptedContext = {
|
|
443215
443374
|
agentId: input.agentId,
|
|
@@ -443621,7 +443780,7 @@ var init_control_inputs = __esm(async () => {
|
|
|
443621
443780
|
});
|
|
443622
443781
|
|
|
443623
443782
|
// src/websocket/terminal-handler.ts
|
|
443624
|
-
import { existsSync as
|
|
443783
|
+
import { existsSync as existsSync57 } from "node:fs";
|
|
443625
443784
|
import * as os7 from "node:os";
|
|
443626
443785
|
import WebSocket7 from "ws";
|
|
443627
443786
|
function getTerminalKey(connectionId, terminalId) {
|
|
@@ -443637,7 +443796,7 @@ function getDefaultShell() {
|
|
|
443637
443796
|
"/bin/bash"
|
|
443638
443797
|
];
|
|
443639
443798
|
for (const candidate of candidates2) {
|
|
443640
|
-
if (candidate &&
|
|
443799
|
+
if (candidate && existsSync57(candidate)) {
|
|
443641
443800
|
return candidate;
|
|
443642
443801
|
}
|
|
443643
443802
|
}
|
|
@@ -444034,6 +444193,24 @@ function revokeRecoveryClaims(listener, connectionId, connectionGeneration) {
|
|
|
444034
444193
|
claim.revoke();
|
|
444035
444194
|
}
|
|
444036
444195
|
}
|
|
444196
|
+
function recoveryRefusals(listener) {
|
|
444197
|
+
const generation4 = listener.connectionGeneration ?? undefined;
|
|
444198
|
+
let state2 = refusalCounts.get(listener);
|
|
444199
|
+
if (!state2 || state2.generation !== generation4) {
|
|
444200
|
+
state2 = { generation: generation4, count: 0, refused: false };
|
|
444201
|
+
refusalCounts.set(listener, state2);
|
|
444202
|
+
}
|
|
444203
|
+
return state2;
|
|
444204
|
+
}
|
|
444205
|
+
function recoveryRetryDelay(listener, base2) {
|
|
444206
|
+
const state2 = recoveryRefusals(listener);
|
|
444207
|
+
if (!state2.refused)
|
|
444208
|
+
return base2;
|
|
444209
|
+
state2.refused = false;
|
|
444210
|
+
if (++state2.count === 5)
|
|
444211
|
+
debugWarn("recovery", "Recovery refused because another connection owns the conversation; abandoned until the next reconnect");
|
|
444212
|
+
return state2.count >= 5 ? Infinity : Math.min(base2 * 2 ** (state2.count - 1), 300000);
|
|
444213
|
+
}
|
|
444037
444214
|
async function acquireRecoveryClaim(runtime, onLost = () => {}, dependencies4 = {}) {
|
|
444038
444215
|
const connectionId = runtime.listener.connectionId;
|
|
444039
444216
|
const connectionGeneration = runtime.listener.connectionGeneration;
|
|
@@ -444074,8 +444251,13 @@ async function acquireRecoveryClaim(runtime, onLost = () => {}, dependencies4 =
|
|
|
444074
444251
|
const claim = new RecoveryClaim(runtime, runtime.agentId, runtime.conversationId, connectionId, connectionGeneration, response.token, response.fence, request2, dependencies4.schedule ?? ((callback, delay6) => setTimeout(callback, delay6)), dependencies4.cancel ?? ((timer) => clearTimeout(timer)), onLost, now2, requestedAt + RECOVERY_CLAIM_TTL_MS - RECOVERY_CLAIM_EXPIRY_MARGIN_MS);
|
|
444075
444252
|
runtime.listener.activeRecoveryClaims ??= new Set;
|
|
444076
444253
|
runtime.listener.activeRecoveryClaims.add(claim);
|
|
444254
|
+
refusalCounts.delete(runtime.listener);
|
|
444077
444255
|
return claim;
|
|
444078
444256
|
} catch (error5) {
|
|
444257
|
+
if (error5 instanceof ApiRequestError && error5.status === 409 && /"owner_mismatch"/.test(error5.responseText)) {
|
|
444258
|
+
recoveryRefusals(runtime.listener).refused = true;
|
|
444259
|
+
return null;
|
|
444260
|
+
}
|
|
444079
444261
|
debugWarn("recovery", "Recovery claim acquisition failed", error5);
|
|
444080
444262
|
return null;
|
|
444081
444263
|
}
|
|
@@ -444115,12 +444297,13 @@ async function getRecoveryEligibility(runtime, readStatus = getAgentRuntimeStatu
|
|
|
444115
444297
|
async function canRecoverConversation(runtime, readStatus = getAgentRuntimeStatus) {
|
|
444116
444298
|
return await getRecoveryEligibility(runtime, readStatus) === "owned";
|
|
444117
444299
|
}
|
|
444118
|
-
var RECOVERY_CLAIM_TTL_MS = 15000, RECOVERY_CLAIM_RENEW_MS = 5000, RECOVERY_CLAIM_EXPIRY_MARGIN_MS = 500, defaultRecoveryClaimRequest = (agentId, body3) => apiRequest("POST", `/v1/agents/${encodeURIComponent(agentId)}/recovery-claims`, body3, { signal: AbortSignal.timeout(5000) });
|
|
444300
|
+
var RECOVERY_CLAIM_TTL_MS = 15000, RECOVERY_CLAIM_RENEW_MS = 5000, RECOVERY_CLAIM_EXPIRY_MARGIN_MS = 500, defaultRecoveryClaimRequest = (agentId, body3) => apiRequest("POST", `/v1/agents/${encodeURIComponent(agentId)}/recovery-claims`, body3, { signal: AbortSignal.timeout(5000) }), refusalCounts;
|
|
444119
444301
|
var init_recovery_ownership = __esm(async () => {
|
|
444120
444302
|
init_agents8();
|
|
444121
444303
|
init_request();
|
|
444122
444304
|
init_debug();
|
|
444123
444305
|
await init_teleport();
|
|
444306
|
+
refusalCounts = new WeakMap;
|
|
444124
444307
|
});
|
|
444125
444308
|
|
|
444126
444309
|
// src/agent/approval-recovery.ts
|
|
@@ -445679,7 +445862,7 @@ var init_tui_perf = __esm(() => {
|
|
|
445679
445862
|
|
|
445680
445863
|
// src/cli/helpers/chunk-log.ts
|
|
445681
445864
|
import {
|
|
445682
|
-
existsSync as
|
|
445865
|
+
existsSync as existsSync58,
|
|
445683
445866
|
mkdirSync as mkdirSync46,
|
|
445684
445867
|
readdirSync as readdirSync24,
|
|
445685
445868
|
unlinkSync as unlinkSync15,
|
|
@@ -445780,7 +445963,7 @@ class ChunkLog {
|
|
|
445780
445963
|
if (this.dirCreated || !this.agentDir)
|
|
445781
445964
|
return;
|
|
445782
445965
|
try {
|
|
445783
|
-
if (!
|
|
445966
|
+
if (!existsSync58(this.agentDir)) {
|
|
445784
445967
|
mkdirSync46(this.agentDir, { recursive: true });
|
|
445785
445968
|
}
|
|
445786
445969
|
this.dirCreated = true;
|
|
@@ -445805,7 +445988,7 @@ class ChunkLog {
|
|
|
445805
445988
|
if (!this.agentDir)
|
|
445806
445989
|
return;
|
|
445807
445990
|
try {
|
|
445808
|
-
if (!
|
|
445991
|
+
if (!existsSync58(this.agentDir))
|
|
445809
445992
|
return;
|
|
445810
445993
|
const files = readdirSync24(this.agentDir).filter((f4) => f4.endsWith(".jsonl")).sort();
|
|
445811
445994
|
if (files.length >= MAX_SESSION_FILES2) {
|
|
@@ -447233,6 +447416,7 @@ function finishListenerTurn(runtime, lease, options) {
|
|
|
447233
447416
|
debugWarn("recovery", "Failed to retire completed listener work", error5);
|
|
447234
447417
|
}
|
|
447235
447418
|
}
|
|
447419
|
+
runtime.activeConnectionId = null;
|
|
447236
447420
|
return transition2;
|
|
447237
447421
|
}
|
|
447238
447422
|
var init_turn_terminal = __esm(async () => {
|
|
@@ -449703,7 +449887,7 @@ __export(exports_diff, {
|
|
|
449703
449887
|
ADV_DIFF_IGNORE_WHITESPACE: () => ADV_DIFF_IGNORE_WHITESPACE,
|
|
449704
449888
|
ADV_DIFF_CONTEXT_LINES: () => ADV_DIFF_CONTEXT_LINES
|
|
449705
449889
|
});
|
|
449706
|
-
import { basename as
|
|
449890
|
+
import { basename as basename22 } from "node:path";
|
|
449707
449891
|
function readFileOrNull(p2) {
|
|
449708
449892
|
try {
|
|
449709
449893
|
return __require("node:fs").readFileSync(p2, "utf-8");
|
|
@@ -449727,7 +449911,7 @@ function applyAllOccurrences(content, oldStr, newStr) {
|
|
|
449727
449911
|
return { ok: true, out: content.split(oldStr).join(newStr) };
|
|
449728
449912
|
}
|
|
449729
449913
|
function computeAdvancedDiff(input, opts) {
|
|
449730
|
-
const fileName =
|
|
449914
|
+
const fileName = basename22(input.filePath || "");
|
|
449731
449915
|
const fileContent = opts?.oldStrOverride !== undefined ? opts.oldStrOverride : readFileOrNull(input.filePath);
|
|
449732
449916
|
if (fileContent === null && input.kind !== "write") {
|
|
449733
449917
|
return { mode: "fallback", reason: "File not readable" };
|
|
@@ -449759,7 +449943,7 @@ function computeAdvancedDiff(input, opts) {
|
|
|
449759
449943
|
return { mode: "advanced", fileName, oldStr, newStr, hunks };
|
|
449760
449944
|
}
|
|
449761
449945
|
function parsePatchToAdvancedDiff(patchLines, filePath) {
|
|
449762
|
-
const fileName =
|
|
449946
|
+
const fileName = basename22(filePath);
|
|
449763
449947
|
const hunks = [];
|
|
449764
449948
|
let currentHunk = null;
|
|
449765
449949
|
let oldLine = 1;
|
|
@@ -450037,8 +450221,8 @@ function isFormatterSegment(tokens) {
|
|
|
450037
450221
|
}
|
|
450038
450222
|
}
|
|
450039
450223
|
function isShellExecutor2(token2) {
|
|
450040
|
-
const
|
|
450041
|
-
return ["bash", "sh", "zsh", "dash", "ksh"].includes(
|
|
450224
|
+
const basename23 = token2.split("/").pop() ?? token2;
|
|
450225
|
+
return ["bash", "sh", "zsh", "dash", "ksh"].includes(basename23.toLowerCase());
|
|
450042
450226
|
}
|
|
450043
450227
|
function normalizeRawCommand(command) {
|
|
450044
450228
|
if (Array.isArray(command)) {
|
|
@@ -450825,7 +451009,7 @@ var init_format_args_display = __esm(() => {
|
|
|
450825
451009
|
});
|
|
450826
451010
|
|
|
450827
451011
|
// src/helpers/diff-preview.ts
|
|
450828
|
-
import path41, { basename as
|
|
451012
|
+
import path41, { basename as basename23 } from "node:path";
|
|
450829
451013
|
function parseHunkLinePrefix(raw2) {
|
|
450830
451014
|
if (raw2.length === 0) {
|
|
450831
451015
|
return { type: "context", content: "" };
|
|
@@ -450931,7 +451115,7 @@ async function computeDiffPreviews(toolName2, toolArgs, workingDirectory = getCu
|
|
|
450931
451115
|
filePath: resolvedFilePath,
|
|
450932
451116
|
content: toolArgs.content || ""
|
|
450933
451117
|
});
|
|
450934
|
-
previews.push(toDiffPreview(result3,
|
|
451118
|
+
previews.push(toDiffPreview(result3, basename23(filePath)));
|
|
450935
451119
|
}
|
|
450936
451120
|
} else if (isFileEditTool3(toolName2)) {
|
|
450937
451121
|
const filePath = toolArgs.file_path;
|
|
@@ -450944,7 +451128,7 @@ async function computeDiffPreviews(toolName2, toolArgs, workingDirectory = getCu
|
|
|
450944
451128
|
newString: toolArgs.new_string || "",
|
|
450945
451129
|
replaceAll: toolArgs.replace_all
|
|
450946
451130
|
});
|
|
450947
|
-
previews.push(toDiffPreview(result3,
|
|
451131
|
+
previews.push(toDiffPreview(result3, basename23(filePath)));
|
|
450948
451132
|
}
|
|
450949
451133
|
} else if (isPatchTool2(toolName2) && toolArgs.input) {
|
|
450950
451134
|
const operations2 = parsePatchOperations2(toolArgs.input);
|
|
@@ -450952,7 +451136,7 @@ async function computeDiffPreviews(toolName2, toolArgs, workingDirectory = getCu
|
|
|
450952
451136
|
if (op.kind === "add" || op.kind === "update") {
|
|
450953
451137
|
const result3 = parsePatchToAdvancedDiff2(op.patchLines, op.path);
|
|
450954
451138
|
if (result3) {
|
|
450955
|
-
previews.push(toDiffPreview(result3,
|
|
451139
|
+
previews.push(toDiffPreview(result3, basename23(op.path)));
|
|
450956
451140
|
}
|
|
450957
451141
|
}
|
|
450958
451142
|
}
|
|
@@ -451008,7 +451192,28 @@ function safeJsonParseOr(json2, defaultValue) {
|
|
|
451008
451192
|
async function getMissingRequiredArgs(toolName2, parsedArgs, toolContextId) {
|
|
451009
451193
|
const schema5 = getToolSchema(toolName2, toolContextId);
|
|
451010
451194
|
const required6 = schema5?.input_schema?.required || [];
|
|
451011
|
-
|
|
451195
|
+
const properties4 = schema5?.input_schema?.properties;
|
|
451196
|
+
return required6.filter((key3) => {
|
|
451197
|
+
if (!(key3 in parsedArgs) || parsedArgs[key3] === undefined)
|
|
451198
|
+
return true;
|
|
451199
|
+
if (parsedArgs[key3] === null)
|
|
451200
|
+
return !schemaAllowsNull2(properties4?.[key3]);
|
|
451201
|
+
return false;
|
|
451202
|
+
});
|
|
451203
|
+
}
|
|
451204
|
+
function typeAllowsNull(schema5) {
|
|
451205
|
+
if (!schema5 || typeof schema5 !== "object")
|
|
451206
|
+
return false;
|
|
451207
|
+
const type3 = schema5.type;
|
|
451208
|
+
return type3 === "null" || Array.isArray(type3) && type3.includes("null");
|
|
451209
|
+
}
|
|
451210
|
+
function schemaAllowsNull2(schema5) {
|
|
451211
|
+
if (typeAllowsNull(schema5))
|
|
451212
|
+
return true;
|
|
451213
|
+
if (!schema5 || typeof schema5 !== "object")
|
|
451214
|
+
return false;
|
|
451215
|
+
const { anyOf: anyOf3, oneOf: oneOf3 } = schema5;
|
|
451216
|
+
return [anyOf3, oneOf3].some((branches) => Array.isArray(branches) && branches.some(typeAllowsNull));
|
|
451012
451217
|
}
|
|
451013
451218
|
function formatMissingRequiredArgsReason(toolName2, parsedArgs, missingRequiredArgs, argsParse) {
|
|
451014
451219
|
const received = Object.keys(parsedArgs).join(", ");
|
|
@@ -451685,7 +451890,7 @@ async function handleApprovalStop(params) {
|
|
|
451685
451890
|
const sendOptions = buildSendOptions() ?? {};
|
|
451686
451891
|
if (shouldInterrupt())
|
|
451687
451892
|
return interruptTermination();
|
|
451688
|
-
const consumedQueuedTurn = params.allowQueuedContinuation === false ? null : consumeQueuedTurn(runtime
|
|
451893
|
+
const consumedQueuedTurn = params.allowQueuedContinuation === false ? null : consumeQueuedTurn(runtime);
|
|
451689
451894
|
if (consumedQueuedTurn) {
|
|
451690
451895
|
const { dequeuedBatch, queuedTurn } = consumedQueuedTurn;
|
|
451691
451896
|
await params.onConsumeQueuedTurn?.(queuedTurn);
|
|
@@ -451797,7 +452002,7 @@ var init_turn_approval = __esm(async () => {
|
|
|
451797
452002
|
});
|
|
451798
452003
|
|
|
451799
452004
|
// src/agent/attached-repository-git-sync.ts
|
|
451800
|
-
import { existsSync as
|
|
452005
|
+
import { existsSync as existsSync59 } from "node:fs";
|
|
451801
452006
|
import { join as join81 } from "node:path";
|
|
451802
452007
|
async function getPendingCommitCount(path42) {
|
|
451803
452008
|
const divergence = await getMemoryAheadBehind(path42);
|
|
@@ -451828,7 +452033,7 @@ async function syncPendingAttachedRepositoryCommitsUnlocked(params) {
|
|
|
451828
452033
|
path: path42,
|
|
451829
452034
|
permissions: params.repository.permissions ?? "unknown"
|
|
451830
452035
|
};
|
|
451831
|
-
if (!
|
|
452036
|
+
if (!existsSync59(join81(path42, ".git"))) {
|
|
451832
452037
|
return {
|
|
451833
452038
|
...resultBase,
|
|
451834
452039
|
status: "skipped",
|
|
@@ -451998,7 +452203,7 @@ var init_attached_repository_git_sync = __esm(() => {
|
|
|
451998
452203
|
});
|
|
451999
452204
|
|
|
452000
452205
|
// src/reminders/memory-git-sync.ts
|
|
452001
|
-
import { existsSync as
|
|
452206
|
+
import { existsSync as existsSync60 } from "node:fs";
|
|
452002
452207
|
import { join as join82 } from "node:path";
|
|
452003
452208
|
function formatMemoryRepairInProgressReminder(result3) {
|
|
452004
452209
|
return `${SYSTEM_REMINDER_OPEN}
|
|
@@ -452109,7 +452314,7 @@ async function runPostTurnMemorySync(params, dependencies4 = {}) {
|
|
|
452109
452314
|
if (memorySyncEnabled) {
|
|
452110
452315
|
try {
|
|
452111
452316
|
const memoryDir = getScopedMemoryFilesystemRoot(params.agentId);
|
|
452112
|
-
const release =
|
|
452317
|
+
const release = existsSync60(join82(memoryDir, ".git")) ? await (dependencies4.claimOperation ?? claimMemoryOperation)(memoryDir) : undefined;
|
|
452113
452318
|
if (release !== null) {
|
|
452114
452319
|
try {
|
|
452115
452320
|
const result3 = await syncMemory(params.agentId);
|
|
@@ -452946,12 +453151,12 @@ function rowToolCalls(row, index, diagnostics2) {
|
|
|
452946
453151
|
}
|
|
452947
453152
|
return calls;
|
|
452948
453153
|
}
|
|
452949
|
-
function
|
|
453154
|
+
function contentText3(content) {
|
|
452950
453155
|
if (typeof content === "string") {
|
|
452951
453156
|
if (content.startsWith(CONTENT_JSON_PREFIX)) {
|
|
452952
453157
|
const encoded = content.slice(CONTENT_JSON_PREFIX.length);
|
|
452953
453158
|
try {
|
|
452954
|
-
return
|
|
453159
|
+
return contentText3(JSON.parse(encoded));
|
|
452955
453160
|
} catch {
|
|
452956
453161
|
return encoded;
|
|
452957
453162
|
}
|
|
@@ -453037,7 +453242,7 @@ var init_hermes = __esm(() => {
|
|
|
453037
453242
|
});
|
|
453038
453243
|
};
|
|
453039
453244
|
if (row.role === "user") {
|
|
453040
|
-
const content =
|
|
453245
|
+
const content = contentText3(row.content);
|
|
453041
453246
|
if (content) {
|
|
453042
453247
|
emit({
|
|
453043
453248
|
type: "message",
|
|
@@ -453057,7 +453262,7 @@ var init_hermes = __esm(() => {
|
|
|
453057
453262
|
...timestamp ? { timestamp } : {}
|
|
453058
453263
|
});
|
|
453059
453264
|
}
|
|
453060
|
-
const content =
|
|
453265
|
+
const content = contentText3(row.content);
|
|
453061
453266
|
if (content) {
|
|
453062
453267
|
emit({
|
|
453063
453268
|
type: "message",
|
|
@@ -453080,7 +453285,7 @@ var init_hermes = __esm(() => {
|
|
|
453080
453285
|
if (row.role === "tool") {
|
|
453081
453286
|
emit({
|
|
453082
453287
|
type: "tool_result",
|
|
453083
|
-
content:
|
|
453288
|
+
content: contentText3(row.content),
|
|
453084
453289
|
...typeof row.tool_call_id === "string" && row.tool_call_id ? { callId: row.tool_call_id } : {},
|
|
453085
453290
|
...timestamp ? { timestamp } : {}
|
|
453086
453291
|
});
|
|
@@ -454722,7 +454927,7 @@ var init_listing_shared = __esm(() => {
|
|
|
454722
454927
|
|
|
454723
454928
|
// node_modules/@letta-ai/trajectory/dist/adapters/claude-code/list.js
|
|
454724
454929
|
import { homedir as homedir45 } from "node:os";
|
|
454725
|
-
import { basename as
|
|
454930
|
+
import { basename as basename24, join as join85 } from "node:path";
|
|
454726
454931
|
async function listClaudeCodeTrajectories(root2) {
|
|
454727
454932
|
const base2 = root2 ?? join85(homedir45(), ".claude", "projects");
|
|
454728
454933
|
const items3 = [];
|
|
@@ -454734,7 +454939,7 @@ async function listClaudeCodeTrajectories(root2) {
|
|
|
454734
454939
|
if (!entry.isFile || !entry.name.endsWith(".jsonl"))
|
|
454735
454940
|
continue;
|
|
454736
454941
|
const path42 = join85(projectPath, entry.name);
|
|
454737
|
-
const listing = listingFromFile(
|
|
454942
|
+
const listing = listingFromFile(basename24(entry.name, ".jsonl"), path42);
|
|
454738
454943
|
if (listing)
|
|
454739
454944
|
items3.push(listing);
|
|
454740
454945
|
}
|
|
@@ -454747,12 +454952,12 @@ var init_list = __esm(() => {
|
|
|
454747
454952
|
|
|
454748
454953
|
// node_modules/@letta-ai/trajectory/dist/adapters/codex/list.js
|
|
454749
454954
|
import { homedir as homedir46 } from "node:os";
|
|
454750
|
-
import { basename as
|
|
454955
|
+
import { basename as basename25, join as join86 } from "node:path";
|
|
454751
454956
|
async function listCodexTrajectories(root2) {
|
|
454752
454957
|
const base2 = root2 ?? join86(homedir46(), ".codex", "sessions");
|
|
454753
454958
|
const items3 = [];
|
|
454754
454959
|
for (const path42 of collectFiles(base2, ".jsonl", 4)) {
|
|
454755
|
-
const listing = listingFromFile(
|
|
454960
|
+
const listing = listingFromFile(basename25(path42, ".jsonl"), path42);
|
|
454756
454961
|
if (listing)
|
|
454757
454962
|
items3.push(listing);
|
|
454758
454963
|
}
|
|
@@ -454857,9 +455062,9 @@ var init_list5 = __esm(() => {
|
|
|
454857
455062
|
});
|
|
454858
455063
|
|
|
454859
455064
|
// node_modules/@letta-ai/trajectory/dist/adapters/openclaw/list.js
|
|
454860
|
-
import { existsSync as
|
|
455065
|
+
import { existsSync as existsSync61 } from "node:fs";
|
|
454861
455066
|
import { homedir as homedir50 } from "node:os";
|
|
454862
|
-
import { basename as
|
|
455067
|
+
import { basename as basename26, join as join90 } from "node:path";
|
|
454863
455068
|
async function listOpenClawTrajectories(root2) {
|
|
454864
455069
|
const base2 = root2 ?? defaultStateDir();
|
|
454865
455070
|
const items3 = [];
|
|
@@ -454872,7 +455077,7 @@ async function listOpenClawTrajectories(root2) {
|
|
|
454872
455077
|
if (!entry.isFile || !entry.name.endsWith(".jsonl"))
|
|
454873
455078
|
continue;
|
|
454874
455079
|
const path42 = join90(sessionsPath, entry.name);
|
|
454875
|
-
const listing = listingFromFile(
|
|
455080
|
+
const listing = listingFromFile(basename26(entry.name, ".jsonl"), path42);
|
|
454876
455081
|
if (listing)
|
|
454877
455082
|
items3.push(listing);
|
|
454878
455083
|
}
|
|
@@ -454884,7 +455089,7 @@ function defaultStateDir() {
|
|
|
454884
455089
|
if (override)
|
|
454885
455090
|
return override;
|
|
454886
455091
|
const current = join90(homedir50(), ".openclaw");
|
|
454887
|
-
if (
|
|
455092
|
+
if (existsSync61(current))
|
|
454888
455093
|
return current;
|
|
454889
455094
|
return join90(homedir50(), ".clawdbot");
|
|
454890
455095
|
}
|
|
@@ -457390,6 +457595,11 @@ var init_execution_context_mcp_originator = __esm(async () => {
|
|
|
457390
457595
|
await init_manager2();
|
|
457391
457596
|
});
|
|
457392
457597
|
|
|
457598
|
+
// src/websocket/listener/mcp-originator-scope.ts
|
|
457599
|
+
function getEffectiveMcpOriginatorId(message2) {
|
|
457600
|
+
return message2.mcpOriginatorTokenPresent === true ? message2.mcpOriginatorSuperRunId : undefined;
|
|
457601
|
+
}
|
|
457602
|
+
|
|
457393
457603
|
// src/websocket/listener/turn-finalizer.ts
|
|
457394
457604
|
function applyTurnOriginSwap(parkedInput, consumedTurn, turnToolContextId) {
|
|
457395
457605
|
retireMcpOriginatorTokensOnOriginSwap(parkedInput.mcpOriginatorSuperRunId, consumedTurn.mcpOriginatorSuperRunId);
|
|
@@ -457397,7 +457607,6 @@ function applyTurnOriginSwap(parkedInput, consumedTurn, turnToolContextId) {
|
|
|
457397
457607
|
}
|
|
457398
457608
|
function createQueuedTurnConsumer(params) {
|
|
457399
457609
|
return {
|
|
457400
|
-
activeOriginatorScope: getMcpOriginatorScope(params.parkedInput),
|
|
457401
457610
|
allowQueuedContinuation: params.parkedInput.messages.some((message2) => ("content" in message2)),
|
|
457402
457611
|
onConsumeQueuedTurn: async (queuedTurn) => {
|
|
457403
457612
|
applyTurnOriginSwap(params.parkedInput, queuedTurn, params.turnToolContextId);
|
|
@@ -457501,6 +457710,37 @@ var init_turn_finalizer = __esm(async () => {
|
|
|
457501
457710
|
]);
|
|
457502
457711
|
});
|
|
457503
457712
|
|
|
457713
|
+
// src/websocket/listener/turn-max-turns.ts
|
|
457714
|
+
function finishTurnIfMaxTurnsReached(params) {
|
|
457715
|
+
const { runtime, buffers, stopReason, agentId, conversationId } = params;
|
|
457716
|
+
const maxTurns = runtime.executionSettings?.max_turns;
|
|
457717
|
+
if (maxTurns === undefined || buffers.usage.stepCount < maxTurns || stopReason === "error" && params.fallbackError) {
|
|
457718
|
+
return false;
|
|
457719
|
+
}
|
|
457720
|
+
const message2 = `Maximum turns limit reached (${buffers.usage.stepCount}/${maxTurns} steps)`;
|
|
457721
|
+
if (stopReason === "requires_approval") {
|
|
457722
|
+
populateInterruptQueue(runtime, {
|
|
457723
|
+
lastExecutionResults: null,
|
|
457724
|
+
lastExecutingToolCallIds: [],
|
|
457725
|
+
lastNeedsUserInputToolCallIds: params.approvals.map((a2) => a2.toolCallId),
|
|
457726
|
+
agentId,
|
|
457727
|
+
conversationId,
|
|
457728
|
+
denialReason: message2
|
|
457729
|
+
});
|
|
457730
|
+
}
|
|
457731
|
+
params.finishTurn({
|
|
457732
|
+
stopReason: "max_steps",
|
|
457733
|
+
socket: params.socket,
|
|
457734
|
+
agentId,
|
|
457735
|
+
conversationId,
|
|
457736
|
+
errorNotice: { message: message2, runId: params.runId }
|
|
457737
|
+
});
|
|
457738
|
+
return true;
|
|
457739
|
+
}
|
|
457740
|
+
var init_turn_max_turns = __esm(async () => {
|
|
457741
|
+
await init_interrupts();
|
|
457742
|
+
});
|
|
457743
|
+
|
|
457504
457744
|
// src/websocket/listener/turn-observers.ts
|
|
457505
457745
|
function registerTurnObserver(otid, hooks) {
|
|
457506
457746
|
hooksByOtid.set(otid, hooks);
|
|
@@ -458387,18 +458627,18 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
|
|
|
458387
458627
|
break;
|
|
458388
458628
|
}
|
|
458389
458629
|
lastApprovalContinuationAccepted = false;
|
|
458390
|
-
|
|
458391
|
-
|
|
458392
|
-
|
|
458393
|
-
|
|
458394
|
-
|
|
458395
|
-
|
|
458396
|
-
|
|
458397
|
-
|
|
458398
|
-
|
|
458399
|
-
|
|
458400
|
-
|
|
458401
|
-
|
|
458630
|
+
if (finishTurnIfMaxTurnsReached({
|
|
458631
|
+
runtime,
|
|
458632
|
+
socket,
|
|
458633
|
+
buffers,
|
|
458634
|
+
stopReason,
|
|
458635
|
+
approvals,
|
|
458636
|
+
fallbackError,
|
|
458637
|
+
runId: runId || runtime.activeRunId,
|
|
458638
|
+
agentId,
|
|
458639
|
+
conversationId,
|
|
458640
|
+
finishTurn
|
|
458641
|
+
})) {
|
|
458402
458642
|
break;
|
|
458403
458643
|
}
|
|
458404
458644
|
if (stopReason === "end_turn") {
|
|
@@ -458925,6 +459165,7 @@ var init_turn = __esm(async () => {
|
|
|
458925
459165
|
init_turn_correlation(),
|
|
458926
459166
|
init_turn_durability_ownership(),
|
|
458927
459167
|
init_turn_finalizer(),
|
|
459168
|
+
init_turn_max_turns(),
|
|
458928
459169
|
init_turn_send(),
|
|
458929
459170
|
init_turn_setup(),
|
|
458930
459171
|
init_turn_status(),
|
|
@@ -460199,42 +460440,9 @@ function stampInboundUserMessageOtids(incoming) {
|
|
|
460199
460440
|
function rejectReplacement(reason) {
|
|
460200
460441
|
throw new Error(`Invalid listener replacement lineage: ${reason}`);
|
|
460201
460442
|
}
|
|
460202
|
-
function cloneRawData(frame) {
|
|
460203
|
-
if (Array.isArray(frame))
|
|
460204
|
-
return frame.map((chunk2) => Buffer.from(chunk2));
|
|
460205
|
-
if (Buffer.isBuffer(frame))
|
|
460206
|
-
return Buffer.from(frame);
|
|
460207
|
-
if (frame instanceof ArrayBuffer)
|
|
460208
|
-
return frame.slice(0);
|
|
460209
|
-
return Buffer.from(new Uint8Array(frame));
|
|
460210
|
-
}
|
|
460211
|
-
function cloneStartupFrameHandoff(handoff) {
|
|
460212
|
-
return handoff.kind === "overflow" ? { ...handoff } : { ...handoff, frames: handoff.frames.map(cloneRawData) };
|
|
460213
|
-
}
|
|
460214
|
-
function cloneDispositionLedger(ledger) {
|
|
460215
|
-
return {
|
|
460216
|
-
entries: new Map([...ledger.entries].map(([key3, entry]) => [key3, structuredClone(entry)])),
|
|
460217
|
-
scopeCounts: new Map(ledger.scopeCounts),
|
|
460218
|
-
quarantinedCount: ledger.quarantinedCount,
|
|
460219
|
-
abandonedReservations: new Map([...ledger.abandonedReservations].map(([key3, reservation]) => [
|
|
460220
|
-
key3,
|
|
460221
|
-
{ ...reservation }
|
|
460222
|
-
])),
|
|
460223
|
-
expiryQueue: ledger.expiryQueue.map((entry) => ({ ...entry })),
|
|
460224
|
-
expiryQueueHead: ledger.expiryQueueHead,
|
|
460225
|
-
nextGeneration: ledger.nextGeneration,
|
|
460226
|
-
persistentPath: ledger.persistentPath
|
|
460227
|
-
};
|
|
460228
|
-
}
|
|
460229
460443
|
function createListenerClientReplacement(runtime, opts) {
|
|
460230
460444
|
const lineageId = resolveStartupLineageId(runtime, opts);
|
|
460231
460445
|
const generation4 = runtime.startupGenerationByLineage.get(lineageId) ?? 0;
|
|
460232
|
-
const startupFrameHandoff = cloneStartupFrameHandoff(runtime.pendingStartupFramesByLineage.get(lineageId) ?? {
|
|
460233
|
-
kind: "frames",
|
|
460234
|
-
frames: [],
|
|
460235
|
-
byteLength: 0
|
|
460236
|
-
});
|
|
460237
|
-
const clientMessageIdsByRunIdByConversation = cloneTurnCorrelationIndex(runtime.clientMessageIdsByRunIdByConversation);
|
|
460238
460446
|
const replacement = Object.freeze({
|
|
460239
460447
|
deviceId: opts.deviceId,
|
|
460240
460448
|
connectionName: opts.connectionName,
|
|
@@ -460247,10 +460455,7 @@ function createListenerClientReplacement(runtime, opts) {
|
|
|
460247
460455
|
connectionName: opts.connectionName,
|
|
460248
460456
|
lineageId,
|
|
460249
460457
|
generation: generation4,
|
|
460250
|
-
authorityEpoch: getRuntimeAuthorityEpoch(runtime)
|
|
460251
|
-
ledger: cloneDispositionLedger(runtime.acceptedInputDispositionLedger),
|
|
460252
|
-
startupFrameHandoff: cloneStartupFrameHandoff(startupFrameHandoff),
|
|
460253
|
-
clientMessageIdsByRunIdByConversation: cloneTurnCorrelationIndex(clientMessageIdsByRunIdByConversation)
|
|
460458
|
+
authorityEpoch: getRuntimeAuthorityEpoch(runtime)
|
|
460254
460459
|
});
|
|
460255
460460
|
return replacement;
|
|
460256
460461
|
}
|
|
@@ -460265,54 +460470,29 @@ function resolveAdoptableReplacement(opts) {
|
|
|
460265
460470
|
rejectReplacement("identity_mismatch");
|
|
460266
460471
|
}
|
|
460267
460472
|
const issuer = provenance.issuer;
|
|
460268
|
-
if (succeededListenerRuntimes.has(issuer)) {
|
|
460269
|
-
rejectReplacement("superseded_issuer");
|
|
460270
|
-
}
|
|
460271
460473
|
if ((issuer.startupGenerationByLineage.get(provenance.lineageId) ?? 0) !== provenance.generation) {
|
|
460272
460474
|
rejectReplacement("stale_generation");
|
|
460273
460475
|
}
|
|
460274
460476
|
if (provenance.authorityEpoch === null || provenance.authorityEpoch !== getLatestRuntimeAuthorityEpoch()) {
|
|
460275
460477
|
rejectReplacement("unauthoritative_issuer");
|
|
460276
460478
|
}
|
|
460277
|
-
|
|
460278
|
-
if (issuer.intentionallyClosed) {
|
|
460279
|
-
if (activeRuntime2 !== null && activeRuntime2 !== issuer) {
|
|
460280
|
-
rejectReplacement("unauthoritative_issuer");
|
|
460281
|
-
}
|
|
460282
|
-
} else if (issuer !== activeRuntime2) {
|
|
460479
|
+
if (issuer.intentionallyClosed || issuer !== getActiveRuntime()) {
|
|
460283
460480
|
rejectReplacement("unauthoritative_issuer");
|
|
460284
460481
|
}
|
|
460285
460482
|
return provenance;
|
|
460286
460483
|
}
|
|
460287
|
-
function
|
|
460288
|
-
resolveAdoptableReplacement(opts);
|
|
460289
|
-
}
|
|
460290
|
-
function adoptListenerClientReplacement(runtime, opts) {
|
|
460484
|
+
function adoptListenerClientReplacement(opts) {
|
|
460291
460485
|
const provenance = resolveAdoptableReplacement(opts);
|
|
460292
|
-
|
|
460293
|
-
|
|
460294
|
-
|
|
460295
|
-
|
|
460296
|
-
|
|
460297
|
-
|
|
460298
|
-
runtime.acceptedInputDispositionLedger.abandonedReservations = new Map([
|
|
460299
|
-
...provenance.issuer.acceptedInputDispositionLedger.abandonedReservations
|
|
460300
|
-
].map(([key3, reservation]) => [key3, { ...reservation }]));
|
|
460301
|
-
runtime.clientMessageIdsByRunIdByConversation = mergeTurnCorrelationIndexes(provenance.clientMessageIdsByRunIdByConversation, provenance.issuer.clientMessageIdsByRunIdByConversation, runtime.clientMessageIdsByRunIdByConversation);
|
|
460302
|
-
runtime.startupGenerationByLineage.set(provenance.lineageId, provenance.generation);
|
|
460303
|
-
if (provenance.startupFrameHandoff.kind === "overflow" || provenance.startupFrameHandoff.frames.length > 0) {
|
|
460304
|
-
runtime.pendingStartupFramesByLineage.set(provenance.lineageId, cloneStartupFrameHandoff(provenance.startupFrameHandoff));
|
|
460305
|
-
}
|
|
460306
|
-
}
|
|
460307
|
-
var replacementProvenance, succeededListenerRuntimes;
|
|
460486
|
+
if (!provenance || !opts.replacement)
|
|
460487
|
+
return null;
|
|
460488
|
+
replacementProvenance.delete(opts.replacement);
|
|
460489
|
+
return provenance.issuer;
|
|
460490
|
+
}
|
|
460491
|
+
var replacementProvenance;
|
|
460308
460492
|
var init_listener_replacement = __esm(async () => {
|
|
460309
460493
|
init_startup_ingress();
|
|
460310
|
-
await
|
|
460311
|
-
init_runtime6(),
|
|
460312
|
-
init_turn_correlation()
|
|
460313
|
-
]);
|
|
460494
|
+
await init_runtime6();
|
|
460314
460495
|
replacementProvenance = new WeakMap;
|
|
460315
|
-
succeededListenerRuntimes = new WeakSet;
|
|
460316
460496
|
});
|
|
460317
460497
|
|
|
460318
460498
|
// src/websocket/listener/listener-task.ts
|
|
@@ -460592,9 +460772,9 @@ __export(exports_custom, {
|
|
|
460592
460772
|
GLOBAL_COMMANDS_DIR: () => GLOBAL_COMMANDS_DIR,
|
|
460593
460773
|
COMMANDS_DIR: () => COMMANDS_DIR
|
|
460594
460774
|
});
|
|
460595
|
-
import { existsSync as
|
|
460775
|
+
import { existsSync as existsSync62 } from "node:fs";
|
|
460596
460776
|
import { readdir as readdir11, readFile as readFile25 } from "node:fs/promises";
|
|
460597
|
-
import { basename as
|
|
460777
|
+
import { basename as basename28, dirname as dirname36, join as join93 } from "node:path";
|
|
460598
460778
|
async function getCustomCommands() {
|
|
460599
460779
|
if (cachedCommands !== null) {
|
|
460600
460780
|
return cachedCommands;
|
|
@@ -460626,7 +460806,7 @@ async function discoverCustomCommands(projectPath = join93(process.cwd(), COMMAN
|
|
|
460626
460806
|
return result3;
|
|
460627
460807
|
}
|
|
460628
460808
|
async function discoverFromDirectory(dirPath, source) {
|
|
460629
|
-
if (!
|
|
460809
|
+
if (!existsSync62(dirPath)) {
|
|
460630
460810
|
return [];
|
|
460631
460811
|
}
|
|
460632
460812
|
const commands = [];
|
|
@@ -460654,7 +460834,7 @@ async function findCommandFiles(currentPath, rootPath, commands, source) {
|
|
|
460654
460834
|
async function parseCommandFile(filePath, rootPath, source) {
|
|
460655
460835
|
const content = await readFile25(filePath, "utf-8");
|
|
460656
460836
|
const { frontmatter, body: body3 } = parseFrontmatter(content);
|
|
460657
|
-
const id2 =
|
|
460837
|
+
const id2 = basename28(filePath, ".md");
|
|
460658
460838
|
const relativePath = dirname36(filePath).slice(rootPath.length);
|
|
460659
460839
|
const namespace = relativePath.replace(/^[/\\]/, "") || undefined;
|
|
460660
460840
|
let description = getStringField(frontmatter, "description");
|
|
@@ -461673,7 +461853,6 @@ function buildAppServerInfoResponse(command, options) {
|
|
|
461673
461853
|
runtime_external_tools_update: true,
|
|
461674
461854
|
structured_outputs: options.backend === "api",
|
|
461675
461855
|
write_file_base64: true,
|
|
461676
|
-
mcp_originator_queue_isolation: true,
|
|
461677
461856
|
split_channels: false
|
|
461678
461857
|
}
|
|
461679
461858
|
};
|
|
@@ -463691,16 +463870,29 @@ async function preparePairedListenerTransport(params) {
|
|
|
463691
463870
|
runtime.streamTransport = streamSocket;
|
|
463692
463871
|
return { kind: "ready", transport: streamSocket, streamSocket };
|
|
463693
463872
|
}
|
|
463873
|
+
function createListenerLifecycleLog(opts) {
|
|
463874
|
+
return (message2) => {
|
|
463875
|
+
if (opts.onLog) {
|
|
463876
|
+
opts.onLog(`[Listen] ${message2}`);
|
|
463877
|
+
return;
|
|
463878
|
+
}
|
|
463879
|
+
debugLog("Listen", message2);
|
|
463880
|
+
};
|
|
463881
|
+
}
|
|
463882
|
+
function formatListenerSocketClose(channel, code2, reason) {
|
|
463883
|
+
const text3 = reason.toString();
|
|
463884
|
+
const truncated = text3.length > MAX_CLOSE_REASON_LENGTH ? `${text3.slice(0, MAX_CLOSE_REASON_LENGTH)}...` : text3;
|
|
463885
|
+
return `${channel} socket closed (code=${code2}, reason=${JSON.stringify(truncated)})`;
|
|
463886
|
+
}
|
|
463694
463887
|
function attachSplitStreamSocketHandlers(params) {
|
|
463695
463888
|
params.streamSocket.on("error", (error5) => {
|
|
463889
|
+
params.log?.(`stream socket error: ${error5.message}`);
|
|
463696
463890
|
params.trackListenerError("listener_stream_socket_error", error5, "listener_stream_socket");
|
|
463697
463891
|
if (isDebugEnabled())
|
|
463698
463892
|
console.error("[Listen] Stream WebSocket error:", error5);
|
|
463699
463893
|
});
|
|
463700
463894
|
params.streamSocket.on("close", (code2, reason) => {
|
|
463701
|
-
|
|
463702
|
-
console.log(`[Listen] Stream WebSocket closed (code: ${code2}, reason: ${reason.toString()})`);
|
|
463703
|
-
}
|
|
463895
|
+
params.log?.(formatListenerSocketClose("stream", code2, reason));
|
|
463704
463896
|
terminateControlAfterStreamClose(params.runtime, params.streamSocket, code2, reason);
|
|
463705
463897
|
});
|
|
463706
463898
|
}
|
|
@@ -463748,6 +463940,7 @@ function handleListenerSocketOpenFailure({
|
|
|
463748
463940
|
}
|
|
463749
463941
|
terminateCurrentSocketPair(runtime, controlSocket, streamSocket);
|
|
463750
463942
|
}
|
|
463943
|
+
var MAX_CLOSE_REASON_LENGTH = 120;
|
|
463751
463944
|
var init_split_stream_lifecycle = __esm(async () => {
|
|
463752
463945
|
init_debug();
|
|
463753
463946
|
init_constants3();
|
|
@@ -463945,7 +464138,9 @@ async function handleSubagentMessageCommand(command, parent, deps = {}) {
|
|
|
463945
464138
|
interrupt: receipt.interrupt,
|
|
463946
464139
|
captureReservation,
|
|
463947
464140
|
toolCallId: command.tool_call_id,
|
|
463948
|
-
publishResult: true
|
|
464141
|
+
publishResult: true,
|
|
464142
|
+
emitCompletionNotification: false,
|
|
464143
|
+
claimsParentRuntime: false
|
|
463949
464144
|
});
|
|
463950
464145
|
} catch (error5) {
|
|
463951
464146
|
await receipt.interrupt().catch(() => {
|
|
@@ -465410,10 +465605,10 @@ async function recoverRecordedTurns(listener, deps = {}) {
|
|
|
465410
465605
|
}
|
|
465411
465606
|
} finally {
|
|
465412
465607
|
recovering.delete(listener);
|
|
465608
|
+
const retryDelayMs = recoveryRetryDelay(listener, deps.retryDelayMs ?? 5000);
|
|
465413
465609
|
if (pendingRecoveries.delete(listener)) {
|
|
465414
465610
|
scheduleRecordedTurnRecovery(listener, () => recoverRecordedTurns(listener, deps), deps.retryDelayMs);
|
|
465415
|
-
} else if (deferred2 && !listener.intentionallyClosed) {
|
|
465416
|
-
const retryDelayMs = deps.retryDelayMs ?? 5000;
|
|
465611
|
+
} else if (deferred2 && Number.isFinite(retryDelayMs) && !listener.intentionallyClosed) {
|
|
465417
465612
|
const timer2 = setTimeout(() => {
|
|
465418
465613
|
retryTimers.delete(listener);
|
|
465419
465614
|
scheduleRecordedTurnRecovery(listener, () => recoverRecordedTurns(listener, deps), retryDelayMs);
|
|
@@ -465494,6 +465689,39 @@ var init_socket_send = __esm(() => {
|
|
|
465494
465689
|
init_debug();
|
|
465495
465690
|
});
|
|
465496
465691
|
|
|
465692
|
+
// src/websocket/listener/startup-deadline.ts
|
|
465693
|
+
function startListenerStartupDeadline(runtime, transport3, opts, enabled = true) {
|
|
465694
|
+
const socket = runtime.socket;
|
|
465695
|
+
if (!enabled || !socket || socket !== transport3)
|
|
465696
|
+
return () => {};
|
|
465697
|
+
const configured = Number(process.env.LETTA_LISTENER_STARTUP_DEADLINE_MS);
|
|
465698
|
+
const deadlineMs = Number.isFinite(configured) && configured > 0 ? configured : 60000;
|
|
465699
|
+
const clear = () => {
|
|
465700
|
+
clearTimeout(timer);
|
|
465701
|
+
socket.off("close", clear);
|
|
465702
|
+
};
|
|
465703
|
+
const timer = setTimeout(() => {
|
|
465704
|
+
clear();
|
|
465705
|
+
if (runtime.socket !== socket || runtime.intentionallyClosed)
|
|
465706
|
+
return;
|
|
465707
|
+
const message2 = `Listener startup did not finish within ${deadlineMs}ms; reconnecting`;
|
|
465708
|
+
try {
|
|
465709
|
+
if (opts.onLog)
|
|
465710
|
+
opts.onLog(message2);
|
|
465711
|
+
else
|
|
465712
|
+
debugLog("Listen", message2);
|
|
465713
|
+
} finally {
|
|
465714
|
+
socket.terminate();
|
|
465715
|
+
}
|
|
465716
|
+
}, deadlineMs);
|
|
465717
|
+
socket.once("close", clear);
|
|
465718
|
+
timer.unref();
|
|
465719
|
+
return clear;
|
|
465720
|
+
}
|
|
465721
|
+
var init_startup_deadline = __esm(() => {
|
|
465722
|
+
init_debug();
|
|
465723
|
+
});
|
|
465724
|
+
|
|
465497
465725
|
// src/websocket/listener/recovery-sync.ts
|
|
465498
465726
|
function isBackendNotFoundError2(error5) {
|
|
465499
465727
|
return error5 instanceof APIError && (error5.status === 404 || error5.status === 422) || error5 instanceof Error && error5.name === "LocalBackendNotFoundError";
|
|
@@ -465848,6 +466076,7 @@ async function startConnectedListenerRuntime(runtime, transport3, opts, processQ
|
|
|
465848
466076
|
startListenerPongHeartbeat(runtime, transport3, trackListenerError4);
|
|
465849
466077
|
}
|
|
465850
466078
|
const heartbeat = options.startHeartbeat !== false && runtime.heartbeatInterval;
|
|
466079
|
+
const clearStartupDeadline = startListenerStartupDeadline(runtime, transport3, opts, options.startStartupDeadline);
|
|
465851
466080
|
let startupComplete = false;
|
|
465852
466081
|
try {
|
|
465853
466082
|
if (!await completeInitialConnectionStartup(runtime, startupConnection, transport3, opts, options))
|
|
@@ -465869,6 +466098,7 @@ async function startConnectedListenerRuntime(runtime, transport3, opts, processQ
|
|
|
465869
466098
|
return;
|
|
465870
466099
|
startupComplete = true;
|
|
465871
466100
|
} finally {
|
|
466101
|
+
clearStartupDeadline();
|
|
465872
466102
|
if (!startupComplete && heartbeat) {
|
|
465873
466103
|
clearInterval(heartbeat);
|
|
465874
466104
|
if (runtime.heartbeatInterval === heartbeat)
|
|
@@ -466019,13 +466249,15 @@ async function attachOpenListenerSocket(runtime, socket, opts, options = {}) {
|
|
|
466019
466249
|
});
|
|
466020
466250
|
}
|
|
466021
466251
|
async function startListenerClient(opts) {
|
|
466022
|
-
|
|
466252
|
+
const resumedRuntime = adoptListenerClientReplacement(opts);
|
|
466023
466253
|
const existingRuntime = getActiveRuntime();
|
|
466024
|
-
if (existingRuntime)
|
|
466254
|
+
if (existingRuntime && !resumedRuntime)
|
|
466025
466255
|
stopRuntime(existingRuntime, true);
|
|
466256
|
+
const runtime = resumedRuntime ?? createRuntime();
|
|
466257
|
+
if (resumedRuntime && runtime.connectionId) {
|
|
466258
|
+
revokeRecoveryClaims(runtime, runtime.connectionId);
|
|
466259
|
+
resumeListenerConnectionIdentity(runtime, runtime.connectionId, opts.connectionId);
|
|
466026
466260
|
}
|
|
466027
|
-
const runtime = createRuntime();
|
|
466028
|
-
adoptListenerClientReplacement(runtime, opts);
|
|
466029
466261
|
runtime.onWsEvent = opts.onWsEvent;
|
|
466030
466262
|
runtime.connectionId = opts.connectionId;
|
|
466031
466263
|
runtime.connectionName = opts.connectionName;
|
|
@@ -466033,7 +466265,8 @@ async function startListenerClient(opts) {
|
|
|
466033
466265
|
telemetry.setSurface(getListenerTelemetrySurface());
|
|
466034
466266
|
telemetry.init();
|
|
466035
466267
|
setExplicitOrganizationId(opts.organizationId);
|
|
466036
|
-
|
|
466268
|
+
if (!resumedRuntime)
|
|
466269
|
+
await reloadListenerModAdapter(runtime);
|
|
466037
466270
|
await connectWithRetry(runtime, opts);
|
|
466038
466271
|
}
|
|
466039
466272
|
async function startLocalChannelListener(opts) {
|
|
@@ -466081,6 +466314,9 @@ async function connectWithRetry(runtime, opts, attempt2 = 0, startTime = Date.no
|
|
|
466081
466314
|
if (attempt2 > 0) {
|
|
466082
466315
|
if (elapsedTime >= MAX_RETRY_DURATION_MS) {
|
|
466083
466316
|
if (runtime.everConnected && opts.onNeedsReregister) {
|
|
466317
|
+
rejectPendingExternalToolCallsForConnection(runtime, opts.connectionId, "Listener connection re-registered");
|
|
466318
|
+
killListenerConnectionTerminals(opts.connectionId);
|
|
466319
|
+
revokeRecoveryClaims(runtime, opts.connectionId);
|
|
466084
466320
|
opts.onNeedsReregister(createListenerClientReplacement(runtime, opts));
|
|
466085
466321
|
return;
|
|
466086
466322
|
}
|
|
@@ -466124,6 +466360,7 @@ async function connectWithRetry(runtime, opts, attempt2 = 0, startTime = Date.no
|
|
|
466124
466360
|
const headers = { Authorization: `Bearer ${apiKey}` };
|
|
466125
466361
|
const socket = new WebSocket11(url2.toString(), { headers });
|
|
466126
466362
|
let streamSocket = streamUrl && !pairIdentity ? new WebSocket11(streamUrl.toString(), { headers }) : null;
|
|
466363
|
+
const lifecycleLog = createListenerLifecycleLog(opts);
|
|
466127
466364
|
const fileCommandSession = createFileCommandSession({
|
|
466128
466365
|
socket,
|
|
466129
466366
|
safeSocketSend,
|
|
@@ -466162,7 +466399,8 @@ async function connectWithRetry(runtime, opts, attempt2 = 0, startTime = Date.no
|
|
|
466162
466399
|
attachSplitStreamSocketHandlers({
|
|
466163
466400
|
runtime,
|
|
466164
466401
|
streamSocket,
|
|
466165
|
-
trackListenerError: trackListenerError4
|
|
466402
|
+
trackListenerError: trackListenerError4,
|
|
466403
|
+
log: lifecycleLog
|
|
466166
466404
|
});
|
|
466167
466405
|
}
|
|
466168
466406
|
socket.on("open", () => {
|
|
@@ -466192,7 +466430,8 @@ async function connectWithRetry(runtime, opts, attempt2 = 0, startTime = Date.no
|
|
|
466192
466430
|
attachSplitStreamSocketHandlers({
|
|
466193
466431
|
runtime,
|
|
466194
466432
|
streamSocket: streamOpen.streamSocket,
|
|
466195
|
-
trackListenerError: trackListenerError4
|
|
466433
|
+
trackListenerError: trackListenerError4,
|
|
466434
|
+
log: lifecycleLog
|
|
466196
466435
|
});
|
|
466197
466436
|
}
|
|
466198
466437
|
if (!isCurrentSocketPair(runtime, socket, streamSocket))
|
|
@@ -466231,9 +466470,12 @@ async function connectWithRetry(runtime, opts, attempt2 = 0, startTime = Date.no
|
|
|
466231
466470
|
recordListenerPong(runtime, socket);
|
|
466232
466471
|
return;
|
|
466233
466472
|
}
|
|
466473
|
+
if (!isCurrentSocketPair(runtime, socket, streamSocket))
|
|
466474
|
+
return;
|
|
466234
466475
|
pendingStartupFrames.accept(data, handleMessage);
|
|
466235
466476
|
});
|
|
466236
466477
|
socket.on("close", (code2, reason) => {
|
|
466478
|
+
lifecycleLog(formatListenerSocketClose("control", code2, reason));
|
|
466237
466479
|
abortStartupIngress();
|
|
466238
466480
|
if (!shouldHandleControlSocketClose(runtime, socket, opts.connectionId)) {
|
|
466239
466481
|
return;
|
|
@@ -466245,14 +466487,11 @@ async function connectWithRetry(runtime, opts, attempt2 = 0, startTime = Date.no
|
|
|
466245
466487
|
});
|
|
466246
466488
|
fileCommandSession.dispose();
|
|
466247
466489
|
const reasonText = reason.toString();
|
|
466248
|
-
const terminalClose = runtime.intentionallyClosed || code2 === 1008 || code2 === 1000 && reasonText === "Replaced by new connection";
|
|
466490
|
+
const terminalClose = runtime.intentionallyClosed || code2 === 1008 && reasonText !== CLOUD_ENVIRONMENT_NOT_FOUND_CLOSE_REASON || code2 === 1000 && reasonText === "Replaced by new connection";
|
|
466249
466491
|
if (!terminalClose && runtime.hasSuccessfulConnection) {
|
|
466250
466492
|
opts.onRetrying?.(0, MAX_RETRY_ATTEMPTS, 0, opts.connectionId);
|
|
466251
466493
|
}
|
|
466252
466494
|
clearRuntimeTimers(runtime);
|
|
466253
|
-
if (isDebugEnabled()) {
|
|
466254
|
-
console.log(`[Listen] WebSocket disconnected (code: ${code2}, reason: ${reason.toString()})`);
|
|
466255
|
-
}
|
|
466256
466495
|
if (!terminalClose) {
|
|
466257
466496
|
for (const conversationRuntime of runtime.conversationRuntimes.values()) {
|
|
466258
466497
|
rejectPendingApprovalResolversForConnection(conversationRuntime, opts.connectionId, "Listener connection closed");
|
|
@@ -466264,7 +466503,8 @@ async function connectWithRetry(runtime, opts, attempt2 = 0, startTime = Date.no
|
|
|
466264
466503
|
revokeRecoveryClaims(runtime, undefined, closingGeneration);
|
|
466265
466504
|
}
|
|
466266
466505
|
suspendListenerConnection(runtime, opts.connectionId);
|
|
466267
|
-
|
|
466506
|
+
if (terminalClose)
|
|
466507
|
+
killAllTerminals();
|
|
466268
466508
|
clearListenerWarmState(runtime);
|
|
466269
466509
|
if (streamSocket) {
|
|
466270
466510
|
streamSocket.removeAllListeners("message");
|
|
@@ -466277,27 +466517,21 @@ async function connectWithRetry(runtime, opts, attempt2 = 0, startTime = Date.no
|
|
|
466277
466517
|
runtime.socket = null;
|
|
466278
466518
|
runtime.streamSocket = null;
|
|
466279
466519
|
runtime.streamTransport = null;
|
|
466280
|
-
if (terminalClose) {
|
|
466281
|
-
|
|
466282
|
-
|
|
466520
|
+
if (code2 === 1008 && !terminalClose && opts.onNeedsReregister) {
|
|
466521
|
+
rejectPendingExternalToolCallsForConnection(runtime, opts.connectionId, "Listener connection re-registered");
|
|
466522
|
+
killListenerConnectionTerminals(opts.connectionId);
|
|
466523
|
+
revokeRecoveryClaims(runtime, opts.connectionId);
|
|
466524
|
+
opts.onNeedsReregister(createListenerClientReplacement(runtime, opts));
|
|
466525
|
+
return;
|
|
466526
|
+
}
|
|
466527
|
+
if (terminalClose || code2 === 1008) {
|
|
466528
|
+
if (getActiveRuntime() === runtime)
|
|
466283
466529
|
setActiveRuntime(null);
|
|
466284
|
-
}
|
|
466285
466530
|
stopRuntime(runtime, true);
|
|
466286
|
-
if (code2 === 1008)
|
|
466287
|
-
|
|
466288
|
-
|
|
466289
|
-
|
|
466290
|
-
if (opts.onNeedsReregister) {
|
|
466291
|
-
if (!replacement) {
|
|
466292
|
-
throw new Error("Missing listener replacement lineage");
|
|
466293
|
-
}
|
|
466294
|
-
opts.onNeedsReregister(replacement);
|
|
466295
|
-
} else {
|
|
466296
|
-
opts.onDisconnected();
|
|
466297
|
-
}
|
|
466298
|
-
return;
|
|
466299
|
-
}
|
|
466300
|
-
opts.onDisconnected();
|
|
466531
|
+
if (code2 === 1008 && opts.onNeedsReregister)
|
|
466532
|
+
opts.onNeedsReregister();
|
|
466533
|
+
else
|
|
466534
|
+
opts.onDisconnected();
|
|
466301
466535
|
return;
|
|
466302
466536
|
}
|
|
466303
466537
|
const nextAttempt = runtime.hasSuccessfulConnection ? 0 : attempt2 + 1;
|
|
@@ -466308,7 +466542,10 @@ async function connectWithRetry(runtime, opts, attempt2 = 0, startTime = Date.no
|
|
|
466308
466542
|
});
|
|
466309
466543
|
});
|
|
466310
466544
|
socket.on("error", (error5) => {
|
|
466545
|
+
if (runtime.socket !== socket)
|
|
466546
|
+
return;
|
|
466311
466547
|
trackListenerError4("listener_websocket_error", error5, "listener_socket");
|
|
466548
|
+
lifecycleLog(`control socket error: ${error5.message}`);
|
|
466312
466549
|
safeEmitWsEvent("recv", "lifecycle", {
|
|
466313
466550
|
type: "_ws_error",
|
|
466314
466551
|
message: error5.message
|
|
@@ -466347,6 +466584,7 @@ var init_lifecycle = __esm(async () => {
|
|
|
466347
466584
|
init_listener_task();
|
|
466348
466585
|
init_permission_mode();
|
|
466349
466586
|
init_socket_send();
|
|
466587
|
+
init_startup_deadline();
|
|
466350
466588
|
init_startup_frame_buffer();
|
|
466351
466589
|
init_startup_ingress();
|
|
466352
466590
|
init_stream_observers();
|
|
@@ -469669,7 +469907,7 @@ async function runListenSubcommand(argv) {
|
|
|
469669
469907
|
},
|
|
469670
469908
|
onConnected: () => {},
|
|
469671
469909
|
onConnectionReady: async (connectedId) => {
|
|
469672
|
-
const ready = await completeListenerConnectionStartup(connectedId, readiness, startChannelGateway);
|
|
469910
|
+
const ready = await completeListenerConnectionStartup(connectedId, readiness, startChannelGateway, (error5) => logListenerMessage(`[ChannelGateway] startup failed: ${error5}`));
|
|
469673
469911
|
if (!ready)
|
|
469674
469912
|
return;
|
|
469675
469913
|
sessionLog.log("Local channel listener ready.");
|
|
@@ -469752,7 +469990,8 @@ async function runListenSubcommand(argv) {
|
|
|
469752
469990
|
console.log(`[${formatTimestamp3()}] ${arrow}${tag} ${json2}`);
|
|
469753
469991
|
}
|
|
469754
469992
|
};
|
|
469755
|
-
if (debugMode
|
|
469993
|
+
if (shouldUseNonInteractiveListenerOutput(debugMode, !!lifecycleOutput)) {
|
|
469994
|
+
const printPlainLines = debugMode || !lifecycleOutput;
|
|
469756
469995
|
const startNonInteractiveClient = async (connId, url2, nextSupportsSplitStatusChannels, nextSupportsPairedListenerGenerations, replacement) => {
|
|
469757
469996
|
await startListenerClient2({
|
|
469758
469997
|
replacement,
|
|
@@ -469768,18 +470007,18 @@ async function runListenSubcommand(argv) {
|
|
|
469768
470007
|
onStatusChange: (status) => {
|
|
469769
470008
|
sessionLog.log(`status: ${status}`);
|
|
469770
470009
|
readiness.setStatus(status);
|
|
469771
|
-
if (
|
|
470010
|
+
if (printPlainLines) {
|
|
469772
470011
|
console.log(`[${formatTimestamp3()}] status: ${status}`);
|
|
469773
470012
|
}
|
|
469774
470013
|
},
|
|
469775
470014
|
onLog: logListenerMessage,
|
|
469776
470015
|
onConnected: () => {},
|
|
469777
470016
|
onConnectionReady: async (connectedId) => {
|
|
469778
|
-
const ready = await completeListenerConnectionStartup(connectedId, readiness, startChannelGateway);
|
|
470017
|
+
const ready = await completeListenerConnectionStartup(connectedId, readiness, startChannelGateway, (error5) => logListenerMessage(`[ChannelGateway] startup failed: ${error5}`));
|
|
469779
470018
|
if (!ready)
|
|
469780
470019
|
return;
|
|
469781
470020
|
sessionLog.log("Connected. Awaiting instructions.");
|
|
469782
|
-
if (
|
|
470021
|
+
if (printPlainLines) {
|
|
469783
470022
|
console.log(`[${formatTimestamp3()}] Connected. Awaiting instructions.`);
|
|
469784
470023
|
console.log("");
|
|
469785
470024
|
}
|
|
@@ -469787,13 +470026,13 @@ async function runListenSubcommand(argv) {
|
|
|
469787
470026
|
onRetrying: (attempt2, _maxAttempts, nextRetryIn) => {
|
|
469788
470027
|
readiness.setCloudReconnecting();
|
|
469789
470028
|
sessionLog.log(`Reconnecting (attempt ${attempt2}, retry in ${Math.round(nextRetryIn / 1000)}s)`);
|
|
469790
|
-
if (
|
|
470029
|
+
if (printPlainLines) {
|
|
469791
470030
|
console.log(`[${formatTimestamp3()}] Reconnecting (attempt ${attempt2}, retry in ${Math.round(nextRetryIn / 1000)}s)`);
|
|
469792
470031
|
}
|
|
469793
470032
|
},
|
|
469794
470033
|
onNeedsReregister: async (replacement2) => {
|
|
469795
470034
|
readiness.setCloudReconnecting();
|
|
469796
|
-
if (
|
|
470035
|
+
if (printPlainLines) {
|
|
469797
470036
|
console.log(`[${formatTimestamp3()}] Computer connection expired, re-registering...`);
|
|
469798
470037
|
}
|
|
469799
470038
|
try {
|
|
@@ -469855,7 +470094,7 @@ async function runListenSubcommand(argv) {
|
|
|
469855
470094
|
onLog: logListenerMessage,
|
|
469856
470095
|
onConnected: () => {},
|
|
469857
470096
|
onConnectionReady: async (connectedId) => {
|
|
469858
|
-
const ready = await completeListenerConnectionStartup(connectedId, readiness, startChannelGateway);
|
|
470097
|
+
const ready = await completeListenerConnectionStartup(connectedId, readiness, startChannelGateway, (error5) => logListenerMessage(`[ChannelGateway] startup failed: ${error5}`));
|
|
469859
470098
|
if (!ready)
|
|
469860
470099
|
return;
|
|
469861
470100
|
sessionLog.log("Connected. Awaiting instructions.");
|
|
@@ -469958,7 +470197,7 @@ var init_listen = __esm(async () => {
|
|
|
469958
470197
|
import { randomUUID as randomUUID55 } from "node:crypto";
|
|
469959
470198
|
import {
|
|
469960
470199
|
copyFileSync as copyFileSync3,
|
|
469961
|
-
existsSync as
|
|
470200
|
+
existsSync as existsSync63,
|
|
469962
470201
|
mkdirSync as mkdirSync47,
|
|
469963
470202
|
readdirSync as readdirSync26,
|
|
469964
470203
|
readFileSync as readFileSync48,
|
|
@@ -469966,7 +470205,7 @@ import {
|
|
|
469966
470205
|
} from "node:fs";
|
|
469967
470206
|
import { join as join94 } from "node:path";
|
|
469968
470207
|
function readJsonl(path46) {
|
|
469969
|
-
if (!
|
|
470208
|
+
if (!existsSync63(path46))
|
|
469970
470209
|
return [];
|
|
469971
470210
|
return readFileSync48(path46, "utf8").split(`
|
|
469972
470211
|
`).filter((line) => line.trim().length > 0).map((line) => JSON.parse(line));
|
|
@@ -470254,13 +470493,13 @@ function migrateLocalBackendTranscripts(input) {
|
|
|
470254
470493
|
skipped: [],
|
|
470255
470494
|
dryRun: input.dryRun === true
|
|
470256
470495
|
};
|
|
470257
|
-
if (!
|
|
470496
|
+
if (!existsSync63(conversationsDir))
|
|
470258
470497
|
return result3;
|
|
470259
470498
|
for (const name of readdirSync26(conversationsDir)) {
|
|
470260
470499
|
const conversationDir = join94(conversationsDir, name);
|
|
470261
470500
|
const messagesPath = join94(conversationDir, "messages.jsonl");
|
|
470262
470501
|
const manifestPath = join94(conversationDir, "manifest.json");
|
|
470263
|
-
const hasManifest =
|
|
470502
|
+
const hasManifest = existsSync63(manifestPath);
|
|
470264
470503
|
const existingManifest = hasManifest ? (() => {
|
|
470265
470504
|
try {
|
|
470266
470505
|
return JSON.parse(readFileSync48(manifestPath, "utf8"));
|
|
@@ -470304,7 +470543,7 @@ function migrateLocalBackendTranscripts(input) {
|
|
|
470304
470543
|
copyFileSync3(messagesPath, backupPath);
|
|
470305
470544
|
const conversationPath = join94(conversationDir, "conversation.json");
|
|
470306
470545
|
let conversation;
|
|
470307
|
-
if (
|
|
470546
|
+
if (existsSync63(conversationPath)) {
|
|
470308
470547
|
try {
|
|
470309
470548
|
conversation = JSON.parse(readFileSync48(conversationPath, "utf8"));
|
|
470310
470549
|
} catch {
|
|
@@ -470498,7 +470737,7 @@ var init_memory_tokens = __esm(() => {
|
|
|
470498
470737
|
});
|
|
470499
470738
|
|
|
470500
470739
|
// src/cli/subcommands/memory.ts
|
|
470501
|
-
import { cpSync, existsSync as
|
|
470740
|
+
import { cpSync, existsSync as existsSync64, mkdirSync as mkdirSync48, rmSync as rmSync22, statSync as statSync24 } from "node:fs";
|
|
470502
470741
|
import { readdir as readdir12 } from "node:fs/promises";
|
|
470503
470742
|
import { dirname as dirname37, join as join95 } from "node:path";
|
|
470504
470743
|
import { parseArgs as parseArgs11 } from "node:util";
|
|
@@ -470560,7 +470799,7 @@ function formatBackupTimestamp(date5 = new Date) {
|
|
|
470560
470799
|
}
|
|
470561
470800
|
async function listBackups(agentId) {
|
|
470562
470801
|
const agentRoot = getAgentRoot(agentId);
|
|
470563
|
-
if (!
|
|
470802
|
+
if (!existsSync64(agentRoot)) {
|
|
470564
470803
|
return [];
|
|
470565
470804
|
}
|
|
470566
470805
|
const entries2 = await readdir12(agentRoot, { withFileTypes: true });
|
|
@@ -470665,14 +470904,14 @@ async function runMemorySubcommand(argv, deps = {}) {
|
|
|
470665
470904
|
}
|
|
470666
470905
|
if (action3 === "backup") {
|
|
470667
470906
|
const root2 = getMemoryRoot(agentId);
|
|
470668
|
-
if (!
|
|
470907
|
+
if (!existsSync64(root2)) {
|
|
470669
470908
|
console.error(`Memory directory not found for agent ${agentId}.`);
|
|
470670
470909
|
return 1;
|
|
470671
470910
|
}
|
|
470672
470911
|
const agentRoot = getAgentRoot(agentId);
|
|
470673
470912
|
const backupName = `memory-backup-${formatBackupTimestamp()}`;
|
|
470674
470913
|
const backupPath = join95(agentRoot, backupName);
|
|
470675
|
-
if (
|
|
470914
|
+
if (existsSync64(backupPath)) {
|
|
470676
470915
|
console.error(`Backup already exists at ${backupPath}`);
|
|
470677
470916
|
return 1;
|
|
470678
470917
|
}
|
|
@@ -470696,7 +470935,7 @@ async function runMemorySubcommand(argv, deps = {}) {
|
|
|
470696
470935
|
return 1;
|
|
470697
470936
|
}
|
|
470698
470937
|
const backupPath = resolveBackupPath(agentId, from);
|
|
470699
|
-
if (!
|
|
470938
|
+
if (!existsSync64(backupPath)) {
|
|
470700
470939
|
console.error(`Backup not found: ${backupPath}`);
|
|
470701
470940
|
return 1;
|
|
470702
470941
|
}
|
|
@@ -470718,11 +470957,11 @@ async function runMemorySubcommand(argv, deps = {}) {
|
|
|
470718
470957
|
return 1;
|
|
470719
470958
|
}
|
|
470720
470959
|
const root2 = getMemoryRoot(agentId);
|
|
470721
|
-
if (!
|
|
470960
|
+
if (!existsSync64(root2)) {
|
|
470722
470961
|
console.error(`Memory directory not found for agent ${agentId}.`);
|
|
470723
470962
|
return 1;
|
|
470724
470963
|
}
|
|
470725
|
-
if (
|
|
470964
|
+
if (existsSync64(out)) {
|
|
470726
470965
|
const stat15 = statSync24(out);
|
|
470727
470966
|
if (stat15.isDirectory()) {
|
|
470728
470967
|
const contents = await readdir12(out);
|
|
@@ -470771,10 +471010,10 @@ var init_memory7 = __esm(() => {
|
|
|
470771
471010
|
});
|
|
470772
471011
|
|
|
470773
471012
|
// src/backend/local/transcript-search.ts
|
|
470774
|
-
import { existsSync as
|
|
471013
|
+
import { existsSync as existsSync65, readdirSync as readdirSync27, readFileSync as readFileSync49, statSync as statSync25 } from "node:fs";
|
|
470775
471014
|
import { join as join96 } from "node:path";
|
|
470776
471015
|
function readJsonFile3(path46) {
|
|
470777
|
-
if (!
|
|
471016
|
+
if (!existsSync65(path46))
|
|
470778
471017
|
return;
|
|
470779
471018
|
try {
|
|
470780
471019
|
return JSON.parse(readFileSync49(path46, "utf8"));
|
|
@@ -471056,7 +471295,7 @@ function collectConversationMessages(input) {
|
|
|
471056
471295
|
}
|
|
471057
471296
|
function conversationDirectories(storageDir) {
|
|
471058
471297
|
const conversationsDir = join96(storageDir, "conversations");
|
|
471059
|
-
if (!
|
|
471298
|
+
if (!existsSync65(conversationsDir))
|
|
471060
471299
|
return [];
|
|
471061
471300
|
try {
|
|
471062
471301
|
return readdirSync27(conversationsDir).map((entry) => join96(conversationsDir, entry)).filter((entryPath) => statSync25(entryPath).isDirectory());
|
|
@@ -471970,13 +472209,13 @@ var init_model2 = __esm(() => {
|
|
|
471970
472209
|
import { spawn as spawn13 } from "node:child_process";
|
|
471971
472210
|
import {
|
|
471972
472211
|
copyFileSync as copyFileSync4,
|
|
471973
|
-
existsSync as
|
|
471974
|
-
lstatSync as
|
|
472212
|
+
existsSync as existsSync66,
|
|
472213
|
+
lstatSync as lstatSync4,
|
|
471975
472214
|
mkdirSync as mkdirSync49,
|
|
471976
472215
|
mkdtempSync as mkdtempSync5,
|
|
471977
472216
|
readdirSync as readdirSync28,
|
|
471978
472217
|
readFileSync as readFileSync50,
|
|
471979
|
-
renameSync as
|
|
472218
|
+
renameSync as renameSync11,
|
|
471980
472219
|
rmSync as rmSync23,
|
|
471981
472220
|
writeFileSync as writeFileSync40
|
|
471982
472221
|
} from "node:fs";
|
|
@@ -472019,7 +472258,7 @@ function formatRepository(repository) {
|
|
|
472019
472258
|
function isLocalLettaModPackageDirectory(packageDirectory) {
|
|
472020
472259
|
const resolvedPackageDirectory = path46.resolve(packageDirectory);
|
|
472021
472260
|
try {
|
|
472022
|
-
const packageStats =
|
|
472261
|
+
const packageStats = lstatSync4(resolvedPackageDirectory);
|
|
472023
472262
|
if (packageStats.isSymbolicLink() || !packageStats.isDirectory()) {
|
|
472024
472263
|
return false;
|
|
472025
472264
|
}
|
|
@@ -472046,7 +472285,7 @@ function validateManifestEntriesExist(packageRoot, entries2) {
|
|
|
472046
472285
|
const entryPath = resolvePackageRelativePath(packageRoot, entry);
|
|
472047
472286
|
let stats;
|
|
472048
472287
|
try {
|
|
472049
|
-
stats =
|
|
472288
|
+
stats = lstatSync4(entryPath);
|
|
472050
472289
|
} catch {
|
|
472051
472290
|
throw new Error(`Package mod entry does not exist: ${entry}`);
|
|
472052
472291
|
}
|
|
@@ -472062,7 +472301,7 @@ function resolvePackageDirectory(packageDirectory) {
|
|
|
472062
472301
|
const resolvedPackageDirectory = path46.resolve(packageDirectory);
|
|
472063
472302
|
let packageStats;
|
|
472064
472303
|
try {
|
|
472065
|
-
packageStats =
|
|
472304
|
+
packageStats = lstatSync4(resolvedPackageDirectory);
|
|
472066
472305
|
} catch {
|
|
472067
472306
|
throw new Error(`Package directory does not exist: ${packageDirectory}`);
|
|
472068
472307
|
}
|
|
@@ -472120,7 +472359,7 @@ function copyPackageDirectory(sourceRoot, targetRoot) {
|
|
|
472120
472359
|
continue;
|
|
472121
472360
|
const sourcePath = path46.join(sourceRoot, entry.name);
|
|
472122
472361
|
const targetPath = path46.join(targetRoot, entry.name);
|
|
472123
|
-
const stats =
|
|
472362
|
+
const stats = lstatSync4(sourcePath);
|
|
472124
472363
|
if (stats.isSymbolicLink()) {
|
|
472125
472364
|
throw new Error(`Package contains unsupported symlink: ${sourcePath}`);
|
|
472126
472365
|
}
|
|
@@ -472154,7 +472393,7 @@ function copyDependencyDirectoryFiltered(params) {
|
|
|
472154
472393
|
}
|
|
472155
472394
|
const sourcePath = path46.join(params.sourceRoot, entry.name);
|
|
472156
472395
|
const targetPath = path46.join(params.targetRoot, entry.name);
|
|
472157
|
-
const stats =
|
|
472396
|
+
const stats = lstatSync4(sourcePath);
|
|
472158
472397
|
if (stats.isSymbolicLink()) {
|
|
472159
472398
|
throw new Error(`Package dependency contains unsupported symlink: ${sourcePath}`);
|
|
472160
472399
|
}
|
|
@@ -472179,7 +472418,7 @@ function copyDependencyDirectoryFiltered(params) {
|
|
|
472179
472418
|
return copied;
|
|
472180
472419
|
}
|
|
472181
472420
|
function copyDependencyNodeModules(params) {
|
|
472182
|
-
if (!
|
|
472421
|
+
if (!existsSync66(params.sourceNodeModulesDirectory))
|
|
472183
472422
|
return;
|
|
472184
472423
|
copyDependencyDirectoryFiltered({
|
|
472185
472424
|
installedPackageName: params.installedPackageName,
|
|
@@ -472189,7 +472428,7 @@ function copyDependencyNodeModules(params) {
|
|
|
472189
472428
|
}
|
|
472190
472429
|
function copyPackageInternalNodeModules(params) {
|
|
472191
472430
|
const sourceNodeModulesDirectory = path46.join(params.packageDirectory, "node_modules");
|
|
472192
|
-
if (!
|
|
472431
|
+
if (!existsSync66(sourceNodeModulesDirectory))
|
|
472193
472432
|
return;
|
|
472194
472433
|
copyDependencyDirectoryFiltered({
|
|
472195
472434
|
sourceRoot: sourceNodeModulesDirectory,
|
|
@@ -472211,12 +472450,12 @@ function removeIfExists(targetPath) {
|
|
|
472211
472450
|
}
|
|
472212
472451
|
function restoreDestination(params) {
|
|
472213
472452
|
rmSync23(params.destinationRoot, { force: true, recursive: true });
|
|
472214
|
-
if (params.backupRoot &&
|
|
472215
|
-
|
|
472453
|
+
if (params.backupRoot && existsSync66(params.backupRoot)) {
|
|
472454
|
+
renameSync11(params.backupRoot, params.destinationRoot);
|
|
472216
472455
|
}
|
|
472217
472456
|
}
|
|
472218
472457
|
function restoreDestinationIfNeeded(params) {
|
|
472219
|
-
if (!params.backupRoot || !
|
|
472458
|
+
if (!params.backupRoot || !existsSync66(params.backupRoot)) {
|
|
472220
472459
|
rmSync23(params.destinationRoot, { force: true, recursive: true });
|
|
472221
472460
|
return;
|
|
472222
472461
|
}
|
|
@@ -472257,13 +472496,13 @@ function installPreparedManagedModPackage(params) {
|
|
|
472257
472496
|
targetPackageRoot: stagingRoot
|
|
472258
472497
|
});
|
|
472259
472498
|
}
|
|
472260
|
-
if (
|
|
472499
|
+
if (existsSync66(destinationRoot)) {
|
|
472261
472500
|
backupRoot = makeSiblingTempDirectory(destinationRoot, "backup");
|
|
472262
472501
|
rmSync23(backupRoot, { force: true, recursive: true });
|
|
472263
|
-
|
|
472502
|
+
renameSync11(destinationRoot, backupRoot);
|
|
472264
472503
|
destinationNeedsRollback = true;
|
|
472265
472504
|
}
|
|
472266
|
-
|
|
472505
|
+
renameSync11(stagingRoot, destinationRoot);
|
|
472267
472506
|
destinationNeedsRollback = true;
|
|
472268
472507
|
stagingRoot = null;
|
|
472269
472508
|
try {
|
|
@@ -472542,13 +472781,13 @@ function hasRuntimeDependencies(packageJson) {
|
|
|
472542
472781
|
}
|
|
472543
472782
|
function readPackageJsonIfExists(packageDirectory) {
|
|
472544
472783
|
const packageJsonPath = path46.join(packageDirectory, "package.json");
|
|
472545
|
-
if (!
|
|
472784
|
+
if (!existsSync66(packageJsonPath))
|
|
472546
472785
|
return null;
|
|
472547
472786
|
return readPackageJson(packageJsonPath);
|
|
472548
472787
|
}
|
|
472549
472788
|
function isRegularModFile(filePath) {
|
|
472550
472789
|
try {
|
|
472551
|
-
const stats =
|
|
472790
|
+
const stats = lstatSync4(filePath);
|
|
472552
472791
|
return !stats.isSymbolicLink() && stats.isFile();
|
|
472553
472792
|
} catch {
|
|
472554
472793
|
return false;
|
|
@@ -472556,8 +472795,8 @@ function isRegularModFile(filePath) {
|
|
|
472556
472795
|
}
|
|
472557
472796
|
function inferCompatibilityModEntries(packageDirectory) {
|
|
472558
472797
|
const modsDirectory = path46.join(packageDirectory, "mods");
|
|
472559
|
-
if (
|
|
472560
|
-
const stats =
|
|
472798
|
+
if (existsSync66(modsDirectory)) {
|
|
472799
|
+
const stats = lstatSync4(modsDirectory);
|
|
472561
472800
|
if (stats.isSymbolicLink()) {
|
|
472562
472801
|
throw new Error(`Package mods directory must not be a symlink: mods`);
|
|
472563
472802
|
}
|
|
@@ -472831,8 +473070,8 @@ var init_package_installer = __esm(() => {
|
|
|
472831
473070
|
// src/mods/package-scaffolder.ts
|
|
472832
473071
|
import {
|
|
472833
473072
|
copyFileSync as copyFileSync5,
|
|
472834
|
-
existsSync as
|
|
472835
|
-
lstatSync as
|
|
473073
|
+
existsSync as existsSync67,
|
|
473074
|
+
lstatSync as lstatSync5,
|
|
472836
473075
|
mkdirSync as mkdirSync50,
|
|
472837
473076
|
rmSync as rmSync24,
|
|
472838
473077
|
writeFileSync as writeFileSync41
|
|
@@ -472858,7 +473097,7 @@ function readSourceFile(sourceFile) {
|
|
|
472858
473097
|
const resolvedSourceFile = path47.resolve(sourceFile);
|
|
472859
473098
|
let stats;
|
|
472860
473099
|
try {
|
|
472861
|
-
stats =
|
|
473100
|
+
stats = lstatSync5(resolvedSourceFile);
|
|
472862
473101
|
} catch {
|
|
472863
473102
|
throw new Error(`Mod file does not exist: ${sourceFile}`);
|
|
472864
473103
|
}
|
|
@@ -472924,7 +473163,7 @@ function scaffoldLocalModPackage(options) {
|
|
|
472924
473163
|
const sourceFile = readSourceFile(options.sourceFile);
|
|
472925
473164
|
const packageName = assertValidPackageName(options.packageName);
|
|
472926
473165
|
const outputDirectory = path47.resolve(options.outputDirectory ?? defaultOutputDirectory(sourceFile, packageName));
|
|
472927
|
-
if (
|
|
473166
|
+
if (existsSync67(outputDirectory)) {
|
|
472928
473167
|
throw new Error(`Output directory already exists: ${outputDirectory}`);
|
|
472929
473168
|
}
|
|
472930
473169
|
const modFileName = path47.basename(sourceFile);
|
|
@@ -473480,7 +473719,7 @@ var init_sandbox_files = __esm(() => {
|
|
|
473480
473719
|
|
|
473481
473720
|
// src/cli/subcommands/sandbox.ts
|
|
473482
473721
|
import { readFile as readFile27, stat as stat15, writeFile as writeFile19 } from "node:fs/promises";
|
|
473483
|
-
import { basename as
|
|
473722
|
+
import { basename as basename29, resolve as resolve40 } from "node:path";
|
|
473484
473723
|
import { parseArgs as parseArgs16 } from "node:util";
|
|
473485
473724
|
function printUsage13() {
|
|
473486
473725
|
console.log(`
|
|
@@ -473631,13 +473870,13 @@ async function runSandboxSubcommand(argv, deps = {}) {
|
|
|
473631
473870
|
throw new Error(`${localPath2} is not a file`);
|
|
473632
473871
|
const data2 = await (deps.readLocalFile ?? readFile27)(localPath2);
|
|
473633
473872
|
const sandbox2 = await ensureSandbox();
|
|
473634
|
-
const result3 = await (deps.uploadFile ?? uploadFileToSandbox)(sandbox2.sandboxId, { blob: new Blob([data2]), name:
|
|
473873
|
+
const result3 = await (deps.uploadFile ?? uploadFileToSandbox)(sandbox2.sandboxId, { blob: new Blob([data2]), name: basename29(localPath2) });
|
|
473635
473874
|
console.log(JSON.stringify({ ...result3, ...targetOutput }, null, 2));
|
|
473636
473875
|
return 0;
|
|
473637
473876
|
}
|
|
473638
473877
|
const sandbox = await ensureSandbox();
|
|
473639
473878
|
const data = await (deps.downloadFile ?? downloadFileFromSandbox)(sandbox.sandboxId, path48);
|
|
473640
|
-
const localPath = resolve40(parsed.values.to ??
|
|
473879
|
+
const localPath = resolve40(parsed.values.to ?? basename29(path48));
|
|
473641
473880
|
await (deps.writeLocalFile ?? writeFile19)(localPath, data);
|
|
473642
473881
|
console.log(JSON.stringify({
|
|
473643
473882
|
path: localPath,
|
|
@@ -474547,7 +474786,7 @@ var init_setup7 = __esm(async () => {
|
|
|
474547
474786
|
});
|
|
474548
474787
|
|
|
474549
474788
|
// src/cli/subcommands/shared-memory.ts
|
|
474550
|
-
import { existsSync as
|
|
474789
|
+
import { existsSync as existsSync68 } from "node:fs";
|
|
474551
474790
|
import { join as join98 } from "node:path";
|
|
474552
474791
|
import { parseArgs as parseArgs19 } from "node:util";
|
|
474553
474792
|
function printUsage16() {
|
|
@@ -474740,7 +474979,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
|
|
|
474740
474979
|
invalidateClientSkills(agentId);
|
|
474741
474980
|
const recompileError = await recompileAndReportFailure(recompileAgent, agentId);
|
|
474742
474981
|
const mountDir = getRepositoryMountDir(agentId, repository.name);
|
|
474743
|
-
const mounted =
|
|
474982
|
+
const mounted = existsSync68(join98(mountDir, ".git"));
|
|
474744
474983
|
console.log(JSON.stringify({
|
|
474745
474984
|
attached: true,
|
|
474746
474985
|
repository: { id: repository.id, name: repository.name },
|
|
@@ -476269,7 +476508,7 @@ var init_AgentSelector = __esm(async () => {
|
|
|
476269
476508
|
// src/cli/subcommands/skills.ts
|
|
476270
476509
|
import {
|
|
476271
476510
|
cpSync as cpSync2,
|
|
476272
|
-
existsSync as
|
|
476511
|
+
existsSync as existsSync69,
|
|
476273
476512
|
mkdtempSync as mkdtempSync6,
|
|
476274
476513
|
readFileSync as readFileSync51,
|
|
476275
476514
|
rmSync as rmSync25,
|
|
@@ -476278,7 +476517,7 @@ import {
|
|
|
476278
476517
|
} from "node:fs";
|
|
476279
476518
|
import { mkdir as mkdir16, readdir as readdir13 } from "node:fs/promises";
|
|
476280
476519
|
import { tmpdir as tmpdir14 } from "node:os";
|
|
476281
|
-
import { basename as
|
|
476520
|
+
import { basename as basename30, dirname as dirname39, join as join99, normalize as normalize4, resolve as resolve41, sep as sep8 } from "node:path";
|
|
476282
476521
|
import { parseArgs as parseArgs20, TextDecoder as TextDecoder2, TextEncoder as TextEncoder2 } from "node:util";
|
|
476283
476522
|
function printUsage17() {
|
|
476284
476523
|
console.log(`
|
|
@@ -476473,7 +476712,7 @@ function parseDirectSkillFileUrlSpecifier(input) {
|
|
|
476473
476712
|
if (url2.protocol !== "https:" && !(url2.protocol === "http:" && isLocalhostHostname(url2.hostname))) {
|
|
476474
476713
|
return null;
|
|
476475
476714
|
}
|
|
476476
|
-
if (
|
|
476715
|
+
if (basename30(url2.pathname).toLowerCase() !== "skill.md")
|
|
476477
476716
|
return null;
|
|
476478
476717
|
return { url: url2.toString() };
|
|
476479
476718
|
}
|
|
@@ -476721,14 +476960,14 @@ function getSkillName(sourceDir) {
|
|
|
476721
476960
|
const skillMd = readFileSync51(join99(sourceDir, "SKILL.md"), "utf8");
|
|
476722
476961
|
const { frontmatter } = parseFrontmatter(skillMd);
|
|
476723
476962
|
const frontmatterName = frontmatter.name;
|
|
476724
|
-
const name = typeof frontmatterName === "string" && frontmatterName.trim() ? frontmatterName :
|
|
476963
|
+
const name = typeof frontmatterName === "string" && frontmatterName.trim() ? frontmatterName : basename30(sourceDir);
|
|
476725
476964
|
return sanitizeSkillName(name);
|
|
476726
476965
|
}
|
|
476727
476966
|
async function installSkillDirectory(params) {
|
|
476728
476967
|
const sourceDir = resolve41(params.sourceDir);
|
|
476729
476968
|
const memoryDir = resolve41(params.memoryDir);
|
|
476730
476969
|
const skillMdPath = join99(sourceDir, "SKILL.md");
|
|
476731
|
-
if (!
|
|
476970
|
+
if (!existsSync69(skillMdPath)) {
|
|
476732
476971
|
throw new Error("No SKILL.md found in the skill directory.");
|
|
476733
476972
|
}
|
|
476734
476973
|
if (!statSync26(sourceDir).isDirectory()) {
|
|
@@ -476738,7 +476977,7 @@ async function installSkillDirectory(params) {
|
|
|
476738
476977
|
const skillsDir = join99(memoryDir, "skills");
|
|
476739
476978
|
const targetPath = join99(skillsDir, name);
|
|
476740
476979
|
assertInside(skillsDir, targetPath);
|
|
476741
|
-
if (
|
|
476980
|
+
if (existsSync69(targetPath)) {
|
|
476742
476981
|
if (!params.force) {
|
|
476743
476982
|
throw new Error(`Skill "${name}" already exists at ${targetPath}. Re-run with --force to replace it.`);
|
|
476744
476983
|
}
|
|
@@ -476747,14 +476986,14 @@ async function installSkillDirectory(params) {
|
|
|
476747
476986
|
await mkdir16(skillsDir, { recursive: true });
|
|
476748
476987
|
cpSync2(sourceDir, targetPath, {
|
|
476749
476988
|
recursive: true,
|
|
476750
|
-
filter: (source) =>
|
|
476989
|
+
filter: (source) => basename30(source) !== ".git"
|
|
476751
476990
|
});
|
|
476752
476991
|
return { name, path: normalize4(targetPath) };
|
|
476753
476992
|
}
|
|
476754
476993
|
async function listSkillDirectories(params) {
|
|
476755
476994
|
const memoryDir = resolve41(params.memoryDir);
|
|
476756
476995
|
const skillsDir = join99(memoryDir, "skills");
|
|
476757
|
-
if (!
|
|
476996
|
+
if (!existsSync69(skillsDir))
|
|
476758
476997
|
return [];
|
|
476759
476998
|
const entries2 = await readdir13(skillsDir, { withFileTypes: true });
|
|
476760
476999
|
const skills = [];
|
|
@@ -476763,7 +477002,7 @@ async function listSkillDirectories(params) {
|
|
|
476763
477002
|
continue;
|
|
476764
477003
|
const skillDir = join99(skillsDir, entry.name);
|
|
476765
477004
|
const skillMdPath = join99(skillDir, "SKILL.md");
|
|
476766
|
-
if (!
|
|
477005
|
+
if (!existsSync69(skillMdPath))
|
|
476767
477006
|
continue;
|
|
476768
477007
|
let name = entry.name;
|
|
476769
477008
|
let description;
|
|
@@ -476787,7 +477026,7 @@ async function deleteSkillDirectory(params) {
|
|
|
476787
477026
|
const name = sanitizeSkillName(params.name);
|
|
476788
477027
|
const targetPath = join99(skillsDir, name);
|
|
476789
477028
|
assertInside(skillsDir, targetPath);
|
|
476790
|
-
if (!
|
|
477029
|
+
if (!existsSync69(targetPath)) {
|
|
476791
477030
|
throw new Error(`Skill "${name}" is not installed at ${targetPath}.`);
|
|
476792
477031
|
}
|
|
476793
477032
|
if (!statSync26(targetPath).isDirectory()) {
|
|
@@ -476836,7 +477075,7 @@ async function installSkill(specifier, agentId, force) {
|
|
|
476836
477075
|
tmpDir = downloaded.tmpDir;
|
|
476837
477076
|
const sourceDir = resolve41(downloaded.sourceDir);
|
|
476838
477077
|
assertInside(tmpDir, sourceDir);
|
|
476839
|
-
if (!
|
|
477078
|
+
if (!existsSync69(sourceDir)) {
|
|
476840
477079
|
const missingPath = source.type === "git" ? source.location.subdir ?? "." : source.type === "direct-file" ? source.location.url : source.location.slug;
|
|
476841
477080
|
throw new Error(`Skill path not found: ${missingPath}`);
|
|
476842
477081
|
}
|
|
@@ -477467,7 +477706,7 @@ import {
|
|
|
477467
477706
|
stat as stat17,
|
|
477468
477707
|
writeFile as writeFile20
|
|
477469
477708
|
} from "node:fs/promises";
|
|
477470
|
-
import { basename as
|
|
477709
|
+
import { basename as basename31, join as join101 } from "node:path";
|
|
477471
477710
|
function fileTimestamp(startedAt) {
|
|
477472
477711
|
if (!startedAt)
|
|
477473
477712
|
return "unknown-date";
|
|
@@ -477635,10 +477874,10 @@ async function runTrajectoryExport(options) {
|
|
|
477635
477874
|
if (!supported.includes(explicit.source)) {
|
|
477636
477875
|
throw new Error(`Unknown source "${explicit.source}" in --transcript. The installed trajectory package supports: ${supported.join(", ")}.`);
|
|
477637
477876
|
}
|
|
477638
|
-
await exportTranscript(explicit.source,
|
|
477877
|
+
await exportTranscript(explicit.source, basename31(explicit.path).replace(/\.[^.]+$/, ""), explicit.path, () => readFile29(explicit.path, "utf-8"));
|
|
477639
477878
|
}
|
|
477640
477879
|
for (const checkpoint of options.deepagents ?? []) {
|
|
477641
|
-
await exportCheckpoint(checkpoint, `${
|
|
477880
|
+
await exportCheckpoint(checkpoint, `${basename31(checkpoint.path)}-${checkpoint.threadId}`);
|
|
477642
477881
|
}
|
|
477643
477882
|
manifest2.sessions.sort((a2, b3) => (a2.startedAt ?? "").localeCompare(b3.startedAt ?? ""));
|
|
477644
477883
|
await writeFile20(join101(options.outDir, MANIFEST_NAME), JSON.stringify(manifest2, null, 2), "utf-8");
|
|
@@ -481086,7 +481325,7 @@ var init_message_channel_gateway_tool = __esm(() => {
|
|
|
481086
481325
|
});
|
|
481087
481326
|
|
|
481088
481327
|
// src/channels/custom/scaffolding.ts
|
|
481089
|
-
import { existsSync as
|
|
481328
|
+
import { existsSync as existsSync70, mkdirSync as mkdirSync51, rmSync as rmSync26, writeFileSync as writeFileSync43 } from "node:fs";
|
|
481090
481329
|
function removeUserPlugin(channelId) {
|
|
481091
481330
|
if (FIRST_PARTY_SET.has(channelId)) {
|
|
481092
481331
|
return;
|
|
@@ -481095,7 +481334,7 @@ function removeUserPlugin(channelId) {
|
|
|
481095
481334
|
return;
|
|
481096
481335
|
}
|
|
481097
481336
|
const channelDir = getChannelDir(channelId);
|
|
481098
|
-
if (!
|
|
481337
|
+
if (!existsSync70(channelDir)) {
|
|
481099
481338
|
return;
|
|
481100
481339
|
}
|
|
481101
481340
|
try {
|
|
@@ -487874,7 +488113,7 @@ var BYTES_PER_TOKEN = 4;
|
|
|
487874
488113
|
|
|
487875
488114
|
// src/cli/helpers/window-title-config.ts
|
|
487876
488115
|
import { homedir as homedir55 } from "node:os";
|
|
487877
|
-
import { basename as
|
|
488116
|
+
import { basename as basename32, resolve as resolve42 } from "node:path";
|
|
487878
488117
|
function isWindowTitleField(value) {
|
|
487879
488118
|
return WINDOW_TITLE_FIELDS.includes(value);
|
|
487880
488119
|
}
|
|
@@ -488033,7 +488272,7 @@ function terminalTitleProjectName(data) {
|
|
|
488033
488272
|
if (!directory)
|
|
488034
488273
|
return null;
|
|
488035
488274
|
const resolved2 = resolve42(directory);
|
|
488036
|
-
const name =
|
|
488275
|
+
const name = basename32(resolved2) || formatDirectoryDisplay(resolved2) || resolved2;
|
|
488037
488276
|
return truncateTerminalTitlePart(name, 24);
|
|
488038
488277
|
}
|
|
488039
488278
|
function titleDirectory(data) {
|
|
@@ -488715,7 +488954,7 @@ var init_cli_mod_context = __esm(() => {
|
|
|
488715
488954
|
|
|
488716
488955
|
// src/cli/helpers/reflection-arena-hf-upload.ts
|
|
488717
488956
|
import { execFile as execFileCb5 } from "node:child_process";
|
|
488718
|
-
import { existsSync as
|
|
488957
|
+
import { existsSync as existsSync72 } from "node:fs";
|
|
488719
488958
|
import { appendFile as appendFile3, chmod, mkdir as mkdir18, writeFile as writeFile21 } from "node:fs/promises";
|
|
488720
488959
|
import { homedir as homedir56 } from "node:os";
|
|
488721
488960
|
import { join as join105 } from "node:path";
|
|
@@ -488769,7 +489008,7 @@ async function writeGitAskpass(repoRoot) {
|
|
|
488769
489008
|
}
|
|
488770
489009
|
async function prepareHfRepo(env6) {
|
|
488771
489010
|
await mkdir18(HF_CACHE_ROOT, { recursive: true });
|
|
488772
|
-
if (!
|
|
489011
|
+
if (!existsSync72(join105(HF_REPO_DIR, ".git"))) {
|
|
488773
489012
|
await runGit6(HF_CACHE_ROOT, ["clone", "--depth", "1", HF_REPO_URL, HF_REPO_DIR], env6);
|
|
488774
489013
|
return HF_REPO_DIR;
|
|
488775
489014
|
}
|
|
@@ -490328,7 +490567,7 @@ __export(exports_terminal_keybinding_installer, {
|
|
|
490328
490567
|
});
|
|
490329
490568
|
import {
|
|
490330
490569
|
copyFileSync as copyFileSync6,
|
|
490331
|
-
existsSync as
|
|
490570
|
+
existsSync as existsSync73,
|
|
490332
490571
|
mkdirSync as mkdirSync53,
|
|
490333
490572
|
readFileSync as readFileSync53,
|
|
490334
490573
|
writeFileSync as writeFileSync45
|
|
@@ -490397,7 +490636,7 @@ function parseKeybindings(content) {
|
|
|
490397
490636
|
}
|
|
490398
490637
|
}
|
|
490399
490638
|
function keybindingExists(keybindingsPath) {
|
|
490400
|
-
if (!
|
|
490639
|
+
if (!existsSync73(keybindingsPath))
|
|
490401
490640
|
return false;
|
|
490402
490641
|
try {
|
|
490403
490642
|
const content = readFileSync53(keybindingsPath, { encoding: "utf-8" });
|
|
@@ -490410,7 +490649,7 @@ function keybindingExists(keybindingsPath) {
|
|
|
490410
490649
|
}
|
|
490411
490650
|
}
|
|
490412
490651
|
function createBackup(keybindingsPath) {
|
|
490413
|
-
if (!
|
|
490652
|
+
if (!existsSync73(keybindingsPath))
|
|
490414
490653
|
return null;
|
|
490415
490654
|
const backupPath = `${keybindingsPath}.letta-backup`;
|
|
490416
490655
|
try {
|
|
@@ -490426,12 +490665,12 @@ function installKeybinding(keybindingsPath) {
|
|
|
490426
490665
|
return { success: true, alreadyExists: true };
|
|
490427
490666
|
}
|
|
490428
490667
|
const parentDir = dirname40(keybindingsPath);
|
|
490429
|
-
if (!
|
|
490668
|
+
if (!existsSync73(parentDir)) {
|
|
490430
490669
|
mkdirSync53(parentDir, { recursive: true });
|
|
490431
490670
|
}
|
|
490432
490671
|
let keybindings = [];
|
|
490433
490672
|
let backupPath = null;
|
|
490434
|
-
if (
|
|
490673
|
+
if (existsSync73(keybindingsPath)) {
|
|
490435
490674
|
backupPath = createBackup(keybindingsPath);
|
|
490436
490675
|
const content = readFileSync53(keybindingsPath, { encoding: "utf-8" });
|
|
490437
490676
|
const parsed = parseKeybindings(content);
|
|
@@ -490461,7 +490700,7 @@ function installKeybinding(keybindingsPath) {
|
|
|
490461
490700
|
}
|
|
490462
490701
|
function removeKeybinding(keybindingsPath) {
|
|
490463
490702
|
try {
|
|
490464
|
-
if (!
|
|
490703
|
+
if (!existsSync73(keybindingsPath)) {
|
|
490465
490704
|
return { success: true };
|
|
490466
490705
|
}
|
|
490467
490706
|
const content = readFileSync53(keybindingsPath, { encoding: "utf-8" });
|
|
@@ -490529,11 +490768,11 @@ function getWezTermConfigPath() {
|
|
|
490529
490768
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
490530
490769
|
if (xdgConfig) {
|
|
490531
490770
|
const xdgPath = join107(xdgConfig, "wezterm", "wezterm.lua");
|
|
490532
|
-
if (
|
|
490771
|
+
if (existsSync73(xdgPath))
|
|
490533
490772
|
return xdgPath;
|
|
490534
490773
|
}
|
|
490535
490774
|
const configPath = join107(homedir58(), ".config", "wezterm", "wezterm.lua");
|
|
490536
|
-
if (
|
|
490775
|
+
if (existsSync73(configPath))
|
|
490537
490776
|
return configPath;
|
|
490538
490777
|
return join107(homedir58(), ".wezterm.lua");
|
|
490539
490778
|
}
|
|
@@ -490638,7 +490877,7 @@ ${WEZTERM_DELETE_FIX}
|
|
|
490638
490877
|
`;
|
|
490639
490878
|
}
|
|
490640
490879
|
function wezTermDeleteFixExists(configPath) {
|
|
490641
|
-
if (!
|
|
490880
|
+
if (!existsSync73(configPath))
|
|
490642
490881
|
return false;
|
|
490643
490882
|
try {
|
|
490644
490883
|
const content = readFileSync53(configPath, { encoding: "utf-8" });
|
|
@@ -490655,14 +490894,14 @@ function installWezTermDeleteFix() {
|
|
|
490655
490894
|
}
|
|
490656
490895
|
let content = "";
|
|
490657
490896
|
let backupPath = null;
|
|
490658
|
-
if (
|
|
490897
|
+
if (existsSync73(configPath)) {
|
|
490659
490898
|
backupPath = `${configPath}.letta-backup`;
|
|
490660
490899
|
copyFileSync6(configPath, backupPath);
|
|
490661
490900
|
content = readFileSync53(configPath, { encoding: "utf-8" });
|
|
490662
490901
|
}
|
|
490663
490902
|
content = injectWezTermDeleteFix(content);
|
|
490664
490903
|
const parentDir = dirname40(configPath);
|
|
490665
|
-
if (!
|
|
490904
|
+
if (!existsSync73(parentDir)) {
|
|
490666
490905
|
mkdirSync53(parentDir, { recursive: true });
|
|
490667
490906
|
}
|
|
490668
490907
|
writeFileSync45(configPath, content, { encoding: "utf-8" });
|
|
@@ -492659,9 +492898,9 @@ function getHeaderText(fileEdit) {
|
|
|
492659
492898
|
const relPath = relative13(cwd2, fileEdit.filePath);
|
|
492660
492899
|
const displayPath = relPath.startsWith("..") ? fileEdit.filePath : relPath;
|
|
492661
492900
|
if (t2 === "write") {
|
|
492662
|
-
const { existsSync:
|
|
492901
|
+
const { existsSync: existsSync74 } = __require("node:fs");
|
|
492663
492902
|
try {
|
|
492664
|
-
if (
|
|
492903
|
+
if (existsSync74(fileEdit.filePath)) {
|
|
492665
492904
|
return `Overwrite ${displayPath}?`;
|
|
492666
492905
|
}
|
|
492667
492906
|
} catch {}
|
|
@@ -501578,9 +501817,9 @@ var init_InputRich = __esm(async () => {
|
|
|
501578
501817
|
});
|
|
501579
501818
|
|
|
501580
501819
|
// src/cli/commands/install-github-app.ts
|
|
501581
|
-
import { execFileSync as
|
|
501820
|
+
import { execFileSync as execFileSync12 } from "node:child_process";
|
|
501582
501821
|
import {
|
|
501583
|
-
existsSync as
|
|
501822
|
+
existsSync as existsSync74,
|
|
501584
501823
|
mkdirSync as mkdirSync54,
|
|
501585
501824
|
mkdtempSync as mkdtempSync7,
|
|
501586
501825
|
readFileSync as readFileSync54,
|
|
@@ -501591,7 +501830,7 @@ import { tmpdir as tmpdir15 } from "node:os";
|
|
|
501591
501830
|
import { dirname as dirname41, join as join109 } from "node:path";
|
|
501592
501831
|
function runCommand(command, args, cwd2, input) {
|
|
501593
501832
|
try {
|
|
501594
|
-
return
|
|
501833
|
+
return execFileSync12(command, args, {
|
|
501595
501834
|
cwd: cwd2,
|
|
501596
501835
|
encoding: "utf8",
|
|
501597
501836
|
stdio: [input ? "pipe" : "ignore", "pipe", "pipe"],
|
|
@@ -501822,12 +502061,12 @@ function runGit7(args, cwd2) {
|
|
|
501822
502061
|
}
|
|
501823
502062
|
function writeWorkflow(repoDir, workflowPath, content) {
|
|
501824
502063
|
const absolutePath = join109(repoDir, workflowPath);
|
|
501825
|
-
if (!
|
|
502064
|
+
if (!existsSync74(dirname41(absolutePath))) {
|
|
501826
502065
|
mkdirSync54(dirname41(absolutePath), { recursive: true });
|
|
501827
502066
|
}
|
|
501828
502067
|
const next = `${content.trimEnd()}
|
|
501829
502068
|
`;
|
|
501830
|
-
if (
|
|
502069
|
+
if (existsSync74(absolutePath)) {
|
|
501831
502070
|
const previous = readFileSync54(absolutePath, "utf8");
|
|
501832
502071
|
if (previous === next) {
|
|
501833
502072
|
return false;
|
|
@@ -505717,7 +505956,7 @@ __export(exports_generate_memory_viewer, {
|
|
|
505717
505956
|
generateAndOpenMemoryViewer: () => generateAndOpenMemoryViewer
|
|
505718
505957
|
});
|
|
505719
505958
|
import { execFile as execFileCb7 } from "node:child_process";
|
|
505720
|
-
import { chmodSync as chmodSync8, existsSync as
|
|
505959
|
+
import { chmodSync as chmodSync8, existsSync as existsSync75, mkdirSync as mkdirSync55, writeFileSync as writeFileSync47 } from "node:fs";
|
|
505721
505960
|
import { homedir as homedir61 } from "node:os";
|
|
505722
505961
|
import { join as join110 } from "node:path";
|
|
505723
505962
|
import { promisify as promisify22 } from "node:util";
|
|
@@ -506028,7 +506267,7 @@ ${m4.body}` : m4.subject;
|
|
|
506028
506267
|
async function generateAndOpenMemoryViewer(agentId, options) {
|
|
506029
506268
|
const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
506030
506269
|
const repoDir = memoryRoot;
|
|
506031
|
-
if (!
|
|
506270
|
+
if (!existsSync75(join110(repoDir, ".git"))) {
|
|
506032
506271
|
throw new Error("Memory viewer requires memfs. Run /memfs enable first.");
|
|
506033
506272
|
}
|
|
506034
506273
|
const data = await collectMemoryData(agentId, repoDir, memoryRoot, options?.conversationId);
|
|
@@ -506038,7 +506277,7 @@ async function generateAndOpenMemoryViewer(agentId, options) {
|
|
|
506038
506277
|
data.context = applyContextUsageSnapshot(data.context, options?.contextUsage);
|
|
506039
506278
|
const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
|
|
506040
506279
|
const html5 = memory_viewer_template_default.replace("<!--LETTA_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
506041
|
-
if (!
|
|
506280
|
+
if (!existsSync75(VIEWERS_DIR)) {
|
|
506042
506281
|
mkdirSync55(VIEWERS_DIR, { recursive: true, mode: 448 });
|
|
506043
506282
|
}
|
|
506044
506283
|
try {
|
|
@@ -506075,7 +506314,7 @@ var init_generate_memory_viewer = __esm(() => {
|
|
|
506075
506314
|
});
|
|
506076
506315
|
|
|
506077
506316
|
// src/cli/components/MemfsTreeViewer.tsx
|
|
506078
|
-
import { existsSync as
|
|
506317
|
+
import { existsSync as existsSync76 } from "node:fs";
|
|
506079
506318
|
import { join as join111 } from "node:path";
|
|
506080
506319
|
function renderTreePrefix(node) {
|
|
506081
506320
|
let prefix = "";
|
|
@@ -506104,8 +506343,8 @@ function MemfsTreeViewer({
|
|
|
506104
506343
|
const [status, setStatus] = import_react88.useState(null);
|
|
506105
506344
|
const statusTimerRef = import_react88.useRef(null);
|
|
506106
506345
|
const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
506107
|
-
const memoryExists =
|
|
506108
|
-
const hasGitRepo = import_react88.useMemo(() =>
|
|
506346
|
+
const memoryExists = existsSync76(memoryRoot);
|
|
506347
|
+
const hasGitRepo = import_react88.useMemo(() => existsSync76(join111(memoryRoot, ".git")), [memoryRoot]);
|
|
506109
506348
|
function showStatus(msg, durationMs) {
|
|
506110
506349
|
if (statusTimerRef.current)
|
|
506111
506350
|
clearTimeout(statusTimerRef.current);
|
|
@@ -514952,9 +515191,9 @@ function getFileEditHeader(toolName2, toolArgs) {
|
|
|
514952
515191
|
const relPath = relative13(cwd2, filePath);
|
|
514953
515192
|
const displayPath = relPath.startsWith("..") ? filePath : relPath;
|
|
514954
515193
|
if (t2 === "write") {
|
|
514955
|
-
const { existsSync:
|
|
515194
|
+
const { existsSync: existsSync77 } = __require("node:fs");
|
|
514956
515195
|
try {
|
|
514957
|
-
if (
|
|
515196
|
+
if (existsSync77(filePath)) {
|
|
514958
515197
|
return `Overwrite ${displayPath}?`;
|
|
514959
515198
|
}
|
|
514960
515199
|
} catch {}
|
|
@@ -516722,7 +516961,7 @@ __export(exports_generate_diff_viewer, {
|
|
|
516722
516961
|
generateAndOpenDiffViewer: () => generateAndOpenDiffViewer
|
|
516723
516962
|
});
|
|
516724
516963
|
import { execFile as execFileCb8 } from "node:child_process";
|
|
516725
|
-
import { chmodSync as chmodSync9, existsSync as
|
|
516964
|
+
import { chmodSync as chmodSync9, existsSync as existsSync77, mkdirSync as mkdirSync56, writeFileSync as writeFileSync48 } from "node:fs";
|
|
516726
516965
|
import { homedir as homedir63 } from "node:os";
|
|
516727
516966
|
import { isAbsolute as isAbsolute27, join as join113, resolve as resolve44 } from "node:path";
|
|
516728
516967
|
import { promisify as promisify23 } from "node:util";
|
|
@@ -516947,7 +517186,7 @@ async function generateAndOpenDiffViewer(targetPath) {
|
|
|
516947
517186
|
};
|
|
516948
517187
|
const jsonPayload = JSON.stringify(payload).replace(/</g, "\\u003c");
|
|
516949
517188
|
const html5 = diff_viewer_template_default.replace("<!--LETTA_DIFF_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
516950
|
-
if (!
|
|
517189
|
+
if (!existsSync77(VIEWERS_DIR2)) {
|
|
516951
517190
|
mkdirSync56(VIEWERS_DIR2, { recursive: true, mode: 448 });
|
|
516952
517191
|
}
|
|
516953
517192
|
try {
|
|
@@ -518983,12 +519222,12 @@ __export(exports_shell_aliases, {
|
|
|
518983
519222
|
expandAliases: () => expandAliases,
|
|
518984
519223
|
clearAliasCache: () => clearAliasCache
|
|
518985
519224
|
});
|
|
518986
|
-
import { existsSync as
|
|
519225
|
+
import { existsSync as existsSync78, readFileSync as readFileSync55 } from "node:fs";
|
|
518987
519226
|
import { homedir as homedir64 } from "node:os";
|
|
518988
519227
|
import { join as join114 } from "node:path";
|
|
518989
519228
|
function parseAliasesFromFile(filePath) {
|
|
518990
519229
|
const aliases = new Map;
|
|
518991
|
-
if (!
|
|
519230
|
+
if (!existsSync78(filePath)) {
|
|
518992
519231
|
return aliases;
|
|
518993
519232
|
}
|
|
518994
519233
|
try {
|
|
@@ -520203,6 +520442,16 @@ var init_retry2 = __esm(() => {
|
|
|
520203
520442
|
function stripSystemReminders2(text3) {
|
|
520204
520443
|
return text3.replace(new RegExp(`${SYSTEM_REMINDER_OPEN}[\\s\\S]*?${SYSTEM_REMINDER_CLOSE}`, "g"), "").replace(new RegExp(`${SYSTEM_ALERT_OPEN}[\\s\\S]*?${SYSTEM_ALERT_CLOSE}`, "g"), "").trim();
|
|
520205
520444
|
}
|
|
520445
|
+
function getRestorableUserText(input) {
|
|
520446
|
+
const message2 = input.find((item) => item?.type === "message");
|
|
520447
|
+
const content = message2 && "content" in message2 ? message2.content : undefined;
|
|
520448
|
+
if (typeof content === "string")
|
|
520449
|
+
return stripSystemReminders2(content);
|
|
520450
|
+
if (!Array.isArray(content))
|
|
520451
|
+
return "";
|
|
520452
|
+
return content.flatMap((c) => c.type === "text" && !c.text.includes(SYSTEM_REMINDER_OPEN) && !c.text.includes(SYSTEM_ALERT_OPEN) ? [c.text] : []).join(`
|
|
520453
|
+
`).trim();
|
|
520454
|
+
}
|
|
520206
520455
|
var init_system_reminders2 = __esm(() => {
|
|
520207
520456
|
init_constants2();
|
|
520208
520457
|
});
|
|
@@ -520735,20 +520984,9 @@ function useConversationLoop(ctx) {
|
|
|
520735
520984
|
const agent = await getBackend().retrieveAgent(agentIdRef.current);
|
|
520736
520985
|
const { pendingApprovals: serverApprovals } = await getResumeDataFromBackend(agent, conversationIdRef.current);
|
|
520737
520986
|
if (serverApprovals && serverApprovals.length > 0) {
|
|
520738
|
-
const
|
|
520739
|
-
if (
|
|
520740
|
-
|
|
520741
|
-
let textToRestore = "";
|
|
520742
|
-
if (typeof content === "string") {
|
|
520743
|
-
textToRestore = stripSystemReminders2(content);
|
|
520744
|
-
} else if (Array.isArray(content)) {
|
|
520745
|
-
textToRestore = content.filter((c) => typeof c === "object" && c !== null && ("type" in c) && c.type === "text" && ("text" in c) && typeof c.text === "string" && !c.text.includes(SYSTEM_REMINDER_OPEN) && !c.text.includes(SYSTEM_ALERT_OPEN)).map((c) => c.text).join(`
|
|
520746
|
-
`);
|
|
520747
|
-
}
|
|
520748
|
-
if (textToRestore.trim()) {
|
|
520749
|
-
setRestoredInput(textToRestore);
|
|
520750
|
-
}
|
|
520751
|
-
}
|
|
520987
|
+
const textToRestore = getRestorableUserText(currentInput);
|
|
520988
|
+
if (textToRestore)
|
|
520989
|
+
setRestoredInput(textToRestore);
|
|
520752
520990
|
setApprovalResults([]);
|
|
520753
520991
|
setAutoHandledResults([]);
|
|
520754
520992
|
setAutoDeniedApprovals([]);
|
|
@@ -520766,6 +521004,13 @@ function useConversationLoop(ctx) {
|
|
|
520766
521004
|
sendDesktopNotification("Approval needed");
|
|
520767
521005
|
return;
|
|
520768
521006
|
}
|
|
521007
|
+
const plainInput = rebuildInputWithFreshDenials(currentInput, [], "");
|
|
521008
|
+
if (plainInput.length > 0 && llmApiErrorRetriesRef.current < LLM_API_ERROR_MAX_RETRIES3) {
|
|
521009
|
+
llmApiErrorRetriesRef.current += 1;
|
|
521010
|
+
currentInput = plainInput;
|
|
521011
|
+
buffersRef.current.interrupted = false;
|
|
521012
|
+
continue;
|
|
521013
|
+
}
|
|
520769
521014
|
} catch {}
|
|
520770
521015
|
}
|
|
520771
521016
|
}
|
|
@@ -521371,20 +521616,9 @@ ${feedback}
|
|
|
521371
521616
|
const agent = await getBackend().retrieveAgent(agentIdRef.current);
|
|
521372
521617
|
const { pendingApprovals: serverApprovals } = await getResumeDataFromBackend(agent, conversationIdRef.current);
|
|
521373
521618
|
if (serverApprovals && serverApprovals.length > 0) {
|
|
521374
|
-
const
|
|
521375
|
-
if (
|
|
521376
|
-
|
|
521377
|
-
let textToRestore = "";
|
|
521378
|
-
if (typeof content === "string") {
|
|
521379
|
-
textToRestore = stripSystemReminders2(content);
|
|
521380
|
-
} else if (Array.isArray(content)) {
|
|
521381
|
-
textToRestore = content.filter((c) => typeof c === "object" && c !== null && ("type" in c) && c.type === "text" && ("text" in c) && typeof c.text === "string" && !c.text.includes(SYSTEM_REMINDER_OPEN) && !c.text.includes(SYSTEM_ALERT_OPEN)).map((c) => c.text).join(`
|
|
521382
|
-
`);
|
|
521383
|
-
}
|
|
521384
|
-
if (textToRestore.trim()) {
|
|
521385
|
-
setRestoredInput(textToRestore);
|
|
521386
|
-
}
|
|
521387
|
-
}
|
|
521619
|
+
const textToRestore = getRestorableUserText(currentInput);
|
|
521620
|
+
if (textToRestore)
|
|
521621
|
+
setRestoredInput(textToRestore);
|
|
521388
521622
|
setApprovalResults([]);
|
|
521389
521623
|
setAutoHandledResults([]);
|
|
521390
521624
|
setAutoDeniedApprovals([]);
|
|
@@ -521402,6 +521636,13 @@ ${feedback}
|
|
|
521402
521636
|
sendDesktopNotification("Approval needed");
|
|
521403
521637
|
return;
|
|
521404
521638
|
}
|
|
521639
|
+
const plainInput = rebuildInputWithFreshDenials(currentInput, [], "");
|
|
521640
|
+
if (plainInput.length > 0 && llmApiErrorRetriesRef.current < LLM_API_ERROR_MAX_RETRIES3) {
|
|
521641
|
+
llmApiErrorRetriesRef.current += 1;
|
|
521642
|
+
currentInput = plainInput;
|
|
521643
|
+
buffersRef.current.interrupted = false;
|
|
521644
|
+
continue;
|
|
521645
|
+
}
|
|
521405
521646
|
} catch {}
|
|
521406
521647
|
}
|
|
521407
521648
|
const approvalPendingDetected = isApprovalPendingError(detailFromRun) || isApprovalPendingError(latestErrorText);
|
|
@@ -521751,7 +521992,6 @@ var init_use_conversation_loop = __esm(async () => {
|
|
|
521751
521992
|
init_reflection_transcript();
|
|
521752
521993
|
init_thinking_messages();
|
|
521753
521994
|
init_tool_name_mapping2();
|
|
521754
|
-
init_constants2();
|
|
521755
521995
|
init_hooks();
|
|
521756
521996
|
init_format_denial();
|
|
521757
521997
|
init_mode();
|
|
@@ -527088,7 +527328,7 @@ __export(exports_worktree_diff_list, {
|
|
|
527088
527328
|
listWorktreeDiffOptions: () => listWorktreeDiffOptions
|
|
527089
527329
|
});
|
|
527090
527330
|
import { execFile as execFileCb9 } from "node:child_process";
|
|
527091
|
-
import { basename as
|
|
527331
|
+
import { basename as basename33 } from "node:path";
|
|
527092
527332
|
import { promisify as promisify24 } from "node:util";
|
|
527093
527333
|
async function runGit9(cwd2, args) {
|
|
527094
527334
|
try {
|
|
@@ -527137,7 +527377,7 @@ function parseWorktreeList(output, currentPath) {
|
|
|
527137
527377
|
if (current?.path) {
|
|
527138
527378
|
worktrees.push({
|
|
527139
527379
|
path: current.path,
|
|
527140
|
-
name:
|
|
527380
|
+
name: basename33(current.path),
|
|
527141
527381
|
branch: current.branch ?? "detached",
|
|
527142
527382
|
head: current.head ?? "",
|
|
527143
527383
|
isCurrent: current.path === currentPath,
|
|
@@ -527163,7 +527403,7 @@ function parseWorktreeList(output, currentPath) {
|
|
|
527163
527403
|
if (current?.path) {
|
|
527164
527404
|
worktrees.push({
|
|
527165
527405
|
path: current.path,
|
|
527166
|
-
name:
|
|
527406
|
+
name: basename33(current.path),
|
|
527167
527407
|
branch: current.branch ?? "detached",
|
|
527168
527408
|
head: current.head ?? "",
|
|
527169
527409
|
isCurrent: current.path === currentPath,
|
|
@@ -527320,7 +527560,7 @@ var init_conversation_switch_alert = __esm(() => {
|
|
|
527320
527560
|
|
|
527321
527561
|
// src/cli/app/use-submit-handler.ts
|
|
527322
527562
|
import { randomUUID as randomUUID67 } from "node:crypto";
|
|
527323
|
-
import { existsSync as
|
|
527563
|
+
import { existsSync as existsSync79, readFileSync as readFileSync56, renameSync as renameSync12 } from "node:fs";
|
|
527324
527564
|
import { tmpdir as tmpdir16 } from "node:os";
|
|
527325
527565
|
import { join as join115 } from "node:path";
|
|
527326
527566
|
async function findCustomCommandByName(commandName) {
|
|
@@ -527933,7 +528173,7 @@ ${SYSTEM_REMINDER_CLOSE}`),
|
|
|
527933
528173
|
join115(memoryRoot, "system", "persona.md"),
|
|
527934
528174
|
join115(memoryRoot, "memory", "system", "persona.md")
|
|
527935
528175
|
];
|
|
527936
|
-
const personaPath = personaCandidates.find((candidate) =>
|
|
528176
|
+
const personaPath = personaCandidates.find((candidate) => existsSync79(candidate));
|
|
527937
528177
|
if (personaPath) {
|
|
527938
528178
|
const personaContent = readFileSync56(personaPath, "utf-8");
|
|
527939
528179
|
setCurrentPersonalityId(detectPersonalityFromPersonaFile(personaContent));
|
|
@@ -528775,12 +529015,12 @@ Path: ${memoryDir}`, true);
|
|
|
528775
529015
|
setCommandRunning(true);
|
|
528776
529016
|
try {
|
|
528777
529017
|
const memoryDir = getScopedMemoryFilesystemRoot(agentId);
|
|
528778
|
-
if (!
|
|
529018
|
+
if (!existsSync79(memoryDir)) {
|
|
528779
529019
|
updateMemorySyncCommand(cmdId, "No local memory filesystem found to reset.", true, msg);
|
|
528780
529020
|
return { submitted: true };
|
|
528781
529021
|
}
|
|
528782
529022
|
const backupDir = join115(tmpdir16(), `letta-memfs-reset-${agentId}-${Date.now()}`);
|
|
528783
|
-
|
|
529023
|
+
renameSync12(memoryDir, backupDir);
|
|
528784
529024
|
if (getBackend().capabilities.localMemfs) {
|
|
528785
529025
|
const { initializeLocalMemoryRepo: initializeLocalMemoryRepo2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
|
|
528786
529026
|
await initializeLocalMemoryRepo2({
|
|
@@ -531733,9 +531973,9 @@ Memory may be stale. Try running: git -C ${getScopedMemoryFilesystemRoot(agentId
|
|
|
531733
531973
|
(async () => {
|
|
531734
531974
|
try {
|
|
531735
531975
|
const { watch: watch4 } = await import("node:fs");
|
|
531736
|
-
const { existsSync:
|
|
531976
|
+
const { existsSync: existsSync80 } = await import("node:fs");
|
|
531737
531977
|
const memRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
531738
|
-
if (!
|
|
531978
|
+
if (!existsSync80(memRoot))
|
|
531739
531979
|
return;
|
|
531740
531980
|
watcher2 = watch4(memRoot, { recursive: true }, () => {});
|
|
531741
531981
|
memfsWatcherRef.current = watcher2;
|
|
@@ -533536,7 +533776,9 @@ async function main() {
|
|
|
533536
533776
|
}
|
|
533537
533777
|
const subcommandResult = await runSubcommand(subcommandArgs);
|
|
533538
533778
|
if (subcommandResult !== null) {
|
|
533539
|
-
process.
|
|
533779
|
+
process.channel?.unref();
|
|
533780
|
+
process.exitCode = subcommandResult;
|
|
533781
|
+
return;
|
|
533540
533782
|
}
|
|
533541
533783
|
await settingsManager.initialize();
|
|
533542
533784
|
const settings3 = await settingsManager.getSettingsWithSecureTokens();
|
|
@@ -537155,4 +537397,4 @@ function registerBunOAuthFlows() {
|
|
|
537155
537397
|
registerBunOAuthFlows();
|
|
537156
537398
|
await init_src5().then(() => exports_src2);
|
|
537157
537399
|
|
|
537158
|
-
//# debugId=
|
|
537400
|
+
//# debugId=B1F6CA2886AACEA464756E2164756E21
|