@letta-ai/letta-code 0.16.2 → 0.16.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/letta.js 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.4",
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,20 +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
33088
- }
33089
- },
33090
- {
33091
- id: "sonnet-4.6-xhigh",
33092
- handle: "anthropic/claude-sonnet-4-6",
33093
- label: "Sonnet 4.6",
33094
- description: "Sonnet 4.6 (max reasoning)",
33095
- updateArgs: {
33096
- context_window: 200000,
33097
- max_output_tokens: 128000,
33098
- reasoning_effort: "xhigh",
33099
- enable_reasoner: true,
33100
- max_reasoning_tokens: 31999
33095
+ max_reasoning_tokens: 12000,
33096
+ parallel_tool_calls: true
33101
33097
  }
33102
33098
  },
33103
33099
  {
@@ -33108,7 +33104,8 @@ var init_models2 = __esm(() => {
33108
33104
  updateArgs: {
33109
33105
  context_window: 180000,
33110
33106
  max_output_tokens: 64000,
33111
- max_reasoning_tokens: 31999
33107
+ max_reasoning_tokens: 31999,
33108
+ parallel_tool_calls: true
33112
33109
  }
33113
33110
  },
33114
33111
  {
@@ -33119,7 +33116,8 @@ var init_models2 = __esm(() => {
33119
33116
  updateArgs: {
33120
33117
  enable_reasoner: false,
33121
33118
  context_window: 180000,
33122
- max_output_tokens: 64000
33119
+ max_output_tokens: 64000,
33120
+ parallel_tool_calls: true
33123
33121
  }
33124
33122
  },
33125
33123
  {
@@ -33132,7 +33130,8 @@ var init_models2 = __esm(() => {
33132
33130
  context_window: 200000,
33133
33131
  max_output_tokens: 128000,
33134
33132
  reasoning_effort: "high",
33135
- enable_reasoner: true
33133
+ enable_reasoner: true,
33134
+ parallel_tool_calls: true
33136
33135
  }
33137
33136
  },
33138
33137
  {
@@ -33144,7 +33143,8 @@ var init_models2 = __esm(() => {
33144
33143
  context_window: 200000,
33145
33144
  max_output_tokens: 128000,
33146
33145
  reasoning_effort: "none",
33147
- enable_reasoner: false
33146
+ enable_reasoner: false,
33147
+ parallel_tool_calls: true
33148
33148
  }
33149
33149
  },
33150
33150
  {
@@ -33157,7 +33157,8 @@ var init_models2 = __esm(() => {
33157
33157
  max_output_tokens: 128000,
33158
33158
  reasoning_effort: "low",
33159
33159
  enable_reasoner: true,
33160
- max_reasoning_tokens: 4000
33160
+ max_reasoning_tokens: 4000,
33161
+ parallel_tool_calls: true
33161
33162
  }
33162
33163
  },
33163
33164
  {
@@ -33170,20 +33171,8 @@ var init_models2 = __esm(() => {
33170
33171
  max_output_tokens: 128000,
33171
33172
  reasoning_effort: "medium",
33172
33173
  enable_reasoner: true,
33173
- max_reasoning_tokens: 12000
33174
- }
33175
- },
33176
- {
33177
- id: "opus-4.6-xhigh",
33178
- handle: "anthropic/claude-opus-4-6",
33179
- label: "Opus 4.6",
33180
- description: "Opus 4.6 (max reasoning)",
33181
- updateArgs: {
33182
- context_window: 200000,
33183
- max_output_tokens: 128000,
33184
- reasoning_effort: "xhigh",
33185
- enable_reasoner: true,
33186
- max_reasoning_tokens: 31999
33174
+ max_reasoning_tokens: 12000,
33175
+ parallel_tool_calls: true
33187
33176
  }
33188
33177
  },
33189
33178
  {
@@ -33194,7 +33183,8 @@ var init_models2 = __esm(() => {
33194
33183
  updateArgs: {
33195
33184
  context_window: 180000,
33196
33185
  max_output_tokens: 64000,
33197
- max_reasoning_tokens: 31999
33186
+ max_reasoning_tokens: 31999,
33187
+ parallel_tool_calls: true
33198
33188
  }
33199
33189
  },
33200
33190
  {
@@ -33207,7 +33197,8 @@ var init_models2 = __esm(() => {
33207
33197
  updateArgs: {
33208
33198
  context_window: 180000,
33209
33199
  max_output_tokens: 64000,
33210
- max_reasoning_tokens: 31999
33200
+ max_reasoning_tokens: 31999,
33201
+ parallel_tool_calls: true
33211
33202
  }
33212
33203
  },
33213
33204
  {
@@ -33218,7 +33209,8 @@ var init_models2 = __esm(() => {
33218
33209
  isFeatured: true,
33219
33210
  updateArgs: {
33220
33211
  context_window: 180000,
33221
- max_output_tokens: 64000
33212
+ max_output_tokens: 64000,
33213
+ parallel_tool_calls: true
33222
33214
  }
33223
33215
  },
33224
33216
  {
@@ -33230,7 +33222,8 @@ var init_models2 = __esm(() => {
33230
33222
  reasoning_effort: "none",
33231
33223
  verbosity: "low",
33232
33224
  context_window: 272000,
33233
- max_output_tokens: 128000
33225
+ max_output_tokens: 128000,
33226
+ parallel_tool_calls: true
33234
33227
  }
33235
33228
  },
33236
33229
  {
@@ -33242,7 +33235,8 @@ var init_models2 = __esm(() => {
33242
33235
  reasoning_effort: "low",
33243
33236
  verbosity: "low",
33244
33237
  context_window: 272000,
33245
- max_output_tokens: 128000
33238
+ max_output_tokens: 128000,
33239
+ parallel_tool_calls: true
33246
33240
  }
33247
33241
  },
33248
33242
  {
@@ -33254,7 +33248,8 @@ var init_models2 = __esm(() => {
33254
33248
  reasoning_effort: "medium",
33255
33249
  verbosity: "low",
33256
33250
  context_window: 272000,
33257
- max_output_tokens: 128000
33251
+ max_output_tokens: 128000,
33252
+ parallel_tool_calls: true
33258
33253
  }
33259
33254
  },
33260
33255
  {
@@ -33267,7 +33262,8 @@ var init_models2 = __esm(() => {
33267
33262
  reasoning_effort: "high",
33268
33263
  verbosity: "low",
33269
33264
  context_window: 272000,
33270
- max_output_tokens: 128000
33265
+ max_output_tokens: 128000,
33266
+ parallel_tool_calls: true
33271
33267
  }
33272
33268
  },
33273
33269
  {
@@ -33279,7 +33275,8 @@ var init_models2 = __esm(() => {
33279
33275
  reasoning_effort: "xhigh",
33280
33276
  verbosity: "low",
33281
33277
  context_window: 272000,
33282
- max_output_tokens: 128000
33278
+ max_output_tokens: 128000,
33279
+ parallel_tool_calls: true
33283
33280
  }
33284
33281
  },
33285
33282
  {
@@ -33291,7 +33288,8 @@ var init_models2 = __esm(() => {
33291
33288
  reasoning_effort: "medium",
33292
33289
  verbosity: "medium",
33293
33290
  context_window: 272000,
33294
- max_output_tokens: 128000
33291
+ max_output_tokens: 128000,
33292
+ parallel_tool_calls: true
33295
33293
  }
33296
33294
  },
33297
33295
  {
@@ -33303,7 +33301,8 @@ var init_models2 = __esm(() => {
33303
33301
  reasoning_effort: "high",
33304
33302
  verbosity: "medium",
33305
33303
  context_window: 272000,
33306
- max_output_tokens: 128000
33304
+ max_output_tokens: 128000,
33305
+ parallel_tool_calls: true
33307
33306
  }
33308
33307
  },
33309
33308
  {
@@ -33315,7 +33314,8 @@ var init_models2 = __esm(() => {
33315
33314
  reasoning_effort: "medium",
33316
33315
  verbosity: "medium",
33317
33316
  context_window: 272000,
33318
- max_output_tokens: 128000
33317
+ max_output_tokens: 128000,
33318
+ parallel_tool_calls: true
33319
33319
  }
33320
33320
  },
33321
33321
  {
@@ -33327,7 +33327,8 @@ var init_models2 = __esm(() => {
33327
33327
  reasoning_effort: "high",
33328
33328
  verbosity: "medium",
33329
33329
  context_window: 272000,
33330
- max_output_tokens: 128000
33330
+ max_output_tokens: 128000,
33331
+ parallel_tool_calls: true
33331
33332
  }
33332
33333
  },
33333
33334
  {
@@ -33339,7 +33340,8 @@ var init_models2 = __esm(() => {
33339
33340
  reasoning_effort: "medium",
33340
33341
  verbosity: "medium",
33341
33342
  context_window: 272000,
33342
- max_output_tokens: 128000
33343
+ max_output_tokens: 128000,
33344
+ parallel_tool_calls: true
33343
33345
  }
33344
33346
  },
33345
33347
  {
@@ -33351,7 +33353,8 @@ var init_models2 = __esm(() => {
33351
33353
  reasoning_effort: "high",
33352
33354
  verbosity: "medium",
33353
33355
  context_window: 272000,
33354
- max_output_tokens: 128000
33356
+ max_output_tokens: 128000,
33357
+ parallel_tool_calls: true
33355
33358
  }
33356
33359
  },
33357
33360
  {
@@ -33363,7 +33366,8 @@ var init_models2 = __esm(() => {
33363
33366
  reasoning_effort: "medium",
33364
33367
  verbosity: "medium",
33365
33368
  context_window: 272000,
33366
- max_output_tokens: 128000
33369
+ max_output_tokens: 128000,
33370
+ parallel_tool_calls: true
33367
33371
  }
33368
33372
  },
33369
33373
  {
@@ -33375,7 +33379,8 @@ var init_models2 = __esm(() => {
33375
33379
  reasoning_effort: "high",
33376
33380
  verbosity: "medium",
33377
33381
  context_window: 272000,
33378
- max_output_tokens: 128000
33382
+ max_output_tokens: 128000,
33383
+ parallel_tool_calls: true
33379
33384
  }
33380
33385
  },
33381
33386
  {
@@ -33387,7 +33392,8 @@ var init_models2 = __esm(() => {
33387
33392
  reasoning_effort: "xhigh",
33388
33393
  verbosity: "medium",
33389
33394
  context_window: 272000,
33390
- max_output_tokens: 128000
33395
+ max_output_tokens: 128000,
33396
+ parallel_tool_calls: true
33391
33397
  }
33392
33398
  },
33393
33399
  {
@@ -33399,7 +33405,8 @@ var init_models2 = __esm(() => {
33399
33405
  reasoning_effort: "medium",
33400
33406
  verbosity: "medium",
33401
33407
  context_window: 272000,
33402
- max_output_tokens: 128000
33408
+ max_output_tokens: 128000,
33409
+ parallel_tool_calls: true
33403
33410
  }
33404
33411
  },
33405
33412
  {
@@ -33411,7 +33418,8 @@ var init_models2 = __esm(() => {
33411
33418
  reasoning_effort: "none",
33412
33419
  verbosity: "medium",
33413
33420
  context_window: 272000,
33414
- max_output_tokens: 128000
33421
+ max_output_tokens: 128000,
33422
+ parallel_tool_calls: true
33415
33423
  }
33416
33424
  },
33417
33425
  {
@@ -33423,7 +33431,8 @@ var init_models2 = __esm(() => {
33423
33431
  reasoning_effort: "low",
33424
33432
  verbosity: "medium",
33425
33433
  context_window: 272000,
33426
- max_output_tokens: 128000
33434
+ max_output_tokens: 128000,
33435
+ parallel_tool_calls: true
33427
33436
  }
33428
33437
  },
33429
33438
  {
@@ -33436,7 +33445,8 @@ var init_models2 = __esm(() => {
33436
33445
  reasoning_effort: "medium",
33437
33446
  verbosity: "medium",
33438
33447
  context_window: 272000,
33439
- max_output_tokens: 128000
33448
+ max_output_tokens: 128000,
33449
+ parallel_tool_calls: true
33440
33450
  }
33441
33451
  },
33442
33452
  {
@@ -33448,7 +33458,8 @@ var init_models2 = __esm(() => {
33448
33458
  reasoning_effort: "high",
33449
33459
  verbosity: "medium",
33450
33460
  context_window: 272000,
33451
- max_output_tokens: 128000
33461
+ max_output_tokens: 128000,
33462
+ parallel_tool_calls: true
33452
33463
  }
33453
33464
  },
33454
33465
  {
@@ -33460,7 +33471,8 @@ var init_models2 = __esm(() => {
33460
33471
  reasoning_effort: "xhigh",
33461
33472
  verbosity: "medium",
33462
33473
  context_window: 272000,
33463
- max_output_tokens: 128000
33474
+ max_output_tokens: 128000,
33475
+ parallel_tool_calls: true
33464
33476
  }
33465
33477
  },
33466
33478
  {
@@ -33472,7 +33484,8 @@ var init_models2 = __esm(() => {
33472
33484
  reasoning_effort: "none",
33473
33485
  verbosity: "medium",
33474
33486
  context_window: 272000,
33475
- max_output_tokens: 128000
33487
+ max_output_tokens: 128000,
33488
+ parallel_tool_calls: true
33476
33489
  }
33477
33490
  },
33478
33491
  {
@@ -33484,7 +33497,8 @@ var init_models2 = __esm(() => {
33484
33497
  reasoning_effort: "low",
33485
33498
  verbosity: "medium",
33486
33499
  context_window: 272000,
33487
- max_output_tokens: 128000
33500
+ max_output_tokens: 128000,
33501
+ parallel_tool_calls: true
33488
33502
  }
33489
33503
  },
33490
33504
  {
@@ -33497,7 +33511,8 @@ var init_models2 = __esm(() => {
33497
33511
  reasoning_effort: "medium",
33498
33512
  verbosity: "medium",
33499
33513
  context_window: 272000,
33500
- max_output_tokens: 128000
33514
+ max_output_tokens: 128000,
33515
+ parallel_tool_calls: true
33501
33516
  }
33502
33517
  },
33503
33518
  {
@@ -33509,7 +33524,8 @@ var init_models2 = __esm(() => {
33509
33524
  reasoning_effort: "high",
33510
33525
  verbosity: "medium",
33511
33526
  context_window: 272000,
33512
- max_output_tokens: 128000
33527
+ max_output_tokens: 128000,
33528
+ parallel_tool_calls: true
33513
33529
  }
33514
33530
  },
33515
33531
  {
@@ -33521,7 +33537,8 @@ var init_models2 = __esm(() => {
33521
33537
  reasoning_effort: "xhigh",
33522
33538
  verbosity: "medium",
33523
33539
  context_window: 272000,
33524
- max_output_tokens: 128000
33540
+ max_output_tokens: 128000,
33541
+ parallel_tool_calls: true
33525
33542
  }
33526
33543
  },
33527
33544
  {
@@ -33533,7 +33550,8 @@ var init_models2 = __esm(() => {
33533
33550
  reasoning_effort: "none",
33534
33551
  verbosity: "medium",
33535
33552
  context_window: 272000,
33536
- max_output_tokens: 128000
33553
+ max_output_tokens: 128000,
33554
+ parallel_tool_calls: true
33537
33555
  }
33538
33556
  },
33539
33557
  {
@@ -33545,7 +33563,8 @@ var init_models2 = __esm(() => {
33545
33563
  reasoning_effort: "low",
33546
33564
  verbosity: "medium",
33547
33565
  context_window: 272000,
33548
- max_output_tokens: 128000
33566
+ max_output_tokens: 128000,
33567
+ parallel_tool_calls: true
33549
33568
  }
33550
33569
  },
33551
33570
  {
@@ -33557,7 +33576,8 @@ var init_models2 = __esm(() => {
33557
33576
  reasoning_effort: "medium",
33558
33577
  verbosity: "medium",
33559
33578
  context_window: 272000,
33560
- max_output_tokens: 128000
33579
+ max_output_tokens: 128000,
33580
+ parallel_tool_calls: true
33561
33581
  }
33562
33582
  },
33563
33583
  {
@@ -33569,7 +33589,8 @@ var init_models2 = __esm(() => {
33569
33589
  reasoning_effort: "high",
33570
33590
  verbosity: "medium",
33571
33591
  context_window: 272000,
33572
- max_output_tokens: 128000
33592
+ max_output_tokens: 128000,
33593
+ parallel_tool_calls: true
33573
33594
  }
33574
33595
  },
33575
33596
  {
@@ -33581,7 +33602,8 @@ var init_models2 = __esm(() => {
33581
33602
  reasoning_effort: "none",
33582
33603
  verbosity: "medium",
33583
33604
  context_window: 272000,
33584
- max_output_tokens: 128000
33605
+ max_output_tokens: 128000,
33606
+ parallel_tool_calls: true
33585
33607
  }
33586
33608
  },
33587
33609
  {
@@ -33594,7 +33616,8 @@ var init_models2 = __esm(() => {
33594
33616
  reasoning_effort: "medium",
33595
33617
  verbosity: "medium",
33596
33618
  context_window: 272000,
33597
- max_output_tokens: 128000
33619
+ max_output_tokens: 128000,
33620
+ parallel_tool_calls: true
33598
33621
  }
33599
33622
  },
33600
33623
  {
@@ -33606,7 +33629,8 @@ var init_models2 = __esm(() => {
33606
33629
  reasoning_effort: "high",
33607
33630
  verbosity: "medium",
33608
33631
  context_window: 272000,
33609
- max_output_tokens: 128000
33632
+ max_output_tokens: 128000,
33633
+ parallel_tool_calls: true
33610
33634
  }
33611
33635
  },
33612
33636
  {
@@ -33618,7 +33642,8 @@ var init_models2 = __esm(() => {
33618
33642
  reasoning_effort: "medium",
33619
33643
  verbosity: "medium",
33620
33644
  context_window: 272000,
33621
- max_output_tokens: 128000
33645
+ max_output_tokens: 128000,
33646
+ parallel_tool_calls: true
33622
33647
  }
33623
33648
  },
33624
33649
  {
@@ -33630,7 +33655,8 @@ var init_models2 = __esm(() => {
33630
33655
  reasoning_effort: "high",
33631
33656
  verbosity: "medium",
33632
33657
  context_window: 272000,
33633
- max_output_tokens: 128000
33658
+ max_output_tokens: 128000,
33659
+ parallel_tool_calls: true
33634
33660
  }
33635
33661
  },
33636
33662
  {
@@ -33642,7 +33668,8 @@ var init_models2 = __esm(() => {
33642
33668
  reasoning_effort: "xhigh",
33643
33669
  verbosity: "medium",
33644
33670
  context_window: 272000,
33645
- max_output_tokens: 128000
33671
+ max_output_tokens: 128000,
33672
+ parallel_tool_calls: true
33646
33673
  }
33647
33674
  },
33648
33675
  {
@@ -33654,7 +33681,8 @@ var init_models2 = __esm(() => {
33654
33681
  reasoning_effort: "minimal",
33655
33682
  verbosity: "medium",
33656
33683
  context_window: 272000,
33657
- max_output_tokens: 128000
33684
+ max_output_tokens: 128000,
33685
+ parallel_tool_calls: true
33658
33686
  }
33659
33687
  },
33660
33688
  {
@@ -33666,7 +33694,8 @@ var init_models2 = __esm(() => {
33666
33694
  reasoning_effort: "low",
33667
33695
  verbosity: "medium",
33668
33696
  context_window: 272000,
33669
- max_output_tokens: 128000
33697
+ max_output_tokens: 128000,
33698
+ parallel_tool_calls: true
33670
33699
  }
33671
33700
  },
33672
33701
  {
@@ -33678,7 +33707,8 @@ var init_models2 = __esm(() => {
33678
33707
  reasoning_effort: "medium",
33679
33708
  verbosity: "medium",
33680
33709
  context_window: 272000,
33681
- max_output_tokens: 128000
33710
+ max_output_tokens: 128000,
33711
+ parallel_tool_calls: true
33682
33712
  }
33683
33713
  },
33684
33714
  {
@@ -33690,7 +33720,8 @@ var init_models2 = __esm(() => {
33690
33720
  reasoning_effort: "high",
33691
33721
  verbosity: "medium",
33692
33722
  context_window: 272000,
33693
- max_output_tokens: 128000
33723
+ max_output_tokens: 128000,
33724
+ parallel_tool_calls: true
33694
33725
  }
33695
33726
  },
33696
33727
  {
@@ -33702,7 +33733,8 @@ var init_models2 = __esm(() => {
33702
33733
  reasoning_effort: "medium",
33703
33734
  verbosity: "medium",
33704
33735
  context_window: 272000,
33705
- max_output_tokens: 128000
33736
+ max_output_tokens: 128000,
33737
+ parallel_tool_calls: true
33706
33738
  }
33707
33739
  },
33708
33740
  {
@@ -33714,7 +33746,8 @@ var init_models2 = __esm(() => {
33714
33746
  reasoning_effort: "medium",
33715
33747
  verbosity: "medium",
33716
33748
  context_window: 272000,
33717
- max_output_tokens: 128000
33749
+ max_output_tokens: 128000,
33750
+ parallel_tool_calls: true
33718
33751
  }
33719
33752
  },
33720
33753
  {
@@ -33725,7 +33758,8 @@ var init_models2 = __esm(() => {
33725
33758
  isFeatured: true,
33726
33759
  free: true,
33727
33760
  updateArgs: {
33728
- context_window: 200000
33761
+ context_window: 200000,
33762
+ parallel_tool_calls: true
33729
33763
  }
33730
33764
  },
33731
33765
  {
@@ -33736,7 +33770,8 @@ var init_models2 = __esm(() => {
33736
33770
  isFeatured: true,
33737
33771
  free: true,
33738
33772
  updateArgs: {
33739
- context_window: 200000
33773
+ context_window: 200000,
33774
+ parallel_tool_calls: true
33740
33775
  }
33741
33776
  },
33742
33777
  {
@@ -33748,7 +33783,8 @@ var init_models2 = __esm(() => {
33748
33783
  free: true,
33749
33784
  updateArgs: {
33750
33785
  context_window: 160000,
33751
- max_output_tokens: 64000
33786
+ max_output_tokens: 64000,
33787
+ parallel_tool_calls: true
33752
33788
  }
33753
33789
  },
33754
33790
  {
@@ -33760,7 +33796,8 @@ var init_models2 = __esm(() => {
33760
33796
  free: true,
33761
33797
  updateArgs: {
33762
33798
  context_window: 160000,
33763
- max_output_tokens: 64000
33799
+ max_output_tokens: 64000,
33800
+ parallel_tool_calls: true
33764
33801
  }
33765
33802
  },
33766
33803
  {
@@ -33770,7 +33807,8 @@ var init_models2 = __esm(() => {
33770
33807
  description: "Minimax's latest model",
33771
33808
  updateArgs: {
33772
33809
  context_window: 160000,
33773
- max_output_tokens: 64000
33810
+ max_output_tokens: 64000,
33811
+ parallel_tool_calls: true
33774
33812
  }
33775
33813
  },
33776
33814
  {
@@ -33779,7 +33817,8 @@ var init_models2 = __esm(() => {
33779
33817
  label: "Kimi K2",
33780
33818
  description: "Kimi's K2 model",
33781
33819
  updateArgs: {
33782
- context_window: 262144
33820
+ context_window: 262144,
33821
+ parallel_tool_calls: true
33783
33822
  }
33784
33823
  },
33785
33824
  {
@@ -33790,7 +33829,8 @@ var init_models2 = __esm(() => {
33790
33829
  updateArgs: {
33791
33830
  context_window: 256000,
33792
33831
  max_output_tokens: 16000,
33793
- temperature: 1
33832
+ temperature: 1,
33833
+ parallel_tool_calls: true
33794
33834
  }
33795
33835
  },
33796
33836
  {
@@ -33800,7 +33840,8 @@ var init_models2 = __esm(() => {
33800
33840
  description: "Kimi's latest coding model",
33801
33841
  isFeatured: true,
33802
33842
  updateArgs: {
33803
- context_window: 262144
33843
+ context_window: 262144,
33844
+ parallel_tool_calls: true
33804
33845
  }
33805
33846
  },
33806
33847
  {
@@ -33809,7 +33850,8 @@ var init_models2 = __esm(() => {
33809
33850
  label: "DeepSeek Chat V3.1",
33810
33851
  description: "DeepSeek V3.1 model",
33811
33852
  updateArgs: {
33812
- context_window: 128000
33853
+ context_window: 128000,
33854
+ parallel_tool_calls: true
33813
33855
  }
33814
33856
  },
33815
33857
  {
@@ -33818,7 +33860,11 @@ var init_models2 = __esm(() => {
33818
33860
  label: "Gemini 3.1 Pro",
33819
33861
  description: "Google's latest and smartest model",
33820
33862
  isFeatured: true,
33821
- updateArgs: { context_window: 180000, temperature: 1 }
33863
+ updateArgs: {
33864
+ context_window: 180000,
33865
+ temperature: 1,
33866
+ parallel_tool_calls: true
33867
+ }
33822
33868
  },
33823
33869
  {
33824
33870
  id: "gemini-3",
@@ -33826,7 +33872,11 @@ var init_models2 = __esm(() => {
33826
33872
  label: "Gemini 3 Pro",
33827
33873
  description: "Google's smartest model",
33828
33874
  isFeatured: true,
33829
- updateArgs: { context_window: 180000, temperature: 1 }
33875
+ updateArgs: {
33876
+ context_window: 180000,
33877
+ temperature: 1,
33878
+ parallel_tool_calls: true
33879
+ }
33830
33880
  },
33831
33881
  {
33832
33882
  id: "gemini-3-flash",
@@ -33834,60 +33884,222 @@ var init_models2 = __esm(() => {
33834
33884
  label: "Gemini 3 Flash",
33835
33885
  description: "Google's fastest Gemini 3 model",
33836
33886
  isFeatured: true,
33837
- updateArgs: { context_window: 180000, temperature: 1 }
33887
+ updateArgs: {
33888
+ context_window: 180000,
33889
+ temperature: 1,
33890
+ parallel_tool_calls: true
33891
+ }
33838
33892
  },
33839
33893
  {
33840
33894
  id: "gemini-flash",
33841
33895
  handle: "google_ai/gemini-2.5-flash",
33842
33896
  label: "Gemini 2.5 Flash",
33843
33897
  description: "Google's fastest model",
33844
- updateArgs: { context_window: 180000 }
33898
+ updateArgs: { context_window: 180000, parallel_tool_calls: true }
33845
33899
  },
33846
33900
  {
33847
33901
  id: "gemini-pro",
33848
33902
  handle: "google_ai/gemini-2.5-pro",
33849
33903
  label: "Gemini 2.5 Pro",
33850
33904
  description: "Google's last generation flagship model",
33851
- updateArgs: { context_window: 180000 }
33905
+ updateArgs: { context_window: 180000, parallel_tool_calls: true }
33852
33906
  },
33853
33907
  {
33854
33908
  id: "gpt-4.1",
33855
33909
  handle: "openai/gpt-4.1",
33856
33910
  label: "GPT-4.1",
33857
33911
  description: "OpenAI's most recent non-reasoner model",
33858
- updateArgs: { context_window: 1047576 }
33912
+ updateArgs: { context_window: 1047576, parallel_tool_calls: true }
33859
33913
  },
33860
33914
  {
33861
33915
  id: "gpt-4.1-mini",
33862
33916
  handle: "openai/gpt-4.1-mini-2025-04-14",
33863
33917
  label: "GPT-4.1-Mini",
33864
33918
  description: "OpenAI's most recent non-reasoner model (mini version)",
33865
- updateArgs: { context_window: 1047576 }
33919
+ updateArgs: { context_window: 1047576, parallel_tool_calls: true }
33866
33920
  },
33867
33921
  {
33868
33922
  id: "gpt-4.1-nano",
33869
33923
  handle: "openai/gpt-4.1-nano-2025-04-14",
33870
33924
  label: "GPT-4.1-Nano",
33871
33925
  description: "OpenAI's most recent non-reasoner model (nano version)",
33872
- updateArgs: { context_window: 1047576 }
33926
+ updateArgs: { context_window: 1047576, parallel_tool_calls: true }
33873
33927
  },
33874
33928
  {
33875
33929
  id: "o4-mini",
33876
33930
  handle: "openai/o4-mini",
33877
33931
  label: "o4-mini",
33878
33932
  description: "OpenAI's latest o-series reasoning model",
33879
- updateArgs: { context_window: 180000 }
33933
+ updateArgs: { context_window: 180000, parallel_tool_calls: true }
33880
33934
  },
33881
33935
  {
33882
33936
  id: "gemini-3-vertex",
33883
33937
  handle: "google_vertex/gemini-3-pro-preview",
33884
33938
  label: "Gemini 3 Pro",
33885
33939
  description: "Google's smartest Gemini 3 Pro model (via Vertex AI)",
33886
- updateArgs: { context_window: 180000, temperature: 1 }
33940
+ updateArgs: {
33941
+ context_window: 180000,
33942
+ temperature: 1,
33943
+ parallel_tool_calls: true
33944
+ }
33887
33945
  }
33888
33946
  ];
33889
33947
  });
33890
33948
 
33949
+ // src/agent/http-headers.ts
33950
+ function getLettaCodeHeaders2(apiKey) {
33951
+ return {
33952
+ "Content-Type": "application/json",
33953
+ "User-Agent": `letta-code/${package_default.version}`,
33954
+ "X-Letta-Source": "letta-code",
33955
+ ...apiKey ? { Authorization: `Bearer ${apiKey}` } : {}
33956
+ };
33957
+ }
33958
+ function getMcpOAuthHeaders(apiKey) {
33959
+ return {
33960
+ ...getLettaCodeHeaders2(apiKey),
33961
+ Accept: "text/event-stream"
33962
+ };
33963
+ }
33964
+ var init_http_headers = __esm(() => {
33965
+ init_package();
33966
+ });
33967
+
33968
+ // src/providers/openai-codex-provider.ts
33969
+ var exports_openai_codex_provider = {};
33970
+ __export(exports_openai_codex_provider, {
33971
+ updateOpenAICodexProvider: () => updateOpenAICodexProvider,
33972
+ removeOpenAICodexProvider: () => removeOpenAICodexProvider,
33973
+ listProviders: () => listProviders,
33974
+ getOpenAICodexProvider: () => getOpenAICodexProvider,
33975
+ deleteOpenAICodexProvider: () => deleteOpenAICodexProvider,
33976
+ createOrUpdateOpenAICodexProvider: () => createOrUpdateOpenAICodexProvider,
33977
+ createOpenAICodexProvider: () => createOpenAICodexProvider,
33978
+ checkOpenAICodexEligibility: () => checkOpenAICodexEligibility,
33979
+ OPENAI_CODEX_PROVIDER_NAME: () => OPENAI_CODEX_PROVIDER_NAME,
33980
+ CHATGPT_OAUTH_PROVIDER_TYPE: () => CHATGPT_OAUTH_PROVIDER_TYPE
33981
+ });
33982
+ async function getLettaConfig() {
33983
+ const settings = await settingsManager.getSettingsWithSecureTokens();
33984
+ const baseUrl = process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
33985
+ const apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY || "";
33986
+ return { baseUrl, apiKey };
33987
+ }
33988
+ async function providersRequest(method, path2, body) {
33989
+ const { baseUrl, apiKey } = await getLettaConfig();
33990
+ const url = `${baseUrl}${path2}`;
33991
+ const response = await fetch(url, {
33992
+ method,
33993
+ headers: getLettaCodeHeaders2(apiKey),
33994
+ ...body && { body: JSON.stringify(body) }
33995
+ });
33996
+ if (!response.ok) {
33997
+ const errorText = await response.text();
33998
+ if (response.status === 403) {
33999
+ try {
34000
+ const errorData = JSON.parse(errorText);
34001
+ if (errorData.error && typeof errorData.error === "string" && errorData.error.includes("only available for pro or enterprise")) {
34002
+ throw new Error("PLAN_UPGRADE_REQUIRED");
34003
+ }
34004
+ } catch (parseError) {
34005
+ if (parseError instanceof Error && parseError.message === "PLAN_UPGRADE_REQUIRED") {
34006
+ throw parseError;
34007
+ }
34008
+ }
34009
+ }
34010
+ throw new Error(`Provider API error (${response.status}): ${errorText}`);
34011
+ }
34012
+ const text = await response.text();
34013
+ if (!text) {
34014
+ return {};
34015
+ }
34016
+ return JSON.parse(text);
34017
+ }
34018
+ async function listProviders() {
34019
+ try {
34020
+ const response = await providersRequest("GET", "/v1/providers");
34021
+ return response;
34022
+ } catch {
34023
+ return [];
34024
+ }
34025
+ }
34026
+ async function getOpenAICodexProvider() {
34027
+ const providers = await listProviders();
34028
+ return providers.find((p) => p.name === OPENAI_CODEX_PROVIDER_NAME) || null;
34029
+ }
34030
+ async function createOpenAICodexProvider(config) {
34031
+ const apiKeyJson = JSON.stringify({
34032
+ access_token: config.access_token,
34033
+ id_token: config.id_token,
34034
+ refresh_token: config.refresh_token,
34035
+ account_id: config.account_id,
34036
+ expires_at: config.expires_at
34037
+ });
34038
+ return providersRequest("POST", "/v1/providers", {
34039
+ name: OPENAI_CODEX_PROVIDER_NAME,
34040
+ provider_type: CHATGPT_OAUTH_PROVIDER_TYPE,
34041
+ api_key: apiKeyJson
34042
+ });
34043
+ }
34044
+ async function updateOpenAICodexProvider(providerId, config) {
34045
+ const apiKeyJson = JSON.stringify({
34046
+ access_token: config.access_token,
34047
+ id_token: config.id_token,
34048
+ refresh_token: config.refresh_token,
34049
+ account_id: config.account_id,
34050
+ expires_at: config.expires_at
34051
+ });
34052
+ return providersRequest("PATCH", `/v1/providers/${providerId}`, {
34053
+ api_key: apiKeyJson
34054
+ });
34055
+ }
34056
+ async function deleteOpenAICodexProvider(providerId) {
34057
+ await providersRequest("DELETE", `/v1/providers/${providerId}`);
34058
+ }
34059
+ async function createOrUpdateOpenAICodexProvider(config) {
34060
+ const existing = await getOpenAICodexProvider();
34061
+ if (existing) {
34062
+ return updateOpenAICodexProvider(existing.id, config);
34063
+ } else {
34064
+ return createOpenAICodexProvider(config);
34065
+ }
34066
+ }
34067
+ async function removeOpenAICodexProvider() {
34068
+ const existing = await getOpenAICodexProvider();
34069
+ if (existing) {
34070
+ await deleteOpenAICodexProvider(existing.id);
34071
+ }
34072
+ }
34073
+ async function checkOpenAICodexEligibility() {
34074
+ try {
34075
+ const balance = await providersRequest("GET", "/v1/metadata/balance");
34076
+ const billingTier = balance.billing_tier.toLowerCase();
34077
+ if (billingTier === "pro" || billingTier === "enterprise") {
34078
+ return {
34079
+ eligible: true,
34080
+ billing_tier: balance.billing_tier
34081
+ };
34082
+ }
34083
+ return {
34084
+ eligible: false,
34085
+ billing_tier: balance.billing_tier,
34086
+ reason: `ChatGPT OAuth requires a Pro or Enterprise plan. Current plan: ${balance.billing_tier}`
34087
+ };
34088
+ } catch (error) {
34089
+ console.warn("Failed to check ChatGPT OAuth eligibility:", error);
34090
+ return {
34091
+ eligible: true,
34092
+ billing_tier: "unknown"
34093
+ };
34094
+ }
34095
+ }
34096
+ var OPENAI_CODEX_PROVIDER_NAME = "chatgpt-plus-pro", CHATGPT_OAUTH_PROVIDER_TYPE = "chatgpt_oauth";
34097
+ var init_openai_codex_provider = __esm(async () => {
34098
+ init_http_headers();
34099
+ init_oauth();
34100
+ await init_settings_manager();
34101
+ });
34102
+
33891
34103
  // src/agent/model.ts
33892
34104
  var exports_model = {};
33893
34105
  __export(exports_model, {
@@ -33897,6 +34109,7 @@ __export(exports_model, {
33897
34109
  getReasoningTierOptionsForHandle: () => getReasoningTierOptionsForHandle,
33898
34110
  getModelUpdateArgs: () => getModelUpdateArgs,
33899
34111
  getModelShortName: () => getModelShortName,
34112
+ getModelPresetUpdateForAgent: () => getModelPresetUpdateForAgent,
33900
34113
  getModelInfoForLlmConfig: () => getModelInfoForLlmConfig,
33901
34114
  getModelInfo: () => getModelInfo,
33902
34115
  getModelDisplayName: () => getModelDisplayName,
@@ -33992,6 +34205,27 @@ function getModelUpdateArgs(modelIdentifier) {
33992
34205
  const modelInfo = getModelInfo(modelIdentifier);
33993
34206
  return modelInfo?.updateArgs;
33994
34207
  }
34208
+ function getModelPresetUpdateForAgent(agent) {
34209
+ const directHandle = typeof agent.model === "string" && agent.model.length > 0 ? agent.model : null;
34210
+ const endpointType = agent.llm_config?.model_endpoint_type;
34211
+ const llmModel = agent.llm_config?.model;
34212
+ 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;
34213
+ const modelHandle = directHandle ?? llmDerivedHandle;
34214
+ if (!modelHandle)
34215
+ return null;
34216
+ const modelInfo = getModelInfoForLlmConfig(modelHandle, {
34217
+ reasoning_effort: agent.llm_config?.reasoning_effort ?? null,
34218
+ enable_reasoner: agent.llm_config?.enable_reasoner ?? null
34219
+ });
34220
+ const updateArgs = modelInfo?.updateArgs ?? getModelUpdateArgs(modelHandle);
34221
+ if (!updateArgs || Object.keys(updateArgs).length === 0) {
34222
+ return null;
34223
+ }
34224
+ return {
34225
+ modelHandle: modelInfo?.handle ?? modelHandle,
34226
+ updateArgs
34227
+ };
34228
+ }
33995
34229
  function findModelByHandle(handle) {
33996
34230
  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
34231
  const exactMatch = models.find((m) => m.handle === handle);
@@ -34039,8 +34273,9 @@ function resolveModelByLlmConfig(llmConfigModel) {
34039
34273
  return null;
34040
34274
  }
34041
34275
  var models, REASONING_EFFORT_ORDER;
34042
- var init_model = __esm(() => {
34276
+ var init_model = __esm(async () => {
34043
34277
  init_models2();
34278
+ await init_openai_codex_provider();
34044
34279
  models = models_default;
34045
34280
  REASONING_EFFORT_ORDER = [
34046
34281
  "none",
@@ -34295,12 +34530,12 @@ function getLoadingMessage(loadingState, continueSession) {
34295
34530
  }
34296
34531
  var import_react25, jsx_dev_runtime6;
34297
34532
  var init_WelcomeScreen = __esm(async () => {
34298
- init_model();
34299
34533
  init_version();
34300
34534
  init_useTerminalWidth();
34301
34535
  init_colors();
34302
34536
  await __promiseAll([
34303
34537
  init_build2(),
34538
+ init_model(),
34304
34539
  init_settings_manager(),
34305
34540
  init_AnimatedLogo(),
34306
34541
  init_Text2()
@@ -39854,160 +40089,6 @@ var init_hooks = __esm(async () => {
39854
40089
  init_types();
39855
40090
  });
39856
40091
 
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
40092
  // src/telemetry/index.ts
40012
40093
  class TelemetryManager {
40013
40094
  events = [];
@@ -42693,10 +42774,10 @@ async function switchToolsetForModel(modelIdentifier, agentId) {
42693
42774
  }
42694
42775
  var CODEX_TOOLS, CODEX_SNAKE_TOOLS, GEMINI_TOOLS, MEMORY_TOOL_NAMES;
42695
42776
  var init_toolset = __esm(async () => {
42696
- init_model();
42697
42777
  init_filter();
42698
42778
  await __promiseAll([
42699
42779
  init_client2(),
42780
+ init_model(),
42700
42781
  init_manager3()
42701
42782
  ]);
42702
42783
  CODEX_TOOLS = OPENAI_PASCAL_TOOLS;
@@ -43179,7 +43260,7 @@ var init_shellRunner = __esm(() => {
43179
43260
  });
43180
43261
 
43181
43262
  // src/tools/impl/overflow.ts
43182
- import { randomUUID } from "node:crypto";
43263
+ import { randomUUID as randomUUID2 } from "node:crypto";
43183
43264
  import * as fs3 from "node:fs";
43184
43265
  import * as os2 from "node:os";
43185
43266
  import * as path4 from "node:path";
@@ -43200,7 +43281,7 @@ function ensureOverflowDirectory(workingDirectory) {
43200
43281
  }
43201
43282
  function writeOverflowFile(content, workingDirectory, toolName) {
43202
43283
  const overflowDir = ensureOverflowDirectory(workingDirectory);
43203
- const uuid = randomUUID();
43284
+ const uuid = randomUUID2();
43204
43285
  const filename = toolName ? `${toolName.toLowerCase()}-${uuid}.txt` : `${uuid}.txt`;
43205
43286
  const filePath = path4.join(overflowDir, filename);
43206
43287
  fs3.writeFileSync(filePath, content, "utf-8");
@@ -60193,7 +60274,7 @@ __export(exports_skills, {
60193
60274
  GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR
60194
60275
  });
60195
60276
  import { existsSync as existsSync7 } from "node:fs";
60196
- import { readdir as readdir4, readFile as readFile3 } from "node:fs/promises";
60277
+ import { readdir as readdir4, readFile as readFile3, realpath as realpath2, stat as stat2 } from "node:fs/promises";
60197
60278
  import { dirname as dirname4, join as join12 } from "node:path";
60198
60279
  import { fileURLToPath as fileURLToPath6 } from "node:url";
60199
60280
  function getBundledSkillsPath() {
@@ -60265,25 +60346,52 @@ async function discoverSkills(projectSkillsPath = join12(process.cwd(), SKILLS_D
60265
60346
  errors: allErrors
60266
60347
  };
60267
60348
  }
60268
- async function findSkillFiles(currentPath, rootPath, skills, errors, source) {
60349
+ async function findSkillFiles(currentPath, rootPath, skills, errors, source, visitedRealPaths = new Set) {
60350
+ try {
60351
+ const resolvedPath = await realpath2(currentPath);
60352
+ if (visitedRealPaths.has(resolvedPath)) {
60353
+ return;
60354
+ }
60355
+ visitedRealPaths.add(resolvedPath);
60356
+ } catch (error) {
60357
+ errors.push({
60358
+ path: currentPath,
60359
+ message: `Failed to resolve directory path: ${error instanceof Error ? error.message : String(error)}`
60360
+ });
60361
+ return;
60362
+ }
60269
60363
  try {
60270
60364
  const entries = await readdir4(currentPath, { withFileTypes: true });
60271
60365
  for (const entry of entries) {
60272
60366
  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);
60367
+ try {
60368
+ let isDirectory = entry.isDirectory();
60369
+ let isFile = entry.isFile();
60370
+ if (entry.isSymbolicLink()) {
60371
+ const entryStat = await stat2(fullPath);
60372
+ isDirectory = entryStat.isDirectory();
60373
+ isFile = entryStat.isFile();
60374
+ }
60375
+ if (isDirectory) {
60376
+ await findSkillFiles(fullPath, rootPath, skills, errors, source, visitedRealPaths);
60377
+ } else if (isFile && entry.name.toUpperCase() === "SKILL.MD") {
60378
+ try {
60379
+ const skill = await parseSkillFile(fullPath, rootPath, source);
60380
+ if (skill) {
60381
+ skills.push(skill);
60382
+ }
60383
+ } catch (error) {
60384
+ errors.push({
60385
+ path: fullPath,
60386
+ message: error instanceof Error ? error.message : String(error)
60387
+ });
60280
60388
  }
60281
- } catch (error) {
60282
- errors.push({
60283
- path: fullPath,
60284
- message: error instanceof Error ? error.message : String(error)
60285
- });
60286
60389
  }
60390
+ } catch (error) {
60391
+ errors.push({
60392
+ path: fullPath,
60393
+ message: `Failed to inspect path: ${error instanceof Error ? error.message : String(error)}`
60394
+ });
60287
60395
  }
60288
60396
  }
60289
60397
  } catch (error) {
@@ -61292,13 +61400,13 @@ var init_manager2 = __esm(async () => {
61292
61400
  init_mode();
61293
61401
  init_session();
61294
61402
  init_context();
61295
- init_model();
61296
61403
  init_subagents();
61297
61404
  await __promiseAll([
61298
61405
  init_settings_manager(),
61299
61406
  init_shellEnv(),
61300
61407
  init_available_models(),
61301
- init_client2()
61408
+ init_client2(),
61409
+ init_model()
61302
61410
  ]);
61303
61411
  BYOK_PROVIDER_TO_BASE = {
61304
61412
  "lc-anthropic": "anthropic",
@@ -66513,12 +66621,12 @@ function clearToolsWithLock() {
66513
66621
  }
66514
66622
  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
66623
  var init_manager3 = __esm(async () => {
66516
- init_model();
66517
66624
  init_subagents();
66518
66625
  init_constants();
66519
66626
  init_debug();
66520
66627
  await __promiseAll([
66521
66628
  init_approval_execution(),
66629
+ init_model(),
66522
66630
  init_hooks(),
66523
66631
  init_openai_codex_provider(),
66524
66632
  init_telemetry(),
@@ -66937,9 +67045,16 @@ var init_approval_execution = __esm(async () => {
66937
67045
  // src/agent/check-approval.ts
66938
67046
  var exports_check_approval = {};
66939
67047
  __export(exports_check_approval, {
67048
+ prepareMessageHistory: () => prepareMessageHistory2,
66940
67049
  getResumeData: () => getResumeData2,
66941
67050
  extractApprovals: () => extractApprovals2
66942
67051
  });
67052
+ function isPrimaryMessageType2(messageType) {
67053
+ return messageType === "user_message" || messageType === "assistant_message" || messageType === "event_message" || messageType === "summary_message";
67054
+ }
67055
+ function isAnchorMessageType2(messageType) {
67056
+ return messageType === "user_message" || messageType === "assistant_message";
67057
+ }
66943
67058
  function isBackfillEnabled2() {
66944
67059
  const val = process.env.LETTA_BACKFILL;
66945
67060
  return val !== "0" && val !== "false";
@@ -66958,9 +67073,62 @@ function extractApprovals2(messageToCheck) {
66958
67073
  }
66959
67074
  return { pendingApproval, pendingApprovals };
66960
67075
  }
66961
- function prepareMessageHistory2(messages) {
66962
- const historyCount = Math.min(MESSAGE_HISTORY_LIMIT2, messages.length);
66963
- let messageHistory = messages.slice(-historyCount);
67076
+ function prepareMessageHistory2(messages, opts) {
67077
+ const isRenderable = (msg) => {
67078
+ const t = msg.message_type;
67079
+ 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") {
67080
+ return true;
67081
+ }
67082
+ const ts = t;
67083
+ return ts === "event_message" || ts === "summary_message";
67084
+ };
67085
+ const renderable = messages.filter(isRenderable);
67086
+ if (opts?.primaryOnly) {
67087
+ const convo = renderable.filter((m) => isPrimaryMessageType2(m.message_type));
67088
+ let trimmed = convo.slice(-BACKFILL_PRIMARY_MESSAGE_LIMIT2);
67089
+ const hasAssistant = trimmed.some((m) => m.message_type === "assistant_message");
67090
+ if (!hasAssistant) {
67091
+ const lastAssistantIndex = convo.map((m) => m.message_type).lastIndexOf("assistant_message");
67092
+ if (lastAssistantIndex >= 0) {
67093
+ const lastAssistant = convo[lastAssistantIndex];
67094
+ if (lastAssistant) {
67095
+ const tailLimit = Math.max(BACKFILL_PRIMARY_MESSAGE_LIMIT2 - 1, 0);
67096
+ const newestTail = tailLimit > 0 ? convo.slice(-tailLimit) : [];
67097
+ trimmed = [lastAssistant, ...newestTail];
67098
+ }
67099
+ }
67100
+ }
67101
+ if (trimmed.length > 0)
67102
+ return trimmed;
67103
+ const reasoning = renderable.filter((m) => m.message_type === "reasoning_message");
67104
+ if (reasoning.length > 0) {
67105
+ return reasoning.slice(-BACKFILL_PRIMARY_MESSAGE_LIMIT2);
67106
+ }
67107
+ return [];
67108
+ }
67109
+ const isPrimary = (msg) => {
67110
+ const t = msg.message_type;
67111
+ return t === "user_message" || t === "assistant_message" || t === "reasoning_message" || t === "event_message" || t === "summary_message";
67112
+ };
67113
+ let primaryCount = 0;
67114
+ let startIndex = Math.max(0, renderable.length - 1);
67115
+ for (let i = renderable.length - 1;i >= 0; i -= 1) {
67116
+ const msg = renderable[i];
67117
+ if (!msg)
67118
+ continue;
67119
+ if (isPrimary(msg)) {
67120
+ primaryCount += 1;
67121
+ if (primaryCount >= BACKFILL_PRIMARY_MESSAGE_LIMIT2) {
67122
+ startIndex = i;
67123
+ break;
67124
+ }
67125
+ }
67126
+ startIndex = i;
67127
+ }
67128
+ let messageHistory = renderable.slice(startIndex);
67129
+ if (messageHistory.length > BACKFILL_MAX_RENDERABLE_MESSAGES2) {
67130
+ messageHistory = messageHistory.slice(-BACKFILL_MAX_RENDERABLE_MESSAGES2);
67131
+ }
66964
67132
  if (messageHistory[0]?.message_type === "tool_return_message") {
66965
67133
  messageHistory = messageHistory.slice(1);
66966
67134
  }
@@ -66968,11 +67136,57 @@ function prepareMessageHistory2(messages) {
66968
67136
  }
66969
67137
  function sortChronological2(messages) {
66970
67138
  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();
67139
+ const ta = a.date ? new Date(a.date).getTime() : 0;
67140
+ const tb = b.date ? new Date(b.date).getTime() : 0;
67141
+ if (!Number.isFinite(ta) && !Number.isFinite(tb))
67142
+ return 0;
67143
+ if (!Number.isFinite(ta))
67144
+ return -1;
67145
+ if (!Number.isFinite(tb))
67146
+ return 1;
67147
+ return ta - tb;
66974
67148
  });
66975
67149
  }
67150
+ async function fetchConversationBackfillMessages2(client, conversationId) {
67151
+ const collected = [];
67152
+ const seen = new Set;
67153
+ let cursorBefore = null;
67154
+ let assistantCount = 0;
67155
+ let anchorCount = 0;
67156
+ for (let pageIndex = 0;pageIndex < BACKFILL_MAX_PAGES2; pageIndex += 1) {
67157
+ const page = await client.conversations.messages.list(conversationId, {
67158
+ limit: BACKFILL_PAGE_LIMIT2,
67159
+ order: "desc",
67160
+ ...cursorBefore ? { before: cursorBefore } : {}
67161
+ });
67162
+ const items = page.getPaginatedItems();
67163
+ if (items.length === 0)
67164
+ break;
67165
+ cursorBefore = items[items.length - 1]?.id ?? null;
67166
+ for (const m of items) {
67167
+ if (!m?.id)
67168
+ continue;
67169
+ const key = "otid" in m && m.otid ? `otid:${String(m.otid)}` : `id:${m.id}:${m.message_type ?? ""}`;
67170
+ if (seen.has(key))
67171
+ continue;
67172
+ seen.add(key);
67173
+ collected.push(m);
67174
+ if (m.message_type === "assistant_message")
67175
+ assistantCount += 1;
67176
+ if (isAnchorMessageType2(m.message_type))
67177
+ anchorCount += 1;
67178
+ }
67179
+ if (assistantCount >= BACKFILL_MIN_ASSISTANT2 && anchorCount >= BACKFILL_ANCHOR_MESSAGE_LIMIT2) {
67180
+ break;
67181
+ }
67182
+ if (items.length < BACKFILL_PAGE_LIMIT2)
67183
+ break;
67184
+ }
67185
+ if (assistantCount < BACKFILL_MIN_ASSISTANT2) {
67186
+ debugWarn("check-approval", `Backfill scan found 0 assistant messages in last ${collected.length} messages (tool-heavy conversation?)`);
67187
+ }
67188
+ return sortChronological2(collected);
67189
+ }
66976
67190
  async function getResumeData2(client, agent, conversationId) {
66977
67191
  try {
66978
67192
  let inContextMessageIds;
@@ -66988,14 +67202,13 @@ async function getResumeData2(client, agent, conversationId) {
66988
67202
  debugWarn("check-approval", "No in-context messages - no pending approvals");
66989
67203
  if (isBackfillEnabled2()) {
66990
67204
  try {
66991
- const backfill = await client.conversations.messages.list(conversationId, {
66992
- limit: MESSAGE_HISTORY_LIMIT2,
66993
- order: "desc"
66994
- });
67205
+ const backfill = await fetchConversationBackfillMessages2(client, conversationId);
66995
67206
  return {
66996
67207
  pendingApproval: null,
66997
67208
  pendingApprovals: [],
66998
- messageHistory: sortChronological2(backfill.getPaginatedItems())
67209
+ messageHistory: prepareMessageHistory2(backfill, {
67210
+ primaryOnly: true
67211
+ })
66999
67212
  };
67000
67213
  } catch (backfillError) {
67001
67214
  debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
@@ -67014,11 +67227,7 @@ async function getResumeData2(client, agent, conversationId) {
67014
67227
  const retrievedMessages = await client.messages.retrieve(lastInContextId);
67015
67228
  if (isBackfillEnabled2()) {
67016
67229
  try {
67017
- const backfillPage = await client.conversations.messages.list(conversationId, {
67018
- limit: MESSAGE_HISTORY_LIMIT2,
67019
- order: "desc"
67020
- });
67021
- messages = sortChronological2(backfillPage.getPaginatedItems());
67230
+ messages = await fetchConversationBackfillMessages2(client, conversationId);
67022
67231
  } catch (backfillError) {
67023
67232
  debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
67024
67233
  }
@@ -67031,7 +67240,9 @@ async function getResumeData2(client, agent, conversationId) {
67031
67240
  return {
67032
67241
  pendingApproval,
67033
67242
  pendingApprovals,
67034
- messageHistory: prepareMessageHistory2(messages)
67243
+ messageHistory: prepareMessageHistory2(messages, {
67244
+ primaryOnly: true
67245
+ })
67035
67246
  };
67036
67247
  }
67037
67248
  } else {
@@ -67040,7 +67251,7 @@ async function getResumeData2(client, agent, conversationId) {
67040
67251
  return {
67041
67252
  pendingApproval: null,
67042
67253
  pendingApprovals: [],
67043
- messageHistory: prepareMessageHistory2(messages)
67254
+ messageHistory: prepareMessageHistory2(messages, { primaryOnly: true })
67044
67255
  };
67045
67256
  } else {
67046
67257
  inContextMessageIds = agent.message_ids;
@@ -67060,13 +67271,13 @@ async function getResumeData2(client, agent, conversationId) {
67060
67271
  if (isBackfillEnabled2()) {
67061
67272
  try {
67062
67273
  const messagesPage = await client.agents.messages.list(agent.id, {
67063
- limit: MESSAGE_HISTORY_LIMIT2,
67274
+ limit: BACKFILL_PAGE_LIMIT2,
67064
67275
  order: "desc",
67065
67276
  conversation_id: "default"
67066
67277
  });
67067
67278
  messages = sortChronological2(messagesPage.items);
67068
67279
  if (process.env.DEBUG) {
67069
- console.log(`[DEBUG] agents.messages.list(conversation_id=default) returned ${messagesPage.items.length} messages`);
67280
+ console.log(`[DEBUG] agents.messages.list(conversation_id=default) returned ${messages.length} messages`);
67070
67281
  }
67071
67282
  } catch (backfillError) {
67072
67283
  debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
@@ -67080,7 +67291,9 @@ async function getResumeData2(client, agent, conversationId) {
67080
67291
  return {
67081
67292
  pendingApproval,
67082
67293
  pendingApprovals,
67083
- messageHistory: prepareMessageHistory2(messages)
67294
+ messageHistory: prepareMessageHistory2(messages, {
67295
+ primaryOnly: true
67296
+ })
67084
67297
  };
67085
67298
  }
67086
67299
  } else {
@@ -67089,7 +67302,7 @@ async function getResumeData2(client, agent, conversationId) {
67089
67302
  return {
67090
67303
  pendingApproval: null,
67091
67304
  pendingApprovals: [],
67092
- messageHistory: prepareMessageHistory2(messages)
67305
+ messageHistory: prepareMessageHistory2(messages, { primaryOnly: true })
67093
67306
  };
67094
67307
  }
67095
67308
  } catch (error) {
@@ -67100,7 +67313,7 @@ async function getResumeData2(client, agent, conversationId) {
67100
67313
  return { pendingApproval: null, pendingApprovals: [], messageHistory: [] };
67101
67314
  }
67102
67315
  }
67103
- var MESSAGE_HISTORY_LIMIT2 = 15;
67316
+ 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
67317
  var init_check_approval = __esm(() => {
67105
67318
  init_error();
67106
67319
  init_debug();
@@ -67856,6 +68069,13 @@ function extractTextPart(v) {
67856
68069
  }
67857
68070
  return "";
67858
68071
  }
68072
+ function markCompactionCompleted(ctx) {
68073
+ if (!ctx)
68074
+ return;
68075
+ ctx.pendingCompaction = true;
68076
+ ctx.pendingSkillsReinject = true;
68077
+ ctx.pendingReflectionTrigger = true;
68078
+ }
67859
68079
  function resolveLineIdForKind(b, canonicalId, kind) {
67860
68080
  const existing = b.byId.get(canonicalId);
67861
68081
  if (!existing || existing.kind === kind)
@@ -68046,6 +68266,7 @@ function onChunk(b, chunk, ctx) {
68046
68266
  phase: "finished",
68047
68267
  summary: compactionSummary
68048
68268
  }));
68269
+ markCompactionCompleted(ctx);
68049
68270
  }
68050
68271
  break;
68051
68272
  }
@@ -68253,11 +68474,7 @@ function onChunk(b, chunk, ctx) {
68253
68474
  break;
68254
68475
  }
68255
68476
  }
68256
- if (ctx) {
68257
- ctx.pendingCompaction = true;
68258
- ctx.pendingSkillsReinject = true;
68259
- ctx.pendingReflectionTrigger = true;
68260
- }
68477
+ markCompactionCompleted(ctx);
68261
68478
  break;
68262
68479
  }
68263
68480
  if (msgType === "event_message") {
@@ -69313,7 +69530,7 @@ __export(exports_skills2, {
69313
69530
  GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR2
69314
69531
  });
69315
69532
  import { existsSync as existsSync10 } from "node:fs";
69316
- import { readdir as readdir6, readFile as readFile5 } from "node:fs/promises";
69533
+ import { readdir as readdir6, readFile as readFile5, realpath as realpath3, stat as stat3 } from "node:fs/promises";
69317
69534
  import { dirname as dirname8, join as join19 } from "node:path";
69318
69535
  import { fileURLToPath as fileURLToPath7 } from "node:url";
69319
69536
  function getBundledSkillsPath2() {
@@ -69385,25 +69602,52 @@ async function discoverSkills2(projectSkillsPath = join19(process.cwd(), SKILLS_
69385
69602
  errors: allErrors
69386
69603
  };
69387
69604
  }
69388
- async function findSkillFiles2(currentPath, rootPath, skills, errors, source) {
69605
+ async function findSkillFiles2(currentPath, rootPath, skills, errors, source, visitedRealPaths = new Set) {
69606
+ try {
69607
+ const resolvedPath = await realpath3(currentPath);
69608
+ if (visitedRealPaths.has(resolvedPath)) {
69609
+ return;
69610
+ }
69611
+ visitedRealPaths.add(resolvedPath);
69612
+ } catch (error) {
69613
+ errors.push({
69614
+ path: currentPath,
69615
+ message: `Failed to resolve directory path: ${error instanceof Error ? error.message : String(error)}`
69616
+ });
69617
+ return;
69618
+ }
69389
69619
  try {
69390
69620
  const entries = await readdir6(currentPath, { withFileTypes: true });
69391
69621
  for (const entry of entries) {
69392
69622
  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);
69623
+ try {
69624
+ let isDirectory = entry.isDirectory();
69625
+ let isFile = entry.isFile();
69626
+ if (entry.isSymbolicLink()) {
69627
+ const entryStat = await stat3(fullPath);
69628
+ isDirectory = entryStat.isDirectory();
69629
+ isFile = entryStat.isFile();
69630
+ }
69631
+ if (isDirectory) {
69632
+ await findSkillFiles2(fullPath, rootPath, skills, errors, source, visitedRealPaths);
69633
+ } else if (isFile && entry.name.toUpperCase() === "SKILL.MD") {
69634
+ try {
69635
+ const skill2 = await parseSkillFile2(fullPath, rootPath, source);
69636
+ if (skill2) {
69637
+ skills.push(skill2);
69638
+ }
69639
+ } catch (error) {
69640
+ errors.push({
69641
+ path: fullPath,
69642
+ message: error instanceof Error ? error.message : String(error)
69643
+ });
69400
69644
  }
69401
- } catch (error) {
69402
- errors.push({
69403
- path: fullPath,
69404
- message: error instanceof Error ? error.message : String(error)
69405
- });
69406
69645
  }
69646
+ } catch (error) {
69647
+ errors.push({
69648
+ path: fullPath,
69649
+ message: `Failed to inspect path: ${error instanceof Error ? error.message : String(error)}`
69650
+ });
69407
69651
  }
69408
69652
  }
69409
69653
  } catch (error) {
@@ -70112,7 +70356,7 @@ __export(exports_overflow, {
70112
70356
  cleanupOldOverflowFiles: () => cleanupOldOverflowFiles,
70113
70357
  OVERFLOW_CONFIG: () => OVERFLOW_CONFIG2
70114
70358
  });
70115
- import { randomUUID as randomUUID2 } from "node:crypto";
70359
+ import { randomUUID as randomUUID4 } from "node:crypto";
70116
70360
  import * as fs10 from "node:fs";
70117
70361
  import * as os3 from "node:os";
70118
70362
  import * as path20 from "node:path";
@@ -70133,7 +70377,7 @@ function ensureOverflowDirectory2(workingDirectory) {
70133
70377
  }
70134
70378
  function writeOverflowFile2(content, workingDirectory, toolName) {
70135
70379
  const overflowDir = ensureOverflowDirectory2(workingDirectory);
70136
- const uuid = randomUUID2();
70380
+ const uuid = randomUUID4();
70137
70381
  const filename = toolName ? `${toolName.toLowerCase()}-${uuid}.txt` : `${uuid}.txt`;
70138
70382
  const filePath = path20.join(overflowDir, filename);
70139
70383
  fs10.writeFileSync(filePath, content, "utf-8");
@@ -71894,16 +72138,88 @@ var init_create = __esm(async () => {
71894
72138
  init_http_headers();
71895
72139
  init_memory();
71896
72140
  init_memoryPrompt();
71897
- init_model();
71898
72141
  init_promptAssets();
71899
72142
  await __promiseAll([
71900
72143
  init_settings_manager(),
71901
72144
  init_available_models(),
71902
72145
  init_client2(),
72146
+ init_model(),
71903
72147
  init_modify()
71904
72148
  ]);
71905
72149
  });
71906
72150
 
72151
+ // src/agent/listMessagesRouting.ts
72152
+ function resolveListMessagesRoute(listReq, sessionConvId, sessionAgentId) {
72153
+ const targetConvId = listReq.conversation_id ?? sessionConvId;
72154
+ if (targetConvId !== "default") {
72155
+ return { kind: "conversations", conversationId: targetConvId };
72156
+ }
72157
+ return { kind: "agents", agentId: listReq.agent_id ?? sessionAgentId };
72158
+ }
72159
+
72160
+ // src/agent/listMessagesHandler.ts
72161
+ import { randomUUID as randomUUID5 } from "node:crypto";
72162
+ async function handleListMessages(params) {
72163
+ const {
72164
+ listReq,
72165
+ sessionConversationId,
72166
+ sessionAgentId,
72167
+ sessionId,
72168
+ requestId,
72169
+ client
72170
+ } = params;
72171
+ const limit2 = listReq.limit ?? 50;
72172
+ const order = listReq.order ?? "desc";
72173
+ const cursorOpts = {
72174
+ ...listReq.before ? { before: listReq.before } : {},
72175
+ ...listReq.after ? { after: listReq.after } : {}
72176
+ };
72177
+ try {
72178
+ let items;
72179
+ const route = resolveListMessagesRoute(listReq, sessionConversationId, sessionAgentId);
72180
+ if (route.kind === "conversations") {
72181
+ const page = await client.conversations.messages.list(route.conversationId, { limit: limit2, order, ...cursorOpts });
72182
+ items = page.getPaginatedItems();
72183
+ } else {
72184
+ const page = await client.agents.messages.list(route.agentId, {
72185
+ limit: limit2,
72186
+ order,
72187
+ ...cursorOpts
72188
+ });
72189
+ items = page.items;
72190
+ }
72191
+ const hasMore = items.length >= limit2;
72192
+ const oldestId = items.length > 0 ? items[items.length - 1]?.id : undefined;
72193
+ const payload = {
72194
+ messages: items,
72195
+ next_before: oldestId ?? null,
72196
+ has_more: hasMore
72197
+ };
72198
+ return {
72199
+ type: "control_response",
72200
+ response: {
72201
+ subtype: "success",
72202
+ request_id: requestId,
72203
+ response: payload
72204
+ },
72205
+ session_id: sessionId,
72206
+ uuid: randomUUID5()
72207
+ };
72208
+ } catch (err) {
72209
+ return {
72210
+ type: "control_response",
72211
+ response: {
72212
+ subtype: "error",
72213
+ request_id: requestId,
72214
+ error: err instanceof Error ? err.message : "list_messages failed"
72215
+ },
72216
+ session_id: sessionId,
72217
+ uuid: randomUUID5()
72218
+ };
72219
+ }
72220
+ }
72221
+ var init_listMessagesHandler = () => {};
72222
+
71907
72223
  // src/agent/stats.ts
71908
72224
  class SessionStats {
71909
72225
  sessionStartMs;
@@ -72551,6 +72867,72 @@ function mergeQueuedTurnInput(queued, options) {
72551
72867
  return mergedParts.length > 0 ? mergedParts : null;
72552
72868
  }
72553
72869
 
72870
+ // src/cli/helpers/agentInfo.ts
72871
+ function getRelativeTime(dateStr) {
72872
+ const date = new Date(dateStr);
72873
+ const now = new Date;
72874
+ const diffMs = now.getTime() - date.getTime();
72875
+ const diffSecs = Math.floor(diffMs / 1000);
72876
+ const diffMins = Math.floor(diffSecs / 60);
72877
+ const diffHours = Math.floor(diffMins / 60);
72878
+ const diffDays = Math.floor(diffHours / 24);
72879
+ if (diffDays > 0) {
72880
+ return `${diffDays} day${diffDays === 1 ? "" : "s"} ago`;
72881
+ }
72882
+ if (diffHours > 0) {
72883
+ return `${diffHours} hour${diffHours === 1 ? "" : "s"} ago`;
72884
+ }
72885
+ if (diffMins > 0) {
72886
+ return `${diffMins} minute${diffMins === 1 ? "" : "s"} ago`;
72887
+ }
72888
+ return "just now";
72889
+ }
72890
+ function buildAgentInfo(options) {
72891
+ try {
72892
+ const { agentInfo, serverUrl } = options;
72893
+ let actualServerUrl = LETTA_CLOUD_API_URL;
72894
+ try {
72895
+ const settings = settingsManager.getSettings();
72896
+ actualServerUrl = serverUrl || process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
72897
+ } catch {}
72898
+ let lastRunInfo = "No previous messages";
72899
+ if (agentInfo.lastRunAt) {
72900
+ try {
72901
+ const lastRunDate = new Date(agentInfo.lastRunAt);
72902
+ const localLastRun = lastRunDate.toLocaleString();
72903
+ const relativeTime = getRelativeTime(agentInfo.lastRunAt);
72904
+ lastRunInfo = `${localLastRun} (${relativeTime})`;
72905
+ } catch {
72906
+ lastRunInfo = "(failed to parse last run time)";
72907
+ }
72908
+ }
72909
+ const showMemoryDir = (() => {
72910
+ try {
72911
+ return settingsManager.isMemfsEnabled(agentInfo.id);
72912
+ } catch {
72913
+ return false;
72914
+ }
72915
+ })();
72916
+ const memoryDirLine = showMemoryDir ? `
72917
+ - **Memory directory (also stored in \`MEMORY_DIR\` env var)**: \`${getMemoryFilesystemRoot(agentInfo.id)}\`` : "";
72918
+ return `${SYSTEM_REMINDER_OPEN} This is an automated message providing information about you.
72919
+ - **Agent ID (also stored in \`AGENT_ID\` env var)**: ${agentInfo.id}${memoryDirLine}
72920
+ - **Agent name**: ${agentInfo.name || "(unnamed)"} (the user can change this with /rename)
72921
+ - **Agent description**: ${agentInfo.description || "(no description)"} (the user can change this with /description)
72922
+ - **Last message**: ${lastRunInfo}
72923
+ - **Server location**: ${actualServerUrl}
72924
+ ${SYSTEM_REMINDER_CLOSE}`;
72925
+ } catch {
72926
+ return "";
72927
+ }
72928
+ }
72929
+ var init_agentInfo = __esm(async () => {
72930
+ init_memoryFilesystem();
72931
+ init_oauth();
72932
+ init_constants();
72933
+ await init_settings_manager();
72934
+ });
72935
+
72554
72936
  // src/cli/helpers/sessionContext.ts
72555
72937
  import { execSync as execSync2 } from "node:child_process";
72556
72938
  import { platform as platform3 } from "node:os";
@@ -72579,25 +72961,6 @@ function getDeviceType() {
72579
72961
  return p;
72580
72962
  }
72581
72963
  }
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
72964
  function safeGitExec(command, cwd2) {
72602
72965
  try {
72603
72966
  return execSync2(command, { cwd: cwd2, encoding: "utf-8", stdio: "pipe" }).trim();
@@ -72630,9 +72993,8 @@ function getGitInfo() {
72630
72993
  return { isGitRepo: false };
72631
72994
  }
72632
72995
  }
72633
- function buildSessionContext(options) {
72996
+ function buildSessionContext() {
72634
72997
  try {
72635
- const { agentInfo, serverUrl } = options;
72636
72998
  const cwd2 = process.cwd();
72637
72999
  let version = "unknown";
72638
73000
  try {
@@ -72647,31 +73009,6 @@ function buildSessionContext(options) {
72647
73009
  localTime = getLocalTime();
72648
73010
  } catch {}
72649
73011
  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
73012
  let context3 = `${SYSTEM_REMINDER_OPEN}
72676
73013
  This is an automated message providing context about the user's environment.
72677
73014
  The user has just initiated a new connection via the [Letta Code CLI client](https://docs.letta.com/letta-code/index.md).
@@ -72707,25 +73044,15 @@ ${gitInfo.status}
72707
73044
  - For multiline strings (git commits, PR bodies), use simple quoted strings instead
72708
73045
  `;
72709
73046
  }
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}`;
73047
+ context3 += SYSTEM_REMINDER_CLOSE;
72718
73048
  return context3;
72719
73049
  } catch {
72720
73050
  return "";
72721
73051
  }
72722
73052
  }
72723
- var init_sessionContext = __esm(async () => {
72724
- init_memoryFilesystem();
72725
- init_oauth();
73053
+ var init_sessionContext = __esm(() => {
72726
73054
  init_constants();
72727
73055
  init_version();
72728
- await init_settings_manager();
72729
73056
  });
72730
73057
 
72731
73058
  // src/reminders/catalog.ts
@@ -72734,9 +73061,19 @@ var init_catalog = __esm(() => {
72734
73061
  SHARED_REMINDER_CATALOG = [
72735
73062
  {
72736
73063
  id: "session-context",
72737
- description: "First-turn device/agent/git context",
73064
+ description: "First-turn device/git/cwd context",
72738
73065
  modes: ["interactive", "headless-one-shot", "headless-bidirectional"]
72739
73066
  },
73067
+ {
73068
+ id: "agent-info",
73069
+ description: "Agent identity (ID, name, server, memory dir)",
73070
+ modes: [
73071
+ "interactive",
73072
+ "headless-one-shot",
73073
+ "headless-bidirectional",
73074
+ "subagent"
73075
+ ]
73076
+ },
72740
73077
  {
72741
73078
  id: "skills",
72742
73079
  description: "Available skills system reminder (with reinjection)",
@@ -72779,14 +73116,11 @@ var init_catalog = __esm(() => {
72779
73116
 
72780
73117
  // src/reminders/engine.ts
72781
73118
  import { join as join23 } from "node:path";
72782
- async function buildSessionContextReminder(context3) {
72783
- if (!context3.sessionContextReminderEnabled || context3.state.hasSentSessionContext) {
73119
+ async function buildAgentInfoReminder(context3) {
73120
+ if (context3.state.hasSentAgentInfo) {
72784
73121
  return null;
72785
73122
  }
72786
- if (!settingsManager.getSetting("sessionContextEnabled")) {
72787
- return null;
72788
- }
72789
- const reminder = buildSessionContext({
73123
+ const reminder = buildAgentInfo({
72790
73124
  agentInfo: {
72791
73125
  id: context3.agent.id,
72792
73126
  name: context3.agent.name,
@@ -72795,6 +73129,17 @@ async function buildSessionContextReminder(context3) {
72795
73129
  },
72796
73130
  serverUrl: context3.agent.serverUrl
72797
73131
  });
73132
+ context3.state.hasSentAgentInfo = true;
73133
+ return reminder || null;
73134
+ }
73135
+ async function buildSessionContextReminder(context3) {
73136
+ if (!context3.sessionContextReminderEnabled || context3.state.hasSentSessionContext) {
73137
+ return null;
73138
+ }
73139
+ if (!settingsManager.getSetting("sessionContextEnabled")) {
73140
+ return null;
73141
+ }
73142
+ const reminder = buildSessionContext();
72798
73143
  context3.state.hasSentSessionContext = true;
72799
73144
  return reminder || null;
72800
73145
  }
@@ -73010,12 +73355,13 @@ var PERMISSION_MODE_DESCRIPTIONS, MAX_COMMAND_REMINDERS_PER_TURN = 10, MAX_TOOLS
73010
73355
  var init_engine = __esm(async () => {
73011
73356
  init_context();
73012
73357
  init_skills();
73358
+ init_sessionContext();
73013
73359
  init_constants();
73014
73360
  init_mode();
73015
73361
  init_catalog();
73016
73362
  await __promiseAll([
73363
+ init_agentInfo(),
73017
73364
  init_memoryReminder(),
73018
- init_sessionContext(),
73019
73365
  init_settings_manager()
73020
73366
  ]);
73021
73367
  PERMISSION_MODE_DESCRIPTIONS = {
@@ -73025,6 +73371,7 @@ var init_engine = __esm(async () => {
73025
73371
  bypassPermissions: "All tools auto-approved. Bias toward action."
73026
73372
  };
73027
73373
  sharedReminderProviders = {
73374
+ "agent-info": buildAgentInfoReminder,
73028
73375
  "session-context": buildSessionContextReminder,
73029
73376
  skills: buildSkillsReminder,
73030
73377
  "permission-mode": buildPermissionModeReminder,
@@ -73040,6 +73387,7 @@ var init_engine = __esm(async () => {
73040
73387
  // src/reminders/state.ts
73041
73388
  function createSharedReminderState() {
73042
73389
  return {
73390
+ hasSentAgentInfo: false,
73043
73391
  hasSentSessionContext: false,
73044
73392
  hasInjectedSkillsReminder: false,
73045
73393
  cachedSkillsReminder: null,
@@ -73263,9 +73611,9 @@ async function importAgentFromRegistry(options) {
73263
73611
  }
73264
73612
  var AGENT_REGISTRY_OWNER = "letta-ai", AGENT_REGISTRY_REPO = "agent-file", AGENT_REGISTRY_BRANCH = "main";
73265
73613
  var init_import = __esm(async () => {
73266
- init_model();
73267
73614
  await __promiseAll([
73268
73615
  init_client2(),
73616
+ init_model(),
73269
73617
  init_modify()
73270
73618
  ]);
73271
73619
  });
@@ -73338,6 +73686,7 @@ __export(exports_headless, {
73338
73686
  mergeBidirectionalQueuedInput: () => mergeBidirectionalQueuedInput,
73339
73687
  handleHeadlessCommand: () => handleHeadlessCommand
73340
73688
  });
73689
+ import { randomUUID as randomUUID6 } from "node:crypto";
73341
73690
  import { parseArgs as parseArgs6 } from "node:util";
73342
73691
  function mergeBidirectionalQueuedInput(queued) {
73343
73692
  return mergeQueuedTurnInput(queued, {
@@ -73868,18 +74217,34 @@ In headless mode, use:
73868
74217
  }
73869
74218
  markMilestone("HEADLESS_AGENT_RESOLVED");
73870
74219
  const isResumingAgent = !!(specifiedAgentId || shouldContinue || !forceNew && !fromAfFile);
73871
- if (isResumingAgent && (model || systemPromptPreset)) {
74220
+ if (isResumingAgent) {
74221
+ const { updateAgentLLMConfig: updateAgentLLMConfig2 } = await init_modify().then(() => exports_modify);
73872
74222
  if (model) {
73873
- const { resolveModel: resolveModel2 } = await Promise.resolve().then(() => (init_model(), exports_model));
74223
+ const { resolveModel: resolveModel2 } = await init_model().then(() => exports_model);
73874
74224
  const modelHandle = resolveModel2(model);
73875
- if (!modelHandle) {
74225
+ if (typeof modelHandle !== "string") {
73876
74226
  console.error(`Error: Invalid model "${model}"`);
73877
74227
  process.exit(1);
73878
74228
  }
73879
- const { updateAgentLLMConfig: updateAgentLLMConfig2 } = await init_modify().then(() => exports_modify);
73880
74229
  const updateArgs = getModelUpdateArgs(model);
73881
74230
  await updateAgentLLMConfig2(agent.id, modelHandle, updateArgs);
73882
74231
  agent = await client.agents.retrieve(agent.id);
74232
+ } else {
74233
+ const { getModelPresetUpdateForAgent: getModelPresetUpdateForAgent2 } = await init_model().then(() => exports_model);
74234
+ const presetRefresh = getModelPresetUpdateForAgent2(agent);
74235
+ if (presetRefresh) {
74236
+ const resumeRefreshUpdateArgs = {};
74237
+ if (typeof presetRefresh.updateArgs.max_output_tokens === "number") {
74238
+ resumeRefreshUpdateArgs.max_output_tokens = presetRefresh.updateArgs.max_output_tokens;
74239
+ }
74240
+ if (typeof presetRefresh.updateArgs.parallel_tool_calls === "boolean") {
74241
+ resumeRefreshUpdateArgs.parallel_tool_calls = presetRefresh.updateArgs.parallel_tool_calls;
74242
+ }
74243
+ if (Object.keys(resumeRefreshUpdateArgs).length > 0) {
74244
+ await updateAgentLLMConfig2(agent.id, presetRefresh.modelHandle, resumeRefreshUpdateArgs);
74245
+ agent = await client.agents.retrieve(agent.id);
74246
+ }
74247
+ }
73883
74248
  }
73884
74249
  if (systemPromptPreset) {
73885
74250
  const { updateAgentSystemPrompt: updateAgentSystemPrompt2 } = await init_modify().then(() => exports_modify);
@@ -73951,6 +74316,8 @@ In headless mode, use:
73951
74316
  isolated_block_labels: isolatedBlockLabels
73952
74317
  });
73953
74318
  conversationId = conversation.id;
74319
+ } else if (isSubagent) {
74320
+ conversationId = "default";
73954
74321
  } else {
73955
74322
  const conversation = await client.conversations.create({
73956
74323
  agent_id: agent.id,
@@ -74185,7 +74552,7 @@ ${loadedContents.join(`
74185
74552
  message: `Maximum turns limit reached (${buffers.usage.stepCount}/${maxTurns} steps)`,
74186
74553
  stop_reason: "max_steps",
74187
74554
  session_id: sessionId,
74188
- uuid: `error-max-turns-${crypto.randomUUID()}`
74555
+ uuid: `error-max-turns-${randomUUID6()}`
74189
74556
  };
74190
74557
  console.log(JSON.stringify(errorMsg));
74191
74558
  } else {
@@ -74234,7 +74601,7 @@ ${loadedContents.join(`
74234
74601
  recovery_type: "approval_pending",
74235
74602
  message: "Detected pending approval conflict on send; resolving before retry",
74236
74603
  session_id: sessionId,
74237
- uuid: `recovery-pre-stream-${crypto.randomUUID()}`
74604
+ uuid: `recovery-pre-stream-${randomUUID6()}`
74238
74605
  };
74239
74606
  console.log(JSON.stringify(recoveryMsg));
74240
74607
  } else {
@@ -74253,7 +74620,7 @@ ${loadedContents.join(`
74253
74620
  max_attempts: CONVERSATION_BUSY_MAX_RETRIES,
74254
74621
  delay_ms: CONVERSATION_BUSY_RETRY_DELAY_MS,
74255
74622
  session_id: sessionId,
74256
- uuid: `retry-conversation-busy-${crypto.randomUUID()}`
74623
+ uuid: `retry-conversation-busy-${randomUUID6()}`
74257
74624
  };
74258
74625
  console.log(JSON.stringify(retryMsg));
74259
74626
  } else {
@@ -74275,7 +74642,7 @@ ${loadedContents.join(`
74275
74642
  max_attempts: LLM_API_ERROR_MAX_RETRIES,
74276
74643
  delay_ms: delayMs,
74277
74644
  session_id: sessionId,
74278
- uuid: `retry-pre-stream-${crypto.randomUUID()}`
74645
+ uuid: `retry-pre-stream-${randomUUID6()}`
74279
74646
  };
74280
74647
  console.log(JSON.stringify(retryMsg));
74281
74648
  } else {
@@ -74310,7 +74677,7 @@ ${loadedContents.join(`
74310
74677
  stop_reason: "error",
74311
74678
  run_id: errorInfo.run_id,
74312
74679
  session_id: sessionId,
74313
- uuid: crypto.randomUUID(),
74680
+ uuid: randomUUID6(),
74314
74681
  ...errorInfo.error_type && errorInfo.run_id && {
74315
74682
  api_error: {
74316
74683
  message_type: "error_message",
@@ -74332,7 +74699,7 @@ ${loadedContents.join(`
74332
74699
  message: "Detected pending approval conflict; auto-denying stale approval and retrying",
74333
74700
  run_id: recoveryRunId ?? undefined,
74334
74701
  session_id: sessionId,
74335
- uuid: `recovery-${recoveryRunId || crypto.randomUUID()}`
74702
+ uuid: `recovery-${recoveryRunId || randomUUID6()}`
74336
74703
  };
74337
74704
  console.log(JSON.stringify(recoveryMsg));
74338
74705
  approvalPendingRecovery = true;
@@ -74372,7 +74739,7 @@ ${loadedContents.join(`
74372
74739
  type: "stream_event",
74373
74740
  event: chunk,
74374
74741
  session_id: sessionId,
74375
- uuid: uuid || crypto.randomUUID()
74742
+ uuid: uuid || randomUUID6()
74376
74743
  };
74377
74744
  console.log(JSON.stringify(streamEvent));
74378
74745
  } else {
@@ -74380,7 +74747,7 @@ ${loadedContents.join(`
74380
74747
  type: "message",
74381
74748
  ...chunk,
74382
74749
  session_id: sessionId,
74383
- uuid: uuid || crypto.randomUUID()
74750
+ uuid: uuid || randomUUID6()
74384
74751
  };
74385
74752
  console.log(JSON.stringify(msg));
74386
74753
  }
@@ -74488,7 +74855,7 @@ ${loadedContents.join(`
74488
74855
  delay_ms: delayMs,
74489
74856
  run_id: lastRunId ?? undefined,
74490
74857
  session_id: sessionId,
74491
- uuid: `retry-${lastRunId || crypto.randomUUID()}`
74858
+ uuid: `retry-${lastRunId || randomUUID6()}`
74492
74859
  };
74493
74860
  console.log(JSON.stringify(retryMsg));
74494
74861
  } else {
@@ -74508,7 +74875,7 @@ ${loadedContents.join(`
74508
74875
  message: "Tool call ID mismatch; fetching actual pending approvals and resyncing",
74509
74876
  run_id: lastRunId ?? undefined,
74510
74877
  session_id: sessionId,
74511
- uuid: `recovery-${lastRunId || crypto.randomUUID()}`
74878
+ uuid: `recovery-${lastRunId || randomUUID6()}`
74512
74879
  };
74513
74880
  console.log(JSON.stringify(recoveryMsg));
74514
74881
  } else {
@@ -74525,7 +74892,7 @@ ${loadedContents.join(`
74525
74892
  stop_reason: stopReason,
74526
74893
  run_id: lastRunId ?? undefined,
74527
74894
  session_id: sessionId,
74528
- uuid: `error-${lastRunId || crypto.randomUUID()}`
74895
+ uuid: `error-${lastRunId || randomUUID6()}`
74529
74896
  };
74530
74897
  console.log(JSON.stringify(errorMsg));
74531
74898
  } else {
@@ -74564,7 +74931,7 @@ ${loadedContents.join(`
74564
74931
  delay_ms: delayMs,
74565
74932
  run_id: lastRunId ?? undefined,
74566
74933
  session_id: sessionId,
74567
- uuid: `retry-${lastRunId || crypto.randomUUID()}`
74934
+ uuid: `retry-${lastRunId || randomUUID6()}`
74568
74935
  };
74569
74936
  console.log(JSON.stringify(retryMsg));
74570
74937
  } else {
@@ -74605,7 +74972,7 @@ ${loadedContents.join(`
74605
74972
  stop_reason: stopReason,
74606
74973
  run_id: lastRunId ?? undefined,
74607
74974
  session_id: sessionId,
74608
- uuid: `error-${lastRunId || crypto.randomUUID()}`
74975
+ uuid: `error-${lastRunId || randomUUID6()}`
74609
74976
  };
74610
74977
  console.log(JSON.stringify(errorMsg));
74611
74978
  } else {
@@ -74623,7 +74990,7 @@ ${loadedContents.join(`
74623
74990
  stop_reason: "error",
74624
74991
  run_id: lastKnownRunId ?? undefined,
74625
74992
  session_id: sessionId,
74626
- uuid: `error-${lastKnownRunId || crypto.randomUUID()}`
74993
+ uuid: `error-${lastKnownRunId || randomUUID6()}`
74627
74994
  };
74628
74995
  console.log(JSON.stringify(errorMsg));
74629
74996
  } else {
@@ -74909,7 +75276,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
74909
75276
  message: "Invalid JSON input",
74910
75277
  stop_reason: "error",
74911
75278
  session_id: sessionId,
74912
- uuid: crypto.randomUUID()
75279
+ uuid: randomUUID6()
74913
75280
  };
74914
75281
  console.log(JSON.stringify(errorMsg2));
74915
75282
  continue;
@@ -74936,7 +75303,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
74936
75303
  }
74937
75304
  },
74938
75305
  session_id: sessionId,
74939
- uuid: crypto.randomUUID()
75306
+ uuid: randomUUID6()
74940
75307
  };
74941
75308
  console.log(JSON.stringify(initResponse));
74942
75309
  } else if (subtype === "interrupt") {
@@ -74951,7 +75318,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
74951
75318
  request_id: requestId ?? ""
74952
75319
  },
74953
75320
  session_id: sessionId,
74954
- uuid: crypto.randomUUID()
75321
+ uuid: randomUUID6()
74955
75322
  };
74956
75323
  console.log(JSON.stringify(interruptResponse));
74957
75324
  } else if (subtype === "register_external_tools") {
@@ -74999,9 +75366,20 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
74999
75366
  response: { registered: tools.length }
75000
75367
  },
75001
75368
  session_id: sessionId,
75002
- uuid: crypto.randomUUID()
75369
+ uuid: randomUUID6()
75003
75370
  };
75004
75371
  console.log(JSON.stringify(registerResponse));
75372
+ } else if (subtype === "list_messages") {
75373
+ const listReq = message.request;
75374
+ const listResp = await handleListMessages({
75375
+ listReq,
75376
+ sessionConversationId: conversationId,
75377
+ sessionAgentId: agent.id,
75378
+ sessionId,
75379
+ requestId: requestId ?? "",
75380
+ client
75381
+ });
75382
+ console.log(JSON.stringify(listResp));
75005
75383
  } else {
75006
75384
  const errorResponse = {
75007
75385
  type: "control_response",
@@ -75011,7 +75389,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
75011
75389
  error: `Unknown control request subtype: ${subtype}`
75012
75390
  },
75013
75391
  session_id: sessionId,
75014
- uuid: crypto.randomUUID()
75392
+ uuid: randomUUID6()
75015
75393
  };
75016
75394
  console.log(JSON.stringify(errorResponse));
75017
75395
  }
@@ -75135,7 +75513,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
75135
75513
  recovery_type: "approval_pending",
75136
75514
  message: "Detected pending approval conflict on send; resolving before retry",
75137
75515
  session_id: sessionId,
75138
- uuid: `recovery-bidir-${crypto.randomUUID()}`
75516
+ uuid: `recovery-bidir-${randomUUID6()}`
75139
75517
  };
75140
75518
  console.log(JSON.stringify(recoveryMsg));
75141
75519
  await resolveAllPendingApprovals();
@@ -75153,7 +75531,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
75153
75531
  max_attempts: LLM_API_ERROR_MAX_RETRIES,
75154
75532
  delay_ms: delayMs,
75155
75533
  session_id: sessionId,
75156
- uuid: `retry-bidir-${crypto.randomUUID()}`
75534
+ uuid: `retry-bidir-${randomUUID6()}`
75157
75535
  };
75158
75536
  console.log(JSON.stringify(retryMsg));
75159
75537
  await new Promise((resolve22) => setTimeout(resolve22, delayMs));
@@ -75175,7 +75553,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
75175
75553
  stop_reason: "error",
75176
75554
  run_id: errorInfo.run_id,
75177
75555
  session_id: sessionId,
75178
- uuid: crypto.randomUUID(),
75556
+ uuid: randomUUID6(),
75179
75557
  ...errorInfo.error_type && errorInfo.run_id && {
75180
75558
  api_error: {
75181
75559
  message_type: "error_message",
@@ -75199,7 +75577,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
75199
75577
  type: "stream_event",
75200
75578
  event: chunk,
75201
75579
  session_id: sessionId,
75202
- uuid: uuid || crypto.randomUUID()
75580
+ uuid: uuid || randomUUID6()
75203
75581
  };
75204
75582
  console.log(JSON.stringify(streamEvent));
75205
75583
  } else {
@@ -75207,7 +75585,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
75207
75585
  type: "message",
75208
75586
  ...chunk,
75209
75587
  session_id: sessionId,
75210
- uuid: uuid || crypto.randomUUID()
75588
+ uuid: uuid || randomUUID6()
75211
75589
  };
75212
75590
  console.log(JSON.stringify(msg));
75213
75591
  }
@@ -75344,7 +75722,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
75344
75722
  message: errorDetails,
75345
75723
  stop_reason: "error",
75346
75724
  session_id: sessionId,
75347
- uuid: crypto.randomUUID()
75725
+ uuid: randomUUID6()
75348
75726
  };
75349
75727
  console.log(JSON.stringify(errorMsg2));
75350
75728
  const errorResultMsg = {
@@ -75373,7 +75751,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
75373
75751
  message: `Unknown message type: ${message.type}`,
75374
75752
  stop_reason: "error",
75375
75753
  session_id: sessionId,
75376
- uuid: crypto.randomUUID()
75754
+ uuid: randomUUID6()
75377
75755
  };
75378
75756
  console.log(JSON.stringify(errorMsg));
75379
75757
  }
@@ -75384,8 +75762,8 @@ var LLM_API_ERROR_MAX_RETRIES = 3, CONVERSATION_BUSY_MAX_RETRIES = 1, CONVERSATI
75384
75762
  var init_headless = __esm(async () => {
75385
75763
  init_error();
75386
75764
  init_context();
75765
+ init_listMessagesHandler();
75387
75766
  init_memory();
75388
- init_model();
75389
75767
  init_skillSources();
75390
75768
  init_errorFormatter();
75391
75769
  init_messageQueueBridge();
@@ -75397,6 +75775,7 @@ var init_headless = __esm(async () => {
75397
75775
  init_client2(),
75398
75776
  init_create(),
75399
75777
  init_message(),
75778
+ init_model(),
75400
75779
  init_accumulator(),
75401
75780
  init_approvalClassification(),
75402
75781
  init_memoryReminder(),
@@ -77056,12 +77435,12 @@ function AgentSelector({
77056
77435
  }
77057
77436
  var import_react31, jsx_dev_runtime11, SOLID_LINE2 = "─", TABS, TAB_DESCRIPTIONS, TAB_EMPTY_STATES, DISPLAY_PAGE_SIZE2 = 5, FETCH_PAGE_SIZE2 = 20;
77058
77437
  var init_AgentSelector = __esm(async () => {
77059
- init_model();
77060
77438
  init_useTerminalWidth();
77061
77439
  init_colors();
77062
77440
  await __promiseAll([
77063
77441
  init_build2(),
77064
77442
  init_client2(),
77443
+ init_model(),
77065
77444
  init_settings_manager(),
77066
77445
  init_MarkdownDisplay(),
77067
77446
  init_Text2()
@@ -81196,9 +81575,404 @@ var init_InlineTaskApproval = __esm(async () => {
81196
81575
  InlineTaskApproval.displayName = "InlineTaskApproval";
81197
81576
  });
81198
81577
 
81578
+ // src/web/plan-viewer-template.txt
81579
+ var plan_viewer_template_default = `<!DOCTYPE html>
81580
+ <html lang="en">
81581
+ <head>
81582
+ <meta charset="UTF-8">
81583
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
81584
+ <title>Plan | Letta Code</title>
81585
+ <style>
81586
+ @import url('https://fonts.googleapis.com/css2?family=Manrope:wght@300;400;500;600;700&display=swap');
81587
+ @import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500&display=swap');
81588
+ :root {
81589
+ --accent: hsl(240, 93%, 35%);
81590
+ --accent-light: hsl(240, 67%, 98%);
81591
+ --accent-light-border: hsl(240, 62%, 94%);
81592
+ --bg: #ffffff;
81593
+ --panel: #ffffff;
81594
+ --border: hsl(210, 10%, 92.2%);
81595
+ --text: hsl(0, 0%, 8%);
81596
+ --text-muted: hsl(210, 3%, 28%);
81597
+ --text-dim: hsl(210, 3%, 66%);
81598
+ --mono: 'Fira Code', Menlo, Courier, monospace;
81599
+ --sans: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', sans-serif;
81600
+ --serif: 'Iowan Old Style', 'Palatino Linotype', 'Book Antiqua', Georgia, serif;
81601
+ --radius: 6px;
81602
+ --max-w: 860px;
81603
+ --surface: hsl(0, 0%, 98%);
81604
+ --surface-2: hsl(0, 0%, 96%);
81605
+ --hover: hsl(0, 0%, 96%);
81606
+ --hover-accent: hsl(240, 67%, 98%);
81607
+ }
81608
+
81609
+ html.dark {
81610
+ --accent: hsl(240, 80%, 68%);
81611
+ --accent-light: hsl(240, 20%, 18%);
81612
+ --accent-light-border: hsl(240, 15%, 25%);
81613
+ --bg: hsl(0, 0%, 11%);
81614
+ --panel: hsl(0, 0%, 13%);
81615
+ --surface: hsl(0, 0%, 15%);
81616
+ --surface-2: hsl(0, 0%, 18%);
81617
+ --hover: hsl(0, 0%, 18%);
81618
+ --hover-accent: hsl(240, 15%, 20%);
81619
+ --border: hsl(210, 3%, 20%);
81620
+ --text: hsl(210, 7%, 84%);
81621
+ --text-muted: hsl(210, 3%, 60%);
81622
+ --text-dim: hsl(210, 3%, 42%);
81623
+ }
81624
+ * { box-sizing: border-box; margin: 0; padding: 0; }
81625
+ body {
81626
+ font-family: var(--mono);
81627
+ color: var(--text);
81628
+ background: var(--bg);
81629
+ line-height: 1.55;
81630
+ font-weight: 400;
81631
+ font-size: 13px;
81632
+ }
81633
+ a { color: var(--accent); text-decoration: none; }
81634
+ a:hover { text-decoration: underline; }
81635
+
81636
+ .app-shell {
81637
+ max-width: var(--max-w);
81638
+ margin: 22px auto;
81639
+ border: 1px solid var(--border);
81640
+ border-radius: 8px;
81641
+ overflow: hidden;
81642
+ background: var(--panel);
81643
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 6px 16px rgba(0, 0, 0, 0.04);
81644
+ }
81645
+
81646
+ .header {
81647
+ padding: 14px 20px;
81648
+ border-bottom: 1px solid var(--border);
81649
+ background: var(--panel);
81650
+ display: flex;
81651
+ gap: 12px;
81652
+ align-items: center;
81653
+ }
81654
+ .header h1 { display: none; }
81655
+ .header-brand {
81656
+ display: flex;
81657
+ flex-direction: column;
81658
+ gap: 3px;
81659
+ }
81660
+ .header-brand svg {
81661
+ height: 26px;
81662
+ width: auto;
81663
+ fill: var(--text);
81664
+ }
81665
+ .header .agent-meta {
81666
+ margin-left: auto;
81667
+ text-align: right;
81668
+ }
81669
+ .header .agent-name {
81670
+ font-family: var(--sans);
81671
+ font-size: 13px;
81672
+ font-weight: 500;
81673
+ color: var(--text-muted);
81674
+ }
81675
+ .header .plan-path {
81676
+ font-family: var(--mono);
81677
+ font-size: 11px;
81678
+ color: var(--text-dim);
81679
+ margin-top: 2px;
81680
+ }
81681
+
81682
+ .content-area {
81683
+ position: relative;
81684
+ }
81685
+ .file-meta {
81686
+ position: relative;
81687
+ border-bottom: 1px solid var(--border);
81688
+ background: var(--surface);
81689
+ padding: 10px 14px;
81690
+ min-height: 38px;
81691
+ }
81692
+ .raw-toggle {
81693
+ position: absolute;
81694
+ top: 8px;
81695
+ right: 10px;
81696
+ font-size: 11px;
81697
+ padding: 3px 8px;
81698
+ border: 1px solid var(--border);
81699
+ border-radius: 4px;
81700
+ background: var(--panel);
81701
+ color: var(--text-muted);
81702
+ cursor: pointer;
81703
+ z-index: 2;
81704
+ }
81705
+ .raw-toggle:hover { background: var(--accent-light); color: var(--accent); }
81706
+ .raw-toggle.active { background: var(--accent); color: #fff; border-color: var(--accent); }
81707
+
81708
+ .file-body {
81709
+ padding: 20px 28px;
81710
+ overflow: auto;
81711
+ font-family: var(--serif);
81712
+ font-size: 16px;
81713
+ }
81714
+ .file-body h1, .file-body h2, .file-body h3 {
81715
+ margin-top: 18px;
81716
+ margin-bottom: 8px;
81717
+ }
81718
+ .file-body h1 { font-size: 30px; }
81719
+ .file-body h2 { font-size: 23px; border-bottom: 1px solid var(--border); padding-bottom: 3px; }
81720
+ .file-body h3 { font-size: 18px; }
81721
+ .file-body p, .file-body ul, .file-body ol, .file-body pre, .file-body table, .file-body blockquote {
81722
+ margin-bottom: 12px;
81723
+ }
81724
+ .file-body ul, .file-body ol {
81725
+ padding-left: 28px;
81726
+ }
81727
+ .file-body code {
81728
+ font-family: var(--mono);
81729
+ background: var(--surface-2);
81730
+ border: 1px solid var(--border);
81731
+ border-radius: 4px;
81732
+ padding: 1px 5px;
81733
+ font-size: 13px;
81734
+ }
81735
+ .file-body pre {
81736
+ background: var(--surface-2);
81737
+ border: 1px solid var(--border);
81738
+ border-radius: 8px;
81739
+ padding: 12px;
81740
+ overflow: auto;
81741
+ }
81742
+ .file-body pre code {
81743
+ border: none;
81744
+ background: transparent;
81745
+ padding: 0;
81746
+ }
81747
+ .file-body table {
81748
+ width: 100%;
81749
+ border-collapse: collapse;
81750
+ border: 1px solid var(--border);
81751
+ }
81752
+ .file-body th, .file-body td {
81753
+ padding: 6px 10px;
81754
+ border: 1px solid var(--border);
81755
+ }
81756
+ .file-body th { background: var(--surface); text-align: left; }
81757
+ .file-body blockquote {
81758
+ border-left: 3px solid var(--accent);
81759
+ padding-left: 12px;
81760
+ color: var(--text-muted);
81761
+ }
81762
+ .file-body-raw {
81763
+ padding: 20px 28px;
81764
+ overflow: auto;
81765
+ font-family: var(--mono);
81766
+ font-size: 13px;
81767
+ white-space: pre-wrap;
81768
+ word-break: break-word;
81769
+ line-height: 1.6;
81770
+ color: var(--text);
81771
+ display: none;
81772
+ }
81773
+
81774
+ .generated {
81775
+ margin-top: 14px;
81776
+ border-top: 1px solid var(--border);
81777
+ padding: 10px 16px 16px;
81778
+ font-size: 12px;
81779
+ color: var(--text-dim);
81780
+ text-align: center;
81781
+ }
81782
+
81783
+ html.dark .file-meta { background: var(--surface); }
81784
+ html.dark .file-body { color: var(--text); }
81785
+ html.dark .file-body h1, html.dark .file-body h2, html.dark .file-body h3 { color: var(--text); border-color: var(--border); }
81786
+ html.dark .file-body th { background: var(--surface); color: var(--text); }
81787
+ html.dark .file-body td { border-color: var(--border); }
81788
+ html.dark .file-body th { border-color: var(--border); }
81789
+ html.dark .file-body table { border-color: var(--border); }
81790
+ html.dark .file-body a { color: var(--accent); }
81791
+ html.dark .file-body-raw { background: var(--surface-2); color: var(--text); }
81792
+ html.dark .agent-name { color: var(--text-dim); }
81793
+ </style>
81794
+ </head>
81795
+ <body>
81796
+ <div class="app-shell">
81797
+ <header class="header">
81798
+ <h1>Plan</h1>
81799
+ <div class="header-brand">
81800
+ <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>
81801
+ </div>
81802
+ <div class="agent-meta">
81803
+ <div class="agent-name" id="agent-name"></div>
81804
+ <div class="plan-path" id="plan-path"></div>
81805
+ </div>
81806
+ </header>
81807
+
81808
+ <div class="content-area">
81809
+ <div class="file-meta">
81810
+ <button class="raw-toggle" id="raw-toggle">Raw</button>
81811
+ </div>
81812
+ <article class="file-body" id="rendered-view"></article>
81813
+ <pre class="file-body-raw" id="raw-view"></pre>
81814
+ </div>
81815
+
81816
+ <div class="generated" id="generated-at"></div>
81817
+ </div>
81818
+
81819
+ <script type="application/json" id="letta-data"><!--LETTA_PLAN_DATA_PLACEHOLDER--></script>
81820
+ <script>
81821
+ /**
81822
+ * marked v15.0.4 - a markdown parser
81823
+ * Copyright (c) 2011-2024, Christopher Jeffrey. (MIT Licensed)
81824
+ * https://github.com/markedjs/marked
81825
+ */
81826
+ !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}));
81827
+ </script>
81828
+ <script>
81829
+ (function() {
81830
+ 'use strict';
81831
+
81832
+ if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
81833
+ document.documentElement.classList.add('dark');
81834
+ }
81835
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {
81836
+ document.documentElement.classList.toggle('dark', e.matches);
81837
+ });
81838
+
81839
+ var dataEl = document.getElementById('letta-data');
81840
+ var DATA;
81841
+ try {
81842
+ DATA = JSON.parse(dataEl.textContent);
81843
+ } catch (err) {
81844
+ document.body.innerHTML = '<div style="padding:20px;color:red">Failed to parse data: ' + String(err && err.message ? err.message : err) + '</div>';
81845
+ return;
81846
+ }
81847
+
81848
+ function escHtml(s) {
81849
+ return String(s || '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
81850
+ }
81851
+
81852
+ function sanitizeUrl(raw) {
81853
+ if (!raw) return '';
81854
+ return String(raw).replace(/[\\x00-\\x1f\\x7f]/g, '').trim();
81855
+ }
81856
+ function isSafeUrl(clean) {
81857
+ if (!clean) return false;
81858
+ if (/^(https?:|mailto:)/i.test(clean)) return true;
81859
+ return !clean.startsWith('//') && !/^[a-z][a-z0-9+.-]*:/i.test(clean);
81860
+ }
81861
+
81862
+ function escAttr(s) {
81863
+ return escHtml(s).replace(/"/g, '&quot;').replace(/'/g, '&#39;');
81864
+ }
81865
+
81866
+ var renderer = new marked.Renderer();
81867
+ renderer.html = function(token) {
81868
+ return escHtml(token && token.text ? token.text : '');
81869
+ };
81870
+ renderer.link = function(opts) {
81871
+ var clean = sanitizeUrl(opts && opts.href ? opts.href : '');
81872
+ var safeHref = isSafeUrl(clean) ? escAttr(clean) : '#';
81873
+ var titleAttr = opts && opts.title ? ' title="' + escAttr(opts.title) + '"' : '';
81874
+ var inner = this.parser && opts && opts.tokens ? this.parser.parseInline(opts.tokens) : escHtml('');
81875
+ return '<a href="' + safeHref + '"' + titleAttr + ' rel="noopener" target="_blank">' + inner + '</a>';
81876
+ };
81877
+ renderer.image = function(opts) {
81878
+ var clean = sanitizeUrl(opts && opts.href ? opts.href : '');
81879
+ var safeHref = isSafeUrl(clean) ? escAttr(clean) : '';
81880
+ var titleAttr = opts && opts.title ? ' title="' + escAttr(opts.title) + '"' : '';
81881
+ var alt = escAttr(opts && opts.text ? opts.text : '');
81882
+ return safeHref
81883
+ ? '<img src="' + safeHref + '" alt="' + alt + '"' + titleAttr + '>'
81884
+ : '[' + escHtml(opts && opts.text ? opts.text : '') + ']';
81885
+ };
81886
+ marked.use({ renderer: renderer, gfm: true, breaks: true });
81887
+
81888
+ function renderMarkdown(text) {
81889
+ try {
81890
+ return marked.parse(String(text || ''));
81891
+ } catch (_) {
81892
+ return '<pre>' + escHtml(String(text || '')) + '</pre>';
81893
+ }
81894
+ }
81895
+
81896
+ // Header
81897
+ var agentName = DATA.agent && DATA.agent.name ? DATA.agent.name : '';
81898
+ var nameEl = document.getElementById('agent-name');
81899
+ if (agentName) {
81900
+ nameEl.textContent = agentName + "'s plan";
81901
+ } else {
81902
+ nameEl.textContent = 'Plan';
81903
+ }
81904
+ var pathEl = document.getElementById('plan-path');
81905
+ if (DATA.planFilePath) {
81906
+ pathEl.textContent = DATA.planFilePath;
81907
+ }
81908
+ document.getElementById('generated-at').textContent = 'Generated ' + new Date(DATA.generatedAt).toLocaleString();
81909
+
81910
+ // Content
81911
+ var renderedView = document.getElementById('rendered-view');
81912
+ var rawView = document.getElementById('raw-view');
81913
+ var toggleBtn = document.getElementById('raw-toggle');
81914
+ var rawMode = false;
81915
+
81916
+ renderedView.innerHTML = renderMarkdown(DATA.planContent || '');
81917
+ rawView.textContent = DATA.planContent || '';
81918
+
81919
+ toggleBtn.addEventListener('click', function() {
81920
+ rawMode = !rawMode;
81921
+ renderedView.style.display = rawMode ? 'none' : '';
81922
+ rawView.style.display = rawMode ? 'block' : '';
81923
+ toggleBtn.textContent = rawMode ? 'Rendered' : 'Raw';
81924
+ toggleBtn.classList.toggle('active', rawMode);
81925
+ });
81926
+ })();
81927
+ </script>
81928
+ </body>
81929
+ </html>
81930
+ `;
81931
+ var init_plan_viewer_template = () => {};
81932
+
81933
+ // src/web/generate-plan-viewer.ts
81934
+ import { chmodSync as chmodSync2, existsSync as existsSync14, mkdirSync as mkdirSync10, writeFileSync as writeFileSync7 } from "node:fs";
81935
+ import { homedir as homedir17 } from "node:os";
81936
+ import { join as join25 } from "node:path";
81937
+ async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
81938
+ const data = {
81939
+ agent: { name: options?.agentName ?? "" },
81940
+ planContent,
81941
+ planFilePath,
81942
+ generatedAt: new Date().toISOString()
81943
+ };
81944
+ const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
81945
+ const html = plan_viewer_template_default.replace("<!--LETTA_PLAN_DATA_PLACEHOLDER-->", () => jsonPayload);
81946
+ if (!existsSync14(VIEWERS_DIR)) {
81947
+ mkdirSync10(VIEWERS_DIR, { recursive: true, mode: 448 });
81948
+ }
81949
+ try {
81950
+ chmodSync2(VIEWERS_DIR, 448);
81951
+ } catch {}
81952
+ const filePath = join25(VIEWERS_DIR, "plan.html");
81953
+ writeFileSync7(filePath, html);
81954
+ chmodSync2(filePath, 384);
81955
+ const isTmux = Boolean(process.env.TMUX);
81956
+ if (!isTmux) {
81957
+ try {
81958
+ const { default: openUrl } = await Promise.resolve().then(() => (init_open(), exports_open));
81959
+ await openUrl(filePath, { wait: false });
81960
+ } catch {
81961
+ throw new Error(`Could not open browser. Run: open ${filePath}`);
81962
+ }
81963
+ }
81964
+ return { filePath, opened: !isTmux };
81965
+ }
81966
+ var VIEWERS_DIR;
81967
+ var init_generate_plan_viewer = __esm(() => {
81968
+ init_plan_viewer_template();
81969
+ VIEWERS_DIR = join25(homedir17(), ".letta", "viewers");
81970
+ });
81971
+
81199
81972
  // src/cli/components/StaticPlanApproval.tsx
81200
81973
  var import_react44, jsx_dev_runtime23, StaticPlanApproval;
81201
81974
  var init_StaticPlanApproval = __esm(async () => {
81975
+ init_generate_plan_viewer();
81202
81976
  init_useProgressIndicator();
81203
81977
  init_useTerminalWidth();
81204
81978
  init_useTextInputCursor();
@@ -81214,9 +81988,13 @@ var init_StaticPlanApproval = __esm(async () => {
81214
81988
  onApproveAndAcceptEdits,
81215
81989
  onKeepPlanning,
81216
81990
  onCancel,
81217
- isFocused = true
81991
+ isFocused = true,
81992
+ planContent,
81993
+ planFilePath,
81994
+ agentName
81218
81995
  }) => {
81219
81996
  const [selectedOption, setSelectedOption] = import_react44.useState(0);
81997
+ const [browserStatus, setBrowserStatus] = import_react44.useState("");
81220
81998
  const {
81221
81999
  text: customReason,
81222
82000
  cursorPos,
@@ -81225,6 +82003,18 @@ var init_StaticPlanApproval = __esm(async () => {
81225
82003
  } = useTextInputCursor();
81226
82004
  const columns = useTerminalWidth();
81227
82005
  useProgressIndicator();
82006
+ const openInBrowser = import_react44.useCallback(() => {
82007
+ if (!planContent || !planFilePath)
82008
+ return;
82009
+ setBrowserStatus("Opening in browser...");
82010
+ generateAndOpenPlanViewer(planContent, planFilePath, { agentName }).then((result) => {
82011
+ setBrowserStatus(result.opened ? "Opened in browser" : `Run: open ${result.filePath}`);
82012
+ setTimeout(() => setBrowserStatus(""), 5000);
82013
+ }).catch(() => {
82014
+ setBrowserStatus("Failed to open browser");
82015
+ setTimeout(() => setBrowserStatus(""), 5000);
82016
+ });
82017
+ }, [planContent, planFilePath, agentName]);
81228
82018
  const customOptionIndex = 2;
81229
82019
  const maxOptionIndex = customOptionIndex;
81230
82020
  const isOnCustomOption = selectedOption === customOptionIndex;
@@ -81236,6 +82026,10 @@ var init_StaticPlanApproval = __esm(async () => {
81236
82026
  onCancel();
81237
82027
  return;
81238
82028
  }
82029
+ if ((input === "o" || input === "O") && !isOnCustomOption && planContent) {
82030
+ openInBrowser();
82031
+ return;
82032
+ }
81239
82033
  if (key.upArrow) {
81240
82034
  setSelectedOption((prev) => Math.max(0, prev - 1));
81241
82035
  return;
@@ -81283,7 +82077,8 @@ var init_StaticPlanApproval = __esm(async () => {
81283
82077
  return;
81284
82078
  }
81285
82079
  }, { isActive: isFocused });
81286
- const hintText = isOnCustomOption ? customReason ? "Enter to submit · Esc to clear" : "Type feedback · Esc to cancel" : "Enter to select · Esc to cancel";
82080
+ const browserHint = planContent ? " · O open in browser" : "";
82081
+ const hintText = isOnCustomOption ? customReason ? "Enter to submit · Esc to clear" : "Type feedback · Esc to cancel" : `Enter to select${browserHint} · Esc to cancel`;
81287
82082
  return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
81288
82083
  flexDirection: "column",
81289
82084
  children: [
@@ -81387,7 +82182,7 @@ var init_StaticPlanApproval = __esm(async () => {
81387
82182
  marginTop: 1,
81388
82183
  children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text2, {
81389
82184
  dimColor: true,
81390
- children: hintText
82185
+ children: browserStatus || hintText
81391
82186
  }, undefined, false, undefined, this)
81392
82187
  }, undefined, false, undefined, this)
81393
82188
  ]
@@ -81501,7 +82296,10 @@ var init_ApprovalSwitch = __esm(async () => {
81501
82296
  precomputedDiff,
81502
82297
  allDiffs,
81503
82298
  showPreview = true,
81504
- defaultScope = "project"
82299
+ defaultScope = "project",
82300
+ planContent,
82301
+ planFilePath,
82302
+ agentName
81505
82303
  }) => {
81506
82304
  const toolName = approval.toolName;
81507
82305
  if (toolName === "ExitPlanMode" && onPlanApprove && onPlanKeepPlanning) {
@@ -81510,7 +82308,10 @@ var init_ApprovalSwitch = __esm(async () => {
81510
82308
  onApproveAndAcceptEdits: () => onPlanApprove(true),
81511
82309
  onKeepPlanning: onPlanKeepPlanning,
81512
82310
  onCancel: onCancel ?? (() => {}),
81513
- isFocused
82311
+ isFocused,
82312
+ planContent,
82313
+ planFilePath,
82314
+ agentName
81514
82315
  }, undefined, false, undefined, this);
81515
82316
  }
81516
82317
  if (isFileEditTool(toolName) || isFileWriteTool(toolName) || isPatchTool(toolName)) {
@@ -83161,9 +83962,9 @@ var init_pasteRegistry = __esm(() => {
83161
83962
 
83162
83963
  // src/cli/helpers/clipboard.ts
83163
83964
  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";
83965
+ import { existsSync as existsSync15, readFileSync as readFileSync3, statSync as statSync4, unlinkSync as unlinkSync5 } from "node:fs";
83165
83966
  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";
83967
+ import { basename as basename3, extname as extname5, isAbsolute as isAbsolute16, join as join26, resolve as resolve22 } from "node:path";
83167
83968
  function countLines2(text) {
83168
83969
  return (text.match(/\r\n|\r|\n/g) || []).length + 1;
83169
83970
  }
@@ -83213,7 +84014,7 @@ function translatePasteForImages(paste) {
83213
84014
  if (!isAbsolute16(filePath))
83214
84015
  filePath = resolve22(process.cwd(), filePath);
83215
84016
  const ext3 = extname5(filePath || "").toLowerCase();
83216
- if (IMAGE_EXTS.has(ext3) && existsSync14(filePath) && statSync4(filePath).isFile()) {
84017
+ if (IMAGE_EXTS.has(ext3) && existsSync15(filePath) && statSync4(filePath).isFile()) {
83217
84018
  const buf = readFileSync3(filePath);
83218
84019
  const b64 = buf.toString("base64");
83219
84020
  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 +84032,7 @@ function translatePasteForImages(paste) {
83231
84032
  function getClipboardImageToTempFile() {
83232
84033
  if (process.platform !== "darwin")
83233
84034
  return null;
83234
- const tempPath = join25(tmpdir3(), `letta-clipboard-${Date.now()}.bin`);
84035
+ const tempPath = join26(tmpdir3(), `letta-clipboard-${Date.now()}.bin`);
83235
84036
  try {
83236
84037
  const jxa = `
83237
84038
  ObjC.import('AppKit');
@@ -83254,11 +84055,11 @@ function getClipboardImageToTempFile() {
83254
84055
  encoding: "utf8",
83255
84056
  stdio: ["ignore", "pipe", "ignore"]
83256
84057
  }).trim();
83257
- if (!uti || !existsSync14(tempPath))
84058
+ if (!uti || !existsSync15(tempPath))
83258
84059
  return null;
83259
84060
  return { tempPath, uti };
83260
84061
  } catch {
83261
- if (existsSync14(tempPath)) {
84062
+ if (existsSync15(tempPath)) {
83262
84063
  try {
83263
84064
  unlinkSync5(tempPath);
83264
84065
  } catch {}
@@ -83291,7 +84092,7 @@ async function tryImportClipboardImageMac() {
83291
84092
  height: resized.height
83292
84093
  };
83293
84094
  } catch (err) {
83294
- if (existsSync14(tempPath)) {
84095
+ if (existsSync15(tempPath)) {
83295
84096
  try {
83296
84097
  unlinkSync5(tempPath);
83297
84098
  } catch {}
@@ -83868,13 +84669,13 @@ __export(exports_terminalKeybindingInstaller, {
83868
84669
  });
83869
84670
  import {
83870
84671
  copyFileSync,
83871
- existsSync as existsSync15,
83872
- mkdirSync as mkdirSync10,
84672
+ existsSync as existsSync16,
84673
+ mkdirSync as mkdirSync11,
83873
84674
  readFileSync as readFileSync4,
83874
- writeFileSync as writeFileSync7
84675
+ writeFileSync as writeFileSync8
83875
84676
  } 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";
84677
+ import { homedir as homedir18, platform as platform4 } from "node:os";
84678
+ import { dirname as dirname11, join as join27 } from "node:path";
83878
84679
  function detectTerminalType() {
83879
84680
  if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
83880
84681
  return "cursor";
@@ -83906,16 +84707,16 @@ function getKeybindingsPath(terminal) {
83906
84707
  }[terminal];
83907
84708
  const os5 = platform4();
83908
84709
  if (os5 === "darwin") {
83909
- return join26(homedir17(), "Library", "Application Support", appName, "User", "keybindings.json");
84710
+ return join27(homedir18(), "Library", "Application Support", appName, "User", "keybindings.json");
83910
84711
  }
83911
84712
  if (os5 === "win32") {
83912
84713
  const appData = process.env.APPDATA;
83913
84714
  if (!appData)
83914
84715
  return null;
83915
- return join26(appData, appName, "User", "keybindings.json");
84716
+ return join27(appData, appName, "User", "keybindings.json");
83916
84717
  }
83917
84718
  if (os5 === "linux") {
83918
- return join26(homedir17(), ".config", appName, "User", "keybindings.json");
84719
+ return join27(homedir18(), ".config", appName, "User", "keybindings.json");
83919
84720
  }
83920
84721
  return null;
83921
84722
  }
@@ -83937,7 +84738,7 @@ function parseKeybindings(content) {
83937
84738
  }
83938
84739
  }
83939
84740
  function keybindingExists(keybindingsPath) {
83940
- if (!existsSync15(keybindingsPath))
84741
+ if (!existsSync16(keybindingsPath))
83941
84742
  return false;
83942
84743
  try {
83943
84744
  const content = readFileSync4(keybindingsPath, { encoding: "utf-8" });
@@ -83950,7 +84751,7 @@ function keybindingExists(keybindingsPath) {
83950
84751
  }
83951
84752
  }
83952
84753
  function createBackup(keybindingsPath) {
83953
- if (!existsSync15(keybindingsPath))
84754
+ if (!existsSync16(keybindingsPath))
83954
84755
  return null;
83955
84756
  const backupPath = `${keybindingsPath}.letta-backup`;
83956
84757
  try {
@@ -83966,12 +84767,12 @@ function installKeybinding(keybindingsPath) {
83966
84767
  return { success: true, alreadyExists: true };
83967
84768
  }
83968
84769
  const parentDir = dirname11(keybindingsPath);
83969
- if (!existsSync15(parentDir)) {
83970
- mkdirSync10(parentDir, { recursive: true });
84770
+ if (!existsSync16(parentDir)) {
84771
+ mkdirSync11(parentDir, { recursive: true });
83971
84772
  }
83972
84773
  let keybindings = [];
83973
84774
  let backupPath = null;
83974
- if (existsSync15(keybindingsPath)) {
84775
+ if (existsSync16(keybindingsPath)) {
83975
84776
  backupPath = createBackup(keybindingsPath);
83976
84777
  const content = readFileSync4(keybindingsPath, { encoding: "utf-8" });
83977
84778
  const parsed = parseKeybindings(content);
@@ -83986,7 +84787,7 @@ function installKeybinding(keybindingsPath) {
83986
84787
  keybindings.push(SHIFT_ENTER_KEYBINDING);
83987
84788
  const newContent = `${JSON.stringify(keybindings, null, 2)}
83988
84789
  `;
83989
- writeFileSync7(keybindingsPath, newContent, { encoding: "utf-8" });
84790
+ writeFileSync8(keybindingsPath, newContent, { encoding: "utf-8" });
83990
84791
  return {
83991
84792
  success: true,
83992
84793
  backupPath: backupPath ?? undefined
@@ -84001,7 +84802,7 @@ function installKeybinding(keybindingsPath) {
84001
84802
  }
84002
84803
  function removeKeybinding(keybindingsPath) {
84003
84804
  try {
84004
- if (!existsSync15(keybindingsPath)) {
84805
+ if (!existsSync16(keybindingsPath)) {
84005
84806
  return { success: true };
84006
84807
  }
84007
84808
  const content = readFileSync4(keybindingsPath, { encoding: "utf-8" });
@@ -84015,7 +84816,7 @@ function removeKeybinding(keybindingsPath) {
84015
84816
  const filtered = keybindings.filter((kb) => !(kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus")));
84016
84817
  const newContent = `${JSON.stringify(filtered, null, 2)}
84017
84818
  `;
84018
- writeFileSync7(keybindingsPath, newContent, { encoding: "utf-8" });
84819
+ writeFileSync8(keybindingsPath, newContent, { encoding: "utf-8" });
84019
84820
  return { success: true };
84020
84821
  } catch (error) {
84021
84822
  const message = error instanceof Error ? error.message : String(error);
@@ -84068,17 +84869,17 @@ function getWezTermConfigPath() {
84068
84869
  }
84069
84870
  const xdgConfig = process.env.XDG_CONFIG_HOME;
84070
84871
  if (xdgConfig) {
84071
- const xdgPath = join26(xdgConfig, "wezterm", "wezterm.lua");
84072
- if (existsSync15(xdgPath))
84872
+ const xdgPath = join27(xdgConfig, "wezterm", "wezterm.lua");
84873
+ if (existsSync16(xdgPath))
84073
84874
  return xdgPath;
84074
84875
  }
84075
- const configPath = join26(homedir17(), ".config", "wezterm", "wezterm.lua");
84076
- if (existsSync15(configPath))
84876
+ const configPath = join27(homedir18(), ".config", "wezterm", "wezterm.lua");
84877
+ if (existsSync16(configPath))
84077
84878
  return configPath;
84078
- return join26(homedir17(), ".wezterm.lua");
84879
+ return join27(homedir18(), ".wezterm.lua");
84079
84880
  }
84080
84881
  function wezTermDeleteFixExists(configPath) {
84081
- if (!existsSync15(configPath))
84882
+ if (!existsSync16(configPath))
84082
84883
  return false;
84083
84884
  try {
84084
84885
  const content = readFileSync4(configPath, { encoding: "utf-8" });
@@ -84095,7 +84896,7 @@ function installWezTermDeleteFix() {
84095
84896
  }
84096
84897
  let content = "";
84097
84898
  let backupPath = null;
84098
- if (existsSync15(configPath)) {
84899
+ if (existsSync16(configPath)) {
84099
84900
  backupPath = `${configPath}.letta-backup`;
84100
84901
  copyFileSync(configPath, backupPath);
84101
84902
  content = readFileSync4(configPath, { encoding: "utf-8" });
@@ -84125,10 +84926,10 @@ ${WEZTERM_DELETE_FIX}
84125
84926
  `;
84126
84927
  }
84127
84928
  const parentDir = dirname11(configPath);
84128
- if (!existsSync15(parentDir)) {
84129
- mkdirSync10(parentDir, { recursive: true });
84929
+ if (!existsSync16(parentDir)) {
84930
+ mkdirSync11(parentDir, { recursive: true });
84130
84931
  }
84131
- writeFileSync7(configPath, content, { encoding: "utf-8" });
84932
+ writeFileSync8(configPath, content, { encoding: "utf-8" });
84132
84933
  return {
84133
84934
  success: true,
84134
84935
  backupPath: backupPath ?? undefined
@@ -84257,6 +85058,14 @@ var init_registry = __esm(() => {
84257
85058
  return "Opening memory viewer...";
84258
85059
  }
84259
85060
  },
85061
+ "/palace": {
85062
+ desc: "Open the Memory Palace in your browser",
85063
+ order: 16,
85064
+ noArgs: true,
85065
+ handler: () => {
85066
+ return "Opening Memory Palace...";
85067
+ }
85068
+ },
84260
85069
  "/sleeptime": {
84261
85070
  desc: "Configure reflection reminder trigger settings",
84262
85071
  order: 15.5,
@@ -84275,7 +85084,7 @@ var init_registry = __esm(() => {
84275
85084
  },
84276
85085
  "/search": {
84277
85086
  desc: "Search messages across all agents (/search [query])",
84278
- order: 16,
85087
+ order: 15.1,
84279
85088
  handler: () => {
84280
85089
  return "Opening message search...";
84281
85090
  }
@@ -84616,9 +85425,9 @@ __export(exports_custom, {
84616
85425
  GLOBAL_COMMANDS_DIR: () => GLOBAL_COMMANDS_DIR,
84617
85426
  COMMANDS_DIR: () => COMMANDS_DIR
84618
85427
  });
84619
- import { existsSync as existsSync16 } from "node:fs";
85428
+ import { existsSync as existsSync17 } from "node:fs";
84620
85429
  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";
85430
+ import { basename as basename4, dirname as dirname12, join as join28 } from "node:path";
84622
85431
  async function getCustomCommands() {
84623
85432
  if (cachedCommands !== null) {
84624
85433
  return cachedCommands;
@@ -84629,7 +85438,7 @@ async function getCustomCommands() {
84629
85438
  function refreshCustomCommands() {
84630
85439
  cachedCommands = null;
84631
85440
  }
84632
- async function discoverCustomCommands(projectPath = join27(process.cwd(), COMMANDS_DIR)) {
85441
+ async function discoverCustomCommands(projectPath = join28(process.cwd(), COMMANDS_DIR)) {
84633
85442
  const commandsById = new Map;
84634
85443
  const userCommands = await discoverFromDirectory(GLOBAL_COMMANDS_DIR, "user");
84635
85444
  for (const cmd of userCommands) {
@@ -84650,7 +85459,7 @@ async function discoverCustomCommands(projectPath = join27(process.cwd(), COMMAN
84650
85459
  return result;
84651
85460
  }
84652
85461
  async function discoverFromDirectory(dirPath, source) {
84653
- if (!existsSync16(dirPath)) {
85462
+ if (!existsSync17(dirPath)) {
84654
85463
  return [];
84655
85464
  }
84656
85465
  const commands2 = [];
@@ -84661,7 +85470,7 @@ async function findCommandFiles(currentPath, rootPath, commands2, source) {
84661
85470
  try {
84662
85471
  const entries = await readdir9(currentPath, { withFileTypes: true });
84663
85472
  for (const entry of entries) {
84664
- const fullPath = join27(currentPath, entry.name);
85473
+ const fullPath = join28(currentPath, entry.name);
84665
85474
  if (entry.isDirectory()) {
84666
85475
  await findCommandFiles(fullPath, rootPath, commands2, source);
84667
85476
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
@@ -84746,7 +85555,7 @@ async function findCustomCommand(commandName) {
84746
85555
  }
84747
85556
  var COMMANDS_DIR = ".commands", GLOBAL_COMMANDS_DIR, cachedCommands = null;
84748
85557
  var init_custom = __esm(() => {
84749
- GLOBAL_COMMANDS_DIR = join27(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
85558
+ GLOBAL_COMMANDS_DIR = join28(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
84750
85559
  });
84751
85560
 
84752
85561
  // src/cli/components/HelpDialog.tsx
@@ -87240,7 +88049,7 @@ function charsToTokens(chars) {
87240
88049
  // src/cli/components/AgentInfoBar.tsx
87241
88050
  function formatReasoningLabel(effort) {
87242
88051
  if (effort === "none")
87243
- return "no";
88052
+ return null;
87244
88053
  if (effort === "xhigh")
87245
88054
  return "max";
87246
88055
  if (effort === "minimal")
@@ -87424,7 +88233,7 @@ var init_AgentInfoBar = __esm(async () => {
87424
88233
 
87425
88234
  // src/cli/helpers/fileSearch.ts
87426
88235
  import { readdirSync as readdirSync6, statSync as statSync5 } from "node:fs";
87427
- import { join as join28, resolve as resolve23 } from "node:path";
88236
+ import { join as join29, resolve as resolve23 } from "node:path";
87428
88237
  function shouldExcludeEntry(entry) {
87429
88238
  if (entry.startsWith(".")) {
87430
88239
  return true;
@@ -87442,7 +88251,7 @@ function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = [],
87442
88251
  continue;
87443
88252
  }
87444
88253
  try {
87445
- const fullPath = join28(dir, entry);
88254
+ const fullPath = join29(dir, entry);
87446
88255
  const stats = statSync5(fullPath);
87447
88256
  const relativePath = fullPath.startsWith(process.cwd()) ? fullPath.slice(process.cwd().length + 1) : fullPath;
87448
88257
  const matches = pattern.length === 0 || relativePath.toLowerCase().includes(pattern.toLowerCase());
@@ -87497,7 +88306,7 @@ async function searchFiles(query, deep = false) {
87497
88306
  const matchingEntries = entries.filter((entry) => !shouldExcludeEntry(entry)).filter((entry) => searchPattern.length === 0 || entry.toLowerCase().includes(searchPattern.toLowerCase()));
87498
88307
  for (const entry of matchingEntries.slice(0, 50)) {
87499
88308
  try {
87500
- const fullPath = join28(searchDir, entry);
88309
+ const fullPath = join29(searchDir, entry);
87501
88310
  const stats = statSync5(fullPath);
87502
88311
  const relativePath = fullPath.startsWith(process.cwd()) ? fullPath.slice(process.cwd().length + 1) : fullPath;
87503
88312
  results.push({
@@ -88194,7 +89003,7 @@ function truncateEnd(value, maxChars) {
88194
89003
  }
88195
89004
  function getReasoningEffortTag(effort) {
88196
89005
  if (effort === "none")
88197
- return "no";
89006
+ return null;
88198
89007
  if (effort === "xhigh")
88199
89008
  return "max";
88200
89009
  if (effort === "minimal")
@@ -90705,7 +91514,7 @@ var init_McpSelector = __esm(async () => {
90705
91514
 
90706
91515
  // src/agent/memoryScanner.ts
90707
91516
  import { readdirSync as readdirSync7, readFileSync as readFileSync5, statSync as statSync6 } from "node:fs";
90708
- import { join as join29, relative as relative7 } from "node:path";
91517
+ import { join as join30, relative as relative7 } from "node:path";
90709
91518
  function scanMemoryFilesystem(memoryRoot) {
90710
91519
  const nodes = [];
90711
91520
  const scanDir = (dir, depth, parentIsLast) => {
@@ -90717,8 +91526,8 @@ function scanMemoryFilesystem(memoryRoot) {
90717
91526
  }
90718
91527
  const filtered = entries.filter((name) => !name.startsWith("."));
90719
91528
  const sorted = filtered.sort((a, b) => {
90720
- const aPath = join29(dir, a);
90721
- const bPath = join29(dir, b);
91529
+ const aPath = join30(dir, a);
91530
+ const bPath = join30(dir, b);
90722
91531
  let aIsDir = false;
90723
91532
  let bIsDir = false;
90724
91533
  try {
@@ -90738,7 +91547,7 @@ function scanMemoryFilesystem(memoryRoot) {
90738
91547
  return a.localeCompare(b);
90739
91548
  });
90740
91549
  sorted.forEach((name, index) => {
90741
- const fullPath = join29(dir, name);
91550
+ const fullPath = join30(dir, name);
90742
91551
  let isDir = false;
90743
91552
  try {
90744
91553
  isDir = statSync6(fullPath).isDirectory();
@@ -92408,10 +93217,14 @@ html.dark .warning-badge { background: hsl(42, 30%, 18%); color: hsl(42, 80%, 70
92408
93217
  var init_memory_viewer_template = () => {};
92409
93218
 
92410
93219
  // src/web/generate-memory-viewer.ts
93220
+ var exports_generate_memory_viewer = {};
93221
+ __export(exports_generate_memory_viewer, {
93222
+ generateAndOpenMemoryViewer: () => generateAndOpenMemoryViewer
93223
+ });
92411
93224
  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";
93225
+ import { chmodSync as chmodSync3, existsSync as existsSync18, mkdirSync as mkdirSync12, writeFileSync as writeFileSync9 } from "node:fs";
93226
+ import { homedir as homedir19 } from "node:os";
93227
+ import { join as join31 } from "node:path";
92415
93228
  import { promisify as promisify10 } from "node:util";
92416
93229
  async function runGitSafe(cwd2, args) {
92417
93230
  try {
@@ -92694,15 +93507,15 @@ async function generateAndOpenMemoryViewer(agentId, options) {
92694
93507
  }
92695
93508
  const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
92696
93509
  const html = memory_viewer_template_default.replace("<!--LETTA_DATA_PLACEHOLDER-->", () => jsonPayload);
92697
- if (!existsSync17(VIEWERS_DIR)) {
92698
- mkdirSync11(VIEWERS_DIR, { recursive: true, mode: 448 });
93510
+ if (!existsSync18(VIEWERS_DIR2)) {
93511
+ mkdirSync12(VIEWERS_DIR2, { recursive: true, mode: 448 });
92699
93512
  }
92700
93513
  try {
92701
- chmodSync2(VIEWERS_DIR, 448);
93514
+ chmodSync3(VIEWERS_DIR2, 448);
92702
93515
  } catch {}
92703
- const filePath = join30(VIEWERS_DIR, `memory-${encodeURIComponent(agentId)}.html`);
92704
- writeFileSync8(filePath, html);
92705
- chmodSync2(filePath, 384);
93516
+ const filePath = join31(VIEWERS_DIR2, `memory-${encodeURIComponent(agentId)}.html`);
93517
+ writeFileSync9(filePath, html);
93518
+ chmodSync3(filePath, 384);
92706
93519
  const isTmux = Boolean(process.env.TMUX);
92707
93520
  if (!isTmux) {
92708
93521
  try {
@@ -92714,7 +93527,7 @@ async function generateAndOpenMemoryViewer(agentId, options) {
92714
93527
  }
92715
93528
  return { filePath, opened: !isTmux };
92716
93529
  }
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;
93530
+ 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
93531
  var init_generate_memory_viewer = __esm(async () => {
92719
93532
  init_memoryFilesystem();
92720
93533
  init_memoryScanner();
@@ -92724,12 +93537,12 @@ var init_generate_memory_viewer = __esm(async () => {
92724
93537
  init_memoryGit()
92725
93538
  ]);
92726
93539
  execFile10 = promisify10(execFileCb2);
92727
- VIEWERS_DIR = join30(homedir18(), ".letta", "viewers");
93540
+ VIEWERS_DIR2 = join31(homedir19(), ".letta", "viewers");
92728
93541
  REFLECTION_PATTERN = /\(reflection\)|🔮|reflection:/i;
92729
93542
  });
92730
93543
 
92731
93544
  // src/cli/components/MemfsTreeViewer.tsx
92732
- import { existsSync as existsSync18 } from "node:fs";
93545
+ import { existsSync as existsSync19 } from "node:fs";
92733
93546
  function renderTreePrefix(node) {
92734
93547
  let prefix = "";
92735
93548
  for (let i = 0;i < node.depth; i++) {
@@ -92755,7 +93568,7 @@ function MemfsTreeViewer({
92755
93568
  const [status, setStatus] = import_react72.useState(null);
92756
93569
  const statusTimerRef = import_react72.useRef(null);
92757
93570
  const memoryRoot = getMemoryFilesystemRoot(agentId);
92758
- const memoryExists = existsSync18(memoryRoot);
93571
+ const memoryExists = existsSync19(memoryRoot);
92759
93572
  const hasGitRepo = import_react72.useMemo(() => isGitRepo(agentId), [agentId]);
92760
93573
  function showStatus(msg, durationMs) {
92761
93574
  if (statusTimerRef.current)
@@ -94763,12 +95576,12 @@ function ModelSelector({
94763
95576
  }
94764
95577
  var import_react76, jsx_dev_runtime54, SOLID_LINE20 = "─", VISIBLE_ITEMS2 = 8, BYOK_PROVIDER_PREFIXES;
94765
95578
  var init_ModelSelector = __esm(async () => {
94766
- init_model();
94767
95579
  init_useTerminalWidth();
94768
95580
  init_colors();
94769
95581
  await __promiseAll([
94770
95582
  init_build2(),
94771
95583
  init_available_models(),
95584
+ init_model(),
94772
95585
  init_Text2()
94773
95586
  ]);
94774
95587
  import_react76 = __toESM(require_react(), 1);
@@ -95362,11 +96175,11 @@ var init_byok_providers = __esm(async () => {
95362
96175
 
95363
96176
  // src/utils/aws-credentials.ts
95364
96177
  import { readFile as readFile10 } from "node:fs/promises";
95365
- import { homedir as homedir19 } from "node:os";
95366
- import { join as join31 } from "node:path";
96178
+ import { homedir as homedir20 } from "node:os";
96179
+ import { join as join32 } from "node:path";
95367
96180
  async function parseAwsCredentials() {
95368
- const credentialsPath = join31(homedir19(), ".aws", "credentials");
95369
- const configPath = join31(homedir19(), ".aws", "config");
96181
+ const credentialsPath = join32(homedir20(), ".aws", "credentials");
96182
+ const configPath = join32(homedir20(), ".aws", "config");
95370
96183
  const profiles = new Map;
95371
96184
  try {
95372
96185
  const content = await readFile10(credentialsPath, "utf-8");
@@ -96474,8 +97287,8 @@ function SkillsDialog({ onClose, agentId }) {
96474
97287
  try {
96475
97288
  const { discoverSkills: discoverSkills3, SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills(), exports_skills));
96476
97289
  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);
97290
+ const { join: join33 } = await import("node:path");
97291
+ const skillsDir = getSkillsDirectory2() || join33(process.cwd(), SKILLS_DIR3);
96479
97292
  const result = await discoverSkills3(skillsDir, agentId, {
96480
97293
  sources: getSkillSources2()
96481
97294
  });
@@ -97120,8 +97933,10 @@ function getSubagentModelDisplay(model) {
97120
97933
  };
97121
97934
  }
97122
97935
  var init_subagentDisplay = __esm(async () => {
97123
- init_model();
97124
- await init_openai_codex_provider();
97936
+ await __promiseAll([
97937
+ init_model(),
97938
+ init_openai_codex_provider()
97939
+ ]);
97125
97940
  });
97126
97941
 
97127
97942
  // src/cli/components/SubagentGroupDisplay.tsx
@@ -101180,12 +101995,12 @@ __export(exports_shellAliases, {
101180
101995
  expandAliases: () => expandAliases,
101181
101996
  clearAliasCache: () => clearAliasCache
101182
101997
  });
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";
101998
+ import { existsSync as existsSync20, readFileSync as readFileSync6 } from "node:fs";
101999
+ import { homedir as homedir21 } from "node:os";
102000
+ import { join as join33 } from "node:path";
101186
102001
  function parseAliasesFromFile(filePath) {
101187
102002
  const aliases = new Map;
101188
- if (!existsSync19(filePath)) {
102003
+ if (!existsSync20(filePath)) {
101189
102004
  return aliases;
101190
102005
  }
101191
102006
  try {
@@ -101251,10 +102066,10 @@ function loadAliases(forceReload = false) {
101251
102066
  if (aliasCache && !forceReload) {
101252
102067
  return aliasCache;
101253
102068
  }
101254
- const home = homedir20();
102069
+ const home = homedir21();
101255
102070
  const allAliases = new Map;
101256
102071
  for (const file of ALIAS_FILES) {
101257
- const filePath = join32(home, file);
102072
+ const filePath = join33(home, file);
101258
102073
  const fileAliases = parseAliasesFromFile(filePath);
101259
102074
  for (const [name, value] of fileAliases) {
101260
102075
  allAliases.set(name, value);
@@ -102590,9 +103405,9 @@ var exports_App = {};
102590
103405
  __export(exports_App, {
102591
103406
  default: () => App2
102592
103407
  });
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";
103408
+ import { existsSync as existsSync21, readFileSync as readFileSync7, renameSync as renameSync2, writeFileSync as writeFileSync10 } from "node:fs";
103409
+ import { homedir as homedir22, tmpdir as tmpdir4 } from "node:os";
103410
+ import { join as join34 } from "node:path";
102596
103411
  function deriveReasoningEffort(modelSettings, llmConfig) {
102597
103412
  if (modelSettings && "provider_type" in modelSettings) {
102598
103413
  if (modelSettings.provider_type === "openai" && "reasoning" in modelSettings && modelSettings.reasoning) {
@@ -102789,7 +103604,21 @@ ${SYSTEM_REMINDER_CLOSE}
102789
103604
  }
102790
103605
  function planFileExists() {
102791
103606
  const planFilePath = permissionMode.getPlanFilePath();
102792
- return !!planFilePath && existsSync20(planFilePath);
103607
+ return !!planFilePath && existsSync21(planFilePath);
103608
+ }
103609
+ function _readPlanFile() {
103610
+ const planFilePath = permissionMode.getPlanFilePath();
103611
+ if (!planFilePath) {
103612
+ return "No plan file path set.";
103613
+ }
103614
+ if (!existsSync21(planFilePath)) {
103615
+ return `Plan file not found at ${planFilePath}`;
103616
+ }
103617
+ try {
103618
+ return readFileSync7(planFilePath, "utf-8");
103619
+ } catch {
103620
+ return `Failed to read plan file at ${planFilePath}`;
103621
+ }
102793
103622
  }
102794
103623
  function getQuestionsFromApproval(approval) {
102795
103624
  const parsed = safeJsonParseOr(approval.toolArgs, {});
@@ -103887,8 +104716,8 @@ function App2({
103887
104716
  if (!planFilePath)
103888
104717
  return;
103889
104718
  try {
103890
- const { readFileSync: readFileSync8, existsSync: existsSync21 } = __require("node:fs");
103891
- if (!existsSync21(planFilePath))
104719
+ const { readFileSync: readFileSync8, existsSync: existsSync22 } = __require("node:fs");
104720
+ if (!existsSync22(planFilePath))
103892
104721
  return;
103893
104722
  const planContent = readFileSync8(planFilePath, "utf-8");
103894
104723
  const previewItem = {
@@ -104051,7 +104880,7 @@ function App2({
104051
104880
  const lastRunCompletion = agent.last_run_completion;
104052
104881
  setAgentLastRunAt(lastRunCompletion ?? null);
104053
104882
  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));
104883
+ const { getModelInfoForLlmConfig: getModelInfoForLlmConfig2 } = await init_model().then(() => exports_model);
104055
104884
  const modelInfo = getModelInfoForLlmConfig2(agentModelHandle || "", agent.llm_config);
104056
104885
  if (modelInfo) {
104057
104886
  setCurrentModelId(modelInfo.id);
@@ -104167,9 +104996,9 @@ Memory may be stale. Try running: git -C ~/.letta/agents/${agentId}/memory pull`
104167
104996
  (async () => {
104168
104997
  try {
104169
104998
  const { watch } = await import("node:fs");
104170
- const { existsSync: existsSync21 } = await import("node:fs");
104999
+ const { existsSync: existsSync22 } = await import("node:fs");
104171
105000
  const memRoot = getMemoryFilesystemRoot(agentId);
104172
- if (!existsSync21(memRoot))
105001
+ if (!existsSync22(memRoot))
104173
105002
  return;
104174
105003
  watcher = watch(memRoot, { recursive: true }, () => {});
104175
105004
  memfsWatcherRef.current = watcher;
@@ -104191,6 +105020,17 @@ Memory may be stale. Try running: git -C ~/.letta/agents/${agentId}/memory pull`
104191
105020
  };
104192
105021
  }, [agentId]);
104193
105022
  const processConversation = import_react96.useCallback(async (initialInput, options) => {
105023
+ const pinnedPermissionMode = uiPermissionModeRef.current;
105024
+ const restorePinnedPermissionMode = () => {
105025
+ if (pinnedPermissionMode === "plan")
105026
+ return;
105027
+ if (permissionMode.getMode() !== pinnedPermissionMode) {
105028
+ permissionMode.setMode(pinnedPermissionMode);
105029
+ }
105030
+ if (uiPermissionModeRef.current !== pinnedPermissionMode) {
105031
+ setUiPermissionMode(pinnedPermissionMode);
105032
+ }
105033
+ };
104194
105034
  buffersRef.current.approvalsPending = false;
104195
105035
  if (buffersRef.current.serverToolCalls.size > 0) {
104196
105036
  let didPromote = false;
@@ -104423,6 +105263,7 @@ ${newState.originalPrompt}`
104423
105263
  refreshDerived();
104424
105264
  if (!cancelled) {
104425
105265
  buffersRef.current.interrupted = false;
105266
+ restorePinnedPermissionMode();
104426
105267
  continue;
104427
105268
  }
104428
105269
  }
@@ -104454,6 +105295,7 @@ ${newState.originalPrompt}`
104454
105295
  if (!cancelled) {
104455
105296
  buffersRef.current.interrupted = false;
104456
105297
  conversationBusyRetriesRef.current = 0;
105298
+ restorePinnedPermissionMode();
104457
105299
  continue;
104458
105300
  }
104459
105301
  }
@@ -104523,7 +105365,7 @@ ${newState.originalPrompt}`
104523
105365
  const agentEnableReasoner = agent.llm_config?.enable_reasoner;
104524
105366
  if (currentModel !== agentModel || currentEndpoint !== agentEndpoint || currentEffort !== agentEffort || currentEnableReasoner !== agentEnableReasoner) {
104525
105367
  setLlmConfig(agent.llm_config);
104526
- const { getModelInfoForLlmConfig: getModelInfoForLlmConfig2 } = await Promise.resolve().then(() => (init_model(), exports_model));
105368
+ const { getModelInfoForLlmConfig: getModelInfoForLlmConfig2 } = await init_model().then(() => exports_model);
104527
105369
  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
105370
  const modelInfo = getModelInfoForLlmConfig2(agentModelHandle || "", agent.llm_config);
104529
105371
  if (modelInfo) {
@@ -105531,7 +106373,7 @@ ${feedback}
105531
106373
  setConversationId3(targetConversationId);
105532
106374
  resetBootstrapReminderState();
105533
106375
  {
105534
- const { getModelDisplayName: getModelDisplayName2 } = await Promise.resolve().then(() => (init_model(), exports_model));
106376
+ const { getModelDisplayName: getModelDisplayName2 } = await init_model().then(() => exports_model);
105535
106377
  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
106378
  const modelLabel = modelHandle && getModelDisplayName2(modelHandle) || modelHandle || "unknown";
105537
106379
  pendingConversationSwitchRef.current = {
@@ -105637,7 +106479,7 @@ ${feedback}
105637
106479
  agentSwitchContext: {
105638
106480
  name: agent.name || agent.id,
105639
106481
  description: agent.description ?? undefined,
105640
- model: agentModelHandle ? (await Promise.resolve().then(() => (init_model(), exports_model))).getModelDisplayName(agentModelHandle) || agentModelHandle : "unknown",
106482
+ model: agentModelHandle ? (await init_model().then(() => exports_model)).getModelDisplayName(agentModelHandle) || agentModelHandle : "unknown",
105641
106483
  blockCount: agent.blocks?.length ?? 0
105642
106484
  }
105643
106485
  };
@@ -106030,6 +106872,26 @@ ${SYSTEM_REMINDER_CLOSE}` : "";
106030
106872
  setActiveOverlay("memory");
106031
106873
  return { submitted: true };
106032
106874
  }
106875
+ if (trimmed === "/palace") {
106876
+ const cmd = commandRunner.start("/palace", "Opening Memory Palace...");
106877
+ if (!settingsManager.isMemfsEnabled(agentId)) {
106878
+ cmd.finish("Memory Palace requires memfs. Run /memfs enable first.", false);
106879
+ return { submitted: true };
106880
+ }
106881
+ const { generateAndOpenMemoryViewer: generateAndOpenMemoryViewer2 } = await init_generate_memory_viewer().then(() => exports_generate_memory_viewer);
106882
+ generateAndOpenMemoryViewer2(agentId, {
106883
+ agentName: agentName ?? undefined
106884
+ }).then((result2) => {
106885
+ if (result2.opened) {
106886
+ cmd.finish("Opened Memory Palace in browser", true);
106887
+ } else {
106888
+ cmd.finish(`Open manually: ${result2.filePath}`, true);
106889
+ }
106890
+ }).catch((err) => {
106891
+ cmd.finish(`Failed to open: ${err instanceof Error ? err.message : String(err)}`, false);
106892
+ });
106893
+ return { submitted: true };
106894
+ }
106033
106895
  if (msg.trim().startsWith("/mcp")) {
106034
106896
  const mcpCtx = {
106035
106897
  buffersRef,
@@ -107079,7 +107941,7 @@ Press Enter to continue, or type anything to cancel.`, false, "running");
107079
107941
  fileContent = await client.agents.exportFile(agentId, exportParams);
107080
107942
  }
107081
107943
  const fileName = exportParams.conversation_id ? `${exportParams.conversation_id}.af` : `${agentId}.af`;
107082
- writeFileSync9(fileName, JSON.stringify(fileContent, null, 2));
107944
+ writeFileSync10(fileName, JSON.stringify(fileContent, null, 2));
107083
107945
  let summary = `AgentFile exported to ${fileName}`;
107084
107946
  if (skills.length > 0) {
107085
107947
  summary += `
@@ -107169,11 +108031,11 @@ Path: ${result2.memoryDir}`, true, msg);
107169
108031
  setCommandRunning(true);
107170
108032
  try {
107171
108033
  const memoryDir = getMemoryFilesystemRoot(agentId);
107172
- if (!existsSync20(memoryDir)) {
108034
+ if (!existsSync21(memoryDir)) {
107173
108035
  updateMemorySyncCommand(cmdId, "No local memory filesystem found to reset.", true, msg);
107174
108036
  return { submitted: true };
107175
108037
  }
107176
- const backupDir = join33(tmpdir4(), `letta-memfs-reset-${agentId}-${Date.now()}`);
108038
+ const backupDir = join34(tmpdir4(), `letta-memfs-reset-${agentId}-${Date.now()}`);
107177
108039
  renameSync2(memoryDir, backupDir);
107178
108040
  ensureMemoryFilesystemDirs(agentId);
107179
108041
  updateMemorySyncCommand(cmdId, `Memory filesystem reset.
@@ -107201,8 +108063,8 @@ Run \`/memfs sync\` to repopulate from API.`, true, msg);
107201
108063
  await removeGitMemoryTag2(agentId);
107202
108064
  let backupInfo = "";
107203
108065
  const memoryDir = getMemoryFilesystemRoot(agentId);
107204
- if (existsSync20(memoryDir)) {
107205
- const backupDir = join33(tmpdir4(), `letta-memfs-disable-${agentId}-${Date.now()}`);
108066
+ if (existsSync21(memoryDir)) {
108067
+ const backupDir = join34(tmpdir4(), `letta-memfs-disable-${agentId}-${Date.now()}`);
107206
108068
  renameSync2(memoryDir, backupDir);
107207
108069
  backupInfo = `
107208
108070
  Local files backed up to ${backupDir}`;
@@ -108436,7 +109298,7 @@ ${SYSTEM_REMINDER_CLOSE}
108436
109298
  };
108437
109299
  let selectedModel = null;
108438
109300
  try {
108439
- const { getReasoningTierOptionsForHandle: getReasoningTierOptionsForHandle2, models: models2 } = await Promise.resolve().then(() => (init_model(), exports_model));
109301
+ const { getReasoningTierOptionsForHandle: getReasoningTierOptionsForHandle2, models: models2 } = await init_model().then(() => exports_model);
108440
109302
  const pickPreferredModelForHandle = (handle) => {
108441
109303
  const candidates = models2.filter((m) => m.handle === handle);
108442
109304
  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 +109863,7 @@ ${guidance}`);
109001
109863
  setAgentState(reasoningCycleLastConfirmedAgentStateRef.current);
109002
109864
  reasoningCycleLastConfirmedAgentStateRef.current = null;
109003
109865
  }
109004
- const { getModelInfo: getModelInfo2 } = await Promise.resolve().then(() => (init_model(), exports_model));
109866
+ const { getModelInfo: getModelInfo2 } = await init_model().then(() => exports_model);
109005
109867
  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
109868
  const modelInfo = modelHandle ? getModelInfo2(modelHandle) : null;
109007
109869
  setCurrentModelId(modelInfo?.id ?? null);
@@ -109023,7 +109885,7 @@ ${guidance}`);
109023
109885
  if (!modelHandle)
109024
109886
  return;
109025
109887
  const currentEffort = deriveReasoningEffort(agentStateRef.current?.model_settings, current) ?? "none";
109026
- const { models: models2 } = await Promise.resolve().then(() => (init_model(), exports_model));
109888
+ const { models: models2 } = await init_model().then(() => exports_model);
109027
109889
  const tiers = models2.filter((m) => m.handle === modelHandle).map((m) => {
109028
109890
  const effort = m.updateArgs?.reasoning_effort;
109029
109891
  return {
@@ -109197,7 +110059,7 @@ ${guidance}`);
109197
110059
  }
109198
110060
  if (!planFileExists()) {
109199
110061
  const planFilePath = permissionMode.getPlanFilePath();
109200
- const plansDir = join33(homedir21(), ".letta", "plans");
110062
+ const plansDir = join34(homedir22(), ".letta", "plans");
109201
110063
  handlePlanKeepPlanning(`You must write your plan to a plan file before exiting plan mode.
109202
110064
  ` + (planFilePath ? `Plan file path: ${planFilePath}
109203
110065
  ` : "") + `Use a write tool to create your plan in ${plansDir}, then use ExitPlanMode to present the plan to the user.`);
@@ -109576,7 +110438,10 @@ Plan file path: ${planFilePath}`;
109576
110438
  approveAlwaysText: currentApprovalContext?.approveAlwaysText,
109577
110439
  allowPersistence: currentApprovalContext?.allowPersistence ?? true,
109578
110440
  defaultScope: currentApprovalContext?.defaultScope === "user" ? "session" : currentApprovalContext?.defaultScope ?? "project",
109579
- showPreview: showApprovalPreview
110441
+ showPreview: showApprovalPreview,
110442
+ planContent: currentApproval.toolName === "ExitPlanMode" ? _readPlanFile() : undefined,
110443
+ planFilePath: currentApproval.toolName === "ExitPlanMode" ? permissionMode.getPlanFilePath() ?? undefined : undefined,
110444
+ agentName: agentName ?? undefined
109580
110445
  }, undefined, false, undefined, this) : ln.kind === "user" ? /* @__PURE__ */ jsx_dev_runtime74.jsxDEV(UserMessage, {
109581
110446
  line: ln,
109582
110447
  prompt: statusLine.prompt
@@ -109628,7 +110493,10 @@ Plan file path: ${planFilePath}`;
109628
110493
  approveAlwaysText: currentApprovalContext?.approveAlwaysText,
109629
110494
  allowPersistence: currentApprovalContext?.allowPersistence ?? true,
109630
110495
  defaultScope: currentApprovalContext?.defaultScope === "user" ? "session" : currentApprovalContext?.defaultScope ?? "project",
109631
- showPreview: showApprovalPreview
110496
+ showPreview: showApprovalPreview,
110497
+ planContent: currentApproval.toolName === "ExitPlanMode" ? _readPlanFile() : undefined,
110498
+ planFilePath: currentApproval.toolName === "ExitPlanMode" ? permissionMode.getPlanFilePath() ?? undefined : undefined,
110499
+ agentName: agentName ?? undefined
109632
110500
  }, undefined, false, undefined, this)
109633
110501
  }, undefined, false, undefined, this),
109634
110502
  /* @__PURE__ */ jsx_dev_runtime74.jsxDEV(SubagentGroupDisplay, {}, undefined, false, undefined, this)
@@ -110301,7 +111169,6 @@ var init_App2 = __esm(async () => {
110301
111169
  init_http_headers();
110302
111170
  init_memory();
110303
111171
  init_memoryFilesystem();
110304
- init_model();
110305
111172
  init_promptAssets();
110306
111173
  init_constants();
110307
111174
  init_mode();
@@ -110323,6 +111190,7 @@ var init_App2 = __esm(async () => {
110323
111190
  init_pasteRegistry();
110324
111191
  init_planName();
110325
111192
  init_queuedMessageParts();
111193
+ init_sessionContext();
110326
111194
  init_statusLineHelp();
110327
111195
  init_statusLinePayload();
110328
111196
  init_statusLineRuntime();
@@ -110338,6 +111206,7 @@ var init_App2 = __esm(async () => {
110338
111206
  init_client2(),
110339
111207
  init_create(),
110340
111208
  init_message(),
111209
+ init_model(),
110341
111210
  init_hooks(),
110342
111211
  init_openai_codex_provider(),
110343
111212
  init_engine(),
@@ -110388,7 +111257,6 @@ var init_App2 = __esm(async () => {
110388
111257
  init_approvalClassification(),
110389
111258
  init_formatArgsDisplay(),
110390
111259
  init_memoryReminder(),
110391
- init_sessionContext(),
110392
111260
  init_statusLineConfig(),
110393
111261
  init_stream(),
110394
111262
  init_subagentAggregation(),
@@ -110452,13 +111320,13 @@ __export(exports_terminalKeybindingInstaller2, {
110452
111320
  });
110453
111321
  import {
110454
111322
  copyFileSync as copyFileSync2,
110455
- existsSync as existsSync21,
110456
- mkdirSync as mkdirSync12,
111323
+ existsSync as existsSync22,
111324
+ mkdirSync as mkdirSync13,
110457
111325
  readFileSync as readFileSync8,
110458
- writeFileSync as writeFileSync10
111326
+ writeFileSync as writeFileSync11
110459
111327
  } 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";
111328
+ import { homedir as homedir23, platform as platform5 } from "node:os";
111329
+ import { dirname as dirname13, join as join35 } from "node:path";
110462
111330
  function detectTerminalType2() {
110463
111331
  if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
110464
111332
  return "cursor";
@@ -110490,16 +111358,16 @@ function getKeybindingsPath2(terminal) {
110490
111358
  }[terminal];
110491
111359
  const os6 = platform5();
110492
111360
  if (os6 === "darwin") {
110493
- return join34(homedir22(), "Library", "Application Support", appName, "User", "keybindings.json");
111361
+ return join35(homedir23(), "Library", "Application Support", appName, "User", "keybindings.json");
110494
111362
  }
110495
111363
  if (os6 === "win32") {
110496
111364
  const appData = process.env.APPDATA;
110497
111365
  if (!appData)
110498
111366
  return null;
110499
- return join34(appData, appName, "User", "keybindings.json");
111367
+ return join35(appData, appName, "User", "keybindings.json");
110500
111368
  }
110501
111369
  if (os6 === "linux") {
110502
- return join34(homedir22(), ".config", appName, "User", "keybindings.json");
111370
+ return join35(homedir23(), ".config", appName, "User", "keybindings.json");
110503
111371
  }
110504
111372
  return null;
110505
111373
  }
@@ -110521,7 +111389,7 @@ function parseKeybindings2(content) {
110521
111389
  }
110522
111390
  }
110523
111391
  function keybindingExists2(keybindingsPath) {
110524
- if (!existsSync21(keybindingsPath))
111392
+ if (!existsSync22(keybindingsPath))
110525
111393
  return false;
110526
111394
  try {
110527
111395
  const content = readFileSync8(keybindingsPath, { encoding: "utf-8" });
@@ -110534,7 +111402,7 @@ function keybindingExists2(keybindingsPath) {
110534
111402
  }
110535
111403
  }
110536
111404
  function createBackup2(keybindingsPath) {
110537
- if (!existsSync21(keybindingsPath))
111405
+ if (!existsSync22(keybindingsPath))
110538
111406
  return null;
110539
111407
  const backupPath = `${keybindingsPath}.letta-backup`;
110540
111408
  try {
@@ -110550,12 +111418,12 @@ function installKeybinding2(keybindingsPath) {
110550
111418
  return { success: true, alreadyExists: true };
110551
111419
  }
110552
111420
  const parentDir = dirname13(keybindingsPath);
110553
- if (!existsSync21(parentDir)) {
110554
- mkdirSync12(parentDir, { recursive: true });
111421
+ if (!existsSync22(parentDir)) {
111422
+ mkdirSync13(parentDir, { recursive: true });
110555
111423
  }
110556
111424
  let keybindings = [];
110557
111425
  let backupPath = null;
110558
- if (existsSync21(keybindingsPath)) {
111426
+ if (existsSync22(keybindingsPath)) {
110559
111427
  backupPath = createBackup2(keybindingsPath);
110560
111428
  const content = readFileSync8(keybindingsPath, { encoding: "utf-8" });
110561
111429
  const parsed = parseKeybindings2(content);
@@ -110570,7 +111438,7 @@ function installKeybinding2(keybindingsPath) {
110570
111438
  keybindings.push(SHIFT_ENTER_KEYBINDING2);
110571
111439
  const newContent = `${JSON.stringify(keybindings, null, 2)}
110572
111440
  `;
110573
- writeFileSync10(keybindingsPath, newContent, { encoding: "utf-8" });
111441
+ writeFileSync11(keybindingsPath, newContent, { encoding: "utf-8" });
110574
111442
  return {
110575
111443
  success: true,
110576
111444
  backupPath: backupPath ?? undefined
@@ -110585,7 +111453,7 @@ function installKeybinding2(keybindingsPath) {
110585
111453
  }
110586
111454
  function removeKeybinding2(keybindingsPath) {
110587
111455
  try {
110588
- if (!existsSync21(keybindingsPath)) {
111456
+ if (!existsSync22(keybindingsPath)) {
110589
111457
  return { success: true };
110590
111458
  }
110591
111459
  const content = readFileSync8(keybindingsPath, { encoding: "utf-8" });
@@ -110599,7 +111467,7 @@ function removeKeybinding2(keybindingsPath) {
110599
111467
  const filtered = keybindings.filter((kb) => !(kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus")));
110600
111468
  const newContent = `${JSON.stringify(filtered, null, 2)}
110601
111469
  `;
110602
- writeFileSync10(keybindingsPath, newContent, { encoding: "utf-8" });
111470
+ writeFileSync11(keybindingsPath, newContent, { encoding: "utf-8" });
110603
111471
  return { success: true };
110604
111472
  } catch (error) {
110605
111473
  const message = error instanceof Error ? error.message : String(error);
@@ -110652,17 +111520,17 @@ function getWezTermConfigPath2() {
110652
111520
  }
110653
111521
  const xdgConfig = process.env.XDG_CONFIG_HOME;
110654
111522
  if (xdgConfig) {
110655
- const xdgPath = join34(xdgConfig, "wezterm", "wezterm.lua");
110656
- if (existsSync21(xdgPath))
111523
+ const xdgPath = join35(xdgConfig, "wezterm", "wezterm.lua");
111524
+ if (existsSync22(xdgPath))
110657
111525
  return xdgPath;
110658
111526
  }
110659
- const configPath = join34(homedir22(), ".config", "wezterm", "wezterm.lua");
110660
- if (existsSync21(configPath))
111527
+ const configPath = join35(homedir23(), ".config", "wezterm", "wezterm.lua");
111528
+ if (existsSync22(configPath))
110661
111529
  return configPath;
110662
- return join34(homedir22(), ".wezterm.lua");
111530
+ return join35(homedir23(), ".wezterm.lua");
110663
111531
  }
110664
111532
  function wezTermDeleteFixExists2(configPath) {
110665
- if (!existsSync21(configPath))
111533
+ if (!existsSync22(configPath))
110666
111534
  return false;
110667
111535
  try {
110668
111536
  const content = readFileSync8(configPath, { encoding: "utf-8" });
@@ -110679,7 +111547,7 @@ function installWezTermDeleteFix2() {
110679
111547
  }
110680
111548
  let content = "";
110681
111549
  let backupPath = null;
110682
- if (existsSync21(configPath)) {
111550
+ if (existsSync22(configPath)) {
110683
111551
  backupPath = `${configPath}.letta-backup`;
110684
111552
  copyFileSync2(configPath, backupPath);
110685
111553
  content = readFileSync8(configPath, { encoding: "utf-8" });
@@ -110709,10 +111577,10 @@ ${WEZTERM_DELETE_FIX2}
110709
111577
  `;
110710
111578
  }
110711
111579
  const parentDir = dirname13(configPath);
110712
- if (!existsSync21(parentDir)) {
110713
- mkdirSync12(parentDir, { recursive: true });
111580
+ if (!existsSync22(parentDir)) {
111581
+ mkdirSync13(parentDir, { recursive: true });
110714
111582
  }
110715
- writeFileSync10(configPath, content, { encoding: "utf-8" });
111583
+ writeFileSync11(configPath, content, { encoding: "utf-8" });
110716
111584
  return {
110717
111585
  success: true,
110718
111586
  backupPath: backupPath ?? undefined
@@ -110757,10 +111625,10 @@ __export(exports_settings2, {
110757
111625
  loadProjectSettings: () => loadProjectSettings2,
110758
111626
  getSetting: () => getSetting2
110759
111627
  });
110760
- import { homedir as homedir23 } from "node:os";
110761
- import { join as join35 } from "node:path";
111628
+ import { homedir as homedir24 } from "node:os";
111629
+ import { join as join36 } from "node:path";
110762
111630
  function getSettingsPath2() {
110763
- return join35(homedir23(), ".letta", "settings.json");
111631
+ return join36(homedir24(), ".letta", "settings.json");
110764
111632
  }
110765
111633
  async function loadSettings2() {
110766
111634
  const settingsPath = getSettingsPath2();
@@ -110797,7 +111665,7 @@ async function getSetting2(key) {
110797
111665
  return settings[key];
110798
111666
  }
110799
111667
  function getProjectSettingsPath2() {
110800
- return join35(process.cwd(), ".letta", "settings.local.json");
111668
+ return join36(process.cwd(), ".letta", "settings.local.json");
110801
111669
  }
110802
111670
  async function loadProjectSettings2() {
110803
111671
  const settingsPath = getProjectSettingsPath2();
@@ -110815,7 +111683,7 @@ async function loadProjectSettings2() {
110815
111683
  }
110816
111684
  async function saveProjectSettings2(settings) {
110817
111685
  const settingsPath = getProjectSettingsPath2();
110818
- const dirPath = join35(process.cwd(), ".letta");
111686
+ const dirPath = join36(process.cwd(), ".letta");
110819
111687
  try {
110820
111688
  if (!exists(dirPath)) {
110821
111689
  await mkdir(dirPath, { recursive: true });
@@ -110902,6 +111770,7 @@ __export(exports_model2, {
110902
111770
  getReasoningTierOptionsForHandle: () => getReasoningTierOptionsForHandle2,
110903
111771
  getModelUpdateArgs: () => getModelUpdateArgs2,
110904
111772
  getModelShortName: () => getModelShortName2,
111773
+ getModelPresetUpdateForAgent: () => getModelPresetUpdateForAgent2,
110905
111774
  getModelInfoForLlmConfig: () => getModelInfoForLlmConfig2,
110906
111775
  getModelInfo: () => getModelInfo2,
110907
111776
  getModelDisplayName: () => getModelDisplayName2,
@@ -110997,6 +111866,27 @@ function getModelUpdateArgs2(modelIdentifier) {
110997
111866
  const modelInfo = getModelInfo2(modelIdentifier);
110998
111867
  return modelInfo?.updateArgs;
110999
111868
  }
111869
+ function getModelPresetUpdateForAgent2(agent) {
111870
+ const directHandle = typeof agent.model === "string" && agent.model.length > 0 ? agent.model : null;
111871
+ const endpointType = agent.llm_config?.model_endpoint_type;
111872
+ const llmModel = agent.llm_config?.model;
111873
+ 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;
111874
+ const modelHandle = directHandle ?? llmDerivedHandle;
111875
+ if (!modelHandle)
111876
+ return null;
111877
+ const modelInfo = getModelInfoForLlmConfig2(modelHandle, {
111878
+ reasoning_effort: agent.llm_config?.reasoning_effort ?? null,
111879
+ enable_reasoner: agent.llm_config?.enable_reasoner ?? null
111880
+ });
111881
+ const updateArgs = modelInfo?.updateArgs ?? getModelUpdateArgs2(modelHandle);
111882
+ if (!updateArgs || Object.keys(updateArgs).length === 0) {
111883
+ return null;
111884
+ }
111885
+ return {
111886
+ modelHandle: modelInfo?.handle ?? modelHandle,
111887
+ updateArgs
111888
+ };
111889
+ }
111000
111890
  function findModelByHandle2(handle) {
111001
111891
  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
111892
  const exactMatch = models2.find((m) => m.handle === handle);
@@ -111044,8 +111934,9 @@ function resolveModelByLlmConfig2(llmConfigModel) {
111044
111934
  return null;
111045
111935
  }
111046
111936
  var models2, REASONING_EFFORT_ORDER2;
111047
- var init_model2 = __esm(() => {
111937
+ var init_model2 = __esm(async () => {
111048
111938
  init_models2();
111939
+ await init_openai_codex_provider();
111049
111940
  models2 = models_default;
111050
111941
  REASONING_EFFORT_ORDER2 = [
111051
111942
  "none",
@@ -111387,12 +112278,12 @@ var init_create3 = __esm(async () => {
111387
112278
  init_http_headers();
111388
112279
  init_memory();
111389
112280
  init_memoryPrompt();
111390
- init_model();
111391
112281
  init_promptAssets();
111392
112282
  await __promiseAll([
111393
112283
  init_settings_manager(),
111394
112284
  init_available_models(),
111395
112285
  init_client2(),
112286
+ init_model(),
111396
112287
  init_modify()
111397
112288
  ]);
111398
112289
  });
@@ -111518,7 +112409,7 @@ function parseRegistryHandle2(handle) {
111518
112409
  }
111519
112410
  async function importAgentFromRegistry2(options) {
111520
112411
  const { tmpdir: tmpdir5 } = await import("node:os");
111521
- const { join: join36 } = await import("node:path");
112412
+ const { join: join37 } = await import("node:path");
111522
112413
  const { writeFile: writeFile5, unlink } = await import("node:fs/promises");
111523
112414
  const { author, name } = parseRegistryHandle2(options.handle);
111524
112415
  const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER2}/${AGENT_REGISTRY_REPO2}/refs/heads/${AGENT_REGISTRY_BRANCH2}/agents/@${author}/${name}/${name}.af`;
@@ -111530,7 +112421,7 @@ async function importAgentFromRegistry2(options) {
111530
112421
  throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
111531
112422
  }
111532
112423
  const afContent = await response.text();
111533
- const tempPath = join36(tmpdir5(), `letta-import-${author}-${name}-${Date.now()}.af`);
112424
+ const tempPath = join37(tmpdir5(), `letta-import-${author}-${name}-${Date.now()}.af`);
111534
112425
  await writeFile5(tempPath, afContent, "utf-8");
111535
112426
  try {
111536
112427
  const result = await importAgentFromFile2({
@@ -111548,9 +112439,9 @@ async function importAgentFromRegistry2(options) {
111548
112439
  }
111549
112440
  var AGENT_REGISTRY_OWNER2 = "letta-ai", AGENT_REGISTRY_REPO2 = "agent-file", AGENT_REGISTRY_BRANCH2 = "main";
111550
112441
  var init_import2 = __esm(async () => {
111551
- init_model();
111552
112442
  await __promiseAll([
111553
112443
  init_client2(),
112444
+ init_model(),
111554
112445
  init_modify()
111555
112446
  ]);
111556
112447
  });
@@ -111778,23 +112669,23 @@ __export(exports_memoryFilesystem2, {
111778
112669
  MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR2,
111779
112670
  MEMORY_FS_AGENTS_DIR: () => MEMORY_FS_AGENTS_DIR2
111780
112671
  });
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);
112672
+ import { existsSync as existsSync23, mkdirSync as mkdirSync14 } from "node:fs";
112673
+ import { homedir as homedir25 } from "node:os";
112674
+ import { join as join37 } from "node:path";
112675
+ function getMemoryFilesystemRoot2(agentId, homeDir = homedir25()) {
112676
+ return join37(homeDir, MEMORY_FS_ROOT2, MEMORY_FS_AGENTS_DIR2, agentId, MEMORY_FS_MEMORY_DIR2);
111786
112677
  }
111787
- function getMemorySystemDir2(agentId, homeDir = homedir24()) {
111788
- return join36(getMemoryFilesystemRoot2(agentId, homeDir), MEMORY_SYSTEM_DIR2);
112678
+ function getMemorySystemDir2(agentId, homeDir = homedir25()) {
112679
+ return join37(getMemoryFilesystemRoot2(agentId, homeDir), MEMORY_SYSTEM_DIR2);
111789
112680
  }
111790
- function ensureMemoryFilesystemDirs2(agentId, homeDir = homedir24()) {
112681
+ function ensureMemoryFilesystemDirs2(agentId, homeDir = homedir25()) {
111791
112682
  const root = getMemoryFilesystemRoot2(agentId, homeDir);
111792
112683
  const systemDir = getMemorySystemDir2(agentId, homeDir);
111793
- if (!existsSync22(root)) {
111794
- mkdirSync13(root, { recursive: true });
112684
+ if (!existsSync23(root)) {
112685
+ mkdirSync14(root, { recursive: true });
111795
112686
  }
111796
- if (!existsSync22(systemDir)) {
111797
- mkdirSync13(systemDir, { recursive: true });
112687
+ if (!existsSync23(systemDir)) {
112688
+ mkdirSync14(systemDir, { recursive: true });
111798
112689
  }
111799
112690
  }
111800
112691
  function labelFromRelativePath2(relativePath) {
@@ -112024,7 +112915,18 @@ class InternalServerError extends APIError {
112024
112915
  // src/agent/check-approval.ts
112025
112916
  init_error();
112026
112917
  init_debug();
112027
- var MESSAGE_HISTORY_LIMIT = 15;
112918
+ var BACKFILL_PRIMARY_MESSAGE_LIMIT = 12;
112919
+ var BACKFILL_MAX_RENDERABLE_MESSAGES = 80;
112920
+ var BACKFILL_ANCHOR_MESSAGE_LIMIT = 6;
112921
+ var BACKFILL_PAGE_LIMIT = 200;
112922
+ var BACKFILL_MAX_PAGES = 25;
112923
+ var BACKFILL_MIN_ASSISTANT = 1;
112924
+ function isPrimaryMessageType(messageType) {
112925
+ return messageType === "user_message" || messageType === "assistant_message" || messageType === "event_message" || messageType === "summary_message";
112926
+ }
112927
+ function isAnchorMessageType(messageType) {
112928
+ return messageType === "user_message" || messageType === "assistant_message";
112929
+ }
112028
112930
  function isBackfillEnabled() {
112029
112931
  const val = process.env.LETTA_BACKFILL;
112030
112932
  return val !== "0" && val !== "false";
@@ -112043,9 +112945,62 @@ function extractApprovals(messageToCheck) {
112043
112945
  }
112044
112946
  return { pendingApproval, pendingApprovals };
112045
112947
  }
112046
- function prepareMessageHistory(messages) {
112047
- const historyCount = Math.min(MESSAGE_HISTORY_LIMIT, messages.length);
112048
- let messageHistory = messages.slice(-historyCount);
112948
+ function prepareMessageHistory(messages, opts) {
112949
+ const isRenderable = (msg) => {
112950
+ const t = msg.message_type;
112951
+ 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") {
112952
+ return true;
112953
+ }
112954
+ const ts = t;
112955
+ return ts === "event_message" || ts === "summary_message";
112956
+ };
112957
+ const renderable = messages.filter(isRenderable);
112958
+ if (opts?.primaryOnly) {
112959
+ const convo = renderable.filter((m) => isPrimaryMessageType(m.message_type));
112960
+ let trimmed = convo.slice(-BACKFILL_PRIMARY_MESSAGE_LIMIT);
112961
+ const hasAssistant = trimmed.some((m) => m.message_type === "assistant_message");
112962
+ if (!hasAssistant) {
112963
+ const lastAssistantIndex = convo.map((m) => m.message_type).lastIndexOf("assistant_message");
112964
+ if (lastAssistantIndex >= 0) {
112965
+ const lastAssistant = convo[lastAssistantIndex];
112966
+ if (lastAssistant) {
112967
+ const tailLimit = Math.max(BACKFILL_PRIMARY_MESSAGE_LIMIT - 1, 0);
112968
+ const newestTail = tailLimit > 0 ? convo.slice(-tailLimit) : [];
112969
+ trimmed = [lastAssistant, ...newestTail];
112970
+ }
112971
+ }
112972
+ }
112973
+ if (trimmed.length > 0)
112974
+ return trimmed;
112975
+ const reasoning = renderable.filter((m) => m.message_type === "reasoning_message");
112976
+ if (reasoning.length > 0) {
112977
+ return reasoning.slice(-BACKFILL_PRIMARY_MESSAGE_LIMIT);
112978
+ }
112979
+ return [];
112980
+ }
112981
+ const isPrimary = (msg) => {
112982
+ const t = msg.message_type;
112983
+ return t === "user_message" || t === "assistant_message" || t === "reasoning_message" || t === "event_message" || t === "summary_message";
112984
+ };
112985
+ let primaryCount = 0;
112986
+ let startIndex = Math.max(0, renderable.length - 1);
112987
+ for (let i = renderable.length - 1;i >= 0; i -= 1) {
112988
+ const msg = renderable[i];
112989
+ if (!msg)
112990
+ continue;
112991
+ if (isPrimary(msg)) {
112992
+ primaryCount += 1;
112993
+ if (primaryCount >= BACKFILL_PRIMARY_MESSAGE_LIMIT) {
112994
+ startIndex = i;
112995
+ break;
112996
+ }
112997
+ }
112998
+ startIndex = i;
112999
+ }
113000
+ let messageHistory = renderable.slice(startIndex);
113001
+ if (messageHistory.length > BACKFILL_MAX_RENDERABLE_MESSAGES) {
113002
+ messageHistory = messageHistory.slice(-BACKFILL_MAX_RENDERABLE_MESSAGES);
113003
+ }
112049
113004
  if (messageHistory[0]?.message_type === "tool_return_message") {
112050
113005
  messageHistory = messageHistory.slice(1);
112051
113006
  }
@@ -112053,11 +113008,57 @@ function prepareMessageHistory(messages) {
112053
113008
  }
112054
113009
  function sortChronological(messages) {
112055
113010
  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();
113011
+ const ta = a.date ? new Date(a.date).getTime() : 0;
113012
+ const tb = b.date ? new Date(b.date).getTime() : 0;
113013
+ if (!Number.isFinite(ta) && !Number.isFinite(tb))
113014
+ return 0;
113015
+ if (!Number.isFinite(ta))
113016
+ return -1;
113017
+ if (!Number.isFinite(tb))
113018
+ return 1;
113019
+ return ta - tb;
112059
113020
  });
112060
113021
  }
113022
+ async function fetchConversationBackfillMessages(client, conversationId) {
113023
+ const collected = [];
113024
+ const seen = new Set;
113025
+ let cursorBefore = null;
113026
+ let assistantCount = 0;
113027
+ let anchorCount = 0;
113028
+ for (let pageIndex = 0;pageIndex < BACKFILL_MAX_PAGES; pageIndex += 1) {
113029
+ const page = await client.conversations.messages.list(conversationId, {
113030
+ limit: BACKFILL_PAGE_LIMIT,
113031
+ order: "desc",
113032
+ ...cursorBefore ? { before: cursorBefore } : {}
113033
+ });
113034
+ const items = page.getPaginatedItems();
113035
+ if (items.length === 0)
113036
+ break;
113037
+ cursorBefore = items[items.length - 1]?.id ?? null;
113038
+ for (const m of items) {
113039
+ if (!m?.id)
113040
+ continue;
113041
+ const key = "otid" in m && m.otid ? `otid:${String(m.otid)}` : `id:${m.id}:${m.message_type ?? ""}`;
113042
+ if (seen.has(key))
113043
+ continue;
113044
+ seen.add(key);
113045
+ collected.push(m);
113046
+ if (m.message_type === "assistant_message")
113047
+ assistantCount += 1;
113048
+ if (isAnchorMessageType(m.message_type))
113049
+ anchorCount += 1;
113050
+ }
113051
+ if (assistantCount >= BACKFILL_MIN_ASSISTANT && anchorCount >= BACKFILL_ANCHOR_MESSAGE_LIMIT) {
113052
+ break;
113053
+ }
113054
+ if (items.length < BACKFILL_PAGE_LIMIT)
113055
+ break;
113056
+ }
113057
+ if (assistantCount < BACKFILL_MIN_ASSISTANT) {
113058
+ debugWarn("check-approval", `Backfill scan found 0 assistant messages in last ${collected.length} messages (tool-heavy conversation?)`);
113059
+ }
113060
+ return sortChronological(collected);
113061
+ }
112061
113062
  async function getResumeData(client, agent, conversationId) {
112062
113063
  try {
112063
113064
  let inContextMessageIds;
@@ -112073,14 +113074,13 @@ async function getResumeData(client, agent, conversationId) {
112073
113074
  debugWarn("check-approval", "No in-context messages - no pending approvals");
112074
113075
  if (isBackfillEnabled()) {
112075
113076
  try {
112076
- const backfill = await client.conversations.messages.list(conversationId, {
112077
- limit: MESSAGE_HISTORY_LIMIT,
112078
- order: "desc"
112079
- });
113077
+ const backfill = await fetchConversationBackfillMessages(client, conversationId);
112080
113078
  return {
112081
113079
  pendingApproval: null,
112082
113080
  pendingApprovals: [],
112083
- messageHistory: sortChronological(backfill.getPaginatedItems())
113081
+ messageHistory: prepareMessageHistory(backfill, {
113082
+ primaryOnly: true
113083
+ })
112084
113084
  };
112085
113085
  } catch (backfillError) {
112086
113086
  debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
@@ -112099,11 +113099,7 @@ async function getResumeData(client, agent, conversationId) {
112099
113099
  const retrievedMessages = await client.messages.retrieve(lastInContextId);
112100
113100
  if (isBackfillEnabled()) {
112101
113101
  try {
112102
- const backfillPage = await client.conversations.messages.list(conversationId, {
112103
- limit: MESSAGE_HISTORY_LIMIT,
112104
- order: "desc"
112105
- });
112106
- messages = sortChronological(backfillPage.getPaginatedItems());
113102
+ messages = await fetchConversationBackfillMessages(client, conversationId);
112107
113103
  } catch (backfillError) {
112108
113104
  debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
112109
113105
  }
@@ -112116,7 +113112,9 @@ async function getResumeData(client, agent, conversationId) {
112116
113112
  return {
112117
113113
  pendingApproval,
112118
113114
  pendingApprovals,
112119
- messageHistory: prepareMessageHistory(messages)
113115
+ messageHistory: prepareMessageHistory(messages, {
113116
+ primaryOnly: true
113117
+ })
112120
113118
  };
112121
113119
  }
112122
113120
  } else {
@@ -112125,7 +113123,7 @@ async function getResumeData(client, agent, conversationId) {
112125
113123
  return {
112126
113124
  pendingApproval: null,
112127
113125
  pendingApprovals: [],
112128
- messageHistory: prepareMessageHistory(messages)
113126
+ messageHistory: prepareMessageHistory(messages, { primaryOnly: true })
112129
113127
  };
112130
113128
  } else {
112131
113129
  inContextMessageIds = agent.message_ids;
@@ -112145,13 +113143,13 @@ async function getResumeData(client, agent, conversationId) {
112145
113143
  if (isBackfillEnabled()) {
112146
113144
  try {
112147
113145
  const messagesPage = await client.agents.messages.list(agent.id, {
112148
- limit: MESSAGE_HISTORY_LIMIT,
113146
+ limit: BACKFILL_PAGE_LIMIT,
112149
113147
  order: "desc",
112150
113148
  conversation_id: "default"
112151
113149
  });
112152
113150
  messages = sortChronological(messagesPage.items);
112153
113151
  if (process.env.DEBUG) {
112154
- console.log(`[DEBUG] agents.messages.list(conversation_id=default) returned ${messagesPage.items.length} messages`);
113152
+ console.log(`[DEBUG] agents.messages.list(conversation_id=default) returned ${messages.length} messages`);
112155
113153
  }
112156
113154
  } catch (backfillError) {
112157
113155
  debugWarn("check-approval", `Failed to load message history: ${backfillError instanceof Error ? backfillError.message : String(backfillError)}`);
@@ -112165,7 +113163,9 @@ async function getResumeData(client, agent, conversationId) {
112165
113163
  return {
112166
113164
  pendingApproval,
112167
113165
  pendingApprovals,
112168
- messageHistory: prepareMessageHistory(messages)
113166
+ messageHistory: prepareMessageHistory(messages, {
113167
+ primaryOnly: true
113168
+ })
112169
113169
  };
112170
113170
  }
112171
113171
  } else {
@@ -112174,7 +113174,7 @@ async function getResumeData(client, agent, conversationId) {
112174
113174
  return {
112175
113175
  pendingApproval: null,
112176
113176
  pendingApprovals: [],
112177
- messageHistory: prepareMessageHistory(messages)
113177
+ messageHistory: prepareMessageHistory(messages, { primaryOnly: true })
112178
113178
  };
112179
113179
  }
112180
113180
  } catch (error) {
@@ -114198,8 +115198,8 @@ async function listBackups(agentId) {
114198
115198
  const path19 = join16(agentRoot, entry.name);
114199
115199
  let createdAt = null;
114200
115200
  try {
114201
- const stat2 = statSync2(path19);
114202
- createdAt = stat2.mtime.toISOString();
115201
+ const stat3 = statSync2(path19);
115202
+ createdAt = stat3.mtime.toISOString();
114203
115203
  } catch {
114204
115204
  createdAt = null;
114205
115205
  }
@@ -114319,8 +115319,8 @@ async function runMemfsSubcommand(argv) {
114319
115319
  console.error(`Backup not found: ${backupPath}`);
114320
115320
  return 1;
114321
115321
  }
114322
- const stat2 = statSync2(backupPath);
114323
- if (!stat2.isDirectory()) {
115322
+ const stat3 = statSync2(backupPath);
115323
+ if (!stat3.isDirectory()) {
114324
115324
  console.error(`Backup path is not a directory: ${backupPath}`);
114325
115325
  return 1;
114326
115326
  }
@@ -114342,8 +115342,8 @@ async function runMemfsSubcommand(argv) {
114342
115342
  return 1;
114343
115343
  }
114344
115344
  if (existsSync9(out)) {
114345
- const stat2 = statSync2(out);
114346
- if (stat2.isDirectory()) {
115345
+ const stat3 = statSync2(out);
115346
+ if (stat3.isDirectory()) {
114347
115347
  const contents = await readdir5(out);
114348
115348
  if (contents.length > 0) {
114349
115349
  console.error(`Export directory not empty: ${out}`);
@@ -114779,6 +115779,7 @@ var permissionMode2 = new PermissionModeManager2;
114779
115779
  init_debug();
114780
115780
  init_fs();
114781
115781
  await init_secrets();
115782
+ import { randomUUID as randomUUID3 } from "node:crypto";
114782
115783
  import { homedir as homedir14 } from "node:os";
114783
115784
  import { join as join18 } from "node:path";
114784
115785
  var DEFAULT_SETTINGS2 = {
@@ -114984,7 +115985,7 @@ class SettingsManager2 {
114984
115985
  const settings = this.getSettings();
114985
115986
  let deviceId = settings.deviceId;
114986
115987
  if (!deviceId) {
114987
- deviceId = crypto.randomUUID();
115988
+ deviceId = randomUUID3();
114988
115989
  this.updateSettings({ deviceId });
114989
115990
  }
114990
115991
  return deviceId;
@@ -115874,12 +116875,12 @@ class TelemetryManager2 {
115874
116875
  var telemetry2 = new TelemetryManager2;
115875
116876
 
115876
116877
  // src/tools/manager.ts
115877
- init_model();
115878
116878
  init_subagents();
115879
116879
  init_constants();
115880
116880
  init_debug();
115881
116881
  await __promiseAll([
115882
116882
  init_approval_execution(),
116883
+ init_model(),
115883
116884
  init_hooks(),
115884
116885
  init_openai_codex_provider(),
115885
116886
  init_telemetry(),
@@ -116242,12 +117243,12 @@ EXAMPLES
116242
117243
  console.log(usage);
116243
117244
  }
116244
117245
  async function printInfo() {
116245
- const { join: join37 } = await import("path");
117246
+ const { join: join38 } = await import("path");
116246
117247
  const { getVersion: getVersion3 } = await Promise.resolve().then(() => (init_version2(), exports_version));
116247
117248
  const { SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills2(), exports_skills2));
116248
117249
  const { exists: exists3 } = await Promise.resolve().then(() => (init_fs2(), exports_fs));
116249
117250
  const cwd2 = process.cwd();
116250
- const skillsDir = join37(cwd2, SKILLS_DIR3);
117251
+ const skillsDir = join38(cwd2, SKILLS_DIR3);
116251
117252
  const skillsExist = exists3(skillsDir);
116252
117253
  await settingsManager2.loadLocalProjectSettings(cwd2);
116253
117254
  const localPinned = settingsManager2.getLocalPinnedAgents(cwd2);
@@ -116691,9 +117692,9 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
116691
117692
  }
116692
117693
  } else {
116693
117694
  const { resolve: resolve26 } = await import("path");
116694
- const { existsSync: existsSync23 } = await import("fs");
117695
+ const { existsSync: existsSync24 } = await import("fs");
116695
117696
  const resolvedPath = resolve26(fromAfFile);
116696
- if (!existsSync23(resolvedPath)) {
117697
+ if (!existsSync24(resolvedPath)) {
116697
117698
  console.error(`Error: AgentFile not found: ${resolvedPath}`);
116698
117699
  process.exit(1);
116699
117700
  }
@@ -116940,7 +117941,7 @@ Error: ${message}`);
116940
117941
  if (isSelfHosted) {
116941
117942
  setSelfHostedBaseUrl(baseURL2);
116942
117943
  try {
116943
- const { getDefaultModel: getDefaultModel3 } = await Promise.resolve().then(() => (init_model2(), exports_model2));
117944
+ const { getDefaultModel: getDefaultModel3 } = await init_model2().then(() => exports_model2);
116944
117945
  const defaultModel = getDefaultModel3();
116945
117946
  setSelfHostedDefaultModel(defaultModel);
116946
117947
  const modelsList = await client.models.list();
@@ -117165,7 +118166,7 @@ Error: ${message}`);
117165
118166
  await loadTools2(modelForTools);
117166
118167
  setLoadingState("initializing");
117167
118168
  const { createAgent: createAgent3 } = await init_create3().then(() => exports_create);
117168
- const { getModelUpdateArgs: getModelUpdateArgs3 } = await Promise.resolve().then(() => (init_model2(), exports_model2));
118169
+ const { getModelUpdateArgs: getModelUpdateArgs3 } = await init_model2().then(() => exports_model2);
117169
118170
  let agent = null;
117170
118171
  if (fromAfFile2) {
117171
118172
  setLoadingState("importing");
@@ -117226,7 +118227,7 @@ Error: ${message}`);
117226
118227
  }
117227
118228
  let effectiveModel = selectedServerModel || model;
117228
118229
  if (!effectiveModel && !selfHostedBaseUrl) {
117229
- const { getDefaultModelForTier: getDefaultModelForTier3 } = await Promise.resolve().then(() => (init_model2(), exports_model2));
118230
+ const { getDefaultModelForTier: getDefaultModelForTier3 } = await init_model2().then(() => exports_model2);
117230
118231
  let billingTier = null;
117231
118232
  try {
117232
118233
  const baseURL2 = process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL2;
@@ -117299,18 +118300,34 @@ Error: ${message}`);
117299
118300
  const isReusingExistingAgent = !shouldCreateNew && !fromAfFile2 && agent && agent.id;
117300
118301
  const resuming = !!(continueSession || agentIdArg || isResumingProject || isReusingExistingAgent);
117301
118302
  setIsResumingSession(resuming);
117302
- if (resuming && (model || systemPromptPreset2)) {
118303
+ if (resuming) {
118304
+ const { updateAgentLLMConfig: updateAgentLLMConfig3 } = await init_modify2().then(() => exports_modify2);
117303
118305
  if (model) {
117304
- const { resolveModel: resolveModel3, getModelUpdateArgs: getModelUpdateArgs4 } = await Promise.resolve().then(() => (init_model2(), exports_model2));
118306
+ const { resolveModel: resolveModel3, getModelUpdateArgs: getModelUpdateArgs4 } = await init_model2().then(() => exports_model2);
117305
118307
  const modelHandle = resolveModel3(model);
117306
118308
  if (!modelHandle) {
117307
118309
  console.error(`Error: Invalid model "${model}"`);
117308
118310
  process.exit(1);
117309
118311
  }
117310
- const { updateAgentLLMConfig: updateAgentLLMConfig3 } = await init_modify2().then(() => exports_modify2);
117311
118312
  const updateArgs = getModelUpdateArgs4(model);
117312
118313
  await updateAgentLLMConfig3(agent.id, modelHandle, updateArgs);
117313
118314
  agent = await client.agents.retrieve(agent.id);
118315
+ } else {
118316
+ const { getModelPresetUpdateForAgent: getModelPresetUpdateForAgent3 } = await init_model2().then(() => exports_model2);
118317
+ const presetRefresh = getModelPresetUpdateForAgent3(agent);
118318
+ if (presetRefresh) {
118319
+ const resumeRefreshUpdateArgs = {};
118320
+ if (typeof presetRefresh.updateArgs.max_output_tokens === "number") {
118321
+ resumeRefreshUpdateArgs.max_output_tokens = presetRefresh.updateArgs.max_output_tokens;
118322
+ }
118323
+ if (typeof presetRefresh.updateArgs.parallel_tool_calls === "boolean") {
118324
+ resumeRefreshUpdateArgs.parallel_tool_calls = presetRefresh.updateArgs.parallel_tool_calls;
118325
+ }
118326
+ if (Object.keys(resumeRefreshUpdateArgs).length > 0) {
118327
+ await updateAgentLLMConfig3(agent.id, presetRefresh.modelHandle, resumeRefreshUpdateArgs);
118328
+ agent = await client.agents.retrieve(agent.id);
118329
+ }
118330
+ }
117314
118331
  }
117315
118332
  if (systemPromptPreset2) {
117316
118333
  const { updateAgentSystemPrompt: updateAgentSystemPrompt3 } = await init_modify2().then(() => exports_modify2);
@@ -117557,4 +118574,4 @@ Error during initialization: ${message}`);
117557
118574
  }
117558
118575
  main();
117559
118576
 
117560
- //# debugId=B0F648D57141B93564756E2164756E21
118577
+ //# debugId=1AECAEFBF4648C7A64756E2164756E21