@letta-ai/letta-code 0.27.7 → 0.27.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/letta.js +1095 -534
- package/package.json +2 -1
- package/scripts/check-bundled-skill-scripts.js +169 -0
- package/scripts/check.js +1 -0
- package/skills/converting-mcps-to-skills/SKILL.md +1 -12
- package/skills/converting-mcps-to-skills/scripts/mcp-stdio.ts +192 -57
- package/skills/creating-extensions/references/plan-mode.md +63 -24
- package/skills/creating-skills/scripts/validate-skill.ts +129 -5
- package/skills/image-generation/SKILL.md +110 -0
- package/skills/converting-mcps-to-skills/scripts/package.json +0 -13
package/letta.js
CHANGED
|
@@ -5087,7 +5087,7 @@ var package_default;
|
|
|
5087
5087
|
var init_package = __esm(() => {
|
|
5088
5088
|
package_default = {
|
|
5089
5089
|
name: "@letta-ai/letta-code",
|
|
5090
|
-
version: "0.27.
|
|
5090
|
+
version: "0.27.8",
|
|
5091
5091
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
5092
5092
|
type: "module",
|
|
5093
5093
|
packageManager: "bun@1.3.0",
|
|
@@ -5168,6 +5168,7 @@ var init_package = __esm(() => {
|
|
|
5168
5168
|
"check:filename-casing": "node scripts/check-filename-casing.js",
|
|
5169
5169
|
"check:test-mock-isolation": "bun run scripts/check-test-mock-isolation.js",
|
|
5170
5170
|
"check:test-coverage": "node scripts/check-test-coverage.cjs",
|
|
5171
|
+
"check:bundled-skill-scripts": "node scripts/check-bundled-skill-scripts.js",
|
|
5171
5172
|
check: "bun run scripts/check.js",
|
|
5172
5173
|
dev: "LETTA_DEBUG=${LETTA_DEBUG:-1} LETTA_RESPONSES_WS=${LETTA_RESPONSES_WS:-1} bun --loader=.md:text --loader=.mdx:text --loader=.txt:text run src/index.ts",
|
|
5173
5174
|
build: "node scripts/postinstall-patches.js && bun run build.js",
|
|
@@ -144416,20 +144417,19 @@ var init_models7 = __esm(() => {
|
|
|
144416
144417
|
handle: "letta/auto",
|
|
144417
144418
|
label: "Auto",
|
|
144418
144419
|
description: "Automatically select the best model",
|
|
144419
|
-
isFeatured: true,
|
|
144420
144420
|
free: true,
|
|
144421
144421
|
updateArgs: {
|
|
144422
144422
|
context_window: 140000,
|
|
144423
144423
|
max_output_tokens: 28000,
|
|
144424
144424
|
parallel_tool_calls: true
|
|
144425
|
-
}
|
|
144425
|
+
},
|
|
144426
|
+
isFeatured: true
|
|
144426
144427
|
},
|
|
144427
144428
|
{
|
|
144428
144429
|
id: "auto-fast",
|
|
144429
144430
|
handle: "letta/auto-fast",
|
|
144430
144431
|
label: "Auto Fast",
|
|
144431
144432
|
description: "Automatically select the best fast model",
|
|
144432
|
-
isFeatured: true,
|
|
144433
144433
|
free: true,
|
|
144434
144434
|
updateArgs: {
|
|
144435
144435
|
context_window: 140000,
|
|
@@ -144442,19 +144442,303 @@ var init_models7 = __esm(() => {
|
|
|
144442
144442
|
handle: "letta/auto-chat",
|
|
144443
144443
|
label: "Auto Chat",
|
|
144444
144444
|
description: "Automatically select the best model for chat",
|
|
144445
|
-
isFeatured: true,
|
|
144446
144445
|
free: true,
|
|
144447
144446
|
updateArgs: {
|
|
144448
144447
|
context_window: 140000,
|
|
144449
144448
|
max_output_tokens: 28000,
|
|
144450
144449
|
parallel_tool_calls: true
|
|
144450
|
+
},
|
|
144451
|
+
isFeatured: true
|
|
144452
|
+
},
|
|
144453
|
+
{
|
|
144454
|
+
id: "fable",
|
|
144455
|
+
handle: "anthropic/claude-fable-5",
|
|
144456
|
+
label: "Fable 5",
|
|
144457
|
+
description: "Fable 5 (high reasoning)",
|
|
144458
|
+
isFeatured: true,
|
|
144459
|
+
updateArgs: {
|
|
144460
|
+
context_window: 1e6,
|
|
144461
|
+
max_output_tokens: 128000,
|
|
144462
|
+
enable_reasoner: true,
|
|
144463
|
+
reasoning_effort: "high",
|
|
144464
|
+
parallel_tool_calls: true
|
|
144465
|
+
}
|
|
144466
|
+
},
|
|
144467
|
+
{
|
|
144468
|
+
id: "fable-low",
|
|
144469
|
+
handle: "anthropic/claude-fable-5",
|
|
144470
|
+
label: "Fable 5",
|
|
144471
|
+
description: "Fable 5 (low reasoning)",
|
|
144472
|
+
updateArgs: {
|
|
144473
|
+
context_window: 1e6,
|
|
144474
|
+
max_output_tokens: 128000,
|
|
144475
|
+
enable_reasoner: true,
|
|
144476
|
+
reasoning_effort: "low",
|
|
144477
|
+
max_reasoning_tokens: 4000,
|
|
144478
|
+
parallel_tool_calls: true
|
|
144479
|
+
}
|
|
144480
|
+
},
|
|
144481
|
+
{
|
|
144482
|
+
id: "fable-medium",
|
|
144483
|
+
handle: "anthropic/claude-fable-5",
|
|
144484
|
+
label: "Fable 5",
|
|
144485
|
+
description: "Fable 5 (med reasoning)",
|
|
144486
|
+
updateArgs: {
|
|
144487
|
+
context_window: 1e6,
|
|
144488
|
+
max_output_tokens: 128000,
|
|
144489
|
+
enable_reasoner: true,
|
|
144490
|
+
reasoning_effort: "medium",
|
|
144491
|
+
max_reasoning_tokens: 12000,
|
|
144492
|
+
parallel_tool_calls: true
|
|
144493
|
+
}
|
|
144494
|
+
},
|
|
144495
|
+
{
|
|
144496
|
+
id: "fable-xhigh",
|
|
144497
|
+
handle: "anthropic/claude-fable-5",
|
|
144498
|
+
label: "Fable 5",
|
|
144499
|
+
description: "Fable 5 (extra-high reasoning)",
|
|
144500
|
+
updateArgs: {
|
|
144501
|
+
context_window: 1e6,
|
|
144502
|
+
max_output_tokens: 128000,
|
|
144503
|
+
enable_reasoner: true,
|
|
144504
|
+
reasoning_effort: "xhigh",
|
|
144505
|
+
parallel_tool_calls: true
|
|
144506
|
+
}
|
|
144507
|
+
},
|
|
144508
|
+
{
|
|
144509
|
+
id: "fable-max",
|
|
144510
|
+
handle: "anthropic/claude-fable-5",
|
|
144511
|
+
label: "Fable 5",
|
|
144512
|
+
description: "Fable 5 (max reasoning)",
|
|
144513
|
+
updateArgs: {
|
|
144514
|
+
context_window: 1e6,
|
|
144515
|
+
max_output_tokens: 128000,
|
|
144516
|
+
enable_reasoner: true,
|
|
144517
|
+
reasoning_effort: "max",
|
|
144518
|
+
parallel_tool_calls: true
|
|
144519
|
+
}
|
|
144520
|
+
},
|
|
144521
|
+
{
|
|
144522
|
+
id: "opus",
|
|
144523
|
+
handle: "anthropic/claude-opus-4-8",
|
|
144524
|
+
label: "Opus 4.8",
|
|
144525
|
+
description: "Opus 4.8 (high reasoning)",
|
|
144526
|
+
isFeatured: true,
|
|
144527
|
+
updateArgs: {
|
|
144528
|
+
context_window: 200000,
|
|
144529
|
+
max_output_tokens: 128000,
|
|
144530
|
+
reasoning_effort: "high",
|
|
144531
|
+
enable_reasoner: true,
|
|
144532
|
+
parallel_tool_calls: true
|
|
144533
|
+
}
|
|
144534
|
+
},
|
|
144535
|
+
{
|
|
144536
|
+
id: "opus-4.8-low",
|
|
144537
|
+
handle: "anthropic/claude-opus-4-8",
|
|
144538
|
+
label: "Opus 4.8",
|
|
144539
|
+
description: "Opus 4.8 (low reasoning)",
|
|
144540
|
+
updateArgs: {
|
|
144541
|
+
context_window: 200000,
|
|
144542
|
+
max_output_tokens: 128000,
|
|
144543
|
+
reasoning_effort: "low",
|
|
144544
|
+
enable_reasoner: true,
|
|
144545
|
+
max_reasoning_tokens: 4000,
|
|
144546
|
+
parallel_tool_calls: true
|
|
144547
|
+
}
|
|
144548
|
+
},
|
|
144549
|
+
{
|
|
144550
|
+
id: "opus-4.8-medium",
|
|
144551
|
+
handle: "anthropic/claude-opus-4-8",
|
|
144552
|
+
label: "Opus 4.8",
|
|
144553
|
+
description: "Opus 4.8 (med reasoning)",
|
|
144554
|
+
updateArgs: {
|
|
144555
|
+
context_window: 200000,
|
|
144556
|
+
max_output_tokens: 128000,
|
|
144557
|
+
reasoning_effort: "medium",
|
|
144558
|
+
enable_reasoner: true,
|
|
144559
|
+
max_reasoning_tokens: 12000,
|
|
144560
|
+
parallel_tool_calls: true
|
|
144561
|
+
}
|
|
144562
|
+
},
|
|
144563
|
+
{
|
|
144564
|
+
id: "opus-4.8-high",
|
|
144565
|
+
handle: "anthropic/claude-opus-4-8",
|
|
144566
|
+
label: "Opus 4.8",
|
|
144567
|
+
description: "Opus 4.8 (high reasoning)",
|
|
144568
|
+
updateArgs: {
|
|
144569
|
+
context_window: 200000,
|
|
144570
|
+
max_output_tokens: 128000,
|
|
144571
|
+
reasoning_effort: "high",
|
|
144572
|
+
enable_reasoner: true,
|
|
144573
|
+
parallel_tool_calls: true
|
|
144574
|
+
}
|
|
144575
|
+
},
|
|
144576
|
+
{
|
|
144577
|
+
id: "opus-4.8-xhigh",
|
|
144578
|
+
handle: "anthropic/claude-opus-4-8",
|
|
144579
|
+
label: "Opus 4.8",
|
|
144580
|
+
description: "Opus 4.8 (extra-high reasoning)",
|
|
144581
|
+
updateArgs: {
|
|
144582
|
+
context_window: 200000,
|
|
144583
|
+
max_output_tokens: 128000,
|
|
144584
|
+
reasoning_effort: "xhigh",
|
|
144585
|
+
enable_reasoner: true,
|
|
144586
|
+
parallel_tool_calls: true
|
|
144587
|
+
}
|
|
144588
|
+
},
|
|
144589
|
+
{
|
|
144590
|
+
id: "opus-4.8-max",
|
|
144591
|
+
handle: "anthropic/claude-opus-4-8",
|
|
144592
|
+
label: "Opus 4.8",
|
|
144593
|
+
description: "Opus 4.8 (max reasoning)",
|
|
144594
|
+
updateArgs: {
|
|
144595
|
+
context_window: 200000,
|
|
144596
|
+
max_output_tokens: 128000,
|
|
144597
|
+
reasoning_effort: "max",
|
|
144598
|
+
enable_reasoner: true,
|
|
144599
|
+
parallel_tool_calls: true
|
|
144600
|
+
}
|
|
144601
|
+
},
|
|
144602
|
+
{
|
|
144603
|
+
id: "opus-4.8-1m",
|
|
144604
|
+
handle: "anthropic/claude-opus-4-8",
|
|
144605
|
+
label: "Opus 4.8 1M",
|
|
144606
|
+
description: "Claude Opus 4.8 with 1M token context window (high reasoning)",
|
|
144607
|
+
updateArgs: {
|
|
144608
|
+
context_window: 950000,
|
|
144609
|
+
max_output_tokens: 128000,
|
|
144610
|
+
reasoning_effort: "high",
|
|
144611
|
+
enable_reasoner: true,
|
|
144612
|
+
parallel_tool_calls: true
|
|
144613
|
+
},
|
|
144614
|
+
isFeatured: true
|
|
144615
|
+
},
|
|
144616
|
+
{
|
|
144617
|
+
id: "opus-4.8-1m-no-reasoning",
|
|
144618
|
+
handle: "anthropic/claude-opus-4-8",
|
|
144619
|
+
label: "Opus 4.8 1M",
|
|
144620
|
+
description: "Opus 4.8 1M with no reasoning (faster)",
|
|
144621
|
+
updateArgs: {
|
|
144622
|
+
context_window: 950000,
|
|
144623
|
+
max_output_tokens: 128000,
|
|
144624
|
+
reasoning_effort: "none",
|
|
144625
|
+
enable_reasoner: false,
|
|
144626
|
+
parallel_tool_calls: true
|
|
144627
|
+
}
|
|
144628
|
+
},
|
|
144629
|
+
{
|
|
144630
|
+
id: "opus-4.8-1m-low",
|
|
144631
|
+
handle: "anthropic/claude-opus-4-8",
|
|
144632
|
+
label: "Opus 4.8 1M",
|
|
144633
|
+
description: "Opus 4.8 1M (low reasoning)",
|
|
144634
|
+
updateArgs: {
|
|
144635
|
+
context_window: 950000,
|
|
144636
|
+
max_output_tokens: 128000,
|
|
144637
|
+
reasoning_effort: "low",
|
|
144638
|
+
enable_reasoner: true,
|
|
144639
|
+
parallel_tool_calls: true,
|
|
144640
|
+
max_reasoning_tokens: 4000
|
|
144641
|
+
}
|
|
144642
|
+
},
|
|
144643
|
+
{
|
|
144644
|
+
id: "opus-4.8-1m-medium",
|
|
144645
|
+
handle: "anthropic/claude-opus-4-8",
|
|
144646
|
+
label: "Opus 4.8 1M",
|
|
144647
|
+
description: "Opus 4.8 1M (med reasoning)",
|
|
144648
|
+
updateArgs: {
|
|
144649
|
+
context_window: 950000,
|
|
144650
|
+
max_output_tokens: 128000,
|
|
144651
|
+
reasoning_effort: "medium",
|
|
144652
|
+
enable_reasoner: true,
|
|
144653
|
+
parallel_tool_calls: true,
|
|
144654
|
+
max_reasoning_tokens: 12000
|
|
144655
|
+
}
|
|
144656
|
+
},
|
|
144657
|
+
{
|
|
144658
|
+
id: "opus-4.8-1m-xhigh",
|
|
144659
|
+
handle: "anthropic/claude-opus-4-8",
|
|
144660
|
+
label: "Opus 4.8 1M",
|
|
144661
|
+
description: "Opus 4.8 1M (max reasoning)",
|
|
144662
|
+
updateArgs: {
|
|
144663
|
+
context_window: 950000,
|
|
144664
|
+
max_output_tokens: 128000,
|
|
144665
|
+
reasoning_effort: "xhigh",
|
|
144666
|
+
enable_reasoner: true,
|
|
144667
|
+
parallel_tool_calls: true
|
|
144668
|
+
}
|
|
144669
|
+
},
|
|
144670
|
+
{
|
|
144671
|
+
id: "opus-1m",
|
|
144672
|
+
handle: "anthropic/claude-opus-4-6",
|
|
144673
|
+
label: "Opus 4.6 1M",
|
|
144674
|
+
description: "Claude Opus 4.6 with 1M token context window (high reasoning)",
|
|
144675
|
+
updateArgs: {
|
|
144676
|
+
context_window: 950000,
|
|
144677
|
+
max_output_tokens: 128000,
|
|
144678
|
+
reasoning_effort: "high",
|
|
144679
|
+
enable_reasoner: true,
|
|
144680
|
+
parallel_tool_calls: true
|
|
144681
|
+
}
|
|
144682
|
+
},
|
|
144683
|
+
{
|
|
144684
|
+
id: "opus-1m-no-reasoning",
|
|
144685
|
+
handle: "anthropic/claude-opus-4-6",
|
|
144686
|
+
label: "Opus 4.6 1M",
|
|
144687
|
+
description: "Opus 4.6 1M with no reasoning (faster)",
|
|
144688
|
+
updateArgs: {
|
|
144689
|
+
context_window: 950000,
|
|
144690
|
+
max_output_tokens: 128000,
|
|
144691
|
+
reasoning_effort: "none",
|
|
144692
|
+
enable_reasoner: false,
|
|
144693
|
+
parallel_tool_calls: true
|
|
144694
|
+
}
|
|
144695
|
+
},
|
|
144696
|
+
{
|
|
144697
|
+
id: "opus-1m-low",
|
|
144698
|
+
handle: "anthropic/claude-opus-4-6",
|
|
144699
|
+
label: "Opus 4.6 1M",
|
|
144700
|
+
description: "Opus 4.6 1M (low reasoning)",
|
|
144701
|
+
updateArgs: {
|
|
144702
|
+
context_window: 950000,
|
|
144703
|
+
max_output_tokens: 128000,
|
|
144704
|
+
reasoning_effort: "low",
|
|
144705
|
+
enable_reasoner: true,
|
|
144706
|
+
max_reasoning_tokens: 4000,
|
|
144707
|
+
parallel_tool_calls: true
|
|
144708
|
+
}
|
|
144709
|
+
},
|
|
144710
|
+
{
|
|
144711
|
+
id: "opus-1m-medium",
|
|
144712
|
+
handle: "anthropic/claude-opus-4-6",
|
|
144713
|
+
label: "Opus 4.6 1M",
|
|
144714
|
+
description: "Opus 4.6 1M (med reasoning)",
|
|
144715
|
+
updateArgs: {
|
|
144716
|
+
context_window: 950000,
|
|
144717
|
+
max_output_tokens: 128000,
|
|
144718
|
+
reasoning_effort: "medium",
|
|
144719
|
+
enable_reasoner: true,
|
|
144720
|
+
max_reasoning_tokens: 12000,
|
|
144721
|
+
parallel_tool_calls: true
|
|
144722
|
+
}
|
|
144723
|
+
},
|
|
144724
|
+
{
|
|
144725
|
+
id: "opus-1m-xhigh",
|
|
144726
|
+
handle: "anthropic/claude-opus-4-6",
|
|
144727
|
+
label: "Opus 4.6 1M",
|
|
144728
|
+
description: "Opus 4.6 1M (max reasoning)",
|
|
144729
|
+
updateArgs: {
|
|
144730
|
+
context_window: 950000,
|
|
144731
|
+
max_output_tokens: 128000,
|
|
144732
|
+
reasoning_effort: "xhigh",
|
|
144733
|
+
enable_reasoner: true,
|
|
144734
|
+
parallel_tool_calls: true
|
|
144451
144735
|
}
|
|
144452
144736
|
},
|
|
144453
144737
|
{
|
|
144454
144738
|
id: "sonnet",
|
|
144455
144739
|
handle: "anthropic/claude-sonnet-4-6",
|
|
144456
144740
|
label: "Sonnet 4.6",
|
|
144457
|
-
description: "
|
|
144741
|
+
description: "Sonnet 4.6 (high reasoning)",
|
|
144458
144742
|
isFeatured: true,
|
|
144459
144743
|
updateArgs: {
|
|
144460
144744
|
context_window: 200000,
|
|
@@ -144590,8 +144874,7 @@ var init_models7 = __esm(() => {
|
|
|
144590
144874
|
id: "opus-4.6-high",
|
|
144591
144875
|
handle: "anthropic/claude-opus-4-6",
|
|
144592
144876
|
label: "Opus 4.6",
|
|
144593
|
-
description: "
|
|
144594
|
-
isFeatured: true,
|
|
144877
|
+
description: "Opus 4.6 (high reasoning)",
|
|
144595
144878
|
updateArgs: {
|
|
144596
144879
|
context_window: 200000,
|
|
144597
144880
|
max_output_tokens: 128000,
|
|
@@ -144654,87 +144937,6 @@ var init_models7 = __esm(() => {
|
|
|
144654
144937
|
parallel_tool_calls: true
|
|
144655
144938
|
}
|
|
144656
144939
|
},
|
|
144657
|
-
{
|
|
144658
|
-
id: "opus",
|
|
144659
|
-
handle: "anthropic/claude-opus-4-8",
|
|
144660
|
-
label: "Opus 4.8",
|
|
144661
|
-
description: "Anthropic's best model (high reasoning)",
|
|
144662
|
-
isFeatured: true,
|
|
144663
|
-
updateArgs: {
|
|
144664
|
-
context_window: 200000,
|
|
144665
|
-
max_output_tokens: 128000,
|
|
144666
|
-
reasoning_effort: "high",
|
|
144667
|
-
enable_reasoner: true,
|
|
144668
|
-
parallel_tool_calls: true
|
|
144669
|
-
}
|
|
144670
|
-
},
|
|
144671
|
-
{
|
|
144672
|
-
id: "opus-4.8-low",
|
|
144673
|
-
handle: "anthropic/claude-opus-4-8",
|
|
144674
|
-
label: "Opus 4.8",
|
|
144675
|
-
description: "Opus 4.8 (low reasoning)",
|
|
144676
|
-
updateArgs: {
|
|
144677
|
-
context_window: 200000,
|
|
144678
|
-
max_output_tokens: 128000,
|
|
144679
|
-
reasoning_effort: "low",
|
|
144680
|
-
enable_reasoner: true,
|
|
144681
|
-
max_reasoning_tokens: 4000,
|
|
144682
|
-
parallel_tool_calls: true
|
|
144683
|
-
}
|
|
144684
|
-
},
|
|
144685
|
-
{
|
|
144686
|
-
id: "opus-4.8-medium",
|
|
144687
|
-
handle: "anthropic/claude-opus-4-8",
|
|
144688
|
-
label: "Opus 4.8",
|
|
144689
|
-
description: "Opus 4.8 (med reasoning)",
|
|
144690
|
-
updateArgs: {
|
|
144691
|
-
context_window: 200000,
|
|
144692
|
-
max_output_tokens: 128000,
|
|
144693
|
-
reasoning_effort: "medium",
|
|
144694
|
-
enable_reasoner: true,
|
|
144695
|
-
max_reasoning_tokens: 12000,
|
|
144696
|
-
parallel_tool_calls: true
|
|
144697
|
-
}
|
|
144698
|
-
},
|
|
144699
|
-
{
|
|
144700
|
-
id: "opus-4.8-high",
|
|
144701
|
-
handle: "anthropic/claude-opus-4-8",
|
|
144702
|
-
label: "Opus 4.8",
|
|
144703
|
-
description: "Opus 4.8 (high reasoning)",
|
|
144704
|
-
updateArgs: {
|
|
144705
|
-
context_window: 200000,
|
|
144706
|
-
max_output_tokens: 128000,
|
|
144707
|
-
reasoning_effort: "high",
|
|
144708
|
-
enable_reasoner: true,
|
|
144709
|
-
parallel_tool_calls: true
|
|
144710
|
-
}
|
|
144711
|
-
},
|
|
144712
|
-
{
|
|
144713
|
-
id: "opus-4.8-xhigh",
|
|
144714
|
-
handle: "anthropic/claude-opus-4-8",
|
|
144715
|
-
label: "Opus 4.8",
|
|
144716
|
-
description: "Opus 4.8 (extra-high reasoning)",
|
|
144717
|
-
updateArgs: {
|
|
144718
|
-
context_window: 200000,
|
|
144719
|
-
max_output_tokens: 128000,
|
|
144720
|
-
reasoning_effort: "xhigh",
|
|
144721
|
-
enable_reasoner: true,
|
|
144722
|
-
parallel_tool_calls: true
|
|
144723
|
-
}
|
|
144724
|
-
},
|
|
144725
|
-
{
|
|
144726
|
-
id: "opus-4.8-max",
|
|
144727
|
-
handle: "anthropic/claude-opus-4-8",
|
|
144728
|
-
label: "Opus 4.8",
|
|
144729
|
-
description: "Opus 4.8 (max reasoning)",
|
|
144730
|
-
updateArgs: {
|
|
144731
|
-
context_window: 200000,
|
|
144732
|
-
max_output_tokens: 128000,
|
|
144733
|
-
reasoning_effort: "max",
|
|
144734
|
-
enable_reasoner: true,
|
|
144735
|
-
parallel_tool_calls: true
|
|
144736
|
-
}
|
|
144737
|
-
},
|
|
144738
144940
|
{
|
|
144739
144941
|
id: "opus-4.7-medium",
|
|
144740
144942
|
handle: "anthropic/claude-opus-4-7",
|
|
@@ -144802,79 +145004,11 @@ var init_models7 = __esm(() => {
|
|
|
144802
145004
|
parallel_tool_calls: true
|
|
144803
145005
|
}
|
|
144804
145006
|
},
|
|
144805
|
-
{
|
|
144806
|
-
id: "opus-1m",
|
|
144807
|
-
handle: "anthropic/claude-opus-4-6",
|
|
144808
|
-
label: "Opus 4.6 1M",
|
|
144809
|
-
description: "Claude Opus 4.6 with 1M token context window (high reasoning)",
|
|
144810
|
-
isFeatured: true,
|
|
144811
|
-
updateArgs: {
|
|
144812
|
-
context_window: 950000,
|
|
144813
|
-
max_output_tokens: 128000,
|
|
144814
|
-
reasoning_effort: "high",
|
|
144815
|
-
enable_reasoner: true,
|
|
144816
|
-
parallel_tool_calls: true
|
|
144817
|
-
}
|
|
144818
|
-
},
|
|
144819
|
-
{
|
|
144820
|
-
id: "opus-1m-no-reasoning",
|
|
144821
|
-
handle: "anthropic/claude-opus-4-6",
|
|
144822
|
-
label: "Opus 4.6 1M",
|
|
144823
|
-
description: "Opus 4.6 1M with no reasoning (faster)",
|
|
144824
|
-
updateArgs: {
|
|
144825
|
-
context_window: 950000,
|
|
144826
|
-
max_output_tokens: 128000,
|
|
144827
|
-
reasoning_effort: "none",
|
|
144828
|
-
enable_reasoner: false,
|
|
144829
|
-
parallel_tool_calls: true
|
|
144830
|
-
}
|
|
144831
|
-
},
|
|
144832
|
-
{
|
|
144833
|
-
id: "opus-1m-low",
|
|
144834
|
-
handle: "anthropic/claude-opus-4-6",
|
|
144835
|
-
label: "Opus 4.6 1M",
|
|
144836
|
-
description: "Opus 4.6 1M (low reasoning)",
|
|
144837
|
-
updateArgs: {
|
|
144838
|
-
context_window: 950000,
|
|
144839
|
-
max_output_tokens: 128000,
|
|
144840
|
-
reasoning_effort: "low",
|
|
144841
|
-
enable_reasoner: true,
|
|
144842
|
-
max_reasoning_tokens: 4000,
|
|
144843
|
-
parallel_tool_calls: true
|
|
144844
|
-
}
|
|
144845
|
-
},
|
|
144846
|
-
{
|
|
144847
|
-
id: "opus-1m-medium",
|
|
144848
|
-
handle: "anthropic/claude-opus-4-6",
|
|
144849
|
-
label: "Opus 4.6 1M",
|
|
144850
|
-
description: "Opus 4.6 1M (med reasoning)",
|
|
144851
|
-
updateArgs: {
|
|
144852
|
-
context_window: 950000,
|
|
144853
|
-
max_output_tokens: 128000,
|
|
144854
|
-
reasoning_effort: "medium",
|
|
144855
|
-
enable_reasoner: true,
|
|
144856
|
-
max_reasoning_tokens: 12000,
|
|
144857
|
-
parallel_tool_calls: true
|
|
144858
|
-
}
|
|
144859
|
-
},
|
|
144860
|
-
{
|
|
144861
|
-
id: "opus-1m-xhigh",
|
|
144862
|
-
handle: "anthropic/claude-opus-4-6",
|
|
144863
|
-
label: "Opus 4.6 1M",
|
|
144864
|
-
description: "Opus 4.6 1M (max reasoning)",
|
|
144865
|
-
updateArgs: {
|
|
144866
|
-
context_window: 950000,
|
|
144867
|
-
max_output_tokens: 128000,
|
|
144868
|
-
reasoning_effort: "xhigh",
|
|
144869
|
-
enable_reasoner: true,
|
|
144870
|
-
parallel_tool_calls: true
|
|
144871
|
-
}
|
|
144872
|
-
},
|
|
144873
145007
|
{
|
|
144874
145008
|
id: "opus-4.5",
|
|
144875
145009
|
handle: "anthropic/claude-opus-4-5-20251101",
|
|
144876
145010
|
label: "Opus 4.5",
|
|
144877
|
-
description: "
|
|
145011
|
+
description: "Opus 4.5 (high reasoning)",
|
|
144878
145012
|
updateArgs: {
|
|
144879
145013
|
context_window: 180000,
|
|
144880
145014
|
max_output_tokens: 64000,
|
|
@@ -144930,7 +145064,7 @@ var init_models7 = __esm(() => {
|
|
|
144930
145064
|
handle: "bedrock/us.anthropic.claude-opus-4-5-20251101-v1:0",
|
|
144931
145065
|
label: "Bedrock Opus 4.5",
|
|
144932
145066
|
shortLabel: "Opus 4.5 BR",
|
|
144933
|
-
description: "
|
|
145067
|
+
description: "Opus 4.5 via AWS Bedrock",
|
|
144934
145068
|
updateArgs: {
|
|
144935
145069
|
context_window: 180000,
|
|
144936
145070
|
max_output_tokens: 64000,
|
|
@@ -144943,7 +145077,7 @@ var init_models7 = __esm(() => {
|
|
|
144943
145077
|
handle: "bedrock/us.anthropic.claude-opus-4-6-v1",
|
|
144944
145078
|
label: "Bedrock Opus 4.6",
|
|
144945
145079
|
shortLabel: "Opus 4.6 BR",
|
|
144946
|
-
description: "
|
|
145080
|
+
description: "Opus 4.6 via AWS Bedrock",
|
|
144947
145081
|
updateArgs: {
|
|
144948
145082
|
context_window: 180000,
|
|
144949
145083
|
max_output_tokens: 64000,
|
|
@@ -144956,7 +145090,7 @@ var init_models7 = __esm(() => {
|
|
|
144956
145090
|
handle: "bedrock/us.anthropic.claude-opus-4-7",
|
|
144957
145091
|
label: "Bedrock Opus 4.7",
|
|
144958
145092
|
shortLabel: "Opus 4.7 BR",
|
|
144959
|
-
description: "
|
|
145093
|
+
description: "Opus 4.7 via AWS Bedrock",
|
|
144960
145094
|
updateArgs: {
|
|
144961
145095
|
context_window: 200000,
|
|
144962
145096
|
max_output_tokens: 128000,
|
|
@@ -144970,7 +145104,7 @@ var init_models7 = __esm(() => {
|
|
|
144970
145104
|
handle: "bedrock/us.anthropic.claude-sonnet-4-6",
|
|
144971
145105
|
label: "Bedrock Sonnet 4.6",
|
|
144972
145106
|
shortLabel: "Sonnet 4.6 BR",
|
|
144973
|
-
description: "
|
|
145107
|
+
description: "Sonnet 4.6 via AWS Bedrock",
|
|
144974
145108
|
updateArgs: {
|
|
144975
145109
|
context_window: 180000,
|
|
144976
145110
|
max_output_tokens: 64000,
|
|
@@ -144982,7 +145116,7 @@ var init_models7 = __esm(() => {
|
|
|
144982
145116
|
id: "haiku",
|
|
144983
145117
|
handle: "anthropic/claude-haiku-4-5",
|
|
144984
145118
|
label: "Haiku 4.5",
|
|
144985
|
-
description: "
|
|
145119
|
+
description: "Haiku 4.5",
|
|
144986
145120
|
updateArgs: {
|
|
144987
145121
|
context_window: 180000,
|
|
144988
145122
|
max_output_tokens: 64000,
|
|
@@ -145804,7 +145938,6 @@ var init_models7 = __esm(() => {
|
|
|
145804
145938
|
handle: "openai/gpt-5.3-codex",
|
|
145805
145939
|
label: "GPT-5.3-Codex",
|
|
145806
145940
|
description: "OpenAI's best coding model (high reasoning)",
|
|
145807
|
-
isFeatured: true,
|
|
145808
145941
|
updateArgs: {
|
|
145809
145942
|
reasoning_effort: "high",
|
|
145810
145943
|
verbosity: "medium",
|
|
@@ -146113,12 +146246,17 @@ function displayRegistryHandleForServiceTier(modelHandle, serviceTier) {
|
|
|
146113
146246
|
function getReasoningTierOptionsForHandle(modelHandle, contextWindow) {
|
|
146114
146247
|
const byEffort = new Map;
|
|
146115
146248
|
const registryHandle = normalizeModelHandleForRegistry(modelHandle) ?? modelHandle;
|
|
146249
|
+
const effectiveContextWindow = contextWindow ?? (() => {
|
|
146250
|
+
const contextWindows = models2.filter((model) => model.handle === registryHandle).map((model) => model.updateArgs?.context_window).filter((value) => typeof value === "number");
|
|
146251
|
+
const uniqueContextWindows = [...new Set(contextWindows)];
|
|
146252
|
+
return uniqueContextWindows.length > 1 ? Math.min(...uniqueContextWindows) : undefined;
|
|
146253
|
+
})();
|
|
146116
146254
|
for (const model of models2) {
|
|
146117
146255
|
if (model.handle !== registryHandle)
|
|
146118
146256
|
continue;
|
|
146119
|
-
if (
|
|
146257
|
+
if (effectiveContextWindow !== undefined) {
|
|
146120
146258
|
const mCtx = model.updateArgs?.context_window;
|
|
146121
|
-
if (mCtx !==
|
|
146259
|
+
if (mCtx !== effectiveContextWindow)
|
|
146122
146260
|
continue;
|
|
146123
146261
|
}
|
|
146124
146262
|
const effort = model.updateArgs?.reasoning_effort;
|
|
@@ -163508,8 +163646,9 @@ Prefer this tool over manually running \`git worktree add\` with Bash because it
|
|
|
163508
163646
|
Do not use this tool for read-only tasks, code review, answering questions, continuing work already in the correct checkout, or when the user explicitly asks not to use worktrees.
|
|
163509
163647
|
|
|
163510
163648
|
Behavior:
|
|
163511
|
-
-
|
|
163512
|
-
-
|
|
163649
|
+
- Uses the current cwd as the target git repository by default, or \`repo_path\` when provided.
|
|
163650
|
+
- If the current cwd is not inside a git repository, pass \`repo_path\` instead of falling back to manual \`git worktree\` commands.
|
|
163651
|
+
- Creates the worktree under \`.letta/worktrees/\` for the target repository.
|
|
163513
163652
|
- Creates a new branch from the default base ref unless \`branch_name\` or \`base_ref\` is provided.
|
|
163514
163653
|
- By default, switches the active conversation/session cwd to the new worktree.
|
|
163515
163654
|
- Does not copy uncommitted changes from the current checkout.
|
|
@@ -165080,6 +165219,8 @@ function createSharedReminderState() {
|
|
|
165080
165219
|
hasSentConversationBootstrap: false,
|
|
165081
165220
|
pendingConversationBootstrap: false,
|
|
165082
165221
|
hasSentSecretsInfo: false,
|
|
165222
|
+
pendingSecretsInfoRefresh: false,
|
|
165223
|
+
lastSentSecretNamesKey: null,
|
|
165083
165224
|
lastNotifiedPermissionMode: null,
|
|
165084
165225
|
turnCount: 0,
|
|
165085
165226
|
pendingReflectionTrigger: false,
|
|
@@ -165113,6 +165254,10 @@ function enqueueMemoryGitSyncReminder(state, reminder) {
|
|
|
165113
165254
|
function enqueueToolsetChangeReminder(state, reminder) {
|
|
165114
165255
|
pushBounded(state.pendingToolsetChangeReminders, reminder);
|
|
165115
165256
|
}
|
|
165257
|
+
function markSecretsInfoReminderPending(state) {
|
|
165258
|
+
state.hasSentSecretsInfo = false;
|
|
165259
|
+
state.pendingSecretsInfoRefresh = true;
|
|
165260
|
+
}
|
|
165116
165261
|
var MAX_PENDING_INTERACTION_REMINDERS = 25;
|
|
165117
165262
|
|
|
165118
165263
|
// src/websocket/listener/scope.ts
|
|
@@ -169124,6 +169269,22 @@ async function assertValidBranchName(cwd, branchName) {
|
|
|
169124
169269
|
async function resolveRepoRoot(cwd) {
|
|
169125
169270
|
return await gitStdout(["rev-parse", "--show-toplevel"], cwd);
|
|
169126
169271
|
}
|
|
169272
|
+
async function resolveWorktreeSourceRoot(params) {
|
|
169273
|
+
const sourcePath = params.requestedRepoPath ? path12.resolve(params.currentCwd, params.requestedRepoPath) : params.currentCwd;
|
|
169274
|
+
try {
|
|
169275
|
+
return await resolveRepoRoot(sourcePath);
|
|
169276
|
+
} catch (error54) {
|
|
169277
|
+
if (params.requestedRepoPath) {
|
|
169278
|
+
throw error54;
|
|
169279
|
+
}
|
|
169280
|
+
throw new Error([
|
|
169281
|
+
`Current working directory is not inside a git repository: ${params.currentCwd}`,
|
|
169282
|
+
"Pass `repo_path` to CreateWorktree or start the session from inside the target repo.",
|
|
169283
|
+
formatGitFailure(error54)
|
|
169284
|
+
].join(`
|
|
169285
|
+
`));
|
|
169286
|
+
}
|
|
169287
|
+
}
|
|
169127
169288
|
async function resolvePrimaryWorktreeRoot(repoRoot) {
|
|
169128
169289
|
const commonDir = await gitStdout(["rev-parse", "--path-format=absolute", "--git-common-dir"], repoRoot);
|
|
169129
169290
|
return path12.basename(commonDir) === ".git" ? path12.dirname(commonDir) : repoRoot;
|
|
@@ -169230,7 +169391,10 @@ async function create_worktree(rawArgs) {
|
|
|
169230
169391
|
try {
|
|
169231
169392
|
const runtimeContext = getRuntimeContext();
|
|
169232
169393
|
const currentCwd = runtimeContext?.workingDirectory || process.env.USER_CWD || process.cwd();
|
|
169233
|
-
const repoRoot = await
|
|
169394
|
+
const repoRoot = await resolveWorktreeSourceRoot({
|
|
169395
|
+
currentCwd,
|
|
169396
|
+
requestedRepoPath: getStringArg(args, "repo_path")
|
|
169397
|
+
});
|
|
169234
169398
|
const primaryRoot = await resolvePrimaryWorktreeRoot(repoRoot);
|
|
169235
169399
|
const worktreesDir = path12.join(primaryRoot, ".letta", "worktrees");
|
|
169236
169400
|
const slug = slugifyName(name);
|
|
@@ -187254,6 +187418,7 @@ var init_search_file_content_gemini = __esm(() => {
|
|
|
187254
187418
|
var exports_skills2 = {};
|
|
187255
187419
|
__export(exports_skills2, {
|
|
187256
187420
|
isUserInvocableSkill: () => isUserInvocableSkill,
|
|
187421
|
+
isSkillAvailableForAgent: () => isSkillAvailableForAgent,
|
|
187257
187422
|
isModelInvocableSkill: () => isModelInvocableSkill,
|
|
187258
187423
|
getFrontmatterStringList: () => getFrontmatterStringList,
|
|
187259
187424
|
getFrontmatterString: () => getFrontmatterString,
|
|
@@ -187315,6 +187480,12 @@ function isModelInvocableSkill(skill) {
|
|
|
187315
187480
|
function isUserInvocableSkill(skill) {
|
|
187316
187481
|
return skill.userInvocable !== false;
|
|
187317
187482
|
}
|
|
187483
|
+
function isSkillAvailableForAgent(skill, agentId) {
|
|
187484
|
+
if (skill.source === "bundled" && agentId && isLocalAgentId(agentId) && LOCAL_AGENT_EXCLUDED_BUNDLED_SKILLS.has(skill.id)) {
|
|
187485
|
+
return false;
|
|
187486
|
+
}
|
|
187487
|
+
return true;
|
|
187488
|
+
}
|
|
187318
187489
|
function getAgentSkillsDir(agentId) {
|
|
187319
187490
|
return join23(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents", agentId, "memory/skills");
|
|
187320
187491
|
}
|
|
@@ -187481,9 +187652,10 @@ ${lines.join(`
|
|
|
187481
187652
|
`)}
|
|
187482
187653
|
</system-reminder>`;
|
|
187483
187654
|
}
|
|
187484
|
-
var SKILLS_DIR = ".skills", GLOBAL_SKILLS_DIR;
|
|
187655
|
+
var LOCAL_AGENT_EXCLUDED_BUNDLED_SKILLS, SKILLS_DIR = ".skills", GLOBAL_SKILLS_DIR;
|
|
187485
187656
|
var init_skills3 = __esm(() => {
|
|
187486
187657
|
init_skill_sources();
|
|
187658
|
+
LOCAL_AGENT_EXCLUDED_BUNDLED_SKILLS = new Set(["image-generation"]);
|
|
187487
187659
|
GLOBAL_SKILLS_DIR = join23(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
|
|
187488
187660
|
});
|
|
187489
187661
|
|
|
@@ -187568,7 +187740,7 @@ async function readSkillContent(skillId, skillsDir, agentId) {
|
|
|
187568
187740
|
} catch {}
|
|
187569
187741
|
const bundledSkills = await getBundledSkills();
|
|
187570
187742
|
const bundledSkill = bundledSkills.find((s2) => s2.id === skillId);
|
|
187571
|
-
if (bundledSkill?.path) {
|
|
187743
|
+
if (bundledSkill?.path && isSkillAvailableForAgent(bundledSkill, agentId)) {
|
|
187572
187744
|
try {
|
|
187573
187745
|
const content = await readFile9(bundledSkill.path, "utf-8");
|
|
187574
187746
|
return { content, path: bundledSkill.path };
|
|
@@ -189867,6 +190039,10 @@ var init_CreateWorktree2 = __esm(() => {
|
|
|
189867
190039
|
type: "string",
|
|
189868
190040
|
description: "Optional git ref to base the worktree on. Defaults to the latest remote default branch, usually origin/main."
|
|
189869
190041
|
},
|
|
190042
|
+
repo_path: {
|
|
190043
|
+
type: "string",
|
|
190044
|
+
description: "Optional path to the git repository to create the worktree from. Use this when the current conversation cwd is not inside the target repo."
|
|
190045
|
+
},
|
|
189870
190046
|
refresh_base: {
|
|
189871
190047
|
type: "boolean",
|
|
189872
190048
|
description: "Whether to fetch the remote base branch before creating the worktree. Defaults to true."
|
|
@@ -194935,7 +195111,9 @@ async function collectClientSideSkills(options3) {
|
|
|
194935
195111
|
});
|
|
194936
195112
|
errors7.push(...discovery.errors);
|
|
194937
195113
|
for (const skill2 of discovery.skills) {
|
|
194938
|
-
|
|
195114
|
+
if (isSkillAvailableForAgent(skill2, options3.agentId)) {
|
|
195115
|
+
skillsById.set(skill2.id, skill2);
|
|
195116
|
+
}
|
|
194939
195117
|
}
|
|
194940
195118
|
} catch (error54) {
|
|
194941
195119
|
const message = error54 instanceof Error ? error54.message : `Unknown error: ${String(error54)}`;
|
|
@@ -194946,6 +195124,9 @@ async function collectClientSideSkills(options3) {
|
|
|
194946
195124
|
const memoryDiscovery = await discoverMemorySkills(options3.agentId);
|
|
194947
195125
|
errors7.push(...memoryDiscovery.errors);
|
|
194948
195126
|
for (const skill2 of memoryDiscovery.skills) {
|
|
195127
|
+
if (!isSkillAvailableForAgent(skill2, options3.agentId)) {
|
|
195128
|
+
continue;
|
|
195129
|
+
}
|
|
194949
195130
|
const existing = skillsById.get(skill2.id);
|
|
194950
195131
|
if (existing?.source === "project" || existing?.source === "agent") {
|
|
194951
195132
|
continue;
|
|
@@ -206207,12 +206388,17 @@ function displayRegistryHandleForServiceTier2(modelHandle, serviceTier) {
|
|
|
206207
206388
|
function getReasoningTierOptionsForHandle2(modelHandle, contextWindow) {
|
|
206208
206389
|
const byEffort = new Map;
|
|
206209
206390
|
const registryHandle = normalizeModelHandleForRegistry2(modelHandle) ?? modelHandle;
|
|
206391
|
+
const effectiveContextWindow = contextWindow ?? (() => {
|
|
206392
|
+
const contextWindows = models3.filter((model) => model.handle === registryHandle).map((model) => model.updateArgs?.context_window).filter((value) => typeof value === "number");
|
|
206393
|
+
const uniqueContextWindows = [...new Set(contextWindows)];
|
|
206394
|
+
return uniqueContextWindows.length > 1 ? Math.min(...uniqueContextWindows) : undefined;
|
|
206395
|
+
})();
|
|
206210
206396
|
for (const model of models3) {
|
|
206211
206397
|
if (model.handle !== registryHandle)
|
|
206212
206398
|
continue;
|
|
206213
|
-
if (
|
|
206399
|
+
if (effectiveContextWindow !== undefined) {
|
|
206214
206400
|
const mCtx = model.updateArgs?.context_window;
|
|
206215
|
-
if (mCtx !==
|
|
206401
|
+
if (mCtx !== effectiveContextWindow)
|
|
206216
206402
|
continue;
|
|
206217
206403
|
}
|
|
206218
206404
|
const effort = model.updateArgs?.reasoning_effort;
|
|
@@ -258407,6 +258593,11 @@ function trimToWordLimit(value, maxWords) {
|
|
|
258407
258593
|
}
|
|
258408
258594
|
return words.slice(0, maxWords).join(" ");
|
|
258409
258595
|
}
|
|
258596
|
+
function paginatedItems2(value) {
|
|
258597
|
+
if (Array.isArray(value))
|
|
258598
|
+
return value;
|
|
258599
|
+
return value.getPaginatedItems?.() ?? [];
|
|
258600
|
+
}
|
|
258410
258601
|
function normalizeConversationDescription(value) {
|
|
258411
258602
|
let normalized = value.replace(/\s+/g, " ").trim();
|
|
258412
258603
|
if (normalized.startsWith('"') && normalized.endsWith('"') || normalized.startsWith("'") && normalized.endsWith("'")) {
|
|
@@ -258432,48 +258623,70 @@ function extractAssistantText(content) {
|
|
|
258432
258623
|
}
|
|
258433
258624
|
return "";
|
|
258434
258625
|
}
|
|
258435
|
-
|
|
258436
|
-
|
|
258626
|
+
function extractUserText(content) {
|
|
258627
|
+
if (typeof content === "string") {
|
|
258628
|
+
return content;
|
|
258629
|
+
}
|
|
258630
|
+
if (Array.isArray(content)) {
|
|
258631
|
+
const parts = [];
|
|
258632
|
+
for (const part of content) {
|
|
258633
|
+
if (!part || typeof part !== "object")
|
|
258634
|
+
continue;
|
|
258635
|
+
const record5 = part;
|
|
258636
|
+
if (typeof record5.text === "string") {
|
|
258637
|
+
parts.push(record5.text);
|
|
258638
|
+
} else if (record5.type === "image") {
|
|
258639
|
+
parts.push("[image]");
|
|
258640
|
+
}
|
|
258641
|
+
}
|
|
258642
|
+
return parts.join(`
|
|
258643
|
+
`);
|
|
258644
|
+
}
|
|
258645
|
+
return "";
|
|
258646
|
+
}
|
|
258647
|
+
function messageToDescriptionMessage(message) {
|
|
258648
|
+
if (message.message_type === "user_message") {
|
|
258649
|
+
const content = extractUserText(message.content).trim();
|
|
258650
|
+
return content ? { role: "user", content } : null;
|
|
258651
|
+
}
|
|
258652
|
+
if (message.message_type === "assistant_message") {
|
|
258653
|
+
const content = extractAssistantText(message.content).trim();
|
|
258654
|
+
return content ? { role: "assistant", content } : null;
|
|
258655
|
+
}
|
|
258656
|
+
return null;
|
|
258657
|
+
}
|
|
258658
|
+
function buildConversationDescriptionMessages(messages) {
|
|
258659
|
+
const descriptionMessages = [];
|
|
258660
|
+
for (const message of messages) {
|
|
258661
|
+
const descriptionMessage = messageToDescriptionMessage(message);
|
|
258662
|
+
if (descriptionMessage) {
|
|
258663
|
+
descriptionMessages.push(descriptionMessage);
|
|
258664
|
+
}
|
|
258665
|
+
}
|
|
258666
|
+
return descriptionMessages;
|
|
258667
|
+
}
|
|
258668
|
+
async function generateConversationDescriptionFromSummary(conversationId, messages, model = DEFAULT_SUMMARIZATION_MODEL) {
|
|
258669
|
+
if (messages.length === 0) {
|
|
258670
|
+
return null;
|
|
258671
|
+
}
|
|
258437
258672
|
const abortController = new AbortController;
|
|
258438
258673
|
const timeoutId = setTimeout(() => abortController.abort(), CONVERSATION_DESCRIPTION_TIMEOUT_MS);
|
|
258439
258674
|
try {
|
|
258440
|
-
const
|
|
258441
|
-
|
|
258442
|
-
|
|
258443
|
-
|
|
258444
|
-
|
|
258445
|
-
|
|
258446
|
-
|
|
258447
|
-
|
|
258448
|
-
],
|
|
258449
|
-
override_model: DEFAULT_SUMMARIZATION_MODEL,
|
|
258450
|
-
override_system: CONVERSATION_DESCRIPTION_SYSTEM_PROMPT,
|
|
258451
|
-
max_steps: 1,
|
|
258452
|
-
streaming: true,
|
|
258453
|
-
stream_tokens: false,
|
|
258454
|
-
include_pings: false
|
|
258455
|
-
}, { signal: abortController.signal });
|
|
258456
|
-
let descriptionText = "";
|
|
258457
|
-
for await (const chunk of stream5) {
|
|
258458
|
-
if (chunk && typeof chunk === "object" && "message_type" in chunk && chunk.message_type === "assistant_message") {
|
|
258459
|
-
descriptionText += extractAssistantText(chunk.content);
|
|
258460
|
-
}
|
|
258461
|
-
}
|
|
258462
|
-
return normalizeConversationDescription(descriptionText);
|
|
258675
|
+
const response = await summarizeConversation(conversationId, {
|
|
258676
|
+
prompt: CONVERSATION_DESCRIPTION_SYSTEM_PROMPT,
|
|
258677
|
+
messages,
|
|
258678
|
+
model
|
|
258679
|
+
}, {
|
|
258680
|
+
signal: abortController.signal
|
|
258681
|
+
});
|
|
258682
|
+
return normalizeConversationDescription(response.summary);
|
|
258463
258683
|
} catch (err) {
|
|
258464
258684
|
if (isDebugEnabled()) {
|
|
258465
|
-
console.error("[DEBUG]
|
|
258685
|
+
console.error("[DEBUG] generateConversationDescriptionFromSummary failed:", err);
|
|
258466
258686
|
}
|
|
258467
258687
|
return null;
|
|
258468
258688
|
} finally {
|
|
258469
258689
|
clearTimeout(timeoutId);
|
|
258470
|
-
if (forkId) {
|
|
258471
|
-
client.conversations.delete(forkId).catch((err) => {
|
|
258472
|
-
if (isDebugEnabled()) {
|
|
258473
|
-
console.error("[DEBUG] failed to delete description-fork conversation:", err);
|
|
258474
|
-
}
|
|
258475
|
-
});
|
|
258476
|
-
}
|
|
258477
258690
|
}
|
|
258478
258691
|
}
|
|
258479
258692
|
async function regenerateConversationDescription(conversationId) {
|
|
@@ -258487,8 +258700,13 @@ async function regenerateConversationDescription(conversationId) {
|
|
|
258487
258700
|
return false;
|
|
258488
258701
|
}
|
|
258489
258702
|
try {
|
|
258490
|
-
const
|
|
258491
|
-
|
|
258703
|
+
const page = await getBackend().listConversationMessages(conversationId, {
|
|
258704
|
+
limit: CONVERSATION_DESCRIPTION_MESSAGE_LIMIT,
|
|
258705
|
+
order: "desc",
|
|
258706
|
+
include_return_message_types: ["user_message", "assistant_message"]
|
|
258707
|
+
});
|
|
258708
|
+
const messages = buildConversationDescriptionMessages(paginatedItems2(page).reverse());
|
|
258709
|
+
const description = await generateConversationDescriptionFromSummary(conversationId, messages, DEFAULT_SUMMARIZATION_MODEL);
|
|
258492
258710
|
if (!description) {
|
|
258493
258711
|
return false;
|
|
258494
258712
|
}
|
|
@@ -258501,7 +258719,7 @@ async function regenerateConversationDescription(conversationId) {
|
|
|
258501
258719
|
return false;
|
|
258502
258720
|
}
|
|
258503
258721
|
}
|
|
258504
|
-
var CONVERSATION_DESCRIPTION_MAX_WORDS = 40, CONVERSATION_DESCRIPTION_TIMEOUT_MS = 30000, CONVERSATION_DESCRIPTION_SYSTEM_PROMPT = `You generate short internal conversation descriptions.
|
|
258722
|
+
var CONVERSATION_DESCRIPTION_MAX_WORDS = 40, CONVERSATION_DESCRIPTION_MESSAGE_LIMIT = 40, CONVERSATION_DESCRIPTION_TIMEOUT_MS = 30000, CONVERSATION_DESCRIPTION_SYSTEM_PROMPT = `You generate short internal conversation descriptions.
|
|
258505
258723
|
|
|
258506
258724
|
Output ONLY a concise description of the conversation above.
|
|
258507
258725
|
Rules:
|
|
@@ -258509,10 +258727,9 @@ Rules:
|
|
|
258509
258727
|
- capture the concrete topic, the user's goal, and any meaningful constraints or decisions
|
|
258510
258728
|
- no quotes, markdown, bullets, prefixes, or trailing punctuation
|
|
258511
258729
|
- never call any tools — reply with plain text only
|
|
258512
|
-
- ignore setup noise like tool chatter, system reminders, approvals, and boilerplate unless the conversation is explicitly about them
|
|
258730
|
+
- ignore setup noise like tool chatter, system reminders, approvals, and boilerplate unless the conversation is explicitly about them`;
|
|
258513
258731
|
var init_conversation_description = __esm(() => {
|
|
258514
258732
|
init_backend2();
|
|
258515
|
-
init_client2();
|
|
258516
258733
|
init_conversations2();
|
|
258517
258734
|
init_constants();
|
|
258518
258735
|
init_manager();
|
|
@@ -259913,20 +260130,31 @@ async function buildAgentInfoReminder(context3) {
|
|
|
259913
260130
|
return reminder || null;
|
|
259914
260131
|
}
|
|
259915
260132
|
async function buildSecretsInfoReminder(context3) {
|
|
259916
|
-
if (context3.state.hasSentSecretsInfo) {
|
|
259917
|
-
return null;
|
|
259918
|
-
}
|
|
259919
|
-
context3.state.hasSentSecretsInfo = true;
|
|
259920
260133
|
try {
|
|
259921
260134
|
const { listSecretNames: listSecretNames2 } = await Promise.resolve().then(() => (init_secrets_store(), exports_secrets_store));
|
|
259922
|
-
const names = listSecretNames2();
|
|
260135
|
+
const names = listSecretNames2(context3.agent.id);
|
|
260136
|
+
const namesKey = names.join("\x00");
|
|
260137
|
+
const isRefresh = context3.state.pendingSecretsInfoRefresh;
|
|
260138
|
+
const namesChanged = context3.state.lastSentSecretNamesKey !== null && context3.state.lastSentSecretNamesKey !== namesKey;
|
|
260139
|
+
if (context3.state.hasSentSecretsInfo && !isRefresh && !namesChanged) {
|
|
260140
|
+
return null;
|
|
260141
|
+
}
|
|
260142
|
+
context3.state.hasSentSecretsInfo = true;
|
|
260143
|
+
context3.state.pendingSecretsInfoRefresh = false;
|
|
260144
|
+
context3.state.lastSentSecretNamesKey = namesKey;
|
|
259923
260145
|
if (names.length === 0) {
|
|
260146
|
+
if (isRefresh || namesChanged) {
|
|
260147
|
+
return `${SYSTEM_REMINDER_OPEN}
|
|
260148
|
+
The agent secrets were updated. No secrets are currently set.
|
|
260149
|
+
${SYSTEM_REMINDER_CLOSE}`;
|
|
260150
|
+
}
|
|
259924
260151
|
return null;
|
|
259925
260152
|
}
|
|
259926
260153
|
const list = names.map((n) => `- \`$${n}\``).join(`
|
|
259927
260154
|
`);
|
|
260155
|
+
const intro = isRefresh || namesChanged ? "The agent secrets were updated. The following secrets are now available for use." : "The following secrets are set on your agent and available for use.";
|
|
259928
260156
|
return `${SYSTEM_REMINDER_OPEN}
|
|
259929
|
-
|
|
260157
|
+
${intro}
|
|
259930
260158
|
Reference them with \`$SECRET_NAME\` in shell commands — substitution happens automatically at exec time:
|
|
259931
260159
|
${list}
|
|
259932
260160
|
|
|
@@ -436650,6 +436878,91 @@ var init_goal_loop_mode = __esm(() => {
|
|
|
436650
436878
|
goalLoopMode = new GoalLoopModeManager;
|
|
436651
436879
|
});
|
|
436652
436880
|
|
|
436881
|
+
// src/websocket/listener/commands/secrets.ts
|
|
436882
|
+
function markSecretsReminderRefreshPending(runtime, agentId) {
|
|
436883
|
+
const prefix = `agent:${agentId}::conversation:`;
|
|
436884
|
+
for (const [key2, state] of runtime.reminderStateByConversation) {
|
|
436885
|
+
if (key2.startsWith(prefix)) {
|
|
436886
|
+
markSecretsInfoReminderPending(state);
|
|
436887
|
+
}
|
|
436888
|
+
}
|
|
436889
|
+
for (const conversationRuntime of runtime.conversationRuntimes.values()) {
|
|
436890
|
+
if (conversationRuntime.agentId === agentId) {
|
|
436891
|
+
markSecretsInfoReminderPending(conversationRuntime.reminderState);
|
|
436892
|
+
}
|
|
436893
|
+
}
|
|
436894
|
+
}
|
|
436895
|
+
function handleSecretsCommand(parsed, context3) {
|
|
436896
|
+
const { socket, runtime, safeSocketSend, runDetachedListenerTask } = context3;
|
|
436897
|
+
if (isSecretListCommand(parsed)) {
|
|
436898
|
+
runDetachedListenerTask("secret_list", async () => {
|
|
436899
|
+
try {
|
|
436900
|
+
const { refreshAndListSecrets: refreshAndListSecrets2 } = await Promise.resolve().then(() => (init_secrets_store(), exports_secrets_store));
|
|
436901
|
+
const secrets2 = await refreshAndListSecrets2(parsed.agent_id);
|
|
436902
|
+
safeSocketSend(socket, {
|
|
436903
|
+
type: "secret_list_response",
|
|
436904
|
+
request_id: parsed.request_id,
|
|
436905
|
+
success: true,
|
|
436906
|
+
secrets: secrets2
|
|
436907
|
+
}, "listener_secret_list_send_failed", "listener_secret_list");
|
|
436908
|
+
} catch (error54) {
|
|
436909
|
+
safeSocketSend(socket, {
|
|
436910
|
+
type: "secret_list_response",
|
|
436911
|
+
request_id: parsed.request_id,
|
|
436912
|
+
success: false,
|
|
436913
|
+
secrets: [],
|
|
436914
|
+
error: error54 instanceof Error ? error54.message : "Failed to list secrets"
|
|
436915
|
+
}, "listener_secret_list_send_failed", "listener_secret_list");
|
|
436916
|
+
}
|
|
436917
|
+
});
|
|
436918
|
+
return true;
|
|
436919
|
+
}
|
|
436920
|
+
if (isSecretApplyCommand(parsed)) {
|
|
436921
|
+
runDetachedListenerTask("secret_apply", async () => {
|
|
436922
|
+
for (const key2 of Object.keys(parsed.set)) {
|
|
436923
|
+
if (!/^[A-Z_][A-Z0-9_]*$/.test(key2.toUpperCase())) {
|
|
436924
|
+
safeSocketSend(socket, {
|
|
436925
|
+
type: "secret_apply_response",
|
|
436926
|
+
request_id: parsed.request_id,
|
|
436927
|
+
success: false,
|
|
436928
|
+
names: [],
|
|
436929
|
+
error: `Invalid secret name '${key2}'. Use uppercase letters, numbers, and underscores only.`
|
|
436930
|
+
}, "listener_secret_apply_send_failed", "listener_secret_apply");
|
|
436931
|
+
return;
|
|
436932
|
+
}
|
|
436933
|
+
}
|
|
436934
|
+
try {
|
|
436935
|
+
const { applySecretBatch: applySecretBatch2 } = await Promise.resolve().then(() => (init_secrets_store(), exports_secrets_store));
|
|
436936
|
+
const names = await applySecretBatch2({ set: parsed.set, unset: parsed.unset }, parsed.agent_id);
|
|
436937
|
+
if (parsed.agent_id) {
|
|
436938
|
+
invalidateSecretsCacheForAgent(runtime, parsed.agent_id);
|
|
436939
|
+
markSecretsReminderRefreshPending(runtime, parsed.agent_id);
|
|
436940
|
+
}
|
|
436941
|
+
safeSocketSend(socket, {
|
|
436942
|
+
type: "secret_apply_response",
|
|
436943
|
+
request_id: parsed.request_id,
|
|
436944
|
+
success: true,
|
|
436945
|
+
names
|
|
436946
|
+
}, "listener_secret_apply_send_failed", "listener_secret_apply");
|
|
436947
|
+
} catch (error54) {
|
|
436948
|
+
safeSocketSend(socket, {
|
|
436949
|
+
type: "secret_apply_response",
|
|
436950
|
+
request_id: parsed.request_id,
|
|
436951
|
+
success: false,
|
|
436952
|
+
names: [],
|
|
436953
|
+
error: error54 instanceof Error ? error54.message : "Failed to apply secrets"
|
|
436954
|
+
}, "listener_secret_apply_send_failed", "listener_secret_apply");
|
|
436955
|
+
}
|
|
436956
|
+
});
|
|
436957
|
+
return true;
|
|
436958
|
+
}
|
|
436959
|
+
return false;
|
|
436960
|
+
}
|
|
436961
|
+
var init_secrets2 = __esm(() => {
|
|
436962
|
+
init_protocol_inbound();
|
|
436963
|
+
init_secrets_sync();
|
|
436964
|
+
});
|
|
436965
|
+
|
|
436653
436966
|
// src/websocket/listener/commands.ts
|
|
436654
436967
|
import { spawn as spawn9 } from "node:child_process";
|
|
436655
436968
|
async function handleExecuteCommand(command, socket, conversationRuntime, opts) {
|
|
@@ -436687,7 +437000,7 @@ async function handleExecuteCommand(command, socket, conversationRuntime, opts)
|
|
|
436687
437000
|
output = await handleCompactCommand(conversationRuntime, trimmedArgs);
|
|
436688
437001
|
break;
|
|
436689
437002
|
case "reload":
|
|
436690
|
-
output = await handleReloadCommand(conversationRuntime
|
|
437003
|
+
output = await handleReloadCommand(conversationRuntime);
|
|
436691
437004
|
break;
|
|
436692
437005
|
case "context-limit":
|
|
436693
437006
|
case "set-max-context":
|
|
@@ -436731,7 +437044,8 @@ async function handleExecuteCommand(command, socket, conversationRuntime, opts)
|
|
|
436731
437044
|
conversationRuntime.cancelRequested = false;
|
|
436732
437045
|
}
|
|
436733
437046
|
}
|
|
436734
|
-
async function handleReloadCommand(
|
|
437047
|
+
async function handleReloadCommand(conversationRuntime) {
|
|
437048
|
+
const { listener } = conversationRuntime;
|
|
436735
437049
|
settingsManager.clearCaches();
|
|
436736
437050
|
await settingsManager.loadProjectSettings();
|
|
436737
437051
|
await settingsManager.loadLocalProjectSettings();
|
|
@@ -436741,7 +437055,12 @@ async function handleReloadCommand(listener) {
|
|
|
436741
437055
|
debugLog("commands", "refreshCustomCommands failed during /reload:", error54 instanceof Error ? error54.message : String(error54));
|
|
436742
437056
|
}
|
|
436743
437057
|
await reloadListenerExtensionAdapter(listener);
|
|
436744
|
-
|
|
437058
|
+
if (conversationRuntime.agentId) {
|
|
437059
|
+
invalidateSecretsCacheForAgent(listener, conversationRuntime.agentId);
|
|
437060
|
+
markSecretsReminderRefreshPending(listener, conversationRuntime.agentId);
|
|
437061
|
+
await ensureSecretsHydratedForAgent(listener, conversationRuntime.agentId);
|
|
437062
|
+
}
|
|
437063
|
+
return "Reloaded settings, local extensions, and agent secrets";
|
|
436745
437064
|
}
|
|
436746
437065
|
async function handleUpgradeLettaCodeCommand(opts) {
|
|
436747
437066
|
const log2 = (message) => {
|
|
@@ -437221,9 +437540,11 @@ var init_commands2 = __esm(async () => {
|
|
|
437221
437540
|
init_settings_manager();
|
|
437222
437541
|
init_error_reporting();
|
|
437223
437542
|
init_debug();
|
|
437543
|
+
init_secrets2();
|
|
437224
437544
|
init_permission_mode();
|
|
437225
437545
|
init_protocol_outbound();
|
|
437226
437546
|
init_runtime5();
|
|
437547
|
+
init_secrets_sync();
|
|
437227
437548
|
init_listener_constants();
|
|
437228
437549
|
await __promiseAll([
|
|
437229
437550
|
init_extension_adapter2(),
|
|
@@ -437615,77 +437936,6 @@ var init_git_branches = __esm(() => {
|
|
|
437615
437936
|
init_protocol_outbound();
|
|
437616
437937
|
});
|
|
437617
437938
|
|
|
437618
|
-
// src/websocket/listener/commands/secrets.ts
|
|
437619
|
-
function handleSecretsCommand(parsed, context3) {
|
|
437620
|
-
const { socket, runtime, safeSocketSend, runDetachedListenerTask } = context3;
|
|
437621
|
-
if (isSecretListCommand(parsed)) {
|
|
437622
|
-
runDetachedListenerTask("secret_list", async () => {
|
|
437623
|
-
try {
|
|
437624
|
-
const { refreshAndListSecrets: refreshAndListSecrets2 } = await Promise.resolve().then(() => (init_secrets_store(), exports_secrets_store));
|
|
437625
|
-
const secrets2 = await refreshAndListSecrets2(parsed.agent_id);
|
|
437626
|
-
safeSocketSend(socket, {
|
|
437627
|
-
type: "secret_list_response",
|
|
437628
|
-
request_id: parsed.request_id,
|
|
437629
|
-
success: true,
|
|
437630
|
-
secrets: secrets2
|
|
437631
|
-
}, "listener_secret_list_send_failed", "listener_secret_list");
|
|
437632
|
-
} catch (error54) {
|
|
437633
|
-
safeSocketSend(socket, {
|
|
437634
|
-
type: "secret_list_response",
|
|
437635
|
-
request_id: parsed.request_id,
|
|
437636
|
-
success: false,
|
|
437637
|
-
secrets: [],
|
|
437638
|
-
error: error54 instanceof Error ? error54.message : "Failed to list secrets"
|
|
437639
|
-
}, "listener_secret_list_send_failed", "listener_secret_list");
|
|
437640
|
-
}
|
|
437641
|
-
});
|
|
437642
|
-
return true;
|
|
437643
|
-
}
|
|
437644
|
-
if (isSecretApplyCommand(parsed)) {
|
|
437645
|
-
runDetachedListenerTask("secret_apply", async () => {
|
|
437646
|
-
for (const key2 of Object.keys(parsed.set)) {
|
|
437647
|
-
if (!/^[A-Z_][A-Z0-9_]*$/.test(key2.toUpperCase())) {
|
|
437648
|
-
safeSocketSend(socket, {
|
|
437649
|
-
type: "secret_apply_response",
|
|
437650
|
-
request_id: parsed.request_id,
|
|
437651
|
-
success: false,
|
|
437652
|
-
names: [],
|
|
437653
|
-
error: `Invalid secret name '${key2}'. Use uppercase letters, numbers, and underscores only.`
|
|
437654
|
-
}, "listener_secret_apply_send_failed", "listener_secret_apply");
|
|
437655
|
-
return;
|
|
437656
|
-
}
|
|
437657
|
-
}
|
|
437658
|
-
try {
|
|
437659
|
-
const { applySecretBatch: applySecretBatch2 } = await Promise.resolve().then(() => (init_secrets_store(), exports_secrets_store));
|
|
437660
|
-
const names = await applySecretBatch2({ set: parsed.set, unset: parsed.unset }, parsed.agent_id);
|
|
437661
|
-
if (parsed.agent_id) {
|
|
437662
|
-
invalidateSecretsCacheForAgent(runtime, parsed.agent_id);
|
|
437663
|
-
}
|
|
437664
|
-
safeSocketSend(socket, {
|
|
437665
|
-
type: "secret_apply_response",
|
|
437666
|
-
request_id: parsed.request_id,
|
|
437667
|
-
success: true,
|
|
437668
|
-
names
|
|
437669
|
-
}, "listener_secret_apply_send_failed", "listener_secret_apply");
|
|
437670
|
-
} catch (error54) {
|
|
437671
|
-
safeSocketSend(socket, {
|
|
437672
|
-
type: "secret_apply_response",
|
|
437673
|
-
request_id: parsed.request_id,
|
|
437674
|
-
success: false,
|
|
437675
|
-
names: [],
|
|
437676
|
-
error: error54 instanceof Error ? error54.message : "Failed to apply secrets"
|
|
437677
|
-
}, "listener_secret_apply_send_failed", "listener_secret_apply");
|
|
437678
|
-
}
|
|
437679
|
-
});
|
|
437680
|
-
return true;
|
|
437681
|
-
}
|
|
437682
|
-
return false;
|
|
437683
|
-
}
|
|
437684
|
-
var init_secrets2 = __esm(() => {
|
|
437685
|
-
init_protocol_inbound();
|
|
437686
|
-
init_secrets_sync();
|
|
437687
|
-
});
|
|
437688
|
-
|
|
437689
437939
|
// src/websocket/listener/message-router.ts
|
|
437690
437940
|
function createListenerMessageHandler(params) {
|
|
437691
437941
|
const {
|
|
@@ -441379,6 +441629,7 @@ var init_version2 = __esm(() => {
|
|
|
441379
441629
|
var exports_skills3 = {};
|
|
441380
441630
|
__export(exports_skills3, {
|
|
441381
441631
|
isUserInvocableSkill: () => isUserInvocableSkill2,
|
|
441632
|
+
isSkillAvailableForAgent: () => isSkillAvailableForAgent2,
|
|
441382
441633
|
isModelInvocableSkill: () => isModelInvocableSkill2,
|
|
441383
441634
|
getFrontmatterStringList: () => getFrontmatterStringList2,
|
|
441384
441635
|
getFrontmatterString: () => getFrontmatterString2,
|
|
@@ -441440,6 +441691,12 @@ function isModelInvocableSkill2(skill2) {
|
|
|
441440
441691
|
function isUserInvocableSkill2(skill2) {
|
|
441441
441692
|
return skill2.userInvocable !== false;
|
|
441442
441693
|
}
|
|
441694
|
+
function isSkillAvailableForAgent2(skill2, agentId) {
|
|
441695
|
+
if (skill2.source === "bundled" && agentId && isLocalAgentId(agentId) && LOCAL_AGENT_EXCLUDED_BUNDLED_SKILLS2.has(skill2.id)) {
|
|
441696
|
+
return false;
|
|
441697
|
+
}
|
|
441698
|
+
return true;
|
|
441699
|
+
}
|
|
441443
441700
|
function getAgentSkillsDir2(agentId) {
|
|
441444
441701
|
return join46(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents", agentId, "memory/skills");
|
|
441445
441702
|
}
|
|
@@ -441606,9 +441863,10 @@ ${lines.join(`
|
|
|
441606
441863
|
`)}
|
|
441607
441864
|
</system-reminder>`;
|
|
441608
441865
|
}
|
|
441609
|
-
var SKILLS_DIR2 = ".skills", GLOBAL_SKILLS_DIR2;
|
|
441866
|
+
var LOCAL_AGENT_EXCLUDED_BUNDLED_SKILLS2, SKILLS_DIR2 = ".skills", GLOBAL_SKILLS_DIR2;
|
|
441610
441867
|
var init_skills4 = __esm(() => {
|
|
441611
441868
|
init_skill_sources();
|
|
441869
|
+
LOCAL_AGENT_EXCLUDED_BUNDLED_SKILLS2 = new Set(["image-generation"]);
|
|
441612
441870
|
GLOBAL_SKILLS_DIR2 = join46(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
|
|
441613
441871
|
});
|
|
441614
441872
|
|
|
@@ -443300,6 +443558,232 @@ async function writeWireMessageAsync(msg) {
|
|
|
443300
443558
|
});
|
|
443301
443559
|
}
|
|
443302
443560
|
|
|
443561
|
+
// src/skills/builtin/creating-skills/scripts/validate-skill.ts
|
|
443562
|
+
import { existsSync as existsSync49, readFileSync as readFileSync33 } from "node:fs";
|
|
443563
|
+
import { basename as basename22, join as join50, resolve as resolve34 } from "node:path";
|
|
443564
|
+
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
443565
|
+
function parseQuotedScalar(value) {
|
|
443566
|
+
if (value.startsWith('"')) {
|
|
443567
|
+
if (!value.endsWith('"') || value.length === 1) {
|
|
443568
|
+
throw new Error("Unterminated double-quoted scalar");
|
|
443569
|
+
}
|
|
443570
|
+
return JSON.parse(value);
|
|
443571
|
+
}
|
|
443572
|
+
if (value.startsWith("'")) {
|
|
443573
|
+
if (!value.endsWith("'") || value.length === 1) {
|
|
443574
|
+
throw new Error("Unterminated single-quoted scalar");
|
|
443575
|
+
}
|
|
443576
|
+
return value.slice(1, -1).replace(/''/g, "'");
|
|
443577
|
+
}
|
|
443578
|
+
return value;
|
|
443579
|
+
}
|
|
443580
|
+
function parseScalar(value) {
|
|
443581
|
+
const trimmed = value.trim();
|
|
443582
|
+
if (!trimmed)
|
|
443583
|
+
return "";
|
|
443584
|
+
if (trimmed === "true")
|
|
443585
|
+
return true;
|
|
443586
|
+
if (trimmed === "false")
|
|
443587
|
+
return false;
|
|
443588
|
+
if (trimmed === "null" || trimmed === "~")
|
|
443589
|
+
return null;
|
|
443590
|
+
if (trimmed.startsWith('"') || trimmed.startsWith("'")) {
|
|
443591
|
+
return parseQuotedScalar(trimmed);
|
|
443592
|
+
}
|
|
443593
|
+
if (trimmed.includes(": ")) {
|
|
443594
|
+
throw new Error(`Unexpected ':' in unquoted scalar: ${trimmed}`);
|
|
443595
|
+
}
|
|
443596
|
+
if (/^-?\d+(?:\.\d+)?$/.test(trimmed)) {
|
|
443597
|
+
return Number(trimmed);
|
|
443598
|
+
}
|
|
443599
|
+
return trimmed;
|
|
443600
|
+
}
|
|
443601
|
+
function parseFrontmatterFallback(source2) {
|
|
443602
|
+
const result = {};
|
|
443603
|
+
const lines = source2.split(/\r?\n/);
|
|
443604
|
+
for (let i4 = 0;i4 < lines.length; i4++) {
|
|
443605
|
+
const line = lines[i4];
|
|
443606
|
+
if (line === undefined)
|
|
443607
|
+
continue;
|
|
443608
|
+
const trimmed = line.trim();
|
|
443609
|
+
if (!trimmed || trimmed.startsWith("#")) {
|
|
443610
|
+
continue;
|
|
443611
|
+
}
|
|
443612
|
+
if (/^\s/.test(line)) {
|
|
443613
|
+
continue;
|
|
443614
|
+
}
|
|
443615
|
+
const colonIndex = line.indexOf(":");
|
|
443616
|
+
if (colonIndex <= 0) {
|
|
443617
|
+
throw new Error(`Invalid frontmatter line: ${line}`);
|
|
443618
|
+
}
|
|
443619
|
+
const key2 = line.slice(0, colonIndex).trim();
|
|
443620
|
+
const rawValue = line.slice(colonIndex + 1).trim();
|
|
443621
|
+
if (!key2) {
|
|
443622
|
+
throw new Error(`Invalid frontmatter line: ${line}`);
|
|
443623
|
+
}
|
|
443624
|
+
if (!rawValue) {
|
|
443625
|
+
result[key2] = {};
|
|
443626
|
+
continue;
|
|
443627
|
+
}
|
|
443628
|
+
if (rawValue === "|" || rawValue === ">") {
|
|
443629
|
+
const blockLines = [];
|
|
443630
|
+
for (let j2 = i4 + 1;j2 < lines.length; j2++) {
|
|
443631
|
+
const nextLine = lines[j2];
|
|
443632
|
+
if (nextLine === undefined)
|
|
443633
|
+
continue;
|
|
443634
|
+
if (nextLine.trim() && !/^\s/.test(nextLine)) {
|
|
443635
|
+
break;
|
|
443636
|
+
}
|
|
443637
|
+
blockLines.push(nextLine.replace(/^\s{2}/, ""));
|
|
443638
|
+
i4 = j2;
|
|
443639
|
+
}
|
|
443640
|
+
result[key2] = rawValue === ">" ? blockLines.join(" ").trim() : blockLines.join(`
|
|
443641
|
+
`);
|
|
443642
|
+
continue;
|
|
443643
|
+
}
|
|
443644
|
+
result[key2] = parseScalar(rawValue);
|
|
443645
|
+
}
|
|
443646
|
+
return result;
|
|
443647
|
+
}
|
|
443648
|
+
function parseFrontmatter2(source2) {
|
|
443649
|
+
const bunParse = globalThis.Bun?.YAML?.parse;
|
|
443650
|
+
if (bunParse) {
|
|
443651
|
+
const parsed = bunParse(source2);
|
|
443652
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
443653
|
+
throw new Error("Frontmatter must be a YAML dictionary");
|
|
443654
|
+
}
|
|
443655
|
+
return parsed;
|
|
443656
|
+
}
|
|
443657
|
+
return parseFrontmatterFallback(source2);
|
|
443658
|
+
}
|
|
443659
|
+
function validateSkill(skillPath) {
|
|
443660
|
+
const skillMdPath = join50(skillPath, "SKILL.md");
|
|
443661
|
+
if (!existsSync49(skillMdPath)) {
|
|
443662
|
+
return { valid: false, message: "SKILL.md not found" };
|
|
443663
|
+
}
|
|
443664
|
+
const content = readFileSync33(skillMdPath, "utf-8");
|
|
443665
|
+
if (!content.startsWith("---")) {
|
|
443666
|
+
return { valid: false, message: "No YAML frontmatter found" };
|
|
443667
|
+
}
|
|
443668
|
+
const match4 = content.match(/^---\n([\s\S]*?)\n---/);
|
|
443669
|
+
if (!match4) {
|
|
443670
|
+
return { valid: false, message: "Invalid frontmatter format" };
|
|
443671
|
+
}
|
|
443672
|
+
const frontmatterText = match4[1];
|
|
443673
|
+
let frontmatter;
|
|
443674
|
+
try {
|
|
443675
|
+
frontmatter = parseFrontmatter2(frontmatterText);
|
|
443676
|
+
if (typeof frontmatter !== "object" || frontmatter === null) {
|
|
443677
|
+
return { valid: false, message: "Frontmatter must be a YAML dictionary" };
|
|
443678
|
+
}
|
|
443679
|
+
} catch (e2) {
|
|
443680
|
+
return {
|
|
443681
|
+
valid: false,
|
|
443682
|
+
message: `Invalid YAML in frontmatter: ${e2 instanceof Error ? e2.message : String(e2)}`
|
|
443683
|
+
};
|
|
443684
|
+
}
|
|
443685
|
+
const warnings = [];
|
|
443686
|
+
const unexpectedKeys = Object.keys(frontmatter).filter((key2) => !ALLOWED_PROPERTIES.has(key2));
|
|
443687
|
+
if (unexpectedKeys.length > 0) {
|
|
443688
|
+
warnings.push(`Unknown frontmatter key(s): ${unexpectedKeys.sort().join(", ")}. Known properties are: ${[...ALLOWED_PROPERTIES].sort().join(", ")}`);
|
|
443689
|
+
}
|
|
443690
|
+
if (!("name" in frontmatter)) {
|
|
443691
|
+
return { valid: false, message: "Missing 'name' in frontmatter" };
|
|
443692
|
+
}
|
|
443693
|
+
if (!("description" in frontmatter)) {
|
|
443694
|
+
return { valid: false, message: "Missing 'description' in frontmatter" };
|
|
443695
|
+
}
|
|
443696
|
+
const name = frontmatter.name;
|
|
443697
|
+
if (typeof name !== "string") {
|
|
443698
|
+
return {
|
|
443699
|
+
valid: false,
|
|
443700
|
+
message: `Name must be a string, got ${typeof name}`
|
|
443701
|
+
};
|
|
443702
|
+
}
|
|
443703
|
+
const trimmedName = name.trim();
|
|
443704
|
+
if (trimmedName) {
|
|
443705
|
+
if (!/^[a-z0-9-]+$/.test(trimmedName)) {
|
|
443706
|
+
return {
|
|
443707
|
+
valid: false,
|
|
443708
|
+
message: `Name '${trimmedName}' should be hyphen-case (lowercase letters, digits, and hyphens only)`
|
|
443709
|
+
};
|
|
443710
|
+
}
|
|
443711
|
+
if (trimmedName.startsWith("-") || trimmedName.endsWith("-") || trimmedName.includes("--")) {
|
|
443712
|
+
return {
|
|
443713
|
+
valid: false,
|
|
443714
|
+
message: `Name '${trimmedName}' cannot start/end with hyphen or contain consecutive hyphens`
|
|
443715
|
+
};
|
|
443716
|
+
}
|
|
443717
|
+
if (trimmedName.length > MAX_SKILL_NAME_LENGTH) {
|
|
443718
|
+
return {
|
|
443719
|
+
valid: false,
|
|
443720
|
+
message: `Name is too long (${trimmedName.length} characters). Maximum is ${MAX_SKILL_NAME_LENGTH} characters.`
|
|
443721
|
+
};
|
|
443722
|
+
}
|
|
443723
|
+
const dirName = basename22(skillPath);
|
|
443724
|
+
if (trimmedName !== dirName) {
|
|
443725
|
+
warnings.push(`Name '${trimmedName}' doesn't match directory name '${dirName}'. For portability, these should match.`);
|
|
443726
|
+
}
|
|
443727
|
+
}
|
|
443728
|
+
const description = frontmatter.description;
|
|
443729
|
+
if (typeof description !== "string") {
|
|
443730
|
+
return {
|
|
443731
|
+
valid: false,
|
|
443732
|
+
message: `Description must be a string, got ${typeof description}`
|
|
443733
|
+
};
|
|
443734
|
+
}
|
|
443735
|
+
const trimmedDescription = description.trim();
|
|
443736
|
+
if (trimmedDescription) {
|
|
443737
|
+
if (trimmedDescription.includes("<") || trimmedDescription.includes(">")) {
|
|
443738
|
+
return {
|
|
443739
|
+
valid: false,
|
|
443740
|
+
message: "Description cannot contain angle brackets (< or >)"
|
|
443741
|
+
};
|
|
443742
|
+
}
|
|
443743
|
+
if (trimmedDescription.length > 1024) {
|
|
443744
|
+
return {
|
|
443745
|
+
valid: false,
|
|
443746
|
+
message: `Description is too long (${trimmedDescription.length} characters). Maximum is 1024 characters.`
|
|
443747
|
+
};
|
|
443748
|
+
}
|
|
443749
|
+
}
|
|
443750
|
+
return {
|
|
443751
|
+
valid: true,
|
|
443752
|
+
message: "Skill is valid!",
|
|
443753
|
+
warnings: warnings.length > 0 ? warnings : undefined
|
|
443754
|
+
};
|
|
443755
|
+
}
|
|
443756
|
+
function isMainModule() {
|
|
443757
|
+
const entrypoint = process.argv[1];
|
|
443758
|
+
return entrypoint ? resolve34(entrypoint) === fileURLToPath9(import.meta.url) : false;
|
|
443759
|
+
}
|
|
443760
|
+
var ALLOWED_PROPERTIES, MAX_SKILL_NAME_LENGTH = 64;
|
|
443761
|
+
var init_validate_skill = __esm(() => {
|
|
443762
|
+
ALLOWED_PROPERTIES = new Set([
|
|
443763
|
+
"name",
|
|
443764
|
+
"description",
|
|
443765
|
+
"license",
|
|
443766
|
+
"compatibility",
|
|
443767
|
+
"metadata",
|
|
443768
|
+
"allowed-tools"
|
|
443769
|
+
]);
|
|
443770
|
+
if (isMainModule()) {
|
|
443771
|
+
const args = process.argv.slice(2);
|
|
443772
|
+
if (args.length !== 1) {
|
|
443773
|
+
console.log("Usage: npx tsx validate-skill.ts <skill-directory>");
|
|
443774
|
+
process.exit(1);
|
|
443775
|
+
}
|
|
443776
|
+
const { valid: valid2, message, warnings } = validateSkill(args[0]);
|
|
443777
|
+
console.log(message);
|
|
443778
|
+
if (warnings && warnings.length > 0) {
|
|
443779
|
+
for (const warning of warnings) {
|
|
443780
|
+
console.warn(`Warning: ${warning}`);
|
|
443781
|
+
}
|
|
443782
|
+
}
|
|
443783
|
+
process.exit(valid2 ? 0 : 1);
|
|
443784
|
+
}
|
|
443785
|
+
});
|
|
443786
|
+
|
|
443303
443787
|
// src/agent/github-utils.ts
|
|
443304
443788
|
var exports_github_utils = {};
|
|
443305
443789
|
__export(exports_github_utils, {
|
|
@@ -443309,8 +443793,8 @@ __export(exports_github_utils, {
|
|
|
443309
443793
|
async function fetchGitHubContents(owner, repo, branch, path36) {
|
|
443310
443794
|
const apiPath = path36 ? `repos/${owner}/${repo}/contents/${path36}?ref=${branch}` : `repos/${owner}/${repo}/contents?ref=${branch}`;
|
|
443311
443795
|
try {
|
|
443312
|
-
const {
|
|
443313
|
-
const result =
|
|
443796
|
+
const { execFileSync: execFileSync5 } = await import("node:child_process");
|
|
443797
|
+
const result = execFileSync5("gh", ["api", apiPath], {
|
|
443314
443798
|
encoding: "utf-8",
|
|
443315
443799
|
stdio: ["pipe", "pipe", "ignore"]
|
|
443316
443800
|
});
|
|
@@ -443341,7 +443825,38 @@ __export(exports_import, {
|
|
|
443341
443825
|
});
|
|
443342
443826
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
443343
443827
|
import { access as access2, chmod, mkdir as mkdir13, readFile as readFile17, writeFile as writeFile15 } from "node:fs/promises";
|
|
443344
|
-
import { dirname as dirname26, resolve as
|
|
443828
|
+
import { dirname as dirname26, isAbsolute as isAbsolute22, relative as relative9, resolve as resolve35, sep as sep6, win32 as win324 } from "node:path";
|
|
443829
|
+
function validateImportedSkillName(name) {
|
|
443830
|
+
const trimmedName = name.trim();
|
|
443831
|
+
if (trimmedName !== name || trimmedName.length === 0 || trimmedName.length > MAX_SKILL_NAME_LENGTH || trimmedName === "." || trimmedName === ".." || !IMPORTED_SKILL_NAME_PATTERN.test(trimmedName)) {
|
|
443832
|
+
throw new Error(`Invalid imported skill name "${String(name)}". Skill names may only contain letters, numbers, dots, underscores, and hyphens.`);
|
|
443833
|
+
}
|
|
443834
|
+
return trimmedName;
|
|
443835
|
+
}
|
|
443836
|
+
function assertPathInside(parent, child) {
|
|
443837
|
+
const parentPath = resolve35(parent);
|
|
443838
|
+
const childPath = resolve35(child);
|
|
443839
|
+
const relativePath = relative9(parentPath, childPath);
|
|
443840
|
+
if (relativePath === "" || relativePath === ".." || relativePath.startsWith(`..${sep6}`) || isAbsolute22(relativePath)) {
|
|
443841
|
+
throw new Error(`Imported skill file path escapes skill directory: ${child}`);
|
|
443842
|
+
}
|
|
443843
|
+
}
|
|
443844
|
+
function validateImportedSkillFilePath(filePath) {
|
|
443845
|
+
if (filePath.length === 0 || filePath === "." || filePath.includes("\x00") || filePath.includes("\\") || isAbsolute22(filePath) || win324.isAbsolute(filePath)) {
|
|
443846
|
+
throw new Error(`Invalid imported skill file path "${filePath}".`);
|
|
443847
|
+
}
|
|
443848
|
+
const segments = filePath.split("/");
|
|
443849
|
+
if (segments.some((segment) => !segment || segment === "." || segment === "..")) {
|
|
443850
|
+
throw new Error(`Invalid imported skill file path "${filePath}".`);
|
|
443851
|
+
}
|
|
443852
|
+
return filePath;
|
|
443853
|
+
}
|
|
443854
|
+
function resolveImportedSkillFilePath(skillDir, filePath) {
|
|
443855
|
+
const safeFilePath = validateImportedSkillFilePath(filePath);
|
|
443856
|
+
const fullPath = resolve35(skillDir, safeFilePath);
|
|
443857
|
+
assertPathInside(skillDir, fullPath);
|
|
443858
|
+
return fullPath;
|
|
443859
|
+
}
|
|
443345
443860
|
function tagsEqual(left, right) {
|
|
443346
443861
|
return left.length === right.length && left.every((tag, i4) => tag === right[i4]);
|
|
443347
443862
|
}
|
|
@@ -443374,7 +443889,7 @@ async function importAgentFromFile(options3) {
|
|
|
443374
443889
|
if (!getBackend().capabilities.agentFileImportExport) {
|
|
443375
443890
|
throw new Error("Agent file import is not supported by this backend yet");
|
|
443376
443891
|
}
|
|
443377
|
-
const resolvedPath =
|
|
443892
|
+
const resolvedPath = resolve35(options3.filePath);
|
|
443378
443893
|
try {
|
|
443379
443894
|
await access2(resolvedPath);
|
|
443380
443895
|
} catch {
|
|
@@ -443418,16 +443933,17 @@ async function extractSkillsFromAf(afPath, destDir) {
|
|
|
443418
443933
|
return [];
|
|
443419
443934
|
}
|
|
443420
443935
|
for (const skill2 of afData.skills) {
|
|
443421
|
-
const
|
|
443936
|
+
const skillName = validateImportedSkillName(skill2.name);
|
|
443937
|
+
const skillDir = resolve35(destDir, skillName);
|
|
443422
443938
|
await mkdir13(skillDir, { recursive: true });
|
|
443423
443939
|
if (skill2.files) {
|
|
443424
443940
|
await writeSkillFiles(skillDir, skill2.files);
|
|
443425
|
-
extracted.push(
|
|
443941
|
+
extracted.push(skillName);
|
|
443426
443942
|
} else if (skill2.source_url) {
|
|
443427
443943
|
await fetchSkillFromUrl(skillDir, skill2.source_url);
|
|
443428
|
-
extracted.push(
|
|
443944
|
+
extracted.push(skillName);
|
|
443429
443945
|
} else {
|
|
443430
|
-
console.warn(`Skipping skill ${
|
|
443946
|
+
console.warn(`Skipping skill ${skillName}: no files or source_url`);
|
|
443431
443947
|
}
|
|
443432
443948
|
}
|
|
443433
443949
|
return extracted;
|
|
@@ -443438,7 +443954,7 @@ async function writeSkillFiles(skillDir, files) {
|
|
|
443438
443954
|
}
|
|
443439
443955
|
}
|
|
443440
443956
|
async function writeSkillFile(skillDir, filePath, content) {
|
|
443441
|
-
const fullPath =
|
|
443957
|
+
const fullPath = resolveImportedSkillFilePath(skillDir, filePath);
|
|
443442
443958
|
await mkdir13(dirname26(fullPath), { recursive: true });
|
|
443443
443959
|
await writeFile15(fullPath, content, "utf-8");
|
|
443444
443960
|
const isScript = filePath.startsWith("scripts/") || content.trimStart().startsWith("#!");
|
|
@@ -443492,7 +444008,7 @@ function parseRegistryHandle(handle2) {
|
|
|
443492
444008
|
}
|
|
443493
444009
|
async function importAgentFromRegistry(options3) {
|
|
443494
444010
|
const { tmpdir: tmpdir7 } = await import("node:os");
|
|
443495
|
-
const { join:
|
|
444011
|
+
const { join: join51 } = await import("node:path");
|
|
443496
444012
|
const { writeFile: writeFile16, unlink: unlink4 } = await import("node:fs/promises");
|
|
443497
444013
|
const { author, name } = parseRegistryHandle(options3.handle);
|
|
443498
444014
|
const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER}/${AGENT_REGISTRY_REPO}/refs/heads/${AGENT_REGISTRY_BRANCH}/agents/@${author}/${name}/${name}.af`;
|
|
@@ -443504,7 +444020,7 @@ async function importAgentFromRegistry(options3) {
|
|
|
443504
444020
|
throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
|
|
443505
444021
|
}
|
|
443506
444022
|
const afContent = await response.text();
|
|
443507
|
-
const tempPath =
|
|
444023
|
+
const tempPath = join51(tmpdir7(), `letta-import-${author}-${name}-${Date.now()}.af`);
|
|
443508
444024
|
await writeFile16(tempPath, afContent, "utf-8");
|
|
443509
444025
|
try {
|
|
443510
444026
|
const result = await importAgentFromFile({
|
|
@@ -443521,13 +444037,15 @@ async function importAgentFromRegistry(options3) {
|
|
|
443521
444037
|
} catch {}
|
|
443522
444038
|
}
|
|
443523
444039
|
}
|
|
443524
|
-
var AGENT_REGISTRY_OWNER = "letta-ai", AGENT_REGISTRY_REPO = "agent-file", AGENT_REGISTRY_BRANCH = "main";
|
|
444040
|
+
var IMPORTED_SKILL_NAME_PATTERN, AGENT_REGISTRY_OWNER = "letta-ai", AGENT_REGISTRY_REPO = "agent-file", AGENT_REGISTRY_BRANCH = "main";
|
|
443525
444041
|
var init_import = __esm(() => {
|
|
443526
444042
|
init_backend2();
|
|
443527
444043
|
init_client2();
|
|
444044
|
+
init_validate_skill();
|
|
443528
444045
|
init_create6();
|
|
443529
444046
|
init_model();
|
|
443530
444047
|
init_modify();
|
|
444048
|
+
IMPORTED_SKILL_NAME_PATTERN = /^[A-Za-z0-9._-]+$/;
|
|
443531
444049
|
});
|
|
443532
444050
|
|
|
443533
444051
|
// src/agent/defaults.ts
|
|
@@ -443823,12 +444341,12 @@ async function sendScopedApprovalMessages(params) {
|
|
|
443823
444341
|
});
|
|
443824
444342
|
}
|
|
443825
444343
|
async function flushAndExit(code2) {
|
|
443826
|
-
const flushWritable = (stream5) => new Promise((
|
|
444344
|
+
const flushWritable = (stream5) => new Promise((resolve36) => {
|
|
443827
444345
|
if (stream5.destroyed || stream5.writableEnded) {
|
|
443828
|
-
|
|
444346
|
+
resolve36();
|
|
443829
444347
|
return;
|
|
443830
444348
|
}
|
|
443831
|
-
stream5.write("", () =>
|
|
444349
|
+
stream5.write("", () => resolve36());
|
|
443832
444350
|
});
|
|
443833
444351
|
await Promise.allSettled([
|
|
443834
444352
|
flushWritable(process.stdout),
|
|
@@ -443837,12 +444355,12 @@ async function flushAndExit(code2) {
|
|
|
443837
444355
|
process.exit(code2);
|
|
443838
444356
|
}
|
|
443839
444357
|
async function writeFinalHeadlessStdout(text2) {
|
|
443840
|
-
await new Promise((
|
|
444358
|
+
await new Promise((resolve36) => {
|
|
443841
444359
|
if (process.stdout.destroyed || process.stdout.writableEnded) {
|
|
443842
|
-
|
|
444360
|
+
resolve36();
|
|
443843
444361
|
return;
|
|
443844
444362
|
}
|
|
443845
|
-
process.stdout.write(text2, () =>
|
|
444363
|
+
process.stdout.write(text2, () => resolve36());
|
|
443846
444364
|
});
|
|
443847
444365
|
}
|
|
443848
444366
|
async function handleHeadlessCommand(parsedArgs, model, skillsDirectoryOverride, skillSourcesOverride, systemInfoReminderEnabledOverride, startupOptions = {}) {
|
|
@@ -444911,7 +445429,7 @@ ${loadedContents.join(`
|
|
|
444911
445429
|
} else {
|
|
444912
445430
|
console.error(`Conversation is busy, waiting ${Math.round(retryDelayMs / 1000)}s and retrying...`);
|
|
444913
445431
|
}
|
|
444914
|
-
await new Promise((
|
|
445432
|
+
await new Promise((resolve36) => setTimeout(resolve36, retryDelayMs));
|
|
444915
445433
|
continue;
|
|
444916
445434
|
}
|
|
444917
445435
|
}
|
|
@@ -444960,7 +445478,7 @@ ${loadedContents.join(`
|
|
|
444960
445478
|
const delaySeconds = Math.round(delayMs / 1000);
|
|
444961
445479
|
console.error(`Transient API error before streaming (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
|
|
444962
445480
|
}
|
|
444963
|
-
await new Promise((
|
|
445481
|
+
await new Promise((resolve36) => setTimeout(resolve36, delayMs));
|
|
444964
445482
|
conversationBusyRetries = 0;
|
|
444965
445483
|
continue;
|
|
444966
445484
|
}
|
|
@@ -445190,7 +445708,7 @@ ${loadedContents.join(`
|
|
|
445190
445708
|
const delaySeconds = Math.round(delayMs / 1000);
|
|
445191
445709
|
console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
|
|
445192
445710
|
}
|
|
445193
|
-
await new Promise((
|
|
445711
|
+
await new Promise((resolve36) => setTimeout(resolve36, delayMs));
|
|
445194
445712
|
currentInput = refreshInputOtidsForNewRequest(currentInput);
|
|
445195
445713
|
continue;
|
|
445196
445714
|
}
|
|
@@ -445282,7 +445800,7 @@ ${loadedContents.join(`
|
|
|
445282
445800
|
} else {
|
|
445283
445801
|
console.error(`Empty LLM response, retrying (attempt ${attempt} of ${EMPTY_RESPONSE_MAX_RETRIES2})...`);
|
|
445284
445802
|
}
|
|
445285
|
-
await new Promise((
|
|
445803
|
+
await new Promise((resolve36) => setTimeout(resolve36, delayMs));
|
|
445286
445804
|
currentInput = refreshInputOtidsForNewRequest(currentInput);
|
|
445287
445805
|
continue;
|
|
445288
445806
|
}
|
|
@@ -445310,7 +445828,7 @@ ${loadedContents.join(`
|
|
|
445310
445828
|
const delaySeconds = Math.round(delayMs / 1000);
|
|
445311
445829
|
console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
|
|
445312
445830
|
}
|
|
445313
|
-
await new Promise((
|
|
445831
|
+
await new Promise((resolve36) => setTimeout(resolve36, delayMs));
|
|
445314
445832
|
currentInput = refreshInputOtidsForNewRequest(currentInput);
|
|
445315
445833
|
continue;
|
|
445316
445834
|
}
|
|
@@ -445340,7 +445858,7 @@ ${loadedContents.join(`
|
|
|
445340
445858
|
const delaySeconds = Math.round(delayMs / 1000);
|
|
445341
445859
|
console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
|
|
445342
445860
|
}
|
|
445343
|
-
await new Promise((
|
|
445861
|
+
await new Promise((resolve36) => setTimeout(resolve36, delayMs));
|
|
445344
445862
|
currentInput = refreshInputOtidsForNewRequest(currentInput);
|
|
445345
445863
|
continue;
|
|
445346
445864
|
}
|
|
@@ -445702,9 +446220,9 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
|
|
|
445702
446220
|
const syntheticUserLine = serializeQueuedMessageAsUserLine(queuedMessage);
|
|
445703
446221
|
maybeNotifyBlocked(syntheticUserLine);
|
|
445704
446222
|
if (lineResolver) {
|
|
445705
|
-
const
|
|
446223
|
+
const resolve36 = lineResolver;
|
|
445706
446224
|
lineResolver = null;
|
|
445707
|
-
|
|
446225
|
+
resolve36(syntheticUserLine);
|
|
445708
446226
|
return;
|
|
445709
446227
|
}
|
|
445710
446228
|
lineQueue.push(syntheticUserLine);
|
|
@@ -445712,9 +446230,9 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
|
|
|
445712
446230
|
rl.on("line", (line) => {
|
|
445713
446231
|
maybeNotifyBlocked(line);
|
|
445714
446232
|
if (lineResolver) {
|
|
445715
|
-
const
|
|
446233
|
+
const resolve36 = lineResolver;
|
|
445716
446234
|
lineResolver = null;
|
|
445717
|
-
|
|
446235
|
+
resolve36(line);
|
|
445718
446236
|
} else {
|
|
445719
446237
|
lineQueue.push(line);
|
|
445720
446238
|
}
|
|
@@ -445723,17 +446241,17 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
|
|
|
445723
446241
|
setMessageQueueAdder(null);
|
|
445724
446242
|
msgQueueRuntime.clear("shutdown");
|
|
445725
446243
|
if (lineResolver) {
|
|
445726
|
-
const
|
|
446244
|
+
const resolve36 = lineResolver;
|
|
445727
446245
|
lineResolver = null;
|
|
445728
|
-
|
|
446246
|
+
resolve36(null);
|
|
445729
446247
|
}
|
|
445730
446248
|
});
|
|
445731
446249
|
async function getNextLine() {
|
|
445732
446250
|
if (lineQueue.length > 0) {
|
|
445733
446251
|
return lineQueue.shift() ?? null;
|
|
445734
446252
|
}
|
|
445735
|
-
return new Promise((
|
|
445736
|
-
lineResolver =
|
|
446253
|
+
return new Promise((resolve36) => {
|
|
446254
|
+
lineResolver = resolve36;
|
|
445737
446255
|
});
|
|
445738
446256
|
}
|
|
445739
446257
|
async function requestPermission(toolCallId, toolName, toolInput) {
|
|
@@ -446219,7 +446737,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
|
|
|
446219
446737
|
uuid: `retry-bidir-${randomUUID26()}`
|
|
446220
446738
|
};
|
|
446221
446739
|
writeWireMessage(retryMsg);
|
|
446222
|
-
await new Promise((
|
|
446740
|
+
await new Promise((resolve36) => setTimeout(resolve36, delayMs));
|
|
446223
446741
|
continue;
|
|
446224
446742
|
}
|
|
446225
446743
|
throw preStreamError;
|
|
@@ -446896,7 +447414,7 @@ var MAX_TERMINAL_TITLE_CHARS = 240;
|
|
|
446896
447414
|
|
|
446897
447415
|
// src/cli/helpers/window-title-config.ts
|
|
446898
447416
|
import { homedir as homedir31 } from "node:os";
|
|
446899
|
-
import { basename as
|
|
447417
|
+
import { basename as basename23, resolve as resolve36 } from "node:path";
|
|
446900
447418
|
function isWindowTitleField(value) {
|
|
446901
447419
|
return WINDOW_TITLE_FIELDS.includes(value);
|
|
446902
447420
|
}
|
|
@@ -447054,8 +447572,8 @@ function terminalTitleProjectName(data) {
|
|
|
447054
447572
|
const directory = titleDirectory(data);
|
|
447055
447573
|
if (!directory)
|
|
447056
447574
|
return null;
|
|
447057
|
-
const resolved =
|
|
447058
|
-
const name =
|
|
447575
|
+
const resolved = resolve36(directory);
|
|
447576
|
+
const name = basename23(resolved) || formatDirectoryDisplay(resolved) || resolved;
|
|
447059
447577
|
return truncateTerminalTitlePart(name, 24);
|
|
447060
447578
|
}
|
|
447061
447579
|
function titleDirectory(data) {
|
|
@@ -447064,7 +447582,7 @@ function titleDirectory(data) {
|
|
|
447064
447582
|
function formatDirectoryDisplay(directory) {
|
|
447065
447583
|
if (!directory)
|
|
447066
447584
|
return null;
|
|
447067
|
-
const resolved =
|
|
447585
|
+
const resolved = resolve36(directory);
|
|
447068
447586
|
const home = homedir31();
|
|
447069
447587
|
if (resolved === home)
|
|
447070
447588
|
return "~";
|
|
@@ -447450,8 +447968,8 @@ async function pushToMemoryRepositoryWithTimeout(agentId) {
|
|
|
447450
447968
|
try {
|
|
447451
447969
|
return await Promise.race([
|
|
447452
447970
|
pushToMemoryRepository(agentId),
|
|
447453
|
-
new Promise((
|
|
447454
|
-
timeout = setTimeout(() =>
|
|
447971
|
+
new Promise((resolve37) => {
|
|
447972
|
+
timeout = setTimeout(() => resolve37("timeout"), INITIAL_PUSH_TIMEOUT_MS);
|
|
447455
447973
|
})
|
|
447456
447974
|
]);
|
|
447457
447975
|
} finally {
|
|
@@ -447709,13 +448227,13 @@ __export(exports_terminal_keybinding_installer, {
|
|
|
447709
448227
|
});
|
|
447710
448228
|
import {
|
|
447711
448229
|
copyFileSync as copyFileSync2,
|
|
447712
|
-
existsSync as
|
|
448230
|
+
existsSync as existsSync51,
|
|
447713
448231
|
mkdirSync as mkdirSync37,
|
|
447714
|
-
readFileSync as
|
|
448232
|
+
readFileSync as readFileSync35,
|
|
447715
448233
|
writeFileSync as writeFileSync27
|
|
447716
448234
|
} from "node:fs";
|
|
447717
448235
|
import { homedir as homedir32, platform as platform8 } from "node:os";
|
|
447718
|
-
import { dirname as dirname27, join as
|
|
448236
|
+
import { dirname as dirname27, join as join52 } from "node:path";
|
|
447719
448237
|
function detectTerminalType() {
|
|
447720
448238
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
447721
448239
|
return "cursor";
|
|
@@ -447747,16 +448265,16 @@ function getKeybindingsPath(terminal) {
|
|
|
447747
448265
|
}[terminal];
|
|
447748
448266
|
const os7 = platform8();
|
|
447749
448267
|
if (os7 === "darwin") {
|
|
447750
|
-
return
|
|
448268
|
+
return join52(homedir32(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
447751
448269
|
}
|
|
447752
448270
|
if (os7 === "win32") {
|
|
447753
448271
|
const appData = process.env.APPDATA;
|
|
447754
448272
|
if (!appData)
|
|
447755
448273
|
return null;
|
|
447756
|
-
return
|
|
448274
|
+
return join52(appData, appName, "User", "keybindings.json");
|
|
447757
448275
|
}
|
|
447758
448276
|
if (os7 === "linux") {
|
|
447759
|
-
return
|
|
448277
|
+
return join52(homedir32(), ".config", appName, "User", "keybindings.json");
|
|
447760
448278
|
}
|
|
447761
448279
|
return null;
|
|
447762
448280
|
}
|
|
@@ -447778,10 +448296,10 @@ function parseKeybindings(content) {
|
|
|
447778
448296
|
}
|
|
447779
448297
|
}
|
|
447780
448298
|
function keybindingExists(keybindingsPath) {
|
|
447781
|
-
if (!
|
|
448299
|
+
if (!existsSync51(keybindingsPath))
|
|
447782
448300
|
return false;
|
|
447783
448301
|
try {
|
|
447784
|
-
const content =
|
|
448302
|
+
const content = readFileSync35(keybindingsPath, { encoding: "utf-8" });
|
|
447785
448303
|
const keybindings = parseKeybindings(content);
|
|
447786
448304
|
if (!keybindings)
|
|
447787
448305
|
return false;
|
|
@@ -447791,7 +448309,7 @@ function keybindingExists(keybindingsPath) {
|
|
|
447791
448309
|
}
|
|
447792
448310
|
}
|
|
447793
448311
|
function createBackup(keybindingsPath) {
|
|
447794
|
-
if (!
|
|
448312
|
+
if (!existsSync51(keybindingsPath))
|
|
447795
448313
|
return null;
|
|
447796
448314
|
const backupPath = `${keybindingsPath}.letta-backup`;
|
|
447797
448315
|
try {
|
|
@@ -447807,14 +448325,14 @@ function installKeybinding(keybindingsPath) {
|
|
|
447807
448325
|
return { success: true, alreadyExists: true };
|
|
447808
448326
|
}
|
|
447809
448327
|
const parentDir = dirname27(keybindingsPath);
|
|
447810
|
-
if (!
|
|
448328
|
+
if (!existsSync51(parentDir)) {
|
|
447811
448329
|
mkdirSync37(parentDir, { recursive: true });
|
|
447812
448330
|
}
|
|
447813
448331
|
let keybindings = [];
|
|
447814
448332
|
let backupPath = null;
|
|
447815
|
-
if (
|
|
448333
|
+
if (existsSync51(keybindingsPath)) {
|
|
447816
448334
|
backupPath = createBackup(keybindingsPath);
|
|
447817
|
-
const content =
|
|
448335
|
+
const content = readFileSync35(keybindingsPath, { encoding: "utf-8" });
|
|
447818
448336
|
const parsed = parseKeybindings(content);
|
|
447819
448337
|
if (parsed === null) {
|
|
447820
448338
|
return {
|
|
@@ -447842,10 +448360,10 @@ function installKeybinding(keybindingsPath) {
|
|
|
447842
448360
|
}
|
|
447843
448361
|
function removeKeybinding(keybindingsPath) {
|
|
447844
448362
|
try {
|
|
447845
|
-
if (!
|
|
448363
|
+
if (!existsSync51(keybindingsPath)) {
|
|
447846
448364
|
return { success: true };
|
|
447847
448365
|
}
|
|
447848
|
-
const content =
|
|
448366
|
+
const content = readFileSync35(keybindingsPath, { encoding: "utf-8" });
|
|
447849
448367
|
const keybindings = parseKeybindings(content);
|
|
447850
448368
|
if (!keybindings) {
|
|
447851
448369
|
return {
|
|
@@ -447909,14 +448427,14 @@ function getWezTermConfigPath() {
|
|
|
447909
448427
|
}
|
|
447910
448428
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
447911
448429
|
if (xdgConfig) {
|
|
447912
|
-
const xdgPath =
|
|
447913
|
-
if (
|
|
448430
|
+
const xdgPath = join52(xdgConfig, "wezterm", "wezterm.lua");
|
|
448431
|
+
if (existsSync51(xdgPath))
|
|
447914
448432
|
return xdgPath;
|
|
447915
448433
|
}
|
|
447916
|
-
const configPath =
|
|
447917
|
-
if (
|
|
448434
|
+
const configPath = join52(homedir32(), ".config", "wezterm", "wezterm.lua");
|
|
448435
|
+
if (existsSync51(configPath))
|
|
447918
448436
|
return configPath;
|
|
447919
|
-
return
|
|
448437
|
+
return join52(homedir32(), ".wezterm.lua");
|
|
447920
448438
|
}
|
|
447921
448439
|
function stripLuaCommentsFromLine(line, blockCommentEnd) {
|
|
447922
448440
|
let code2 = "";
|
|
@@ -448019,10 +448537,10 @@ ${WEZTERM_DELETE_FIX}
|
|
|
448019
448537
|
`;
|
|
448020
448538
|
}
|
|
448021
448539
|
function wezTermDeleteFixExists(configPath) {
|
|
448022
|
-
if (!
|
|
448540
|
+
if (!existsSync51(configPath))
|
|
448023
448541
|
return false;
|
|
448024
448542
|
try {
|
|
448025
|
-
const content =
|
|
448543
|
+
const content = readFileSync35(configPath, { encoding: "utf-8" });
|
|
448026
448544
|
return content.includes("Letta Code: Fix Delete key") || content.includes("key = 'Delete'") && content.includes("SendString") && content.includes("\\x1b[3~");
|
|
448027
448545
|
} catch {
|
|
448028
448546
|
return false;
|
|
@@ -448036,14 +448554,14 @@ function installWezTermDeleteFix() {
|
|
|
448036
448554
|
}
|
|
448037
448555
|
let content = "";
|
|
448038
448556
|
let backupPath = null;
|
|
448039
|
-
if (
|
|
448557
|
+
if (existsSync51(configPath)) {
|
|
448040
448558
|
backupPath = `${configPath}.letta-backup`;
|
|
448041
448559
|
copyFileSync2(configPath, backupPath);
|
|
448042
|
-
content =
|
|
448560
|
+
content = readFileSync35(configPath, { encoding: "utf-8" });
|
|
448043
448561
|
}
|
|
448044
448562
|
content = injectWezTermDeleteFix(content);
|
|
448045
448563
|
const parentDir = dirname27(configPath);
|
|
448046
|
-
if (!
|
|
448564
|
+
if (!existsSync51(parentDir)) {
|
|
448047
448565
|
mkdirSync37(parentDir, { recursive: true });
|
|
448048
448566
|
}
|
|
448049
448567
|
writeFileSync27(configPath, content, { encoding: "utf-8" });
|
|
@@ -448095,9 +448613,9 @@ __export(exports_settings2, {
|
|
|
448095
448613
|
getSetting: () => getSetting
|
|
448096
448614
|
});
|
|
448097
448615
|
import { homedir as homedir33 } from "node:os";
|
|
448098
|
-
import { join as
|
|
448616
|
+
import { join as join53 } from "node:path";
|
|
448099
448617
|
function getSettingsPath() {
|
|
448100
|
-
return
|
|
448618
|
+
return join53(homedir33(), ".letta", "settings.json");
|
|
448101
448619
|
}
|
|
448102
448620
|
async function loadSettings() {
|
|
448103
448621
|
const settingsPath = getSettingsPath();
|
|
@@ -448134,7 +448652,7 @@ async function getSetting(key2) {
|
|
|
448134
448652
|
return settings3[key2];
|
|
448135
448653
|
}
|
|
448136
448654
|
function getProjectSettingsPath() {
|
|
448137
|
-
return
|
|
448655
|
+
return join53(process.cwd(), ".letta", "settings.local.json");
|
|
448138
448656
|
}
|
|
448139
448657
|
async function loadProjectSettings() {
|
|
448140
448658
|
const settingsPath = getProjectSettingsPath();
|
|
@@ -448152,7 +448670,7 @@ async function loadProjectSettings() {
|
|
|
448152
448670
|
}
|
|
448153
448671
|
async function saveProjectSettings(settings3) {
|
|
448154
448672
|
const settingsPath = getProjectSettingsPath();
|
|
448155
|
-
const dirPath =
|
|
448673
|
+
const dirPath = join53(process.cwd(), ".letta");
|
|
448156
448674
|
try {
|
|
448157
448675
|
if (!exists(dirPath)) {
|
|
448158
448676
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -449895,10 +450413,10 @@ var init_InlineBashApproval = __esm(async () => {
|
|
|
449895
450413
|
});
|
|
449896
450414
|
|
|
449897
450415
|
// src/cli/components/DiffRenderer.tsx
|
|
449898
|
-
import { relative as
|
|
450416
|
+
import { relative as relative10 } from "node:path";
|
|
449899
450417
|
function formatDisplayPath4(filePath) {
|
|
449900
450418
|
const cwd2 = process.cwd();
|
|
449901
|
-
const relativePath =
|
|
450419
|
+
const relativePath = relative10(cwd2, filePath);
|
|
449902
450420
|
if (relativePath.startsWith("..")) {
|
|
449903
450421
|
return filePath;
|
|
449904
450422
|
}
|
|
@@ -450257,10 +450775,10 @@ var init_DiffRenderer = __esm(async () => {
|
|
|
450257
450775
|
});
|
|
450258
450776
|
|
|
450259
450777
|
// src/cli/components/AdvancedDiffRenderer.tsx
|
|
450260
|
-
import { relative as
|
|
450778
|
+
import { relative as relative11 } from "node:path";
|
|
450261
450779
|
function formatRelativePath(filePath) {
|
|
450262
450780
|
const cwd2 = process.cwd();
|
|
450263
|
-
const relativePath =
|
|
450781
|
+
const relativePath = relative11(cwd2, filePath);
|
|
450264
450782
|
return relativePath.startsWith("..") ? relativePath : `./${relativePath}`;
|
|
450265
450783
|
}
|
|
450266
450784
|
function padLeft(n, width) {
|
|
@@ -450542,7 +451060,7 @@ function AdvancedDiffRenderer(props) {
|
|
|
450542
451060
|
}
|
|
450543
451061
|
const { hunks } = result;
|
|
450544
451062
|
const filePath = props.filePath;
|
|
450545
|
-
const
|
|
451063
|
+
const relative12 = formatRelativePath(filePath);
|
|
450546
451064
|
const lang41 = languageFromPath(filePath);
|
|
450547
451065
|
const shouldHighlight = lang41 && !exceedsAdvancedDiffHighlightLimits(hunks);
|
|
450548
451066
|
const hunkSyntaxLines = [];
|
|
@@ -450565,7 +451083,7 @@ function AdvancedDiffRenderer(props) {
|
|
|
450565
451083
|
const rows = buildAdvancedDiffRows(hunks, hunkSyntaxLines);
|
|
450566
451084
|
const maxDisplayNo = rows.reduce((m4, r5) => Math.max(m4, r5.displayNo), 1);
|
|
450567
451085
|
const gutterWidth = String(maxDisplayNo).length;
|
|
450568
|
-
const header = props.kind === "write" ? `Wrote changes to ${
|
|
451086
|
+
const header = props.kind === "write" ? `Wrote changes to ${relative12}` : `Updated ${relative12}`;
|
|
450569
451087
|
if (rows.length === 0) {
|
|
450570
451088
|
const noChangesGutter = 4;
|
|
450571
451089
|
return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
|
|
@@ -450616,7 +451134,7 @@ function AdvancedDiffRenderer(props) {
|
|
|
450616
451134
|
"No changes to ",
|
|
450617
451135
|
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text2, {
|
|
450618
451136
|
bold: true,
|
|
450619
|
-
children:
|
|
451137
|
+
children: relative12
|
|
450620
451138
|
}, undefined, false, undefined, this),
|
|
450621
451139
|
" (file content identical)"
|
|
450622
451140
|
]
|
|
@@ -450722,9 +451240,9 @@ function getHeaderText(fileEdit) {
|
|
|
450722
451240
|
} else if (operations.length === 1) {
|
|
450723
451241
|
const op = operations[0];
|
|
450724
451242
|
if (op) {
|
|
450725
|
-
const { relative:
|
|
451243
|
+
const { relative: relative13 } = __require("node:path");
|
|
450726
451244
|
const cwd3 = process.cwd();
|
|
450727
|
-
const relPath2 =
|
|
451245
|
+
const relPath2 = relative13(cwd3, op.path);
|
|
450728
451246
|
const displayPath2 = relPath2.startsWith("..") ? op.path : relPath2;
|
|
450729
451247
|
if (op.kind === "add") {
|
|
450730
451248
|
return `Write to ${displayPath2}?`;
|
|
@@ -450738,14 +451256,14 @@ function getHeaderText(fileEdit) {
|
|
|
450738
451256
|
}
|
|
450739
451257
|
return "Apply patch?";
|
|
450740
451258
|
}
|
|
450741
|
-
const { relative:
|
|
451259
|
+
const { relative: relative12 } = __require("node:path");
|
|
450742
451260
|
const cwd2 = process.cwd();
|
|
450743
|
-
const relPath =
|
|
451261
|
+
const relPath = relative12(cwd2, fileEdit.filePath);
|
|
450744
451262
|
const displayPath = relPath.startsWith("..") ? fileEdit.filePath : relPath;
|
|
450745
451263
|
if (t2 === "write" || t2 === "write_file" || t2 === "writefile" || t2 === "write_file_gemini" || t2 === "writefilegemini") {
|
|
450746
|
-
const { existsSync:
|
|
451264
|
+
const { existsSync: existsSync52 } = __require("node:fs");
|
|
450747
451265
|
try {
|
|
450748
|
-
if (
|
|
451266
|
+
if (existsSync52(fileEdit.filePath)) {
|
|
450749
451267
|
return `Overwrite ${displayPath}?`;
|
|
450750
451268
|
}
|
|
450751
451269
|
} catch {}
|
|
@@ -450923,9 +451441,9 @@ var init_InlineFileEditApproval = __esm(async () => {
|
|
|
450923
451441
|
children: fileEdit.patchInput ? /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
|
|
450924
451442
|
flexDirection: "column",
|
|
450925
451443
|
children: parsePatchOperations2(fileEdit.patchInput).map((op, idx) => {
|
|
450926
|
-
const { relative:
|
|
451444
|
+
const { relative: relative12 } = __require("node:path");
|
|
450927
451445
|
const cwd2 = process.cwd();
|
|
450928
|
-
const relPath =
|
|
451446
|
+
const relPath = relative12(cwd2, op.path);
|
|
450929
451447
|
const displayPath = relPath.startsWith("..") ? op.path : relPath;
|
|
450930
451448
|
const diffKey = fileEdit.toolCallId ? `${fileEdit.toolCallId}:${op.path}` : undefined;
|
|
450931
451449
|
const opDiff = diffKey && allDiffs ? allDiffs.get(diffKey) : undefined;
|
|
@@ -453726,7 +454244,7 @@ function isConversationPinned2(params) {
|
|
|
453726
454244
|
function buildConversationSelectorHints2(params) {
|
|
453727
454245
|
return params.isSelectedDefaultConversation ? "Enter select · ↑↓ navigate · Esc clear/cancel" : "Enter select · ↑↓ navigate · Alt+P pin/unpin · Esc clear/cancel";
|
|
453728
454246
|
}
|
|
453729
|
-
function
|
|
454247
|
+
function paginatedItems4(value) {
|
|
453730
454248
|
return Array.isArray(value) ? value : value.getPaginatedItems();
|
|
453731
454249
|
}
|
|
453732
454250
|
function formatRelativeTime4(dateStr) {
|
|
@@ -453908,7 +454426,7 @@ function ConversationSelector2({
|
|
|
453908
454426
|
include_return_message_types: RESUME_PREVIEW_MESSAGE_TYPES2,
|
|
453909
454427
|
agent_id: agentId
|
|
453910
454428
|
});
|
|
453911
|
-
const chronological = [...
|
|
454429
|
+
const chronological = [...paginatedItems4(messages)].reverse();
|
|
453912
454430
|
const stats = getMessageStats2(chronological);
|
|
453913
454431
|
setConversations((prev) => prev.map((c) => c.conversation.id === convId ? {
|
|
453914
454432
|
...c,
|
|
@@ -453964,10 +454482,10 @@ function ConversationSelector2({
|
|
|
453964
454482
|
order: "asc"
|
|
453965
454483
|
})
|
|
453966
454484
|
]).then(([msgs, firstMsgs]) => {
|
|
453967
|
-
const items3 =
|
|
454485
|
+
const items3 = paginatedItems4(msgs);
|
|
453968
454486
|
if (items3.length === 0)
|
|
453969
454487
|
return null;
|
|
453970
|
-
const firstMessage =
|
|
454488
|
+
const firstMessage = paginatedItems4(firstMsgs)[0];
|
|
453971
454489
|
const stats = getMessageStats2([...items3].reverse());
|
|
453972
454490
|
return buildDefaultConversationEntry2(agentId, stats, getMessageTimestamp2(firstMessage));
|
|
453973
454491
|
}).catch(() => null) : Promise.resolve(null);
|
|
@@ -454080,7 +454598,7 @@ function ConversationSelector2({
|
|
|
454080
454598
|
order_by: "last_run_completion",
|
|
454081
454599
|
summary_search: query2
|
|
454082
454600
|
});
|
|
454083
|
-
const results =
|
|
454601
|
+
const results = paginatedItems4(page);
|
|
454084
454602
|
const seenConversationIds = new Set;
|
|
454085
454603
|
const dedupedResults = results.filter((conversation) => {
|
|
454086
454604
|
const conversationId = conversation.id;
|
|
@@ -455071,6 +455589,7 @@ function FeedbackDialog({
|
|
|
455071
455589
|
}) {
|
|
455072
455590
|
const terminalWidth = useTerminalWidth();
|
|
455073
455591
|
const solidLine = SOLID_LINE11.repeat(Math.max(terminalWidth, 10));
|
|
455592
|
+
const inputWidth = Math.max(terminalWidth - INPUT_PROMPT.length, 10);
|
|
455074
455593
|
const [feedbackText, setFeedbackText] = import_react72.useState(initialValue);
|
|
455075
455594
|
const [error54, setError] = import_react72.useState("");
|
|
455076
455595
|
use_input_default((_input, key2) => {
|
|
@@ -455121,15 +455640,23 @@ function FeedbackDialog({
|
|
|
455121
455640
|
/* @__PURE__ */ jsx_dev_runtime46.jsxDEV(Box_default, {
|
|
455122
455641
|
flexDirection: "row",
|
|
455123
455642
|
children: [
|
|
455124
|
-
/* @__PURE__ */ jsx_dev_runtime46.jsxDEV(
|
|
455125
|
-
|
|
455126
|
-
|
|
455643
|
+
/* @__PURE__ */ jsx_dev_runtime46.jsxDEV(Box_default, {
|
|
455644
|
+
width: INPUT_PROMPT.length,
|
|
455645
|
+
flexShrink: 0,
|
|
455646
|
+
children: /* @__PURE__ */ jsx_dev_runtime46.jsxDEV(Text2, {
|
|
455647
|
+
color: colors.selector.itemHighlighted,
|
|
455648
|
+
children: INPUT_PROMPT
|
|
455649
|
+
}, undefined, false, undefined, this)
|
|
455127
455650
|
}, undefined, false, undefined, this),
|
|
455128
|
-
/* @__PURE__ */ jsx_dev_runtime46.jsxDEV(
|
|
455129
|
-
|
|
455130
|
-
|
|
455131
|
-
|
|
455132
|
-
|
|
455651
|
+
/* @__PURE__ */ jsx_dev_runtime46.jsxDEV(Box_default, {
|
|
455652
|
+
width: inputWidth,
|
|
455653
|
+
flexGrow: 1,
|
|
455654
|
+
children: /* @__PURE__ */ jsx_dev_runtime46.jsxDEV(PasteAwareTextInput, {
|
|
455655
|
+
value: feedbackText,
|
|
455656
|
+
onChange: setFeedbackText,
|
|
455657
|
+
onSubmit: handleSubmit,
|
|
455658
|
+
placeholder: "(type your feedback)"
|
|
455659
|
+
}, undefined, false, undefined, this)
|
|
455133
455660
|
}, undefined, false, undefined, this)
|
|
455134
455661
|
]
|
|
455135
455662
|
}, undefined, true, undefined, this),
|
|
@@ -455156,7 +455683,7 @@ function FeedbackDialog({
|
|
|
455156
455683
|
]
|
|
455157
455684
|
}, undefined, true, undefined, this);
|
|
455158
455685
|
}
|
|
455159
|
-
var import_react72, jsx_dev_runtime46, SOLID_LINE11 = "─";
|
|
455686
|
+
var import_react72, jsx_dev_runtime46, SOLID_LINE11 = "─", INPUT_PROMPT = "> ";
|
|
455160
455687
|
var init_FeedbackDialog = __esm(async () => {
|
|
455161
455688
|
init_use_terminal_width();
|
|
455162
455689
|
init_colors();
|
|
@@ -455381,11 +455908,11 @@ var init_HelpDialog = __esm(async () => {
|
|
|
455381
455908
|
|
|
455382
455909
|
// src/hooks/writer.ts
|
|
455383
455910
|
import { homedir as homedir34 } from "node:os";
|
|
455384
|
-
import { resolve as
|
|
455911
|
+
import { resolve as resolve37 } from "node:path";
|
|
455385
455912
|
function isProjectSettingsPathCollidingWithGlobal2(workingDirectory) {
|
|
455386
455913
|
const home = process.env.HOME || homedir34();
|
|
455387
|
-
const globalSettingsPath =
|
|
455388
|
-
const projectSettingsPath =
|
|
455914
|
+
const globalSettingsPath = resolve37(home, ".letta", "settings.json");
|
|
455915
|
+
const projectSettingsPath = resolve37(workingDirectory, ".letta", "settings.json");
|
|
455389
455916
|
return globalSettingsPath === projectSettingsPath;
|
|
455390
455917
|
}
|
|
455391
455918
|
function loadHooksFromLocation(location, workingDirectory = process.cwd()) {
|
|
@@ -458226,7 +458753,7 @@ import { spawn as spawn10, spawnSync as spawnSync3 } from "node:child_process";
|
|
|
458226
458753
|
import {
|
|
458227
458754
|
chmodSync as chmodSync6,
|
|
458228
458755
|
createWriteStream as createWriteStream4,
|
|
458229
|
-
existsSync as
|
|
458756
|
+
existsSync as existsSync52,
|
|
458230
458757
|
mkdirSync as mkdirSync38,
|
|
458231
458758
|
readdirSync as readdirSync20,
|
|
458232
458759
|
renameSync as renameSync5,
|
|
@@ -458234,7 +458761,7 @@ import {
|
|
|
458234
458761
|
statSync as statSync19
|
|
458235
458762
|
} from "node:fs";
|
|
458236
458763
|
import { arch as arch4, homedir as homedir35, platform as platform9 } from "node:os";
|
|
458237
|
-
import { basename as
|
|
458764
|
+
import { basename as basename24, join as join54 } from "node:path";
|
|
458238
458765
|
function toDisplayPath(value) {
|
|
458239
458766
|
return value.replace(/\\/g, "/");
|
|
458240
458767
|
}
|
|
@@ -458361,9 +458888,9 @@ async function walkDirectoryWithFd(baseDir, fdPath, query2, maxResults, signal)
|
|
|
458361
458888
|
if (query2) {
|
|
458362
458889
|
args.push(buildFdPathQuery(query2));
|
|
458363
458890
|
}
|
|
458364
|
-
return await new Promise((
|
|
458891
|
+
return await new Promise((resolve38) => {
|
|
458365
458892
|
if (signal.aborted) {
|
|
458366
|
-
|
|
458893
|
+
resolve38([]);
|
|
458367
458894
|
return;
|
|
458368
458895
|
}
|
|
458369
458896
|
const child = spawn10(fdPath, args, {
|
|
@@ -458376,7 +458903,7 @@ async function walkDirectoryWithFd(baseDir, fdPath, query2, maxResults, signal)
|
|
|
458376
458903
|
return;
|
|
458377
458904
|
resolved = true;
|
|
458378
458905
|
signal.removeEventListener("abort", onAbort);
|
|
458379
|
-
|
|
458906
|
+
resolve38(results);
|
|
458380
458907
|
};
|
|
458381
458908
|
const onAbort = () => {
|
|
458382
458909
|
if (child.exitCode === null) {
|
|
@@ -458476,7 +459003,7 @@ class FileAutocompleteProvider {
|
|
|
458476
459003
|
}
|
|
458477
459004
|
expandHomePath(path37) {
|
|
458478
459005
|
if (path37.startsWith("~/")) {
|
|
458479
|
-
const expandedPath =
|
|
459006
|
+
const expandedPath = join54(homedir35(), path37.slice(2));
|
|
458480
459007
|
return path37.endsWith("/") && !expandedPath.endsWith("/") ? `${expandedPath}/` : expandedPath;
|
|
458481
459008
|
} else if (path37 === "~") {
|
|
458482
459009
|
return homedir35();
|
|
@@ -458497,7 +459024,7 @@ class FileAutocompleteProvider {
|
|
|
458497
459024
|
} else if (displayBase.startsWith("/")) {
|
|
458498
459025
|
baseDir = displayBase;
|
|
458499
459026
|
} else {
|
|
458500
|
-
baseDir =
|
|
459027
|
+
baseDir = join54(this.basePath, displayBase);
|
|
458501
459028
|
}
|
|
458502
459029
|
try {
|
|
458503
459030
|
if (!statSync19(baseDir).isDirectory()) {
|
|
@@ -458516,7 +459043,7 @@ class FileAutocompleteProvider {
|
|
|
458516
459043
|
return `${toDisplayPath(displayBase)}${normalizedRelativePath}`;
|
|
458517
459044
|
}
|
|
458518
459045
|
scoreEntry(filePath, query2, isDirectory) {
|
|
458519
|
-
const fileName =
|
|
459046
|
+
const fileName = basename24(filePath);
|
|
458520
459047
|
const lowerFileName = fileName.toLowerCase();
|
|
458521
459048
|
const lowerQuery = query2.toLowerCase();
|
|
458522
459049
|
let score = 0;
|
|
@@ -458554,7 +459081,7 @@ class FileAutocompleteProvider {
|
|
|
458554
459081
|
for (const { path: entryPath, isDirectory } of topEntries) {
|
|
458555
459082
|
const pathWithoutSlash = isDirectory ? entryPath.slice(0, -1) : entryPath;
|
|
458556
459083
|
const displayPath2 = scopedQuery ? this.scopedPathForDisplay(scopedQuery.displayBase, pathWithoutSlash) : pathWithoutSlash;
|
|
458557
|
-
const entryName =
|
|
459084
|
+
const entryName = basename24(pathWithoutSlash);
|
|
458558
459085
|
const completionPath = isDirectory ? `${displayPath2}/` : displayPath2;
|
|
458559
459086
|
const value = buildCompletionValue(completionPath, {
|
|
458560
459087
|
isDirectory,
|
|
@@ -458576,9 +459103,9 @@ class FileAutocompleteProvider {
|
|
|
458576
459103
|
var PATH_DELIMITERS2, FD_TOOLS_DIR2, FD_BINARY_NAME2, FD_LOCAL_PATH2;
|
|
458577
459104
|
var init_file_autocomplete = __esm(() => {
|
|
458578
459105
|
PATH_DELIMITERS2 = new Set([" ", "\t", '"', "'", "="]);
|
|
458579
|
-
FD_TOOLS_DIR2 =
|
|
459106
|
+
FD_TOOLS_DIR2 = join54(homedir35(), ".letta", "bin");
|
|
458580
459107
|
FD_BINARY_NAME2 = platform9() === "win32" ? "fd.exe" : "fd";
|
|
458581
|
-
FD_LOCAL_PATH2 =
|
|
459108
|
+
FD_LOCAL_PATH2 = join54(FD_TOOLS_DIR2, FD_BINARY_NAME2);
|
|
458582
459109
|
});
|
|
458583
459110
|
|
|
458584
459111
|
// src/cli/hooks/use-autocomplete-navigation.ts
|
|
@@ -461486,15 +462013,15 @@ var init_agents7 = __esm(() => {
|
|
|
461486
462013
|
// src/cli/commands/install-github-app.ts
|
|
461487
462014
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
461488
462015
|
import {
|
|
461489
|
-
existsSync as
|
|
462016
|
+
existsSync as existsSync53,
|
|
461490
462017
|
mkdirSync as mkdirSync39,
|
|
461491
462018
|
mkdtempSync as mkdtempSync2,
|
|
461492
|
-
readFileSync as
|
|
462019
|
+
readFileSync as readFileSync36,
|
|
461493
462020
|
rmSync as rmSync11,
|
|
461494
462021
|
writeFileSync as writeFileSync28
|
|
461495
462022
|
} from "node:fs";
|
|
461496
462023
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
461497
|
-
import { dirname as dirname28, join as
|
|
462024
|
+
import { dirname as dirname28, join as join55 } from "node:path";
|
|
461498
462025
|
function runCommand(command, args, cwd2, input) {
|
|
461499
462026
|
try {
|
|
461500
462027
|
return execFileSync5(command, args, {
|
|
@@ -461715,8 +462242,8 @@ async function createLettaAgent(apiKey, name) {
|
|
|
461715
462242
|
return createMinimalAgent(apiKey, name);
|
|
461716
462243
|
}
|
|
461717
462244
|
function cloneRepoToTemp(repo) {
|
|
461718
|
-
const tempDir = mkdtempSync2(
|
|
461719
|
-
const repoDir =
|
|
462245
|
+
const tempDir = mkdtempSync2(join55(tmpdir7(), "letta-install-github-app-"));
|
|
462246
|
+
const repoDir = join55(tempDir, "repo");
|
|
461720
462247
|
runCommand("gh", ["repo", "clone", repo, repoDir, "--", "--depth=1"]);
|
|
461721
462248
|
return { tempDir, repoDir };
|
|
461722
462249
|
}
|
|
@@ -461727,14 +462254,14 @@ function runGit4(args, cwd2) {
|
|
|
461727
462254
|
return runCommand("git", args, cwd2);
|
|
461728
462255
|
}
|
|
461729
462256
|
function writeWorkflow(repoDir, workflowPath, content) {
|
|
461730
|
-
const absolutePath =
|
|
461731
|
-
if (!
|
|
462257
|
+
const absolutePath = join55(repoDir, workflowPath);
|
|
462258
|
+
if (!existsSync53(dirname28(absolutePath))) {
|
|
461732
462259
|
mkdirSync39(dirname28(absolutePath), { recursive: true });
|
|
461733
462260
|
}
|
|
461734
462261
|
const next = `${content.trimEnd()}
|
|
461735
462262
|
`;
|
|
461736
|
-
if (
|
|
461737
|
-
const previous =
|
|
462263
|
+
if (existsSync53(absolutePath)) {
|
|
462264
|
+
const previous = readFileSync36(absolutePath, "utf8");
|
|
461738
462265
|
if (previous === next) {
|
|
461739
462266
|
return false;
|
|
461740
462267
|
}
|
|
@@ -466138,9 +466665,9 @@ __export(exports_generate_memory_viewer, {
|
|
|
466138
466665
|
generateAndOpenMemoryViewer: () => generateAndOpenMemoryViewer
|
|
466139
466666
|
});
|
|
466140
466667
|
import { execFile as execFileCb4 } from "node:child_process";
|
|
466141
|
-
import { chmodSync as chmodSync7, existsSync as
|
|
466668
|
+
import { chmodSync as chmodSync7, existsSync as existsSync54, mkdirSync as mkdirSync40, writeFileSync as writeFileSync29 } from "node:fs";
|
|
466142
466669
|
import { homedir as homedir36 } from "node:os";
|
|
466143
|
-
import { join as
|
|
466670
|
+
import { join as join56 } from "node:path";
|
|
466144
466671
|
import { promisify as promisify15 } from "node:util";
|
|
466145
466672
|
function messagesFromOverview(overview) {
|
|
466146
466673
|
return overview.messages?.map((message) => ({
|
|
@@ -466178,7 +466705,7 @@ async function runGitSafe(cwd2, args) {
|
|
|
466178
466705
|
return "";
|
|
466179
466706
|
}
|
|
466180
466707
|
}
|
|
466181
|
-
function
|
|
466708
|
+
function parseFrontmatter3(raw2) {
|
|
466182
466709
|
if (!raw2.startsWith("---")) {
|
|
466183
466710
|
return { frontmatter: {}, body: raw2 };
|
|
466184
466711
|
}
|
|
@@ -466207,7 +466734,7 @@ function collectFiles(memoryRoot) {
|
|
|
466207
466734
|
const fileNodes = getFileNodes(treeNodes);
|
|
466208
466735
|
return fileNodes.filter((n) => n.name.endsWith(".md")).map((n) => {
|
|
466209
466736
|
const raw2 = readFileContent(n.fullPath);
|
|
466210
|
-
const { frontmatter, body: body3 } =
|
|
466737
|
+
const { frontmatter, body: body3 } = parseFrontmatter3(raw2);
|
|
466211
466738
|
return {
|
|
466212
466739
|
path: n.relativePath,
|
|
466213
466740
|
isSystem: n.relativePath.startsWith("system/") || n.relativePath.startsWith("system\\"),
|
|
@@ -466449,7 +466976,7 @@ ${m4.body}` : m4.subject;
|
|
|
466449
466976
|
async function generateAndOpenMemoryViewer(agentId, options3) {
|
|
466450
466977
|
const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
466451
466978
|
const repoDir = memoryRoot;
|
|
466452
|
-
if (!
|
|
466979
|
+
if (!existsSync54(join56(repoDir, ".git"))) {
|
|
466453
466980
|
throw new Error("Memory viewer requires memfs. Run /memfs enable first.");
|
|
466454
466981
|
}
|
|
466455
466982
|
const data = await collectMemoryData(agentId, repoDir, memoryRoot, options3?.conversationId);
|
|
@@ -466459,13 +466986,13 @@ async function generateAndOpenMemoryViewer(agentId, options3) {
|
|
|
466459
466986
|
data.context = applyContextUsageSnapshot(data.context, options3?.contextUsage);
|
|
466460
466987
|
const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
|
|
466461
466988
|
const html5 = memory_viewer_template_default.replace("<!--LETTA_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
466462
|
-
if (!
|
|
466989
|
+
if (!existsSync54(VIEWERS_DIR)) {
|
|
466463
466990
|
mkdirSync40(VIEWERS_DIR, { recursive: true, mode: 448 });
|
|
466464
466991
|
}
|
|
466465
466992
|
try {
|
|
466466
466993
|
chmodSync7(VIEWERS_DIR, 448);
|
|
466467
466994
|
} catch {}
|
|
466468
|
-
const filePath =
|
|
466995
|
+
const filePath = join56(VIEWERS_DIR, `memory-${encodeURIComponent(agentId)}.html`);
|
|
466469
466996
|
writeFileSync29(filePath, html5);
|
|
466470
466997
|
chmodSync7(filePath, 384);
|
|
466471
466998
|
const skipOpen = Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
|
|
@@ -466490,13 +467017,13 @@ var init_generate_memory_viewer = __esm(() => {
|
|
|
466490
467017
|
init_local_memory_context();
|
|
466491
467018
|
init_memory_viewer_template();
|
|
466492
467019
|
execFile17 = promisify15(execFileCb4);
|
|
466493
|
-
VIEWERS_DIR =
|
|
467020
|
+
VIEWERS_DIR = join56(homedir36(), ".letta", "viewers");
|
|
466494
467021
|
REFLECTION_PATTERN = /\(reflection\)|🔮|reflection:/i;
|
|
466495
467022
|
});
|
|
466496
467023
|
|
|
466497
467024
|
// src/cli/components/MemfsTreeViewer.tsx
|
|
466498
|
-
import { existsSync as
|
|
466499
|
-
import { join as
|
|
467025
|
+
import { existsSync as existsSync55 } from "node:fs";
|
|
467026
|
+
import { join as join57 } from "node:path";
|
|
466500
467027
|
function renderTreePrefix(node) {
|
|
466501
467028
|
let prefix = "";
|
|
466502
467029
|
for (let i4 = 0;i4 < node.depth; i4++) {
|
|
@@ -466524,8 +467051,8 @@ function MemfsTreeViewer({
|
|
|
466524
467051
|
const [status, setStatus] = import_react91.useState(null);
|
|
466525
467052
|
const statusTimerRef = import_react91.useRef(null);
|
|
466526
467053
|
const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
466527
|
-
const memoryExists =
|
|
466528
|
-
const hasGitRepo = import_react91.useMemo(() =>
|
|
467054
|
+
const memoryExists = existsSync55(memoryRoot);
|
|
467055
|
+
const hasGitRepo = import_react91.useMemo(() => existsSync55(join57(memoryRoot, ".git")), [memoryRoot]);
|
|
466529
467056
|
function showStatus(msg, durationMs) {
|
|
466530
467057
|
if (statusTimerRef.current)
|
|
466531
467058
|
clearTimeout(statusTimerRef.current);
|
|
@@ -468881,10 +469408,10 @@ var init_PersonalitySelector = __esm(async () => {
|
|
|
468881
469408
|
// src/utils/aws-credentials.ts
|
|
468882
469409
|
import { readFile as readFile18 } from "node:fs/promises";
|
|
468883
469410
|
import { homedir as homedir37 } from "node:os";
|
|
468884
|
-
import { join as
|
|
469411
|
+
import { join as join58 } from "node:path";
|
|
468885
469412
|
async function parseAwsCredentials() {
|
|
468886
|
-
const credentialsPath =
|
|
468887
|
-
const configPath =
|
|
469413
|
+
const credentialsPath = join58(homedir37(), ".aws", "credentials");
|
|
469414
|
+
const configPath = join58(homedir37(), ".aws", "config");
|
|
468888
469415
|
const profiles = new Map;
|
|
468889
469416
|
try {
|
|
468890
469417
|
const content = await readFile18(credentialsPath, "utf-8");
|
|
@@ -470239,8 +470766,8 @@ function SkillsDialog({ onClose, agentId }) {
|
|
|
470239
470766
|
try {
|
|
470240
470767
|
const { discoverSkills: discoverSkills3, SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills3(), exports_skills2));
|
|
470241
470768
|
const { getSkillsDirectory: getSkillsDirectory2, getSkillSources: getSkillSources2 } = await Promise.resolve().then(() => (init_context(), exports_context));
|
|
470242
|
-
const { join:
|
|
470243
|
-
const skillsDir = getSkillsDirectory2() ||
|
|
470769
|
+
const { join: join59 } = await import("node:path");
|
|
470770
|
+
const skillsDir = getSkillsDirectory2() || join59(process.cwd(), SKILLS_DIR3);
|
|
470244
470771
|
const result = await discoverSkills3(skillsDir, agentId, {
|
|
470245
470772
|
sources: getSkillSources2()
|
|
470246
470773
|
});
|
|
@@ -474189,9 +474716,9 @@ function getFileEditHeader(toolName, toolArgs) {
|
|
|
474189
474716
|
} else if (operations.length === 1) {
|
|
474190
474717
|
const op = operations[0];
|
|
474191
474718
|
if (op) {
|
|
474192
|
-
const { relative:
|
|
474719
|
+
const { relative: relative13 } = __require("node:path");
|
|
474193
474720
|
const cwd3 = process.cwd();
|
|
474194
|
-
const relPath2 =
|
|
474721
|
+
const relPath2 = relative13(cwd3, op.path);
|
|
474195
474722
|
const displayPath3 = relPath2.startsWith("..") ? op.path : relPath2;
|
|
474196
474723
|
if (op.kind === "add")
|
|
474197
474724
|
return `Write to ${displayPath3}?`;
|
|
@@ -474205,14 +474732,14 @@ function getFileEditHeader(toolName, toolArgs) {
|
|
|
474205
474732
|
return "Apply patch?";
|
|
474206
474733
|
}
|
|
474207
474734
|
const filePath = args.file_path || "";
|
|
474208
|
-
const { relative:
|
|
474735
|
+
const { relative: relative12 } = __require("node:path");
|
|
474209
474736
|
const cwd2 = process.cwd();
|
|
474210
|
-
const relPath =
|
|
474737
|
+
const relPath = relative12(cwd2, filePath);
|
|
474211
474738
|
const displayPath2 = relPath.startsWith("..") ? filePath : relPath;
|
|
474212
474739
|
if (t2 === "write" || t2 === "write_file" || t2 === "writefile" || t2 === "write_file_gemini" || t2 === "writefilegemini") {
|
|
474213
|
-
const { existsSync:
|
|
474740
|
+
const { existsSync: existsSync56 } = __require("node:fs");
|
|
474214
474741
|
try {
|
|
474215
|
-
if (
|
|
474742
|
+
if (existsSync56(filePath)) {
|
|
474216
474743
|
return `Overwrite ${displayPath2}?`;
|
|
474217
474744
|
}
|
|
474218
474745
|
} catch {}
|
|
@@ -474294,9 +474821,9 @@ var init_ApprovalPreview = __esm(async () => {
|
|
|
474294
474821
|
/* @__PURE__ */ jsx_dev_runtime90.jsxDEV(Box_default, {
|
|
474295
474822
|
flexDirection: "column",
|
|
474296
474823
|
children: operations.map((op, idx) => {
|
|
474297
|
-
const { relative:
|
|
474824
|
+
const { relative: relative12 } = __require("node:path");
|
|
474298
474825
|
const cwd2 = process.cwd();
|
|
474299
|
-
const relPath =
|
|
474826
|
+
const relPath = relative12(cwd2, op.path);
|
|
474300
474827
|
const displayPath2 = relPath.startsWith("..") ? op.path : relPath;
|
|
474301
474828
|
const diffKey = toolCallId ? `${toolCallId}:${op.path}` : undefined;
|
|
474302
474829
|
const opDiff = diffKey && allDiffs ? allDiffs.get(diffKey) : undefined;
|
|
@@ -489516,9 +490043,9 @@ __export(exports_generate_diff_viewer, {
|
|
|
489516
490043
|
generateAndOpenDiffViewer: () => generateAndOpenDiffViewer
|
|
489517
490044
|
});
|
|
489518
490045
|
import { execFile as execFileCb5 } from "node:child_process";
|
|
489519
|
-
import { chmodSync as chmodSync8, existsSync as
|
|
490046
|
+
import { chmodSync as chmodSync8, existsSync as existsSync56, mkdirSync as mkdirSync41, writeFileSync as writeFileSync30 } from "node:fs";
|
|
489520
490047
|
import { homedir as homedir38 } from "node:os";
|
|
489521
|
-
import { isAbsolute as
|
|
490048
|
+
import { isAbsolute as isAbsolute23, join as join59, resolve as resolve38 } from "node:path";
|
|
489522
490049
|
import { promisify as promisify16 } from "node:util";
|
|
489523
490050
|
async function runGit5(cwd2, args) {
|
|
489524
490051
|
try {
|
|
@@ -489716,7 +490243,7 @@ function escapeHtml2(value) {
|
|
|
489716
490243
|
function resolveTargetPath(targetPath) {
|
|
489717
490244
|
if (!targetPath?.trim())
|
|
489718
490245
|
return process.cwd();
|
|
489719
|
-
return
|
|
490246
|
+
return isAbsolute23(targetPath) ? targetPath : resolve38(process.cwd(), targetPath);
|
|
489720
490247
|
}
|
|
489721
490248
|
function shouldSkipOpen() {
|
|
489722
490249
|
return Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
|
|
@@ -489737,13 +490264,13 @@ async function generateAndOpenDiffViewer(targetPath) {
|
|
|
489737
490264
|
};
|
|
489738
490265
|
const jsonPayload = JSON.stringify(payload).replace(/</g, "\\u003c");
|
|
489739
490266
|
const html5 = diff_viewer_template_default.replace("<!--LETTA_DIFF_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
489740
|
-
if (!
|
|
490267
|
+
if (!existsSync56(VIEWERS_DIR2)) {
|
|
489741
490268
|
mkdirSync41(VIEWERS_DIR2, { recursive: true, mode: 448 });
|
|
489742
490269
|
}
|
|
489743
490270
|
try {
|
|
489744
490271
|
chmodSync8(VIEWERS_DIR2, 448);
|
|
489745
490272
|
} catch {}
|
|
489746
|
-
const filePath =
|
|
490273
|
+
const filePath = join59(VIEWERS_DIR2, `diff-${encodeURIComponent(worktreePath)}.html`);
|
|
489747
490274
|
writeFileSync30(filePath, html5);
|
|
489748
490275
|
chmodSync8(filePath, 384);
|
|
489749
490276
|
const skipOpen = shouldSkipOpen();
|
|
@@ -489814,7 +490341,7 @@ var init_generate_diff_viewer = __esm(() => {
|
|
|
489814
490341
|
init_ssr();
|
|
489815
490342
|
init_diff_viewer_template();
|
|
489816
490343
|
execFile18 = promisify16(execFileCb5);
|
|
489817
|
-
VIEWERS_DIR2 =
|
|
490344
|
+
VIEWERS_DIR2 = join59(homedir38(), ".letta", "viewers");
|
|
489818
490345
|
GIT_MAX_BUFFER = 50 * 1024 * 1024;
|
|
489819
490346
|
});
|
|
489820
490347
|
|
|
@@ -491777,16 +492304,16 @@ __export(exports_shell_aliases, {
|
|
|
491777
492304
|
expandAliases: () => expandAliases,
|
|
491778
492305
|
clearAliasCache: () => clearAliasCache
|
|
491779
492306
|
});
|
|
491780
|
-
import { existsSync as
|
|
492307
|
+
import { existsSync as existsSync57, readFileSync as readFileSync37 } from "node:fs";
|
|
491781
492308
|
import { homedir as homedir39 } from "node:os";
|
|
491782
|
-
import { join as
|
|
492309
|
+
import { join as join60 } from "node:path";
|
|
491783
492310
|
function parseAliasesFromFile(filePath) {
|
|
491784
492311
|
const aliases = new Map;
|
|
491785
|
-
if (!
|
|
492312
|
+
if (!existsSync57(filePath)) {
|
|
491786
492313
|
return aliases;
|
|
491787
492314
|
}
|
|
491788
492315
|
try {
|
|
491789
|
-
const content =
|
|
492316
|
+
const content = readFileSync37(filePath, "utf-8");
|
|
491790
492317
|
const lines = content.split(`
|
|
491791
492318
|
`);
|
|
491792
492319
|
let inFunction = false;
|
|
@@ -491851,7 +492378,7 @@ function loadAliases(forceReload = false) {
|
|
|
491851
492378
|
const home = homedir39();
|
|
491852
492379
|
const allAliases = new Map;
|
|
491853
492380
|
for (const file3 of ALIAS_FILES) {
|
|
491854
|
-
const filePath =
|
|
492381
|
+
const filePath = join60(home, file3);
|
|
491855
492382
|
const fileAliases = parseAliasesFromFile(filePath);
|
|
491856
492383
|
for (const [name, value] of fileAliases) {
|
|
491857
492384
|
allAliases.set(name, value);
|
|
@@ -492949,7 +493476,7 @@ var init_system_reminders = __esm(() => {
|
|
|
492949
493476
|
// src/cli/app/use-conversation-loop.ts
|
|
492950
493477
|
import { randomUUID as randomUUID29 } from "node:crypto";
|
|
492951
493478
|
function sleep9(ms) {
|
|
492952
|
-
return new Promise((
|
|
493479
|
+
return new Promise((resolve39) => setTimeout(resolve39, ms));
|
|
492953
493480
|
}
|
|
492954
493481
|
function makeExecutionPhaseHook(setExecutionPhase) {
|
|
492955
493482
|
return ({ chunk }) => {
|
|
@@ -493428,7 +493955,7 @@ function useConversationLoop(ctx) {
|
|
|
493428
493955
|
cancelled = true;
|
|
493429
493956
|
break;
|
|
493430
493957
|
}
|
|
493431
|
-
await new Promise((
|
|
493958
|
+
await new Promise((resolve39) => setTimeout(resolve39, 100));
|
|
493432
493959
|
}
|
|
493433
493960
|
buffersRef.current.byId.delete(statusId);
|
|
493434
493961
|
buffersRef.current.order = buffersRef.current.order.filter((id2) => id2 !== statusId);
|
|
@@ -493492,7 +494019,7 @@ function useConversationLoop(ctx) {
|
|
|
493492
494019
|
cancelled = true;
|
|
493493
494020
|
break;
|
|
493494
494021
|
}
|
|
493495
|
-
await new Promise((
|
|
494022
|
+
await new Promise((resolve39) => setTimeout(resolve39, 100));
|
|
493496
494023
|
}
|
|
493497
494024
|
if (retryStatusId) {
|
|
493498
494025
|
buffersRef.current.byId.delete(retryStatusId);
|
|
@@ -494297,7 +494824,7 @@ ${feedback}
|
|
|
494297
494824
|
});
|
|
494298
494825
|
buffersRef.current.order.push(statusId);
|
|
494299
494826
|
refreshDerived();
|
|
494300
|
-
await new Promise((
|
|
494827
|
+
await new Promise((resolve39) => setTimeout(resolve39, delayMs));
|
|
494301
494828
|
buffersRef.current.byId.delete(statusId);
|
|
494302
494829
|
buffersRef.current.order = buffersRef.current.order.filter((id2) => id2 !== statusId);
|
|
494303
494830
|
refreshDerived();
|
|
@@ -494357,7 +494884,7 @@ ${feedback}
|
|
|
494357
494884
|
cancelled = true;
|
|
494358
494885
|
break;
|
|
494359
494886
|
}
|
|
494360
|
-
await new Promise((
|
|
494887
|
+
await new Promise((resolve39) => setTimeout(resolve39, 100));
|
|
494361
494888
|
}
|
|
494362
494889
|
if (retryStatusId) {
|
|
494363
494890
|
buffersRef.current.byId.delete(retryStatusId);
|
|
@@ -497733,7 +498260,7 @@ __export(exports_worktree_diff_list, {
|
|
|
497733
498260
|
listWorktreeDiffOptions: () => listWorktreeDiffOptions
|
|
497734
498261
|
});
|
|
497735
498262
|
import { execFile as execFileCb6 } from "node:child_process";
|
|
497736
|
-
import { basename as
|
|
498263
|
+
import { basename as basename25 } from "node:path";
|
|
497737
498264
|
import { promisify as promisify17 } from "node:util";
|
|
497738
498265
|
async function runGit6(cwd2, args) {
|
|
497739
498266
|
try {
|
|
@@ -497782,7 +498309,7 @@ function parseWorktreeList(output, currentPath) {
|
|
|
497782
498309
|
if (current?.path) {
|
|
497783
498310
|
worktrees.push({
|
|
497784
498311
|
path: current.path,
|
|
497785
|
-
name:
|
|
498312
|
+
name: basename25(current.path),
|
|
497786
498313
|
branch: current.branch ?? "detached",
|
|
497787
498314
|
head: current.head ?? "",
|
|
497788
498315
|
isCurrent: current.path === currentPath,
|
|
@@ -497808,7 +498335,7 @@ function parseWorktreeList(output, currentPath) {
|
|
|
497808
498335
|
if (current?.path) {
|
|
497809
498336
|
worktrees.push({
|
|
497810
498337
|
path: current.path,
|
|
497811
|
-
name:
|
|
498338
|
+
name: basename25(current.path),
|
|
497812
498339
|
branch: current.branch ?? "detached",
|
|
497813
498340
|
head: current.head ?? "",
|
|
497814
498341
|
isCurrent: current.path === currentPath,
|
|
@@ -497878,14 +498405,14 @@ __export(exports_export, {
|
|
|
497878
498405
|
packageSkills: () => packageSkills
|
|
497879
498406
|
});
|
|
497880
498407
|
import { readdir as readdir14, readFile as readFile19 } from "node:fs/promises";
|
|
497881
|
-
import { relative as
|
|
498408
|
+
import { relative as relative12, resolve as resolve39 } from "node:path";
|
|
497882
498409
|
async function packageSkills(agentId, skillsDir) {
|
|
497883
498410
|
const skills = [];
|
|
497884
498411
|
const skillNames = new Set;
|
|
497885
498412
|
const dirsToCheck = skillsDir ? [skillsDir] : [
|
|
497886
498413
|
agentId && getAgentSkillsDir(agentId),
|
|
497887
|
-
|
|
497888
|
-
|
|
498414
|
+
resolve39(process.cwd(), ".skills"),
|
|
498415
|
+
resolve39(process.env.HOME || "~", ".letta", "skills")
|
|
497889
498416
|
].filter((dir) => Boolean(dir));
|
|
497890
498417
|
for (const baseDir of dirsToCheck) {
|
|
497891
498418
|
try {
|
|
@@ -497895,8 +498422,8 @@ async function packageSkills(agentId, skillsDir) {
|
|
|
497895
498422
|
continue;
|
|
497896
498423
|
if (skillNames.has(entry.name))
|
|
497897
498424
|
continue;
|
|
497898
|
-
const skillDir =
|
|
497899
|
-
const skillMdPath =
|
|
498425
|
+
const skillDir = resolve39(baseDir, entry.name);
|
|
498426
|
+
const skillMdPath = resolve39(skillDir, "SKILL.md");
|
|
497900
498427
|
try {
|
|
497901
498428
|
await readFile19(skillMdPath, "utf-8");
|
|
497902
498429
|
} catch {
|
|
@@ -497926,12 +498453,12 @@ async function readSkillFiles(skillDir) {
|
|
|
497926
498453
|
async function walk(dir) {
|
|
497927
498454
|
const entries = await readdir14(dir, { withFileTypes: true });
|
|
497928
498455
|
for (const entry of entries) {
|
|
497929
|
-
const fullPath =
|
|
498456
|
+
const fullPath = resolve39(dir, entry.name);
|
|
497930
498457
|
if (entry.isDirectory()) {
|
|
497931
498458
|
await walk(fullPath);
|
|
497932
498459
|
} else {
|
|
497933
498460
|
const content = await readFile19(fullPath, "utf-8");
|
|
497934
|
-
const relativePath =
|
|
498461
|
+
const relativePath = relative12(skillDir, fullPath).replace(/\\/g, "/");
|
|
497935
498462
|
files[relativePath] = content;
|
|
497936
498463
|
}
|
|
497937
498464
|
}
|
|
@@ -498066,9 +498593,9 @@ var init_conversation_switch_alert = __esm(() => {
|
|
|
498066
498593
|
|
|
498067
498594
|
// src/cli/app/use-submit-handler.ts
|
|
498068
498595
|
import { randomUUID as randomUUID31 } from "node:crypto";
|
|
498069
|
-
import { existsSync as
|
|
498596
|
+
import { existsSync as existsSync58, readFileSync as readFileSync38, renameSync as renameSync6, writeFileSync as writeFileSync31 } from "node:fs";
|
|
498070
498597
|
import { tmpdir as tmpdir8 } from "node:os";
|
|
498071
|
-
import { join as
|
|
498598
|
+
import { join as join61 } from "node:path";
|
|
498072
498599
|
async function findCustomCommandByName(commandName) {
|
|
498073
498600
|
const { findCustomCommand: findCustomCommand2 } = await Promise.resolve().then(() => (init_custom(), exports_custom));
|
|
498074
498601
|
return findCustomCommand2(commandName);
|
|
@@ -498535,12 +499062,12 @@ ${SYSTEM_REMINDER_CLOSE}`),
|
|
|
498535
499062
|
try {
|
|
498536
499063
|
const memoryRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
498537
499064
|
const personaCandidates = [
|
|
498538
|
-
|
|
498539
|
-
|
|
499065
|
+
join61(memoryRoot, "system", "persona.md"),
|
|
499066
|
+
join61(memoryRoot, "memory", "system", "persona.md")
|
|
498540
499067
|
];
|
|
498541
|
-
const personaPath = personaCandidates.find((candidate) =>
|
|
499068
|
+
const personaPath = personaCandidates.find((candidate) => existsSync58(candidate));
|
|
498542
499069
|
if (personaPath) {
|
|
498543
|
-
const personaContent =
|
|
499070
|
+
const personaContent = readFileSync38(personaPath, "utf-8");
|
|
498544
499071
|
setCurrentPersonalityId(detectPersonalityFromPersonaFile(personaContent));
|
|
498545
499072
|
} else {
|
|
498546
499073
|
setCurrentPersonalityId(null);
|
|
@@ -499493,11 +500020,11 @@ Path: ${memoryDir}`, true);
|
|
|
499493
500020
|
setCommandRunning(true);
|
|
499494
500021
|
try {
|
|
499495
500022
|
const memoryDir = getScopedMemoryFilesystemRoot(agentId);
|
|
499496
|
-
if (!
|
|
500023
|
+
if (!existsSync58(memoryDir)) {
|
|
499497
500024
|
updateMemorySyncCommand(cmdId, "No local memory filesystem found to reset.", true, msg);
|
|
499498
500025
|
return { submitted: true };
|
|
499499
500026
|
}
|
|
499500
|
-
const backupDir =
|
|
500027
|
+
const backupDir = join61(tmpdir8(), `letta-memfs-reset-${agentId}-${Date.now()}`);
|
|
499501
500028
|
renameSync6(memoryDir, backupDir);
|
|
499502
500029
|
if (getBackend().capabilities.localMemfs) {
|
|
499503
500030
|
const { initializeLocalMemoryRepo: initializeLocalMemoryRepo2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
|
|
@@ -499541,8 +500068,8 @@ Run \`/memfs sync\` to repopulate from API.`, true, msg);
|
|
|
499541
500068
|
await removeGitMemoryTag2(agentId);
|
|
499542
500069
|
let backupInfo = "";
|
|
499543
500070
|
const memoryDir = getScopedMemoryFilesystemRoot(agentId);
|
|
499544
|
-
if (
|
|
499545
|
-
const backupDir =
|
|
500071
|
+
if (existsSync58(memoryDir)) {
|
|
500072
|
+
const backupDir = join61(tmpdir8(), `letta-memfs-disable-${agentId}-${Date.now()}`);
|
|
499546
500073
|
renameSync6(memoryDir, backupDir);
|
|
499547
500074
|
backupInfo = `
|
|
499548
500075
|
Local files backed up to ${backupDir}`;
|
|
@@ -502281,9 +502808,9 @@ Memory may be stale. Try running: git -C ${getScopedMemoryFilesystemRoot(agentId
|
|
|
502281
502808
|
(async () => {
|
|
502282
502809
|
try {
|
|
502283
502810
|
const { watch: watch3 } = await import("node:fs");
|
|
502284
|
-
const { existsSync:
|
|
502811
|
+
const { existsSync: existsSync59 } = await import("node:fs");
|
|
502285
502812
|
const memRoot = getScopedMemoryFilesystemRoot(agentId);
|
|
502286
|
-
if (!
|
|
502813
|
+
if (!existsSync59(memRoot))
|
|
502287
502814
|
return;
|
|
502288
502815
|
watcher = watch3(memRoot, { recursive: true }, () => {});
|
|
502289
502816
|
memfsWatcherRef.current = watcher;
|
|
@@ -503495,13 +504022,13 @@ __export(exports_terminal_keybinding_installer2, {
|
|
|
503495
504022
|
});
|
|
503496
504023
|
import {
|
|
503497
504024
|
copyFileSync as copyFileSync3,
|
|
503498
|
-
existsSync as
|
|
504025
|
+
existsSync as existsSync59,
|
|
503499
504026
|
mkdirSync as mkdirSync42,
|
|
503500
|
-
readFileSync as
|
|
504027
|
+
readFileSync as readFileSync39,
|
|
503501
504028
|
writeFileSync as writeFileSync32
|
|
503502
504029
|
} from "node:fs";
|
|
503503
504030
|
import { homedir as homedir41, platform as platform10 } from "node:os";
|
|
503504
|
-
import { dirname as dirname29, join as
|
|
504031
|
+
import { dirname as dirname29, join as join62 } from "node:path";
|
|
503505
504032
|
function detectTerminalType2() {
|
|
503506
504033
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
503507
504034
|
return "cursor";
|
|
@@ -503533,16 +504060,16 @@ function getKeybindingsPath2(terminal) {
|
|
|
503533
504060
|
}[terminal];
|
|
503534
504061
|
const os8 = platform10();
|
|
503535
504062
|
if (os8 === "darwin") {
|
|
503536
|
-
return
|
|
504063
|
+
return join62(homedir41(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
503537
504064
|
}
|
|
503538
504065
|
if (os8 === "win32") {
|
|
503539
504066
|
const appData = process.env.APPDATA;
|
|
503540
504067
|
if (!appData)
|
|
503541
504068
|
return null;
|
|
503542
|
-
return
|
|
504069
|
+
return join62(appData, appName, "User", "keybindings.json");
|
|
503543
504070
|
}
|
|
503544
504071
|
if (os8 === "linux") {
|
|
503545
|
-
return
|
|
504072
|
+
return join62(homedir41(), ".config", appName, "User", "keybindings.json");
|
|
503546
504073
|
}
|
|
503547
504074
|
return null;
|
|
503548
504075
|
}
|
|
@@ -503564,10 +504091,10 @@ function parseKeybindings2(content) {
|
|
|
503564
504091
|
}
|
|
503565
504092
|
}
|
|
503566
504093
|
function keybindingExists2(keybindingsPath) {
|
|
503567
|
-
if (!
|
|
504094
|
+
if (!existsSync59(keybindingsPath))
|
|
503568
504095
|
return false;
|
|
503569
504096
|
try {
|
|
503570
|
-
const content =
|
|
504097
|
+
const content = readFileSync39(keybindingsPath, { encoding: "utf-8" });
|
|
503571
504098
|
const keybindings = parseKeybindings2(content);
|
|
503572
504099
|
if (!keybindings)
|
|
503573
504100
|
return false;
|
|
@@ -503577,7 +504104,7 @@ function keybindingExists2(keybindingsPath) {
|
|
|
503577
504104
|
}
|
|
503578
504105
|
}
|
|
503579
504106
|
function createBackup2(keybindingsPath) {
|
|
503580
|
-
if (!
|
|
504107
|
+
if (!existsSync59(keybindingsPath))
|
|
503581
504108
|
return null;
|
|
503582
504109
|
const backupPath = `${keybindingsPath}.letta-backup`;
|
|
503583
504110
|
try {
|
|
@@ -503593,14 +504120,14 @@ function installKeybinding2(keybindingsPath) {
|
|
|
503593
504120
|
return { success: true, alreadyExists: true };
|
|
503594
504121
|
}
|
|
503595
504122
|
const parentDir = dirname29(keybindingsPath);
|
|
503596
|
-
if (!
|
|
504123
|
+
if (!existsSync59(parentDir)) {
|
|
503597
504124
|
mkdirSync42(parentDir, { recursive: true });
|
|
503598
504125
|
}
|
|
503599
504126
|
let keybindings = [];
|
|
503600
504127
|
let backupPath = null;
|
|
503601
|
-
if (
|
|
504128
|
+
if (existsSync59(keybindingsPath)) {
|
|
503602
504129
|
backupPath = createBackup2(keybindingsPath);
|
|
503603
|
-
const content =
|
|
504130
|
+
const content = readFileSync39(keybindingsPath, { encoding: "utf-8" });
|
|
503604
504131
|
const parsed = parseKeybindings2(content);
|
|
503605
504132
|
if (parsed === null) {
|
|
503606
504133
|
return {
|
|
@@ -503628,10 +504155,10 @@ function installKeybinding2(keybindingsPath) {
|
|
|
503628
504155
|
}
|
|
503629
504156
|
function removeKeybinding2(keybindingsPath) {
|
|
503630
504157
|
try {
|
|
503631
|
-
if (!
|
|
504158
|
+
if (!existsSync59(keybindingsPath)) {
|
|
503632
504159
|
return { success: true };
|
|
503633
504160
|
}
|
|
503634
|
-
const content =
|
|
504161
|
+
const content = readFileSync39(keybindingsPath, { encoding: "utf-8" });
|
|
503635
504162
|
const keybindings = parseKeybindings2(content);
|
|
503636
504163
|
if (!keybindings) {
|
|
503637
504164
|
return {
|
|
@@ -503695,14 +504222,14 @@ function getWezTermConfigPath2() {
|
|
|
503695
504222
|
}
|
|
503696
504223
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
503697
504224
|
if (xdgConfig) {
|
|
503698
|
-
const xdgPath =
|
|
503699
|
-
if (
|
|
504225
|
+
const xdgPath = join62(xdgConfig, "wezterm", "wezterm.lua");
|
|
504226
|
+
if (existsSync59(xdgPath))
|
|
503700
504227
|
return xdgPath;
|
|
503701
504228
|
}
|
|
503702
|
-
const configPath =
|
|
503703
|
-
if (
|
|
504229
|
+
const configPath = join62(homedir41(), ".config", "wezterm", "wezterm.lua");
|
|
504230
|
+
if (existsSync59(configPath))
|
|
503704
504231
|
return configPath;
|
|
503705
|
-
return
|
|
504232
|
+
return join62(homedir41(), ".wezterm.lua");
|
|
503706
504233
|
}
|
|
503707
504234
|
function stripLuaCommentsFromLine2(line, blockCommentEnd) {
|
|
503708
504235
|
let code2 = "";
|
|
@@ -503805,10 +504332,10 @@ ${WEZTERM_DELETE_FIX2}
|
|
|
503805
504332
|
`;
|
|
503806
504333
|
}
|
|
503807
504334
|
function wezTermDeleteFixExists2(configPath) {
|
|
503808
|
-
if (!
|
|
504335
|
+
if (!existsSync59(configPath))
|
|
503809
504336
|
return false;
|
|
503810
504337
|
try {
|
|
503811
|
-
const content =
|
|
504338
|
+
const content = readFileSync39(configPath, { encoding: "utf-8" });
|
|
503812
504339
|
return content.includes("Letta Code: Fix Delete key") || content.includes("key = 'Delete'") && content.includes("SendString") && content.includes("\\x1b[3~");
|
|
503813
504340
|
} catch {
|
|
503814
504341
|
return false;
|
|
@@ -503822,14 +504349,14 @@ function installWezTermDeleteFix2() {
|
|
|
503822
504349
|
}
|
|
503823
504350
|
let content = "";
|
|
503824
504351
|
let backupPath = null;
|
|
503825
|
-
if (
|
|
504352
|
+
if (existsSync59(configPath)) {
|
|
503826
504353
|
backupPath = `${configPath}.letta-backup`;
|
|
503827
504354
|
copyFileSync3(configPath, backupPath);
|
|
503828
|
-
content =
|
|
504355
|
+
content = readFileSync39(configPath, { encoding: "utf-8" });
|
|
503829
504356
|
}
|
|
503830
504357
|
content = injectWezTermDeleteFix2(content);
|
|
503831
504358
|
const parentDir = dirname29(configPath);
|
|
503832
|
-
if (!
|
|
504359
|
+
if (!existsSync59(parentDir)) {
|
|
503833
504360
|
mkdirSync42(parentDir, { recursive: true });
|
|
503834
504361
|
}
|
|
503835
504362
|
writeFileSync32(configPath, content, { encoding: "utf-8" });
|
|
@@ -503881,9 +504408,9 @@ __export(exports_settings3, {
|
|
|
503881
504408
|
getSetting: () => getSetting2
|
|
503882
504409
|
});
|
|
503883
504410
|
import { homedir as homedir42 } from "node:os";
|
|
503884
|
-
import { join as
|
|
504411
|
+
import { join as join63 } from "node:path";
|
|
503885
504412
|
function getSettingsPath2() {
|
|
503886
|
-
return
|
|
504413
|
+
return join63(homedir42(), ".letta", "settings.json");
|
|
503887
504414
|
}
|
|
503888
504415
|
async function loadSettings2() {
|
|
503889
504416
|
const settingsPath = getSettingsPath2();
|
|
@@ -503920,7 +504447,7 @@ async function getSetting2(key2) {
|
|
|
503920
504447
|
return settings3[key2];
|
|
503921
504448
|
}
|
|
503922
504449
|
function getProjectSettingsPath2() {
|
|
503923
|
-
return
|
|
504450
|
+
return join63(process.cwd(), ".letta", "settings.local.json");
|
|
503924
504451
|
}
|
|
503925
504452
|
async function loadProjectSettings2() {
|
|
503926
504453
|
const settingsPath = getProjectSettingsPath2();
|
|
@@ -503938,7 +504465,7 @@ async function loadProjectSettings2() {
|
|
|
503938
504465
|
}
|
|
503939
504466
|
async function saveProjectSettings2(settings3) {
|
|
503940
504467
|
const settingsPath = getProjectSettingsPath2();
|
|
503941
|
-
const dirPath =
|
|
504468
|
+
const dirPath = join63(process.cwd(), ".letta");
|
|
503942
504469
|
try {
|
|
503943
504470
|
if (!exists(dirPath)) {
|
|
503944
504471
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -504479,7 +505006,38 @@ __export(exports_import2, {
|
|
|
504479
505006
|
});
|
|
504480
505007
|
import { createReadStream as createReadStream3 } from "node:fs";
|
|
504481
505008
|
import { access as access3, chmod as chmod2, mkdir as mkdir14, readFile as readFile20, writeFile as writeFile16 } from "node:fs/promises";
|
|
504482
|
-
import { dirname as dirname30, resolve as
|
|
505009
|
+
import { dirname as dirname30, isAbsolute as isAbsolute24, relative as relative13, resolve as resolve40, sep as sep7, win32 as win325 } from "node:path";
|
|
505010
|
+
function validateImportedSkillName2(name) {
|
|
505011
|
+
const trimmedName = name.trim();
|
|
505012
|
+
if (trimmedName !== name || trimmedName.length === 0 || trimmedName.length > MAX_SKILL_NAME_LENGTH || trimmedName === "." || trimmedName === ".." || !IMPORTED_SKILL_NAME_PATTERN2.test(trimmedName)) {
|
|
505013
|
+
throw new Error(`Invalid imported skill name "${String(name)}". Skill names may only contain letters, numbers, dots, underscores, and hyphens.`);
|
|
505014
|
+
}
|
|
505015
|
+
return trimmedName;
|
|
505016
|
+
}
|
|
505017
|
+
function assertPathInside2(parent, child) {
|
|
505018
|
+
const parentPath = resolve40(parent);
|
|
505019
|
+
const childPath = resolve40(child);
|
|
505020
|
+
const relativePath = relative13(parentPath, childPath);
|
|
505021
|
+
if (relativePath === "" || relativePath === ".." || relativePath.startsWith(`..${sep7}`) || isAbsolute24(relativePath)) {
|
|
505022
|
+
throw new Error(`Imported skill file path escapes skill directory: ${child}`);
|
|
505023
|
+
}
|
|
505024
|
+
}
|
|
505025
|
+
function validateImportedSkillFilePath2(filePath) {
|
|
505026
|
+
if (filePath.length === 0 || filePath === "." || filePath.includes("\x00") || filePath.includes("\\") || isAbsolute24(filePath) || win325.isAbsolute(filePath)) {
|
|
505027
|
+
throw new Error(`Invalid imported skill file path "${filePath}".`);
|
|
505028
|
+
}
|
|
505029
|
+
const segments = filePath.split("/");
|
|
505030
|
+
if (segments.some((segment) => !segment || segment === "." || segment === "..")) {
|
|
505031
|
+
throw new Error(`Invalid imported skill file path "${filePath}".`);
|
|
505032
|
+
}
|
|
505033
|
+
return filePath;
|
|
505034
|
+
}
|
|
505035
|
+
function resolveImportedSkillFilePath2(skillDir, filePath) {
|
|
505036
|
+
const safeFilePath = validateImportedSkillFilePath2(filePath);
|
|
505037
|
+
const fullPath = resolve40(skillDir, safeFilePath);
|
|
505038
|
+
assertPathInside2(skillDir, fullPath);
|
|
505039
|
+
return fullPath;
|
|
505040
|
+
}
|
|
504483
505041
|
function tagsEqual2(left, right) {
|
|
504484
505042
|
return left.length === right.length && left.every((tag, i4) => tag === right[i4]);
|
|
504485
505043
|
}
|
|
@@ -504512,7 +505070,7 @@ async function importAgentFromFile2(options3) {
|
|
|
504512
505070
|
if (!getBackend().capabilities.agentFileImportExport) {
|
|
504513
505071
|
throw new Error("Agent file import is not supported by this backend yet");
|
|
504514
505072
|
}
|
|
504515
|
-
const resolvedPath =
|
|
505073
|
+
const resolvedPath = resolve40(options3.filePath);
|
|
504516
505074
|
try {
|
|
504517
505075
|
await access3(resolvedPath);
|
|
504518
505076
|
} catch {
|
|
@@ -504556,16 +505114,17 @@ async function extractSkillsFromAf2(afPath, destDir) {
|
|
|
504556
505114
|
return [];
|
|
504557
505115
|
}
|
|
504558
505116
|
for (const skill2 of afData.skills) {
|
|
504559
|
-
const
|
|
505117
|
+
const skillName = validateImportedSkillName2(skill2.name);
|
|
505118
|
+
const skillDir = resolve40(destDir, skillName);
|
|
504560
505119
|
await mkdir14(skillDir, { recursive: true });
|
|
504561
505120
|
if (skill2.files) {
|
|
504562
505121
|
await writeSkillFiles2(skillDir, skill2.files);
|
|
504563
|
-
extracted.push(
|
|
505122
|
+
extracted.push(skillName);
|
|
504564
505123
|
} else if (skill2.source_url) {
|
|
504565
505124
|
await fetchSkillFromUrl2(skillDir, skill2.source_url);
|
|
504566
|
-
extracted.push(
|
|
505125
|
+
extracted.push(skillName);
|
|
504567
505126
|
} else {
|
|
504568
|
-
console.warn(`Skipping skill ${
|
|
505127
|
+
console.warn(`Skipping skill ${skillName}: no files or source_url`);
|
|
504569
505128
|
}
|
|
504570
505129
|
}
|
|
504571
505130
|
return extracted;
|
|
@@ -504576,7 +505135,7 @@ async function writeSkillFiles2(skillDir, files) {
|
|
|
504576
505135
|
}
|
|
504577
505136
|
}
|
|
504578
505137
|
async function writeSkillFile2(skillDir, filePath, content) {
|
|
504579
|
-
const fullPath =
|
|
505138
|
+
const fullPath = resolveImportedSkillFilePath2(skillDir, filePath);
|
|
504580
505139
|
await mkdir14(dirname30(fullPath), { recursive: true });
|
|
504581
505140
|
await writeFile16(fullPath, content, "utf-8");
|
|
504582
505141
|
const isScript = filePath.startsWith("scripts/") || content.trimStart().startsWith("#!");
|
|
@@ -504630,7 +505189,7 @@ function parseRegistryHandle2(handle2) {
|
|
|
504630
505189
|
}
|
|
504631
505190
|
async function importAgentFromRegistry2(options3) {
|
|
504632
505191
|
const { tmpdir: tmpdir9 } = await import("node:os");
|
|
504633
|
-
const { join:
|
|
505192
|
+
const { join: join64 } = await import("node:path");
|
|
504634
505193
|
const { writeFile: writeFile17, unlink: unlink4 } = await import("node:fs/promises");
|
|
504635
505194
|
const { author, name } = parseRegistryHandle2(options3.handle);
|
|
504636
505195
|
const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER2}/${AGENT_REGISTRY_REPO2}/refs/heads/${AGENT_REGISTRY_BRANCH2}/agents/@${author}/${name}/${name}.af`;
|
|
@@ -504642,7 +505201,7 @@ async function importAgentFromRegistry2(options3) {
|
|
|
504642
505201
|
throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
|
|
504643
505202
|
}
|
|
504644
505203
|
const afContent = await response.text();
|
|
504645
|
-
const tempPath =
|
|
505204
|
+
const tempPath = join64(tmpdir9(), `letta-import-${author}-${name}-${Date.now()}.af`);
|
|
504646
505205
|
await writeFile17(tempPath, afContent, "utf-8");
|
|
504647
505206
|
try {
|
|
504648
505207
|
const result = await importAgentFromFile2({
|
|
@@ -504659,13 +505218,15 @@ async function importAgentFromRegistry2(options3) {
|
|
|
504659
505218
|
} catch {}
|
|
504660
505219
|
}
|
|
504661
505220
|
}
|
|
504662
|
-
var AGENT_REGISTRY_OWNER2 = "letta-ai", AGENT_REGISTRY_REPO2 = "agent-file", AGENT_REGISTRY_BRANCH2 = "main";
|
|
505221
|
+
var IMPORTED_SKILL_NAME_PATTERN2, AGENT_REGISTRY_OWNER2 = "letta-ai", AGENT_REGISTRY_REPO2 = "agent-file", AGENT_REGISTRY_BRANCH2 = "main";
|
|
504663
505222
|
var init_import2 = __esm(() => {
|
|
504664
505223
|
init_backend2();
|
|
504665
505224
|
init_client2();
|
|
505225
|
+
init_validate_skill();
|
|
504666
505226
|
init_create6();
|
|
504667
505227
|
init_model();
|
|
504668
505228
|
init_modify();
|
|
505229
|
+
IMPORTED_SKILL_NAME_PATTERN2 = /^[A-Za-z0-9._-]+$/;
|
|
504669
505230
|
});
|
|
504670
505231
|
|
|
504671
505232
|
// src/agent/memory-filesystem.ts
|
|
@@ -504693,14 +505254,14 @@ __export(exports_memory_filesystem2, {
|
|
|
504693
505254
|
MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR2,
|
|
504694
505255
|
MEMORY_FS_AGENTS_DIR: () => MEMORY_FS_AGENTS_DIR2
|
|
504695
505256
|
});
|
|
504696
|
-
import { existsSync as
|
|
505257
|
+
import { existsSync as existsSync60, mkdirSync as mkdirSync43 } from "node:fs";
|
|
504697
505258
|
import { homedir as homedir43 } from "node:os";
|
|
504698
|
-
import { join as
|
|
505259
|
+
import { join as join64, resolve as resolve41 } from "node:path";
|
|
504699
505260
|
function getMemoryFilesystemRoot2(agentId, homeDir = homedir43()) {
|
|
504700
|
-
return
|
|
505261
|
+
return join64(homeDir, MEMORY_FS_ROOT2, MEMORY_FS_AGENTS_DIR2, agentId, MEMORY_FS_MEMORY_DIR2);
|
|
504701
505262
|
}
|
|
504702
505263
|
function getMemorySystemDir2(agentId, homeDir = homedir43()) {
|
|
504703
|
-
return
|
|
505264
|
+
return join64(getMemoryFilesystemRoot2(agentId, homeDir), MEMORY_SYSTEM_DIR2);
|
|
504704
505265
|
}
|
|
504705
505266
|
function getScopedMemoryFilesystemRoot2(agentId, options3 = {}) {
|
|
504706
505267
|
const env6 = options3.env ?? process.env;
|
|
@@ -504725,7 +505286,7 @@ function resolveScopedMemoryDir2(options3 = {}) {
|
|
|
504725
505286
|
} catch {}
|
|
504726
505287
|
const directMemoryDir = (env6.LETTA_MEMORY_DIR || env6.MEMORY_DIR || "").trim();
|
|
504727
505288
|
if (directMemoryDir) {
|
|
504728
|
-
return
|
|
505289
|
+
return resolve41(directMemoryDir);
|
|
504729
505290
|
}
|
|
504730
505291
|
const envAgentId = (env6.LETTA_AGENT_ID || env6.AGENT_ID || "").trim();
|
|
504731
505292
|
if (envAgentId) {
|
|
@@ -504736,10 +505297,10 @@ function resolveScopedMemoryDir2(options3 = {}) {
|
|
|
504736
505297
|
function ensureMemoryFilesystemDirs2(agentId, homeDir = homedir43()) {
|
|
504737
505298
|
const root2 = getMemoryFilesystemRoot2(agentId, homeDir);
|
|
504738
505299
|
const systemDir = getMemorySystemDir2(agentId, homeDir);
|
|
504739
|
-
if (!
|
|
505300
|
+
if (!existsSync60(root2)) {
|
|
504740
505301
|
mkdirSync43(root2, { recursive: true });
|
|
504741
505302
|
}
|
|
504742
|
-
if (!
|
|
505303
|
+
if (!existsSync60(systemDir)) {
|
|
504743
505304
|
mkdirSync43(systemDir, { recursive: true });
|
|
504744
505305
|
}
|
|
504745
505306
|
}
|
|
@@ -513113,7 +513674,7 @@ function getExplicitAgentId(values2) {
|
|
|
513113
513674
|
const explicitAgent = values2.agent || values2["agent-id"];
|
|
513114
513675
|
return typeof explicitAgent === "string" && explicitAgent.trim() ? explicitAgent.trim() : null;
|
|
513115
513676
|
}
|
|
513116
|
-
function
|
|
513677
|
+
function paginatedItems3(page) {
|
|
513117
513678
|
if (Array.isArray(page))
|
|
513118
513679
|
return page;
|
|
513119
513680
|
const items3 = page.items;
|
|
@@ -513127,7 +513688,7 @@ async function findAgentsByName(name) {
|
|
|
513127
513688
|
limit: 100
|
|
513128
513689
|
});
|
|
513129
513690
|
const normalizedName = name.toLowerCase();
|
|
513130
|
-
return
|
|
513691
|
+
return paginatedItems3(page).filter((agent2) => agent2.name?.toLowerCase() === normalizedName);
|
|
513131
513692
|
}
|
|
513132
513693
|
async function resolveAgentByName(name) {
|
|
513133
513694
|
const matches2 = await findAgentsByName(name);
|
|
@@ -515938,12 +516499,12 @@ EXAMPLES
|
|
|
515938
516499
|
console.log(usage);
|
|
515939
516500
|
}
|
|
515940
516501
|
async function printInfo() {
|
|
515941
|
-
const { join:
|
|
516502
|
+
const { join: join65 } = await import("path");
|
|
515942
516503
|
const { getVersion: getVersion3 } = await Promise.resolve().then(() => (init_version2(), exports_version2));
|
|
515943
516504
|
const { SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills4(), exports_skills3));
|
|
515944
516505
|
const { exists: exists3 } = await Promise.resolve().then(() => (init_fs2(), exports_fs));
|
|
515945
516506
|
const cwd2 = process.cwd();
|
|
515946
|
-
const skillsDir =
|
|
516507
|
+
const skillsDir = join65(cwd2, SKILLS_DIR3);
|
|
515947
516508
|
const skillsExist = exists3(skillsDir);
|
|
515948
516509
|
await settingsManager2.loadLocalProjectSettings(cwd2);
|
|
515949
516510
|
const localPinned = settingsManager2.getLocalPinnedAgents(cwd2);
|
|
@@ -516040,7 +516601,7 @@ async function findLocalAgentsByName(name) {
|
|
|
516040
516601
|
query_text: name,
|
|
516041
516602
|
limit: 100
|
|
516042
516603
|
});
|
|
516043
|
-
return
|
|
516604
|
+
return paginatedItems5(page).filter((agent2) => agent2.name?.toLowerCase() === normalizedName);
|
|
516044
516605
|
} catch {
|
|
516045
516606
|
return [];
|
|
516046
516607
|
}
|
|
@@ -516129,7 +516690,7 @@ async function resolveConversationAcrossBackends(conversationId, backendLookupOr
|
|
|
516129
516690
|
}
|
|
516130
516691
|
return null;
|
|
516131
516692
|
}
|
|
516132
|
-
function
|
|
516693
|
+
function paginatedItems5(page) {
|
|
516133
516694
|
if (Array.isArray(page))
|
|
516134
516695
|
return page;
|
|
516135
516696
|
if (page && typeof page === "object") {
|
|
@@ -516164,7 +516725,7 @@ async function getLocalBackendStartupFallbackSession(backend4) {
|
|
|
516164
516725
|
const candidates2 = [];
|
|
516165
516726
|
try {
|
|
516166
516727
|
const agentsPage = await backend4.listAgents({ limit: 20 });
|
|
516167
|
-
for (const agent2 of
|
|
516728
|
+
for (const agent2 of paginatedItems5(agentsPage)) {
|
|
516168
516729
|
const lastActiveAt = agent2.last_run_completion ?? "";
|
|
516169
516730
|
candidates2.push({ agentId: agent2.id, lastActiveAt });
|
|
516170
516731
|
}
|
|
@@ -516175,7 +516736,7 @@ async function getLocalBackendStartupFallbackSession(backend4) {
|
|
|
516175
516736
|
order: "desc",
|
|
516176
516737
|
order_by: "last_run_completion"
|
|
516177
516738
|
});
|
|
516178
|
-
for (const conversation of
|
|
516739
|
+
for (const conversation of paginatedItems5(conversationsPage)) {
|
|
516179
516740
|
if (!conversation.agent_id)
|
|
516180
516741
|
continue;
|
|
516181
516742
|
candidates2.push({
|
|
@@ -516280,7 +516841,7 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
516280
516841
|
printHelp();
|
|
516281
516842
|
const helpDelayMs = Number.parseInt(process.env.LETTA_TEST_HELP_EXIT_DELAY_MS ?? "", 10);
|
|
516282
516843
|
if (Number.isFinite(helpDelayMs) && helpDelayMs > 0) {
|
|
516283
|
-
await new Promise((
|
|
516844
|
+
await new Promise((resolve42) => setTimeout(resolve42, helpDelayMs));
|
|
516284
516845
|
}
|
|
516285
516846
|
process.exit(0);
|
|
516286
516847
|
}
|
|
@@ -516573,10 +517134,10 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
516573
517134
|
process.exit(1);
|
|
516574
517135
|
}
|
|
516575
517136
|
} else {
|
|
516576
|
-
const { resolve:
|
|
516577
|
-
const { existsSync:
|
|
516578
|
-
const resolvedPath =
|
|
516579
|
-
if (!
|
|
517137
|
+
const { resolve: resolve42 } = await import("path");
|
|
517138
|
+
const { existsSync: existsSync61 } = await import("fs");
|
|
517139
|
+
const resolvedPath = resolve42(fromAfFile);
|
|
517140
|
+
if (!existsSync61(resolvedPath)) {
|
|
516580
517141
|
console.error(`Error: AgentFile not found: ${resolvedPath}`);
|
|
516581
517142
|
process.exit(1);
|
|
516582
517143
|
}
|
|
@@ -517611,4 +518172,4 @@ Error during initialization: ${message}`);
|
|
|
517611
518172
|
}
|
|
517612
518173
|
main2();
|
|
517613
518174
|
|
|
517614
|
-
//# debugId=
|
|
518175
|
+
//# debugId=0B9ED738B787990264756E2164756E21
|