@letta-ai/letta-code 0.30.4 → 0.30.5
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/agent-presets.js +125 -19
- package/dist/agent-presets.js.map +3 -3
- package/dist/mcp-client.js +2 -2
- package/dist/mcp-client.js.map +1 -1
- package/dist/types/agent/create-agent-request.d.ts +55 -25
- package/dist/types/agent/create-agent-request.d.ts.map +1 -1
- package/dist/types/agent/modify.d.ts.map +1 -1
- package/dist/types/agent/subagents/index.d.ts +1 -0
- package/dist/types/agent/subagents/index.d.ts.map +1 -1
- package/dist/types/agent/subagents/manager.d.ts +1 -0
- package/dist/types/agent/subagents/manager.d.ts.map +1 -1
- package/dist/types/agent/subagents/subagent-launcher.d.ts.map +1 -1
- package/dist/types/agent-presets.d.ts +1 -1
- package/dist/types/agent-presets.d.ts.map +1 -1
- package/dist/types/cli/helpers/memory-reminder.d.ts +9 -3
- package/dist/types/cli/helpers/memory-reminder.d.ts.map +1 -1
- package/dist/types/reflection-settings.d.ts +9 -0
- package/dist/types/reflection-settings.d.ts.map +1 -0
- package/dist/types/settings-manager.d.ts +9 -10
- package/dist/types/settings-manager.d.ts.map +1 -1
- package/dist/types/telemetry/index.d.ts +15 -1
- package/dist/types/telemetry/index.d.ts.map +1 -1
- package/dist/types/tools/impl/process_manager.d.ts +1 -0
- package/dist/types/tools/impl/process_manager.d.ts.map +1 -1
- package/dist/types/tools/impl/task.d.ts +4 -0
- package/dist/types/tools/impl/task.d.ts.map +1 -1
- package/dist/types/types/protocol_v2.d.ts +5 -0
- package/dist/types/types/protocol_v2.d.ts.map +1 -1
- package/dist/types/websocket/listener/protocol-outbound.d.ts.map +1 -1
- package/letta.js +1493 -807
- package/package.json +1 -1
- package/scripts/isolated-unit-tests.json +11 -0
- package/scripts/source-file-size-baseline.json +4 -4
- package/skills/managing-shared-memory/SKILL.md +47 -81
package/letta.js
CHANGED
|
@@ -5359,7 +5359,9 @@ var init_settings_manager = __esm(() => {
|
|
|
5359
5359
|
recentModels: [],
|
|
5360
5360
|
memoryReminderInterval: 25,
|
|
5361
5361
|
reflectionTrigger: "step-count",
|
|
5362
|
-
reflectionStepCount: 25
|
|
5362
|
+
reflectionStepCount: 25,
|
|
5363
|
+
reflectionMerge: "auto",
|
|
5364
|
+
reflectionMergeInstructions: ""
|
|
5363
5365
|
};
|
|
5364
5366
|
DEFAULT_PROJECT_SETTINGS = {};
|
|
5365
5367
|
DEFAULT_LOCAL_PROJECT_SETTINGS = {
|
|
@@ -5462,7 +5464,7 @@ var package_default;
|
|
|
5462
5464
|
var init_package = __esm(() => {
|
|
5463
5465
|
package_default = {
|
|
5464
5466
|
name: "@letta-ai/letta-code",
|
|
5465
|
-
version: "0.30.
|
|
5467
|
+
version: "0.30.5",
|
|
5466
5468
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
5467
5469
|
type: "module",
|
|
5468
5470
|
packageManager: "bun@1.3.0",
|
|
@@ -6486,6 +6488,14 @@ class TelemetryManager {
|
|
|
6486
6488
|
};
|
|
6487
6489
|
this.track("reflection_end", data);
|
|
6488
6490
|
}
|
|
6491
|
+
trackReflectionWorktreeCleanup(options) {
|
|
6492
|
+
const data = {
|
|
6493
|
+
...options,
|
|
6494
|
+
version: getVersion(),
|
|
6495
|
+
platform: process.platform
|
|
6496
|
+
};
|
|
6497
|
+
this.track("reflection_worktree_cleanup", data);
|
|
6498
|
+
}
|
|
6489
6499
|
trackReflectionArenaVote(vote) {
|
|
6490
6500
|
this.track("reflection_arena_vote", {
|
|
6491
6501
|
...vote,
|
|
@@ -141415,6 +141425,73 @@ var init_models7 = __esm(() => {
|
|
|
141415
141425
|
parallel_tool_calls: true
|
|
141416
141426
|
}
|
|
141417
141427
|
},
|
|
141428
|
+
{
|
|
141429
|
+
id: "opus-5",
|
|
141430
|
+
handle: "anthropic/claude-opus-5",
|
|
141431
|
+
label: "Opus 5",
|
|
141432
|
+
description: "Opus 5 (high reasoning)",
|
|
141433
|
+
updateArgs: {
|
|
141434
|
+
context_window: 200000,
|
|
141435
|
+
max_output_tokens: 128000,
|
|
141436
|
+
enable_reasoner: true,
|
|
141437
|
+
reasoning_effort: "high",
|
|
141438
|
+
parallel_tool_calls: true
|
|
141439
|
+
}
|
|
141440
|
+
},
|
|
141441
|
+
{
|
|
141442
|
+
id: "opus-5-low",
|
|
141443
|
+
handle: "anthropic/claude-opus-5",
|
|
141444
|
+
label: "Opus 5",
|
|
141445
|
+
description: "Opus 5 (low reasoning)",
|
|
141446
|
+
updateArgs: {
|
|
141447
|
+
context_window: 200000,
|
|
141448
|
+
max_output_tokens: 128000,
|
|
141449
|
+
enable_reasoner: true,
|
|
141450
|
+
reasoning_effort: "low",
|
|
141451
|
+
max_reasoning_tokens: 4000,
|
|
141452
|
+
parallel_tool_calls: true
|
|
141453
|
+
}
|
|
141454
|
+
},
|
|
141455
|
+
{
|
|
141456
|
+
id: "opus-5-medium",
|
|
141457
|
+
handle: "anthropic/claude-opus-5",
|
|
141458
|
+
label: "Opus 5",
|
|
141459
|
+
description: "Opus 5 (med reasoning)",
|
|
141460
|
+
updateArgs: {
|
|
141461
|
+
context_window: 200000,
|
|
141462
|
+
max_output_tokens: 128000,
|
|
141463
|
+
enable_reasoner: true,
|
|
141464
|
+
reasoning_effort: "medium",
|
|
141465
|
+
max_reasoning_tokens: 12000,
|
|
141466
|
+
parallel_tool_calls: true
|
|
141467
|
+
}
|
|
141468
|
+
},
|
|
141469
|
+
{
|
|
141470
|
+
id: "opus-5-xhigh",
|
|
141471
|
+
handle: "anthropic/claude-opus-5",
|
|
141472
|
+
label: "Opus 5",
|
|
141473
|
+
description: "Opus 5 (extra-high reasoning)",
|
|
141474
|
+
updateArgs: {
|
|
141475
|
+
context_window: 200000,
|
|
141476
|
+
max_output_tokens: 128000,
|
|
141477
|
+
enable_reasoner: true,
|
|
141478
|
+
reasoning_effort: "xhigh",
|
|
141479
|
+
parallel_tool_calls: true
|
|
141480
|
+
}
|
|
141481
|
+
},
|
|
141482
|
+
{
|
|
141483
|
+
id: "opus-5-max",
|
|
141484
|
+
handle: "anthropic/claude-opus-5",
|
|
141485
|
+
label: "Opus 5",
|
|
141486
|
+
description: "Opus 5 (max reasoning)",
|
|
141487
|
+
updateArgs: {
|
|
141488
|
+
context_window: 200000,
|
|
141489
|
+
max_output_tokens: 128000,
|
|
141490
|
+
enable_reasoner: true,
|
|
141491
|
+
reasoning_effort: "max",
|
|
141492
|
+
parallel_tool_calls: true
|
|
141493
|
+
}
|
|
141494
|
+
},
|
|
141418
141495
|
{
|
|
141419
141496
|
id: "opus",
|
|
141420
141497
|
handle: "anthropic/claude-opus-4-8",
|
|
@@ -141689,7 +141766,7 @@ var init_models7 = __esm(() => {
|
|
|
141689
141766
|
id: "sonnet-5-xhigh",
|
|
141690
141767
|
handle: "anthropic/claude-sonnet-5",
|
|
141691
141768
|
label: "Sonnet 5",
|
|
141692
|
-
description: "Sonnet 5 (
|
|
141769
|
+
description: "Sonnet 5 (extra-high reasoning)",
|
|
141693
141770
|
updateArgs: {
|
|
141694
141771
|
context_window: 1e6,
|
|
141695
141772
|
max_output_tokens: 128000,
|
|
@@ -141698,6 +141775,19 @@ var init_models7 = __esm(() => {
|
|
|
141698
141775
|
parallel_tool_calls: true
|
|
141699
141776
|
}
|
|
141700
141777
|
},
|
|
141778
|
+
{
|
|
141779
|
+
id: "sonnet-5-max",
|
|
141780
|
+
handle: "anthropic/claude-sonnet-5",
|
|
141781
|
+
label: "Sonnet 5",
|
|
141782
|
+
description: "Sonnet 5 (max reasoning)",
|
|
141783
|
+
updateArgs: {
|
|
141784
|
+
context_window: 1e6,
|
|
141785
|
+
max_output_tokens: 128000,
|
|
141786
|
+
reasoning_effort: "max",
|
|
141787
|
+
enable_reasoner: true,
|
|
141788
|
+
parallel_tool_calls: true
|
|
141789
|
+
}
|
|
141790
|
+
},
|
|
141701
141791
|
{
|
|
141702
141792
|
id: "sonnet-4.6",
|
|
141703
141793
|
handle: "anthropic/claude-sonnet-4-6",
|
|
@@ -145321,7 +145411,7 @@ __export(exports_modify, {
|
|
|
145321
145411
|
__modifyTestUtils: () => __modifyTestUtils
|
|
145322
145412
|
});
|
|
145323
145413
|
function supportsDistinctAnthropicXHighEffort(modelHandle) {
|
|
145324
|
-
return modelHandle.includes("claude-fable-5") || modelHandle.includes("claude-opus-4-7") || modelHandle.includes("claude-opus-4-8");
|
|
145414
|
+
return modelHandle.includes("claude-fable-5") || modelHandle.includes("claude-opus-5") || modelHandle.includes("claude-sonnet-5") || modelHandle.includes("claude-opus-4-7") || modelHandle.includes("claude-opus-4-8");
|
|
145325
145415
|
}
|
|
145326
145416
|
function buildModelSettings(modelHandle, updateArgs) {
|
|
145327
145417
|
const explicitProviderType = typeof updateArgs?.provider_type === "string" ? updateArgs.provider_type : undefined;
|
|
@@ -175417,10 +175507,18 @@ function normalizeTrigger(value, fallback) {
|
|
|
175417
175507
|
}
|
|
175418
175508
|
return fallback;
|
|
175419
175509
|
}
|
|
175510
|
+
function normalizeMerge(value, fallback) {
|
|
175511
|
+
return value === "auto" || value === "explicit" ? value : fallback;
|
|
175512
|
+
}
|
|
175513
|
+
function normalizeMergeInstructions(value, fallback) {
|
|
175514
|
+
return typeof value === "string" ? value.trim() : fallback;
|
|
175515
|
+
}
|
|
175420
175516
|
function applyExplicitReflectionOverrides(base2, raw) {
|
|
175421
175517
|
return {
|
|
175422
175518
|
trigger: normalizeTrigger(raw.reflectionTrigger, base2.trigger),
|
|
175423
|
-
stepCount: normalizeStepCount(raw.reflectionStepCount, base2.stepCount)
|
|
175519
|
+
stepCount: normalizeStepCount(raw.reflectionStepCount, base2.stepCount),
|
|
175520
|
+
merge: normalizeMerge(raw.reflectionMerge, base2.merge),
|
|
175521
|
+
mergeInstructions: normalizeMergeInstructions(raw.reflectionMergeInstructions, base2.mergeInstructions)
|
|
175424
175522
|
};
|
|
175425
175523
|
}
|
|
175426
175524
|
function applyPersistedAgentScopedSettings(base2, raw) {
|
|
@@ -175429,32 +175527,42 @@ function applyPersistedAgentScopedSettings(base2, raw) {
|
|
|
175429
175527
|
}
|
|
175430
175528
|
return {
|
|
175431
175529
|
trigger: normalizeTrigger(raw.trigger, base2.trigger),
|
|
175432
|
-
stepCount: normalizeStepCount(raw.stepCount, base2.stepCount)
|
|
175530
|
+
stepCount: normalizeStepCount(raw.stepCount, base2.stepCount),
|
|
175531
|
+
merge: normalizeMerge(raw.merge, base2.merge),
|
|
175532
|
+
mergeInstructions: normalizeMergeInstructions(raw.mergeInstructions, base2.mergeInstructions)
|
|
175433
175533
|
};
|
|
175434
175534
|
}
|
|
175435
175535
|
function legacyModeToReflectionSettings(mode) {
|
|
175436
175536
|
if (typeof mode === "number") {
|
|
175437
175537
|
return {
|
|
175438
175538
|
trigger: "step-count",
|
|
175439
|
-
stepCount: normalizeStepCount(mode, DEFAULT_STEP_COUNT)
|
|
175539
|
+
stepCount: normalizeStepCount(mode, DEFAULT_STEP_COUNT),
|
|
175540
|
+
merge: DEFAULT_REFLECTION_SETTINGS.merge,
|
|
175541
|
+
mergeInstructions: DEFAULT_REFLECTION_SETTINGS.mergeInstructions
|
|
175440
175542
|
};
|
|
175441
175543
|
}
|
|
175442
175544
|
if (mode === null) {
|
|
175443
175545
|
return {
|
|
175444
175546
|
trigger: "off",
|
|
175445
|
-
stepCount: DEFAULT_REFLECTION_SETTINGS.stepCount
|
|
175547
|
+
stepCount: DEFAULT_REFLECTION_SETTINGS.stepCount,
|
|
175548
|
+
merge: DEFAULT_REFLECTION_SETTINGS.merge,
|
|
175549
|
+
mergeInstructions: DEFAULT_REFLECTION_SETTINGS.mergeInstructions
|
|
175446
175550
|
};
|
|
175447
175551
|
}
|
|
175448
175552
|
if (mode === "compaction") {
|
|
175449
175553
|
return {
|
|
175450
175554
|
trigger: "compaction-event",
|
|
175451
|
-
stepCount: DEFAULT_REFLECTION_SETTINGS.stepCount
|
|
175555
|
+
stepCount: DEFAULT_REFLECTION_SETTINGS.stepCount,
|
|
175556
|
+
merge: DEFAULT_REFLECTION_SETTINGS.merge,
|
|
175557
|
+
mergeInstructions: DEFAULT_REFLECTION_SETTINGS.mergeInstructions
|
|
175452
175558
|
};
|
|
175453
175559
|
}
|
|
175454
175560
|
if (mode === "auto-compaction") {
|
|
175455
175561
|
return {
|
|
175456
175562
|
trigger: "compaction-event",
|
|
175457
|
-
stepCount: DEFAULT_REFLECTION_SETTINGS.stepCount
|
|
175563
|
+
stepCount: DEFAULT_REFLECTION_SETTINGS.stepCount,
|
|
175564
|
+
merge: DEFAULT_REFLECTION_SETTINGS.merge,
|
|
175565
|
+
mergeInstructions: DEFAULT_REFLECTION_SETTINGS.mergeInstructions
|
|
175458
175566
|
};
|
|
175459
175567
|
}
|
|
175460
175568
|
return { ...DEFAULT_REFLECTION_SETTINGS };
|
|
@@ -175476,16 +175584,6 @@ function getReflectionSettings(agentId, workingDirectory = process.cwd()) {
|
|
|
175476
175584
|
} catch {
|
|
175477
175585
|
localSettings = null;
|
|
175478
175586
|
}
|
|
175479
|
-
if (agentId) {
|
|
175480
|
-
const localScoped = localSettings?.reflectionSettingsByAgent?.[agentId];
|
|
175481
|
-
if (localScoped) {
|
|
175482
|
-
return applyPersistedAgentScopedSettings(DEFAULT_REFLECTION_SETTINGS, localScoped);
|
|
175483
|
-
}
|
|
175484
|
-
const globalScoped = globalSettings.reflectionSettingsByAgent?.[agentId];
|
|
175485
|
-
if (globalScoped) {
|
|
175486
|
-
return applyPersistedAgentScopedSettings(DEFAULT_REFLECTION_SETTINGS, globalScoped);
|
|
175487
|
-
}
|
|
175488
|
-
}
|
|
175489
175587
|
let resolved = legacyModeToReflectionSettings(globalSettings.memoryReminderInterval);
|
|
175490
175588
|
resolved = applyExplicitReflectionOverrides(resolved, globalSettings);
|
|
175491
175589
|
if (localSettings) {
|
|
@@ -175494,6 +175592,10 @@ function getReflectionSettings(agentId, workingDirectory = process.cwd()) {
|
|
|
175494
175592
|
}
|
|
175495
175593
|
resolved = applyExplicitReflectionOverrides(resolved, localSettings);
|
|
175496
175594
|
}
|
|
175595
|
+
if (agentId) {
|
|
175596
|
+
resolved = applyPersistedAgentScopedSettings(resolved, globalSettings.reflectionSettingsByAgent?.[agentId]);
|
|
175597
|
+
resolved = applyPersistedAgentScopedSettings(resolved, localSettings?.reflectionSettingsByAgent?.[agentId]);
|
|
175598
|
+
}
|
|
175497
175599
|
return resolved;
|
|
175498
175600
|
}
|
|
175499
175601
|
function shouldFireStepCountTrigger(stepsSinceLastSuccessfulReflection, settings3 = getReflectionSettings()) {
|
|
@@ -175509,6 +175611,8 @@ async function persistReflectionSettingsForAgent(agentId, settings3, options3 =
|
|
|
175509
175611
|
persistLocalProject = true,
|
|
175510
175612
|
persistGlobal = true
|
|
175511
175613
|
} = options3;
|
|
175614
|
+
const merge2 = normalizeMerge(settings3.merge, DEFAULT_REFLECTION_SETTINGS.merge);
|
|
175615
|
+
const mergeInstructions = normalizeMergeInstructions(settings3.mergeInstructions, DEFAULT_REFLECTION_SETTINGS.mergeInstructions);
|
|
175512
175616
|
const legacyMode = reflectionSettingsToLegacyMode(settings3);
|
|
175513
175617
|
if (persistLocalProject) {
|
|
175514
175618
|
try {
|
|
@@ -175521,11 +175625,15 @@ async function persistReflectionSettingsForAgent(agentId, settings3, options3 =
|
|
|
175521
175625
|
memoryReminderInterval: legacyMode,
|
|
175522
175626
|
reflectionTrigger: settings3.trigger,
|
|
175523
175627
|
reflectionStepCount: settings3.stepCount,
|
|
175628
|
+
reflectionMerge: merge2,
|
|
175629
|
+
reflectionMergeInstructions: mergeInstructions,
|
|
175524
175630
|
reflectionSettingsByAgent: {
|
|
175525
175631
|
...localSettings.reflectionSettingsByAgent ?? {},
|
|
175526
175632
|
[agentId]: {
|
|
175527
175633
|
trigger: settings3.trigger,
|
|
175528
|
-
stepCount: settings3.stepCount
|
|
175634
|
+
stepCount: settings3.stepCount,
|
|
175635
|
+
merge: merge2,
|
|
175636
|
+
mergeInstructions
|
|
175529
175637
|
}
|
|
175530
175638
|
}
|
|
175531
175639
|
}, workingDirectory);
|
|
@@ -175536,11 +175644,15 @@ async function persistReflectionSettingsForAgent(agentId, settings3, options3 =
|
|
|
175536
175644
|
memoryReminderInterval: legacyMode,
|
|
175537
175645
|
reflectionTrigger: settings3.trigger,
|
|
175538
175646
|
reflectionStepCount: settings3.stepCount,
|
|
175647
|
+
reflectionMerge: merge2,
|
|
175648
|
+
reflectionMergeInstructions: mergeInstructions,
|
|
175539
175649
|
reflectionSettingsByAgent: {
|
|
175540
175650
|
...globalSettings.reflectionSettingsByAgent ?? {},
|
|
175541
175651
|
[agentId]: {
|
|
175542
175652
|
trigger: settings3.trigger,
|
|
175543
|
-
stepCount: settings3.stepCount
|
|
175653
|
+
stepCount: settings3.stepCount,
|
|
175654
|
+
merge: merge2,
|
|
175655
|
+
mergeInstructions
|
|
175544
175656
|
}
|
|
175545
175657
|
}
|
|
175546
175658
|
});
|
|
@@ -175551,7 +175663,9 @@ var init_memory_reminder = __esm(() => {
|
|
|
175551
175663
|
init_settings_manager();
|
|
175552
175664
|
DEFAULT_REFLECTION_SETTINGS = {
|
|
175553
175665
|
trigger: "compaction-event",
|
|
175554
|
-
stepCount: DEFAULT_STEP_COUNT
|
|
175666
|
+
stepCount: DEFAULT_STEP_COUNT,
|
|
175667
|
+
merge: "auto",
|
|
175668
|
+
mergeInstructions: ""
|
|
175555
175669
|
};
|
|
175556
175670
|
});
|
|
175557
175671
|
|
|
@@ -175694,7 +175808,7 @@ function buildBackgroundProcessSnapshot(agentId, conversationId = "default") {
|
|
|
175694
175808
|
const taskProcesses = Array.from(backgroundTasks.entries()).filter(([, task]) => task.status === "running" && (!runtimeScope || belongsToRuntime(task, runtimeScope))).map(([processId, task]) => ({
|
|
175695
175809
|
process_id: processId,
|
|
175696
175810
|
kind: "agent_task",
|
|
175697
|
-
task_type: task.subagentType,
|
|
175811
|
+
task_type: task.displayType ?? task.subagentType,
|
|
175698
175812
|
description: task.description,
|
|
175699
175813
|
started_at_ms: task.startTime.getTime(),
|
|
175700
175814
|
status: task.status,
|
|
@@ -349572,7 +349686,9 @@ function buildDeviceStatus(runtime, params) {
|
|
|
349572
349686
|
reflection_settings: scopedAgentId ? {
|
|
349573
349687
|
agent_id: scopedAgentId,
|
|
349574
349688
|
trigger: reflectionSettings?.trigger ?? "compaction-event",
|
|
349575
|
-
step_count: reflectionSettings?.stepCount ?? 25
|
|
349689
|
+
step_count: reflectionSettings?.stepCount ?? 25,
|
|
349690
|
+
merge: reflectionSettings?.merge ?? "auto",
|
|
349691
|
+
merge_instructions: reflectionSettings?.mergeInstructions ?? ""
|
|
349576
349692
|
} : null
|
|
349577
349693
|
};
|
|
349578
349694
|
}
|
|
@@ -364685,6 +364801,9 @@ function resolveSubagentWorkingDirectory(env3 = process.env, fallbackCwd = getCu
|
|
|
364685
364801
|
if (options3.subagentType === "reflection" && options3.launchProfile === "memory-subagent" && options3.memoryScope) {
|
|
364686
364802
|
return env3.USER_CWD || fallbackCwd;
|
|
364687
364803
|
}
|
|
364804
|
+
if (options3.subagentType !== "reflection" && options3.launchProfile === "memory-subagent" && options3.memoryScope?.primaryRoot) {
|
|
364805
|
+
return options3.memoryScope.primaryRoot;
|
|
364806
|
+
}
|
|
364688
364807
|
const primaryRoot = options3.memoryScope?.primaryRoot ?? options3.inheritedPrimaryRoot;
|
|
364689
364808
|
if (options3.subagentType === "reflection" && options3.launchProfile === "memory-subagent" && primaryRoot) {
|
|
364690
364809
|
return primaryRoot;
|
|
@@ -365231,13 +365350,14 @@ function buildSubagentArgs(type3, config3, model, userPrompt, existingAgentId, e
|
|
|
365231
365350
|
return args;
|
|
365232
365351
|
}
|
|
365233
365352
|
async function executeSubagent(type3, config3, model, userPrompt, subagentId, isRetry = false, signal, existingAgentId, existingConversationId, maxTurns, parentAgentIdOverride, transcriptPath, memoryScope, systemPromptOverride) {
|
|
365353
|
+
const withModel = (result) => model ? { ...result, model } : result;
|
|
365234
365354
|
if (signal?.aborted) {
|
|
365235
|
-
return {
|
|
365355
|
+
return withModel({
|
|
365236
365356
|
agentId: "",
|
|
365237
365357
|
report: "",
|
|
365238
365358
|
success: false,
|
|
365239
365359
|
error: INTERRUPTED_BY_USER
|
|
365240
|
-
};
|
|
365360
|
+
});
|
|
365241
365361
|
}
|
|
365242
365362
|
if (model) {
|
|
365243
365363
|
updateSubagent(subagentId, { model });
|
|
@@ -365268,6 +365388,7 @@ async function executeSubagent(type3, config3, model, userPrompt, subagentId, is
|
|
|
365268
365388
|
const inheritedMemoryRoots = resolveAllowedMemoryRoots({
|
|
365269
365389
|
currentAgentId: parentAgentId ?? null
|
|
365270
365390
|
});
|
|
365391
|
+
const effectiveLaunchProfile = memoryScope ? "memory-subagent" : config3.launchProfile;
|
|
365271
365392
|
const localBackendStorageDir = backendMode === "local" ? getLocalBackendStorageDir2() : null;
|
|
365272
365393
|
const inheritedPrimaryRoot = resolveSubagentInheritedPrimaryRoot({
|
|
365273
365394
|
backendMode,
|
|
@@ -365277,7 +365398,7 @@ async function executeSubagent(type3, config3, model, userPrompt, subagentId, is
|
|
|
365277
365398
|
});
|
|
365278
365399
|
const subagentWorkingDirectory = resolveSubagentWorkingDirectory(process.env, getCurrentWorkingDirectory(), {
|
|
365279
365400
|
subagentType: type3,
|
|
365280
|
-
launchProfile:
|
|
365401
|
+
launchProfile: effectiveLaunchProfile,
|
|
365281
365402
|
inheritedPrimaryRoot,
|
|
365282
365403
|
memoryScope
|
|
365283
365404
|
});
|
|
@@ -365289,7 +365410,7 @@ async function executeSubagent(type3, config3, model, userPrompt, subagentId, is
|
|
|
365289
365410
|
backendMode,
|
|
365290
365411
|
localBackendStorageDir,
|
|
365291
365412
|
parentAgentId,
|
|
365292
|
-
launchProfile:
|
|
365413
|
+
launchProfile: effectiveLaunchProfile,
|
|
365293
365414
|
inheritedPrimaryRoot,
|
|
365294
365415
|
memoryScope,
|
|
365295
365416
|
inheritedApiKey,
|
|
@@ -365299,7 +365420,7 @@ async function executeSubagent(type3, config3, model, userPrompt, subagentId, is
|
|
|
365299
365420
|
});
|
|
365300
365421
|
const sandbox = wrapSubagentLauncher({
|
|
365301
365422
|
launcher,
|
|
365302
|
-
launchProfile:
|
|
365423
|
+
launchProfile: effectiveLaunchProfile,
|
|
365303
365424
|
backendMode,
|
|
365304
365425
|
memoryRoots: inheritedMemoryRoots.roots,
|
|
365305
365426
|
inheritedPrimaryRoot,
|
|
@@ -365359,13 +365480,13 @@ async function executeSubagent(type3, config3, model, userPrompt, subagentId, is
|
|
|
365359
365480
|
}
|
|
365360
365481
|
signal?.removeEventListener("abort", abortHandler);
|
|
365361
365482
|
if (wasAborted) {
|
|
365362
|
-
return {
|
|
365483
|
+
return withModel({
|
|
365363
365484
|
agentId: state.agentId || "",
|
|
365364
365485
|
conversationId: state.conversationId || undefined,
|
|
365365
365486
|
report: "",
|
|
365366
365487
|
success: false,
|
|
365367
365488
|
error: INTERRUPTED_BY_USER
|
|
365368
|
-
};
|
|
365489
|
+
});
|
|
365369
365490
|
}
|
|
365370
365491
|
const stderr = Buffer.concat(stderrChunks).toString("utf-8").trim();
|
|
365371
365492
|
if (exitCode !== 0) {
|
|
@@ -365383,16 +365504,16 @@ async function executeSubagent(type3, config3, model, userPrompt, subagentId, is
|
|
|
365383
365504
|
}
|
|
365384
365505
|
const propagatedError = state.finalError?.trim();
|
|
365385
365506
|
const fallbackError = stderr || `Subagent exited with code ${exitCode}`;
|
|
365386
|
-
return {
|
|
365507
|
+
return withModel({
|
|
365387
365508
|
agentId: state.agentId || "",
|
|
365388
365509
|
conversationId: state.conversationId || undefined,
|
|
365389
365510
|
report: "",
|
|
365390
365511
|
success: false,
|
|
365391
365512
|
error: propagatedError || fallbackError
|
|
365392
|
-
};
|
|
365513
|
+
});
|
|
365393
365514
|
}
|
|
365394
365515
|
if (state.finalResult !== null) {
|
|
365395
|
-
return {
|
|
365516
|
+
return withModel({
|
|
365396
365517
|
agentId: state.agentId || "",
|
|
365397
365518
|
conversationId: state.conversationId || undefined,
|
|
365398
365519
|
report: state.finalResult,
|
|
@@ -365401,11 +365522,11 @@ async function executeSubagent(type3, config3, model, userPrompt, subagentId, is
|
|
|
365401
365522
|
totalTokens: state.resultStats?.totalTokens,
|
|
365402
365523
|
stepCount: state.resultStats?.stepCount,
|
|
365403
365524
|
durationMs: state.resultStats?.durationMs
|
|
365404
|
-
};
|
|
365525
|
+
});
|
|
365405
365526
|
}
|
|
365406
365527
|
if (state.finalError) {
|
|
365407
365528
|
debugWarn("subagent", `Subagent ${subagentId} (agentId=${state.agentId}) exited with captured error: ${state.finalError}. ` + `exitCode=${exitCode}, stderr=${stderr.length} bytes`);
|
|
365408
|
-
return {
|
|
365529
|
+
return withModel({
|
|
365409
365530
|
agentId: state.agentId || "",
|
|
365410
365531
|
conversationId: state.conversationId || undefined,
|
|
365411
365532
|
report: "",
|
|
@@ -365414,7 +365535,7 @@ async function executeSubagent(type3, config3, model, userPrompt, subagentId, is
|
|
|
365414
365535
|
totalTokens: state.resultStats?.totalTokens,
|
|
365415
365536
|
stepCount: state.resultStats?.stepCount,
|
|
365416
365537
|
durationMs: state.resultStats?.durationMs
|
|
365417
|
-
};
|
|
365538
|
+
});
|
|
365418
365539
|
}
|
|
365419
365540
|
debugWarn("subagent", `Subagent ${subagentId} (agentId=${state.agentId}) exited cleanly (exitCode=${exitCode}) ` + `but no result event was captured during streaming. ` + `stdout=${Buffer.concat(stdoutChunks).length} bytes, stderr=${stderr.length} bytes`);
|
|
365420
365541
|
const stdout = Buffer.concat(stdoutChunks).toString("utf-8");
|
|
@@ -365427,14 +365548,14 @@ async function executeSubagent(type3, config3, model, userPrompt, subagentId, is
|
|
|
365427
365548
|
return executeSubagent(type3, config3, model, userPrompt, subagentId, true, signal, existingAgentId, existingConversationId, maxTurns, parentAgentIdOverride, transcriptPath, memoryScope, systemPromptOverride);
|
|
365428
365549
|
}
|
|
365429
365550
|
}
|
|
365430
|
-
return result;
|
|
365551
|
+
return withModel(result);
|
|
365431
365552
|
} catch (error54) {
|
|
365432
|
-
return {
|
|
365553
|
+
return withModel({
|
|
365433
365554
|
agentId: "",
|
|
365434
365555
|
report: "",
|
|
365435
365556
|
success: false,
|
|
365436
365557
|
error: getErrorMessage2(error54)
|
|
365437
|
-
};
|
|
365558
|
+
});
|
|
365438
365559
|
}
|
|
365439
365560
|
}
|
|
365440
365561
|
function buildDeploySystemReminder(senderAgentName, senderAgentId) {
|
|
@@ -365446,6 +365567,9 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
365446
365567
|
|
|
365447
365568
|
`;
|
|
365448
365569
|
}
|
|
365570
|
+
function shouldPrependDeploySystemReminder(existingAgentId, parentAgentId) {
|
|
365571
|
+
return !existingAgentId || existingAgentId !== parentAgentId;
|
|
365572
|
+
}
|
|
365449
365573
|
function recallPromptForBackend(backendMode) {
|
|
365450
365574
|
return backendMode === "local" ? recall_subagent_local_default : recall_subagent_default;
|
|
365451
365575
|
}
|
|
@@ -365527,7 +365651,7 @@ async function spawnSubagent(type3, prompt, userModel, subagentId, signal, exist
|
|
|
365527
365651
|
if (forkedContext) {
|
|
365528
365652
|
const systemReminder = buildForkSystemReminder(type3, backendMode);
|
|
365529
365653
|
finalPrompt = systemReminder + prompt;
|
|
365530
|
-
} else {
|
|
365654
|
+
} else if (shouldPrependDeploySystemReminder(existingAgentId, resolvedParentAgentId)) {
|
|
365531
365655
|
const systemReminder = buildDeploySystemReminder(cachedParent.name ?? "", resolvedParentAgentId);
|
|
365532
365656
|
finalPrompt = systemReminder + prompt;
|
|
365533
365657
|
}
|
|
@@ -365687,6 +365811,7 @@ var init_task_notifications = __esm(() => {
|
|
|
365687
365811
|
var exports_task = {};
|
|
365688
365812
|
__export(exports_task, {
|
|
365689
365813
|
waitForBackgroundSubagentLink: () => waitForBackgroundSubagentLink,
|
|
365814
|
+
waitForBackgroundSubagentConversationId: () => waitForBackgroundSubagentConversationId,
|
|
365690
365815
|
waitForBackgroundSubagentAgentId: () => waitForBackgroundSubagentAgentId,
|
|
365691
365816
|
task: () => task,
|
|
365692
365817
|
spawnBackgroundSubagentTask: () => spawnBackgroundSubagentTask
|
|
@@ -365791,10 +365916,33 @@ async function waitForBackgroundSubagentAgentId(subagentId, timeoutMs = null, si
|
|
|
365791
365916
|
await sleep8(BACKGROUND_STARTUP_POLL_MS);
|
|
365792
365917
|
}
|
|
365793
365918
|
}
|
|
365919
|
+
async function waitForBackgroundSubagentConversationId(subagentId, timeoutMs = null, signal) {
|
|
365920
|
+
const deadline = timeoutMs !== null && timeoutMs > 0 ? Date.now() + timeoutMs : null;
|
|
365921
|
+
while (true) {
|
|
365922
|
+
if (signal?.aborted) {
|
|
365923
|
+
return null;
|
|
365924
|
+
}
|
|
365925
|
+
const agent2 = getSnapshot().agents.find((a) => a.id === subagentId);
|
|
365926
|
+
if (!agent2) {
|
|
365927
|
+
return null;
|
|
365928
|
+
}
|
|
365929
|
+
if (agent2.conversationId) {
|
|
365930
|
+
return agent2.conversationId;
|
|
365931
|
+
}
|
|
365932
|
+
if (agent2.status === "error" || agent2.status === "completed") {
|
|
365933
|
+
return agent2.conversationId ?? null;
|
|
365934
|
+
}
|
|
365935
|
+
if (deadline !== null && Date.now() >= deadline) {
|
|
365936
|
+
return agent2.conversationId ?? null;
|
|
365937
|
+
}
|
|
365938
|
+
await sleep8(BACKGROUND_STARTUP_POLL_MS);
|
|
365939
|
+
}
|
|
365940
|
+
}
|
|
365794
365941
|
function spawnBackgroundSubagentTask(args) {
|
|
365795
365942
|
assertBackgroundTaskCapacity();
|
|
365796
365943
|
const {
|
|
365797
365944
|
subagentType,
|
|
365945
|
+
displayType,
|
|
365798
365946
|
prompt,
|
|
365799
365947
|
description,
|
|
365800
365948
|
model,
|
|
@@ -365824,13 +365972,14 @@ function spawnBackgroundSubagentTask(args) {
|
|
|
365824
365972
|
const completeSubagentFn = deps?.completeSubagentImpl ?? completeSubagent;
|
|
365825
365973
|
const getSubagentSnapshotFn = deps?.getSubagentSnapshotImpl ?? getSnapshot;
|
|
365826
365974
|
const subagentId = generateSubagentIdFn();
|
|
365827
|
-
registerSubagentFn(subagentId, subagentType, description, toolCallId, true, silentCompletion, resolvedParentScope, prompt);
|
|
365975
|
+
registerSubagentFn(subagentId, displayType ?? subagentType, description, toolCallId, true, silentCompletion, resolvedParentScope, prompt);
|
|
365828
365976
|
const taskId = getNextTaskId();
|
|
365829
365977
|
const outputFile = createBackgroundOutputFile(taskId);
|
|
365830
365978
|
const abortController = new AbortController;
|
|
365831
365979
|
const bgTask = {
|
|
365832
365980
|
description,
|
|
365833
365981
|
subagentType,
|
|
365982
|
+
displayType,
|
|
365834
365983
|
subagentId,
|
|
365835
365984
|
status: "running",
|
|
365836
365985
|
output: [],
|
|
@@ -365864,6 +366013,7 @@ function spawnBackgroundSubagentTask(args) {
|
|
|
365864
366013
|
error: result.error,
|
|
365865
366014
|
agentId: result.agentId,
|
|
365866
366015
|
conversationId: result.conversationId,
|
|
366016
|
+
model: result.model,
|
|
365867
366017
|
stepCount: result.stepCount,
|
|
365868
366018
|
durationMs: result.durationMs,
|
|
365869
366019
|
report: result.report
|
|
@@ -384829,6 +384979,59 @@ var init_check_approval = __esm(() => {
|
|
|
384829
384979
|
});
|
|
384830
384980
|
|
|
384831
384981
|
// src/agent/create-agent-request.ts
|
|
384982
|
+
function mergeMemoryBlocks(base2, overrides) {
|
|
384983
|
+
const blocks = base2.map((block) => ({ ...block }));
|
|
384984
|
+
for (const override of overrides ?? []) {
|
|
384985
|
+
const index = blocks.findIndex((block) => block.label === override.label);
|
|
384986
|
+
if (index >= 0) {
|
|
384987
|
+
blocks[index] = { ...override };
|
|
384988
|
+
} else {
|
|
384989
|
+
blocks.push({ ...override });
|
|
384990
|
+
}
|
|
384991
|
+
}
|
|
384992
|
+
return blocks;
|
|
384993
|
+
}
|
|
384994
|
+
async function buildCreateAgentRequest(options3 = {}) {
|
|
384995
|
+
const personality = options3.personalityId ? getPersonalityOption(options3.personalityId) : undefined;
|
|
384996
|
+
const modelIdentifier = options3.model ?? personality?.defaultModel;
|
|
384997
|
+
const modelHandle = modelIdentifier ? resolveModel(modelIdentifier) : getDefaultModel();
|
|
384998
|
+
if (!modelHandle) {
|
|
384999
|
+
throw new Error(`Unknown model: ${modelIdentifier}`);
|
|
385000
|
+
}
|
|
385001
|
+
if (!options3.isSubagent && options3.enableMemfs !== undefined && options3.memoryPromptMode !== undefined && options3.enableMemfs !== (options3.memoryPromptMode !== "standard")) {
|
|
385002
|
+
throw new Error("enableMemfs and memoryPromptMode must describe the same memory mode");
|
|
385003
|
+
}
|
|
385004
|
+
const enableMemfs = options3.isSubagent ? false : options3.enableMemfs ?? options3.memoryPromptMode !== "standard";
|
|
385005
|
+
const memoryPromptMode = options3.isSubagent ? "standard" : options3.memoryPromptMode ?? (enableMemfs ? "memfs" : "standard");
|
|
385006
|
+
const personalityTags = options3.personalityId ? getPersonalityCreationTags(options3.personalityId) : [];
|
|
385007
|
+
const personalityBlocks = options3.personalityId ? buildPersonalityMemoryBlocks(options3.personalityId, await getDefaultMemoryBlocks()) : [];
|
|
385008
|
+
const memoryBlocks = options3.isSubagent ? undefined : options3.personalityId || options3.memoryBlocks !== undefined ? mergeMemoryBlocks(personalityBlocks, options3.memoryBlocks) : undefined;
|
|
385009
|
+
const blockIds = options3.isSubagent ? undefined : options3.blockIds;
|
|
385010
|
+
return {
|
|
385011
|
+
agent_type: LETTA_CODE_AGENT_TYPE,
|
|
385012
|
+
...options3.name !== undefined || personality ? { name: options3.name ?? personality?.label } : {},
|
|
385013
|
+
...options3.description !== undefined || personality ? { description: options3.description ?? personality?.description } : {},
|
|
385014
|
+
model: modelHandle,
|
|
385015
|
+
system: options3.system ?? buildSystemPrompt("default", memoryPromptMode),
|
|
385016
|
+
...memoryBlocks !== undefined ? { memory_blocks: memoryBlocks } : {},
|
|
385017
|
+
...blockIds && blockIds.length > 0 ? { block_ids: blockIds } : {},
|
|
385018
|
+
tags: buildCreatedAgentTags({
|
|
385019
|
+
enableMemfs,
|
|
385020
|
+
isSubagent: options3.isSubagent,
|
|
385021
|
+
tags: [...personalityTags, ...options3.extraTags ?? []]
|
|
385022
|
+
}),
|
|
385023
|
+
tools: [...options3.baseTools ?? DEFAULT_CREATED_AGENT_BASE_TOOLS],
|
|
385024
|
+
include_base_tools: false,
|
|
385025
|
+
include_base_tool_rules: false,
|
|
385026
|
+
initial_message_sequence: [],
|
|
385027
|
+
parallel_tool_calls: options3.parallelToolCalls ?? true,
|
|
385028
|
+
compaction_settings: {
|
|
385029
|
+
model: options3.compactionModel ?? DEFAULT_SUMMARIZATION_MODEL
|
|
385030
|
+
},
|
|
385031
|
+
...options3.embedding !== undefined ? { embedding: options3.embedding } : {},
|
|
385032
|
+
...options3.isSubagent ? { hidden: true } : options3.hidden !== undefined ? { hidden: options3.hidden } : {}
|
|
385033
|
+
};
|
|
385034
|
+
}
|
|
384832
385035
|
var LETTA_CODE_AGENT_TYPE = "letta_v1_agent", DEFAULT_CREATED_AGENT_BASE_TOOLS;
|
|
384833
385036
|
var init_create_agent_request = __esm(() => {
|
|
384834
385037
|
init_constants2();
|
|
@@ -384932,8 +385135,7 @@ async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingM
|
|
|
384932
385135
|
isLettaCloud: isLettaCloud2,
|
|
384933
385136
|
isSubagent
|
|
384934
385137
|
});
|
|
384935
|
-
const
|
|
384936
|
-
const toolNames = [...defaultBaseTools];
|
|
385138
|
+
const toolNames = options3.baseTools;
|
|
384937
385139
|
const referencedBlockIds = [];
|
|
384938
385140
|
let filteredMemoryBlocks;
|
|
384939
385141
|
if (options3.memoryBlocks !== undefined) {
|
|
@@ -384971,37 +385173,28 @@ async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingM
|
|
|
384971
385173
|
const contextWindow = modelUpdateArgs?.context_window ?? await getModelContextWindow(modelHandle);
|
|
384972
385174
|
const memMode = memfsConfig.memoryPromptMode;
|
|
384973
385175
|
const systemPromptContent = options3.systemPromptCustom ? options3.systemPromptCustom : await resolveAndBuildSystemPrompt(options3.systemPromptPreset, memMode);
|
|
384974
|
-
const tags = buildCreatedAgentTags({
|
|
384975
|
-
tags: options3.tags,
|
|
384976
|
-
isSubagent,
|
|
384977
|
-
enableMemfs: memfsConfig.enableMemfs
|
|
384978
|
-
});
|
|
384979
385176
|
const agentDescription = options3.description ?? `Letta Code agent created in ${process.cwd()}`;
|
|
384980
|
-
const createAgentRequestBase = {
|
|
384981
|
-
agent_type: LETTA_CODE_AGENT_TYPE,
|
|
384982
|
-
system: systemPromptContent,
|
|
385177
|
+
const createAgentRequestBase = await buildCreateAgentRequest({
|
|
384983
385178
|
name,
|
|
384984
385179
|
description: agentDescription,
|
|
384985
|
-
embedding: embeddingModelVal || undefined,
|
|
384986
385180
|
model: modelHandle,
|
|
384987
|
-
|
|
384988
|
-
|
|
384989
|
-
|
|
384990
|
-
|
|
384991
|
-
|
|
384992
|
-
|
|
384993
|
-
|
|
384994
|
-
|
|
384995
|
-
|
|
384996
|
-
|
|
384997
|
-
|
|
384998
|
-
}
|
|
384999
|
-
};
|
|
385181
|
+
system: systemPromptContent,
|
|
385182
|
+
memoryPromptMode: memMode,
|
|
385183
|
+
memoryBlocks: filteredMemoryBlocks.length > 0 ? filteredMemoryBlocks : undefined,
|
|
385184
|
+
blockIds: referencedBlockIds,
|
|
385185
|
+
extraTags: options3.tags,
|
|
385186
|
+
enableMemfs: memfsConfig.enableMemfs,
|
|
385187
|
+
isSubagent,
|
|
385188
|
+
baseTools: toolNames,
|
|
385189
|
+
embedding: embeddingModelVal || undefined,
|
|
385190
|
+
parallelToolCalls: parallelToolCallsVal
|
|
385191
|
+
});
|
|
385000
385192
|
const createWithTools = (tools) => backend3.createAgent({
|
|
385001
385193
|
...createAgentRequestBase,
|
|
385194
|
+
...contextWindow && { context_window_limit: contextWindow },
|
|
385002
385195
|
tools
|
|
385003
385196
|
});
|
|
385004
|
-
const agent2 = await createAgentWithBaseToolsRecovery(createWithTools,
|
|
385197
|
+
const agent2 = await createAgentWithBaseToolsRecovery(createWithTools, createAgentRequestBase.tools, addBaseToolsToServer);
|
|
385005
385198
|
const mergedUpdateArgs = {
|
|
385006
385199
|
...modelUpdateArgs ?? {},
|
|
385007
385200
|
...options3.updateArgs ?? {}
|
|
@@ -385575,6 +385768,13 @@ var init_args = __esm(() => {
|
|
|
385575
385768
|
mode: "both",
|
|
385576
385769
|
help: { description: "Enable memory filesystem for this agent" }
|
|
385577
385770
|
},
|
|
385771
|
+
stateless: {
|
|
385772
|
+
parser: { type: "boolean" },
|
|
385773
|
+
mode: "headless",
|
|
385774
|
+
help: {
|
|
385775
|
+
description: "Run an existing agent without MemFS enablement or sync"
|
|
385776
|
+
}
|
|
385777
|
+
},
|
|
385578
385778
|
"no-memfs": {
|
|
385579
385779
|
parser: { type: "boolean" },
|
|
385580
385780
|
mode: "both"
|
|
@@ -425742,6 +425942,74 @@ function validateConversationDefaultRequiresAgent(options3) {
|
|
|
425742
425942
|
throw new Error("--conv default requires --agent <agent-id>");
|
|
425743
425943
|
}
|
|
425744
425944
|
}
|
|
425945
|
+
function validateStatelessStartupOptions(options3) {
|
|
425946
|
+
if (!options3.stateless) {
|
|
425947
|
+
return;
|
|
425948
|
+
}
|
|
425949
|
+
if (!options3.isHeadless) {
|
|
425950
|
+
throw new Error("--stateless is only supported in headless mode");
|
|
425951
|
+
}
|
|
425952
|
+
if (options3.memfs) {
|
|
425953
|
+
throw new Error("--stateless cannot be used with --memfs");
|
|
425954
|
+
}
|
|
425955
|
+
if (options3.memfsStartup) {
|
|
425956
|
+
throw new Error("--stateless cannot be used with --memfs-startup");
|
|
425957
|
+
}
|
|
425958
|
+
if (options3.forceNewAgent) {
|
|
425959
|
+
throw new Error("--stateless is for existing agents and cannot be used with --new-agent");
|
|
425960
|
+
}
|
|
425961
|
+
if (!options3.hasExistingAgentSelector) {
|
|
425962
|
+
throw new Error("--stateless requires --agent, --name, or --conversation");
|
|
425963
|
+
}
|
|
425964
|
+
}
|
|
425965
|
+
function validatePrimaryStartupFlagConflicts(options3) {
|
|
425966
|
+
validateStatelessStartupOptions({
|
|
425967
|
+
stateless: options3.stateless,
|
|
425968
|
+
isHeadless: options3.isHeadless,
|
|
425969
|
+
memfs: options3.memfs,
|
|
425970
|
+
memfsStartup: options3.memfsStartup,
|
|
425971
|
+
forceNewAgent: options3.forceNewAgent,
|
|
425972
|
+
hasExistingAgentSelector: Boolean(options3.specifiedAgentId || options3.specifiedAgentName || options3.specifiedConversationId)
|
|
425973
|
+
});
|
|
425974
|
+
validateFlagConflicts({
|
|
425975
|
+
guard: options3.specifiedConversationId && options3.specifiedConversationId !== "default",
|
|
425976
|
+
checks: [
|
|
425977
|
+
{
|
|
425978
|
+
when: options3.specifiedAgentId,
|
|
425979
|
+
message: "--conversation cannot be used with --agent"
|
|
425980
|
+
},
|
|
425981
|
+
{
|
|
425982
|
+
when: options3.specifiedAgentName,
|
|
425983
|
+
message: "--conversation cannot be used with --name"
|
|
425984
|
+
},
|
|
425985
|
+
{
|
|
425986
|
+
when: options3.forceNewAgent,
|
|
425987
|
+
message: "--conversation cannot be used with --new-agent"
|
|
425988
|
+
},
|
|
425989
|
+
{
|
|
425990
|
+
when: options3.importFile,
|
|
425991
|
+
message: "--conversation cannot be used with --import"
|
|
425992
|
+
},
|
|
425993
|
+
{
|
|
425994
|
+
when: options3.shouldResume,
|
|
425995
|
+
message: "--conversation cannot be used with --resume"
|
|
425996
|
+
}
|
|
425997
|
+
]
|
|
425998
|
+
});
|
|
425999
|
+
validateFlagConflicts({
|
|
426000
|
+
guard: options3.forceNewConversation,
|
|
426001
|
+
checks: [
|
|
426002
|
+
{
|
|
426003
|
+
when: options3.specifiedConversationId,
|
|
426004
|
+
message: "--new cannot be used with --conversation"
|
|
426005
|
+
},
|
|
426006
|
+
{
|
|
426007
|
+
when: options3.shouldResume,
|
|
426008
|
+
message: "--new cannot be used with --resume"
|
|
426009
|
+
}
|
|
426010
|
+
]
|
|
426011
|
+
});
|
|
426012
|
+
}
|
|
425745
426013
|
function validateRegistryHandleOrThrow(handle2) {
|
|
425746
426014
|
const normalized = handle2.startsWith("@") ? handle2.slice(1) : handle2;
|
|
425747
426015
|
const parts = normalized.split("/");
|
|
@@ -437758,7 +438026,8 @@ function buildQueuedTurnMessage(runtime, batch) {
|
|
|
437758
438026
|
messages: [
|
|
437759
438027
|
{
|
|
437760
438028
|
role: "user",
|
|
437761
|
-
content: mergedContent2
|
|
438029
|
+
content: mergedContent2,
|
|
438030
|
+
otid: crypto.randomUUID()
|
|
437762
438031
|
}
|
|
437763
438032
|
]
|
|
437764
438033
|
};
|
|
@@ -443817,8 +444086,8 @@ var init_dream_targets = __esm(() => {
|
|
|
443817
444086
|
import { execFile as execFileCb4 } from "node:child_process";
|
|
443818
444087
|
import { randomUUID as randomUUID24 } from "node:crypto";
|
|
443819
444088
|
import { existsSync as existsSync46 } from "node:fs";
|
|
443820
|
-
import { mkdir as mkdir13
|
|
443821
|
-
import { dirname as dirname26, isAbsolute as isAbsolute25, join as join61,
|
|
444089
|
+
import { mkdir as mkdir13 } from "node:fs/promises";
|
|
444090
|
+
import { dirname as dirname26, isAbsolute as isAbsolute25, join as join61, resolve as resolve31 } from "node:path";
|
|
443822
444091
|
import { promisify as promisify13 } from "node:util";
|
|
443823
444092
|
async function runGit4(cwd2, args) {
|
|
443824
444093
|
try {
|
|
@@ -443922,23 +444191,19 @@ function buildReflectionMemoryScope(worktree) {
|
|
|
443922
444191
|
readonlyRoots: [dirname26(worktree.parentMemoryDir)]
|
|
443923
444192
|
};
|
|
443924
444193
|
}
|
|
443925
|
-
function
|
|
444194
|
+
function buildReflectionIntegrationMemoryScope(worktree) {
|
|
443926
444195
|
return {
|
|
443927
|
-
|
|
443928
|
-
|
|
443929
|
-
|
|
443930
|
-
|
|
443931
|
-
|
|
443932
|
-
|
|
443933
|
-
|
|
443934
|
-
error: error54
|
|
444196
|
+
primaryRoot: worktree.worktreeDir,
|
|
444197
|
+
writableRoots: [
|
|
444198
|
+
worktree.worktreeDir,
|
|
444199
|
+
worktree.parentMemoryDir,
|
|
444200
|
+
worktree.gitCommonDir
|
|
444201
|
+
],
|
|
444202
|
+
readonlyRoots: []
|
|
443935
444203
|
};
|
|
443936
444204
|
}
|
|
443937
444205
|
function reflectionIntegrationConsumesTranscript(result) {
|
|
443938
|
-
return result.status === "merged" || result.status === "no_changes"
|
|
443939
|
-
}
|
|
443940
|
-
function reflectionIntegrationNeedsReminder(result) {
|
|
443941
|
-
return result.status === "pending_conflict" || result.status === "pending_manual_merge";
|
|
444206
|
+
return result.status === "merged" || result.status === "no_changes";
|
|
443942
444207
|
}
|
|
443943
444208
|
function reflectionIntegrationShouldRecompile(result) {
|
|
443944
444209
|
return result.status === "merged";
|
|
@@ -443947,6 +444212,9 @@ async function getStatusPorcelain(cwd2) {
|
|
|
443947
444212
|
const { stdout } = await runGit4(cwd2, ["status", "--porcelain"]);
|
|
443948
444213
|
return stdout.trim();
|
|
443949
444214
|
}
|
|
444215
|
+
async function reflectionMemoryParentHasChanges(parentMemoryDir) {
|
|
444216
|
+
return (await getStatusPorcelain(resolve31(parentMemoryDir))).length > 0;
|
|
444217
|
+
}
|
|
443950
444218
|
async function getCommitCount(worktree) {
|
|
443951
444219
|
const { stdout } = await runGit4(worktree.worktreeDir, [
|
|
443952
444220
|
"rev-list",
|
|
@@ -443960,131 +444228,12 @@ async function getHead(cwd2) {
|
|
|
443960
444228
|
const head2 = result?.stdout.trim();
|
|
443961
444229
|
return head2 || undefined;
|
|
443962
444230
|
}
|
|
443963
|
-
async function
|
|
443964
|
-
|
|
443965
|
-
|
|
443966
|
-
|
|
443967
|
-
|
|
443968
|
-
|
|
443969
|
-
return Number.parseInt(result?.stdout.trim() ?? "", 10) || 0;
|
|
443970
|
-
}
|
|
443971
|
-
function parseWorktreeListPorcelain(output) {
|
|
443972
|
-
const entries = [];
|
|
443973
|
-
for (const block of output.split(/\n\s*\n/)) {
|
|
443974
|
-
const entry = {};
|
|
443975
|
-
for (const line of block.split(`
|
|
443976
|
-
`)) {
|
|
443977
|
-
const separatorIndex = line.indexOf(" ");
|
|
443978
|
-
const key2 = separatorIndex === -1 ? line : line.slice(0, separatorIndex);
|
|
443979
|
-
const value = separatorIndex === -1 ? "" : line.slice(separatorIndex + 1);
|
|
443980
|
-
if (key2 === "worktree")
|
|
443981
|
-
entry.path = value;
|
|
443982
|
-
if (key2 === "HEAD")
|
|
443983
|
-
entry.head = value;
|
|
443984
|
-
if (key2 === "branch")
|
|
443985
|
-
entry.branch = value;
|
|
443986
|
-
}
|
|
443987
|
-
if (!entry.path)
|
|
443988
|
-
continue;
|
|
443989
|
-
entries.push({
|
|
443990
|
-
path: entry.path,
|
|
443991
|
-
...entry.head ? { head: entry.head } : {},
|
|
443992
|
-
...entry.branch ? { branch: entry.branch } : {}
|
|
443993
|
-
});
|
|
443994
|
-
}
|
|
443995
|
-
return entries;
|
|
443996
|
-
}
|
|
443997
|
-
async function listPendingReflectionMemoryWorktrees(parentMemoryDir) {
|
|
443998
|
-
const resolvedParent = await realpath4(resolve31(parentMemoryDir));
|
|
443999
|
-
const worktreeBaseDir = join61(dirname26(resolvedParent), "memory-worktrees");
|
|
444000
|
-
const worktreeList = await tryRunGit(resolvedParent, [
|
|
444001
|
-
"worktree",
|
|
444002
|
-
"list",
|
|
444003
|
-
"--porcelain"
|
|
444004
|
-
]);
|
|
444005
|
-
if (!worktreeList)
|
|
444006
|
-
return [];
|
|
444007
|
-
const pending = [];
|
|
444008
|
-
for (const entry of parseWorktreeListPorcelain(worktreeList.stdout)) {
|
|
444009
|
-
const worktreeDir = normalizeGitPath(entry.path, resolvedParent);
|
|
444010
|
-
const relativeWorktreeDir = relative9(worktreeBaseDir, worktreeDir);
|
|
444011
|
-
if (relativeWorktreeDir.startsWith("..") || isAbsolute25(relativeWorktreeDir))
|
|
444012
|
-
continue;
|
|
444013
|
-
const branchName = entry.branch?.startsWith("refs/heads/") ? entry.branch.slice("refs/heads/".length) : undefined;
|
|
444014
|
-
if (!branchName?.startsWith("letta/reflection/"))
|
|
444015
|
-
continue;
|
|
444016
|
-
const isMerged = await tryRunGit(resolvedParent, [
|
|
444017
|
-
"merge-base",
|
|
444018
|
-
"--is-ancestor",
|
|
444019
|
-
branchName,
|
|
444020
|
-
"HEAD"
|
|
444021
|
-
]);
|
|
444022
|
-
if (isMerged) {
|
|
444023
|
-
await cleanupWorktreeAndBranch(resolvedParent, worktreeDir, branchName, {
|
|
444024
|
-
force: true
|
|
444025
|
-
});
|
|
444026
|
-
debugLog("memfs-git", "reflection pending scan cleaned already-merged branch=%s worktree=%s", branchName, worktreeDir);
|
|
444027
|
-
continue;
|
|
444028
|
-
}
|
|
444029
|
-
pending.push({
|
|
444030
|
-
id: branchName.slice("letta/reflection/".length),
|
|
444031
|
-
parentMemoryDir: resolvedParent,
|
|
444032
|
-
reflectionWorktreeDir: worktreeDir,
|
|
444033
|
-
reflectionBranch: branchName,
|
|
444034
|
-
commitCount: await getBranchCommitCount(resolvedParent, branchName),
|
|
444035
|
-
head: entry.head
|
|
444036
|
-
});
|
|
444037
|
-
}
|
|
444038
|
-
if (pending.length > 0) {
|
|
444039
|
-
debugLog("memfs-git", "reflection pending scan found=%d parent=%s branches=%s", pending.length, resolvedParent, pending.map((entry) => entry.reflectionBranch).join(","));
|
|
444040
|
-
}
|
|
444041
|
-
return pending;
|
|
444042
|
-
}
|
|
444043
|
-
async function integratePendingReflectionMemoryWorktrees(parentMemoryDir) {
|
|
444044
|
-
const pendingWorktrees = await listPendingReflectionMemoryWorktrees(parentMemoryDir);
|
|
444045
|
-
const unresolved = [];
|
|
444046
|
-
for (const pending of pendingWorktrees) {
|
|
444047
|
-
const isMerged = await tryRunGit(pending.parentMemoryDir, [
|
|
444048
|
-
"merge-base",
|
|
444049
|
-
"--is-ancestor",
|
|
444050
|
-
pending.reflectionBranch,
|
|
444051
|
-
"HEAD"
|
|
444052
|
-
]);
|
|
444053
|
-
if (isMerged) {
|
|
444054
|
-
await cleanupWorktreeAndBranch(pending.parentMemoryDir, pending.reflectionWorktreeDir, pending.reflectionBranch, { force: true });
|
|
444055
|
-
debugLog("memfs-git", "reflection pending integration cleaned already-merged branch=%s worktree=%s", pending.reflectionBranch, pending.reflectionWorktreeDir);
|
|
444056
|
-
continue;
|
|
444057
|
-
}
|
|
444058
|
-
const worktreeStatus = await getStatusPorcelain(pending.reflectionWorktreeDir);
|
|
444059
|
-
if (worktreeStatus.length > 0) {
|
|
444060
|
-
unresolved.push(buildPendingResultFromPending(pending, "pending_manual_merge", "A previously unresolved reflection memory worktree has uncommitted changes. Background merge was deferred."));
|
|
444061
|
-
debugLog("memfs-git", "reflection pending integration deferred branch=%s reason=worktree_dirty worktree=%s", pending.reflectionBranch, pending.reflectionWorktreeDir);
|
|
444062
|
-
continue;
|
|
444063
|
-
}
|
|
444064
|
-
const parentStatus = await getStatusPorcelain(pending.parentMemoryDir);
|
|
444065
|
-
if (parentStatus.length > 0) {
|
|
444066
|
-
unresolved.push(buildPendingResultFromPending(pending, "pending_manual_merge", "A previously unresolved reflection memory worktree is still unmerged, and the parent memory repo has uncommitted changes. Background merge was deferred."));
|
|
444067
|
-
debugLog("memfs-git", "reflection pending integration deferred branch=%s reason=parent_dirty", pending.reflectionBranch);
|
|
444068
|
-
continue;
|
|
444069
|
-
}
|
|
444070
|
-
const mergeMessage = await buildReflectionMergeMessage(pending.parentMemoryDir, pending.reflectionBranch);
|
|
444071
|
-
const mergeResult = await tryRunGit(pending.parentMemoryDir, [
|
|
444072
|
-
"merge",
|
|
444073
|
-
pending.reflectionBranch,
|
|
444074
|
-
"-m",
|
|
444075
|
-
mergeMessage
|
|
444076
|
-
]);
|
|
444077
|
-
if (!mergeResult) {
|
|
444078
|
-
await tryRunGit(pending.parentMemoryDir, ["merge", "--abort"]);
|
|
444079
|
-
unresolved.push(buildPendingResultFromPending(pending, "pending_conflict", "A previously unresolved reflection memory worktree still has conflicts. The parent merge was aborted and the reflection worktree was preserved."));
|
|
444080
|
-
debugLog("memfs-git", "reflection pending integration conflicted branch=%s mergeAbort=true preservedWorktree=%s", pending.reflectionBranch, pending.reflectionWorktreeDir);
|
|
444081
|
-
continue;
|
|
444082
|
-
}
|
|
444083
|
-
const mergedHead = await getHead(pending.parentMemoryDir);
|
|
444084
|
-
await cleanupWorktreeAndBranch(pending.parentMemoryDir, pending.reflectionWorktreeDir, pending.reflectionBranch, { force: true });
|
|
444085
|
-
debugLog("memfs-git", "reflection pending integration merged branch=%s commitCount=%d parentHead=%s cleanedUp=true", pending.reflectionBranch, pending.commitCount, mergedHead ?? "<none>");
|
|
444086
|
-
}
|
|
444087
|
-
return unresolved;
|
|
444231
|
+
async function inspectReflectionMemoryWorktree(worktree) {
|
|
444232
|
+
return {
|
|
444233
|
+
commitCount: await getCommitCount(worktree),
|
|
444234
|
+
dirty: (await getStatusPorcelain(worktree.worktreeDir)).length > 0,
|
|
444235
|
+
head: await getHead(worktree.worktreeDir)
|
|
444236
|
+
};
|
|
444088
444237
|
}
|
|
444089
444238
|
async function cleanupWorktreeAndBranch(parentMemoryDir, worktreeDir, branchName, options3 = {}) {
|
|
444090
444239
|
const removedWorktree = existsSync46(worktreeDir);
|
|
@@ -444102,19 +444251,28 @@ async function cleanupWorktreeAndBranch(parentMemoryDir, worktreeDir, branchName
|
|
|
444102
444251
|
branchName
|
|
444103
444252
|
]);
|
|
444104
444253
|
}
|
|
444105
|
-
function
|
|
444106
|
-
|
|
444107
|
-
|
|
444108
|
-
|
|
444109
|
-
|
|
444110
|
-
|
|
444111
|
-
|
|
444112
|
-
|
|
444113
|
-
|
|
444114
|
-
|
|
444115
|
-
|
|
444116
|
-
|
|
444117
|
-
|
|
444254
|
+
async function finalizeReflectionMemoryWorktreeImpl(worktree, options3) {
|
|
444255
|
+
if (!existsSync46(worktree.worktreeDir) && options3.knownNoChanges) {
|
|
444256
|
+
const branchHead = (await tryRunGit(worktree.parentMemoryDir, [
|
|
444257
|
+
"rev-parse",
|
|
444258
|
+
"--verify",
|
|
444259
|
+
worktree.branchName
|
|
444260
|
+
]))?.stdout.trim();
|
|
444261
|
+
if (branchHead && branchHead !== worktree.baseHead) {
|
|
444262
|
+
throw new Error(`Cannot finalize missing reflection worktree ${worktree.worktreeDir} as no-op: ${worktree.branchName} advanced from ${worktree.baseHead} to ${branchHead}`);
|
|
444263
|
+
}
|
|
444264
|
+
await cleanupWorktreeAndBranch(worktree.parentMemoryDir, worktree.worktreeDir, worktree.branchName, { force: true });
|
|
444265
|
+
debugLog("memfs-git", "reflection finalized id=%s status=no_changes worktreeMissing=true cleanedUp=true", worktree.id);
|
|
444266
|
+
return {
|
|
444267
|
+
status: "no_changes",
|
|
444268
|
+
parentMemoryDir: worktree.parentMemoryDir,
|
|
444269
|
+
reflectionWorktreeDir: worktree.worktreeDir,
|
|
444270
|
+
reflectionBranch: worktree.branchName,
|
|
444271
|
+
commitCount: 0,
|
|
444272
|
+
head: worktree.baseHead,
|
|
444273
|
+
summary: "Reflection made no memory commits."
|
|
444274
|
+
};
|
|
444275
|
+
}
|
|
444118
444276
|
const commitCount = await getCommitCount(worktree);
|
|
444119
444277
|
const status = await getStatusPorcelain(worktree.worktreeDir);
|
|
444120
444278
|
const head2 = await getHead(worktree.worktreeDir);
|
|
@@ -444131,6 +444289,19 @@ async function finalizeReflectionMemoryWorktree(worktree, options3) {
|
|
|
444131
444289
|
summary: "Reflection memory worktree had uncommitted changes; it was cleaned up so the transcript can be retried."
|
|
444132
444290
|
};
|
|
444133
444291
|
}
|
|
444292
|
+
if (!options3.shouldMerge) {
|
|
444293
|
+
await cleanupWorktreeAndBranch(worktree.parentMemoryDir, worktree.worktreeDir, worktree.branchName, { force: true });
|
|
444294
|
+
debugLog("memfs-git", "reflection finalized id=%s status=failed commitCount=%d cleanedUp=true retryable=true", worktree.id, commitCount);
|
|
444295
|
+
return {
|
|
444296
|
+
status: "failed",
|
|
444297
|
+
parentMemoryDir: worktree.parentMemoryDir,
|
|
444298
|
+
reflectionWorktreeDir: worktree.worktreeDir,
|
|
444299
|
+
reflectionBranch: worktree.branchName,
|
|
444300
|
+
commitCount,
|
|
444301
|
+
head: head2,
|
|
444302
|
+
summary: "Reflection subagent did not complete successfully; the worktree was cleaned up so the transcript can be retried."
|
|
444303
|
+
};
|
|
444304
|
+
}
|
|
444134
444305
|
if (commitCount === 0) {
|
|
444135
444306
|
await cleanupWorktreeAndBranch(worktree.parentMemoryDir, worktree.worktreeDir, worktree.branchName);
|
|
444136
444307
|
debugLog("memfs-git", "reflection finalized id=%s status=no_changes cleanedUp=true", worktree.id);
|
|
@@ -444144,23 +444315,52 @@ async function finalizeReflectionMemoryWorktree(worktree, options3) {
|
|
|
444144
444315
|
summary: "Reflection made no memory commits."
|
|
444145
444316
|
};
|
|
444146
444317
|
}
|
|
444147
|
-
|
|
444318
|
+
const parentStatus = await getStatusPorcelain(worktree.parentMemoryDir);
|
|
444319
|
+
if (parentStatus.length > 0) {
|
|
444148
444320
|
await cleanupWorktreeAndBranch(worktree.parentMemoryDir, worktree.worktreeDir, worktree.branchName, { force: true });
|
|
444149
|
-
debugLog("memfs-git", "reflection finalized id=%s status=
|
|
444321
|
+
debugLog("memfs-git", "reflection finalized id=%s status=parent_dirty commitCount=%d cleanedUp=true retryable=true", worktree.id, commitCount);
|
|
444150
444322
|
return {
|
|
444151
|
-
status: "
|
|
444323
|
+
status: "parent_dirty",
|
|
444152
444324
|
parentMemoryDir: worktree.parentMemoryDir,
|
|
444153
444325
|
reflectionWorktreeDir: worktree.worktreeDir,
|
|
444154
444326
|
reflectionBranch: worktree.branchName,
|
|
444155
444327
|
commitCount,
|
|
444156
444328
|
head: head2,
|
|
444157
|
-
summary: "Reflection produced
|
|
444329
|
+
summary: "Reflection produced memory updates, but the parent memory repo had uncommitted changes; the worktree was cleaned up so the transcript can be retried."
|
|
444158
444330
|
};
|
|
444159
444331
|
}
|
|
444160
|
-
|
|
444161
|
-
|
|
444162
|
-
|
|
444163
|
-
|
|
444332
|
+
if (options3.requireAlreadyMerged) {
|
|
444333
|
+
const alreadyMerged = await tryRunGit(worktree.parentMemoryDir, [
|
|
444334
|
+
"merge-base",
|
|
444335
|
+
"--is-ancestor",
|
|
444336
|
+
worktree.branchName,
|
|
444337
|
+
"HEAD"
|
|
444338
|
+
]);
|
|
444339
|
+
if (!alreadyMerged) {
|
|
444340
|
+
await cleanupWorktreeAndBranch(worktree.parentMemoryDir, worktree.worktreeDir, worktree.branchName, { force: true });
|
|
444341
|
+
return {
|
|
444342
|
+
status: "failed",
|
|
444343
|
+
parentMemoryDir: worktree.parentMemoryDir,
|
|
444344
|
+
reflectionWorktreeDir: worktree.worktreeDir,
|
|
444345
|
+
reflectionBranch: worktree.branchName,
|
|
444346
|
+
commitCount,
|
|
444347
|
+
head: head2,
|
|
444348
|
+
failurePhase: "integration",
|
|
444349
|
+
summary: options3.failureSummary ?? "The primary-agent integration conversation did not merge the reflection branch; the worktree was cleaned up so the transcript can be retried."
|
|
444350
|
+
};
|
|
444351
|
+
}
|
|
444352
|
+
const mergedHead2 = await getHead(worktree.parentMemoryDir);
|
|
444353
|
+
await cleanupWorktreeAndBranch(worktree.parentMemoryDir, worktree.worktreeDir, worktree.branchName);
|
|
444354
|
+
debugLog("memfs-git", "reflection finalized id=%s status=merged integration=primary_agent commitCount=%d parentHead=%s cleanedUp=true", worktree.id, commitCount, mergedHead2 ?? "<none>");
|
|
444355
|
+
return {
|
|
444356
|
+
status: "merged",
|
|
444357
|
+
parentMemoryDir: worktree.parentMemoryDir,
|
|
444358
|
+
reflectionWorktreeDir: worktree.worktreeDir,
|
|
444359
|
+
reflectionBranch: worktree.branchName,
|
|
444360
|
+
commitCount,
|
|
444361
|
+
head: mergedHead2,
|
|
444362
|
+
summary: `Primary agent integrated ${commitCount} reflection memory commit(s).`
|
|
444363
|
+
};
|
|
444164
444364
|
}
|
|
444165
444365
|
debugLog("memfs-git", "reflection merge attempt id=%s branch=%s parent=%s commitCount=%d", worktree.id, worktree.branchName, worktree.parentMemoryDir, commitCount);
|
|
444166
444366
|
const mergeMessage = await buildReflectionMergeMessage(worktree.parentMemoryDir, worktree.branchName);
|
|
@@ -444172,15 +444372,16 @@ async function finalizeReflectionMemoryWorktree(worktree, options3) {
|
|
|
444172
444372
|
]);
|
|
444173
444373
|
if (!mergeResult) {
|
|
444174
444374
|
await tryRunGit(worktree.parentMemoryDir, ["merge", "--abort"]);
|
|
444175
|
-
|
|
444375
|
+
await cleanupWorktreeAndBranch(worktree.parentMemoryDir, worktree.worktreeDir, worktree.branchName, { force: true });
|
|
444376
|
+
debugLog("memfs-git", "reflection finalized id=%s status=merge_conflict commitCount=%d mergeAbort=true cleanedUp=true retryable=true", worktree.id, commitCount);
|
|
444176
444377
|
return {
|
|
444177
|
-
status: "
|
|
444378
|
+
status: "merge_conflict",
|
|
444178
444379
|
parentMemoryDir: worktree.parentMemoryDir,
|
|
444179
444380
|
reflectionWorktreeDir: worktree.worktreeDir,
|
|
444180
444381
|
reflectionBranch: worktree.branchName,
|
|
444181
444382
|
commitCount,
|
|
444182
444383
|
head: head2,
|
|
444183
|
-
summary: "Reflection produced memory updates, but merging them into the parent memory repo
|
|
444384
|
+
summary: "Reflection produced memory updates, but merging them into the parent memory repo conflicted; the worktree was cleaned up so the transcript can be retried."
|
|
444184
444385
|
};
|
|
444185
444386
|
}
|
|
444186
444387
|
const mergedHead = await getHead(worktree.parentMemoryDir);
|
|
@@ -444196,6 +444397,9 @@ async function finalizeReflectionMemoryWorktree(worktree, options3) {
|
|
|
444196
444397
|
summary: `Merged ${commitCount} reflection memory commit(s) into parent memory main.`
|
|
444197
444398
|
};
|
|
444198
444399
|
}
|
|
444400
|
+
async function finalizeReflectionMemoryWorktree(worktree, options3) {
|
|
444401
|
+
return await finalizeReflectionMemoryWorktreeImpl(worktree, options3);
|
|
444402
|
+
}
|
|
444199
444403
|
var execFile13, GIT_TIMEOUT_MS = 30000, HARNESS_GIT_ENV;
|
|
444200
444404
|
var init_memory_worktree = __esm(() => {
|
|
444201
444405
|
init_memory_git_signing();
|
|
@@ -444268,6 +444472,43 @@ var init_memory_subagent_completion = __esm(() => {
|
|
|
444268
444472
|
init_system_prompt_warning();
|
|
444269
444473
|
});
|
|
444270
444474
|
|
|
444475
|
+
// src/cli/helpers/reflection-integration.ts
|
|
444476
|
+
function buildReflectionIntegrationConversationTitle(reflectionSubagentId) {
|
|
444477
|
+
return reflectionSubagentId ? `Reflection integration (reflection ${reflectionSubagentId})` : "Reflection integration";
|
|
444478
|
+
}
|
|
444479
|
+
function buildReflectionIntegrationPrompt(params) {
|
|
444480
|
+
const instructions = params.instructions?.trim();
|
|
444481
|
+
return `Integrate proposed reflection changes into your memory.
|
|
444482
|
+
|
|
444483
|
+
The user configured explicit handling for reflection merges. You are responsible for the entire integration. Work autonomously in this separate conversation; do not interrupt or add messages to the original conversation.
|
|
444484
|
+
|
|
444485
|
+
Reflection worktree: ${params.worktree.worktreeDir}
|
|
444486
|
+
Your memory repository: ${params.worktree.parentMemoryDir}
|
|
444487
|
+
Reflection branch: ${params.worktree.branchName}
|
|
444488
|
+
Reflection base commit: ${params.worktree.baseHead}
|
|
444489
|
+
Original reflection subagent ID: ${params.reflectionSubagentId ?? "unavailable"}
|
|
444490
|
+
|
|
444491
|
+
Work in the reflection worktree while refining the proposal. Start directly by checking both repository states and the proposed diff in one combined shell call; do not create a task plan or spend turns narrating routine Git checks.
|
|
444492
|
+
|
|
444493
|
+
Review the proposal for accuracy, placement, precision, and consistency with existing memory, then make any needed edits. If no edits are needed, do not create another commit. If you edit the proposal, stage only those files and create one follow-up commit on top of the reflection commit; do not amend. Use the subject \`merge(reflection): <concise summary>\`.${params.reflectionSubagentId ? ` Include the trailer \`Reflection-Subagent-ID: ${params.reflectionSubagentId}\`.` : ""}
|
|
444494
|
+
|
|
444495
|
+
Before merging, incorporate the latest committed memory repository HEAD into the reflection branch and resolve conflicts yourself while preserving the intended memory state. If the memory repository has pre-existing uncommitted changes, leave them completely untouched—do not modify, stash, commit, or discard them—and stop the integration.
|
|
444496
|
+
|
|
444497
|
+
Merge the completed reflection branch into your memory repository without pushing, then verify both repositories are clean. Do not remove the worktree or branch; the harness performs final verification and cleanup.
|
|
444498
|
+
|
|
444499
|
+
Do not ask the user questions or wait for input. Handle the integration as far as you safely can and explain any remaining blocker in your final response. If integration remains incomplete, the harness will clean up this proposal without consuming the source transcript so reflection can retry later.
|
|
444500
|
+
|
|
444501
|
+
${instructions ? `## IMPORTANT: Additional reflection merge instructions from the user
|
|
444502
|
+
|
|
444503
|
+
The user explicitly configured the following instructions for this integration. Follow them carefully:
|
|
444504
|
+
|
|
444505
|
+
<reflection-merge-instructions>
|
|
444506
|
+
${instructions}
|
|
444507
|
+
</reflection-merge-instructions>
|
|
444508
|
+
|
|
444509
|
+
` : ""}When finished, provide a concise normal summary of what you reviewed, changed, and merged.`;
|
|
444510
|
+
}
|
|
444511
|
+
|
|
444271
444512
|
// src/telemetry/reflection-threshold-feedback.ts
|
|
444272
444513
|
import { randomUUID as randomUUID25 } from "node:crypto";
|
|
444273
444514
|
async function resolveFeedbackApiKey() {
|
|
@@ -444283,6 +444524,18 @@ function getFeedbackDeviceId() {
|
|
|
444283
444524
|
} catch {}
|
|
444284
444525
|
return randomUUID25();
|
|
444285
444526
|
}
|
|
444527
|
+
function getAlertDeviceType() {
|
|
444528
|
+
switch (process.platform) {
|
|
444529
|
+
case "darwin":
|
|
444530
|
+
return "macOS";
|
|
444531
|
+
case "win32":
|
|
444532
|
+
return "Windows";
|
|
444533
|
+
case "linux":
|
|
444534
|
+
return "Linux";
|
|
444535
|
+
default:
|
|
444536
|
+
return process.platform;
|
|
444537
|
+
}
|
|
444538
|
+
}
|
|
444286
444539
|
function getAlertReasonDescriptions(alertReasons) {
|
|
444287
444540
|
return alertReasons.map((reason) => {
|
|
444288
444541
|
switch (reason) {
|
|
@@ -444323,6 +444576,10 @@ function maybeSendReflectionThresholdFeedback(options3) {
|
|
|
444323
444576
|
feature: "letta-code",
|
|
444324
444577
|
agent_id: agentId,
|
|
444325
444578
|
session_id: telemetry.getSessionId(),
|
|
444579
|
+
version: getVersion(),
|
|
444580
|
+
platform: process.platform,
|
|
444581
|
+
device_type: getAlertDeviceType(),
|
|
444582
|
+
node_version: process.version,
|
|
444326
444583
|
total_wall_ms: options3.durationMs,
|
|
444327
444584
|
step_count: options3.stepCount,
|
|
444328
444585
|
agent_name: options3.parentAgentName ?? undefined,
|
|
@@ -444350,6 +444607,7 @@ var init_reflection_threshold_feedback = __esm(() => {
|
|
|
444350
444607
|
init_metadata();
|
|
444351
444608
|
init_settings_manager();
|
|
444352
444609
|
init_telemetry();
|
|
444610
|
+
init_version();
|
|
444353
444611
|
REFLECTION_DURATION_THRESHOLD_MS = 10 * 60 * 1000;
|
|
444354
444612
|
});
|
|
444355
444613
|
|
|
@@ -444359,10 +444617,11 @@ __export(exports_reflection_launcher, {
|
|
|
444359
444617
|
tryReserveReflectionLaunch: () => tryReserveReflectionLaunch,
|
|
444360
444618
|
shouldRunQueuedReflectionLaunch: () => shouldRunQueuedReflectionLaunch,
|
|
444361
444619
|
releaseReflectionLaunch: () => releaseReflectionLaunch,
|
|
444362
|
-
queuePendingReflectionWorktreeReminders: () => queuePendingReflectionWorktreeReminders,
|
|
444363
444620
|
prepareReflectionMemoryWorktreeLaunch: () => prepareReflectionMemoryWorktreeLaunch,
|
|
444364
444621
|
launchReflectionSubagent: () => launchReflectionSubagent,
|
|
444365
|
-
|
|
444622
|
+
getReflectionMergeLaunchOptions: () => getReflectionMergeLaunchOptions,
|
|
444623
|
+
getReflectionLaunchSkippedMessage: () => getReflectionLaunchSkippedMessage,
|
|
444624
|
+
getReflectionFinalizationContext: () => getReflectionFinalizationContext,
|
|
444366
444625
|
finalizeReflectionMemoryWorktreeLaunch: () => finalizeReflectionMemoryWorktreeLaunch,
|
|
444367
444626
|
emitReflectionRunStart: () => emitReflectionRunStart,
|
|
444368
444627
|
emitReflectionRunEnd: () => emitReflectionRunEnd,
|
|
@@ -444370,11 +444629,56 @@ __export(exports_reflection_launcher, {
|
|
|
444370
444629
|
REFLECTION_AGENT_ID_WAIT_MS: () => REFLECTION_AGENT_ID_WAIT_MS,
|
|
444371
444630
|
AUTO_REFLECTION_DESCRIPTION: () => AUTO_REFLECTION_DESCRIPTION
|
|
444372
444631
|
});
|
|
444632
|
+
function getReflectionMergeLaunchOptions(agentId) {
|
|
444633
|
+
const settings3 = getReflectionSettings(agentId);
|
|
444634
|
+
return {
|
|
444635
|
+
mergePolicy: settings3.merge ?? "auto",
|
|
444636
|
+
mergeInstructions: settings3.mergeInstructions
|
|
444637
|
+
};
|
|
444638
|
+
}
|
|
444639
|
+
function getReflectionFinalizationContext(agentId) {
|
|
444640
|
+
return {
|
|
444641
|
+
agentId,
|
|
444642
|
+
...getReflectionMergeLaunchOptions(agentId)
|
|
444643
|
+
};
|
|
444644
|
+
}
|
|
444645
|
+
function getReflectionLaunchSkippedMessage(reason, surface = "cli") {
|
|
444646
|
+
switch (reason) {
|
|
444647
|
+
case "already_active":
|
|
444648
|
+
return surface === "listener" ? "A reflection agent is already running for this conversation." : "A reflection agent is already running in the background.";
|
|
444649
|
+
case "memfs_disabled":
|
|
444650
|
+
return surface === "listener" ? "Reflection needs the memory filesystem to be enabled for this agent. Use /remember for a lightweight memory update instead." : "Memory filesystem is not enabled. Use /remember instead.";
|
|
444651
|
+
case "no_payload":
|
|
444652
|
+
return surface === "listener" ? "No new transcript content to reflect on for this conversation." : "No new transcript content to reflect on.";
|
|
444653
|
+
case "parent_dirty":
|
|
444654
|
+
return "Parent memory has uncommitted changes; commit or discard them before reflecting.";
|
|
444655
|
+
case "error":
|
|
444656
|
+
return;
|
|
444657
|
+
}
|
|
444658
|
+
}
|
|
444373
444659
|
function drainReflectionTelemetry() {
|
|
444374
444660
|
telemetry.drain().catch((error54) => {
|
|
444375
444661
|
debugWarn("telemetry", `Failed to flush reflection telemetry: ${error54 instanceof Error ? error54.message : String(error54)}`);
|
|
444376
444662
|
});
|
|
444377
444663
|
}
|
|
444664
|
+
function getReflectionWorktreeCleanupOutcome(integration) {
|
|
444665
|
+
switch (integration.status) {
|
|
444666
|
+
case "parent_dirty":
|
|
444667
|
+
return { outcome: "parent_dirty", integrationStatus: "parent_dirty" };
|
|
444668
|
+
case "merge_conflict":
|
|
444669
|
+
return { outcome: "merge_conflict", integrationStatus: "merge_conflict" };
|
|
444670
|
+
case "dirty_uncommitted":
|
|
444671
|
+
return {
|
|
444672
|
+
outcome: "reflection_worktree_dirty",
|
|
444673
|
+
integrationStatus: "dirty_uncommitted"
|
|
444674
|
+
};
|
|
444675
|
+
case "failed":
|
|
444676
|
+
return { outcome: "subagent_failed", integrationStatus: "failed" };
|
|
444677
|
+
case "merged":
|
|
444678
|
+
case "no_changes":
|
|
444679
|
+
return;
|
|
444680
|
+
}
|
|
444681
|
+
}
|
|
444378
444682
|
function emitReflectionRunStart(params) {
|
|
444379
444683
|
telemetry.trackReflectionStart(params.triggerSource, {
|
|
444380
444684
|
subagentId: params.subagentId,
|
|
@@ -444392,7 +444696,7 @@ function emitReflectionRunEnd(params) {
|
|
|
444392
444696
|
error: params.error,
|
|
444393
444697
|
stepCount: params.stepCount,
|
|
444394
444698
|
durationMs: params.durationMs,
|
|
444395
|
-
model: params.
|
|
444699
|
+
model: params.model
|
|
444396
444700
|
});
|
|
444397
444701
|
drainReflectionTelemetry();
|
|
444398
444702
|
maybeSendReflectionThresholdFeedback({
|
|
@@ -444407,7 +444711,7 @@ function emitReflectionRunEnd(params) {
|
|
|
444407
444711
|
stepCount: params.stepCount,
|
|
444408
444712
|
durationMs: params.durationMs,
|
|
444409
444713
|
surface: params.feedbackContext?.surface,
|
|
444410
|
-
model: params.
|
|
444714
|
+
model: params.model
|
|
444411
444715
|
});
|
|
444412
444716
|
}
|
|
444413
444717
|
function isReflectionSubagentActiveForAgent(agentId) {
|
|
@@ -444480,84 +444784,64 @@ function getReflectionCompletionMessage(integration) {
|
|
|
444480
444784
|
return;
|
|
444481
444785
|
case "no_changes":
|
|
444482
444786
|
return ({ action: action3 }) => `${action3}; no durable memory changes were needed.`;
|
|
444483
|
-
case "
|
|
444484
|
-
return
|
|
444485
|
-
case "
|
|
444486
|
-
return
|
|
444787
|
+
case "parent_dirty":
|
|
444788
|
+
return "Tried to reflect, but parent memory had uncommitted changes; will retry later.";
|
|
444789
|
+
case "merge_conflict":
|
|
444790
|
+
return "Tried to reflect, but memory updates conflicted with newer changes; will retry later.";
|
|
444487
444791
|
case "dirty_uncommitted":
|
|
444488
444792
|
return "Tried to reflect, but memory changes were not committed cleanly; will retry later.";
|
|
444489
444793
|
case "failed":
|
|
444490
|
-
return "Tried to reflect, but memory updates were not completed cleanly; will retry later.";
|
|
444794
|
+
return integration.failurePhase === "integration" ? `${integration.summary} Will retry later.` : "Tried to reflect, but memory updates were not completed cleanly; will retry later.";
|
|
444491
444795
|
}
|
|
444492
444796
|
}
|
|
444493
|
-
function
|
|
444494
|
-
|
|
444495
|
-
|
|
444496
|
-
|
|
444497
|
-
|
|
444498
|
-
|
|
444499
|
-
|
|
444500
|
-
|
|
444501
|
-
|
|
444502
|
-
|
|
444503
|
-
|
|
444504
|
-
|
|
444505
|
-
|
|
444506
|
-
|
|
444507
|
-
|
|
444508
|
-
|
|
444509
|
-
|
|
444510
|
-
|
|
444511
|
-
|
|
444512
|
-
|
|
444513
|
-
|
|
444514
|
-
|
|
444515
|
-
|
|
444516
|
-
|
|
444517
|
-
|
|
444518
|
-
|
|
444519
|
-
|
|
444520
|
-
|
|
444521
|
-
|
|
444522
|
-
|
|
444523
|
-
|
|
444524
|
-
|
|
444525
|
-
|
|
444526
|
-
|
|
444527
|
-
|
|
444528
|
-
|
|
444529
|
-
|
|
444530
|
-
|
|
444531
|
-
|
|
444532
|
-
|
|
444533
|
-
|
|
444534
|
-
|
|
444535
|
-
|
|
444536
|
-
|
|
444537
|
-
|
|
444538
|
-
|
|
444539
|
-
${SYSTEM_REMINDER_CLOSE}`;
|
|
444540
|
-
return formatReflectionIntegrationNotification(reminder);
|
|
444541
|
-
}
|
|
444542
|
-
function queueReflectionIntegrationReminder(params) {
|
|
444543
|
-
addToMessageQueue({
|
|
444544
|
-
kind: "task_notification",
|
|
444545
|
-
text: formatReflectionIntegrationReminder(params.integration),
|
|
444546
|
-
agentId: params.agentId,
|
|
444547
|
-
conversationId: params.conversationId
|
|
444797
|
+
async function runExplicitReflectionIntegration(params) {
|
|
444798
|
+
const {
|
|
444799
|
+
spawnBackgroundSubagentTask: spawnBackgroundSubagentTask2,
|
|
444800
|
+
waitForBackgroundSubagentConversationId: waitForBackgroundSubagentConversationId2
|
|
444801
|
+
} = await Promise.resolve().then(() => (init_task(), exports_task));
|
|
444802
|
+
return await new Promise((resolve32) => {
|
|
444803
|
+
try {
|
|
444804
|
+
const { subagentId } = spawnBackgroundSubagentTask2({
|
|
444805
|
+
subagentType: "general-purpose",
|
|
444806
|
+
displayType: "reflection integration",
|
|
444807
|
+
prompt: buildReflectionIntegrationPrompt({
|
|
444808
|
+
worktree: params.worktree,
|
|
444809
|
+
instructions: params.instructions,
|
|
444810
|
+
reflectionSubagentId: params.reflectionSubagentId
|
|
444811
|
+
}),
|
|
444812
|
+
description: "Integrate reflection memory changes",
|
|
444813
|
+
existingAgentId: params.agentId,
|
|
444814
|
+
memoryScope: buildReflectionIntegrationMemoryScope(params.worktree),
|
|
444815
|
+
parentScope: {
|
|
444816
|
+
agentId: params.agentId,
|
|
444817
|
+
conversationId: params.conversationId
|
|
444818
|
+
},
|
|
444819
|
+
silentCompletion: true,
|
|
444820
|
+
onComplete: (result) => {
|
|
444821
|
+
resolve32({
|
|
444822
|
+
success: result.success,
|
|
444823
|
+
error: result.success ? undefined : result.error ?? "Reflection integration did not complete",
|
|
444824
|
+
conversationId: result.conversationId
|
|
444825
|
+
});
|
|
444826
|
+
}
|
|
444827
|
+
});
|
|
444828
|
+
waitForBackgroundSubagentConversationId2(subagentId, REFLECTION_AGENT_ID_WAIT_MS).then(async (conversationId) => {
|
|
444829
|
+
if (!conversationId)
|
|
444830
|
+
return;
|
|
444831
|
+
await getBackend().updateConversation(conversationId, {
|
|
444832
|
+
summary: buildReflectionIntegrationConversationTitle(params.reflectionSubagentId)
|
|
444833
|
+
});
|
|
444834
|
+
}).catch((error54) => {
|
|
444835
|
+
debugWarn("memory", `Failed to title reflection integration conversation: ${error54 instanceof Error ? error54.message : String(error54)}`);
|
|
444836
|
+
});
|
|
444837
|
+
} catch (error54) {
|
|
444838
|
+
resolve32({
|
|
444839
|
+
success: false,
|
|
444840
|
+
error: error54 instanceof Error ? error54.message : String(error54)
|
|
444841
|
+
});
|
|
444842
|
+
}
|
|
444548
444843
|
});
|
|
444549
444844
|
}
|
|
444550
|
-
async function queuePendingReflectionWorktreeReminders(params) {
|
|
444551
|
-
const memoryDir = getScopedMemoryFilesystemRoot(params.agentId);
|
|
444552
|
-
const unresolvedIntegrations = await integratePendingReflectionMemoryWorktrees(memoryDir);
|
|
444553
|
-
for (const integration of unresolvedIntegrations) {
|
|
444554
|
-
queueReflectionIntegrationReminder({
|
|
444555
|
-
agentId: params.agentId,
|
|
444556
|
-
conversationId: params.conversationId,
|
|
444557
|
-
integration
|
|
444558
|
-
});
|
|
444559
|
-
}
|
|
444560
|
-
}
|
|
444561
444845
|
async function prepareReflectionMemoryWorktreeLaunch(params) {
|
|
444562
444846
|
const memoryDir = getScopedMemoryFilesystemRoot(params.agentId);
|
|
444563
444847
|
const worktree = await createReflectionMemoryWorktree({
|
|
@@ -444577,16 +444861,39 @@ async function prepareReflectionMemoryWorktreeLaunch(params) {
|
|
|
444577
444861
|
}
|
|
444578
444862
|
}
|
|
444579
444863
|
async function finalizeReflectionMemoryWorktreeLaunch(params) {
|
|
444864
|
+
let integrationRun;
|
|
444865
|
+
if (params.subagentSuccess && params.mergePolicy === "explicit") {
|
|
444866
|
+
const state = params.knownNoChanges ? { commitCount: 0, dirty: false } : await inspectReflectionMemoryWorktree(params.worktree);
|
|
444867
|
+
if (state.commitCount > 0 || state.dirty) {
|
|
444868
|
+
integrationRun = await (params.runExplicitIntegration ?? runExplicitReflectionIntegration)({
|
|
444869
|
+
agentId: params.agentId,
|
|
444870
|
+
conversationId: params.conversationId,
|
|
444871
|
+
worktree: params.worktree,
|
|
444872
|
+
instructions: params.mergeInstructions,
|
|
444873
|
+
reflectionSubagentId: params.subagentAgentId
|
|
444874
|
+
});
|
|
444875
|
+
}
|
|
444876
|
+
}
|
|
444580
444877
|
const integration = await finalizeReflectionMemoryWorktree(params.worktree, {
|
|
444581
|
-
shouldMerge: params.subagentSuccess
|
|
444878
|
+
shouldMerge: params.subagentSuccess,
|
|
444879
|
+
knownNoChanges: params.knownNoChanges,
|
|
444880
|
+
requireAlreadyMerged: params.mergePolicy === "explicit" && integrationRun !== undefined,
|
|
444881
|
+
failureSummary: integrationRun?.error ? `Reflection integration did not complete (${integrationRun.error}); the worktree was cleaned up so the transcript can be retried.` : undefined
|
|
444582
444882
|
});
|
|
444583
444883
|
const completionSuccess = params.subagentSuccess && reflectionIntegrationConsumesTranscript(integration);
|
|
444584
|
-
|
|
444585
|
-
|
|
444586
|
-
|
|
444587
|
-
|
|
444588
|
-
|
|
444884
|
+
const cleanup = getReflectionWorktreeCleanupOutcome(integration);
|
|
444885
|
+
if (cleanup) {
|
|
444886
|
+
telemetry.trackReflectionWorktreeCleanup({
|
|
444887
|
+
outcome: cleanup.outcome,
|
|
444888
|
+
integration_status: cleanup.integrationStatus,
|
|
444889
|
+
trigger_source: params.telemetryContext?.triggerSource,
|
|
444890
|
+
subagent_id: params.subagentAgentId,
|
|
444891
|
+
conversation_id: params.conversationId,
|
|
444892
|
+
reflection_worktree_id: params.worktree.id,
|
|
444893
|
+
commit_count: integration.commitCount,
|
|
444894
|
+
model: params.model ?? undefined
|
|
444589
444895
|
});
|
|
444896
|
+
drainReflectionTelemetry();
|
|
444590
444897
|
}
|
|
444591
444898
|
const completionMessage = await handleMemorySubagentCompletion({
|
|
444592
444899
|
agentId: params.agentId,
|
|
@@ -444602,7 +444909,27 @@ async function finalizeReflectionMemoryWorktreeLaunch(params) {
|
|
|
444602
444909
|
recompileQueuedByConversation: params.recompileQueuedByConversation,
|
|
444603
444910
|
logRecompileFailure: params.logRecompileFailure
|
|
444604
444911
|
});
|
|
444605
|
-
|
|
444912
|
+
if (completionSuccess && integrationRun?.conversationId) {
|
|
444913
|
+
try {
|
|
444914
|
+
const body3 = {
|
|
444915
|
+
summary: buildReflectionIntegrationConversationTitle(params.subagentAgentId),
|
|
444916
|
+
archived: true
|
|
444917
|
+
};
|
|
444918
|
+
if (params.updateIntegrationConversation) {
|
|
444919
|
+
await params.updateIntegrationConversation(integrationRun.conversationId, body3);
|
|
444920
|
+
} else {
|
|
444921
|
+
await getBackend().updateConversation(integrationRun.conversationId, body3);
|
|
444922
|
+
}
|
|
444923
|
+
} catch (error54) {
|
|
444924
|
+
debugWarn("memory", `Failed to archive reflection integration conversation: ${error54 instanceof Error ? error54.message : String(error54)}`);
|
|
444925
|
+
}
|
|
444926
|
+
}
|
|
444927
|
+
return {
|
|
444928
|
+
integration,
|
|
444929
|
+
completionSuccess,
|
|
444930
|
+
completionMessage,
|
|
444931
|
+
integrationConversationId: integrationRun?.conversationId
|
|
444932
|
+
};
|
|
444606
444933
|
}
|
|
444607
444934
|
async function launchReflectionSubagent(options3) {
|
|
444608
444935
|
const {
|
|
@@ -444615,19 +444942,10 @@ async function launchReflectionSubagent(options3) {
|
|
|
444615
444942
|
recompileQueuedByConversation,
|
|
444616
444943
|
onCompletionMessage
|
|
444617
444944
|
} = options3;
|
|
444945
|
+
const reflectionSettings = options3.reflectionSettings ?? getReflectionSettings(agentId);
|
|
444618
444946
|
if (!memfsEnabled) {
|
|
444619
444947
|
return { launched: false, reason: "memfs_disabled" };
|
|
444620
444948
|
}
|
|
444621
|
-
if (triggerSource === "compaction-event" && !options3.skipPendingWorktreeReminderScan) {
|
|
444622
|
-
try {
|
|
444623
|
-
await queuePendingReflectionWorktreeReminders({
|
|
444624
|
-
agentId,
|
|
444625
|
-
conversationId
|
|
444626
|
-
});
|
|
444627
|
-
} catch (error54) {
|
|
444628
|
-
debugWarn("memory", "Failed to queue pending reflection worktree reminders after compaction:", error54 instanceof Error ? error54.message : String(error54));
|
|
444629
|
-
}
|
|
444630
|
-
}
|
|
444631
444949
|
if (!tryReserveReflectionLaunch(agentId)) {
|
|
444632
444950
|
debugLog("memory", `Skipping reflection launch (${triggerSource}) because one is already active`);
|
|
444633
444951
|
if (reservedReflectionAgentIds.has(agentId)) {
|
|
@@ -444638,6 +444956,12 @@ async function launchReflectionSubagent(options3) {
|
|
|
444638
444956
|
let releaseOnComplete = false;
|
|
444639
444957
|
let preparedWorktree;
|
|
444640
444958
|
try {
|
|
444959
|
+
const memoryDir = getScopedMemoryFilesystemRoot(agentId);
|
|
444960
|
+
if (await reflectionMemoryParentHasChanges(memoryDir)) {
|
|
444961
|
+
debugLog("memory", `Skipping reflection launch (${triggerSource}) because parent memory has uncommitted changes`);
|
|
444962
|
+
releaseReflectionLaunch(agentId);
|
|
444963
|
+
return { launched: false, reason: "parent_dirty" };
|
|
444964
|
+
}
|
|
444641
444965
|
const autoPayload = await buildAutoReflectionPayload(agentId, conversationId);
|
|
444642
444966
|
if (!autoPayload) {
|
|
444643
444967
|
debugLog("memory", `Skipping reflection launch (${triggerSource}) because transcript has no new content`);
|
|
@@ -444658,7 +444982,7 @@ async function launchReflectionSubagent(options3) {
|
|
|
444658
444982
|
conversationId,
|
|
444659
444983
|
startMessageId: autoPayload.startMessageId,
|
|
444660
444984
|
endMessageId: autoPayload.endMessageId,
|
|
444661
|
-
model: options3.
|
|
444985
|
+
model: options3.model
|
|
444662
444986
|
});
|
|
444663
444987
|
};
|
|
444664
444988
|
const { subagentId } = spawnBackgroundSubagentTask2({
|
|
@@ -444675,6 +444999,7 @@ async function launchReflectionSubagent(options3) {
|
|
|
444675
444999
|
success: success2,
|
|
444676
445000
|
error: error54,
|
|
444677
445001
|
agentId: reflectionAgentId,
|
|
445002
|
+
model: reflectionModel,
|
|
444678
445003
|
stepCount,
|
|
444679
445004
|
durationMs
|
|
444680
445005
|
}) => {
|
|
@@ -444688,16 +445013,25 @@ async function launchReflectionSubagent(options3) {
|
|
|
444688
445013
|
error: error54,
|
|
444689
445014
|
stepCount,
|
|
444690
445015
|
durationMs,
|
|
445016
|
+
model: reflectionModel,
|
|
444691
445017
|
feedbackContext: options3.feedbackContext
|
|
444692
445018
|
});
|
|
444693
445019
|
const completionConversationId = resolveCompletionConversationId(options3.completionConversationId, conversationId);
|
|
444694
|
-
const {
|
|
445020
|
+
const {
|
|
445021
|
+
completionSuccess,
|
|
445022
|
+
completionMessage,
|
|
445023
|
+
integrationConversationId
|
|
445024
|
+
} = await finalizeReflectionMemoryWorktreeLaunch({
|
|
444695
445025
|
worktree,
|
|
444696
445026
|
subagentSuccess: success2,
|
|
444697
445027
|
subagentError: error54,
|
|
444698
445028
|
agentId,
|
|
444699
445029
|
conversationId: completionConversationId,
|
|
444700
445030
|
subagentAgentId: reflectionAgentId ?? undefined,
|
|
445031
|
+
model: reflectionModel,
|
|
445032
|
+
mergePolicy: reflectionSettings.merge,
|
|
445033
|
+
mergeInstructions: reflectionSettings.mergeInstructions,
|
|
445034
|
+
telemetryContext: { triggerSource },
|
|
444701
445035
|
recompileByConversation,
|
|
444702
445036
|
recompileQueuedByConversation,
|
|
444703
445037
|
logRecompileFailure: (message) => debugWarn("memory", message)
|
|
@@ -444706,7 +445040,8 @@ async function launchReflectionSubagent(options3) {
|
|
|
444706
445040
|
await onCompletionMessage?.(completionMessage, {
|
|
444707
445041
|
success: completionSuccess,
|
|
444708
445042
|
error: error54,
|
|
444709
|
-
reflectionAgentId: reflectionAgentId ?? undefined
|
|
445043
|
+
reflectionAgentId: reflectionAgentId ?? undefined,
|
|
445044
|
+
integrationConversationId
|
|
444710
445045
|
});
|
|
444711
445046
|
} finally {
|
|
444712
445047
|
releaseReflectionLaunch(agentId);
|
|
@@ -444747,14 +445082,13 @@ var init_reflection_launcher = __esm(() => {
|
|
|
444747
445082
|
init_memory_filesystem2();
|
|
444748
445083
|
init_memory_worktree();
|
|
444749
445084
|
init_subagent_state();
|
|
445085
|
+
init_backend2();
|
|
444750
445086
|
init_memory_reminder();
|
|
444751
445087
|
init_memory_subagent_completion();
|
|
444752
445088
|
init_reflection_transcript();
|
|
444753
|
-
init_constants2();
|
|
444754
445089
|
init_telemetry();
|
|
444755
445090
|
init_reflection_threshold_feedback();
|
|
444756
445091
|
init_debug();
|
|
444757
|
-
init_message_queue_bridge();
|
|
444758
445092
|
reservedReflectionAgentIds = new Set;
|
|
444759
445093
|
pendingReflectionLaunches = new Map;
|
|
444760
445094
|
});
|
|
@@ -444938,8 +445272,7 @@ ${targetInstruction}` : targetInstruction;
|
|
|
444938
445272
|
});
|
|
444939
445273
|
},
|
|
444940
445274
|
feedbackContext: {
|
|
444941
|
-
surface: "letta_code_cli"
|
|
444942
|
-
model: parsed.values.model
|
|
445275
|
+
surface: "letta_code_cli"
|
|
444943
445276
|
}
|
|
444944
445277
|
});
|
|
444945
445278
|
if (!result.launched) {
|
|
@@ -444962,6 +445295,9 @@ ${targetInstruction}` : targetInstruction;
|
|
|
444962
445295
|
case "memfs_disabled":
|
|
444963
445296
|
console.error(`Memory filesystem is not enabled for ${agentId}.`);
|
|
444964
445297
|
return 1;
|
|
445298
|
+
case "parent_dirty":
|
|
445299
|
+
console.error("Parent memory has uncommitted changes; commit or discard them before reflecting.");
|
|
445300
|
+
return 1;
|
|
444965
445301
|
default: {
|
|
444966
445302
|
const message = result.error instanceof Error ? result.error.message : String(result.error ?? "Unknown error");
|
|
444967
445303
|
console.error(`Failed to start reflection pass: ${message}`);
|
|
@@ -448563,7 +448899,7 @@ function isSetReflectionSettingsCommand(value) {
|
|
|
448563
448899
|
return false;
|
|
448564
448900
|
}
|
|
448565
448901
|
const settings3 = c.settings;
|
|
448566
|
-
return (settings3.trigger === "off" || settings3.trigger === "step-count" || settings3.trigger === "compaction-event") && typeof settings3.step_count === "number" && Number.isInteger(settings3.step_count) && settings3.step_count > 0 && (c.scope === undefined || c.scope === "local_project" || c.scope === "global" || c.scope === "both");
|
|
448902
|
+
return (settings3.trigger === "off" || settings3.trigger === "step-count" || settings3.trigger === "compaction-event") && typeof settings3.step_count === "number" && Number.isInteger(settings3.step_count) && settings3.step_count > 0 && (settings3.merge === undefined || settings3.merge === "auto" || settings3.merge === "explicit") && (settings3.merge_instructions === undefined || typeof settings3.merge_instructions === "string") && (c.scope === undefined || c.scope === "local_project" || c.scope === "global" || c.scope === "both");
|
|
448567
448903
|
}
|
|
448568
448904
|
function isGetExperimentsCommand(value) {
|
|
448569
448905
|
if (!value || typeof value !== "object")
|
|
@@ -449443,7 +449779,7 @@ __export(exports_memory_scanner, {
|
|
|
449443
449779
|
getFileNodes: () => getFileNodes
|
|
449444
449780
|
});
|
|
449445
449781
|
import { readdirSync as readdirSync18, readFileSync as readFileSync33, statSync as statSync17 } from "node:fs";
|
|
449446
|
-
import { join as join63, relative as
|
|
449782
|
+
import { join as join63, relative as relative9 } from "node:path";
|
|
449447
449783
|
function scanMemoryFilesystem(memoryRoot) {
|
|
449448
449784
|
const nodes = [];
|
|
449449
449785
|
const scanDir = (dir, depth, parentIsLast) => {
|
|
@@ -449483,7 +449819,7 @@ function scanMemoryFilesystem(memoryRoot) {
|
|
|
449483
449819
|
} catch {
|
|
449484
449820
|
return;
|
|
449485
449821
|
}
|
|
449486
|
-
const relativePath =
|
|
449822
|
+
const relativePath = relative9(memoryRoot, fullPath).replace(/\\/g, "/");
|
|
449487
449823
|
const isLast = index === sorted.length - 1;
|
|
449488
449824
|
nodes.push({
|
|
449489
449825
|
name: isDir ? `${name}/` : name,
|
|
@@ -449900,14 +450236,14 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
449900
450236
|
} = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
449901
450237
|
const { readFile: readFile20 } = await import("node:fs/promises");
|
|
449902
450238
|
const { existsSync: existsSync48 } = await import("node:fs");
|
|
449903
|
-
const { isAbsolute: isAbsolute26, join: join64, normalize: normalize5, relative:
|
|
450239
|
+
const { isAbsolute: isAbsolute26, join: join64, normalize: normalize5, relative: relative10, sep: sep7 } = await import("node:path");
|
|
449904
450240
|
if (isAbsolute26(parsed.path) || parsed.path.length === 0) {
|
|
449905
450241
|
sendFailure("path must be a non-empty relative path");
|
|
449906
450242
|
return;
|
|
449907
450243
|
}
|
|
449908
450244
|
const memoryRoot = getScopedMemoryFilesystemRoot2(parsed.agent_id);
|
|
449909
450245
|
const absolutePath = normalize5(join64(memoryRoot, parsed.path));
|
|
449910
|
-
const rel =
|
|
450246
|
+
const rel = relative10(memoryRoot, absolutePath);
|
|
449911
450247
|
if (rel.startsWith("..") || rel === "" || isAbsolute26(rel) || rel.split(sep7).includes("..")) {
|
|
449912
450248
|
sendFailure("path must resolve inside the memory root");
|
|
449913
450249
|
return;
|
|
@@ -449966,14 +450302,14 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
449966
450302
|
const { commitMemoryWrite: commitMemoryWrite2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
|
|
449967
450303
|
const { writeFile: writeFile16, mkdir: mkdir15 } = await import("node:fs/promises");
|
|
449968
450304
|
const { existsSync: existsSync48 } = await import("node:fs");
|
|
449969
|
-
const { dirname: dirname27, isAbsolute: isAbsolute26, join: join64, normalize: normalize5, relative:
|
|
450305
|
+
const { dirname: dirname27, isAbsolute: isAbsolute26, join: join64, normalize: normalize5, relative: relative10, sep: sep7 } = await import("node:path");
|
|
449970
450306
|
if (isAbsolute26(parsed.path) || parsed.path.length === 0) {
|
|
449971
450307
|
sendFailure("write_memory_file: path must be a non-empty relative path");
|
|
449972
450308
|
return;
|
|
449973
450309
|
}
|
|
449974
450310
|
const memoryRoot = getScopedMemoryFilesystemRoot2(parsed.agent_id);
|
|
449975
450311
|
const absolutePath = normalize5(join64(memoryRoot, parsed.path));
|
|
449976
|
-
const rel =
|
|
450312
|
+
const rel = relative10(memoryRoot, absolutePath);
|
|
449977
450313
|
if (rel.startsWith("..") || rel === "" || isAbsolute26(rel) || rel.split(sep7).includes("..")) {
|
|
449978
450314
|
sendFailure("write_memory_file: path must resolve inside the memory root");
|
|
449979
450315
|
return;
|
|
@@ -450064,14 +450400,14 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
450064
450400
|
const { commitMemoryWrite: commitMemoryWrite2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
|
|
450065
450401
|
const { unlink: unlink6 } = await import("node:fs/promises");
|
|
450066
450402
|
const { existsSync: existsSync48 } = await import("node:fs");
|
|
450067
|
-
const { isAbsolute: isAbsolute26, join: join64, normalize: normalize5, relative:
|
|
450403
|
+
const { isAbsolute: isAbsolute26, join: join64, normalize: normalize5, relative: relative10, sep: sep7 } = await import("node:path");
|
|
450068
450404
|
if (isAbsolute26(parsed.path) || parsed.path.length === 0) {
|
|
450069
450405
|
sendFailure("delete_memory_file: path must be a non-empty relative path");
|
|
450070
450406
|
return;
|
|
450071
450407
|
}
|
|
450072
450408
|
const memoryRoot = getScopedMemoryFilesystemRoot2(parsed.agent_id);
|
|
450073
450409
|
const absolutePath = normalize5(join64(memoryRoot, parsed.path));
|
|
450074
|
-
const rel =
|
|
450410
|
+
const rel = relative10(memoryRoot, absolutePath);
|
|
450075
450411
|
if (rel.startsWith("..") || rel === "" || isAbsolute26(rel) || rel.split(sep7).includes("..")) {
|
|
450076
450412
|
sendFailure("delete_memory_file: path must resolve inside the memory root");
|
|
450077
450413
|
return;
|
|
@@ -451407,7 +451743,9 @@ function toReflectionSettingsResponse(agentId, workingDirectory) {
|
|
|
451407
451743
|
return {
|
|
451408
451744
|
agent_id: agentId,
|
|
451409
451745
|
trigger: settings3.trigger,
|
|
451410
|
-
step_count: settings3.stepCount
|
|
451746
|
+
step_count: settings3.stepCount,
|
|
451747
|
+
merge: settings3.merge,
|
|
451748
|
+
merge_instructions: settings3.mergeInstructions
|
|
451411
451749
|
};
|
|
451412
451750
|
}
|
|
451413
451751
|
function resolveReflectionSettingsScope(scope) {
|
|
@@ -451488,9 +451826,12 @@ async function handleReflectionSettingsCommand(parsed, socket, listener, safeSoc
|
|
|
451488
451826
|
}
|
|
451489
451827
|
const { persistLocalProject, persistGlobal, normalizedScope } = resolveReflectionSettingsScope(parsed.scope);
|
|
451490
451828
|
try {
|
|
451829
|
+
const currentSettings = getReflectionSettings(agentId, workingDirectory);
|
|
451491
451830
|
await persistReflectionSettingsForAgent(agentId, {
|
|
451492
451831
|
trigger: parsed.settings.trigger,
|
|
451493
|
-
stepCount: parsed.settings.step_count
|
|
451832
|
+
stepCount: parsed.settings.step_count,
|
|
451833
|
+
merge: parsed.settings.merge ?? currentSettings.merge,
|
|
451834
|
+
mergeInstructions: parsed.settings.merge_instructions ?? currentSettings.mergeInstructions
|
|
451494
451835
|
}, {
|
|
451495
451836
|
workingDirectory,
|
|
451496
451837
|
persistLocalProject,
|
|
@@ -456901,7 +457242,7 @@ var init_diff4 = __esm(() => {
|
|
|
456901
457242
|
});
|
|
456902
457243
|
|
|
456903
457244
|
// src/cli/helpers/shell-semantic-display.ts
|
|
456904
|
-
import { relative as
|
|
457245
|
+
import { relative as relative10 } from "node:path";
|
|
456905
457246
|
function quoteSummaryValue(value) {
|
|
456906
457247
|
return JSON.stringify(value);
|
|
456907
457248
|
}
|
|
@@ -456968,7 +457309,7 @@ function formatDisplayPath2(filePath) {
|
|
|
456968
457309
|
return ".";
|
|
456969
457310
|
}
|
|
456970
457311
|
const cwd2 = process.cwd();
|
|
456971
|
-
const relativePath =
|
|
457312
|
+
const relativePath = relative10(cwd2, filePath);
|
|
456972
457313
|
if (relativePath === "") {
|
|
456973
457314
|
return ".";
|
|
456974
457315
|
}
|
|
@@ -457593,13 +457934,13 @@ __export(exports_format_args_display, {
|
|
|
457593
457934
|
parsePatchInput: () => parsePatchInput,
|
|
457594
457935
|
formatArgsDisplay: () => formatArgsDisplay
|
|
457595
457936
|
});
|
|
457596
|
-
import { relative as
|
|
457937
|
+
import { relative as relative11 } from "node:path";
|
|
457597
457938
|
function formatItemCount(count) {
|
|
457598
457939
|
return `${String(count)} item${count === 1 ? "" : "s"}`;
|
|
457599
457940
|
}
|
|
457600
457941
|
function formatDisplayPath3(filePath) {
|
|
457601
457942
|
const cwd2 = process.cwd();
|
|
457602
|
-
const relativePath =
|
|
457943
|
+
const relativePath = relative11(cwd2, filePath);
|
|
457603
457944
|
if (relativePath.startsWith("..")) {
|
|
457604
457945
|
return filePath;
|
|
457605
457946
|
}
|
|
@@ -458753,7 +459094,7 @@ var init_post_turn_reflection = __esm(() => {
|
|
|
458753
459094
|
});
|
|
458754
459095
|
|
|
458755
459096
|
// src/websocket/listener/turn-events.ts
|
|
458756
|
-
function
|
|
459097
|
+
function escapeTaskNotificationSummary(summary) {
|
|
458757
459098
|
return summary.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
458758
459099
|
}
|
|
458759
459100
|
function isTurnInputArray(value) {
|
|
@@ -458818,7 +459159,6 @@ function buildMaybeLaunchReflectionSubagent(params) {
|
|
|
458818
459159
|
conversationId,
|
|
458819
459160
|
memfsEnabled: settingsManager.isMemfsEnabled(agentId),
|
|
458820
459161
|
triggerSource,
|
|
458821
|
-
skipPendingWorktreeReminderScan: triggerSource === "compaction-event",
|
|
458822
459162
|
reflectionSettings,
|
|
458823
459163
|
description: AUTO_REFLECTION_DESCRIPTION,
|
|
458824
459164
|
recompileByConversation: runtime.listener.systemPromptRecompileByConversation,
|
|
@@ -458827,8 +459167,8 @@ function buildMaybeLaunchReflectionSubagent(params) {
|
|
|
458827
459167
|
surface: getListenerTelemetrySurface()
|
|
458828
459168
|
},
|
|
458829
459169
|
onCompletionMessage: async (completionMessage, reflectionResult) => {
|
|
458830
|
-
const reflectionAgentIdTag = reflectionResult.reflectionAgentId ? `<reflection-agent-id>${
|
|
458831
|
-
const notificationXml = `<task-notification><summary>${
|
|
459170
|
+
const reflectionAgentIdTag = reflectionResult.reflectionAgentId ? `<reflection-agent-id>${escapeTaskNotificationSummary(reflectionResult.reflectionAgentId)}</reflection-agent-id>` : "";
|
|
459171
|
+
const notificationXml = `<task-notification><summary>${escapeTaskNotificationSummary(completionMessage)}</summary>${reflectionAgentIdTag}</task-notification>`;
|
|
458832
459172
|
emitCanonicalMessageDelta(socket, runtime, {
|
|
458833
459173
|
type: "message",
|
|
458834
459174
|
id: `user-msg-${crypto.randomUUID()}`,
|
|
@@ -458898,10 +459238,6 @@ async function completeSuccessfulListenerTurn(params) {
|
|
|
458898
459238
|
reflectionSettings,
|
|
458899
459239
|
reminderState: params.runtime.reminderState,
|
|
458900
459240
|
contextTracker: params.runtime.contextTracker,
|
|
458901
|
-
onCompaction: () => queuePendingReflectionWorktreeReminders({
|
|
458902
|
-
agentId: params.agentId,
|
|
458903
|
-
conversationId: params.conversationId
|
|
458904
|
-
}),
|
|
458905
459241
|
launch: buildMaybeLaunchReflectionSubagent({
|
|
458906
459242
|
runtime: params.runtime,
|
|
458907
459243
|
socket: params.socket,
|
|
@@ -458926,7 +459262,6 @@ var init_turn_completion = __esm(async () => {
|
|
|
458926
459262
|
init_conversation_description();
|
|
458927
459263
|
init_memory_reminder();
|
|
458928
459264
|
init_post_turn_reflection();
|
|
458929
|
-
init_reflection_launcher();
|
|
458930
459265
|
init_reflection_transcript();
|
|
458931
459266
|
init_settings_manager();
|
|
458932
459267
|
init_debug();
|
|
@@ -460639,7 +460974,7 @@ var init_turn = __esm(async () => {
|
|
|
460639
460974
|
});
|
|
460640
460975
|
|
|
460641
460976
|
// src/websocket/listener/control-inputs.ts
|
|
460642
|
-
import { realpath as
|
|
460977
|
+
import { realpath as realpath4, stat as stat13 } from "node:fs/promises";
|
|
460643
460978
|
import path38 from "node:path";
|
|
460644
460979
|
function trackListenerError2(errorType, error54, context3) {
|
|
460645
460980
|
trackBoundaryError({
|
|
@@ -460900,7 +461235,7 @@ async function handleCwdChange(msg, socket, runtime) {
|
|
|
460900
461235
|
throw new Error("Working directory cannot be empty");
|
|
460901
461236
|
}
|
|
460902
461237
|
const resolvedPath = path38.isAbsolute(requestedPath) ? requestedPath : path38.resolve(currentWorkingDirectory, requestedPath);
|
|
460903
|
-
const normalizedPath = await
|
|
461238
|
+
const normalizedPath = await realpath4(resolvedPath);
|
|
460904
461239
|
const stats = await stat13(normalizedPath);
|
|
460905
461240
|
if (!stats.isDirectory()) {
|
|
460906
461241
|
throw new Error(`Not a directory: ${normalizedPath}`);
|
|
@@ -461553,8 +461888,8 @@ function normalizeAbsPath(value) {
|
|
|
461553
461888
|
return path40.resolve(value);
|
|
461554
461889
|
}
|
|
461555
461890
|
function isWithinOrEqual(parent, child) {
|
|
461556
|
-
const
|
|
461557
|
-
return
|
|
461891
|
+
const relative13 = path40.relative(parent, child);
|
|
461892
|
+
return relative13 === "" || !relative13.startsWith("..") && !path40.isAbsolute(relative13);
|
|
461558
461893
|
}
|
|
461559
461894
|
function getHomeDirectory() {
|
|
461560
461895
|
return normalizeAbsPath(process.env.HOME || homedir41());
|
|
@@ -461567,10 +461902,10 @@ function getProtectedHomeSegment(absPath) {
|
|
|
461567
461902
|
const target2 = normalizeAbsPath(absPath);
|
|
461568
461903
|
if (!isWithinOrEqual(home, target2))
|
|
461569
461904
|
return null;
|
|
461570
|
-
const
|
|
461571
|
-
if (!
|
|
461905
|
+
const relative13 = path40.relative(home, target2);
|
|
461906
|
+
if (!relative13)
|
|
461572
461907
|
return null;
|
|
461573
|
-
const [firstSegment] =
|
|
461908
|
+
const [firstSegment] = relative13.split(path40.sep);
|
|
461574
461909
|
const normalized = firstSegment?.toLowerCase();
|
|
461575
461910
|
return normalized && PROTECTED_HOME_NAMES.has(normalized) ? normalized : null;
|
|
461576
461911
|
}
|
|
@@ -462684,7 +463019,7 @@ var init_init_command = __esm(() => {
|
|
|
462684
463019
|
|
|
462685
463020
|
// src/cli/helpers/skill-name-frontmatter-repair.ts
|
|
462686
463021
|
import { readdir as readdir12, readFile as readFile22, stat as stat14, writeFile as writeFile16 } from "node:fs/promises";
|
|
462687
|
-
import { basename as basename27, dirname as dirname30, join as join67, relative as
|
|
463022
|
+
import { basename as basename27, dirname as dirname30, join as join67, relative as relative13 } from "node:path";
|
|
462688
463023
|
async function pathExists(path41) {
|
|
462689
463024
|
try {
|
|
462690
463025
|
await stat14(path41);
|
|
@@ -462787,7 +463122,7 @@ async function repairMissingSkillNameFrontmatter(memoryDir) {
|
|
|
462787
463122
|
return result;
|
|
462788
463123
|
}
|
|
462789
463124
|
for (const skillFile of skillFiles.sort()) {
|
|
462790
|
-
const displayPath =
|
|
463125
|
+
const displayPath = relative13(memoryDir, skillFile).replace(/\\/g, "/");
|
|
462791
463126
|
result.scanned++;
|
|
462792
463127
|
try {
|
|
462793
463128
|
const content = await readFile22(skillFile, "utf8");
|
|
@@ -463373,7 +463708,7 @@ async function handleReflectCommand(socket, conversationRuntime) {
|
|
|
463373
463708
|
recompileByConversation: listener.systemPromptRecompileByConversation,
|
|
463374
463709
|
recompileQueuedByConversation: listener.queuedSystemPromptRecompileByConversation,
|
|
463375
463710
|
onCompletionMessage: async (completionMessage, reflectionResult) => {
|
|
463376
|
-
const reflectionAgentIdTag = reflectionResult.reflectionAgentId ? `<reflection-agent-id>${
|
|
463711
|
+
const reflectionAgentIdTag = reflectionResult.reflectionAgentId ? `<reflection-agent-id>${escapeTaskNotificationSummary(reflectionResult.reflectionAgentId)}</reflection-agent-id>` : "";
|
|
463377
463712
|
emitCanonicalMessageDelta(socket, conversationRuntime, {
|
|
463378
463713
|
type: "message",
|
|
463379
463714
|
id: `user-msg-${crypto.randomUUID()}`,
|
|
@@ -463382,7 +463717,7 @@ async function handleReflectCommand(socket, conversationRuntime) {
|
|
|
463382
463717
|
content: [
|
|
463383
463718
|
{
|
|
463384
463719
|
type: "text",
|
|
463385
|
-
text: `<task-notification><summary>${
|
|
463720
|
+
text: `<task-notification><summary>${escapeTaskNotificationSummary(completionMessage)}</summary>${reflectionAgentIdTag}</task-notification>`
|
|
463386
463721
|
}
|
|
463387
463722
|
]
|
|
463388
463723
|
}, { agent_id: agentId, conversation_id: conversationId });
|
|
@@ -471135,8 +471470,8 @@ function isRecord13(value) {
|
|
|
471135
471470
|
function isPathInsideOrEqual2(childPath, parentPath) {
|
|
471136
471471
|
const child = path41.resolve(childPath);
|
|
471137
471472
|
const parent = path41.resolve(parentPath);
|
|
471138
|
-
const
|
|
471139
|
-
return
|
|
471473
|
+
const relative14 = path41.relative(parent, child);
|
|
471474
|
+
return relative14 === "" || !!relative14 && !relative14.startsWith("..") && !path41.isAbsolute(relative14);
|
|
471140
471475
|
}
|
|
471141
471476
|
function readPackageJson(packageJsonPath) {
|
|
471142
471477
|
let parsed;
|
|
@@ -472658,7 +472993,22 @@ var init_server = __esm(async () => {
|
|
|
472658
472993
|
|
|
472659
472994
|
// src/auth/LettaLoginView.tsx
|
|
472660
472995
|
import { hostname as hostname7 } from "node:os";
|
|
472996
|
+
async function completeLettaLogin(tokens, options3) {
|
|
472997
|
+
const settings3 = options3.settings ?? settingsManager;
|
|
472998
|
+
const now = options3.now?.() ?? Date.now();
|
|
472999
|
+
settings3.updateSettings({
|
|
473000
|
+
env: { LETTA_API_KEY: tokens.access_token },
|
|
473001
|
+
refreshToken: tokens.refresh_token,
|
|
473002
|
+
tokenExpiresAt: now + tokens.expires_in * 1000,
|
|
473003
|
+
preferredBackendMode: "api"
|
|
473004
|
+
});
|
|
473005
|
+
await settings3.flush();
|
|
473006
|
+
if (options3.activateCloudBackend) {
|
|
473007
|
+
configureBackendMode("api");
|
|
473008
|
+
}
|
|
473009
|
+
}
|
|
472661
473010
|
function LettaLoginView({
|
|
473011
|
+
activateCloudBackend,
|
|
472662
473012
|
onComplete,
|
|
472663
473013
|
onCancel,
|
|
472664
473014
|
successMessage = "Signed in with Letta. Switch agents with /agents."
|
|
@@ -472703,15 +473053,7 @@ function LettaLoginView({
|
|
|
472703
473053
|
return;
|
|
472704
473054
|
}
|
|
472705
473055
|
const tokens = await pollForToken2(deviceData.device_code, deviceData.interval, deviceData.expires_in, deviceId, deviceName, controller.signal);
|
|
472706
|
-
|
|
472707
|
-
settingsManager.updateSettings({
|
|
472708
|
-
env: { LETTA_API_KEY: tokens.access_token },
|
|
472709
|
-
refreshToken: tokens.refresh_token,
|
|
472710
|
-
tokenExpiresAt: now + tokens.expires_in * 1000,
|
|
472711
|
-
preferredBackendMode: "api"
|
|
472712
|
-
});
|
|
472713
|
-
await settingsManager.flush();
|
|
472714
|
-
configureBackendMode("api");
|
|
473056
|
+
await completeLettaLogin(tokens, { activateCloudBackend });
|
|
472715
473057
|
setDoneMessage(successMessage);
|
|
472716
473058
|
setTimeout(() => onCompleteRef.current?.(), 500);
|
|
472717
473059
|
} catch (err) {
|
|
@@ -472726,7 +473068,7 @@ function LettaLoginView({
|
|
|
472726
473068
|
cancelledRef.current = true;
|
|
472727
473069
|
abortControllerRef.current?.abort();
|
|
472728
473070
|
};
|
|
472729
|
-
}, [successMessage]);
|
|
473071
|
+
}, [activateCloudBackend, successMessage]);
|
|
472730
473072
|
if (doneMessage) {
|
|
472731
473073
|
return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
|
|
472732
473074
|
flexDirection: "column",
|
|
@@ -472926,6 +473268,7 @@ function SetupUI({
|
|
|
472926
473268
|
children: " "
|
|
472927
473269
|
}, undefined, false, undefined, this),
|
|
472928
473270
|
/* @__PURE__ */ jsx_dev_runtime15.jsxDEV(LettaLoginView, {
|
|
473271
|
+
activateCloudBackend: true,
|
|
472929
473272
|
onComplete: () => onComplete({ kind: "cloud-login" }),
|
|
472930
473273
|
onCancel: () => setMode("menu"),
|
|
472931
473274
|
successMessage: "Signed in with Letta. Starting Letta Code..."
|
|
@@ -473094,6 +473437,252 @@ var init_setup7 = __esm(async () => {
|
|
|
473094
473437
|
await init_setup6();
|
|
473095
473438
|
});
|
|
473096
473439
|
|
|
473440
|
+
// src/cli/subcommands/shared-memory.ts
|
|
473441
|
+
import { existsSync as existsSync57 } from "node:fs";
|
|
473442
|
+
import { join as join72 } from "node:path";
|
|
473443
|
+
import { parseArgs as parseArgs14 } from "node:util";
|
|
473444
|
+
function printUsage12() {
|
|
473445
|
+
console.log(`
|
|
473446
|
+
Usage:
|
|
473447
|
+
letta shared-memory list [--agent <id>]
|
|
473448
|
+
letta shared-memory create --name <name>
|
|
473449
|
+
letta shared-memory attach <name-or-id> [--agent <id>]
|
|
473450
|
+
letta shared-memory detach <name-or-id> [--agent <id>]
|
|
473451
|
+
letta shared-memory sync [--agent <id>]
|
|
473452
|
+
letta shared-memory history <name-or-id> [--path <file>] [--limit <n>]
|
|
473453
|
+
|
|
473454
|
+
Actions:
|
|
473455
|
+
list List org repositories, marking which are attached to the agent
|
|
473456
|
+
create Create a new shared memory repository
|
|
473457
|
+
attach Attach a repository to the agent, clone its local mount, and
|
|
473458
|
+
recompile the agent's system prompt
|
|
473459
|
+
detach Detach a repository from the agent and recompile
|
|
473460
|
+
sync Clone/pull local mounts for every repository attached to the agent
|
|
473461
|
+
history List commits for a repository (optionally scoped to one path)
|
|
473462
|
+
|
|
473463
|
+
Notes:
|
|
473464
|
+
- Output is JSON only.
|
|
473465
|
+
- Agent id comes from --agent or AGENT_ID/LETTA_AGENT_ID in the env.
|
|
473466
|
+
- Uses CLI auth; override with LETTA_API_KEY/LETTA_BASE_URL if needed.
|
|
473467
|
+
- Attached repositories mount at $MEMORY_DIR/../<name> as normal git
|
|
473468
|
+
checkouts. Edit files and commit/push there like MemFS — no API calls
|
|
473469
|
+
are needed for file content.
|
|
473470
|
+
|
|
473471
|
+
Examples:
|
|
473472
|
+
letta shared-memory list
|
|
473473
|
+
letta shared-memory create --name shared-notes
|
|
473474
|
+
letta shared-memory attach shared-notes
|
|
473475
|
+
letta shared-memory history shared-notes --path docs/plan.md
|
|
473476
|
+
`.trim());
|
|
473477
|
+
}
|
|
473478
|
+
function parseSharedMemoryArgs(argv) {
|
|
473479
|
+
return parseArgs14({
|
|
473480
|
+
args: argv,
|
|
473481
|
+
options: SHARED_MEMORY_OPTIONS,
|
|
473482
|
+
strict: true,
|
|
473483
|
+
allowPositionals: true
|
|
473484
|
+
});
|
|
473485
|
+
}
|
|
473486
|
+
function resolveSharedMemoryAgentId(agent2, agentId, env5 = process.env) {
|
|
473487
|
+
return (agent2 || agentId || env5.LETTA_AGENT_ID || env5.AGENT_ID || "").trim();
|
|
473488
|
+
}
|
|
473489
|
+
function parseLimit4(value, fallback) {
|
|
473490
|
+
if (typeof value !== "string" || value.length === 0)
|
|
473491
|
+
return fallback;
|
|
473492
|
+
const parsed = Number.parseInt(value, 10);
|
|
473493
|
+
return Number.isNaN(parsed) || parsed <= 0 ? fallback : parsed;
|
|
473494
|
+
}
|
|
473495
|
+
async function listOrgRepositories(request) {
|
|
473496
|
+
const repositories = [];
|
|
473497
|
+
const limit3 = 50;
|
|
473498
|
+
let offset = 0;
|
|
473499
|
+
for (;; ) {
|
|
473500
|
+
const page = await request("GET", `/v1/repositories?limit=${limit3}&offset=${offset}`);
|
|
473501
|
+
repositories.push(...page.repositories);
|
|
473502
|
+
if (!page.has_next_page)
|
|
473503
|
+
break;
|
|
473504
|
+
offset += limit3;
|
|
473505
|
+
}
|
|
473506
|
+
return repositories;
|
|
473507
|
+
}
|
|
473508
|
+
async function listAgentRepositories(request, agentId) {
|
|
473509
|
+
const response = await request("GET", `/v1/agents/${encodeURIComponent(agentId)}/repositories`);
|
|
473510
|
+
return response.repositories.filter((repository) => !repository.is_primary && repository.name !== "memory");
|
|
473511
|
+
}
|
|
473512
|
+
function resolveRepositoryReference(repositories, reference) {
|
|
473513
|
+
const trimmed = reference.trim();
|
|
473514
|
+
if (!trimmed)
|
|
473515
|
+
return null;
|
|
473516
|
+
return repositories.find((repository) => repository.id === trimmed) ?? repositories.find((repository) => repository.name === trimmed) ?? null;
|
|
473517
|
+
}
|
|
473518
|
+
async function waitForAttachedRepository(request, agentId, repositoryId, poll) {
|
|
473519
|
+
for (let attempt = 0;attempt < poll.attempts; attempt += 1) {
|
|
473520
|
+
const attached = await listAgentRepositories(request, agentId);
|
|
473521
|
+
if (attached.some((repository) => repository.id === repositoryId)) {
|
|
473522
|
+
return true;
|
|
473523
|
+
}
|
|
473524
|
+
await new Promise((resolvePoll) => setTimeout(resolvePoll, poll.intervalMs));
|
|
473525
|
+
}
|
|
473526
|
+
return false;
|
|
473527
|
+
}
|
|
473528
|
+
async function defaultRecompileAgent(agentId) {
|
|
473529
|
+
const { getClient: getClient2 } = await Promise.resolve().then(() => (init_client2(), exports_client));
|
|
473530
|
+
const client = await getClient2();
|
|
473531
|
+
await client.agents.recompile(agentId, { update_timestamp: false });
|
|
473532
|
+
}
|
|
473533
|
+
async function recompileAndReportFailure(recompileAgent, agentId) {
|
|
473534
|
+
try {
|
|
473535
|
+
await recompileAgent(agentId);
|
|
473536
|
+
return null;
|
|
473537
|
+
} catch (error54) {
|
|
473538
|
+
return error54 instanceof Error ? error54.message : String(error54);
|
|
473539
|
+
}
|
|
473540
|
+
}
|
|
473541
|
+
function requireAgentId(parsed) {
|
|
473542
|
+
const agentId = resolveSharedMemoryAgentId(parsed.values.agent, parsed.values["agent-id"]);
|
|
473543
|
+
if (!agentId) {
|
|
473544
|
+
console.error("Agent id required: pass --agent <id> or set AGENT_ID/LETTA_AGENT_ID.");
|
|
473545
|
+
return null;
|
|
473546
|
+
}
|
|
473547
|
+
return agentId;
|
|
473548
|
+
}
|
|
473549
|
+
async function runSharedMemorySubcommand(argv, deps = {}) {
|
|
473550
|
+
let parsed;
|
|
473551
|
+
try {
|
|
473552
|
+
parsed = parseSharedMemoryArgs(argv);
|
|
473553
|
+
} catch (error54) {
|
|
473554
|
+
console.error(error54 instanceof Error ? error54.message : String(error54));
|
|
473555
|
+
printUsage12();
|
|
473556
|
+
return 1;
|
|
473557
|
+
}
|
|
473558
|
+
const [action3, reference] = parsed.positionals;
|
|
473559
|
+
if (parsed.values.help || !action3 || action3 === "help") {
|
|
473560
|
+
printUsage12();
|
|
473561
|
+
return 0;
|
|
473562
|
+
}
|
|
473563
|
+
if (isLocalBackendEnvEnabled()) {
|
|
473564
|
+
console.error("Shared memory requires a Letta Cloud agent; the local backend does not support it.");
|
|
473565
|
+
return 1;
|
|
473566
|
+
}
|
|
473567
|
+
await (deps.initializeSettings ?? (() => settingsManager.initialize()))();
|
|
473568
|
+
const request = deps.request ?? apiRequest;
|
|
473569
|
+
const syncRepositories = deps.syncRepositories ?? syncAttachedAgentRepositories;
|
|
473570
|
+
const recompileAgent = deps.recompileAgent ?? defaultRecompileAgent;
|
|
473571
|
+
try {
|
|
473572
|
+
if (action3 === "list") {
|
|
473573
|
+
const agentId = resolveSharedMemoryAgentId(parsed.values.agent, parsed.values["agent-id"]);
|
|
473574
|
+
const repositories = await listOrgRepositories(request);
|
|
473575
|
+
let attachedIds = new Set;
|
|
473576
|
+
if (agentId && !isLocalAgentId(agentId)) {
|
|
473577
|
+
const attached = await listAgentRepositories(request, agentId);
|
|
473578
|
+
attachedIds = new Set(attached.map((repository) => repository.id));
|
|
473579
|
+
}
|
|
473580
|
+
console.log(JSON.stringify({
|
|
473581
|
+
repositories: repositories.map((repository) => ({
|
|
473582
|
+
...repository,
|
|
473583
|
+
...agentId ? { attached: attachedIds.has(repository.id) } : {}
|
|
473584
|
+
}))
|
|
473585
|
+
}, null, 2));
|
|
473586
|
+
return 0;
|
|
473587
|
+
}
|
|
473588
|
+
if (action3 === "create") {
|
|
473589
|
+
const name = parsed.values.name?.trim();
|
|
473590
|
+
if (!name) {
|
|
473591
|
+
console.error("Usage: letta shared-memory create --name <name>");
|
|
473592
|
+
return 1;
|
|
473593
|
+
}
|
|
473594
|
+
const repository = await request("POST", "/v1/repositories", { name });
|
|
473595
|
+
console.log(JSON.stringify(repository, null, 2));
|
|
473596
|
+
return 0;
|
|
473597
|
+
}
|
|
473598
|
+
if (action3 === "attach" || action3 === "detach" || action3 === "history") {
|
|
473599
|
+
if (!reference) {
|
|
473600
|
+
console.error(`Usage: letta shared-memory ${action3} <name-or-id>`);
|
|
473601
|
+
return 1;
|
|
473602
|
+
}
|
|
473603
|
+
const repositories = await listOrgRepositories(request);
|
|
473604
|
+
const repository = resolveRepositoryReference(repositories, reference);
|
|
473605
|
+
if (!repository) {
|
|
473606
|
+
console.error(`Repository not found: ${reference}. Run \`letta shared-memory list\` to see available repositories.`);
|
|
473607
|
+
return 1;
|
|
473608
|
+
}
|
|
473609
|
+
if (action3 === "history") {
|
|
473610
|
+
const limit3 = parseLimit4(parsed.values.limit, 20);
|
|
473611
|
+
const query2 = new URLSearchParams({ limit: String(limit3) });
|
|
473612
|
+
if (parsed.values.path) {
|
|
473613
|
+
query2.set("path", parsed.values.path);
|
|
473614
|
+
}
|
|
473615
|
+
const versions2 = await request("GET", `/v1/repositories/${encodeURIComponent(repository.id)}/versions?${query2}`);
|
|
473616
|
+
console.log(JSON.stringify({ repository: repository.name, ...versions2 }, null, 2));
|
|
473617
|
+
return 0;
|
|
473618
|
+
}
|
|
473619
|
+
const agentId = requireAgentId(parsed);
|
|
473620
|
+
if (!agentId)
|
|
473621
|
+
return 1;
|
|
473622
|
+
if (action3 === "attach") {
|
|
473623
|
+
await request("POST", `/v1/agents/${encodeURIComponent(agentId)}/repositories`, { repository_id: repository.id });
|
|
473624
|
+
const visible = await waitForAttachedRepository(request, agentId, repository.id, deps.attachPoll ?? DEFAULT_ATTACH_POLL);
|
|
473625
|
+
if (!visible) {
|
|
473626
|
+
console.error(`Attach accepted but ${repository.name} did not appear in the agent's repository list. Retry \`letta shared-memory sync\` shortly.`);
|
|
473627
|
+
return 1;
|
|
473628
|
+
}
|
|
473629
|
+
const sync2 = await syncRepositories(agentId);
|
|
473630
|
+
const recompileError = await recompileAndReportFailure(recompileAgent, agentId);
|
|
473631
|
+
const mountDir = getRepositoryMountDir(agentId, repository.name);
|
|
473632
|
+
const mounted = existsSync57(join72(mountDir, ".git"));
|
|
473633
|
+
console.log(JSON.stringify({
|
|
473634
|
+
attached: true,
|
|
473635
|
+
repository: { id: repository.id, name: repository.name },
|
|
473636
|
+
mount: mounted ? mountDir : null,
|
|
473637
|
+
sync: sync2.summaries,
|
|
473638
|
+
...recompileError ? { recompile_failed: recompileError } : {},
|
|
473639
|
+
note: mounted ? "Edit files under the mount and commit/push with git, like MemFS." : "The repository is attached but its local mount was not created — see `sync` above. Resolve the reported error, then re-run `letta shared-memory sync`."
|
|
473640
|
+
}, null, 2));
|
|
473641
|
+
return mounted ? 0 : 1;
|
|
473642
|
+
}
|
|
473643
|
+
await request("DELETE", `/v1/agents/${encodeURIComponent(agentId)}/repositories/${encodeURIComponent(repository.id)}`);
|
|
473644
|
+
const detachRecompileError = await recompileAndReportFailure(recompileAgent, agentId);
|
|
473645
|
+
console.log(JSON.stringify({
|
|
473646
|
+
detached: true,
|
|
473647
|
+
repository: { id: repository.id, name: repository.name },
|
|
473648
|
+
...detachRecompileError ? { recompile_failed: detachRecompileError } : {},
|
|
473649
|
+
note: "The local mount was left in place; delete it manually if no longer needed."
|
|
473650
|
+
}, null, 2));
|
|
473651
|
+
return 0;
|
|
473652
|
+
}
|
|
473653
|
+
if (action3 === "sync") {
|
|
473654
|
+
const agentId = requireAgentId(parsed);
|
|
473655
|
+
if (!agentId)
|
|
473656
|
+
return 1;
|
|
473657
|
+
const result = await syncRepositories(agentId);
|
|
473658
|
+
console.log(JSON.stringify(result, null, 2));
|
|
473659
|
+
return result.failed > 0 ? 1 : 0;
|
|
473660
|
+
}
|
|
473661
|
+
console.error(`Unknown action: ${action3}`);
|
|
473662
|
+
printUsage12();
|
|
473663
|
+
return 1;
|
|
473664
|
+
} catch (error54) {
|
|
473665
|
+
console.error(error54 instanceof Error ? error54.message : String(error54));
|
|
473666
|
+
return 1;
|
|
473667
|
+
}
|
|
473668
|
+
}
|
|
473669
|
+
var SHARED_MEMORY_OPTIONS, DEFAULT_ATTACH_POLL;
|
|
473670
|
+
var init_shared_memory = __esm(() => {
|
|
473671
|
+
init_memory_git();
|
|
473672
|
+
init_request();
|
|
473673
|
+
init_paths();
|
|
473674
|
+
init_settings_manager();
|
|
473675
|
+
SHARED_MEMORY_OPTIONS = {
|
|
473676
|
+
help: { type: "boolean", short: "h" },
|
|
473677
|
+
agent: { type: "string" },
|
|
473678
|
+
"agent-id": { type: "string" },
|
|
473679
|
+
name: { type: "string" },
|
|
473680
|
+
path: { type: "string" },
|
|
473681
|
+
limit: { type: "string" }
|
|
473682
|
+
};
|
|
473683
|
+
DEFAULT_ATTACH_POLL = { intervalMs: 1000, attempts: 15 };
|
|
473684
|
+
});
|
|
473685
|
+
|
|
473097
473686
|
// src/cli/components/AgentSelectorFooter.tsx
|
|
473098
473687
|
function buildCloudPageText(params) {
|
|
473099
473688
|
return `Page ${params.cloudPage + 1}${params.cloudHasMore ? "+" : `/${params.cloudTotalPages || 1}`}${params.cloudLoadingMore ? " (loading...)" : ""}`;
|
|
@@ -474567,7 +475156,7 @@ var init_AgentSelector = __esm(async () => {
|
|
|
474567
475156
|
// src/cli/subcommands/skills.ts
|
|
474568
475157
|
import {
|
|
474569
475158
|
cpSync as cpSync2,
|
|
474570
|
-
existsSync as
|
|
475159
|
+
existsSync as existsSync58,
|
|
474571
475160
|
mkdtempSync as mkdtempSync4,
|
|
474572
475161
|
readFileSync as readFileSync38,
|
|
474573
475162
|
rmSync as rmSync14,
|
|
@@ -474576,9 +475165,9 @@ import {
|
|
|
474576
475165
|
} from "node:fs";
|
|
474577
475166
|
import { mkdir as mkdir15, readdir as readdir14 } from "node:fs/promises";
|
|
474578
475167
|
import { tmpdir as tmpdir10 } from "node:os";
|
|
474579
|
-
import { basename as basename28, dirname as dirname33, join as
|
|
474580
|
-
import { parseArgs as
|
|
474581
|
-
function
|
|
475168
|
+
import { basename as basename28, dirname as dirname33, join as join73, normalize as normalize5, resolve as resolve33, sep as sep7 } from "node:path";
|
|
475169
|
+
import { parseArgs as parseArgs15, TextDecoder as TextDecoder2, TextEncoder as TextEncoder2 } from "node:util";
|
|
475170
|
+
function printUsage13() {
|
|
474582
475171
|
console.log(`
|
|
474583
475172
|
Usage:
|
|
474584
475173
|
letta install <thing> [--agent <id> | -n <agent name>] [--force]
|
|
@@ -474605,7 +475194,7 @@ Options:
|
|
|
474605
475194
|
`.trim());
|
|
474606
475195
|
}
|
|
474607
475196
|
function parseSkillsArgs(argv) {
|
|
474608
|
-
return
|
|
475197
|
+
return parseArgs15({
|
|
474609
475198
|
args: argv,
|
|
474610
475199
|
options: SKILLS_OPTIONS,
|
|
474611
475200
|
strict: true,
|
|
@@ -474868,14 +475457,14 @@ async function resolveBranchAndSubdir(location) {
|
|
|
474868
475457
|
}
|
|
474869
475458
|
async function cloneSkillSource(location) {
|
|
474870
475459
|
const resolvedLocation = await resolveBranchAndSubdir(location);
|
|
474871
|
-
const tmpDir = mkdtempSync4(
|
|
475460
|
+
const tmpDir = mkdtempSync4(join73(tmpdir10(), "letta-skill-install-"));
|
|
474872
475461
|
const args = ["clone", "--depth", "1"];
|
|
474873
475462
|
if (resolvedLocation.branch) {
|
|
474874
475463
|
args.push("--branch", resolvedLocation.branch);
|
|
474875
475464
|
}
|
|
474876
475465
|
args.push(resolvedLocation.repoUrl, tmpDir);
|
|
474877
475466
|
await execFile16("git", args, { timeout: 120000 });
|
|
474878
|
-
const sourceDir = resolvedLocation.subdir ?
|
|
475467
|
+
const sourceDir = resolvedLocation.subdir ? join73(tmpDir, resolvedLocation.subdir) : tmpDir;
|
|
474879
475468
|
return { tmpDir, sourceDir };
|
|
474880
475469
|
}
|
|
474881
475470
|
function assertDirectSkillFileSize(receivedBytes, maxBytes) {
|
|
@@ -474930,11 +475519,11 @@ async function downloadDirectSkillFileSource(location, options3 = {}) {
|
|
|
474930
475519
|
throw new Error(`Direct skill file download failed for ${location.url}: ${response.status}`);
|
|
474931
475520
|
}
|
|
474932
475521
|
const skillText = await readResponseTextWithLimit(response, MAX_DIRECT_SKILL_FILE_BYTES);
|
|
474933
|
-
const tmpDir = mkdtempSync4(
|
|
475522
|
+
const tmpDir = mkdtempSync4(join73(tmpdir10(), "letta-direct-skill-"));
|
|
474934
475523
|
try {
|
|
474935
|
-
const sourceDir =
|
|
475524
|
+
const sourceDir = join73(tmpDir, "skill");
|
|
474936
475525
|
await mkdir15(sourceDir, { recursive: true });
|
|
474937
|
-
writeFileSync30(
|
|
475526
|
+
writeFileSync30(join73(sourceDir, "SKILL.md"), skillText, "utf8");
|
|
474938
475527
|
return { tmpDir, sourceDir };
|
|
474939
475528
|
} catch (error54) {
|
|
474940
475529
|
rmSync14(tmpDir, { recursive: true, force: true });
|
|
@@ -474975,9 +475564,9 @@ function assertSafeZipMember(name) {
|
|
|
474975
475564
|
}
|
|
474976
475565
|
async function downloadClawHubSkillSource(location) {
|
|
474977
475566
|
const version2 = await resolveClawHubVersion(location);
|
|
474978
|
-
const tmpDir = mkdtempSync4(
|
|
474979
|
-
const zipPath =
|
|
474980
|
-
const sourceDir =
|
|
475567
|
+
const tmpDir = mkdtempSync4(join73(tmpdir10(), "letta-clawhub-skill-"));
|
|
475568
|
+
const zipPath = join73(tmpDir, "skill.zip");
|
|
475569
|
+
const sourceDir = join73(tmpDir, "skill");
|
|
474981
475570
|
await mkdir15(sourceDir, { recursive: true });
|
|
474982
475571
|
const url2 = new URL(`${CLAWHUB_API_BASE_URL}/download`);
|
|
474983
475572
|
url2.searchParams.set("slug", location.slug);
|
|
@@ -475016,7 +475605,7 @@ function sanitizeSkillName(name) {
|
|
|
475016
475605
|
return trimmed;
|
|
475017
475606
|
}
|
|
475018
475607
|
function getSkillName(sourceDir) {
|
|
475019
|
-
const skillMd = readFileSync38(
|
|
475608
|
+
const skillMd = readFileSync38(join73(sourceDir, "SKILL.md"), "utf8");
|
|
475020
475609
|
const { frontmatter } = parseFrontmatter(skillMd);
|
|
475021
475610
|
const frontmatterName = frontmatter.name;
|
|
475022
475611
|
const name = typeof frontmatterName === "string" && frontmatterName.trim() ? frontmatterName : basename28(sourceDir);
|
|
@@ -475025,18 +475614,18 @@ function getSkillName(sourceDir) {
|
|
|
475025
475614
|
async function installSkillDirectory(params) {
|
|
475026
475615
|
const sourceDir = resolve33(params.sourceDir);
|
|
475027
475616
|
const memoryDir = resolve33(params.memoryDir);
|
|
475028
|
-
const skillMdPath =
|
|
475029
|
-
if (!
|
|
475617
|
+
const skillMdPath = join73(sourceDir, "SKILL.md");
|
|
475618
|
+
if (!existsSync58(skillMdPath)) {
|
|
475030
475619
|
throw new Error("No SKILL.md found in the skill directory.");
|
|
475031
475620
|
}
|
|
475032
475621
|
if (!statSync20(sourceDir).isDirectory()) {
|
|
475033
475622
|
throw new Error(`Skill source is not a directory: ${sourceDir}`);
|
|
475034
475623
|
}
|
|
475035
475624
|
const name = getSkillName(sourceDir);
|
|
475036
|
-
const skillsDir =
|
|
475037
|
-
const targetPath =
|
|
475625
|
+
const skillsDir = join73(memoryDir, "skills");
|
|
475626
|
+
const targetPath = join73(skillsDir, name);
|
|
475038
475627
|
assertInside(skillsDir, targetPath);
|
|
475039
|
-
if (
|
|
475628
|
+
if (existsSync58(targetPath)) {
|
|
475040
475629
|
if (!params.force) {
|
|
475041
475630
|
throw new Error(`Skill "${name}" already exists at ${targetPath}. Re-run with --force to replace it.`);
|
|
475042
475631
|
}
|
|
@@ -475051,17 +475640,17 @@ async function installSkillDirectory(params) {
|
|
|
475051
475640
|
}
|
|
475052
475641
|
async function listSkillDirectories(params) {
|
|
475053
475642
|
const memoryDir = resolve33(params.memoryDir);
|
|
475054
|
-
const skillsDir =
|
|
475055
|
-
if (!
|
|
475643
|
+
const skillsDir = join73(memoryDir, "skills");
|
|
475644
|
+
if (!existsSync58(skillsDir))
|
|
475056
475645
|
return [];
|
|
475057
475646
|
const entries = await readdir14(skillsDir, { withFileTypes: true });
|
|
475058
475647
|
const skills = [];
|
|
475059
475648
|
for (const entry of entries) {
|
|
475060
475649
|
if (!entry.isDirectory())
|
|
475061
475650
|
continue;
|
|
475062
|
-
const skillDir =
|
|
475063
|
-
const skillMdPath =
|
|
475064
|
-
if (!
|
|
475651
|
+
const skillDir = join73(skillsDir, entry.name);
|
|
475652
|
+
const skillMdPath = join73(skillDir, "SKILL.md");
|
|
475653
|
+
if (!existsSync58(skillMdPath))
|
|
475065
475654
|
continue;
|
|
475066
475655
|
let name = entry.name;
|
|
475067
475656
|
let description;
|
|
@@ -475081,11 +475670,11 @@ async function listSkillDirectories(params) {
|
|
|
475081
475670
|
}
|
|
475082
475671
|
async function deleteSkillDirectory(params) {
|
|
475083
475672
|
const memoryDir = resolve33(params.memoryDir);
|
|
475084
|
-
const skillsDir =
|
|
475673
|
+
const skillsDir = join73(memoryDir, "skills");
|
|
475085
475674
|
const name = sanitizeSkillName(params.name);
|
|
475086
|
-
const targetPath =
|
|
475675
|
+
const targetPath = join73(skillsDir, name);
|
|
475087
475676
|
assertInside(skillsDir, targetPath);
|
|
475088
|
-
if (!
|
|
475677
|
+
if (!existsSync58(targetPath)) {
|
|
475089
475678
|
throw new Error(`Skill "${name}" is not installed at ${targetPath}.`);
|
|
475090
475679
|
}
|
|
475091
475680
|
if (!statSync20(targetPath).isDirectory()) {
|
|
@@ -475134,7 +475723,7 @@ async function installSkill(specifier, agentId, force) {
|
|
|
475134
475723
|
tmpDir = downloaded.tmpDir;
|
|
475135
475724
|
const sourceDir = resolve33(downloaded.sourceDir);
|
|
475136
475725
|
assertInside(tmpDir, sourceDir);
|
|
475137
|
-
if (!
|
|
475726
|
+
if (!existsSync58(sourceDir)) {
|
|
475138
475727
|
const missingPath = source2.type === "git" ? source2.location.subdir ?? "." : source2.type === "direct-file" ? source2.location.url : source2.location.slug;
|
|
475139
475728
|
throw new Error(`Skill path not found: ${missingPath}`);
|
|
475140
475729
|
}
|
|
@@ -475253,17 +475842,17 @@ async function runInstall(argv, options3 = {}) {
|
|
|
475253
475842
|
parsed = parseSkillsArgs(argv);
|
|
475254
475843
|
} catch (error54) {
|
|
475255
475844
|
console.error(`Error: ${error54 instanceof Error ? error54.message : String(error54)}`);
|
|
475256
|
-
|
|
475845
|
+
printUsage13();
|
|
475257
475846
|
return 1;
|
|
475258
475847
|
}
|
|
475259
475848
|
const [specifier] = parsed.positionals;
|
|
475260
475849
|
if (parsed.values.help || !specifier || specifier === "help") {
|
|
475261
|
-
|
|
475850
|
+
printUsage13();
|
|
475262
475851
|
return 0;
|
|
475263
475852
|
}
|
|
475264
475853
|
if (parsed.positionals.length > 1) {
|
|
475265
475854
|
console.error(`Unexpected argument: ${parsed.positionals[1]}`);
|
|
475266
|
-
|
|
475855
|
+
printUsage13();
|
|
475267
475856
|
return 1;
|
|
475268
475857
|
}
|
|
475269
475858
|
if (specifier.startsWith("npm:")) {
|
|
@@ -475354,16 +475943,16 @@ async function runList2(argv) {
|
|
|
475354
475943
|
parsed = parseSkillsArgs(argv);
|
|
475355
475944
|
} catch (error54) {
|
|
475356
475945
|
console.error(`Error: ${error54 instanceof Error ? error54.message : String(error54)}`);
|
|
475357
|
-
|
|
475946
|
+
printUsage13();
|
|
475358
475947
|
return 1;
|
|
475359
475948
|
}
|
|
475360
475949
|
if (parsed.values.help) {
|
|
475361
|
-
|
|
475950
|
+
printUsage13();
|
|
475362
475951
|
return 0;
|
|
475363
475952
|
}
|
|
475364
475953
|
if (parsed.positionals.length > 0) {
|
|
475365
475954
|
console.error(`Unexpected argument: ${parsed.positionals[0]}`);
|
|
475366
|
-
|
|
475955
|
+
printUsage13();
|
|
475367
475956
|
return 1;
|
|
475368
475957
|
}
|
|
475369
475958
|
try {
|
|
@@ -475384,17 +475973,17 @@ async function runDelete(argv) {
|
|
|
475384
475973
|
parsed = parseSkillsArgs(argv);
|
|
475385
475974
|
} catch (error54) {
|
|
475386
475975
|
console.error(`Error: ${error54 instanceof Error ? error54.message : String(error54)}`);
|
|
475387
|
-
|
|
475976
|
+
printUsage13();
|
|
475388
475977
|
return 1;
|
|
475389
475978
|
}
|
|
475390
475979
|
const [skillName] = parsed.positionals;
|
|
475391
475980
|
if (parsed.values.help || !skillName || skillName === "help") {
|
|
475392
|
-
|
|
475981
|
+
printUsage13();
|
|
475393
475982
|
return 0;
|
|
475394
475983
|
}
|
|
475395
475984
|
if (parsed.positionals.length > 1) {
|
|
475396
475985
|
console.error(`Unexpected argument: ${parsed.positionals[1]}`);
|
|
475397
|
-
|
|
475986
|
+
printUsage13();
|
|
475398
475987
|
return 1;
|
|
475399
475988
|
}
|
|
475400
475989
|
const agentId = getExplicitAgentId2(parsed.values);
|
|
@@ -475434,11 +476023,11 @@ async function runSkillsSubcommand(argv) {
|
|
|
475434
476023
|
case "help":
|
|
475435
476024
|
case "--help":
|
|
475436
476025
|
case "-h":
|
|
475437
|
-
|
|
476026
|
+
printUsage13();
|
|
475438
476027
|
return 0;
|
|
475439
476028
|
default:
|
|
475440
476029
|
console.error(`Unknown action: ${action3}`);
|
|
475441
|
-
|
|
476030
|
+
printUsage13();
|
|
475442
476031
|
return 1;
|
|
475443
476032
|
}
|
|
475444
476033
|
}
|
|
@@ -475458,7 +476047,7 @@ var init_skills4 = __esm(() => {
|
|
|
475458
476047
|
|
|
475459
476048
|
// src/cli/subcommands/trajectories/readers.ts
|
|
475460
476049
|
import { readdir as readdir15, readFile as readFile24, stat as stat15 } from "node:fs/promises";
|
|
475461
|
-
import { join as
|
|
476050
|
+
import { join as join74 } from "node:path";
|
|
475462
476051
|
async function loadSessionTranscript(item) {
|
|
475463
476052
|
const stats = await stat15(item.path);
|
|
475464
476053
|
if (stats.isDirectory()) {
|
|
@@ -475470,13 +476059,13 @@ async function loadSessionTranscript(item) {
|
|
|
475470
476059
|
return readFile24(item.path, "utf-8");
|
|
475471
476060
|
}
|
|
475472
476061
|
async function assembleEventDirectory(sessionDir) {
|
|
475473
|
-
const eventsSubdir =
|
|
476062
|
+
const eventsSubdir = join74(sessionDir, "events");
|
|
475474
476063
|
const eventsDir = (await stat15(eventsSubdir).catch(() => null))?.isDirectory() ? eventsSubdir : sessionDir;
|
|
475475
476064
|
const names = (await readdir15(eventsDir, { withFileTypes: true })).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort((a2, b3) => Number.parseInt(a2, 10) - Number.parseInt(b3, 10) || a2.localeCompare(b3));
|
|
475476
476065
|
if (names.length === 0) {
|
|
475477
476066
|
throw new Error(`No event files found in ${eventsDir}`);
|
|
475478
476067
|
}
|
|
475479
|
-
const events = await Promise.all(names.map(async (name) => JSON.parse(await readFile24(
|
|
476068
|
+
const events = await Promise.all(names.map(async (name) => JSON.parse(await readFile24(join74(eventsDir, name), "utf-8"))));
|
|
475480
476069
|
return JSON.stringify(events);
|
|
475481
476070
|
}
|
|
475482
476071
|
async function openReadOnlyDatabase(path43) {
|
|
@@ -475554,7 +476143,7 @@ import {
|
|
|
475554
476143
|
stat as stat16,
|
|
475555
476144
|
writeFile as writeFile18
|
|
475556
476145
|
} from "node:fs/promises";
|
|
475557
|
-
import { basename as basename29, join as
|
|
476146
|
+
import { basename as basename29, join as join75 } from "node:path";
|
|
475558
476147
|
function fileTimestamp(startedAt) {
|
|
475559
476148
|
if (!startedAt)
|
|
475560
476149
|
return "unknown-date";
|
|
@@ -475624,7 +476213,7 @@ async function prepareOutDir(outDir) {
|
|
|
475624
476213
|
throw new Error(`--out ${outDir} is not empty and has no ${MANIFEST_NAME}; refusing to overwrite a directory this tool did not create`);
|
|
475625
476214
|
}
|
|
475626
476215
|
for (const entry of entries) {
|
|
475627
|
-
await rm10(
|
|
476216
|
+
await rm10(join75(outDir, entry), { recursive: true, force: true });
|
|
475628
476217
|
}
|
|
475629
476218
|
} catch (error54) {
|
|
475630
476219
|
if (error54.code !== "ENOENT")
|
|
@@ -475667,14 +476256,14 @@ async function runTrajectoryExport(options3) {
|
|
|
475667
476256
|
}
|
|
475668
476257
|
const sessionId = sessionHash(source2, id2);
|
|
475669
476258
|
const base3 = `${fileTimestamp(stats.startedAt)}_${sessionId}`;
|
|
475670
|
-
let file3 =
|
|
476259
|
+
let file3 = join75(source2, `${base3}.json`);
|
|
475671
476260
|
for (let suffix = 2;usedFiles.has(file3); suffix += 1) {
|
|
475672
|
-
file3 =
|
|
476261
|
+
file3 = join75(source2, `${base3}-${suffix}.json`);
|
|
475673
476262
|
}
|
|
475674
476263
|
usedFiles.add(file3);
|
|
475675
476264
|
const body3 = JSON.stringify(records);
|
|
475676
|
-
await mkdir16(
|
|
475677
|
-
await writeFile18(
|
|
476265
|
+
await mkdir16(join75(options3.outDir, source2), { recursive: true });
|
|
476266
|
+
await writeFile18(join75(options3.outDir, file3), body3, "utf-8");
|
|
475678
476267
|
counts.exported += 1;
|
|
475679
476268
|
manifest2.sessions.push({
|
|
475680
476269
|
source: source2,
|
|
@@ -475728,7 +476317,7 @@ async function runTrajectoryExport(options3) {
|
|
|
475728
476317
|
await exportCheckpoint(checkpoint2, `${basename29(checkpoint2.path)}-${checkpoint2.threadId}`);
|
|
475729
476318
|
}
|
|
475730
476319
|
manifest2.sessions.sort((a2, b3) => (a2.startedAt ?? "").localeCompare(b3.startedAt ?? ""));
|
|
475731
|
-
await writeFile18(
|
|
476320
|
+
await writeFile18(join75(options3.outDir, MANIFEST_NAME), JSON.stringify(manifest2, null, 2), "utf-8");
|
|
475732
476321
|
return manifest2;
|
|
475733
476322
|
}
|
|
475734
476323
|
var MANIFEST_NAME = "manifest.json", FIRST_PROMPT_MAX_CHARS = 200, LIST_PAGE_LIMIT = 1000;
|
|
@@ -475740,13 +476329,13 @@ var init_export = __esm(() => {
|
|
|
475740
476329
|
|
|
475741
476330
|
// src/cli/subcommands/trajectories/review.ts
|
|
475742
476331
|
import { readFile as readFile26 } from "node:fs/promises";
|
|
475743
|
-
import { isAbsolute as isAbsolute27, join as
|
|
476332
|
+
import { isAbsolute as isAbsolute27, join as join76 } from "node:path";
|
|
475744
476333
|
async function readManifest(dir) {
|
|
475745
476334
|
let raw2;
|
|
475746
476335
|
try {
|
|
475747
|
-
raw2 = await readFile26(
|
|
476336
|
+
raw2 = await readFile26(join76(dir, "manifest.json"), "utf-8");
|
|
475748
476337
|
} catch {
|
|
475749
|
-
throw new Error(`No manifest at ${
|
|
476338
|
+
throw new Error(`No manifest at ${join76(dir, "manifest.json")}. Run: letta trajectories export --out ${dir}`);
|
|
475750
476339
|
}
|
|
475751
476340
|
return JSON.parse(raw2);
|
|
475752
476341
|
}
|
|
@@ -475755,7 +476344,7 @@ function filterSessions(sessions, filter3) {
|
|
|
475755
476344
|
}
|
|
475756
476345
|
async function resolveSessionFile(dir, target2) {
|
|
475757
476346
|
if (target2.endsWith(".json")) {
|
|
475758
|
-
const direct = isAbsolute27(target2) ? target2 :
|
|
476347
|
+
const direct = isAbsolute27(target2) ? target2 : join76(dir, target2);
|
|
475759
476348
|
try {
|
|
475760
476349
|
await readFile26(direct, "utf-8");
|
|
475761
476350
|
return direct;
|
|
@@ -475766,7 +476355,7 @@ async function resolveSessionFile(dir, target2) {
|
|
|
475766
476355
|
if (!entry) {
|
|
475767
476356
|
throw new Error(`No session "${target2}" in ${dir} (pass a file path, a manifest-relative file, or a sessionId)`);
|
|
475768
476357
|
}
|
|
475769
|
-
return
|
|
476358
|
+
return join76(dir, entry.file);
|
|
475770
476359
|
}
|
|
475771
476360
|
function stamp(timestamp) {
|
|
475772
476361
|
return (timestamp ?? "").slice(0, 19);
|
|
@@ -475809,7 +476398,7 @@ async function searchSessions(dir, keyword, options3 = {}) {
|
|
|
475809
476398
|
for (const session of filterSessions(manifest2.sessions, options3)) {
|
|
475810
476399
|
let records;
|
|
475811
476400
|
try {
|
|
475812
|
-
records = JSON.parse(await readFile26(
|
|
476401
|
+
records = JSON.parse(await readFile26(join76(dir, session.file), "utf-8"));
|
|
475813
476402
|
} catch {
|
|
475814
476403
|
continue;
|
|
475815
476404
|
}
|
|
@@ -475841,8 +476430,8 @@ var init_review = () => {};
|
|
|
475841
476430
|
|
|
475842
476431
|
// src/cli/subcommands/trajectories.ts
|
|
475843
476432
|
import { readFile as readFile27 } from "node:fs/promises";
|
|
475844
|
-
import { parseArgs as
|
|
475845
|
-
function
|
|
476433
|
+
import { parseArgs as parseArgs16 } from "node:util";
|
|
476434
|
+
function printUsage14() {
|
|
475846
476435
|
console.log(`
|
|
475847
476436
|
Usage:
|
|
475848
476437
|
letta trajectories export [options]
|
|
@@ -475980,7 +476569,7 @@ ${results.length} session(s) matched "${keyword}"`);
|
|
|
475980
476569
|
return 0;
|
|
475981
476570
|
}
|
|
475982
476571
|
function parseTrajectoriesArgs(argv) {
|
|
475983
|
-
return
|
|
476572
|
+
return parseArgs16({
|
|
475984
476573
|
args: argv,
|
|
475985
476574
|
options: TRAJECTORIES_OPTIONS,
|
|
475986
476575
|
strict: true,
|
|
@@ -475993,12 +476582,12 @@ async function runTrajectoriesSubcommand(argv) {
|
|
|
475993
476582
|
parsed = parseTrajectoriesArgs(argv);
|
|
475994
476583
|
} catch (error54) {
|
|
475995
476584
|
console.error(`Error: ${error54 instanceof Error ? error54.message : String(error54)}`);
|
|
475996
|
-
|
|
476585
|
+
printUsage14();
|
|
475997
476586
|
return 1;
|
|
475998
476587
|
}
|
|
475999
476588
|
const [action3] = parsed.positionals;
|
|
476000
476589
|
if (parsed.values.help || action3 === "help" || !action3) {
|
|
476001
|
-
|
|
476590
|
+
printUsage14();
|
|
476002
476591
|
return parsed.values.help || action3 === "help" ? 0 : 1;
|
|
476003
476592
|
}
|
|
476004
476593
|
const asJson = Boolean(parsed.values.json);
|
|
@@ -476030,7 +476619,7 @@ async function runTrajectoriesSubcommand(argv) {
|
|
|
476030
476619
|
}
|
|
476031
476620
|
if (action3 !== "export") {
|
|
476032
476621
|
console.error(`Unknown command: ${action3}`);
|
|
476033
|
-
|
|
476622
|
+
printUsage14();
|
|
476034
476623
|
return 1;
|
|
476035
476624
|
}
|
|
476036
476625
|
const options3 = {
|
|
@@ -477763,7 +478352,7 @@ var init_gateway_core = __esm(() => {
|
|
|
477763
478352
|
});
|
|
477764
478353
|
|
|
477765
478354
|
// src/channels/custom/scaffolding.ts
|
|
477766
|
-
import { existsSync as
|
|
478355
|
+
import { existsSync as existsSync59, mkdirSync as mkdirSync42, rmSync as rmSync15, writeFileSync as writeFileSync31 } from "node:fs";
|
|
477767
478356
|
function removeUserPlugin(channelId) {
|
|
477768
478357
|
if (FIRST_PARTY_SET.has(channelId)) {
|
|
477769
478358
|
return;
|
|
@@ -477772,7 +478361,7 @@ function removeUserPlugin(channelId) {
|
|
|
477772
478361
|
return;
|
|
477773
478362
|
}
|
|
477774
478363
|
const channelDir = getChannelDir(channelId);
|
|
477775
|
-
if (!
|
|
478364
|
+
if (!existsSync59(channelDir)) {
|
|
477776
478365
|
return;
|
|
477777
478366
|
}
|
|
477778
478367
|
try {
|
|
@@ -479037,14 +479626,14 @@ var exports_channel_gateway = {};
|
|
|
479037
479626
|
__export(exports_channel_gateway, {
|
|
479038
479627
|
runChannelGatewaySubcommand: () => runChannelGatewaySubcommand
|
|
479039
479628
|
});
|
|
479040
|
-
import { parseArgs as
|
|
479629
|
+
import { parseArgs as parseArgs17 } from "node:util";
|
|
479041
479630
|
function isGatewayCommandEnvelope(value) {
|
|
479042
479631
|
return Boolean(value && typeof value === "object" && "type" in value && value.type === "command" && "requestId" in value && typeof value.requestId === "string" && "command" in value && value.command && typeof value.command === "object");
|
|
479043
479632
|
}
|
|
479044
479633
|
async function runChannelGatewaySubcommand(argv) {
|
|
479045
479634
|
let values2;
|
|
479046
479635
|
try {
|
|
479047
|
-
({ values: values2 } =
|
|
479636
|
+
({ values: values2 } = parseArgs17({
|
|
479048
479637
|
args: argv,
|
|
479049
479638
|
strict: true,
|
|
479050
479639
|
allowPositionals: false,
|
|
@@ -479181,6 +479770,7 @@ function subcommandNeedsEarlyBackendMode(command) {
|
|
|
479181
479770
|
case "mods":
|
|
479182
479771
|
case "remote":
|
|
479183
479772
|
case "server":
|
|
479773
|
+
case "shared-memory":
|
|
479184
479774
|
case "skills":
|
|
479185
479775
|
return true;
|
|
479186
479776
|
default:
|
|
@@ -479225,6 +479815,8 @@ async function runSubcommand(argv) {
|
|
|
479225
479815
|
return runSetupSubcommand(rest3);
|
|
479226
479816
|
case "install":
|
|
479227
479817
|
return runInstallSubcommand(rest3);
|
|
479818
|
+
case "shared-memory":
|
|
479819
|
+
return runSharedMemorySubcommand(rest3);
|
|
479228
479820
|
case "skills":
|
|
479229
479821
|
return runSkillsSubcommand(rest3);
|
|
479230
479822
|
case "cron":
|
|
@@ -479255,6 +479847,7 @@ var init_router = __esm(async () => {
|
|
|
479255
479847
|
init_local_backend2();
|
|
479256
479848
|
init_memory7();
|
|
479257
479849
|
init_messages10();
|
|
479850
|
+
init_shared_memory();
|
|
479258
479851
|
init_skills4();
|
|
479259
479852
|
init_trajectories();
|
|
479260
479853
|
await __promiseAll([
|
|
@@ -479489,17 +480082,17 @@ var exports_bootstrap_tools = {};
|
|
|
479489
480082
|
__export(exports_bootstrap_tools, {
|
|
479490
480083
|
bootstrapBaseToolsIfNeeded: () => bootstrapBaseToolsIfNeeded
|
|
479491
480084
|
});
|
|
479492
|
-
import { existsSync as
|
|
480085
|
+
import { existsSync as existsSync60, mkdirSync as mkdirSync43, writeFileSync as writeFileSync32 } from "node:fs";
|
|
479493
480086
|
import { homedir as homedir42 } from "node:os";
|
|
479494
|
-
import { join as
|
|
480087
|
+
import { join as join77 } from "node:path";
|
|
479495
480088
|
async function bootstrapBaseToolsIfNeeded() {
|
|
479496
|
-
if (
|
|
480089
|
+
if (existsSync60(MARKER_PATH))
|
|
479497
480090
|
return;
|
|
479498
480091
|
debugLog("bootstrap", "No marker found, bootstrapping base tools...");
|
|
479499
480092
|
try {
|
|
479500
480093
|
const success2 = await addBaseToolsToServer();
|
|
479501
480094
|
if (success2) {
|
|
479502
|
-
mkdirSync43(
|
|
480095
|
+
mkdirSync43(join77(homedir42(), ".letta"), { recursive: true });
|
|
479503
480096
|
writeFileSync32(MARKER_PATH, new Date().toISOString(), "utf-8");
|
|
479504
480097
|
}
|
|
479505
480098
|
} catch (err) {
|
|
@@ -479510,7 +480103,7 @@ var MARKER_PATH;
|
|
|
479510
480103
|
var init_bootstrap_tools = __esm(() => {
|
|
479511
480104
|
init_debug();
|
|
479512
480105
|
init_create5();
|
|
479513
|
-
MARKER_PATH =
|
|
480106
|
+
MARKER_PATH = join77(homedir42(), ".letta", ".bootstrapped");
|
|
479514
480107
|
});
|
|
479515
480108
|
|
|
479516
480109
|
// src/utils/headless-stdout-guard.ts
|
|
@@ -479856,8 +480449,17 @@ var init_local_backend_mod_events = __esm(() => {
|
|
|
479856
480449
|
init_local_backend();
|
|
479857
480450
|
});
|
|
479858
480451
|
|
|
480452
|
+
// src/headless-memfs-policy.ts
|
|
480453
|
+
function resolveHeadlessMemfsPolicy(options3) {
|
|
480454
|
+
const isFreshStatelessSubagent = options3.isSubagentRole && options3.newAgentRequested;
|
|
480455
|
+
return {
|
|
480456
|
+
isFreshStatelessSubagent,
|
|
480457
|
+
isStatelessSession: options3.statelessRequested || isFreshStatelessSubagent
|
|
480458
|
+
};
|
|
480459
|
+
}
|
|
480460
|
+
|
|
479859
480461
|
// src/headless-mod-adapter.ts
|
|
479860
|
-
import { join as
|
|
480462
|
+
import { join as join78 } from "node:path";
|
|
479861
480463
|
function isHeadlessMemfsEnabled(agentId) {
|
|
479862
480464
|
try {
|
|
479863
480465
|
return settingsManager.isMemfsEnabled(agentId);
|
|
@@ -479928,7 +480530,7 @@ function createHeadlessModContext(options3) {
|
|
|
479928
480530
|
};
|
|
479929
480531
|
}
|
|
479930
480532
|
function createHeadlessModAdapter(options3) {
|
|
479931
|
-
const agentModsDirectory = isHeadlessMemfsEnabled(options3.agent.id) ?
|
|
480533
|
+
const agentModsDirectory = isHeadlessMemfsEnabled(options3.agent.id) ? join78(getScopedMemoryFilesystemRoot(options3.agent.id), "mods") : undefined;
|
|
479932
480534
|
return createModAdapter({
|
|
479933
480535
|
...agentModsDirectory ? { agentModsDirectory } : {},
|
|
479934
480536
|
...options3.cacheDirectory ? { cacheDirectory: options3.cacheDirectory } : {},
|
|
@@ -486215,49 +486817,49 @@ var require_fast_uri = __commonJS((exports, module3) => {
|
|
|
486215
486817
|
schemelessOptions.skipEscape = true;
|
|
486216
486818
|
return serialize(resolved, schemelessOptions);
|
|
486217
486819
|
}
|
|
486218
|
-
function resolveComponent(base3,
|
|
486820
|
+
function resolveComponent(base3, relative14, options3, skipNormalization) {
|
|
486219
486821
|
const target2 = {};
|
|
486220
486822
|
if (!skipNormalization) {
|
|
486221
486823
|
base3 = parse9(serialize(base3, options3), options3);
|
|
486222
|
-
|
|
486824
|
+
relative14 = parse9(serialize(relative14, options3), options3);
|
|
486223
486825
|
}
|
|
486224
486826
|
options3 = options3 || {};
|
|
486225
|
-
if (!options3.tolerant &&
|
|
486226
|
-
target2.scheme =
|
|
486227
|
-
target2.userinfo =
|
|
486228
|
-
target2.host =
|
|
486229
|
-
target2.port =
|
|
486230
|
-
target2.path = removeDotSegments(
|
|
486231
|
-
target2.query =
|
|
486827
|
+
if (!options3.tolerant && relative14.scheme) {
|
|
486828
|
+
target2.scheme = relative14.scheme;
|
|
486829
|
+
target2.userinfo = relative14.userinfo;
|
|
486830
|
+
target2.host = relative14.host;
|
|
486831
|
+
target2.port = relative14.port;
|
|
486832
|
+
target2.path = removeDotSegments(relative14.path || "");
|
|
486833
|
+
target2.query = relative14.query;
|
|
486232
486834
|
} else {
|
|
486233
|
-
if (
|
|
486234
|
-
target2.userinfo =
|
|
486235
|
-
target2.host =
|
|
486236
|
-
target2.port =
|
|
486237
|
-
target2.path = removeDotSegments(
|
|
486238
|
-
target2.query =
|
|
486835
|
+
if (relative14.userinfo !== undefined || relative14.host !== undefined || relative14.port !== undefined) {
|
|
486836
|
+
target2.userinfo = relative14.userinfo;
|
|
486837
|
+
target2.host = relative14.host;
|
|
486838
|
+
target2.port = relative14.port;
|
|
486839
|
+
target2.path = removeDotSegments(relative14.path || "");
|
|
486840
|
+
target2.query = relative14.query;
|
|
486239
486841
|
} else {
|
|
486240
|
-
if (!
|
|
486842
|
+
if (!relative14.path) {
|
|
486241
486843
|
target2.path = base3.path;
|
|
486242
|
-
if (
|
|
486243
|
-
target2.query =
|
|
486844
|
+
if (relative14.query !== undefined) {
|
|
486845
|
+
target2.query = relative14.query;
|
|
486244
486846
|
} else {
|
|
486245
486847
|
target2.query = base3.query;
|
|
486246
486848
|
}
|
|
486247
486849
|
} else {
|
|
486248
|
-
if (
|
|
486249
|
-
target2.path = removeDotSegments(
|
|
486850
|
+
if (relative14.path[0] === "/") {
|
|
486851
|
+
target2.path = removeDotSegments(relative14.path);
|
|
486250
486852
|
} else {
|
|
486251
486853
|
if ((base3.userinfo !== undefined || base3.host !== undefined || base3.port !== undefined) && !base3.path) {
|
|
486252
|
-
target2.path = "/" +
|
|
486854
|
+
target2.path = "/" + relative14.path;
|
|
486253
486855
|
} else if (!base3.path) {
|
|
486254
|
-
target2.path =
|
|
486856
|
+
target2.path = relative14.path;
|
|
486255
486857
|
} else {
|
|
486256
|
-
target2.path = base3.path.slice(0, base3.path.lastIndexOf("/") + 1) +
|
|
486858
|
+
target2.path = base3.path.slice(0, base3.path.lastIndexOf("/") + 1) + relative14.path;
|
|
486257
486859
|
}
|
|
486258
486860
|
target2.path = removeDotSegments(target2.path);
|
|
486259
486861
|
}
|
|
486260
|
-
target2.query =
|
|
486862
|
+
target2.query = relative14.query;
|
|
486261
486863
|
}
|
|
486262
486864
|
target2.userinfo = base3.userinfo;
|
|
486263
486865
|
target2.host = base3.host;
|
|
@@ -486265,7 +486867,7 @@ var require_fast_uri = __commonJS((exports, module3) => {
|
|
|
486265
486867
|
}
|
|
486266
486868
|
target2.scheme = base3.scheme;
|
|
486267
486869
|
}
|
|
486268
|
-
target2.fragment =
|
|
486870
|
+
target2.fragment = relative14.fragment;
|
|
486269
486871
|
return target2;
|
|
486270
486872
|
}
|
|
486271
486873
|
function equal3(uriA, uriB, options3) {
|
|
@@ -491284,7 +491886,7 @@ var init_mcp_client = __esm(() => {
|
|
|
491284
491886
|
init_streamableHttp();
|
|
491285
491887
|
DEFAULT_CLIENT_INFO = {
|
|
491286
491888
|
name: "letta-code",
|
|
491287
|
-
version: "0.30.
|
|
491889
|
+
version: "0.30.5"
|
|
491288
491890
|
};
|
|
491289
491891
|
});
|
|
491290
491892
|
|
|
@@ -491706,8 +492308,8 @@ var init_mcp_runtime = __esm(async () => {
|
|
|
491706
492308
|
});
|
|
491707
492309
|
|
|
491708
492310
|
// src/skills/builtin/creating-skills/scripts/validate-skill.ts
|
|
491709
|
-
import { existsSync as
|
|
491710
|
-
import { basename as basename30, join as
|
|
492311
|
+
import { existsSync as existsSync61, readFileSync as readFileSync39 } from "node:fs";
|
|
492312
|
+
import { basename as basename30, join as join79, resolve as resolve34 } from "node:path";
|
|
491711
492313
|
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
491712
492314
|
function parseQuotedScalar(value) {
|
|
491713
492315
|
if (value.startsWith('"')) {
|
|
@@ -491804,8 +492406,8 @@ function parseFrontmatter2(source2) {
|
|
|
491804
492406
|
return parseFrontmatterFallback(source2);
|
|
491805
492407
|
}
|
|
491806
492408
|
function validateSkill(skillPath) {
|
|
491807
|
-
const skillMdPath =
|
|
491808
|
-
if (!
|
|
492409
|
+
const skillMdPath = join79(skillPath, "SKILL.md");
|
|
492410
|
+
if (!existsSync61(skillMdPath)) {
|
|
491809
492411
|
return { valid: false, message: "SKILL.md not found" };
|
|
491810
492412
|
}
|
|
491811
492413
|
const content = readFileSync39(skillMdPath, "utf-8");
|
|
@@ -491972,7 +492574,7 @@ __export(exports_import, {
|
|
|
491972
492574
|
});
|
|
491973
492575
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
491974
492576
|
import { access as access2, chmod, mkdir as mkdir17, readFile as readFile28, writeFile as writeFile19 } from "node:fs/promises";
|
|
491975
|
-
import { dirname as dirname34, isAbsolute as isAbsolute28, relative as
|
|
492577
|
+
import { dirname as dirname34, isAbsolute as isAbsolute28, relative as relative14, resolve as resolve35, sep as sep8, win32 as win325 } from "node:path";
|
|
491976
492578
|
function validateImportedSkillName(name) {
|
|
491977
492579
|
const trimmedName = name.trim();
|
|
491978
492580
|
if (trimmedName !== name || trimmedName.length === 0 || trimmedName.length > MAX_SKILL_NAME_LENGTH || trimmedName === "." || trimmedName === ".." || !IMPORTED_SKILL_NAME_PATTERN.test(trimmedName)) {
|
|
@@ -491983,7 +492585,7 @@ function validateImportedSkillName(name) {
|
|
|
491983
492585
|
function assertPathInside(parent, child) {
|
|
491984
492586
|
const parentPath = resolve35(parent);
|
|
491985
492587
|
const childPath = resolve35(child);
|
|
491986
|
-
const relativePath =
|
|
492588
|
+
const relativePath = relative14(parentPath, childPath);
|
|
491987
492589
|
if (relativePath === "" || relativePath === ".." || relativePath.startsWith(`..${sep8}`) || isAbsolute28(relativePath)) {
|
|
491988
492590
|
throw new Error(`Imported skill file path escapes skill directory: ${child}`);
|
|
491989
492591
|
}
|
|
@@ -492153,7 +492755,7 @@ function parseRegistryHandle(handle2) {
|
|
|
492153
492755
|
}
|
|
492154
492756
|
async function importAgentFromRegistry(options3) {
|
|
492155
492757
|
const { tmpdir: tmpdir11 } = await import("node:os");
|
|
492156
|
-
const { join:
|
|
492758
|
+
const { join: join80 } = await import("node:path");
|
|
492157
492759
|
const { writeFile: writeFile20, unlink: unlink6 } = await import("node:fs/promises");
|
|
492158
492760
|
const { author, name } = parseRegistryHandle(options3.handle);
|
|
492159
492761
|
const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER}/${AGENT_REGISTRY_REPO}/refs/heads/${AGENT_REGISTRY_BRANCH}/agents/@${author}/${name}/${name}.af`;
|
|
@@ -492165,7 +492767,7 @@ async function importAgentFromRegistry(options3) {
|
|
|
492165
492767
|
throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
|
|
492166
492768
|
}
|
|
492167
492769
|
const afContent = await response.text();
|
|
492168
|
-
const tempPath =
|
|
492770
|
+
const tempPath = join80(tmpdir11(), `letta-import-${author}-${name}-${Date.now()}.af`);
|
|
492169
492771
|
await writeFile20(tempPath, afContent, "utf-8");
|
|
492170
492772
|
try {
|
|
492171
492773
|
const result = await importAgentFromFile({
|
|
@@ -492424,6 +493026,7 @@ function hasReflectionOverrides(overrides) {
|
|
|
492424
493026
|
async function applyReflectionOverrides(agentId, overrides) {
|
|
492425
493027
|
const current = getReflectionSettings(agentId);
|
|
492426
493028
|
const merged = {
|
|
493029
|
+
...current,
|
|
492427
493030
|
trigger: overrides.trigger ?? current.trigger,
|
|
492428
493031
|
stepCount: overrides.stepCount ?? current.stepCount
|
|
492429
493032
|
};
|
|
@@ -492815,9 +493418,14 @@ In headless mode, use:
|
|
|
492815
493418
|
const noBundledSkillsFlag = values2["no-bundled-skills"];
|
|
492816
493419
|
const skillSourcesRaw = values2["skill-sources"];
|
|
492817
493420
|
const memfsFlag = values2.memfs;
|
|
493421
|
+
const statelessFlag = values2.stateless;
|
|
492818
493422
|
const isSubagentRole = process.env.LETTA_CODE_AGENT_ROLE === "subagent";
|
|
492819
|
-
const
|
|
492820
|
-
|
|
493423
|
+
const { isFreshStatelessSubagent, isStatelessSession } = resolveHeadlessMemfsPolicy({
|
|
493424
|
+
statelessRequested: Boolean(statelessFlag),
|
|
493425
|
+
isSubagentRole,
|
|
493426
|
+
newAgentRequested: Boolean(forceNew)
|
|
493427
|
+
});
|
|
493428
|
+
if (isStatelessSession && backend3.capabilities.localMemfs) {
|
|
492821
493429
|
const { disableLocalBackendMemfsForProcess: disableLocalBackendMemfsForProcess2 } = await Promise.resolve().then(() => (init_paths(), exports_paths));
|
|
492822
493430
|
disableLocalBackendMemfsForProcess2();
|
|
492823
493431
|
}
|
|
@@ -492829,7 +493437,7 @@ In headless mode, use:
|
|
|
492829
493437
|
console.error("Error: --memfs is not supported by this backend yet");
|
|
492830
493438
|
process.exit(1);
|
|
492831
493439
|
}
|
|
492832
|
-
const shouldAutoEnableMemfsForNewAgent = !memfsFlag && !
|
|
493440
|
+
const shouldAutoEnableMemfsForNewAgent = !memfsFlag && !isStatelessSession;
|
|
492833
493441
|
const fromAfFile = resolveImportFlagAlias({
|
|
492834
493442
|
importFlagValue: values2.import,
|
|
492835
493443
|
fromAfFlagValue: values2["from-af"]
|
|
@@ -492917,35 +493525,17 @@ In headless mode, use:
|
|
|
492917
493525
|
}
|
|
492918
493526
|
}
|
|
492919
493527
|
try {
|
|
492920
|
-
|
|
492921
|
-
|
|
492922
|
-
|
|
492923
|
-
|
|
492924
|
-
|
|
492925
|
-
|
|
492926
|
-
|
|
492927
|
-
|
|
492928
|
-
|
|
492929
|
-
|
|
492930
|
-
|
|
492931
|
-
{
|
|
492932
|
-
when: forceNew,
|
|
492933
|
-
message: "--conversation cannot be used with --new-agent"
|
|
492934
|
-
},
|
|
492935
|
-
{
|
|
492936
|
-
when: fromAfFile,
|
|
492937
|
-
message: "--conversation cannot be used with --import"
|
|
492938
|
-
}
|
|
492939
|
-
]
|
|
492940
|
-
});
|
|
492941
|
-
validateFlagConflicts({
|
|
492942
|
-
guard: forceNewConversation,
|
|
492943
|
-
checks: [
|
|
492944
|
-
{
|
|
492945
|
-
when: specifiedConversationId,
|
|
492946
|
-
message: "--new cannot be used with --conversation"
|
|
492947
|
-
}
|
|
492948
|
-
]
|
|
493528
|
+
validatePrimaryStartupFlagConflicts({
|
|
493529
|
+
specifiedConversationId,
|
|
493530
|
+
specifiedAgentId,
|
|
493531
|
+
specifiedAgentName,
|
|
493532
|
+
forceNewAgent: forceNew,
|
|
493533
|
+
forceNewConversation,
|
|
493534
|
+
importFile: fromAfFile,
|
|
493535
|
+
stateless: statelessFlag,
|
|
493536
|
+
isHeadless: true,
|
|
493537
|
+
memfs: memfsFlag,
|
|
493538
|
+
memfsStartup: values2["memfs-startup"]
|
|
492949
493539
|
});
|
|
492950
493540
|
} catch (error54) {
|
|
492951
493541
|
return reportAndExitHeadless("headless_flag_conflict_validation_failed", error54, "headless_startup_flag_conflicts");
|
|
@@ -493076,7 +493666,7 @@ In headless mode, use:
|
|
|
493076
493666
|
if (!agent2 && forceNew) {
|
|
493077
493667
|
const { isLettaCloud: isLettaCloud2 } = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
493078
493668
|
const willAutoEnableMemfs = backend3.capabilities.remoteMemfs && shouldAutoEnableMemfsForNewAgent && await isLettaCloud2();
|
|
493079
|
-
const effectiveMemoryMode = backend3.capabilities.localMemfs ?
|
|
493669
|
+
const effectiveMemoryMode = backend3.capabilities.localMemfs ? isFreshStatelessSubagent ? "standard" : "local-memfs" : requestedMemoryPromptMode ?? (willAutoEnableMemfs ? "memfs" : undefined);
|
|
493080
493670
|
const personalityOptions = personality ? await buildCreateAgentOptionsForPersonality({
|
|
493081
493671
|
personalityId: personality,
|
|
493082
493672
|
model,
|
|
@@ -493178,19 +493768,21 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
|
|
|
493178
493768
|
let effectiveReflectionSettings;
|
|
493179
493769
|
const isSubagent = process.env.LETTA_CODE_AGENT_ROLE === "subagent";
|
|
493180
493770
|
let startupMemfsFlag = autoEnableMemfsForFreshAgent ? true : memfsFlag;
|
|
493181
|
-
if (backend3.capabilities.remoteMemfs && !autoEnableMemfsForFreshAgent) {
|
|
493771
|
+
if (!isStatelessSession && backend3.capabilities.remoteMemfs && !autoEnableMemfsForFreshAgent) {
|
|
493182
493772
|
const { hydrateMemfsSettingFromAgent: hydrateMemfsSettingFromAgent2, isLettaCloud: isLettaCloud2 } = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
493183
493773
|
const memfsEnabled = await hydrateMemfsSettingFromAgent2(agent2);
|
|
493184
|
-
if (!memfsEnabled &&
|
|
493774
|
+
if (!memfsEnabled && await isLettaCloud2()) {
|
|
493185
493775
|
startupMemfsFlag = true;
|
|
493186
493776
|
}
|
|
493187
493777
|
}
|
|
493188
493778
|
let memfsBgPromise;
|
|
493189
493779
|
const secretsAgentId = agent2?.id;
|
|
493190
493780
|
const secretsInitPromise = secretsAgentId ? Promise.resolve().then(() => (init_secrets_store(), exports_secrets_store)).then(({ initSecretsFromServer: initSecretsFromServer2 }) => initSecretsFromServer2(secretsAgentId, agent2 ?? undefined)) : Promise.resolve();
|
|
493191
|
-
if (
|
|
493781
|
+
if (isStatelessSession) {
|
|
493782
|
+
settingsManager.setMemfsEnabled(agent2.id, false);
|
|
493783
|
+
} else if (!backend3.capabilities.remoteMemfs) {
|
|
493192
493784
|
if (backend3.capabilities.localMemfs) {
|
|
493193
|
-
settingsManager.setMemfsEnabled(agent2.id,
|
|
493785
|
+
settingsManager.setMemfsEnabled(agent2.id, true);
|
|
493194
493786
|
}
|
|
493195
493787
|
} else if (memfsStartupPolicy === "skip") {
|
|
493196
493788
|
try {
|
|
@@ -493281,7 +493873,8 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
|
|
|
493281
493873
|
debugWarn("headless startup", `Failed to clear persisted client tool rules for ${startupAgentId}: ${error54 instanceof Error ? error54.message : String(error54)}`);
|
|
493282
493874
|
});
|
|
493283
493875
|
try {
|
|
493284
|
-
|
|
493876
|
+
const resolvedReflectionSettings = await applyReflectionOverrides(agent2.id, reflectionOverrides);
|
|
493877
|
+
effectiveReflectionSettings = isStatelessSession ? { ...resolvedReflectionSettings, trigger: "off" } : resolvedReflectionSettings;
|
|
493285
493878
|
} catch (error54) {
|
|
493286
493879
|
console.error(`Failed to apply sleeptime settings: ${error54 instanceof Error ? error54.message : String(error54)}`);
|
|
493287
493880
|
process.exit(1);
|
|
@@ -496935,10 +497528,10 @@ var init_queued_message_parts = __esm(() => {
|
|
|
496935
497528
|
|
|
496936
497529
|
// src/cli/helpers/reflection-arena-hf-upload.ts
|
|
496937
497530
|
import { execFile as execFileCb5 } from "node:child_process";
|
|
496938
|
-
import { existsSync as
|
|
497531
|
+
import { existsSync as existsSync63 } from "node:fs";
|
|
496939
497532
|
import { appendFile as appendFile2, chmod as chmod2, mkdir as mkdir18, writeFile as writeFile20 } from "node:fs/promises";
|
|
496940
497533
|
import { homedir as homedir45 } from "node:os";
|
|
496941
|
-
import { join as
|
|
497534
|
+
import { join as join81 } from "node:path";
|
|
496942
497535
|
import { promisify as promisify15 } from "node:util";
|
|
496943
497536
|
function buildGitEnv(token2, askpassPath) {
|
|
496944
497537
|
return {
|
|
@@ -496974,7 +497567,7 @@ async function runGit6(cwd2, args, env5) {
|
|
|
496974
497567
|
}
|
|
496975
497568
|
}
|
|
496976
497569
|
async function writeGitAskpass(repoRoot) {
|
|
496977
|
-
const askpassPath =
|
|
497570
|
+
const askpassPath = join81(repoRoot, "hf-askpass.sh");
|
|
496978
497571
|
await writeFile20(askpassPath, [
|
|
496979
497572
|
"#!/bin/sh",
|
|
496980
497573
|
'case "$1" in',
|
|
@@ -496989,7 +497582,7 @@ async function writeGitAskpass(repoRoot) {
|
|
|
496989
497582
|
}
|
|
496990
497583
|
async function prepareHfRepo(env5) {
|
|
496991
497584
|
await mkdir18(HF_CACHE_ROOT, { recursive: true });
|
|
496992
|
-
if (!
|
|
497585
|
+
if (!existsSync63(join81(HF_REPO_DIR, ".git"))) {
|
|
496993
497586
|
await runGit6(HF_CACHE_ROOT, ["clone", "--depth", "1", HF_REPO_URL, HF_REPO_DIR], env5);
|
|
496994
497587
|
return HF_REPO_DIR;
|
|
496995
497588
|
}
|
|
@@ -497024,8 +497617,8 @@ async function maybeUploadReflectionArenaChoiceToHf(row) {
|
|
|
497024
497617
|
const env5 = buildGitEnv(token2, askpassPath);
|
|
497025
497618
|
try {
|
|
497026
497619
|
const repoDir = await prepareHfRepo(env5);
|
|
497027
|
-
await mkdir18(
|
|
497028
|
-
await appendFile2(
|
|
497620
|
+
await mkdir18(join81(repoDir, "data"), { recursive: true });
|
|
497621
|
+
await appendFile2(join81(repoDir, HF_DATASET_PATH), `${JSON.stringify(row)}
|
|
497029
497622
|
`, {
|
|
497030
497623
|
encoding: "utf-8"
|
|
497031
497624
|
});
|
|
@@ -497053,8 +497646,8 @@ var init_reflection_arena_hf_upload = __esm(() => {
|
|
|
497053
497646
|
init_version();
|
|
497054
497647
|
execFile17 = promisify15(execFileCb5);
|
|
497055
497648
|
HF_REPO_URL = `https://huggingface.co/datasets/${HF_REPO_ID}`;
|
|
497056
|
-
HF_CACHE_ROOT =
|
|
497057
|
-
HF_REPO_DIR =
|
|
497649
|
+
HF_CACHE_ROOT = join81(homedir45(), ".letta", "reflection-arena", "hf-upload");
|
|
497650
|
+
HF_REPO_DIR = join81(HF_CACHE_ROOT, "repo");
|
|
497058
497651
|
});
|
|
497059
497652
|
|
|
497060
497653
|
// src/cli/helpers/reflection-arena.ts
|
|
@@ -497062,7 +497655,7 @@ import { execFile as execFileCb6 } from "node:child_process";
|
|
|
497062
497655
|
import { randomInt as randomInt2, randomUUID as randomUUID34 } from "node:crypto";
|
|
497063
497656
|
import { appendFile as appendFile3, mkdir as mkdir19, readFile as readFile29, writeFile as writeFile21 } from "node:fs/promises";
|
|
497064
497657
|
import { homedir as homedir46 } from "node:os";
|
|
497065
|
-
import { join as
|
|
497658
|
+
import { join as join82 } from "node:path";
|
|
497066
497659
|
import { promisify as promisify16 } from "node:util";
|
|
497067
497660
|
function sampleReflectionArenaComparisonModel(excludedModels = []) {
|
|
497068
497661
|
const excluded = new Set(excludedModels);
|
|
@@ -497078,30 +497671,49 @@ function sampleReflectionArenaComparisonModel(excludedModels = []) {
|
|
|
497078
497671
|
}
|
|
497079
497672
|
return candidates2[0]?.model ?? "letta/auto";
|
|
497080
497673
|
}
|
|
497081
|
-
async function
|
|
497674
|
+
async function getGitOutput(cwd2, args) {
|
|
497082
497675
|
try {
|
|
497083
|
-
const { stdout } = await execFile18("git",
|
|
497676
|
+
const { stdout } = await execFile18("git", args, {
|
|
497084
497677
|
cwd: cwd2,
|
|
497085
497678
|
encoding: "utf-8",
|
|
497086
497679
|
timeout: 30000,
|
|
497087
497680
|
maxBuffer: 1024 * 1024
|
|
497088
497681
|
});
|
|
497089
|
-
return stdout.trim()
|
|
497682
|
+
return stdout.trim();
|
|
497090
497683
|
} catch {
|
|
497091
497684
|
return null;
|
|
497092
497685
|
}
|
|
497093
497686
|
}
|
|
497687
|
+
async function getGitHead(cwd2) {
|
|
497688
|
+
return await getGitOutput(cwd2, ["rev-parse", "HEAD"]) || null;
|
|
497689
|
+
}
|
|
497690
|
+
async function reflectionMemoryWorktreeHasNoChanges(worktree) {
|
|
497691
|
+
const [count, status] = await Promise.all([
|
|
497692
|
+
getGitOutput(worktree.worktreeDir, [
|
|
497693
|
+
"rev-list",
|
|
497694
|
+
"--count",
|
|
497695
|
+
`${worktree.baseHead}..HEAD`
|
|
497696
|
+
]),
|
|
497697
|
+
getGitOutput(worktree.worktreeDir, ["status", "--porcelain"])
|
|
497698
|
+
]);
|
|
497699
|
+
if (count === null || status === null)
|
|
497700
|
+
return;
|
|
497701
|
+
return count === "0" && status.length === 0;
|
|
497702
|
+
}
|
|
497703
|
+
function candidateIsConfirmedNoOp(candidate) {
|
|
497704
|
+
return candidate.result?.success === true && candidate.result.memoryNoChanges === true && candidate.result.memoryHead === candidate.worktree.baseHead;
|
|
497705
|
+
}
|
|
497094
497706
|
function getReflectionArenaRoot() {
|
|
497095
|
-
return
|
|
497707
|
+
return join82(homedir46(), ".letta", "reflection-arena");
|
|
497096
497708
|
}
|
|
497097
497709
|
function getReflectionArenaRunsDir() {
|
|
497098
|
-
return
|
|
497710
|
+
return join82(getReflectionArenaRoot(), "runs");
|
|
497099
497711
|
}
|
|
497100
497712
|
function getReflectionArenaChoiceLogPath() {
|
|
497101
|
-
return
|
|
497713
|
+
return join82(getReflectionArenaRoot(), "choices.jsonl");
|
|
497102
497714
|
}
|
|
497103
497715
|
function getReflectionArenaRunPath(runId) {
|
|
497104
|
-
return
|
|
497716
|
+
return join82(getReflectionArenaRunsDir(), `${runId}.json`);
|
|
497105
497717
|
}
|
|
497106
497718
|
async function saveReflectionArenaRun(run) {
|
|
497107
497719
|
await mkdir19(getReflectionArenaRunsDir(), { recursive: true });
|
|
@@ -497393,6 +498005,11 @@ async function markCandidateComplete(params) {
|
|
|
497393
498005
|
});
|
|
497394
498006
|
}
|
|
497395
498007
|
async function launchReflectionArena(options3) {
|
|
498008
|
+
const memoryDir = getScopedMemoryFilesystemRoot(options3.agentId);
|
|
498009
|
+
if (await reflectionMemoryParentHasChanges(memoryDir)) {
|
|
498010
|
+
debugLog("memory", `Skipping reflection arena launch (${options3.triggerSource}) because parent memory has uncommitted changes`);
|
|
498011
|
+
return { launched: false, reason: "parent_dirty" };
|
|
498012
|
+
}
|
|
497396
498013
|
const payload = await buildAutoReflectionPayload(options3.agentId, options3.conversationId);
|
|
497397
498014
|
if (!payload) {
|
|
497398
498015
|
return { launched: false, reason: "no_payload" };
|
|
@@ -497439,7 +498056,8 @@ async function startReflectionArenaRun(options3) {
|
|
|
497439
498056
|
payloadPath: options3.payload.payloadPath,
|
|
497440
498057
|
runId,
|
|
497441
498058
|
startMessageId: options3.payload.startMessageId,
|
|
497442
|
-
status: "running"
|
|
498059
|
+
status: "running",
|
|
498060
|
+
triggerSource: options3.triggerSource
|
|
497443
498061
|
};
|
|
497444
498062
|
await saveReflectionArenaRun(run);
|
|
497445
498063
|
const { spawnBackgroundSubagentTask: spawnBackgroundSubagentTask2, waitForBackgroundSubagentAgentId: waitForBackgroundSubagentAgentId2 } = await Promise.resolve().then(() => (init_task(), exports_task));
|
|
@@ -497464,11 +498082,16 @@ async function startReflectionArenaRun(options3) {
|
|
|
497464
498082
|
error: error54,
|
|
497465
498083
|
agentId,
|
|
497466
498084
|
conversationId,
|
|
498085
|
+
model: resolvedModel,
|
|
497467
498086
|
stepCount,
|
|
497468
498087
|
durationMs,
|
|
497469
498088
|
report
|
|
497470
498089
|
}) => {
|
|
497471
498090
|
try {
|
|
498091
|
+
const [memoryHead, memoryNoChanges] = await Promise.all([
|
|
498092
|
+
getGitHead(candidate.worktree.worktreeDir),
|
|
498093
|
+
reflectionMemoryWorktreeHasNoChanges(candidate.worktree)
|
|
498094
|
+
]);
|
|
497472
498095
|
emitReflectionRunEnd({
|
|
497473
498096
|
parentAgentId: options3.agentId,
|
|
497474
498097
|
triggerSource: options3.triggerSource,
|
|
@@ -497478,9 +498101,9 @@ async function startReflectionArenaRun(options3) {
|
|
|
497478
498101
|
error: error54,
|
|
497479
498102
|
stepCount,
|
|
497480
498103
|
durationMs,
|
|
498104
|
+
model: resolvedModel ?? model,
|
|
497481
498105
|
feedbackContext: {
|
|
497482
|
-
...options3.feedbackContext
|
|
497483
|
-
model
|
|
498106
|
+
...options3.feedbackContext
|
|
497484
498107
|
}
|
|
497485
498108
|
});
|
|
497486
498109
|
if (!success2 && model !== REFLECTION_ARENA_MODEL_A_DEFAULT && isRetryableArenaModelError(error54)) {
|
|
@@ -497501,9 +498124,12 @@ async function startReflectionArenaRun(options3) {
|
|
|
497501
498124
|
error: error54,
|
|
497502
498125
|
agentId,
|
|
497503
498126
|
conversationId,
|
|
498127
|
+
model: resolvedModel ?? model,
|
|
497504
498128
|
stepCount,
|
|
497505
498129
|
durationMs,
|
|
497506
|
-
report
|
|
498130
|
+
report,
|
|
498131
|
+
...memoryHead ? { memoryHead } : {},
|
|
498132
|
+
...memoryNoChanges !== undefined ? { memoryNoChanges } : {}
|
|
497507
498133
|
}
|
|
497508
498134
|
});
|
|
497509
498135
|
if (updated.status === "awaiting_choice") {
|
|
@@ -497561,14 +498187,19 @@ async function finalizeReflectionArenaChoice(options3) {
|
|
|
497561
498187
|
throw new Error(`Unknown reflection arena label: ${options3.choice}`);
|
|
497562
498188
|
}
|
|
497563
498189
|
memoryBaseCommit = chosen.worktree.baseHead;
|
|
497564
|
-
memoryCandidateCommit = await getGitHead(chosen.worktree.worktreeDir);
|
|
498190
|
+
memoryCandidateCommit = await getGitHead(chosen.worktree.worktreeDir) ?? chosen.result?.memoryHead ?? null;
|
|
497565
498191
|
const finalized = await finalizeReflectionMemoryWorktreeLaunch({
|
|
497566
498192
|
worktree: chosen.worktree,
|
|
497567
498193
|
subagentSuccess: chosen.result?.success ?? false,
|
|
497568
498194
|
subagentError: chosen.result?.error,
|
|
497569
|
-
|
|
498195
|
+
knownNoChanges: candidateIsConfirmedNoOp(chosen),
|
|
498196
|
+
...getReflectionFinalizationContext(run.agentId),
|
|
497570
498197
|
conversationId: run.conversationId,
|
|
497571
498198
|
subagentAgentId: chosen.result?.agentId,
|
|
498199
|
+
model: chosen.result?.model ?? chosen.model,
|
|
498200
|
+
telemetryContext: {
|
|
498201
|
+
triggerSource: run.triggerSource ?? "compaction-event"
|
|
498202
|
+
},
|
|
497572
498203
|
recompileByConversation: options3.recompileByConversation,
|
|
497573
498204
|
recompileQueuedByConversation: options3.recompileQueuedByConversation,
|
|
497574
498205
|
logRecompileFailure: (message) => debugWarn("memory", message)
|
|
@@ -497581,7 +498212,8 @@ async function finalizeReflectionArenaChoice(options3) {
|
|
|
497581
498212
|
}
|
|
497582
498213
|
discarded.push(candidate.label);
|
|
497583
498214
|
await finalizeReflectionMemoryWorktree(candidate.worktree, {
|
|
497584
|
-
shouldMerge: false
|
|
498215
|
+
shouldMerge: false,
|
|
498216
|
+
knownNoChanges: candidateIsConfirmedNoOp(candidate)
|
|
497585
498217
|
});
|
|
497586
498218
|
}
|
|
497587
498219
|
await finalizeAutoReflectionPayload(run.agentId, run.conversationId, run.payloadPath, run.endSnapshotLine, integration ? reflectionIntegrationConsumesTranscript(integration) : false);
|
|
@@ -497621,6 +498253,7 @@ async function finalizeReflectionArenaChoice(options3) {
|
|
|
497621
498253
|
}
|
|
497622
498254
|
var execFile18, REFLECTION_ARENA_TELEMETRY_TRANSCRIPT_MAX_CHARS = 1e6, REFLECTION_ARENA_MODEL_A_DEFAULT = "letta/auto-memory", REFLECTION_ARENA_COMPARISON_MODEL_POOL, ANSI_BOLD = "\x1B[1m", ANSI_CYAN = "\x1B[36m", ANSI_MAGENTA = "\x1B[35m", ANSI_RESET_BOLD = "\x1B[22m", ANSI_RESET_FOREGROUND = "\x1B[39m", REFLECTION_ARENA_CANDIDATE_COUNT = 2, REFLECTION_ARENA_CHOICE_QUESTION = "Which reflection should be merged?", REFLECTION_ARENA_NOTES_QUESTION = "Optional feedback for this choice?", updateLocks;
|
|
497623
498255
|
var init_reflection_arena = __esm(() => {
|
|
498256
|
+
init_memory_filesystem2();
|
|
497624
498257
|
init_memory_worktree();
|
|
497625
498258
|
init_app_urls();
|
|
497626
498259
|
init_reflection_arena_hf_upload();
|
|
@@ -498192,13 +498825,13 @@ __export(exports_terminal_keybinding_installer, {
|
|
|
498192
498825
|
});
|
|
498193
498826
|
import {
|
|
498194
498827
|
copyFileSync as copyFileSync6,
|
|
498195
|
-
existsSync as
|
|
498828
|
+
existsSync as existsSync64,
|
|
498196
498829
|
mkdirSync as mkdirSync45,
|
|
498197
498830
|
readFileSync as readFileSync41,
|
|
498198
498831
|
writeFileSync as writeFileSync34
|
|
498199
498832
|
} from "node:fs";
|
|
498200
498833
|
import { homedir as homedir47, platform as platform10 } from "node:os";
|
|
498201
|
-
import { dirname as dirname35, join as
|
|
498834
|
+
import { dirname as dirname35, join as join83 } from "node:path";
|
|
498202
498835
|
function detectTerminalType() {
|
|
498203
498836
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
498204
498837
|
return "cursor";
|
|
@@ -498230,16 +498863,16 @@ function getKeybindingsPath(terminal) {
|
|
|
498230
498863
|
}[terminal];
|
|
498231
498864
|
const os8 = platform10();
|
|
498232
498865
|
if (os8 === "darwin") {
|
|
498233
|
-
return
|
|
498866
|
+
return join83(homedir47(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
498234
498867
|
}
|
|
498235
498868
|
if (os8 === "win32") {
|
|
498236
498869
|
const appData = process.env.APPDATA;
|
|
498237
498870
|
if (!appData)
|
|
498238
498871
|
return null;
|
|
498239
|
-
return
|
|
498872
|
+
return join83(appData, appName, "User", "keybindings.json");
|
|
498240
498873
|
}
|
|
498241
498874
|
if (os8 === "linux") {
|
|
498242
|
-
return
|
|
498875
|
+
return join83(homedir47(), ".config", appName, "User", "keybindings.json");
|
|
498243
498876
|
}
|
|
498244
498877
|
return null;
|
|
498245
498878
|
}
|
|
@@ -498261,7 +498894,7 @@ function parseKeybindings(content) {
|
|
|
498261
498894
|
}
|
|
498262
498895
|
}
|
|
498263
498896
|
function keybindingExists(keybindingsPath) {
|
|
498264
|
-
if (!
|
|
498897
|
+
if (!existsSync64(keybindingsPath))
|
|
498265
498898
|
return false;
|
|
498266
498899
|
try {
|
|
498267
498900
|
const content = readFileSync41(keybindingsPath, { encoding: "utf-8" });
|
|
@@ -498274,7 +498907,7 @@ function keybindingExists(keybindingsPath) {
|
|
|
498274
498907
|
}
|
|
498275
498908
|
}
|
|
498276
498909
|
function createBackup(keybindingsPath) {
|
|
498277
|
-
if (!
|
|
498910
|
+
if (!existsSync64(keybindingsPath))
|
|
498278
498911
|
return null;
|
|
498279
498912
|
const backupPath = `${keybindingsPath}.letta-backup`;
|
|
498280
498913
|
try {
|
|
@@ -498290,12 +498923,12 @@ function installKeybinding(keybindingsPath) {
|
|
|
498290
498923
|
return { success: true, alreadyExists: true };
|
|
498291
498924
|
}
|
|
498292
498925
|
const parentDir = dirname35(keybindingsPath);
|
|
498293
|
-
if (!
|
|
498926
|
+
if (!existsSync64(parentDir)) {
|
|
498294
498927
|
mkdirSync45(parentDir, { recursive: true });
|
|
498295
498928
|
}
|
|
498296
498929
|
let keybindings = [];
|
|
498297
498930
|
let backupPath = null;
|
|
498298
|
-
if (
|
|
498931
|
+
if (existsSync64(keybindingsPath)) {
|
|
498299
498932
|
backupPath = createBackup(keybindingsPath);
|
|
498300
498933
|
const content = readFileSync41(keybindingsPath, { encoding: "utf-8" });
|
|
498301
498934
|
const parsed = parseKeybindings(content);
|
|
@@ -498325,7 +498958,7 @@ function installKeybinding(keybindingsPath) {
|
|
|
498325
498958
|
}
|
|
498326
498959
|
function removeKeybinding(keybindingsPath) {
|
|
498327
498960
|
try {
|
|
498328
|
-
if (!
|
|
498961
|
+
if (!existsSync64(keybindingsPath)) {
|
|
498329
498962
|
return { success: true };
|
|
498330
498963
|
}
|
|
498331
498964
|
const content = readFileSync41(keybindingsPath, { encoding: "utf-8" });
|
|
@@ -498392,14 +499025,14 @@ function getWezTermConfigPath() {
|
|
|
498392
499025
|
}
|
|
498393
499026
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
498394
499027
|
if (xdgConfig) {
|
|
498395
|
-
const xdgPath =
|
|
498396
|
-
if (
|
|
499028
|
+
const xdgPath = join83(xdgConfig, "wezterm", "wezterm.lua");
|
|
499029
|
+
if (existsSync64(xdgPath))
|
|
498397
499030
|
return xdgPath;
|
|
498398
499031
|
}
|
|
498399
|
-
const configPath =
|
|
498400
|
-
if (
|
|
499032
|
+
const configPath = join83(homedir47(), ".config", "wezterm", "wezterm.lua");
|
|
499033
|
+
if (existsSync64(configPath))
|
|
498401
499034
|
return configPath;
|
|
498402
|
-
return
|
|
499035
|
+
return join83(homedir47(), ".wezterm.lua");
|
|
498403
499036
|
}
|
|
498404
499037
|
function stripLuaCommentsFromLine(line, blockCommentEnd) {
|
|
498405
499038
|
let code2 = "";
|
|
@@ -498502,7 +499135,7 @@ ${WEZTERM_DELETE_FIX}
|
|
|
498502
499135
|
`;
|
|
498503
499136
|
}
|
|
498504
499137
|
function wezTermDeleteFixExists(configPath) {
|
|
498505
|
-
if (!
|
|
499138
|
+
if (!existsSync64(configPath))
|
|
498506
499139
|
return false;
|
|
498507
499140
|
try {
|
|
498508
499141
|
const content = readFileSync41(configPath, { encoding: "utf-8" });
|
|
@@ -498519,14 +499152,14 @@ function installWezTermDeleteFix() {
|
|
|
498519
499152
|
}
|
|
498520
499153
|
let content = "";
|
|
498521
499154
|
let backupPath = null;
|
|
498522
|
-
if (
|
|
499155
|
+
if (existsSync64(configPath)) {
|
|
498523
499156
|
backupPath = `${configPath}.letta-backup`;
|
|
498524
499157
|
copyFileSync6(configPath, backupPath);
|
|
498525
499158
|
content = readFileSync41(configPath, { encoding: "utf-8" });
|
|
498526
499159
|
}
|
|
498527
499160
|
content = injectWezTermDeleteFix(content);
|
|
498528
499161
|
const parentDir = dirname35(configPath);
|
|
498529
|
-
if (!
|
|
499162
|
+
if (!existsSync64(parentDir)) {
|
|
498530
499163
|
mkdirSync45(parentDir, { recursive: true });
|
|
498531
499164
|
}
|
|
498532
499165
|
writeFileSync34(configPath, content, { encoding: "utf-8" });
|
|
@@ -498578,9 +499211,9 @@ __export(exports_settings2, {
|
|
|
498578
499211
|
getSetting: () => getSetting
|
|
498579
499212
|
});
|
|
498580
499213
|
import { homedir as homedir48 } from "node:os";
|
|
498581
|
-
import { join as
|
|
499214
|
+
import { join as join84 } from "node:path";
|
|
498582
499215
|
function getSettingsPath() {
|
|
498583
|
-
return
|
|
499216
|
+
return join84(homedir48(), ".letta", "settings.json");
|
|
498584
499217
|
}
|
|
498585
499218
|
async function loadSettings() {
|
|
498586
499219
|
const settingsPath = getSettingsPath();
|
|
@@ -498617,7 +499250,7 @@ async function getSetting(key2) {
|
|
|
498617
499250
|
return settings3[key2];
|
|
498618
499251
|
}
|
|
498619
499252
|
function getProjectSettingsPath() {
|
|
498620
|
-
return
|
|
499253
|
+
return join84(process.cwd(), ".letta", "settings.local.json");
|
|
498621
499254
|
}
|
|
498622
499255
|
async function loadProjectSettings() {
|
|
498623
499256
|
const settingsPath = getProjectSettingsPath();
|
|
@@ -498635,7 +499268,7 @@ async function loadProjectSettings() {
|
|
|
498635
499268
|
}
|
|
498636
499269
|
async function saveProjectSettings(settings3) {
|
|
498637
499270
|
const settingsPath = getProjectSettingsPath();
|
|
498638
|
-
const dirPath =
|
|
499271
|
+
const dirPath = join84(process.cwd(), ".letta");
|
|
498639
499272
|
try {
|
|
498640
499273
|
if (!exists(dirPath)) {
|
|
498641
499274
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -498806,7 +499439,7 @@ var init_registry2 = __esm(() => {
|
|
|
498806
499439
|
}
|
|
498807
499440
|
},
|
|
498808
499441
|
"/sleeptime": {
|
|
498809
|
-
desc: "Configure sleep-time reflection trigger settings",
|
|
499442
|
+
desc: "Configure sleep-time reflection trigger and merge settings",
|
|
498810
499443
|
order: 15.5,
|
|
498811
499444
|
noArgs: true,
|
|
498812
499445
|
handler: () => {
|
|
@@ -499674,10 +500307,10 @@ var init_InlineBashApproval = __esm(async () => {
|
|
|
499674
500307
|
});
|
|
499675
500308
|
|
|
499676
500309
|
// src/cli/components/DiffRenderer.tsx
|
|
499677
|
-
import { relative as
|
|
500310
|
+
import { relative as relative15 } from "node:path";
|
|
499678
500311
|
function formatDisplayPath4(filePath) {
|
|
499679
500312
|
const cwd2 = process.cwd();
|
|
499680
|
-
const relativePath =
|
|
500313
|
+
const relativePath = relative15(cwd2, filePath);
|
|
499681
500314
|
if (relativePath.startsWith("..")) {
|
|
499682
500315
|
return filePath;
|
|
499683
500316
|
}
|
|
@@ -500036,10 +500669,10 @@ var init_DiffRenderer = __esm(async () => {
|
|
|
500036
500669
|
});
|
|
500037
500670
|
|
|
500038
500671
|
// src/cli/components/AdvancedDiffRenderer.tsx
|
|
500039
|
-
import { relative as
|
|
500672
|
+
import { relative as relative16 } from "node:path";
|
|
500040
500673
|
function formatRelativePath(filePath) {
|
|
500041
500674
|
const cwd2 = process.cwd();
|
|
500042
|
-
const relativePath =
|
|
500675
|
+
const relativePath = relative16(cwd2, filePath);
|
|
500043
500676
|
return relativePath.startsWith("..") ? relativePath : `./${relativePath}`;
|
|
500044
500677
|
}
|
|
500045
500678
|
function padLeft(n, width) {
|
|
@@ -500321,7 +500954,7 @@ function AdvancedDiffRenderer(props) {
|
|
|
500321
500954
|
}
|
|
500322
500955
|
const { hunks } = result;
|
|
500323
500956
|
const filePath = props.filePath;
|
|
500324
|
-
const
|
|
500957
|
+
const relative17 = formatRelativePath(filePath);
|
|
500325
500958
|
const lang41 = languageFromPath(filePath);
|
|
500326
500959
|
const shouldHighlight = lang41 && !exceedsAdvancedDiffHighlightLimits(hunks);
|
|
500327
500960
|
const hunkSyntaxLines = [];
|
|
@@ -500344,7 +500977,7 @@ function AdvancedDiffRenderer(props) {
|
|
|
500344
500977
|
const rows = buildAdvancedDiffRows(hunks, hunkSyntaxLines);
|
|
500345
500978
|
const maxDisplayNo = rows.reduce((m4, r5) => Math.max(m4, r5.displayNo), 1);
|
|
500346
500979
|
const gutterWidth = String(maxDisplayNo).length;
|
|
500347
|
-
const header = props.kind === "write" ? `Wrote changes to ${
|
|
500980
|
+
const header = props.kind === "write" ? `Wrote changes to ${relative17}` : `Updated ${relative17}`;
|
|
500348
500981
|
if (rows.length === 0) {
|
|
500349
500982
|
const noChangesGutter = 4;
|
|
500350
500983
|
return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
|
|
@@ -500395,7 +501028,7 @@ function AdvancedDiffRenderer(props) {
|
|
|
500395
501028
|
"No changes to ",
|
|
500396
501029
|
/* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text2, {
|
|
500397
501030
|
bold: true,
|
|
500398
|
-
children:
|
|
501031
|
+
children: relative17
|
|
500399
501032
|
}, undefined, false, undefined, this),
|
|
500400
501033
|
" (file content identical)"
|
|
500401
501034
|
]
|
|
@@ -500501,9 +501134,9 @@ function getHeaderText(fileEdit) {
|
|
|
500501
501134
|
} else if (operations.length === 1) {
|
|
500502
501135
|
const op = operations[0];
|
|
500503
501136
|
if (op) {
|
|
500504
|
-
const { relative:
|
|
501137
|
+
const { relative: relative18 } = __require("node:path");
|
|
500505
501138
|
const cwd3 = process.cwd();
|
|
500506
|
-
const relPath2 =
|
|
501139
|
+
const relPath2 = relative18(cwd3, op.path);
|
|
500507
501140
|
const displayPath2 = relPath2.startsWith("..") ? op.path : relPath2;
|
|
500508
501141
|
if (op.kind === "add") {
|
|
500509
501142
|
return `Write to ${displayPath2}?`;
|
|
@@ -500517,14 +501150,14 @@ function getHeaderText(fileEdit) {
|
|
|
500517
501150
|
}
|
|
500518
501151
|
return "Apply patch?";
|
|
500519
501152
|
}
|
|
500520
|
-
const { relative:
|
|
501153
|
+
const { relative: relative17 } = __require("node:path");
|
|
500521
501154
|
const cwd2 = process.cwd();
|
|
500522
|
-
const relPath =
|
|
501155
|
+
const relPath = relative17(cwd2, fileEdit.filePath);
|
|
500523
501156
|
const displayPath = relPath.startsWith("..") ? fileEdit.filePath : relPath;
|
|
500524
501157
|
if (t2 === "write" || t2 === "write_file" || t2 === "writefile" || t2 === "write_file_gemini" || t2 === "writefilegemini") {
|
|
500525
|
-
const { existsSync:
|
|
501158
|
+
const { existsSync: existsSync65 } = __require("node:fs");
|
|
500526
501159
|
try {
|
|
500527
|
-
if (
|
|
501160
|
+
if (existsSync65(fileEdit.filePath)) {
|
|
500528
501161
|
return `Overwrite ${displayPath}?`;
|
|
500529
501162
|
}
|
|
500530
501163
|
} catch {}
|
|
@@ -500702,9 +501335,9 @@ var init_InlineFileEditApproval = __esm(async () => {
|
|
|
500702
501335
|
children: fileEdit.patchInput ? /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
|
|
500703
501336
|
flexDirection: "column",
|
|
500704
501337
|
children: parsePatchOperations2(fileEdit.patchInput).map((op, idx) => {
|
|
500705
|
-
const { relative:
|
|
501338
|
+
const { relative: relative17 } = __require("node:path");
|
|
500706
501339
|
const cwd2 = process.cwd();
|
|
500707
|
-
const relPath =
|
|
501340
|
+
const relPath = relative17(cwd2, op.path);
|
|
500708
501341
|
const displayPath = relPath.startsWith("..") ? op.path : relPath;
|
|
500709
501342
|
const diffKey = fileEdit.toolCallId ? `${fileEdit.toolCallId}:${op.path}` : undefined;
|
|
500710
501343
|
const opDiff = diffKey && allDiffs ? allDiffs.get(diffKey) : undefined;
|
|
@@ -510019,7 +510652,7 @@ var init_agents8 = __esm(() => {
|
|
|
510019
510652
|
// src/cli/commands/install-github-app.ts
|
|
510020
510653
|
import { execFileSync as execFileSync8 } from "node:child_process";
|
|
510021
510654
|
import {
|
|
510022
|
-
existsSync as
|
|
510655
|
+
existsSync as existsSync65,
|
|
510023
510656
|
mkdirSync as mkdirSync46,
|
|
510024
510657
|
mkdtempSync as mkdtempSync5,
|
|
510025
510658
|
readFileSync as readFileSync42,
|
|
@@ -510027,7 +510660,7 @@ import {
|
|
|
510027
510660
|
writeFileSync as writeFileSync35
|
|
510028
510661
|
} from "node:fs";
|
|
510029
510662
|
import { tmpdir as tmpdir11 } from "node:os";
|
|
510030
|
-
import { dirname as dirname36, join as
|
|
510663
|
+
import { dirname as dirname36, join as join85 } from "node:path";
|
|
510031
510664
|
function runCommand(command, args, cwd2, input) {
|
|
510032
510665
|
try {
|
|
510033
510666
|
return execFileSync8(command, args, {
|
|
@@ -510248,8 +510881,8 @@ async function createLettaAgent(apiKey, name) {
|
|
|
510248
510881
|
return createMinimalAgent(apiKey, name);
|
|
510249
510882
|
}
|
|
510250
510883
|
function cloneRepoToTemp(repo) {
|
|
510251
|
-
const tempDir = mkdtempSync5(
|
|
510252
|
-
const repoDir =
|
|
510884
|
+
const tempDir = mkdtempSync5(join85(tmpdir11(), "letta-install-github-app-"));
|
|
510885
|
+
const repoDir = join85(tempDir, "repo");
|
|
510253
510886
|
runCommand("gh", ["repo", "clone", repo, repoDir, "--", "--depth=1"]);
|
|
510254
510887
|
return { tempDir, repoDir };
|
|
510255
510888
|
}
|
|
@@ -510260,13 +510893,13 @@ function runGit7(args, cwd2) {
|
|
|
510260
510893
|
return runCommand("git", args, cwd2);
|
|
510261
510894
|
}
|
|
510262
510895
|
function writeWorkflow(repoDir, workflowPath, content) {
|
|
510263
|
-
const absolutePath =
|
|
510264
|
-
if (!
|
|
510896
|
+
const absolutePath = join85(repoDir, workflowPath);
|
|
510897
|
+
if (!existsSync65(dirname36(absolutePath))) {
|
|
510265
510898
|
mkdirSync46(dirname36(absolutePath), { recursive: true });
|
|
510266
510899
|
}
|
|
510267
510900
|
const next = `${content.trimEnd()}
|
|
510268
510901
|
`;
|
|
510269
|
-
if (
|
|
510902
|
+
if (existsSync65(absolutePath)) {
|
|
510270
510903
|
const previous = readFileSync42(absolutePath, "utf8");
|
|
510271
510904
|
if (previous === next) {
|
|
510272
510905
|
return false;
|
|
@@ -511223,6 +511856,7 @@ function LettaLoginOverlay({
|
|
|
511223
511856
|
command: "/login",
|
|
511224
511857
|
title: "Sign in with Letta",
|
|
511225
511858
|
children: /* @__PURE__ */ jsx_dev_runtime63.jsxDEV(LettaLoginView, {
|
|
511859
|
+
activateCloudBackend: false,
|
|
511226
511860
|
onComplete,
|
|
511227
511861
|
onCancel
|
|
511228
511862
|
}, undefined, false, undefined, this)
|
|
@@ -514155,9 +514789,9 @@ __export(exports_generate_memory_viewer, {
|
|
|
514155
514789
|
generateAndOpenMemoryViewer: () => generateAndOpenMemoryViewer
|
|
514156
514790
|
});
|
|
514157
514791
|
import { execFile as execFileCb7 } from "node:child_process";
|
|
514158
|
-
import { chmodSync as chmodSync7, existsSync as
|
|
514792
|
+
import { chmodSync as chmodSync7, existsSync as existsSync66, mkdirSync as mkdirSync47, writeFileSync as writeFileSync36 } from "node:fs";
|
|
514159
514793
|
import { homedir as homedir50 } from "node:os";
|
|
514160
|
-
import { join as
|
|
514794
|
+
import { join as join86 } from "node:path";
|
|
514161
514795
|
import { promisify as promisify17 } from "node:util";
|
|
514162
514796
|
function messagesFromOverview(overview) {
|
|
514163
514797
|
return overview.messages?.map((message) => ({
|
|
@@ -514466,7 +515100,7 @@ ${m4.body}` : m4.subject;
|
|
|
514466
515100
|
async function generateAndOpenMemoryViewer(agentId, options3) {
|
|
514467
515101
|
const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
514468
515102
|
const repoDir = memoryRoot;
|
|
514469
|
-
if (!
|
|
515103
|
+
if (!existsSync66(join86(repoDir, ".git"))) {
|
|
514470
515104
|
throw new Error("Memory viewer requires memfs. Run /memfs enable first.");
|
|
514471
515105
|
}
|
|
514472
515106
|
const data = await collectMemoryData(agentId, repoDir, memoryRoot, options3?.conversationId);
|
|
@@ -514476,13 +515110,13 @@ async function generateAndOpenMemoryViewer(agentId, options3) {
|
|
|
514476
515110
|
data.context = applyContextUsageSnapshot(data.context, options3?.contextUsage);
|
|
514477
515111
|
const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
|
|
514478
515112
|
const html5 = memory_viewer_template_default.replace("<!--LETTA_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
514479
|
-
if (!
|
|
515113
|
+
if (!existsSync66(VIEWERS_DIR)) {
|
|
514480
515114
|
mkdirSync47(VIEWERS_DIR, { recursive: true, mode: 448 });
|
|
514481
515115
|
}
|
|
514482
515116
|
try {
|
|
514483
515117
|
chmodSync7(VIEWERS_DIR, 448);
|
|
514484
515118
|
} catch {}
|
|
514485
|
-
const filePath =
|
|
515119
|
+
const filePath = join86(VIEWERS_DIR, `memory-${encodeURIComponent(agentId)}.html`);
|
|
514486
515120
|
writeFileSync36(filePath, html5);
|
|
514487
515121
|
chmodSync7(filePath, 384);
|
|
514488
515122
|
const skipOpen = Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
|
|
@@ -514507,13 +515141,13 @@ var init_generate_memory_viewer = __esm(() => {
|
|
|
514507
515141
|
init_local_memory_context();
|
|
514508
515142
|
init_memory_viewer_template();
|
|
514509
515143
|
execFile19 = promisify17(execFileCb7);
|
|
514510
|
-
VIEWERS_DIR =
|
|
515144
|
+
VIEWERS_DIR = join86(homedir50(), ".letta", "viewers");
|
|
514511
515145
|
REFLECTION_PATTERN = /\(reflection\)|🔮|reflection:/i;
|
|
514512
515146
|
});
|
|
514513
515147
|
|
|
514514
515148
|
// src/cli/components/MemfsTreeViewer.tsx
|
|
514515
|
-
import { existsSync as
|
|
514516
|
-
import { join as
|
|
515149
|
+
import { existsSync as existsSync67 } from "node:fs";
|
|
515150
|
+
import { join as join87 } from "node:path";
|
|
514517
515151
|
function renderTreePrefix(node) {
|
|
514518
515152
|
let prefix = "";
|
|
514519
515153
|
for (let i4 = 0;i4 < node.depth; i4++) {
|
|
@@ -514541,8 +515175,8 @@ function MemfsTreeViewer({
|
|
|
514541
515175
|
const [status, setStatus] = import_react87.useState(null);
|
|
514542
515176
|
const statusTimerRef = import_react87.useRef(null);
|
|
514543
515177
|
const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
514544
|
-
const memoryExists =
|
|
514545
|
-
const hasGitRepo = import_react87.useMemo(() =>
|
|
515178
|
+
const memoryExists = existsSync67(memoryRoot);
|
|
515179
|
+
const hasGitRepo = import_react87.useMemo(() => existsSync67(join87(memoryRoot, ".git")), [memoryRoot]);
|
|
514546
515180
|
function showStatus(msg, durationMs) {
|
|
514547
515181
|
if (statusTimerRef.current)
|
|
514548
515182
|
clearTimeout(statusTimerRef.current);
|
|
@@ -516919,10 +517553,10 @@ var init_PersonalitySelector = __esm(async () => {
|
|
|
516919
517553
|
// src/utils/aws-credentials.ts
|
|
516920
517554
|
import { readFile as readFile30 } from "node:fs/promises";
|
|
516921
517555
|
import { homedir as homedir51 } from "node:os";
|
|
516922
|
-
import { join as
|
|
517556
|
+
import { join as join88 } from "node:path";
|
|
516923
517557
|
async function parseAwsCredentials() {
|
|
516924
|
-
const credentialsPath =
|
|
516925
|
-
const configPath =
|
|
517558
|
+
const credentialsPath = join88(homedir51(), ".aws", "credentials");
|
|
517559
|
+
const configPath = join88(homedir51(), ".aws", "config");
|
|
516926
517560
|
const profiles = new Map;
|
|
516927
517561
|
try {
|
|
516928
517562
|
const content = await readFile30(credentialsPath, "utf-8");
|
|
@@ -518501,8 +519135,8 @@ function SkillsDialog({ onClose, agentId }) {
|
|
|
518501
519135
|
try {
|
|
518502
519136
|
const { discoverSkills: discoverSkills2, SKILLS_DIR: SKILLS_DIR2 } = await Promise.resolve().then(() => (init_skills3(), exports_skills2));
|
|
518503
519137
|
const { getSkillsDirectory: getSkillsDirectory2, getSkillSources: getSkillSources2 } = await Promise.resolve().then(() => (init_context(), exports_context));
|
|
518504
|
-
const { join:
|
|
518505
|
-
const skillsDir = getSkillsDirectory2() ||
|
|
519138
|
+
const { join: join89 } = await import("node:path");
|
|
519139
|
+
const skillsDir = getSkillsDirectory2() || join89(process.cwd(), SKILLS_DIR2);
|
|
518506
519140
|
const result = await discoverSkills2(skillsDir, agentId, {
|
|
518507
519141
|
sources: getSkillSources2()
|
|
518508
519142
|
});
|
|
@@ -518717,6 +519351,36 @@ var init_SkillsDialog = __esm(async () => {
|
|
|
518717
519351
|
});
|
|
518718
519352
|
|
|
518719
519353
|
// src/cli/components/SleeptimeSelector.tsx
|
|
519354
|
+
function triggerFocusRow(trigger) {
|
|
519355
|
+
switch (trigger) {
|
|
519356
|
+
case "off":
|
|
519357
|
+
return "trigger-off";
|
|
519358
|
+
case "step-count":
|
|
519359
|
+
return "trigger-step-count";
|
|
519360
|
+
case "compaction-event":
|
|
519361
|
+
return "trigger-compaction";
|
|
519362
|
+
}
|
|
519363
|
+
}
|
|
519364
|
+
function mergeFocusRow(merge3) {
|
|
519365
|
+
return merge3 === "explicit" ? "merge-explicit" : "merge-auto";
|
|
519366
|
+
}
|
|
519367
|
+
function ChoiceRow(props) {
|
|
519368
|
+
const { focused, selected, children } = props;
|
|
519369
|
+
return /* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Box_default, {
|
|
519370
|
+
flexDirection: "row",
|
|
519371
|
+
children: [
|
|
519372
|
+
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
519373
|
+
children: focused ? "> " : " "
|
|
519374
|
+
}, undefined, false, undefined, this),
|
|
519375
|
+
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
519376
|
+
backgroundColor: selected ? colors.selector.itemHighlighted : undefined,
|
|
519377
|
+
color: selected ? "black" : undefined,
|
|
519378
|
+
bold: selected,
|
|
519379
|
+
children
|
|
519380
|
+
}, undefined, false, undefined, this)
|
|
519381
|
+
]
|
|
519382
|
+
}, undefined, true, undefined, this);
|
|
519383
|
+
}
|
|
518720
519384
|
function cycleOption(options3, current, direction) {
|
|
518721
519385
|
if (options3.length === 0) {
|
|
518722
519386
|
return current;
|
|
@@ -518729,7 +519393,9 @@ function cycleOption(options3, current, direction) {
|
|
|
518729
519393
|
function parseInitialState(initialSettings) {
|
|
518730
519394
|
return {
|
|
518731
519395
|
trigger: initialSettings.trigger === "off" || initialSettings.trigger === "step-count" || initialSettings.trigger === "compaction-event" ? initialSettings.trigger : "step-count",
|
|
518732
|
-
stepCount: String(Number.isInteger(initialSettings.stepCount) && initialSettings.stepCount > 0 ? initialSettings.stepCount : Number(DEFAULT_STEP_COUNT2))
|
|
519396
|
+
stepCount: String(Number.isInteger(initialSettings.stepCount) && initialSettings.stepCount > 0 ? initialSettings.stepCount : Number(DEFAULT_STEP_COUNT2)),
|
|
519397
|
+
merge: initialSettings.merge === "explicit" ? "explicit" : "auto",
|
|
519398
|
+
mergeInstructions: initialSettings.mergeInstructions ?? ""
|
|
518733
519399
|
};
|
|
518734
519400
|
}
|
|
518735
519401
|
function parseStepCount(raw2) {
|
|
@@ -518752,19 +519418,28 @@ function SleeptimeSelector({
|
|
|
518752
519418
|
const initialState = import_react96.useMemo(() => parseInitialState(initialSettings), [initialSettings]);
|
|
518753
519419
|
const [trigger, setTrigger] = import_react96.useState(initialState.trigger);
|
|
518754
519420
|
const [stepCountInput, setStepCountInput] = import_react96.useState(initialState.stepCount);
|
|
518755
|
-
const [
|
|
519421
|
+
const [merge3, setMerge] = import_react96.useState(initialState.merge);
|
|
519422
|
+
const [mergeInstructions, setMergeInstructions] = import_react96.useState(initialState.mergeInstructions);
|
|
519423
|
+
const [focusRow, setFocusRow] = import_react96.useState(() => triggerFocusRow(initialState.trigger));
|
|
518756
519424
|
const [validationError, setValidationError] = import_react96.useState(null);
|
|
518757
519425
|
const visibleRows = import_react96.useMemo(() => {
|
|
518758
|
-
const rows = [
|
|
518759
|
-
|
|
518760
|
-
|
|
519426
|
+
const rows = [
|
|
519427
|
+
"trigger-off",
|
|
519428
|
+
"trigger-step-count",
|
|
519429
|
+
"trigger-compaction",
|
|
519430
|
+
"merge-auto",
|
|
519431
|
+
"merge-explicit"
|
|
519432
|
+
];
|
|
519433
|
+
if (merge3 === "explicit") {
|
|
519434
|
+
rows.push("merge-instructions");
|
|
518761
519435
|
}
|
|
518762
519436
|
return rows;
|
|
518763
|
-
}, [
|
|
518764
|
-
const isEditingStepCount = focusRow === "
|
|
519437
|
+
}, [merge3]);
|
|
519438
|
+
const isEditingStepCount = focusRow === "trigger-step-count";
|
|
519439
|
+
const isEditingMergeInstructions = focusRow === "merge-instructions" && merge3 === "explicit";
|
|
518765
519440
|
import_react96.useEffect(() => {
|
|
518766
519441
|
if (!visibleRows.includes(focusRow)) {
|
|
518767
|
-
setFocusRow(visibleRows[visibleRows.length - 1] ?? "trigger");
|
|
519442
|
+
setFocusRow(visibleRows[visibleRows.length - 1] ?? "trigger-off");
|
|
518768
519443
|
}
|
|
518769
519444
|
}, [focusRow, visibleRows]);
|
|
518770
519445
|
const saveSelection = () => {
|
|
@@ -518776,16 +519451,42 @@ function SleeptimeSelector({
|
|
|
518776
519451
|
}
|
|
518777
519452
|
onSave({
|
|
518778
519453
|
trigger,
|
|
518779
|
-
stepCount
|
|
519454
|
+
stepCount,
|
|
519455
|
+
merge: merge3,
|
|
519456
|
+
mergeInstructions
|
|
518780
519457
|
});
|
|
518781
519458
|
return;
|
|
518782
519459
|
}
|
|
518783
519460
|
const fallbackStepCount = parseStepCount(stepCountInput) ?? Number(DEFAULT_STEP_COUNT2);
|
|
518784
519461
|
onSave({
|
|
518785
519462
|
trigger,
|
|
518786
|
-
stepCount: fallbackStepCount
|
|
519463
|
+
stepCount: fallbackStepCount,
|
|
519464
|
+
merge: merge3,
|
|
519465
|
+
mergeInstructions
|
|
518787
519466
|
});
|
|
518788
519467
|
};
|
|
519468
|
+
const selectFocusedOption = () => {
|
|
519469
|
+
switch (focusRow) {
|
|
519470
|
+
case "trigger-off":
|
|
519471
|
+
setTrigger("off");
|
|
519472
|
+
break;
|
|
519473
|
+
case "trigger-step-count":
|
|
519474
|
+
setTrigger("step-count");
|
|
519475
|
+
break;
|
|
519476
|
+
case "trigger-compaction":
|
|
519477
|
+
setTrigger("compaction-event");
|
|
519478
|
+
break;
|
|
519479
|
+
case "merge-auto":
|
|
519480
|
+
setMerge("auto");
|
|
519481
|
+
break;
|
|
519482
|
+
case "merge-explicit":
|
|
519483
|
+
setMerge("explicit");
|
|
519484
|
+
break;
|
|
519485
|
+
case "merge-instructions":
|
|
519486
|
+
break;
|
|
519487
|
+
}
|
|
519488
|
+
setValidationError(null);
|
|
519489
|
+
};
|
|
518789
519490
|
use_input_default((input, key2) => {
|
|
518790
519491
|
if (key2.ctrl && input === "c") {
|
|
518791
519492
|
onCancel();
|
|
@@ -518805,35 +519506,55 @@ function SleeptimeSelector({
|
|
|
518805
519506
|
saveSelection();
|
|
518806
519507
|
return;
|
|
518807
519508
|
}
|
|
518808
|
-
if (key2.upArrow || key2.downArrow) {
|
|
519509
|
+
if (key2.upArrow || key2.downArrow || key2.tab) {
|
|
518809
519510
|
if (visibleRows.length === 0)
|
|
518810
519511
|
return;
|
|
518811
519512
|
setValidationError(null);
|
|
518812
|
-
const direction = key2.
|
|
519513
|
+
const direction = key2.upArrow ? -1 : 1;
|
|
518813
519514
|
const currentIndex = visibleRows.indexOf(focusRow);
|
|
518814
519515
|
const safeIndex = currentIndex >= 0 ? currentIndex : 0;
|
|
518815
519516
|
const nextIndex = (safeIndex + direction + visibleRows.length) % visibleRows.length;
|
|
518816
|
-
const nextRow = visibleRows[nextIndex] ?? "trigger";
|
|
519517
|
+
const nextRow = visibleRows[nextIndex] ?? "trigger-off";
|
|
518817
519518
|
setFocusRow(nextRow);
|
|
518818
519519
|
return;
|
|
518819
519520
|
}
|
|
518820
|
-
if (
|
|
519521
|
+
if (input === " " && !isEditingMergeInstructions) {
|
|
519522
|
+
selectFocusedOption();
|
|
519523
|
+
return;
|
|
519524
|
+
}
|
|
519525
|
+
if (key2.leftArrow || key2.rightArrow) {
|
|
518821
519526
|
setValidationError(null);
|
|
518822
519527
|
const direction = key2.leftArrow ? -1 : 1;
|
|
518823
|
-
if (focusRow
|
|
518824
|
-
|
|
519528
|
+
if (focusRow.startsWith("trigger-")) {
|
|
519529
|
+
const nextTrigger = cycleOption(TRIGGER_OPTIONS, trigger, direction);
|
|
519530
|
+
setTrigger(nextTrigger);
|
|
519531
|
+
setFocusRow(triggerFocusRow(nextTrigger));
|
|
519532
|
+
} else if (focusRow.startsWith("merge-")) {
|
|
519533
|
+
const nextMerge = cycleOption(MERGE_OPTIONS, merge3, direction);
|
|
519534
|
+
setMerge(nextMerge);
|
|
519535
|
+
setFocusRow(mergeFocusRow(nextMerge));
|
|
518825
519536
|
}
|
|
518826
519537
|
return;
|
|
518827
519538
|
}
|
|
518828
|
-
if (!isEditingStepCount)
|
|
519539
|
+
if (!isEditingStepCount && !isEditingMergeInstructions)
|
|
518829
519540
|
return;
|
|
518830
519541
|
if (key2.backspace || key2.delete) {
|
|
518831
|
-
|
|
519542
|
+
if (isEditingStepCount) {
|
|
519543
|
+
setTrigger("step-count");
|
|
519544
|
+
setStepCountInput((prev) => prev.slice(0, -1));
|
|
519545
|
+
} else {
|
|
519546
|
+
setMergeInstructions((prev) => prev.slice(0, -1));
|
|
519547
|
+
}
|
|
518832
519548
|
setValidationError(null);
|
|
518833
519549
|
return;
|
|
518834
519550
|
}
|
|
518835
519551
|
if (input && input.length > 0 && !key2.ctrl && !key2.meta && !key2.tab && !key2.upArrow && !key2.downArrow && !key2.leftArrow && !key2.rightArrow) {
|
|
518836
|
-
|
|
519552
|
+
if (isEditingStepCount) {
|
|
519553
|
+
setTrigger("step-count");
|
|
519554
|
+
setStepCountInput((prev) => `${prev}${input}`);
|
|
519555
|
+
} else {
|
|
519556
|
+
setMergeInstructions((prev) => `${prev}${input}`);
|
|
519557
|
+
}
|
|
518837
519558
|
setValidationError(null);
|
|
518838
519559
|
}
|
|
518839
519560
|
});
|
|
@@ -518851,79 +519572,73 @@ function SleeptimeSelector({
|
|
|
518851
519572
|
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Box_default, {
|
|
518852
519573
|
height: 1
|
|
518853
519574
|
}, undefined, false, undefined, this),
|
|
518854
|
-
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
518855
|
-
bold: true,
|
|
518856
|
-
color: colors.selector.title,
|
|
518857
|
-
children: "Configure your sleep-time (dream) settings"
|
|
518858
|
-
}, undefined, false, undefined, this),
|
|
518859
|
-
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Box_default, {
|
|
518860
|
-
height: 1
|
|
518861
|
-
}, undefined, false, undefined, this),
|
|
518862
519575
|
memfsEnabled ? /* @__PURE__ */ jsx_dev_runtime74.jsxDEV(jsx_dev_runtime74.Fragment, {
|
|
518863
519576
|
children: [
|
|
519577
|
+
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
519578
|
+
bold: true,
|
|
519579
|
+
color: colors.selector.title,
|
|
519580
|
+
children: "Dream Settings"
|
|
519581
|
+
}, undefined, false, undefined, this),
|
|
518864
519582
|
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Box_default, {
|
|
518865
|
-
|
|
519583
|
+
height: 1
|
|
519584
|
+
}, undefined, false, undefined, this),
|
|
519585
|
+
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(ChoiceRow, {
|
|
519586
|
+
focused: focusRow === "trigger-off",
|
|
519587
|
+
selected: trigger === "off",
|
|
519588
|
+
children: " Off "
|
|
519589
|
+
}, undefined, false, undefined, this),
|
|
519590
|
+
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(ChoiceRow, {
|
|
519591
|
+
focused: focusRow === "trigger-step-count",
|
|
519592
|
+
selected: trigger === "step-count",
|
|
519593
|
+
children: ` Every [${stepCountInput}${isEditingStepCount ? "█" : ""}] steps `
|
|
519594
|
+
}, undefined, false, undefined, this),
|
|
519595
|
+
validationError && /* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
519596
|
+
color: colors.error.text,
|
|
519597
|
+
children: ` Error: ${validationError}`
|
|
519598
|
+
}, undefined, false, undefined, this),
|
|
519599
|
+
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(ChoiceRow, {
|
|
519600
|
+
focused: focusRow === "trigger-compaction",
|
|
519601
|
+
selected: trigger === "compaction-event",
|
|
519602
|
+
children: " On compaction "
|
|
519603
|
+
}, undefined, false, undefined, this),
|
|
519604
|
+
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Box_default, {
|
|
519605
|
+
height: 1
|
|
519606
|
+
}, undefined, false, undefined, this),
|
|
519607
|
+
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
519608
|
+
bold: true,
|
|
519609
|
+
color: colors.selector.title,
|
|
519610
|
+
children: "Memory updates"
|
|
519611
|
+
}, undefined, false, undefined, this),
|
|
519612
|
+
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Box_default, {
|
|
519613
|
+
height: 1
|
|
519614
|
+
}, undefined, false, undefined, this),
|
|
519615
|
+
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(ChoiceRow, {
|
|
519616
|
+
focused: focusRow === "merge-auto",
|
|
519617
|
+
selected: merge3 === "auto",
|
|
519618
|
+
children: " Apply automatically "
|
|
519619
|
+
}, undefined, false, undefined, this),
|
|
519620
|
+
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(ChoiceRow, {
|
|
519621
|
+
focused: focusRow === "merge-explicit",
|
|
519622
|
+
selected: merge3 === "explicit",
|
|
519623
|
+
children: " Agent reviews before applying "
|
|
519624
|
+
}, undefined, false, undefined, this),
|
|
519625
|
+
merge3 === "explicit" && /* @__PURE__ */ jsx_dev_runtime74.jsxDEV(jsx_dev_runtime74.Fragment, {
|
|
518866
519626
|
children: [
|
|
518867
|
-
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(
|
|
518868
|
-
|
|
519627
|
+
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Box_default, {
|
|
519628
|
+
height: 1
|
|
518869
519629
|
}, undefined, false, undefined, this),
|
|
518870
519630
|
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
518871
519631
|
bold: true,
|
|
518872
|
-
children: "
|
|
518873
|
-
}, undefined, false, undefined, this),
|
|
518874
|
-
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
518875
|
-
children: " "
|
|
518876
|
-
}, undefined, false, undefined, this),
|
|
518877
|
-
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
518878
|
-
backgroundColor: trigger === "off" ? colors.selector.itemHighlighted : undefined,
|
|
518879
|
-
color: trigger === "off" ? "black" : undefined,
|
|
518880
|
-
bold: trigger === "off",
|
|
518881
|
-
children: " Off "
|
|
518882
|
-
}, undefined, false, undefined, this),
|
|
518883
|
-
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
518884
|
-
children: " "
|
|
518885
|
-
}, undefined, false, undefined, this),
|
|
518886
|
-
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
518887
|
-
backgroundColor: trigger === "step-count" ? colors.selector.itemHighlighted : undefined,
|
|
518888
|
-
color: trigger === "step-count" ? "black" : undefined,
|
|
518889
|
-
bold: trigger === "step-count",
|
|
518890
|
-
children: " Step count "
|
|
518891
|
-
}, undefined, false, undefined, this),
|
|
518892
|
-
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
518893
|
-
children: " "
|
|
518894
|
-
}, undefined, false, undefined, this),
|
|
518895
|
-
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
518896
|
-
backgroundColor: trigger === "compaction-event" ? colors.selector.itemHighlighted : undefined,
|
|
518897
|
-
color: trigger === "compaction-event" ? "black" : undefined,
|
|
518898
|
-
bold: trigger === "compaction-event",
|
|
518899
|
-
children: " Compaction event "
|
|
518900
|
-
}, undefined, false, undefined, this)
|
|
518901
|
-
]
|
|
518902
|
-
}, undefined, true, undefined, this),
|
|
518903
|
-
trigger === "step-count" && /* @__PURE__ */ jsx_dev_runtime74.jsxDEV(jsx_dev_runtime74.Fragment, {
|
|
518904
|
-
children: [
|
|
518905
|
-
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Box_default, {
|
|
518906
|
-
height: 1
|
|
519632
|
+
children: " Review instructions"
|
|
518907
519633
|
}, undefined, false, undefined, this),
|
|
518908
519634
|
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Box_default, {
|
|
518909
519635
|
flexDirection: "row",
|
|
518910
519636
|
children: [
|
|
518911
519637
|
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
518912
|
-
children: focusRow === "
|
|
518913
|
-
}, undefined, false, undefined, this),
|
|
518914
|
-
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
518915
|
-
bold: true,
|
|
518916
|
-
children: "Step count: "
|
|
519638
|
+
children: focusRow === "merge-instructions" ? "> " : " "
|
|
518917
519639
|
}, undefined, false, undefined, this),
|
|
518918
519640
|
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
518919
|
-
children:
|
|
518920
|
-
}, undefined, false, undefined, this),
|
|
518921
|
-
isEditingStepCount && /* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
518922
|
-
children: "█"
|
|
518923
|
-
}, undefined, false, undefined, this),
|
|
518924
|
-
validationError && /* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
518925
|
-
color: colors.error.text,
|
|
518926
|
-
children: ` (error: ${validationError})`
|
|
519641
|
+
children: `[${mergeInstructions}${isEditingMergeInstructions ? "█" : ""}]`
|
|
518927
519642
|
}, undefined, false, undefined, this)
|
|
518928
519643
|
]
|
|
518929
519644
|
}, undefined, true, undefined, this)
|
|
@@ -518934,13 +519649,13 @@ function SleeptimeSelector({
|
|
|
518934
519649
|
}, undefined, false, undefined, this),
|
|
518935
519650
|
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
518936
519651
|
dimColor: true,
|
|
518937
|
-
children: " Enter
|
|
519652
|
+
children: " Enter save · ↑↓/Tab move · Space select · ←→ options · Esc cancel"
|
|
518938
519653
|
}, undefined, false, undefined, this)
|
|
518939
519654
|
]
|
|
518940
519655
|
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime74.jsxDEV(jsx_dev_runtime74.Fragment, {
|
|
518941
519656
|
children: [
|
|
518942
519657
|
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Text2, {
|
|
518943
|
-
children: "
|
|
519658
|
+
children: "Dream settings require the memory filesystem (MemFS) to be enabled for this agent."
|
|
518944
519659
|
}, undefined, false, undefined, this),
|
|
518945
519660
|
/* @__PURE__ */ jsx_dev_runtime74.jsxDEV(Box_default, {
|
|
518946
519661
|
height: 1
|
|
@@ -518954,7 +519669,7 @@ function SleeptimeSelector({
|
|
|
518954
519669
|
]
|
|
518955
519670
|
}, undefined, true, undefined, this);
|
|
518956
519671
|
}
|
|
518957
|
-
var import_react96, jsx_dev_runtime74, SOLID_LINE18 = "─", DEFAULT_STEP_COUNT2 = "25", TRIGGER_OPTIONS;
|
|
519672
|
+
var import_react96, jsx_dev_runtime74, SOLID_LINE18 = "─", DEFAULT_STEP_COUNT2 = "25", TRIGGER_OPTIONS, MERGE_OPTIONS;
|
|
518958
519673
|
var init_SleeptimeSelector = __esm(async () => {
|
|
518959
519674
|
init_use_terminal_width();
|
|
518960
519675
|
init_colors();
|
|
@@ -518969,6 +519684,7 @@ var init_SleeptimeSelector = __esm(async () => {
|
|
|
518969
519684
|
"step-count",
|
|
518970
519685
|
"compaction-event"
|
|
518971
519686
|
];
|
|
519687
|
+
MERGE_OPTIONS = ["auto", "explicit"];
|
|
518972
519688
|
});
|
|
518973
519689
|
|
|
518974
519690
|
// src/cli/components/StatusMessage.tsx
|
|
@@ -519683,7 +520399,8 @@ function parseEnterWorktreeResult(text2) {
|
|
|
519683
520399
|
`);
|
|
519684
520400
|
const firstLine = normalized.split(`
|
|
519685
520401
|
`).find((line) => line.trim());
|
|
519686
|
-
|
|
520402
|
+
const action3 = firstLine?.trim() === "Created worktree." ? "created" : firstLine?.trim() === "Switched to existing worktree." ? "switched" : null;
|
|
520403
|
+
if (!action3) {
|
|
519687
520404
|
return null;
|
|
519688
520405
|
}
|
|
519689
520406
|
const field = (name) => {
|
|
@@ -519691,11 +520408,12 @@ function parseEnterWorktreeResult(text2) {
|
|
|
519691
520408
|
return match4?.[1]?.trim();
|
|
519692
520409
|
};
|
|
519693
520410
|
const result = {
|
|
520411
|
+
action: action3,
|
|
519694
520412
|
path: field("Path"),
|
|
519695
520413
|
branch: field("Branch"),
|
|
519696
520414
|
base: field("Base")
|
|
519697
520415
|
};
|
|
519698
|
-
if (normalized.includes("This conversation's working directory is now the new worktree.")) {
|
|
520416
|
+
if (normalized.includes("This conversation's working directory is now the new worktree.") || normalized.includes("This conversation's working directory is now this worktree.")) {
|
|
519699
520417
|
result.switchedCwd = true;
|
|
519700
520418
|
} else if (normalized.includes("The conversation working directory was left unchanged.")) {
|
|
519701
520419
|
result.switchedCwd = false;
|
|
@@ -519775,7 +520493,7 @@ function EnterWorktreeResultRenderer({
|
|
|
519775
520493
|
flexGrow: 1,
|
|
519776
520494
|
width: contentWidth,
|
|
519777
520495
|
children: /* @__PURE__ */ jsx_dev_runtime79.jsxDEV(Text2, {
|
|
519778
|
-
children: "Created worktree"
|
|
520496
|
+
children: parsed.action === "created" ? "Created worktree" : "Switched to existing worktree"
|
|
519779
520497
|
}, undefined, false, undefined, this)
|
|
519780
520498
|
}, undefined, false, undefined, this)
|
|
519781
520499
|
]
|
|
@@ -520833,7 +521551,7 @@ var init_ToolCallMessageRich = __esm(async () => {
|
|
|
520833
521551
|
let shellSemanticKind = null;
|
|
520834
521552
|
let hasShellDescription = false;
|
|
520835
521553
|
if (!isQuestionTool(rawName)) {
|
|
520836
|
-
const
|
|
521554
|
+
const parseArgs18 = () => {
|
|
520837
521555
|
if (!argsText.trim()) {
|
|
520838
521556
|
return { formatted: null, parseable: true };
|
|
520839
521557
|
}
|
|
@@ -520847,7 +521565,7 @@ var init_ToolCallMessageRich = __esm(async () => {
|
|
|
520847
521565
|
return { formatted: null, parseable: false };
|
|
520848
521566
|
}
|
|
520849
521567
|
};
|
|
520850
|
-
const { formatted, parseable } =
|
|
521568
|
+
const { formatted, parseable } = parseArgs18();
|
|
520851
521569
|
const argsComplete = parseable || line.phase === "running" || line.phase === "finished" || !isStreaming;
|
|
520852
521570
|
if (!argsComplete) {
|
|
520853
521571
|
args = "(…)";
|
|
@@ -522407,9 +523125,9 @@ function getFileEditHeader(toolName, toolArgs) {
|
|
|
522407
523125
|
} else if (operations.length === 1) {
|
|
522408
523126
|
const op = operations[0];
|
|
522409
523127
|
if (op) {
|
|
522410
|
-
const { relative:
|
|
523128
|
+
const { relative: relative18 } = __require("node:path");
|
|
522411
523129
|
const cwd3 = process.cwd();
|
|
522412
|
-
const relPath2 =
|
|
523130
|
+
const relPath2 = relative18(cwd3, op.path);
|
|
522413
523131
|
const displayPath3 = relPath2.startsWith("..") ? op.path : relPath2;
|
|
522414
523132
|
if (op.kind === "add")
|
|
522415
523133
|
return `Write to ${displayPath3}?`;
|
|
@@ -522423,14 +523141,14 @@ function getFileEditHeader(toolName, toolArgs) {
|
|
|
522423
523141
|
return "Apply patch?";
|
|
522424
523142
|
}
|
|
522425
523143
|
const filePath = args.file_path || "";
|
|
522426
|
-
const { relative:
|
|
523144
|
+
const { relative: relative17 } = __require("node:path");
|
|
522427
523145
|
const cwd2 = process.cwd();
|
|
522428
|
-
const relPath =
|
|
523146
|
+
const relPath = relative17(cwd2, filePath);
|
|
522429
523147
|
const displayPath2 = relPath.startsWith("..") ? filePath : relPath;
|
|
522430
523148
|
if (t2 === "write" || t2 === "write_file" || t2 === "writefile" || t2 === "write_file_gemini" || t2 === "writefilegemini") {
|
|
522431
|
-
const { existsSync:
|
|
523149
|
+
const { existsSync: existsSync68 } = __require("node:fs");
|
|
522432
523150
|
try {
|
|
522433
|
-
if (
|
|
523151
|
+
if (existsSync68(filePath)) {
|
|
522434
523152
|
return `Overwrite ${displayPath2}?`;
|
|
522435
523153
|
}
|
|
522436
523154
|
} catch {}
|
|
@@ -522513,9 +523231,9 @@ var init_ApprovalPreview = __esm(async () => {
|
|
|
522513
523231
|
/* @__PURE__ */ jsx_dev_runtime90.jsxDEV(Box_default, {
|
|
522514
523232
|
flexDirection: "column",
|
|
522515
523233
|
children: operations.map((op, idx) => {
|
|
522516
|
-
const { relative:
|
|
523234
|
+
const { relative: relative17 } = __require("node:path");
|
|
522517
523235
|
const cwd2 = process.cwd();
|
|
522518
|
-
const relPath =
|
|
523236
|
+
const relPath = relative17(cwd2, op.path);
|
|
522519
523237
|
const displayPath2 = relPath.startsWith("..") ? op.path : relPath;
|
|
522520
523238
|
const diffKey = toolCallId ? `${toolCallId}:${op.path}` : undefined;
|
|
522521
523239
|
const opDiff = diffKey && allDiffs ? allDiffs.get(diffKey) : undefined;
|
|
@@ -523064,7 +523782,7 @@ function updateCommandResult(buffersRef, refreshDerived, cmdId, input, output, s
|
|
|
523064
523782
|
buffersRef.current.byId.set(cmdId, line);
|
|
523065
523783
|
refreshDerived();
|
|
523066
523784
|
}
|
|
523067
|
-
function
|
|
523785
|
+
function parseArgs18(msg) {
|
|
523068
523786
|
return msg.trim().split(/\s+/).filter(Boolean);
|
|
523069
523787
|
}
|
|
523070
523788
|
function formatConnectUsage() {
|
|
@@ -523419,7 +524137,7 @@ ${formatBedrockUsage2()}`, false);
|
|
|
523419
524137
|
}
|
|
523420
524138
|
}
|
|
523421
524139
|
async function handleConnect(ctx, msg) {
|
|
523422
|
-
const parts =
|
|
524140
|
+
const parts = parseArgs18(msg);
|
|
523423
524141
|
const providerToken = parts[1];
|
|
523424
524142
|
if (!providerToken) {
|
|
523425
524143
|
addCommandResult(ctx.buffersRef, ctx.refreshDerived, msg, formatConnectUsage(), false);
|
|
@@ -537770,9 +538488,9 @@ __export(exports_generate_diff_viewer, {
|
|
|
537770
538488
|
generateAndOpenDiffViewer: () => generateAndOpenDiffViewer
|
|
537771
538489
|
});
|
|
537772
538490
|
import { execFile as execFileCb8 } from "node:child_process";
|
|
537773
|
-
import { chmodSync as chmodSync8, existsSync as
|
|
538491
|
+
import { chmodSync as chmodSync8, existsSync as existsSync68, mkdirSync as mkdirSync48, writeFileSync as writeFileSync37 } from "node:fs";
|
|
537774
538492
|
import { homedir as homedir52 } from "node:os";
|
|
537775
|
-
import { isAbsolute as isAbsolute29, join as
|
|
538493
|
+
import { isAbsolute as isAbsolute29, join as join89, resolve as resolve38 } from "node:path";
|
|
537776
538494
|
import { promisify as promisify18 } from "node:util";
|
|
537777
538495
|
async function runGit8(cwd2, args) {
|
|
537778
538496
|
try {
|
|
@@ -537991,13 +538709,13 @@ async function generateAndOpenDiffViewer(targetPath) {
|
|
|
537991
538709
|
};
|
|
537992
538710
|
const jsonPayload = JSON.stringify(payload).replace(/</g, "\\u003c");
|
|
537993
538711
|
const html5 = diff_viewer_template_default.replace("<!--LETTA_DIFF_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
537994
|
-
if (!
|
|
538712
|
+
if (!existsSync68(VIEWERS_DIR2)) {
|
|
537995
538713
|
mkdirSync48(VIEWERS_DIR2, { recursive: true, mode: 448 });
|
|
537996
538714
|
}
|
|
537997
538715
|
try {
|
|
537998
538716
|
chmodSync8(VIEWERS_DIR2, 448);
|
|
537999
538717
|
} catch {}
|
|
538000
|
-
const filePath =
|
|
538718
|
+
const filePath = join89(VIEWERS_DIR2, `diff-${encodeURIComponent(worktreePath)}.html`);
|
|
538001
538719
|
writeFileSync37(filePath, html5);
|
|
538002
538720
|
chmodSync8(filePath, 384);
|
|
538003
538721
|
const skipOpen = shouldSkipOpen();
|
|
@@ -538068,7 +538786,7 @@ var init_generate_diff_viewer = __esm(() => {
|
|
|
538068
538786
|
init_ssr();
|
|
538069
538787
|
init_diff_viewer_template();
|
|
538070
538788
|
execFile20 = promisify18(execFileCb8);
|
|
538071
|
-
VIEWERS_DIR2 =
|
|
538789
|
+
VIEWERS_DIR2 = join89(homedir52(), ".letta", "viewers");
|
|
538072
538790
|
GIT_MAX_BUFFER = 50 * 1024 * 1024;
|
|
538073
538791
|
});
|
|
538074
538792
|
|
|
@@ -540056,12 +540774,12 @@ __export(exports_shell_aliases, {
|
|
|
540056
540774
|
expandAliases: () => expandAliases,
|
|
540057
540775
|
clearAliasCache: () => clearAliasCache
|
|
540058
540776
|
});
|
|
540059
|
-
import { existsSync as
|
|
540777
|
+
import { existsSync as existsSync69, readFileSync as readFileSync43 } from "node:fs";
|
|
540060
540778
|
import { homedir as homedir53 } from "node:os";
|
|
540061
|
-
import { join as
|
|
540779
|
+
import { join as join90 } from "node:path";
|
|
540062
540780
|
function parseAliasesFromFile(filePath) {
|
|
540063
540781
|
const aliases = new Map;
|
|
540064
|
-
if (!
|
|
540782
|
+
if (!existsSync69(filePath)) {
|
|
540065
540783
|
return aliases;
|
|
540066
540784
|
}
|
|
540067
540785
|
try {
|
|
@@ -540130,7 +540848,7 @@ function loadAliases(forceReload = false) {
|
|
|
540130
540848
|
const home = homedir53();
|
|
540131
540849
|
const allAliases = new Map;
|
|
540132
540850
|
for (const file3 of ALIAS_FILES) {
|
|
540133
|
-
const filePath =
|
|
540851
|
+
const filePath = join90(home, file3);
|
|
540134
540852
|
const fileAliases = parseAliasesFromFile(filePath);
|
|
540135
540853
|
for (const [name, value] of fileAliases) {
|
|
540136
540854
|
allAliases.set(name, value);
|
|
@@ -540312,13 +541030,14 @@ var init_use_bash_handlers = __esm(async () => {
|
|
|
540312
541030
|
|
|
540313
541031
|
// src/cli/app/reflection.ts
|
|
540314
541032
|
function formatReflectionSettings(settings3) {
|
|
541033
|
+
const memoryUpdates = settings3.merge === "explicit" ? "agent reviews before applying" : "apply automatically";
|
|
540315
541034
|
if (settings3.trigger === "off") {
|
|
540316
|
-
return
|
|
541035
|
+
return `Off, ${memoryUpdates}`;
|
|
540317
541036
|
}
|
|
540318
541037
|
if (settings3.trigger === "compaction-event") {
|
|
540319
|
-
return
|
|
541038
|
+
return `On compaction, ${memoryUpdates}`;
|
|
540320
541039
|
}
|
|
540321
|
-
return `
|
|
541040
|
+
return `Every ${settings3.stepCount} steps, ${memoryUpdates}`;
|
|
540322
541041
|
}
|
|
540323
541042
|
|
|
540324
541043
|
// src/cli/app/use-configuration-handlers.ts
|
|
@@ -540472,7 +541191,7 @@ function useConfigurationHandlers(ctx) {
|
|
|
540472
541191
|
const rawReasoningEffort = modelUpdateArgs?.reasoning_effort;
|
|
540473
541192
|
const providerType = providerTypeFromUpdateArgs(modelUpdateArgs);
|
|
540474
541193
|
const isOpenAICompatibleProxy = modelUpdateArgs?.[OPENAI_COMPATIBLE_PROXY_UPDATE_ARG] === true && providerType === "openai";
|
|
540475
|
-
const usesDistinctXHighLabel = /Fable 5|Opus 4\.[78]|GPT-5\.6/.test(model2.label);
|
|
541194
|
+
const usesDistinctXHighLabel = /Fable 5|Opus 4\.[78]|Opus 5|Sonnet 5|GPT-5\.6/.test(model2.label);
|
|
540476
541195
|
const reasoningLevel = isOpenAICompatibleProxy && rawReasoningEffort === null ? "default" : typeof rawReasoningEffort === "string" ? rawReasoningEffort === "none" ? "no" : rawReasoningEffort === "xhigh" ? usesDistinctXHighLabel ? "extra-high" : "max" : rawReasoningEffort : modelUpdateArgs?.enable_reasoner === false ? "no" : null;
|
|
540477
541196
|
const selectedContextWindow = Number(model2.updateArgs?.context_window) || undefined;
|
|
540478
541197
|
const capabilitiesMap = getCachedModelReasoningCapabilities();
|
|
@@ -543840,7 +544559,7 @@ var init_use_queued_approval_submit = __esm(() => {
|
|
|
543840
544559
|
|
|
543841
544560
|
// src/cli/app/use-reasoning-cycle.ts
|
|
543842
544561
|
function supportsDistinctAnthropicXHighEffort2(modelHandle) {
|
|
543843
|
-
return modelHandle.includes("claude-fable-5") || modelHandle.includes("claude-opus-4-7") || modelHandle.includes("claude-opus-4-8");
|
|
544562
|
+
return modelHandle.includes("claude-fable-5") || modelHandle.includes("claude-opus-5") || modelHandle.includes("claude-sonnet-5") || modelHandle.includes("claude-opus-4-7") || modelHandle.includes("claude-opus-4-8");
|
|
543844
544563
|
}
|
|
543845
544564
|
function serviceTierForReasoningCycle(modelHandle, modelSettings) {
|
|
543846
544565
|
if (!getChatGptFastRegistryHandleForModelHandle(modelHandle)) {
|
|
@@ -546424,7 +547143,7 @@ var init_mods2 = __esm(async () => {
|
|
|
546424
547143
|
});
|
|
546425
547144
|
|
|
546426
547145
|
// src/cli/helpers/chdir-command.ts
|
|
546427
|
-
import { realpath as
|
|
547146
|
+
import { realpath as realpath5, stat as stat17 } from "node:fs/promises";
|
|
546428
547147
|
import { homedir as homedir54 } from "node:os";
|
|
546429
547148
|
import path46 from "node:path";
|
|
546430
547149
|
function parseChdirCommand(input) {
|
|
@@ -546462,7 +547181,7 @@ function expandHome(value) {
|
|
|
546462
547181
|
async function resolveChdirTarget(pathArg, currentWorkingDirectory) {
|
|
546463
547182
|
const expanded = expandHome(pathArg);
|
|
546464
547183
|
const resolved = path46.isAbsolute(expanded) ? expanded : path46.resolve(currentWorkingDirectory, expanded);
|
|
546465
|
-
const normalized = await
|
|
547184
|
+
const normalized = await realpath5(resolved);
|
|
546466
547185
|
const stats = await stat17(normalized);
|
|
546467
547186
|
if (!stats.isDirectory()) {
|
|
546468
547187
|
throw new Error(`Not a directory: ${normalized}`);
|
|
@@ -548252,7 +548971,7 @@ __export(exports_export, {
|
|
|
548252
548971
|
packageSkills: () => packageSkills
|
|
548253
548972
|
});
|
|
548254
548973
|
import { readdir as readdir17, readFile as readFile32 } from "node:fs/promises";
|
|
548255
|
-
import { relative as
|
|
548974
|
+
import { relative as relative17, resolve as resolve39 } from "node:path";
|
|
548256
548975
|
async function packageSkills(agentId, skillsDir) {
|
|
548257
548976
|
const skills = [];
|
|
548258
548977
|
const skillNames = new Set;
|
|
@@ -548305,7 +549024,7 @@ async function readSkillFiles(skillDir) {
|
|
|
548305
549024
|
await walk(fullPath);
|
|
548306
549025
|
} else {
|
|
548307
549026
|
const content = await readFile32(fullPath, "utf-8");
|
|
548308
|
-
const relativePath =
|
|
549027
|
+
const relativePath = relative17(skillDir, fullPath).replace(/\\/g, "/");
|
|
548309
549028
|
files[relativePath] = content;
|
|
548310
549029
|
}
|
|
548311
549030
|
}
|
|
@@ -548440,9 +549159,9 @@ var init_conversation_switch_alert = __esm(() => {
|
|
|
548440
549159
|
|
|
548441
549160
|
// src/cli/app/use-submit-handler.ts
|
|
548442
549161
|
import { randomUUID as randomUUID39 } from "node:crypto";
|
|
548443
|
-
import { existsSync as
|
|
549162
|
+
import { existsSync as existsSync70, readFileSync as readFileSync44, renameSync as renameSync8, writeFileSync as writeFileSync38 } from "node:fs";
|
|
548444
549163
|
import { tmpdir as tmpdir12 } from "node:os";
|
|
548445
|
-
import { join as
|
|
549164
|
+
import { join as join91 } from "node:path";
|
|
548446
549165
|
async function findCustomCommandByName(commandName) {
|
|
548447
549166
|
const { findCustomCommand: findCustomCommand2 } = await Promise.resolve().then(() => (init_custom(), exports_custom));
|
|
548448
549167
|
return findCustomCommand2(commandName);
|
|
@@ -549137,10 +549856,10 @@ ${SYSTEM_REMINDER_CLOSE}`),
|
|
|
549137
549856
|
try {
|
|
549138
549857
|
const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
549139
549858
|
const personaCandidates = [
|
|
549140
|
-
|
|
549141
|
-
|
|
549859
|
+
join91(memoryRoot, "system", "persona.md"),
|
|
549860
|
+
join91(memoryRoot, "memory", "system", "persona.md")
|
|
549142
549861
|
];
|
|
549143
|
-
const personaPath = personaCandidates.find((candidate) =>
|
|
549862
|
+
const personaPath = personaCandidates.find((candidate) => existsSync70(candidate));
|
|
549144
549863
|
if (personaPath) {
|
|
549145
549864
|
const personaContent = readFileSync44(personaPath, "utf-8");
|
|
549146
549865
|
setCurrentPersonalityId(detectPersonalityFromPersonaFile(personaContent));
|
|
@@ -549650,8 +550369,7 @@ Tip: Use /clear instead to clear the current message buffer.`;
|
|
|
549650
550369
|
feedbackContext: {
|
|
549651
550370
|
parentAgentName: agentName,
|
|
549652
550371
|
parentAgentDescription: agentDescription,
|
|
549653
|
-
surface: "letta_code_tui"
|
|
549654
|
-
model: currentModelId
|
|
550372
|
+
surface: "letta_code_tui"
|
|
549655
550373
|
},
|
|
549656
550374
|
onReady: (message2, readyRun) => {
|
|
549657
550375
|
appendTaskNotificationEvents([message2]);
|
|
@@ -549669,7 +550387,6 @@ Tip: Use /clear instead to clear the current message buffer.`;
|
|
|
549669
550387
|
conversationId: compactConversationId,
|
|
549670
550388
|
memfsEnabled: isActiveMemfsEnabled(agentId),
|
|
549671
550389
|
triggerSource: "compaction-event",
|
|
549672
|
-
skipPendingWorktreeReminderScan: true,
|
|
549673
550390
|
description: AUTO_REFLECTION_DESCRIPTION,
|
|
549674
550391
|
completionConversationId: () => conversationIdRef.current,
|
|
549675
550392
|
recompileByConversation: systemPromptRecompileByConversationRef.current,
|
|
@@ -549680,8 +550397,7 @@ Tip: Use /clear instead to clear the current message buffer.`;
|
|
|
549680
550397
|
feedbackContext: {
|
|
549681
550398
|
parentAgentName: agentName,
|
|
549682
550399
|
parentAgentDescription: agentDescription,
|
|
549683
|
-
surface: "letta_code_tui"
|
|
549684
|
-
model: currentModelId
|
|
550400
|
+
surface: "letta_code_tui"
|
|
549685
550401
|
}
|
|
549686
550402
|
});
|
|
549687
550403
|
}
|
|
@@ -550020,11 +550736,11 @@ Path: ${memoryDir}`, true);
|
|
|
550020
550736
|
setCommandRunning(true);
|
|
550021
550737
|
try {
|
|
550022
550738
|
const memoryDir = getScopedMemoryFilesystemRoot(agentId);
|
|
550023
|
-
if (!
|
|
550739
|
+
if (!existsSync70(memoryDir)) {
|
|
550024
550740
|
updateMemorySyncCommand(cmdId, "No local memory filesystem found to reset.", true, msg);
|
|
550025
550741
|
return { submitted: true };
|
|
550026
550742
|
}
|
|
550027
|
-
const backupDir =
|
|
550743
|
+
const backupDir = join91(tmpdir12(), `letta-memfs-reset-${agentId}-${Date.now()}`);
|
|
550028
550744
|
renameSync8(memoryDir, backupDir);
|
|
550029
550745
|
if (getBackend().capabilities.localMemfs) {
|
|
550030
550746
|
const { initializeLocalMemoryRepo: initializeLocalMemoryRepo2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
|
|
@@ -550193,8 +550909,7 @@ Resumed reflection arena choice prompt for run ${run2.runId}.`, true);
|
|
|
550193
550909
|
feedbackContext: {
|
|
550194
550910
|
parentAgentName: agentName,
|
|
550195
550911
|
parentAgentDescription: agentDescription,
|
|
550196
|
-
surface: "letta_code_tui"
|
|
550197
|
-
model: currentModelId
|
|
550912
|
+
surface: "letta_code_tui"
|
|
550198
550913
|
},
|
|
550199
550914
|
onReady: (message2, readyRun) => {
|
|
550200
550915
|
appendTaskNotificationEvents([message2]);
|
|
@@ -550242,8 +550957,7 @@ Resumed reflection arena choice prompt for run ${run2.runId}.`, true);
|
|
|
550242
550957
|
feedbackContext: {
|
|
550243
550958
|
parentAgentName: agentName,
|
|
550244
550959
|
parentAgentDescription: agentDescription,
|
|
550245
|
-
surface: "letta_code_tui"
|
|
550246
|
-
model: currentModelId
|
|
550960
|
+
surface: "letta_code_tui"
|
|
550247
550961
|
},
|
|
550248
550962
|
onReady: (message2, readyRun) => {
|
|
550249
550963
|
appendTaskNotificationEvents([message2]);
|
|
@@ -550254,7 +550968,7 @@ Resumed reflection arena choice prompt for run ${run2.runId}.`, true);
|
|
|
550254
550968
|
}
|
|
550255
550969
|
});
|
|
550256
550970
|
if (!arenaResult.launched) {
|
|
550257
|
-
cmd.fail(
|
|
550971
|
+
cmd.fail(getReflectionLaunchSkippedMessage(arenaResult.reason) ?? "Failed to start reflection arena.");
|
|
550258
550972
|
return { submitted: true };
|
|
550259
550973
|
}
|
|
550260
550974
|
cmd.finish(`Started reflection arena run ${arenaResult.run.runId}. View the transcript payload here: ${arenaResult.payloadPath}`, true);
|
|
@@ -550276,17 +550990,13 @@ Resumed reflection arena choice prompt for run ${run2.runId}.`, true);
|
|
|
550276
550990
|
feedbackContext: {
|
|
550277
550991
|
parentAgentName: agentName,
|
|
550278
550992
|
parentAgentDescription: agentDescription,
|
|
550279
|
-
surface: "letta_code_tui"
|
|
550280
|
-
model: currentModelId
|
|
550993
|
+
surface: "letta_code_tui"
|
|
550281
550994
|
}
|
|
550282
550995
|
});
|
|
550283
550996
|
if (!result2.launched) {
|
|
550284
|
-
|
|
550285
|
-
|
|
550286
|
-
|
|
550287
|
-
cmd.fail("No new transcript content to reflect on.");
|
|
550288
|
-
} else if (result2.reason === "memfs_disabled") {
|
|
550289
|
-
cmd.fail("Memory filesystem is not enabled. Use /remember instead.");
|
|
550997
|
+
const skippedMessage = getReflectionLaunchSkippedMessage(result2.reason);
|
|
550998
|
+
if (skippedMessage) {
|
|
550999
|
+
cmd.fail(skippedMessage);
|
|
550290
551000
|
} else {
|
|
550291
551001
|
const errorDetails = formatErrorDetails2(result2.error ?? "Unknown error", agentId);
|
|
550292
551002
|
cmd.fail(`Failed to start reflection agent: ${errorDetails}`);
|
|
@@ -550380,13 +551090,15 @@ Resumed reflection arena choice prompt for run ${run2.runId}.`, true);
|
|
|
550380
551090
|
onComplete: async ({
|
|
550381
551091
|
success: reflectionSuccess,
|
|
550382
551092
|
error: reflectionError,
|
|
550383
|
-
agentId: reflectionAgentId2
|
|
551093
|
+
agentId: reflectionAgentId2,
|
|
551094
|
+
model: reflectionModel
|
|
550384
551095
|
}) => {
|
|
550385
551096
|
try {
|
|
550386
551097
|
telemetry.trackReflectionEnd("manual", reflectionSuccess, {
|
|
550387
551098
|
subagentId: reflectionAgentId2 ?? undefined,
|
|
550388
551099
|
conversationId: reflectionConversationId,
|
|
550389
|
-
error: reflectionError
|
|
551100
|
+
error: reflectionError,
|
|
551101
|
+
model: reflectionModel
|
|
550390
551102
|
});
|
|
550391
551103
|
const { completionSuccess, completionMessage } = await finalizeReflectionMemoryWorktreeLaunch({
|
|
550392
551104
|
worktree: worktree2,
|
|
@@ -550395,6 +551107,9 @@ Resumed reflection arena choice prompt for run ${run2.runId}.`, true);
|
|
|
550395
551107
|
agentId,
|
|
550396
551108
|
conversationId: conversationIdRef.current,
|
|
550397
551109
|
subagentAgentId: reflectionAgentId2 ?? undefined,
|
|
551110
|
+
model: reflectionModel,
|
|
551111
|
+
...getReflectionMergeLaunchOptions(agentId),
|
|
551112
|
+
telemetryContext: { triggerSource: "manual" },
|
|
550398
551113
|
recompileByConversation: systemPromptRecompileByConversationRef.current,
|
|
550399
551114
|
recompileQueuedByConversation: queuedSystemPromptRecompileByConversationRef.current,
|
|
550400
551115
|
logRecompileFailure: (message2) => debugWarn("memory", message2)
|
|
@@ -550470,13 +551185,15 @@ Resumed reflection arena choice prompt for run ${run2.runId}.`, true);
|
|
|
550470
551185
|
onComplete: async ({
|
|
550471
551186
|
success: success2,
|
|
550472
551187
|
error: error54,
|
|
550473
|
-
agentId: reflectionAgentId2
|
|
551188
|
+
agentId: reflectionAgentId2,
|
|
551189
|
+
model: reflectionModel
|
|
550474
551190
|
}) => {
|
|
550475
551191
|
try {
|
|
550476
551192
|
telemetry.trackReflectionEnd("manual", success2, {
|
|
550477
551193
|
subagentId: reflectionAgentId2 ?? undefined,
|
|
550478
551194
|
conversationId: reflectionConversationId,
|
|
550479
|
-
error: error54
|
|
551195
|
+
error: error54,
|
|
551196
|
+
model: reflectionModel
|
|
550480
551197
|
});
|
|
550481
551198
|
const { completionSuccess, completionMessage } = await finalizeReflectionMemoryWorktreeLaunch({
|
|
550482
551199
|
worktree,
|
|
@@ -550485,6 +551202,9 @@ Resumed reflection arena choice prompt for run ${run2.runId}.`, true);
|
|
|
550485
551202
|
agentId,
|
|
550486
551203
|
conversationId: conversationIdRef.current,
|
|
550487
551204
|
subagentAgentId: reflectionAgentId2 ?? undefined,
|
|
551205
|
+
model: reflectionModel,
|
|
551206
|
+
...getReflectionMergeLaunchOptions(agentId),
|
|
551207
|
+
telemetryContext: { triggerSource: "manual" },
|
|
550488
551208
|
recompileByConversation: systemPromptRecompileByConversationRef.current,
|
|
550489
551209
|
recompileQueuedByConversation: queuedSystemPromptRecompileByConversationRef.current,
|
|
550490
551210
|
logRecompileFailure: (message2) => debugWarn("memory", message2)
|
|
@@ -550975,7 +551695,7 @@ var init_use_submit_handler = __esm(async () => {
|
|
|
550975
551695
|
});
|
|
550976
551696
|
|
|
550977
551697
|
// src/cli/app/AppCoordinator.tsx
|
|
550978
|
-
import { join as
|
|
551698
|
+
import { join as join92 } from "node:path";
|
|
550979
551699
|
function buildStartupCommandHints(options3) {
|
|
550980
551700
|
const {
|
|
550981
551701
|
isResumingConversation,
|
|
@@ -552282,7 +553002,7 @@ function App2({
|
|
|
552282
553002
|
agentId: a2.agentId ?? null
|
|
552283
553003
|
}))
|
|
552284
553004
|
});
|
|
552285
|
-
const agentModsDirectory = modContext.memfs.enabled && modContext.memfs.memoryDir ?
|
|
553005
|
+
const agentModsDirectory = modContext.memfs.enabled && modContext.memfs.memoryDir ? join92(modContext.memfs.memoryDir, "mods") : null;
|
|
552286
553006
|
const modAdapter = useLocalModAdapter(modContext, {
|
|
552287
553007
|
agentModsDirectory,
|
|
552288
553008
|
disabled: modsDisabled
|
|
@@ -553060,9 +553780,9 @@ Memory may be stale. Try running: git -C ${getScopedMemoryFilesystemRoot(agentId
|
|
|
553060
553780
|
(async () => {
|
|
553061
553781
|
try {
|
|
553062
553782
|
const { watch: watch3 } = await import("node:fs");
|
|
553063
|
-
const { existsSync:
|
|
553783
|
+
const { existsSync: existsSync71 } = await import("node:fs");
|
|
553064
553784
|
const memRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
553065
|
-
if (!
|
|
553785
|
+
if (!existsSync71(memRoot))
|
|
553066
553786
|
return;
|
|
553067
553787
|
watcher2 = watch3(memRoot, { recursive: true }, () => {});
|
|
553068
553788
|
memfsWatcherRef.current = watcher2;
|
|
@@ -553097,10 +553817,6 @@ Memory may be stale. Try running: git -C ${getScopedMemoryFilesystemRoot(agentId
|
|
|
553097
553817
|
reflectionSettings: reflectionSettings2,
|
|
553098
553818
|
reminderState: sharedReminderStateRef.current,
|
|
553099
553819
|
contextTracker: contextTrackerRef.current,
|
|
553100
|
-
onCompaction: () => queuePendingReflectionWorktreeReminders({
|
|
553101
|
-
agentId: reflectionAgentId,
|
|
553102
|
-
conversationId: conversationIdRef.current ?? "default"
|
|
553103
|
-
}),
|
|
553104
553820
|
launch: async (triggerSource) => {
|
|
553105
553821
|
if (experimentManager.isEnabled("reflection_arena")) {
|
|
553106
553822
|
const arenaResult = await launchReflectionArena({
|
|
@@ -553114,8 +553830,7 @@ Memory may be stale. Try running: git -C ${getScopedMemoryFilesystemRoot(agentId
|
|
|
553114
553830
|
feedbackContext: {
|
|
553115
553831
|
parentAgentName: agentName,
|
|
553116
553832
|
parentAgentDescription: agentDescription,
|
|
553117
|
-
surface: "letta_code_tui"
|
|
553118
|
-
model: currentModelId
|
|
553833
|
+
surface: "letta_code_tui"
|
|
553119
553834
|
},
|
|
553120
553835
|
onReady: (message, readyRun) => {
|
|
553121
553836
|
appendTaskNotificationEvents([message]);
|
|
@@ -553132,7 +553847,6 @@ Memory may be stale. Try running: git -C ${getScopedMemoryFilesystemRoot(agentId
|
|
|
553132
553847
|
conversationId: conversationIdRef.current ?? "default",
|
|
553133
553848
|
memfsEnabled: isActiveMemfsEnabled(reflectionAgentId),
|
|
553134
553849
|
triggerSource,
|
|
553135
|
-
skipPendingWorktreeReminderScan: triggerSource === "compaction-event",
|
|
553136
553850
|
reflectionSettings: reflectionSettings2,
|
|
553137
553851
|
description: AUTO_REFLECTION_DESCRIPTION,
|
|
553138
553852
|
completionConversationId: () => conversationIdRef.current,
|
|
@@ -553144,8 +553858,7 @@ Memory may be stale. Try running: git -C ${getScopedMemoryFilesystemRoot(agentId
|
|
|
553144
553858
|
feedbackContext: {
|
|
553145
553859
|
parentAgentName: agentName,
|
|
553146
553860
|
parentAgentDescription: agentDescription,
|
|
553147
|
-
surface: "letta_code_tui"
|
|
553148
|
-
model: currentModelId
|
|
553861
|
+
surface: "letta_code_tui"
|
|
553149
553862
|
}
|
|
553150
553863
|
});
|
|
553151
553864
|
return result.launched;
|
|
@@ -553154,12 +553867,7 @@ Memory may be stale. Try running: git -C ${getScopedMemoryFilesystemRoot(agentId
|
|
|
553154
553867
|
} catch (error54) {
|
|
553155
553868
|
debugWarn("memory", `Failed to evaluate post-turn reflection: ${error54 instanceof Error ? error54.message : String(error54)}`);
|
|
553156
553869
|
}
|
|
553157
|
-
}, [
|
|
553158
|
-
agentName,
|
|
553159
|
-
agentDescription,
|
|
553160
|
-
currentModelId,
|
|
553161
|
-
appendTaskNotificationEvents
|
|
553162
|
-
]);
|
|
553870
|
+
}, [agentName, agentDescription, appendTaskNotificationEvents]);
|
|
553163
553871
|
const processConversation = useConversationLoop({
|
|
553164
553872
|
abortControllerRef,
|
|
553165
553873
|
agentIdRef,
|
|
@@ -554640,12 +555348,12 @@ EXAMPLES
|
|
|
554640
555348
|
console.log(usage);
|
|
554641
555349
|
}
|
|
554642
555350
|
async function printInfo() {
|
|
554643
|
-
const { join:
|
|
555351
|
+
const { join: join93 } = await import("node:path");
|
|
554644
555352
|
const { getVersion: getVersion2 } = await Promise.resolve().then(() => (init_version(), exports_version));
|
|
554645
555353
|
const { SKILLS_DIR: SKILLS_DIR2 } = await Promise.resolve().then(() => (init_skills3(), exports_skills2));
|
|
554646
555354
|
const { exists: exists2 } = await Promise.resolve().then(() => (init_fs(), exports_fs));
|
|
554647
555355
|
const cwd2 = process.cwd();
|
|
554648
|
-
const skillsDir =
|
|
555356
|
+
const skillsDir = join93(cwd2, SKILLS_DIR2);
|
|
554649
555357
|
const skillsExist = exists2(skillsDir);
|
|
554650
555358
|
await settingsManager.loadLocalProjectSettings(cwd2);
|
|
554651
555359
|
const pinned = settingsManager.getPinnedAgents();
|
|
@@ -555099,40 +555807,18 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
555099
555807
|
}
|
|
555100
555808
|
}
|
|
555101
555809
|
try {
|
|
555102
|
-
|
|
555103
|
-
|
|
555104
|
-
|
|
555105
|
-
|
|
555106
|
-
|
|
555107
|
-
|
|
555108
|
-
|
|
555109
|
-
|
|
555110
|
-
|
|
555111
|
-
|
|
555112
|
-
|
|
555113
|
-
|
|
555114
|
-
when: forceNew,
|
|
555115
|
-
message: "--conversation cannot be used with --new-agent"
|
|
555116
|
-
},
|
|
555117
|
-
{
|
|
555118
|
-
when: fromAfFile,
|
|
555119
|
-
message: "--conversation cannot be used with --import"
|
|
555120
|
-
},
|
|
555121
|
-
{
|
|
555122
|
-
when: shouldResume,
|
|
555123
|
-
message: "--conversation cannot be used with --resume"
|
|
555124
|
-
}
|
|
555125
|
-
]
|
|
555126
|
-
});
|
|
555127
|
-
validateFlagConflicts({
|
|
555128
|
-
guard: forceNewConversation,
|
|
555129
|
-
checks: [
|
|
555130
|
-
{
|
|
555131
|
-
when: specifiedConversationId,
|
|
555132
|
-
message: "--new cannot be used with --conversation"
|
|
555133
|
-
},
|
|
555134
|
-
{ when: shouldResume, message: "--new cannot be used with --resume" }
|
|
555135
|
-
]
|
|
555810
|
+
validatePrimaryStartupFlagConflicts({
|
|
555811
|
+
specifiedConversationId,
|
|
555812
|
+
specifiedAgentId,
|
|
555813
|
+
specifiedAgentName,
|
|
555814
|
+
forceNewAgent: forceNew,
|
|
555815
|
+
forceNewConversation,
|
|
555816
|
+
importFile: fromAfFile,
|
|
555817
|
+
shouldResume,
|
|
555818
|
+
stateless: values2.stateless,
|
|
555819
|
+
isHeadless,
|
|
555820
|
+
memfs: memfsFlag,
|
|
555821
|
+
memfsStartup: values2["memfs-startup"]
|
|
555136
555822
|
});
|
|
555137
555823
|
} catch (error54) {
|
|
555138
555824
|
console.error(error54 instanceof Error ? `Error: ${error54.message}` : String(error54));
|
|
@@ -555176,9 +555862,9 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
555176
555862
|
}
|
|
555177
555863
|
} else {
|
|
555178
555864
|
const { resolve: resolve40 } = await import("node:path");
|
|
555179
|
-
const { existsSync:
|
|
555865
|
+
const { existsSync: existsSync71 } = await import("node:fs");
|
|
555180
555866
|
const resolvedPath = resolve40(fromAfFile);
|
|
555181
|
-
if (!
|
|
555867
|
+
if (!existsSync71(resolvedPath)) {
|
|
555182
555868
|
console.error(`Error: AgentFile not found: ${resolvedPath}`);
|
|
555183
555869
|
process.exit(1);
|
|
555184
555870
|
}
|
|
@@ -558301,4 +558987,4 @@ function registerBunOAuthFlows() {
|
|
|
558301
558987
|
registerBunOAuthFlows();
|
|
558302
558988
|
await init_src5().then(() => exports_src2);
|
|
558303
558989
|
|
|
558304
|
-
//# debugId=
|
|
558990
|
+
//# debugId=AF6DD74653AB022F64756E2164756E21
|