github-issue-tower-defence-management 1.88.1 → 1.89.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 +7 -0
- package/README.md +11 -0
- package/bin/adapter/entry-points/cli/index.js +21 -0
- package/bin/adapter/entry-points/cli/index.js.map +1 -1
- package/bin/adapter/entry-points/handlers/OauthTokenSelectHandler.js +97 -0
- package/bin/adapter/entry-points/handlers/OauthTokenSelectHandler.js.map +1 -0
- package/bin/adapter/proxy/RateLimitCache.js +3 -3
- package/bin/adapter/proxy/RateLimitCache.js.map +1 -1
- package/bin/domain/usecases/OauthTokenSelectUseCase.js +87 -0
- package/bin/domain/usecases/OauthTokenSelectUseCase.js.map +1 -0
- package/package.json +1 -1
- package/src/adapter/entry-points/cli/index.ts +38 -0
- package/src/adapter/entry-points/handlers/OauthTokenSelectHandler.test.ts +204 -0
- package/src/adapter/entry-points/handlers/OauthTokenSelectHandler.ts +132 -0
- package/src/adapter/proxy/RateLimitCache.ts +9 -4
- package/src/domain/usecases/OauthTokenSelectUseCase.test.ts +179 -0
- package/src/domain/usecases/OauthTokenSelectUseCase.ts +158 -0
- package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
- package/types/adapter/entry-points/handlers/OauthTokenSelectHandler.d.ts +20 -0
- package/types/adapter/entry-points/handlers/OauthTokenSelectHandler.d.ts.map +1 -0
- package/types/adapter/proxy/RateLimitCache.d.ts +2 -2
- package/types/adapter/proxy/RateLimitCache.d.ts.map +1 -1
- package/types/domain/usecases/OauthTokenSelectUseCase.d.ts +35 -0
- package/types/domain/usecases/OauthTokenSelectUseCase.d.ts.map +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [1.89.0](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.88.1...v1.89.0) (2026-06-18)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **cli:** add selectOauthToken subcommand printing one rate-limit-aware OAuth token ([#835](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/issues/835)) ([0928646](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/0928646c7b32e9d45d6effc1289dc0460070263b))
|
|
7
|
+
|
|
1
8
|
## [1.88.1](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.88.0...v1.88.1) (2026-06-18)
|
|
2
9
|
|
|
3
10
|
|
package/README.md
CHANGED
|
@@ -21,6 +21,7 @@ Commands:
|
|
|
21
21
|
notifyFinishedIssuePreparation [options] Notify that issue preparation is finished
|
|
22
22
|
checkIssueReviewReadiness [options] Check whether an issue is review-ready (read-only; does not change Status or post any comment)
|
|
23
23
|
serveConsole [options] Start the local TDPM Console HTTP server
|
|
24
|
+
selectOauthToken [options] Print one rate-limit-aware Claude Code OAuth token to stdout (pipeable; read-only)
|
|
24
25
|
help [command] display help for command
|
|
25
26
|
|
|
26
27
|
Options for schedule:
|
|
@@ -58,6 +59,10 @@ Options for serveConsole:
|
|
|
58
59
|
--configFilePath <path> Path to config file for tower defence management (required)
|
|
59
60
|
--port <number> Port for the console HTTP server (default: 9981)
|
|
60
61
|
--consoleDataOutputDir <path> Directory where console data files are written and served from
|
|
62
|
+
|
|
63
|
+
Options for selectOauthToken:
|
|
64
|
+
--tokenListJsonPath <path> Path to the JSON array of { name, token } records (falls back to the CLAUDE_CODE_OAUTH_TOKEN_LIST_JSON_PATH environment variable)
|
|
65
|
+
--cacheDir <path> Directory holding per-token rate-limit cache files (falls back to the TDPM_RATELIMIT_CACHE_DIR environment variable, then to ${XDG_CACHE_HOME:-~/.cache}/tdpm/ratelimit)
|
|
61
66
|
```
|
|
62
67
|
|
|
63
68
|
The `serveConsole` sub-command starts a local HTTP server that serves the TDPM Console. Every response is sent with `Cache-Control: no-store`. Any request path containing a segment that begins with a dot (for example `/.git` or `/.env`) is rejected with HTTP 404. The UI bootstrap assets (HTML and JS) are served without authentication; served `*.json` files and `/api/*` paths require an access token supplied either as the `k` query parameter (`?k=<token>`) or the `X-PV-Token` request header. The access token is read from the `consoleAccessToken` config value and never appears on the command line. When the built UI bundle directory (`ui-dist`) is absent the server still starts and serves a minimal placeholder index for `/` and `/index.html`.
|
|
@@ -72,6 +77,8 @@ The `.done` exclusion is persisted per tab in a `.done.json` file alongside each
|
|
|
72
77
|
|
|
73
78
|
The `checkIssueReviewReadiness` sub-command lets an agent self-check whether an issue is currently review-ready. It does NOT change the issue Status field and does NOT post any comment. It writes a single JSON line to stdout of the shape `{ "reviewReady": boolean, "rejections": [{ "type": string, "detail": string }] }` and exits 0 on a successful evaluation regardless of readiness; a non-zero exit indicates an operational error (auth failure, network error). The rejection types include: `ISSUE_NOT_FOUND`, `NO_REPORT_FROM_AGENT_BOT`, `REPORT_HAS_NEXT_STEP`, `PULL_REQUEST_NOT_FOUND`, `PULL_REQUEST_IS_DRAFT`, `PULL_REQUEST_CONFLICTED`, `ANY_CI_JOB_FAILED_OR_IN_PROGRESS`, `REQUIRED_CI_JOB_NEVER_STARTED`, `ANY_REVIEW_COMMENT_NOT_RESOLVED`, and `MULTIPLE_PULL_REQUESTS_FOUND`. The `--projectUrl` option is optional; when omitted the command still runs using only the issue URL.
|
|
74
79
|
|
|
80
|
+
The `selectOauthToken` sub-command reads the same per-token rate-limit cache that the `startDaemon` proxy writes (see "Claude OAuth Token Rotation" below) and prints exactly one token string to stdout so a caller can choose an appropriate token before launching Claude Code. It is read-only: it never starts the proxy, never mutates any cache file, and never writes the token anywhere. Selection runs in two stages. First, a candidate filter keeps tokens whose 5-hour window is at least 60% free (5-hour utilization at most 0.40) AND whose 7-day window is at least 30% free (7-day utilization at most 0.70), where "% free" is `1 - utilization`. A token with no cache file, or whose window reset epoch has already passed, is treated as fully free (utilization 0) for these checks. Second, among the surviving candidates it selects the single token whose 7-day window reset epoch is nearest in the future (soonest reset), so weekly quota that would otherwise reset unused is consumed first; a candidate with no active 7-day window is treated as having the farthest reset (now + 7 days) and therefore sorts last. The selected token string is written to stdout (pipeable) and the per-candidate decision trace is written to stderr. When no token passes the filter, nothing is written to stdout and the command exits non-zero with an explanatory message on stderr. The token-list path comes from `--tokenListJsonPath` or the `CLAUDE_CODE_OAUTH_TOKEN_LIST_JSON_PATH` environment variable; the cache directory comes from `--cacheDir` or the `TDPM_RATELIMIT_CACHE_DIR` environment variable, defaulting to `${XDG_CACHE_HOME:-~/.cache}/tdpm/ratelimit`.
|
|
81
|
+
|
|
75
82
|
## Example 📖
|
|
76
83
|
|
|
77
84
|
Here's a quick example to illustrate its usage:
|
|
@@ -100,6 +107,10 @@ npx github-issue-tower-defence-management checkIssueReviewReadiness --configFile
|
|
|
100
107
|
npx github-issue-tower-defence-management serveConsole --configFilePath ./preparator-config.yml --port 9981
|
|
101
108
|
```
|
|
102
109
|
|
|
110
|
+
```
|
|
111
|
+
TOKEN=$(npx github-issue-tower-defence-management selectOauthToken --tokenListJsonPath ./claudeCodeOauthTokenList.json)
|
|
112
|
+
```
|
|
113
|
+
|
|
103
114
|
## Config
|
|
104
115
|
|
|
105
116
|
### Schedule Command Config
|
|
@@ -61,6 +61,7 @@ const RevertOrphanedPreparationUseCase_1 = require("../../../domain/usecases/Rev
|
|
|
61
61
|
const path = __importStar(require("path"));
|
|
62
62
|
const consoleServer_1 = require("../console/consoleServer");
|
|
63
63
|
const consoleReadApi_1 = require("../console/consoleReadApi");
|
|
64
|
+
const OauthTokenSelectHandler_1 = require("../handlers/OauthTokenSelectHandler");
|
|
64
65
|
const buildGithubRepositoryParams = (localStorageRepository, token) => [
|
|
65
66
|
localStorageRepository,
|
|
66
67
|
token,
|
|
@@ -412,6 +413,26 @@ exports.program
|
|
|
412
413
|
});
|
|
413
414
|
console.log(`TDPM Console server listening on port ${port}`);
|
|
414
415
|
});
|
|
416
|
+
exports.program
|
|
417
|
+
.command('selectOauthToken')
|
|
418
|
+
.description('Print exactly one Claude Code OAuth token chosen by a rate-limit-aware filter. The token string is written to stdout (pipeable); the per-candidate decision trace is written to stderr. Exits non-zero when no token passes the filter.')
|
|
419
|
+
.option('--tokenListJsonPath <path>', 'Path to the JSON array of { name, token } records. Falls back to the CLAUDE_CODE_OAUTH_TOKEN_LIST_JSON_PATH environment variable.')
|
|
420
|
+
.option('--cacheDir <path>', 'Directory holding per-token rate-limit cache files. Falls back to the TDPM_RATELIMIT_CACHE_DIR environment variable, then to ${XDG_CACHE_HOME:-~/.cache}/tdpm/ratelimit.')
|
|
421
|
+
.action((options) => {
|
|
422
|
+
const handler = new OauthTokenSelectHandler_1.OauthTokenSelectHandler();
|
|
423
|
+
const output = handler.handle({
|
|
424
|
+
tokenListJsonPath: options.tokenListJsonPath ?? null,
|
|
425
|
+
cacheDirectory: options.cacheDir ?? null,
|
|
426
|
+
nowEpochSeconds: Date.now() / 1000,
|
|
427
|
+
});
|
|
428
|
+
for (const line of output.diagnostics) {
|
|
429
|
+
console.error(line);
|
|
430
|
+
}
|
|
431
|
+
if (output.selectedToken === null) {
|
|
432
|
+
process.exit(1);
|
|
433
|
+
}
|
|
434
|
+
process.stdout.write(`${output.selectedToken}\n`);
|
|
435
|
+
});
|
|
415
436
|
/* istanbul ignore next */
|
|
416
437
|
if (process.argv && require.main === module) {
|
|
417
438
|
exports.program.parse(process.argv);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OauthTokenSelectHandler = exports.resolveCacheDirectory = exports.resolveTokenListJsonPath = void 0;
|
|
4
|
+
const OauthTokenSelectUseCase_1 = require("../../../domain/usecases/OauthTokenSelectUseCase");
|
|
5
|
+
const RateLimitCache_1 = require("../../proxy/RateLimitCache");
|
|
6
|
+
const TokenListLoader_1 = require("../../proxy/TokenListLoader");
|
|
7
|
+
const DEFAULT_TOKEN_LIST_PATH_ENV = 'CLAUDE_CODE_OAUTH_TOKEN_LIST_JSON_PATH';
|
|
8
|
+
const DEFAULT_CACHE_DIRECTORY_ENV = 'TDPM_RATELIMIT_CACHE_DIR';
|
|
9
|
+
const resolveTokenListJsonPath = (explicitPath) => {
|
|
10
|
+
if (explicitPath !== null && explicitPath.length > 0) {
|
|
11
|
+
return explicitPath;
|
|
12
|
+
}
|
|
13
|
+
const fromEnv = process.env[DEFAULT_TOKEN_LIST_PATH_ENV];
|
|
14
|
+
if (fromEnv !== undefined && fromEnv.length > 0) {
|
|
15
|
+
return fromEnv;
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
};
|
|
19
|
+
exports.resolveTokenListJsonPath = resolveTokenListJsonPath;
|
|
20
|
+
const resolveCacheDirectory = (explicitDirectory) => {
|
|
21
|
+
if (explicitDirectory !== null && explicitDirectory.length > 0) {
|
|
22
|
+
return explicitDirectory;
|
|
23
|
+
}
|
|
24
|
+
const fromEnv = process.env[DEFAULT_CACHE_DIRECTORY_ENV];
|
|
25
|
+
if (fromEnv !== undefined && fromEnv.length > 0) {
|
|
26
|
+
return fromEnv;
|
|
27
|
+
}
|
|
28
|
+
return (0, RateLimitCache_1.cacheDir)();
|
|
29
|
+
};
|
|
30
|
+
exports.resolveCacheDirectory = resolveCacheDirectory;
|
|
31
|
+
class OauthTokenSelectHandler {
|
|
32
|
+
constructor(useCase = new OauthTokenSelectUseCase_1.OauthTokenSelectUseCase()) {
|
|
33
|
+
this.useCase = useCase;
|
|
34
|
+
this.handle = (input) => {
|
|
35
|
+
const tokenListJsonPath = (0, exports.resolveTokenListJsonPath)(input.tokenListJsonPath);
|
|
36
|
+
if (tokenListJsonPath === null) {
|
|
37
|
+
return {
|
|
38
|
+
selectedToken: null,
|
|
39
|
+
selectedName: null,
|
|
40
|
+
diagnostics: [
|
|
41
|
+
`No token list path provided. Pass --tokenListJsonPath or set ${DEFAULT_TOKEN_LIST_PATH_ENV}.`,
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const entries = (0, TokenListLoader_1.loadTokenEntries)(tokenListJsonPath);
|
|
46
|
+
if (entries === null) {
|
|
47
|
+
return {
|
|
48
|
+
selectedToken: null,
|
|
49
|
+
selectedName: null,
|
|
50
|
+
diagnostics: [
|
|
51
|
+
`No usable token entries loaded from ${tokenListJsonPath}.`,
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const cacheDirectory = (0, exports.resolveCacheDirectory)(input.cacheDirectory);
|
|
56
|
+
const candidates = entries.map(({ name, token }) => {
|
|
57
|
+
const snapshot = (0, RateLimitCache_1.readRateLimit)(token, cacheDirectory);
|
|
58
|
+
return {
|
|
59
|
+
name,
|
|
60
|
+
token,
|
|
61
|
+
snapshot: snapshot === null
|
|
62
|
+
? null
|
|
63
|
+
: {
|
|
64
|
+
fiveHourUtilization: snapshot.fiveHourUtilization,
|
|
65
|
+
fiveHourReset: snapshot.fiveHourReset,
|
|
66
|
+
sevenDayUtilization: snapshot.sevenDayUtilization,
|
|
67
|
+
sevenDayReset: snapshot.sevenDayReset,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
const result = this.useCase.run(candidates, input.nowEpochSeconds);
|
|
72
|
+
return {
|
|
73
|
+
selectedToken: result.selected?.token ?? null,
|
|
74
|
+
selectedName: result.selected?.name ?? null,
|
|
75
|
+
diagnostics: this.formatDiagnostics(result, input.nowEpochSeconds),
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
this.formatDiagnostics = (result, nowEpochSeconds) => {
|
|
79
|
+
const lines = result.metrics.map((metric) => {
|
|
80
|
+
const secondsUntilSevenDayEnd = Math.round(metric.sevenDayEndEpoch - nowEpochSeconds);
|
|
81
|
+
const status = metric.eligible
|
|
82
|
+
? 'eligible'
|
|
83
|
+
: `excluded (${metric.exclusionReason})`;
|
|
84
|
+
return `${metric.name}: 5h ${Math.round(metric.fiveHourFreeRatio * 100)}% free, 7d ${Math.round(metric.sevenDayFreeRatio * 100)}% free, 7d-end in ${secondsUntilSevenDayEnd}s -> ${status}`;
|
|
85
|
+
});
|
|
86
|
+
if (result.selected === null) {
|
|
87
|
+
lines.push('No eligible token passed the rate-limit filter.');
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
lines.push(`Selected ${result.selected.name} (soonest 7d reset among eligible tokens).`);
|
|
91
|
+
}
|
|
92
|
+
return lines;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
exports.OauthTokenSelectHandler = OauthTokenSelectHandler;
|
|
97
|
+
//# sourceMappingURL=OauthTokenSelectHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OauthTokenSelectHandler.js","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/OauthTokenSelectHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -49,7 +49,7 @@ const cacheDir = () => {
|
|
|
49
49
|
exports.cacheDir = cacheDir;
|
|
50
50
|
const hashToken = (token) => crypto.createHash(HASH_ALGORITHM).update(token).digest('hex');
|
|
51
51
|
exports.hashToken = hashToken;
|
|
52
|
-
const cachePathForToken = (token
|
|
52
|
+
const cachePathForToken = (token, baseDir = (0, exports.cacheDir)()) => path.join(baseDir, `${(0, exports.hashToken)(token)}.json`);
|
|
53
53
|
exports.cachePathForToken = cachePathForToken;
|
|
54
54
|
const isRecord = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
55
55
|
const readPayload = (filePath) => {
|
|
@@ -211,8 +211,8 @@ const parseModelRateLimitsFromHeaders = (headers) => {
|
|
|
211
211
|
return result;
|
|
212
212
|
};
|
|
213
213
|
exports.parseModelRateLimitsFromHeaders = parseModelRateLimitsFromHeaders;
|
|
214
|
-
const readRateLimit = (token) => {
|
|
215
|
-
const filePath = (0, exports.cachePathForToken)(token);
|
|
214
|
+
const readRateLimit = (token, baseDir = (0, exports.cacheDir)()) => {
|
|
215
|
+
const filePath = (0, exports.cachePathForToken)(token, baseDir);
|
|
216
216
|
if (!fs.existsSync(filePath))
|
|
217
217
|
return null;
|
|
218
218
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RateLimitCache.js","sourceRoot":"","sources":["../../../src/adapter/proxy/RateLimitCache.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AACjC,uCAAyB;AACzB,uCAAyB;AACzB,2CAA6B;AAsBhB,QAAA,UAAU,GAAG,IAAI,CAAC;AAE/B,MAAM,cAAc,GAAG,QAAQ,CAAC;AAEnB,QAAA,uCAAuC,GAAG,EAAE,CAAC;AAE7C,QAAA,mCAAmC,GAAG,GAAG,CAAC;AAEhD,MAAM,QAAQ,GAAG,GAAW,EAAE;IACnC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC7E,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;AAC9C,CAAC,CAAC;AAHW,QAAA,QAAQ,YAGnB;AAEK,MAAM,SAAS,GAAG,CAAC,KAAa,EAAU,EAAE,CACjD,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AADnD,QAAA,SAAS,aAC0C;AAEzD,MAAM,iBAAiB,GAAG,
|
|
1
|
+
{"version":3,"file":"RateLimitCache.js","sourceRoot":"","sources":["../../../src/adapter/proxy/RateLimitCache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OauthTokenSelectUseCase = void 0;
|
|
4
|
+
const SECONDS_PER_DAY = 86400;
|
|
5
|
+
const SEVEN_DAYS_IN_SECONDS = 7 * SECONDS_PER_DAY;
|
|
6
|
+
const FIVE_HOUR_MIN_FREE_RATIO = 0.6;
|
|
7
|
+
const SEVEN_DAY_MIN_FREE_RATIO = 0.3;
|
|
8
|
+
class OauthTokenSelectUseCase {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.run = (candidates, nowEpochSeconds) => {
|
|
11
|
+
const evaluated = candidates.map((candidate) => ({
|
|
12
|
+
candidate,
|
|
13
|
+
metric: this.evaluate(candidate, nowEpochSeconds),
|
|
14
|
+
}));
|
|
15
|
+
const metrics = evaluated.map((entry) => entry.metric);
|
|
16
|
+
const eligible = evaluated.filter((entry) => entry.metric.eligible);
|
|
17
|
+
if (eligible.length === 0) {
|
|
18
|
+
return { selected: null, metrics };
|
|
19
|
+
}
|
|
20
|
+
const best = eligible.reduce((bestEntry, currentEntry) => currentEntry.metric.sevenDayEndEpoch < bestEntry.metric.sevenDayEndEpoch
|
|
21
|
+
? currentEntry
|
|
22
|
+
: bestEntry);
|
|
23
|
+
return { selected: best.candidate, metrics };
|
|
24
|
+
};
|
|
25
|
+
this.evaluate = (candidate, nowEpochSeconds) => {
|
|
26
|
+
const fiveHourFreeRatio = this.fiveHourFreeRatio(candidate.snapshot, nowEpochSeconds);
|
|
27
|
+
const sevenDayFreeRatio = this.sevenDayFreeRatio(candidate.snapshot, nowEpochSeconds);
|
|
28
|
+
const sevenDayEndEpoch = this.sevenDayEndEpoch(candidate.snapshot, nowEpochSeconds);
|
|
29
|
+
const exclusionReason = this.exclusionReason(fiveHourFreeRatio, sevenDayFreeRatio);
|
|
30
|
+
return {
|
|
31
|
+
name: candidate.name,
|
|
32
|
+
fiveHourFreeRatio,
|
|
33
|
+
sevenDayFreeRatio,
|
|
34
|
+
sevenDayEndEpoch,
|
|
35
|
+
eligible: exclusionReason === null,
|
|
36
|
+
exclusionReason,
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
this.exclusionReason = (fiveHourFreeRatio, sevenDayFreeRatio) => {
|
|
40
|
+
if (fiveHourFreeRatio < FIVE_HOUR_MIN_FREE_RATIO) {
|
|
41
|
+
return `5h window only ${this.toPercent(fiveHourFreeRatio)}% free (requires >= ${this.toPercent(FIVE_HOUR_MIN_FREE_RATIO)}%)`;
|
|
42
|
+
}
|
|
43
|
+
if (sevenDayFreeRatio < SEVEN_DAY_MIN_FREE_RATIO) {
|
|
44
|
+
return `7d window only ${this.toPercent(sevenDayFreeRatio)}% free (requires >= ${this.toPercent(SEVEN_DAY_MIN_FREE_RATIO)}%)`;
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
};
|
|
48
|
+
this.fiveHourFreeRatio = (snapshot, nowEpochSeconds) => {
|
|
49
|
+
if (snapshot === null) {
|
|
50
|
+
return 1;
|
|
51
|
+
}
|
|
52
|
+
if (this.windowExpired(snapshot.fiveHourReset, nowEpochSeconds)) {
|
|
53
|
+
return 1;
|
|
54
|
+
}
|
|
55
|
+
return this.freeRatioFromUtilization(snapshot.fiveHourUtilization);
|
|
56
|
+
};
|
|
57
|
+
this.sevenDayFreeRatio = (snapshot, nowEpochSeconds) => {
|
|
58
|
+
if (snapshot === null) {
|
|
59
|
+
return 1;
|
|
60
|
+
}
|
|
61
|
+
if (this.windowExpired(snapshot.sevenDayReset, nowEpochSeconds)) {
|
|
62
|
+
return 1;
|
|
63
|
+
}
|
|
64
|
+
return this.freeRatioFromUtilization(snapshot.sevenDayUtilization);
|
|
65
|
+
};
|
|
66
|
+
this.sevenDayEndEpoch = (snapshot, nowEpochSeconds) => {
|
|
67
|
+
if (snapshot === null) {
|
|
68
|
+
return nowEpochSeconds + SEVEN_DAYS_IN_SECONDS;
|
|
69
|
+
}
|
|
70
|
+
if (snapshot.sevenDayReset <= 0) {
|
|
71
|
+
return nowEpochSeconds + SEVEN_DAYS_IN_SECONDS;
|
|
72
|
+
}
|
|
73
|
+
if (this.windowExpired(snapshot.sevenDayReset, nowEpochSeconds)) {
|
|
74
|
+
return nowEpochSeconds + SEVEN_DAYS_IN_SECONDS;
|
|
75
|
+
}
|
|
76
|
+
return snapshot.sevenDayReset;
|
|
77
|
+
};
|
|
78
|
+
this.windowExpired = (resetEpoch, nowEpochSeconds) => resetEpoch > 0 && nowEpochSeconds > resetEpoch;
|
|
79
|
+
this.freeRatioFromUtilization = (utilization) => {
|
|
80
|
+
const bounded = Math.min(Math.max(utilization, 0), 1);
|
|
81
|
+
return 1 - bounded;
|
|
82
|
+
};
|
|
83
|
+
this.toPercent = (ratio) => Math.round(ratio * 100);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
exports.OauthTokenSelectUseCase = OauthTokenSelectUseCase;
|
|
87
|
+
//# sourceMappingURL=OauthTokenSelectUseCase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OauthTokenSelectUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/OauthTokenSelectUseCase.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
startConsoleServer,
|
|
38
38
|
} from '../console/consoleServer';
|
|
39
39
|
import { IssueTitleStateCache } from '../console/consoleReadApi';
|
|
40
|
+
import { OauthTokenSelectHandler } from '../handlers/OauthTokenSelectHandler';
|
|
40
41
|
|
|
41
42
|
type StartDaemonOptions = {
|
|
42
43
|
projectUrl?: string;
|
|
@@ -72,6 +73,11 @@ type ServeConsoleOptions = {
|
|
|
72
73
|
consoleDataOutputDir?: string;
|
|
73
74
|
};
|
|
74
75
|
|
|
76
|
+
type SelectOauthTokenOptions = {
|
|
77
|
+
tokenListJsonPath?: string;
|
|
78
|
+
cacheDir?: string;
|
|
79
|
+
};
|
|
80
|
+
|
|
75
81
|
const buildGithubRepositoryParams = (
|
|
76
82
|
localStorageRepository: LocalStorageRepository,
|
|
77
83
|
token: string,
|
|
@@ -681,6 +687,38 @@ program
|
|
|
681
687
|
console.log(`TDPM Console server listening on port ${port}`);
|
|
682
688
|
});
|
|
683
689
|
|
|
690
|
+
program
|
|
691
|
+
.command('selectOauthToken')
|
|
692
|
+
.description(
|
|
693
|
+
'Print exactly one Claude Code OAuth token chosen by a rate-limit-aware filter. The token string is written to stdout (pipeable); the per-candidate decision trace is written to stderr. Exits non-zero when no token passes the filter.',
|
|
694
|
+
)
|
|
695
|
+
.option(
|
|
696
|
+
'--tokenListJsonPath <path>',
|
|
697
|
+
'Path to the JSON array of { name, token } records. Falls back to the CLAUDE_CODE_OAUTH_TOKEN_LIST_JSON_PATH environment variable.',
|
|
698
|
+
)
|
|
699
|
+
.option(
|
|
700
|
+
'--cacheDir <path>',
|
|
701
|
+
'Directory holding per-token rate-limit cache files. Falls back to the TDPM_RATELIMIT_CACHE_DIR environment variable, then to ${XDG_CACHE_HOME:-~/.cache}/tdpm/ratelimit.',
|
|
702
|
+
)
|
|
703
|
+
.action((options: SelectOauthTokenOptions) => {
|
|
704
|
+
const handler = new OauthTokenSelectHandler();
|
|
705
|
+
const output = handler.handle({
|
|
706
|
+
tokenListJsonPath: options.tokenListJsonPath ?? null,
|
|
707
|
+
cacheDirectory: options.cacheDir ?? null,
|
|
708
|
+
nowEpochSeconds: Date.now() / 1000,
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
for (const line of output.diagnostics) {
|
|
712
|
+
console.error(line);
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
if (output.selectedToken === null) {
|
|
716
|
+
process.exit(1);
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
process.stdout.write(`${output.selectedToken}\n`);
|
|
720
|
+
});
|
|
721
|
+
|
|
684
722
|
/* istanbul ignore next */
|
|
685
723
|
if (process.argv && require.main === module) {
|
|
686
724
|
program.parse(process.argv);
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as os from 'os';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { hashToken } from '../../proxy/RateLimitCache';
|
|
5
|
+
import {
|
|
6
|
+
OauthTokenSelectHandler,
|
|
7
|
+
resolveCacheDirectory,
|
|
8
|
+
resolveTokenListJsonPath,
|
|
9
|
+
} from './OauthTokenSelectHandler';
|
|
10
|
+
|
|
11
|
+
const NOW = 2_000_000;
|
|
12
|
+
const HOUR = 3600;
|
|
13
|
+
const DAY = 86400;
|
|
14
|
+
|
|
15
|
+
type FakeHeaders = {
|
|
16
|
+
fiveHourUtilization: number;
|
|
17
|
+
fiveHourReset: number;
|
|
18
|
+
sevenDayUtilization: number;
|
|
19
|
+
sevenDayReset: number;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
describe('OauthTokenSelectHandler', () => {
|
|
23
|
+
let tempDir: string;
|
|
24
|
+
let cacheDirectory: string;
|
|
25
|
+
let tokenListPath: string;
|
|
26
|
+
const originalTokenListEnv =
|
|
27
|
+
process.env.CLAUDE_CODE_OAUTH_TOKEN_LIST_JSON_PATH;
|
|
28
|
+
const originalCacheEnv = process.env.TDPM_RATELIMIT_CACHE_DIR;
|
|
29
|
+
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'select-token-'));
|
|
32
|
+
cacheDirectory = path.join(tempDir, 'cache');
|
|
33
|
+
fs.mkdirSync(cacheDirectory, { recursive: true });
|
|
34
|
+
tokenListPath = path.join(tempDir, 'tokens.json');
|
|
35
|
+
delete process.env.CLAUDE_CODE_OAUTH_TOKEN_LIST_JSON_PATH;
|
|
36
|
+
delete process.env.TDPM_RATELIMIT_CACHE_DIR;
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
afterEach(() => {
|
|
40
|
+
if (originalTokenListEnv === undefined) {
|
|
41
|
+
delete process.env.CLAUDE_CODE_OAUTH_TOKEN_LIST_JSON_PATH;
|
|
42
|
+
} else {
|
|
43
|
+
process.env.CLAUDE_CODE_OAUTH_TOKEN_LIST_JSON_PATH = originalTokenListEnv;
|
|
44
|
+
}
|
|
45
|
+
if (originalCacheEnv === undefined) {
|
|
46
|
+
delete process.env.TDPM_RATELIMIT_CACHE_DIR;
|
|
47
|
+
} else {
|
|
48
|
+
process.env.TDPM_RATELIMIT_CACHE_DIR = originalCacheEnv;
|
|
49
|
+
}
|
|
50
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const writeTokenList = (entries: { name: string; token: string }[]): void => {
|
|
54
|
+
fs.writeFileSync(tokenListPath, JSON.stringify(entries));
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const writeCache = (token: string, headers: FakeHeaders): void => {
|
|
58
|
+
const payload = {
|
|
59
|
+
ts: NOW,
|
|
60
|
+
headers: {
|
|
61
|
+
'anthropic-ratelimit-unified-status': 'allowed',
|
|
62
|
+
'anthropic-ratelimit-unified-5h-status': 'allowed',
|
|
63
|
+
'anthropic-ratelimit-unified-5h-reset': String(headers.fiveHourReset),
|
|
64
|
+
'anthropic-ratelimit-unified-5h-utilization': String(
|
|
65
|
+
headers.fiveHourUtilization,
|
|
66
|
+
),
|
|
67
|
+
'anthropic-ratelimit-unified-7d-status': 'allowed',
|
|
68
|
+
'anthropic-ratelimit-unified-7d-reset': String(headers.sevenDayReset),
|
|
69
|
+
'anthropic-ratelimit-unified-7d-utilization': String(
|
|
70
|
+
headers.sevenDayUtilization,
|
|
71
|
+
),
|
|
72
|
+
},
|
|
73
|
+
modelWeeklyLimits: {},
|
|
74
|
+
};
|
|
75
|
+
fs.writeFileSync(
|
|
76
|
+
path.join(cacheDirectory, `${hashToken(token)}.json`),
|
|
77
|
+
JSON.stringify(payload),
|
|
78
|
+
);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
it('selects the eligible token with the soonest 7d reset', () => {
|
|
82
|
+
writeTokenList([
|
|
83
|
+
{ name: 'far', token: 'fake-far' },
|
|
84
|
+
{ name: 'soon', token: 'fake-soon' },
|
|
85
|
+
]);
|
|
86
|
+
writeCache('fake-far', {
|
|
87
|
+
fiveHourUtilization: 0.1,
|
|
88
|
+
fiveHourReset: NOW + HOUR,
|
|
89
|
+
sevenDayUtilization: 0.1,
|
|
90
|
+
sevenDayReset: NOW + 6 * DAY,
|
|
91
|
+
});
|
|
92
|
+
writeCache('fake-soon', {
|
|
93
|
+
fiveHourUtilization: 0.1,
|
|
94
|
+
fiveHourReset: NOW + HOUR,
|
|
95
|
+
sevenDayUtilization: 0.1,
|
|
96
|
+
sevenDayReset: NOW + 2 * DAY,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const handler = new OauthTokenSelectHandler();
|
|
100
|
+
const output = handler.handle({
|
|
101
|
+
tokenListJsonPath: tokenListPath,
|
|
102
|
+
cacheDirectory,
|
|
103
|
+
nowEpochSeconds: NOW,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
expect(output.selectedName).toBe('soon');
|
|
107
|
+
expect(output.selectedToken).toBe('fake-soon');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('treats a token with no cache file as fully free', () => {
|
|
111
|
+
writeTokenList([{ name: 'fresh', token: 'fake-fresh' }]);
|
|
112
|
+
|
|
113
|
+
const handler = new OauthTokenSelectHandler();
|
|
114
|
+
const output = handler.handle({
|
|
115
|
+
tokenListJsonPath: tokenListPath,
|
|
116
|
+
cacheDirectory,
|
|
117
|
+
nowEpochSeconds: NOW,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
expect(output.selectedName).toBe('fresh');
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('returns null and a diagnostic when no token passes the filter', () => {
|
|
124
|
+
writeTokenList([{ name: 'busy', token: 'fake-busy' }]);
|
|
125
|
+
writeCache('fake-busy', {
|
|
126
|
+
fiveHourUtilization: 0.9,
|
|
127
|
+
fiveHourReset: NOW + HOUR,
|
|
128
|
+
sevenDayUtilization: 0.1,
|
|
129
|
+
sevenDayReset: NOW + DAY,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const handler = new OauthTokenSelectHandler();
|
|
133
|
+
const output = handler.handle({
|
|
134
|
+
tokenListJsonPath: tokenListPath,
|
|
135
|
+
cacheDirectory,
|
|
136
|
+
nowEpochSeconds: NOW,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
expect(output.selectedToken).toBeNull();
|
|
140
|
+
expect(output.diagnostics.join('\n')).toContain(
|
|
141
|
+
'No eligible token passed the rate-limit filter.',
|
|
142
|
+
);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('returns a diagnostic when no token list path is resolvable', () => {
|
|
146
|
+
const handler = new OauthTokenSelectHandler();
|
|
147
|
+
const output = handler.handle({
|
|
148
|
+
tokenListJsonPath: null,
|
|
149
|
+
cacheDirectory,
|
|
150
|
+
nowEpochSeconds: NOW,
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
expect(output.selectedToken).toBeNull();
|
|
154
|
+
expect(output.diagnostics.join('\n')).toContain('No token list path');
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('returns a diagnostic when the token list file has no usable entries', () => {
|
|
158
|
+
fs.writeFileSync(tokenListPath, JSON.stringify([]));
|
|
159
|
+
|
|
160
|
+
const handler = new OauthTokenSelectHandler();
|
|
161
|
+
const output = handler.handle({
|
|
162
|
+
tokenListJsonPath: tokenListPath,
|
|
163
|
+
cacheDirectory,
|
|
164
|
+
nowEpochSeconds: NOW,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
expect(output.selectedToken).toBeNull();
|
|
168
|
+
expect(output.diagnostics.join('\n')).toContain('No usable token entries');
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
describe('resolveTokenListJsonPath', () => {
|
|
172
|
+
it('prefers the explicit path over the environment variable', () => {
|
|
173
|
+
process.env.CLAUDE_CODE_OAUTH_TOKEN_LIST_JSON_PATH = '/from/env.json';
|
|
174
|
+
expect(resolveTokenListJsonPath('/explicit.json')).toBe('/explicit.json');
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('falls back to the environment variable when no explicit path is given', () => {
|
|
178
|
+
process.env.CLAUDE_CODE_OAUTH_TOKEN_LIST_JSON_PATH = '/from/env.json';
|
|
179
|
+
expect(resolveTokenListJsonPath(null)).toBe('/from/env.json');
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('returns null when neither source provides a path', () => {
|
|
183
|
+
expect(resolveTokenListJsonPath(null)).toBeNull();
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
describe('resolveCacheDirectory', () => {
|
|
188
|
+
it('prefers the explicit directory over the environment variable', () => {
|
|
189
|
+
process.env.TDPM_RATELIMIT_CACHE_DIR = '/from/env';
|
|
190
|
+
expect(resolveCacheDirectory('/explicit')).toBe('/explicit');
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('falls back to the environment variable when no explicit directory is given', () => {
|
|
194
|
+
process.env.TDPM_RATELIMIT_CACHE_DIR = '/from/env';
|
|
195
|
+
expect(resolveCacheDirectory(null)).toBe('/from/env');
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('falls back to the default tdpm cache directory', () => {
|
|
199
|
+
expect(resolveCacheDirectory(null)).toContain(
|
|
200
|
+
path.join('tdpm', 'ratelimit'),
|
|
201
|
+
);
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
});
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OauthTokenCandidate,
|
|
3
|
+
OauthTokenSelectResult,
|
|
4
|
+
OauthTokenSelectUseCase,
|
|
5
|
+
} from '../../../domain/usecases/OauthTokenSelectUseCase';
|
|
6
|
+
import { cacheDir, readRateLimit } from '../../proxy/RateLimitCache';
|
|
7
|
+
import { loadTokenEntries } from '../../proxy/TokenListLoader';
|
|
8
|
+
|
|
9
|
+
export type OauthTokenSelectHandlerInput = {
|
|
10
|
+
tokenListJsonPath: string | null;
|
|
11
|
+
cacheDirectory: string | null;
|
|
12
|
+
nowEpochSeconds: number;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type OauthTokenSelectHandlerOutput = {
|
|
16
|
+
selectedToken: string | null;
|
|
17
|
+
selectedName: string | null;
|
|
18
|
+
diagnostics: string[];
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const DEFAULT_TOKEN_LIST_PATH_ENV = 'CLAUDE_CODE_OAUTH_TOKEN_LIST_JSON_PATH';
|
|
22
|
+
const DEFAULT_CACHE_DIRECTORY_ENV = 'TDPM_RATELIMIT_CACHE_DIR';
|
|
23
|
+
|
|
24
|
+
export const resolveTokenListJsonPath = (
|
|
25
|
+
explicitPath: string | null,
|
|
26
|
+
): string | null => {
|
|
27
|
+
if (explicitPath !== null && explicitPath.length > 0) {
|
|
28
|
+
return explicitPath;
|
|
29
|
+
}
|
|
30
|
+
const fromEnv = process.env[DEFAULT_TOKEN_LIST_PATH_ENV];
|
|
31
|
+
if (fromEnv !== undefined && fromEnv.length > 0) {
|
|
32
|
+
return fromEnv;
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const resolveCacheDirectory = (
|
|
38
|
+
explicitDirectory: string | null,
|
|
39
|
+
): string => {
|
|
40
|
+
if (explicitDirectory !== null && explicitDirectory.length > 0) {
|
|
41
|
+
return explicitDirectory;
|
|
42
|
+
}
|
|
43
|
+
const fromEnv = process.env[DEFAULT_CACHE_DIRECTORY_ENV];
|
|
44
|
+
if (fromEnv !== undefined && fromEnv.length > 0) {
|
|
45
|
+
return fromEnv;
|
|
46
|
+
}
|
|
47
|
+
return cacheDir();
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export class OauthTokenSelectHandler {
|
|
51
|
+
constructor(
|
|
52
|
+
private readonly useCase: OauthTokenSelectUseCase = new OauthTokenSelectUseCase(),
|
|
53
|
+
) {}
|
|
54
|
+
|
|
55
|
+
handle = (
|
|
56
|
+
input: OauthTokenSelectHandlerInput,
|
|
57
|
+
): OauthTokenSelectHandlerOutput => {
|
|
58
|
+
const tokenListJsonPath = resolveTokenListJsonPath(input.tokenListJsonPath);
|
|
59
|
+
if (tokenListJsonPath === null) {
|
|
60
|
+
return {
|
|
61
|
+
selectedToken: null,
|
|
62
|
+
selectedName: null,
|
|
63
|
+
diagnostics: [
|
|
64
|
+
`No token list path provided. Pass --tokenListJsonPath or set ${DEFAULT_TOKEN_LIST_PATH_ENV}.`,
|
|
65
|
+
],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const entries = loadTokenEntries(tokenListJsonPath);
|
|
70
|
+
if (entries === null) {
|
|
71
|
+
return {
|
|
72
|
+
selectedToken: null,
|
|
73
|
+
selectedName: null,
|
|
74
|
+
diagnostics: [
|
|
75
|
+
`No usable token entries loaded from ${tokenListJsonPath}.`,
|
|
76
|
+
],
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const cacheDirectory = resolveCacheDirectory(input.cacheDirectory);
|
|
81
|
+
|
|
82
|
+
const candidates: OauthTokenCandidate[] = entries.map(({ name, token }) => {
|
|
83
|
+
const snapshot = readRateLimit(token, cacheDirectory);
|
|
84
|
+
return {
|
|
85
|
+
name,
|
|
86
|
+
token,
|
|
87
|
+
snapshot:
|
|
88
|
+
snapshot === null
|
|
89
|
+
? null
|
|
90
|
+
: {
|
|
91
|
+
fiveHourUtilization: snapshot.fiveHourUtilization,
|
|
92
|
+
fiveHourReset: snapshot.fiveHourReset,
|
|
93
|
+
sevenDayUtilization: snapshot.sevenDayUtilization,
|
|
94
|
+
sevenDayReset: snapshot.sevenDayReset,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const result = this.useCase.run(candidates, input.nowEpochSeconds);
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
selectedToken: result.selected?.token ?? null,
|
|
103
|
+
selectedName: result.selected?.name ?? null,
|
|
104
|
+
diagnostics: this.formatDiagnostics(result, input.nowEpochSeconds),
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
private formatDiagnostics = (
|
|
109
|
+
result: OauthTokenSelectResult,
|
|
110
|
+
nowEpochSeconds: number,
|
|
111
|
+
): string[] => {
|
|
112
|
+
const lines = result.metrics.map((metric) => {
|
|
113
|
+
const secondsUntilSevenDayEnd = Math.round(
|
|
114
|
+
metric.sevenDayEndEpoch - nowEpochSeconds,
|
|
115
|
+
);
|
|
116
|
+
const status = metric.eligible
|
|
117
|
+
? 'eligible'
|
|
118
|
+
: `excluded (${metric.exclusionReason})`;
|
|
119
|
+
return `${metric.name}: 5h ${Math.round(metric.fiveHourFreeRatio * 100)}% free, 7d ${Math.round(metric.sevenDayFreeRatio * 100)}% free, 7d-end in ${secondsUntilSevenDayEnd}s -> ${status}`;
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
if (result.selected === null) {
|
|
123
|
+
lines.push('No eligible token passed the rate-limit filter.');
|
|
124
|
+
} else {
|
|
125
|
+
lines.push(
|
|
126
|
+
`Selected ${result.selected.name} (soonest 7d reset among eligible tokens).`,
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return lines;
|
|
131
|
+
};
|
|
132
|
+
}
|
|
@@ -39,8 +39,10 @@ export const cacheDir = (): string => {
|
|
|
39
39
|
export const hashToken = (token: string): string =>
|
|
40
40
|
crypto.createHash(HASH_ALGORITHM).update(token).digest('hex');
|
|
41
41
|
|
|
42
|
-
export const cachePathForToken = (
|
|
43
|
-
|
|
42
|
+
export const cachePathForToken = (
|
|
43
|
+
token: string,
|
|
44
|
+
baseDir: string = cacheDir(),
|
|
45
|
+
): string => path.join(baseDir, `${hashToken(token)}.json`);
|
|
44
46
|
|
|
45
47
|
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
46
48
|
value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
@@ -222,8 +224,11 @@ export const parseModelRateLimitsFromHeaders = (
|
|
|
222
224
|
return result;
|
|
223
225
|
};
|
|
224
226
|
|
|
225
|
-
export const readRateLimit = (
|
|
226
|
-
|
|
227
|
+
export const readRateLimit = (
|
|
228
|
+
token: string,
|
|
229
|
+
baseDir: string = cacheDir(),
|
|
230
|
+
): RateLimitSnapshot | null => {
|
|
231
|
+
const filePath = cachePathForToken(token, baseDir);
|
|
227
232
|
if (!fs.existsSync(filePath)) return null;
|
|
228
233
|
try {
|
|
229
234
|
const raw = fs.readFileSync(filePath, 'utf8');
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OauthTokenCandidate,
|
|
3
|
+
OauthTokenSelectUseCase,
|
|
4
|
+
OauthTokenWindowSnapshot,
|
|
5
|
+
} from './OauthTokenSelectUseCase';
|
|
6
|
+
|
|
7
|
+
const NOW = 1_000_000;
|
|
8
|
+
const HOUR = 3600;
|
|
9
|
+
const DAY = 86400;
|
|
10
|
+
|
|
11
|
+
const snapshot = (
|
|
12
|
+
overrides: Partial<OauthTokenWindowSnapshot>,
|
|
13
|
+
): OauthTokenWindowSnapshot => ({
|
|
14
|
+
fiveHourUtilization: 0,
|
|
15
|
+
fiveHourReset: NOW + HOUR,
|
|
16
|
+
sevenDayUtilization: 0,
|
|
17
|
+
sevenDayReset: NOW + DAY,
|
|
18
|
+
...overrides,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const candidate = (
|
|
22
|
+
name: string,
|
|
23
|
+
snapshotValue: OauthTokenWindowSnapshot | null,
|
|
24
|
+
): OauthTokenCandidate => ({
|
|
25
|
+
name,
|
|
26
|
+
token: `fake-token-${name}`,
|
|
27
|
+
snapshot: snapshotValue,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe('OauthTokenSelectUseCase', () => {
|
|
31
|
+
const useCase = new OauthTokenSelectUseCase();
|
|
32
|
+
|
|
33
|
+
it('selects the eligible token whose 7d window resets soonest', () => {
|
|
34
|
+
const result = useCase.run(
|
|
35
|
+
[
|
|
36
|
+
candidate(
|
|
37
|
+
'far',
|
|
38
|
+
snapshot({ sevenDayUtilization: 0.1, sevenDayReset: NOW + 6 * DAY }),
|
|
39
|
+
),
|
|
40
|
+
candidate(
|
|
41
|
+
'soon',
|
|
42
|
+
snapshot({ sevenDayUtilization: 0.1, sevenDayReset: NOW + 2 * DAY }),
|
|
43
|
+
),
|
|
44
|
+
candidate(
|
|
45
|
+
'middle',
|
|
46
|
+
snapshot({ sevenDayUtilization: 0.1, sevenDayReset: NOW + 4 * DAY }),
|
|
47
|
+
),
|
|
48
|
+
],
|
|
49
|
+
NOW,
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
expect(result.selected?.name).toBe('soon');
|
|
53
|
+
expect(result.selected?.token).toBe('fake-token-soon');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('excludes a token whose 5h window is less than 60% free', () => {
|
|
57
|
+
const result = useCase.run(
|
|
58
|
+
[
|
|
59
|
+
candidate('busy5h', snapshot({ fiveHourUtilization: 0.41 })),
|
|
60
|
+
candidate('ok', snapshot({ fiveHourUtilization: 0.4 })),
|
|
61
|
+
],
|
|
62
|
+
NOW,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
expect(result.selected?.name).toBe('ok');
|
|
66
|
+
const busy = result.metrics.find((m) => m.name === 'busy5h');
|
|
67
|
+
expect(busy?.eligible).toBe(false);
|
|
68
|
+
expect(busy?.exclusionReason).toContain('5h window');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('treats exactly 40% used 5h utilization as eligible (boundary)', () => {
|
|
72
|
+
const result = useCase.run(
|
|
73
|
+
[candidate('boundary', snapshot({ fiveHourUtilization: 0.4 }))],
|
|
74
|
+
NOW,
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
expect(result.selected?.name).toBe('boundary');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('excludes a token whose 7d window is less than 30% free', () => {
|
|
81
|
+
const result = useCase.run(
|
|
82
|
+
[
|
|
83
|
+
candidate('busy7d', snapshot({ sevenDayUtilization: 0.71 })),
|
|
84
|
+
candidate('ok', snapshot({ sevenDayUtilization: 0.7 })),
|
|
85
|
+
],
|
|
86
|
+
NOW,
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
expect(result.selected?.name).toBe('ok');
|
|
90
|
+
const busy = result.metrics.find((m) => m.name === 'busy7d');
|
|
91
|
+
expect(busy?.eligible).toBe(false);
|
|
92
|
+
expect(busy?.exclusionReason).toContain('7d window');
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('treats a token with no snapshot as fully free', () => {
|
|
96
|
+
const result = useCase.run([candidate('fresh', null)], NOW);
|
|
97
|
+
|
|
98
|
+
expect(result.selected?.name).toBe('fresh');
|
|
99
|
+
const fresh = result.metrics.find((m) => m.name === 'fresh');
|
|
100
|
+
expect(fresh?.fiveHourFreeRatio).toBe(1);
|
|
101
|
+
expect(fresh?.sevenDayFreeRatio).toBe(1);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('treats an expired window as fully free', () => {
|
|
105
|
+
const result = useCase.run(
|
|
106
|
+
[
|
|
107
|
+
candidate(
|
|
108
|
+
'expired',
|
|
109
|
+
snapshot({
|
|
110
|
+
fiveHourUtilization: 0.99,
|
|
111
|
+
fiveHourReset: NOW - HOUR,
|
|
112
|
+
sevenDayUtilization: 0.99,
|
|
113
|
+
sevenDayReset: NOW - DAY,
|
|
114
|
+
}),
|
|
115
|
+
),
|
|
116
|
+
],
|
|
117
|
+
NOW,
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
expect(result.selected?.name).toBe('expired');
|
|
121
|
+
const expired = result.metrics.find((m) => m.name === 'expired');
|
|
122
|
+
expect(expired?.fiveHourFreeRatio).toBe(1);
|
|
123
|
+
expect(expired?.sevenDayFreeRatio).toBe(1);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('treats a token with no active 7d window as having the farthest 7d end', () => {
|
|
127
|
+
const result = useCase.run(
|
|
128
|
+
[
|
|
129
|
+
candidate(
|
|
130
|
+
'noSevenDay',
|
|
131
|
+
snapshot({ sevenDayReset: 0, sevenDayUtilization: 0 }),
|
|
132
|
+
),
|
|
133
|
+
candidate(
|
|
134
|
+
'activeSoon',
|
|
135
|
+
snapshot({
|
|
136
|
+
sevenDayUtilization: 0.1,
|
|
137
|
+
sevenDayReset: NOW + 3 * DAY,
|
|
138
|
+
}),
|
|
139
|
+
),
|
|
140
|
+
],
|
|
141
|
+
NOW,
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
expect(result.selected?.name).toBe('activeSoon');
|
|
145
|
+
const noSevenDay = result.metrics.find((m) => m.name === 'noSevenDay');
|
|
146
|
+
expect(noSevenDay?.sevenDayEndEpoch).toBe(NOW + 7 * DAY);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it('returns null selection when no token passes the filter', () => {
|
|
150
|
+
const result = useCase.run(
|
|
151
|
+
[
|
|
152
|
+
candidate('busy', snapshot({ fiveHourUtilization: 0.9 })),
|
|
153
|
+
candidate('alsoBusy', snapshot({ sevenDayUtilization: 0.9 })),
|
|
154
|
+
],
|
|
155
|
+
NOW,
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
expect(result.selected).toBeNull();
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('returns null selection for an empty candidate list', () => {
|
|
162
|
+
const result = useCase.run([], NOW);
|
|
163
|
+
|
|
164
|
+
expect(result.selected).toBeNull();
|
|
165
|
+
expect(result.metrics).toEqual([]);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('reports per-candidate metrics for every input token', () => {
|
|
169
|
+
const result = useCase.run(
|
|
170
|
+
[
|
|
171
|
+
candidate('a', snapshot({ fiveHourUtilization: 0.2 })),
|
|
172
|
+
candidate('b', snapshot({ fiveHourUtilization: 0.95 })),
|
|
173
|
+
],
|
|
174
|
+
NOW,
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
expect(result.metrics.map((m) => m.name)).toEqual(['a', 'b']);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
export type OauthTokenWindowSnapshot = {
|
|
2
|
+
fiveHourUtilization: number;
|
|
3
|
+
fiveHourReset: number;
|
|
4
|
+
sevenDayUtilization: number;
|
|
5
|
+
sevenDayReset: number;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type OauthTokenCandidate = {
|
|
9
|
+
name: string;
|
|
10
|
+
token: string;
|
|
11
|
+
snapshot: OauthTokenWindowSnapshot | null;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type OauthTokenCandidateMetrics = {
|
|
15
|
+
name: string;
|
|
16
|
+
fiveHourFreeRatio: number;
|
|
17
|
+
sevenDayFreeRatio: number;
|
|
18
|
+
sevenDayEndEpoch: number;
|
|
19
|
+
eligible: boolean;
|
|
20
|
+
exclusionReason: string | null;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type OauthTokenSelectResult = {
|
|
24
|
+
selected: OauthTokenCandidate | null;
|
|
25
|
+
metrics: OauthTokenCandidateMetrics[];
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const SECONDS_PER_DAY = 86400;
|
|
29
|
+
const SEVEN_DAYS_IN_SECONDS = 7 * SECONDS_PER_DAY;
|
|
30
|
+
|
|
31
|
+
const FIVE_HOUR_MIN_FREE_RATIO = 0.6;
|
|
32
|
+
const SEVEN_DAY_MIN_FREE_RATIO = 0.3;
|
|
33
|
+
|
|
34
|
+
export class OauthTokenSelectUseCase {
|
|
35
|
+
run = (
|
|
36
|
+
candidates: OauthTokenCandidate[],
|
|
37
|
+
nowEpochSeconds: number,
|
|
38
|
+
): OauthTokenSelectResult => {
|
|
39
|
+
const evaluated = candidates.map((candidate) => ({
|
|
40
|
+
candidate,
|
|
41
|
+
metric: this.evaluate(candidate, nowEpochSeconds),
|
|
42
|
+
}));
|
|
43
|
+
|
|
44
|
+
const metrics = evaluated.map((entry) => entry.metric);
|
|
45
|
+
const eligible = evaluated.filter((entry) => entry.metric.eligible);
|
|
46
|
+
|
|
47
|
+
if (eligible.length === 0) {
|
|
48
|
+
return { selected: null, metrics };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const best = eligible.reduce((bestEntry, currentEntry) =>
|
|
52
|
+
currentEntry.metric.sevenDayEndEpoch < bestEntry.metric.sevenDayEndEpoch
|
|
53
|
+
? currentEntry
|
|
54
|
+
: bestEntry,
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
return { selected: best.candidate, metrics };
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
private evaluate = (
|
|
61
|
+
candidate: OauthTokenCandidate,
|
|
62
|
+
nowEpochSeconds: number,
|
|
63
|
+
): OauthTokenCandidateMetrics => {
|
|
64
|
+
const fiveHourFreeRatio = this.fiveHourFreeRatio(
|
|
65
|
+
candidate.snapshot,
|
|
66
|
+
nowEpochSeconds,
|
|
67
|
+
);
|
|
68
|
+
const sevenDayFreeRatio = this.sevenDayFreeRatio(
|
|
69
|
+
candidate.snapshot,
|
|
70
|
+
nowEpochSeconds,
|
|
71
|
+
);
|
|
72
|
+
const sevenDayEndEpoch = this.sevenDayEndEpoch(
|
|
73
|
+
candidate.snapshot,
|
|
74
|
+
nowEpochSeconds,
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
const exclusionReason = this.exclusionReason(
|
|
78
|
+
fiveHourFreeRatio,
|
|
79
|
+
sevenDayFreeRatio,
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
name: candidate.name,
|
|
84
|
+
fiveHourFreeRatio,
|
|
85
|
+
sevenDayFreeRatio,
|
|
86
|
+
sevenDayEndEpoch,
|
|
87
|
+
eligible: exclusionReason === null,
|
|
88
|
+
exclusionReason,
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
private exclusionReason = (
|
|
93
|
+
fiveHourFreeRatio: number,
|
|
94
|
+
sevenDayFreeRatio: number,
|
|
95
|
+
): string | null => {
|
|
96
|
+
if (fiveHourFreeRatio < FIVE_HOUR_MIN_FREE_RATIO) {
|
|
97
|
+
return `5h window only ${this.toPercent(fiveHourFreeRatio)}% free (requires >= ${this.toPercent(FIVE_HOUR_MIN_FREE_RATIO)}%)`;
|
|
98
|
+
}
|
|
99
|
+
if (sevenDayFreeRatio < SEVEN_DAY_MIN_FREE_RATIO) {
|
|
100
|
+
return `7d window only ${this.toPercent(sevenDayFreeRatio)}% free (requires >= ${this.toPercent(SEVEN_DAY_MIN_FREE_RATIO)}%)`;
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
private fiveHourFreeRatio = (
|
|
106
|
+
snapshot: OauthTokenWindowSnapshot | null,
|
|
107
|
+
nowEpochSeconds: number,
|
|
108
|
+
): number => {
|
|
109
|
+
if (snapshot === null) {
|
|
110
|
+
return 1;
|
|
111
|
+
}
|
|
112
|
+
if (this.windowExpired(snapshot.fiveHourReset, nowEpochSeconds)) {
|
|
113
|
+
return 1;
|
|
114
|
+
}
|
|
115
|
+
return this.freeRatioFromUtilization(snapshot.fiveHourUtilization);
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
private sevenDayFreeRatio = (
|
|
119
|
+
snapshot: OauthTokenWindowSnapshot | null,
|
|
120
|
+
nowEpochSeconds: number,
|
|
121
|
+
): number => {
|
|
122
|
+
if (snapshot === null) {
|
|
123
|
+
return 1;
|
|
124
|
+
}
|
|
125
|
+
if (this.windowExpired(snapshot.sevenDayReset, nowEpochSeconds)) {
|
|
126
|
+
return 1;
|
|
127
|
+
}
|
|
128
|
+
return this.freeRatioFromUtilization(snapshot.sevenDayUtilization);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
private sevenDayEndEpoch = (
|
|
132
|
+
snapshot: OauthTokenWindowSnapshot | null,
|
|
133
|
+
nowEpochSeconds: number,
|
|
134
|
+
): number => {
|
|
135
|
+
if (snapshot === null) {
|
|
136
|
+
return nowEpochSeconds + SEVEN_DAYS_IN_SECONDS;
|
|
137
|
+
}
|
|
138
|
+
if (snapshot.sevenDayReset <= 0) {
|
|
139
|
+
return nowEpochSeconds + SEVEN_DAYS_IN_SECONDS;
|
|
140
|
+
}
|
|
141
|
+
if (this.windowExpired(snapshot.sevenDayReset, nowEpochSeconds)) {
|
|
142
|
+
return nowEpochSeconds + SEVEN_DAYS_IN_SECONDS;
|
|
143
|
+
}
|
|
144
|
+
return snapshot.sevenDayReset;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
private windowExpired = (
|
|
148
|
+
resetEpoch: number,
|
|
149
|
+
nowEpochSeconds: number,
|
|
150
|
+
): boolean => resetEpoch > 0 && nowEpochSeconds > resetEpoch;
|
|
151
|
+
|
|
152
|
+
private freeRatioFromUtilization = (utilization: number): number => {
|
|
153
|
+
const bounded = Math.min(Math.max(utilization, 0), 1);
|
|
154
|
+
return 1 - bounded;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
private toPercent = (ratio: number): number => Math.round(ratio * 100);
|
|
158
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,UAAU,EACV,cAAc,EACd,wBAAwB,EACxB,YAAY,EACZ,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,UAAU,EACV,cAAc,EACd,wBAAwB,EACxB,YAAY,EACZ,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAuFzB,eAAO,MAAM,OAAO,SAAgB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { OauthTokenSelectUseCase } from '../../../domain/usecases/OauthTokenSelectUseCase';
|
|
2
|
+
export type OauthTokenSelectHandlerInput = {
|
|
3
|
+
tokenListJsonPath: string | null;
|
|
4
|
+
cacheDirectory: string | null;
|
|
5
|
+
nowEpochSeconds: number;
|
|
6
|
+
};
|
|
7
|
+
export type OauthTokenSelectHandlerOutput = {
|
|
8
|
+
selectedToken: string | null;
|
|
9
|
+
selectedName: string | null;
|
|
10
|
+
diagnostics: string[];
|
|
11
|
+
};
|
|
12
|
+
export declare const resolveTokenListJsonPath: (explicitPath: string | null) => string | null;
|
|
13
|
+
export declare const resolveCacheDirectory: (explicitDirectory: string | null) => string;
|
|
14
|
+
export declare class OauthTokenSelectHandler {
|
|
15
|
+
private readonly useCase;
|
|
16
|
+
constructor(useCase?: OauthTokenSelectUseCase);
|
|
17
|
+
handle: (input: OauthTokenSelectHandlerInput) => OauthTokenSelectHandlerOutput;
|
|
18
|
+
private formatDiagnostics;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=OauthTokenSelectHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OauthTokenSelectHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/OauthTokenSelectHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,uBAAuB,EACxB,MAAM,kDAAkD,CAAC;AAI1D,MAAM,MAAM,4BAA4B,GAAG;IACzC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AAKF,eAAO,MAAM,wBAAwB,GACnC,cAAc,MAAM,GAAG,IAAI,KAC1B,MAAM,GAAG,IASX,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,mBAAmB,MAAM,GAAG,IAAI,KAC/B,MASF,CAAC;AAEF,qBAAa,uBAAuB;IAEhC,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,GAAE,uBAAuD;IAGnF,MAAM,GACJ,OAAO,4BAA4B,KAClC,6BAA6B,CAiD9B;IAEF,OAAO,CAAC,iBAAiB,CAuBvB;CACH"}
|
|
@@ -21,10 +21,10 @@ export declare const HEADERLESS_429_DEFAULT_COOLDOWN_SECONDS = 90;
|
|
|
21
21
|
export declare const HEADERLESS_429_MAX_COOLDOWN_SECONDS = 600;
|
|
22
22
|
export declare const cacheDir: () => string;
|
|
23
23
|
export declare const hashToken: (token: string) => string;
|
|
24
|
-
export declare const cachePathForToken: (token: string) => string;
|
|
24
|
+
export declare const cachePathForToken: (token: string, baseDir?: string) => string;
|
|
25
25
|
export declare const writeRateLimit: (token: string, headers: Record<string, string | string[] | undefined>, statusCode?: number | null) => void;
|
|
26
26
|
export declare const writeModelRateLimit: (token: string, limits: Record<string, ModelWeeklyLimit>) => void;
|
|
27
27
|
export declare const parseModelRateLimitsFromBody: (body: string) => Record<string, ModelWeeklyLimit>;
|
|
28
28
|
export declare const parseModelRateLimitsFromHeaders: (headers: Record<string, string>) => Record<string, ModelWeeklyLimit>;
|
|
29
|
-
export declare const readRateLimit: (token: string) => RateLimitSnapshot | null;
|
|
29
|
+
export declare const readRateLimit: (token: string, baseDir?: string) => RateLimitSnapshot | null;
|
|
30
30
|
//# sourceMappingURL=RateLimitCache.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RateLimitCache.d.ts","sourceRoot":"","sources":["../../../src/adapter/proxy/RateLimitCache.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACpD,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,UAAU,OAAO,CAAC;AAI/B,eAAO,MAAM,uCAAuC,KAAK,CAAC;AAE1D,eAAO,MAAM,mCAAmC,MAAM,CAAC;AAEvD,eAAO,MAAM,QAAQ,QAAO,MAG3B,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,OAAO,MAAM,KAAG,MACqB,CAAC;AAEhE,eAAO,MAAM,iBAAiB,
|
|
1
|
+
{"version":3,"file":"RateLimitCache.d.ts","sourceRoot":"","sources":["../../../src/adapter/proxy/RateLimitCache.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACpD,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,UAAU,OAAO,CAAC;AAI/B,eAAO,MAAM,uCAAuC,KAAK,CAAC;AAE1D,eAAO,MAAM,mCAAmC,MAAM,CAAC;AAEvD,eAAO,MAAM,QAAQ,QAAO,MAG3B,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,OAAO,MAAM,KAAG,MACqB,CAAC;AAEhE,eAAO,MAAM,iBAAiB,GAC5B,OAAO,MAAM,EACb,UAAS,MAAmB,KAC3B,MAAwD,CAAC;AA4C5D,eAAO,MAAM,cAAc,GACzB,OAAO,MAAM,EACb,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,EACtD,aAAY,MAAM,GAAG,IAAW,KAC/B,IAmDF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,MAAM,EACb,QAAQ,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,KACvC,IAkBF,CAAC;AAEF,eAAO,MAAM,4BAA4B,GACvC,MAAM,MAAM,KACX,MAAM,CAAC,MAAM,EAAE,gBAAgB,CA0BjC,CAAC;AAOF,eAAO,MAAM,+BAA+B,GAC1C,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC9B,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAmBjC,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,OAAO,MAAM,EACb,UAAS,MAAmB,KAC3B,iBAAiB,GAAG,IAwDtB,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type OauthTokenWindowSnapshot = {
|
|
2
|
+
fiveHourUtilization: number;
|
|
3
|
+
fiveHourReset: number;
|
|
4
|
+
sevenDayUtilization: number;
|
|
5
|
+
sevenDayReset: number;
|
|
6
|
+
};
|
|
7
|
+
export type OauthTokenCandidate = {
|
|
8
|
+
name: string;
|
|
9
|
+
token: string;
|
|
10
|
+
snapshot: OauthTokenWindowSnapshot | null;
|
|
11
|
+
};
|
|
12
|
+
export type OauthTokenCandidateMetrics = {
|
|
13
|
+
name: string;
|
|
14
|
+
fiveHourFreeRatio: number;
|
|
15
|
+
sevenDayFreeRatio: number;
|
|
16
|
+
sevenDayEndEpoch: number;
|
|
17
|
+
eligible: boolean;
|
|
18
|
+
exclusionReason: string | null;
|
|
19
|
+
};
|
|
20
|
+
export type OauthTokenSelectResult = {
|
|
21
|
+
selected: OauthTokenCandidate | null;
|
|
22
|
+
metrics: OauthTokenCandidateMetrics[];
|
|
23
|
+
};
|
|
24
|
+
export declare class OauthTokenSelectUseCase {
|
|
25
|
+
run: (candidates: OauthTokenCandidate[], nowEpochSeconds: number) => OauthTokenSelectResult;
|
|
26
|
+
private evaluate;
|
|
27
|
+
private exclusionReason;
|
|
28
|
+
private fiveHourFreeRatio;
|
|
29
|
+
private sevenDayFreeRatio;
|
|
30
|
+
private sevenDayEndEpoch;
|
|
31
|
+
private windowExpired;
|
|
32
|
+
private freeRatioFromUtilization;
|
|
33
|
+
private toPercent;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=OauthTokenSelectUseCase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OauthTokenSelectUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/OauthTokenSelectUseCase.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,wBAAwB,GAAG;IACrC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,wBAAwB,GAAG,IAAI,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,OAAO,EAAE,0BAA0B,EAAE,CAAC;CACvC,CAAC;AAQF,qBAAa,uBAAuB;IAClC,GAAG,GACD,YAAY,mBAAmB,EAAE,EACjC,iBAAiB,MAAM,KACtB,sBAAsB,CAoBvB;IAEF,OAAO,CAAC,QAAQ,CA8Bd;IAEF,OAAO,CAAC,eAAe,CAWrB;IAEF,OAAO,CAAC,iBAAiB,CAWvB;IAEF,OAAO,CAAC,iBAAiB,CAWvB;IAEF,OAAO,CAAC,gBAAgB,CActB;IAEF,OAAO,CAAC,aAAa,CAGwC;IAE7D,OAAO,CAAC,wBAAwB,CAG9B;IAEF,OAAO,CAAC,SAAS,CAAsD;CACxE"}
|