github-issue-tower-defence-management 1.63.1 → 1.65.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 +1 -1
- package/bin/domain/usecases/StartPreparationUseCase.js +75 -28
- package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
- package/package.json +1 -1
- package/src/domain/usecases/StartPreparationUseCase.test.ts +231 -2
- package/src/domain/usecases/StartPreparationUseCase.ts +106 -42
- package/types/domain/usecases/StartPreparationUseCase.d.ts +3 -1
- package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [1.65.0](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.64.0...v1.65.0) (2026-05-26)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **core:** log skipped issues when allowedIssueAuthors filter is active ([8ab1a29](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/8ab1a29b88b6d0f37fbac596ce4166c1f8d87b5a)), closes [#620](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/issues/620)
|
|
7
|
+
|
|
8
|
+
# [1.64.0](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.63.1...v1.64.0) (2026-05-26)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **core:** route spawn to a usable model per token using per-model 7d availability ([f3bdf07](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/f3bdf07dea62cf01b62647942cc8175604d6d826)), closes [#672](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/issues/672)
|
|
14
|
+
|
|
1
15
|
## [1.63.1](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.63.0...v1.63.1) (2026-05-25)
|
|
2
16
|
|
|
3
17
|
|
package/README.md
CHANGED
|
@@ -213,7 +213,7 @@ When `claudeCodeOauthTokenListJsonPath` is set, `startDaemon` distributes prepar
|
|
|
213
213
|
|
|
214
214
|
2. Local reverse proxy (`127.0.0.1:8787`): on each `startDaemon` run, the daemon TCP-probes the port. If nothing responds, it spawns a detached child running `bin/adapter/proxy/proxyEntry.js`. The proxy forwards every request to `api.anthropic.com`, observes the `anthropic-ratelimit-unified-*` response headers, and writes them to a per-token cache file at `${XDG_CACHE_HOME:-~/.cache}/tdpm/ratelimit/<sha256-of-token>.json`. The cache file stores the latest 5-hour and 7-day utilization, reset epochs, and the unified, 5-hour, and 7-day statuses (used to detect `blocked` and `rejected` state per window). In addition to the unified headers, the proxy inspects the streamed response body for `rate_limit` events (objects carrying `rateLimitType`, `status`, and `resetsAt`) and records the model-specific weekly limits — at minimum `seven_day_sonnet` and `seven_day` — per token. These model-specific weekly limits are exposed only in the response body, never in the unified headers, so a token can appear healthy on `anthropic-ratelimit-unified-7d-*` while its Sonnet weekly limit is exhausted.
|
|
215
215
|
|
|
216
|
-
3. Selection: before spawning each `aw` job, the daemon reads every token's cache file. A cached observation is treated as expired once its reset epoch has passed: when the current time is past the 5-hour reset, that token's 5-hour utilization is treated as `0` and any 5-hour-window rejection is cleared; a 7-day-window rejection is cleared once the 7-day reset has passed; a model-specific weekly limit rejection is cleared once that limit's `resetsAt` has passed. This stale-reset expiry prevents a token that has actually recovered from being locked out of rotation forever (an excluded token receives no new requests, so the proxy never re-observes it). After expiry normalization, tokens whose status is `blocked
|
|
216
|
+
3. Selection: before spawning each `aw` job, the daemon reads every token's cache file. A cached observation is treated as expired once its reset epoch has passed: when the current time is past the 5-hour reset, that token's 5-hour utilization is treated as `0` and any 5-hour-window rejection is cleared; a 7-day-window rejection is cleared once the 7-day reset has passed; a model-specific weekly limit rejection is cleared once that limit's `resetsAt` has passed. This stale-reset expiry prevents a token that has actually recovered from being locked out of rotation forever (an excluded token receives no new requests, so the proxy never re-observes it). After expiry normalization, tokens whose status is `blocked` or whose remaining (non-expired) rejection is still active are excluded. Tokens are also excluded when all candidate model-specific weekly limits are exhausted or the general `seven_day` limit is rejected; however, when only the default model's weekly limit is rejected (e.g., `seven_day_sonnet`), the token remains in rotation and is spawned with a fallback model whose limit is still available (e.g., `seven_day_opus`). The model name maps to a limit type: a model name containing `sonnet` maps to `seven_day_sonnet`, one containing `opus` maps to `seven_day_opus`, otherwise `seven_day`; the generic `seven_day` rejection also excludes regardless of model. The remaining tokens are sorted by 5-hour utilization ascending. Each available token receives up to six concurrent preparation slots through 80% 5-hour utilization; above 80%, its slot count decays exponentially; at 95% or higher, its slot count is 0. The first token (lowest utilization) is selected for the next spawn, then the next, weighted round-robin by remaining slots, for the duration of the run. The effective preparation limit is the sum of available token slots; a lower explicit `maximumPreparingIssuesCount` remains honored. When a token list is configured but no token has remaining slots, preparation is skipped for that run. The selected token, the selected model (which may differ from the default when a fallback model was chosen), and the proxy URL (`http://127.0.0.1:8787`) are passed to the child `aw` process as `CLAUDE_CODE_OAUTH_TOKEN`, the model argument, and `ANTHROPIC_BASE_URL` environment variables. The child inherits the parent process's environment, so no further wiring is required inside `aw`.
|
|
217
217
|
|
|
218
218
|
When `claudeCodeOauthTokenListJsonPath` is unset, no proxy is started and `aw` runs with whatever `CLAUDE_CODE_OAUTH_TOKEN` and `ANTHROPIC_BASE_URL` are already in the environment.
|
|
219
219
|
|
|
@@ -12,6 +12,10 @@ class StartPreparationUseCase {
|
|
|
12
12
|
this.issueRepository = issueRepository;
|
|
13
13
|
this.localCommandRunner = localCommandRunner;
|
|
14
14
|
this.claudeTokenUsageRepository = claudeTokenUsageRepository;
|
|
15
|
+
this.KNOWN_MODEL_SPECIFIC_LIMIT_TYPES = [
|
|
16
|
+
'seven_day_sonnet',
|
|
17
|
+
'seven_day_opus',
|
|
18
|
+
];
|
|
15
19
|
this.weeklyLimitTypeForModel = (modelName) => {
|
|
16
20
|
const normalized = (modelName ?? '').toLowerCase();
|
|
17
21
|
if (normalized.includes('sonnet'))
|
|
@@ -20,12 +24,38 @@ class StartPreparationUseCase {
|
|
|
20
24
|
return 'seven_day_opus';
|
|
21
25
|
return 'seven_day';
|
|
22
26
|
};
|
|
23
|
-
this.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
this.deriveFallbackModelName = (limitType, defaultModelName) => {
|
|
28
|
+
if (limitType === this.weeklyLimitTypeForModel(defaultModelName)) {
|
|
29
|
+
return defaultModelName;
|
|
30
|
+
}
|
|
31
|
+
if (limitType === 'seven_day_opus' &&
|
|
32
|
+
defaultModelName.toLowerCase().includes('sonnet')) {
|
|
33
|
+
return defaultModelName.replace(/sonnet/gi, 'opus');
|
|
34
|
+
}
|
|
35
|
+
if (limitType === 'seven_day_sonnet' &&
|
|
36
|
+
defaultModelName.toLowerCase().includes('opus')) {
|
|
37
|
+
return defaultModelName.replace(/opus/gi, 'sonnet');
|
|
38
|
+
}
|
|
39
|
+
return defaultModelName;
|
|
40
|
+
};
|
|
41
|
+
this.selectModelForToken = (usage, defaultModelName) => {
|
|
42
|
+
const generalLimit = usage.modelWeeklyLimits['seven_day'];
|
|
43
|
+
if (generalLimit !== undefined && generalLimit.rejected)
|
|
44
|
+
return null;
|
|
45
|
+
if (defaultModelName === null)
|
|
46
|
+
return null;
|
|
47
|
+
const defaultLimitType = this.weeklyLimitTypeForModel(defaultModelName);
|
|
48
|
+
const candidateLimitTypes = [
|
|
49
|
+
defaultLimitType,
|
|
50
|
+
...this.KNOWN_MODEL_SPECIFIC_LIMIT_TYPES.filter((t) => t !== defaultLimitType),
|
|
51
|
+
];
|
|
52
|
+
for (const limitType of candidateLimitTypes) {
|
|
53
|
+
const limit = usage.modelWeeklyLimits[limitType];
|
|
54
|
+
if (limit === undefined || !limit.rejected) {
|
|
55
|
+
return this.deriveFallbackModelName(limitType, defaultModelName);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
29
59
|
};
|
|
30
60
|
this.maximumPreparingProcessCountForToken = (fiveHourUtilization) => {
|
|
31
61
|
if (fiveHourUtilization <= PROCESS_COUNT_DECAY_START_UTILIZATION) {
|
|
@@ -43,20 +73,27 @@ class StartPreparationUseCase {
|
|
|
43
73
|
return Math.max(1, Math.floor(MAXIMUM_PREPARING_PROCESS_COUNT_PER_TOKEN * remainingRatio));
|
|
44
74
|
};
|
|
45
75
|
this.selectRotationTokens = (tokenUsages, modelName) => {
|
|
46
|
-
const weeklyLimitType = this.weeklyLimitTypeForModel(modelName);
|
|
47
76
|
return tokenUsages
|
|
48
77
|
.filter((usage) => !usage.blocked)
|
|
49
78
|
.filter((usage) => !usage.rejected)
|
|
50
|
-
.
|
|
51
|
-
.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
79
|
+
.flatMap((usage) => {
|
|
80
|
+
const selectedModel = this.selectModelForToken(usage, modelName);
|
|
81
|
+
if (selectedModel === null)
|
|
82
|
+
return [];
|
|
83
|
+
return [
|
|
84
|
+
{
|
|
85
|
+
token: usage.token,
|
|
86
|
+
model: selectedModel,
|
|
87
|
+
fiveHourUtilization: usage.fiveHourUtilization,
|
|
88
|
+
maximumPreparingProcessCount: this.maximumPreparingProcessCountForToken(usage.fiveHourUtilization),
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
})
|
|
56
92
|
.filter((usage) => usage.maximumPreparingProcessCount > 0)
|
|
57
93
|
.sort((a, b) => a.fiveHourUtilization - b.fiveHourUtilization)
|
|
58
94
|
.map((usage) => ({
|
|
59
95
|
token: usage.token,
|
|
96
|
+
model: usage.model,
|
|
60
97
|
maximumPreparingProcessCount: usage.maximumPreparingProcessCount,
|
|
61
98
|
}));
|
|
62
99
|
};
|
|
@@ -66,7 +103,7 @@ class StartPreparationUseCase {
|
|
|
66
103
|
for (let i = 0; i < slotCount; i++) {
|
|
67
104
|
tokenSlots.push(...rotationTokens
|
|
68
105
|
.filter((token) => i < token.maximumPreparingProcessCount)
|
|
69
|
-
.map((token) => token.token));
|
|
106
|
+
.map((token) => ({ token: token.token, model: token.model })));
|
|
70
107
|
}
|
|
71
108
|
return tokenSlots;
|
|
72
109
|
};
|
|
@@ -78,10 +115,12 @@ class StartPreparationUseCase {
|
|
|
78
115
|
};
|
|
79
116
|
this.buildRotationOrder = (tokenUsages, utilizationPercentageThreshold, modelName) => {
|
|
80
117
|
const weeklyLimitType = this.weeklyLimitTypeForModel(modelName);
|
|
118
|
+
const isWeeklyLimitRejected = (usage) => usage.modelWeeklyLimits[weeklyLimitType]?.rejected === true ||
|
|
119
|
+
usage.modelWeeklyLimits['seven_day']?.rejected === true;
|
|
81
120
|
const selectedTokens = tokenUsages
|
|
82
121
|
.filter((usage) => !usage.blocked)
|
|
83
122
|
.filter((usage) => !usage.rejected)
|
|
84
|
-
.filter((usage) => !
|
|
123
|
+
.filter((usage) => !isWeeklyLimitRejected(usage))
|
|
85
124
|
.filter((usage) => this.maximumPreparingProcessCountForToken(usage.fiveHourUtilization) >
|
|
86
125
|
0)
|
|
87
126
|
.sort((a, b) => a.fiveHourUtilization - b.fiveHourUtilization);
|
|
@@ -95,7 +134,7 @@ class StartPreparationUseCase {
|
|
|
95
134
|
rejected: usage.rejected,
|
|
96
135
|
thresholdExcluded: !usage.blocked &&
|
|
97
136
|
!usage.rejected &&
|
|
98
|
-
!
|
|
137
|
+
!isWeeklyLimitRejected(usage) &&
|
|
99
138
|
this.maximumPreparingProcessCountForToken(usage.fiveHourUtilization) === 0,
|
|
100
139
|
}));
|
|
101
140
|
const selectedEntries = selectedTokens.map((usage) => ({
|
|
@@ -117,7 +156,7 @@ class StartPreparationUseCase {
|
|
|
117
156
|
if (tokenUsages.length > 0) {
|
|
118
157
|
const ranked = this.selectRotationTokens(tokenUsages, params.defaultLlmModelName);
|
|
119
158
|
if (ranked.length === 0) {
|
|
120
|
-
console.warn(`All ${tokenUsages.length} configured Claude OAuth token(s) are unavailable (blocked, rejected,
|
|
159
|
+
console.warn(`All ${tokenUsages.length} configured Claude OAuth token(s) are unavailable (blocked, rejected, all model weekly limits exhausted, or 5h utilization >= 95%). Skipping starting preparation.`);
|
|
121
160
|
return { rotationOrder };
|
|
122
161
|
}
|
|
123
162
|
await this.claudeTokenUsageRepository.ensureObservable();
|
|
@@ -158,6 +197,12 @@ class StartPreparationUseCase {
|
|
|
158
197
|
}
|
|
159
198
|
if (params.allowedIssueAuthors !== null &&
|
|
160
199
|
!params.allowedIssueAuthors.includes(issue.author)) {
|
|
200
|
+
if (issue.author === '') {
|
|
201
|
+
console.warn(`Skipping issue ${issue.url}: author is unknown (empty string); deny-by-default when allowedIssueAuthors is configured.`);
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
console.warn(`Skipping issue ${issue.url}: author '${issue.author}' is not in the allowedIssueAuthors list.`);
|
|
205
|
+
}
|
|
161
206
|
continue;
|
|
162
207
|
}
|
|
163
208
|
const agent = issue.labels
|
|
@@ -174,7 +219,7 @@ class StartPreparationUseCase {
|
|
|
174
219
|
.find((label) => label.startsWith('llm-model:'))
|
|
175
220
|
?.replace('llm-model:', '')
|
|
176
221
|
.trim() || params.defaultLlmModelName;
|
|
177
|
-
if (!model) {
|
|
222
|
+
if (!model && rotationTokenSlots === null) {
|
|
178
223
|
console.error(`No LLM model configured for issue ${issue.url}. Provide --defaultLlmModelName or add an llm-model: label.`);
|
|
179
224
|
continue;
|
|
180
225
|
}
|
|
@@ -230,10 +275,21 @@ class StartPreparationUseCase {
|
|
|
230
275
|
}
|
|
231
276
|
await this.issueRepository.updateStatus(project, issue, preparationStatusOption.id);
|
|
232
277
|
issue.status = WorkflowStatus_1.PREPARATION_STATUS_NAME;
|
|
278
|
+
let spawnEnv;
|
|
279
|
+
let spawnModel = model ?? '';
|
|
280
|
+
if (rotationTokenSlots !== null && proxyBaseUrl !== null) {
|
|
281
|
+
const selected = rotationTokenSlots[(currentPreparationIssueCount + startedInThisRunCount) %
|
|
282
|
+
rotationTokenSlots.length];
|
|
283
|
+
spawnModel = selected.model;
|
|
284
|
+
spawnEnv = {
|
|
285
|
+
CLAUDE_CODE_OAUTH_TOKEN: selected.token,
|
|
286
|
+
ANTHROPIC_BASE_URL: proxyBaseUrl,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
233
289
|
const awArgs = [
|
|
234
290
|
issue.url,
|
|
235
291
|
agent,
|
|
236
|
-
|
|
292
|
+
spawnModel,
|
|
237
293
|
'--configFilePath',
|
|
238
294
|
params.configFilePath,
|
|
239
295
|
'--branch',
|
|
@@ -244,15 +300,6 @@ class StartPreparationUseCase {
|
|
|
244
300
|
const codexHome = params.codexHomeCandidates[startedInThisRunCount % params.codexHomeCandidates.length];
|
|
245
301
|
awArgs.push('--codexHome', codexHome);
|
|
246
302
|
}
|
|
247
|
-
let spawnEnv;
|
|
248
|
-
if (rotationTokenSlots !== null && proxyBaseUrl !== null) {
|
|
249
|
-
const selected = rotationTokenSlots[(currentPreparationIssueCount + startedInThisRunCount) %
|
|
250
|
-
rotationTokenSlots.length];
|
|
251
|
-
spawnEnv = {
|
|
252
|
-
CLAUDE_CODE_OAUTH_TOKEN: selected,
|
|
253
|
-
ANTHROPIC_BASE_URL: proxyBaseUrl,
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
303
|
await this.localCommandRunner.runCommand('aw', awArgs, spawnEnv ? { env: spawnEnv } : undefined);
|
|
257
304
|
startedInThisRunCount++;
|
|
258
305
|
updatedCurrentPreparationIssueCount++;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StartPreparationUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/StartPreparationUseCase.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"StartPreparationUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/StartPreparationUseCase.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1712,6 +1712,9 @@ describe('StartPreparationUseCase', () => {
|
|
|
1712
1712
|
stderr: '',
|
|
1713
1713
|
exitCode: 0,
|
|
1714
1714
|
});
|
|
1715
|
+
const consoleWarnSpy = jest
|
|
1716
|
+
.spyOn(console, 'warn')
|
|
1717
|
+
.mockImplementation(() => {});
|
|
1715
1718
|
|
|
1716
1719
|
await useCase.run({
|
|
1717
1720
|
projectUrl: 'https://github.com/user/repo',
|
|
@@ -1732,6 +1735,10 @@ describe('StartPreparationUseCase', () => {
|
|
|
1732
1735
|
status: 'Preparation',
|
|
1733
1736
|
});
|
|
1734
1737
|
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
|
|
1738
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
1739
|
+
`Skipping issue https://github.com/user/repo/issues/2: author 'user3' is not in the allowedIssueAuthors list.`,
|
|
1740
|
+
);
|
|
1741
|
+
consoleWarnSpy.mockRestore();
|
|
1735
1742
|
});
|
|
1736
1743
|
|
|
1737
1744
|
it('should process all issues when allowedIssueAuthors is null', async () => {
|
|
@@ -1804,6 +1811,9 @@ describe('StartPreparationUseCase', () => {
|
|
|
1804
1811
|
stderr: '',
|
|
1805
1812
|
exitCode: 0,
|
|
1806
1813
|
});
|
|
1814
|
+
const consoleWarnSpy = jest
|
|
1815
|
+
.spyOn(console, 'warn')
|
|
1816
|
+
.mockImplementation(() => {});
|
|
1807
1817
|
|
|
1808
1818
|
await useCase.run({
|
|
1809
1819
|
projectUrl: 'https://github.com/user/repo',
|
|
@@ -1823,6 +1833,10 @@ describe('StartPreparationUseCase', () => {
|
|
|
1823
1833
|
url: 'https://github.com/user/repo/issues/2',
|
|
1824
1834
|
});
|
|
1825
1835
|
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
|
|
1836
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
1837
|
+
'Skipping issue https://github.com/user/repo/issues/1: author is unknown (empty string); deny-by-default when allowedIssueAuthors is configured.',
|
|
1838
|
+
);
|
|
1839
|
+
consoleWarnSpy.mockRestore();
|
|
1826
1840
|
});
|
|
1827
1841
|
|
|
1828
1842
|
it('should skip issue with empty author when allowedIssueAuthors is set', async () => {
|
|
@@ -1843,6 +1857,9 @@ describe('StartPreparationUseCase', () => {
|
|
|
1843
1857
|
stderr: '',
|
|
1844
1858
|
exitCode: 0,
|
|
1845
1859
|
});
|
|
1860
|
+
const consoleWarnSpy = jest
|
|
1861
|
+
.spyOn(console, 'warn')
|
|
1862
|
+
.mockImplementation(() => {});
|
|
1846
1863
|
|
|
1847
1864
|
await useCase.run({
|
|
1848
1865
|
projectUrl: 'https://github.com/user/repo',
|
|
@@ -1859,6 +1876,10 @@ describe('StartPreparationUseCase', () => {
|
|
|
1859
1876
|
|
|
1860
1877
|
expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(0);
|
|
1861
1878
|
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(0);
|
|
1879
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
1880
|
+
'Skipping issue https://github.com/user/repo/issues/1: author is unknown (empty string); deny-by-default when allowedIssueAuthors is configured.',
|
|
1881
|
+
);
|
|
1882
|
+
consoleWarnSpy.mockRestore();
|
|
1862
1883
|
});
|
|
1863
1884
|
|
|
1864
1885
|
it('should not pass --codexHome when codexHomeCandidates is null', async () => {
|
|
@@ -3148,7 +3169,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
3148
3169
|
expect(mockLocalCommandRunner.runCommand.mock.calls[0][2]).toBeUndefined();
|
|
3149
3170
|
});
|
|
3150
3171
|
|
|
3151
|
-
it('should
|
|
3172
|
+
it('should keep a token in rotation with opus model when seven_day_sonnet is rejected and seven_day_opus is available', async () => {
|
|
3152
3173
|
const awaitingIssue = createMockIssue({
|
|
3153
3174
|
url: 'url1',
|
|
3154
3175
|
title: 'Issue 1',
|
|
@@ -3204,10 +3225,13 @@ describe('StartPreparationUseCase', () => {
|
|
|
3204
3225
|
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
|
|
3205
3226
|
expect(mockLocalCommandRunner.runCommand.mock.calls[0][2]).toEqual({
|
|
3206
3227
|
env: {
|
|
3207
|
-
CLAUDE_CODE_OAUTH_TOKEN: 'token-
|
|
3228
|
+
CLAUDE_CODE_OAUTH_TOKEN: 'token-sonnet-exhausted',
|
|
3208
3229
|
ANTHROPIC_BASE_URL: 'http://127.0.0.1:8787',
|
|
3209
3230
|
},
|
|
3210
3231
|
});
|
|
3232
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][1][2]).toBe(
|
|
3233
|
+
'claude-opus-4-6',
|
|
3234
|
+
);
|
|
3211
3235
|
});
|
|
3212
3236
|
|
|
3213
3237
|
it('should re-admit a token whose seven_day_sonnet rejection has been cleared by stale-reset expiry', async () => {
|
|
@@ -3395,6 +3419,211 @@ describe('StartPreparationUseCase', () => {
|
|
|
3395
3419
|
},
|
|
3396
3420
|
});
|
|
3397
3421
|
});
|
|
3422
|
+
|
|
3423
|
+
it('should include a token in rotation with opus model when seven_day_sonnet is rejected but seven_day_opus is available', async () => {
|
|
3424
|
+
const awaitingIssue = createMockIssue({
|
|
3425
|
+
url: 'url1',
|
|
3426
|
+
title: 'Issue 1',
|
|
3427
|
+
labels: ['category:impl'],
|
|
3428
|
+
status: 'Awaiting Workspace',
|
|
3429
|
+
number: 1,
|
|
3430
|
+
itemId: 'item-1',
|
|
3431
|
+
});
|
|
3432
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
3433
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
3434
|
+
createMockStoryObjectMap([awaitingIssue]),
|
|
3435
|
+
);
|
|
3436
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
3437
|
+
stdout: '',
|
|
3438
|
+
stderr: '',
|
|
3439
|
+
exitCode: 0,
|
|
3440
|
+
});
|
|
3441
|
+
const futureReset = Math.floor(Date.now() / 1000) + 3600;
|
|
3442
|
+
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
3443
|
+
{
|
|
3444
|
+
token: 'token-sonnet-exhausted',
|
|
3445
|
+
fiveHourUtilization: 0.1,
|
|
3446
|
+
blocked: false,
|
|
3447
|
+
rejected: false,
|
|
3448
|
+
modelWeeklyLimits: {
|
|
3449
|
+
seven_day_sonnet: { rejected: true, resetsAt: futureReset },
|
|
3450
|
+
},
|
|
3451
|
+
},
|
|
3452
|
+
]);
|
|
3453
|
+
|
|
3454
|
+
await useCase.run({
|
|
3455
|
+
projectUrl: 'https://github.com/user/repo',
|
|
3456
|
+
defaultAgentName: 'agent1',
|
|
3457
|
+
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
3458
|
+
defaultLlmAgentName: null,
|
|
3459
|
+
configFilePath: '/path/to/config.yml',
|
|
3460
|
+
maximumPreparingIssuesCount: null,
|
|
3461
|
+
utilizationPercentageThreshold: 90,
|
|
3462
|
+
allowedIssueAuthors: null,
|
|
3463
|
+
codexHomeCandidates: null,
|
|
3464
|
+
allowIssueCacheMinutes: 0,
|
|
3465
|
+
});
|
|
3466
|
+
|
|
3467
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
|
|
3468
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][1][2]).toBe(
|
|
3469
|
+
'claude-opus-4-6',
|
|
3470
|
+
);
|
|
3471
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][2]).toEqual({
|
|
3472
|
+
env: {
|
|
3473
|
+
CLAUDE_CODE_OAUTH_TOKEN: 'token-sonnet-exhausted',
|
|
3474
|
+
ANTHROPIC_BASE_URL: 'http://127.0.0.1:8787',
|
|
3475
|
+
},
|
|
3476
|
+
});
|
|
3477
|
+
});
|
|
3478
|
+
|
|
3479
|
+
it('should exclude a token from rotation when both seven_day_sonnet and seven_day_opus weekly limits are rejected', async () => {
|
|
3480
|
+
const awaitingIssue = createMockIssue({
|
|
3481
|
+
url: 'url1',
|
|
3482
|
+
title: 'Issue 1',
|
|
3483
|
+
labels: ['category:impl'],
|
|
3484
|
+
status: 'Awaiting Workspace',
|
|
3485
|
+
number: 1,
|
|
3486
|
+
itemId: 'item-1',
|
|
3487
|
+
});
|
|
3488
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
3489
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
3490
|
+
createMockStoryObjectMap([awaitingIssue]),
|
|
3491
|
+
);
|
|
3492
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
3493
|
+
stdout: '',
|
|
3494
|
+
stderr: '',
|
|
3495
|
+
exitCode: 0,
|
|
3496
|
+
});
|
|
3497
|
+
const futureReset = Math.floor(Date.now() / 1000) + 3600;
|
|
3498
|
+
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
3499
|
+
{
|
|
3500
|
+
token: 'token-all-exhausted',
|
|
3501
|
+
fiveHourUtilization: 0.1,
|
|
3502
|
+
blocked: false,
|
|
3503
|
+
rejected: false,
|
|
3504
|
+
modelWeeklyLimits: {
|
|
3505
|
+
seven_day_sonnet: { rejected: true, resetsAt: futureReset },
|
|
3506
|
+
seven_day_opus: { rejected: true, resetsAt: futureReset },
|
|
3507
|
+
},
|
|
3508
|
+
},
|
|
3509
|
+
]);
|
|
3510
|
+
|
|
3511
|
+
await useCase.run({
|
|
3512
|
+
projectUrl: 'https://github.com/user/repo',
|
|
3513
|
+
defaultAgentName: 'agent1',
|
|
3514
|
+
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
3515
|
+
defaultLlmAgentName: null,
|
|
3516
|
+
configFilePath: '/path/to/config.yml',
|
|
3517
|
+
maximumPreparingIssuesCount: null,
|
|
3518
|
+
utilizationPercentageThreshold: 90,
|
|
3519
|
+
allowedIssueAuthors: null,
|
|
3520
|
+
codexHomeCandidates: null,
|
|
3521
|
+
allowIssueCacheMinutes: 0,
|
|
3522
|
+
});
|
|
3523
|
+
|
|
3524
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(0);
|
|
3525
|
+
});
|
|
3526
|
+
|
|
3527
|
+
it('should use default model for a token with no modelWeeklyLimits entries', async () => {
|
|
3528
|
+
const awaitingIssue = createMockIssue({
|
|
3529
|
+
url: 'url1',
|
|
3530
|
+
title: 'Issue 1',
|
|
3531
|
+
labels: ['category:impl'],
|
|
3532
|
+
status: 'Awaiting Workspace',
|
|
3533
|
+
number: 1,
|
|
3534
|
+
itemId: 'item-1',
|
|
3535
|
+
});
|
|
3536
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
3537
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
3538
|
+
createMockStoryObjectMap([awaitingIssue]),
|
|
3539
|
+
);
|
|
3540
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
3541
|
+
stdout: '',
|
|
3542
|
+
stderr: '',
|
|
3543
|
+
exitCode: 0,
|
|
3544
|
+
});
|
|
3545
|
+
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
3546
|
+
{
|
|
3547
|
+
token: 'token-no-limits',
|
|
3548
|
+
fiveHourUtilization: 0.1,
|
|
3549
|
+
blocked: false,
|
|
3550
|
+
rejected: false,
|
|
3551
|
+
modelWeeklyLimits: {},
|
|
3552
|
+
},
|
|
3553
|
+
]);
|
|
3554
|
+
|
|
3555
|
+
await useCase.run({
|
|
3556
|
+
projectUrl: 'https://github.com/user/repo',
|
|
3557
|
+
defaultAgentName: 'agent1',
|
|
3558
|
+
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
3559
|
+
defaultLlmAgentName: null,
|
|
3560
|
+
configFilePath: '/path/to/config.yml',
|
|
3561
|
+
maximumPreparingIssuesCount: null,
|
|
3562
|
+
utilizationPercentageThreshold: 90,
|
|
3563
|
+
allowedIssueAuthors: null,
|
|
3564
|
+
codexHomeCandidates: null,
|
|
3565
|
+
allowIssueCacheMinutes: 0,
|
|
3566
|
+
});
|
|
3567
|
+
|
|
3568
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
|
|
3569
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][1][2]).toBe(
|
|
3570
|
+
'claude-sonnet-4-6',
|
|
3571
|
+
);
|
|
3572
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][2]).toEqual({
|
|
3573
|
+
env: {
|
|
3574
|
+
CLAUDE_CODE_OAUTH_TOKEN: 'token-no-limits',
|
|
3575
|
+
ANTHROPIC_BASE_URL: 'http://127.0.0.1:8787',
|
|
3576
|
+
},
|
|
3577
|
+
});
|
|
3578
|
+
});
|
|
3579
|
+
|
|
3580
|
+
it('should exclude a token when seven_day general limit is rejected even if per-model limits are available', async () => {
|
|
3581
|
+
const awaitingIssue = createMockIssue({
|
|
3582
|
+
url: 'url1',
|
|
3583
|
+
title: 'Issue 1',
|
|
3584
|
+
labels: ['category:impl'],
|
|
3585
|
+
status: 'Awaiting Workspace',
|
|
3586
|
+
number: 1,
|
|
3587
|
+
itemId: 'item-1',
|
|
3588
|
+
});
|
|
3589
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
3590
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
3591
|
+
createMockStoryObjectMap([awaitingIssue]),
|
|
3592
|
+
);
|
|
3593
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
3594
|
+
stdout: '',
|
|
3595
|
+
stderr: '',
|
|
3596
|
+
exitCode: 0,
|
|
3597
|
+
});
|
|
3598
|
+
const futureReset = Math.floor(Date.now() / 1000) + 3600;
|
|
3599
|
+
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
3600
|
+
{
|
|
3601
|
+
token: 'token-general-limit-rejected',
|
|
3602
|
+
fiveHourUtilization: 0.1,
|
|
3603
|
+
blocked: false,
|
|
3604
|
+
rejected: false,
|
|
3605
|
+
modelWeeklyLimits: {
|
|
3606
|
+
seven_day: { rejected: true, resetsAt: futureReset },
|
|
3607
|
+
seven_day_sonnet: { rejected: false, resetsAt: futureReset },
|
|
3608
|
+
},
|
|
3609
|
+
},
|
|
3610
|
+
]);
|
|
3611
|
+
|
|
3612
|
+
await useCase.run({
|
|
3613
|
+
projectUrl: 'https://github.com/user/repo',
|
|
3614
|
+
defaultAgentName: 'agent1',
|
|
3615
|
+
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
3616
|
+
defaultLlmAgentName: null,
|
|
3617
|
+
configFilePath: '/path/to/config.yml',
|
|
3618
|
+
maximumPreparingIssuesCount: null,
|
|
3619
|
+
utilizationPercentageThreshold: 90,
|
|
3620
|
+
allowedIssueAuthors: null,
|
|
3621
|
+
codexHomeCandidates: null,
|
|
3622
|
+
allowIssueCacheMinutes: 0,
|
|
3623
|
+
});
|
|
3624
|
+
|
|
3625
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(0);
|
|
3626
|
+
});
|
|
3398
3627
|
});
|
|
3399
3628
|
|
|
3400
3629
|
describe('StartPreparationUseCase.buildRotationOrder', () => {
|
|
@@ -15,6 +15,7 @@ const PROCESS_COUNT_DECAY_STEEPNESS = 2;
|
|
|
15
15
|
|
|
16
16
|
type RotationToken = {
|
|
17
17
|
token: string;
|
|
18
|
+
model: string;
|
|
18
19
|
maximumPreparingProcessCount: number;
|
|
19
20
|
};
|
|
20
21
|
|
|
@@ -43,6 +44,11 @@ export class StartPreparationUseCase {
|
|
|
43
44
|
private readonly claudeTokenUsageRepository: ClaudeTokenUsageRepository,
|
|
44
45
|
) {}
|
|
45
46
|
|
|
47
|
+
private readonly KNOWN_MODEL_SPECIFIC_LIMIT_TYPES = [
|
|
48
|
+
'seven_day_sonnet',
|
|
49
|
+
'seven_day_opus',
|
|
50
|
+
];
|
|
51
|
+
|
|
46
52
|
private weeklyLimitTypeForModel = (modelName: string | null): string => {
|
|
47
53
|
const normalized = (modelName ?? '').toLowerCase();
|
|
48
54
|
if (normalized.includes('sonnet')) return 'seven_day_sonnet';
|
|
@@ -50,14 +56,53 @@ export class StartPreparationUseCase {
|
|
|
50
56
|
return 'seven_day';
|
|
51
57
|
};
|
|
52
58
|
|
|
53
|
-
private
|
|
59
|
+
private deriveFallbackModelName = (
|
|
60
|
+
limitType: string,
|
|
61
|
+
defaultModelName: string,
|
|
62
|
+
): string => {
|
|
63
|
+
if (limitType === this.weeklyLimitTypeForModel(defaultModelName)) {
|
|
64
|
+
return defaultModelName;
|
|
65
|
+
}
|
|
66
|
+
if (
|
|
67
|
+
limitType === 'seven_day_opus' &&
|
|
68
|
+
defaultModelName.toLowerCase().includes('sonnet')
|
|
69
|
+
) {
|
|
70
|
+
return defaultModelName.replace(/sonnet/gi, 'opus');
|
|
71
|
+
}
|
|
72
|
+
if (
|
|
73
|
+
limitType === 'seven_day_sonnet' &&
|
|
74
|
+
defaultModelName.toLowerCase().includes('opus')
|
|
75
|
+
) {
|
|
76
|
+
return defaultModelName.replace(/opus/gi, 'sonnet');
|
|
77
|
+
}
|
|
78
|
+
return defaultModelName;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
private selectModelForToken = (
|
|
54
82
|
usage: ClaudeTokenUsage,
|
|
55
|
-
|
|
56
|
-
):
|
|
57
|
-
const
|
|
58
|
-
if (
|
|
59
|
-
|
|
60
|
-
|
|
83
|
+
defaultModelName: string | null,
|
|
84
|
+
): string | null => {
|
|
85
|
+
const generalLimit = usage.modelWeeklyLimits['seven_day'];
|
|
86
|
+
if (generalLimit !== undefined && generalLimit.rejected) return null;
|
|
87
|
+
|
|
88
|
+
if (defaultModelName === null) return null;
|
|
89
|
+
|
|
90
|
+
const defaultLimitType = this.weeklyLimitTypeForModel(defaultModelName);
|
|
91
|
+
const candidateLimitTypes = [
|
|
92
|
+
defaultLimitType,
|
|
93
|
+
...this.KNOWN_MODEL_SPECIFIC_LIMIT_TYPES.filter(
|
|
94
|
+
(t) => t !== defaultLimitType,
|
|
95
|
+
),
|
|
96
|
+
];
|
|
97
|
+
|
|
98
|
+
for (const limitType of candidateLimitTypes) {
|
|
99
|
+
const limit = usage.modelWeeklyLimits[limitType];
|
|
100
|
+
if (limit === undefined || !limit.rejected) {
|
|
101
|
+
return this.deriveFallbackModelName(limitType, defaultModelName);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return null;
|
|
61
106
|
};
|
|
62
107
|
|
|
63
108
|
private maximumPreparingProcessCountForToken = (
|
|
@@ -87,40 +132,45 @@ export class StartPreparationUseCase {
|
|
|
87
132
|
tokenUsages: ClaudeTokenUsage[],
|
|
88
133
|
modelName: string | null,
|
|
89
134
|
): RotationToken[] => {
|
|
90
|
-
const weeklyLimitType = this.weeklyLimitTypeForModel(modelName);
|
|
91
135
|
return tokenUsages
|
|
92
136
|
.filter((usage) => !usage.blocked)
|
|
93
137
|
.filter((usage) => !usage.rejected)
|
|
94
|
-
.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
138
|
+
.flatMap((usage) => {
|
|
139
|
+
const selectedModel = this.selectModelForToken(usage, modelName);
|
|
140
|
+
if (selectedModel === null) return [];
|
|
141
|
+
return [
|
|
142
|
+
{
|
|
143
|
+
token: usage.token,
|
|
144
|
+
model: selectedModel,
|
|
145
|
+
fiveHourUtilization: usage.fiveHourUtilization,
|
|
146
|
+
maximumPreparingProcessCount:
|
|
147
|
+
this.maximumPreparingProcessCountForToken(
|
|
148
|
+
usage.fiveHourUtilization,
|
|
149
|
+
),
|
|
150
|
+
},
|
|
151
|
+
];
|
|
152
|
+
})
|
|
104
153
|
.filter((usage) => usage.maximumPreparingProcessCount > 0)
|
|
105
154
|
.sort((a, b) => a.fiveHourUtilization - b.fiveHourUtilization)
|
|
106
155
|
.map((usage) => ({
|
|
107
156
|
token: usage.token,
|
|
157
|
+
model: usage.model,
|
|
108
158
|
maximumPreparingProcessCount: usage.maximumPreparingProcessCount,
|
|
109
159
|
}));
|
|
110
160
|
};
|
|
111
161
|
|
|
112
162
|
private createRotationTokenSlots = (
|
|
113
163
|
rotationTokens: RotationToken[],
|
|
114
|
-
): string
|
|
164
|
+
): Array<{ token: string; model: string }> => {
|
|
115
165
|
const slotCount = Math.max(
|
|
116
166
|
...rotationTokens.map((token) => token.maximumPreparingProcessCount),
|
|
117
167
|
);
|
|
118
|
-
const tokenSlots: string
|
|
168
|
+
const tokenSlots: Array<{ token: string; model: string }> = [];
|
|
119
169
|
for (let i = 0; i < slotCount; i++) {
|
|
120
170
|
tokenSlots.push(
|
|
121
171
|
...rotationTokens
|
|
122
172
|
.filter((token) => i < token.maximumPreparingProcessCount)
|
|
123
|
-
.map((token) => token.token),
|
|
173
|
+
.map((token) => ({ token: token.token, model: token.model })),
|
|
124
174
|
);
|
|
125
175
|
}
|
|
126
176
|
return tokenSlots;
|
|
@@ -128,7 +178,7 @@ export class StartPreparationUseCase {
|
|
|
128
178
|
|
|
129
179
|
private resolveMaximumPreparingIssuesCount = (
|
|
130
180
|
configuredMaximumPreparingIssuesCount: number | null,
|
|
131
|
-
rotationTokenSlots: string
|
|
181
|
+
rotationTokenSlots: Array<{ token: string; model: string }> | null,
|
|
132
182
|
): number => {
|
|
133
183
|
if (rotationTokenSlots === null) {
|
|
134
184
|
return configuredMaximumPreparingIssuesCount ?? 6;
|
|
@@ -145,12 +195,13 @@ export class StartPreparationUseCase {
|
|
|
145
195
|
modelName: string | null,
|
|
146
196
|
): RotationOrderEntry[] => {
|
|
147
197
|
const weeklyLimitType = this.weeklyLimitTypeForModel(modelName);
|
|
198
|
+
const isWeeklyLimitRejected = (usage: ClaudeTokenUsage): boolean =>
|
|
199
|
+
usage.modelWeeklyLimits[weeklyLimitType]?.rejected === true ||
|
|
200
|
+
usage.modelWeeklyLimits['seven_day']?.rejected === true;
|
|
148
201
|
const selectedTokens = tokenUsages
|
|
149
202
|
.filter((usage) => !usage.blocked)
|
|
150
203
|
.filter((usage) => !usage.rejected)
|
|
151
|
-
.filter(
|
|
152
|
-
(usage) => !this.isModelWeeklyLimitRejected(usage, weeklyLimitType),
|
|
153
|
-
)
|
|
204
|
+
.filter((usage) => !isWeeklyLimitRejected(usage))
|
|
154
205
|
.filter(
|
|
155
206
|
(usage) =>
|
|
156
207
|
this.maximumPreparingProcessCountForToken(usage.fiveHourUtilization) >
|
|
@@ -168,7 +219,7 @@ export class StartPreparationUseCase {
|
|
|
168
219
|
thresholdExcluded:
|
|
169
220
|
!usage.blocked &&
|
|
170
221
|
!usage.rejected &&
|
|
171
|
-
!
|
|
222
|
+
!isWeeklyLimitRejected(usage) &&
|
|
172
223
|
this.maximumPreparingProcessCountForToken(
|
|
173
224
|
usage.fiveHourUtilization,
|
|
174
225
|
) === 0,
|
|
@@ -199,7 +250,8 @@ export class StartPreparationUseCase {
|
|
|
199
250
|
}): Promise<{ rotationOrder: RotationOrderEntry[] | null }> => {
|
|
200
251
|
const tokenUsages =
|
|
201
252
|
await this.claudeTokenUsageRepository.getAvailableTokenUsages();
|
|
202
|
-
let rotationTokenSlots: string
|
|
253
|
+
let rotationTokenSlots: Array<{ token: string; model: string }> | null =
|
|
254
|
+
null;
|
|
203
255
|
let proxyBaseUrl: string | null = null;
|
|
204
256
|
const rotationOrder: RotationOrderEntry[] | null =
|
|
205
257
|
tokenUsages.length > 0
|
|
@@ -216,7 +268,7 @@ export class StartPreparationUseCase {
|
|
|
216
268
|
);
|
|
217
269
|
if (ranked.length === 0) {
|
|
218
270
|
console.warn(
|
|
219
|
-
`All ${tokenUsages.length} configured Claude OAuth token(s) are unavailable (blocked, rejected,
|
|
271
|
+
`All ${tokenUsages.length} configured Claude OAuth token(s) are unavailable (blocked, rejected, all model weekly limits exhausted, or 5h utilization >= 95%). Skipping starting preparation.`,
|
|
220
272
|
);
|
|
221
273
|
return { rotationOrder };
|
|
222
274
|
}
|
|
@@ -296,6 +348,15 @@ export class StartPreparationUseCase {
|
|
|
296
348
|
params.allowedIssueAuthors !== null &&
|
|
297
349
|
!params.allowedIssueAuthors.includes(issue.author)
|
|
298
350
|
) {
|
|
351
|
+
if (issue.author === '') {
|
|
352
|
+
console.warn(
|
|
353
|
+
`Skipping issue ${issue.url}: author is unknown (empty string); deny-by-default when allowedIssueAuthors is configured.`,
|
|
354
|
+
);
|
|
355
|
+
} else {
|
|
356
|
+
console.warn(
|
|
357
|
+
`Skipping issue ${issue.url}: author '${issue.author}' is not in the allowedIssueAuthors list.`,
|
|
358
|
+
);
|
|
359
|
+
}
|
|
299
360
|
continue;
|
|
300
361
|
}
|
|
301
362
|
const agent =
|
|
@@ -314,7 +375,7 @@ export class StartPreparationUseCase {
|
|
|
314
375
|
.find((label: string) => label.startsWith('llm-model:'))
|
|
315
376
|
?.replace('llm-model:', '')
|
|
316
377
|
.trim() || params.defaultLlmModelName;
|
|
317
|
-
if (!model) {
|
|
378
|
+
if (!model && rotationTokenSlots === null) {
|
|
318
379
|
console.error(
|
|
319
380
|
`No LLM model configured for issue ${issue.url}. Provide --defaultLlmModelName or add an llm-model: label.`,
|
|
320
381
|
);
|
|
@@ -397,10 +458,25 @@ export class StartPreparationUseCase {
|
|
|
397
458
|
);
|
|
398
459
|
issue.status = PREPARATION_STATUS_NAME;
|
|
399
460
|
|
|
461
|
+
let spawnEnv: Record<string, string> | undefined;
|
|
462
|
+
let spawnModel = model ?? '';
|
|
463
|
+
if (rotationTokenSlots !== null && proxyBaseUrl !== null) {
|
|
464
|
+
const selected =
|
|
465
|
+
rotationTokenSlots[
|
|
466
|
+
(currentPreparationIssueCount + startedInThisRunCount) %
|
|
467
|
+
rotationTokenSlots.length
|
|
468
|
+
];
|
|
469
|
+
spawnModel = selected.model;
|
|
470
|
+
spawnEnv = {
|
|
471
|
+
CLAUDE_CODE_OAUTH_TOKEN: selected.token,
|
|
472
|
+
ANTHROPIC_BASE_URL: proxyBaseUrl,
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
|
|
400
476
|
const awArgs: string[] = [
|
|
401
477
|
issue.url,
|
|
402
478
|
agent,
|
|
403
|
-
|
|
479
|
+
spawnModel,
|
|
404
480
|
'--configFilePath',
|
|
405
481
|
params.configFilePath,
|
|
406
482
|
'--branch',
|
|
@@ -416,18 +492,6 @@ export class StartPreparationUseCase {
|
|
|
416
492
|
];
|
|
417
493
|
awArgs.push('--codexHome', codexHome);
|
|
418
494
|
}
|
|
419
|
-
let spawnEnv: Record<string, string> | undefined;
|
|
420
|
-
if (rotationTokenSlots !== null && proxyBaseUrl !== null) {
|
|
421
|
-
const selected =
|
|
422
|
-
rotationTokenSlots[
|
|
423
|
-
(currentPreparationIssueCount + startedInThisRunCount) %
|
|
424
|
-
rotationTokenSlots.length
|
|
425
|
-
];
|
|
426
|
-
spawnEnv = {
|
|
427
|
-
CLAUDE_CODE_OAUTH_TOKEN: selected,
|
|
428
|
-
ANTHROPIC_BASE_URL: proxyBaseUrl,
|
|
429
|
-
};
|
|
430
|
-
}
|
|
431
495
|
await this.localCommandRunner.runCommand(
|
|
432
496
|
'aw',
|
|
433
497
|
awArgs,
|
|
@@ -16,8 +16,10 @@ export declare class StartPreparationUseCase {
|
|
|
16
16
|
private readonly localCommandRunner;
|
|
17
17
|
private readonly claudeTokenUsageRepository;
|
|
18
18
|
constructor(projectRepository: Pick<ProjectRepository, 'getByUrl'>, issueRepository: Pick<IssueRepository, 'getStoryObjectMap' | 'updateStatus' | 'findRelatedOpenPRs' | 'getOpenPullRequest' | 'closePullRequest' | 'deletePullRequestBranch' | 'createCommentByUrl'>, localCommandRunner: LocalCommandRunner, claudeTokenUsageRepository: ClaudeTokenUsageRepository);
|
|
19
|
+
private readonly KNOWN_MODEL_SPECIFIC_LIMIT_TYPES;
|
|
19
20
|
private weeklyLimitTypeForModel;
|
|
20
|
-
private
|
|
21
|
+
private deriveFallbackModelName;
|
|
22
|
+
private selectModelForToken;
|
|
21
23
|
private maximumPreparingProcessCountForToken;
|
|
22
24
|
private selectRotationTokens;
|
|
23
25
|
private createRotationTokenSlots;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StartPreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/StartPreparationUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,0BAA0B,EAAE,MAAM,iDAAiD,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"StartPreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/StartPreparationUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,0BAA0B,EAAE,MAAM,iDAAiD,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAiBhE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB,EAAE,MAAM,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,iBAAiB,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,qBAAa,uBAAuB;IAEhC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAUhC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,0BAA0B;gBAZ1B,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC,EACtD,eAAe,EAAE,IAAI,CACpC,eAAe,EACb,mBAAmB,GACnB,cAAc,GACd,oBAAoB,GACpB,oBAAoB,GACpB,kBAAkB,GAClB,yBAAyB,GACzB,oBAAoB,CACvB,EACgB,kBAAkB,EAAE,kBAAkB,EACtC,0BAA0B,EAAE,0BAA0B;IAGzE,OAAO,CAAC,QAAQ,CAAC,gCAAgC,CAG/C;IAEF,OAAO,CAAC,uBAAuB,CAK7B;IAEF,OAAO,CAAC,uBAAuB,CAoB7B;IAEF,OAAO,CAAC,mBAAmB,CAyBzB;IAEF,OAAO,CAAC,oCAAoC,CAqB1C;IAEF,OAAO,CAAC,oBAAoB,CA6B1B;IAEF,OAAO,CAAC,wBAAwB,CAe9B;IAEF,OAAO,CAAC,kCAAkC,CAWxC;IAEF,kBAAkB,GAChB,aAAa,gBAAgB,EAAE,EAC/B,gCAAgC,MAAM,EACtC,WAAW,MAAM,GAAG,IAAI,KACvB,kBAAkB,EAAE,CAyCrB;IAEF,GAAG,GAAU,QAAQ;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,EAAE,MAAM,CAAC;QACzB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,cAAc,EAAE,MAAM,CAAC;QACvB,2BAA2B,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3C,8BAA8B,EAAE,MAAM,CAAC;QACvC,mBAAmB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACrC,mBAAmB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACrC,sBAAsB,EAAE,MAAM,CAAC;KAChC,KAAG,OAAO,CAAC;QAAE,aAAa,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAAA;KAAE,CAAC,CA8PzD;CACH"}
|