github-issue-tower-defence-management 1.73.2 → 1.74.0
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/CHANGELOG.md +14 -0
- package/README.md +3 -0
- package/bin/adapter/entry-points/cli/index.js +3 -0
- package/bin/adapter/entry-points/cli/index.js.map +1 -1
- package/bin/adapter/entry-points/cli/projectConfig.js +6 -0
- package/bin/adapter/entry-points/cli/projectConfig.js.map +1 -1
- package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +8 -2
- package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
- package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js +8 -8
- package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js.map +1 -1
- package/bin/adapter/repositories/issue/GraphqlProjectItemRepository.js +27 -7
- package/bin/adapter/repositories/issue/GraphqlProjectItemRepository.js.map +1 -1
- package/bin/domain/usecases/HandleScheduledEventUseCase.js +1 -0
- package/bin/domain/usecases/HandleScheduledEventUseCase.js.map +1 -1
- package/bin/domain/usecases/SetDependedIssueUrlForOpenTaskPRsUseCase.js +6 -1
- package/bin/domain/usecases/SetDependedIssueUrlForOpenTaskPRsUseCase.js.map +1 -1
- package/bin/domain/usecases/StartPreparationUseCase.js +21 -5
- package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
- package/package.json +1 -1
- package/src/adapter/entry-points/cli/index.test.ts +2 -0
- package/src/adapter/entry-points/cli/index.ts +7 -0
- package/src/adapter/entry-points/cli/projectConfig.ts +8 -0
- package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +3 -0
- package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.test.ts +114 -1
- package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.ts +21 -11
- package/src/adapter/repositories/issue/GraphqlProjectItemRepository.test.ts +103 -0
- package/src/adapter/repositories/issue/GraphqlProjectItemRepository.ts +33 -9
- package/src/domain/usecases/HandleScheduledEventUseCase.ts +3 -0
- package/src/domain/usecases/SetDependedIssueUrlForOpenTaskPRsUseCase.test.ts +57 -0
- package/src/domain/usecases/SetDependedIssueUrlForOpenTaskPRsUseCase.ts +11 -5
- package/src/domain/usecases/StartPreparationUseCase.test.ts +409 -0
- package/src/domain/usecases/StartPreparationUseCase.ts +32 -4
- package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
- package/types/adapter/entry-points/cli/projectConfig.d.ts +1 -0
- package/types/adapter/entry-points/cli/projectConfig.d.ts.map +1 -1
- package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -1
- package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts.map +1 -1
- package/types/adapter/repositories/issue/GraphqlProjectItemRepository.d.ts +2 -2
- package/types/adapter/repositories/issue/GraphqlProjectItemRepository.d.ts.map +1 -1
- package/types/domain/usecases/HandleScheduledEventUseCase.d.ts +1 -0
- package/types/domain/usecases/HandleScheduledEventUseCase.d.ts.map +1 -1
- package/types/domain/usecases/SetDependedIssueUrlForOpenTaskPRsUseCase.d.ts.map +1 -1
- package/types/domain/usecases/StartPreparationUseCase.d.ts +2 -0
- package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
|
@@ -146,6 +146,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
146
146
|
projectUrl: 'https://github.com/user/repo',
|
|
147
147
|
defaultAgentName: 'agent1',
|
|
148
148
|
defaultLlmModelName: 'claude-opus',
|
|
149
|
+
fallbackLlmModelName: null,
|
|
149
150
|
defaultLlmAgentName: null,
|
|
150
151
|
configFilePath: '/path/to/config.yml',
|
|
151
152
|
maximumPreparingIssuesCount: null,
|
|
@@ -211,6 +212,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
211
212
|
projectUrl: 'https://github.com/user/repo',
|
|
212
213
|
defaultAgentName: 'agent1',
|
|
213
214
|
defaultLlmModelName: 'claude-opus',
|
|
215
|
+
fallbackLlmModelName: null,
|
|
214
216
|
defaultLlmAgentName: null,
|
|
215
217
|
configFilePath: '/path/to/config.yml',
|
|
216
218
|
maximumPreparingIssuesCount: null,
|
|
@@ -268,6 +270,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
268
270
|
projectUrl: 'https://github.com/user/repo',
|
|
269
271
|
defaultAgentName: 'agent1',
|
|
270
272
|
defaultLlmModelName: 'claude-opus',
|
|
273
|
+
fallbackLlmModelName: null,
|
|
271
274
|
defaultLlmAgentName: null,
|
|
272
275
|
configFilePath: '/path/to/config.yml',
|
|
273
276
|
maximumPreparingIssuesCount: null,
|
|
@@ -316,6 +319,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
316
319
|
projectUrl: 'https://github.com/user/repo',
|
|
317
320
|
defaultAgentName: 'agent1',
|
|
318
321
|
defaultLlmModelName: 'claude-opus',
|
|
322
|
+
fallbackLlmModelName: null,
|
|
319
323
|
defaultLlmAgentName: null,
|
|
320
324
|
configFilePath: '/path/to/config.yml',
|
|
321
325
|
maximumPreparingIssuesCount: null,
|
|
@@ -365,6 +369,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
365
369
|
projectUrl: 'https://github.com/user/repo',
|
|
366
370
|
defaultAgentName: 'agent1',
|
|
367
371
|
defaultLlmModelName: 'claude-opus',
|
|
372
|
+
fallbackLlmModelName: null,
|
|
368
373
|
defaultLlmAgentName: null,
|
|
369
374
|
configFilePath: '/path/to/config.yml',
|
|
370
375
|
maximumPreparingIssuesCount: null,
|
|
@@ -413,6 +418,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
413
418
|
projectUrl: 'https://github.com/user/repo',
|
|
414
419
|
defaultAgentName: 'agent1',
|
|
415
420
|
defaultLlmModelName: 'claude-opus',
|
|
421
|
+
fallbackLlmModelName: null,
|
|
416
422
|
defaultLlmAgentName: null,
|
|
417
423
|
configFilePath: '/path/to/config.yml',
|
|
418
424
|
maximumPreparingIssuesCount: null,
|
|
@@ -479,6 +485,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
479
485
|
projectUrl: 'https://github.com/user/repo',
|
|
480
486
|
defaultAgentName: 'agent1',
|
|
481
487
|
defaultLlmModelName: 'claude-opus',
|
|
488
|
+
fallbackLlmModelName: null,
|
|
482
489
|
defaultLlmAgentName: null,
|
|
483
490
|
configFilePath: '/path/to/config.yml',
|
|
484
491
|
maximumPreparingIssuesCount: null,
|
|
@@ -568,6 +575,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
568
575
|
projectUrl: 'https://github.com/user/repo',
|
|
569
576
|
defaultAgentName: 'agent1',
|
|
570
577
|
defaultLlmModelName: 'claude-opus',
|
|
578
|
+
fallbackLlmModelName: null,
|
|
571
579
|
defaultLlmAgentName: null,
|
|
572
580
|
configFilePath: '/path/to/config.yml',
|
|
573
581
|
maximumPreparingIssuesCount: null,
|
|
@@ -631,6 +639,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
631
639
|
projectUrl: 'https://github.com/user/repo',
|
|
632
640
|
defaultAgentName: 'agent1',
|
|
633
641
|
defaultLlmModelName: 'claude-opus',
|
|
642
|
+
fallbackLlmModelName: null,
|
|
634
643
|
defaultLlmAgentName: null,
|
|
635
644
|
configFilePath: '/path/to/config.yml',
|
|
636
645
|
maximumPreparingIssuesCount: null,
|
|
@@ -675,6 +684,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
675
684
|
projectUrl: 'https://github.com/user/repo',
|
|
676
685
|
defaultAgentName: 'agent1',
|
|
677
686
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
687
|
+
fallbackLlmModelName: null,
|
|
678
688
|
defaultLlmAgentName: null,
|
|
679
689
|
configFilePath: '/path/to/config.yml',
|
|
680
690
|
maximumPreparingIssuesCount: null,
|
|
@@ -732,6 +742,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
732
742
|
projectUrl: 'https://github.com/user/repo',
|
|
733
743
|
defaultAgentName: 'agent1',
|
|
734
744
|
defaultLlmModelName: null,
|
|
745
|
+
fallbackLlmModelName: null,
|
|
735
746
|
defaultLlmAgentName: null,
|
|
736
747
|
configFilePath: '/path/to/config.yml',
|
|
737
748
|
maximumPreparingIssuesCount: null,
|
|
@@ -767,6 +778,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
767
778
|
projectUrl: 'https://github.com/user/repo',
|
|
768
779
|
defaultAgentName: 'agent1',
|
|
769
780
|
defaultLlmModelName: 'claude-opus',
|
|
781
|
+
fallbackLlmModelName: null,
|
|
770
782
|
defaultLlmAgentName: null,
|
|
771
783
|
configFilePath: '/path/to/config.yml',
|
|
772
784
|
maximumPreparingIssuesCount: null,
|
|
@@ -812,6 +824,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
812
824
|
projectUrl: 'https://github.com/user/repo',
|
|
813
825
|
defaultAgentName: 'agent1',
|
|
814
826
|
defaultLlmModelName: 'claude-opus',
|
|
827
|
+
fallbackLlmModelName: null,
|
|
815
828
|
defaultLlmAgentName: null,
|
|
816
829
|
configFilePath: '/path/to/config.yml',
|
|
817
830
|
maximumPreparingIssuesCount: null,
|
|
@@ -857,6 +870,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
857
870
|
projectUrl: 'https://github.com/user/repo',
|
|
858
871
|
defaultAgentName: 'agent1',
|
|
859
872
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
873
|
+
fallbackLlmModelName: null,
|
|
860
874
|
defaultLlmAgentName: 'default-llm-agent',
|
|
861
875
|
configFilePath: '/path/to/config.yml',
|
|
862
876
|
maximumPreparingIssuesCount: null,
|
|
@@ -902,6 +916,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
902
916
|
projectUrl: 'https://github.com/user/repo',
|
|
903
917
|
defaultAgentName: 'agent1',
|
|
904
918
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
919
|
+
fallbackLlmModelName: null,
|
|
905
920
|
defaultLlmAgentName: 'default-llm-agent',
|
|
906
921
|
configFilePath: '/path/to/config.yml',
|
|
907
922
|
maximumPreparingIssuesCount: null,
|
|
@@ -947,6 +962,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
947
962
|
projectUrl: 'https://github.com/user/repo',
|
|
948
963
|
defaultAgentName: 'agent1',
|
|
949
964
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
965
|
+
fallbackLlmModelName: null,
|
|
950
966
|
defaultLlmAgentName: 'default-llm-agent',
|
|
951
967
|
configFilePath: '/path/to/config.yml',
|
|
952
968
|
maximumPreparingIssuesCount: null,
|
|
@@ -992,6 +1008,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
992
1008
|
projectUrl: 'https://github.com/user/repo',
|
|
993
1009
|
defaultAgentName: 'agent1',
|
|
994
1010
|
defaultLlmModelName: 'claude-opus',
|
|
1011
|
+
fallbackLlmModelName: null,
|
|
995
1012
|
defaultLlmAgentName: null,
|
|
996
1013
|
configFilePath: '/path/to/config.yml',
|
|
997
1014
|
maximumPreparingIssuesCount: null,
|
|
@@ -1040,6 +1057,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1040
1057
|
projectUrl: 'https://github.com/user/repo',
|
|
1041
1058
|
defaultAgentName: 'agent1',
|
|
1042
1059
|
defaultLlmModelName: null,
|
|
1060
|
+
fallbackLlmModelName: null,
|
|
1043
1061
|
defaultLlmAgentName: null,
|
|
1044
1062
|
configFilePath: '/path/to/config.yml',
|
|
1045
1063
|
maximumPreparingIssuesCount: null,
|
|
@@ -1088,6 +1106,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1088
1106
|
projectUrl: 'https://github.com/user/repo',
|
|
1089
1107
|
defaultAgentName: 'agent1',
|
|
1090
1108
|
defaultLlmModelName: null,
|
|
1109
|
+
fallbackLlmModelName: null,
|
|
1091
1110
|
defaultLlmAgentName: null,
|
|
1092
1111
|
configFilePath: '/path/to/config.yml',
|
|
1093
1112
|
maximumPreparingIssuesCount: null,
|
|
@@ -1138,6 +1157,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1138
1157
|
projectUrl: 'https://github.com/user/repo',
|
|
1139
1158
|
defaultAgentName: 'agent1',
|
|
1140
1159
|
defaultLlmModelName: null,
|
|
1160
|
+
fallbackLlmModelName: null,
|
|
1141
1161
|
defaultLlmAgentName: null,
|
|
1142
1162
|
configFilePath: '/path/to/config.yml',
|
|
1143
1163
|
maximumPreparingIssuesCount: null,
|
|
@@ -1173,6 +1193,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1173
1193
|
projectUrl: 'https://github.com/user/repo',
|
|
1174
1194
|
defaultAgentName: 'agent1',
|
|
1175
1195
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
1196
|
+
fallbackLlmModelName: null,
|
|
1176
1197
|
defaultLlmAgentName: null,
|
|
1177
1198
|
configFilePath: '/path/to/config.yml',
|
|
1178
1199
|
maximumPreparingIssuesCount: 3,
|
|
@@ -1207,6 +1228,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1207
1228
|
projectUrl: 'https://github.com/user/repo',
|
|
1208
1229
|
defaultAgentName: 'agent1',
|
|
1209
1230
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
1231
|
+
fallbackLlmModelName: null,
|
|
1210
1232
|
defaultLlmAgentName: null,
|
|
1211
1233
|
configFilePath: '/path/to/config.yml',
|
|
1212
1234
|
maximumPreparingIssuesCount: null,
|
|
@@ -1264,6 +1286,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1264
1286
|
projectUrl: 'https://github.com/user/repo',
|
|
1265
1287
|
defaultAgentName: 'agent1',
|
|
1266
1288
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
1289
|
+
fallbackLlmModelName: null,
|
|
1267
1290
|
defaultLlmAgentName: null,
|
|
1268
1291
|
configFilePath: '/path/to/config.yml',
|
|
1269
1292
|
maximumPreparingIssuesCount: 12,
|
|
@@ -1330,6 +1353,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1330
1353
|
projectUrl: 'https://github.com/user/repo',
|
|
1331
1354
|
defaultAgentName: 'agent1',
|
|
1332
1355
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
1356
|
+
fallbackLlmModelName: null,
|
|
1333
1357
|
defaultLlmAgentName: null,
|
|
1334
1358
|
configFilePath: '/path/to/config.yml',
|
|
1335
1359
|
maximumPreparingIssuesCount: 20,
|
|
@@ -1394,6 +1418,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1394
1418
|
projectUrl: 'https://github.com/user/repo',
|
|
1395
1419
|
defaultAgentName: 'agent1',
|
|
1396
1420
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
1421
|
+
fallbackLlmModelName: null,
|
|
1397
1422
|
defaultLlmAgentName: null,
|
|
1398
1423
|
configFilePath: '/path/to/config.yml',
|
|
1399
1424
|
maximumPreparingIssuesCount: null,
|
|
@@ -1442,6 +1467,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1442
1467
|
projectUrl: 'https://github.com/user/repo',
|
|
1443
1468
|
defaultAgentName: 'agent1',
|
|
1444
1469
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
1470
|
+
fallbackLlmModelName: null,
|
|
1445
1471
|
defaultLlmAgentName: null,
|
|
1446
1472
|
configFilePath: '/path/to/config.yml',
|
|
1447
1473
|
maximumPreparingIssuesCount: null,
|
|
@@ -1497,6 +1523,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1497
1523
|
projectUrl: 'https://github.com/user/repo',
|
|
1498
1524
|
defaultAgentName: 'agent1',
|
|
1499
1525
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
1526
|
+
fallbackLlmModelName: null,
|
|
1500
1527
|
defaultLlmAgentName: null,
|
|
1501
1528
|
configFilePath: '/path/to/config.yml',
|
|
1502
1529
|
maximumPreparingIssuesCount: null,
|
|
@@ -1555,6 +1582,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1555
1582
|
projectUrl: 'https://github.com/user/repo',
|
|
1556
1583
|
defaultAgentName: 'agent1',
|
|
1557
1584
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
1585
|
+
fallbackLlmModelName: null,
|
|
1558
1586
|
defaultLlmAgentName: null,
|
|
1559
1587
|
configFilePath: '/path/to/config.yml',
|
|
1560
1588
|
maximumPreparingIssuesCount: null,
|
|
@@ -1603,6 +1631,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1603
1631
|
projectUrl: 'https://github.com/user/repo',
|
|
1604
1632
|
defaultAgentName: 'agent1',
|
|
1605
1633
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
1634
|
+
fallbackLlmModelName: null,
|
|
1606
1635
|
defaultLlmAgentName: null,
|
|
1607
1636
|
configFilePath: '/path/to/config.yml',
|
|
1608
1637
|
maximumPreparingIssuesCount: null,
|
|
@@ -1651,6 +1680,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1651
1680
|
projectUrl: 'https://github.com/user/repo',
|
|
1652
1681
|
defaultAgentName: 'agent1',
|
|
1653
1682
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
1683
|
+
fallbackLlmModelName: null,
|
|
1654
1684
|
defaultLlmAgentName: null,
|
|
1655
1685
|
configFilePath: '/path/to/config.yml',
|
|
1656
1686
|
maximumPreparingIssuesCount: null,
|
|
@@ -1699,6 +1729,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1699
1729
|
projectUrl: 'https://github.com/user/repo',
|
|
1700
1730
|
defaultAgentName: 'agent1',
|
|
1701
1731
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
1732
|
+
fallbackLlmModelName: null,
|
|
1702
1733
|
defaultLlmAgentName: null,
|
|
1703
1734
|
configFilePath: '/path/to/config.yml',
|
|
1704
1735
|
maximumPreparingIssuesCount: null,
|
|
@@ -1753,6 +1784,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1753
1784
|
projectUrl: 'https://github.com/user/repo',
|
|
1754
1785
|
defaultAgentName: 'agent1',
|
|
1755
1786
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
1787
|
+
fallbackLlmModelName: null,
|
|
1756
1788
|
defaultLlmAgentName: null,
|
|
1757
1789
|
configFilePath: '/path/to/config.yml',
|
|
1758
1790
|
maximumPreparingIssuesCount: null,
|
|
@@ -1801,6 +1833,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1801
1833
|
projectUrl: 'https://github.com/user/repo',
|
|
1802
1834
|
defaultAgentName: 'agent1',
|
|
1803
1835
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
1836
|
+
fallbackLlmModelName: null,
|
|
1804
1837
|
defaultLlmAgentName: null,
|
|
1805
1838
|
configFilePath: '/path/to/config.yml',
|
|
1806
1839
|
maximumPreparingIssuesCount: null,
|
|
@@ -1847,6 +1880,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1847
1880
|
projectUrl: 'https://github.com/user/repo',
|
|
1848
1881
|
defaultAgentName: 'agent1',
|
|
1849
1882
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
1883
|
+
fallbackLlmModelName: null,
|
|
1850
1884
|
defaultLlmAgentName: null,
|
|
1851
1885
|
configFilePath: '/path/to/config.yml',
|
|
1852
1886
|
maximumPreparingIssuesCount: null,
|
|
@@ -1887,6 +1921,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1887
1921
|
projectUrl: 'https://github.com/user/repo',
|
|
1888
1922
|
defaultAgentName: 'agent1',
|
|
1889
1923
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
1924
|
+
fallbackLlmModelName: null,
|
|
1890
1925
|
defaultLlmAgentName: null,
|
|
1891
1926
|
configFilePath: '/path/to/config.yml',
|
|
1892
1927
|
maximumPreparingIssuesCount: null,
|
|
@@ -1924,6 +1959,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1924
1959
|
projectUrl: 'https://github.com/user/repo',
|
|
1925
1960
|
defaultAgentName: 'agent1',
|
|
1926
1961
|
defaultLlmModelName: 'claude-opus',
|
|
1962
|
+
fallbackLlmModelName: null,
|
|
1927
1963
|
defaultLlmAgentName: null,
|
|
1928
1964
|
configFilePath: '/path/to/config.yml',
|
|
1929
1965
|
maximumPreparingIssuesCount: null,
|
|
@@ -1972,6 +2008,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
1972
2008
|
projectUrl: 'https://github.com/user/repo',
|
|
1973
2009
|
defaultAgentName: 'agent1',
|
|
1974
2010
|
defaultLlmModelName: 'claude-opus',
|
|
2011
|
+
fallbackLlmModelName: null,
|
|
1975
2012
|
defaultLlmAgentName: null,
|
|
1976
2013
|
configFilePath: '/path/to/config.yml',
|
|
1977
2014
|
maximumPreparingIssuesCount: null,
|
|
@@ -2020,6 +2057,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2020
2057
|
projectUrl: 'https://github.com/user/repo',
|
|
2021
2058
|
defaultAgentName: 'agent1',
|
|
2022
2059
|
defaultLlmModelName: 'claude-opus',
|
|
2060
|
+
fallbackLlmModelName: null,
|
|
2023
2061
|
defaultLlmAgentName: null,
|
|
2024
2062
|
configFilePath: '/path/to/config.yml',
|
|
2025
2063
|
maximumPreparingIssuesCount: null,
|
|
@@ -2088,6 +2126,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2088
2126
|
projectUrl: 'https://github.com/user/repo',
|
|
2089
2127
|
defaultAgentName: 'agent1',
|
|
2090
2128
|
defaultLlmModelName: 'claude-opus',
|
|
2129
|
+
fallbackLlmModelName: null,
|
|
2091
2130
|
defaultLlmAgentName: null,
|
|
2092
2131
|
configFilePath: '/path/to/config.yml',
|
|
2093
2132
|
maximumPreparingIssuesCount: null,
|
|
@@ -2153,6 +2192,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2153
2192
|
projectUrl: 'https://github.com/user/repo',
|
|
2154
2193
|
defaultAgentName: 'agent1',
|
|
2155
2194
|
defaultLlmModelName: 'claude-opus',
|
|
2195
|
+
fallbackLlmModelName: null,
|
|
2156
2196
|
defaultLlmAgentName: null,
|
|
2157
2197
|
configFilePath: '/path/to/config.yml',
|
|
2158
2198
|
maximumPreparingIssuesCount: null,
|
|
@@ -2212,6 +2252,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2212
2252
|
projectUrl: 'https://github.com/user/repo',
|
|
2213
2253
|
defaultAgentName: 'agent1',
|
|
2214
2254
|
defaultLlmModelName: 'claude-opus',
|
|
2255
|
+
fallbackLlmModelName: null,
|
|
2215
2256
|
defaultLlmAgentName: null,
|
|
2216
2257
|
configFilePath: '/path/to/config.yml',
|
|
2217
2258
|
maximumPreparingIssuesCount: null,
|
|
@@ -2240,6 +2281,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2240
2281
|
projectUrl: 'https://github.com/user/repo',
|
|
2241
2282
|
defaultAgentName: 'agent1',
|
|
2242
2283
|
defaultLlmModelName: null,
|
|
2284
|
+
fallbackLlmModelName: null,
|
|
2243
2285
|
defaultLlmAgentName: null,
|
|
2244
2286
|
configFilePath: '/path/to/config.yml',
|
|
2245
2287
|
maximumPreparingIssuesCount: null,
|
|
@@ -2287,6 +2329,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2287
2329
|
projectUrl: 'https://github.com/user/repo',
|
|
2288
2330
|
defaultAgentName: 'agent1',
|
|
2289
2331
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
2332
|
+
fallbackLlmModelName: null,
|
|
2290
2333
|
defaultLlmAgentName: null,
|
|
2291
2334
|
configFilePath: '/path/to/config.yml',
|
|
2292
2335
|
maximumPreparingIssuesCount: null,
|
|
@@ -2337,6 +2380,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2337
2380
|
projectUrl: 'https://github.com/user/repo',
|
|
2338
2381
|
defaultAgentName: 'agent1',
|
|
2339
2382
|
defaultLlmModelName: 'claude-opus',
|
|
2383
|
+
fallbackLlmModelName: null,
|
|
2340
2384
|
defaultLlmAgentName: null,
|
|
2341
2385
|
configFilePath: '/path/to/config.yml',
|
|
2342
2386
|
maximumPreparingIssuesCount: null,
|
|
@@ -2423,6 +2467,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2423
2467
|
projectUrl: 'https://github.com/user/repo',
|
|
2424
2468
|
defaultAgentName: 'agent1',
|
|
2425
2469
|
defaultLlmModelName: 'claude-opus',
|
|
2470
|
+
fallbackLlmModelName: null,
|
|
2426
2471
|
defaultLlmAgentName: null,
|
|
2427
2472
|
configFilePath: '/path/to/config.yml',
|
|
2428
2473
|
maximumPreparingIssuesCount: null,
|
|
@@ -2480,6 +2525,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2480
2525
|
projectUrl: 'https://github.com/user/repo',
|
|
2481
2526
|
defaultAgentName: 'agent1',
|
|
2482
2527
|
defaultLlmModelName: 'claude-opus',
|
|
2528
|
+
fallbackLlmModelName: null,
|
|
2483
2529
|
defaultLlmAgentName: null,
|
|
2484
2530
|
configFilePath: '/path/to/config.yml',
|
|
2485
2531
|
maximumPreparingIssuesCount: null,
|
|
@@ -2551,6 +2597,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2551
2597
|
projectUrl: 'https://github.com/user/repo',
|
|
2552
2598
|
defaultAgentName: 'agent1',
|
|
2553
2599
|
defaultLlmModelName: 'claude-opus',
|
|
2600
|
+
fallbackLlmModelName: null,
|
|
2554
2601
|
defaultLlmAgentName: null,
|
|
2555
2602
|
configFilePath: '/path/to/config.yml',
|
|
2556
2603
|
maximumPreparingIssuesCount: null,
|
|
@@ -2634,6 +2681,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2634
2681
|
projectUrl: 'https://github.com/user/repo',
|
|
2635
2682
|
defaultAgentName: 'agent1',
|
|
2636
2683
|
defaultLlmModelName: 'claude-opus',
|
|
2684
|
+
fallbackLlmModelName: null,
|
|
2637
2685
|
defaultLlmAgentName: null,
|
|
2638
2686
|
configFilePath: '/path/to/config.yml',
|
|
2639
2687
|
maximumPreparingIssuesCount: null,
|
|
@@ -2696,6 +2744,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2696
2744
|
projectUrl: 'https://github.com/user/repo',
|
|
2697
2745
|
defaultAgentName: 'agent1',
|
|
2698
2746
|
defaultLlmModelName: 'claude-opus',
|
|
2747
|
+
fallbackLlmModelName: null,
|
|
2699
2748
|
defaultLlmAgentName: null,
|
|
2700
2749
|
configFilePath: '/path/to/config.yml',
|
|
2701
2750
|
maximumPreparingIssuesCount: null,
|
|
@@ -2761,6 +2810,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2761
2810
|
projectUrl: 'https://github.com/user/repo',
|
|
2762
2811
|
defaultAgentName: 'agent1',
|
|
2763
2812
|
defaultLlmModelName: 'claude-opus',
|
|
2813
|
+
fallbackLlmModelName: null,
|
|
2764
2814
|
defaultLlmAgentName: null,
|
|
2765
2815
|
configFilePath: '/path/to/config.yml',
|
|
2766
2816
|
maximumPreparingIssuesCount: null,
|
|
@@ -2829,6 +2879,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2829
2879
|
projectUrl: 'https://github.com/user/repo',
|
|
2830
2880
|
defaultAgentName: 'agent1',
|
|
2831
2881
|
defaultLlmModelName: 'claude-opus',
|
|
2882
|
+
fallbackLlmModelName: null,
|
|
2832
2883
|
defaultLlmAgentName: null,
|
|
2833
2884
|
configFilePath: '/path/to/config.yml',
|
|
2834
2885
|
maximumPreparingIssuesCount: null,
|
|
@@ -2937,6 +2988,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2937
2988
|
projectUrl: 'https://github.com/user/repo',
|
|
2938
2989
|
defaultAgentName: 'agent1',
|
|
2939
2990
|
defaultLlmModelName: 'claude-opus',
|
|
2991
|
+
fallbackLlmModelName: null,
|
|
2940
2992
|
defaultLlmAgentName: null,
|
|
2941
2993
|
configFilePath: '/path/to/config.yml',
|
|
2942
2994
|
maximumPreparingIssuesCount: null,
|
|
@@ -2995,6 +3047,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2995
3047
|
projectUrl: 'https://github.com/user/repo',
|
|
2996
3048
|
defaultAgentName: 'agent1',
|
|
2997
3049
|
defaultLlmModelName: 'claude-opus',
|
|
3050
|
+
fallbackLlmModelName: null,
|
|
2998
3051
|
defaultLlmAgentName: null,
|
|
2999
3052
|
configFilePath: '/path/to/config.yml',
|
|
3000
3053
|
maximumPreparingIssuesCount: null,
|
|
@@ -3057,6 +3110,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
3057
3110
|
projectUrl: 'https://github.com/user/repo',
|
|
3058
3111
|
defaultAgentName: 'agent1',
|
|
3059
3112
|
defaultLlmModelName: 'claude-opus',
|
|
3113
|
+
fallbackLlmModelName: null,
|
|
3060
3114
|
defaultLlmAgentName: null,
|
|
3061
3115
|
configFilePath: '/path/to/config.yml',
|
|
3062
3116
|
maximumPreparingIssuesCount: null,
|
|
@@ -3119,6 +3173,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
3119
3173
|
projectUrl: 'https://github.com/user/repo',
|
|
3120
3174
|
defaultAgentName: 'agent1',
|
|
3121
3175
|
defaultLlmModelName: 'claude-opus',
|
|
3176
|
+
fallbackLlmModelName: null,
|
|
3122
3177
|
defaultLlmAgentName: null,
|
|
3123
3178
|
configFilePath: '/path/to/config.yml',
|
|
3124
3179
|
maximumPreparingIssuesCount: null,
|
|
@@ -3181,6 +3236,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
3181
3236
|
projectUrl: 'https://github.com/user/repo',
|
|
3182
3237
|
defaultAgentName: 'agent1',
|
|
3183
3238
|
defaultLlmModelName: 'claude-opus',
|
|
3239
|
+
fallbackLlmModelName: null,
|
|
3184
3240
|
defaultLlmAgentName: null,
|
|
3185
3241
|
configFilePath: '/path/to/config.yml',
|
|
3186
3242
|
maximumPreparingIssuesCount: null,
|
|
@@ -3246,6 +3302,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
3246
3302
|
projectUrl: 'https://github.com/user/repo',
|
|
3247
3303
|
defaultAgentName: 'agent1',
|
|
3248
3304
|
defaultLlmModelName: 'claude-opus',
|
|
3305
|
+
fallbackLlmModelName: null,
|
|
3249
3306
|
defaultLlmAgentName: null,
|
|
3250
3307
|
configFilePath: '/path/to/config.yml',
|
|
3251
3308
|
maximumPreparingIssuesCount: null,
|
|
@@ -3293,6 +3350,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
3293
3350
|
projectUrl: 'https://github.com/user/repo',
|
|
3294
3351
|
defaultAgentName: 'agent1',
|
|
3295
3352
|
defaultLlmModelName: 'claude-opus',
|
|
3353
|
+
fallbackLlmModelName: null,
|
|
3296
3354
|
defaultLlmAgentName: null,
|
|
3297
3355
|
configFilePath: '/path/to/config.yml',
|
|
3298
3356
|
maximumPreparingIssuesCount: null,
|
|
@@ -3358,6 +3416,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
3358
3416
|
projectUrl: 'https://github.com/user/repo',
|
|
3359
3417
|
defaultAgentName: 'agent1',
|
|
3360
3418
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
3419
|
+
fallbackLlmModelName: null,
|
|
3361
3420
|
defaultLlmAgentName: null,
|
|
3362
3421
|
configFilePath: '/path/to/config.yml',
|
|
3363
3422
|
maximumPreparingIssuesCount: null,
|
|
@@ -3423,6 +3482,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
3423
3482
|
projectUrl: 'https://github.com/user/repo',
|
|
3424
3483
|
defaultAgentName: 'agent1',
|
|
3425
3484
|
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
3485
|
+
fallbackLlmModelName: null,
|
|
3426
3486
|
defaultLlmAgentName: null,
|
|
3427
3487
|
configFilePath: '/path/to/config.yml',
|
|
3428
3488
|
maximumPreparingIssuesCount: null,
|
|
@@ -3488,6 +3548,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
3488
3548
|
projectUrl: 'https://github.com/user/repo',
|
|
3489
3549
|
defaultAgentName: 'agent1',
|
|
3490
3550
|
defaultLlmModelName: 'claude-opus',
|
|
3551
|
+
fallbackLlmModelName: null,
|
|
3491
3552
|
defaultLlmAgentName: null,
|
|
3492
3553
|
configFilePath: '/path/to/config.yml',
|
|
3493
3554
|
maximumPreparingIssuesCount: null,
|
|
@@ -3553,6 +3614,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
3553
3614
|
projectUrl: 'https://github.com/user/repo',
|
|
3554
3615
|
defaultAgentName: 'agent1',
|
|
3555
3616
|
defaultLlmModelName: 'claude-opus',
|
|
3617
|
+
fallbackLlmModelName: null,
|
|
3556
3618
|
defaultLlmAgentName: null,
|
|
3557
3619
|
configFilePath: '/path/to/config.yml',
|
|
3558
3620
|
maximumPreparingIssuesCount: null,
|
|
@@ -3626,6 +3688,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
3626
3688
|
projectUrl: 'https://github.com/user/repo',
|
|
3627
3689
|
defaultAgentName: 'agent1',
|
|
3628
3690
|
defaultLlmModelName: 'claude-opus',
|
|
3691
|
+
fallbackLlmModelName: null,
|
|
3629
3692
|
defaultLlmAgentName: null,
|
|
3630
3693
|
configFilePath: '/path/to/config.yml',
|
|
3631
3694
|
maximumPreparingIssuesCount: null,
|
|
@@ -3699,6 +3762,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
3699
3762
|
projectUrl: 'https://github.com/user/repo',
|
|
3700
3763
|
defaultAgentName: 'agent1',
|
|
3701
3764
|
defaultLlmModelName: 'claude-opus',
|
|
3765
|
+
fallbackLlmModelName: null,
|
|
3702
3766
|
defaultLlmAgentName: null,
|
|
3703
3767
|
configFilePath: '/path/to/config.yml',
|
|
3704
3768
|
maximumPreparingIssuesCount: null,
|
|
@@ -3777,6 +3841,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
3777
3841
|
projectUrl: 'https://github.com/user/repo',
|
|
3778
3842
|
defaultAgentName: 'agent1',
|
|
3779
3843
|
defaultLlmModelName: 'claude-opus',
|
|
3844
|
+
fallbackLlmModelName: null,
|
|
3780
3845
|
defaultLlmAgentName: null,
|
|
3781
3846
|
configFilePath: '/path/to/config.yml',
|
|
3782
3847
|
maximumPreparingIssuesCount: null,
|
|
@@ -3882,6 +3947,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
3882
3947
|
projectUrl: 'https://github.com/user/repo',
|
|
3883
3948
|
defaultAgentName: 'agent1',
|
|
3884
3949
|
defaultLlmModelName: 'claude-opus',
|
|
3950
|
+
fallbackLlmModelName: null,
|
|
3885
3951
|
defaultLlmAgentName: null,
|
|
3886
3952
|
configFilePath: '/path/to/config.yml',
|
|
3887
3953
|
maximumPreparingIssuesCount: null,
|
|
@@ -3953,6 +4019,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
3953
4019
|
projectUrl: 'https://github.com/user/repo',
|
|
3954
4020
|
defaultAgentName: 'agent1',
|
|
3955
4021
|
defaultLlmModelName: 'claude-opus',
|
|
4022
|
+
fallbackLlmModelName: null,
|
|
3956
4023
|
defaultLlmAgentName: null,
|
|
3957
4024
|
configFilePath: '/path/to/config.yml',
|
|
3958
4025
|
maximumPreparingIssuesCount: null,
|
|
@@ -4021,6 +4088,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
4021
4088
|
projectUrl: 'https://github.com/user/repo',
|
|
4022
4089
|
defaultAgentName: 'agent1',
|
|
4023
4090
|
defaultLlmModelName: 'claude-opus',
|
|
4091
|
+
fallbackLlmModelName: null,
|
|
4024
4092
|
defaultLlmAgentName: null,
|
|
4025
4093
|
configFilePath: '/path/to/config.yml',
|
|
4026
4094
|
maximumPreparingIssuesCount: null,
|
|
@@ -4068,6 +4136,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
4068
4136
|
projectUrl: 'https://github.com/user/repo',
|
|
4069
4137
|
defaultAgentName: params.defaultAgentName,
|
|
4070
4138
|
defaultLlmModelName: 'claude-opus',
|
|
4139
|
+
fallbackLlmModelName: null,
|
|
4071
4140
|
defaultLlmAgentName: params.defaultLlmAgentName,
|
|
4072
4141
|
configFilePath: '/path/to/config.yml',
|
|
4073
4142
|
maximumPreparingIssuesCount: null,
|
|
@@ -4172,6 +4241,346 @@ describe('StartPreparationUseCase', () => {
|
|
|
4172
4241
|
expect(selectedAgent).toBe('impl');
|
|
4173
4242
|
});
|
|
4174
4243
|
});
|
|
4244
|
+
|
|
4245
|
+
describe('Sonnet-to-Opus weekly limit fallback', () => {
|
|
4246
|
+
const futureReset = Math.floor(Date.now() / 1000) + 3600;
|
|
4247
|
+
|
|
4248
|
+
it('spawns preparations with the Opus fallback model when the sonnet default is selected and every token has its seven_day_sonnet weekly limit exhausted while opus capacity remains', async () => {
|
|
4249
|
+
const awaitingIssue = createMockIssue({
|
|
4250
|
+
url: 'url1',
|
|
4251
|
+
title: 'Issue 1',
|
|
4252
|
+
labels: ['category:impl'],
|
|
4253
|
+
status: 'Awaiting Workspace',
|
|
4254
|
+
number: 1,
|
|
4255
|
+
itemId: 'item-1',
|
|
4256
|
+
});
|
|
4257
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
4258
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
4259
|
+
createMockStoryObjectMap([awaitingIssue]),
|
|
4260
|
+
);
|
|
4261
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
4262
|
+
stdout: '',
|
|
4263
|
+
stderr: '',
|
|
4264
|
+
exitCode: 0,
|
|
4265
|
+
});
|
|
4266
|
+
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
4267
|
+
{
|
|
4268
|
+
name: 'token-sonnet-exhausted',
|
|
4269
|
+
token: 'token-sonnet-exhausted',
|
|
4270
|
+
fiveHourUtilization: 0.1,
|
|
4271
|
+
sevenDayUtilization: 0,
|
|
4272
|
+
blocked: false,
|
|
4273
|
+
rejected: false,
|
|
4274
|
+
modelWeeklyLimits: {
|
|
4275
|
+
seven_day_sonnet: { rejected: true, resetsAt: futureReset },
|
|
4276
|
+
},
|
|
4277
|
+
},
|
|
4278
|
+
]);
|
|
4279
|
+
|
|
4280
|
+
await useCase.run({
|
|
4281
|
+
projectUrl: 'https://github.com/user/repo',
|
|
4282
|
+
defaultAgentName: 'agent1',
|
|
4283
|
+
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
4284
|
+
fallbackLlmModelName: null,
|
|
4285
|
+
defaultLlmAgentName: null,
|
|
4286
|
+
configFilePath: '/path/to/config.yml',
|
|
4287
|
+
maximumPreparingIssuesCount: null,
|
|
4288
|
+
utilizationPercentageThreshold: 90,
|
|
4289
|
+
allowedIssueAuthors: null,
|
|
4290
|
+
codexHomeCandidates: null,
|
|
4291
|
+
allowIssueCacheMinutes: 0,
|
|
4292
|
+
labelsAsLlmAgentName: null,
|
|
4293
|
+
});
|
|
4294
|
+
|
|
4295
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
|
|
4296
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][1]).toEqual([
|
|
4297
|
+
'url1',
|
|
4298
|
+
'impl',
|
|
4299
|
+
'claude-opus-4-8',
|
|
4300
|
+
'--configFilePath',
|
|
4301
|
+
'/path/to/config.yml',
|
|
4302
|
+
'--branch',
|
|
4303
|
+
'i1',
|
|
4304
|
+
]);
|
|
4305
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][2]).toEqual({
|
|
4306
|
+
env: {
|
|
4307
|
+
CLAUDE_CODE_OAUTH_TOKEN: 'token-sonnet-exhausted',
|
|
4308
|
+
ANTHROPIC_BASE_URL: 'http://127.0.0.1:8787',
|
|
4309
|
+
},
|
|
4310
|
+
});
|
|
4311
|
+
});
|
|
4312
|
+
|
|
4313
|
+
it('uses the configured fallbackLlmModelName instead of the default when falling back to opus', async () => {
|
|
4314
|
+
const awaitingIssue = createMockIssue({
|
|
4315
|
+
url: 'url1',
|
|
4316
|
+
title: 'Issue 1',
|
|
4317
|
+
labels: ['category:impl'],
|
|
4318
|
+
status: 'Awaiting Workspace',
|
|
4319
|
+
number: 1,
|
|
4320
|
+
itemId: 'item-1',
|
|
4321
|
+
});
|
|
4322
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
4323
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
4324
|
+
createMockStoryObjectMap([awaitingIssue]),
|
|
4325
|
+
);
|
|
4326
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
4327
|
+
stdout: '',
|
|
4328
|
+
stderr: '',
|
|
4329
|
+
exitCode: 0,
|
|
4330
|
+
});
|
|
4331
|
+
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
4332
|
+
{
|
|
4333
|
+
name: 'token-sonnet-exhausted',
|
|
4334
|
+
token: 'token-sonnet-exhausted',
|
|
4335
|
+
fiveHourUtilization: 0.1,
|
|
4336
|
+
sevenDayUtilization: 0,
|
|
4337
|
+
blocked: false,
|
|
4338
|
+
rejected: false,
|
|
4339
|
+
modelWeeklyLimits: {
|
|
4340
|
+
seven_day_sonnet: { rejected: true, resetsAt: futureReset },
|
|
4341
|
+
},
|
|
4342
|
+
},
|
|
4343
|
+
]);
|
|
4344
|
+
|
|
4345
|
+
await useCase.run({
|
|
4346
|
+
projectUrl: 'https://github.com/user/repo',
|
|
4347
|
+
defaultAgentName: 'agent1',
|
|
4348
|
+
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
4349
|
+
fallbackLlmModelName: 'claude-opus-4-8',
|
|
4350
|
+
defaultLlmAgentName: null,
|
|
4351
|
+
configFilePath: '/path/to/config.yml',
|
|
4352
|
+
maximumPreparingIssuesCount: null,
|
|
4353
|
+
utilizationPercentageThreshold: 90,
|
|
4354
|
+
allowedIssueAuthors: null,
|
|
4355
|
+
codexHomeCandidates: null,
|
|
4356
|
+
allowIssueCacheMinutes: 0,
|
|
4357
|
+
labelsAsLlmAgentName: null,
|
|
4358
|
+
});
|
|
4359
|
+
|
|
4360
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
|
|
4361
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][1][2]).toBe(
|
|
4362
|
+
'claude-opus-4-8',
|
|
4363
|
+
);
|
|
4364
|
+
});
|
|
4365
|
+
|
|
4366
|
+
it('skips preparation when the sonnet default is exhausted and the opus fallback is also exhausted via the generic seven_day weekly limit', async () => {
|
|
4367
|
+
const awaitingIssue = createMockIssue({
|
|
4368
|
+
url: 'url1',
|
|
4369
|
+
title: 'Issue 1',
|
|
4370
|
+
labels: ['category:impl'],
|
|
4371
|
+
status: 'Awaiting Workspace',
|
|
4372
|
+
number: 1,
|
|
4373
|
+
itemId: 'item-1',
|
|
4374
|
+
});
|
|
4375
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
4376
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
4377
|
+
createMockStoryObjectMap([awaitingIssue]),
|
|
4378
|
+
);
|
|
4379
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
4380
|
+
stdout: '',
|
|
4381
|
+
stderr: '',
|
|
4382
|
+
exitCode: 0,
|
|
4383
|
+
});
|
|
4384
|
+
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
4385
|
+
{
|
|
4386
|
+
name: 'token-fully-exhausted',
|
|
4387
|
+
token: 'token-fully-exhausted',
|
|
4388
|
+
fiveHourUtilization: 0.1,
|
|
4389
|
+
sevenDayUtilization: 0,
|
|
4390
|
+
blocked: false,
|
|
4391
|
+
rejected: false,
|
|
4392
|
+
modelWeeklyLimits: {
|
|
4393
|
+
seven_day_sonnet: { rejected: true, resetsAt: futureReset },
|
|
4394
|
+
seven_day: { rejected: true, resetsAt: futureReset },
|
|
4395
|
+
},
|
|
4396
|
+
},
|
|
4397
|
+
]);
|
|
4398
|
+
const consoleWarnSpy = jest
|
|
4399
|
+
.spyOn(console, 'warn')
|
|
4400
|
+
.mockImplementation(() => {});
|
|
4401
|
+
|
|
4402
|
+
await useCase.run({
|
|
4403
|
+
projectUrl: 'https://github.com/user/repo',
|
|
4404
|
+
defaultAgentName: 'agent1',
|
|
4405
|
+
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
4406
|
+
fallbackLlmModelName: null,
|
|
4407
|
+
defaultLlmAgentName: null,
|
|
4408
|
+
configFilePath: '/path/to/config.yml',
|
|
4409
|
+
maximumPreparingIssuesCount: null,
|
|
4410
|
+
utilizationPercentageThreshold: 90,
|
|
4411
|
+
allowedIssueAuthors: null,
|
|
4412
|
+
codexHomeCandidates: null,
|
|
4413
|
+
allowIssueCacheMinutes: 0,
|
|
4414
|
+
labelsAsLlmAgentName: null,
|
|
4415
|
+
});
|
|
4416
|
+
|
|
4417
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(0);
|
|
4418
|
+
expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(0);
|
|
4419
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
4420
|
+
expect.stringContaining('Skipping starting preparation'),
|
|
4421
|
+
);
|
|
4422
|
+
consoleWarnSpy.mockRestore();
|
|
4423
|
+
});
|
|
4424
|
+
|
|
4425
|
+
it('uses the sonnet default with no fallback when sonnet tokens are available', async () => {
|
|
4426
|
+
const awaitingIssue = createMockIssue({
|
|
4427
|
+
url: 'url1',
|
|
4428
|
+
title: 'Issue 1',
|
|
4429
|
+
labels: ['category:impl'],
|
|
4430
|
+
status: 'Awaiting Workspace',
|
|
4431
|
+
number: 1,
|
|
4432
|
+
itemId: 'item-1',
|
|
4433
|
+
});
|
|
4434
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
4435
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
4436
|
+
createMockStoryObjectMap([awaitingIssue]),
|
|
4437
|
+
);
|
|
4438
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
4439
|
+
stdout: '',
|
|
4440
|
+
stderr: '',
|
|
4441
|
+
exitCode: 0,
|
|
4442
|
+
});
|
|
4443
|
+
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
4444
|
+
{
|
|
4445
|
+
name: 'token-ok',
|
|
4446
|
+
token: 'token-ok',
|
|
4447
|
+
fiveHourUtilization: 0.1,
|
|
4448
|
+
sevenDayUtilization: 0,
|
|
4449
|
+
blocked: false,
|
|
4450
|
+
rejected: false,
|
|
4451
|
+
modelWeeklyLimits: {},
|
|
4452
|
+
},
|
|
4453
|
+
]);
|
|
4454
|
+
|
|
4455
|
+
await useCase.run({
|
|
4456
|
+
projectUrl: 'https://github.com/user/repo',
|
|
4457
|
+
defaultAgentName: 'agent1',
|
|
4458
|
+
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
4459
|
+
fallbackLlmModelName: null,
|
|
4460
|
+
defaultLlmAgentName: null,
|
|
4461
|
+
configFilePath: '/path/to/config.yml',
|
|
4462
|
+
maximumPreparingIssuesCount: null,
|
|
4463
|
+
utilizationPercentageThreshold: 90,
|
|
4464
|
+
allowedIssueAuthors: null,
|
|
4465
|
+
codexHomeCandidates: null,
|
|
4466
|
+
allowIssueCacheMinutes: 0,
|
|
4467
|
+
labelsAsLlmAgentName: null,
|
|
4468
|
+
});
|
|
4469
|
+
|
|
4470
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
|
|
4471
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][1][2]).toBe(
|
|
4472
|
+
'claude-sonnet-4-6',
|
|
4473
|
+
);
|
|
4474
|
+
});
|
|
4475
|
+
|
|
4476
|
+
it('does not fall back to opus for an issue whose llm-model label explicitly set the model even when the sonnet weekly limit is exhausted', async () => {
|
|
4477
|
+
const awaitingIssue = createMockIssue({
|
|
4478
|
+
url: 'url1',
|
|
4479
|
+
title: 'Issue 1',
|
|
4480
|
+
labels: ['category:impl', 'llm-model:claude-sonnet-4-6'],
|
|
4481
|
+
status: 'Awaiting Workspace',
|
|
4482
|
+
number: 1,
|
|
4483
|
+
itemId: 'item-1',
|
|
4484
|
+
});
|
|
4485
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
4486
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
4487
|
+
createMockStoryObjectMap([awaitingIssue]),
|
|
4488
|
+
);
|
|
4489
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
4490
|
+
stdout: '',
|
|
4491
|
+
stderr: '',
|
|
4492
|
+
exitCode: 0,
|
|
4493
|
+
});
|
|
4494
|
+
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
4495
|
+
{
|
|
4496
|
+
name: 'token-sonnet-exhausted',
|
|
4497
|
+
token: 'token-sonnet-exhausted',
|
|
4498
|
+
fiveHourUtilization: 0.1,
|
|
4499
|
+
sevenDayUtilization: 0,
|
|
4500
|
+
blocked: false,
|
|
4501
|
+
rejected: false,
|
|
4502
|
+
modelWeeklyLimits: {
|
|
4503
|
+
seven_day_sonnet: { rejected: true, resetsAt: futureReset },
|
|
4504
|
+
},
|
|
4505
|
+
},
|
|
4506
|
+
]);
|
|
4507
|
+
|
|
4508
|
+
await useCase.run({
|
|
4509
|
+
projectUrl: 'https://github.com/user/repo',
|
|
4510
|
+
defaultAgentName: 'agent1',
|
|
4511
|
+
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
4512
|
+
fallbackLlmModelName: null,
|
|
4513
|
+
defaultLlmAgentName: null,
|
|
4514
|
+
configFilePath: '/path/to/config.yml',
|
|
4515
|
+
maximumPreparingIssuesCount: null,
|
|
4516
|
+
utilizationPercentageThreshold: 90,
|
|
4517
|
+
allowedIssueAuthors: null,
|
|
4518
|
+
codexHomeCandidates: null,
|
|
4519
|
+
allowIssueCacheMinutes: 0,
|
|
4520
|
+
labelsAsLlmAgentName: null,
|
|
4521
|
+
});
|
|
4522
|
+
|
|
4523
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
|
|
4524
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][1][2]).toBe(
|
|
4525
|
+
'claude-sonnet-4-6',
|
|
4526
|
+
);
|
|
4527
|
+
});
|
|
4528
|
+
|
|
4529
|
+
it('does not fall back to opus when sonnet tokens are merely throttled by 5-hour utilization rather than the weekly limit', async () => {
|
|
4530
|
+
const awaitingIssue = createMockIssue({
|
|
4531
|
+
url: 'url1',
|
|
4532
|
+
title: 'Issue 1',
|
|
4533
|
+
labels: ['category:impl'],
|
|
4534
|
+
status: 'Awaiting Workspace',
|
|
4535
|
+
number: 1,
|
|
4536
|
+
itemId: 'item-1',
|
|
4537
|
+
});
|
|
4538
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
4539
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
4540
|
+
createMockStoryObjectMap([awaitingIssue]),
|
|
4541
|
+
);
|
|
4542
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
4543
|
+
stdout: '',
|
|
4544
|
+
stderr: '',
|
|
4545
|
+
exitCode: 0,
|
|
4546
|
+
});
|
|
4547
|
+
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
4548
|
+
{
|
|
4549
|
+
name: 'token-throttled',
|
|
4550
|
+
token: 'token-throttled',
|
|
4551
|
+
fiveHourUtilization: 0.95,
|
|
4552
|
+
sevenDayUtilization: 0,
|
|
4553
|
+
blocked: false,
|
|
4554
|
+
rejected: false,
|
|
4555
|
+
modelWeeklyLimits: {},
|
|
4556
|
+
},
|
|
4557
|
+
]);
|
|
4558
|
+
const consoleWarnSpy = jest
|
|
4559
|
+
.spyOn(console, 'warn')
|
|
4560
|
+
.mockImplementation(() => {});
|
|
4561
|
+
|
|
4562
|
+
await useCase.run({
|
|
4563
|
+
projectUrl: 'https://github.com/user/repo',
|
|
4564
|
+
defaultAgentName: 'agent1',
|
|
4565
|
+
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
4566
|
+
fallbackLlmModelName: null,
|
|
4567
|
+
defaultLlmAgentName: null,
|
|
4568
|
+
configFilePath: '/path/to/config.yml',
|
|
4569
|
+
maximumPreparingIssuesCount: null,
|
|
4570
|
+
utilizationPercentageThreshold: 90,
|
|
4571
|
+
allowedIssueAuthors: null,
|
|
4572
|
+
codexHomeCandidates: null,
|
|
4573
|
+
allowIssueCacheMinutes: 0,
|
|
4574
|
+
labelsAsLlmAgentName: null,
|
|
4575
|
+
});
|
|
4576
|
+
|
|
4577
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(0);
|
|
4578
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
4579
|
+
expect.stringContaining('Skipping starting preparation'),
|
|
4580
|
+
);
|
|
4581
|
+
consoleWarnSpy.mockRestore();
|
|
4582
|
+
});
|
|
4583
|
+
});
|
|
4175
4584
|
});
|
|
4176
4585
|
|
|
4177
4586
|
describe('StartPreparationUseCase.buildRotationOrder', () => {
|