github-issue-tower-defence-management 1.82.1 → 1.83.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/.github/workflows/commit-lint.yml +7 -2
- package/.github/workflows/create-pr.yml +23 -5
- package/CHANGELOG.md +7 -0
- package/README.md +4 -4
- package/bin/domain/usecases/StartPreparationUseCase.js +60 -46
- package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
- package/package.json +1 -1
- package/src/domain/usecases/StartPreparationUseCase.test.ts +265 -68
- package/src/domain/usecases/StartPreparationUseCase.ts +94 -73
- package/types/domain/usecases/StartPreparationUseCase.d.ts +1 -0
- package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
|
@@ -54,7 +54,12 @@ jobs:
|
|
|
54
54
|
loose-matching: true
|
|
55
55
|
- name: Install commitlint
|
|
56
56
|
run: |
|
|
57
|
-
|
|
57
|
+
mkdir -p /tmp/commitlint-run
|
|
58
|
+
cd /tmp/commitlint-run
|
|
59
|
+
npm init -y
|
|
60
|
+
npm install --no-audit --no-fund --save-dev @commitlint/cli @commitlint/config-conventional
|
|
58
61
|
- name: Lint commits
|
|
62
|
+
env:
|
|
63
|
+
NODE_PATH: /tmp/commitlint-run/node_modules
|
|
59
64
|
run: |
|
|
60
|
-
|
|
65
|
+
/tmp/commitlint-run/node_modules/.bin/commitlint --from=origin/main --to=HEAD --config $GITHUB_WORKSPACE/.github/workflows/configs/commitlint.config.js
|
|
@@ -76,18 +76,36 @@ jobs:
|
|
|
76
76
|
- name: Enable Auto Merge for PR
|
|
77
77
|
if: steps.resolve_pr.outputs.pr_number
|
|
78
78
|
run: |
|
|
79
|
+
RULESET_METHOD=$(gh api "repos/${{ github.repository }}/rules/branches/main" \
|
|
80
|
+
--jq '[.[] | select(.type == "pull_request") | .parameters.allowed_merge_methods // empty][0][0]' 2>/dev/null || echo "")
|
|
81
|
+
if [ -n "$RULESET_METHOD" ] && [ "$RULESET_METHOD" != "null" ]; then
|
|
82
|
+
MERGE_METHOD=$(echo "$RULESET_METHOD" | tr '[:lower:]' '[:upper:]')
|
|
83
|
+
else
|
|
84
|
+
ALLOW_SQUASH=$(gh api "repos/${{ github.repository }}" --jq '.allow_squash_merge')
|
|
85
|
+
ALLOW_REBASE=$(gh api "repos/${{ github.repository }}" --jq '.allow_rebase_merge')
|
|
86
|
+
if [ "$ALLOW_SQUASH" = "true" ]; then
|
|
87
|
+
MERGE_METHOD="SQUASH"
|
|
88
|
+
elif [ "$ALLOW_REBASE" = "true" ]; then
|
|
89
|
+
MERGE_METHOD="REBASE"
|
|
90
|
+
else
|
|
91
|
+
MERGE_METHOD="MERGE"
|
|
92
|
+
fi
|
|
93
|
+
fi
|
|
79
94
|
RESPONSE=$(curl -s -X POST \
|
|
80
95
|
-H "Authorization: bearer ${{ steps.app-token.outputs.token }}" \
|
|
81
96
|
-H "Content-Type: application/json" \
|
|
82
|
-
-d
|
|
83
|
-
"query": "mutation(
|
|
84
|
-
"variables": {
|
|
85
|
-
"id": "
|
|
97
|
+
-d "{
|
|
98
|
+
\"query\": \"mutation(\$id: ID!, \$mergeMethod: PullRequestMergeMethod!) { enablePullRequestAutoMerge(input: { pullRequestId: \$id, mergeMethod: \$mergeMethod }) { clientMutationId } }\",
|
|
99
|
+
\"variables\": {
|
|
100
|
+
\"id\": \"${{ steps.get_pr_id.outputs.node_id }}\",
|
|
101
|
+
\"mergeMethod\": \"$MERGE_METHOD\"
|
|
86
102
|
}
|
|
87
|
-
}
|
|
103
|
+
}" \
|
|
88
104
|
"https://api.github.com/graphql")
|
|
89
105
|
echo "$RESPONSE"
|
|
90
106
|
if echo "$RESPONSE" | jq -e '.errors' >/dev/null; then
|
|
91
107
|
echo "Failed to enable auto merge"
|
|
92
108
|
exit 1
|
|
93
109
|
fi
|
|
110
|
+
env:
|
|
111
|
+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [1.83.0](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.82.1...v1.83.0) (2026-06-14)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **core:** route spawn model per token from each token's weekly availability ([#829](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/issues/829)) ([d270a26](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/d270a2609ed17fff33e010a236af17d9838928be)), closes [#828](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/issues/828)
|
|
7
|
+
|
|
1
8
|
## [1.82.1](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.82.0...v1.82.1) (2026-06-12)
|
|
2
9
|
|
|
3
10
|
|
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ Options for startDaemon:
|
|
|
33
33
|
--projectUrl <url> GitHub project URL
|
|
34
34
|
--defaultAgentName <name> Default agent name
|
|
35
35
|
--defaultLlmModelName <name> Default LLM model name
|
|
36
|
-
--fallbackLlmModelName <name> LLM model
|
|
36
|
+
--fallbackLlmModelName <name> LLM model a token falls back to when the default Sonnet model's 7-day weekly limit is exhausted for that token while its fallback weekly window still has capacity; routing is decided per token, so tokens with Sonnet headroom keep using Sonnet in the same pass (default: claude-opus-4-8)
|
|
37
37
|
--defaultLlmAgentName <name> Default LLM agent name
|
|
38
38
|
--maximumPreparingIssuesCount <count> Maximum number of issues in preparation status (default: 6 per available Claude OAuth token, otherwise 6)
|
|
39
39
|
--allowIssueCacheMinutes <minutes> Allow cache for issues in minutes (default: 10)
|
|
@@ -108,7 +108,7 @@ startPreparation?: # Optional: Enable automatic issue preparation workflow
|
|
|
108
108
|
defaultAgentName: string # Default agent name to assign for preparation
|
|
109
109
|
configFilePath: string # Path to config file passed to the aw command
|
|
110
110
|
defaultLlmModelName?: string | null # Optional: Default LLM model name (overridable via llm-model: label)
|
|
111
|
-
fallbackLlmModelName?: string | null # Optional: LLM model
|
|
111
|
+
fallbackLlmModelName?: string | null # Optional: LLM model a token falls back to when defaultLlmModelName is a Sonnet model and that token's 7-day Sonnet weekly limit is exhausted while its fallback weekly window still has capacity (default: claude-opus-4-8). Routing is decided per token, so tokens with Sonnet headroom keep using Sonnet in the same pass. Per-issue llm-model: labels remain authoritative and are never overridden by the fallback
|
|
112
112
|
defaultLlmAgentName?: string | null # Optional: Default LLM agent name (overridable via llm-agent: label)
|
|
113
113
|
maximumPreparingIssuesCount: number | null # Max concurrent preparing issues. When token rotation is active, effective concurrency is also capped at 6 per available token. When null, the default is 6 per available token, or 6 without token rotation
|
|
114
114
|
utilizationPercentageThreshold?: number # Optional: 5-hour utilization hard threshold (percentage, default 90). Tokens at or above this value are excluded from rotation
|
|
@@ -185,7 +185,7 @@ projectUrl: string # URL of the GitHub project
|
|
|
185
185
|
projectName: string # Project name (used for cache directory path)
|
|
186
186
|
defaultAgentName: string # Default agent name for issue preparation
|
|
187
187
|
defaultLlmModelName?: string # Optional: Default LLM model name
|
|
188
|
-
fallbackLlmModelName?: string # Optional: LLM model
|
|
188
|
+
fallbackLlmModelName?: string # Optional: LLM model a token falls back to when defaultLlmModelName is a Sonnet model and that token's 7-day Sonnet weekly limit is exhausted while its fallback weekly window still has capacity (default: claude-opus-4-8). Routing is decided per token, so tokens with Sonnet headroom keep using Sonnet in the same pass. Per-issue llm-model: labels remain authoritative
|
|
189
189
|
defaultLlmAgentName?: string # Optional: Default LLM agent name
|
|
190
190
|
maximumPreparingIssuesCount?: number # Optional: Max concurrent preparing issues. When token rotation is active, effective concurrency is also capped at 6 per available token. Omitted defaults to 6 per available token, or 6 without token rotation
|
|
191
191
|
allowIssueCacheMinutes?: number # Optional: Allow cache for issues in minutes (default: 10)
|
|
@@ -246,7 +246,7 @@ When `claudeCodeOauthTokenListJsonPath` is set, `startDaemon` distributes prepar
|
|
|
246
246
|
|
|
247
247
|
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. When a response is an HTTP 429 that carries no `anthropic-ratelimit-*` headers at all (for example a `rate_limit_error` with `x-should-retry: true`), the proxy records a short-lived per-token cooldown as a `blockedUntilEpoch` field on that token's cache file without discarding the last-good snapshot: the cooldown end is `now + Retry-After` seconds when the `Retry-After` header is present (clamped to a maximum of 600 seconds), otherwise a fixed default of 90 seconds. A later response that does carry `anthropic-ratelimit-*` headers overwrites the cache and clears the cooldown.
|
|
248
248
|
|
|
249
|
-
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; likewise, when the 7-day reset has passed, the 7-day utilization is treated as `0` and any 7-day-window rejection is cleared; 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`, whose remaining (non-expired) rejection is still active, whose `blockedUntilEpoch` cooldown is still in the future, whose 5-hour utilization meets or exceeds the configured threshold
|
|
249
|
+
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; likewise, when the 7-day reset has passed, the 7-day utilization is treated as `0` and any 7-day-window rejection is cleared; 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`, whose remaining (non-expired) rejection is still active, whose `blockedUntilEpoch` cooldown is still in the future, or whose 5-hour utilization meets or exceeds the configured threshold are excluded. The model for each remaining token is then routed independently: the configured default model is preferred when that token's matching weekly window is not rejected, otherwise the configured fallback model (default `claude-opus-4-8`) is used when its matching weekly window is not rejected; a token is excluded for weekly limits only when every candidate model's weekly window is rejected or the generic `seven_day` window is rejected. This routing is per token, so within a single pass a token whose `seven_day_sonnet` window is exhausted is spawned on the fallback Opus model while sibling tokens that still have Sonnet headroom keep using Sonnet. A cooled-down token becomes selectable again automatically once its `blockedUntilEpoch` has passed. 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 excludes a token regardless of model. The remaining eligible tokens are sorted by time until the 7-day reset deadline ascending (soonest 7-day reset first, so quota that would otherwise expire unused is consumed first), with 5-hour utilization ascending as the tiebreaker. The 7-day reset deadline for a given spawn is read from the per-model weekly limit entry in `modelWeeklyLimits` matching the model that will be used (`seven_day_sonnet`, `seven_day_opus`, or the generic `seven_day`); when no model-specific or generic `seven_day` entry exists but the cache snapshot recorded a non-expired top-level `anthropic-ratelimit-unified-7d-reset` deadline, that header value is bridged into a synthesized generic `seven_day` entry whose `rejected` flag matches the (non-expired) `anthropic-ratelimit-unified-7d-status` rejection. When neither source supplies a deadline, the token is treated as having an infinite deadline and sorts last. Each token's per-run concurrent preparation slot count is determined by both its 5-hour and 7-day utilization, taking the more restrictive (minimum) of the two so concurrency ramps down as either window fills: for each window, at or below 80% the token receives the full six concurrent slots; above 80%, the slot count is reduced proportionally — specifically `ceil(6 × (1 − util) / 0.2)` — with a minimum of 1 slot at any utilization level, so near-exhausted tokens still participate rather than being cut off entirely. The final slot count is the minimum of the 5-hour-derived and 7-day-derived counts. Before each `aw` spawn, among the tokens that still have an available slot (slot count minus the in-flight count minus the count already spawned this run, greater than zero), the token whose 7-day reset is soonest is selected; in-flight slot count from prior runs no longer routes new work away from a soon-reset token, so a soon-reset token's slots are filled before a later-reset token receives any, and remaining slot count is used only as the tiebreaker when two candidates share the same 7-day reset. The effective preparation limit for a run is the lesser of the sum of all eligible tokens' slot counts and the explicit `maximumPreparingIssuesCount` (which defaults to 6). When a token list is configured but no eligible token remains after filtering, preparation is skipped for that run. The selected token and the proxy URL (`http://127.0.0.1:8787`) are passed to the child `aw` process as `CLAUDE_CODE_OAUTH_TOKEN` and `ANTHROPIC_BASE_URL` environment variables. The child inherits the parent process's environment, so no further wiring is required inside `aw`.
|
|
250
250
|
|
|
251
251
|
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.
|
|
252
252
|
|
|
@@ -28,6 +28,21 @@ class StartPreparationUseCase {
|
|
|
28
28
|
const general = usage.modelWeeklyLimits['seven_day'];
|
|
29
29
|
return general !== undefined && general.rejected;
|
|
30
30
|
};
|
|
31
|
+
this.selectModelForToken = (usage, defaultModelName, fallbackModelName) => {
|
|
32
|
+
const generalWeeklyLimit = usage.modelWeeklyLimits['seven_day'];
|
|
33
|
+
if (generalWeeklyLimit !== undefined && generalWeeklyLimit.rejected) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
const candidateModelNames = [defaultModelName, fallbackModelName].filter((modelName) => modelName !== null && modelName !== '');
|
|
37
|
+
for (const candidateModelName of candidateModelNames) {
|
|
38
|
+
const weeklyLimitType = this.weeklyLimitTypeForModel(candidateModelName);
|
|
39
|
+
const specificWeeklyLimit = usage.modelWeeklyLimits[weeklyLimitType];
|
|
40
|
+
if (specificWeeklyLimit === undefined || !specificWeeklyLimit.rejected) {
|
|
41
|
+
return candidateModelName;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
};
|
|
31
46
|
this.secondsUntilSevenDayReset = (usage, weeklyLimitType, nowEpochSeconds) => {
|
|
32
47
|
const specific = usage.modelWeeklyLimits[weeklyLimitType];
|
|
33
48
|
if (specific !== undefined) {
|
|
@@ -39,9 +54,9 @@ class StartPreparationUseCase {
|
|
|
39
54
|
}
|
|
40
55
|
return Number.POSITIVE_INFINITY;
|
|
41
56
|
};
|
|
42
|
-
this.compareBySevenDayDeadlineThenUtilization = (a, b,
|
|
43
|
-
const aSecondsUntilReset = this.secondsUntilSevenDayReset(a,
|
|
44
|
-
const bSecondsUntilReset = this.secondsUntilSevenDayReset(b,
|
|
57
|
+
this.compareBySevenDayDeadlineThenUtilization = (a, aWeeklyLimitType, b, bWeeklyLimitType, nowEpochSeconds) => {
|
|
58
|
+
const aSecondsUntilReset = this.secondsUntilSevenDayReset(a, aWeeklyLimitType, nowEpochSeconds);
|
|
59
|
+
const bSecondsUntilReset = this.secondsUntilSevenDayReset(b, bWeeklyLimitType, nowEpochSeconds);
|
|
45
60
|
if (aSecondsUntilReset !== bSecondsUntilReset) {
|
|
46
61
|
return aSecondsUntilReset - bSecondsUntilReset;
|
|
47
62
|
}
|
|
@@ -59,23 +74,28 @@ class StartPreparationUseCase {
|
|
|
59
74
|
const fiveHourLimit = this.taperedConcurrentLimit(fiveHourUtilization, FIVE_HOUR_THROTTLE_START_THRESHOLD);
|
|
60
75
|
return Math.min(sevenDayLimit, fiveHourLimit);
|
|
61
76
|
};
|
|
62
|
-
this.selectRotationTokens = (tokenUsages, utilizationPercentageThreshold,
|
|
63
|
-
const weeklyLimitType = this.weeklyLimitTypeForModel(modelName);
|
|
77
|
+
this.selectRotationTokens = (tokenUsages, utilizationPercentageThreshold, defaultModelName, fallbackModelName, maxConcurrent) => {
|
|
64
78
|
const nowEpochSeconds = Date.now() / 1000;
|
|
65
79
|
const eligibleTokens = tokenUsages
|
|
66
80
|
.filter((usage) => !usage.blocked)
|
|
67
81
|
.filter((usage) => !usage.rejected)
|
|
68
82
|
.filter((usage) => !this.isWithinCooldown(usage, nowEpochSeconds))
|
|
69
|
-
.filter((usage) => !this.isModelWeeklyLimitRejected(usage, weeklyLimitType))
|
|
70
83
|
.filter((usage) => usage.fiveHourUtilization * 100 < utilizationPercentageThreshold)
|
|
71
|
-
.
|
|
84
|
+
.flatMap((usage) => {
|
|
85
|
+
const model = this.selectModelForToken(usage, defaultModelName, fallbackModelName);
|
|
86
|
+
if (model === null)
|
|
87
|
+
return [];
|
|
88
|
+
return [{ usage, model }];
|
|
89
|
+
})
|
|
90
|
+
.sort((a, b) => this.compareBySevenDayDeadlineThenUtilization(a.usage, this.weeklyLimitTypeForModel(a.model), b.usage, this.weeklyLimitTypeForModel(b.model), nowEpochSeconds));
|
|
72
91
|
if (eligibleTokens.length === 0) {
|
|
73
92
|
return { tokens: [], effectiveCap: 0, tokensWithLimits: [] };
|
|
74
93
|
}
|
|
75
|
-
const tokensWithLimits = eligibleTokens.map((usage) => ({
|
|
94
|
+
const tokensWithLimits = eligibleTokens.map(({ usage, model }) => ({
|
|
76
95
|
token: usage.token,
|
|
96
|
+
model,
|
|
77
97
|
limit: this.getTokenConcurrentLimit(usage.fiveHourUtilization, usage.sevenDayUtilization),
|
|
78
|
-
secondsUntilSevenDayReset: this.secondsUntilSevenDayReset(usage,
|
|
98
|
+
secondsUntilSevenDayReset: this.secondsUntilSevenDayReset(usage, this.weeklyLimitTypeForModel(model), nowEpochSeconds),
|
|
79
99
|
}));
|
|
80
100
|
const totalCapacity = tokensWithLimits.reduce((sum, t) => sum + t.limit, 0);
|
|
81
101
|
const effectiveCap = Math.min(maxConcurrent, totalCapacity);
|
|
@@ -99,7 +119,7 @@ class StartPreparationUseCase {
|
|
|
99
119
|
.filter((usage) => !this.isWithinCooldown(usage, nowEpochSeconds))
|
|
100
120
|
.filter((usage) => !this.isModelWeeklyLimitRejected(usage, weeklyLimitType))
|
|
101
121
|
.filter((usage) => usage.fiveHourUtilization * 100 < utilizationPercentageThreshold)
|
|
102
|
-
.sort((a, b) => this.compareBySevenDayDeadlineThenUtilization(a, b, weeklyLimitType, nowEpochSeconds));
|
|
122
|
+
.sort((a, b) => this.compareBySevenDayDeadlineThenUtilization(a, weeklyLimitType, b, weeklyLimitType, nowEpochSeconds));
|
|
103
123
|
const selectedTokenValues = new Set(selectedTokens.map((u) => u.token));
|
|
104
124
|
const excluded = tokenUsages
|
|
105
125
|
.filter((usage) => !selectedTokenValues.has(usage.token))
|
|
@@ -138,27 +158,11 @@ class StartPreparationUseCase {
|
|
|
138
158
|
: null;
|
|
139
159
|
const maximumPreparingIssuesCount = params.maximumPreparingIssuesCount ?? NORMAL_CONCURRENT_LIMIT;
|
|
140
160
|
let effectiveMaxPreparingIssuesCount = maximumPreparingIssuesCount;
|
|
141
|
-
|
|
161
|
+
const fallbackLlmModelName = params.fallbackLlmModelName ?? exports.DEFAULT_FALLBACK_LLM_MODEL_NAME;
|
|
142
162
|
if (tokenUsages.length > 0) {
|
|
143
|
-
const { tokens:
|
|
144
|
-
let selectedTokens = ranked;
|
|
145
|
-
let selectedCap = effectiveCap;
|
|
146
|
-
let selectedTokensWithLimitsLocal = rankedTokensWithLimits;
|
|
147
|
-
if (selectedTokens.length === 0 &&
|
|
148
|
-
this.weeklyLimitTypeForModel(params.defaultLlmModelName) ===
|
|
149
|
-
'seven_day_sonnet') {
|
|
150
|
-
const fallbackModelName = params.fallbackLlmModelName ?? exports.DEFAULT_FALLBACK_LLM_MODEL_NAME;
|
|
151
|
-
const { tokens: fallbackRanked, effectiveCap: fallbackCap, tokensWithLimits: fallbackTokensWithLimits, } = this.selectRotationTokens(tokenUsages, params.utilizationPercentageThreshold, fallbackModelName, maximumPreparingIssuesCount);
|
|
152
|
-
if (fallbackRanked.length > 0) {
|
|
153
|
-
console.warn(`Sonnet 7-day weekly limit (${this.weeklyLimitTypeForModel(params.defaultLlmModelName)}) is exhausted across all configured Claude OAuth token(s). Falling back to ${fallbackModelName}.`);
|
|
154
|
-
selectedTokens = fallbackRanked;
|
|
155
|
-
selectedCap = fallbackCap;
|
|
156
|
-
selectedTokensWithLimitsLocal = fallbackTokensWithLimits;
|
|
157
|
-
effectiveDefaultLlmModelName = fallbackModelName;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
163
|
+
const { tokens: selectedTokens, effectiveCap: selectedCap, tokensWithLimits: selectedTokensWithLimitsLocal, } = this.selectRotationTokens(tokenUsages, params.utilizationPercentageThreshold, params.defaultLlmModelName, fallbackLlmModelName, maximumPreparingIssuesCount);
|
|
160
164
|
if (selectedTokens.length === 0) {
|
|
161
|
-
console.warn(`All ${tokenUsages.length} configured Claude OAuth token(s) are unavailable (blocked, rejected, weekly
|
|
165
|
+
console.warn(`All ${tokenUsages.length} configured Claude OAuth token(s) are unavailable (blocked, rejected, weekly limits for the configured model(s) exhausted, or 5h utilization >= ${params.utilizationPercentageThreshold}%). Skipping starting preparation.`);
|
|
162
166
|
return { rotationOrder };
|
|
163
167
|
}
|
|
164
168
|
await this.claudeTokenUsageRepository.ensureObservable();
|
|
@@ -221,11 +225,13 @@ class StartPreparationUseCase {
|
|
|
221
225
|
.trim() ||
|
|
222
226
|
params.defaultLlmAgentName ||
|
|
223
227
|
params.defaultAgentName;
|
|
224
|
-
const
|
|
228
|
+
const labelModelName = issue.labels
|
|
225
229
|
.find((label) => label.startsWith('llm-model:'))
|
|
226
230
|
?.replace('llm-model:', '')
|
|
227
|
-
.trim()
|
|
228
|
-
if (!
|
|
231
|
+
.trim();
|
|
232
|
+
if (!labelModelName &&
|
|
233
|
+
!params.defaultLlmModelName &&
|
|
234
|
+
rotationTokens === null) {
|
|
229
235
|
console.error(`No LLM model configured for issue ${issue.url}. Provide --defaultLlmModelName or add an llm-model: label.`);
|
|
230
236
|
continue;
|
|
231
237
|
}
|
|
@@ -281,25 +287,13 @@ class StartPreparationUseCase {
|
|
|
281
287
|
}
|
|
282
288
|
await this.issueRepository.updateStatus(project, issue, preparationStatusOption.id);
|
|
283
289
|
issue.status = WorkflowStatus_1.PREPARATION_STATUS_NAME;
|
|
284
|
-
const awArgs = [
|
|
285
|
-
issue.url,
|
|
286
|
-
agent,
|
|
287
|
-
model,
|
|
288
|
-
'--configFilePath',
|
|
289
|
-
params.configFilePath,
|
|
290
|
-
'--branch',
|
|
291
|
-
branchName,
|
|
292
|
-
];
|
|
293
|
-
if (params.codexHomeCandidates !== null &&
|
|
294
|
-
params.codexHomeCandidates.length > 0) {
|
|
295
|
-
const codexHome = params.codexHomeCandidates[startedInThisRunCount % params.codexHomeCandidates.length];
|
|
296
|
-
awArgs.push('--codexHome', codexHome);
|
|
297
|
-
}
|
|
298
290
|
let spawnEnv;
|
|
291
|
+
let routedModelName = null;
|
|
299
292
|
if (rotationTokens !== null && proxyBaseUrl !== null) {
|
|
300
293
|
const tokenWithSoonestResetAmongAvailable = selectedTokensWithLimits
|
|
301
294
|
.map((t) => ({
|
|
302
295
|
token: t.token,
|
|
296
|
+
model: t.model,
|
|
303
297
|
remaining: t.limit -
|
|
304
298
|
(tokenInFlightCounts[t.token] ?? 0) -
|
|
305
299
|
(spawnedInThisRunByToken[t.token] ?? 0),
|
|
@@ -316,6 +310,7 @@ class StartPreparationUseCase {
|
|
|
316
310
|
break;
|
|
317
311
|
}
|
|
318
312
|
const selected = tokenWithSoonestResetAmongAvailable.token;
|
|
313
|
+
routedModelName = tokenWithSoonestResetAmongAvailable.model;
|
|
319
314
|
spawnedInThisRunByToken[selected] =
|
|
320
315
|
(spawnedInThisRunByToken[selected] ?? 0) + 1;
|
|
321
316
|
spawnEnv = {
|
|
@@ -323,6 +318,25 @@ class StartPreparationUseCase {
|
|
|
323
318
|
ANTHROPIC_BASE_URL: proxyBaseUrl,
|
|
324
319
|
};
|
|
325
320
|
}
|
|
321
|
+
const model = labelModelName || routedModelName || params.defaultLlmModelName;
|
|
322
|
+
if (!model) {
|
|
323
|
+
console.error(`No LLM model configured for issue ${issue.url}. Provide --defaultLlmModelName or add an llm-model: label.`);
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
const awArgs = [
|
|
327
|
+
issue.url,
|
|
328
|
+
agent,
|
|
329
|
+
model,
|
|
330
|
+
'--configFilePath',
|
|
331
|
+
params.configFilePath,
|
|
332
|
+
'--branch',
|
|
333
|
+
branchName,
|
|
334
|
+
];
|
|
335
|
+
if (params.codexHomeCandidates !== null &&
|
|
336
|
+
params.codexHomeCandidates.length > 0) {
|
|
337
|
+
const codexHome = params.codexHomeCandidates[startedInThisRunCount % params.codexHomeCandidates.length];
|
|
338
|
+
awArgs.push('--codexHome', codexHome);
|
|
339
|
+
}
|
|
326
340
|
await this.localCommandRunner.runCommand('aw', awArgs, spawnEnv ? { env: spawnEnv } : undefined);
|
|
327
341
|
startedInThisRunCount++;
|
|
328
342
|
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
|
@@ -3776,74 +3776,6 @@ describe('StartPreparationUseCase', () => {
|
|
|
3776
3776
|
expect(mockLocalCommandRunner.runCommand.mock.calls[0][2]).toBeUndefined();
|
|
3777
3777
|
});
|
|
3778
3778
|
|
|
3779
|
-
it('should exclude a token whose seven_day_sonnet weekly limit is rejected when the model is sonnet', async () => {
|
|
3780
|
-
const awaitingIssue = createMockIssue({
|
|
3781
|
-
url: 'url1',
|
|
3782
|
-
title: 'Issue 1',
|
|
3783
|
-
labels: ['category:impl'],
|
|
3784
|
-
status: 'Awaiting Workspace',
|
|
3785
|
-
number: 1,
|
|
3786
|
-
itemId: 'item-1',
|
|
3787
|
-
});
|
|
3788
|
-
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
3789
|
-
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
3790
|
-
createMockStoryObjectMap([awaitingIssue]),
|
|
3791
|
-
);
|
|
3792
|
-
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
3793
|
-
stdout: '',
|
|
3794
|
-
stderr: '',
|
|
3795
|
-
exitCode: 0,
|
|
3796
|
-
});
|
|
3797
|
-
const futureReset = Math.floor(Date.now() / 1000) + 3600;
|
|
3798
|
-
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
3799
|
-
{
|
|
3800
|
-
name: 'token-sonnet-exhausted',
|
|
3801
|
-
token: 'token-sonnet-exhausted',
|
|
3802
|
-
fiveHourUtilization: 0.1,
|
|
3803
|
-
sevenDayUtilization: 0,
|
|
3804
|
-
blocked: false,
|
|
3805
|
-
rejected: false,
|
|
3806
|
-
blockedUntilEpoch: 0,
|
|
3807
|
-
modelWeeklyLimits: {
|
|
3808
|
-
seven_day_sonnet: { rejected: true, resetsAt: futureReset },
|
|
3809
|
-
},
|
|
3810
|
-
},
|
|
3811
|
-
{
|
|
3812
|
-
name: 'token-ok',
|
|
3813
|
-
token: 'token-ok',
|
|
3814
|
-
fiveHourUtilization: 0.5,
|
|
3815
|
-
sevenDayUtilization: 0,
|
|
3816
|
-
blocked: false,
|
|
3817
|
-
rejected: false,
|
|
3818
|
-
blockedUntilEpoch: 0,
|
|
3819
|
-
modelWeeklyLimits: {},
|
|
3820
|
-
},
|
|
3821
|
-
]);
|
|
3822
|
-
|
|
3823
|
-
await useCase.run({
|
|
3824
|
-
projectUrl: 'https://github.com/user/repo',
|
|
3825
|
-
defaultAgentName: 'agent1',
|
|
3826
|
-
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
3827
|
-
fallbackLlmModelName: null,
|
|
3828
|
-
defaultLlmAgentName: null,
|
|
3829
|
-
configFilePath: '/path/to/config.yml',
|
|
3830
|
-
maximumPreparingIssuesCount: null,
|
|
3831
|
-
utilizationPercentageThreshold: 90,
|
|
3832
|
-
allowedIssueAuthors: null,
|
|
3833
|
-
codexHomeCandidates: null,
|
|
3834
|
-
allowIssueCacheMinutes: 0,
|
|
3835
|
-
labelsAsLlmAgentName: null,
|
|
3836
|
-
});
|
|
3837
|
-
|
|
3838
|
-
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
|
|
3839
|
-
expect(mockLocalCommandRunner.runCommand.mock.calls[0][2]).toEqual({
|
|
3840
|
-
env: {
|
|
3841
|
-
CLAUDE_CODE_OAUTH_TOKEN: 'token-ok',
|
|
3842
|
-
ANTHROPIC_BASE_URL: 'http://127.0.0.1:8787',
|
|
3843
|
-
},
|
|
3844
|
-
});
|
|
3845
|
-
});
|
|
3846
|
-
|
|
3847
3779
|
it('should re-admit a token whose seven_day_sonnet rejection has been cleared by stale-reset expiry', async () => {
|
|
3848
3780
|
const awaitingIssue = createMockIssue({
|
|
3849
3781
|
url: 'url1',
|
|
@@ -5015,6 +4947,271 @@ describe('StartPreparationUseCase', () => {
|
|
|
5015
4947
|
});
|
|
5016
4948
|
});
|
|
5017
4949
|
|
|
4950
|
+
describe('per-token model weekly-limit routing', () => {
|
|
4951
|
+
const futureReset = Math.floor(Date.now() / 1000) + 3600;
|
|
4952
|
+
|
|
4953
|
+
it('routes a token whose seven_day_sonnet weekly limit is rejected to Opus while a sibling token with Sonnet headroom uses Sonnet in the same pass', async () => {
|
|
4954
|
+
const issues = [
|
|
4955
|
+
createMockIssue({
|
|
4956
|
+
url: 'url1',
|
|
4957
|
+
title: 'Issue 1',
|
|
4958
|
+
labels: ['category:impl'],
|
|
4959
|
+
status: 'Awaiting Workspace',
|
|
4960
|
+
number: 1,
|
|
4961
|
+
itemId: 'item-1',
|
|
4962
|
+
}),
|
|
4963
|
+
createMockIssue({
|
|
4964
|
+
url: 'url2',
|
|
4965
|
+
title: 'Issue 2',
|
|
4966
|
+
labels: ['category:impl'],
|
|
4967
|
+
status: 'Awaiting Workspace',
|
|
4968
|
+
number: 2,
|
|
4969
|
+
itemId: 'item-2',
|
|
4970
|
+
}),
|
|
4971
|
+
];
|
|
4972
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
4973
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
4974
|
+
createMockStoryObjectMap(issues),
|
|
4975
|
+
);
|
|
4976
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
4977
|
+
stdout: '',
|
|
4978
|
+
stderr: '',
|
|
4979
|
+
exitCode: 0,
|
|
4980
|
+
});
|
|
4981
|
+
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
4982
|
+
{
|
|
4983
|
+
name: 'token-sonnet-exhausted',
|
|
4984
|
+
token: 'token-sonnet-exhausted',
|
|
4985
|
+
fiveHourUtilization: 0.1,
|
|
4986
|
+
sevenDayUtilization: 0,
|
|
4987
|
+
blocked: false,
|
|
4988
|
+
rejected: false,
|
|
4989
|
+
blockedUntilEpoch: 0,
|
|
4990
|
+
modelWeeklyLimits: {
|
|
4991
|
+
seven_day_sonnet: { rejected: true, resetsAt: futureReset },
|
|
4992
|
+
},
|
|
4993
|
+
},
|
|
4994
|
+
{
|
|
4995
|
+
name: 'token-sonnet-ok',
|
|
4996
|
+
token: 'token-sonnet-ok',
|
|
4997
|
+
fiveHourUtilization: 0.5,
|
|
4998
|
+
sevenDayUtilization: 0,
|
|
4999
|
+
blocked: false,
|
|
5000
|
+
rejected: false,
|
|
5001
|
+
blockedUntilEpoch: 0,
|
|
5002
|
+
modelWeeklyLimits: {},
|
|
5003
|
+
},
|
|
5004
|
+
]);
|
|
5005
|
+
|
|
5006
|
+
await useCase.run({
|
|
5007
|
+
projectUrl: 'https://github.com/user/repo',
|
|
5008
|
+
defaultAgentName: 'agent1',
|
|
5009
|
+
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
5010
|
+
fallbackLlmModelName: 'claude-opus-4-8',
|
|
5011
|
+
defaultLlmAgentName: null,
|
|
5012
|
+
configFilePath: '/path/to/config.yml',
|
|
5013
|
+
maximumPreparingIssuesCount: null,
|
|
5014
|
+
utilizationPercentageThreshold: 90,
|
|
5015
|
+
allowedIssueAuthors: null,
|
|
5016
|
+
codexHomeCandidates: null,
|
|
5017
|
+
allowIssueCacheMinutes: 0,
|
|
5018
|
+
labelsAsLlmAgentName: null,
|
|
5019
|
+
});
|
|
5020
|
+
|
|
5021
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(2);
|
|
5022
|
+
const callForExhausted =
|
|
5023
|
+
mockLocalCommandRunner.runCommand.mock.calls.find(
|
|
5024
|
+
(call) =>
|
|
5025
|
+
call[2]?.env?.CLAUDE_CODE_OAUTH_TOKEN === 'token-sonnet-exhausted',
|
|
5026
|
+
);
|
|
5027
|
+
const callForOk = mockLocalCommandRunner.runCommand.mock.calls.find(
|
|
5028
|
+
(call) => call[2]?.env?.CLAUDE_CODE_OAUTH_TOKEN === 'token-sonnet-ok',
|
|
5029
|
+
);
|
|
5030
|
+
expect(callForExhausted).toBeDefined();
|
|
5031
|
+
expect(callForOk).toBeDefined();
|
|
5032
|
+
expect(callForExhausted?.[1][2]).toBe('claude-opus-4-8');
|
|
5033
|
+
expect(callForOk?.[1][2]).toBe('claude-sonnet-4-6');
|
|
5034
|
+
});
|
|
5035
|
+
|
|
5036
|
+
it('excludes a token whose seven_day_sonnet and seven_day_opus weekly limits are both rejected', async () => {
|
|
5037
|
+
const awaitingIssue = createMockIssue({
|
|
5038
|
+
url: 'url1',
|
|
5039
|
+
title: 'Issue 1',
|
|
5040
|
+
labels: ['category:impl'],
|
|
5041
|
+
status: 'Awaiting Workspace',
|
|
5042
|
+
number: 1,
|
|
5043
|
+
itemId: 'item-1',
|
|
5044
|
+
});
|
|
5045
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
5046
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
5047
|
+
createMockStoryObjectMap([awaitingIssue]),
|
|
5048
|
+
);
|
|
5049
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
5050
|
+
stdout: '',
|
|
5051
|
+
stderr: '',
|
|
5052
|
+
exitCode: 0,
|
|
5053
|
+
});
|
|
5054
|
+
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
5055
|
+
{
|
|
5056
|
+
name: 'token-both-exhausted',
|
|
5057
|
+
token: 'token-both-exhausted',
|
|
5058
|
+
fiveHourUtilization: 0.1,
|
|
5059
|
+
sevenDayUtilization: 0,
|
|
5060
|
+
blocked: false,
|
|
5061
|
+
rejected: false,
|
|
5062
|
+
blockedUntilEpoch: 0,
|
|
5063
|
+
modelWeeklyLimits: {
|
|
5064
|
+
seven_day_sonnet: { rejected: true, resetsAt: futureReset },
|
|
5065
|
+
seven_day_opus: { rejected: true, resetsAt: futureReset },
|
|
5066
|
+
},
|
|
5067
|
+
},
|
|
5068
|
+
]);
|
|
5069
|
+
const consoleWarnSpy = jest
|
|
5070
|
+
.spyOn(console, 'warn')
|
|
5071
|
+
.mockImplementation(() => {});
|
|
5072
|
+
|
|
5073
|
+
await useCase.run({
|
|
5074
|
+
projectUrl: 'https://github.com/user/repo',
|
|
5075
|
+
defaultAgentName: 'agent1',
|
|
5076
|
+
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
5077
|
+
fallbackLlmModelName: 'claude-opus-4-8',
|
|
5078
|
+
defaultLlmAgentName: null,
|
|
5079
|
+
configFilePath: '/path/to/config.yml',
|
|
5080
|
+
maximumPreparingIssuesCount: null,
|
|
5081
|
+
utilizationPercentageThreshold: 90,
|
|
5082
|
+
allowedIssueAuthors: null,
|
|
5083
|
+
codexHomeCandidates: null,
|
|
5084
|
+
allowIssueCacheMinutes: 0,
|
|
5085
|
+
labelsAsLlmAgentName: null,
|
|
5086
|
+
});
|
|
5087
|
+
|
|
5088
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(0);
|
|
5089
|
+
expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(0);
|
|
5090
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
5091
|
+
expect.stringContaining('Skipping starting preparation'),
|
|
5092
|
+
);
|
|
5093
|
+
consoleWarnSpy.mockRestore();
|
|
5094
|
+
});
|
|
5095
|
+
|
|
5096
|
+
it('excludes a token whose generic seven_day weekly limit is rejected even when the per-model windows are open', async () => {
|
|
5097
|
+
const awaitingIssue = createMockIssue({
|
|
5098
|
+
url: 'url1',
|
|
5099
|
+
title: 'Issue 1',
|
|
5100
|
+
labels: ['category:impl'],
|
|
5101
|
+
status: 'Awaiting Workspace',
|
|
5102
|
+
number: 1,
|
|
5103
|
+
itemId: 'item-1',
|
|
5104
|
+
});
|
|
5105
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
5106
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
5107
|
+
createMockStoryObjectMap([awaitingIssue]),
|
|
5108
|
+
);
|
|
5109
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
5110
|
+
stdout: '',
|
|
5111
|
+
stderr: '',
|
|
5112
|
+
exitCode: 0,
|
|
5113
|
+
});
|
|
5114
|
+
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
5115
|
+
{
|
|
5116
|
+
name: 'token-general-exhausted',
|
|
5117
|
+
token: 'token-general-exhausted',
|
|
5118
|
+
fiveHourUtilization: 0.1,
|
|
5119
|
+
sevenDayUtilization: 0,
|
|
5120
|
+
blocked: false,
|
|
5121
|
+
rejected: false,
|
|
5122
|
+
blockedUntilEpoch: 0,
|
|
5123
|
+
modelWeeklyLimits: {
|
|
5124
|
+
seven_day: { rejected: true, resetsAt: futureReset },
|
|
5125
|
+
},
|
|
5126
|
+
},
|
|
5127
|
+
]);
|
|
5128
|
+
const consoleWarnSpy = jest
|
|
5129
|
+
.spyOn(console, 'warn')
|
|
5130
|
+
.mockImplementation(() => {});
|
|
5131
|
+
|
|
5132
|
+
await useCase.run({
|
|
5133
|
+
projectUrl: 'https://github.com/user/repo',
|
|
5134
|
+
defaultAgentName: 'agent1',
|
|
5135
|
+
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
5136
|
+
fallbackLlmModelName: 'claude-opus-4-8',
|
|
5137
|
+
defaultLlmAgentName: null,
|
|
5138
|
+
configFilePath: '/path/to/config.yml',
|
|
5139
|
+
maximumPreparingIssuesCount: null,
|
|
5140
|
+
utilizationPercentageThreshold: 90,
|
|
5141
|
+
allowedIssueAuthors: null,
|
|
5142
|
+
codexHomeCandidates: null,
|
|
5143
|
+
allowIssueCacheMinutes: 0,
|
|
5144
|
+
labelsAsLlmAgentName: null,
|
|
5145
|
+
});
|
|
5146
|
+
|
|
5147
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(0);
|
|
5148
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
5149
|
+
expect.stringContaining('Skipping starting preparation'),
|
|
5150
|
+
);
|
|
5151
|
+
consoleWarnSpy.mockRestore();
|
|
5152
|
+
});
|
|
5153
|
+
|
|
5154
|
+
it('lets a per-issue llm-model label override the per-token routed model', async () => {
|
|
5155
|
+
const awaitingIssue = createMockIssue({
|
|
5156
|
+
url: 'url1',
|
|
5157
|
+
title: 'Issue 1',
|
|
5158
|
+
labels: ['category:impl', 'llm-model:claude-3-5-haiku-20241022'],
|
|
5159
|
+
status: 'Awaiting Workspace',
|
|
5160
|
+
number: 1,
|
|
5161
|
+
itemId: 'item-1',
|
|
5162
|
+
});
|
|
5163
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
5164
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
5165
|
+
createMockStoryObjectMap([awaitingIssue]),
|
|
5166
|
+
);
|
|
5167
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
5168
|
+
stdout: '',
|
|
5169
|
+
stderr: '',
|
|
5170
|
+
exitCode: 0,
|
|
5171
|
+
});
|
|
5172
|
+
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
5173
|
+
{
|
|
5174
|
+
name: 'token-sonnet-exhausted',
|
|
5175
|
+
token: 'token-sonnet-exhausted',
|
|
5176
|
+
fiveHourUtilization: 0.1,
|
|
5177
|
+
sevenDayUtilization: 0,
|
|
5178
|
+
blocked: false,
|
|
5179
|
+
rejected: false,
|
|
5180
|
+
blockedUntilEpoch: 0,
|
|
5181
|
+
modelWeeklyLimits: {
|
|
5182
|
+
seven_day_sonnet: { rejected: true, resetsAt: futureReset },
|
|
5183
|
+
},
|
|
5184
|
+
},
|
|
5185
|
+
]);
|
|
5186
|
+
|
|
5187
|
+
await useCase.run({
|
|
5188
|
+
projectUrl: 'https://github.com/user/repo',
|
|
5189
|
+
defaultAgentName: 'agent1',
|
|
5190
|
+
defaultLlmModelName: 'claude-sonnet-4-6',
|
|
5191
|
+
fallbackLlmModelName: 'claude-opus-4-8',
|
|
5192
|
+
defaultLlmAgentName: null,
|
|
5193
|
+
configFilePath: '/path/to/config.yml',
|
|
5194
|
+
maximumPreparingIssuesCount: null,
|
|
5195
|
+
utilizationPercentageThreshold: 90,
|
|
5196
|
+
allowedIssueAuthors: null,
|
|
5197
|
+
codexHomeCandidates: null,
|
|
5198
|
+
allowIssueCacheMinutes: 0,
|
|
5199
|
+
labelsAsLlmAgentName: null,
|
|
5200
|
+
});
|
|
5201
|
+
|
|
5202
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
|
|
5203
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][1][2]).toBe(
|
|
5204
|
+
'claude-3-5-haiku-20241022',
|
|
5205
|
+
);
|
|
5206
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][2]).toEqual({
|
|
5207
|
+
env: {
|
|
5208
|
+
CLAUDE_CODE_OAUTH_TOKEN: 'token-sonnet-exhausted',
|
|
5209
|
+
ANTHROPIC_BASE_URL: 'http://127.0.0.1:8787',
|
|
5210
|
+
},
|
|
5211
|
+
});
|
|
5212
|
+
});
|
|
5213
|
+
});
|
|
5214
|
+
|
|
5018
5215
|
describe('per-token in-flight global concurrency enforcement', () => {
|
|
5019
5216
|
it('should not spawn when the selected token already has its full in-flight limit occupied by processes from other projects', async () => {
|
|
5020
5217
|
const awaitingIssues: Issue[] = [
|
|
@@ -61,6 +61,29 @@ export class StartPreparationUseCase {
|
|
|
61
61
|
return general !== undefined && general.rejected;
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
+
private selectModelForToken = (
|
|
65
|
+
usage: ClaudeTokenUsage,
|
|
66
|
+
defaultModelName: string | null,
|
|
67
|
+
fallbackModelName: string | null,
|
|
68
|
+
): string | null => {
|
|
69
|
+
const generalWeeklyLimit = usage.modelWeeklyLimits['seven_day'];
|
|
70
|
+
if (generalWeeklyLimit !== undefined && generalWeeklyLimit.rejected) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const candidateModelNames = [defaultModelName, fallbackModelName].filter(
|
|
74
|
+
(modelName): modelName is string =>
|
|
75
|
+
modelName !== null && modelName !== '',
|
|
76
|
+
);
|
|
77
|
+
for (const candidateModelName of candidateModelNames) {
|
|
78
|
+
const weeklyLimitType = this.weeklyLimitTypeForModel(candidateModelName);
|
|
79
|
+
const specificWeeklyLimit = usage.modelWeeklyLimits[weeklyLimitType];
|
|
80
|
+
if (specificWeeklyLimit === undefined || !specificWeeklyLimit.rejected) {
|
|
81
|
+
return candidateModelName;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
};
|
|
86
|
+
|
|
64
87
|
private secondsUntilSevenDayReset = (
|
|
65
88
|
usage: ClaudeTokenUsage,
|
|
66
89
|
weeklyLimitType: string,
|
|
@@ -79,18 +102,19 @@ export class StartPreparationUseCase {
|
|
|
79
102
|
|
|
80
103
|
private compareBySevenDayDeadlineThenUtilization = (
|
|
81
104
|
a: ClaudeTokenUsage,
|
|
105
|
+
aWeeklyLimitType: string,
|
|
82
106
|
b: ClaudeTokenUsage,
|
|
83
|
-
|
|
107
|
+
bWeeklyLimitType: string,
|
|
84
108
|
nowEpochSeconds: number,
|
|
85
109
|
): number => {
|
|
86
110
|
const aSecondsUntilReset = this.secondsUntilSevenDayReset(
|
|
87
111
|
a,
|
|
88
|
-
|
|
112
|
+
aWeeklyLimitType,
|
|
89
113
|
nowEpochSeconds,
|
|
90
114
|
);
|
|
91
115
|
const bSecondsUntilReset = this.secondsUntilSevenDayReset(
|
|
92
116
|
b,
|
|
93
|
-
|
|
117
|
+
bWeeklyLimitType,
|
|
94
118
|
nowEpochSeconds,
|
|
95
119
|
);
|
|
96
120
|
if (aSecondsUntilReset !== bSecondsUntilReset) {
|
|
@@ -128,35 +152,43 @@ export class StartPreparationUseCase {
|
|
|
128
152
|
private selectRotationTokens = (
|
|
129
153
|
tokenUsages: ClaudeTokenUsage[],
|
|
130
154
|
utilizationPercentageThreshold: number,
|
|
131
|
-
|
|
155
|
+
defaultModelName: string | null,
|
|
156
|
+
fallbackModelName: string | null,
|
|
132
157
|
maxConcurrent: number,
|
|
133
158
|
): {
|
|
134
159
|
tokens: string[];
|
|
135
160
|
effectiveCap: number;
|
|
136
161
|
tokensWithLimits: Array<{
|
|
137
162
|
token: string;
|
|
163
|
+
model: string;
|
|
138
164
|
limit: number;
|
|
139
165
|
secondsUntilSevenDayReset: number;
|
|
140
166
|
}>;
|
|
141
167
|
} => {
|
|
142
|
-
const weeklyLimitType = this.weeklyLimitTypeForModel(modelName);
|
|
143
168
|
const nowEpochSeconds = Date.now() / 1000;
|
|
144
169
|
const eligibleTokens = tokenUsages
|
|
145
170
|
.filter((usage) => !usage.blocked)
|
|
146
171
|
.filter((usage) => !usage.rejected)
|
|
147
172
|
.filter((usage) => !this.isWithinCooldown(usage, nowEpochSeconds))
|
|
148
|
-
.filter(
|
|
149
|
-
(usage) => !this.isModelWeeklyLimitRejected(usage, weeklyLimitType),
|
|
150
|
-
)
|
|
151
173
|
.filter(
|
|
152
174
|
(usage) =>
|
|
153
175
|
usage.fiveHourUtilization * 100 < utilizationPercentageThreshold,
|
|
154
176
|
)
|
|
177
|
+
.flatMap((usage) => {
|
|
178
|
+
const model = this.selectModelForToken(
|
|
179
|
+
usage,
|
|
180
|
+
defaultModelName,
|
|
181
|
+
fallbackModelName,
|
|
182
|
+
);
|
|
183
|
+
if (model === null) return [];
|
|
184
|
+
return [{ usage, model }];
|
|
185
|
+
})
|
|
155
186
|
.sort((a, b) =>
|
|
156
187
|
this.compareBySevenDayDeadlineThenUtilization(
|
|
157
|
-
a,
|
|
158
|
-
|
|
159
|
-
|
|
188
|
+
a.usage,
|
|
189
|
+
this.weeklyLimitTypeForModel(a.model),
|
|
190
|
+
b.usage,
|
|
191
|
+
this.weeklyLimitTypeForModel(b.model),
|
|
160
192
|
nowEpochSeconds,
|
|
161
193
|
),
|
|
162
194
|
);
|
|
@@ -165,15 +197,16 @@ export class StartPreparationUseCase {
|
|
|
165
197
|
return { tokens: [], effectiveCap: 0, tokensWithLimits: [] };
|
|
166
198
|
}
|
|
167
199
|
|
|
168
|
-
const tokensWithLimits = eligibleTokens.map((usage) => ({
|
|
200
|
+
const tokensWithLimits = eligibleTokens.map(({ usage, model }) => ({
|
|
169
201
|
token: usage.token,
|
|
202
|
+
model,
|
|
170
203
|
limit: this.getTokenConcurrentLimit(
|
|
171
204
|
usage.fiveHourUtilization,
|
|
172
205
|
usage.sevenDayUtilization,
|
|
173
206
|
),
|
|
174
207
|
secondsUntilSevenDayReset: this.secondsUntilSevenDayReset(
|
|
175
208
|
usage,
|
|
176
|
-
|
|
209
|
+
this.weeklyLimitTypeForModel(model),
|
|
177
210
|
nowEpochSeconds,
|
|
178
211
|
),
|
|
179
212
|
}));
|
|
@@ -215,6 +248,7 @@ export class StartPreparationUseCase {
|
|
|
215
248
|
.sort((a, b) =>
|
|
216
249
|
this.compareBySevenDayDeadlineThenUtilization(
|
|
217
250
|
a,
|
|
251
|
+
weeklyLimitType,
|
|
218
252
|
b,
|
|
219
253
|
weeklyLimitType,
|
|
220
254
|
nowEpochSeconds,
|
|
@@ -272,6 +306,7 @@ export class StartPreparationUseCase {
|
|
|
272
306
|
let proxyBaseUrl: string | null = null;
|
|
273
307
|
let selectedTokensWithLimits: Array<{
|
|
274
308
|
token: string;
|
|
309
|
+
model: string;
|
|
275
310
|
limit: number;
|
|
276
311
|
secondsUntilSevenDayReset: number;
|
|
277
312
|
}> = [];
|
|
@@ -287,51 +322,23 @@ export class StartPreparationUseCase {
|
|
|
287
322
|
const maximumPreparingIssuesCount =
|
|
288
323
|
params.maximumPreparingIssuesCount ?? NORMAL_CONCURRENT_LIMIT;
|
|
289
324
|
let effectiveMaxPreparingIssuesCount = maximumPreparingIssuesCount;
|
|
290
|
-
|
|
325
|
+
const fallbackLlmModelName =
|
|
326
|
+
params.fallbackLlmModelName ?? DEFAULT_FALLBACK_LLM_MODEL_NAME;
|
|
291
327
|
if (tokenUsages.length > 0) {
|
|
292
328
|
const {
|
|
293
|
-
tokens:
|
|
294
|
-
effectiveCap,
|
|
295
|
-
tokensWithLimits:
|
|
329
|
+
tokens: selectedTokens,
|
|
330
|
+
effectiveCap: selectedCap,
|
|
331
|
+
tokensWithLimits: selectedTokensWithLimitsLocal,
|
|
296
332
|
} = this.selectRotationTokens(
|
|
297
333
|
tokenUsages,
|
|
298
334
|
params.utilizationPercentageThreshold,
|
|
299
335
|
params.defaultLlmModelName,
|
|
336
|
+
fallbackLlmModelName,
|
|
300
337
|
maximumPreparingIssuesCount,
|
|
301
338
|
);
|
|
302
|
-
let selectedTokens = ranked;
|
|
303
|
-
let selectedCap = effectiveCap;
|
|
304
|
-
let selectedTokensWithLimitsLocal = rankedTokensWithLimits;
|
|
305
|
-
if (
|
|
306
|
-
selectedTokens.length === 0 &&
|
|
307
|
-
this.weeklyLimitTypeForModel(params.defaultLlmModelName) ===
|
|
308
|
-
'seven_day_sonnet'
|
|
309
|
-
) {
|
|
310
|
-
const fallbackModelName =
|
|
311
|
-
params.fallbackLlmModelName ?? DEFAULT_FALLBACK_LLM_MODEL_NAME;
|
|
312
|
-
const {
|
|
313
|
-
tokens: fallbackRanked,
|
|
314
|
-
effectiveCap: fallbackCap,
|
|
315
|
-
tokensWithLimits: fallbackTokensWithLimits,
|
|
316
|
-
} = this.selectRotationTokens(
|
|
317
|
-
tokenUsages,
|
|
318
|
-
params.utilizationPercentageThreshold,
|
|
319
|
-
fallbackModelName,
|
|
320
|
-
maximumPreparingIssuesCount,
|
|
321
|
-
);
|
|
322
|
-
if (fallbackRanked.length > 0) {
|
|
323
|
-
console.warn(
|
|
324
|
-
`Sonnet 7-day weekly limit (${this.weeklyLimitTypeForModel(params.defaultLlmModelName)}) is exhausted across all configured Claude OAuth token(s). Falling back to ${fallbackModelName}.`,
|
|
325
|
-
);
|
|
326
|
-
selectedTokens = fallbackRanked;
|
|
327
|
-
selectedCap = fallbackCap;
|
|
328
|
-
selectedTokensWithLimitsLocal = fallbackTokensWithLimits;
|
|
329
|
-
effectiveDefaultLlmModelName = fallbackModelName;
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
339
|
if (selectedTokens.length === 0) {
|
|
333
340
|
console.warn(
|
|
334
|
-
`All ${tokenUsages.length} configured Claude OAuth token(s) are unavailable (blocked, rejected, weekly
|
|
341
|
+
`All ${tokenUsages.length} configured Claude OAuth token(s) are unavailable (blocked, rejected, weekly limits for the configured model(s) exhausted, or 5h utilization >= ${params.utilizationPercentageThreshold}%). Skipping starting preparation.`,
|
|
335
342
|
);
|
|
336
343
|
return { rotationOrder };
|
|
337
344
|
}
|
|
@@ -434,12 +441,15 @@ export class StartPreparationUseCase {
|
|
|
434
441
|
.trim() ||
|
|
435
442
|
params.defaultLlmAgentName ||
|
|
436
443
|
params.defaultAgentName;
|
|
437
|
-
const
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
444
|
+
const labelModelName = issue.labels
|
|
445
|
+
.find((label: string) => label.startsWith('llm-model:'))
|
|
446
|
+
?.replace('llm-model:', '')
|
|
447
|
+
.trim();
|
|
448
|
+
if (
|
|
449
|
+
!labelModelName &&
|
|
450
|
+
!params.defaultLlmModelName &&
|
|
451
|
+
rotationTokens === null
|
|
452
|
+
) {
|
|
443
453
|
console.error(
|
|
444
454
|
`No LLM model configured for issue ${issue.url}. Provide --defaultLlmModelName or add an llm-model: label.`,
|
|
445
455
|
);
|
|
@@ -522,30 +532,13 @@ export class StartPreparationUseCase {
|
|
|
522
532
|
);
|
|
523
533
|
issue.status = PREPARATION_STATUS_NAME;
|
|
524
534
|
|
|
525
|
-
const awArgs: string[] = [
|
|
526
|
-
issue.url,
|
|
527
|
-
agent,
|
|
528
|
-
model,
|
|
529
|
-
'--configFilePath',
|
|
530
|
-
params.configFilePath,
|
|
531
|
-
'--branch',
|
|
532
|
-
branchName,
|
|
533
|
-
];
|
|
534
|
-
if (
|
|
535
|
-
params.codexHomeCandidates !== null &&
|
|
536
|
-
params.codexHomeCandidates.length > 0
|
|
537
|
-
) {
|
|
538
|
-
const codexHome =
|
|
539
|
-
params.codexHomeCandidates[
|
|
540
|
-
startedInThisRunCount % params.codexHomeCandidates.length
|
|
541
|
-
];
|
|
542
|
-
awArgs.push('--codexHome', codexHome);
|
|
543
|
-
}
|
|
544
535
|
let spawnEnv: Record<string, string> | undefined;
|
|
536
|
+
let routedModelName: string | null = null;
|
|
545
537
|
if (rotationTokens !== null && proxyBaseUrl !== null) {
|
|
546
538
|
const tokenWithSoonestResetAmongAvailable = selectedTokensWithLimits
|
|
547
539
|
.map((t) => ({
|
|
548
540
|
token: t.token,
|
|
541
|
+
model: t.model,
|
|
549
542
|
remaining:
|
|
550
543
|
t.limit -
|
|
551
544
|
(tokenInFlightCounts[t.token] ?? 0) -
|
|
@@ -563,6 +556,7 @@ export class StartPreparationUseCase {
|
|
|
563
556
|
break;
|
|
564
557
|
}
|
|
565
558
|
const selected = tokenWithSoonestResetAmongAvailable.token;
|
|
559
|
+
routedModelName = tokenWithSoonestResetAmongAvailable.model;
|
|
566
560
|
spawnedInThisRunByToken[selected] =
|
|
567
561
|
(spawnedInThisRunByToken[selected] ?? 0) + 1;
|
|
568
562
|
spawnEnv = {
|
|
@@ -570,6 +564,33 @@ export class StartPreparationUseCase {
|
|
|
570
564
|
ANTHROPIC_BASE_URL: proxyBaseUrl,
|
|
571
565
|
};
|
|
572
566
|
}
|
|
567
|
+
const model =
|
|
568
|
+
labelModelName || routedModelName || params.defaultLlmModelName;
|
|
569
|
+
if (!model) {
|
|
570
|
+
console.error(
|
|
571
|
+
`No LLM model configured for issue ${issue.url}. Provide --defaultLlmModelName or add an llm-model: label.`,
|
|
572
|
+
);
|
|
573
|
+
continue;
|
|
574
|
+
}
|
|
575
|
+
const awArgs: string[] = [
|
|
576
|
+
issue.url,
|
|
577
|
+
agent,
|
|
578
|
+
model,
|
|
579
|
+
'--configFilePath',
|
|
580
|
+
params.configFilePath,
|
|
581
|
+
'--branch',
|
|
582
|
+
branchName,
|
|
583
|
+
];
|
|
584
|
+
if (
|
|
585
|
+
params.codexHomeCandidates !== null &&
|
|
586
|
+
params.codexHomeCandidates.length > 0
|
|
587
|
+
) {
|
|
588
|
+
const codexHome =
|
|
589
|
+
params.codexHomeCandidates[
|
|
590
|
+
startedInThisRunCount % params.codexHomeCandidates.length
|
|
591
|
+
];
|
|
592
|
+
awArgs.push('--codexHome', codexHome);
|
|
593
|
+
}
|
|
573
594
|
await this.localCommandRunner.runCommand(
|
|
574
595
|
'aw',
|
|
575
596
|
awArgs,
|
|
@@ -21,6 +21,7 @@ export declare class StartPreparationUseCase {
|
|
|
21
21
|
private weeklyLimitTypeForModel;
|
|
22
22
|
private isWithinCooldown;
|
|
23
23
|
private isModelWeeklyLimitRejected;
|
|
24
|
+
private selectModelForToken;
|
|
24
25
|
private secondsUntilSevenDayReset;
|
|
25
26
|
private compareBySevenDayDeadlineThenUtilization;
|
|
26
27
|
private taperedConcurrentLimit;
|
|
@@ -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;AAShE,eAAO,MAAM,+BAA+B,oBAAoB,CAAC;AAEjE,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;IAC3B,gBAAgB,EAAE,OAAO,CAAC;CAC3B,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,uBAAuB,CAK7B;IAEF,OAAO,CAAC,gBAAgB,CAGgC;IAExD,OAAO,CAAC,0BAA0B,CAQhC;IAEF,OAAO,CAAC,yBAAyB,CAc/B;IAEF,OAAO,CAAC,wCAAwC,
|
|
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;AAShE,eAAO,MAAM,+BAA+B,oBAAoB,CAAC;AAEjE,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;IAC3B,gBAAgB,EAAE,OAAO,CAAC;CAC3B,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,uBAAuB,CAK7B;IAEF,OAAO,CAAC,gBAAgB,CAGgC;IAExD,OAAO,CAAC,0BAA0B,CAQhC;IAEF,OAAO,CAAC,mBAAmB,CAqBzB;IAEF,OAAO,CAAC,yBAAyB,CAc/B;IAEF,OAAO,CAAC,wCAAwC,CAqB9C;IAEF,OAAO,CAAC,sBAAsB,CAS5B;IAEF,uBAAuB,GACrB,qBAAqB,MAAM,EAC3B,qBAAqB,MAAM,KAC1B,MAAM,CAUP;IAEF,OAAO,CAAC,oBAAoB,CA4E1B;IAEF,kBAAkB,GAChB,aAAa,gBAAgB,EAAE,EAC/B,gCAAgC,MAAM,EACtC,WAAW,MAAM,GAAG,IAAI,KACvB,kBAAkB,EAAE,CAqDrB;IAEF,GAAG,GAAU,QAAQ;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,EAAE,MAAM,CAAC;QACzB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;QACpC,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;QAC/B,oBAAoB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;KACvC,KAAG,OAAO,CAAC;QAAE,aAAa,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAAA;KAAE,CAAC,CA6SzD;CACH"}
|