@letta-ai/letta-code 0.34.23 → 0.34.25
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 +6 -5
- 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/shell-launchers.d.ts.map +1 -1
- package/dist/types/tools/impl/wake.d.ts +4 -2
- package/dist/types/tools/impl/wake.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 +876 -614
- package/npm-shrinkwrap.json +18 -18
- 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/codex-watch/release-analysis.test.ts +70 -0
- package/scripts/codex-watch/release-analysis.ts +5 -5
- package/scripts/source-file-size-baseline.json +3 -3
- package/skills/maintaining-deferred-memory/SKILL.md +2 -0
- 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.25",
|
|
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-
|
|
6245
|
+
lettaRuntimeGraphSha512: "sha512-75ArKlsNj6BLjfiYR7ejV9jl0U3L7r1mXtWLYoNBVFkpR+NgT29dy3I6c7xawN3klfWjTCPVa5kpHtS7gVbD0A==",
|
|
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 };
|
|
@@ -186483,11 +186516,11 @@ async function listCloudSchedules(agentId, options = {}) {
|
|
|
186483
186516
|
}
|
|
186484
186517
|
});
|
|
186485
186518
|
}
|
|
186486
|
-
async function getCloudSchedule(agentId, scheduleId) {
|
|
186487
|
-
return apiRequest("GET", `${schedulePath(agentId)}/${encodeURIComponent(scheduleId)}
|
|
186519
|
+
async function getCloudSchedule(agentId, scheduleId, actingUserId) {
|
|
186520
|
+
return apiRequest("GET", `${schedulePath(agentId)}/${encodeURIComponent(scheduleId)}`, undefined, actingUserRequestOptions(actingUserId));
|
|
186488
186521
|
}
|
|
186489
|
-
async function deleteCloudSchedule(agentId, scheduleId) {
|
|
186490
|
-
await apiRequest("DELETE", `${schedulePath(agentId)}/${encodeURIComponent(scheduleId)}`, {});
|
|
186522
|
+
async function deleteCloudSchedule(agentId, scheduleId, actingUserId) {
|
|
186523
|
+
await apiRequest("DELETE", `${schedulePath(agentId)}/${encodeURIComponent(scheduleId)}`, {}, actingUserRequestOptions(actingUserId));
|
|
186491
186524
|
}
|
|
186492
186525
|
async function listCloudScheduleHistory(agentId, scheduleId, options = {}) {
|
|
186493
186526
|
return apiRequest("GET", `${schedulePath(agentId)}/${encodeURIComponent(scheduleId)}/history`, undefined, {
|
|
@@ -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.25"
|
|
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();
|
|
@@ -240547,25 +240616,41 @@ async function cancelWake(args, scope, deps) {
|
|
|
240547
240616
|
const id2 = args.id?.trim();
|
|
240548
240617
|
if (!id2)
|
|
240549
240618
|
throw new Error("Wake cancel requires id.");
|
|
240550
|
-
|
|
240551
|
-
const
|
|
240552
|
-
if (
|
|
240553
|
-
if (
|
|
240554
|
-
throw new Error(
|
|
240619
|
+
args.signal?.throwIfAborted();
|
|
240620
|
+
const local = (deps.getLocal ?? getTask)(id2);
|
|
240621
|
+
if (local?.agent_id === scope.agentId && local.conversation_id === scope.conversationId && (local.status === "active" || local.status === "paused")) {
|
|
240622
|
+
if (!(deps.deleteLocal ?? deleteTask)(id2)) {
|
|
240623
|
+
throw new Error(`Wake ${id2} was already removed.`);
|
|
240555
240624
|
}
|
|
240625
|
+
return result2("success", {
|
|
240626
|
+
action: "cancelled",
|
|
240627
|
+
id: id2,
|
|
240628
|
+
runner: "local",
|
|
240629
|
+
warnings: []
|
|
240630
|
+
});
|
|
240631
|
+
}
|
|
240632
|
+
if (resolveBackendMode() === "local" || isLocalAgentId(scope.agentId)) {
|
|
240556
240633
|
throw new Error(`Wake ${id2} was not found in the current conversation.`);
|
|
240557
240634
|
}
|
|
240558
|
-
|
|
240559
|
-
|
|
240560
|
-
await (deps.
|
|
240561
|
-
}
|
|
240562
|
-
|
|
240635
|
+
let cloud;
|
|
240636
|
+
try {
|
|
240637
|
+
cloud = await (deps.getCloud ?? getCloudSchedule)(scope.agentId, id2, getRuntimeActingUserId());
|
|
240638
|
+
} catch (error5) {
|
|
240639
|
+
if (error5 instanceof ApiRequestError && (error5.status === 404 || error5.status === 405)) {
|
|
240640
|
+
throw new Error(`Wake ${id2} was not found in the current conversation.`);
|
|
240641
|
+
}
|
|
240642
|
+
throw error5;
|
|
240643
|
+
}
|
|
240644
|
+
if (cloud.conversation_id !== scope.conversationId) {
|
|
240645
|
+
throw new Error(`Wake ${id2} was not found in the current conversation.`);
|
|
240563
240646
|
}
|
|
240647
|
+
args.signal?.throwIfAborted();
|
|
240648
|
+
await (deps.deleteCloud ?? deleteCloudSchedule)(scope.agentId, id2, getRuntimeActingUserId());
|
|
240564
240649
|
return result2("success", {
|
|
240565
240650
|
action: "cancelled",
|
|
240566
240651
|
id: id2,
|
|
240567
|
-
runner:
|
|
240568
|
-
warnings:
|
|
240652
|
+
runner: "cloud",
|
|
240653
|
+
warnings: []
|
|
240569
240654
|
});
|
|
240570
240655
|
}
|
|
240571
240656
|
async function wake(args, deps = {}) {
|
|
@@ -243307,7 +243392,7 @@ class CodexAppServerClient {
|
|
|
243307
243392
|
await this.request("initialize", {
|
|
243308
243393
|
clientInfo: {
|
|
243309
243394
|
name: "letta-code",
|
|
243310
|
-
version: "0.34.
|
|
243395
|
+
version: "0.34.25"
|
|
243311
243396
|
},
|
|
243312
243397
|
capabilities: null
|
|
243313
243398
|
});
|
|
@@ -244017,7 +244102,7 @@ var init_conversation_bootstrap = __esm(() => {
|
|
|
244017
244102
|
|
|
244018
244103
|
// src/cli/helpers/session-context.ts
|
|
244019
244104
|
import { platform as platform7 } from "node:os";
|
|
244020
|
-
import { basename as
|
|
244105
|
+
import { basename as basename21 } from "node:path";
|
|
244021
244106
|
function getLocalTime() {
|
|
244022
244107
|
const now2 = new Date;
|
|
244023
244108
|
return now2.toLocaleString(undefined, {
|
|
@@ -244061,7 +244146,7 @@ function getGitInfo(cwd2) {
|
|
|
244061
244146
|
};
|
|
244062
244147
|
}
|
|
244063
244148
|
function buildUnixShellLine(shellContext) {
|
|
244064
|
-
const shellName =
|
|
244149
|
+
const shellName = basename21(shellContext.displayName) || shellContext.displayName;
|
|
244065
244150
|
return `- **Shell**: ${shellName}
|
|
244066
244151
|
`;
|
|
244067
244152
|
}
|
|
@@ -246771,7 +246856,7 @@ function isAppServerInfoResponseMessage(message2) {
|
|
|
246771
246856
|
return false;
|
|
246772
246857
|
}
|
|
246773
246858
|
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") &&
|
|
246859
|
+
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
246860
|
}
|
|
246776
246861
|
var APP_SERVER_PROTOCOL_VERSION = 1;
|
|
246777
246862
|
|
|
@@ -248740,7 +248825,7 @@ var init_memory_operation = __esm(() => {
|
|
|
248740
248825
|
// src/agent/memory-worktree.ts
|
|
248741
248826
|
import { execFile as execFileCb4 } from "node:child_process";
|
|
248742
248827
|
import { randomUUID as randomUUID41 } from "node:crypto";
|
|
248743
|
-
import { existsSync as
|
|
248828
|
+
import { existsSync as existsSync45 } from "node:fs";
|
|
248744
248829
|
import { mkdir as mkdir12 } from "node:fs/promises";
|
|
248745
248830
|
import { dirname as dirname29, isAbsolute as isAbsolute23, join as join67, resolve as resolve36 } from "node:path";
|
|
248746
248831
|
import { promisify as promisify17 } from "node:util";
|
|
@@ -248932,7 +249017,7 @@ async function inspectReflectionMemoryWorktree(worktree) {
|
|
|
248932
249017
|
};
|
|
248933
249018
|
}
|
|
248934
249019
|
async function cleanupWorktreeAndBranch(parentMemoryDir, worktreeDir, branchName, options = {}) {
|
|
248935
|
-
const removedWorktree =
|
|
249020
|
+
const removedWorktree = existsSync45(worktreeDir);
|
|
248936
249021
|
if (removedWorktree) {
|
|
248937
249022
|
await runGit4(parentMemoryDir, [
|
|
248938
249023
|
"worktree",
|
|
@@ -248948,7 +249033,7 @@ async function cleanupWorktreeAndBranch(parentMemoryDir, worktreeDir, branchName
|
|
|
248948
249033
|
]);
|
|
248949
249034
|
}
|
|
248950
249035
|
async function finalizeReflectionMemoryWorktreeUnlocked(worktree, options) {
|
|
248951
|
-
if (!
|
|
249036
|
+
if (!existsSync45(worktree.worktreeDir) && options.knownNoChanges) {
|
|
248952
249037
|
const branchHead = (await tryRunGit(worktree.parentMemoryDir, [
|
|
248953
249038
|
"rev-parse",
|
|
248954
249039
|
"--verify",
|
|
@@ -249135,7 +249220,7 @@ async function integrateMemoryWorkerWorktree(worktree, options = {}) {
|
|
|
249135
249220
|
await cleanup(true);
|
|
249136
249221
|
return { status: "no_changes" };
|
|
249137
249222
|
}
|
|
249138
|
-
if (
|
|
249223
|
+
if (existsSync45(worktree.worktreeDir)) {
|
|
249139
249224
|
await runGit4(worktree.parentMemoryDir, [
|
|
249140
249225
|
"worktree",
|
|
249141
249226
|
"remove",
|
|
@@ -251200,7 +251285,7 @@ __export(exports_skill, {
|
|
|
251200
251285
|
loadRenderedSkillContent: () => loadRenderedSkillContent,
|
|
251201
251286
|
getResolvedSkillsDir: () => getResolvedSkillsDir
|
|
251202
251287
|
});
|
|
251203
|
-
import { existsSync as
|
|
251288
|
+
import { existsSync as existsSync46, readdirSync as readdirSync17 } from "node:fs";
|
|
251204
251289
|
import { readFile as readFile17 } from "node:fs/promises";
|
|
251205
251290
|
import { dirname as dirname30, join as join68 } from "node:path";
|
|
251206
251291
|
async function readSkillFromRoot(skillsRoot, skillId) {
|
|
@@ -251222,7 +251307,7 @@ async function readSkillFromRoot(skillsRoot, skillId) {
|
|
|
251222
251307
|
function getMemorySkillsDirs2(agentId) {
|
|
251223
251308
|
const dirs = new Set;
|
|
251224
251309
|
const scopedMemoryDir = resolveScopedMemoryDir({ agentId });
|
|
251225
|
-
if (scopedMemoryDir && scopedMemoryDir.trim().length > 0 &&
|
|
251310
|
+
if (scopedMemoryDir && scopedMemoryDir.trim().length > 0 && existsSync46(scopedMemoryDir)) {
|
|
251226
251311
|
dirs.add(join68(scopedMemoryDir.trim(), "skills"));
|
|
251227
251312
|
} else {
|
|
251228
251313
|
const fallbackMemoryDir = (process.env.LETTA_MEMORY_DIR || process.env.MEMORY_DIR || "").trim();
|
|
@@ -252799,7 +252884,7 @@ var init_watch_pr = __esm(async () => {
|
|
|
252799
252884
|
});
|
|
252800
252885
|
|
|
252801
252886
|
// src/tools/workflow/sdk-loader.ts
|
|
252802
|
-
import { existsSync as
|
|
252887
|
+
import { existsSync as existsSync47, readFileSync as readFileSync37 } from "node:fs";
|
|
252803
252888
|
import { createRequire as createRequire6 } from "node:module";
|
|
252804
252889
|
import { dirname as dirname31, join as join69 } from "node:path";
|
|
252805
252890
|
import { fileURLToPath as fileURLToPath7, pathToFileURL as pathToFileURL3 } from "node:url";
|
|
@@ -252823,7 +252908,7 @@ function preferRunningCliForSubagents() {
|
|
|
252823
252908
|
if (process.env.LETTA_CLI_PATH)
|
|
252824
252909
|
return;
|
|
252825
252910
|
const entry = process.argv[1];
|
|
252826
|
-
if (entry && /(^|[\\/])letta\.js$/.test(entry) &&
|
|
252911
|
+
if (entry && /(^|[\\/])letta\.js$/.test(entry) && existsSync47(entry)) {
|
|
252827
252912
|
process.env.LETTA_CLI_PATH = entry;
|
|
252828
252913
|
}
|
|
252829
252914
|
}
|
|
@@ -252854,7 +252939,7 @@ function probeInstalledSdkDirs(startDirs) {
|
|
|
252854
252939
|
let dir = start2;
|
|
252855
252940
|
while (true) {
|
|
252856
252941
|
const candidate = join69(dir, "node_modules", ...SDK_PACKAGE.split("/"));
|
|
252857
|
-
if (
|
|
252942
|
+
if (existsSync47(join69(candidate, "package.json")) && !found.includes(candidate)) {
|
|
252858
252943
|
found.push(candidate);
|
|
252859
252944
|
}
|
|
252860
252945
|
const parent = dirname31(dir);
|
|
@@ -255327,15 +255412,28 @@ var init_interrupted_turn_schema = __esm(async () => {
|
|
|
255327
255412
|
await init_teleport_protocol_inbound();
|
|
255328
255413
|
});
|
|
255329
255414
|
|
|
255415
|
+
// src/utils/rename-sync-with-retry.ts
|
|
255416
|
+
import { renameSync as renameSync10 } from "node:fs";
|
|
255417
|
+
function renameSyncWithRetry(source, destination, platform9 = process.platform, rename3 = renameSync10) {
|
|
255418
|
+
const sleeper = new Int32Array(new SharedArrayBuffer(4));
|
|
255419
|
+
for (let attempt2 = 0;; attempt2++) {
|
|
255420
|
+
try {
|
|
255421
|
+
rename3(source, destination);
|
|
255422
|
+
return;
|
|
255423
|
+
} catch (error5) {
|
|
255424
|
+
const code2 = error5.code;
|
|
255425
|
+
if (platform9 !== "win32" || attempt2 >= 9 || !["EPERM", "EACCES", "EBUSY"].includes(code2 ?? "")) {
|
|
255426
|
+
throw error5;
|
|
255427
|
+
}
|
|
255428
|
+
Atomics.wait(sleeper, 0, 0, 10 * (attempt2 + 1));
|
|
255429
|
+
}
|
|
255430
|
+
}
|
|
255431
|
+
}
|
|
255432
|
+
var init_rename_sync_with_retry = () => {};
|
|
255433
|
+
|
|
255330
255434
|
// src/websocket/listener/interrupted-turn-storage.ts
|
|
255331
255435
|
import { createHash as createHash11 } from "node:crypto";
|
|
255332
|
-
import {
|
|
255333
|
-
closeSync as closeSync7,
|
|
255334
|
-
fsyncSync as fsyncSync4,
|
|
255335
|
-
openSync as openSync7,
|
|
255336
|
-
renameSync as renameSync10,
|
|
255337
|
-
writeFileSync as writeFileSync29
|
|
255338
|
-
} from "node:fs";
|
|
255436
|
+
import { closeSync as closeSync7, fsyncSync as fsyncSync4, openSync as openSync7, writeFileSync as writeFileSync29 } from "node:fs";
|
|
255339
255437
|
import { homedir as homedir35 } from "node:os";
|
|
255340
255438
|
import { join as join71 } from "node:path";
|
|
255341
255439
|
function writeInterruptedTurnRecordFile(temporary, destination, directory, record6, syncDirectory) {
|
|
@@ -255343,7 +255441,7 @@ function writeInterruptedTurnRecordFile(temporary, destination, directory, recor
|
|
|
255343
255441
|
mode: 384,
|
|
255344
255442
|
flush: true
|
|
255345
255443
|
});
|
|
255346
|
-
|
|
255444
|
+
renameSyncWithRetry(temporary, destination);
|
|
255347
255445
|
syncDirectory(directory);
|
|
255348
255446
|
}
|
|
255349
255447
|
function fsyncInterruptedTurnDirectory(directory, platform9 = process.platform) {
|
|
@@ -255367,6 +255465,7 @@ function defaultInterruptedTurnDirectory() {
|
|
|
255367
255465
|
}
|
|
255368
255466
|
var init_interrupted_turn_storage = __esm(() => {
|
|
255369
255467
|
init_server_url();
|
|
255468
|
+
init_rename_sync_with_retry();
|
|
255370
255469
|
});
|
|
255371
255470
|
|
|
255372
255471
|
// src/websocket/listener/recorded-tool-results.ts
|
|
@@ -255432,11 +255531,10 @@ function createRecoveryAuthorityGuard(dependencies4) {
|
|
|
255432
255531
|
// src/websocket/listener/recovery-lineage-sidecar.ts
|
|
255433
255532
|
import { createHash as createHash12, randomUUID as randomUUID44 } from "node:crypto";
|
|
255434
255533
|
import {
|
|
255435
|
-
existsSync as
|
|
255534
|
+
existsSync as existsSync48,
|
|
255436
255535
|
mkdirSync as mkdirSync35,
|
|
255437
255536
|
readdirSync as readdirSync18,
|
|
255438
255537
|
readFileSync as readFileSync39,
|
|
255439
|
-
renameSync as renameSync11,
|
|
255440
255538
|
rmSync as rmSync18,
|
|
255441
255539
|
statSync as statSync19,
|
|
255442
255540
|
writeFileSync as writeFileSync30
|
|
@@ -255477,7 +255575,7 @@ function createRecoveryLineageSidecarAccess(params) {
|
|
|
255477
255575
|
mode: 384,
|
|
255478
255576
|
flush: true
|
|
255479
255577
|
});
|
|
255480
|
-
|
|
255578
|
+
renameSyncWithRetry(temporary, destination);
|
|
255481
255579
|
params.syncDirectory(params.directory);
|
|
255482
255580
|
} finally {
|
|
255483
255581
|
rmSync18(temporary, { force: true });
|
|
@@ -255727,7 +255825,7 @@ function createRecoveryLineageSidecarAccess(params) {
|
|
|
255727
255825
|
const removeMalformedOrphan = (file) => {
|
|
255728
255826
|
const separator = file.indexOf(".recovery-");
|
|
255729
255827
|
const mainFile = separator >= 0 ? file.slice(0, separator) : "";
|
|
255730
|
-
if (!mainFile ||
|
|
255828
|
+
if (!mainFile || existsSync48(join72(params.directory, mainFile)))
|
|
255731
255829
|
return;
|
|
255732
255830
|
try {
|
|
255733
255831
|
rmSync18(join72(params.directory, file), { force: true });
|
|
@@ -255809,6 +255907,7 @@ function createRecoveryLineageSidecarAccess(params) {
|
|
|
255809
255907
|
}
|
|
255810
255908
|
var sidecarWriterInstanceId;
|
|
255811
255909
|
var init_recovery_lineage_sidecar = __esm(async () => {
|
|
255910
|
+
init_rename_sync_with_retry();
|
|
255812
255911
|
init_durable_file_lock();
|
|
255813
255912
|
await init_interrupted_turn_schema();
|
|
255814
255913
|
sidecarWriterInstanceId = randomUUID44();
|
|
@@ -255817,7 +255916,7 @@ var init_recovery_lineage_sidecar = __esm(async () => {
|
|
|
255817
255916
|
// src/websocket/listener/interrupted-turn-record.ts
|
|
255818
255917
|
import { randomUUID as randomUUID45 } from "node:crypto";
|
|
255819
255918
|
import {
|
|
255820
|
-
existsSync as
|
|
255919
|
+
existsSync as existsSync49,
|
|
255821
255920
|
mkdirSync as mkdirSync36,
|
|
255822
255921
|
readFileSync as readFileSync40,
|
|
255823
255922
|
rmSync as rmSync19,
|
|
@@ -255874,7 +255973,7 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
|
|
|
255874
255973
|
const recoveryAuthority = createRecoveryAuthorityGuard({
|
|
255875
255974
|
path: path32,
|
|
255876
255975
|
readRecord: readRecord2,
|
|
255877
|
-
exists:
|
|
255976
|
+
exists: existsSync49,
|
|
255878
255977
|
acquire: (destination) => acquireDurableFileLock(destination, {
|
|
255879
255978
|
waitMs: dependencies4.lockWaitMs
|
|
255880
255979
|
}),
|
|
@@ -255908,7 +256007,7 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
|
|
|
255908
256007
|
});
|
|
255909
256008
|
try {
|
|
255910
256009
|
const current = readRecord2(destination);
|
|
255911
|
-
if (!
|
|
256010
|
+
if (!existsSync49(destination)) {
|
|
255912
256011
|
removeSidecar(sidecar);
|
|
255913
256012
|
} else if (current && current.recoveryClaimCompletion?.lineageId !== sidecar.lineageId) {
|
|
255914
256013
|
removeSidecar(sidecar);
|
|
@@ -255933,7 +256032,7 @@ function createInterruptedTurnStore(directory = defaultInterruptedTurnDirectory(
|
|
|
255933
256032
|
},
|
|
255934
256033
|
listDurableInputOwnership() {
|
|
255935
256034
|
const snapshot2 = rawSnapshot();
|
|
255936
|
-
return collectInterruptedTurnInputOwnershipWithSidecars(snapshot2.records, readMainView, listSidecars(), (agentId, conversationId) =>
|
|
256035
|
+
return collectInterruptedTurnInputOwnershipWithSidecars(snapshot2.records, readMainView, listSidecars(), (agentId, conversationId) => existsSync49(path32(agentId, conversationId)), snapshot2.unreadableScopes);
|
|
255937
256036
|
},
|
|
255938
256037
|
read(agentId, conversationId) {
|
|
255939
256038
|
const current = readRecord2(path32(agentId, conversationId));
|
|
@@ -257492,7 +257591,7 @@ function socketForTransport(transport3) {
|
|
|
257492
257591
|
}
|
|
257493
257592
|
function refreshLegacySingleConnection(runtime) {
|
|
257494
257593
|
const live = [...runtime.connections.values()].filter((connection) => isListenerTransportOpen(connection.writer));
|
|
257495
|
-
const only = live.length === 1 ? live[0] : null;
|
|
257594
|
+
const only = live.find(({ id: id2 }) => id2 === runtime.connectionId) ?? (live.length === 1 ? live[0] : null);
|
|
257496
257595
|
runtime.transport = runtime.processTransport ?? only?.writer ?? null;
|
|
257497
257596
|
runtime.streamTransport = only?.streamWriter ?? null;
|
|
257498
257597
|
runtime.socket = only ? socketForTransport(only.writer) : null;
|
|
@@ -257718,6 +257817,26 @@ function suspendListenerConnection(runtime, connectionId) {
|
|
|
257718
257817
|
getResumeStates(runtime).set(connectionId, resumeState);
|
|
257719
257818
|
return closed;
|
|
257720
257819
|
}
|
|
257820
|
+
function resumeListenerConnectionIdentity(runtime, previousId, nextId2) {
|
|
257821
|
+
const states3 = getResumeStates(runtime);
|
|
257822
|
+
const previous = states3.get(previousId);
|
|
257823
|
+
states3.delete(previousId);
|
|
257824
|
+
if (previous)
|
|
257825
|
+
states3.set(nextId2, previous);
|
|
257826
|
+
for (const conversation of runtime.conversationRuntimes.values()) {
|
|
257827
|
+
for (const [itemId, message2] of conversation.queuedMessagesByItemId) {
|
|
257828
|
+
if (message2.connectionId === previousId) {
|
|
257829
|
+
conversation.queuedMessagesByItemId.set(itemId, {
|
|
257830
|
+
...message2,
|
|
257831
|
+
connectionId: nextId2
|
|
257832
|
+
});
|
|
257833
|
+
}
|
|
257834
|
+
}
|
|
257835
|
+
if (conversation.activeConnectionId === previousId) {
|
|
257836
|
+
conversation.activeConnectionId = nextId2;
|
|
257837
|
+
}
|
|
257838
|
+
}
|
|
257839
|
+
}
|
|
257721
257840
|
|
|
257722
257841
|
class ProcessRuntimeTransport {
|
|
257723
257842
|
runtime;
|
|
@@ -257763,9 +257882,6 @@ var init_connection = __esm(async () => {
|
|
|
257763
257882
|
});
|
|
257764
257883
|
|
|
257765
257884
|
// src/queue/queue-runtime.ts
|
|
257766
|
-
function isCoalescable(kind) {
|
|
257767
|
-
return kind === "message" || kind === "task_notification" || kind === "cron_prompt" || kind === "mod_continue";
|
|
257768
|
-
}
|
|
257769
257885
|
function hasSameScope(a2, b3) {
|
|
257770
257886
|
return (a2.agentId ?? null) === (b3.agentId ?? null) && (a2.conversationId ?? null) === (b3.conversationId ?? null);
|
|
257771
257887
|
}
|
|
@@ -257787,7 +257903,7 @@ class QueueRuntime {
|
|
|
257787
257903
|
this.callbacks = options.callbacks ?? {};
|
|
257788
257904
|
}
|
|
257789
257905
|
enqueue(input, options = {}) {
|
|
257790
|
-
if (options.preserveExisting && (this.store.length >= this.hardMaxItems || this.store.length >= this.maxItems
|
|
257906
|
+
if (options.preserveExisting && (this.store.length >= this.hardMaxItems || this.store.length >= this.maxItems)) {
|
|
257791
257907
|
return null;
|
|
257792
257908
|
}
|
|
257793
257909
|
if (this.store.length >= this.hardMaxItems) {
|
|
@@ -257797,9 +257913,8 @@ class QueueRuntime {
|
|
|
257797
257913
|
this.safeCallback("onDropped", phantom, "buffer_limit", this.store.length);
|
|
257798
257914
|
return null;
|
|
257799
257915
|
}
|
|
257800
|
-
if (this.store.length >= this.maxItems
|
|
257801
|
-
const
|
|
257802
|
-
const dropped = dropIdx !== -1 ? this.store[dropIdx] : undefined;
|
|
257916
|
+
if (this.store.length >= this.maxItems) {
|
|
257917
|
+
const dropped = this.store[0];
|
|
257803
257918
|
if (dropped !== undefined) {
|
|
257804
257919
|
if (!this.mutationAllowed("beforeDropped", dropped)) {
|
|
257805
257920
|
const rejected = this.makeItem(input);
|
|
@@ -257808,7 +257923,7 @@ class QueueRuntime {
|
|
|
257808
257923
|
this.safeCallback("onDropped", rejected, "buffer_limit", this.store.length);
|
|
257809
257924
|
return null;
|
|
257810
257925
|
}
|
|
257811
|
-
this.store.
|
|
257926
|
+
this.store.shift();
|
|
257812
257927
|
const item2 = this.makeItem(input);
|
|
257813
257928
|
this.store.push(item2);
|
|
257814
257929
|
this.safeCallback("onDropped", dropped, "buffer_limit", this.store.length);
|
|
@@ -257846,16 +257961,14 @@ class QueueRuntime {
|
|
|
257846
257961
|
}
|
|
257847
257962
|
const batch = [];
|
|
257848
257963
|
const first = this.store.find((item) => !item.paused);
|
|
257849
|
-
if (first
|
|
257964
|
+
if (first) {
|
|
257850
257965
|
for (const item of this.store) {
|
|
257851
257966
|
if (item.paused)
|
|
257852
257967
|
continue;
|
|
257853
|
-
if (!
|
|
257968
|
+
if (!hasSameScope(first, item))
|
|
257854
257969
|
break;
|
|
257855
257970
|
batch.push(item);
|
|
257856
257971
|
}
|
|
257857
|
-
} else if (first) {
|
|
257858
|
-
batch.push(first);
|
|
257859
257972
|
}
|
|
257860
257973
|
if (batch.length === 0) {
|
|
257861
257974
|
return null;
|
|
@@ -258248,12 +258361,11 @@ import { randomUUID as randomUUID46 } from "node:crypto";
|
|
|
258248
258361
|
import {
|
|
258249
258362
|
chmodSync as chmodSync7,
|
|
258250
258363
|
closeSync as closeSync8,
|
|
258251
|
-
existsSync as
|
|
258364
|
+
existsSync as existsSync50,
|
|
258252
258365
|
fsyncSync as fsyncSync5,
|
|
258253
258366
|
mkdirSync as mkdirSync37,
|
|
258254
258367
|
openSync as openSync8,
|
|
258255
258368
|
readFileSync as readFileSync41,
|
|
258256
|
-
renameSync as renameSync12,
|
|
258257
258369
|
statSync as statSync20,
|
|
258258
258370
|
unlinkSync as unlinkSync11,
|
|
258259
258371
|
writeFileSync as writeFileSync32
|
|
@@ -258392,7 +258504,7 @@ function validateDurableStore(value) {
|
|
|
258392
258504
|
return value;
|
|
258393
258505
|
}
|
|
258394
258506
|
function readDurableStore(path32) {
|
|
258395
|
-
if (!
|
|
258507
|
+
if (!existsSync50(path32))
|
|
258396
258508
|
return emptyDurableStore();
|
|
258397
258509
|
const size2 = statSync20(path32).size;
|
|
258398
258510
|
if (size2 > MAX_INPUT_DISPOSITION_STORE_BYTES) {
|
|
@@ -258420,7 +258532,7 @@ function writeDurableStore(path32, store3) {
|
|
|
258420
258532
|
} finally {
|
|
258421
258533
|
closeSync8(fd);
|
|
258422
258534
|
}
|
|
258423
|
-
|
|
258535
|
+
renameSyncWithRetry(temporaryPath, path32);
|
|
258424
258536
|
fsyncDirectory(dirname33(path32));
|
|
258425
258537
|
} catch (error5) {
|
|
258426
258538
|
try {
|
|
@@ -258822,6 +258934,7 @@ function loadDurableQueuedInputEntries(listener) {
|
|
|
258822
258934
|
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;
|
|
258823
258935
|
var init_input_disposition = __esm(async () => {
|
|
258824
258936
|
init_server_url();
|
|
258937
|
+
init_rename_sync_with_retry();
|
|
258825
258938
|
init_durable_file_lock();
|
|
258826
258939
|
init_input_disposition_capacity();
|
|
258827
258940
|
init_input_disposition_expiry();
|
|
@@ -258846,7 +258959,6 @@ import {
|
|
|
258846
258959
|
openSync as openSync9,
|
|
258847
258960
|
readdirSync as readdirSync19,
|
|
258848
258961
|
readFileSync as readFileSync42,
|
|
258849
|
-
renameSync as renameSync13,
|
|
258850
258962
|
rmSync as rmSync20,
|
|
258851
258963
|
writeFileSync as writeFileSync33
|
|
258852
258964
|
} from "node:fs";
|
|
@@ -258942,7 +259054,7 @@ function createTurnFinishedStore(directory = defaultDirectory(), options = {}) {
|
|
|
258942
259054
|
mode: 384,
|
|
258943
259055
|
flush: true
|
|
258944
259056
|
});
|
|
258945
|
-
|
|
259057
|
+
renameSyncWithRetry(temporary, destination);
|
|
258946
259058
|
fsyncDirectory2(directory);
|
|
258947
259059
|
} finally {
|
|
258948
259060
|
rmSync20(temporary, { force: true });
|
|
@@ -259294,6 +259406,7 @@ var TurnFinishedCapacityError, MAX_PENDING_TERMINALS_PER_CONVERSATION = 64, DELI
|
|
|
259294
259406
|
var init_turn_finished_replay = __esm(async () => {
|
|
259295
259407
|
init_server_url();
|
|
259296
259408
|
init_debug();
|
|
259409
|
+
init_rename_sync_with_retry();
|
|
259297
259410
|
init_durable_file_lock();
|
|
259298
259411
|
await __promiseAll([
|
|
259299
259412
|
init_connection(),
|
|
@@ -259958,20 +260071,6 @@ var init_image_policy = __esm(async () => {
|
|
|
259958
260071
|
await init_message_image_normalization();
|
|
259959
260072
|
});
|
|
259960
260073
|
|
|
259961
|
-
// src/websocket/listener/mcp-originator-scope.ts
|
|
259962
|
-
function getMcpOriginatorScope(message2) {
|
|
259963
|
-
return message2?.mcpOriginatorSuperRunId ? {
|
|
259964
|
-
superRunId: message2.mcpOriginatorSuperRunId,
|
|
259965
|
-
tokenPresent: message2.mcpOriginatorTokenPresent === true
|
|
259966
|
-
} : null;
|
|
259967
|
-
}
|
|
259968
|
-
function sameMcpOriginatorScope(a2, b3) {
|
|
259969
|
-
return a2 === null || b3 === null ? a2 === b3 : a2.superRunId === b3.superRunId && a2.tokenPresent === b3.tokenPresent;
|
|
259970
|
-
}
|
|
259971
|
-
function getEffectiveMcpOriginatorId(message2) {
|
|
259972
|
-
return message2.mcpOriginatorTokenPresent === true ? message2.mcpOriginatorSuperRunId : undefined;
|
|
259973
|
-
}
|
|
259974
|
-
|
|
259975
260074
|
// src/websocket/listener/queue.ts
|
|
259976
260075
|
function getQueueItemScope(item) {
|
|
259977
260076
|
if (!item) {
|
|
@@ -260030,7 +260129,7 @@ function buildQueuedTurnMessage(runtime, batch) {
|
|
|
260030
260129
|
messageOriginatorIds.push(undefined);
|
|
260031
260130
|
originatorVotes.push(null);
|
|
260032
260131
|
messages.push(withMessageAttribution({ role: "user", content: item.content }, item.actingUserId ?? undefined));
|
|
260033
|
-
} else
|
|
260132
|
+
} else {
|
|
260034
260133
|
messageOriginatorIds.push(undefined);
|
|
260035
260134
|
originatorVotes.push(null);
|
|
260036
260135
|
messages.push({
|
|
@@ -260095,15 +260194,12 @@ function shouldProcessInboundMessageDirectly(runtime, parsed) {
|
|
|
260095
260194
|
});
|
|
260096
260195
|
return getListenerBlockedReason(runtime.turnLifecycle.snapshot(), activeScope ? getPendingControlRequestCount(runtime.listener, activeScope) : 0) === null;
|
|
260097
260196
|
}
|
|
260098
|
-
function consumeQueuedTurn(runtime
|
|
260197
|
+
function consumeQueuedTurn(runtime) {
|
|
260099
260198
|
const queuedItems = runtime.queueRuntime.peekReady();
|
|
260100
260199
|
const firstQueuedItem = queuedItems[0];
|
|
260101
|
-
if (!firstQueuedItem
|
|
260200
|
+
if (!firstQueuedItem) {
|
|
260102
260201
|
return null;
|
|
260103
260202
|
}
|
|
260104
|
-
const firstScope = getMcpOriginatorScope(firstQueuedItem.kind === "message" ? runtime.queuedMessagesByItemId.get(firstQueuedItem.id) : undefined);
|
|
260105
|
-
if (activeScope !== undefined && !sameMcpOriginatorScope(firstScope, activeScope))
|
|
260106
|
-
return null;
|
|
260107
260203
|
let queueLen = 0;
|
|
260108
260204
|
let hasMessage = false;
|
|
260109
260205
|
let hasTaskNotification = false;
|
|
@@ -260114,7 +260210,7 @@ function consumeQueuedTurn(runtime, activeScope) {
|
|
|
260114
260210
|
let batchPreferences = JSON.stringify(getStoredClientPreferences(runtime.agentId, runtime.conversationId));
|
|
260115
260211
|
const isNoCoalesce = (candidate) => candidate.kind === "message" && candidate.noCoalesce === true;
|
|
260116
260212
|
for (const item of queuedItems) {
|
|
260117
|
-
if (!
|
|
260213
|
+
if (!hasSameQueueScope(firstQueuedItem, item)) {
|
|
260118
260214
|
break;
|
|
260119
260215
|
}
|
|
260120
260216
|
const incoming = runtime.queuedMessagesByItemId.get(item.id);
|
|
@@ -260160,6 +260256,25 @@ function consumeQueuedTurn(runtime, activeScope) {
|
|
|
260160
260256
|
if (!dequeuedBatch) {
|
|
260161
260257
|
return null;
|
|
260162
260258
|
}
|
|
260259
|
+
for (const item of dequeuedBatch.items) {
|
|
260260
|
+
if (item.kind !== "cron_prompt")
|
|
260261
|
+
continue;
|
|
260262
|
+
try {
|
|
260263
|
+
const task2 = getTask(item.cronTaskId);
|
|
260264
|
+
if (task2 && task2.agent_id === item.agentId) {
|
|
260265
|
+
safeAppendCronRunLogForTask(task2, {
|
|
260266
|
+
status: "ok",
|
|
260267
|
+
outcome: "delivered",
|
|
260268
|
+
reason: "dequeued",
|
|
260269
|
+
queueItemId: item.id,
|
|
260270
|
+
conversationId: item.conversationId,
|
|
260271
|
+
runAtMs: Date.now()
|
|
260272
|
+
});
|
|
260273
|
+
}
|
|
260274
|
+
} catch (error5) {
|
|
260275
|
+
debugWarn("Cron", "Error reading task for dequeued cron prompt:", error5);
|
|
260276
|
+
}
|
|
260277
|
+
}
|
|
260163
260278
|
const clientMessageIds = getDequeuedClientMessageIds(runtime, dequeuedBatch);
|
|
260164
260279
|
const queuedTurn = buildQueuedTurnMessage(runtime, dequeuedBatch);
|
|
260165
260280
|
if (!queuedTurn) {
|
|
@@ -260318,7 +260433,8 @@ function scheduleQueuePump(runtime, socket, opts, processQueuedTurn) {
|
|
|
260318
260433
|
}
|
|
260319
260434
|
var init_queue = __esm(async () => {
|
|
260320
260435
|
init_mcp_originator_tokens();
|
|
260321
|
-
|
|
260436
|
+
init_cron_file();
|
|
260437
|
+
init_run_log();
|
|
260322
260438
|
init_error_reporting();
|
|
260323
260439
|
init_debug();
|
|
260324
260440
|
init_transport();
|
|
@@ -261076,6 +261192,11 @@ function taskMatchesCronSchedulerScope(task2, scope) {
|
|
|
261076
261192
|
return true;
|
|
261077
261193
|
return scope === "local" ? isLocalAgentId(task2.agent_id) : !isLocalAgentId(task2.agent_id);
|
|
261078
261194
|
}
|
|
261195
|
+
function clearSlowLeaseRetry() {
|
|
261196
|
+
if (slowLeaseRetryTimer)
|
|
261197
|
+
clearInterval(slowLeaseRetryTimer);
|
|
261198
|
+
slowLeaseRetryTimer = null;
|
|
261199
|
+
}
|
|
261079
261200
|
function logScheduler(opts, message2) {
|
|
261080
261201
|
if (opts.onLog) {
|
|
261081
261202
|
opts.onLog(`[Cron] ${message2}`);
|
|
@@ -261466,16 +261587,31 @@ function startScheduler(socket, opts, processQueuedTurn, _retryCount = 0) {
|
|
|
261466
261587
|
try {
|
|
261467
261588
|
token2 = claimSchedulerLease(scope);
|
|
261468
261589
|
} catch (err) {
|
|
261590
|
+
if (slowLeaseRetryTimer)
|
|
261591
|
+
return;
|
|
261469
261592
|
if (_retryCount < MAX_LEASE_RETRIES) {
|
|
261470
261593
|
logScheduler(opts, `Could not claim scheduler lease (attempt ${_retryCount + 1}/${MAX_LEASE_RETRIES + 1}): ${err instanceof Error ? err.message : err}`);
|
|
261471
261594
|
logScheduler(opts, "Cron tasks will not fire until the scheduler starts. Retrying...");
|
|
261472
261595
|
setTimeout(() => startScheduler(socket, opts, processQueuedTurn, _retryCount + 1), LEASE_RETRY_MS);
|
|
261473
261596
|
} else {
|
|
261474
261597
|
logScheduler(opts, `Failed to claim scheduler lease after ${MAX_LEASE_RETRIES + 1} attempts. Cron tasks will not fire.`);
|
|
261475
|
-
logScheduler(opts,
|
|
261598
|
+
logScheduler(opts, `Another process may hold the lease. Retrying every ${SLOW_LEASE_RETRY_MS / 60000} minutes.`);
|
|
261599
|
+
slowLeaseRetryTimer = setInterval(() => {
|
|
261600
|
+
const ctx = listenerFireContext;
|
|
261601
|
+
if (!ctx || schedulerState) {
|
|
261602
|
+
clearSlowLeaseRetry();
|
|
261603
|
+
return;
|
|
261604
|
+
}
|
|
261605
|
+
startScheduler(ctx.socket, ctx.opts, ctx.processQueuedTurn, _retryCount);
|
|
261606
|
+
}, SLOW_LEASE_RETRY_MS);
|
|
261607
|
+
slowLeaseRetryTimer.unref?.();
|
|
261476
261608
|
}
|
|
261477
261609
|
return;
|
|
261478
261610
|
}
|
|
261611
|
+
if (slowLeaseRetryTimer) {
|
|
261612
|
+
clearSlowLeaseRetry();
|
|
261613
|
+
logScheduler(opts, "Claimed scheduler lease on slow retry.");
|
|
261614
|
+
}
|
|
261479
261615
|
const now2 = new Date;
|
|
261480
261616
|
const state2 = {
|
|
261481
261617
|
token: token2,
|
|
@@ -261523,6 +261659,7 @@ function startScheduler(socket, opts, processQueuedTurn, _retryCount = 0) {
|
|
|
261523
261659
|
}
|
|
261524
261660
|
function stopScheduler() {
|
|
261525
261661
|
listenerFireContext = null;
|
|
261662
|
+
clearSlowLeaseRetry();
|
|
261526
261663
|
if (!schedulerState)
|
|
261527
261664
|
return;
|
|
261528
261665
|
clearInterval(schedulerState.tickInterval);
|
|
@@ -261536,7 +261673,7 @@ function stopScheduler() {
|
|
|
261536
261673
|
} catch {}
|
|
261537
261674
|
schedulerState = null;
|
|
261538
261675
|
}
|
|
261539
|
-
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";
|
|
261676
|
+
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";
|
|
261540
261677
|
var init_scheduler = __esm(async () => {
|
|
261541
261678
|
init_backend2();
|
|
261542
261679
|
init_debug();
|
|
@@ -261554,6 +261691,7 @@ var init_scheduler = __esm(async () => {
|
|
|
261554
261691
|
init_runtime6()
|
|
261555
261692
|
]);
|
|
261556
261693
|
GC_INTERVAL_MS = 60 * 60000;
|
|
261694
|
+
SLOW_LEASE_RETRY_MS = 5 * 60000;
|
|
261557
261695
|
});
|
|
261558
261696
|
|
|
261559
261697
|
// src/cron/index.ts
|
|
@@ -261656,8 +261794,9 @@ Add options:
|
|
|
261656
261794
|
conversation; "default" for the agent default)
|
|
261657
261795
|
--computer <id> (managed Cloud sandbox only) Run on a connected
|
|
261658
261796
|
external computer (deviceId from \`letta computers
|
|
261659
|
-
list\`).
|
|
261660
|
-
|
|
261797
|
+
list\`). If that computer is offline at fire
|
|
261798
|
+
time, that run fails (no Cloud sandbox fallback);
|
|
261799
|
+
omit --computer to run in the Cloud sandbox.
|
|
261661
261800
|
|
|
261662
261801
|
List/filter options:
|
|
261663
261802
|
--agent <id> Filter by agent ID
|
|
@@ -261882,7 +262021,7 @@ async function handleCloudAdd(params) {
|
|
|
261882
262021
|
output.notes = notes;
|
|
261883
262022
|
}
|
|
261884
262023
|
console.log(JSON.stringify(output, null, 2));
|
|
261885
|
-
console.error(targetDeviceId ? `Created Cloud schedule: it fires from the cloud and runs on computer "${targetDeviceId}" (
|
|
262024
|
+
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).");
|
|
261886
262025
|
return 0;
|
|
261887
262026
|
} catch (err) {
|
|
261888
262027
|
console.error(`Error: failed to create Cloud schedule: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -264250,6 +264389,11 @@ var init_listen_first_run_welcome = __esm(async () => {
|
|
|
264250
264389
|
await init_AnimatedLogo();
|
|
264251
264390
|
});
|
|
264252
264391
|
|
|
264392
|
+
// src/cli/subcommands/listen-output-mode.ts
|
|
264393
|
+
function shouldUseNonInteractiveListenerOutput(debugMode, lifecycleOutput, stdoutIsTTY = process.stdout.isTTY) {
|
|
264394
|
+
return debugMode || lifecycleOutput || !stdoutIsTTY;
|
|
264395
|
+
}
|
|
264396
|
+
|
|
264253
264397
|
// src/cli/subcommands/listen-process-anchor.ts
|
|
264254
264398
|
import { MessageChannel as MessageChannel2 } from "node:worker_threads";
|
|
264255
264399
|
function createMessageChannelProcessAnchor() {
|
|
@@ -264307,7 +264451,7 @@ function printListenUsage() {
|
|
|
264307
264451
|
}
|
|
264308
264452
|
|
|
264309
264453
|
// src/cli/subcommands/listener-readiness.ts
|
|
264310
|
-
async function completeListenerConnectionStartup(expectedConnection, readiness, startGateway = async () => {}) {
|
|
264454
|
+
async function completeListenerConnectionStartup(expectedConnection, readiness, startGateway = async () => {}, onGatewayError = console.error) {
|
|
264311
264455
|
const { getActiveRuntime: getActiveRuntime2 } = await init_runtime6().then(() => exports_runtime);
|
|
264312
264456
|
const runtime = getActiveRuntime2();
|
|
264313
264457
|
const connection = runtime?.connections.get(expectedConnection.id);
|
|
@@ -264317,12 +264461,12 @@ async function completeListenerConnectionStartup(expectedConnection, readiness,
|
|
|
264317
264461
|
const { isListenerTransportOpen: isListenerTransportOpen2 } = await Promise.resolve().then(() => (init_transport(), exports_transport));
|
|
264318
264462
|
if (!isListenerTransportOpen2(connection.writer))
|
|
264319
264463
|
return false;
|
|
264320
|
-
await startGateway();
|
|
264321
264464
|
if (getActiveRuntime2()?.connections.get(connection.id) !== connection)
|
|
264322
264465
|
return false;
|
|
264323
264466
|
if (!connection.initialized || !connection.ingressReady || connection.cancellation.signal.aborted || !isListenerTransportOpen2(connection.writer))
|
|
264324
264467
|
return false;
|
|
264325
264468
|
readiness.completeCloudStartup(epoch);
|
|
264469
|
+
Promise.resolve().then(startGateway).catch(onGatewayError);
|
|
264326
264470
|
return true;
|
|
264327
264471
|
}
|
|
264328
264472
|
function applyGatewayLifecycleReadiness(readiness, event) {
|
|
@@ -264475,7 +264619,7 @@ var init_service_protocol = __esm(() => {
|
|
|
264475
264619
|
// src/websocket/listen-log.ts
|
|
264476
264620
|
import {
|
|
264477
264621
|
appendFileSync as appendFileSync8,
|
|
264478
|
-
existsSync as
|
|
264622
|
+
existsSync as existsSync51,
|
|
264479
264623
|
mkdirSync as mkdirSync39,
|
|
264480
264624
|
readdirSync as readdirSync20,
|
|
264481
264625
|
unlinkSync as unlinkSync12
|
|
@@ -264495,7 +264639,7 @@ function formatFileTimestamp(now2) {
|
|
|
264495
264639
|
}
|
|
264496
264640
|
function pruneOldLogs(dir, maxFiles) {
|
|
264497
264641
|
try {
|
|
264498
|
-
if (!
|
|
264642
|
+
if (!existsSync51(dir))
|
|
264499
264643
|
return;
|
|
264500
264644
|
const files = readdirSync20(dir).filter((f4) => f4.endsWith(".log")).sort();
|
|
264501
264645
|
if (files.length >= maxFiles) {
|
|
@@ -264547,7 +264691,7 @@ class RemoteSessionLog {
|
|
|
264547
264691
|
const previous = this.path;
|
|
264548
264692
|
this.rotation += 1;
|
|
264549
264693
|
this.path = this.freshPath();
|
|
264550
|
-
while (
|
|
264694
|
+
while (existsSync51(this.path)) {
|
|
264551
264695
|
this.rotation += 1;
|
|
264552
264696
|
this.path = this.freshPath();
|
|
264553
264697
|
}
|
|
@@ -264571,7 +264715,7 @@ class RemoteSessionLog {
|
|
|
264571
264715
|
if (this.dirCreated)
|
|
264572
264716
|
return;
|
|
264573
264717
|
try {
|
|
264574
|
-
if (!
|
|
264718
|
+
if (!existsSync51(this.dir)) {
|
|
264575
264719
|
mkdirSync39(this.dir, { recursive: true });
|
|
264576
264720
|
}
|
|
264577
264721
|
this.dirCreated = true;
|
|
@@ -265180,9 +265324,10 @@ var init_auth3 = __esm(() => {
|
|
|
265180
265324
|
});
|
|
265181
265325
|
|
|
265182
265326
|
// src/websocket/listener/manual-instance-lock.ts
|
|
265327
|
+
import { execFileSync as execFileSync11 } from "node:child_process";
|
|
265183
265328
|
import { createHash as createHash15, randomUUID as randomUUID48 } from "node:crypto";
|
|
265184
265329
|
import { link as link4, mkdir as mkdir13, readFile as readFile21, rm as rm11, unlink as unlink3, writeFile as writeFile15 } from "node:fs/promises";
|
|
265185
|
-
import { homedir as homedir39 } from "node:os";
|
|
265330
|
+
import { homedir as homedir39, uptime as uptime2 } from "node:os";
|
|
265186
265331
|
import path32 from "node:path";
|
|
265187
265332
|
function hasErrorCode3(error5, code2) {
|
|
265188
265333
|
return typeof error5 === "object" && error5 !== null && "code" in error5 && error5.code === code2;
|
|
@@ -265195,6 +265340,32 @@ function defaultIsProcessAlive2(pid) {
|
|
|
265195
265340
|
return !hasErrorCode3(error5, "ESRCH");
|
|
265196
265341
|
}
|
|
265197
265342
|
}
|
|
265343
|
+
function getDefaultBootTimeMs() {
|
|
265344
|
+
return Date.now() - uptime2() * 1000;
|
|
265345
|
+
}
|
|
265346
|
+
function defaultGetProcessCommand(pid) {
|
|
265347
|
+
if (process.platform === "win32")
|
|
265348
|
+
return null;
|
|
265349
|
+
try {
|
|
265350
|
+
return execFileSync11("ps", ["-p", String(pid), "-o", "command="], {
|
|
265351
|
+
encoding: "utf-8",
|
|
265352
|
+
timeout: 1000,
|
|
265353
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
265354
|
+
}).trim();
|
|
265355
|
+
} catch {
|
|
265356
|
+
return null;
|
|
265357
|
+
}
|
|
265358
|
+
}
|
|
265359
|
+
function isOwnerAlive2(record6, deps) {
|
|
265360
|
+
if (!deps.isProcessAlive(record6.pid))
|
|
265361
|
+
return false;
|
|
265362
|
+
const acquiredAtMs = Date.parse(record6.acquiredAt);
|
|
265363
|
+
if (!Number.isFinite(acquiredAtMs) || acquiredAtMs >= deps.bootTimeMs - BOOT_TIME_SLACK_MS2) {
|
|
265364
|
+
return true;
|
|
265365
|
+
}
|
|
265366
|
+
const command = deps.getProcessCommand(record6.pid);
|
|
265367
|
+
return !command || /letta/i.test(command);
|
|
265368
|
+
}
|
|
265198
265369
|
function getDefaultLockRoot() {
|
|
265199
265370
|
return path32.join(process.env.HOME || homedir39(), ".letta");
|
|
265200
265371
|
}
|
|
@@ -265279,7 +265450,7 @@ async function recoverDeadOwner(lockPath, staleContents, recoveryOwnerContents,
|
|
|
265279
265450
|
if (!claimOwner) {
|
|
265280
265451
|
throw new ManualListenerLockUnavailableError(`Listener lock recovery record is invalid: ${claimPath}`, lockPath);
|
|
265281
265452
|
}
|
|
265282
|
-
if (
|
|
265453
|
+
if (isOwnerAlive2(claimOwner, deps)) {
|
|
265283
265454
|
return false;
|
|
265284
265455
|
}
|
|
265285
265456
|
}
|
|
@@ -265310,6 +265481,8 @@ async function acquireManualListenerLock(scope, overrides = {}) {
|
|
|
265310
265481
|
processId: process.pid,
|
|
265311
265482
|
ownerToken: randomUUID48(),
|
|
265312
265483
|
isProcessAlive: defaultIsProcessAlive2,
|
|
265484
|
+
bootTimeMs: getDefaultBootTimeMs(),
|
|
265485
|
+
getProcessCommand: defaultGetProcessCommand,
|
|
265313
265486
|
...overrides
|
|
265314
265487
|
};
|
|
265315
265488
|
const listenerLockDir = path32.join(deps.lockRoot, "listeners");
|
|
@@ -265369,7 +265542,7 @@ async function acquireManualListenerLock(scope, overrides = {}) {
|
|
|
265369
265542
|
if (!incumbent) {
|
|
265370
265543
|
throw new ManualListenerLockUnavailableError(`Listener lock is corrupt or belongs to an incompatible version: ${lockPath}`, lockPath);
|
|
265371
265544
|
}
|
|
265372
|
-
if (
|
|
265545
|
+
if (isOwnerAlive2(incumbent, deps)) {
|
|
265373
265546
|
throw new ManualListenerAlreadyRunningError(incumbent.pid, lockPath);
|
|
265374
265547
|
}
|
|
265375
265548
|
const recovered = await recoverDeadOwner(lockPath, incumbentContents, ownerContents, scopeHash, deps);
|
|
@@ -265378,7 +265551,7 @@ async function acquireManualListenerLock(scope, overrides = {}) {
|
|
|
265378
265551
|
}
|
|
265379
265552
|
}
|
|
265380
265553
|
}
|
|
265381
|
-
var RECOVERY_MAX_DEPTH2 = 64, ManualListenerAlreadyRunningError, ManualListenerLockUnavailableError;
|
|
265554
|
+
var RECOVERY_MAX_DEPTH2 = 64, BOOT_TIME_SLACK_MS2 = 60000, ManualListenerAlreadyRunningError, ManualListenerLockUnavailableError;
|
|
265382
265555
|
var init_manual_instance_lock = __esm(() => {
|
|
265383
265556
|
ManualListenerAlreadyRunningError = class ManualListenerAlreadyRunningError extends Error {
|
|
265384
265557
|
holderPid;
|
|
@@ -267610,10 +267783,10 @@ async function handleListMemoryCommand(parsed, socket, safeSocketSend, overrides
|
|
|
267610
267783
|
const isMemfsEnabledOnServer2 = overrides.isMemfsEnabledOnServer ?? actualIsMemfsEnabledOnServer;
|
|
267611
267784
|
const { scanMemoryFilesystem: scanMemoryFilesystem2, getFileNodes: getFileNodes2, readFileContent: readFileContent2 } = await Promise.resolve().then(() => (init_memory_scanner(), exports_memory_scanner));
|
|
267612
267785
|
const { parseFrontmatter: parseFrontmatter2 } = await Promise.resolve().then(() => exports_frontmatter);
|
|
267613
|
-
const { existsSync:
|
|
267614
|
-
const { join: join78, posix:
|
|
267786
|
+
const { existsSync: existsSync52, statSync: statSync22 } = await import("node:fs");
|
|
267787
|
+
const { join: join78, posix: posix4 } = await import("node:path");
|
|
267615
267788
|
const memoryRoot = getMemoryFilesystemRoot2(parsed.agent_id);
|
|
267616
|
-
let memfsInitialized =
|
|
267789
|
+
let memfsInitialized = existsSync52(join78(memoryRoot, ".git"));
|
|
267617
267790
|
const memfsEnabled = memfsInitialized ? true : await isMemfsEnabledOnServer2(parsed.agent_id);
|
|
267618
267791
|
if (!memfsEnabled) {
|
|
267619
267792
|
safeSocketSend(socket, {
|
|
@@ -267631,7 +267804,7 @@ async function handleListMemoryCommand(parsed, socket, safeSocketSend, overrides
|
|
|
267631
267804
|
await ensureLocalMemfsCheckout2(parsed.agent_id, {
|
|
267632
267805
|
pullOnExistingRepo: true
|
|
267633
267806
|
});
|
|
267634
|
-
memfsInitialized =
|
|
267807
|
+
memfsInitialized = existsSync52(join78(memoryRoot, ".git"));
|
|
267635
267808
|
if (!memfsInitialized) {
|
|
267636
267809
|
throw new Error("MemFS is enabled, but the local memory checkout could not be initialized.");
|
|
267637
267810
|
}
|
|
@@ -267660,8 +267833,8 @@ async function handleListMemoryCommand(parsed, socket, safeSocketSend, overrides
|
|
|
267660
267833
|
if (!target2) {
|
|
267661
267834
|
return null;
|
|
267662
267835
|
}
|
|
267663
|
-
const sourceDir =
|
|
267664
|
-
const candidate = target2.startsWith("./") || target2.startsWith("../") ?
|
|
267836
|
+
const sourceDir = posix4.dirname(sourcePath.replace(/\\/g, "/"));
|
|
267837
|
+
const candidate = target2.startsWith("./") || target2.startsWith("../") ? posix4.normalize(posix4.join(sourceDir, target2)) : posix4.normalize(target2.startsWith("/") ? target2.slice(1) : target2);
|
|
267665
267838
|
if (!candidate || candidate.startsWith("../") || candidate === "." || candidate === "..") {
|
|
267666
267839
|
return null;
|
|
267667
267840
|
}
|
|
@@ -267669,10 +267842,10 @@ async function handleListMemoryCommand(parsed, socket, safeSocketSend, overrides
|
|
|
267669
267842
|
const candidates2 = new Set([withExtension]);
|
|
267670
267843
|
const isExplicitRelative = target2.startsWith("./") || target2.startsWith("../");
|
|
267671
267844
|
if (!isExplicitRelative && !target2.startsWith("/") && sourceDir && sourceDir !== ".") {
|
|
267672
|
-
candidates2.add(
|
|
267845
|
+
candidates2.add(posix4.normalize(posix4.join(sourceDir, withExtension)));
|
|
267673
267846
|
}
|
|
267674
267847
|
if (!withExtension.startsWith("system/")) {
|
|
267675
|
-
candidates2.add(
|
|
267848
|
+
candidates2.add(posix4.normalize(`system/${withExtension}`));
|
|
267676
267849
|
}
|
|
267677
267850
|
for (const resolved2 of candidates2) {
|
|
267678
267851
|
if (allPaths.has(resolved2)) {
|
|
@@ -267931,7 +268104,7 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
267931
268104
|
isMemfsEnabledOnServer: isMemfsEnabledOnServer2
|
|
267932
268105
|
} = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
267933
268106
|
const { readFile: readFile22 } = await import("node:fs/promises");
|
|
267934
|
-
const { existsSync:
|
|
268107
|
+
const { existsSync: existsSync52 } = await import("node:fs");
|
|
267935
268108
|
const { isAbsolute: isAbsolute25, join: join78, normalize: normalize4, relative: relative8, sep: sep8 } = await import("node:path");
|
|
267936
268109
|
if (isAbsolute25(parsed.path) || parsed.path.length === 0) {
|
|
267937
268110
|
sendFailure("path must be a non-empty relative path");
|
|
@@ -267944,14 +268117,14 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
267944
268117
|
sendFailure("path must resolve inside the memory root");
|
|
267945
268118
|
return;
|
|
267946
268119
|
}
|
|
267947
|
-
if (!
|
|
268120
|
+
if (!existsSync52(join78(memoryRoot, ".git"))) {
|
|
267948
268121
|
const enabled = await isMemfsEnabledOnServer2(parsed.agent_id);
|
|
267949
268122
|
if (!enabled) {
|
|
267950
268123
|
sendFailure("memfs is not enabled for this agent");
|
|
267951
268124
|
return;
|
|
267952
268125
|
}
|
|
267953
268126
|
await ensureLocalMemfsCheckout2(parsed.agent_id);
|
|
267954
|
-
if (!
|
|
268127
|
+
if (!existsSync52(join78(memoryRoot, ".git"))) {
|
|
267955
268128
|
sendFailure("failed to initialize local memory checkout");
|
|
267956
268129
|
return;
|
|
267957
268130
|
}
|
|
@@ -267997,7 +268170,7 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
267997
268170
|
} = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
267998
268171
|
const { commitMemoryWrite: commitMemoryWrite2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
|
|
267999
268172
|
const { writeFile: writeFile16, mkdir: mkdir14 } = await import("node:fs/promises");
|
|
268000
|
-
const { existsSync:
|
|
268173
|
+
const { existsSync: existsSync52 } = await import("node:fs");
|
|
268001
268174
|
const { dirname: dirname34, isAbsolute: isAbsolute25, join: join78, normalize: normalize4, relative: relative8, sep: sep8 } = await import("node:path");
|
|
268002
268175
|
if (isAbsolute25(parsed.path) || parsed.path.length === 0) {
|
|
268003
268176
|
sendFailure("write_memory_file: path must be a non-empty relative path");
|
|
@@ -268010,14 +268183,14 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
268010
268183
|
sendFailure("write_memory_file: path must resolve inside the memory root");
|
|
268011
268184
|
return;
|
|
268012
268185
|
}
|
|
268013
|
-
if (!
|
|
268186
|
+
if (!existsSync52(join78(memoryRoot, ".git"))) {
|
|
268014
268187
|
const enabled = await isMemfsEnabledOnServer2(parsed.agent_id);
|
|
268015
268188
|
if (!enabled) {
|
|
268016
268189
|
sendFailure("write_memory_file: memfs is not enabled for this agent");
|
|
268017
268190
|
return;
|
|
268018
268191
|
}
|
|
268019
268192
|
await ensureLocalMemfsCheckout2(parsed.agent_id);
|
|
268020
|
-
if (!
|
|
268193
|
+
if (!existsSync52(join78(memoryRoot, ".git"))) {
|
|
268021
268194
|
sendFailure("write_memory_file: failed to initialize local memory checkout");
|
|
268022
268195
|
return;
|
|
268023
268196
|
}
|
|
@@ -268095,7 +268268,7 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
268095
268268
|
} = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
268096
268269
|
const { commitMemoryWrite: commitMemoryWrite2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
|
|
268097
268270
|
const { unlink: unlink4 } = await import("node:fs/promises");
|
|
268098
|
-
const { existsSync:
|
|
268271
|
+
const { existsSync: existsSync52 } = await import("node:fs");
|
|
268099
268272
|
const { isAbsolute: isAbsolute25, join: join78, normalize: normalize4, relative: relative8, sep: sep8 } = await import("node:path");
|
|
268100
268273
|
if (isAbsolute25(parsed.path) || parsed.path.length === 0) {
|
|
268101
268274
|
sendFailure("delete_memory_file: path must be a non-empty relative path");
|
|
@@ -268108,21 +268281,21 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
268108
268281
|
sendFailure("delete_memory_file: path must resolve inside the memory root");
|
|
268109
268282
|
return;
|
|
268110
268283
|
}
|
|
268111
|
-
if (!
|
|
268284
|
+
if (!existsSync52(join78(memoryRoot, ".git"))) {
|
|
268112
268285
|
const enabled = await isMemfsEnabledOnServer2(parsed.agent_id);
|
|
268113
268286
|
if (!enabled) {
|
|
268114
268287
|
sendFailure("delete_memory_file: memfs is not enabled for this agent");
|
|
268115
268288
|
return;
|
|
268116
268289
|
}
|
|
268117
268290
|
await ensureLocalMemfsCheckout2(parsed.agent_id);
|
|
268118
|
-
if (!
|
|
268291
|
+
if (!existsSync52(join78(memoryRoot, ".git"))) {
|
|
268119
268292
|
sendFailure("delete_memory_file: failed to initialize local memory checkout");
|
|
268120
268293
|
return;
|
|
268121
268294
|
}
|
|
268122
268295
|
}
|
|
268123
268296
|
const pathspec = rel.split(sep8).join("/");
|
|
268124
268297
|
const removeIfPresent = async () => {
|
|
268125
|
-
if (!
|
|
268298
|
+
if (!existsSync52(absolutePath))
|
|
268126
268299
|
return false;
|
|
268127
268300
|
await unlink4(absolutePath);
|
|
268128
268301
|
return true;
|
|
@@ -268317,7 +268490,7 @@ __export(exports_remote_model_catalog, {
|
|
|
268317
268490
|
applyCatalogModels: () => applyCatalogModels,
|
|
268318
268491
|
__testResetRemoteModelCatalog: () => __testResetRemoteModelCatalog
|
|
268319
268492
|
});
|
|
268320
|
-
import { existsSync as
|
|
268493
|
+
import { existsSync as existsSync52, mkdirSync as mkdirSync40, readFileSync as readFileSync44, writeFileSync as writeFileSync34 } from "node:fs";
|
|
268321
268494
|
import { homedir as homedir40 } from "node:os";
|
|
268322
268495
|
import { dirname as dirname34, join as join78 } from "node:path";
|
|
268323
268496
|
function catalogCachePath() {
|
|
@@ -268421,7 +268594,7 @@ function persistCatalogCache(entries2, source) {
|
|
|
268421
268594
|
function loadPersistedModelCatalog(source) {
|
|
268422
268595
|
try {
|
|
268423
268596
|
const path33 = catalogCachePath();
|
|
268424
|
-
if (!
|
|
268597
|
+
if (!existsSync52(path33)) {
|
|
268425
268598
|
return false;
|
|
268426
268599
|
}
|
|
268427
268600
|
const parsed = JSON.parse(readFileSync44(path33, "utf-8"));
|
|
@@ -269114,7 +269287,7 @@ function recordStaleHandleUse(collector, owner, capability, onDiagnostic) {
|
|
|
269114
269287
|
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().";
|
|
269115
269288
|
|
|
269116
269289
|
// src/mods/paths.ts
|
|
269117
|
-
import { existsSync as
|
|
269290
|
+
import { existsSync as existsSync53 } from "node:fs";
|
|
269118
269291
|
import { homedir as homedir41 } from "node:os";
|
|
269119
269292
|
import path33 from "node:path";
|
|
269120
269293
|
function getGlobalModsDirectory(homeDirectory = homedir41()) {
|
|
@@ -269128,10 +269301,10 @@ function resolveDefaultGlobalModsDirectory(homeDirectory = homedir41(), env6 = p
|
|
|
269128
269301
|
if (environmentDirectory)
|
|
269129
269302
|
return environmentDirectory;
|
|
269130
269303
|
const modsDirectory = getGlobalModsDirectory(homeDirectory);
|
|
269131
|
-
if (
|
|
269304
|
+
if (existsSync53(modsDirectory))
|
|
269132
269305
|
return modsDirectory;
|
|
269133
269306
|
const legacyDirectory = getLegacyGlobalExtensionsDirectory(homeDirectory);
|
|
269134
|
-
if (
|
|
269307
|
+
if (existsSync53(legacyDirectory))
|
|
269135
269308
|
return legacyDirectory;
|
|
269136
269309
|
return modsDirectory;
|
|
269137
269310
|
}
|
|
@@ -377138,10 +377311,10 @@ ${lanes.join(`
|
|
|
377138
377311
|
}
|
|
377139
377312
|
function getDefaultLibFilePriority(a2) {
|
|
377140
377313
|
if (containsPath(defaultLibraryPath, a2.fileName, false)) {
|
|
377141
|
-
const
|
|
377142
|
-
if (
|
|
377314
|
+
const basename22 = getBaseFileName(a2.fileName);
|
|
377315
|
+
if (basename22 === "lib.d.ts" || basename22 === "lib.es6.d.ts")
|
|
377143
377316
|
return 0;
|
|
377144
|
-
const name = removeSuffix(removePrefix(
|
|
377317
|
+
const name = removeSuffix(removePrefix(basename22, "lib."), ".d.ts");
|
|
377145
377318
|
const index = libs.indexOf(name);
|
|
377146
377319
|
if (index !== -1)
|
|
377147
377320
|
return index + 1;
|
|
@@ -429704,8 +429877,8 @@ ${options.prefix}` : `
|
|
|
429704
429877
|
}
|
|
429705
429878
|
};
|
|
429706
429879
|
for (const file of files) {
|
|
429707
|
-
const
|
|
429708
|
-
if (
|
|
429880
|
+
const basename22 = getBaseFileName(file);
|
|
429881
|
+
if (basename22 === "package.json" || basename22 === "bower.json") {
|
|
429709
429882
|
createProjectWatcher(file, "FileWatcher");
|
|
429710
429883
|
continue;
|
|
429711
429884
|
}
|
|
@@ -432582,8 +432755,8 @@ All files are: ${JSON.stringify(names2)}`, "Err");
|
|
|
432582
432755
|
const fileOrDirectoryPath = removeIgnoredPath(this.toPath(fileOrDirectory));
|
|
432583
432756
|
if (!fileOrDirectoryPath)
|
|
432584
432757
|
return;
|
|
432585
|
-
const
|
|
432586
|
-
if (((_a10 = result3.affectedModuleSpecifierCacheProjects) == null ? undefined : _a10.size) && (
|
|
432758
|
+
const basename22 = getBaseFileName(fileOrDirectoryPath);
|
|
432759
|
+
if (((_a10 = result3.affectedModuleSpecifierCacheProjects) == null ? undefined : _a10.size) && (basename22 === "package.json" || basename22 === "node_modules")) {
|
|
432587
432760
|
result3.affectedModuleSpecifierCacheProjects.forEach((project) => {
|
|
432588
432761
|
var _a22;
|
|
432589
432762
|
(_a22 = project.getModuleSpecifierCache()) == null || _a22.clear();
|
|
@@ -438189,7 +438362,7 @@ var init_package_manifest = __esm(() => {
|
|
|
438189
438362
|
|
|
438190
438363
|
// src/mods/package-registry.ts
|
|
438191
438364
|
import {
|
|
438192
|
-
existsSync as
|
|
438365
|
+
existsSync as existsSync54,
|
|
438193
438366
|
mkdirSync as mkdirSync42,
|
|
438194
438367
|
readFileSync as readFileSync46,
|
|
438195
438368
|
rmSync as rmSync21,
|
|
@@ -438261,7 +438434,7 @@ function getRegistryPath(modsRoot) {
|
|
|
438261
438434
|
}
|
|
438262
438435
|
function readRegistryObject(modsRoot) {
|
|
438263
438436
|
const registryPath = getRegistryPath(modsRoot);
|
|
438264
|
-
if (!
|
|
438437
|
+
if (!existsSync54(registryPath)) {
|
|
438265
438438
|
return { diagnostics: [], ok: false, registryExists: false, registryPath };
|
|
438266
438439
|
}
|
|
438267
438440
|
const registryResult = parseJsonFile(registryPath);
|
|
@@ -438693,7 +438866,7 @@ function writePackageRegistry(registryPath, registry4) {
|
|
|
438693
438866
|
}
|
|
438694
438867
|
function validateManagedModPackageRegistryForMutation(modsRoot) {
|
|
438695
438868
|
const registryPath = getRegistryPath(modsRoot);
|
|
438696
|
-
const contents =
|
|
438869
|
+
const contents = existsSync54(registryPath) ? readFileSync46(registryPath, "utf8") : null;
|
|
438697
438870
|
const registry4 = readMutablePackageRegistry(modsRoot, {
|
|
438698
438871
|
createIfMissing: true
|
|
438699
438872
|
});
|
|
@@ -438816,10 +438989,10 @@ var init_package_registry = __esm(() => {
|
|
|
438816
438989
|
});
|
|
438817
438990
|
|
|
438818
438991
|
// src/mods/mod-sources.ts
|
|
438819
|
-
import { existsSync as
|
|
438992
|
+
import { existsSync as existsSync55, readdirSync as readdirSync22 } from "node:fs";
|
|
438820
438993
|
import path37 from "node:path";
|
|
438821
438994
|
function listModFiles(directory) {
|
|
438822
|
-
if (!
|
|
438995
|
+
if (!existsSync55(directory))
|
|
438823
438996
|
return [];
|
|
438824
438997
|
return readdirSync22(directory, { withFileTypes: true }).filter((entry) => {
|
|
438825
438998
|
if (!entry.isFile())
|
|
@@ -438835,7 +439008,7 @@ function resolveLocalModSources(options = {}) {
|
|
|
438835
439008
|
const includeGlobalMods = options.includeGlobalMods !== false;
|
|
438836
439009
|
const managedPackages = includeGlobalMods ? resolveManagedModPackages(globalModsDirectory) : { diagnostics: [], files: [], packages: [] };
|
|
438837
439010
|
const sources = [];
|
|
438838
|
-
if (includeGlobalMods && legacyGlobalExtensionsDirectory && path37.resolve(legacyGlobalExtensionsDirectory) !== path37.resolve(globalModsDirectory) &&
|
|
439011
|
+
if (includeGlobalMods && legacyGlobalExtensionsDirectory && path37.resolve(legacyGlobalExtensionsDirectory) !== path37.resolve(globalModsDirectory) && existsSync55(legacyGlobalExtensionsDirectory)) {
|
|
438839
439012
|
sources.push({
|
|
438840
439013
|
files: listModFiles(legacyGlobalExtensionsDirectory),
|
|
438841
439014
|
legacyMigrationTargetRoot: globalModsDirectory,
|
|
@@ -438874,7 +439047,7 @@ var init_mod_sources = __esm(() => {
|
|
|
438874
439047
|
|
|
438875
439048
|
// src/mods/runtime-dependencies.ts
|
|
438876
439049
|
import {
|
|
438877
|
-
lstatSync as
|
|
439050
|
+
lstatSync as lstatSync3,
|
|
438878
439051
|
mkdirSync as mkdirSync43,
|
|
438879
439052
|
readlinkSync,
|
|
438880
439053
|
symlinkSync,
|
|
@@ -438895,7 +439068,7 @@ function ensureRuntimeDependencySymlink(cacheDirectory, packageName, resolveRunt
|
|
|
438895
439068
|
const packageDirectory = path38.resolve(resolveRuntimePackageDirectory(packageName));
|
|
438896
439069
|
mkdirSync43(nodeModulesDirectory, { recursive: true });
|
|
438897
439070
|
try {
|
|
438898
|
-
const stats =
|
|
439071
|
+
const stats = lstatSync3(linkPath);
|
|
438899
439072
|
if (!stats.isSymbolicLink())
|
|
438900
439073
|
return;
|
|
438901
439074
|
const existingTarget = readlinkSync(linkPath);
|
|
@@ -439014,7 +439187,7 @@ function createNoopModPanelHandle() {
|
|
|
439014
439187
|
// src/mods/mod-engine.ts
|
|
439015
439188
|
import { createHash as createHash16 } from "node:crypto";
|
|
439016
439189
|
import {
|
|
439017
|
-
existsSync as
|
|
439190
|
+
existsSync as existsSync56,
|
|
439018
439191
|
mkdirSync as mkdirSync44,
|
|
439019
439192
|
readdirSync as readdirSync23,
|
|
439020
439193
|
readFileSync as readFileSync47,
|
|
@@ -439204,7 +439377,7 @@ function createImportableModPath(modPath, cacheDirectory, source) {
|
|
|
439204
439377
|
}
|
|
439205
439378
|
const baseName = path39.basename(modPath, fileExtension).replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
439206
439379
|
const importPath = path39.join(importCacheDirectory, `.letta-mod-${baseName}-${hash3}.mjs`);
|
|
439207
|
-
if (!
|
|
439380
|
+
if (!existsSync56(importPath)) {
|
|
439208
439381
|
writeFileSync37(importPath, importableSource, "utf8");
|
|
439209
439382
|
}
|
|
439210
439383
|
try {
|
|
@@ -442627,19 +442800,19 @@ function emitSkillsUpdated(socket, safeSocketSend) {
|
|
|
442627
442800
|
}
|
|
442628
442801
|
async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
442629
442802
|
const {
|
|
442630
|
-
existsSync:
|
|
442631
|
-
lstatSync:
|
|
442803
|
+
existsSync: existsSync57,
|
|
442804
|
+
lstatSync: lstatSync4,
|
|
442632
442805
|
mkdirSync: mkdirSync45,
|
|
442633
442806
|
rmdirSync: rmdirSync2,
|
|
442634
442807
|
symlinkSync: symlinkSync2,
|
|
442635
442808
|
unlinkSync: unlinkSync15
|
|
442636
442809
|
} = await import("node:fs");
|
|
442637
|
-
const { basename:
|
|
442810
|
+
const { basename: basename22, join: join80 } = await import("node:path");
|
|
442638
442811
|
const lettaHome = process.env.LETTA_HOME || join80(process.env.HOME || process.env.USERPROFILE || "~", ".letta");
|
|
442639
442812
|
const globalSkillsDir = join80(lettaHome, "skills");
|
|
442640
442813
|
if (parsed.type === "skill_enable") {
|
|
442641
442814
|
try {
|
|
442642
|
-
if (!
|
|
442815
|
+
if (!existsSync57(parsed.skill_path)) {
|
|
442643
442816
|
safeSocketSend(socket, {
|
|
442644
442817
|
type: "skill_enable_response",
|
|
442645
442818
|
request_id: parsed.request_id,
|
|
@@ -442649,7 +442822,7 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
442649
442822
|
return true;
|
|
442650
442823
|
}
|
|
442651
442824
|
const skillMdPath = join80(parsed.skill_path, "SKILL.md");
|
|
442652
|
-
if (!
|
|
442825
|
+
if (!existsSync57(skillMdPath)) {
|
|
442653
442826
|
safeSocketSend(socket, {
|
|
442654
442827
|
type: "skill_enable_response",
|
|
442655
442828
|
request_id: parsed.request_id,
|
|
@@ -442658,11 +442831,11 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
442658
442831
|
}, "listener_skill_send_failed", "listener_skill_command");
|
|
442659
442832
|
return true;
|
|
442660
442833
|
}
|
|
442661
|
-
const linkName =
|
|
442834
|
+
const linkName = basename22(parsed.skill_path);
|
|
442662
442835
|
const linkPath = join80(globalSkillsDir, linkName);
|
|
442663
442836
|
mkdirSync45(globalSkillsDir, { recursive: true });
|
|
442664
|
-
if (
|
|
442665
|
-
const stat12 =
|
|
442837
|
+
if (existsSync57(linkPath)) {
|
|
442838
|
+
const stat12 = lstatSync4(linkPath);
|
|
442666
442839
|
if (stat12.isSymbolicLink()) {
|
|
442667
442840
|
if (process.platform === "win32") {
|
|
442668
442841
|
rmdirSync2(linkPath);
|
|
@@ -442703,7 +442876,7 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
442703
442876
|
if (parsed.type === "skill_disable") {
|
|
442704
442877
|
try {
|
|
442705
442878
|
const linkPath = join80(globalSkillsDir, parsed.name);
|
|
442706
|
-
if (!
|
|
442879
|
+
if (!existsSync57(linkPath)) {
|
|
442707
442880
|
safeSocketSend(socket, {
|
|
442708
442881
|
type: "skill_disable_response",
|
|
442709
442882
|
request_id: parsed.request_id,
|
|
@@ -442712,7 +442885,7 @@ async function handleSkillCommand(parsed, socket, safeSocketSend) {
|
|
|
442712
442885
|
}, "listener_skill_send_failed", "listener_skill_command");
|
|
442713
442886
|
return true;
|
|
442714
442887
|
}
|
|
442715
|
-
const stat12 =
|
|
442888
|
+
const stat12 = lstatSync4(linkPath);
|
|
442716
442889
|
if (!stat12.isSymbolicLink()) {
|
|
442717
442890
|
safeSocketSend(socket, {
|
|
442718
442891
|
type: "skill_disable_response",
|
|
@@ -443211,7 +443384,7 @@ function populateInterruptQueue(runtime, input) {
|
|
|
443211
443384
|
type: "approval",
|
|
443212
443385
|
tool_call_id: toolCallId,
|
|
443213
443386
|
approve: false,
|
|
443214
|
-
reason: "User interrupted the stream"
|
|
443387
|
+
reason: input.denialReason ?? "User interrupted the stream"
|
|
443215
443388
|
}));
|
|
443216
443389
|
runtime.pendingInterruptedContext = {
|
|
443217
443390
|
agentId: input.agentId,
|
|
@@ -443623,7 +443796,7 @@ var init_control_inputs = __esm(async () => {
|
|
|
443623
443796
|
});
|
|
443624
443797
|
|
|
443625
443798
|
// src/websocket/terminal-handler.ts
|
|
443626
|
-
import { existsSync as
|
|
443799
|
+
import { existsSync as existsSync57 } from "node:fs";
|
|
443627
443800
|
import * as os7 from "node:os";
|
|
443628
443801
|
import WebSocket7 from "ws";
|
|
443629
443802
|
function getTerminalKey(connectionId, terminalId) {
|
|
@@ -443639,7 +443812,7 @@ function getDefaultShell() {
|
|
|
443639
443812
|
"/bin/bash"
|
|
443640
443813
|
];
|
|
443641
443814
|
for (const candidate of candidates2) {
|
|
443642
|
-
if (candidate &&
|
|
443815
|
+
if (candidate && existsSync57(candidate)) {
|
|
443643
443816
|
return candidate;
|
|
443644
443817
|
}
|
|
443645
443818
|
}
|
|
@@ -444036,6 +444209,24 @@ function revokeRecoveryClaims(listener, connectionId, connectionGeneration) {
|
|
|
444036
444209
|
claim.revoke();
|
|
444037
444210
|
}
|
|
444038
444211
|
}
|
|
444212
|
+
function recoveryRefusals(listener) {
|
|
444213
|
+
const generation4 = listener.connectionGeneration ?? undefined;
|
|
444214
|
+
let state2 = refusalCounts.get(listener);
|
|
444215
|
+
if (!state2 || state2.generation !== generation4) {
|
|
444216
|
+
state2 = { generation: generation4, count: 0, refused: false };
|
|
444217
|
+
refusalCounts.set(listener, state2);
|
|
444218
|
+
}
|
|
444219
|
+
return state2;
|
|
444220
|
+
}
|
|
444221
|
+
function recoveryRetryDelay(listener, base2) {
|
|
444222
|
+
const state2 = recoveryRefusals(listener);
|
|
444223
|
+
if (!state2.refused)
|
|
444224
|
+
return base2;
|
|
444225
|
+
state2.refused = false;
|
|
444226
|
+
if (++state2.count === 5)
|
|
444227
|
+
debugWarn("recovery", "Recovery refused because another connection owns the conversation; abandoned until the next reconnect");
|
|
444228
|
+
return state2.count >= 5 ? Infinity : Math.min(base2 * 2 ** (state2.count - 1), 300000);
|
|
444229
|
+
}
|
|
444039
444230
|
async function acquireRecoveryClaim(runtime, onLost = () => {}, dependencies4 = {}) {
|
|
444040
444231
|
const connectionId = runtime.listener.connectionId;
|
|
444041
444232
|
const connectionGeneration = runtime.listener.connectionGeneration;
|
|
@@ -444076,8 +444267,13 @@ async function acquireRecoveryClaim(runtime, onLost = () => {}, dependencies4 =
|
|
|
444076
444267
|
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);
|
|
444077
444268
|
runtime.listener.activeRecoveryClaims ??= new Set;
|
|
444078
444269
|
runtime.listener.activeRecoveryClaims.add(claim);
|
|
444270
|
+
refusalCounts.delete(runtime.listener);
|
|
444079
444271
|
return claim;
|
|
444080
444272
|
} catch (error5) {
|
|
444273
|
+
if (error5 instanceof ApiRequestError && error5.status === 409 && /"owner_mismatch"/.test(error5.responseText)) {
|
|
444274
|
+
recoveryRefusals(runtime.listener).refused = true;
|
|
444275
|
+
return null;
|
|
444276
|
+
}
|
|
444081
444277
|
debugWarn("recovery", "Recovery claim acquisition failed", error5);
|
|
444082
444278
|
return null;
|
|
444083
444279
|
}
|
|
@@ -444117,12 +444313,13 @@ async function getRecoveryEligibility(runtime, readStatus = getAgentRuntimeStatu
|
|
|
444117
444313
|
async function canRecoverConversation(runtime, readStatus = getAgentRuntimeStatus) {
|
|
444118
444314
|
return await getRecoveryEligibility(runtime, readStatus) === "owned";
|
|
444119
444315
|
}
|
|
444120
|
-
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) });
|
|
444316
|
+
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;
|
|
444121
444317
|
var init_recovery_ownership = __esm(async () => {
|
|
444122
444318
|
init_agents8();
|
|
444123
444319
|
init_request();
|
|
444124
444320
|
init_debug();
|
|
444125
444321
|
await init_teleport();
|
|
444322
|
+
refusalCounts = new WeakMap;
|
|
444126
444323
|
});
|
|
444127
444324
|
|
|
444128
444325
|
// src/agent/approval-recovery.ts
|
|
@@ -445681,7 +445878,7 @@ var init_tui_perf = __esm(() => {
|
|
|
445681
445878
|
|
|
445682
445879
|
// src/cli/helpers/chunk-log.ts
|
|
445683
445880
|
import {
|
|
445684
|
-
existsSync as
|
|
445881
|
+
existsSync as existsSync58,
|
|
445685
445882
|
mkdirSync as mkdirSync46,
|
|
445686
445883
|
readdirSync as readdirSync24,
|
|
445687
445884
|
unlinkSync as unlinkSync15,
|
|
@@ -445782,7 +445979,7 @@ class ChunkLog {
|
|
|
445782
445979
|
if (this.dirCreated || !this.agentDir)
|
|
445783
445980
|
return;
|
|
445784
445981
|
try {
|
|
445785
|
-
if (!
|
|
445982
|
+
if (!existsSync58(this.agentDir)) {
|
|
445786
445983
|
mkdirSync46(this.agentDir, { recursive: true });
|
|
445787
445984
|
}
|
|
445788
445985
|
this.dirCreated = true;
|
|
@@ -445807,7 +446004,7 @@ class ChunkLog {
|
|
|
445807
446004
|
if (!this.agentDir)
|
|
445808
446005
|
return;
|
|
445809
446006
|
try {
|
|
445810
|
-
if (!
|
|
446007
|
+
if (!existsSync58(this.agentDir))
|
|
445811
446008
|
return;
|
|
445812
446009
|
const files = readdirSync24(this.agentDir).filter((f4) => f4.endsWith(".jsonl")).sort();
|
|
445813
446010
|
if (files.length >= MAX_SESSION_FILES2) {
|
|
@@ -447235,6 +447432,7 @@ function finishListenerTurn(runtime, lease, options) {
|
|
|
447235
447432
|
debugWarn("recovery", "Failed to retire completed listener work", error5);
|
|
447236
447433
|
}
|
|
447237
447434
|
}
|
|
447435
|
+
runtime.activeConnectionId = null;
|
|
447238
447436
|
return transition2;
|
|
447239
447437
|
}
|
|
447240
447438
|
var init_turn_terminal = __esm(async () => {
|
|
@@ -449705,7 +449903,7 @@ __export(exports_diff, {
|
|
|
449705
449903
|
ADV_DIFF_IGNORE_WHITESPACE: () => ADV_DIFF_IGNORE_WHITESPACE,
|
|
449706
449904
|
ADV_DIFF_CONTEXT_LINES: () => ADV_DIFF_CONTEXT_LINES
|
|
449707
449905
|
});
|
|
449708
|
-
import { basename as
|
|
449906
|
+
import { basename as basename22 } from "node:path";
|
|
449709
449907
|
function readFileOrNull(p2) {
|
|
449710
449908
|
try {
|
|
449711
449909
|
return __require("node:fs").readFileSync(p2, "utf-8");
|
|
@@ -449729,7 +449927,7 @@ function applyAllOccurrences(content, oldStr, newStr) {
|
|
|
449729
449927
|
return { ok: true, out: content.split(oldStr).join(newStr) };
|
|
449730
449928
|
}
|
|
449731
449929
|
function computeAdvancedDiff(input, opts) {
|
|
449732
|
-
const fileName =
|
|
449930
|
+
const fileName = basename22(input.filePath || "");
|
|
449733
449931
|
const fileContent = opts?.oldStrOverride !== undefined ? opts.oldStrOverride : readFileOrNull(input.filePath);
|
|
449734
449932
|
if (fileContent === null && input.kind !== "write") {
|
|
449735
449933
|
return { mode: "fallback", reason: "File not readable" };
|
|
@@ -449761,7 +449959,7 @@ function computeAdvancedDiff(input, opts) {
|
|
|
449761
449959
|
return { mode: "advanced", fileName, oldStr, newStr, hunks };
|
|
449762
449960
|
}
|
|
449763
449961
|
function parsePatchToAdvancedDiff(patchLines, filePath) {
|
|
449764
|
-
const fileName =
|
|
449962
|
+
const fileName = basename22(filePath);
|
|
449765
449963
|
const hunks = [];
|
|
449766
449964
|
let currentHunk = null;
|
|
449767
449965
|
let oldLine = 1;
|
|
@@ -450039,8 +450237,8 @@ function isFormatterSegment(tokens) {
|
|
|
450039
450237
|
}
|
|
450040
450238
|
}
|
|
450041
450239
|
function isShellExecutor2(token2) {
|
|
450042
|
-
const
|
|
450043
|
-
return ["bash", "sh", "zsh", "dash", "ksh"].includes(
|
|
450240
|
+
const basename23 = token2.split("/").pop() ?? token2;
|
|
450241
|
+
return ["bash", "sh", "zsh", "dash", "ksh"].includes(basename23.toLowerCase());
|
|
450044
450242
|
}
|
|
450045
450243
|
function normalizeRawCommand(command) {
|
|
450046
450244
|
if (Array.isArray(command)) {
|
|
@@ -450827,7 +451025,7 @@ var init_format_args_display = __esm(() => {
|
|
|
450827
451025
|
});
|
|
450828
451026
|
|
|
450829
451027
|
// src/helpers/diff-preview.ts
|
|
450830
|
-
import path41, { basename as
|
|
451028
|
+
import path41, { basename as basename23 } from "node:path";
|
|
450831
451029
|
function parseHunkLinePrefix(raw2) {
|
|
450832
451030
|
if (raw2.length === 0) {
|
|
450833
451031
|
return { type: "context", content: "" };
|
|
@@ -450933,7 +451131,7 @@ async function computeDiffPreviews(toolName2, toolArgs, workingDirectory = getCu
|
|
|
450933
451131
|
filePath: resolvedFilePath,
|
|
450934
451132
|
content: toolArgs.content || ""
|
|
450935
451133
|
});
|
|
450936
|
-
previews.push(toDiffPreview(result3,
|
|
451134
|
+
previews.push(toDiffPreview(result3, basename23(filePath)));
|
|
450937
451135
|
}
|
|
450938
451136
|
} else if (isFileEditTool3(toolName2)) {
|
|
450939
451137
|
const filePath = toolArgs.file_path;
|
|
@@ -450946,7 +451144,7 @@ async function computeDiffPreviews(toolName2, toolArgs, workingDirectory = getCu
|
|
|
450946
451144
|
newString: toolArgs.new_string || "",
|
|
450947
451145
|
replaceAll: toolArgs.replace_all
|
|
450948
451146
|
});
|
|
450949
|
-
previews.push(toDiffPreview(result3,
|
|
451147
|
+
previews.push(toDiffPreview(result3, basename23(filePath)));
|
|
450950
451148
|
}
|
|
450951
451149
|
} else if (isPatchTool2(toolName2) && toolArgs.input) {
|
|
450952
451150
|
const operations2 = parsePatchOperations2(toolArgs.input);
|
|
@@ -450954,7 +451152,7 @@ async function computeDiffPreviews(toolName2, toolArgs, workingDirectory = getCu
|
|
|
450954
451152
|
if (op.kind === "add" || op.kind === "update") {
|
|
450955
451153
|
const result3 = parsePatchToAdvancedDiff2(op.patchLines, op.path);
|
|
450956
451154
|
if (result3) {
|
|
450957
|
-
previews.push(toDiffPreview(result3,
|
|
451155
|
+
previews.push(toDiffPreview(result3, basename23(op.path)));
|
|
450958
451156
|
}
|
|
450959
451157
|
}
|
|
450960
451158
|
}
|
|
@@ -451010,7 +451208,28 @@ function safeJsonParseOr(json2, defaultValue) {
|
|
|
451010
451208
|
async function getMissingRequiredArgs(toolName2, parsedArgs, toolContextId) {
|
|
451011
451209
|
const schema5 = getToolSchema(toolName2, toolContextId);
|
|
451012
451210
|
const required6 = schema5?.input_schema?.required || [];
|
|
451013
|
-
|
|
451211
|
+
const properties4 = schema5?.input_schema?.properties;
|
|
451212
|
+
return required6.filter((key3) => {
|
|
451213
|
+
if (!(key3 in parsedArgs) || parsedArgs[key3] === undefined)
|
|
451214
|
+
return true;
|
|
451215
|
+
if (parsedArgs[key3] === null)
|
|
451216
|
+
return !schemaAllowsNull2(properties4?.[key3]);
|
|
451217
|
+
return false;
|
|
451218
|
+
});
|
|
451219
|
+
}
|
|
451220
|
+
function typeAllowsNull(schema5) {
|
|
451221
|
+
if (!schema5 || typeof schema5 !== "object")
|
|
451222
|
+
return false;
|
|
451223
|
+
const type3 = schema5.type;
|
|
451224
|
+
return type3 === "null" || Array.isArray(type3) && type3.includes("null");
|
|
451225
|
+
}
|
|
451226
|
+
function schemaAllowsNull2(schema5) {
|
|
451227
|
+
if (typeAllowsNull(schema5))
|
|
451228
|
+
return true;
|
|
451229
|
+
if (!schema5 || typeof schema5 !== "object")
|
|
451230
|
+
return false;
|
|
451231
|
+
const { anyOf: anyOf3, oneOf: oneOf3 } = schema5;
|
|
451232
|
+
return [anyOf3, oneOf3].some((branches) => Array.isArray(branches) && branches.some(typeAllowsNull));
|
|
451014
451233
|
}
|
|
451015
451234
|
function formatMissingRequiredArgsReason(toolName2, parsedArgs, missingRequiredArgs, argsParse) {
|
|
451016
451235
|
const received = Object.keys(parsedArgs).join(", ");
|
|
@@ -451687,7 +451906,7 @@ async function handleApprovalStop(params) {
|
|
|
451687
451906
|
const sendOptions = buildSendOptions() ?? {};
|
|
451688
451907
|
if (shouldInterrupt())
|
|
451689
451908
|
return interruptTermination();
|
|
451690
|
-
const consumedQueuedTurn = params.allowQueuedContinuation === false ? null : consumeQueuedTurn(runtime
|
|
451909
|
+
const consumedQueuedTurn = params.allowQueuedContinuation === false ? null : consumeQueuedTurn(runtime);
|
|
451691
451910
|
if (consumedQueuedTurn) {
|
|
451692
451911
|
const { dequeuedBatch, queuedTurn } = consumedQueuedTurn;
|
|
451693
451912
|
await params.onConsumeQueuedTurn?.(queuedTurn);
|
|
@@ -451799,7 +452018,7 @@ var init_turn_approval = __esm(async () => {
|
|
|
451799
452018
|
});
|
|
451800
452019
|
|
|
451801
452020
|
// src/agent/attached-repository-git-sync.ts
|
|
451802
|
-
import { existsSync as
|
|
452021
|
+
import { existsSync as existsSync59 } from "node:fs";
|
|
451803
452022
|
import { join as join81 } from "node:path";
|
|
451804
452023
|
async function getPendingCommitCount(path42) {
|
|
451805
452024
|
const divergence = await getMemoryAheadBehind(path42);
|
|
@@ -451830,7 +452049,7 @@ async function syncPendingAttachedRepositoryCommitsUnlocked(params) {
|
|
|
451830
452049
|
path: path42,
|
|
451831
452050
|
permissions: params.repository.permissions ?? "unknown"
|
|
451832
452051
|
};
|
|
451833
|
-
if (!
|
|
452052
|
+
if (!existsSync59(join81(path42, ".git"))) {
|
|
451834
452053
|
return {
|
|
451835
452054
|
...resultBase,
|
|
451836
452055
|
status: "skipped",
|
|
@@ -452000,7 +452219,7 @@ var init_attached_repository_git_sync = __esm(() => {
|
|
|
452000
452219
|
});
|
|
452001
452220
|
|
|
452002
452221
|
// src/reminders/memory-git-sync.ts
|
|
452003
|
-
import { existsSync as
|
|
452222
|
+
import { existsSync as existsSync60 } from "node:fs";
|
|
452004
452223
|
import { join as join82 } from "node:path";
|
|
452005
452224
|
function formatMemoryRepairInProgressReminder(result3) {
|
|
452006
452225
|
return `${SYSTEM_REMINDER_OPEN}
|
|
@@ -452111,7 +452330,7 @@ async function runPostTurnMemorySync(params, dependencies4 = {}) {
|
|
|
452111
452330
|
if (memorySyncEnabled) {
|
|
452112
452331
|
try {
|
|
452113
452332
|
const memoryDir = getScopedMemoryFilesystemRoot(params.agentId);
|
|
452114
|
-
const release =
|
|
452333
|
+
const release = existsSync60(join82(memoryDir, ".git")) ? await (dependencies4.claimOperation ?? claimMemoryOperation)(memoryDir) : undefined;
|
|
452115
452334
|
if (release !== null) {
|
|
452116
452335
|
try {
|
|
452117
452336
|
const result3 = await syncMemory(params.agentId);
|
|
@@ -452948,12 +453167,12 @@ function rowToolCalls(row, index, diagnostics2) {
|
|
|
452948
453167
|
}
|
|
452949
453168
|
return calls;
|
|
452950
453169
|
}
|
|
452951
|
-
function
|
|
453170
|
+
function contentText3(content) {
|
|
452952
453171
|
if (typeof content === "string") {
|
|
452953
453172
|
if (content.startsWith(CONTENT_JSON_PREFIX)) {
|
|
452954
453173
|
const encoded = content.slice(CONTENT_JSON_PREFIX.length);
|
|
452955
453174
|
try {
|
|
452956
|
-
return
|
|
453175
|
+
return contentText3(JSON.parse(encoded));
|
|
452957
453176
|
} catch {
|
|
452958
453177
|
return encoded;
|
|
452959
453178
|
}
|
|
@@ -453039,7 +453258,7 @@ var init_hermes = __esm(() => {
|
|
|
453039
453258
|
});
|
|
453040
453259
|
};
|
|
453041
453260
|
if (row.role === "user") {
|
|
453042
|
-
const content =
|
|
453261
|
+
const content = contentText3(row.content);
|
|
453043
453262
|
if (content) {
|
|
453044
453263
|
emit({
|
|
453045
453264
|
type: "message",
|
|
@@ -453059,7 +453278,7 @@ var init_hermes = __esm(() => {
|
|
|
453059
453278
|
...timestamp ? { timestamp } : {}
|
|
453060
453279
|
});
|
|
453061
453280
|
}
|
|
453062
|
-
const content =
|
|
453281
|
+
const content = contentText3(row.content);
|
|
453063
453282
|
if (content) {
|
|
453064
453283
|
emit({
|
|
453065
453284
|
type: "message",
|
|
@@ -453082,7 +453301,7 @@ var init_hermes = __esm(() => {
|
|
|
453082
453301
|
if (row.role === "tool") {
|
|
453083
453302
|
emit({
|
|
453084
453303
|
type: "tool_result",
|
|
453085
|
-
content:
|
|
453304
|
+
content: contentText3(row.content),
|
|
453086
453305
|
...typeof row.tool_call_id === "string" && row.tool_call_id ? { callId: row.tool_call_id } : {},
|
|
453087
453306
|
...timestamp ? { timestamp } : {}
|
|
453088
453307
|
});
|
|
@@ -454724,7 +454943,7 @@ var init_listing_shared = __esm(() => {
|
|
|
454724
454943
|
|
|
454725
454944
|
// node_modules/@letta-ai/trajectory/dist/adapters/claude-code/list.js
|
|
454726
454945
|
import { homedir as homedir45 } from "node:os";
|
|
454727
|
-
import { basename as
|
|
454946
|
+
import { basename as basename24, join as join85 } from "node:path";
|
|
454728
454947
|
async function listClaudeCodeTrajectories(root2) {
|
|
454729
454948
|
const base2 = root2 ?? join85(homedir45(), ".claude", "projects");
|
|
454730
454949
|
const items3 = [];
|
|
@@ -454736,7 +454955,7 @@ async function listClaudeCodeTrajectories(root2) {
|
|
|
454736
454955
|
if (!entry.isFile || !entry.name.endsWith(".jsonl"))
|
|
454737
454956
|
continue;
|
|
454738
454957
|
const path42 = join85(projectPath, entry.name);
|
|
454739
|
-
const listing = listingFromFile(
|
|
454958
|
+
const listing = listingFromFile(basename24(entry.name, ".jsonl"), path42);
|
|
454740
454959
|
if (listing)
|
|
454741
454960
|
items3.push(listing);
|
|
454742
454961
|
}
|
|
@@ -454749,12 +454968,12 @@ var init_list = __esm(() => {
|
|
|
454749
454968
|
|
|
454750
454969
|
// node_modules/@letta-ai/trajectory/dist/adapters/codex/list.js
|
|
454751
454970
|
import { homedir as homedir46 } from "node:os";
|
|
454752
|
-
import { basename as
|
|
454971
|
+
import { basename as basename25, join as join86 } from "node:path";
|
|
454753
454972
|
async function listCodexTrajectories(root2) {
|
|
454754
454973
|
const base2 = root2 ?? join86(homedir46(), ".codex", "sessions");
|
|
454755
454974
|
const items3 = [];
|
|
454756
454975
|
for (const path42 of collectFiles(base2, ".jsonl", 4)) {
|
|
454757
|
-
const listing = listingFromFile(
|
|
454976
|
+
const listing = listingFromFile(basename25(path42, ".jsonl"), path42);
|
|
454758
454977
|
if (listing)
|
|
454759
454978
|
items3.push(listing);
|
|
454760
454979
|
}
|
|
@@ -454859,9 +455078,9 @@ var init_list5 = __esm(() => {
|
|
|
454859
455078
|
});
|
|
454860
455079
|
|
|
454861
455080
|
// node_modules/@letta-ai/trajectory/dist/adapters/openclaw/list.js
|
|
454862
|
-
import { existsSync as
|
|
455081
|
+
import { existsSync as existsSync61 } from "node:fs";
|
|
454863
455082
|
import { homedir as homedir50 } from "node:os";
|
|
454864
|
-
import { basename as
|
|
455083
|
+
import { basename as basename26, join as join90 } from "node:path";
|
|
454865
455084
|
async function listOpenClawTrajectories(root2) {
|
|
454866
455085
|
const base2 = root2 ?? defaultStateDir();
|
|
454867
455086
|
const items3 = [];
|
|
@@ -454874,7 +455093,7 @@ async function listOpenClawTrajectories(root2) {
|
|
|
454874
455093
|
if (!entry.isFile || !entry.name.endsWith(".jsonl"))
|
|
454875
455094
|
continue;
|
|
454876
455095
|
const path42 = join90(sessionsPath, entry.name);
|
|
454877
|
-
const listing = listingFromFile(
|
|
455096
|
+
const listing = listingFromFile(basename26(entry.name, ".jsonl"), path42);
|
|
454878
455097
|
if (listing)
|
|
454879
455098
|
items3.push(listing);
|
|
454880
455099
|
}
|
|
@@ -454886,7 +455105,7 @@ function defaultStateDir() {
|
|
|
454886
455105
|
if (override)
|
|
454887
455106
|
return override;
|
|
454888
455107
|
const current = join90(homedir50(), ".openclaw");
|
|
454889
|
-
if (
|
|
455108
|
+
if (existsSync61(current))
|
|
454890
455109
|
return current;
|
|
454891
455110
|
return join90(homedir50(), ".clawdbot");
|
|
454892
455111
|
}
|
|
@@ -457392,6 +457611,11 @@ var init_execution_context_mcp_originator = __esm(async () => {
|
|
|
457392
457611
|
await init_manager2();
|
|
457393
457612
|
});
|
|
457394
457613
|
|
|
457614
|
+
// src/websocket/listener/mcp-originator-scope.ts
|
|
457615
|
+
function getEffectiveMcpOriginatorId(message2) {
|
|
457616
|
+
return message2.mcpOriginatorTokenPresent === true ? message2.mcpOriginatorSuperRunId : undefined;
|
|
457617
|
+
}
|
|
457618
|
+
|
|
457395
457619
|
// src/websocket/listener/turn-finalizer.ts
|
|
457396
457620
|
function applyTurnOriginSwap(parkedInput, consumedTurn, turnToolContextId) {
|
|
457397
457621
|
retireMcpOriginatorTokensOnOriginSwap(parkedInput.mcpOriginatorSuperRunId, consumedTurn.mcpOriginatorSuperRunId);
|
|
@@ -457399,7 +457623,6 @@ function applyTurnOriginSwap(parkedInput, consumedTurn, turnToolContextId) {
|
|
|
457399
457623
|
}
|
|
457400
457624
|
function createQueuedTurnConsumer(params) {
|
|
457401
457625
|
return {
|
|
457402
|
-
activeOriginatorScope: getMcpOriginatorScope(params.parkedInput),
|
|
457403
457626
|
allowQueuedContinuation: params.parkedInput.messages.some((message2) => ("content" in message2)),
|
|
457404
457627
|
onConsumeQueuedTurn: async (queuedTurn) => {
|
|
457405
457628
|
applyTurnOriginSwap(params.parkedInput, queuedTurn, params.turnToolContextId);
|
|
@@ -457503,6 +457726,37 @@ var init_turn_finalizer = __esm(async () => {
|
|
|
457503
457726
|
]);
|
|
457504
457727
|
});
|
|
457505
457728
|
|
|
457729
|
+
// src/websocket/listener/turn-max-turns.ts
|
|
457730
|
+
function finishTurnIfMaxTurnsReached(params) {
|
|
457731
|
+
const { runtime, buffers, stopReason, agentId, conversationId } = params;
|
|
457732
|
+
const maxTurns = runtime.executionSettings?.max_turns;
|
|
457733
|
+
if (maxTurns === undefined || buffers.usage.stepCount < maxTurns || stopReason === "error" && params.fallbackError) {
|
|
457734
|
+
return false;
|
|
457735
|
+
}
|
|
457736
|
+
const message2 = `Maximum turns limit reached (${buffers.usage.stepCount}/${maxTurns} steps)`;
|
|
457737
|
+
if (stopReason === "requires_approval") {
|
|
457738
|
+
populateInterruptQueue(runtime, {
|
|
457739
|
+
lastExecutionResults: null,
|
|
457740
|
+
lastExecutingToolCallIds: [],
|
|
457741
|
+
lastNeedsUserInputToolCallIds: params.approvals.map((a2) => a2.toolCallId),
|
|
457742
|
+
agentId,
|
|
457743
|
+
conversationId,
|
|
457744
|
+
denialReason: message2
|
|
457745
|
+
});
|
|
457746
|
+
}
|
|
457747
|
+
params.finishTurn({
|
|
457748
|
+
stopReason: "max_steps",
|
|
457749
|
+
socket: params.socket,
|
|
457750
|
+
agentId,
|
|
457751
|
+
conversationId,
|
|
457752
|
+
errorNotice: { message: message2, runId: params.runId }
|
|
457753
|
+
});
|
|
457754
|
+
return true;
|
|
457755
|
+
}
|
|
457756
|
+
var init_turn_max_turns = __esm(async () => {
|
|
457757
|
+
await init_interrupts();
|
|
457758
|
+
});
|
|
457759
|
+
|
|
457506
457760
|
// src/websocket/listener/turn-observers.ts
|
|
457507
457761
|
function registerTurnObserver(otid, hooks) {
|
|
457508
457762
|
hooksByOtid.set(otid, hooks);
|
|
@@ -458389,18 +458643,18 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
|
|
|
458389
458643
|
break;
|
|
458390
458644
|
}
|
|
458391
458645
|
lastApprovalContinuationAccepted = false;
|
|
458392
|
-
|
|
458393
|
-
|
|
458394
|
-
|
|
458395
|
-
|
|
458396
|
-
|
|
458397
|
-
|
|
458398
|
-
|
|
458399
|
-
|
|
458400
|
-
|
|
458401
|
-
|
|
458402
|
-
|
|
458403
|
-
|
|
458646
|
+
if (finishTurnIfMaxTurnsReached({
|
|
458647
|
+
runtime,
|
|
458648
|
+
socket,
|
|
458649
|
+
buffers,
|
|
458650
|
+
stopReason,
|
|
458651
|
+
approvals,
|
|
458652
|
+
fallbackError,
|
|
458653
|
+
runId: runId || runtime.activeRunId,
|
|
458654
|
+
agentId,
|
|
458655
|
+
conversationId,
|
|
458656
|
+
finishTurn
|
|
458657
|
+
})) {
|
|
458404
458658
|
break;
|
|
458405
458659
|
}
|
|
458406
458660
|
if (stopReason === "end_turn") {
|
|
@@ -458927,6 +459181,7 @@ var init_turn = __esm(async () => {
|
|
|
458927
459181
|
init_turn_correlation(),
|
|
458928
459182
|
init_turn_durability_ownership(),
|
|
458929
459183
|
init_turn_finalizer(),
|
|
459184
|
+
init_turn_max_turns(),
|
|
458930
459185
|
init_turn_send(),
|
|
458931
459186
|
init_turn_setup(),
|
|
458932
459187
|
init_turn_status(),
|
|
@@ -460201,42 +460456,9 @@ function stampInboundUserMessageOtids(incoming) {
|
|
|
460201
460456
|
function rejectReplacement(reason) {
|
|
460202
460457
|
throw new Error(`Invalid listener replacement lineage: ${reason}`);
|
|
460203
460458
|
}
|
|
460204
|
-
function cloneRawData(frame) {
|
|
460205
|
-
if (Array.isArray(frame))
|
|
460206
|
-
return frame.map((chunk2) => Buffer.from(chunk2));
|
|
460207
|
-
if (Buffer.isBuffer(frame))
|
|
460208
|
-
return Buffer.from(frame);
|
|
460209
|
-
if (frame instanceof ArrayBuffer)
|
|
460210
|
-
return frame.slice(0);
|
|
460211
|
-
return Buffer.from(new Uint8Array(frame));
|
|
460212
|
-
}
|
|
460213
|
-
function cloneStartupFrameHandoff(handoff) {
|
|
460214
|
-
return handoff.kind === "overflow" ? { ...handoff } : { ...handoff, frames: handoff.frames.map(cloneRawData) };
|
|
460215
|
-
}
|
|
460216
|
-
function cloneDispositionLedger(ledger) {
|
|
460217
|
-
return {
|
|
460218
|
-
entries: new Map([...ledger.entries].map(([key3, entry]) => [key3, structuredClone(entry)])),
|
|
460219
|
-
scopeCounts: new Map(ledger.scopeCounts),
|
|
460220
|
-
quarantinedCount: ledger.quarantinedCount,
|
|
460221
|
-
abandonedReservations: new Map([...ledger.abandonedReservations].map(([key3, reservation]) => [
|
|
460222
|
-
key3,
|
|
460223
|
-
{ ...reservation }
|
|
460224
|
-
])),
|
|
460225
|
-
expiryQueue: ledger.expiryQueue.map((entry) => ({ ...entry })),
|
|
460226
|
-
expiryQueueHead: ledger.expiryQueueHead,
|
|
460227
|
-
nextGeneration: ledger.nextGeneration,
|
|
460228
|
-
persistentPath: ledger.persistentPath
|
|
460229
|
-
};
|
|
460230
|
-
}
|
|
460231
460459
|
function createListenerClientReplacement(runtime, opts) {
|
|
460232
460460
|
const lineageId = resolveStartupLineageId(runtime, opts);
|
|
460233
460461
|
const generation4 = runtime.startupGenerationByLineage.get(lineageId) ?? 0;
|
|
460234
|
-
const startupFrameHandoff = cloneStartupFrameHandoff(runtime.pendingStartupFramesByLineage.get(lineageId) ?? {
|
|
460235
|
-
kind: "frames",
|
|
460236
|
-
frames: [],
|
|
460237
|
-
byteLength: 0
|
|
460238
|
-
});
|
|
460239
|
-
const clientMessageIdsByRunIdByConversation = cloneTurnCorrelationIndex(runtime.clientMessageIdsByRunIdByConversation);
|
|
460240
460462
|
const replacement = Object.freeze({
|
|
460241
460463
|
deviceId: opts.deviceId,
|
|
460242
460464
|
connectionName: opts.connectionName,
|
|
@@ -460249,10 +460471,7 @@ function createListenerClientReplacement(runtime, opts) {
|
|
|
460249
460471
|
connectionName: opts.connectionName,
|
|
460250
460472
|
lineageId,
|
|
460251
460473
|
generation: generation4,
|
|
460252
|
-
authorityEpoch: getRuntimeAuthorityEpoch(runtime)
|
|
460253
|
-
ledger: cloneDispositionLedger(runtime.acceptedInputDispositionLedger),
|
|
460254
|
-
startupFrameHandoff: cloneStartupFrameHandoff(startupFrameHandoff),
|
|
460255
|
-
clientMessageIdsByRunIdByConversation: cloneTurnCorrelationIndex(clientMessageIdsByRunIdByConversation)
|
|
460474
|
+
authorityEpoch: getRuntimeAuthorityEpoch(runtime)
|
|
460256
460475
|
});
|
|
460257
460476
|
return replacement;
|
|
460258
460477
|
}
|
|
@@ -460267,54 +460486,29 @@ function resolveAdoptableReplacement(opts) {
|
|
|
460267
460486
|
rejectReplacement("identity_mismatch");
|
|
460268
460487
|
}
|
|
460269
460488
|
const issuer = provenance.issuer;
|
|
460270
|
-
if (succeededListenerRuntimes.has(issuer)) {
|
|
460271
|
-
rejectReplacement("superseded_issuer");
|
|
460272
|
-
}
|
|
460273
460489
|
if ((issuer.startupGenerationByLineage.get(provenance.lineageId) ?? 0) !== provenance.generation) {
|
|
460274
460490
|
rejectReplacement("stale_generation");
|
|
460275
460491
|
}
|
|
460276
460492
|
if (provenance.authorityEpoch === null || provenance.authorityEpoch !== getLatestRuntimeAuthorityEpoch()) {
|
|
460277
460493
|
rejectReplacement("unauthoritative_issuer");
|
|
460278
460494
|
}
|
|
460279
|
-
|
|
460280
|
-
if (issuer.intentionallyClosed) {
|
|
460281
|
-
if (activeRuntime2 !== null && activeRuntime2 !== issuer) {
|
|
460282
|
-
rejectReplacement("unauthoritative_issuer");
|
|
460283
|
-
}
|
|
460284
|
-
} else if (issuer !== activeRuntime2) {
|
|
460495
|
+
if (issuer.intentionallyClosed || issuer !== getActiveRuntime()) {
|
|
460285
460496
|
rejectReplacement("unauthoritative_issuer");
|
|
460286
460497
|
}
|
|
460287
460498
|
return provenance;
|
|
460288
460499
|
}
|
|
460289
|
-
function
|
|
460290
|
-
resolveAdoptableReplacement(opts);
|
|
460291
|
-
}
|
|
460292
|
-
function adoptListenerClientReplacement(runtime, opts) {
|
|
460500
|
+
function adoptListenerClientReplacement(opts) {
|
|
460293
460501
|
const provenance = resolveAdoptableReplacement(opts);
|
|
460294
|
-
|
|
460295
|
-
|
|
460296
|
-
|
|
460297
|
-
|
|
460298
|
-
|
|
460299
|
-
|
|
460300
|
-
runtime.acceptedInputDispositionLedger.abandonedReservations = new Map([
|
|
460301
|
-
...provenance.issuer.acceptedInputDispositionLedger.abandonedReservations
|
|
460302
|
-
].map(([key3, reservation]) => [key3, { ...reservation }]));
|
|
460303
|
-
runtime.clientMessageIdsByRunIdByConversation = mergeTurnCorrelationIndexes(provenance.clientMessageIdsByRunIdByConversation, provenance.issuer.clientMessageIdsByRunIdByConversation, runtime.clientMessageIdsByRunIdByConversation);
|
|
460304
|
-
runtime.startupGenerationByLineage.set(provenance.lineageId, provenance.generation);
|
|
460305
|
-
if (provenance.startupFrameHandoff.kind === "overflow" || provenance.startupFrameHandoff.frames.length > 0) {
|
|
460306
|
-
runtime.pendingStartupFramesByLineage.set(provenance.lineageId, cloneStartupFrameHandoff(provenance.startupFrameHandoff));
|
|
460307
|
-
}
|
|
460308
|
-
}
|
|
460309
|
-
var replacementProvenance, succeededListenerRuntimes;
|
|
460502
|
+
if (!provenance || !opts.replacement)
|
|
460503
|
+
return null;
|
|
460504
|
+
replacementProvenance.delete(opts.replacement);
|
|
460505
|
+
return provenance.issuer;
|
|
460506
|
+
}
|
|
460507
|
+
var replacementProvenance;
|
|
460310
460508
|
var init_listener_replacement = __esm(async () => {
|
|
460311
460509
|
init_startup_ingress();
|
|
460312
|
-
await
|
|
460313
|
-
init_runtime6(),
|
|
460314
|
-
init_turn_correlation()
|
|
460315
|
-
]);
|
|
460510
|
+
await init_runtime6();
|
|
460316
460511
|
replacementProvenance = new WeakMap;
|
|
460317
|
-
succeededListenerRuntimes = new WeakSet;
|
|
460318
460512
|
});
|
|
460319
460513
|
|
|
460320
460514
|
// src/websocket/listener/listener-task.ts
|
|
@@ -460553,7 +460747,14 @@ async function requestCloudReflectionRun(scope, args = "", backend3 = getBackend
|
|
|
460553
460747
|
if (!backend3.retrieveReflectionConfig) {
|
|
460554
460748
|
throw new Error("Unable to determine reflection ownership on this backend.");
|
|
460555
460749
|
}
|
|
460556
|
-
|
|
460750
|
+
let config2;
|
|
460751
|
+
try {
|
|
460752
|
+
config2 = await backend3.retrieveReflectionConfig(capturedScope.agentId, actingUserRequestOptions(capturedScope.actingUserId));
|
|
460753
|
+
} catch (error5) {
|
|
460754
|
+
if (error5 instanceof APIError && error5.status === 404)
|
|
460755
|
+
return null;
|
|
460756
|
+
throw error5;
|
|
460757
|
+
}
|
|
460557
460758
|
if (config2 === null || config2.cutover === false)
|
|
460558
460759
|
return null;
|
|
460559
460760
|
if (config2.cutover !== true) {
|
|
@@ -460578,6 +460779,7 @@ async function requestReflectionRun(scope, args = "", backend3 = getBackend()) {
|
|
|
460578
460779
|
return formatReflectionReceipt(receipt);
|
|
460579
460780
|
}
|
|
460580
460781
|
var init_reflection_runs2 = __esm(() => {
|
|
460782
|
+
init_error();
|
|
460581
460783
|
init_backend2();
|
|
460582
460784
|
init_reflection_runs();
|
|
460583
460785
|
});
|
|
@@ -460594,9 +460796,9 @@ __export(exports_custom, {
|
|
|
460594
460796
|
GLOBAL_COMMANDS_DIR: () => GLOBAL_COMMANDS_DIR,
|
|
460595
460797
|
COMMANDS_DIR: () => COMMANDS_DIR
|
|
460596
460798
|
});
|
|
460597
|
-
import { existsSync as
|
|
460799
|
+
import { existsSync as existsSync62 } from "node:fs";
|
|
460598
460800
|
import { readdir as readdir11, readFile as readFile25 } from "node:fs/promises";
|
|
460599
|
-
import { basename as
|
|
460801
|
+
import { basename as basename28, dirname as dirname36, join as join93 } from "node:path";
|
|
460600
460802
|
async function getCustomCommands() {
|
|
460601
460803
|
if (cachedCommands !== null) {
|
|
460602
460804
|
return cachedCommands;
|
|
@@ -460628,7 +460830,7 @@ async function discoverCustomCommands(projectPath = join93(process.cwd(), COMMAN
|
|
|
460628
460830
|
return result3;
|
|
460629
460831
|
}
|
|
460630
460832
|
async function discoverFromDirectory(dirPath, source) {
|
|
460631
|
-
if (!
|
|
460833
|
+
if (!existsSync62(dirPath)) {
|
|
460632
460834
|
return [];
|
|
460633
460835
|
}
|
|
460634
460836
|
const commands = [];
|
|
@@ -460656,7 +460858,7 @@ async function findCommandFiles(currentPath, rootPath, commands, source) {
|
|
|
460656
460858
|
async function parseCommandFile(filePath, rootPath, source) {
|
|
460657
460859
|
const content = await readFile25(filePath, "utf-8");
|
|
460658
460860
|
const { frontmatter, body: body3 } = parseFrontmatter(content);
|
|
460659
|
-
const id2 =
|
|
460861
|
+
const id2 = basename28(filePath, ".md");
|
|
460660
460862
|
const relativePath = dirname36(filePath).slice(rootPath.length);
|
|
460661
460863
|
const namespace = relativePath.replace(/^[/\\]/, "") || undefined;
|
|
460662
460864
|
let description = getStringField(frontmatter, "description");
|
|
@@ -461675,7 +461877,6 @@ function buildAppServerInfoResponse(command, options) {
|
|
|
461675
461877
|
runtime_external_tools_update: true,
|
|
461676
461878
|
structured_outputs: options.backend === "api",
|
|
461677
461879
|
write_file_base64: true,
|
|
461678
|
-
mcp_originator_queue_isolation: true,
|
|
461679
461880
|
split_channels: false
|
|
461680
461881
|
}
|
|
461681
461882
|
};
|
|
@@ -463693,16 +463894,29 @@ async function preparePairedListenerTransport(params) {
|
|
|
463693
463894
|
runtime.streamTransport = streamSocket;
|
|
463694
463895
|
return { kind: "ready", transport: streamSocket, streamSocket };
|
|
463695
463896
|
}
|
|
463897
|
+
function createListenerLifecycleLog(opts) {
|
|
463898
|
+
return (message2) => {
|
|
463899
|
+
if (opts.onLog) {
|
|
463900
|
+
opts.onLog(`[Listen] ${message2}`);
|
|
463901
|
+
return;
|
|
463902
|
+
}
|
|
463903
|
+
debugLog("Listen", message2);
|
|
463904
|
+
};
|
|
463905
|
+
}
|
|
463906
|
+
function formatListenerSocketClose(channel, code2, reason) {
|
|
463907
|
+
const text3 = reason.toString();
|
|
463908
|
+
const truncated = text3.length > MAX_CLOSE_REASON_LENGTH ? `${text3.slice(0, MAX_CLOSE_REASON_LENGTH)}...` : text3;
|
|
463909
|
+
return `${channel} socket closed (code=${code2}, reason=${JSON.stringify(truncated)})`;
|
|
463910
|
+
}
|
|
463696
463911
|
function attachSplitStreamSocketHandlers(params) {
|
|
463697
463912
|
params.streamSocket.on("error", (error5) => {
|
|
463913
|
+
params.log?.(`stream socket error: ${error5.message}`);
|
|
463698
463914
|
params.trackListenerError("listener_stream_socket_error", error5, "listener_stream_socket");
|
|
463699
463915
|
if (isDebugEnabled())
|
|
463700
463916
|
console.error("[Listen] Stream WebSocket error:", error5);
|
|
463701
463917
|
});
|
|
463702
463918
|
params.streamSocket.on("close", (code2, reason) => {
|
|
463703
|
-
|
|
463704
|
-
console.log(`[Listen] Stream WebSocket closed (code: ${code2}, reason: ${reason.toString()})`);
|
|
463705
|
-
}
|
|
463919
|
+
params.log?.(formatListenerSocketClose("stream", code2, reason));
|
|
463706
463920
|
terminateControlAfterStreamClose(params.runtime, params.streamSocket, code2, reason);
|
|
463707
463921
|
});
|
|
463708
463922
|
}
|
|
@@ -463750,6 +463964,7 @@ function handleListenerSocketOpenFailure({
|
|
|
463750
463964
|
}
|
|
463751
463965
|
terminateCurrentSocketPair(runtime, controlSocket, streamSocket);
|
|
463752
463966
|
}
|
|
463967
|
+
var MAX_CLOSE_REASON_LENGTH = 120;
|
|
463753
463968
|
var init_split_stream_lifecycle = __esm(async () => {
|
|
463754
463969
|
init_debug();
|
|
463755
463970
|
init_constants3();
|
|
@@ -465414,10 +465629,10 @@ async function recoverRecordedTurns(listener, deps = {}) {
|
|
|
465414
465629
|
}
|
|
465415
465630
|
} finally {
|
|
465416
465631
|
recovering.delete(listener);
|
|
465632
|
+
const retryDelayMs = recoveryRetryDelay(listener, deps.retryDelayMs ?? 5000);
|
|
465417
465633
|
if (pendingRecoveries.delete(listener)) {
|
|
465418
465634
|
scheduleRecordedTurnRecovery(listener, () => recoverRecordedTurns(listener, deps), deps.retryDelayMs);
|
|
465419
|
-
} else if (deferred2 && !listener.intentionallyClosed) {
|
|
465420
|
-
const retryDelayMs = deps.retryDelayMs ?? 5000;
|
|
465635
|
+
} else if (deferred2 && Number.isFinite(retryDelayMs) && !listener.intentionallyClosed) {
|
|
465421
465636
|
const timer2 = setTimeout(() => {
|
|
465422
465637
|
retryTimers.delete(listener);
|
|
465423
465638
|
scheduleRecordedTurnRecovery(listener, () => recoverRecordedTurns(listener, deps), retryDelayMs);
|
|
@@ -465498,6 +465713,39 @@ var init_socket_send = __esm(() => {
|
|
|
465498
465713
|
init_debug();
|
|
465499
465714
|
});
|
|
465500
465715
|
|
|
465716
|
+
// src/websocket/listener/startup-deadline.ts
|
|
465717
|
+
function startListenerStartupDeadline(runtime, transport3, opts, enabled = true) {
|
|
465718
|
+
const socket = runtime.socket;
|
|
465719
|
+
if (!enabled || !socket || socket !== transport3)
|
|
465720
|
+
return () => {};
|
|
465721
|
+
const configured = Number(process.env.LETTA_LISTENER_STARTUP_DEADLINE_MS);
|
|
465722
|
+
const deadlineMs = Number.isFinite(configured) && configured > 0 ? configured : 60000;
|
|
465723
|
+
const clear = () => {
|
|
465724
|
+
clearTimeout(timer);
|
|
465725
|
+
socket.off("close", clear);
|
|
465726
|
+
};
|
|
465727
|
+
const timer = setTimeout(() => {
|
|
465728
|
+
clear();
|
|
465729
|
+
if (runtime.socket !== socket || runtime.intentionallyClosed)
|
|
465730
|
+
return;
|
|
465731
|
+
const message2 = `Listener startup did not finish within ${deadlineMs}ms; reconnecting`;
|
|
465732
|
+
try {
|
|
465733
|
+
if (opts.onLog)
|
|
465734
|
+
opts.onLog(message2);
|
|
465735
|
+
else
|
|
465736
|
+
debugLog("Listen", message2);
|
|
465737
|
+
} finally {
|
|
465738
|
+
socket.terminate();
|
|
465739
|
+
}
|
|
465740
|
+
}, deadlineMs);
|
|
465741
|
+
socket.once("close", clear);
|
|
465742
|
+
timer.unref();
|
|
465743
|
+
return clear;
|
|
465744
|
+
}
|
|
465745
|
+
var init_startup_deadline = __esm(() => {
|
|
465746
|
+
init_debug();
|
|
465747
|
+
});
|
|
465748
|
+
|
|
465501
465749
|
// src/websocket/listener/recovery-sync.ts
|
|
465502
465750
|
function isBackendNotFoundError2(error5) {
|
|
465503
465751
|
return error5 instanceof APIError && (error5.status === 404 || error5.status === 422) || error5 instanceof Error && error5.name === "LocalBackendNotFoundError";
|
|
@@ -465852,6 +466100,7 @@ async function startConnectedListenerRuntime(runtime, transport3, opts, processQ
|
|
|
465852
466100
|
startListenerPongHeartbeat(runtime, transport3, trackListenerError4);
|
|
465853
466101
|
}
|
|
465854
466102
|
const heartbeat = options.startHeartbeat !== false && runtime.heartbeatInterval;
|
|
466103
|
+
const clearStartupDeadline = startListenerStartupDeadline(runtime, transport3, opts, options.startStartupDeadline);
|
|
465855
466104
|
let startupComplete = false;
|
|
465856
466105
|
try {
|
|
465857
466106
|
if (!await completeInitialConnectionStartup(runtime, startupConnection, transport3, opts, options))
|
|
@@ -465873,6 +466122,7 @@ async function startConnectedListenerRuntime(runtime, transport3, opts, processQ
|
|
|
465873
466122
|
return;
|
|
465874
466123
|
startupComplete = true;
|
|
465875
466124
|
} finally {
|
|
466125
|
+
clearStartupDeadline();
|
|
465876
466126
|
if (!startupComplete && heartbeat) {
|
|
465877
466127
|
clearInterval(heartbeat);
|
|
465878
466128
|
if (runtime.heartbeatInterval === heartbeat)
|
|
@@ -466023,13 +466273,15 @@ async function attachOpenListenerSocket(runtime, socket, opts, options = {}) {
|
|
|
466023
466273
|
});
|
|
466024
466274
|
}
|
|
466025
466275
|
async function startListenerClient(opts) {
|
|
466026
|
-
|
|
466276
|
+
const resumedRuntime = adoptListenerClientReplacement(opts);
|
|
466027
466277
|
const existingRuntime = getActiveRuntime();
|
|
466028
|
-
if (existingRuntime)
|
|
466278
|
+
if (existingRuntime && !resumedRuntime)
|
|
466029
466279
|
stopRuntime(existingRuntime, true);
|
|
466280
|
+
const runtime = resumedRuntime ?? createRuntime();
|
|
466281
|
+
if (resumedRuntime && runtime.connectionId) {
|
|
466282
|
+
revokeRecoveryClaims(runtime, runtime.connectionId);
|
|
466283
|
+
resumeListenerConnectionIdentity(runtime, runtime.connectionId, opts.connectionId);
|
|
466030
466284
|
}
|
|
466031
|
-
const runtime = createRuntime();
|
|
466032
|
-
adoptListenerClientReplacement(runtime, opts);
|
|
466033
466285
|
runtime.onWsEvent = opts.onWsEvent;
|
|
466034
466286
|
runtime.connectionId = opts.connectionId;
|
|
466035
466287
|
runtime.connectionName = opts.connectionName;
|
|
@@ -466037,7 +466289,8 @@ async function startListenerClient(opts) {
|
|
|
466037
466289
|
telemetry.setSurface(getListenerTelemetrySurface());
|
|
466038
466290
|
telemetry.init();
|
|
466039
466291
|
setExplicitOrganizationId(opts.organizationId);
|
|
466040
|
-
|
|
466292
|
+
if (!resumedRuntime)
|
|
466293
|
+
await reloadListenerModAdapter(runtime);
|
|
466041
466294
|
await connectWithRetry(runtime, opts);
|
|
466042
466295
|
}
|
|
466043
466296
|
async function startLocalChannelListener(opts) {
|
|
@@ -466085,6 +466338,9 @@ async function connectWithRetry(runtime, opts, attempt2 = 0, startTime = Date.no
|
|
|
466085
466338
|
if (attempt2 > 0) {
|
|
466086
466339
|
if (elapsedTime >= MAX_RETRY_DURATION_MS) {
|
|
466087
466340
|
if (runtime.everConnected && opts.onNeedsReregister) {
|
|
466341
|
+
rejectPendingExternalToolCallsForConnection(runtime, opts.connectionId, "Listener connection re-registered");
|
|
466342
|
+
killListenerConnectionTerminals(opts.connectionId);
|
|
466343
|
+
revokeRecoveryClaims(runtime, opts.connectionId);
|
|
466088
466344
|
opts.onNeedsReregister(createListenerClientReplacement(runtime, opts));
|
|
466089
466345
|
return;
|
|
466090
466346
|
}
|
|
@@ -466128,6 +466384,7 @@ async function connectWithRetry(runtime, opts, attempt2 = 0, startTime = Date.no
|
|
|
466128
466384
|
const headers = { Authorization: `Bearer ${apiKey}` };
|
|
466129
466385
|
const socket = new WebSocket11(url2.toString(), { headers });
|
|
466130
466386
|
let streamSocket = streamUrl && !pairIdentity ? new WebSocket11(streamUrl.toString(), { headers }) : null;
|
|
466387
|
+
const lifecycleLog = createListenerLifecycleLog(opts);
|
|
466131
466388
|
const fileCommandSession = createFileCommandSession({
|
|
466132
466389
|
socket,
|
|
466133
466390
|
safeSocketSend,
|
|
@@ -466166,7 +466423,8 @@ async function connectWithRetry(runtime, opts, attempt2 = 0, startTime = Date.no
|
|
|
466166
466423
|
attachSplitStreamSocketHandlers({
|
|
466167
466424
|
runtime,
|
|
466168
466425
|
streamSocket,
|
|
466169
|
-
trackListenerError: trackListenerError4
|
|
466426
|
+
trackListenerError: trackListenerError4,
|
|
466427
|
+
log: lifecycleLog
|
|
466170
466428
|
});
|
|
466171
466429
|
}
|
|
466172
466430
|
socket.on("open", () => {
|
|
@@ -466196,7 +466454,8 @@ async function connectWithRetry(runtime, opts, attempt2 = 0, startTime = Date.no
|
|
|
466196
466454
|
attachSplitStreamSocketHandlers({
|
|
466197
466455
|
runtime,
|
|
466198
466456
|
streamSocket: streamOpen.streamSocket,
|
|
466199
|
-
trackListenerError: trackListenerError4
|
|
466457
|
+
trackListenerError: trackListenerError4,
|
|
466458
|
+
log: lifecycleLog
|
|
466200
466459
|
});
|
|
466201
466460
|
}
|
|
466202
466461
|
if (!isCurrentSocketPair(runtime, socket, streamSocket))
|
|
@@ -466235,9 +466494,12 @@ async function connectWithRetry(runtime, opts, attempt2 = 0, startTime = Date.no
|
|
|
466235
466494
|
recordListenerPong(runtime, socket);
|
|
466236
466495
|
return;
|
|
466237
466496
|
}
|
|
466497
|
+
if (!isCurrentSocketPair(runtime, socket, streamSocket))
|
|
466498
|
+
return;
|
|
466238
466499
|
pendingStartupFrames.accept(data, handleMessage);
|
|
466239
466500
|
});
|
|
466240
466501
|
socket.on("close", (code2, reason) => {
|
|
466502
|
+
lifecycleLog(formatListenerSocketClose("control", code2, reason));
|
|
466241
466503
|
abortStartupIngress();
|
|
466242
466504
|
if (!shouldHandleControlSocketClose(runtime, socket, opts.connectionId)) {
|
|
466243
466505
|
return;
|
|
@@ -466249,14 +466511,11 @@ async function connectWithRetry(runtime, opts, attempt2 = 0, startTime = Date.no
|
|
|
466249
466511
|
});
|
|
466250
466512
|
fileCommandSession.dispose();
|
|
466251
466513
|
const reasonText = reason.toString();
|
|
466252
|
-
const terminalClose = runtime.intentionallyClosed || code2 === 1008 || code2 === 1000 && reasonText === "Replaced by new connection";
|
|
466514
|
+
const terminalClose = runtime.intentionallyClosed || code2 === 1008 && reasonText !== CLOUD_ENVIRONMENT_NOT_FOUND_CLOSE_REASON || code2 === 1000 && reasonText === "Replaced by new connection";
|
|
466253
466515
|
if (!terminalClose && runtime.hasSuccessfulConnection) {
|
|
466254
466516
|
opts.onRetrying?.(0, MAX_RETRY_ATTEMPTS, 0, opts.connectionId);
|
|
466255
466517
|
}
|
|
466256
466518
|
clearRuntimeTimers(runtime);
|
|
466257
|
-
if (isDebugEnabled()) {
|
|
466258
|
-
console.log(`[Listen] WebSocket disconnected (code: ${code2}, reason: ${reason.toString()})`);
|
|
466259
|
-
}
|
|
466260
466519
|
if (!terminalClose) {
|
|
466261
466520
|
for (const conversationRuntime of runtime.conversationRuntimes.values()) {
|
|
466262
466521
|
rejectPendingApprovalResolversForConnection(conversationRuntime, opts.connectionId, "Listener connection closed");
|
|
@@ -466268,7 +466527,8 @@ async function connectWithRetry(runtime, opts, attempt2 = 0, startTime = Date.no
|
|
|
466268
466527
|
revokeRecoveryClaims(runtime, undefined, closingGeneration);
|
|
466269
466528
|
}
|
|
466270
466529
|
suspendListenerConnection(runtime, opts.connectionId);
|
|
466271
|
-
|
|
466530
|
+
if (terminalClose)
|
|
466531
|
+
killAllTerminals();
|
|
466272
466532
|
clearListenerWarmState(runtime);
|
|
466273
466533
|
if (streamSocket) {
|
|
466274
466534
|
streamSocket.removeAllListeners("message");
|
|
@@ -466281,27 +466541,21 @@ async function connectWithRetry(runtime, opts, attempt2 = 0, startTime = Date.no
|
|
|
466281
466541
|
runtime.socket = null;
|
|
466282
466542
|
runtime.streamSocket = null;
|
|
466283
466543
|
runtime.streamTransport = null;
|
|
466284
|
-
if (terminalClose) {
|
|
466285
|
-
|
|
466286
|
-
|
|
466544
|
+
if (code2 === 1008 && !terminalClose && opts.onNeedsReregister) {
|
|
466545
|
+
rejectPendingExternalToolCallsForConnection(runtime, opts.connectionId, "Listener connection re-registered");
|
|
466546
|
+
killListenerConnectionTerminals(opts.connectionId);
|
|
466547
|
+
revokeRecoveryClaims(runtime, opts.connectionId);
|
|
466548
|
+
opts.onNeedsReregister(createListenerClientReplacement(runtime, opts));
|
|
466549
|
+
return;
|
|
466550
|
+
}
|
|
466551
|
+
if (terminalClose || code2 === 1008) {
|
|
466552
|
+
if (getActiveRuntime() === runtime)
|
|
466287
466553
|
setActiveRuntime(null);
|
|
466288
|
-
}
|
|
466289
466554
|
stopRuntime(runtime, true);
|
|
466290
|
-
if (code2 === 1008)
|
|
466291
|
-
|
|
466292
|
-
|
|
466293
|
-
|
|
466294
|
-
if (opts.onNeedsReregister) {
|
|
466295
|
-
if (!replacement) {
|
|
466296
|
-
throw new Error("Missing listener replacement lineage");
|
|
466297
|
-
}
|
|
466298
|
-
opts.onNeedsReregister(replacement);
|
|
466299
|
-
} else {
|
|
466300
|
-
opts.onDisconnected();
|
|
466301
|
-
}
|
|
466302
|
-
return;
|
|
466303
|
-
}
|
|
466304
|
-
opts.onDisconnected();
|
|
466555
|
+
if (code2 === 1008 && opts.onNeedsReregister)
|
|
466556
|
+
opts.onNeedsReregister();
|
|
466557
|
+
else
|
|
466558
|
+
opts.onDisconnected();
|
|
466305
466559
|
return;
|
|
466306
466560
|
}
|
|
466307
466561
|
const nextAttempt = runtime.hasSuccessfulConnection ? 0 : attempt2 + 1;
|
|
@@ -466312,7 +466566,10 @@ async function connectWithRetry(runtime, opts, attempt2 = 0, startTime = Date.no
|
|
|
466312
466566
|
});
|
|
466313
466567
|
});
|
|
466314
466568
|
socket.on("error", (error5) => {
|
|
466569
|
+
if (runtime.socket !== socket)
|
|
466570
|
+
return;
|
|
466315
466571
|
trackListenerError4("listener_websocket_error", error5, "listener_socket");
|
|
466572
|
+
lifecycleLog(`control socket error: ${error5.message}`);
|
|
466316
466573
|
safeEmitWsEvent("recv", "lifecycle", {
|
|
466317
466574
|
type: "_ws_error",
|
|
466318
466575
|
message: error5.message
|
|
@@ -466351,6 +466608,7 @@ var init_lifecycle = __esm(async () => {
|
|
|
466351
466608
|
init_listener_task();
|
|
466352
466609
|
init_permission_mode();
|
|
466353
466610
|
init_socket_send();
|
|
466611
|
+
init_startup_deadline();
|
|
466354
466612
|
init_startup_frame_buffer();
|
|
466355
466613
|
init_startup_ingress();
|
|
466356
466614
|
init_stream_observers();
|
|
@@ -469673,7 +469931,7 @@ async function runListenSubcommand(argv) {
|
|
|
469673
469931
|
},
|
|
469674
469932
|
onConnected: () => {},
|
|
469675
469933
|
onConnectionReady: async (connectedId) => {
|
|
469676
|
-
const ready = await completeListenerConnectionStartup(connectedId, readiness, startChannelGateway);
|
|
469934
|
+
const ready = await completeListenerConnectionStartup(connectedId, readiness, startChannelGateway, (error5) => logListenerMessage(`[ChannelGateway] startup failed: ${error5}`));
|
|
469677
469935
|
if (!ready)
|
|
469678
469936
|
return;
|
|
469679
469937
|
sessionLog.log("Local channel listener ready.");
|
|
@@ -469756,7 +470014,8 @@ async function runListenSubcommand(argv) {
|
|
|
469756
470014
|
console.log(`[${formatTimestamp3()}] ${arrow}${tag} ${json2}`);
|
|
469757
470015
|
}
|
|
469758
470016
|
};
|
|
469759
|
-
if (debugMode
|
|
470017
|
+
if (shouldUseNonInteractiveListenerOutput(debugMode, !!lifecycleOutput)) {
|
|
470018
|
+
const printPlainLines = debugMode || !lifecycleOutput;
|
|
469760
470019
|
const startNonInteractiveClient = async (connId, url2, nextSupportsSplitStatusChannels, nextSupportsPairedListenerGenerations, replacement) => {
|
|
469761
470020
|
await startListenerClient2({
|
|
469762
470021
|
replacement,
|
|
@@ -469772,18 +470031,18 @@ async function runListenSubcommand(argv) {
|
|
|
469772
470031
|
onStatusChange: (status) => {
|
|
469773
470032
|
sessionLog.log(`status: ${status}`);
|
|
469774
470033
|
readiness.setStatus(status);
|
|
469775
|
-
if (
|
|
470034
|
+
if (printPlainLines) {
|
|
469776
470035
|
console.log(`[${formatTimestamp3()}] status: ${status}`);
|
|
469777
470036
|
}
|
|
469778
470037
|
},
|
|
469779
470038
|
onLog: logListenerMessage,
|
|
469780
470039
|
onConnected: () => {},
|
|
469781
470040
|
onConnectionReady: async (connectedId) => {
|
|
469782
|
-
const ready = await completeListenerConnectionStartup(connectedId, readiness, startChannelGateway);
|
|
470041
|
+
const ready = await completeListenerConnectionStartup(connectedId, readiness, startChannelGateway, (error5) => logListenerMessage(`[ChannelGateway] startup failed: ${error5}`));
|
|
469783
470042
|
if (!ready)
|
|
469784
470043
|
return;
|
|
469785
470044
|
sessionLog.log("Connected. Awaiting instructions.");
|
|
469786
|
-
if (
|
|
470045
|
+
if (printPlainLines) {
|
|
469787
470046
|
console.log(`[${formatTimestamp3()}] Connected. Awaiting instructions.`);
|
|
469788
470047
|
console.log("");
|
|
469789
470048
|
}
|
|
@@ -469791,13 +470050,13 @@ async function runListenSubcommand(argv) {
|
|
|
469791
470050
|
onRetrying: (attempt2, _maxAttempts, nextRetryIn) => {
|
|
469792
470051
|
readiness.setCloudReconnecting();
|
|
469793
470052
|
sessionLog.log(`Reconnecting (attempt ${attempt2}, retry in ${Math.round(nextRetryIn / 1000)}s)`);
|
|
469794
|
-
if (
|
|
470053
|
+
if (printPlainLines) {
|
|
469795
470054
|
console.log(`[${formatTimestamp3()}] Reconnecting (attempt ${attempt2}, retry in ${Math.round(nextRetryIn / 1000)}s)`);
|
|
469796
470055
|
}
|
|
469797
470056
|
},
|
|
469798
470057
|
onNeedsReregister: async (replacement2) => {
|
|
469799
470058
|
readiness.setCloudReconnecting();
|
|
469800
|
-
if (
|
|
470059
|
+
if (printPlainLines) {
|
|
469801
470060
|
console.log(`[${formatTimestamp3()}] Computer connection expired, re-registering...`);
|
|
469802
470061
|
}
|
|
469803
470062
|
try {
|
|
@@ -469859,7 +470118,7 @@ async function runListenSubcommand(argv) {
|
|
|
469859
470118
|
onLog: logListenerMessage,
|
|
469860
470119
|
onConnected: () => {},
|
|
469861
470120
|
onConnectionReady: async (connectedId) => {
|
|
469862
|
-
const ready = await completeListenerConnectionStartup(connectedId, readiness, startChannelGateway);
|
|
470121
|
+
const ready = await completeListenerConnectionStartup(connectedId, readiness, startChannelGateway, (error5) => logListenerMessage(`[ChannelGateway] startup failed: ${error5}`));
|
|
469863
470122
|
if (!ready)
|
|
469864
470123
|
return;
|
|
469865
470124
|
sessionLog.log("Connected. Awaiting instructions.");
|
|
@@ -469962,7 +470221,7 @@ var init_listen = __esm(async () => {
|
|
|
469962
470221
|
import { randomUUID as randomUUID55 } from "node:crypto";
|
|
469963
470222
|
import {
|
|
469964
470223
|
copyFileSync as copyFileSync3,
|
|
469965
|
-
existsSync as
|
|
470224
|
+
existsSync as existsSync63,
|
|
469966
470225
|
mkdirSync as mkdirSync47,
|
|
469967
470226
|
readdirSync as readdirSync26,
|
|
469968
470227
|
readFileSync as readFileSync48,
|
|
@@ -469970,7 +470229,7 @@ import {
|
|
|
469970
470229
|
} from "node:fs";
|
|
469971
470230
|
import { join as join94 } from "node:path";
|
|
469972
470231
|
function readJsonl(path46) {
|
|
469973
|
-
if (!
|
|
470232
|
+
if (!existsSync63(path46))
|
|
469974
470233
|
return [];
|
|
469975
470234
|
return readFileSync48(path46, "utf8").split(`
|
|
469976
470235
|
`).filter((line) => line.trim().length > 0).map((line) => JSON.parse(line));
|
|
@@ -470258,13 +470517,13 @@ function migrateLocalBackendTranscripts(input) {
|
|
|
470258
470517
|
skipped: [],
|
|
470259
470518
|
dryRun: input.dryRun === true
|
|
470260
470519
|
};
|
|
470261
|
-
if (!
|
|
470520
|
+
if (!existsSync63(conversationsDir))
|
|
470262
470521
|
return result3;
|
|
470263
470522
|
for (const name of readdirSync26(conversationsDir)) {
|
|
470264
470523
|
const conversationDir = join94(conversationsDir, name);
|
|
470265
470524
|
const messagesPath = join94(conversationDir, "messages.jsonl");
|
|
470266
470525
|
const manifestPath = join94(conversationDir, "manifest.json");
|
|
470267
|
-
const hasManifest =
|
|
470526
|
+
const hasManifest = existsSync63(manifestPath);
|
|
470268
470527
|
const existingManifest = hasManifest ? (() => {
|
|
470269
470528
|
try {
|
|
470270
470529
|
return JSON.parse(readFileSync48(manifestPath, "utf8"));
|
|
@@ -470308,7 +470567,7 @@ function migrateLocalBackendTranscripts(input) {
|
|
|
470308
470567
|
copyFileSync3(messagesPath, backupPath);
|
|
470309
470568
|
const conversationPath = join94(conversationDir, "conversation.json");
|
|
470310
470569
|
let conversation;
|
|
470311
|
-
if (
|
|
470570
|
+
if (existsSync63(conversationPath)) {
|
|
470312
470571
|
try {
|
|
470313
470572
|
conversation = JSON.parse(readFileSync48(conversationPath, "utf8"));
|
|
470314
470573
|
} catch {
|
|
@@ -470502,7 +470761,7 @@ var init_memory_tokens = __esm(() => {
|
|
|
470502
470761
|
});
|
|
470503
470762
|
|
|
470504
470763
|
// src/cli/subcommands/memory.ts
|
|
470505
|
-
import { cpSync, existsSync as
|
|
470764
|
+
import { cpSync, existsSync as existsSync64, mkdirSync as mkdirSync48, rmSync as rmSync22, statSync as statSync24 } from "node:fs";
|
|
470506
470765
|
import { readdir as readdir12 } from "node:fs/promises";
|
|
470507
470766
|
import { dirname as dirname37, join as join95 } from "node:path";
|
|
470508
470767
|
import { parseArgs as parseArgs11 } from "node:util";
|
|
@@ -470564,7 +470823,7 @@ function formatBackupTimestamp(date5 = new Date) {
|
|
|
470564
470823
|
}
|
|
470565
470824
|
async function listBackups(agentId) {
|
|
470566
470825
|
const agentRoot = getAgentRoot(agentId);
|
|
470567
|
-
if (!
|
|
470826
|
+
if (!existsSync64(agentRoot)) {
|
|
470568
470827
|
return [];
|
|
470569
470828
|
}
|
|
470570
470829
|
const entries2 = await readdir12(agentRoot, { withFileTypes: true });
|
|
@@ -470669,14 +470928,14 @@ async function runMemorySubcommand(argv, deps = {}) {
|
|
|
470669
470928
|
}
|
|
470670
470929
|
if (action3 === "backup") {
|
|
470671
470930
|
const root2 = getMemoryRoot(agentId);
|
|
470672
|
-
if (!
|
|
470931
|
+
if (!existsSync64(root2)) {
|
|
470673
470932
|
console.error(`Memory directory not found for agent ${agentId}.`);
|
|
470674
470933
|
return 1;
|
|
470675
470934
|
}
|
|
470676
470935
|
const agentRoot = getAgentRoot(agentId);
|
|
470677
470936
|
const backupName = `memory-backup-${formatBackupTimestamp()}`;
|
|
470678
470937
|
const backupPath = join95(agentRoot, backupName);
|
|
470679
|
-
if (
|
|
470938
|
+
if (existsSync64(backupPath)) {
|
|
470680
470939
|
console.error(`Backup already exists at ${backupPath}`);
|
|
470681
470940
|
return 1;
|
|
470682
470941
|
}
|
|
@@ -470700,7 +470959,7 @@ async function runMemorySubcommand(argv, deps = {}) {
|
|
|
470700
470959
|
return 1;
|
|
470701
470960
|
}
|
|
470702
470961
|
const backupPath = resolveBackupPath(agentId, from);
|
|
470703
|
-
if (!
|
|
470962
|
+
if (!existsSync64(backupPath)) {
|
|
470704
470963
|
console.error(`Backup not found: ${backupPath}`);
|
|
470705
470964
|
return 1;
|
|
470706
470965
|
}
|
|
@@ -470722,11 +470981,11 @@ async function runMemorySubcommand(argv, deps = {}) {
|
|
|
470722
470981
|
return 1;
|
|
470723
470982
|
}
|
|
470724
470983
|
const root2 = getMemoryRoot(agentId);
|
|
470725
|
-
if (!
|
|
470984
|
+
if (!existsSync64(root2)) {
|
|
470726
470985
|
console.error(`Memory directory not found for agent ${agentId}.`);
|
|
470727
470986
|
return 1;
|
|
470728
470987
|
}
|
|
470729
|
-
if (
|
|
470988
|
+
if (existsSync64(out)) {
|
|
470730
470989
|
const stat15 = statSync24(out);
|
|
470731
470990
|
if (stat15.isDirectory()) {
|
|
470732
470991
|
const contents = await readdir12(out);
|
|
@@ -470775,10 +471034,10 @@ var init_memory7 = __esm(() => {
|
|
|
470775
471034
|
});
|
|
470776
471035
|
|
|
470777
471036
|
// src/backend/local/transcript-search.ts
|
|
470778
|
-
import { existsSync as
|
|
471037
|
+
import { existsSync as existsSync65, readdirSync as readdirSync27, readFileSync as readFileSync49, statSync as statSync25 } from "node:fs";
|
|
470779
471038
|
import { join as join96 } from "node:path";
|
|
470780
471039
|
function readJsonFile3(path46) {
|
|
470781
|
-
if (!
|
|
471040
|
+
if (!existsSync65(path46))
|
|
470782
471041
|
return;
|
|
470783
471042
|
try {
|
|
470784
471043
|
return JSON.parse(readFileSync49(path46, "utf8"));
|
|
@@ -471060,7 +471319,7 @@ function collectConversationMessages(input) {
|
|
|
471060
471319
|
}
|
|
471061
471320
|
function conversationDirectories(storageDir) {
|
|
471062
471321
|
const conversationsDir = join96(storageDir, "conversations");
|
|
471063
|
-
if (!
|
|
471322
|
+
if (!existsSync65(conversationsDir))
|
|
471064
471323
|
return [];
|
|
471065
471324
|
try {
|
|
471066
471325
|
return readdirSync27(conversationsDir).map((entry) => join96(conversationsDir, entry)).filter((entryPath) => statSync25(entryPath).isDirectory());
|
|
@@ -471974,13 +472233,13 @@ var init_model2 = __esm(() => {
|
|
|
471974
472233
|
import { spawn as spawn13 } from "node:child_process";
|
|
471975
472234
|
import {
|
|
471976
472235
|
copyFileSync as copyFileSync4,
|
|
471977
|
-
existsSync as
|
|
471978
|
-
lstatSync as
|
|
472236
|
+
existsSync as existsSync66,
|
|
472237
|
+
lstatSync as lstatSync4,
|
|
471979
472238
|
mkdirSync as mkdirSync49,
|
|
471980
472239
|
mkdtempSync as mkdtempSync5,
|
|
471981
472240
|
readdirSync as readdirSync28,
|
|
471982
472241
|
readFileSync as readFileSync50,
|
|
471983
|
-
renameSync as
|
|
472242
|
+
renameSync as renameSync11,
|
|
471984
472243
|
rmSync as rmSync23,
|
|
471985
472244
|
writeFileSync as writeFileSync40
|
|
471986
472245
|
} from "node:fs";
|
|
@@ -472023,7 +472282,7 @@ function formatRepository(repository) {
|
|
|
472023
472282
|
function isLocalLettaModPackageDirectory(packageDirectory) {
|
|
472024
472283
|
const resolvedPackageDirectory = path46.resolve(packageDirectory);
|
|
472025
472284
|
try {
|
|
472026
|
-
const packageStats =
|
|
472285
|
+
const packageStats = lstatSync4(resolvedPackageDirectory);
|
|
472027
472286
|
if (packageStats.isSymbolicLink() || !packageStats.isDirectory()) {
|
|
472028
472287
|
return false;
|
|
472029
472288
|
}
|
|
@@ -472050,7 +472309,7 @@ function validateManifestEntriesExist(packageRoot, entries2) {
|
|
|
472050
472309
|
const entryPath = resolvePackageRelativePath(packageRoot, entry);
|
|
472051
472310
|
let stats;
|
|
472052
472311
|
try {
|
|
472053
|
-
stats =
|
|
472312
|
+
stats = lstatSync4(entryPath);
|
|
472054
472313
|
} catch {
|
|
472055
472314
|
throw new Error(`Package mod entry does not exist: ${entry}`);
|
|
472056
472315
|
}
|
|
@@ -472066,7 +472325,7 @@ function resolvePackageDirectory(packageDirectory) {
|
|
|
472066
472325
|
const resolvedPackageDirectory = path46.resolve(packageDirectory);
|
|
472067
472326
|
let packageStats;
|
|
472068
472327
|
try {
|
|
472069
|
-
packageStats =
|
|
472328
|
+
packageStats = lstatSync4(resolvedPackageDirectory);
|
|
472070
472329
|
} catch {
|
|
472071
472330
|
throw new Error(`Package directory does not exist: ${packageDirectory}`);
|
|
472072
472331
|
}
|
|
@@ -472124,7 +472383,7 @@ function copyPackageDirectory(sourceRoot, targetRoot) {
|
|
|
472124
472383
|
continue;
|
|
472125
472384
|
const sourcePath = path46.join(sourceRoot, entry.name);
|
|
472126
472385
|
const targetPath = path46.join(targetRoot, entry.name);
|
|
472127
|
-
const stats =
|
|
472386
|
+
const stats = lstatSync4(sourcePath);
|
|
472128
472387
|
if (stats.isSymbolicLink()) {
|
|
472129
472388
|
throw new Error(`Package contains unsupported symlink: ${sourcePath}`);
|
|
472130
472389
|
}
|
|
@@ -472158,7 +472417,7 @@ function copyDependencyDirectoryFiltered(params) {
|
|
|
472158
472417
|
}
|
|
472159
472418
|
const sourcePath = path46.join(params.sourceRoot, entry.name);
|
|
472160
472419
|
const targetPath = path46.join(params.targetRoot, entry.name);
|
|
472161
|
-
const stats =
|
|
472420
|
+
const stats = lstatSync4(sourcePath);
|
|
472162
472421
|
if (stats.isSymbolicLink()) {
|
|
472163
472422
|
throw new Error(`Package dependency contains unsupported symlink: ${sourcePath}`);
|
|
472164
472423
|
}
|
|
@@ -472183,7 +472442,7 @@ function copyDependencyDirectoryFiltered(params) {
|
|
|
472183
472442
|
return copied;
|
|
472184
472443
|
}
|
|
472185
472444
|
function copyDependencyNodeModules(params) {
|
|
472186
|
-
if (!
|
|
472445
|
+
if (!existsSync66(params.sourceNodeModulesDirectory))
|
|
472187
472446
|
return;
|
|
472188
472447
|
copyDependencyDirectoryFiltered({
|
|
472189
472448
|
installedPackageName: params.installedPackageName,
|
|
@@ -472193,7 +472452,7 @@ function copyDependencyNodeModules(params) {
|
|
|
472193
472452
|
}
|
|
472194
472453
|
function copyPackageInternalNodeModules(params) {
|
|
472195
472454
|
const sourceNodeModulesDirectory = path46.join(params.packageDirectory, "node_modules");
|
|
472196
|
-
if (!
|
|
472455
|
+
if (!existsSync66(sourceNodeModulesDirectory))
|
|
472197
472456
|
return;
|
|
472198
472457
|
copyDependencyDirectoryFiltered({
|
|
472199
472458
|
sourceRoot: sourceNodeModulesDirectory,
|
|
@@ -472215,12 +472474,12 @@ function removeIfExists(targetPath) {
|
|
|
472215
472474
|
}
|
|
472216
472475
|
function restoreDestination(params) {
|
|
472217
472476
|
rmSync23(params.destinationRoot, { force: true, recursive: true });
|
|
472218
|
-
if (params.backupRoot &&
|
|
472219
|
-
|
|
472477
|
+
if (params.backupRoot && existsSync66(params.backupRoot)) {
|
|
472478
|
+
renameSync11(params.backupRoot, params.destinationRoot);
|
|
472220
472479
|
}
|
|
472221
472480
|
}
|
|
472222
472481
|
function restoreDestinationIfNeeded(params) {
|
|
472223
|
-
if (!params.backupRoot || !
|
|
472482
|
+
if (!params.backupRoot || !existsSync66(params.backupRoot)) {
|
|
472224
472483
|
rmSync23(params.destinationRoot, { force: true, recursive: true });
|
|
472225
472484
|
return;
|
|
472226
472485
|
}
|
|
@@ -472261,13 +472520,13 @@ function installPreparedManagedModPackage(params) {
|
|
|
472261
472520
|
targetPackageRoot: stagingRoot
|
|
472262
472521
|
});
|
|
472263
472522
|
}
|
|
472264
|
-
if (
|
|
472523
|
+
if (existsSync66(destinationRoot)) {
|
|
472265
472524
|
backupRoot = makeSiblingTempDirectory(destinationRoot, "backup");
|
|
472266
472525
|
rmSync23(backupRoot, { force: true, recursive: true });
|
|
472267
|
-
|
|
472526
|
+
renameSync11(destinationRoot, backupRoot);
|
|
472268
472527
|
destinationNeedsRollback = true;
|
|
472269
472528
|
}
|
|
472270
|
-
|
|
472529
|
+
renameSync11(stagingRoot, destinationRoot);
|
|
472271
472530
|
destinationNeedsRollback = true;
|
|
472272
472531
|
stagingRoot = null;
|
|
472273
472532
|
try {
|
|
@@ -472546,13 +472805,13 @@ function hasRuntimeDependencies(packageJson) {
|
|
|
472546
472805
|
}
|
|
472547
472806
|
function readPackageJsonIfExists(packageDirectory) {
|
|
472548
472807
|
const packageJsonPath = path46.join(packageDirectory, "package.json");
|
|
472549
|
-
if (!
|
|
472808
|
+
if (!existsSync66(packageJsonPath))
|
|
472550
472809
|
return null;
|
|
472551
472810
|
return readPackageJson(packageJsonPath);
|
|
472552
472811
|
}
|
|
472553
472812
|
function isRegularModFile(filePath) {
|
|
472554
472813
|
try {
|
|
472555
|
-
const stats =
|
|
472814
|
+
const stats = lstatSync4(filePath);
|
|
472556
472815
|
return !stats.isSymbolicLink() && stats.isFile();
|
|
472557
472816
|
} catch {
|
|
472558
472817
|
return false;
|
|
@@ -472560,8 +472819,8 @@ function isRegularModFile(filePath) {
|
|
|
472560
472819
|
}
|
|
472561
472820
|
function inferCompatibilityModEntries(packageDirectory) {
|
|
472562
472821
|
const modsDirectory = path46.join(packageDirectory, "mods");
|
|
472563
|
-
if (
|
|
472564
|
-
const stats =
|
|
472822
|
+
if (existsSync66(modsDirectory)) {
|
|
472823
|
+
const stats = lstatSync4(modsDirectory);
|
|
472565
472824
|
if (stats.isSymbolicLink()) {
|
|
472566
472825
|
throw new Error(`Package mods directory must not be a symlink: mods`);
|
|
472567
472826
|
}
|
|
@@ -472835,8 +473094,8 @@ var init_package_installer = __esm(() => {
|
|
|
472835
473094
|
// src/mods/package-scaffolder.ts
|
|
472836
473095
|
import {
|
|
472837
473096
|
copyFileSync as copyFileSync5,
|
|
472838
|
-
existsSync as
|
|
472839
|
-
lstatSync as
|
|
473097
|
+
existsSync as existsSync67,
|
|
473098
|
+
lstatSync as lstatSync5,
|
|
472840
473099
|
mkdirSync as mkdirSync50,
|
|
472841
473100
|
rmSync as rmSync24,
|
|
472842
473101
|
writeFileSync as writeFileSync41
|
|
@@ -472862,7 +473121,7 @@ function readSourceFile(sourceFile) {
|
|
|
472862
473121
|
const resolvedSourceFile = path47.resolve(sourceFile);
|
|
472863
473122
|
let stats;
|
|
472864
473123
|
try {
|
|
472865
|
-
stats =
|
|
473124
|
+
stats = lstatSync5(resolvedSourceFile);
|
|
472866
473125
|
} catch {
|
|
472867
473126
|
throw new Error(`Mod file does not exist: ${sourceFile}`);
|
|
472868
473127
|
}
|
|
@@ -472928,7 +473187,7 @@ function scaffoldLocalModPackage(options) {
|
|
|
472928
473187
|
const sourceFile = readSourceFile(options.sourceFile);
|
|
472929
473188
|
const packageName = assertValidPackageName(options.packageName);
|
|
472930
473189
|
const outputDirectory = path47.resolve(options.outputDirectory ?? defaultOutputDirectory(sourceFile, packageName));
|
|
472931
|
-
if (
|
|
473190
|
+
if (existsSync67(outputDirectory)) {
|
|
472932
473191
|
throw new Error(`Output directory already exists: ${outputDirectory}`);
|
|
472933
473192
|
}
|
|
472934
473193
|
const modFileName = path47.basename(sourceFile);
|
|
@@ -473484,7 +473743,7 @@ var init_sandbox_files = __esm(() => {
|
|
|
473484
473743
|
|
|
473485
473744
|
// src/cli/subcommands/sandbox.ts
|
|
473486
473745
|
import { readFile as readFile27, stat as stat15, writeFile as writeFile19 } from "node:fs/promises";
|
|
473487
|
-
import { basename as
|
|
473746
|
+
import { basename as basename29, resolve as resolve40 } from "node:path";
|
|
473488
473747
|
import { parseArgs as parseArgs16 } from "node:util";
|
|
473489
473748
|
function printUsage13() {
|
|
473490
473749
|
console.log(`
|
|
@@ -473635,13 +473894,13 @@ async function runSandboxSubcommand(argv, deps = {}) {
|
|
|
473635
473894
|
throw new Error(`${localPath2} is not a file`);
|
|
473636
473895
|
const data2 = await (deps.readLocalFile ?? readFile27)(localPath2);
|
|
473637
473896
|
const sandbox2 = await ensureSandbox();
|
|
473638
|
-
const result3 = await (deps.uploadFile ?? uploadFileToSandbox)(sandbox2.sandboxId, { blob: new Blob([data2]), name:
|
|
473897
|
+
const result3 = await (deps.uploadFile ?? uploadFileToSandbox)(sandbox2.sandboxId, { blob: new Blob([data2]), name: basename29(localPath2) });
|
|
473639
473898
|
console.log(JSON.stringify({ ...result3, ...targetOutput }, null, 2));
|
|
473640
473899
|
return 0;
|
|
473641
473900
|
}
|
|
473642
473901
|
const sandbox = await ensureSandbox();
|
|
473643
473902
|
const data = await (deps.downloadFile ?? downloadFileFromSandbox)(sandbox.sandboxId, path48);
|
|
473644
|
-
const localPath = resolve40(parsed.values.to ??
|
|
473903
|
+
const localPath = resolve40(parsed.values.to ?? basename29(path48));
|
|
473645
473904
|
await (deps.writeLocalFile ?? writeFile19)(localPath, data);
|
|
473646
473905
|
console.log(JSON.stringify({
|
|
473647
473906
|
path: localPath,
|
|
@@ -474551,7 +474810,7 @@ var init_setup7 = __esm(async () => {
|
|
|
474551
474810
|
});
|
|
474552
474811
|
|
|
474553
474812
|
// src/cli/subcommands/shared-memory.ts
|
|
474554
|
-
import { existsSync as
|
|
474813
|
+
import { existsSync as existsSync68 } from "node:fs";
|
|
474555
474814
|
import { join as join98 } from "node:path";
|
|
474556
474815
|
import { parseArgs as parseArgs19 } from "node:util";
|
|
474557
474816
|
function printUsage16() {
|
|
@@ -474744,7 +475003,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
|
|
|
474744
475003
|
invalidateClientSkills(agentId);
|
|
474745
475004
|
const recompileError = await recompileAndReportFailure(recompileAgent, agentId);
|
|
474746
475005
|
const mountDir = getRepositoryMountDir(agentId, repository.name);
|
|
474747
|
-
const mounted =
|
|
475006
|
+
const mounted = existsSync68(join98(mountDir, ".git"));
|
|
474748
475007
|
console.log(JSON.stringify({
|
|
474749
475008
|
attached: true,
|
|
474750
475009
|
repository: { id: repository.id, name: repository.name },
|
|
@@ -476273,7 +476532,7 @@ var init_AgentSelector = __esm(async () => {
|
|
|
476273
476532
|
// src/cli/subcommands/skills.ts
|
|
476274
476533
|
import {
|
|
476275
476534
|
cpSync as cpSync2,
|
|
476276
|
-
existsSync as
|
|
476535
|
+
existsSync as existsSync69,
|
|
476277
476536
|
mkdtempSync as mkdtempSync6,
|
|
476278
476537
|
readFileSync as readFileSync51,
|
|
476279
476538
|
rmSync as rmSync25,
|
|
@@ -476282,7 +476541,7 @@ import {
|
|
|
476282
476541
|
} from "node:fs";
|
|
476283
476542
|
import { mkdir as mkdir16, readdir as readdir13 } from "node:fs/promises";
|
|
476284
476543
|
import { tmpdir as tmpdir14 } from "node:os";
|
|
476285
|
-
import { basename as
|
|
476544
|
+
import { basename as basename30, dirname as dirname39, join as join99, normalize as normalize4, resolve as resolve41, sep as sep8 } from "node:path";
|
|
476286
476545
|
import { parseArgs as parseArgs20, TextDecoder as TextDecoder2, TextEncoder as TextEncoder2 } from "node:util";
|
|
476287
476546
|
function printUsage17() {
|
|
476288
476547
|
console.log(`
|
|
@@ -476477,7 +476736,7 @@ function parseDirectSkillFileUrlSpecifier(input) {
|
|
|
476477
476736
|
if (url2.protocol !== "https:" && !(url2.protocol === "http:" && isLocalhostHostname(url2.hostname))) {
|
|
476478
476737
|
return null;
|
|
476479
476738
|
}
|
|
476480
|
-
if (
|
|
476739
|
+
if (basename30(url2.pathname).toLowerCase() !== "skill.md")
|
|
476481
476740
|
return null;
|
|
476482
476741
|
return { url: url2.toString() };
|
|
476483
476742
|
}
|
|
@@ -476725,14 +476984,14 @@ function getSkillName(sourceDir) {
|
|
|
476725
476984
|
const skillMd = readFileSync51(join99(sourceDir, "SKILL.md"), "utf8");
|
|
476726
476985
|
const { frontmatter } = parseFrontmatter(skillMd);
|
|
476727
476986
|
const frontmatterName = frontmatter.name;
|
|
476728
|
-
const name = typeof frontmatterName === "string" && frontmatterName.trim() ? frontmatterName :
|
|
476987
|
+
const name = typeof frontmatterName === "string" && frontmatterName.trim() ? frontmatterName : basename30(sourceDir);
|
|
476729
476988
|
return sanitizeSkillName(name);
|
|
476730
476989
|
}
|
|
476731
476990
|
async function installSkillDirectory(params) {
|
|
476732
476991
|
const sourceDir = resolve41(params.sourceDir);
|
|
476733
476992
|
const memoryDir = resolve41(params.memoryDir);
|
|
476734
476993
|
const skillMdPath = join99(sourceDir, "SKILL.md");
|
|
476735
|
-
if (!
|
|
476994
|
+
if (!existsSync69(skillMdPath)) {
|
|
476736
476995
|
throw new Error("No SKILL.md found in the skill directory.");
|
|
476737
476996
|
}
|
|
476738
476997
|
if (!statSync26(sourceDir).isDirectory()) {
|
|
@@ -476742,7 +477001,7 @@ async function installSkillDirectory(params) {
|
|
|
476742
477001
|
const skillsDir = join99(memoryDir, "skills");
|
|
476743
477002
|
const targetPath = join99(skillsDir, name);
|
|
476744
477003
|
assertInside(skillsDir, targetPath);
|
|
476745
|
-
if (
|
|
477004
|
+
if (existsSync69(targetPath)) {
|
|
476746
477005
|
if (!params.force) {
|
|
476747
477006
|
throw new Error(`Skill "${name}" already exists at ${targetPath}. Re-run with --force to replace it.`);
|
|
476748
477007
|
}
|
|
@@ -476751,14 +477010,14 @@ async function installSkillDirectory(params) {
|
|
|
476751
477010
|
await mkdir16(skillsDir, { recursive: true });
|
|
476752
477011
|
cpSync2(sourceDir, targetPath, {
|
|
476753
477012
|
recursive: true,
|
|
476754
|
-
filter: (source) =>
|
|
477013
|
+
filter: (source) => basename30(source) !== ".git"
|
|
476755
477014
|
});
|
|
476756
477015
|
return { name, path: normalize4(targetPath) };
|
|
476757
477016
|
}
|
|
476758
477017
|
async function listSkillDirectories(params) {
|
|
476759
477018
|
const memoryDir = resolve41(params.memoryDir);
|
|
476760
477019
|
const skillsDir = join99(memoryDir, "skills");
|
|
476761
|
-
if (!
|
|
477020
|
+
if (!existsSync69(skillsDir))
|
|
476762
477021
|
return [];
|
|
476763
477022
|
const entries2 = await readdir13(skillsDir, { withFileTypes: true });
|
|
476764
477023
|
const skills = [];
|
|
@@ -476767,7 +477026,7 @@ async function listSkillDirectories(params) {
|
|
|
476767
477026
|
continue;
|
|
476768
477027
|
const skillDir = join99(skillsDir, entry.name);
|
|
476769
477028
|
const skillMdPath = join99(skillDir, "SKILL.md");
|
|
476770
|
-
if (!
|
|
477029
|
+
if (!existsSync69(skillMdPath))
|
|
476771
477030
|
continue;
|
|
476772
477031
|
let name = entry.name;
|
|
476773
477032
|
let description;
|
|
@@ -476791,7 +477050,7 @@ async function deleteSkillDirectory(params) {
|
|
|
476791
477050
|
const name = sanitizeSkillName(params.name);
|
|
476792
477051
|
const targetPath = join99(skillsDir, name);
|
|
476793
477052
|
assertInside(skillsDir, targetPath);
|
|
476794
|
-
if (!
|
|
477053
|
+
if (!existsSync69(targetPath)) {
|
|
476795
477054
|
throw new Error(`Skill "${name}" is not installed at ${targetPath}.`);
|
|
476796
477055
|
}
|
|
476797
477056
|
if (!statSync26(targetPath).isDirectory()) {
|
|
@@ -476840,7 +477099,7 @@ async function installSkill(specifier, agentId, force) {
|
|
|
476840
477099
|
tmpDir = downloaded.tmpDir;
|
|
476841
477100
|
const sourceDir = resolve41(downloaded.sourceDir);
|
|
476842
477101
|
assertInside(tmpDir, sourceDir);
|
|
476843
|
-
if (!
|
|
477102
|
+
if (!existsSync69(sourceDir)) {
|
|
476844
477103
|
const missingPath = source.type === "git" ? source.location.subdir ?? "." : source.type === "direct-file" ? source.location.url : source.location.slug;
|
|
476845
477104
|
throw new Error(`Skill path not found: ${missingPath}`);
|
|
476846
477105
|
}
|
|
@@ -477471,7 +477730,7 @@ import {
|
|
|
477471
477730
|
stat as stat17,
|
|
477472
477731
|
writeFile as writeFile20
|
|
477473
477732
|
} from "node:fs/promises";
|
|
477474
|
-
import { basename as
|
|
477733
|
+
import { basename as basename31, join as join101 } from "node:path";
|
|
477475
477734
|
function fileTimestamp(startedAt) {
|
|
477476
477735
|
if (!startedAt)
|
|
477477
477736
|
return "unknown-date";
|
|
@@ -477639,10 +477898,10 @@ async function runTrajectoryExport(options) {
|
|
|
477639
477898
|
if (!supported.includes(explicit.source)) {
|
|
477640
477899
|
throw new Error(`Unknown source "${explicit.source}" in --transcript. The installed trajectory package supports: ${supported.join(", ")}.`);
|
|
477641
477900
|
}
|
|
477642
|
-
await exportTranscript(explicit.source,
|
|
477901
|
+
await exportTranscript(explicit.source, basename31(explicit.path).replace(/\.[^.]+$/, ""), explicit.path, () => readFile29(explicit.path, "utf-8"));
|
|
477643
477902
|
}
|
|
477644
477903
|
for (const checkpoint of options.deepagents ?? []) {
|
|
477645
|
-
await exportCheckpoint(checkpoint, `${
|
|
477904
|
+
await exportCheckpoint(checkpoint, `${basename31(checkpoint.path)}-${checkpoint.threadId}`);
|
|
477646
477905
|
}
|
|
477647
477906
|
manifest2.sessions.sort((a2, b3) => (a2.startedAt ?? "").localeCompare(b3.startedAt ?? ""));
|
|
477648
477907
|
await writeFile20(join101(options.outDir, MANIFEST_NAME), JSON.stringify(manifest2, null, 2), "utf-8");
|
|
@@ -481090,7 +481349,7 @@ var init_message_channel_gateway_tool = __esm(() => {
|
|
|
481090
481349
|
});
|
|
481091
481350
|
|
|
481092
481351
|
// src/channels/custom/scaffolding.ts
|
|
481093
|
-
import { existsSync as
|
|
481352
|
+
import { existsSync as existsSync70, mkdirSync as mkdirSync51, rmSync as rmSync26, writeFileSync as writeFileSync43 } from "node:fs";
|
|
481094
481353
|
function removeUserPlugin(channelId) {
|
|
481095
481354
|
if (FIRST_PARTY_SET.has(channelId)) {
|
|
481096
481355
|
return;
|
|
@@ -481099,7 +481358,7 @@ function removeUserPlugin(channelId) {
|
|
|
481099
481358
|
return;
|
|
481100
481359
|
}
|
|
481101
481360
|
const channelDir = getChannelDir(channelId);
|
|
481102
|
-
if (!
|
|
481361
|
+
if (!existsSync70(channelDir)) {
|
|
481103
481362
|
return;
|
|
481104
481363
|
}
|
|
481105
481364
|
try {
|
|
@@ -487878,7 +488137,7 @@ var BYTES_PER_TOKEN = 4;
|
|
|
487878
488137
|
|
|
487879
488138
|
// src/cli/helpers/window-title-config.ts
|
|
487880
488139
|
import { homedir as homedir55 } from "node:os";
|
|
487881
|
-
import { basename as
|
|
488140
|
+
import { basename as basename32, resolve as resolve42 } from "node:path";
|
|
487882
488141
|
function isWindowTitleField(value) {
|
|
487883
488142
|
return WINDOW_TITLE_FIELDS.includes(value);
|
|
487884
488143
|
}
|
|
@@ -488037,7 +488296,7 @@ function terminalTitleProjectName(data) {
|
|
|
488037
488296
|
if (!directory)
|
|
488038
488297
|
return null;
|
|
488039
488298
|
const resolved2 = resolve42(directory);
|
|
488040
|
-
const name =
|
|
488299
|
+
const name = basename32(resolved2) || formatDirectoryDisplay(resolved2) || resolved2;
|
|
488041
488300
|
return truncateTerminalTitlePart(name, 24);
|
|
488042
488301
|
}
|
|
488043
488302
|
function titleDirectory(data) {
|
|
@@ -488719,7 +488978,7 @@ var init_cli_mod_context = __esm(() => {
|
|
|
488719
488978
|
|
|
488720
488979
|
// src/cli/helpers/reflection-arena-hf-upload.ts
|
|
488721
488980
|
import { execFile as execFileCb5 } from "node:child_process";
|
|
488722
|
-
import { existsSync as
|
|
488981
|
+
import { existsSync as existsSync72 } from "node:fs";
|
|
488723
488982
|
import { appendFile as appendFile3, chmod, mkdir as mkdir18, writeFile as writeFile21 } from "node:fs/promises";
|
|
488724
488983
|
import { homedir as homedir56 } from "node:os";
|
|
488725
488984
|
import { join as join105 } from "node:path";
|
|
@@ -488773,7 +489032,7 @@ async function writeGitAskpass(repoRoot) {
|
|
|
488773
489032
|
}
|
|
488774
489033
|
async function prepareHfRepo(env6) {
|
|
488775
489034
|
await mkdir18(HF_CACHE_ROOT, { recursive: true });
|
|
488776
|
-
if (!
|
|
489035
|
+
if (!existsSync72(join105(HF_REPO_DIR, ".git"))) {
|
|
488777
489036
|
await runGit6(HF_CACHE_ROOT, ["clone", "--depth", "1", HF_REPO_URL, HF_REPO_DIR], env6);
|
|
488778
489037
|
return HF_REPO_DIR;
|
|
488779
489038
|
}
|
|
@@ -490332,7 +490591,7 @@ __export(exports_terminal_keybinding_installer, {
|
|
|
490332
490591
|
});
|
|
490333
490592
|
import {
|
|
490334
490593
|
copyFileSync as copyFileSync6,
|
|
490335
|
-
existsSync as
|
|
490594
|
+
existsSync as existsSync73,
|
|
490336
490595
|
mkdirSync as mkdirSync53,
|
|
490337
490596
|
readFileSync as readFileSync53,
|
|
490338
490597
|
writeFileSync as writeFileSync45
|
|
@@ -490401,7 +490660,7 @@ function parseKeybindings(content) {
|
|
|
490401
490660
|
}
|
|
490402
490661
|
}
|
|
490403
490662
|
function keybindingExists(keybindingsPath) {
|
|
490404
|
-
if (!
|
|
490663
|
+
if (!existsSync73(keybindingsPath))
|
|
490405
490664
|
return false;
|
|
490406
490665
|
try {
|
|
490407
490666
|
const content = readFileSync53(keybindingsPath, { encoding: "utf-8" });
|
|
@@ -490414,7 +490673,7 @@ function keybindingExists(keybindingsPath) {
|
|
|
490414
490673
|
}
|
|
490415
490674
|
}
|
|
490416
490675
|
function createBackup(keybindingsPath) {
|
|
490417
|
-
if (!
|
|
490676
|
+
if (!existsSync73(keybindingsPath))
|
|
490418
490677
|
return null;
|
|
490419
490678
|
const backupPath = `${keybindingsPath}.letta-backup`;
|
|
490420
490679
|
try {
|
|
@@ -490430,12 +490689,12 @@ function installKeybinding(keybindingsPath) {
|
|
|
490430
490689
|
return { success: true, alreadyExists: true };
|
|
490431
490690
|
}
|
|
490432
490691
|
const parentDir = dirname40(keybindingsPath);
|
|
490433
|
-
if (!
|
|
490692
|
+
if (!existsSync73(parentDir)) {
|
|
490434
490693
|
mkdirSync53(parentDir, { recursive: true });
|
|
490435
490694
|
}
|
|
490436
490695
|
let keybindings = [];
|
|
490437
490696
|
let backupPath = null;
|
|
490438
|
-
if (
|
|
490697
|
+
if (existsSync73(keybindingsPath)) {
|
|
490439
490698
|
backupPath = createBackup(keybindingsPath);
|
|
490440
490699
|
const content = readFileSync53(keybindingsPath, { encoding: "utf-8" });
|
|
490441
490700
|
const parsed = parseKeybindings(content);
|
|
@@ -490465,7 +490724,7 @@ function installKeybinding(keybindingsPath) {
|
|
|
490465
490724
|
}
|
|
490466
490725
|
function removeKeybinding(keybindingsPath) {
|
|
490467
490726
|
try {
|
|
490468
|
-
if (!
|
|
490727
|
+
if (!existsSync73(keybindingsPath)) {
|
|
490469
490728
|
return { success: true };
|
|
490470
490729
|
}
|
|
490471
490730
|
const content = readFileSync53(keybindingsPath, { encoding: "utf-8" });
|
|
@@ -490533,11 +490792,11 @@ function getWezTermConfigPath() {
|
|
|
490533
490792
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
490534
490793
|
if (xdgConfig) {
|
|
490535
490794
|
const xdgPath = join107(xdgConfig, "wezterm", "wezterm.lua");
|
|
490536
|
-
if (
|
|
490795
|
+
if (existsSync73(xdgPath))
|
|
490537
490796
|
return xdgPath;
|
|
490538
490797
|
}
|
|
490539
490798
|
const configPath = join107(homedir58(), ".config", "wezterm", "wezterm.lua");
|
|
490540
|
-
if (
|
|
490799
|
+
if (existsSync73(configPath))
|
|
490541
490800
|
return configPath;
|
|
490542
490801
|
return join107(homedir58(), ".wezterm.lua");
|
|
490543
490802
|
}
|
|
@@ -490642,7 +490901,7 @@ ${WEZTERM_DELETE_FIX}
|
|
|
490642
490901
|
`;
|
|
490643
490902
|
}
|
|
490644
490903
|
function wezTermDeleteFixExists(configPath) {
|
|
490645
|
-
if (!
|
|
490904
|
+
if (!existsSync73(configPath))
|
|
490646
490905
|
return false;
|
|
490647
490906
|
try {
|
|
490648
490907
|
const content = readFileSync53(configPath, { encoding: "utf-8" });
|
|
@@ -490659,14 +490918,14 @@ function installWezTermDeleteFix() {
|
|
|
490659
490918
|
}
|
|
490660
490919
|
let content = "";
|
|
490661
490920
|
let backupPath = null;
|
|
490662
|
-
if (
|
|
490921
|
+
if (existsSync73(configPath)) {
|
|
490663
490922
|
backupPath = `${configPath}.letta-backup`;
|
|
490664
490923
|
copyFileSync6(configPath, backupPath);
|
|
490665
490924
|
content = readFileSync53(configPath, { encoding: "utf-8" });
|
|
490666
490925
|
}
|
|
490667
490926
|
content = injectWezTermDeleteFix(content);
|
|
490668
490927
|
const parentDir = dirname40(configPath);
|
|
490669
|
-
if (!
|
|
490928
|
+
if (!existsSync73(parentDir)) {
|
|
490670
490929
|
mkdirSync53(parentDir, { recursive: true });
|
|
490671
490930
|
}
|
|
490672
490931
|
writeFileSync45(configPath, content, { encoding: "utf-8" });
|
|
@@ -492663,9 +492922,9 @@ function getHeaderText(fileEdit) {
|
|
|
492663
492922
|
const relPath = relative13(cwd2, fileEdit.filePath);
|
|
492664
492923
|
const displayPath = relPath.startsWith("..") ? fileEdit.filePath : relPath;
|
|
492665
492924
|
if (t2 === "write") {
|
|
492666
|
-
const { existsSync:
|
|
492925
|
+
const { existsSync: existsSync74 } = __require("node:fs");
|
|
492667
492926
|
try {
|
|
492668
|
-
if (
|
|
492927
|
+
if (existsSync74(fileEdit.filePath)) {
|
|
492669
492928
|
return `Overwrite ${displayPath}?`;
|
|
492670
492929
|
}
|
|
492671
492930
|
} catch {}
|
|
@@ -501582,9 +501841,9 @@ var init_InputRich = __esm(async () => {
|
|
|
501582
501841
|
});
|
|
501583
501842
|
|
|
501584
501843
|
// src/cli/commands/install-github-app.ts
|
|
501585
|
-
import { execFileSync as
|
|
501844
|
+
import { execFileSync as execFileSync12 } from "node:child_process";
|
|
501586
501845
|
import {
|
|
501587
|
-
existsSync as
|
|
501846
|
+
existsSync as existsSync74,
|
|
501588
501847
|
mkdirSync as mkdirSync54,
|
|
501589
501848
|
mkdtempSync as mkdtempSync7,
|
|
501590
501849
|
readFileSync as readFileSync54,
|
|
@@ -501595,7 +501854,7 @@ import { tmpdir as tmpdir15 } from "node:os";
|
|
|
501595
501854
|
import { dirname as dirname41, join as join109 } from "node:path";
|
|
501596
501855
|
function runCommand(command, args, cwd2, input) {
|
|
501597
501856
|
try {
|
|
501598
|
-
return
|
|
501857
|
+
return execFileSync12(command, args, {
|
|
501599
501858
|
cwd: cwd2,
|
|
501600
501859
|
encoding: "utf8",
|
|
501601
501860
|
stdio: [input ? "pipe" : "ignore", "pipe", "pipe"],
|
|
@@ -501826,12 +502085,12 @@ function runGit7(args, cwd2) {
|
|
|
501826
502085
|
}
|
|
501827
502086
|
function writeWorkflow(repoDir, workflowPath, content) {
|
|
501828
502087
|
const absolutePath = join109(repoDir, workflowPath);
|
|
501829
|
-
if (!
|
|
502088
|
+
if (!existsSync74(dirname41(absolutePath))) {
|
|
501830
502089
|
mkdirSync54(dirname41(absolutePath), { recursive: true });
|
|
501831
502090
|
}
|
|
501832
502091
|
const next = `${content.trimEnd()}
|
|
501833
502092
|
`;
|
|
501834
|
-
if (
|
|
502093
|
+
if (existsSync74(absolutePath)) {
|
|
501835
502094
|
const previous = readFileSync54(absolutePath, "utf8");
|
|
501836
502095
|
if (previous === next) {
|
|
501837
502096
|
return false;
|
|
@@ -505721,7 +505980,7 @@ __export(exports_generate_memory_viewer, {
|
|
|
505721
505980
|
generateAndOpenMemoryViewer: () => generateAndOpenMemoryViewer
|
|
505722
505981
|
});
|
|
505723
505982
|
import { execFile as execFileCb7 } from "node:child_process";
|
|
505724
|
-
import { chmodSync as chmodSync8, existsSync as
|
|
505983
|
+
import { chmodSync as chmodSync8, existsSync as existsSync75, mkdirSync as mkdirSync55, writeFileSync as writeFileSync47 } from "node:fs";
|
|
505725
505984
|
import { homedir as homedir61 } from "node:os";
|
|
505726
505985
|
import { join as join110 } from "node:path";
|
|
505727
505986
|
import { promisify as promisify22 } from "node:util";
|
|
@@ -506032,7 +506291,7 @@ ${m4.body}` : m4.subject;
|
|
|
506032
506291
|
async function generateAndOpenMemoryViewer(agentId, options) {
|
|
506033
506292
|
const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
506034
506293
|
const repoDir = memoryRoot;
|
|
506035
|
-
if (!
|
|
506294
|
+
if (!existsSync75(join110(repoDir, ".git"))) {
|
|
506036
506295
|
throw new Error("Memory viewer requires memfs. Run /memfs enable first.");
|
|
506037
506296
|
}
|
|
506038
506297
|
const data = await collectMemoryData(agentId, repoDir, memoryRoot, options?.conversationId);
|
|
@@ -506042,7 +506301,7 @@ async function generateAndOpenMemoryViewer(agentId, options) {
|
|
|
506042
506301
|
data.context = applyContextUsageSnapshot(data.context, options?.contextUsage);
|
|
506043
506302
|
const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
|
|
506044
506303
|
const html5 = memory_viewer_template_default.replace("<!--LETTA_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
506045
|
-
if (!
|
|
506304
|
+
if (!existsSync75(VIEWERS_DIR)) {
|
|
506046
506305
|
mkdirSync55(VIEWERS_DIR, { recursive: true, mode: 448 });
|
|
506047
506306
|
}
|
|
506048
506307
|
try {
|
|
@@ -506079,7 +506338,7 @@ var init_generate_memory_viewer = __esm(() => {
|
|
|
506079
506338
|
});
|
|
506080
506339
|
|
|
506081
506340
|
// src/cli/components/MemfsTreeViewer.tsx
|
|
506082
|
-
import { existsSync as
|
|
506341
|
+
import { existsSync as existsSync76 } from "node:fs";
|
|
506083
506342
|
import { join as join111 } from "node:path";
|
|
506084
506343
|
function renderTreePrefix(node) {
|
|
506085
506344
|
let prefix = "";
|
|
@@ -506108,8 +506367,8 @@ function MemfsTreeViewer({
|
|
|
506108
506367
|
const [status, setStatus] = import_react88.useState(null);
|
|
506109
506368
|
const statusTimerRef = import_react88.useRef(null);
|
|
506110
506369
|
const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
506111
|
-
const memoryExists =
|
|
506112
|
-
const hasGitRepo = import_react88.useMemo(() =>
|
|
506370
|
+
const memoryExists = existsSync76(memoryRoot);
|
|
506371
|
+
const hasGitRepo = import_react88.useMemo(() => existsSync76(join111(memoryRoot, ".git")), [memoryRoot]);
|
|
506113
506372
|
function showStatus(msg, durationMs) {
|
|
506114
506373
|
if (statusTimerRef.current)
|
|
506115
506374
|
clearTimeout(statusTimerRef.current);
|
|
@@ -514956,9 +515215,9 @@ function getFileEditHeader(toolName2, toolArgs) {
|
|
|
514956
515215
|
const relPath = relative13(cwd2, filePath);
|
|
514957
515216
|
const displayPath = relPath.startsWith("..") ? filePath : relPath;
|
|
514958
515217
|
if (t2 === "write") {
|
|
514959
|
-
const { existsSync:
|
|
515218
|
+
const { existsSync: existsSync77 } = __require("node:fs");
|
|
514960
515219
|
try {
|
|
514961
|
-
if (
|
|
515220
|
+
if (existsSync77(filePath)) {
|
|
514962
515221
|
return `Overwrite ${displayPath}?`;
|
|
514963
515222
|
}
|
|
514964
515223
|
} catch {}
|
|
@@ -516726,7 +516985,7 @@ __export(exports_generate_diff_viewer, {
|
|
|
516726
516985
|
generateAndOpenDiffViewer: () => generateAndOpenDiffViewer
|
|
516727
516986
|
});
|
|
516728
516987
|
import { execFile as execFileCb8 } from "node:child_process";
|
|
516729
|
-
import { chmodSync as chmodSync9, existsSync as
|
|
516988
|
+
import { chmodSync as chmodSync9, existsSync as existsSync77, mkdirSync as mkdirSync56, writeFileSync as writeFileSync48 } from "node:fs";
|
|
516730
516989
|
import { homedir as homedir63 } from "node:os";
|
|
516731
516990
|
import { isAbsolute as isAbsolute27, join as join113, resolve as resolve44 } from "node:path";
|
|
516732
516991
|
import { promisify as promisify23 } from "node:util";
|
|
@@ -516951,7 +517210,7 @@ async function generateAndOpenDiffViewer(targetPath) {
|
|
|
516951
517210
|
};
|
|
516952
517211
|
const jsonPayload = JSON.stringify(payload).replace(/</g, "\\u003c");
|
|
516953
517212
|
const html5 = diff_viewer_template_default.replace("<!--LETTA_DIFF_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
516954
|
-
if (!
|
|
517213
|
+
if (!existsSync77(VIEWERS_DIR2)) {
|
|
516955
517214
|
mkdirSync56(VIEWERS_DIR2, { recursive: true, mode: 448 });
|
|
516956
517215
|
}
|
|
516957
517216
|
try {
|
|
@@ -518987,12 +519246,12 @@ __export(exports_shell_aliases, {
|
|
|
518987
519246
|
expandAliases: () => expandAliases,
|
|
518988
519247
|
clearAliasCache: () => clearAliasCache
|
|
518989
519248
|
});
|
|
518990
|
-
import { existsSync as
|
|
519249
|
+
import { existsSync as existsSync78, readFileSync as readFileSync55 } from "node:fs";
|
|
518991
519250
|
import { homedir as homedir64 } from "node:os";
|
|
518992
519251
|
import { join as join114 } from "node:path";
|
|
518993
519252
|
function parseAliasesFromFile(filePath) {
|
|
518994
519253
|
const aliases = new Map;
|
|
518995
|
-
if (!
|
|
519254
|
+
if (!existsSync78(filePath)) {
|
|
518996
519255
|
return aliases;
|
|
518997
519256
|
}
|
|
518998
519257
|
try {
|
|
@@ -520207,6 +520466,16 @@ var init_retry2 = __esm(() => {
|
|
|
520207
520466
|
function stripSystemReminders2(text3) {
|
|
520208
520467
|
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();
|
|
520209
520468
|
}
|
|
520469
|
+
function getRestorableUserText(input) {
|
|
520470
|
+
const message2 = input.find((item) => item?.type === "message");
|
|
520471
|
+
const content = message2 && "content" in message2 ? message2.content : undefined;
|
|
520472
|
+
if (typeof content === "string")
|
|
520473
|
+
return stripSystemReminders2(content);
|
|
520474
|
+
if (!Array.isArray(content))
|
|
520475
|
+
return "";
|
|
520476
|
+
return content.flatMap((c) => c.type === "text" && !c.text.includes(SYSTEM_REMINDER_OPEN) && !c.text.includes(SYSTEM_ALERT_OPEN) ? [c.text] : []).join(`
|
|
520477
|
+
`).trim();
|
|
520478
|
+
}
|
|
520210
520479
|
var init_system_reminders2 = __esm(() => {
|
|
520211
520480
|
init_constants2();
|
|
520212
520481
|
});
|
|
@@ -520739,20 +521008,9 @@ function useConversationLoop(ctx) {
|
|
|
520739
521008
|
const agent = await getBackend().retrieveAgent(agentIdRef.current);
|
|
520740
521009
|
const { pendingApprovals: serverApprovals } = await getResumeDataFromBackend(agent, conversationIdRef.current);
|
|
520741
521010
|
if (serverApprovals && serverApprovals.length > 0) {
|
|
520742
|
-
const
|
|
520743
|
-
if (
|
|
520744
|
-
|
|
520745
|
-
let textToRestore = "";
|
|
520746
|
-
if (typeof content === "string") {
|
|
520747
|
-
textToRestore = stripSystemReminders2(content);
|
|
520748
|
-
} else if (Array.isArray(content)) {
|
|
520749
|
-
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(`
|
|
520750
|
-
`);
|
|
520751
|
-
}
|
|
520752
|
-
if (textToRestore.trim()) {
|
|
520753
|
-
setRestoredInput(textToRestore);
|
|
520754
|
-
}
|
|
520755
|
-
}
|
|
521011
|
+
const textToRestore = getRestorableUserText(currentInput);
|
|
521012
|
+
if (textToRestore)
|
|
521013
|
+
setRestoredInput(textToRestore);
|
|
520756
521014
|
setApprovalResults([]);
|
|
520757
521015
|
setAutoHandledResults([]);
|
|
520758
521016
|
setAutoDeniedApprovals([]);
|
|
@@ -520770,6 +521028,13 @@ function useConversationLoop(ctx) {
|
|
|
520770
521028
|
sendDesktopNotification("Approval needed");
|
|
520771
521029
|
return;
|
|
520772
521030
|
}
|
|
521031
|
+
const plainInput = rebuildInputWithFreshDenials(currentInput, [], "");
|
|
521032
|
+
if (plainInput.length > 0 && llmApiErrorRetriesRef.current < LLM_API_ERROR_MAX_RETRIES3) {
|
|
521033
|
+
llmApiErrorRetriesRef.current += 1;
|
|
521034
|
+
currentInput = plainInput;
|
|
521035
|
+
buffersRef.current.interrupted = false;
|
|
521036
|
+
continue;
|
|
521037
|
+
}
|
|
520773
521038
|
} catch {}
|
|
520774
521039
|
}
|
|
520775
521040
|
}
|
|
@@ -521375,20 +521640,9 @@ ${feedback}
|
|
|
521375
521640
|
const agent = await getBackend().retrieveAgent(agentIdRef.current);
|
|
521376
521641
|
const { pendingApprovals: serverApprovals } = await getResumeDataFromBackend(agent, conversationIdRef.current);
|
|
521377
521642
|
if (serverApprovals && serverApprovals.length > 0) {
|
|
521378
|
-
const
|
|
521379
|
-
if (
|
|
521380
|
-
|
|
521381
|
-
let textToRestore = "";
|
|
521382
|
-
if (typeof content === "string") {
|
|
521383
|
-
textToRestore = stripSystemReminders2(content);
|
|
521384
|
-
} else if (Array.isArray(content)) {
|
|
521385
|
-
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(`
|
|
521386
|
-
`);
|
|
521387
|
-
}
|
|
521388
|
-
if (textToRestore.trim()) {
|
|
521389
|
-
setRestoredInput(textToRestore);
|
|
521390
|
-
}
|
|
521391
|
-
}
|
|
521643
|
+
const textToRestore = getRestorableUserText(currentInput);
|
|
521644
|
+
if (textToRestore)
|
|
521645
|
+
setRestoredInput(textToRestore);
|
|
521392
521646
|
setApprovalResults([]);
|
|
521393
521647
|
setAutoHandledResults([]);
|
|
521394
521648
|
setAutoDeniedApprovals([]);
|
|
@@ -521406,6 +521660,13 @@ ${feedback}
|
|
|
521406
521660
|
sendDesktopNotification("Approval needed");
|
|
521407
521661
|
return;
|
|
521408
521662
|
}
|
|
521663
|
+
const plainInput = rebuildInputWithFreshDenials(currentInput, [], "");
|
|
521664
|
+
if (plainInput.length > 0 && llmApiErrorRetriesRef.current < LLM_API_ERROR_MAX_RETRIES3) {
|
|
521665
|
+
llmApiErrorRetriesRef.current += 1;
|
|
521666
|
+
currentInput = plainInput;
|
|
521667
|
+
buffersRef.current.interrupted = false;
|
|
521668
|
+
continue;
|
|
521669
|
+
}
|
|
521409
521670
|
} catch {}
|
|
521410
521671
|
}
|
|
521411
521672
|
const approvalPendingDetected = isApprovalPendingError(detailFromRun) || isApprovalPendingError(latestErrorText);
|
|
@@ -521755,7 +522016,6 @@ var init_use_conversation_loop = __esm(async () => {
|
|
|
521755
522016
|
init_reflection_transcript();
|
|
521756
522017
|
init_thinking_messages();
|
|
521757
522018
|
init_tool_name_mapping2();
|
|
521758
|
-
init_constants2();
|
|
521759
522019
|
init_hooks();
|
|
521760
522020
|
init_format_denial();
|
|
521761
522021
|
init_mode();
|
|
@@ -527092,7 +527352,7 @@ __export(exports_worktree_diff_list, {
|
|
|
527092
527352
|
listWorktreeDiffOptions: () => listWorktreeDiffOptions
|
|
527093
527353
|
});
|
|
527094
527354
|
import { execFile as execFileCb9 } from "node:child_process";
|
|
527095
|
-
import { basename as
|
|
527355
|
+
import { basename as basename33 } from "node:path";
|
|
527096
527356
|
import { promisify as promisify24 } from "node:util";
|
|
527097
527357
|
async function runGit9(cwd2, args) {
|
|
527098
527358
|
try {
|
|
@@ -527141,7 +527401,7 @@ function parseWorktreeList(output, currentPath) {
|
|
|
527141
527401
|
if (current?.path) {
|
|
527142
527402
|
worktrees.push({
|
|
527143
527403
|
path: current.path,
|
|
527144
|
-
name:
|
|
527404
|
+
name: basename33(current.path),
|
|
527145
527405
|
branch: current.branch ?? "detached",
|
|
527146
527406
|
head: current.head ?? "",
|
|
527147
527407
|
isCurrent: current.path === currentPath,
|
|
@@ -527167,7 +527427,7 @@ function parseWorktreeList(output, currentPath) {
|
|
|
527167
527427
|
if (current?.path) {
|
|
527168
527428
|
worktrees.push({
|
|
527169
527429
|
path: current.path,
|
|
527170
|
-
name:
|
|
527430
|
+
name: basename33(current.path),
|
|
527171
527431
|
branch: current.branch ?? "detached",
|
|
527172
527432
|
head: current.head ?? "",
|
|
527173
527433
|
isCurrent: current.path === currentPath,
|
|
@@ -527324,7 +527584,7 @@ var init_conversation_switch_alert = __esm(() => {
|
|
|
527324
527584
|
|
|
527325
527585
|
// src/cli/app/use-submit-handler.ts
|
|
527326
527586
|
import { randomUUID as randomUUID67 } from "node:crypto";
|
|
527327
|
-
import { existsSync as
|
|
527587
|
+
import { existsSync as existsSync79, readFileSync as readFileSync56, renameSync as renameSync12 } from "node:fs";
|
|
527328
527588
|
import { tmpdir as tmpdir16 } from "node:os";
|
|
527329
527589
|
import { join as join115 } from "node:path";
|
|
527330
527590
|
async function findCustomCommandByName(commandName) {
|
|
@@ -527937,7 +528197,7 @@ ${SYSTEM_REMINDER_CLOSE}`),
|
|
|
527937
528197
|
join115(memoryRoot, "system", "persona.md"),
|
|
527938
528198
|
join115(memoryRoot, "memory", "system", "persona.md")
|
|
527939
528199
|
];
|
|
527940
|
-
const personaPath = personaCandidates.find((candidate) =>
|
|
528200
|
+
const personaPath = personaCandidates.find((candidate) => existsSync79(candidate));
|
|
527941
528201
|
if (personaPath) {
|
|
527942
528202
|
const personaContent = readFileSync56(personaPath, "utf-8");
|
|
527943
528203
|
setCurrentPersonalityId(detectPersonalityFromPersonaFile(personaContent));
|
|
@@ -528779,12 +529039,12 @@ Path: ${memoryDir}`, true);
|
|
|
528779
529039
|
setCommandRunning(true);
|
|
528780
529040
|
try {
|
|
528781
529041
|
const memoryDir = getScopedMemoryFilesystemRoot(agentId);
|
|
528782
|
-
if (!
|
|
529042
|
+
if (!existsSync79(memoryDir)) {
|
|
528783
529043
|
updateMemorySyncCommand(cmdId, "No local memory filesystem found to reset.", true, msg);
|
|
528784
529044
|
return { submitted: true };
|
|
528785
529045
|
}
|
|
528786
529046
|
const backupDir = join115(tmpdir16(), `letta-memfs-reset-${agentId}-${Date.now()}`);
|
|
528787
|
-
|
|
529047
|
+
renameSync12(memoryDir, backupDir);
|
|
528788
529048
|
if (getBackend().capabilities.localMemfs) {
|
|
528789
529049
|
const { initializeLocalMemoryRepo: initializeLocalMemoryRepo2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
|
|
528790
529050
|
await initializeLocalMemoryRepo2({
|
|
@@ -531737,9 +531997,9 @@ Memory may be stale. Try running: git -C ${getScopedMemoryFilesystemRoot(agentId
|
|
|
531737
531997
|
(async () => {
|
|
531738
531998
|
try {
|
|
531739
531999
|
const { watch: watch4 } = await import("node:fs");
|
|
531740
|
-
const { existsSync:
|
|
532000
|
+
const { existsSync: existsSync80 } = await import("node:fs");
|
|
531741
532001
|
const memRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
531742
|
-
if (!
|
|
532002
|
+
if (!existsSync80(memRoot))
|
|
531743
532003
|
return;
|
|
531744
532004
|
watcher2 = watch4(memRoot, { recursive: true }, () => {});
|
|
531745
532005
|
memfsWatcherRef.current = watcher2;
|
|
@@ -533540,7 +533800,9 @@ async function main() {
|
|
|
533540
533800
|
}
|
|
533541
533801
|
const subcommandResult = await runSubcommand(subcommandArgs);
|
|
533542
533802
|
if (subcommandResult !== null) {
|
|
533543
|
-
process.
|
|
533803
|
+
process.channel?.unref();
|
|
533804
|
+
process.exitCode = subcommandResult;
|
|
533805
|
+
return;
|
|
533544
533806
|
}
|
|
533545
533807
|
await settingsManager.initialize();
|
|
533546
533808
|
const settings3 = await settingsManager.getSettingsWithSecureTokens();
|
|
@@ -537159,4 +537421,4 @@ function registerBunOAuthFlows() {
|
|
|
537159
537421
|
registerBunOAuthFlows();
|
|
537160
537422
|
await init_src5().then(() => exports_src2);
|
|
537161
537423
|
|
|
537162
|
-
//# debugId=
|
|
537424
|
+
//# debugId=F0CE6FA9F2A192C264756E2164756E21
|