@letta-ai/letta-code 0.16.2 → 0.16.3

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.
Files changed (2) hide show
  1. package/letta.js +1554 -593
  2. package/package.json +4 -1
package/letta.js CHANGED
@@ -3122,7 +3122,7 @@ var package_default;
3122
3122
  var init_package = __esm(() => {
3123
3123
  package_default = {
3124
3124
  name: "@letta-ai/letta-code",
3125
- version: "0.16.2",
3125
+ version: "0.16.3",
3126
3126
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
3127
3127
  type: "module",
3128
3128
  bin: {
@@ -3148,6 +3148,9 @@ var init_package = __esm(() => {
3148
3148
  url: "https://github.com/letta-ai/letta-code.git"
3149
3149
  },
3150
3150
  license: "Apache-2.0",
3151
+ engines: {
3152
+ node: ">=18"
3153
+ },
3151
3154
  publishConfig: {
3152
3155
  access: "public"
3153
3156
  },
@@ -3516,6 +3519,7 @@ var exports_settings_manager = {};
3516
3519
  __export(exports_settings_manager, {
3517
3520
  settingsManager: () => settingsManager
3518
3521
  });
3522
+ import { randomUUID } from "node:crypto";
3519
3523
  import { homedir } from "node:os";
3520
3524
  import { join } from "node:path";
3521
3525
  function isSubagentProcess() {
@@ -3701,7 +3705,7 @@ class SettingsManager {
3701
3705
  const settings = this.getSettings();
3702
3706
  let deviceId = settings.deviceId;
3703
3707
  if (!deviceId) {
3704
- deviceId = crypto.randomUUID();
3708
+ deviceId = randomUUID();
3705
3709
  this.updateSettings({ deviceId });
3706
3710
  }
3707
3711
  return deviceId;
@@ -33034,7 +33038,8 @@ var init_models2 = __esm(() => {
33034
33038
  context_window: 200000,
33035
33039
  max_output_tokens: 128000,
33036
33040
  reasoning_effort: "high",
33037
- enable_reasoner: true
33041
+ enable_reasoner: true,
33042
+ parallel_tool_calls: true
33038
33043
  }
33039
33044
  },
33040
33045
  {
@@ -33046,7 +33051,8 @@ var init_models2 = __esm(() => {
33046
33051
  context_window: 1e6,
33047
33052
  max_output_tokens: 128000,
33048
33053
  reasoning_effort: "high",
33049
- enable_reasoner: true
33054
+ enable_reasoner: true,
33055
+ parallel_tool_calls: true
33050
33056
  }
33051
33057
  },
33052
33058
  {
@@ -33058,7 +33064,8 @@ var init_models2 = __esm(() => {
33058
33064
  context_window: 200000,
33059
33065
  max_output_tokens: 128000,
33060
33066
  reasoning_effort: "none",
33061
- enable_reasoner: false
33067
+ enable_reasoner: false,
33068
+ parallel_tool_calls: true
33062
33069
  }
33063
33070
  },
33064
33071
  {
@@ -33071,7 +33078,8 @@ var init_models2 = __esm(() => {
33071
33078
  max_output_tokens: 128000,
33072
33079
  reasoning_effort: "low",
33073
33080
  enable_reasoner: true,
33074
- max_reasoning_tokens: 4000
33081
+ max_reasoning_tokens: 4000,
33082
+ parallel_tool_calls: true
33075
33083
  }
33076
33084
  },
33077
33085
  {
@@ -33084,7 +33092,8 @@ var init_models2 = __esm(() => {
33084
33092
  max_output_tokens: 128000,
33085
33093
  reasoning_effort: "medium",
33086
33094
  enable_reasoner: true,
33087
- max_reasoning_tokens: 12000
33095
+ max_reasoning_tokens: 12000,
33096
+ parallel_tool_calls: true
33088
33097
  }
33089
33098
  },
33090
33099
  {
@@ -33097,7 +33106,8 @@ var init_models2 = __esm(() => {
33097
33106
  max_output_tokens: 128000,
33098
33107
  reasoning_effort: "xhigh",
33099
33108
  enable_reasoner: true,
33100
- max_reasoning_tokens: 31999
33109
+ max_reasoning_tokens: 31999,
33110
+ parallel_tool_calls: true
33101
33111
  }
33102
33112
  },
33103
33113
  {
@@ -33108,7 +33118,8 @@ var init_models2 = __esm(() => {
33108
33118
  updateArgs: {
33109
33119
  context_window: 180000,
33110
33120
  max_output_tokens: 64000,
33111
- max_reasoning_tokens: 31999
33121
+ max_reasoning_tokens: 31999,
33122
+ parallel_tool_calls: true
33112
33123
  }
33113
33124
  },
33114
33125
  {
@@ -33119,7 +33130,8 @@ var init_models2 = __esm(() => {
33119
33130
  updateArgs: {
33120
33131
  enable_reasoner: false,
33121
33132
  context_window: 180000,
33122
- max_output_tokens: 64000
33133
+ max_output_tokens: 64000,
33134
+ parallel_tool_calls: true
33123
33135
  }
33124
33136
  },
33125
33137
  {
@@ -33132,7 +33144,8 @@ var init_models2 = __esm(() => {
33132
33144
  context_window: 200000,
33133
33145
  max_output_tokens: 128000,
33134
33146
  reasoning_effort: "high",
33135
- enable_reasoner: true
33147
+ enable_reasoner: true,
33148
+ parallel_tool_calls: true
33136
33149
  }
33137
33150
  },
33138
33151
  {
@@ -33144,7 +33157,8 @@ var init_models2 = __esm(() => {
33144
33157
  context_window: 200000,
33145
33158
  max_output_tokens: 128000,
33146
33159
  reasoning_effort: "none",
33147
- enable_reasoner: false
33160
+ enable_reasoner: false,
33161
+ parallel_tool_calls: true
33148
33162
  }
33149
33163
  },
33150
33164
  {
@@ -33157,7 +33171,8 @@ var init_models2 = __esm(() => {
33157
33171
  max_output_tokens: 128000,
33158
33172
  reasoning_effort: "low",
33159
33173
  enable_reasoner: true,
33160
- max_reasoning_tokens: 4000
33174
+ max_reasoning_tokens: 4000,
33175
+ parallel_tool_calls: true
33161
33176
  }
33162
33177
  },
33163
33178
  {
@@ -33170,7 +33185,8 @@ var init_models2 = __esm(() => {
33170
33185
  max_output_tokens: 128000,
33171
33186
  reasoning_effort: "medium",
33172
33187
  enable_reasoner: true,
33173
- max_reasoning_tokens: 12000
33188
+ max_reasoning_tokens: 12000,
33189
+ parallel_tool_calls: true
33174
33190
  }
33175
33191
  },
33176
33192
  {
@@ -33183,7 +33199,8 @@ var init_models2 = __esm(() => {
33183
33199
  max_output_tokens: 128000,
33184
33200
  reasoning_effort: "xhigh",
33185
33201
  enable_reasoner: true,
33186
- max_reasoning_tokens: 31999
33202
+ max_reasoning_tokens: 31999,
33203
+ parallel_tool_calls: true
33187
33204
  }
33188
33205
  },
33189
33206
  {
@@ -33194,7 +33211,8 @@ var init_models2 = __esm(() => {
33194
33211
  updateArgs: {
33195
33212
  context_window: 180000,
33196
33213
  max_output_tokens: 64000,
33197
- max_reasoning_tokens: 31999
33214
+ max_reasoning_tokens: 31999,
33215
+ parallel_tool_calls: true
33198
33216
  }
33199
33217
  },
33200
33218
  {
@@ -33207,7 +33225,8 @@ var init_models2 = __esm(() => {
33207
33225
  updateArgs: {
33208
33226
  context_window: 180000,
33209
33227
  max_output_tokens: 64000,
33210
- max_reasoning_tokens: 31999
33228
+ max_reasoning_tokens: 31999,
33229
+ parallel_tool_calls: true
33211
33230
  }
33212
33231
  },
33213
33232
  {
@@ -33218,7 +33237,8 @@ var init_models2 = __esm(() => {
33218
33237
  isFeatured: true,
33219
33238
  updateArgs: {
33220
33239
  context_window: 180000,
33221
- max_output_tokens: 64000
33240
+ max_output_tokens: 64000,
33241
+ parallel_tool_calls: true
33222
33242
  }
33223
33243
  },
33224
33244
  {
@@ -33230,7 +33250,8 @@ var init_models2 = __esm(() => {
33230
33250
  reasoning_effort: "none",
33231
33251
  verbosity: "low",
33232
33252
  context_window: 272000,
33233
- max_output_tokens: 128000
33253
+ max_output_tokens: 128000,
33254
+ parallel_tool_calls: true
33234
33255
  }
33235
33256
  },
33236
33257
  {
@@ -33242,7 +33263,8 @@ var init_models2 = __esm(() => {
33242
33263
  reasoning_effort: "low",
33243
33264
  verbosity: "low",
33244
33265
  context_window: 272000,
33245
- max_output_tokens: 128000
33266
+ max_output_tokens: 128000,
33267
+ parallel_tool_calls: true
33246
33268
  }
33247
33269
  },
33248
33270
  {
@@ -33254,7 +33276,8 @@ var init_models2 = __esm(() => {
33254
33276
  reasoning_effort: "medium",
33255
33277
  verbosity: "low",
33256
33278
  context_window: 272000,
33257
- max_output_tokens: 128000
33279
+ max_output_tokens: 128000,
33280
+ parallel_tool_calls: true
33258
33281
  }
33259
33282
  },
33260
33283
  {
@@ -33267,7 +33290,8 @@ var init_models2 = __esm(() => {
33267
33290
  reasoning_effort: "high",
33268
33291
  verbosity: "low",
33269
33292
  context_window: 272000,
33270
- max_output_tokens: 128000
33293
+ max_output_tokens: 128000,
33294
+ parallel_tool_calls: true
33271
33295
  }
33272
33296
  },
33273
33297
  {
@@ -33279,7 +33303,8 @@ var init_models2 = __esm(() => {
33279
33303
  reasoning_effort: "xhigh",
33280
33304
  verbosity: "low",
33281
33305
  context_window: 272000,
33282
- max_output_tokens: 128000
33306
+ max_output_tokens: 128000,
33307
+ parallel_tool_calls: true
33283
33308
  }
33284
33309
  },
33285
33310
  {
@@ -33291,7 +33316,8 @@ var init_models2 = __esm(() => {
33291
33316
  reasoning_effort: "medium",
33292
33317
  verbosity: "medium",
33293
33318
  context_window: 272000,
33294
- max_output_tokens: 128000
33319
+ max_output_tokens: 128000,
33320
+ parallel_tool_calls: true
33295
33321
  }
33296
33322
  },
33297
33323
  {
@@ -33303,7 +33329,8 @@ var init_models2 = __esm(() => {
33303
33329
  reasoning_effort: "high",
33304
33330
  verbosity: "medium",
33305
33331
  context_window: 272000,
33306
- max_output_tokens: 128000
33332
+ max_output_tokens: 128000,
33333
+ parallel_tool_calls: true
33307
33334
  }
33308
33335
  },
33309
33336
  {
@@ -33315,7 +33342,8 @@ var init_models2 = __esm(() => {
33315
33342
  reasoning_effort: "medium",
33316
33343
  verbosity: "medium",
33317
33344
  context_window: 272000,
33318
- max_output_tokens: 128000
33345
+ max_output_tokens: 128000,
33346
+ parallel_tool_calls: true
33319
33347
  }
33320
33348
  },
33321
33349
  {
@@ -33327,7 +33355,8 @@ var init_models2 = __esm(() => {
33327
33355
  reasoning_effort: "high",
33328
33356
  verbosity: "medium",
33329
33357
  context_window: 272000,
33330
- max_output_tokens: 128000
33358
+ max_output_tokens: 128000,
33359
+ parallel_tool_calls: true
33331
33360
  }
33332
33361
  },
33333
33362
  {
@@ -33339,7 +33368,8 @@ var init_models2 = __esm(() => {
33339
33368
  reasoning_effort: "medium",
33340
33369
  verbosity: "medium",
33341
33370
  context_window: 272000,
33342
- max_output_tokens: 128000
33371
+ max_output_tokens: 128000,
33372
+ parallel_tool_calls: true
33343
33373
  }
33344
33374
  },
33345
33375
  {
@@ -33351,7 +33381,8 @@ var init_models2 = __esm(() => {
33351
33381
  reasoning_effort: "high",
33352
33382
  verbosity: "medium",
33353
33383
  context_window: 272000,
33354
- max_output_tokens: 128000
33384
+ max_output_tokens: 128000,
33385
+ parallel_tool_calls: true
33355
33386
  }
33356
33387
  },
33357
33388
  {
@@ -33363,7 +33394,8 @@ var init_models2 = __esm(() => {
33363
33394
  reasoning_effort: "medium",
33364
33395
  verbosity: "medium",
33365
33396
  context_window: 272000,
33366
- max_output_tokens: 128000
33397
+ max_output_tokens: 128000,
33398
+ parallel_tool_calls: true
33367
33399
  }
33368
33400
  },
33369
33401
  {
@@ -33375,7 +33407,8 @@ var init_models2 = __esm(() => {
33375
33407
  reasoning_effort: "high",
33376
33408
  verbosity: "medium",
33377
33409
  context_window: 272000,
33378
- max_output_tokens: 128000
33410
+ max_output_tokens: 128000,
33411
+ parallel_tool_calls: true
33379
33412
  }
33380
33413
  },
33381
33414
  {
@@ -33387,7 +33420,8 @@ var init_models2 = __esm(() => {
33387
33420
  reasoning_effort: "xhigh",
33388
33421
  verbosity: "medium",
33389
33422
  context_window: 272000,
33390
- max_output_tokens: 128000
33423
+ max_output_tokens: 128000,
33424
+ parallel_tool_calls: true
33391
33425
  }
33392
33426
  },
33393
33427
  {
@@ -33399,7 +33433,8 @@ var init_models2 = __esm(() => {
33399
33433
  reasoning_effort: "medium",
33400
33434
  verbosity: "medium",
33401
33435
  context_window: 272000,
33402
- max_output_tokens: 128000
33436
+ max_output_tokens: 128000,
33437
+ parallel_tool_calls: true
33403
33438
  }
33404
33439
  },
33405
33440
  {
@@ -33411,7 +33446,8 @@ var init_models2 = __esm(() => {
33411
33446
  reasoning_effort: "none",
33412
33447
  verbosity: "medium",
33413
33448
  context_window: 272000,
33414
- max_output_tokens: 128000
33449
+ max_output_tokens: 128000,
33450
+ parallel_tool_calls: true
33415
33451
  }
33416
33452
  },
33417
33453
  {
@@ -33423,7 +33459,8 @@ var init_models2 = __esm(() => {
33423
33459
  reasoning_effort: "low",
33424
33460
  verbosity: "medium",
33425
33461
  context_window: 272000,
33426
- max_output_tokens: 128000
33462
+ max_output_tokens: 128000,
33463
+ parallel_tool_calls: true
33427
33464
  }
33428
33465
  },
33429
33466
  {
@@ -33436,7 +33473,8 @@ var init_models2 = __esm(() => {
33436
33473
  reasoning_effort: "medium",
33437
33474
  verbosity: "medium",
33438
33475
  context_window: 272000,
33439
- max_output_tokens: 128000
33476
+ max_output_tokens: 128000,
33477
+ parallel_tool_calls: true
33440
33478
  }
33441
33479
  },
33442
33480
  {
@@ -33448,7 +33486,8 @@ var init_models2 = __esm(() => {
33448
33486
  reasoning_effort: "high",
33449
33487
  verbosity: "medium",
33450
33488
  context_window: 272000,
33451
- max_output_tokens: 128000
33489
+ max_output_tokens: 128000,
33490
+ parallel_tool_calls: true
33452
33491
  }
33453
33492
  },
33454
33493
  {
@@ -33460,7 +33499,8 @@ var init_models2 = __esm(() => {
33460
33499
  reasoning_effort: "xhigh",
33461
33500
  verbosity: "medium",
33462
33501
  context_window: 272000,
33463
- max_output_tokens: 128000
33502
+ max_output_tokens: 128000,
33503
+ parallel_tool_calls: true
33464
33504
  }
33465
33505
  },
33466
33506
  {
@@ -33472,7 +33512,8 @@ var init_models2 = __esm(() => {
33472
33512
  reasoning_effort: "none",
33473
33513
  verbosity: "medium",
33474
33514
  context_window: 272000,
33475
- max_output_tokens: 128000
33515
+ max_output_tokens: 128000,
33516
+ parallel_tool_calls: true
33476
33517
  }
33477
33518
  },
33478
33519
  {
@@ -33484,7 +33525,8 @@ var init_models2 = __esm(() => {
33484
33525
  reasoning_effort: "low",
33485
33526
  verbosity: "medium",
33486
33527
  context_window: 272000,
33487
- max_output_tokens: 128000
33528
+ max_output_tokens: 128000,
33529
+ parallel_tool_calls: true
33488
33530
  }
33489
33531
  },
33490
33532
  {
@@ -33497,7 +33539,8 @@ var init_models2 = __esm(() => {
33497
33539
  reasoning_effort: "medium",
33498
33540
  verbosity: "medium",
33499
33541
  context_window: 272000,
33500
- max_output_tokens: 128000
33542
+ max_output_tokens: 128000,
33543
+ parallel_tool_calls: true
33501
33544
  }
33502
33545
  },
33503
33546
  {
@@ -33509,7 +33552,8 @@ var init_models2 = __esm(() => {
33509
33552
  reasoning_effort: "high",
33510
33553
  verbosity: "medium",
33511
33554
  context_window: 272000,
33512
- max_output_tokens: 128000
33555
+ max_output_tokens: 128000,
33556
+ parallel_tool_calls: true
33513
33557
  }
33514
33558
  },
33515
33559
  {
@@ -33521,7 +33565,8 @@ var init_models2 = __esm(() => {
33521
33565
  reasoning_effort: "xhigh",
33522
33566
  verbosity: "medium",
33523
33567
  context_window: 272000,
33524
- max_output_tokens: 128000
33568
+ max_output_tokens: 128000,
33569
+ parallel_tool_calls: true
33525
33570
  }
33526
33571
  },
33527
33572
  {
@@ -33533,7 +33578,8 @@ var init_models2 = __esm(() => {
33533
33578
  reasoning_effort: "none",
33534
33579
  verbosity: "medium",
33535
33580
  context_window: 272000,
33536
- max_output_tokens: 128000
33581
+ max_output_tokens: 128000,
33582
+ parallel_tool_calls: true
33537
33583
  }
33538
33584
  },
33539
33585
  {
@@ -33545,7 +33591,8 @@ var init_models2 = __esm(() => {
33545
33591
  reasoning_effort: "low",
33546
33592
  verbosity: "medium",
33547
33593
  context_window: 272000,
33548
- max_output_tokens: 128000
33594
+ max_output_tokens: 128000,
33595
+ parallel_tool_calls: true
33549
33596
  }
33550
33597
  },
33551
33598
  {
@@ -33557,7 +33604,8 @@ var init_models2 = __esm(() => {
33557
33604
  reasoning_effort: "medium",
33558
33605
  verbosity: "medium",
33559
33606
  context_window: 272000,
33560
- max_output_tokens: 128000
33607
+ max_output_tokens: 128000,
33608
+ parallel_tool_calls: true
33561
33609
  }
33562
33610
  },
33563
33611
  {
@@ -33569,7 +33617,8 @@ var init_models2 = __esm(() => {
33569
33617
  reasoning_effort: "high",
33570
33618
  verbosity: "medium",
33571
33619
  context_window: 272000,
33572
- max_output_tokens: 128000
33620
+ max_output_tokens: 128000,
33621
+ parallel_tool_calls: true
33573
33622
  }
33574
33623
  },
33575
33624
  {
@@ -33581,7 +33630,8 @@ var init_models2 = __esm(() => {
33581
33630
  reasoning_effort: "none",
33582
33631
  verbosity: "medium",
33583
33632
  context_window: 272000,
33584
- max_output_tokens: 128000
33633
+ max_output_tokens: 128000,
33634
+ parallel_tool_calls: true
33585
33635
  }
33586
33636
  },
33587
33637
  {
@@ -33594,7 +33644,8 @@ var init_models2 = __esm(() => {
33594
33644
  reasoning_effort: "medium",
33595
33645
  verbosity: "medium",
33596
33646
  context_window: 272000,
33597
- max_output_tokens: 128000
33647
+ max_output_tokens: 128000,
33648
+ parallel_tool_calls: true
33598
33649
  }
33599
33650
  },
33600
33651
  {
@@ -33606,7 +33657,8 @@ var init_models2 = __esm(() => {
33606
33657
  reasoning_effort: "high",
33607
33658
  verbosity: "medium",
33608
33659
  context_window: 272000,
33609
- max_output_tokens: 128000
33660
+ max_output_tokens: 128000,
33661
+ parallel_tool_calls: true
33610
33662
  }
33611
33663
  },
33612
33664
  {
@@ -33618,7 +33670,8 @@ var init_models2 = __esm(() => {
33618
33670
  reasoning_effort: "medium",
33619
33671
  verbosity: "medium",
33620
33672
  context_window: 272000,
33621
- max_output_tokens: 128000
33673
+ max_output_tokens: 128000,
33674
+ parallel_tool_calls: true
33622
33675
  }
33623
33676
  },
33624
33677
  {
@@ -33630,7 +33683,8 @@ var init_models2 = __esm(() => {
33630
33683
  reasoning_effort: "high",
33631
33684
  verbosity: "medium",
33632
33685
  context_window: 272000,
33633
- max_output_tokens: 128000
33686
+ max_output_tokens: 128000,
33687
+ parallel_tool_calls: true
33634
33688
  }
33635
33689
  },
33636
33690
  {
@@ -33642,7 +33696,8 @@ var init_models2 = __esm(() => {
33642
33696
  reasoning_effort: "xhigh",
33643
33697
  verbosity: "medium",
33644
33698
  context_window: 272000,
33645
- max_output_tokens: 128000
33699
+ max_output_tokens: 128000,
33700
+ parallel_tool_calls: true
33646
33701
  }
33647
33702
  },
33648
33703
  {
@@ -33654,7 +33709,8 @@ var init_models2 = __esm(() => {
33654
33709
  reasoning_effort: "minimal",
33655
33710
  verbosity: "medium",
33656
33711
  context_window: 272000,
33657
- max_output_tokens: 128000
33712
+ max_output_tokens: 128000,
33713
+ parallel_tool_calls: true
33658
33714
  }
33659
33715
  },
33660
33716
  {
@@ -33666,7 +33722,8 @@ var init_models2 = __esm(() => {
33666
33722
  reasoning_effort: "low",
33667
33723
  verbosity: "medium",
33668
33724
  context_window: 272000,
33669
- max_output_tokens: 128000
33725
+ max_output_tokens: 128000,
33726
+ parallel_tool_calls: true
33670
33727
  }
33671
33728
  },
33672
33729
  {
@@ -33678,7 +33735,8 @@ var init_models2 = __esm(() => {
33678
33735
  reasoning_effort: "medium",
33679
33736
  verbosity: "medium",
33680
33737
  context_window: 272000,
33681
- max_output_tokens: 128000
33738
+ max_output_tokens: 128000,
33739
+ parallel_tool_calls: true
33682
33740
  }
33683
33741
  },
33684
33742
  {
@@ -33690,7 +33748,8 @@ var init_models2 = __esm(() => {
33690
33748
  reasoning_effort: "high",
33691
33749
  verbosity: "medium",
33692
33750
  context_window: 272000,
33693
- max_output_tokens: 128000
33751
+ max_output_tokens: 128000,
33752
+ parallel_tool_calls: true
33694
33753
  }
33695
33754
  },
33696
33755
  {
@@ -33702,7 +33761,8 @@ var init_models2 = __esm(() => {
33702
33761
  reasoning_effort: "medium",
33703
33762
  verbosity: "medium",
33704
33763
  context_window: 272000,
33705
- max_output_tokens: 128000
33764
+ max_output_tokens: 128000,
33765
+ parallel_tool_calls: true
33706
33766
  }
33707
33767
  },
33708
33768
  {
@@ -33714,7 +33774,8 @@ var init_models2 = __esm(() => {
33714
33774
  reasoning_effort: "medium",
33715
33775
  verbosity: "medium",
33716
33776
  context_window: 272000,
33717
- max_output_tokens: 128000
33777
+ max_output_tokens: 128000,
33778
+ parallel_tool_calls: true
33718
33779
  }
33719
33780
  },
33720
33781
  {
@@ -33725,7 +33786,8 @@ var init_models2 = __esm(() => {
33725
33786
  isFeatured: true,
33726
33787
  free: true,
33727
33788
  updateArgs: {
33728
- context_window: 200000
33789
+ context_window: 200000,
33790
+ parallel_tool_calls: true
33729
33791
  }
33730
33792
  },
33731
33793
  {
@@ -33736,7 +33798,8 @@ var init_models2 = __esm(() => {
33736
33798
  isFeatured: true,
33737
33799
  free: true,
33738
33800
  updateArgs: {
33739
- context_window: 200000
33801
+ context_window: 200000,
33802
+ parallel_tool_calls: true
33740
33803
  }
33741
33804
  },
33742
33805
  {
@@ -33748,7 +33811,8 @@ var init_models2 = __esm(() => {
33748
33811
  free: true,
33749
33812
  updateArgs: {
33750
33813
  context_window: 160000,
33751
- max_output_tokens: 64000
33814
+ max_output_tokens: 64000,
33815
+ parallel_tool_calls: true
33752
33816
  }
33753
33817
  },
33754
33818
  {
@@ -33760,7 +33824,8 @@ var init_models2 = __esm(() => {
33760
33824
  free: true,
33761
33825
  updateArgs: {
33762
33826
  context_window: 160000,
33763
- max_output_tokens: 64000
33827
+ max_output_tokens: 64000,
33828
+ parallel_tool_calls: true
33764
33829
  }
33765
33830
  },
33766
33831
  {
@@ -33770,7 +33835,8 @@ var init_models2 = __esm(() => {
33770
33835
  description: "Minimax's latest model",
33771
33836
  updateArgs: {
33772
33837
  context_window: 160000,
33773
- max_output_tokens: 64000
33838
+ max_output_tokens: 64000,
33839
+ parallel_tool_calls: true
33774
33840
  }
33775
33841
  },
33776
33842
  {
@@ -33779,7 +33845,8 @@ var init_models2 = __esm(() => {
33779
33845
  label: "Kimi K2",
33780
33846
  description: "Kimi's K2 model",
33781
33847
  updateArgs: {
33782
- context_window: 262144
33848
+ context_window: 262144,
33849
+ parallel_tool_calls: true
33783
33850
  }
33784
33851
  },
33785
33852
  {
@@ -33790,7 +33857,8 @@ var init_models2 = __esm(() => {
33790
33857
  updateArgs: {
33791
33858
  context_window: 256000,
33792
33859
  max_output_tokens: 16000,
33793
- temperature: 1
33860
+ temperature: 1,
33861
+ parallel_tool_calls: true
33794
33862
  }
33795
33863
  },
33796
33864
  {
@@ -33800,7 +33868,8 @@ var init_models2 = __esm(() => {
33800
33868
  description: "Kimi's latest coding model",
33801
33869
  isFeatured: true,
33802
33870
  updateArgs: {
33803
- context_window: 262144
33871
+ context_window: 262144,
33872
+ parallel_tool_calls: true
33804
33873
  }
33805
33874
  },
33806
33875
  {
@@ -33809,7 +33878,8 @@ var init_models2 = __esm(() => {
33809
33878
  label: "DeepSeek Chat V3.1",
33810
33879
  description: "DeepSeek V3.1 model",
33811
33880
  updateArgs: {
33812
- context_window: 128000
33881
+ context_window: 128000,
33882
+ parallel_tool_calls: true
33813
33883
  }
33814
33884
  },
33815
33885
  {
@@ -33818,7 +33888,11 @@ var init_models2 = __esm(() => {
33818
33888
  label: "Gemini 3.1 Pro",
33819
33889
  description: "Google's latest and smartest model",
33820
33890
  isFeatured: true,
33821
- updateArgs: { context_window: 180000, temperature: 1 }
33891
+ updateArgs: {
33892
+ context_window: 180000,
33893
+ temperature: 1,
33894
+ parallel_tool_calls: true
33895
+ }
33822
33896
  },
33823
33897
  {
33824
33898
  id: "gemini-3",
@@ -33826,7 +33900,11 @@ var init_models2 = __esm(() => {
33826
33900
  label: "Gemini 3 Pro",
33827
33901
  description: "Google's smartest model",
33828
33902
  isFeatured: true,
33829
- updateArgs: { context_window: 180000, temperature: 1 }
33903
+ updateArgs: {
33904
+ context_window: 180000,
33905
+ temperature: 1,
33906
+ parallel_tool_calls: true
33907
+ }
33830
33908
  },
33831
33909
  {
33832
33910
  id: "gemini-3-flash",
@@ -33834,60 +33912,222 @@ var init_models2 = __esm(() => {
33834
33912
  label: "Gemini 3 Flash",
33835
33913
  description: "Google's fastest Gemini 3 model",
33836
33914
  isFeatured: true,
33837
- updateArgs: { context_window: 180000, temperature: 1 }
33915
+ updateArgs: {
33916
+ context_window: 180000,
33917
+ temperature: 1,
33918
+ parallel_tool_calls: true
33919
+ }
33838
33920
  },
33839
33921
  {
33840
33922
  id: "gemini-flash",
33841
33923
  handle: "google_ai/gemini-2.5-flash",
33842
33924
  label: "Gemini 2.5 Flash",
33843
33925
  description: "Google's fastest model",
33844
- updateArgs: { context_window: 180000 }
33926
+ updateArgs: { context_window: 180000, parallel_tool_calls: true }
33845
33927
  },
33846
33928
  {
33847
33929
  id: "gemini-pro",
33848
33930
  handle: "google_ai/gemini-2.5-pro",
33849
33931
  label: "Gemini 2.5 Pro",
33850
33932
  description: "Google's last generation flagship model",
33851
- updateArgs: { context_window: 180000 }
33933
+ updateArgs: { context_window: 180000, parallel_tool_calls: true }
33852
33934
  },
33853
33935
  {
33854
33936
  id: "gpt-4.1",
33855
33937
  handle: "openai/gpt-4.1",
33856
33938
  label: "GPT-4.1",
33857
33939
  description: "OpenAI's most recent non-reasoner model",
33858
- updateArgs: { context_window: 1047576 }
33940
+ updateArgs: { context_window: 1047576, parallel_tool_calls: true }
33859
33941
  },
33860
33942
  {
33861
33943
  id: "gpt-4.1-mini",
33862
33944
  handle: "openai/gpt-4.1-mini-2025-04-14",
33863
33945
  label: "GPT-4.1-Mini",
33864
33946
  description: "OpenAI's most recent non-reasoner model (mini version)",
33865
- updateArgs: { context_window: 1047576 }
33947
+ updateArgs: { context_window: 1047576, parallel_tool_calls: true }
33866
33948
  },
33867
33949
  {
33868
33950
  id: "gpt-4.1-nano",
33869
33951
  handle: "openai/gpt-4.1-nano-2025-04-14",
33870
33952
  label: "GPT-4.1-Nano",
33871
33953
  description: "OpenAI's most recent non-reasoner model (nano version)",
33872
- updateArgs: { context_window: 1047576 }
33954
+ updateArgs: { context_window: 1047576, parallel_tool_calls: true }
33873
33955
  },
33874
33956
  {
33875
33957
  id: "o4-mini",
33876
33958
  handle: "openai/o4-mini",
33877
33959
  label: "o4-mini",
33878
33960
  description: "OpenAI's latest o-series reasoning model",
33879
- updateArgs: { context_window: 180000 }
33961
+ updateArgs: { context_window: 180000, parallel_tool_calls: true }
33880
33962
  },
33881
33963
  {
33882
33964
  id: "gemini-3-vertex",
33883
33965
  handle: "google_vertex/gemini-3-pro-preview",
33884
33966
  label: "Gemini 3 Pro",
33885
33967
  description: "Google's smartest Gemini 3 Pro model (via Vertex AI)",
33886
- updateArgs: { context_window: 180000, temperature: 1 }
33968
+ updateArgs: {
33969
+ context_window: 180000,
33970
+ temperature: 1,
33971
+ parallel_tool_calls: true
33972
+ }
33887
33973
  }
33888
33974
  ];
33889
33975
  });
33890
33976
 
33977
+ // src/agent/http-headers.ts
33978
+ function getLettaCodeHeaders2(apiKey) {
33979
+ return {
33980
+ "Content-Type": "application/json",
33981
+ "User-Agent": `letta-code/${package_default.version}`,
33982
+ "X-Letta-Source": "letta-code",
33983
+ ...apiKey ? { Authorization: `Bearer ${apiKey}` } : {}
33984
+ };
33985
+ }
33986
+ function getMcpOAuthHeaders(apiKey) {
33987
+ return {
33988
+ ...getLettaCodeHeaders2(apiKey),
33989
+ Accept: "text/event-stream"
33990
+ };
33991
+ }
33992
+ var init_http_headers = __esm(() => {
33993
+ init_package();
33994
+ });
33995
+
33996
+ // src/providers/openai-codex-provider.ts
33997
+ var exports_openai_codex_provider = {};
33998
+ __export(exports_openai_codex_provider, {
33999
+ updateOpenAICodexProvider: () => updateOpenAICodexProvider,
34000
+ removeOpenAICodexProvider: () => removeOpenAICodexProvider,
34001
+ listProviders: () => listProviders,
34002
+ getOpenAICodexProvider: () => getOpenAICodexProvider,
34003
+ deleteOpenAICodexProvider: () => deleteOpenAICodexProvider,
34004
+ createOrUpdateOpenAICodexProvider: () => createOrUpdateOpenAICodexProvider,
34005
+ createOpenAICodexProvider: () => createOpenAICodexProvider,
34006
+ checkOpenAICodexEligibility: () => checkOpenAICodexEligibility,
34007
+ OPENAI_CODEX_PROVIDER_NAME: () => OPENAI_CODEX_PROVIDER_NAME,
34008
+ CHATGPT_OAUTH_PROVIDER_TYPE: () => CHATGPT_OAUTH_PROVIDER_TYPE
34009
+ });
34010
+ async function getLettaConfig() {
34011
+ const settings = await settingsManager.getSettingsWithSecureTokens();
34012
+ const baseUrl = process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
34013
+ const apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY || "";
34014
+ return { baseUrl, apiKey };
34015
+ }
34016
+ async function providersRequest(method, path2, body) {
34017
+ const { baseUrl, apiKey } = await getLettaConfig();
34018
+ const url = `${baseUrl}${path2}`;
34019
+ const response = await fetch(url, {
34020
+ method,
34021
+ headers: getLettaCodeHeaders2(apiKey),
34022
+ ...body && { body: JSON.stringify(body) }
34023
+ });
34024
+ if (!response.ok) {
34025
+ const errorText = await response.text();
34026
+ if (response.status === 403) {
34027
+ try {
34028
+ const errorData = JSON.parse(errorText);
34029
+ if (errorData.error && typeof errorData.error === "string" && errorData.error.includes("only available for pro or enterprise")) {
34030
+ throw new Error("PLAN_UPGRADE_REQUIRED");
34031
+ }
34032
+ } catch (parseError) {
34033
+ if (parseError instanceof Error && parseError.message === "PLAN_UPGRADE_REQUIRED") {
34034
+ throw parseError;
34035
+ }
34036
+ }
34037
+ }
34038
+ throw new Error(`Provider API error (${response.status}): ${errorText}`);
34039
+ }
34040
+ const text = await response.text();
34041
+ if (!text) {
34042
+ return {};
34043
+ }
34044
+ return JSON.parse(text);
34045
+ }
34046
+ async function listProviders() {
34047
+ try {
34048
+ const response = await providersRequest("GET", "/v1/providers");
34049
+ return response;
34050
+ } catch {
34051
+ return [];
34052
+ }
34053
+ }
34054
+ async function getOpenAICodexProvider() {
34055
+ const providers = await listProviders();
34056
+ return providers.find((p) => p.name === OPENAI_CODEX_PROVIDER_NAME) || null;
34057
+ }
34058
+ async function createOpenAICodexProvider(config) {
34059
+ const apiKeyJson = JSON.stringify({
34060
+ access_token: config.access_token,
34061
+ id_token: config.id_token,
34062
+ refresh_token: config.refresh_token,
34063
+ account_id: config.account_id,
34064
+ expires_at: config.expires_at
34065
+ });
34066
+ return providersRequest("POST", "/v1/providers", {
34067
+ name: OPENAI_CODEX_PROVIDER_NAME,
34068
+ provider_type: CHATGPT_OAUTH_PROVIDER_TYPE,
34069
+ api_key: apiKeyJson
34070
+ });
34071
+ }
34072
+ async function updateOpenAICodexProvider(providerId, config) {
34073
+ const apiKeyJson = JSON.stringify({
34074
+ access_token: config.access_token,
34075
+ id_token: config.id_token,
34076
+ refresh_token: config.refresh_token,
34077
+ account_id: config.account_id,
34078
+ expires_at: config.expires_at
34079
+ });
34080
+ return providersRequest("PATCH", `/v1/providers/${providerId}`, {
34081
+ api_key: apiKeyJson
34082
+ });
34083
+ }
34084
+ async function deleteOpenAICodexProvider(providerId) {
34085
+ await providersRequest("DELETE", `/v1/providers/${providerId}`);
34086
+ }
34087
+ async function createOrUpdateOpenAICodexProvider(config) {
34088
+ const existing = await getOpenAICodexProvider();
34089
+ if (existing) {
34090
+ return updateOpenAICodexProvider(existing.id, config);
34091
+ } else {
34092
+ return createOpenAICodexProvider(config);
34093
+ }
34094
+ }
34095
+ async function removeOpenAICodexProvider() {
34096
+ const existing = await getOpenAICodexProvider();
34097
+ if (existing) {
34098
+ await deleteOpenAICodexProvider(existing.id);
34099
+ }
34100
+ }
34101
+ async function checkOpenAICodexEligibility() {
34102
+ try {
34103
+ const balance = await providersRequest("GET", "/v1/metadata/balance");
34104
+ const billingTier = balance.billing_tier.toLowerCase();
34105
+ if (billingTier === "pro" || billingTier === "enterprise") {
34106
+ return {
34107
+ eligible: true,
34108
+ billing_tier: balance.billing_tier
34109
+ };
34110
+ }
34111
+ return {
34112
+ eligible: false,
34113
+ billing_tier: balance.billing_tier,
34114
+ reason: `ChatGPT OAuth requires a Pro or Enterprise plan. Current plan: ${balance.billing_tier}`
34115
+ };
34116
+ } catch (error) {
34117
+ console.warn("Failed to check ChatGPT OAuth eligibility:", error);
34118
+ return {
34119
+ eligible: true,
34120
+ billing_tier: "unknown"
34121
+ };
34122
+ }
34123
+ }
34124
+ var OPENAI_CODEX_PROVIDER_NAME = "chatgpt-plus-pro", CHATGPT_OAUTH_PROVIDER_TYPE = "chatgpt_oauth";
34125
+ var init_openai_codex_provider = __esm(async () => {
34126
+ init_http_headers();
34127
+ init_oauth();
34128
+ await init_settings_manager();
34129
+ });
34130
+
33891
34131
  // src/agent/model.ts
33892
34132
  var exports_model = {};
33893
34133
  __export(exports_model, {
@@ -33897,6 +34137,7 @@ __export(exports_model, {
33897
34137
  getReasoningTierOptionsForHandle: () => getReasoningTierOptionsForHandle,
33898
34138
  getModelUpdateArgs: () => getModelUpdateArgs,
33899
34139
  getModelShortName: () => getModelShortName,
34140
+ getModelPresetUpdateForAgent: () => getModelPresetUpdateForAgent,
33900
34141
  getModelInfoForLlmConfig: () => getModelInfoForLlmConfig,
33901
34142
  getModelInfo: () => getModelInfo,
33902
34143
  getModelDisplayName: () => getModelDisplayName,
@@ -33992,6 +34233,27 @@ function getModelUpdateArgs(modelIdentifier) {
33992
34233
  const modelInfo = getModelInfo(modelIdentifier);
33993
34234
  return modelInfo?.updateArgs;
33994
34235
  }
34236
+ function getModelPresetUpdateForAgent(agent) {
34237
+ const directHandle = typeof agent.model === "string" && agent.model.length > 0 ? agent.model : null;
34238
+ const endpointType = agent.llm_config?.model_endpoint_type;
34239
+ const llmModel = agent.llm_config?.model;
34240
+ const llmDerivedHandle = typeof endpointType === "string" && endpointType.length > 0 && typeof llmModel === "string" && llmModel.length > 0 ? `${endpointType === "chatgpt_oauth" ? OPENAI_CODEX_PROVIDER_NAME : endpointType}/${llmModel}` : typeof llmModel === "string" && llmModel.includes("/") ? llmModel : null;
34241
+ const modelHandle = directHandle ?? llmDerivedHandle;
34242
+ if (!modelHandle)
34243
+ return null;
34244
+ const modelInfo = getModelInfoForLlmConfig(modelHandle, {
34245
+ reasoning_effort: agent.llm_config?.reasoning_effort ?? null,
34246
+ enable_reasoner: agent.llm_config?.enable_reasoner ?? null
34247
+ });
34248
+ const updateArgs = modelInfo?.updateArgs ?? getModelUpdateArgs(modelHandle);
34249
+ if (!updateArgs || Object.keys(updateArgs).length === 0) {
34250
+ return null;
34251
+ }
34252
+ return {
34253
+ modelHandle: modelInfo?.handle ?? modelHandle,
34254
+ updateArgs
34255
+ };
34256
+ }
33995
34257
  function findModelByHandle(handle) {
33996
34258
  const pickPreferred = (candidates) => candidates.find((m) => m.isDefault) ?? candidates.find((m) => m.isFeatured) ?? candidates.find((m) => m.updateArgs?.reasoning_effort === "medium") ?? candidates.find((m) => m.updateArgs?.reasoning_effort === "high") ?? candidates[0] ?? null;
33997
34259
  const exactMatch = models.find((m) => m.handle === handle);
@@ -34039,8 +34301,9 @@ function resolveModelByLlmConfig(llmConfigModel) {
34039
34301
  return null;
34040
34302
  }
34041
34303
  var models, REASONING_EFFORT_ORDER;
34042
- var init_model = __esm(() => {
34304
+ var init_model = __esm(async () => {
34043
34305
  init_models2();
34306
+ await init_openai_codex_provider();
34044
34307
  models = models_default;
34045
34308
  REASONING_EFFORT_ORDER = [
34046
34309
  "none",
@@ -34295,12 +34558,12 @@ function getLoadingMessage(loadingState, continueSession) {
34295
34558
  }
34296
34559
  var import_react25, jsx_dev_runtime6;
34297
34560
  var init_WelcomeScreen = __esm(async () => {
34298
- init_model();
34299
34561
  init_version();
34300
34562
  init_useTerminalWidth();
34301
34563
  init_colors();
34302
34564
  await __promiseAll([
34303
34565
  init_build2(),
34566
+ init_model(),
34304
34567
  init_settings_manager(),
34305
34568
  init_AnimatedLogo(),
34306
34569
  init_Text2()
@@ -39854,160 +40117,6 @@ var init_hooks = __esm(async () => {
39854
40117
  init_types();
39855
40118
  });
39856
40119
 
39857
- // src/agent/http-headers.ts
39858
- function getLettaCodeHeaders2(apiKey) {
39859
- return {
39860
- "Content-Type": "application/json",
39861
- "User-Agent": `letta-code/${package_default.version}`,
39862
- "X-Letta-Source": "letta-code",
39863
- ...apiKey ? { Authorization: `Bearer ${apiKey}` } : {}
39864
- };
39865
- }
39866
- function getMcpOAuthHeaders(apiKey) {
39867
- return {
39868
- ...getLettaCodeHeaders2(apiKey),
39869
- Accept: "text/event-stream"
39870
- };
39871
- }
39872
- var init_http_headers = __esm(() => {
39873
- init_package();
39874
- });
39875
-
39876
- // src/providers/openai-codex-provider.ts
39877
- var exports_openai_codex_provider = {};
39878
- __export(exports_openai_codex_provider, {
39879
- updateOpenAICodexProvider: () => updateOpenAICodexProvider,
39880
- removeOpenAICodexProvider: () => removeOpenAICodexProvider,
39881
- listProviders: () => listProviders,
39882
- getOpenAICodexProvider: () => getOpenAICodexProvider,
39883
- deleteOpenAICodexProvider: () => deleteOpenAICodexProvider,
39884
- createOrUpdateOpenAICodexProvider: () => createOrUpdateOpenAICodexProvider,
39885
- createOpenAICodexProvider: () => createOpenAICodexProvider,
39886
- checkOpenAICodexEligibility: () => checkOpenAICodexEligibility,
39887
- OPENAI_CODEX_PROVIDER_NAME: () => OPENAI_CODEX_PROVIDER_NAME,
39888
- CHATGPT_OAUTH_PROVIDER_TYPE: () => CHATGPT_OAUTH_PROVIDER_TYPE
39889
- });
39890
- async function getLettaConfig() {
39891
- const settings = await settingsManager.getSettingsWithSecureTokens();
39892
- const baseUrl = process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
39893
- const apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY || "";
39894
- return { baseUrl, apiKey };
39895
- }
39896
- async function providersRequest(method, path2, body) {
39897
- const { baseUrl, apiKey } = await getLettaConfig();
39898
- const url = `${baseUrl}${path2}`;
39899
- const response = await fetch(url, {
39900
- method,
39901
- headers: getLettaCodeHeaders2(apiKey),
39902
- ...body && { body: JSON.stringify(body) }
39903
- });
39904
- if (!response.ok) {
39905
- const errorText = await response.text();
39906
- if (response.status === 403) {
39907
- try {
39908
- const errorData = JSON.parse(errorText);
39909
- if (errorData.error && typeof errorData.error === "string" && errorData.error.includes("only available for pro or enterprise")) {
39910
- throw new Error("PLAN_UPGRADE_REQUIRED");
39911
- }
39912
- } catch (parseError) {
39913
- if (parseError instanceof Error && parseError.message === "PLAN_UPGRADE_REQUIRED") {
39914
- throw parseError;
39915
- }
39916
- }
39917
- }
39918
- throw new Error(`Provider API error (${response.status}): ${errorText}`);
39919
- }
39920
- const text = await response.text();
39921
- if (!text) {
39922
- return {};
39923
- }
39924
- return JSON.parse(text);
39925
- }
39926
- async function listProviders() {
39927
- try {
39928
- const response = await providersRequest("GET", "/v1/providers");
39929
- return response;
39930
- } catch {
39931
- return [];
39932
- }
39933
- }
39934
- async function getOpenAICodexProvider() {
39935
- const providers = await listProviders();
39936
- return providers.find((p) => p.name === OPENAI_CODEX_PROVIDER_NAME) || null;
39937
- }
39938
- async function createOpenAICodexProvider(config) {
39939
- const apiKeyJson = JSON.stringify({
39940
- access_token: config.access_token,
39941
- id_token: config.id_token,
39942
- refresh_token: config.refresh_token,
39943
- account_id: config.account_id,
39944
- expires_at: config.expires_at
39945
- });
39946
- return providersRequest("POST", "/v1/providers", {
39947
- name: OPENAI_CODEX_PROVIDER_NAME,
39948
- provider_type: CHATGPT_OAUTH_PROVIDER_TYPE,
39949
- api_key: apiKeyJson
39950
- });
39951
- }
39952
- async function updateOpenAICodexProvider(providerId, config) {
39953
- const apiKeyJson = JSON.stringify({
39954
- access_token: config.access_token,
39955
- id_token: config.id_token,
39956
- refresh_token: config.refresh_token,
39957
- account_id: config.account_id,
39958
- expires_at: config.expires_at
39959
- });
39960
- return providersRequest("PATCH", `/v1/providers/${providerId}`, {
39961
- api_key: apiKeyJson
39962
- });
39963
- }
39964
- async function deleteOpenAICodexProvider(providerId) {
39965
- await providersRequest("DELETE", `/v1/providers/${providerId}`);
39966
- }
39967
- async function createOrUpdateOpenAICodexProvider(config) {
39968
- const existing = await getOpenAICodexProvider();
39969
- if (existing) {
39970
- return updateOpenAICodexProvider(existing.id, config);
39971
- } else {
39972
- return createOpenAICodexProvider(config);
39973
- }
39974
- }
39975
- async function removeOpenAICodexProvider() {
39976
- const existing = await getOpenAICodexProvider();
39977
- if (existing) {
39978
- await deleteOpenAICodexProvider(existing.id);
39979
- }
39980
- }
39981
- async function checkOpenAICodexEligibility() {
39982
- try {
39983
- const balance = await providersRequest("GET", "/v1/metadata/balance");
39984
- const billingTier = balance.billing_tier.toLowerCase();
39985
- if (billingTier === "pro" || billingTier === "enterprise") {
39986
- return {
39987
- eligible: true,
39988
- billing_tier: balance.billing_tier
39989
- };
39990
- }
39991
- return {
39992
- eligible: false,
39993
- billing_tier: balance.billing_tier,
39994
- reason: `ChatGPT OAuth requires a Pro or Enterprise plan. Current plan: ${balance.billing_tier}`
39995
- };
39996
- } catch (error) {
39997
- console.warn("Failed to check ChatGPT OAuth eligibility:", error);
39998
- return {
39999
- eligible: true,
40000
- billing_tier: "unknown"
40001
- };
40002
- }
40003
- }
40004
- var OPENAI_CODEX_PROVIDER_NAME = "chatgpt-plus-pro", CHATGPT_OAUTH_PROVIDER_TYPE = "chatgpt_oauth";
40005
- var init_openai_codex_provider = __esm(async () => {
40006
- init_http_headers();
40007
- init_oauth();
40008
- await init_settings_manager();
40009
- });
40010
-
40011
40120
  // src/telemetry/index.ts
40012
40121
  class TelemetryManager {
40013
40122
  events = [];
@@ -42693,10 +42802,10 @@ async function switchToolsetForModel(modelIdentifier, agentId) {
42693
42802
  }
42694
42803
  var CODEX_TOOLS, CODEX_SNAKE_TOOLS, GEMINI_TOOLS, MEMORY_TOOL_NAMES;
42695
42804
  var init_toolset = __esm(async () => {
42696
- init_model();
42697
42805
  init_filter();
42698
42806
  await __promiseAll([
42699
42807
  init_client2(),
42808
+ init_model(),
42700
42809
  init_manager3()
42701
42810
  ]);
42702
42811
  CODEX_TOOLS = OPENAI_PASCAL_TOOLS;
@@ -43179,7 +43288,7 @@ var init_shellRunner = __esm(() => {
43179
43288
  });
43180
43289
 
43181
43290
  // src/tools/impl/overflow.ts
43182
- import { randomUUID } from "node:crypto";
43291
+ import { randomUUID as randomUUID2 } from "node:crypto";
43183
43292
  import * as fs3 from "node:fs";
43184
43293
  import * as os2 from "node:os";
43185
43294
  import * as path4 from "node:path";
@@ -43200,7 +43309,7 @@ function ensureOverflowDirectory(workingDirectory) {
43200
43309
  }
43201
43310
  function writeOverflowFile(content, workingDirectory, toolName) {
43202
43311
  const overflowDir = ensureOverflowDirectory(workingDirectory);
43203
- const uuid = randomUUID();
43312
+ const uuid = randomUUID2();
43204
43313
  const filename = toolName ? `${toolName.toLowerCase()}-${uuid}.txt` : `${uuid}.txt`;
43205
43314
  const filePath = path4.join(overflowDir, filename);
43206
43315
  fs3.writeFileSync(filePath, content, "utf-8");
@@ -60193,7 +60302,7 @@ __export(exports_skills, {
60193
60302
  GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR
60194
60303
  });
60195
60304
  import { existsSync as existsSync7 } from "node:fs";
60196
- import { readdir as readdir4, readFile as readFile3 } from "node:fs/promises";
60305
+ import { readdir as readdir4, readFile as readFile3, realpath as realpath2, stat as stat2 } from "node:fs/promises";
60197
60306
  import { dirname as dirname4, join as join12 } from "node:path";
60198
60307
  import { fileURLToPath as fileURLToPath6 } from "node:url";
60199
60308
  function getBundledSkillsPath() {
@@ -60265,25 +60374,52 @@ async function discoverSkills(projectSkillsPath = join12(process.cwd(), SKILLS_D
60265
60374
  errors: allErrors
60266
60375
  };
60267
60376
  }
60268
- async function findSkillFiles(currentPath, rootPath, skills, errors, source) {
60377
+ async function findSkillFiles(currentPath, rootPath, skills, errors, source, visitedRealPaths = new Set) {
60378
+ try {
60379
+ const resolvedPath = await realpath2(currentPath);
60380
+ if (visitedRealPaths.has(resolvedPath)) {
60381
+ return;
60382
+ }
60383
+ visitedRealPaths.add(resolvedPath);
60384
+ } catch (error) {
60385
+ errors.push({
60386
+ path: currentPath,
60387
+ message: `Failed to resolve directory path: ${error instanceof Error ? error.message : String(error)}`
60388
+ });
60389
+ return;
60390
+ }
60269
60391
  try {
60270
60392
  const entries = await readdir4(currentPath, { withFileTypes: true });
60271
60393
  for (const entry of entries) {
60272
60394
  const fullPath = join12(currentPath, entry.name);
60273
- if (entry.isDirectory()) {
60274
- await findSkillFiles(fullPath, rootPath, skills, errors, source);
60275
- } else if (entry.isFile() && entry.name.toUpperCase() === "SKILL.MD") {
60276
- try {
60277
- const skill = await parseSkillFile(fullPath, rootPath, source);
60278
- if (skill) {
60279
- skills.push(skill);
60395
+ try {
60396
+ let isDirectory = entry.isDirectory();
60397
+ let isFile = entry.isFile();
60398
+ if (entry.isSymbolicLink()) {
60399
+ const entryStat = await stat2(fullPath);
60400
+ isDirectory = entryStat.isDirectory();
60401
+ isFile = entryStat.isFile();
60402
+ }
60403
+ if (isDirectory) {
60404
+ await findSkillFiles(fullPath, rootPath, skills, errors, source, visitedRealPaths);
60405
+ } else if (isFile && entry.name.toUpperCase() === "SKILL.MD") {
60406
+ try {
60407
+ const skill = await parseSkillFile(fullPath, rootPath, source);
60408
+ if (skill) {
60409
+ skills.push(skill);
60410
+ }
60411
+ } catch (error) {
60412
+ errors.push({
60413
+ path: fullPath,
60414
+ message: error instanceof Error ? error.message : String(error)
60415
+ });
60280
60416
  }
60281
- } catch (error) {
60282
- errors.push({
60283
- path: fullPath,
60284
- message: error instanceof Error ? error.message : String(error)
60285
- });
60286
60417
  }
60418
+ } catch (error) {
60419
+ errors.push({
60420
+ path: fullPath,
60421
+ message: `Failed to inspect path: ${error instanceof Error ? error.message : String(error)}`
60422
+ });
60287
60423
  }
60288
60424
  }
60289
60425
  } catch (error) {
@@ -61292,13 +61428,13 @@ var init_manager2 = __esm(async () => {
61292
61428
  init_mode();
61293
61429
  init_session();
61294
61430
  init_context();
61295
- init_model();
61296
61431
  init_subagents();
61297
61432
  await __promiseAll([
61298
61433
  init_settings_manager(),
61299
61434
  init_shellEnv(),
61300
61435
  init_available_models(),
61301
- init_client2()
61436
+ init_client2(),
61437
+ init_model()
61302
61438
  ]);
61303
61439
  BYOK_PROVIDER_TO_BASE = {
61304
61440
  "lc-anthropic": "anthropic",
@@ -66513,12 +66649,12 @@ function clearToolsWithLock() {
66513
66649
  }
66514
66650
  var TOOL_NAMES, STREAMING_SHELL_TOOLS, TOOL_NAME_MAPPINGS, ANTHROPIC_DEFAULT_TOOLS, OPENAI_DEFAULT_TOOLS, GEMINI_DEFAULT_TOOLS, OPENAI_PASCAL_TOOLS, GEMINI_PASCAL_TOOLS, TOOL_PERMISSIONS, REGISTRY_KEY, SWITCH_LOCK_KEY, EXECUTION_CONTEXTS_KEY, toolRegistry, toolExecutionContextCounter = 0, EXTERNAL_TOOLS_KEY, EXTERNAL_EXECUTOR_KEY;
66515
66651
  var init_manager3 = __esm(async () => {
66516
- init_model();
66517
66652
  init_subagents();
66518
66653
  init_constants();
66519
66654
  init_debug();
66520
66655
  await __promiseAll([
66521
66656
  init_approval_execution(),
66657
+ init_model(),
66522
66658
  init_hooks(),
66523
66659
  init_openai_codex_provider(),
66524
66660
  init_telemetry(),
@@ -66937,9 +67073,16 @@ var init_approval_execution = __esm(async () => {
66937
67073
  // src/agent/check-approval.ts
66938
67074
  var exports_check_approval = {};
66939
67075
  __export(exports_check_approval, {
67076
+ prepareMessageHistory: () => prepareMessageHistory2,
66940
67077
  getResumeData: () => getResumeData2,
66941
67078
  extractApprovals: () => extractApprovals2
66942
67079
  });
67080
+ function isPrimaryMessageType2(messageType) {
67081
+ return messageType === "user_message" || messageType === "assistant_message" || messageType === "event_message" || messageType === "summary_message";
67082
+ }
67083
+ function isAnchorMessageType2(messageType) {
67084
+ return messageType === "user_message" || messageType === "assistant_message";
67085
+ }
66943
67086
  function isBackfillEnabled2() {
66944
67087
  const val = process.env.LETTA_BACKFILL;
66945
67088
  return val !== "0" && val !== "false";
@@ -66958,9 +67101,62 @@ function extractApprovals2(messageToCheck) {
66958
67101
  }
66959
67102
  return { pendingApproval, pendingApprovals };
66960
67103
  }
66961
- function prepareMessageHistory2(messages) {
66962
- const historyCount = Math.min(MESSAGE_HISTORY_LIMIT2, messages.length);
66963
- let messageHistory = messages.slice(-historyCount);
67104
+ function prepareMessageHistory2(messages, opts) {
67105
+ const isRenderable = (msg) => {
67106
+ const t = msg.message_type;
67107
+ if (t === "user_message" || t === "assistant_message" || t === "reasoning_message" || t === "tool_call_message" || t === "tool_return_message" || t === "approval_request_message" || t === "approval_response_message") {
67108
+ return true;
67109
+ }
67110
+ const ts = t;
67111
+ return ts === "event_message" || ts === "summary_message";
67112
+ };
67113
+ const renderable = messages.filter(isRenderable);
67114
+ if (opts?.primaryOnly) {
67115
+ const convo = renderable.filter((m) => isPrimaryMessageType2(m.message_type));
67116
+ let trimmed = convo.slice(-BACKFILL_PRIMARY_MESSAGE_LIMIT2);
67117
+ const hasAssistant = trimmed.some((m) => m.message_type === "assistant_message");
67118
+ if (!hasAssistant) {
67119
+ const lastAssistantIndex = convo.map((m) => m.message_type).lastIndexOf("assistant_message");
67120
+ if (lastAssistantIndex >= 0) {
67121
+ const lastAssistant = convo[lastAssistantIndex];
67122
+ if (lastAssistant) {
67123
+ const tailLimit = Math.max(BACKFILL_PRIMARY_MESSAGE_LIMIT2 - 1, 0);
67124
+ const newestTail = tailLimit > 0 ? convo.slice(-tailLimit) : [];
67125
+ trimmed = [lastAssistant, ...newestTail];
67126
+ }
67127
+ }
67128
+ }
67129
+ if (trimmed.length > 0)
67130
+ return trimmed;
67131
+ const reasoning = renderable.filter((m) => m.message_type === "reasoning_message");
67132
+ if (reasoning.length > 0) {
67133
+ return reasoning.slice(-BACKFILL_PRIMARY_MESSAGE_LIMIT2);
67134
+ }
67135
+ return [];
67136
+ }
67137
+ const isPrimary = (msg) => {
67138
+ const t = msg.message_type;
67139
+ return t === "user_message" || t === "assistant_message" || t === "reasoning_message" || t === "event_message" || t === "summary_message";
67140
+ };
67141
+ let primaryCount = 0;
67142
+ let startIndex = Math.max(0, renderable.length - 1);
67143
+ for (let i = renderable.length - 1;i >= 0; i -= 1) {
67144
+ const msg = renderable[i];
67145
+ if (!msg)
67146
+ continue;
67147
+ if (isPrimary(msg)) {
67148
+ primaryCount += 1;
67149
+ if (primaryCount >= BACKFILL_PRIMARY_MESSAGE_LIMIT2) {
67150
+ startIndex = i;
67151
+ break;
67152
+ }
67153
+ }
67154
+ startIndex = i;
67155
+ }
67156
+ let messageHistory = renderable.slice(startIndex);
67157
+ if (messageHistory.length > BACKFILL_MAX_RENDERABLE_MESSAGES2) {
67158
+ messageHistory = messageHistory.slice(-BACKFILL_MAX_RENDERABLE_MESSAGES2);
67159
+ }
66964
67160
  if (messageHistory[0]?.message_type === "tool_return_message") {
66965
67161
  messageHistory = messageHistory.slice(1);
66966
67162
  }
@@ -66968,11 +67164,57 @@ function prepareMessageHistory2(messages) {
66968
67164
  }
66969
67165
  function sortChronological2(messages) {
66970
67166
  return [...messages].sort((a, b) => {
66971
- const dateA = a.date ?? "";
66972
- const dateB = b.date ?? "";
66973
- return new Date(dateA).getTime() - new Date(dateB).getTime();
67167
+ const ta = a.date ? new Date(a.date).getTime() : 0;
67168
+ const tb = b.date ? new Date(b.date).getTime() : 0;
67169
+ if (!Number.isFinite(ta) && !Number.isFinite(tb))
67170
+ return 0;
67171
+ if (!Number.isFinite(ta))
67172
+ return -1;
67173
+ if (!Number.isFinite(tb))
67174
+ return 1;
67175
+ return ta - tb;
66974
67176
  });
66975
67177
  }
67178
+ async function fetchConversationBackfillMessages2(client, conversationId) {
67179
+ const collected = [];
67180
+ const seen = new Set;
67181
+ let cursorBefore = null;
67182
+ let assistantCount = 0;
67183
+ let anchorCount = 0;
67184
+ for (let pageIndex = 0;pageIndex < BACKFILL_MAX_PAGES2; pageIndex += 1) {
67185
+ const page = await client.conversations.messages.list(conversationId, {
67186
+ limit: BACKFILL_PAGE_LIMIT2,
67187
+ order: "desc",
67188
+ ...cursorBefore ? { before: cursorBefore } : {}
67189
+ });
67190
+ const items = page.getPaginatedItems();
67191
+ if (items.length === 0)
67192
+ break;
67193
+ cursorBefore = items[items.length - 1]?.id ?? null;
67194
+ for (const m of items) {
67195
+ if (!m?.id)
67196
+ continue;
67197
+ const key = "otid" in m && m.otid ? `otid:${String(m.otid)}` : `id:${m.id}:${m.message_type ?? ""}`;
67198
+ if (seen.has(key))
67199
+ continue;
67200
+ seen.add(key);
67201
+ collected.push(m);
67202
+ if (m.message_type === "assistant_message")
67203
+ assistantCount += 1;
67204
+ if (isAnchorMessageType2(m.message_type))
67205
+ anchorCount += 1;
67206
+ }
67207
+ if (assistantCount >= BACKFILL_MIN_ASSISTANT2 && anchorCount >= BACKFILL_ANCHOR_MESSAGE_LIMIT2) {
67208
+ break;
67209
+ }
67210
+ if (items.length < BACKFILL_PAGE_LIMIT2)
67211
+ break;
67212
+ }
67213
+ if (assistantCount < BACKFILL_MIN_ASSISTANT2) {
67214
+ debugWarn("check-approval", `Backfill scan found 0 assistant messages in last ${collected.length} messages (tool-heavy conversation?)`);
67215
+ }
67216
+ return sortChronological2(collected);
67217
+ }
66976
67218
  async function getResumeData2(client, agent, conversationId) {
66977
67219
  try {
66978
67220
  let inContextMessageIds;
@@ -66988,14 +67230,13 @@ async function getResumeData2(client, agent, conversationId) {
66988
67230
  debugWarn("check-approval", "No in-context messages - no pending approvals");
66989
67231
  if (isBackfillEnabled2()) {
66990
67232
  try {
66991
- const backfill = await client.conversations.messages.list(conversationId, {
66992
- limit: MESSAGE_HISTORY_LIMIT2,
66993
- order: "desc"
66994
- });
67233
+ const backfill = await fetchConversationBackfillMessages2(client, conversationId);
66995
67234
  return {
66996
67235
  pendingApproval: null,
66997
67236
  pendingApprovals: [],
66998
- messageHistory: sortChronological2(backfill.getPaginatedItems())
67237
+ messageHistory: prepareMessageHistory2(backfill, {
67238
+ primaryOnly: true
67239
+ })
66999
67240
  };
67000
67241
  } catch (backfillError) {
67001
67242
  debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
@@ -67014,11 +67255,7 @@ async function getResumeData2(client, agent, conversationId) {
67014
67255
  const retrievedMessages = await client.messages.retrieve(lastInContextId);
67015
67256
  if (isBackfillEnabled2()) {
67016
67257
  try {
67017
- const backfillPage = await client.conversations.messages.list(conversationId, {
67018
- limit: MESSAGE_HISTORY_LIMIT2,
67019
- order: "desc"
67020
- });
67021
- messages = sortChronological2(backfillPage.getPaginatedItems());
67258
+ messages = await fetchConversationBackfillMessages2(client, conversationId);
67022
67259
  } catch (backfillError) {
67023
67260
  debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
67024
67261
  }
@@ -67031,7 +67268,9 @@ async function getResumeData2(client, agent, conversationId) {
67031
67268
  return {
67032
67269
  pendingApproval,
67033
67270
  pendingApprovals,
67034
- messageHistory: prepareMessageHistory2(messages)
67271
+ messageHistory: prepareMessageHistory2(messages, {
67272
+ primaryOnly: true
67273
+ })
67035
67274
  };
67036
67275
  }
67037
67276
  } else {
@@ -67040,7 +67279,7 @@ async function getResumeData2(client, agent, conversationId) {
67040
67279
  return {
67041
67280
  pendingApproval: null,
67042
67281
  pendingApprovals: [],
67043
- messageHistory: prepareMessageHistory2(messages)
67282
+ messageHistory: prepareMessageHistory2(messages, { primaryOnly: true })
67044
67283
  };
67045
67284
  } else {
67046
67285
  inContextMessageIds = agent.message_ids;
@@ -67060,13 +67299,13 @@ async function getResumeData2(client, agent, conversationId) {
67060
67299
  if (isBackfillEnabled2()) {
67061
67300
  try {
67062
67301
  const messagesPage = await client.agents.messages.list(agent.id, {
67063
- limit: MESSAGE_HISTORY_LIMIT2,
67302
+ limit: BACKFILL_PAGE_LIMIT2,
67064
67303
  order: "desc",
67065
67304
  conversation_id: "default"
67066
67305
  });
67067
67306
  messages = sortChronological2(messagesPage.items);
67068
67307
  if (process.env.DEBUG) {
67069
- console.log(`[DEBUG] agents.messages.list(conversation_id=default) returned ${messagesPage.items.length} messages`);
67308
+ console.log(`[DEBUG] agents.messages.list(conversation_id=default) returned ${messages.length} messages`);
67070
67309
  }
67071
67310
  } catch (backfillError) {
67072
67311
  debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
@@ -67080,7 +67319,9 @@ async function getResumeData2(client, agent, conversationId) {
67080
67319
  return {
67081
67320
  pendingApproval,
67082
67321
  pendingApprovals,
67083
- messageHistory: prepareMessageHistory2(messages)
67322
+ messageHistory: prepareMessageHistory2(messages, {
67323
+ primaryOnly: true
67324
+ })
67084
67325
  };
67085
67326
  }
67086
67327
  } else {
@@ -67089,7 +67330,7 @@ async function getResumeData2(client, agent, conversationId) {
67089
67330
  return {
67090
67331
  pendingApproval: null,
67091
67332
  pendingApprovals: [],
67092
- messageHistory: prepareMessageHistory2(messages)
67333
+ messageHistory: prepareMessageHistory2(messages, { primaryOnly: true })
67093
67334
  };
67094
67335
  }
67095
67336
  } catch (error) {
@@ -67100,7 +67341,7 @@ async function getResumeData2(client, agent, conversationId) {
67100
67341
  return { pendingApproval: null, pendingApprovals: [], messageHistory: [] };
67101
67342
  }
67102
67343
  }
67103
- var MESSAGE_HISTORY_LIMIT2 = 15;
67344
+ var BACKFILL_PRIMARY_MESSAGE_LIMIT2 = 12, BACKFILL_MAX_RENDERABLE_MESSAGES2 = 80, BACKFILL_ANCHOR_MESSAGE_LIMIT2 = 6, BACKFILL_PAGE_LIMIT2 = 200, BACKFILL_MAX_PAGES2 = 25, BACKFILL_MIN_ASSISTANT2 = 1;
67104
67345
  var init_check_approval = __esm(() => {
67105
67346
  init_error();
67106
67347
  init_debug();
@@ -67856,6 +68097,13 @@ function extractTextPart(v) {
67856
68097
  }
67857
68098
  return "";
67858
68099
  }
68100
+ function markCompactionCompleted(ctx) {
68101
+ if (!ctx)
68102
+ return;
68103
+ ctx.pendingCompaction = true;
68104
+ ctx.pendingSkillsReinject = true;
68105
+ ctx.pendingReflectionTrigger = true;
68106
+ }
67859
68107
  function resolveLineIdForKind(b, canonicalId, kind) {
67860
68108
  const existing = b.byId.get(canonicalId);
67861
68109
  if (!existing || existing.kind === kind)
@@ -68046,6 +68294,7 @@ function onChunk(b, chunk, ctx) {
68046
68294
  phase: "finished",
68047
68295
  summary: compactionSummary
68048
68296
  }));
68297
+ markCompactionCompleted(ctx);
68049
68298
  }
68050
68299
  break;
68051
68300
  }
@@ -68253,11 +68502,7 @@ function onChunk(b, chunk, ctx) {
68253
68502
  break;
68254
68503
  }
68255
68504
  }
68256
- if (ctx) {
68257
- ctx.pendingCompaction = true;
68258
- ctx.pendingSkillsReinject = true;
68259
- ctx.pendingReflectionTrigger = true;
68260
- }
68505
+ markCompactionCompleted(ctx);
68261
68506
  break;
68262
68507
  }
68263
68508
  if (msgType === "event_message") {
@@ -69313,7 +69558,7 @@ __export(exports_skills2, {
69313
69558
  GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR2
69314
69559
  });
69315
69560
  import { existsSync as existsSync10 } from "node:fs";
69316
- import { readdir as readdir6, readFile as readFile5 } from "node:fs/promises";
69561
+ import { readdir as readdir6, readFile as readFile5, realpath as realpath3, stat as stat3 } from "node:fs/promises";
69317
69562
  import { dirname as dirname8, join as join19 } from "node:path";
69318
69563
  import { fileURLToPath as fileURLToPath7 } from "node:url";
69319
69564
  function getBundledSkillsPath2() {
@@ -69385,25 +69630,52 @@ async function discoverSkills2(projectSkillsPath = join19(process.cwd(), SKILLS_
69385
69630
  errors: allErrors
69386
69631
  };
69387
69632
  }
69388
- async function findSkillFiles2(currentPath, rootPath, skills, errors, source) {
69633
+ async function findSkillFiles2(currentPath, rootPath, skills, errors, source, visitedRealPaths = new Set) {
69634
+ try {
69635
+ const resolvedPath = await realpath3(currentPath);
69636
+ if (visitedRealPaths.has(resolvedPath)) {
69637
+ return;
69638
+ }
69639
+ visitedRealPaths.add(resolvedPath);
69640
+ } catch (error) {
69641
+ errors.push({
69642
+ path: currentPath,
69643
+ message: `Failed to resolve directory path: ${error instanceof Error ? error.message : String(error)}`
69644
+ });
69645
+ return;
69646
+ }
69389
69647
  try {
69390
69648
  const entries = await readdir6(currentPath, { withFileTypes: true });
69391
69649
  for (const entry of entries) {
69392
69650
  const fullPath = join19(currentPath, entry.name);
69393
- if (entry.isDirectory()) {
69394
- await findSkillFiles2(fullPath, rootPath, skills, errors, source);
69395
- } else if (entry.isFile() && entry.name.toUpperCase() === "SKILL.MD") {
69396
- try {
69397
- const skill2 = await parseSkillFile2(fullPath, rootPath, source);
69398
- if (skill2) {
69399
- skills.push(skill2);
69651
+ try {
69652
+ let isDirectory = entry.isDirectory();
69653
+ let isFile = entry.isFile();
69654
+ if (entry.isSymbolicLink()) {
69655
+ const entryStat = await stat3(fullPath);
69656
+ isDirectory = entryStat.isDirectory();
69657
+ isFile = entryStat.isFile();
69658
+ }
69659
+ if (isDirectory) {
69660
+ await findSkillFiles2(fullPath, rootPath, skills, errors, source, visitedRealPaths);
69661
+ } else if (isFile && entry.name.toUpperCase() === "SKILL.MD") {
69662
+ try {
69663
+ const skill2 = await parseSkillFile2(fullPath, rootPath, source);
69664
+ if (skill2) {
69665
+ skills.push(skill2);
69666
+ }
69667
+ } catch (error) {
69668
+ errors.push({
69669
+ path: fullPath,
69670
+ message: error instanceof Error ? error.message : String(error)
69671
+ });
69400
69672
  }
69401
- } catch (error) {
69402
- errors.push({
69403
- path: fullPath,
69404
- message: error instanceof Error ? error.message : String(error)
69405
- });
69406
69673
  }
69674
+ } catch (error) {
69675
+ errors.push({
69676
+ path: fullPath,
69677
+ message: `Failed to inspect path: ${error instanceof Error ? error.message : String(error)}`
69678
+ });
69407
69679
  }
69408
69680
  }
69409
69681
  } catch (error) {
@@ -70112,7 +70384,7 @@ __export(exports_overflow, {
70112
70384
  cleanupOldOverflowFiles: () => cleanupOldOverflowFiles,
70113
70385
  OVERFLOW_CONFIG: () => OVERFLOW_CONFIG2
70114
70386
  });
70115
- import { randomUUID as randomUUID2 } from "node:crypto";
70387
+ import { randomUUID as randomUUID4 } from "node:crypto";
70116
70388
  import * as fs10 from "node:fs";
70117
70389
  import * as os3 from "node:os";
70118
70390
  import * as path20 from "node:path";
@@ -70133,7 +70405,7 @@ function ensureOverflowDirectory2(workingDirectory) {
70133
70405
  }
70134
70406
  function writeOverflowFile2(content, workingDirectory, toolName) {
70135
70407
  const overflowDir = ensureOverflowDirectory2(workingDirectory);
70136
- const uuid = randomUUID2();
70408
+ const uuid = randomUUID4();
70137
70409
  const filename = toolName ? `${toolName.toLowerCase()}-${uuid}.txt` : `${uuid}.txt`;
70138
70410
  const filePath = path20.join(overflowDir, filename);
70139
70411
  fs10.writeFileSync(filePath, content, "utf-8");
@@ -71894,12 +72166,12 @@ var init_create = __esm(async () => {
71894
72166
  init_http_headers();
71895
72167
  init_memory();
71896
72168
  init_memoryPrompt();
71897
- init_model();
71898
72169
  init_promptAssets();
71899
72170
  await __promiseAll([
71900
72171
  init_settings_manager(),
71901
72172
  init_available_models(),
71902
72173
  init_client2(),
72174
+ init_model(),
71903
72175
  init_modify()
71904
72176
  ]);
71905
72177
  });
@@ -72551,6 +72823,72 @@ function mergeQueuedTurnInput(queued, options) {
72551
72823
  return mergedParts.length > 0 ? mergedParts : null;
72552
72824
  }
72553
72825
 
72826
+ // src/cli/helpers/agentInfo.ts
72827
+ function getRelativeTime(dateStr) {
72828
+ const date = new Date(dateStr);
72829
+ const now = new Date;
72830
+ const diffMs = now.getTime() - date.getTime();
72831
+ const diffSecs = Math.floor(diffMs / 1000);
72832
+ const diffMins = Math.floor(diffSecs / 60);
72833
+ const diffHours = Math.floor(diffMins / 60);
72834
+ const diffDays = Math.floor(diffHours / 24);
72835
+ if (diffDays > 0) {
72836
+ return `${diffDays} day${diffDays === 1 ? "" : "s"} ago`;
72837
+ }
72838
+ if (diffHours > 0) {
72839
+ return `${diffHours} hour${diffHours === 1 ? "" : "s"} ago`;
72840
+ }
72841
+ if (diffMins > 0) {
72842
+ return `${diffMins} minute${diffMins === 1 ? "" : "s"} ago`;
72843
+ }
72844
+ return "just now";
72845
+ }
72846
+ function buildAgentInfo(options) {
72847
+ try {
72848
+ const { agentInfo, serverUrl } = options;
72849
+ let actualServerUrl = LETTA_CLOUD_API_URL;
72850
+ try {
72851
+ const settings = settingsManager.getSettings();
72852
+ actualServerUrl = serverUrl || process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
72853
+ } catch {}
72854
+ let lastRunInfo = "No previous messages";
72855
+ if (agentInfo.lastRunAt) {
72856
+ try {
72857
+ const lastRunDate = new Date(agentInfo.lastRunAt);
72858
+ const localLastRun = lastRunDate.toLocaleString();
72859
+ const relativeTime = getRelativeTime(agentInfo.lastRunAt);
72860
+ lastRunInfo = `${localLastRun} (${relativeTime})`;
72861
+ } catch {
72862
+ lastRunInfo = "(failed to parse last run time)";
72863
+ }
72864
+ }
72865
+ const showMemoryDir = (() => {
72866
+ try {
72867
+ return settingsManager.isMemfsEnabled(agentInfo.id);
72868
+ } catch {
72869
+ return false;
72870
+ }
72871
+ })();
72872
+ const memoryDirLine = showMemoryDir ? `
72873
+ - **Memory directory (also stored in \`MEMORY_DIR\` env var)**: \`${getMemoryFilesystemRoot(agentInfo.id)}\`` : "";
72874
+ return `${SYSTEM_REMINDER_OPEN} This is an automated message providing information about you.
72875
+ - **Agent ID (also stored in \`AGENT_ID\` env var)**: ${agentInfo.id}${memoryDirLine}
72876
+ - **Agent name**: ${agentInfo.name || "(unnamed)"} (the user can change this with /rename)
72877
+ - **Agent description**: ${agentInfo.description || "(no description)"} (the user can change this with /description)
72878
+ - **Last message**: ${lastRunInfo}
72879
+ - **Server location**: ${actualServerUrl}
72880
+ ${SYSTEM_REMINDER_CLOSE}`;
72881
+ } catch {
72882
+ return "";
72883
+ }
72884
+ }
72885
+ var init_agentInfo = __esm(async () => {
72886
+ init_memoryFilesystem();
72887
+ init_oauth();
72888
+ init_constants();
72889
+ await init_settings_manager();
72890
+ });
72891
+
72554
72892
  // src/cli/helpers/sessionContext.ts
72555
72893
  import { execSync as execSync2 } from "node:child_process";
72556
72894
  import { platform as platform3 } from "node:os";
@@ -72579,25 +72917,6 @@ function getDeviceType() {
72579
72917
  return p;
72580
72918
  }
72581
72919
  }
72582
- function getRelativeTime(dateStr) {
72583
- const date = new Date(dateStr);
72584
- const now = new Date;
72585
- const diffMs = now.getTime() - date.getTime();
72586
- const diffSecs = Math.floor(diffMs / 1000);
72587
- const diffMins = Math.floor(diffSecs / 60);
72588
- const diffHours = Math.floor(diffMins / 60);
72589
- const diffDays = Math.floor(diffHours / 24);
72590
- if (diffDays > 0) {
72591
- return `${diffDays} day${diffDays === 1 ? "" : "s"} ago`;
72592
- }
72593
- if (diffHours > 0) {
72594
- return `${diffHours} hour${diffHours === 1 ? "" : "s"} ago`;
72595
- }
72596
- if (diffMins > 0) {
72597
- return `${diffMins} minute${diffMins === 1 ? "" : "s"} ago`;
72598
- }
72599
- return "just now";
72600
- }
72601
72920
  function safeGitExec(command, cwd2) {
72602
72921
  try {
72603
72922
  return execSync2(command, { cwd: cwd2, encoding: "utf-8", stdio: "pipe" }).trim();
@@ -72630,9 +72949,8 @@ function getGitInfo() {
72630
72949
  return { isGitRepo: false };
72631
72950
  }
72632
72951
  }
72633
- function buildSessionContext(options) {
72952
+ function buildSessionContext() {
72634
72953
  try {
72635
- const { agentInfo, serverUrl } = options;
72636
72954
  const cwd2 = process.cwd();
72637
72955
  let version = "unknown";
72638
72956
  try {
@@ -72647,31 +72965,6 @@ function buildSessionContext(options) {
72647
72965
  localTime = getLocalTime();
72648
72966
  } catch {}
72649
72967
  const gitInfo = getGitInfo();
72650
- let actualServerUrl = LETTA_CLOUD_API_URL;
72651
- try {
72652
- const settings = settingsManager.getSettings();
72653
- actualServerUrl = serverUrl || process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
72654
- } catch {}
72655
- let lastRunInfo = "No previous messages";
72656
- if (agentInfo.lastRunAt) {
72657
- try {
72658
- const lastRunDate = new Date(agentInfo.lastRunAt);
72659
- const localLastRun = lastRunDate.toLocaleString();
72660
- const relativeTime = getRelativeTime(agentInfo.lastRunAt);
72661
- lastRunInfo = `${localLastRun} (${relativeTime})`;
72662
- } catch {
72663
- lastRunInfo = "(failed to parse last run time)";
72664
- }
72665
- }
72666
- const showMemoryDir = (() => {
72667
- try {
72668
- return settingsManager.isMemfsEnabled(agentInfo.id);
72669
- } catch {
72670
- return false;
72671
- }
72672
- })();
72673
- const memoryDirLine = showMemoryDir ? `
72674
- - **Memory directory (also stored in \`MEMORY_DIR\` env var)**: \`${getMemoryFilesystemRoot(agentInfo.id)}\`` : "";
72675
72968
  let context3 = `${SYSTEM_REMINDER_OPEN}
72676
72969
  This is an automated message providing context about the user's environment.
72677
72970
  The user has just initiated a new connection via the [Letta Code CLI client](https://docs.letta.com/letta-code/index.md).
@@ -72707,25 +73000,15 @@ ${gitInfo.status}
72707
73000
  - For multiline strings (git commits, PR bodies), use simple quoted strings instead
72708
73001
  `;
72709
73002
  }
72710
- context3 += `
72711
- ## Agent Information (i.e. information about you)
72712
- - **Agent ID (also stored in \`AGENT_ID\` env var)**: ${agentInfo.id}${memoryDirLine}
72713
- - **Agent name**: ${agentInfo.name || "(unnamed)"} (the user can change this with /rename)
72714
- - **Agent description**: ${agentInfo.description || "(no description)"} (the user can change this with /description)
72715
- - **Last message**: ${lastRunInfo}
72716
- - **Server location**: ${actualServerUrl}
72717
- ${SYSTEM_REMINDER_CLOSE}`;
73003
+ context3 += SYSTEM_REMINDER_CLOSE;
72718
73004
  return context3;
72719
73005
  } catch {
72720
73006
  return "";
72721
73007
  }
72722
73008
  }
72723
- var init_sessionContext = __esm(async () => {
72724
- init_memoryFilesystem();
72725
- init_oauth();
73009
+ var init_sessionContext = __esm(() => {
72726
73010
  init_constants();
72727
73011
  init_version();
72728
- await init_settings_manager();
72729
73012
  });
72730
73013
 
72731
73014
  // src/reminders/catalog.ts
@@ -72734,9 +73017,19 @@ var init_catalog = __esm(() => {
72734
73017
  SHARED_REMINDER_CATALOG = [
72735
73018
  {
72736
73019
  id: "session-context",
72737
- description: "First-turn device/agent/git context",
73020
+ description: "First-turn device/git/cwd context",
72738
73021
  modes: ["interactive", "headless-one-shot", "headless-bidirectional"]
72739
73022
  },
73023
+ {
73024
+ id: "agent-info",
73025
+ description: "Agent identity (ID, name, server, memory dir)",
73026
+ modes: [
73027
+ "interactive",
73028
+ "headless-one-shot",
73029
+ "headless-bidirectional",
73030
+ "subagent"
73031
+ ]
73032
+ },
72740
73033
  {
72741
73034
  id: "skills",
72742
73035
  description: "Available skills system reminder (with reinjection)",
@@ -72779,14 +73072,11 @@ var init_catalog = __esm(() => {
72779
73072
 
72780
73073
  // src/reminders/engine.ts
72781
73074
  import { join as join23 } from "node:path";
72782
- async function buildSessionContextReminder(context3) {
72783
- if (!context3.sessionContextReminderEnabled || context3.state.hasSentSessionContext) {
72784
- return null;
72785
- }
72786
- if (!settingsManager.getSetting("sessionContextEnabled")) {
73075
+ async function buildAgentInfoReminder(context3) {
73076
+ if (context3.state.hasSentAgentInfo) {
72787
73077
  return null;
72788
73078
  }
72789
- const reminder = buildSessionContext({
73079
+ const reminder = buildAgentInfo({
72790
73080
  agentInfo: {
72791
73081
  id: context3.agent.id,
72792
73082
  name: context3.agent.name,
@@ -72795,6 +73085,17 @@ async function buildSessionContextReminder(context3) {
72795
73085
  },
72796
73086
  serverUrl: context3.agent.serverUrl
72797
73087
  });
73088
+ context3.state.hasSentAgentInfo = true;
73089
+ return reminder || null;
73090
+ }
73091
+ async function buildSessionContextReminder(context3) {
73092
+ if (!context3.sessionContextReminderEnabled || context3.state.hasSentSessionContext) {
73093
+ return null;
73094
+ }
73095
+ if (!settingsManager.getSetting("sessionContextEnabled")) {
73096
+ return null;
73097
+ }
73098
+ const reminder = buildSessionContext();
72798
73099
  context3.state.hasSentSessionContext = true;
72799
73100
  return reminder || null;
72800
73101
  }
@@ -73010,12 +73311,13 @@ var PERMISSION_MODE_DESCRIPTIONS, MAX_COMMAND_REMINDERS_PER_TURN = 10, MAX_TOOLS
73010
73311
  var init_engine = __esm(async () => {
73011
73312
  init_context();
73012
73313
  init_skills();
73314
+ init_sessionContext();
73013
73315
  init_constants();
73014
73316
  init_mode();
73015
73317
  init_catalog();
73016
73318
  await __promiseAll([
73319
+ init_agentInfo(),
73017
73320
  init_memoryReminder(),
73018
- init_sessionContext(),
73019
73321
  init_settings_manager()
73020
73322
  ]);
73021
73323
  PERMISSION_MODE_DESCRIPTIONS = {
@@ -73025,6 +73327,7 @@ var init_engine = __esm(async () => {
73025
73327
  bypassPermissions: "All tools auto-approved. Bias toward action."
73026
73328
  };
73027
73329
  sharedReminderProviders = {
73330
+ "agent-info": buildAgentInfoReminder,
73028
73331
  "session-context": buildSessionContextReminder,
73029
73332
  skills: buildSkillsReminder,
73030
73333
  "permission-mode": buildPermissionModeReminder,
@@ -73040,6 +73343,7 @@ var init_engine = __esm(async () => {
73040
73343
  // src/reminders/state.ts
73041
73344
  function createSharedReminderState() {
73042
73345
  return {
73346
+ hasSentAgentInfo: false,
73043
73347
  hasSentSessionContext: false,
73044
73348
  hasInjectedSkillsReminder: false,
73045
73349
  cachedSkillsReminder: null,
@@ -73263,9 +73567,9 @@ async function importAgentFromRegistry(options) {
73263
73567
  }
73264
73568
  var AGENT_REGISTRY_OWNER = "letta-ai", AGENT_REGISTRY_REPO = "agent-file", AGENT_REGISTRY_BRANCH = "main";
73265
73569
  var init_import = __esm(async () => {
73266
- init_model();
73267
73570
  await __promiseAll([
73268
73571
  init_client2(),
73572
+ init_model(),
73269
73573
  init_modify()
73270
73574
  ]);
73271
73575
  });
@@ -73338,6 +73642,7 @@ __export(exports_headless, {
73338
73642
  mergeBidirectionalQueuedInput: () => mergeBidirectionalQueuedInput,
73339
73643
  handleHeadlessCommand: () => handleHeadlessCommand
73340
73644
  });
73645
+ import { randomUUID as randomUUID5 } from "node:crypto";
73341
73646
  import { parseArgs as parseArgs6 } from "node:util";
73342
73647
  function mergeBidirectionalQueuedInput(queued) {
73343
73648
  return mergeQueuedTurnInput(queued, {
@@ -73868,18 +74173,34 @@ In headless mode, use:
73868
74173
  }
73869
74174
  markMilestone("HEADLESS_AGENT_RESOLVED");
73870
74175
  const isResumingAgent = !!(specifiedAgentId || shouldContinue || !forceNew && !fromAfFile);
73871
- if (isResumingAgent && (model || systemPromptPreset)) {
74176
+ if (isResumingAgent) {
74177
+ const { updateAgentLLMConfig: updateAgentLLMConfig2 } = await init_modify().then(() => exports_modify);
73872
74178
  if (model) {
73873
- const { resolveModel: resolveModel2 } = await Promise.resolve().then(() => (init_model(), exports_model));
74179
+ const { resolveModel: resolveModel2 } = await init_model().then(() => exports_model);
73874
74180
  const modelHandle = resolveModel2(model);
73875
- if (!modelHandle) {
74181
+ if (typeof modelHandle !== "string") {
73876
74182
  console.error(`Error: Invalid model "${model}"`);
73877
74183
  process.exit(1);
73878
74184
  }
73879
- const { updateAgentLLMConfig: updateAgentLLMConfig2 } = await init_modify().then(() => exports_modify);
73880
74185
  const updateArgs = getModelUpdateArgs(model);
73881
74186
  await updateAgentLLMConfig2(agent.id, modelHandle, updateArgs);
73882
74187
  agent = await client.agents.retrieve(agent.id);
74188
+ } else {
74189
+ const { getModelPresetUpdateForAgent: getModelPresetUpdateForAgent2 } = await init_model().then(() => exports_model);
74190
+ const presetRefresh = getModelPresetUpdateForAgent2(agent);
74191
+ if (presetRefresh) {
74192
+ const resumeRefreshUpdateArgs = {};
74193
+ if (typeof presetRefresh.updateArgs.max_output_tokens === "number") {
74194
+ resumeRefreshUpdateArgs.max_output_tokens = presetRefresh.updateArgs.max_output_tokens;
74195
+ }
74196
+ if (typeof presetRefresh.updateArgs.parallel_tool_calls === "boolean") {
74197
+ resumeRefreshUpdateArgs.parallel_tool_calls = presetRefresh.updateArgs.parallel_tool_calls;
74198
+ }
74199
+ if (Object.keys(resumeRefreshUpdateArgs).length > 0) {
74200
+ await updateAgentLLMConfig2(agent.id, presetRefresh.modelHandle, resumeRefreshUpdateArgs);
74201
+ agent = await client.agents.retrieve(agent.id);
74202
+ }
74203
+ }
73883
74204
  }
73884
74205
  if (systemPromptPreset) {
73885
74206
  const { updateAgentSystemPrompt: updateAgentSystemPrompt2 } = await init_modify().then(() => exports_modify);
@@ -73951,6 +74272,8 @@ In headless mode, use:
73951
74272
  isolated_block_labels: isolatedBlockLabels
73952
74273
  });
73953
74274
  conversationId = conversation.id;
74275
+ } else if (isSubagent) {
74276
+ conversationId = "default";
73954
74277
  } else {
73955
74278
  const conversation = await client.conversations.create({
73956
74279
  agent_id: agent.id,
@@ -74185,7 +74508,7 @@ ${loadedContents.join(`
74185
74508
  message: `Maximum turns limit reached (${buffers.usage.stepCount}/${maxTurns} steps)`,
74186
74509
  stop_reason: "max_steps",
74187
74510
  session_id: sessionId,
74188
- uuid: `error-max-turns-${crypto.randomUUID()}`
74511
+ uuid: `error-max-turns-${randomUUID5()}`
74189
74512
  };
74190
74513
  console.log(JSON.stringify(errorMsg));
74191
74514
  } else {
@@ -74234,7 +74557,7 @@ ${loadedContents.join(`
74234
74557
  recovery_type: "approval_pending",
74235
74558
  message: "Detected pending approval conflict on send; resolving before retry",
74236
74559
  session_id: sessionId,
74237
- uuid: `recovery-pre-stream-${crypto.randomUUID()}`
74560
+ uuid: `recovery-pre-stream-${randomUUID5()}`
74238
74561
  };
74239
74562
  console.log(JSON.stringify(recoveryMsg));
74240
74563
  } else {
@@ -74253,7 +74576,7 @@ ${loadedContents.join(`
74253
74576
  max_attempts: CONVERSATION_BUSY_MAX_RETRIES,
74254
74577
  delay_ms: CONVERSATION_BUSY_RETRY_DELAY_MS,
74255
74578
  session_id: sessionId,
74256
- uuid: `retry-conversation-busy-${crypto.randomUUID()}`
74579
+ uuid: `retry-conversation-busy-${randomUUID5()}`
74257
74580
  };
74258
74581
  console.log(JSON.stringify(retryMsg));
74259
74582
  } else {
@@ -74275,7 +74598,7 @@ ${loadedContents.join(`
74275
74598
  max_attempts: LLM_API_ERROR_MAX_RETRIES,
74276
74599
  delay_ms: delayMs,
74277
74600
  session_id: sessionId,
74278
- uuid: `retry-pre-stream-${crypto.randomUUID()}`
74601
+ uuid: `retry-pre-stream-${randomUUID5()}`
74279
74602
  };
74280
74603
  console.log(JSON.stringify(retryMsg));
74281
74604
  } else {
@@ -74310,7 +74633,7 @@ ${loadedContents.join(`
74310
74633
  stop_reason: "error",
74311
74634
  run_id: errorInfo.run_id,
74312
74635
  session_id: sessionId,
74313
- uuid: crypto.randomUUID(),
74636
+ uuid: randomUUID5(),
74314
74637
  ...errorInfo.error_type && errorInfo.run_id && {
74315
74638
  api_error: {
74316
74639
  message_type: "error_message",
@@ -74332,7 +74655,7 @@ ${loadedContents.join(`
74332
74655
  message: "Detected pending approval conflict; auto-denying stale approval and retrying",
74333
74656
  run_id: recoveryRunId ?? undefined,
74334
74657
  session_id: sessionId,
74335
- uuid: `recovery-${recoveryRunId || crypto.randomUUID()}`
74658
+ uuid: `recovery-${recoveryRunId || randomUUID5()}`
74336
74659
  };
74337
74660
  console.log(JSON.stringify(recoveryMsg));
74338
74661
  approvalPendingRecovery = true;
@@ -74372,7 +74695,7 @@ ${loadedContents.join(`
74372
74695
  type: "stream_event",
74373
74696
  event: chunk,
74374
74697
  session_id: sessionId,
74375
- uuid: uuid || crypto.randomUUID()
74698
+ uuid: uuid || randomUUID5()
74376
74699
  };
74377
74700
  console.log(JSON.stringify(streamEvent));
74378
74701
  } else {
@@ -74380,7 +74703,7 @@ ${loadedContents.join(`
74380
74703
  type: "message",
74381
74704
  ...chunk,
74382
74705
  session_id: sessionId,
74383
- uuid: uuid || crypto.randomUUID()
74706
+ uuid: uuid || randomUUID5()
74384
74707
  };
74385
74708
  console.log(JSON.stringify(msg));
74386
74709
  }
@@ -74488,7 +74811,7 @@ ${loadedContents.join(`
74488
74811
  delay_ms: delayMs,
74489
74812
  run_id: lastRunId ?? undefined,
74490
74813
  session_id: sessionId,
74491
- uuid: `retry-${lastRunId || crypto.randomUUID()}`
74814
+ uuid: `retry-${lastRunId || randomUUID5()}`
74492
74815
  };
74493
74816
  console.log(JSON.stringify(retryMsg));
74494
74817
  } else {
@@ -74508,7 +74831,7 @@ ${loadedContents.join(`
74508
74831
  message: "Tool call ID mismatch; fetching actual pending approvals and resyncing",
74509
74832
  run_id: lastRunId ?? undefined,
74510
74833
  session_id: sessionId,
74511
- uuid: `recovery-${lastRunId || crypto.randomUUID()}`
74834
+ uuid: `recovery-${lastRunId || randomUUID5()}`
74512
74835
  };
74513
74836
  console.log(JSON.stringify(recoveryMsg));
74514
74837
  } else {
@@ -74525,7 +74848,7 @@ ${loadedContents.join(`
74525
74848
  stop_reason: stopReason,
74526
74849
  run_id: lastRunId ?? undefined,
74527
74850
  session_id: sessionId,
74528
- uuid: `error-${lastRunId || crypto.randomUUID()}`
74851
+ uuid: `error-${lastRunId || randomUUID5()}`
74529
74852
  };
74530
74853
  console.log(JSON.stringify(errorMsg));
74531
74854
  } else {
@@ -74564,7 +74887,7 @@ ${loadedContents.join(`
74564
74887
  delay_ms: delayMs,
74565
74888
  run_id: lastRunId ?? undefined,
74566
74889
  session_id: sessionId,
74567
- uuid: `retry-${lastRunId || crypto.randomUUID()}`
74890
+ uuid: `retry-${lastRunId || randomUUID5()}`
74568
74891
  };
74569
74892
  console.log(JSON.stringify(retryMsg));
74570
74893
  } else {
@@ -74605,7 +74928,7 @@ ${loadedContents.join(`
74605
74928
  stop_reason: stopReason,
74606
74929
  run_id: lastRunId ?? undefined,
74607
74930
  session_id: sessionId,
74608
- uuid: `error-${lastRunId || crypto.randomUUID()}`
74931
+ uuid: `error-${lastRunId || randomUUID5()}`
74609
74932
  };
74610
74933
  console.log(JSON.stringify(errorMsg));
74611
74934
  } else {
@@ -74623,7 +74946,7 @@ ${loadedContents.join(`
74623
74946
  stop_reason: "error",
74624
74947
  run_id: lastKnownRunId ?? undefined,
74625
74948
  session_id: sessionId,
74626
- uuid: `error-${lastKnownRunId || crypto.randomUUID()}`
74949
+ uuid: `error-${lastKnownRunId || randomUUID5()}`
74627
74950
  };
74628
74951
  console.log(JSON.stringify(errorMsg));
74629
74952
  } else {
@@ -74909,7 +75232,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
74909
75232
  message: "Invalid JSON input",
74910
75233
  stop_reason: "error",
74911
75234
  session_id: sessionId,
74912
- uuid: crypto.randomUUID()
75235
+ uuid: randomUUID5()
74913
75236
  };
74914
75237
  console.log(JSON.stringify(errorMsg2));
74915
75238
  continue;
@@ -74936,7 +75259,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
74936
75259
  }
74937
75260
  },
74938
75261
  session_id: sessionId,
74939
- uuid: crypto.randomUUID()
75262
+ uuid: randomUUID5()
74940
75263
  };
74941
75264
  console.log(JSON.stringify(initResponse));
74942
75265
  } else if (subtype === "interrupt") {
@@ -74951,7 +75274,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
74951
75274
  request_id: requestId ?? ""
74952
75275
  },
74953
75276
  session_id: sessionId,
74954
- uuid: crypto.randomUUID()
75277
+ uuid: randomUUID5()
74955
75278
  };
74956
75279
  console.log(JSON.stringify(interruptResponse));
74957
75280
  } else if (subtype === "register_external_tools") {
@@ -74999,7 +75322,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
74999
75322
  response: { registered: tools.length }
75000
75323
  },
75001
75324
  session_id: sessionId,
75002
- uuid: crypto.randomUUID()
75325
+ uuid: randomUUID5()
75003
75326
  };
75004
75327
  console.log(JSON.stringify(registerResponse));
75005
75328
  } else {
@@ -75011,7 +75334,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
75011
75334
  error: `Unknown control request subtype: ${subtype}`
75012
75335
  },
75013
75336
  session_id: sessionId,
75014
- uuid: crypto.randomUUID()
75337
+ uuid: randomUUID5()
75015
75338
  };
75016
75339
  console.log(JSON.stringify(errorResponse));
75017
75340
  }
@@ -75135,7 +75458,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
75135
75458
  recovery_type: "approval_pending",
75136
75459
  message: "Detected pending approval conflict on send; resolving before retry",
75137
75460
  session_id: sessionId,
75138
- uuid: `recovery-bidir-${crypto.randomUUID()}`
75461
+ uuid: `recovery-bidir-${randomUUID5()}`
75139
75462
  };
75140
75463
  console.log(JSON.stringify(recoveryMsg));
75141
75464
  await resolveAllPendingApprovals();
@@ -75153,7 +75476,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
75153
75476
  max_attempts: LLM_API_ERROR_MAX_RETRIES,
75154
75477
  delay_ms: delayMs,
75155
75478
  session_id: sessionId,
75156
- uuid: `retry-bidir-${crypto.randomUUID()}`
75479
+ uuid: `retry-bidir-${randomUUID5()}`
75157
75480
  };
75158
75481
  console.log(JSON.stringify(retryMsg));
75159
75482
  await new Promise((resolve22) => setTimeout(resolve22, delayMs));
@@ -75175,7 +75498,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
75175
75498
  stop_reason: "error",
75176
75499
  run_id: errorInfo.run_id,
75177
75500
  session_id: sessionId,
75178
- uuid: crypto.randomUUID(),
75501
+ uuid: randomUUID5(),
75179
75502
  ...errorInfo.error_type && errorInfo.run_id && {
75180
75503
  api_error: {
75181
75504
  message_type: "error_message",
@@ -75199,7 +75522,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
75199
75522
  type: "stream_event",
75200
75523
  event: chunk,
75201
75524
  session_id: sessionId,
75202
- uuid: uuid || crypto.randomUUID()
75525
+ uuid: uuid || randomUUID5()
75203
75526
  };
75204
75527
  console.log(JSON.stringify(streamEvent));
75205
75528
  } else {
@@ -75207,7 +75530,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
75207
75530
  type: "message",
75208
75531
  ...chunk,
75209
75532
  session_id: sessionId,
75210
- uuid: uuid || crypto.randomUUID()
75533
+ uuid: uuid || randomUUID5()
75211
75534
  };
75212
75535
  console.log(JSON.stringify(msg));
75213
75536
  }
@@ -75344,7 +75667,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
75344
75667
  message: errorDetails,
75345
75668
  stop_reason: "error",
75346
75669
  session_id: sessionId,
75347
- uuid: crypto.randomUUID()
75670
+ uuid: randomUUID5()
75348
75671
  };
75349
75672
  console.log(JSON.stringify(errorMsg2));
75350
75673
  const errorResultMsg = {
@@ -75373,7 +75696,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
75373
75696
  message: `Unknown message type: ${message.type}`,
75374
75697
  stop_reason: "error",
75375
75698
  session_id: sessionId,
75376
- uuid: crypto.randomUUID()
75699
+ uuid: randomUUID5()
75377
75700
  };
75378
75701
  console.log(JSON.stringify(errorMsg));
75379
75702
  }
@@ -75385,7 +75708,6 @@ var init_headless = __esm(async () => {
75385
75708
  init_error();
75386
75709
  init_context();
75387
75710
  init_memory();
75388
- init_model();
75389
75711
  init_skillSources();
75390
75712
  init_errorFormatter();
75391
75713
  init_messageQueueBridge();
@@ -75397,6 +75719,7 @@ var init_headless = __esm(async () => {
75397
75719
  init_client2(),
75398
75720
  init_create(),
75399
75721
  init_message(),
75722
+ init_model(),
75400
75723
  init_accumulator(),
75401
75724
  init_approvalClassification(),
75402
75725
  init_memoryReminder(),
@@ -77056,12 +77379,12 @@ function AgentSelector({
77056
77379
  }
77057
77380
  var import_react31, jsx_dev_runtime11, SOLID_LINE2 = "─", TABS, TAB_DESCRIPTIONS, TAB_EMPTY_STATES, DISPLAY_PAGE_SIZE2 = 5, FETCH_PAGE_SIZE2 = 20;
77058
77381
  var init_AgentSelector = __esm(async () => {
77059
- init_model();
77060
77382
  init_useTerminalWidth();
77061
77383
  init_colors();
77062
77384
  await __promiseAll([
77063
77385
  init_build2(),
77064
77386
  init_client2(),
77387
+ init_model(),
77065
77388
  init_settings_manager(),
77066
77389
  init_MarkdownDisplay(),
77067
77390
  init_Text2()
@@ -81196,9 +81519,404 @@ var init_InlineTaskApproval = __esm(async () => {
81196
81519
  InlineTaskApproval.displayName = "InlineTaskApproval";
81197
81520
  });
81198
81521
 
81522
+ // src/web/plan-viewer-template.txt
81523
+ var plan_viewer_template_default = `<!DOCTYPE html>
81524
+ <html lang="en">
81525
+ <head>
81526
+ <meta charset="UTF-8">
81527
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
81528
+ <title>Plan | Letta Code</title>
81529
+ <style>
81530
+ @import url('https://fonts.googleapis.com/css2?family=Manrope:wght@300;400;500;600;700&display=swap');
81531
+ @import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500&display=swap');
81532
+ :root {
81533
+ --accent: hsl(240, 93%, 35%);
81534
+ --accent-light: hsl(240, 67%, 98%);
81535
+ --accent-light-border: hsl(240, 62%, 94%);
81536
+ --bg: #ffffff;
81537
+ --panel: #ffffff;
81538
+ --border: hsl(210, 10%, 92.2%);
81539
+ --text: hsl(0, 0%, 8%);
81540
+ --text-muted: hsl(210, 3%, 28%);
81541
+ --text-dim: hsl(210, 3%, 66%);
81542
+ --mono: 'Fira Code', Menlo, Courier, monospace;
81543
+ --sans: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', sans-serif;
81544
+ --serif: 'Iowan Old Style', 'Palatino Linotype', 'Book Antiqua', Georgia, serif;
81545
+ --radius: 6px;
81546
+ --max-w: 860px;
81547
+ --surface: hsl(0, 0%, 98%);
81548
+ --surface-2: hsl(0, 0%, 96%);
81549
+ --hover: hsl(0, 0%, 96%);
81550
+ --hover-accent: hsl(240, 67%, 98%);
81551
+ }
81552
+
81553
+ html.dark {
81554
+ --accent: hsl(240, 80%, 68%);
81555
+ --accent-light: hsl(240, 20%, 18%);
81556
+ --accent-light-border: hsl(240, 15%, 25%);
81557
+ --bg: hsl(0, 0%, 11%);
81558
+ --panel: hsl(0, 0%, 13%);
81559
+ --surface: hsl(0, 0%, 15%);
81560
+ --surface-2: hsl(0, 0%, 18%);
81561
+ --hover: hsl(0, 0%, 18%);
81562
+ --hover-accent: hsl(240, 15%, 20%);
81563
+ --border: hsl(210, 3%, 20%);
81564
+ --text: hsl(210, 7%, 84%);
81565
+ --text-muted: hsl(210, 3%, 60%);
81566
+ --text-dim: hsl(210, 3%, 42%);
81567
+ }
81568
+ * { box-sizing: border-box; margin: 0; padding: 0; }
81569
+ body {
81570
+ font-family: var(--mono);
81571
+ color: var(--text);
81572
+ background: var(--bg);
81573
+ line-height: 1.55;
81574
+ font-weight: 400;
81575
+ font-size: 13px;
81576
+ }
81577
+ a { color: var(--accent); text-decoration: none; }
81578
+ a:hover { text-decoration: underline; }
81579
+
81580
+ .app-shell {
81581
+ max-width: var(--max-w);
81582
+ margin: 22px auto;
81583
+ border: 1px solid var(--border);
81584
+ border-radius: 8px;
81585
+ overflow: hidden;
81586
+ background: var(--panel);
81587
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 6px 16px rgba(0, 0, 0, 0.04);
81588
+ }
81589
+
81590
+ .header {
81591
+ padding: 14px 20px;
81592
+ border-bottom: 1px solid var(--border);
81593
+ background: var(--panel);
81594
+ display: flex;
81595
+ gap: 12px;
81596
+ align-items: center;
81597
+ }
81598
+ .header h1 { display: none; }
81599
+ .header-brand {
81600
+ display: flex;
81601
+ flex-direction: column;
81602
+ gap: 3px;
81603
+ }
81604
+ .header-brand svg {
81605
+ height: 26px;
81606
+ width: auto;
81607
+ fill: var(--text);
81608
+ }
81609
+ .header .agent-meta {
81610
+ margin-left: auto;
81611
+ text-align: right;
81612
+ }
81613
+ .header .agent-name {
81614
+ font-family: var(--sans);
81615
+ font-size: 13px;
81616
+ font-weight: 500;
81617
+ color: var(--text-muted);
81618
+ }
81619
+ .header .plan-path {
81620
+ font-family: var(--mono);
81621
+ font-size: 11px;
81622
+ color: var(--text-dim);
81623
+ margin-top: 2px;
81624
+ }
81625
+
81626
+ .content-area {
81627
+ position: relative;
81628
+ }
81629
+ .file-meta {
81630
+ position: relative;
81631
+ border-bottom: 1px solid var(--border);
81632
+ background: var(--surface);
81633
+ padding: 10px 14px;
81634
+ min-height: 38px;
81635
+ }
81636
+ .raw-toggle {
81637
+ position: absolute;
81638
+ top: 8px;
81639
+ right: 10px;
81640
+ font-size: 11px;
81641
+ padding: 3px 8px;
81642
+ border: 1px solid var(--border);
81643
+ border-radius: 4px;
81644
+ background: var(--panel);
81645
+ color: var(--text-muted);
81646
+ cursor: pointer;
81647
+ z-index: 2;
81648
+ }
81649
+ .raw-toggle:hover { background: var(--accent-light); color: var(--accent); }
81650
+ .raw-toggle.active { background: var(--accent); color: #fff; border-color: var(--accent); }
81651
+
81652
+ .file-body {
81653
+ padding: 20px 28px;
81654
+ overflow: auto;
81655
+ font-family: var(--serif);
81656
+ font-size: 16px;
81657
+ }
81658
+ .file-body h1, .file-body h2, .file-body h3 {
81659
+ margin-top: 18px;
81660
+ margin-bottom: 8px;
81661
+ }
81662
+ .file-body h1 { font-size: 30px; }
81663
+ .file-body h2 { font-size: 23px; border-bottom: 1px solid var(--border); padding-bottom: 3px; }
81664
+ .file-body h3 { font-size: 18px; }
81665
+ .file-body p, .file-body ul, .file-body ol, .file-body pre, .file-body table, .file-body blockquote {
81666
+ margin-bottom: 12px;
81667
+ }
81668
+ .file-body ul, .file-body ol {
81669
+ padding-left: 28px;
81670
+ }
81671
+ .file-body code {
81672
+ font-family: var(--mono);
81673
+ background: var(--surface-2);
81674
+ border: 1px solid var(--border);
81675
+ border-radius: 4px;
81676
+ padding: 1px 5px;
81677
+ font-size: 13px;
81678
+ }
81679
+ .file-body pre {
81680
+ background: var(--surface-2);
81681
+ border: 1px solid var(--border);
81682
+ border-radius: 8px;
81683
+ padding: 12px;
81684
+ overflow: auto;
81685
+ }
81686
+ .file-body pre code {
81687
+ border: none;
81688
+ background: transparent;
81689
+ padding: 0;
81690
+ }
81691
+ .file-body table {
81692
+ width: 100%;
81693
+ border-collapse: collapse;
81694
+ border: 1px solid var(--border);
81695
+ }
81696
+ .file-body th, .file-body td {
81697
+ padding: 6px 10px;
81698
+ border: 1px solid var(--border);
81699
+ }
81700
+ .file-body th { background: var(--surface); text-align: left; }
81701
+ .file-body blockquote {
81702
+ border-left: 3px solid var(--accent);
81703
+ padding-left: 12px;
81704
+ color: var(--text-muted);
81705
+ }
81706
+ .file-body-raw {
81707
+ padding: 20px 28px;
81708
+ overflow: auto;
81709
+ font-family: var(--mono);
81710
+ font-size: 13px;
81711
+ white-space: pre-wrap;
81712
+ word-break: break-word;
81713
+ line-height: 1.6;
81714
+ color: var(--text);
81715
+ display: none;
81716
+ }
81717
+
81718
+ .generated {
81719
+ margin-top: 14px;
81720
+ border-top: 1px solid var(--border);
81721
+ padding: 10px 16px 16px;
81722
+ font-size: 12px;
81723
+ color: var(--text-dim);
81724
+ text-align: center;
81725
+ }
81726
+
81727
+ html.dark .file-meta { background: var(--surface); }
81728
+ html.dark .file-body { color: var(--text); }
81729
+ html.dark .file-body h1, html.dark .file-body h2, html.dark .file-body h3 { color: var(--text); border-color: var(--border); }
81730
+ html.dark .file-body th { background: var(--surface); color: var(--text); }
81731
+ html.dark .file-body td { border-color: var(--border); }
81732
+ html.dark .file-body th { border-color: var(--border); }
81733
+ html.dark .file-body table { border-color: var(--border); }
81734
+ html.dark .file-body a { color: var(--accent); }
81735
+ html.dark .file-body-raw { background: var(--surface-2); color: var(--text); }
81736
+ html.dark .agent-name { color: var(--text-dim); }
81737
+ </style>
81738
+ </head>
81739
+ <body>
81740
+ <div class="app-shell">
81741
+ <header class="header">
81742
+ <h1>Plan</h1>
81743
+ <div class="header-brand">
81744
+ <svg viewBox="0 0 1020 183" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#lc)"><path d="M109.63 73.09H73.09V109.63H109.63V73.09Z"/><path d="M146.18 24.9V0H36.54V24.9C36.54 31.34 31.33 36.55 24.89 36.55H0V146.19H24.9C31.34 146.19 36.55 151.4 36.55 157.84V182.73H146.19V157.84C146.19 151.4 151.4 146.19 157.84 146.19H182.74V36.54H157.84C151.4 36.54 146.19 31.33 146.19 24.89L146.18 24.9ZM146.18 134.53C146.18 140.96 140.97 146.18 134.53 146.18H48.2C41.76 146.18 36.55 140.97 36.55 134.53V48.19C36.55 41.75 41.76 36.54 48.2 36.54H134.54C140.98 36.54 146.19 41.75 146.19 48.19V134.53H146.18Z"/><path d="M290.2 36.54H274.08V146.18H345.7V130.67H290.2V36.54Z"/><path d="M392.16 68.82H386.43C369.2 68.82 351.83 79.38 351.83 102.97V114.44C351.83 135.82 364.2 148.59 384.93 148.59H393.68C411.17 148.59 423.61 138.3 426.16 121.72L426.38 120.26H409.78L409.51 121.16C407.05 129.29 400.63 133.08 389.3 133.08C374.6 133.08 367.66 126.55 367.49 112.53H426.77V102.96C426.77 79.37 409.39 68.81 392.17 68.81L392.16 68.82ZM367.97 98.84C369.61 88.56 375.9 84.33 389.3 84.33C402.7 84.33 408.98 88.56 410.62 98.84H367.97Z"/><path d="M458.92 36.55H442.81V68.83H432.1V84.34H442.81V115.05C442.81 142.14 459.29 146.18 469.12 146.18H479.29V130.67H473.5C463.15 130.67 458.93 125.44 458.93 112.63V84.33H479.29V68.82H458.93V36.54L458.92 36.55Z"/><path d="M513.36 36.55H497.25V68.83H486.54V84.34H497.25V115.05C497.25 142.14 513.73 146.18 523.56 146.18H533.73V130.67H527.94C517.59 130.67 513.37 125.44 513.37 112.63V84.33H533.73V68.82H513.37V36.54L513.36 36.55Z"/><path d="M616.73 130.67C613.54 130.67 612.12 129.34 612.12 126.36V99.96C612.12 72.87 595.64 68.83 585.81 68.83H571.03C558.25 68.83 544.57 78.19 544.57 92.12V93.39H560.68V92.12C560.68 87.83 565.93 84.34 572.38 84.34H581.43C592.99 84.34 595.49 88.5 595.95 97.8H572.68C554.69 97.8 542.6 107.4 542.6 121.7V123.36C542.6 130.91 545.53 148.46 572.68 148.46C579.61 148.46 591.73 147.25 598.25 139.51C602.2 146.19 610.52 146.19 616.73 146.19H618V130.68H616.73V130.67ZM596 111.78V122.43C596 131.04 582.33 132.93 577.05 132.93C561.71 132.93 558.71 129.19 558.71 122.73C558.71 115.56 565.06 111.78 577.05 111.78H596Z"/><path d="M755.83 109.7C754.29 116.63 750.78 122.3 745.39 126.53C739.99 130.77 732.78 132.92 723.95 132.92C711.01 132.92 701.57 129.46 695.91 122.64C690.28 115.75 687.43 106.62 687.43 95.49V87.66C687.43 76.43 690.29 67.2 695.91 60.21C701.58 53.29 711.02 49.78 723.95 49.78C732.1 49.78 738.92 51.73 744.23 55.6C749.52 59.35 753.12 64.42 754.95 70.66L755.18 71.45H771.8L771.52 70.13C769.99 62.78 767.13 56.35 763.04 51.02C758.94 45.69 753.95 41.58 748.2 38.81C742.46 36.04 736.37 34.64 730.11 34.64H717.77C708.99 34.64 701.01 36.66 694.05 40.66C687.07 44.66 681.51 50.64 677.51 58.42C673.64 66.07 671.67 75.5 671.67 86.46V96.69C671.67 107.65 673.63 117.13 677.51 124.89C681.5 132.57 687.07 138.49 694.04 142.49C701 146.48 708.98 148.5 717.76 148.5H730.1C736.76 148.5 743.1 147.04 748.95 144.17C754.91 141.19 759.96 136.77 763.96 131.03C768.05 125.2 770.75 118.16 771.97 110.1L772.16 108.84H756L755.81 109.7H755.83Z"/><path d="M836.22 72.98C831.27 70.51 825.74 69.25 819.77 69.25H811.04C805.08 69.25 799.54 70.5 794.59 72.98C789.6 75.47 785.55 79.31 782.54 84.4C779.65 89.46 778.18 95.77 778.18 103.16V114.6C778.18 121.98 779.65 128.29 782.55 133.37C785.55 138.45 789.61 142.29 794.59 144.78C799.54 147.25 805.07 148.51 811.04 148.51H819.77C825.73 148.51 831.27 147.26 836.22 144.78C841.21 142.28 845.22 138.44 848.11 133.37C851.11 128.3 852.63 121.99 852.63 114.6V103.16C852.63 95.77 851.11 89.45 848.12 84.4C845.21 79.31 841.21 75.47 836.22 72.98ZM836.89 105.57V112.19C836.89 119.1 835.22 124.41 831.9 128.01C828.72 131.56 823.18 133.36 815.41 133.36C807.64 133.36 802.04 131.56 798.77 128.01C795.56 124.42 793.93 119.1 793.93 112.19V105.57C793.93 98.66 795.56 93.34 798.76 89.76C802.04 86.2 807.64 84.4 815.41 84.4C823.18 84.4 828.72 86.2 831.91 89.76C835.21 93.35 836.89 98.66 836.89 105.57Z"/><path d="M917.7 81.85C915.43 78.73 912.47 76.02 908.85 73.79C904.08 70.78 899.17 69.26 894.27 69.26C884.79 69.26 876.85 72.2 870.64 77.98C864.52 83.69 861.41 92.16 861.41 103.17V114.61C861.41 125.61 864.51 134.13 870.65 139.95C876.85 145.63 884.8 148.52 894.27 148.52C899.17 148.52 904.08 146.99 908.85 143.99C912.47 141.75 915.44 139.05 917.71 135.92V146.1H933.45V36.54H917.7V81.84V81.85ZM914.55 93.8C916.64 97.22 917.7 101.74 917.7 107.22V110.53C917.7 116.02 916.64 120.53 914.55 123.95C912.47 127.35 909.85 129.79 906.76 131.2C903.61 132.63 900.37 133.36 897.13 133.36C890.36 133.36 885.27 131.51 882.01 127.87C878.79 124.18 877.16 118.91 877.16 112.19V105.57C877.16 98.85 878.79 93.58 882 89.9C885.28 86.25 890.37 84.4 897.13 84.4C900.37 84.4 903.61 85.13 906.76 86.56C909.85 87.96 912.47 90.4 914.55 93.81V93.8Z"/><path d="M1019.23 103.16C1019.23 95.85 1017.61 89.58 1014.41 84.53C1011.3 79.35 1007.04 75.46 1001.75 72.97C996.6 70.5 990.92 69.25 984.87 69.25H979.15C973.1 69.25 967.37 70.5 962.12 72.97C956.94 75.46 952.68 79.34 949.47 84.52C946.37 89.59 944.79 95.86 944.79 103.15V114.59C944.79 125.69 947.84 134.21 953.87 139.93C959.97 145.62 967.97 148.5 977.65 148.5H986.38C994.52 148.5 1001.63 146.25 1007.51 141.81C1013.55 137.23 1017.28 130.51 1018.62 121.84L1018.82 120.57H1002.57L1002.33 121.35C999.86 129.43 993.21 133.36 982.01 133.36C974.13 133.36 968.43 131.55 965.06 128C961.81 124.48 960.14 119.27 960.09 112.54H1019.23V103.16ZM960.54 99.2C961.25 94.5 963.09 90.91 966.01 88.5C969.3 85.77 974.69 84.39 982.01 84.39C989.33 84.39 994.66 85.77 997.88 88.51C1000.89 90.92 1002.77 94.51 1003.49 99.19H960.54V99.2Z"/></g><defs><clipPath id="lc"><rect width="1019.23" height="182.72" fill="none"/></clipPath></defs></svg>
81745
+ </div>
81746
+ <div class="agent-meta">
81747
+ <div class="agent-name" id="agent-name"></div>
81748
+ <div class="plan-path" id="plan-path"></div>
81749
+ </div>
81750
+ </header>
81751
+
81752
+ <div class="content-area">
81753
+ <div class="file-meta">
81754
+ <button class="raw-toggle" id="raw-toggle">Raw</button>
81755
+ </div>
81756
+ <article class="file-body" id="rendered-view"></article>
81757
+ <pre class="file-body-raw" id="raw-view"></pre>
81758
+ </div>
81759
+
81760
+ <div class="generated" id="generated-at"></div>
81761
+ </div>
81762
+
81763
+ <script type="application/json" id="letta-data"><!--LETTA_PLAN_DATA_PLACEHOLDER--></script>
81764
+ <script>
81765
+ /**
81766
+ * marked v15.0.4 - a markdown parser
81767
+ * Copyright (c) 2011-2024, Christopher Jeffrey. (MIT Licensed)
81768
+ * https://github.com/markedjs/marked
81769
+ */
81770
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).marked={})}(this,(function(e){"use strict";function t(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}function n(t){e.defaults=t}e.defaults={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null};const s={exec:()=>null};function r(e,t=""){let n="string"==typeof e?e:e.source;const s={replace:(e,t)=>{let r="string"==typeof t?t:t.source;return r=r.replace(i.caret,"$1"),n=n.replace(e,r),s},getRegex:()=>new RegExp(n,t)};return s}const i={codeRemoveIndent:/^(?: {1,4}| {0,3}\\t)/gm,outputLinkReplace:/\\\\([\\[\\]])/g,indentCodeCompensation:/^(\\s+)(?:\`\`\`)/,beginningSpace:/^\\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\\n/g,tabCharGlobal:/\\t/g,multipleSpaceGlobal:/\\s+/g,blankLine:/^[ \\t]*$/,doubleBlankLine:/\\n[ \\t]*\\n[ \\t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\\n {0,3}((?:=+|-+) *)(?=\\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \\t]?/gm,listReplaceTabs:/^\\t+/,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\\[[ xX]\\] /,listReplaceTask:/^\\[[ xX]\\] +/,anyLine:/\\n.*\\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\\||\\| *$/g,tableRowBlankLine:/\\n[ \\t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^<a /i,endATag:/^<\\/a>/i,startPreScriptTag:/^<(pre|code|kbd|script)(\\s|>)/i,endPreScriptTag:/^<\\/(pre|code|kbd|script)(\\s|>)/i,startAngleBracket:/^</,endAngleBracket:/>$/,pedanticHrefTitle:/^([^'"]*[^\\s])\\s+(['"])(.*)\\2/,unicodeAlphaNumeric:/[\\p{L}\\p{N}]/u,escapeTest:/[&<>"']/,escapeReplace:/[&<>"']/g,escapeTestNoEncode:/[<>"']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/,escapeReplaceNoEncode:/[<>"']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/g,unescapeTest:/&(#(?:\\d+)|(?:#x[0-9A-Fa-f]+)|(?:\\w+));?/gi,caret:/(^|[^\\[])\\^/g,percentDecode:/%25/g,findPipe:/\\|/g,splitPipe:/ \\|/,slashPipe:/\\\\\\|/g,carriageReturn:/\\r\\n|\\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\\S*/,endingNewline:/\\n$/,listItemRegex:e=>new RegExp(\`^( {0,3}\${e})((?:[\\t ][^\\\\n]*)?(?:\\\\n|$))\`),nextBulletRegex:e=>new RegExp(\`^ {0,\${Math.min(3,e-1)}}(?:[*+-]|\\\\d{1,9}[.)])((?:[ \\t][^\\\\n]*)?(?:\\\\n|$))\`),hrRegex:e=>new RegExp(\`^ {0,\${Math.min(3,e-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\\\* *){3,})(?:\\\\n+|$)\`),fencesBeginRegex:e=>new RegExp(\`^ {0,\${Math.min(3,e-1)}}(?:\\\`\\\`\\\`|~~~)\`),headingBeginRegex:e=>new RegExp(\`^ {0,\${Math.min(3,e-1)}}#\`),htmlBeginRegex:e=>new RegExp(\`^ {0,\${Math.min(3,e-1)}}<(?:[a-z].*>|!--)\`,"i")},l=/^ {0,3}((?:-[\\t ]*){3,}|(?:_[ \\t]*){3,}|(?:\\*[ \\t]*){3,})(?:\\n+|$)/,o=/(?:[*+-]|\\d{1,9}[.)])/,a=r(/^(?!bull |blockCode|fences|blockquote|heading|html)((?:.|\\n(?!\\s*?\\n|bull |blockCode|fences|blockquote|heading|html))+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/).replace(/bull/g,o).replace(/blockCode/g,/(?: {4}| {0,3}\\t)/).replace(/fences/g,/ {0,3}(?:\`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\\n>]+>\\n/).getRegex(),c=/^([^\\n]+(?:\\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\\n)[^\\n]+)*)/,h=/(?!\\s*\\])(?:\\\\.|[^\\[\\]\\\\])+/,p=r(/^ {0,3}\\[(label)\\]: *(?:\\n[ \\t]*)?([^<\\s][^\\s]*|<.*?>)(?:(?: +(?:\\n[ \\t]*)?| *\\n[ \\t]*)(title))? *(?:\\n+|$)/).replace("label",h).replace("title",/(?:"(?:\\\\"?|[^"\\\\])*"|'[^'\\n]*(?:\\n[^'\\n]+)*\\n?'|\\([^()]*\\))/).getRegex(),u=r(/^( {0,3}bull)([ \\t][^\\n]+?)?(?:\\n|$)/).replace(/bull/g,o).getRegex(),g="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",k=/<!--(?:-?>|[\\s\\S]*?(?:-->|$))/,f=r("^ {0,3}(?:<(script|pre|style|textarea)[\\\\s>][\\\\s\\\\S]*?(?:</\\\\1>[^\\\\n]*\\\\n+|$)|comment[^\\\\n]*(\\\\n+|$)|<\\\\?[\\\\s\\\\S]*?(?:\\\\?>\\\\n*|$)|<![A-Z][\\\\s\\\\S]*?(?:>\\\\n*|$)|<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?(?:\\\\]\\\\]>\\\\n*|$)|</?(tag)(?: +|\\\\n|/?>)[\\\\s\\\\S]*?(?:(?:\\\\n[ \\t]*)+\\\\n|$)|<(?!script|pre|style|textarea)([a-z][\\\\w-]*)(?:attribute)*? */?>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ \\t]*)+\\\\n|$)|</(?!script|pre|style|textarea)[a-z][\\\\w-]*\\\\s*>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ \\t]*)+\\\\n|$))","i").replace("comment",k).replace("tag",g).replace("attribute",/ +[a-zA-Z:_][\\w.:-]*(?: *= *"[^"\\n]*"| *= *'[^'\\n]*'| *= *[^\\s"'=<>\`]+)?/).getRegex(),d=r(c).replace("hr",l).replace("heading"," {0,3}#{1,6}(?:\\\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:\`{3,}(?=[^\`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",g).getRegex(),x={blockquote:r(/^( {0,3}> ?(paragraph|[^\\n]*)(?:\\n|$))+/).replace("paragraph",d).getRegex(),code:/^((?: {4}| {0,3}\\t)[^\\n]+(?:\\n(?:[ \\t]*(?:\\n|$))*)?)+/,def:p,fences:/^ {0,3}(\`{3,}(?=[^\`\\n]*(?:\\n|$))|~{3,})([^\\n]*)(?:\\n|$)(?:|([\\s\\S]*?)(?:\\n|$))(?: {0,3}\\1[~\`]* *(?=\\n|$)|$)/,heading:/^ {0,3}(#{1,6})(?=\\s|$)(.*)(?:\\n+|$)/,hr:l,html:f,lheading:a,list:u,newline:/^(?:[ \\t]*(?:\\n|$))+/,paragraph:d,table:s,text:/^[^\\n]+/},b=r("^ *([^\\\\n ].*)\\\\n {0,3}((?:\\\\| *)?:?-+:? *(?:\\\\| *:?-+:? *)*(?:\\\\| *)?)(?:\\\\n((?:(?! *\\\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\\\n|$))*)\\\\n*|$)").replace("hr",l).replace("heading"," {0,3}#{1,6}(?:\\\\s|$)").replace("blockquote"," {0,3}>").replace("code","(?: {4}| {0,3}\\t)[^\\\\n]").replace("fences"," {0,3}(?:\`{3,}(?=[^\`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",g).getRegex(),w={...x,table:b,paragraph:r(c).replace("hr",l).replace("heading"," {0,3}#{1,6}(?:\\\\s|$)").replace("|lheading","").replace("table",b).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:\`{3,}(?=[^\`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",g).getRegex()},m={...x,html:r("^ *(?:comment *(?:\\\\n|\\\\s*$)|<(tag)[\\\\s\\\\S]+?</\\\\1> *(?:\\\\n{2,}|\\\\s*$)|<tag(?:\\"[^\\"]*\\"|'[^']*'|\\\\s[^'\\"/>\\\\s]*)*?/?> *(?:\\\\n{2,}|\\\\s*$))").replace("comment",k).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\\\b)\\\\w+(?!:|[^\\\\w\\\\s@]*@)\\\\b").getRegex(),def:/^ *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +(["(][^\\n]+[")]))? *(?:\\n+|$)/,heading:/^(#{1,6})(.*)(?:\\n+|$)/,fences:s,lheading:/^(.+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,paragraph:r(c).replace("hr",l).replace("heading"," *#{1,6} *[^\\n]").replace("lheading",a).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},y=/^\\\\([!"#$%&'()*+,\\-./:;<=>?@\\[\\]\\\\^_\`{|}~])/,$=/^( {2,}|\\\\)\\n(?!\\s*$)/,R=/[\\p{P}\\p{S}]/u,S=/[\\s\\p{P}\\p{S}]/u,T=/[^\\s\\p{P}\\p{S}]/u,z=r(/^((?![*_])punctSpace)/,"u").replace(/punctSpace/g,S).getRegex(),A=r(/^(?:\\*+(?:((?!\\*)punct)|[^\\s*]))|^_+(?:((?!_)punct)|([^\\s_]))/,"u").replace(/punct/g,R).getRegex(),_=r("^[^_*]*?__[^_*]*?\\\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\\\*)punct(\\\\*+)(?=[\\\\s]|$)|notPunctSpace(\\\\*+)(?!\\\\*)(?=punctSpace|$)|(?!\\\\*)punctSpace(\\\\*+)(?=notPunctSpace)|[\\\\s](\\\\*+)(?!\\\\*)(?=punct)|(?!\\\\*)punct(\\\\*+)(?!\\\\*)(?=punct)|notPunctSpace(\\\\*+)(?=notPunctSpace)","gu").replace(/notPunctSpace/g,T).replace(/punctSpace/g,S).replace(/punct/g,R).getRegex(),P=r("^[^_*]*?\\\\*\\\\*[^_*]*?_[^_*]*?(?=\\\\*\\\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)","gu").replace(/notPunctSpace/g,T).replace(/punctSpace/g,S).replace(/punct/g,R).getRegex(),I=r(/\\\\(punct)/,"gu").replace(/punct/g,R).getRegex(),L=r(/^<(scheme:[^\\s\\x00-\\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&'*+/=?^_\`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),B=r(k).replace("(?:--\\x3e|$)","--\\x3e").getRegex(),C=r("^comment|^</[a-zA-Z][\\\\w:-]*\\\\s*>|^<[a-zA-Z][\\\\w-]*(?:attribute)*?\\\\s*/?>|^<\\\\?[\\\\s\\\\S]*?\\\\?>|^<![a-zA-Z]+\\\\s[\\\\s\\\\S]*?>|^<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?\\\\]\\\\]>").replace("comment",B).replace("attribute",/\\s+[a-zA-Z:_][\\w.:-]*(?:\\s*=\\s*"[^"]*"|\\s*=\\s*'[^']*'|\\s*=\\s*[^\\s"'=<>\`]+)?/).getRegex(),E=/(?:\\[(?:\\\\.|[^\\[\\]\\\\])*\\]|\\\\.|\`[^\`]*\`|[^\\[\\]\\\\\`])*?/,q=r(/^!?\\[(label)\\]\\(\\s*(href)(?:\\s+(title))?\\s*\\)/).replace("label",E).replace("href",/<(?:\\\\.|[^\\n<>\\\\])+>|[^\\s\\x00-\\x1f]*/).replace("title",/"(?:\\\\"?|[^"\\\\])*"|'(?:\\\\'?|[^'\\\\])*'|\\((?:\\\\\\)?|[^)\\\\])*\\)/).getRegex(),Z=r(/^!?\\[(label)\\]\\[(ref)\\]/).replace("label",E).replace("ref",h).getRegex(),v=r(/^!?\\[(ref)\\](?:\\[\\])?/).replace("ref",h).getRegex(),D={_backpedal:s,anyPunctuation:I,autolink:L,blockSkip:/\\[[^[\\]]*?\\]\\((?:\\\\.|[^\\\\\\(\\)]|\\((?:\\\\.|[^\\\\\\(\\)])*\\))*\\)|\`[^\`]*?\`|<[^<>]*?>/g,br:$,code:/^(\`+)([^\`]|[^\`][\\s\\S]*?[^\`])\\1(?!\`)/,del:s,emStrongLDelim:A,emStrongRDelimAst:_,emStrongRDelimUnd:P,escape:y,link:q,nolink:v,punctuation:z,reflink:Z,reflinkSearch:r("reflink|nolink(?!\\\\()","g").replace("reflink",Z).replace("nolink",v).getRegex(),tag:C,text:/^(\`+|[^\`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\<!\\[\`*_]|\\b_|$)|[^ ](?= {2,}\\n)))/,url:s},M={...D,link:r(/^!?\\[(label)\\]\\((.*?)\\)/).replace("label",E).getRegex(),reflink:r(/^!?\\[(label)\\]\\s*\\[([^\\]]*)\\]/).replace("label",E).getRegex()},O={...D,escape:r(y).replace("])","~|])").getRegex(),url:r(/^((?:ftp|https?):\\/\\/|www\\.)(?:[a-zA-Z0-9\\-]+\\.?)+[^\\s<]*|^email/,"i").replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'"~()&]+|\\([^)]*\\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\\s~])((?:\\\\.|[^\\\\])*?(?:\\\\.|[^\\s~\\\\]))\\1(?=[^~]|$)/,text:/^([\`~]+|[^\`~])(?:(?= {2,}\\n)|(?=[a-zA-Z0-9.!#$%&'*+\\/=?_\`{\\|}~-]+@)|[\\s\\S]*?(?:(?=[\\\\<!\\[\`*~_]|\\b_|https?:\\/\\/|ftp:\\/\\/|www\\.|$)|[^ ](?= {2,}\\n)|[^a-zA-Z0-9.!#$%&'*+\\/=?_\`{\\|}~-](?=[a-zA-Z0-9.!#$%&'*+\\/=?_\`{\\|}~-]+@)))/},Q={...O,br:r($).replace("{2,}","*").getRegex(),text:r(O.text).replace("\\\\b_","\\\\b_| {2,}\\\\n").replace(/\\{2,\\}/g,"*").getRegex()},j={normal:x,gfm:w,pedantic:m},N={normal:D,gfm:O,breaks:Q,pedantic:M},G={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"},H=e=>G[e];function X(e,t){if(t){if(i.escapeTest.test(e))return e.replace(i.escapeReplace,H)}else if(i.escapeTestNoEncode.test(e))return e.replace(i.escapeReplaceNoEncode,H);return e}function F(e){try{e=encodeURI(e).replace(i.percentDecode,"%")}catch{return null}return e}function U(e,t){const n=e.replace(i.findPipe,((e,t,n)=>{let s=!1,r=t;for(;--r>=0&&"\\\\"===n[r];)s=!s;return s?"|":" |"})).split(i.splitPipe);let s=0;if(n[0].trim()||n.shift(),n.length>0&&!n.at(-1)?.trim()&&n.pop(),t)if(n.length>t)n.splice(t);else for(;n.length<t;)n.push("");for(;s<n.length;s++)n[s]=n[s].trim().replace(i.slashPipe,"|");return n}function J(e,t,n){const s=e.length;if(0===s)return"";let r=0;for(;r<s;){const i=e.charAt(s-r-1);if(i!==t||n){if(i===t||!n)break;r++}else r++}return e.slice(0,s-r)}function K(e,t,n,s,r){const i=t.href,l=t.title||null,o=e[1].replace(r.other.outputLinkReplace,"$1");if("!"!==e[0].charAt(0)){s.state.inLink=!0;const e={type:"link",raw:n,href:i,title:l,text:o,tokens:s.inlineTokens(o)};return s.state.inLink=!1,e}return{type:"image",raw:n,href:i,title:l,text:o}}class V{options;rules;lexer;constructor(t){this.options=t||e.defaults}space(e){const t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)return{type:"space",raw:t[0]}}code(e){const t=this.rules.block.code.exec(e);if(t){const e=t[0].replace(this.rules.other.codeRemoveIndent,"");return{type:"code",raw:t[0],codeBlockStyle:"indented",text:this.options.pedantic?e:J(e,"\\n")}}}fences(e){const t=this.rules.block.fences.exec(e);if(t){const e=t[0],n=function(e,t,n){const s=e.match(n.other.indentCodeCompensation);if(null===s)return t;const r=s[1];return t.split("\\n").map((e=>{const t=e.match(n.other.beginningSpace);if(null===t)return e;const[s]=t;return s.length>=r.length?e.slice(r.length):e})).join("\\n")}(e,t[3]||"",this.rules);return{type:"code",raw:e,lang:t[2]?t[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):t[2],text:n}}}heading(e){const t=this.rules.block.heading.exec(e);if(t){let e=t[2].trim();if(this.rules.other.endingHash.test(e)){const t=J(e,"#");this.options.pedantic?e=t.trim():t&&!this.rules.other.endingSpaceChar.test(t)||(e=t.trim())}return{type:"heading",raw:t[0],depth:t[1].length,text:e,tokens:this.lexer.inline(e)}}}hr(e){const t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:J(t[0],"\\n")}}blockquote(e){const t=this.rules.block.blockquote.exec(e);if(t){let e=J(t[0],"\\n").split("\\n"),n="",s="";const r=[];for(;e.length>0;){let t=!1;const i=[];let l;for(l=0;l<e.length;l++)if(this.rules.other.blockquoteStart.test(e[l]))i.push(e[l]),t=!0;else{if(t)break;i.push(e[l])}e=e.slice(l);const o=i.join("\\n"),a=o.replace(this.rules.other.blockquoteSetextReplace,"\\n $1").replace(this.rules.other.blockquoteSetextReplace2,"");n=n?\`\${n}\\n\${o}\`:o,s=s?\`\${s}\\n\${a}\`:a;const c=this.lexer.state.top;if(this.lexer.state.top=!0,this.lexer.blockTokens(a,r,!0),this.lexer.state.top=c,0===e.length)break;const h=r.at(-1);if("code"===h?.type)break;if("blockquote"===h?.type){const t=h,i=t.raw+"\\n"+e.join("\\n"),l=this.blockquote(i);r[r.length-1]=l,n=n.substring(0,n.length-t.raw.length)+l.raw,s=s.substring(0,s.length-t.text.length)+l.text;break}if("list"!==h?.type);else{const t=h,i=t.raw+"\\n"+e.join("\\n"),l=this.list(i);r[r.length-1]=l,n=n.substring(0,n.length-h.raw.length)+l.raw,s=s.substring(0,s.length-t.raw.length)+l.raw,e=i.substring(r.at(-1).raw.length).split("\\n")}}return{type:"blockquote",raw:n,tokens:r,text:s}}}list(e){let t=this.rules.block.list.exec(e);if(t){let n=t[1].trim();const s=n.length>1,r={type:"list",raw:"",ordered:s,start:s?+n.slice(0,-1):"",loose:!1,items:[]};n=s?\`\\\\d{1,9}\\\\\${n.slice(-1)}\`:\`\\\\\${n}\`,this.options.pedantic&&(n=s?n:"[*+-]");const i=this.rules.other.listItemRegex(n);let l=!1;for(;e;){let n=!1,s="",o="";if(!(t=i.exec(e)))break;if(this.rules.block.hr.test(e))break;s=t[0],e=e.substring(s.length);let a=t[2].split("\\n",1)[0].replace(this.rules.other.listReplaceTabs,(e=>" ".repeat(3*e.length))),c=e.split("\\n",1)[0],h=!a.trim(),p=0;if(this.options.pedantic?(p=2,o=a.trimStart()):h?p=t[1].length+1:(p=t[2].search(this.rules.other.nonSpaceChar),p=p>4?1:p,o=a.slice(p),p+=t[1].length),h&&this.rules.other.blankLine.test(c)&&(s+=c+"\\n",e=e.substring(c.length+1),n=!0),!n){const t=this.rules.other.nextBulletRegex(p),n=this.rules.other.hrRegex(p),r=this.rules.other.fencesBeginRegex(p),i=this.rules.other.headingBeginRegex(p),l=this.rules.other.htmlBeginRegex(p);for(;e;){const u=e.split("\\n",1)[0];let g;if(c=u,this.options.pedantic?(c=c.replace(this.rules.other.listReplaceNesting," "),g=c):g=c.replace(this.rules.other.tabCharGlobal," "),r.test(c))break;if(i.test(c))break;if(l.test(c))break;if(t.test(c))break;if(n.test(c))break;if(g.search(this.rules.other.nonSpaceChar)>=p||!c.trim())o+="\\n"+g.slice(p);else{if(h)break;if(a.replace(this.rules.other.tabCharGlobal," ").search(this.rules.other.nonSpaceChar)>=4)break;if(r.test(a))break;if(i.test(a))break;if(n.test(a))break;o+="\\n"+c}h||c.trim()||(h=!0),s+=u+"\\n",e=e.substring(u.length+1),a=g.slice(p)}}r.loose||(l?r.loose=!0:this.rules.other.doubleBlankLine.test(s)&&(l=!0));let u,g=null;this.options.gfm&&(g=this.rules.other.listIsTask.exec(o),g&&(u="[ ] "!==g[0],o=o.replace(this.rules.other.listReplaceTask,""))),r.items.push({type:"list_item",raw:s,task:!!g,checked:u,loose:!1,text:o,tokens:[]}),r.raw+=s}const o=r.items.at(-1);if(!o)return;o.raw=o.raw.trimEnd(),o.text=o.text.trimEnd(),r.raw=r.raw.trimEnd();for(let e=0;e<r.items.length;e++)if(this.lexer.state.top=!1,r.items[e].tokens=this.lexer.blockTokens(r.items[e].text,[]),!r.loose){const t=r.items[e].tokens.filter((e=>"space"===e.type)),n=t.length>0&&t.some((e=>this.rules.other.anyLine.test(e.raw)));r.loose=n}if(r.loose)for(let e=0;e<r.items.length;e++)r.items[e].loose=!0;return r}}html(e){const t=this.rules.block.html.exec(e);if(t){return{type:"html",block:!0,raw:t[0],pre:"pre"===t[1]||"script"===t[1]||"style"===t[1],text:t[0]}}}def(e){const t=this.rules.block.def.exec(e);if(t){const e=t[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal," "),n=t[2]?t[2].replace(this.rules.other.hrefBrackets,"$1").replace(this.rules.inline.anyPunctuation,"$1"):"",s=t[3]?t[3].substring(1,t[3].length-1).replace(this.rules.inline.anyPunctuation,"$1"):t[3];return{type:"def",tag:e,raw:t[0],href:n,title:s}}}table(e){const t=this.rules.block.table.exec(e);if(!t)return;if(!this.rules.other.tableDelimiter.test(t[2]))return;const n=U(t[1]),s=t[2].replace(this.rules.other.tableAlignChars,"").split("|"),r=t[3]?.trim()?t[3].replace(this.rules.other.tableRowBlankLine,"").split("\\n"):[],i={type:"table",raw:t[0],header:[],align:[],rows:[]};if(n.length===s.length){for(const e of s)this.rules.other.tableAlignRight.test(e)?i.align.push("right"):this.rules.other.tableAlignCenter.test(e)?i.align.push("center"):this.rules.other.tableAlignLeft.test(e)?i.align.push("left"):i.align.push(null);for(let e=0;e<n.length;e++)i.header.push({text:n[e],tokens:this.lexer.inline(n[e]),header:!0,align:i.align[e]});for(const e of r)i.rows.push(U(e,i.header.length).map(((e,t)=>({text:e,tokens:this.lexer.inline(e),header:!1,align:i.align[t]}))));return i}}lheading(e){const t=this.rules.block.lheading.exec(e);if(t)return{type:"heading",raw:t[0],depth:"="===t[2].charAt(0)?1:2,text:t[1],tokens:this.lexer.inline(t[1])}}paragraph(e){const t=this.rules.block.paragraph.exec(e);if(t){const e="\\n"===t[1].charAt(t[1].length-1)?t[1].slice(0,-1):t[1];return{type:"paragraph",raw:t[0],text:e,tokens:this.lexer.inline(e)}}}text(e){const t=this.rules.block.text.exec(e);if(t)return{type:"text",raw:t[0],text:t[0],tokens:this.lexer.inline(t[0])}}escape(e){const t=this.rules.inline.escape.exec(e);if(t)return{type:"escape",raw:t[0],text:t[1]}}tag(e){const t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.state.inLink&&this.rules.other.startATag.test(t[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(t[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(t[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(t[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:t[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:t[0]}}link(e){const t=this.rules.inline.link.exec(e);if(t){const e=t[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(e)){if(!this.rules.other.endAngleBracket.test(e))return;const t=J(e.slice(0,-1),"\\\\");if((e.length-t.length)%2==0)return}else{const e=function(e,t){if(-1===e.indexOf(t[1]))return-1;let n=0;for(let s=0;s<e.length;s++)if("\\\\"===e[s])s++;else if(e[s]===t[0])n++;else if(e[s]===t[1]&&(n--,n<0))return s;return-1}(t[2],"()");if(e>-1){const n=(0===t[0].indexOf("!")?5:4)+t[1].length+e;t[2]=t[2].substring(0,e),t[0]=t[0].substring(0,n).trim(),t[3]=""}}let n=t[2],s="";if(this.options.pedantic){const e=this.rules.other.pedanticHrefTitle.exec(n);e&&(n=e[1],s=e[3])}else s=t[3]?t[3].slice(1,-1):"";return n=n.trim(),this.rules.other.startAngleBracket.test(n)&&(n=this.options.pedantic&&!this.rules.other.endAngleBracket.test(e)?n.slice(1):n.slice(1,-1)),K(t,{href:n?n.replace(this.rules.inline.anyPunctuation,"$1"):n,title:s?s.replace(this.rules.inline.anyPunctuation,"$1"):s},t[0],this.lexer,this.rules)}}reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){const e=t[(n[2]||n[1]).replace(this.rules.other.multipleSpaceGlobal," ").toLowerCase()];if(!e){const e=n[0].charAt(0);return{type:"text",raw:e,text:e}}return K(n,e,n[0],this.lexer,this.rules)}}emStrong(e,t,n=""){let s=this.rules.inline.emStrongLDelim.exec(e);if(!s)return;if(s[3]&&n.match(this.rules.other.unicodeAlphaNumeric))return;if(!(s[1]||s[2]||"")||!n||this.rules.inline.punctuation.exec(n)){const n=[...s[0]].length-1;let r,i,l=n,o=0;const a="*"===s[0][0]?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(a.lastIndex=0,t=t.slice(-1*e.length+n);null!=(s=a.exec(t));){if(r=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!r)continue;if(i=[...r].length,s[3]||s[4]){l+=i;continue}if((s[5]||s[6])&&n%3&&!((n+i)%3)){o+=i;continue}if(l-=i,l>0)continue;i=Math.min(i,i+l+o);const t=[...s[0]][0].length,a=e.slice(0,n+s.index+t+i);if(Math.min(n,i)%2){const e=a.slice(1,-1);return{type:"em",raw:a,text:e,tokens:this.lexer.inlineTokens(e)}}const c=a.slice(2,-2);return{type:"strong",raw:a,text:c,tokens:this.lexer.inlineTokens(c)}}}}codespan(e){const t=this.rules.inline.code.exec(e);if(t){let e=t[2].replace(this.rules.other.newLineCharGlobal," ");const n=this.rules.other.nonSpaceChar.test(e),s=this.rules.other.startingSpaceChar.test(e)&&this.rules.other.endingSpaceChar.test(e);return n&&s&&(e=e.substring(1,e.length-1)),{type:"codespan",raw:t[0],text:e}}}br(e){const t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t[0]}}del(e){const t=this.rules.inline.del.exec(e);if(t)return{type:"del",raw:t[0],text:t[2],tokens:this.lexer.inlineTokens(t[2])}}autolink(e){const t=this.rules.inline.autolink.exec(e);if(t){let e,n;return"@"===t[2]?(e=t[1],n="mailto:"+e):(e=t[1],n=e),{type:"link",raw:t[0],text:e,href:n,tokens:[{type:"text",raw:e,text:e}]}}}url(e){let t;if(t=this.rules.inline.url.exec(e)){let e,n;if("@"===t[2])e=t[0],n="mailto:"+e;else{let s;do{s=t[0],t[0]=this.rules.inline._backpedal.exec(t[0])?.[0]??""}while(s!==t[0]);e=t[0],n="www."===t[1]?"http://"+t[0]:t[0]}return{type:"link",raw:t[0],text:e,href:n,tokens:[{type:"text",raw:e,text:e}]}}}inlineText(e){const t=this.rules.inline.text.exec(e);if(t){const e=this.lexer.state.inRawBlock;return{type:"text",raw:t[0],text:t[0],escaped:e}}}}class W{tokens;options;state;tokenizer;inlineQueue;constructor(t){this.tokens=[],this.tokens.links=Object.create(null),this.options=t||e.defaults,this.options.tokenizer=this.options.tokenizer||new V,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};const n={other:i,block:j.normal,inline:N.normal};this.options.pedantic?(n.block=j.pedantic,n.inline=N.pedantic):this.options.gfm&&(n.block=j.gfm,this.options.breaks?n.inline=N.breaks:n.inline=N.gfm),this.tokenizer.rules=n}static get rules(){return{block:j,inline:N}}static lex(e,t){return new W(t).lex(e)}static lexInline(e,t){return new W(t).inlineTokens(e)}lex(e){e=e.replace(i.carriageReturn,"\\n"),this.blockTokens(e,this.tokens);for(let e=0;e<this.inlineQueue.length;e++){const t=this.inlineQueue[e];this.inlineTokens(t.src,t.tokens)}return this.inlineQueue=[],this.tokens}blockTokens(e,t=[],n=!1){for(this.options.pedantic&&(e=e.replace(i.tabCharGlobal," ").replace(i.spaceLine,""));e;){let s;if(this.options.extensions?.block?.some((n=>!!(s=n.call({lexer:this},e,t))&&(e=e.substring(s.raw.length),t.push(s),!0))))continue;if(s=this.tokenizer.space(e)){e=e.substring(s.raw.length);const n=t.at(-1);1===s.raw.length&&void 0!==n?n.raw+="\\n":t.push(s);continue}if(s=this.tokenizer.code(e)){e=e.substring(s.raw.length);const n=t.at(-1);"paragraph"===n?.type||"text"===n?.type?(n.raw+="\\n"+s.raw,n.text+="\\n"+s.text,this.inlineQueue.at(-1).src=n.text):t.push(s);continue}if(s=this.tokenizer.fences(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.heading(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.hr(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.blockquote(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.list(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.html(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.def(e)){e=e.substring(s.raw.length);const n=t.at(-1);"paragraph"===n?.type||"text"===n?.type?(n.raw+="\\n"+s.raw,n.text+="\\n"+s.raw,this.inlineQueue.at(-1).src=n.text):this.tokens.links[s.tag]||(this.tokens.links[s.tag]={href:s.href,title:s.title});continue}if(s=this.tokenizer.table(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.lheading(e)){e=e.substring(s.raw.length),t.push(s);continue}let r=e;if(this.options.extensions?.startBlock){let t=1/0;const n=e.slice(1);let s;this.options.extensions.startBlock.forEach((e=>{s=e.call({lexer:this},n),"number"==typeof s&&s>=0&&(t=Math.min(t,s))})),t<1/0&&t>=0&&(r=e.substring(0,t+1))}if(this.state.top&&(s=this.tokenizer.paragraph(r))){const i=t.at(-1);n&&"paragraph"===i?.type?(i.raw+="\\n"+s.raw,i.text+="\\n"+s.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=i.text):t.push(s),n=r.length!==e.length,e=e.substring(s.raw.length)}else if(s=this.tokenizer.text(e)){e=e.substring(s.raw.length);const n=t.at(-1);"text"===n?.type?(n.raw+="\\n"+s.raw,n.text+="\\n"+s.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=n.text):t.push(s)}else if(e){const t="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(t);break}throw new Error(t)}}return this.state.top=!0,t}inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}inlineTokens(e,t=[]){let n=e,s=null;if(this.tokens.links){const e=Object.keys(this.tokens.links);if(e.length>0)for(;null!=(s=this.tokenizer.rules.inline.reflinkSearch.exec(n));)e.includes(s[0].slice(s[0].lastIndexOf("[")+1,-1))&&(n=n.slice(0,s.index)+"["+"a".repeat(s[0].length-2)+"]"+n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;null!=(s=this.tokenizer.rules.inline.blockSkip.exec(n));)n=n.slice(0,s.index)+"["+"a".repeat(s[0].length-2)+"]"+n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);for(;null!=(s=this.tokenizer.rules.inline.anyPunctuation.exec(n));)n=n.slice(0,s.index)+"++"+n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);let r=!1,i="";for(;e;){let s;if(r||(i=""),r=!1,this.options.extensions?.inline?.some((n=>!!(s=n.call({lexer:this},e,t))&&(e=e.substring(s.raw.length),t.push(s),!0))))continue;if(s=this.tokenizer.escape(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.tag(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.link(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(s.raw.length);const n=t.at(-1);"text"===s.type&&"text"===n?.type?(n.raw+=s.raw,n.text+=s.text):t.push(s);continue}if(s=this.tokenizer.emStrong(e,n,i)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.codespan(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.br(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.del(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.autolink(e)){e=e.substring(s.raw.length),t.push(s);continue}if(!this.state.inLink&&(s=this.tokenizer.url(e))){e=e.substring(s.raw.length),t.push(s);continue}let l=e;if(this.options.extensions?.startInline){let t=1/0;const n=e.slice(1);let s;this.options.extensions.startInline.forEach((e=>{s=e.call({lexer:this},n),"number"==typeof s&&s>=0&&(t=Math.min(t,s))})),t<1/0&&t>=0&&(l=e.substring(0,t+1))}if(s=this.tokenizer.inlineText(l)){e=e.substring(s.raw.length),"_"!==s.raw.slice(-1)&&(i=s.raw.slice(-1)),r=!0;const n=t.at(-1);"text"===n?.type?(n.raw+=s.raw,n.text+=s.text):t.push(s)}else if(e){const t="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(t);break}throw new Error(t)}}return t}}class Y{options;parser;constructor(t){this.options=t||e.defaults}space(e){return""}code({text:e,lang:t,escaped:n}){const s=(t||"").match(i.notSpaceStart)?.[0],r=e.replace(i.endingNewline,"")+"\\n";return s?'<pre><code class="language-'+X(s)+'">'+(n?r:X(r,!0))+"</code></pre>\\n":"<pre><code>"+(n?r:X(r,!0))+"</code></pre>\\n"}blockquote({tokens:e}){return\`<blockquote>\\n\${this.parser.parse(e)}</blockquote>\\n\`}html({text:e}){return e}heading({tokens:e,depth:t}){return\`<h\${t}>\${this.parser.parseInline(e)}</h\${t}>\\n\`}hr(e){return"<hr>\\n"}list(e){const t=e.ordered,n=e.start;let s="";for(let t=0;t<e.items.length;t++){const n=e.items[t];s+=this.listitem(n)}const r=t?"ol":"ul";return"<"+r+(t&&1!==n?' start="'+n+'"':"")+">\\n"+s+"</"+r+">\\n"}listitem(e){let t="";if(e.task){const n=this.checkbox({checked:!!e.checked});e.loose?"paragraph"===e.tokens[0]?.type?(e.tokens[0].text=n+" "+e.tokens[0].text,e.tokens[0].tokens&&e.tokens[0].tokens.length>0&&"text"===e.tokens[0].tokens[0].type&&(e.tokens[0].tokens[0].text=n+" "+X(e.tokens[0].tokens[0].text),e.tokens[0].tokens[0].escaped=!0)):e.tokens.unshift({type:"text",raw:n+" ",text:n+" ",escaped:!0}):t+=n+" "}return t+=this.parser.parse(e.tokens,!!e.loose),\`<li>\${t}</li>\\n\`}checkbox({checked:e}){return"<input "+(e?'checked="" ':"")+'disabled="" type="checkbox">'}paragraph({tokens:e}){return\`<p>\${this.parser.parseInline(e)}</p>\\n\`}table(e){let t="",n="";for(let t=0;t<e.header.length;t++)n+=this.tablecell(e.header[t]);t+=this.tablerow({text:n});let s="";for(let t=0;t<e.rows.length;t++){const r=e.rows[t];n="";for(let e=0;e<r.length;e++)n+=this.tablecell(r[e]);s+=this.tablerow({text:n})}return s&&(s=\`<tbody>\${s}</tbody>\`),"<table>\\n<thead>\\n"+t+"</thead>\\n"+s+"</table>\\n"}tablerow({text:e}){return\`<tr>\\n\${e}</tr>\\n\`}tablecell(e){const t=this.parser.parseInline(e.tokens),n=e.header?"th":"td";return(e.align?\`<\${n} align="\${e.align}">\`:\`<\${n}>\`)+t+\`</\${n}>\\n\`}strong({tokens:e}){return\`<strong>\${this.parser.parseInline(e)}</strong>\`}em({tokens:e}){return\`<em>\${this.parser.parseInline(e)}</em>\`}codespan({text:e}){return\`<code>\${X(e,!0)}</code>\`}br(e){return"<br>"}del({tokens:e}){return\`<del>\${this.parser.parseInline(e)}</del>\`}link({href:e,title:t,tokens:n}){const s=this.parser.parseInline(n),r=F(e);if(null===r)return s;let i='<a href="'+(e=r)+'"';return t&&(i+=' title="'+X(t)+'"'),i+=">"+s+"</a>",i}image({href:e,title:t,text:n}){const s=F(e);if(null===s)return X(n);let r=\`<img src="\${e=s}" alt="\${n}"\`;return t&&(r+=\` title="\${X(t)}"\`),r+=">",r}text(e){return"tokens"in e&&e.tokens?this.parser.parseInline(e.tokens):"escaped"in e&&e.escaped?e.text:X(e.text)}}class ee{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return""+e}image({text:e}){return""+e}br(){return""}}class te{options;renderer;textRenderer;constructor(t){this.options=t||e.defaults,this.options.renderer=this.options.renderer||new Y,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new ee}static parse(e,t){return new te(t).parse(e)}static parseInline(e,t){return new te(t).parseInline(e)}parse(e,t=!0){let n="";for(let s=0;s<e.length;s++){const r=e[s];if(this.options.extensions?.renderers?.[r.type]){const e=r,t=this.options.extensions.renderers[e.type].call({parser:this},e);if(!1!==t||!["space","hr","heading","code","table","blockquote","list","html","paragraph","text"].includes(e.type)){n+=t||"";continue}}const i=r;switch(i.type){case"space":n+=this.renderer.space(i);continue;case"hr":n+=this.renderer.hr(i);continue;case"heading":n+=this.renderer.heading(i);continue;case"code":n+=this.renderer.code(i);continue;case"table":n+=this.renderer.table(i);continue;case"blockquote":n+=this.renderer.blockquote(i);continue;case"list":n+=this.renderer.list(i);continue;case"html":n+=this.renderer.html(i);continue;case"paragraph":n+=this.renderer.paragraph(i);continue;case"text":{let r=i,l=this.renderer.text(r);for(;s+1<e.length&&"text"===e[s+1].type;)r=e[++s],l+="\\n"+this.renderer.text(r);n+=t?this.renderer.paragraph({type:"paragraph",raw:l,text:l,tokens:[{type:"text",raw:l,text:l,escaped:!0}]}):l;continue}default:{const e='Token with "'+i.type+'" type was not found.';if(this.options.silent)return console.error(e),"";throw new Error(e)}}}return n}parseInline(e,t=this.renderer){let n="";for(let s=0;s<e.length;s++){const r=e[s];if(this.options.extensions?.renderers?.[r.type]){const e=this.options.extensions.renderers[r.type].call({parser:this},r);if(!1!==e||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(r.type)){n+=e||"";continue}}const i=r;switch(i.type){case"escape":case"text":n+=t.text(i);break;case"html":n+=t.html(i);break;case"link":n+=t.link(i);break;case"image":n+=t.image(i);break;case"strong":n+=t.strong(i);break;case"em":n+=t.em(i);break;case"codespan":n+=t.codespan(i);break;case"br":n+=t.br(i);break;case"del":n+=t.del(i);break;default:{const e='Token with "'+i.type+'" type was not found.';if(this.options.silent)return console.error(e),"";throw new Error(e)}}}return n}}class ne{options;block;constructor(t){this.options=t||e.defaults}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}provideLexer(){return this.block?W.lex:W.lexInline}provideParser(){return this.block?te.parse:te.parseInline}}class se{defaults={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null};options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=te;Renderer=Y;TextRenderer=ee;Lexer=W;Tokenizer=V;Hooks=ne;constructor(...e){this.use(...e)}walkTokens(e,t){let n=[];for(const s of e)switch(n=n.concat(t.call(this,s)),s.type){case"table":{const e=s;for(const s of e.header)n=n.concat(this.walkTokens(s.tokens,t));for(const s of e.rows)for(const e of s)n=n.concat(this.walkTokens(e.tokens,t));break}case"list":{const e=s;n=n.concat(this.walkTokens(e.items,t));break}default:{const e=s;this.defaults.extensions?.childTokens?.[e.type]?this.defaults.extensions.childTokens[e.type].forEach((s=>{const r=e[s].flat(1/0);n=n.concat(this.walkTokens(r,t))})):e.tokens&&(n=n.concat(this.walkTokens(e.tokens,t)))}}return n}use(...e){const t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach((e=>{const n={...e};if(n.async=this.defaults.async||n.async||!1,e.extensions&&(e.extensions.forEach((e=>{if(!e.name)throw new Error("extension name required");if("renderer"in e){const n=t.renderers[e.name];t.renderers[e.name]=n?function(...t){let s=e.renderer.apply(this,t);return!1===s&&(s=n.apply(this,t)),s}:e.renderer}if("tokenizer"in e){if(!e.level||"block"!==e.level&&"inline"!==e.level)throw new Error("extension level must be 'block' or 'inline'");const n=t[e.level];n?n.unshift(e.tokenizer):t[e.level]=[e.tokenizer],e.start&&("block"===e.level?t.startBlock?t.startBlock.push(e.start):t.startBlock=[e.start]:"inline"===e.level&&(t.startInline?t.startInline.push(e.start):t.startInline=[e.start]))}"childTokens"in e&&e.childTokens&&(t.childTokens[e.name]=e.childTokens)})),n.extensions=t),e.renderer){const t=this.defaults.renderer||new Y(this.defaults);for(const n in e.renderer){if(!(n in t))throw new Error(\`renderer '\${n}' does not exist\`);if(["options","parser"].includes(n))continue;const s=n,r=e.renderer[s],i=t[s];t[s]=(...e)=>{let n=r.apply(t,e);return!1===n&&(n=i.apply(t,e)),n||""}}n.renderer=t}if(e.tokenizer){const t=this.defaults.tokenizer||new V(this.defaults);for(const n in e.tokenizer){if(!(n in t))throw new Error(\`tokenizer '\${n}' does not exist\`);if(["options","rules","lexer"].includes(n))continue;const s=n,r=e.tokenizer[s],i=t[s];t[s]=(...e)=>{let n=r.apply(t,e);return!1===n&&(n=i.apply(t,e)),n}}n.tokenizer=t}if(e.hooks){const t=this.defaults.hooks||new ne;for(const n in e.hooks){if(!(n in t))throw new Error(\`hook '\${n}' does not exist\`);if(["options","block"].includes(n))continue;const s=n,r=e.hooks[s],i=t[s];ne.passThroughHooks.has(n)?t[s]=e=>{if(this.defaults.async)return Promise.resolve(r.call(t,e)).then((e=>i.call(t,e)));const n=r.call(t,e);return i.call(t,n)}:t[s]=(...e)=>{let n=r.apply(t,e);return!1===n&&(n=i.apply(t,e)),n}}n.hooks=t}if(e.walkTokens){const t=this.defaults.walkTokens,s=e.walkTokens;n.walkTokens=function(e){let n=[];return n.push(s.call(this,e)),t&&(n=n.concat(t.call(this,e))),n}}this.defaults={...this.defaults,...n}})),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return W.lex(e,t??this.defaults)}parser(e,t){return te.parse(e,t??this.defaults)}parseMarkdown(e){return(t,n)=>{const s={...n},r={...this.defaults,...s},i=this.onError(!!r.silent,!!r.async);if(!0===this.defaults.async&&!1===s.async)return i(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(null==t)return i(new Error("marked(): input parameter is undefined or null"));if("string"!=typeof t)return i(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(t)+", string expected"));r.hooks&&(r.hooks.options=r,r.hooks.block=e);const l=r.hooks?r.hooks.provideLexer():e?W.lex:W.lexInline,o=r.hooks?r.hooks.provideParser():e?te.parse:te.parseInline;if(r.async)return Promise.resolve(r.hooks?r.hooks.preprocess(t):t).then((e=>l(e,r))).then((e=>r.hooks?r.hooks.processAllTokens(e):e)).then((e=>r.walkTokens?Promise.all(this.walkTokens(e,r.walkTokens)).then((()=>e)):e)).then((e=>o(e,r))).then((e=>r.hooks?r.hooks.postprocess(e):e)).catch(i);try{r.hooks&&(t=r.hooks.preprocess(t));let e=l(t,r);r.hooks&&(e=r.hooks.processAllTokens(e)),r.walkTokens&&this.walkTokens(e,r.walkTokens);let n=o(e,r);return r.hooks&&(n=r.hooks.postprocess(n)),n}catch(e){return i(e)}}}onError(e,t){return n=>{if(n.message+="\\nPlease report this to https://github.com/markedjs/marked.",e){const e="<p>An error occurred:</p><pre>"+X(n.message+"",!0)+"</pre>";return t?Promise.resolve(e):e}if(t)return Promise.reject(n);throw n}}}const re=new se;function ie(e,t){return re.parse(e,t)}ie.options=ie.setOptions=function(e){return re.setOptions(e),ie.defaults=re.defaults,n(ie.defaults),ie},ie.getDefaults=t,ie.defaults=e.defaults,ie.use=function(...e){return re.use(...e),ie.defaults=re.defaults,n(ie.defaults),ie},ie.walkTokens=function(e,t){return re.walkTokens(e,t)},ie.parseInline=re.parseInline,ie.Parser=te,ie.parser=te.parse,ie.Renderer=Y,ie.TextRenderer=ee,ie.Lexer=W,ie.lexer=W.lex,ie.Tokenizer=V,ie.Hooks=ne,ie.parse=ie;const le=ie.options,oe=ie.setOptions,ae=ie.use,ce=ie.walkTokens,he=ie.parseInline,pe=ie,ue=te.parse,ge=W.lex;e.Hooks=ne,e.Lexer=W,e.Marked=se,e.Parser=te,e.Renderer=Y,e.TextRenderer=ee,e.Tokenizer=V,e.getDefaults=t,e.lexer=ge,e.marked=ie,e.options=le,e.parse=pe,e.parseInline=he,e.parser=ue,e.setOptions=oe,e.use=ae,e.walkTokens=ce}));
81771
+ </script>
81772
+ <script>
81773
+ (function() {
81774
+ 'use strict';
81775
+
81776
+ if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
81777
+ document.documentElement.classList.add('dark');
81778
+ }
81779
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {
81780
+ document.documentElement.classList.toggle('dark', e.matches);
81781
+ });
81782
+
81783
+ var dataEl = document.getElementById('letta-data');
81784
+ var DATA;
81785
+ try {
81786
+ DATA = JSON.parse(dataEl.textContent);
81787
+ } catch (err) {
81788
+ document.body.innerHTML = '<div style="padding:20px;color:red">Failed to parse data: ' + String(err && err.message ? err.message : err) + '</div>';
81789
+ return;
81790
+ }
81791
+
81792
+ function escHtml(s) {
81793
+ return String(s || '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
81794
+ }
81795
+
81796
+ function sanitizeUrl(raw) {
81797
+ if (!raw) return '';
81798
+ return String(raw).replace(/[\\x00-\\x1f\\x7f]/g, '').trim();
81799
+ }
81800
+ function isSafeUrl(clean) {
81801
+ if (!clean) return false;
81802
+ if (/^(https?:|mailto:)/i.test(clean)) return true;
81803
+ return !clean.startsWith('//') && !/^[a-z][a-z0-9+.-]*:/i.test(clean);
81804
+ }
81805
+
81806
+ function escAttr(s) {
81807
+ return escHtml(s).replace(/"/g, '&quot;').replace(/'/g, '&#39;');
81808
+ }
81809
+
81810
+ var renderer = new marked.Renderer();
81811
+ renderer.html = function(token) {
81812
+ return escHtml(token && token.text ? token.text : '');
81813
+ };
81814
+ renderer.link = function(opts) {
81815
+ var clean = sanitizeUrl(opts && opts.href ? opts.href : '');
81816
+ var safeHref = isSafeUrl(clean) ? escAttr(clean) : '#';
81817
+ var titleAttr = opts && opts.title ? ' title="' + escAttr(opts.title) + '"' : '';
81818
+ var inner = this.parser && opts && opts.tokens ? this.parser.parseInline(opts.tokens) : escHtml('');
81819
+ return '<a href="' + safeHref + '"' + titleAttr + ' rel="noopener" target="_blank">' + inner + '</a>';
81820
+ };
81821
+ renderer.image = function(opts) {
81822
+ var clean = sanitizeUrl(opts && opts.href ? opts.href : '');
81823
+ var safeHref = isSafeUrl(clean) ? escAttr(clean) : '';
81824
+ var titleAttr = opts && opts.title ? ' title="' + escAttr(opts.title) + '"' : '';
81825
+ var alt = escAttr(opts && opts.text ? opts.text : '');
81826
+ return safeHref
81827
+ ? '<img src="' + safeHref + '" alt="' + alt + '"' + titleAttr + '>'
81828
+ : '[' + escHtml(opts && opts.text ? opts.text : '') + ']';
81829
+ };
81830
+ marked.use({ renderer: renderer, gfm: true, breaks: true });
81831
+
81832
+ function renderMarkdown(text) {
81833
+ try {
81834
+ return marked.parse(String(text || ''));
81835
+ } catch (_) {
81836
+ return '<pre>' + escHtml(String(text || '')) + '</pre>';
81837
+ }
81838
+ }
81839
+
81840
+ // Header
81841
+ var agentName = DATA.agent && DATA.agent.name ? DATA.agent.name : '';
81842
+ var nameEl = document.getElementById('agent-name');
81843
+ if (agentName) {
81844
+ nameEl.textContent = agentName + "'s plan";
81845
+ } else {
81846
+ nameEl.textContent = 'Plan';
81847
+ }
81848
+ var pathEl = document.getElementById('plan-path');
81849
+ if (DATA.planFilePath) {
81850
+ pathEl.textContent = DATA.planFilePath;
81851
+ }
81852
+ document.getElementById('generated-at').textContent = 'Generated ' + new Date(DATA.generatedAt).toLocaleString();
81853
+
81854
+ // Content
81855
+ var renderedView = document.getElementById('rendered-view');
81856
+ var rawView = document.getElementById('raw-view');
81857
+ var toggleBtn = document.getElementById('raw-toggle');
81858
+ var rawMode = false;
81859
+
81860
+ renderedView.innerHTML = renderMarkdown(DATA.planContent || '');
81861
+ rawView.textContent = DATA.planContent || '';
81862
+
81863
+ toggleBtn.addEventListener('click', function() {
81864
+ rawMode = !rawMode;
81865
+ renderedView.style.display = rawMode ? 'none' : '';
81866
+ rawView.style.display = rawMode ? 'block' : '';
81867
+ toggleBtn.textContent = rawMode ? 'Rendered' : 'Raw';
81868
+ toggleBtn.classList.toggle('active', rawMode);
81869
+ });
81870
+ })();
81871
+ </script>
81872
+ </body>
81873
+ </html>
81874
+ `;
81875
+ var init_plan_viewer_template = () => {};
81876
+
81877
+ // src/web/generate-plan-viewer.ts
81878
+ import { chmodSync as chmodSync2, existsSync as existsSync14, mkdirSync as mkdirSync10, writeFileSync as writeFileSync7 } from "node:fs";
81879
+ import { homedir as homedir17 } from "node:os";
81880
+ import { join as join25 } from "node:path";
81881
+ async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
81882
+ const data = {
81883
+ agent: { name: options?.agentName ?? "" },
81884
+ planContent,
81885
+ planFilePath,
81886
+ generatedAt: new Date().toISOString()
81887
+ };
81888
+ const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
81889
+ const html = plan_viewer_template_default.replace("<!--LETTA_PLAN_DATA_PLACEHOLDER-->", () => jsonPayload);
81890
+ if (!existsSync14(VIEWERS_DIR)) {
81891
+ mkdirSync10(VIEWERS_DIR, { recursive: true, mode: 448 });
81892
+ }
81893
+ try {
81894
+ chmodSync2(VIEWERS_DIR, 448);
81895
+ } catch {}
81896
+ const filePath = join25(VIEWERS_DIR, "plan.html");
81897
+ writeFileSync7(filePath, html);
81898
+ chmodSync2(filePath, 384);
81899
+ const isTmux = Boolean(process.env.TMUX);
81900
+ if (!isTmux) {
81901
+ try {
81902
+ const { default: openUrl } = await Promise.resolve().then(() => (init_open(), exports_open));
81903
+ await openUrl(filePath, { wait: false });
81904
+ } catch {
81905
+ throw new Error(`Could not open browser. Run: open ${filePath}`);
81906
+ }
81907
+ }
81908
+ return { filePath, opened: !isTmux };
81909
+ }
81910
+ var VIEWERS_DIR;
81911
+ var init_generate_plan_viewer = __esm(() => {
81912
+ init_plan_viewer_template();
81913
+ VIEWERS_DIR = join25(homedir17(), ".letta", "viewers");
81914
+ });
81915
+
81199
81916
  // src/cli/components/StaticPlanApproval.tsx
81200
81917
  var import_react44, jsx_dev_runtime23, StaticPlanApproval;
81201
81918
  var init_StaticPlanApproval = __esm(async () => {
81919
+ init_generate_plan_viewer();
81202
81920
  init_useProgressIndicator();
81203
81921
  init_useTerminalWidth();
81204
81922
  init_useTextInputCursor();
@@ -81214,9 +81932,13 @@ var init_StaticPlanApproval = __esm(async () => {
81214
81932
  onApproveAndAcceptEdits,
81215
81933
  onKeepPlanning,
81216
81934
  onCancel,
81217
- isFocused = true
81935
+ isFocused = true,
81936
+ planContent,
81937
+ planFilePath,
81938
+ agentName
81218
81939
  }) => {
81219
81940
  const [selectedOption, setSelectedOption] = import_react44.useState(0);
81941
+ const [browserStatus, setBrowserStatus] = import_react44.useState("");
81220
81942
  const {
81221
81943
  text: customReason,
81222
81944
  cursorPos,
@@ -81225,6 +81947,18 @@ var init_StaticPlanApproval = __esm(async () => {
81225
81947
  } = useTextInputCursor();
81226
81948
  const columns = useTerminalWidth();
81227
81949
  useProgressIndicator();
81950
+ const openInBrowser = import_react44.useCallback(() => {
81951
+ if (!planContent || !planFilePath)
81952
+ return;
81953
+ setBrowserStatus("Opening in browser...");
81954
+ generateAndOpenPlanViewer(planContent, planFilePath, { agentName }).then((result) => {
81955
+ setBrowserStatus(result.opened ? "Opened in browser" : `Run: open ${result.filePath}`);
81956
+ setTimeout(() => setBrowserStatus(""), 5000);
81957
+ }).catch(() => {
81958
+ setBrowserStatus("Failed to open browser");
81959
+ setTimeout(() => setBrowserStatus(""), 5000);
81960
+ });
81961
+ }, [planContent, planFilePath, agentName]);
81228
81962
  const customOptionIndex = 2;
81229
81963
  const maxOptionIndex = customOptionIndex;
81230
81964
  const isOnCustomOption = selectedOption === customOptionIndex;
@@ -81236,6 +81970,10 @@ var init_StaticPlanApproval = __esm(async () => {
81236
81970
  onCancel();
81237
81971
  return;
81238
81972
  }
81973
+ if ((input === "o" || input === "O") && !isOnCustomOption && planContent) {
81974
+ openInBrowser();
81975
+ return;
81976
+ }
81239
81977
  if (key.upArrow) {
81240
81978
  setSelectedOption((prev) => Math.max(0, prev - 1));
81241
81979
  return;
@@ -81283,7 +82021,8 @@ var init_StaticPlanApproval = __esm(async () => {
81283
82021
  return;
81284
82022
  }
81285
82023
  }, { isActive: isFocused });
81286
- const hintText = isOnCustomOption ? customReason ? "Enter to submit · Esc to clear" : "Type feedback · Esc to cancel" : "Enter to select · Esc to cancel";
82024
+ const browserHint = planContent ? " · O open in browser" : "";
82025
+ const hintText = isOnCustomOption ? customReason ? "Enter to submit · Esc to clear" : "Type feedback · Esc to cancel" : `Enter to select${browserHint} · Esc to cancel`;
81287
82026
  return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
81288
82027
  flexDirection: "column",
81289
82028
  children: [
@@ -81387,7 +82126,7 @@ var init_StaticPlanApproval = __esm(async () => {
81387
82126
  marginTop: 1,
81388
82127
  children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text2, {
81389
82128
  dimColor: true,
81390
- children: hintText
82129
+ children: browserStatus || hintText
81391
82130
  }, undefined, false, undefined, this)
81392
82131
  }, undefined, false, undefined, this)
81393
82132
  ]
@@ -81501,7 +82240,10 @@ var init_ApprovalSwitch = __esm(async () => {
81501
82240
  precomputedDiff,
81502
82241
  allDiffs,
81503
82242
  showPreview = true,
81504
- defaultScope = "project"
82243
+ defaultScope = "project",
82244
+ planContent,
82245
+ planFilePath,
82246
+ agentName
81505
82247
  }) => {
81506
82248
  const toolName = approval.toolName;
81507
82249
  if (toolName === "ExitPlanMode" && onPlanApprove && onPlanKeepPlanning) {
@@ -81510,7 +82252,10 @@ var init_ApprovalSwitch = __esm(async () => {
81510
82252
  onApproveAndAcceptEdits: () => onPlanApprove(true),
81511
82253
  onKeepPlanning: onPlanKeepPlanning,
81512
82254
  onCancel: onCancel ?? (() => {}),
81513
- isFocused
82255
+ isFocused,
82256
+ planContent,
82257
+ planFilePath,
82258
+ agentName
81514
82259
  }, undefined, false, undefined, this);
81515
82260
  }
81516
82261
  if (isFileEditTool(toolName) || isFileWriteTool(toolName) || isPatchTool(toolName)) {
@@ -83161,9 +83906,9 @@ var init_pasteRegistry = __esm(() => {
83161
83906
 
83162
83907
  // src/cli/helpers/clipboard.ts
83163
83908
  import { execFileSync as execFileSync2 } from "node:child_process";
83164
- import { existsSync as existsSync14, readFileSync as readFileSync3, statSync as statSync4, unlinkSync as unlinkSync5 } from "node:fs";
83909
+ import { existsSync as existsSync15, readFileSync as readFileSync3, statSync as statSync4, unlinkSync as unlinkSync5 } from "node:fs";
83165
83910
  import { tmpdir as tmpdir3 } from "node:os";
83166
- import { basename as basename3, extname as extname5, isAbsolute as isAbsolute16, join as join25, resolve as resolve22 } from "node:path";
83911
+ import { basename as basename3, extname as extname5, isAbsolute as isAbsolute16, join as join26, resolve as resolve22 } from "node:path";
83167
83912
  function countLines2(text) {
83168
83913
  return (text.match(/\r\n|\r|\n/g) || []).length + 1;
83169
83914
  }
@@ -83213,7 +83958,7 @@ function translatePasteForImages(paste) {
83213
83958
  if (!isAbsolute16(filePath))
83214
83959
  filePath = resolve22(process.cwd(), filePath);
83215
83960
  const ext3 = extname5(filePath || "").toLowerCase();
83216
- if (IMAGE_EXTS.has(ext3) && existsSync14(filePath) && statSync4(filePath).isFile()) {
83961
+ if (IMAGE_EXTS.has(ext3) && existsSync15(filePath) && statSync4(filePath).isFile()) {
83217
83962
  const buf = readFileSync3(filePath);
83218
83963
  const b64 = buf.toString("base64");
83219
83964
  const mt = ext3 === ".png" ? "image/png" : ext3 === ".jpg" || ext3 === ".jpeg" ? "image/jpeg" : ext3 === ".gif" ? "image/gif" : ext3 === ".webp" ? "image/webp" : ext3 === ".bmp" ? "image/bmp" : ext3 === ".svg" ? "image/svg+xml" : ext3 === ".tif" || ext3 === ".tiff" ? "image/tiff" : ext3 === ".heic" ? "image/heic" : ext3 === ".heif" ? "image/heif" : ext3 === ".avif" ? "image/avif" : "application/octet-stream";
@@ -83231,7 +83976,7 @@ function translatePasteForImages(paste) {
83231
83976
  function getClipboardImageToTempFile() {
83232
83977
  if (process.platform !== "darwin")
83233
83978
  return null;
83234
- const tempPath = join25(tmpdir3(), `letta-clipboard-${Date.now()}.bin`);
83979
+ const tempPath = join26(tmpdir3(), `letta-clipboard-${Date.now()}.bin`);
83235
83980
  try {
83236
83981
  const jxa = `
83237
83982
  ObjC.import('AppKit');
@@ -83254,11 +83999,11 @@ function getClipboardImageToTempFile() {
83254
83999
  encoding: "utf8",
83255
84000
  stdio: ["ignore", "pipe", "ignore"]
83256
84001
  }).trim();
83257
- if (!uti || !existsSync14(tempPath))
84002
+ if (!uti || !existsSync15(tempPath))
83258
84003
  return null;
83259
84004
  return { tempPath, uti };
83260
84005
  } catch {
83261
- if (existsSync14(tempPath)) {
84006
+ if (existsSync15(tempPath)) {
83262
84007
  try {
83263
84008
  unlinkSync5(tempPath);
83264
84009
  } catch {}
@@ -83291,7 +84036,7 @@ async function tryImportClipboardImageMac() {
83291
84036
  height: resized.height
83292
84037
  };
83293
84038
  } catch (err) {
83294
- if (existsSync14(tempPath)) {
84039
+ if (existsSync15(tempPath)) {
83295
84040
  try {
83296
84041
  unlinkSync5(tempPath);
83297
84042
  } catch {}
@@ -83868,13 +84613,13 @@ __export(exports_terminalKeybindingInstaller, {
83868
84613
  });
83869
84614
  import {
83870
84615
  copyFileSync,
83871
- existsSync as existsSync15,
83872
- mkdirSync as mkdirSync10,
84616
+ existsSync as existsSync16,
84617
+ mkdirSync as mkdirSync11,
83873
84618
  readFileSync as readFileSync4,
83874
- writeFileSync as writeFileSync7
84619
+ writeFileSync as writeFileSync8
83875
84620
  } from "node:fs";
83876
- import { homedir as homedir17, platform as platform4 } from "node:os";
83877
- import { dirname as dirname11, join as join26 } from "node:path";
84621
+ import { homedir as homedir18, platform as platform4 } from "node:os";
84622
+ import { dirname as dirname11, join as join27 } from "node:path";
83878
84623
  function detectTerminalType() {
83879
84624
  if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
83880
84625
  return "cursor";
@@ -83906,16 +84651,16 @@ function getKeybindingsPath(terminal) {
83906
84651
  }[terminal];
83907
84652
  const os5 = platform4();
83908
84653
  if (os5 === "darwin") {
83909
- return join26(homedir17(), "Library", "Application Support", appName, "User", "keybindings.json");
84654
+ return join27(homedir18(), "Library", "Application Support", appName, "User", "keybindings.json");
83910
84655
  }
83911
84656
  if (os5 === "win32") {
83912
84657
  const appData = process.env.APPDATA;
83913
84658
  if (!appData)
83914
84659
  return null;
83915
- return join26(appData, appName, "User", "keybindings.json");
84660
+ return join27(appData, appName, "User", "keybindings.json");
83916
84661
  }
83917
84662
  if (os5 === "linux") {
83918
- return join26(homedir17(), ".config", appName, "User", "keybindings.json");
84663
+ return join27(homedir18(), ".config", appName, "User", "keybindings.json");
83919
84664
  }
83920
84665
  return null;
83921
84666
  }
@@ -83937,7 +84682,7 @@ function parseKeybindings(content) {
83937
84682
  }
83938
84683
  }
83939
84684
  function keybindingExists(keybindingsPath) {
83940
- if (!existsSync15(keybindingsPath))
84685
+ if (!existsSync16(keybindingsPath))
83941
84686
  return false;
83942
84687
  try {
83943
84688
  const content = readFileSync4(keybindingsPath, { encoding: "utf-8" });
@@ -83950,7 +84695,7 @@ function keybindingExists(keybindingsPath) {
83950
84695
  }
83951
84696
  }
83952
84697
  function createBackup(keybindingsPath) {
83953
- if (!existsSync15(keybindingsPath))
84698
+ if (!existsSync16(keybindingsPath))
83954
84699
  return null;
83955
84700
  const backupPath = `${keybindingsPath}.letta-backup`;
83956
84701
  try {
@@ -83966,12 +84711,12 @@ function installKeybinding(keybindingsPath) {
83966
84711
  return { success: true, alreadyExists: true };
83967
84712
  }
83968
84713
  const parentDir = dirname11(keybindingsPath);
83969
- if (!existsSync15(parentDir)) {
83970
- mkdirSync10(parentDir, { recursive: true });
84714
+ if (!existsSync16(parentDir)) {
84715
+ mkdirSync11(parentDir, { recursive: true });
83971
84716
  }
83972
84717
  let keybindings = [];
83973
84718
  let backupPath = null;
83974
- if (existsSync15(keybindingsPath)) {
84719
+ if (existsSync16(keybindingsPath)) {
83975
84720
  backupPath = createBackup(keybindingsPath);
83976
84721
  const content = readFileSync4(keybindingsPath, { encoding: "utf-8" });
83977
84722
  const parsed = parseKeybindings(content);
@@ -83986,7 +84731,7 @@ function installKeybinding(keybindingsPath) {
83986
84731
  keybindings.push(SHIFT_ENTER_KEYBINDING);
83987
84732
  const newContent = `${JSON.stringify(keybindings, null, 2)}
83988
84733
  `;
83989
- writeFileSync7(keybindingsPath, newContent, { encoding: "utf-8" });
84734
+ writeFileSync8(keybindingsPath, newContent, { encoding: "utf-8" });
83990
84735
  return {
83991
84736
  success: true,
83992
84737
  backupPath: backupPath ?? undefined
@@ -84001,7 +84746,7 @@ function installKeybinding(keybindingsPath) {
84001
84746
  }
84002
84747
  function removeKeybinding(keybindingsPath) {
84003
84748
  try {
84004
- if (!existsSync15(keybindingsPath)) {
84749
+ if (!existsSync16(keybindingsPath)) {
84005
84750
  return { success: true };
84006
84751
  }
84007
84752
  const content = readFileSync4(keybindingsPath, { encoding: "utf-8" });
@@ -84015,7 +84760,7 @@ function removeKeybinding(keybindingsPath) {
84015
84760
  const filtered = keybindings.filter((kb) => !(kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus")));
84016
84761
  const newContent = `${JSON.stringify(filtered, null, 2)}
84017
84762
  `;
84018
- writeFileSync7(keybindingsPath, newContent, { encoding: "utf-8" });
84763
+ writeFileSync8(keybindingsPath, newContent, { encoding: "utf-8" });
84019
84764
  return { success: true };
84020
84765
  } catch (error) {
84021
84766
  const message = error instanceof Error ? error.message : String(error);
@@ -84068,17 +84813,17 @@ function getWezTermConfigPath() {
84068
84813
  }
84069
84814
  const xdgConfig = process.env.XDG_CONFIG_HOME;
84070
84815
  if (xdgConfig) {
84071
- const xdgPath = join26(xdgConfig, "wezterm", "wezterm.lua");
84072
- if (existsSync15(xdgPath))
84816
+ const xdgPath = join27(xdgConfig, "wezterm", "wezterm.lua");
84817
+ if (existsSync16(xdgPath))
84073
84818
  return xdgPath;
84074
84819
  }
84075
- const configPath = join26(homedir17(), ".config", "wezterm", "wezterm.lua");
84076
- if (existsSync15(configPath))
84820
+ const configPath = join27(homedir18(), ".config", "wezterm", "wezterm.lua");
84821
+ if (existsSync16(configPath))
84077
84822
  return configPath;
84078
- return join26(homedir17(), ".wezterm.lua");
84823
+ return join27(homedir18(), ".wezterm.lua");
84079
84824
  }
84080
84825
  function wezTermDeleteFixExists(configPath) {
84081
- if (!existsSync15(configPath))
84826
+ if (!existsSync16(configPath))
84082
84827
  return false;
84083
84828
  try {
84084
84829
  const content = readFileSync4(configPath, { encoding: "utf-8" });
@@ -84095,7 +84840,7 @@ function installWezTermDeleteFix() {
84095
84840
  }
84096
84841
  let content = "";
84097
84842
  let backupPath = null;
84098
- if (existsSync15(configPath)) {
84843
+ if (existsSync16(configPath)) {
84099
84844
  backupPath = `${configPath}.letta-backup`;
84100
84845
  copyFileSync(configPath, backupPath);
84101
84846
  content = readFileSync4(configPath, { encoding: "utf-8" });
@@ -84125,10 +84870,10 @@ ${WEZTERM_DELETE_FIX}
84125
84870
  `;
84126
84871
  }
84127
84872
  const parentDir = dirname11(configPath);
84128
- if (!existsSync15(parentDir)) {
84129
- mkdirSync10(parentDir, { recursive: true });
84873
+ if (!existsSync16(parentDir)) {
84874
+ mkdirSync11(parentDir, { recursive: true });
84130
84875
  }
84131
- writeFileSync7(configPath, content, { encoding: "utf-8" });
84876
+ writeFileSync8(configPath, content, { encoding: "utf-8" });
84132
84877
  return {
84133
84878
  success: true,
84134
84879
  backupPath: backupPath ?? undefined
@@ -84257,6 +85002,14 @@ var init_registry = __esm(() => {
84257
85002
  return "Opening memory viewer...";
84258
85003
  }
84259
85004
  },
85005
+ "/palace": {
85006
+ desc: "Open the Memory Palace in your browser",
85007
+ order: 16,
85008
+ noArgs: true,
85009
+ handler: () => {
85010
+ return "Opening Memory Palace...";
85011
+ }
85012
+ },
84260
85013
  "/sleeptime": {
84261
85014
  desc: "Configure reflection reminder trigger settings",
84262
85015
  order: 15.5,
@@ -84275,7 +85028,7 @@ var init_registry = __esm(() => {
84275
85028
  },
84276
85029
  "/search": {
84277
85030
  desc: "Search messages across all agents (/search [query])",
84278
- order: 16,
85031
+ order: 15.1,
84279
85032
  handler: () => {
84280
85033
  return "Opening message search...";
84281
85034
  }
@@ -84616,9 +85369,9 @@ __export(exports_custom, {
84616
85369
  GLOBAL_COMMANDS_DIR: () => GLOBAL_COMMANDS_DIR,
84617
85370
  COMMANDS_DIR: () => COMMANDS_DIR
84618
85371
  });
84619
- import { existsSync as existsSync16 } from "node:fs";
85372
+ import { existsSync as existsSync17 } from "node:fs";
84620
85373
  import { readdir as readdir9, readFile as readFile9 } from "node:fs/promises";
84621
- import { basename as basename4, dirname as dirname12, join as join27 } from "node:path";
85374
+ import { basename as basename4, dirname as dirname12, join as join28 } from "node:path";
84622
85375
  async function getCustomCommands() {
84623
85376
  if (cachedCommands !== null) {
84624
85377
  return cachedCommands;
@@ -84629,7 +85382,7 @@ async function getCustomCommands() {
84629
85382
  function refreshCustomCommands() {
84630
85383
  cachedCommands = null;
84631
85384
  }
84632
- async function discoverCustomCommands(projectPath = join27(process.cwd(), COMMANDS_DIR)) {
85385
+ async function discoverCustomCommands(projectPath = join28(process.cwd(), COMMANDS_DIR)) {
84633
85386
  const commandsById = new Map;
84634
85387
  const userCommands = await discoverFromDirectory(GLOBAL_COMMANDS_DIR, "user");
84635
85388
  for (const cmd of userCommands) {
@@ -84650,7 +85403,7 @@ async function discoverCustomCommands(projectPath = join27(process.cwd(), COMMAN
84650
85403
  return result;
84651
85404
  }
84652
85405
  async function discoverFromDirectory(dirPath, source) {
84653
- if (!existsSync16(dirPath)) {
85406
+ if (!existsSync17(dirPath)) {
84654
85407
  return [];
84655
85408
  }
84656
85409
  const commands2 = [];
@@ -84661,7 +85414,7 @@ async function findCommandFiles(currentPath, rootPath, commands2, source) {
84661
85414
  try {
84662
85415
  const entries = await readdir9(currentPath, { withFileTypes: true });
84663
85416
  for (const entry of entries) {
84664
- const fullPath = join27(currentPath, entry.name);
85417
+ const fullPath = join28(currentPath, entry.name);
84665
85418
  if (entry.isDirectory()) {
84666
85419
  await findCommandFiles(fullPath, rootPath, commands2, source);
84667
85420
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
@@ -84746,7 +85499,7 @@ async function findCustomCommand(commandName) {
84746
85499
  }
84747
85500
  var COMMANDS_DIR = ".commands", GLOBAL_COMMANDS_DIR, cachedCommands = null;
84748
85501
  var init_custom = __esm(() => {
84749
- GLOBAL_COMMANDS_DIR = join27(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
85502
+ GLOBAL_COMMANDS_DIR = join28(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
84750
85503
  });
84751
85504
 
84752
85505
  // src/cli/components/HelpDialog.tsx
@@ -87424,7 +88177,7 @@ var init_AgentInfoBar = __esm(async () => {
87424
88177
 
87425
88178
  // src/cli/helpers/fileSearch.ts
87426
88179
  import { readdirSync as readdirSync6, statSync as statSync5 } from "node:fs";
87427
- import { join as join28, resolve as resolve23 } from "node:path";
88180
+ import { join as join29, resolve as resolve23 } from "node:path";
87428
88181
  function shouldExcludeEntry(entry) {
87429
88182
  if (entry.startsWith(".")) {
87430
88183
  return true;
@@ -87442,7 +88195,7 @@ function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = [],
87442
88195
  continue;
87443
88196
  }
87444
88197
  try {
87445
- const fullPath = join28(dir, entry);
88198
+ const fullPath = join29(dir, entry);
87446
88199
  const stats = statSync5(fullPath);
87447
88200
  const relativePath = fullPath.startsWith(process.cwd()) ? fullPath.slice(process.cwd().length + 1) : fullPath;
87448
88201
  const matches = pattern.length === 0 || relativePath.toLowerCase().includes(pattern.toLowerCase());
@@ -87497,7 +88250,7 @@ async function searchFiles(query, deep = false) {
87497
88250
  const matchingEntries = entries.filter((entry) => !shouldExcludeEntry(entry)).filter((entry) => searchPattern.length === 0 || entry.toLowerCase().includes(searchPattern.toLowerCase()));
87498
88251
  for (const entry of matchingEntries.slice(0, 50)) {
87499
88252
  try {
87500
- const fullPath = join28(searchDir, entry);
88253
+ const fullPath = join29(searchDir, entry);
87501
88254
  const stats = statSync5(fullPath);
87502
88255
  const relativePath = fullPath.startsWith(process.cwd()) ? fullPath.slice(process.cwd().length + 1) : fullPath;
87503
88256
  results.push({
@@ -90705,7 +91458,7 @@ var init_McpSelector = __esm(async () => {
90705
91458
 
90706
91459
  // src/agent/memoryScanner.ts
90707
91460
  import { readdirSync as readdirSync7, readFileSync as readFileSync5, statSync as statSync6 } from "node:fs";
90708
- import { join as join29, relative as relative7 } from "node:path";
91461
+ import { join as join30, relative as relative7 } from "node:path";
90709
91462
  function scanMemoryFilesystem(memoryRoot) {
90710
91463
  const nodes = [];
90711
91464
  const scanDir = (dir, depth, parentIsLast) => {
@@ -90717,8 +91470,8 @@ function scanMemoryFilesystem(memoryRoot) {
90717
91470
  }
90718
91471
  const filtered = entries.filter((name) => !name.startsWith("."));
90719
91472
  const sorted = filtered.sort((a, b) => {
90720
- const aPath = join29(dir, a);
90721
- const bPath = join29(dir, b);
91473
+ const aPath = join30(dir, a);
91474
+ const bPath = join30(dir, b);
90722
91475
  let aIsDir = false;
90723
91476
  let bIsDir = false;
90724
91477
  try {
@@ -90738,7 +91491,7 @@ function scanMemoryFilesystem(memoryRoot) {
90738
91491
  return a.localeCompare(b);
90739
91492
  });
90740
91493
  sorted.forEach((name, index) => {
90741
- const fullPath = join29(dir, name);
91494
+ const fullPath = join30(dir, name);
90742
91495
  let isDir = false;
90743
91496
  try {
90744
91497
  isDir = statSync6(fullPath).isDirectory();
@@ -92408,10 +93161,14 @@ html.dark .warning-badge { background: hsl(42, 30%, 18%); color: hsl(42, 80%, 70
92408
93161
  var init_memory_viewer_template = () => {};
92409
93162
 
92410
93163
  // src/web/generate-memory-viewer.ts
93164
+ var exports_generate_memory_viewer = {};
93165
+ __export(exports_generate_memory_viewer, {
93166
+ generateAndOpenMemoryViewer: () => generateAndOpenMemoryViewer
93167
+ });
92411
93168
  import { execFile as execFileCb2 } from "node:child_process";
92412
- import { chmodSync as chmodSync2, existsSync as existsSync17, mkdirSync as mkdirSync11, writeFileSync as writeFileSync8 } from "node:fs";
92413
- import { homedir as homedir18 } from "node:os";
92414
- import { join as join30 } from "node:path";
93169
+ import { chmodSync as chmodSync3, existsSync as existsSync18, mkdirSync as mkdirSync12, writeFileSync as writeFileSync9 } from "node:fs";
93170
+ import { homedir as homedir19 } from "node:os";
93171
+ import { join as join31 } from "node:path";
92415
93172
  import { promisify as promisify10 } from "node:util";
92416
93173
  async function runGitSafe(cwd2, args) {
92417
93174
  try {
@@ -92694,15 +93451,15 @@ async function generateAndOpenMemoryViewer(agentId, options) {
92694
93451
  }
92695
93452
  const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
92696
93453
  const html = memory_viewer_template_default.replace("<!--LETTA_DATA_PLACEHOLDER-->", () => jsonPayload);
92697
- if (!existsSync17(VIEWERS_DIR)) {
92698
- mkdirSync11(VIEWERS_DIR, { recursive: true, mode: 448 });
93454
+ if (!existsSync18(VIEWERS_DIR2)) {
93455
+ mkdirSync12(VIEWERS_DIR2, { recursive: true, mode: 448 });
92699
93456
  }
92700
93457
  try {
92701
- chmodSync2(VIEWERS_DIR, 448);
93458
+ chmodSync3(VIEWERS_DIR2, 448);
92702
93459
  } catch {}
92703
- const filePath = join30(VIEWERS_DIR, `memory-${encodeURIComponent(agentId)}.html`);
92704
- writeFileSync8(filePath, html);
92705
- chmodSync2(filePath, 384);
93460
+ const filePath = join31(VIEWERS_DIR2, `memory-${encodeURIComponent(agentId)}.html`);
93461
+ writeFileSync9(filePath, html);
93462
+ chmodSync3(filePath, 384);
92706
93463
  const isTmux = Boolean(process.env.TMUX);
92707
93464
  if (!isTmux) {
92708
93465
  try {
@@ -92714,7 +93471,7 @@ async function generateAndOpenMemoryViewer(agentId, options) {
92714
93471
  }
92715
93472
  return { filePath, opened: !isTmux };
92716
93473
  }
92717
- var execFile10, VIEWERS_DIR, MAX_COMMITS = 500, RECENT_DIFF_COUNT = 50, PER_DIFF_CAP = 1e5, TOTAL_PAYLOAD_CAP = 5000000, RECORD_SEP = "\x1E", REFLECTION_PATTERN;
93474
+ var execFile10, VIEWERS_DIR2, MAX_COMMITS = 500, RECENT_DIFF_COUNT = 50, PER_DIFF_CAP = 1e5, TOTAL_PAYLOAD_CAP = 5000000, RECORD_SEP = "\x1E", REFLECTION_PATTERN;
92718
93475
  var init_generate_memory_viewer = __esm(async () => {
92719
93476
  init_memoryFilesystem();
92720
93477
  init_memoryScanner();
@@ -92724,12 +93481,12 @@ var init_generate_memory_viewer = __esm(async () => {
92724
93481
  init_memoryGit()
92725
93482
  ]);
92726
93483
  execFile10 = promisify10(execFileCb2);
92727
- VIEWERS_DIR = join30(homedir18(), ".letta", "viewers");
93484
+ VIEWERS_DIR2 = join31(homedir19(), ".letta", "viewers");
92728
93485
  REFLECTION_PATTERN = /\(reflection\)|🔮|reflection:/i;
92729
93486
  });
92730
93487
 
92731
93488
  // src/cli/components/MemfsTreeViewer.tsx
92732
- import { existsSync as existsSync18 } from "node:fs";
93489
+ import { existsSync as existsSync19 } from "node:fs";
92733
93490
  function renderTreePrefix(node) {
92734
93491
  let prefix = "";
92735
93492
  for (let i = 0;i < node.depth; i++) {
@@ -92755,7 +93512,7 @@ function MemfsTreeViewer({
92755
93512
  const [status, setStatus] = import_react72.useState(null);
92756
93513
  const statusTimerRef = import_react72.useRef(null);
92757
93514
  const memoryRoot = getMemoryFilesystemRoot(agentId);
92758
- const memoryExists = existsSync18(memoryRoot);
93515
+ const memoryExists = existsSync19(memoryRoot);
92759
93516
  const hasGitRepo = import_react72.useMemo(() => isGitRepo(agentId), [agentId]);
92760
93517
  function showStatus(msg, durationMs) {
92761
93518
  if (statusTimerRef.current)
@@ -94763,12 +95520,12 @@ function ModelSelector({
94763
95520
  }
94764
95521
  var import_react76, jsx_dev_runtime54, SOLID_LINE20 = "─", VISIBLE_ITEMS2 = 8, BYOK_PROVIDER_PREFIXES;
94765
95522
  var init_ModelSelector = __esm(async () => {
94766
- init_model();
94767
95523
  init_useTerminalWidth();
94768
95524
  init_colors();
94769
95525
  await __promiseAll([
94770
95526
  init_build2(),
94771
95527
  init_available_models(),
95528
+ init_model(),
94772
95529
  init_Text2()
94773
95530
  ]);
94774
95531
  import_react76 = __toESM(require_react(), 1);
@@ -95362,11 +96119,11 @@ var init_byok_providers = __esm(async () => {
95362
96119
 
95363
96120
  // src/utils/aws-credentials.ts
95364
96121
  import { readFile as readFile10 } from "node:fs/promises";
95365
- import { homedir as homedir19 } from "node:os";
95366
- import { join as join31 } from "node:path";
96122
+ import { homedir as homedir20 } from "node:os";
96123
+ import { join as join32 } from "node:path";
95367
96124
  async function parseAwsCredentials() {
95368
- const credentialsPath = join31(homedir19(), ".aws", "credentials");
95369
- const configPath = join31(homedir19(), ".aws", "config");
96125
+ const credentialsPath = join32(homedir20(), ".aws", "credentials");
96126
+ const configPath = join32(homedir20(), ".aws", "config");
95370
96127
  const profiles = new Map;
95371
96128
  try {
95372
96129
  const content = await readFile10(credentialsPath, "utf-8");
@@ -96474,8 +97231,8 @@ function SkillsDialog({ onClose, agentId }) {
96474
97231
  try {
96475
97232
  const { discoverSkills: discoverSkills3, SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills(), exports_skills));
96476
97233
  const { getSkillsDirectory: getSkillsDirectory2, getSkillSources: getSkillSources2 } = await Promise.resolve().then(() => (init_context(), exports_context));
96477
- const { join: join32 } = await import("node:path");
96478
- const skillsDir = getSkillsDirectory2() || join32(process.cwd(), SKILLS_DIR3);
97234
+ const { join: join33 } = await import("node:path");
97235
+ const skillsDir = getSkillsDirectory2() || join33(process.cwd(), SKILLS_DIR3);
96479
97236
  const result = await discoverSkills3(skillsDir, agentId, {
96480
97237
  sources: getSkillSources2()
96481
97238
  });
@@ -97120,8 +97877,10 @@ function getSubagentModelDisplay(model) {
97120
97877
  };
97121
97878
  }
97122
97879
  var init_subagentDisplay = __esm(async () => {
97123
- init_model();
97124
- await init_openai_codex_provider();
97880
+ await __promiseAll([
97881
+ init_model(),
97882
+ init_openai_codex_provider()
97883
+ ]);
97125
97884
  });
97126
97885
 
97127
97886
  // src/cli/components/SubagentGroupDisplay.tsx
@@ -101180,12 +101939,12 @@ __export(exports_shellAliases, {
101180
101939
  expandAliases: () => expandAliases,
101181
101940
  clearAliasCache: () => clearAliasCache
101182
101941
  });
101183
- import { existsSync as existsSync19, readFileSync as readFileSync6 } from "node:fs";
101184
- import { homedir as homedir20 } from "node:os";
101185
- import { join as join32 } from "node:path";
101942
+ import { existsSync as existsSync20, readFileSync as readFileSync6 } from "node:fs";
101943
+ import { homedir as homedir21 } from "node:os";
101944
+ import { join as join33 } from "node:path";
101186
101945
  function parseAliasesFromFile(filePath) {
101187
101946
  const aliases = new Map;
101188
- if (!existsSync19(filePath)) {
101947
+ if (!existsSync20(filePath)) {
101189
101948
  return aliases;
101190
101949
  }
101191
101950
  try {
@@ -101251,10 +102010,10 @@ function loadAliases(forceReload = false) {
101251
102010
  if (aliasCache && !forceReload) {
101252
102011
  return aliasCache;
101253
102012
  }
101254
- const home = homedir20();
102013
+ const home = homedir21();
101255
102014
  const allAliases = new Map;
101256
102015
  for (const file of ALIAS_FILES) {
101257
- const filePath = join32(home, file);
102016
+ const filePath = join33(home, file);
101258
102017
  const fileAliases = parseAliasesFromFile(filePath);
101259
102018
  for (const [name, value] of fileAliases) {
101260
102019
  allAliases.set(name, value);
@@ -102590,9 +103349,9 @@ var exports_App = {};
102590
103349
  __export(exports_App, {
102591
103350
  default: () => App2
102592
103351
  });
102593
- import { existsSync as existsSync20, readFileSync as readFileSync7, renameSync as renameSync2, writeFileSync as writeFileSync9 } from "node:fs";
102594
- import { homedir as homedir21, tmpdir as tmpdir4 } from "node:os";
102595
- import { join as join33 } from "node:path";
103352
+ import { existsSync as existsSync21, readFileSync as readFileSync7, renameSync as renameSync2, writeFileSync as writeFileSync10 } from "node:fs";
103353
+ import { homedir as homedir22, tmpdir as tmpdir4 } from "node:os";
103354
+ import { join as join34 } from "node:path";
102596
103355
  function deriveReasoningEffort(modelSettings, llmConfig) {
102597
103356
  if (modelSettings && "provider_type" in modelSettings) {
102598
103357
  if (modelSettings.provider_type === "openai" && "reasoning" in modelSettings && modelSettings.reasoning) {
@@ -102789,7 +103548,21 @@ ${SYSTEM_REMINDER_CLOSE}
102789
103548
  }
102790
103549
  function planFileExists() {
102791
103550
  const planFilePath = permissionMode.getPlanFilePath();
102792
- return !!planFilePath && existsSync20(planFilePath);
103551
+ return !!planFilePath && existsSync21(planFilePath);
103552
+ }
103553
+ function _readPlanFile() {
103554
+ const planFilePath = permissionMode.getPlanFilePath();
103555
+ if (!planFilePath) {
103556
+ return "No plan file path set.";
103557
+ }
103558
+ if (!existsSync21(planFilePath)) {
103559
+ return `Plan file not found at ${planFilePath}`;
103560
+ }
103561
+ try {
103562
+ return readFileSync7(planFilePath, "utf-8");
103563
+ } catch {
103564
+ return `Failed to read plan file at ${planFilePath}`;
103565
+ }
102793
103566
  }
102794
103567
  function getQuestionsFromApproval(approval) {
102795
103568
  const parsed = safeJsonParseOr(approval.toolArgs, {});
@@ -103887,8 +104660,8 @@ function App2({
103887
104660
  if (!planFilePath)
103888
104661
  return;
103889
104662
  try {
103890
- const { readFileSync: readFileSync8, existsSync: existsSync21 } = __require("node:fs");
103891
- if (!existsSync21(planFilePath))
104663
+ const { readFileSync: readFileSync8, existsSync: existsSync22 } = __require("node:fs");
104664
+ if (!existsSync22(planFilePath))
103892
104665
  return;
103893
104666
  const planContent = readFileSync8(planFilePath, "utf-8");
103894
104667
  const previewItem = {
@@ -104051,7 +104824,7 @@ function App2({
104051
104824
  const lastRunCompletion = agent.last_run_completion;
104052
104825
  setAgentLastRunAt(lastRunCompletion ?? null);
104053
104826
  const agentModelHandle = agent.llm_config.model_endpoint_type && agent.llm_config.model ? `${agent.llm_config.model_endpoint_type}/${agent.llm_config.model}` : agent.llm_config.model;
104054
- const { getModelInfoForLlmConfig: getModelInfoForLlmConfig2 } = await Promise.resolve().then(() => (init_model(), exports_model));
104827
+ const { getModelInfoForLlmConfig: getModelInfoForLlmConfig2 } = await init_model().then(() => exports_model);
104055
104828
  const modelInfo = getModelInfoForLlmConfig2(agentModelHandle || "", agent.llm_config);
104056
104829
  if (modelInfo) {
104057
104830
  setCurrentModelId(modelInfo.id);
@@ -104167,9 +104940,9 @@ Memory may be stale. Try running: git -C ~/.letta/agents/${agentId}/memory pull`
104167
104940
  (async () => {
104168
104941
  try {
104169
104942
  const { watch } = await import("node:fs");
104170
- const { existsSync: existsSync21 } = await import("node:fs");
104943
+ const { existsSync: existsSync22 } = await import("node:fs");
104171
104944
  const memRoot = getMemoryFilesystemRoot(agentId);
104172
- if (!existsSync21(memRoot))
104945
+ if (!existsSync22(memRoot))
104173
104946
  return;
104174
104947
  watcher = watch(memRoot, { recursive: true }, () => {});
104175
104948
  memfsWatcherRef.current = watcher;
@@ -104191,6 +104964,17 @@ Memory may be stale. Try running: git -C ~/.letta/agents/${agentId}/memory pull`
104191
104964
  };
104192
104965
  }, [agentId]);
104193
104966
  const processConversation = import_react96.useCallback(async (initialInput, options) => {
104967
+ const pinnedPermissionMode = uiPermissionModeRef.current;
104968
+ const restorePinnedPermissionMode = () => {
104969
+ if (pinnedPermissionMode === "plan")
104970
+ return;
104971
+ if (permissionMode.getMode() !== pinnedPermissionMode) {
104972
+ permissionMode.setMode(pinnedPermissionMode);
104973
+ }
104974
+ if (uiPermissionModeRef.current !== pinnedPermissionMode) {
104975
+ setUiPermissionMode(pinnedPermissionMode);
104976
+ }
104977
+ };
104194
104978
  buffersRef.current.approvalsPending = false;
104195
104979
  if (buffersRef.current.serverToolCalls.size > 0) {
104196
104980
  let didPromote = false;
@@ -104423,6 +105207,7 @@ ${newState.originalPrompt}`
104423
105207
  refreshDerived();
104424
105208
  if (!cancelled) {
104425
105209
  buffersRef.current.interrupted = false;
105210
+ restorePinnedPermissionMode();
104426
105211
  continue;
104427
105212
  }
104428
105213
  }
@@ -104454,6 +105239,7 @@ ${newState.originalPrompt}`
104454
105239
  if (!cancelled) {
104455
105240
  buffersRef.current.interrupted = false;
104456
105241
  conversationBusyRetriesRef.current = 0;
105242
+ restorePinnedPermissionMode();
104457
105243
  continue;
104458
105244
  }
104459
105245
  }
@@ -104523,7 +105309,7 @@ ${newState.originalPrompt}`
104523
105309
  const agentEnableReasoner = agent.llm_config?.enable_reasoner;
104524
105310
  if (currentModel !== agentModel || currentEndpoint !== agentEndpoint || currentEffort !== agentEffort || currentEnableReasoner !== agentEnableReasoner) {
104525
105311
  setLlmConfig(agent.llm_config);
104526
- const { getModelInfoForLlmConfig: getModelInfoForLlmConfig2 } = await Promise.resolve().then(() => (init_model(), exports_model));
105312
+ const { getModelInfoForLlmConfig: getModelInfoForLlmConfig2 } = await init_model().then(() => exports_model);
104527
105313
  const agentModelHandle = agent.llm_config.model_endpoint_type && agent.llm_config.model ? `${agent.llm_config.model_endpoint_type}/${agent.llm_config.model}` : agent.llm_config.model;
104528
105314
  const modelInfo = getModelInfoForLlmConfig2(agentModelHandle || "", agent.llm_config);
104529
105315
  if (modelInfo) {
@@ -105531,7 +106317,7 @@ ${feedback}
105531
106317
  setConversationId3(targetConversationId);
105532
106318
  resetBootstrapReminderState();
105533
106319
  {
105534
- const { getModelDisplayName: getModelDisplayName2 } = await Promise.resolve().then(() => (init_model(), exports_model));
106320
+ const { getModelDisplayName: getModelDisplayName2 } = await init_model().then(() => exports_model);
105535
106321
  const modelHandle = agent.model || (agent.llm_config?.model_endpoint_type && agent.llm_config?.model ? `${agent.llm_config.model_endpoint_type}/${agent.llm_config.model}` : null);
105536
106322
  const modelLabel = modelHandle && getModelDisplayName2(modelHandle) || modelHandle || "unknown";
105537
106323
  pendingConversationSwitchRef.current = {
@@ -105637,7 +106423,7 @@ ${feedback}
105637
106423
  agentSwitchContext: {
105638
106424
  name: agent.name || agent.id,
105639
106425
  description: agent.description ?? undefined,
105640
- model: agentModelHandle ? (await Promise.resolve().then(() => (init_model(), exports_model))).getModelDisplayName(agentModelHandle) || agentModelHandle : "unknown",
106426
+ model: agentModelHandle ? (await init_model().then(() => exports_model)).getModelDisplayName(agentModelHandle) || agentModelHandle : "unknown",
105641
106427
  blockCount: agent.blocks?.length ?? 0
105642
106428
  }
105643
106429
  };
@@ -106030,6 +106816,26 @@ ${SYSTEM_REMINDER_CLOSE}` : "";
106030
106816
  setActiveOverlay("memory");
106031
106817
  return { submitted: true };
106032
106818
  }
106819
+ if (trimmed === "/palace") {
106820
+ const cmd = commandRunner.start("/palace", "Opening Memory Palace...");
106821
+ if (!settingsManager.isMemfsEnabled(agentId)) {
106822
+ cmd.finish("Memory Palace requires memfs. Run /memfs enable first.", false);
106823
+ return { submitted: true };
106824
+ }
106825
+ const { generateAndOpenMemoryViewer: generateAndOpenMemoryViewer2 } = await init_generate_memory_viewer().then(() => exports_generate_memory_viewer);
106826
+ generateAndOpenMemoryViewer2(agentId, {
106827
+ agentName: agentName ?? undefined
106828
+ }).then((result2) => {
106829
+ if (result2.opened) {
106830
+ cmd.finish("Opened Memory Palace in browser", true);
106831
+ } else {
106832
+ cmd.finish(`Open manually: ${result2.filePath}`, true);
106833
+ }
106834
+ }).catch((err) => {
106835
+ cmd.finish(`Failed to open: ${err instanceof Error ? err.message : String(err)}`, false);
106836
+ });
106837
+ return { submitted: true };
106838
+ }
106033
106839
  if (msg.trim().startsWith("/mcp")) {
106034
106840
  const mcpCtx = {
106035
106841
  buffersRef,
@@ -107079,7 +107885,7 @@ Press Enter to continue, or type anything to cancel.`, false, "running");
107079
107885
  fileContent = await client.agents.exportFile(agentId, exportParams);
107080
107886
  }
107081
107887
  const fileName = exportParams.conversation_id ? `${exportParams.conversation_id}.af` : `${agentId}.af`;
107082
- writeFileSync9(fileName, JSON.stringify(fileContent, null, 2));
107888
+ writeFileSync10(fileName, JSON.stringify(fileContent, null, 2));
107083
107889
  let summary = `AgentFile exported to ${fileName}`;
107084
107890
  if (skills.length > 0) {
107085
107891
  summary += `
@@ -107169,11 +107975,11 @@ Path: ${result2.memoryDir}`, true, msg);
107169
107975
  setCommandRunning(true);
107170
107976
  try {
107171
107977
  const memoryDir = getMemoryFilesystemRoot(agentId);
107172
- if (!existsSync20(memoryDir)) {
107978
+ if (!existsSync21(memoryDir)) {
107173
107979
  updateMemorySyncCommand(cmdId, "No local memory filesystem found to reset.", true, msg);
107174
107980
  return { submitted: true };
107175
107981
  }
107176
- const backupDir = join33(tmpdir4(), `letta-memfs-reset-${agentId}-${Date.now()}`);
107982
+ const backupDir = join34(tmpdir4(), `letta-memfs-reset-${agentId}-${Date.now()}`);
107177
107983
  renameSync2(memoryDir, backupDir);
107178
107984
  ensureMemoryFilesystemDirs(agentId);
107179
107985
  updateMemorySyncCommand(cmdId, `Memory filesystem reset.
@@ -107201,8 +108007,8 @@ Run \`/memfs sync\` to repopulate from API.`, true, msg);
107201
108007
  await removeGitMemoryTag2(agentId);
107202
108008
  let backupInfo = "";
107203
108009
  const memoryDir = getMemoryFilesystemRoot(agentId);
107204
- if (existsSync20(memoryDir)) {
107205
- const backupDir = join33(tmpdir4(), `letta-memfs-disable-${agentId}-${Date.now()}`);
108010
+ if (existsSync21(memoryDir)) {
108011
+ const backupDir = join34(tmpdir4(), `letta-memfs-disable-${agentId}-${Date.now()}`);
107206
108012
  renameSync2(memoryDir, backupDir);
107207
108013
  backupInfo = `
107208
108014
  Local files backed up to ${backupDir}`;
@@ -108436,7 +109242,7 @@ ${SYSTEM_REMINDER_CLOSE}
108436
109242
  };
108437
109243
  let selectedModel = null;
108438
109244
  try {
108439
- const { getReasoningTierOptionsForHandle: getReasoningTierOptionsForHandle2, models: models2 } = await Promise.resolve().then(() => (init_model(), exports_model));
109245
+ const { getReasoningTierOptionsForHandle: getReasoningTierOptionsForHandle2, models: models2 } = await init_model().then(() => exports_model);
108440
109246
  const pickPreferredModelForHandle = (handle) => {
108441
109247
  const candidates = models2.filter((m) => m.handle === handle);
108442
109248
  return candidates.find((m) => m.isDefault) ?? candidates.find((m) => m.isFeatured) ?? candidates.find((m) => m.updateArgs?.reasoning_effort === "medium") ?? candidates.find((m) => m.updateArgs?.reasoning_effort === "high") ?? candidates[0] ?? null;
@@ -109001,7 +109807,7 @@ ${guidance}`);
109001
109807
  setAgentState(reasoningCycleLastConfirmedAgentStateRef.current);
109002
109808
  reasoningCycleLastConfirmedAgentStateRef.current = null;
109003
109809
  }
109004
- const { getModelInfo: getModelInfo2 } = await Promise.resolve().then(() => (init_model(), exports_model));
109810
+ const { getModelInfo: getModelInfo2 } = await init_model().then(() => exports_model);
109005
109811
  const modelHandle = prev.model_endpoint_type && prev.model ? `${prev.model_endpoint_type === "chatgpt_oauth" ? OPENAI_CODEX_PROVIDER_NAME : prev.model_endpoint_type}/${prev.model}` : prev.model;
109006
109812
  const modelInfo = modelHandle ? getModelInfo2(modelHandle) : null;
109007
109813
  setCurrentModelId(modelInfo?.id ?? null);
@@ -109023,7 +109829,7 @@ ${guidance}`);
109023
109829
  if (!modelHandle)
109024
109830
  return;
109025
109831
  const currentEffort = deriveReasoningEffort(agentStateRef.current?.model_settings, current) ?? "none";
109026
- const { models: models2 } = await Promise.resolve().then(() => (init_model(), exports_model));
109832
+ const { models: models2 } = await init_model().then(() => exports_model);
109027
109833
  const tiers = models2.filter((m) => m.handle === modelHandle).map((m) => {
109028
109834
  const effort = m.updateArgs?.reasoning_effort;
109029
109835
  return {
@@ -109197,7 +110003,7 @@ ${guidance}`);
109197
110003
  }
109198
110004
  if (!planFileExists()) {
109199
110005
  const planFilePath = permissionMode.getPlanFilePath();
109200
- const plansDir = join33(homedir21(), ".letta", "plans");
110006
+ const plansDir = join34(homedir22(), ".letta", "plans");
109201
110007
  handlePlanKeepPlanning(`You must write your plan to a plan file before exiting plan mode.
109202
110008
  ` + (planFilePath ? `Plan file path: ${planFilePath}
109203
110009
  ` : "") + `Use a write tool to create your plan in ${plansDir}, then use ExitPlanMode to present the plan to the user.`);
@@ -109576,7 +110382,10 @@ Plan file path: ${planFilePath}`;
109576
110382
  approveAlwaysText: currentApprovalContext?.approveAlwaysText,
109577
110383
  allowPersistence: currentApprovalContext?.allowPersistence ?? true,
109578
110384
  defaultScope: currentApprovalContext?.defaultScope === "user" ? "session" : currentApprovalContext?.defaultScope ?? "project",
109579
- showPreview: showApprovalPreview
110385
+ showPreview: showApprovalPreview,
110386
+ planContent: currentApproval.toolName === "ExitPlanMode" ? _readPlanFile() : undefined,
110387
+ planFilePath: currentApproval.toolName === "ExitPlanMode" ? permissionMode.getPlanFilePath() ?? undefined : undefined,
110388
+ agentName: agentName ?? undefined
109580
110389
  }, undefined, false, undefined, this) : ln.kind === "user" ? /* @__PURE__ */ jsx_dev_runtime74.jsxDEV(UserMessage, {
109581
110390
  line: ln,
109582
110391
  prompt: statusLine.prompt
@@ -109628,7 +110437,10 @@ Plan file path: ${planFilePath}`;
109628
110437
  approveAlwaysText: currentApprovalContext?.approveAlwaysText,
109629
110438
  allowPersistence: currentApprovalContext?.allowPersistence ?? true,
109630
110439
  defaultScope: currentApprovalContext?.defaultScope === "user" ? "session" : currentApprovalContext?.defaultScope ?? "project",
109631
- showPreview: showApprovalPreview
110440
+ showPreview: showApprovalPreview,
110441
+ planContent: currentApproval.toolName === "ExitPlanMode" ? _readPlanFile() : undefined,
110442
+ planFilePath: currentApproval.toolName === "ExitPlanMode" ? permissionMode.getPlanFilePath() ?? undefined : undefined,
110443
+ agentName: agentName ?? undefined
109632
110444
  }, undefined, false, undefined, this)
109633
110445
  }, undefined, false, undefined, this),
109634
110446
  /* @__PURE__ */ jsx_dev_runtime74.jsxDEV(SubagentGroupDisplay, {}, undefined, false, undefined, this)
@@ -110301,7 +111113,6 @@ var init_App2 = __esm(async () => {
110301
111113
  init_http_headers();
110302
111114
  init_memory();
110303
111115
  init_memoryFilesystem();
110304
- init_model();
110305
111116
  init_promptAssets();
110306
111117
  init_constants();
110307
111118
  init_mode();
@@ -110323,6 +111134,7 @@ var init_App2 = __esm(async () => {
110323
111134
  init_pasteRegistry();
110324
111135
  init_planName();
110325
111136
  init_queuedMessageParts();
111137
+ init_sessionContext();
110326
111138
  init_statusLineHelp();
110327
111139
  init_statusLinePayload();
110328
111140
  init_statusLineRuntime();
@@ -110338,6 +111150,7 @@ var init_App2 = __esm(async () => {
110338
111150
  init_client2(),
110339
111151
  init_create(),
110340
111152
  init_message(),
111153
+ init_model(),
110341
111154
  init_hooks(),
110342
111155
  init_openai_codex_provider(),
110343
111156
  init_engine(),
@@ -110388,7 +111201,6 @@ var init_App2 = __esm(async () => {
110388
111201
  init_approvalClassification(),
110389
111202
  init_formatArgsDisplay(),
110390
111203
  init_memoryReminder(),
110391
- init_sessionContext(),
110392
111204
  init_statusLineConfig(),
110393
111205
  init_stream(),
110394
111206
  init_subagentAggregation(),
@@ -110452,13 +111264,13 @@ __export(exports_terminalKeybindingInstaller2, {
110452
111264
  });
110453
111265
  import {
110454
111266
  copyFileSync as copyFileSync2,
110455
- existsSync as existsSync21,
110456
- mkdirSync as mkdirSync12,
111267
+ existsSync as existsSync22,
111268
+ mkdirSync as mkdirSync13,
110457
111269
  readFileSync as readFileSync8,
110458
- writeFileSync as writeFileSync10
111270
+ writeFileSync as writeFileSync11
110459
111271
  } from "node:fs";
110460
- import { homedir as homedir22, platform as platform5 } from "node:os";
110461
- import { dirname as dirname13, join as join34 } from "node:path";
111272
+ import { homedir as homedir23, platform as platform5 } from "node:os";
111273
+ import { dirname as dirname13, join as join35 } from "node:path";
110462
111274
  function detectTerminalType2() {
110463
111275
  if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
110464
111276
  return "cursor";
@@ -110490,16 +111302,16 @@ function getKeybindingsPath2(terminal) {
110490
111302
  }[terminal];
110491
111303
  const os6 = platform5();
110492
111304
  if (os6 === "darwin") {
110493
- return join34(homedir22(), "Library", "Application Support", appName, "User", "keybindings.json");
111305
+ return join35(homedir23(), "Library", "Application Support", appName, "User", "keybindings.json");
110494
111306
  }
110495
111307
  if (os6 === "win32") {
110496
111308
  const appData = process.env.APPDATA;
110497
111309
  if (!appData)
110498
111310
  return null;
110499
- return join34(appData, appName, "User", "keybindings.json");
111311
+ return join35(appData, appName, "User", "keybindings.json");
110500
111312
  }
110501
111313
  if (os6 === "linux") {
110502
- return join34(homedir22(), ".config", appName, "User", "keybindings.json");
111314
+ return join35(homedir23(), ".config", appName, "User", "keybindings.json");
110503
111315
  }
110504
111316
  return null;
110505
111317
  }
@@ -110521,7 +111333,7 @@ function parseKeybindings2(content) {
110521
111333
  }
110522
111334
  }
110523
111335
  function keybindingExists2(keybindingsPath) {
110524
- if (!existsSync21(keybindingsPath))
111336
+ if (!existsSync22(keybindingsPath))
110525
111337
  return false;
110526
111338
  try {
110527
111339
  const content = readFileSync8(keybindingsPath, { encoding: "utf-8" });
@@ -110534,7 +111346,7 @@ function keybindingExists2(keybindingsPath) {
110534
111346
  }
110535
111347
  }
110536
111348
  function createBackup2(keybindingsPath) {
110537
- if (!existsSync21(keybindingsPath))
111349
+ if (!existsSync22(keybindingsPath))
110538
111350
  return null;
110539
111351
  const backupPath = `${keybindingsPath}.letta-backup`;
110540
111352
  try {
@@ -110550,12 +111362,12 @@ function installKeybinding2(keybindingsPath) {
110550
111362
  return { success: true, alreadyExists: true };
110551
111363
  }
110552
111364
  const parentDir = dirname13(keybindingsPath);
110553
- if (!existsSync21(parentDir)) {
110554
- mkdirSync12(parentDir, { recursive: true });
111365
+ if (!existsSync22(parentDir)) {
111366
+ mkdirSync13(parentDir, { recursive: true });
110555
111367
  }
110556
111368
  let keybindings = [];
110557
111369
  let backupPath = null;
110558
- if (existsSync21(keybindingsPath)) {
111370
+ if (existsSync22(keybindingsPath)) {
110559
111371
  backupPath = createBackup2(keybindingsPath);
110560
111372
  const content = readFileSync8(keybindingsPath, { encoding: "utf-8" });
110561
111373
  const parsed = parseKeybindings2(content);
@@ -110570,7 +111382,7 @@ function installKeybinding2(keybindingsPath) {
110570
111382
  keybindings.push(SHIFT_ENTER_KEYBINDING2);
110571
111383
  const newContent = `${JSON.stringify(keybindings, null, 2)}
110572
111384
  `;
110573
- writeFileSync10(keybindingsPath, newContent, { encoding: "utf-8" });
111385
+ writeFileSync11(keybindingsPath, newContent, { encoding: "utf-8" });
110574
111386
  return {
110575
111387
  success: true,
110576
111388
  backupPath: backupPath ?? undefined
@@ -110585,7 +111397,7 @@ function installKeybinding2(keybindingsPath) {
110585
111397
  }
110586
111398
  function removeKeybinding2(keybindingsPath) {
110587
111399
  try {
110588
- if (!existsSync21(keybindingsPath)) {
111400
+ if (!existsSync22(keybindingsPath)) {
110589
111401
  return { success: true };
110590
111402
  }
110591
111403
  const content = readFileSync8(keybindingsPath, { encoding: "utf-8" });
@@ -110599,7 +111411,7 @@ function removeKeybinding2(keybindingsPath) {
110599
111411
  const filtered = keybindings.filter((kb) => !(kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus")));
110600
111412
  const newContent = `${JSON.stringify(filtered, null, 2)}
110601
111413
  `;
110602
- writeFileSync10(keybindingsPath, newContent, { encoding: "utf-8" });
111414
+ writeFileSync11(keybindingsPath, newContent, { encoding: "utf-8" });
110603
111415
  return { success: true };
110604
111416
  } catch (error) {
110605
111417
  const message = error instanceof Error ? error.message : String(error);
@@ -110652,17 +111464,17 @@ function getWezTermConfigPath2() {
110652
111464
  }
110653
111465
  const xdgConfig = process.env.XDG_CONFIG_HOME;
110654
111466
  if (xdgConfig) {
110655
- const xdgPath = join34(xdgConfig, "wezterm", "wezterm.lua");
110656
- if (existsSync21(xdgPath))
111467
+ const xdgPath = join35(xdgConfig, "wezterm", "wezterm.lua");
111468
+ if (existsSync22(xdgPath))
110657
111469
  return xdgPath;
110658
111470
  }
110659
- const configPath = join34(homedir22(), ".config", "wezterm", "wezterm.lua");
110660
- if (existsSync21(configPath))
111471
+ const configPath = join35(homedir23(), ".config", "wezterm", "wezterm.lua");
111472
+ if (existsSync22(configPath))
110661
111473
  return configPath;
110662
- return join34(homedir22(), ".wezterm.lua");
111474
+ return join35(homedir23(), ".wezterm.lua");
110663
111475
  }
110664
111476
  function wezTermDeleteFixExists2(configPath) {
110665
- if (!existsSync21(configPath))
111477
+ if (!existsSync22(configPath))
110666
111478
  return false;
110667
111479
  try {
110668
111480
  const content = readFileSync8(configPath, { encoding: "utf-8" });
@@ -110679,7 +111491,7 @@ function installWezTermDeleteFix2() {
110679
111491
  }
110680
111492
  let content = "";
110681
111493
  let backupPath = null;
110682
- if (existsSync21(configPath)) {
111494
+ if (existsSync22(configPath)) {
110683
111495
  backupPath = `${configPath}.letta-backup`;
110684
111496
  copyFileSync2(configPath, backupPath);
110685
111497
  content = readFileSync8(configPath, { encoding: "utf-8" });
@@ -110709,10 +111521,10 @@ ${WEZTERM_DELETE_FIX2}
110709
111521
  `;
110710
111522
  }
110711
111523
  const parentDir = dirname13(configPath);
110712
- if (!existsSync21(parentDir)) {
110713
- mkdirSync12(parentDir, { recursive: true });
111524
+ if (!existsSync22(parentDir)) {
111525
+ mkdirSync13(parentDir, { recursive: true });
110714
111526
  }
110715
- writeFileSync10(configPath, content, { encoding: "utf-8" });
111527
+ writeFileSync11(configPath, content, { encoding: "utf-8" });
110716
111528
  return {
110717
111529
  success: true,
110718
111530
  backupPath: backupPath ?? undefined
@@ -110757,10 +111569,10 @@ __export(exports_settings2, {
110757
111569
  loadProjectSettings: () => loadProjectSettings2,
110758
111570
  getSetting: () => getSetting2
110759
111571
  });
110760
- import { homedir as homedir23 } from "node:os";
110761
- import { join as join35 } from "node:path";
111572
+ import { homedir as homedir24 } from "node:os";
111573
+ import { join as join36 } from "node:path";
110762
111574
  function getSettingsPath2() {
110763
- return join35(homedir23(), ".letta", "settings.json");
111575
+ return join36(homedir24(), ".letta", "settings.json");
110764
111576
  }
110765
111577
  async function loadSettings2() {
110766
111578
  const settingsPath = getSettingsPath2();
@@ -110797,7 +111609,7 @@ async function getSetting2(key) {
110797
111609
  return settings[key];
110798
111610
  }
110799
111611
  function getProjectSettingsPath2() {
110800
- return join35(process.cwd(), ".letta", "settings.local.json");
111612
+ return join36(process.cwd(), ".letta", "settings.local.json");
110801
111613
  }
110802
111614
  async function loadProjectSettings2() {
110803
111615
  const settingsPath = getProjectSettingsPath2();
@@ -110815,7 +111627,7 @@ async function loadProjectSettings2() {
110815
111627
  }
110816
111628
  async function saveProjectSettings2(settings) {
110817
111629
  const settingsPath = getProjectSettingsPath2();
110818
- const dirPath = join35(process.cwd(), ".letta");
111630
+ const dirPath = join36(process.cwd(), ".letta");
110819
111631
  try {
110820
111632
  if (!exists(dirPath)) {
110821
111633
  await mkdir(dirPath, { recursive: true });
@@ -110902,6 +111714,7 @@ __export(exports_model2, {
110902
111714
  getReasoningTierOptionsForHandle: () => getReasoningTierOptionsForHandle2,
110903
111715
  getModelUpdateArgs: () => getModelUpdateArgs2,
110904
111716
  getModelShortName: () => getModelShortName2,
111717
+ getModelPresetUpdateForAgent: () => getModelPresetUpdateForAgent2,
110905
111718
  getModelInfoForLlmConfig: () => getModelInfoForLlmConfig2,
110906
111719
  getModelInfo: () => getModelInfo2,
110907
111720
  getModelDisplayName: () => getModelDisplayName2,
@@ -110997,6 +111810,27 @@ function getModelUpdateArgs2(modelIdentifier) {
110997
111810
  const modelInfo = getModelInfo2(modelIdentifier);
110998
111811
  return modelInfo?.updateArgs;
110999
111812
  }
111813
+ function getModelPresetUpdateForAgent2(agent) {
111814
+ const directHandle = typeof agent.model === "string" && agent.model.length > 0 ? agent.model : null;
111815
+ const endpointType = agent.llm_config?.model_endpoint_type;
111816
+ const llmModel = agent.llm_config?.model;
111817
+ const llmDerivedHandle = typeof endpointType === "string" && endpointType.length > 0 && typeof llmModel === "string" && llmModel.length > 0 ? `${endpointType === "chatgpt_oauth" ? OPENAI_CODEX_PROVIDER_NAME : endpointType}/${llmModel}` : typeof llmModel === "string" && llmModel.includes("/") ? llmModel : null;
111818
+ const modelHandle = directHandle ?? llmDerivedHandle;
111819
+ if (!modelHandle)
111820
+ return null;
111821
+ const modelInfo = getModelInfoForLlmConfig2(modelHandle, {
111822
+ reasoning_effort: agent.llm_config?.reasoning_effort ?? null,
111823
+ enable_reasoner: agent.llm_config?.enable_reasoner ?? null
111824
+ });
111825
+ const updateArgs = modelInfo?.updateArgs ?? getModelUpdateArgs2(modelHandle);
111826
+ if (!updateArgs || Object.keys(updateArgs).length === 0) {
111827
+ return null;
111828
+ }
111829
+ return {
111830
+ modelHandle: modelInfo?.handle ?? modelHandle,
111831
+ updateArgs
111832
+ };
111833
+ }
111000
111834
  function findModelByHandle2(handle) {
111001
111835
  const pickPreferred = (candidates) => candidates.find((m) => m.isDefault) ?? candidates.find((m) => m.isFeatured) ?? candidates.find((m) => m.updateArgs?.reasoning_effort === "medium") ?? candidates.find((m) => m.updateArgs?.reasoning_effort === "high") ?? candidates[0] ?? null;
111002
111836
  const exactMatch = models2.find((m) => m.handle === handle);
@@ -111044,8 +111878,9 @@ function resolveModelByLlmConfig2(llmConfigModel) {
111044
111878
  return null;
111045
111879
  }
111046
111880
  var models2, REASONING_EFFORT_ORDER2;
111047
- var init_model2 = __esm(() => {
111881
+ var init_model2 = __esm(async () => {
111048
111882
  init_models2();
111883
+ await init_openai_codex_provider();
111049
111884
  models2 = models_default;
111050
111885
  REASONING_EFFORT_ORDER2 = [
111051
111886
  "none",
@@ -111387,12 +112222,12 @@ var init_create3 = __esm(async () => {
111387
112222
  init_http_headers();
111388
112223
  init_memory();
111389
112224
  init_memoryPrompt();
111390
- init_model();
111391
112225
  init_promptAssets();
111392
112226
  await __promiseAll([
111393
112227
  init_settings_manager(),
111394
112228
  init_available_models(),
111395
112229
  init_client2(),
112230
+ init_model(),
111396
112231
  init_modify()
111397
112232
  ]);
111398
112233
  });
@@ -111518,7 +112353,7 @@ function parseRegistryHandle2(handle) {
111518
112353
  }
111519
112354
  async function importAgentFromRegistry2(options) {
111520
112355
  const { tmpdir: tmpdir5 } = await import("node:os");
111521
- const { join: join36 } = await import("node:path");
112356
+ const { join: join37 } = await import("node:path");
111522
112357
  const { writeFile: writeFile5, unlink } = await import("node:fs/promises");
111523
112358
  const { author, name } = parseRegistryHandle2(options.handle);
111524
112359
  const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER2}/${AGENT_REGISTRY_REPO2}/refs/heads/${AGENT_REGISTRY_BRANCH2}/agents/@${author}/${name}/${name}.af`;
@@ -111530,7 +112365,7 @@ async function importAgentFromRegistry2(options) {
111530
112365
  throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
111531
112366
  }
111532
112367
  const afContent = await response.text();
111533
- const tempPath = join36(tmpdir5(), `letta-import-${author}-${name}-${Date.now()}.af`);
112368
+ const tempPath = join37(tmpdir5(), `letta-import-${author}-${name}-${Date.now()}.af`);
111534
112369
  await writeFile5(tempPath, afContent, "utf-8");
111535
112370
  try {
111536
112371
  const result = await importAgentFromFile2({
@@ -111548,9 +112383,9 @@ async function importAgentFromRegistry2(options) {
111548
112383
  }
111549
112384
  var AGENT_REGISTRY_OWNER2 = "letta-ai", AGENT_REGISTRY_REPO2 = "agent-file", AGENT_REGISTRY_BRANCH2 = "main";
111550
112385
  var init_import2 = __esm(async () => {
111551
- init_model();
111552
112386
  await __promiseAll([
111553
112387
  init_client2(),
112388
+ init_model(),
111554
112389
  init_modify()
111555
112390
  ]);
111556
112391
  });
@@ -111778,23 +112613,23 @@ __export(exports_memoryFilesystem2, {
111778
112613
  MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR2,
111779
112614
  MEMORY_FS_AGENTS_DIR: () => MEMORY_FS_AGENTS_DIR2
111780
112615
  });
111781
- import { existsSync as existsSync22, mkdirSync as mkdirSync13 } from "node:fs";
111782
- import { homedir as homedir24 } from "node:os";
111783
- import { join as join36 } from "node:path";
111784
- function getMemoryFilesystemRoot2(agentId, homeDir = homedir24()) {
111785
- return join36(homeDir, MEMORY_FS_ROOT2, MEMORY_FS_AGENTS_DIR2, agentId, MEMORY_FS_MEMORY_DIR2);
112616
+ import { existsSync as existsSync23, mkdirSync as mkdirSync14 } from "node:fs";
112617
+ import { homedir as homedir25 } from "node:os";
112618
+ import { join as join37 } from "node:path";
112619
+ function getMemoryFilesystemRoot2(agentId, homeDir = homedir25()) {
112620
+ return join37(homeDir, MEMORY_FS_ROOT2, MEMORY_FS_AGENTS_DIR2, agentId, MEMORY_FS_MEMORY_DIR2);
111786
112621
  }
111787
- function getMemorySystemDir2(agentId, homeDir = homedir24()) {
111788
- return join36(getMemoryFilesystemRoot2(agentId, homeDir), MEMORY_SYSTEM_DIR2);
112622
+ function getMemorySystemDir2(agentId, homeDir = homedir25()) {
112623
+ return join37(getMemoryFilesystemRoot2(agentId, homeDir), MEMORY_SYSTEM_DIR2);
111789
112624
  }
111790
- function ensureMemoryFilesystemDirs2(agentId, homeDir = homedir24()) {
112625
+ function ensureMemoryFilesystemDirs2(agentId, homeDir = homedir25()) {
111791
112626
  const root = getMemoryFilesystemRoot2(agentId, homeDir);
111792
112627
  const systemDir = getMemorySystemDir2(agentId, homeDir);
111793
- if (!existsSync22(root)) {
111794
- mkdirSync13(root, { recursive: true });
112628
+ if (!existsSync23(root)) {
112629
+ mkdirSync14(root, { recursive: true });
111795
112630
  }
111796
- if (!existsSync22(systemDir)) {
111797
- mkdirSync13(systemDir, { recursive: true });
112631
+ if (!existsSync23(systemDir)) {
112632
+ mkdirSync14(systemDir, { recursive: true });
111798
112633
  }
111799
112634
  }
111800
112635
  function labelFromRelativePath2(relativePath) {
@@ -112024,7 +112859,18 @@ class InternalServerError extends APIError {
112024
112859
  // src/agent/check-approval.ts
112025
112860
  init_error();
112026
112861
  init_debug();
112027
- var MESSAGE_HISTORY_LIMIT = 15;
112862
+ var BACKFILL_PRIMARY_MESSAGE_LIMIT = 12;
112863
+ var BACKFILL_MAX_RENDERABLE_MESSAGES = 80;
112864
+ var BACKFILL_ANCHOR_MESSAGE_LIMIT = 6;
112865
+ var BACKFILL_PAGE_LIMIT = 200;
112866
+ var BACKFILL_MAX_PAGES = 25;
112867
+ var BACKFILL_MIN_ASSISTANT = 1;
112868
+ function isPrimaryMessageType(messageType) {
112869
+ return messageType === "user_message" || messageType === "assistant_message" || messageType === "event_message" || messageType === "summary_message";
112870
+ }
112871
+ function isAnchorMessageType(messageType) {
112872
+ return messageType === "user_message" || messageType === "assistant_message";
112873
+ }
112028
112874
  function isBackfillEnabled() {
112029
112875
  const val = process.env.LETTA_BACKFILL;
112030
112876
  return val !== "0" && val !== "false";
@@ -112043,9 +112889,62 @@ function extractApprovals(messageToCheck) {
112043
112889
  }
112044
112890
  return { pendingApproval, pendingApprovals };
112045
112891
  }
112046
- function prepareMessageHistory(messages) {
112047
- const historyCount = Math.min(MESSAGE_HISTORY_LIMIT, messages.length);
112048
- let messageHistory = messages.slice(-historyCount);
112892
+ function prepareMessageHistory(messages, opts) {
112893
+ const isRenderable = (msg) => {
112894
+ const t = msg.message_type;
112895
+ if (t === "user_message" || t === "assistant_message" || t === "reasoning_message" || t === "tool_call_message" || t === "tool_return_message" || t === "approval_request_message" || t === "approval_response_message") {
112896
+ return true;
112897
+ }
112898
+ const ts = t;
112899
+ return ts === "event_message" || ts === "summary_message";
112900
+ };
112901
+ const renderable = messages.filter(isRenderable);
112902
+ if (opts?.primaryOnly) {
112903
+ const convo = renderable.filter((m) => isPrimaryMessageType(m.message_type));
112904
+ let trimmed = convo.slice(-BACKFILL_PRIMARY_MESSAGE_LIMIT);
112905
+ const hasAssistant = trimmed.some((m) => m.message_type === "assistant_message");
112906
+ if (!hasAssistant) {
112907
+ const lastAssistantIndex = convo.map((m) => m.message_type).lastIndexOf("assistant_message");
112908
+ if (lastAssistantIndex >= 0) {
112909
+ const lastAssistant = convo[lastAssistantIndex];
112910
+ if (lastAssistant) {
112911
+ const tailLimit = Math.max(BACKFILL_PRIMARY_MESSAGE_LIMIT - 1, 0);
112912
+ const newestTail = tailLimit > 0 ? convo.slice(-tailLimit) : [];
112913
+ trimmed = [lastAssistant, ...newestTail];
112914
+ }
112915
+ }
112916
+ }
112917
+ if (trimmed.length > 0)
112918
+ return trimmed;
112919
+ const reasoning = renderable.filter((m) => m.message_type === "reasoning_message");
112920
+ if (reasoning.length > 0) {
112921
+ return reasoning.slice(-BACKFILL_PRIMARY_MESSAGE_LIMIT);
112922
+ }
112923
+ return [];
112924
+ }
112925
+ const isPrimary = (msg) => {
112926
+ const t = msg.message_type;
112927
+ return t === "user_message" || t === "assistant_message" || t === "reasoning_message" || t === "event_message" || t === "summary_message";
112928
+ };
112929
+ let primaryCount = 0;
112930
+ let startIndex = Math.max(0, renderable.length - 1);
112931
+ for (let i = renderable.length - 1;i >= 0; i -= 1) {
112932
+ const msg = renderable[i];
112933
+ if (!msg)
112934
+ continue;
112935
+ if (isPrimary(msg)) {
112936
+ primaryCount += 1;
112937
+ if (primaryCount >= BACKFILL_PRIMARY_MESSAGE_LIMIT) {
112938
+ startIndex = i;
112939
+ break;
112940
+ }
112941
+ }
112942
+ startIndex = i;
112943
+ }
112944
+ let messageHistory = renderable.slice(startIndex);
112945
+ if (messageHistory.length > BACKFILL_MAX_RENDERABLE_MESSAGES) {
112946
+ messageHistory = messageHistory.slice(-BACKFILL_MAX_RENDERABLE_MESSAGES);
112947
+ }
112049
112948
  if (messageHistory[0]?.message_type === "tool_return_message") {
112050
112949
  messageHistory = messageHistory.slice(1);
112051
112950
  }
@@ -112053,11 +112952,57 @@ function prepareMessageHistory(messages) {
112053
112952
  }
112054
112953
  function sortChronological(messages) {
112055
112954
  return [...messages].sort((a, b) => {
112056
- const dateA = a.date ?? "";
112057
- const dateB = b.date ?? "";
112058
- return new Date(dateA).getTime() - new Date(dateB).getTime();
112955
+ const ta = a.date ? new Date(a.date).getTime() : 0;
112956
+ const tb = b.date ? new Date(b.date).getTime() : 0;
112957
+ if (!Number.isFinite(ta) && !Number.isFinite(tb))
112958
+ return 0;
112959
+ if (!Number.isFinite(ta))
112960
+ return -1;
112961
+ if (!Number.isFinite(tb))
112962
+ return 1;
112963
+ return ta - tb;
112059
112964
  });
112060
112965
  }
112966
+ async function fetchConversationBackfillMessages(client, conversationId) {
112967
+ const collected = [];
112968
+ const seen = new Set;
112969
+ let cursorBefore = null;
112970
+ let assistantCount = 0;
112971
+ let anchorCount = 0;
112972
+ for (let pageIndex = 0;pageIndex < BACKFILL_MAX_PAGES; pageIndex += 1) {
112973
+ const page = await client.conversations.messages.list(conversationId, {
112974
+ limit: BACKFILL_PAGE_LIMIT,
112975
+ order: "desc",
112976
+ ...cursorBefore ? { before: cursorBefore } : {}
112977
+ });
112978
+ const items = page.getPaginatedItems();
112979
+ if (items.length === 0)
112980
+ break;
112981
+ cursorBefore = items[items.length - 1]?.id ?? null;
112982
+ for (const m of items) {
112983
+ if (!m?.id)
112984
+ continue;
112985
+ const key = "otid" in m && m.otid ? `otid:${String(m.otid)}` : `id:${m.id}:${m.message_type ?? ""}`;
112986
+ if (seen.has(key))
112987
+ continue;
112988
+ seen.add(key);
112989
+ collected.push(m);
112990
+ if (m.message_type === "assistant_message")
112991
+ assistantCount += 1;
112992
+ if (isAnchorMessageType(m.message_type))
112993
+ anchorCount += 1;
112994
+ }
112995
+ if (assistantCount >= BACKFILL_MIN_ASSISTANT && anchorCount >= BACKFILL_ANCHOR_MESSAGE_LIMIT) {
112996
+ break;
112997
+ }
112998
+ if (items.length < BACKFILL_PAGE_LIMIT)
112999
+ break;
113000
+ }
113001
+ if (assistantCount < BACKFILL_MIN_ASSISTANT) {
113002
+ debugWarn("check-approval", `Backfill scan found 0 assistant messages in last ${collected.length} messages (tool-heavy conversation?)`);
113003
+ }
113004
+ return sortChronological(collected);
113005
+ }
112061
113006
  async function getResumeData(client, agent, conversationId) {
112062
113007
  try {
112063
113008
  let inContextMessageIds;
@@ -112073,14 +113018,13 @@ async function getResumeData(client, agent, conversationId) {
112073
113018
  debugWarn("check-approval", "No in-context messages - no pending approvals");
112074
113019
  if (isBackfillEnabled()) {
112075
113020
  try {
112076
- const backfill = await client.conversations.messages.list(conversationId, {
112077
- limit: MESSAGE_HISTORY_LIMIT,
112078
- order: "desc"
112079
- });
113021
+ const backfill = await fetchConversationBackfillMessages(client, conversationId);
112080
113022
  return {
112081
113023
  pendingApproval: null,
112082
113024
  pendingApprovals: [],
112083
- messageHistory: sortChronological(backfill.getPaginatedItems())
113025
+ messageHistory: prepareMessageHistory(backfill, {
113026
+ primaryOnly: true
113027
+ })
112084
113028
  };
112085
113029
  } catch (backfillError) {
112086
113030
  debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
@@ -112099,11 +113043,7 @@ async function getResumeData(client, agent, conversationId) {
112099
113043
  const retrievedMessages = await client.messages.retrieve(lastInContextId);
112100
113044
  if (isBackfillEnabled()) {
112101
113045
  try {
112102
- const backfillPage = await client.conversations.messages.list(conversationId, {
112103
- limit: MESSAGE_HISTORY_LIMIT,
112104
- order: "desc"
112105
- });
112106
- messages = sortChronological(backfillPage.getPaginatedItems());
113046
+ messages = await fetchConversationBackfillMessages(client, conversationId);
112107
113047
  } catch (backfillError) {
112108
113048
  debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
112109
113049
  }
@@ -112116,7 +113056,9 @@ async function getResumeData(client, agent, conversationId) {
112116
113056
  return {
112117
113057
  pendingApproval,
112118
113058
  pendingApprovals,
112119
- messageHistory: prepareMessageHistory(messages)
113059
+ messageHistory: prepareMessageHistory(messages, {
113060
+ primaryOnly: true
113061
+ })
112120
113062
  };
112121
113063
  }
112122
113064
  } else {
@@ -112125,7 +113067,7 @@ async function getResumeData(client, agent, conversationId) {
112125
113067
  return {
112126
113068
  pendingApproval: null,
112127
113069
  pendingApprovals: [],
112128
- messageHistory: prepareMessageHistory(messages)
113070
+ messageHistory: prepareMessageHistory(messages, { primaryOnly: true })
112129
113071
  };
112130
113072
  } else {
112131
113073
  inContextMessageIds = agent.message_ids;
@@ -112145,13 +113087,13 @@ async function getResumeData(client, agent, conversationId) {
112145
113087
  if (isBackfillEnabled()) {
112146
113088
  try {
112147
113089
  const messagesPage = await client.agents.messages.list(agent.id, {
112148
- limit: MESSAGE_HISTORY_LIMIT,
113090
+ limit: BACKFILL_PAGE_LIMIT,
112149
113091
  order: "desc",
112150
113092
  conversation_id: "default"
112151
113093
  });
112152
113094
  messages = sortChronological(messagesPage.items);
112153
113095
  if (process.env.DEBUG) {
112154
- console.log(`[DEBUG] agents.messages.list(conversation_id=default) returned ${messagesPage.items.length} messages`);
113096
+ console.log(`[DEBUG] agents.messages.list(conversation_id=default) returned ${messages.length} messages`);
112155
113097
  }
112156
113098
  } catch (backfillError) {
112157
113099
  debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
@@ -112165,7 +113107,9 @@ async function getResumeData(client, agent, conversationId) {
112165
113107
  return {
112166
113108
  pendingApproval,
112167
113109
  pendingApprovals,
112168
- messageHistory: prepareMessageHistory(messages)
113110
+ messageHistory: prepareMessageHistory(messages, {
113111
+ primaryOnly: true
113112
+ })
112169
113113
  };
112170
113114
  }
112171
113115
  } else {
@@ -112174,7 +113118,7 @@ async function getResumeData(client, agent, conversationId) {
112174
113118
  return {
112175
113119
  pendingApproval: null,
112176
113120
  pendingApprovals: [],
112177
- messageHistory: prepareMessageHistory(messages)
113121
+ messageHistory: prepareMessageHistory(messages, { primaryOnly: true })
112178
113122
  };
112179
113123
  }
112180
113124
  } catch (error) {
@@ -114198,8 +115142,8 @@ async function listBackups(agentId) {
114198
115142
  const path19 = join16(agentRoot, entry.name);
114199
115143
  let createdAt = null;
114200
115144
  try {
114201
- const stat2 = statSync2(path19);
114202
- createdAt = stat2.mtime.toISOString();
115145
+ const stat3 = statSync2(path19);
115146
+ createdAt = stat3.mtime.toISOString();
114203
115147
  } catch {
114204
115148
  createdAt = null;
114205
115149
  }
@@ -114319,8 +115263,8 @@ async function runMemfsSubcommand(argv) {
114319
115263
  console.error(`Backup not found: ${backupPath}`);
114320
115264
  return 1;
114321
115265
  }
114322
- const stat2 = statSync2(backupPath);
114323
- if (!stat2.isDirectory()) {
115266
+ const stat3 = statSync2(backupPath);
115267
+ if (!stat3.isDirectory()) {
114324
115268
  console.error(`Backup path is not a directory: ${backupPath}`);
114325
115269
  return 1;
114326
115270
  }
@@ -114342,8 +115286,8 @@ async function runMemfsSubcommand(argv) {
114342
115286
  return 1;
114343
115287
  }
114344
115288
  if (existsSync9(out)) {
114345
- const stat2 = statSync2(out);
114346
- if (stat2.isDirectory()) {
115289
+ const stat3 = statSync2(out);
115290
+ if (stat3.isDirectory()) {
114347
115291
  const contents = await readdir5(out);
114348
115292
  if (contents.length > 0) {
114349
115293
  console.error(`Export directory not empty: ${out}`);
@@ -114779,6 +115723,7 @@ var permissionMode2 = new PermissionModeManager2;
114779
115723
  init_debug();
114780
115724
  init_fs();
114781
115725
  await init_secrets();
115726
+ import { randomUUID as randomUUID3 } from "node:crypto";
114782
115727
  import { homedir as homedir14 } from "node:os";
114783
115728
  import { join as join18 } from "node:path";
114784
115729
  var DEFAULT_SETTINGS2 = {
@@ -114984,7 +115929,7 @@ class SettingsManager2 {
114984
115929
  const settings = this.getSettings();
114985
115930
  let deviceId = settings.deviceId;
114986
115931
  if (!deviceId) {
114987
- deviceId = crypto.randomUUID();
115932
+ deviceId = randomUUID3();
114988
115933
  this.updateSettings({ deviceId });
114989
115934
  }
114990
115935
  return deviceId;
@@ -115874,12 +116819,12 @@ class TelemetryManager2 {
115874
116819
  var telemetry2 = new TelemetryManager2;
115875
116820
 
115876
116821
  // src/tools/manager.ts
115877
- init_model();
115878
116822
  init_subagents();
115879
116823
  init_constants();
115880
116824
  init_debug();
115881
116825
  await __promiseAll([
115882
116826
  init_approval_execution(),
116827
+ init_model(),
115883
116828
  init_hooks(),
115884
116829
  init_openai_codex_provider(),
115885
116830
  init_telemetry(),
@@ -116242,12 +117187,12 @@ EXAMPLES
116242
117187
  console.log(usage);
116243
117188
  }
116244
117189
  async function printInfo() {
116245
- const { join: join37 } = await import("path");
117190
+ const { join: join38 } = await import("path");
116246
117191
  const { getVersion: getVersion3 } = await Promise.resolve().then(() => (init_version2(), exports_version));
116247
117192
  const { SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills2(), exports_skills2));
116248
117193
  const { exists: exists3 } = await Promise.resolve().then(() => (init_fs2(), exports_fs));
116249
117194
  const cwd2 = process.cwd();
116250
- const skillsDir = join37(cwd2, SKILLS_DIR3);
117195
+ const skillsDir = join38(cwd2, SKILLS_DIR3);
116251
117196
  const skillsExist = exists3(skillsDir);
116252
117197
  await settingsManager2.loadLocalProjectSettings(cwd2);
116253
117198
  const localPinned = settingsManager2.getLocalPinnedAgents(cwd2);
@@ -116691,9 +117636,9 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
116691
117636
  }
116692
117637
  } else {
116693
117638
  const { resolve: resolve26 } = await import("path");
116694
- const { existsSync: existsSync23 } = await import("fs");
117639
+ const { existsSync: existsSync24 } = await import("fs");
116695
117640
  const resolvedPath = resolve26(fromAfFile);
116696
- if (!existsSync23(resolvedPath)) {
117641
+ if (!existsSync24(resolvedPath)) {
116697
117642
  console.error(`Error: AgentFile not found: ${resolvedPath}`);
116698
117643
  process.exit(1);
116699
117644
  }
@@ -116940,7 +117885,7 @@ Error: ${message}`);
116940
117885
  if (isSelfHosted) {
116941
117886
  setSelfHostedBaseUrl(baseURL2);
116942
117887
  try {
116943
- const { getDefaultModel: getDefaultModel3 } = await Promise.resolve().then(() => (init_model2(), exports_model2));
117888
+ const { getDefaultModel: getDefaultModel3 } = await init_model2().then(() => exports_model2);
116944
117889
  const defaultModel = getDefaultModel3();
116945
117890
  setSelfHostedDefaultModel(defaultModel);
116946
117891
  const modelsList = await client.models.list();
@@ -117165,7 +118110,7 @@ Error: ${message}`);
117165
118110
  await loadTools2(modelForTools);
117166
118111
  setLoadingState("initializing");
117167
118112
  const { createAgent: createAgent3 } = await init_create3().then(() => exports_create);
117168
- const { getModelUpdateArgs: getModelUpdateArgs3 } = await Promise.resolve().then(() => (init_model2(), exports_model2));
118113
+ const { getModelUpdateArgs: getModelUpdateArgs3 } = await init_model2().then(() => exports_model2);
117169
118114
  let agent = null;
117170
118115
  if (fromAfFile2) {
117171
118116
  setLoadingState("importing");
@@ -117226,7 +118171,7 @@ Error: ${message}`);
117226
118171
  }
117227
118172
  let effectiveModel = selectedServerModel || model;
117228
118173
  if (!effectiveModel && !selfHostedBaseUrl) {
117229
- const { getDefaultModelForTier: getDefaultModelForTier3 } = await Promise.resolve().then(() => (init_model2(), exports_model2));
118174
+ const { getDefaultModelForTier: getDefaultModelForTier3 } = await init_model2().then(() => exports_model2);
117230
118175
  let billingTier = null;
117231
118176
  try {
117232
118177
  const baseURL2 = process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL2;
@@ -117299,18 +118244,34 @@ Error: ${message}`);
117299
118244
  const isReusingExistingAgent = !shouldCreateNew && !fromAfFile2 && agent && agent.id;
117300
118245
  const resuming = !!(continueSession || agentIdArg || isResumingProject || isReusingExistingAgent);
117301
118246
  setIsResumingSession(resuming);
117302
- if (resuming && (model || systemPromptPreset2)) {
118247
+ if (resuming) {
118248
+ const { updateAgentLLMConfig: updateAgentLLMConfig3 } = await init_modify2().then(() => exports_modify2);
117303
118249
  if (model) {
117304
- const { resolveModel: resolveModel3, getModelUpdateArgs: getModelUpdateArgs4 } = await Promise.resolve().then(() => (init_model2(), exports_model2));
118250
+ const { resolveModel: resolveModel3, getModelUpdateArgs: getModelUpdateArgs4 } = await init_model2().then(() => exports_model2);
117305
118251
  const modelHandle = resolveModel3(model);
117306
118252
  if (!modelHandle) {
117307
118253
  console.error(`Error: Invalid model "${model}"`);
117308
118254
  process.exit(1);
117309
118255
  }
117310
- const { updateAgentLLMConfig: updateAgentLLMConfig3 } = await init_modify2().then(() => exports_modify2);
117311
118256
  const updateArgs = getModelUpdateArgs4(model);
117312
118257
  await updateAgentLLMConfig3(agent.id, modelHandle, updateArgs);
117313
118258
  agent = await client.agents.retrieve(agent.id);
118259
+ } else {
118260
+ const { getModelPresetUpdateForAgent: getModelPresetUpdateForAgent3 } = await init_model2().then(() => exports_model2);
118261
+ const presetRefresh = getModelPresetUpdateForAgent3(agent);
118262
+ if (presetRefresh) {
118263
+ const resumeRefreshUpdateArgs = {};
118264
+ if (typeof presetRefresh.updateArgs.max_output_tokens === "number") {
118265
+ resumeRefreshUpdateArgs.max_output_tokens = presetRefresh.updateArgs.max_output_tokens;
118266
+ }
118267
+ if (typeof presetRefresh.updateArgs.parallel_tool_calls === "boolean") {
118268
+ resumeRefreshUpdateArgs.parallel_tool_calls = presetRefresh.updateArgs.parallel_tool_calls;
118269
+ }
118270
+ if (Object.keys(resumeRefreshUpdateArgs).length > 0) {
118271
+ await updateAgentLLMConfig3(agent.id, presetRefresh.modelHandle, resumeRefreshUpdateArgs);
118272
+ agent = await client.agents.retrieve(agent.id);
118273
+ }
118274
+ }
117314
118275
  }
117315
118276
  if (systemPromptPreset2) {
117316
118277
  const { updateAgentSystemPrompt: updateAgentSystemPrompt3 } = await init_modify2().then(() => exports_modify2);
@@ -117557,4 +118518,4 @@ Error during initialization: ${message}`);
117557
118518
  }
117558
118519
  main();
117559
118520
 
117560
- //# debugId=B0F648D57141B93564756E2164756E21
118521
+ //# debugId=3C631D4165C9D76264756E2164756E21