@ai-devkit/agent-manager 0.37.0 → 0.38.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/dist/AgentManager.d.ts +0 -4
- package/dist/AgentManager.d.ts.map +1 -1
- package/dist/AgentManager.js +2 -2
- package/dist/AgentManager.js.map +1 -1
- package/dist/__tests__/capacity/anthropic.test.js +115 -0
- package/dist/__tests__/capacity/anthropic.test.js.map +1 -0
- package/dist/__tests__/capacity/boundaries.test.js +45 -0
- package/dist/__tests__/capacity/boundaries.test.js.map +1 -0
- package/dist/__tests__/capacity/claude.test.js +3 -3
- package/dist/__tests__/capacity/claude.test.js.map +1 -1
- package/dist/__tests__/capacity/codex.test.js +3 -1
- package/dist/__tests__/capacity/codex.test.js.map +1 -1
- package/dist/__tests__/capacity/openai.test.js +21 -12
- package/dist/__tests__/capacity/openai.test.js.map +1 -1
- package/dist/__tests__/capacity/wham.test.js +1 -1
- package/dist/__tests__/capacity/wham.test.js.map +1 -1
- package/dist/__tests__/capacity/zai.test.js +7 -8
- package/dist/__tests__/capacity/zai.test.js.map +1 -1
- package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.js +2 -1
- package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.js.map +1 -1
- package/dist/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.js.map +1 -1
- package/dist/__tests__/harnesses/codex/durable/CodexCliProbe.test.js +7 -15
- package/dist/__tests__/harnesses/codex/durable/CodexCliProbe.test.js.map +1 -1
- package/dist/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.js +3 -1
- package/dist/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.js.map +1 -1
- package/dist/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.js +11 -26
- package/dist/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.js.map +1 -1
- package/dist/__tests__/harnesses/codex/durable/CodexPrintRunner.test.js +3 -7
- package/dist/__tests__/harnesses/codex/durable/CodexPrintRunner.test.js.map +1 -1
- package/dist/__tests__/harnesses/pi/durable/PiCliProbe.test.js +5 -11
- package/dist/__tests__/harnesses/pi/durable/PiCliProbe.test.js.map +1 -1
- package/dist/__tests__/harnesses/pi/durable/PiPrintAgentService.test.js +9 -19
- package/dist/__tests__/harnesses/pi/durable/PiPrintAgentService.test.js.map +1 -1
- package/dist/__tests__/harnesses/pi/durable/PiPrintRunner.test.js +3 -7
- package/dist/__tests__/harnesses/pi/durable/PiPrintRunner.test.js.map +1 -1
- package/dist/__tests__/{readiness → harnesses/readiness}/AgentReadiness.test.js +31 -10
- package/dist/__tests__/harnesses/readiness/AgentReadiness.test.js.map +1 -0
- package/dist/__tests__/harnesses/runtimeProfiles.test.js +89 -0
- package/dist/__tests__/harnesses/runtimeProfiles.test.js.map +1 -0
- package/dist/__tests__/print/DurableAgent.test.js +4 -6
- package/dist/__tests__/print/DurableAgent.test.js.map +1 -1
- package/dist/__tests__/print/DurableAgentRepository.test.js +1 -12
- package/dist/__tests__/print/DurableAgentRepository.test.js.map +1 -1
- package/dist/__tests__/runtime/ManagedAgentRuntime.test.js.map +1 -1
- package/dist/__tests__/terminal/TmuxManager.test.js +1 -1
- package/dist/__tests__/terminal/TmuxManager.test.js.map +1 -1
- package/dist/capacity/index.d.ts +9 -19
- package/dist/capacity/index.d.ts.map +1 -1
- package/dist/capacity/index.js +11 -4
- package/dist/capacity/index.js.map +1 -1
- package/dist/capacity/providers/anthropic.d.ts +9 -0
- package/dist/capacity/providers/anthropic.d.ts.map +1 -0
- package/dist/capacity/{claude.js → providers/anthropic.js} +10 -128
- package/dist/capacity/providers/anthropic.js.map +1 -0
- package/dist/capacity/providers/openai-platform.d.ts +14 -0
- package/dist/capacity/providers/openai-platform.d.ts.map +1 -0
- package/dist/capacity/providers/openai-platform.js +120 -0
- package/dist/capacity/providers/openai-platform.js.map +1 -0
- package/dist/capacity/providers/openai-subscription.d.ts +20 -0
- package/dist/capacity/providers/openai-subscription.d.ts.map +1 -0
- package/dist/capacity/providers/openai-subscription.js +129 -0
- package/dist/capacity/providers/openai-subscription.js.map +1 -0
- package/dist/capacity/providers/zai.d.ts +8 -0
- package/dist/capacity/providers/zai.d.ts.map +1 -0
- package/dist/capacity/{zai.js → providers/zai.js} +17 -62
- package/dist/capacity/providers/zai.js.map +1 -0
- package/dist/capacity/sources/claude.d.ts +9 -0
- package/dist/capacity/sources/claude.d.ts.map +1 -0
- package/dist/capacity/sources/claude.js +17 -0
- package/dist/capacity/sources/claude.js.map +1 -0
- package/dist/capacity/{codex.d.ts → sources/codex.d.ts} +5 -9
- package/dist/capacity/sources/codex.d.ts.map +1 -0
- package/dist/capacity/{codex.js → sources/codex.js} +31 -84
- package/dist/capacity/sources/codex.js.map +1 -0
- package/dist/capacity/sources/pi.d.ts +30 -0
- package/dist/capacity/sources/pi.d.ts.map +1 -0
- package/dist/capacity/sources/pi.js +81 -0
- package/dist/capacity/sources/pi.js.map +1 -0
- package/dist/capacity/types.d.ts +2 -0
- package/dist/capacity/types.d.ts.map +1 -1
- package/dist/capacity/types.js +1 -1
- package/dist/capacity/types.js.map +1 -1
- package/dist/harnesses/claude/credentials.d.ts +10 -0
- package/dist/harnesses/claude/credentials.d.ts.map +1 -0
- package/dist/harnesses/claude/credentials.js +112 -0
- package/dist/harnesses/claude/credentials.js.map +1 -0
- package/dist/harnesses/claude/readiness.d.ts +3 -0
- package/dist/harnesses/claude/readiness.d.ts.map +1 -0
- package/dist/harnesses/claude/readiness.js +63 -0
- package/dist/harnesses/claude/readiness.js.map +1 -0
- package/dist/harnesses/codex/credentials.d.ts +15 -0
- package/dist/harnesses/codex/credentials.d.ts.map +1 -0
- package/dist/harnesses/codex/credentials.js +58 -0
- package/dist/harnesses/codex/credentials.js.map +1 -0
- package/dist/harnesses/codex/readiness.d.ts +3 -0
- package/dist/harnesses/codex/readiness.d.ts.map +1 -0
- package/dist/harnesses/codex/readiness.js +60 -0
- package/dist/harnesses/codex/readiness.js.map +1 -0
- package/dist/harnesses/copilot/readiness.d.ts +3 -0
- package/dist/harnesses/copilot/readiness.d.ts.map +1 -0
- package/dist/harnesses/copilot/readiness.js +39 -0
- package/dist/harnesses/copilot/readiness.js.map +1 -0
- package/dist/harnesses/opencode/readiness.d.ts +3 -0
- package/dist/harnesses/opencode/readiness.d.ts.map +1 -0
- package/dist/harnesses/opencode/readiness.js +50 -0
- package/dist/harnesses/opencode/readiness.js.map +1 -0
- package/dist/harnesses/pi/credentials.d.ts +22 -0
- package/dist/harnesses/pi/credentials.d.ts.map +1 -0
- package/dist/harnesses/pi/credentials.js +98 -0
- package/dist/harnesses/pi/credentials.js.map +1 -0
- package/dist/harnesses/pi/readiness.d.ts +3 -0
- package/dist/harnesses/pi/readiness.d.ts.map +1 -0
- package/dist/harnesses/pi/readiness.js +96 -0
- package/dist/harnesses/pi/readiness.js.map +1 -0
- package/dist/harnesses/readiness/AgentReadiness.d.ts +6 -0
- package/dist/harnesses/readiness/AgentReadiness.d.ts.map +1 -0
- package/dist/harnesses/readiness/AgentReadiness.js +68 -0
- package/dist/harnesses/readiness/AgentReadiness.js.map +1 -0
- package/dist/harnesses/readiness/checks.d.ts +31 -0
- package/dist/harnesses/readiness/checks.d.ts.map +1 -0
- package/dist/harnesses/readiness/checks.js +270 -0
- package/dist/harnesses/readiness/checks.js.map +1 -0
- package/dist/{readiness/AgentReadiness.d.ts → harnesses/readiness/types.d.ts} +19 -10
- package/dist/harnesses/readiness/types.d.ts.map +1 -0
- package/dist/harnesses/readiness/types.js +4 -0
- package/dist/harnesses/readiness/types.js.map +1 -0
- package/dist/harnesses/runtimeProfiles.d.ts +11 -0
- package/dist/harnesses/runtimeProfiles.d.ts.map +1 -0
- package/dist/harnesses/runtimeProfiles.js +99 -0
- package/dist/harnesses/runtimeProfiles.js.map +1 -0
- package/dist/index.d.ts +16 -42
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -23
- package/dist/index.js.map +1 -1
- package/dist/runtime/ManagedAgentRuntime.d.ts +3 -3
- package/dist/runtime/ManagedAgentRuntime.d.ts.map +1 -1
- package/dist/runtime/ManagedAgentRuntime.js +6 -20
- package/dist/runtime/ManagedAgentRuntime.js.map +1 -1
- package/dist/runtime/herdr/HerdrAgentDiscovery.d.ts.map +1 -1
- package/dist/runtime/herdr/HerdrAgentDiscovery.js +2 -43
- package/dist/runtime/herdr/HerdrAgentDiscovery.js.map +1 -1
- package/dist/runtime/tmux/PidPolling.d.ts +1 -1
- package/dist/runtime/tmux/PidPolling.d.ts.map +1 -1
- package/dist/runtime/tmux/PidPolling.js.map +1 -1
- package/dist/runtime/tmux/TmuxAgentRuntime.d.ts +1 -1
- package/dist/runtime/tmux/TmuxAgentRuntime.d.ts.map +1 -1
- package/dist/runtime/tmux/TmuxAgentRuntime.js +1 -1
- package/dist/runtime/tmux/TmuxAgentRuntime.js.map +1 -1
- package/dist/runtime/tmux/TmuxManager.d.ts +12 -0
- package/dist/runtime/tmux/TmuxManager.d.ts.map +1 -0
- package/dist/{terminal → runtime/tmux}/TmuxManager.js +9 -28
- package/dist/runtime/tmux/TmuxManager.js.map +1 -0
- package/dist/runtime/types.d.ts +1 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/terminal/TerminalFocusManager.d.ts +4 -32
- package/dist/terminal/TerminalFocusManager.d.ts.map +1 -1
- package/dist/terminal/TerminalFocusManager.js +17 -267
- package/dist/terminal/TerminalFocusManager.js.map +1 -1
- package/dist/terminal/TtyWriter.d.ts +1 -44
- package/dist/terminal/TtyWriter.d.ts.map +1 -1
- package/dist/terminal/TtyWriter.js +11 -347
- package/dist/terminal/TtyWriter.js.map +1 -1
- package/dist/terminal/backends/index.d.ts +5 -0
- package/dist/terminal/backends/index.d.ts.map +1 -0
- package/dist/terminal/backends/index.js +19 -0
- package/dist/terminal/backends/index.js.map +1 -0
- package/dist/terminal/backends/iterm2.d.ts +3 -0
- package/dist/terminal/backends/iterm2.d.ts.map +1 -0
- package/dist/terminal/backends/iterm2.js +135 -0
- package/dist/terminal/backends/iterm2.js.map +1 -0
- package/dist/terminal/backends/shared.d.ts +7 -0
- package/dist/terminal/backends/shared.d.ts.map +1 -0
- package/dist/terminal/backends/shared.js +35 -0
- package/dist/terminal/backends/shared.js.map +1 -0
- package/dist/terminal/backends/terminal-app.d.ts +3 -0
- package/dist/terminal/backends/terminal-app.d.ts.map +1 -0
- package/dist/terminal/backends/terminal-app.js +129 -0
- package/dist/terminal/backends/terminal-app.js.map +1 -0
- package/dist/terminal/backends/tmux.d.ts +3 -0
- package/dist/terminal/backends/tmux.d.ts.map +1 -0
- package/dist/terminal/backends/tmux.js +76 -0
- package/dist/terminal/backends/tmux.js.map +1 -0
- package/dist/terminal/backends/wezterm.d.ts +3 -0
- package/dist/terminal/backends/wezterm.d.ts.map +1 -0
- package/dist/terminal/backends/wezterm.js +71 -0
- package/dist/terminal/backends/wezterm.js.map +1 -0
- package/dist/terminal/types.d.ts +21 -0
- package/dist/terminal/types.d.ts.map +1 -0
- package/dist/terminal/types.js +10 -0
- package/dist/terminal/types.js.map +1 -0
- package/package.json +1 -1
- package/src/AgentManager.ts +1 -1
- package/src/__tests__/capacity/anthropic.test.ts +105 -0
- package/src/__tests__/capacity/boundaries.test.ts +36 -0
- package/src/__tests__/capacity/claude.test.ts +3 -8
- package/src/__tests__/capacity/codex.test.ts +12 -35
- package/src/__tests__/capacity/fixtures/openai-codex-auth.json +1 -1
- package/src/__tests__/capacity/openai.test.ts +15 -15
- package/src/__tests__/capacity/wham.test.ts +1 -1
- package/src/__tests__/capacity/zai.test.ts +27 -62
- package/src/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.ts +2 -2
- package/src/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.ts +1 -1
- package/src/__tests__/harnesses/codex/durable/CodexCliProbe.test.ts +14 -19
- package/src/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.ts +3 -3
- package/src/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.ts +24 -30
- package/src/__tests__/harnesses/codex/durable/CodexPrintRunner.test.ts +4 -8
- package/src/__tests__/harnesses/pi/durable/PiCliProbe.test.ts +7 -11
- package/src/__tests__/harnesses/pi/durable/PiPrintAgentService.test.ts +19 -22
- package/src/__tests__/harnesses/pi/durable/PiPrintRunner.test.ts +7 -8
- package/src/__tests__/{readiness → harnesses/readiness}/AgentReadiness.test.ts +36 -9
- package/src/__tests__/harnesses/runtimeProfiles.test.ts +110 -0
- package/src/__tests__/print/DurableAgent.test.ts +4 -13
- package/src/__tests__/print/DurableAgentRepository.test.ts +1 -13
- package/src/__tests__/runtime/ManagedAgentRuntime.test.ts +1 -1
- package/src/__tests__/terminal/TmuxManager.test.ts +1 -1
- package/src/capacity/index.ts +29 -23
- package/src/capacity/{claude.ts → providers/anthropic.ts} +16 -131
- package/src/capacity/providers/openai-platform.ts +150 -0
- package/src/capacity/{wham.ts → providers/openai-subscription.ts} +86 -8
- package/src/capacity/{zai.ts → providers/zai.ts} +29 -111
- package/src/capacity/sources/claude.ts +30 -0
- package/src/capacity/{codex.ts → sources/codex.ts} +54 -124
- package/src/capacity/sources/pi.ts +131 -0
- package/src/capacity/types.ts +3 -0
- package/src/harnesses/claude/credentials.ts +122 -0
- package/src/harnesses/claude/readiness.ts +69 -0
- package/src/harnesses/codex/credentials.ts +81 -0
- package/src/harnesses/codex/readiness.ts +72 -0
- package/src/harnesses/copilot/readiness.ts +33 -0
- package/src/harnesses/opencode/readiness.ts +48 -0
- package/src/harnesses/pi/credentials.ts +129 -0
- package/src/harnesses/pi/readiness.ts +104 -0
- package/src/harnesses/readiness/AgentReadiness.ts +87 -0
- package/src/harnesses/readiness/checks.ts +336 -0
- package/src/harnesses/readiness/types.ts +90 -0
- package/src/{utils/agents.ts → harnesses/runtimeProfiles.ts} +34 -38
- package/src/index.ts +15 -128
- package/src/runtime/ManagedAgentRuntime.ts +7 -22
- package/src/runtime/herdr/HerdrAgentDiscovery.ts +3 -19
- package/src/runtime/tmux/PidPolling.ts +1 -1
- package/src/runtime/tmux/TmuxAgentRuntime.ts +1 -1
- package/src/{terminal → runtime/tmux}/TmuxManager.ts +9 -30
- package/src/runtime/types.ts +1 -1
- package/src/terminal/TerminalFocusManager.ts +19 -292
- package/src/terminal/TtyWriter.ts +16 -336
- package/src/terminal/backends/index.ts +21 -0
- package/src/terminal/backends/iterm2.ts +126 -0
- package/src/terminal/backends/shared.ts +42 -0
- package/src/terminal/backends/terminal-app.ts +122 -0
- package/src/terminal/backends/tmux.ts +62 -0
- package/src/terminal/backends/wezterm.ts +65 -0
- package/src/terminal/types.ts +22 -0
- package/dist/__tests__/readiness/AgentReadiness.test.js.map +0 -1
- package/dist/__tests__/utils/agents.test.js +0 -93
- package/dist/__tests__/utils/agents.test.js.map +0 -1
- package/dist/capacity/claude.d.ts +0 -17
- package/dist/capacity/claude.d.ts.map +0 -1
- package/dist/capacity/claude.js.map +0 -1
- package/dist/capacity/codex.d.ts.map +0 -1
- package/dist/capacity/codex.js.map +0 -1
- package/dist/capacity/openai.d.ts +0 -47
- package/dist/capacity/openai.d.ts.map +0 -1
- package/dist/capacity/openai.js +0 -307
- package/dist/capacity/openai.js.map +0 -1
- package/dist/capacity/wham.d.ts +0 -16
- package/dist/capacity/wham.d.ts.map +0 -1
- package/dist/capacity/wham.js +0 -66
- package/dist/capacity/wham.js.map +0 -1
- package/dist/capacity/zai.d.ts +0 -14
- package/dist/capacity/zai.d.ts.map +0 -1
- package/dist/capacity/zai.js.map +0 -1
- package/dist/readiness/AgentReadiness.d.ts.map +0 -1
- package/dist/readiness/AgentReadiness.js +0 -614
- package/dist/readiness/AgentReadiness.js.map +0 -1
- package/dist/terminal/TmuxManager.d.ts +0 -28
- package/dist/terminal/TmuxManager.d.ts.map +0 -1
- package/dist/terminal/TmuxManager.js.map +0 -1
- package/dist/terminal/index.d.ts +0 -5
- package/dist/terminal/index.d.ts.map +0 -1
- package/dist/terminal/index.js +0 -5
- package/dist/terminal/index.js.map +0 -1
- package/dist/utils/agents.d.ts +0 -16
- package/dist/utils/agents.d.ts.map +0 -1
- package/dist/utils/agents.js +0 -117
- package/dist/utils/agents.js.map +0 -1
- package/dist/utils/index.d.ts +0 -8
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -6
- package/dist/utils/index.js.map +0 -1
- package/src/__tests__/utils/agents.test.ts +0 -105
- package/src/capacity/openai.ts +0 -355
- package/src/readiness/AgentReadiness.ts +0 -730
- package/src/terminal/index.ts +0 -4
- package/src/utils/index.ts +0 -14
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
import { execFile } from "node:child_process";
|
|
2
|
-
import { readFile } from "node:fs/promises";
|
|
3
|
-
import { homedir } from "node:os";
|
|
4
|
-
import { isAbsolute, join, resolve } from "node:path";
|
|
5
|
-
import { promisify } from "node:util";
|
|
6
|
-
const execFileAsync = promisify(execFile);
|
|
7
|
-
const CLAUDE_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
|
|
8
|
-
const CLAUDE_KEYCHAIN_SERVICE = "Claude Code-credentials";
|
|
9
1
|
const SESSION_DURATION_MINUTES = 5 * 60;
|
|
10
2
|
const WEEK_DURATION_MINUTES = 7 * 24 * 60;
|
|
3
|
+
const ANTHROPIC_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
|
|
11
4
|
function record(value) {
|
|
12
5
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
13
6
|
}
|
|
@@ -17,103 +10,6 @@ function percent(value) {
|
|
|
17
10
|
function nonEmptyText(value) {
|
|
18
11
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
19
12
|
}
|
|
20
|
-
function credentialsPath(options) {
|
|
21
|
-
const env = options.env ?? process.env;
|
|
22
|
-
const configured = nonEmptyText(env.CLAUDE_CONFIG_DIR);
|
|
23
|
-
if (configured) {
|
|
24
|
-
const profileRoot = isAbsolute(configured) ? configured : resolve(options.cwd ?? process.cwd(), configured);
|
|
25
|
-
return join(profileRoot, ".credentials.json");
|
|
26
|
-
}
|
|
27
|
-
return join(env.HOME || homedir(), ".claude", ".credentials.json");
|
|
28
|
-
}
|
|
29
|
-
function credentialFromPayload(payload, now) {
|
|
30
|
-
if (!payload) return {
|
|
31
|
-
token: null,
|
|
32
|
-
expired: false
|
|
33
|
-
};
|
|
34
|
-
try {
|
|
35
|
-
return credentialFromRoot(record(JSON.parse(payload)), now);
|
|
36
|
-
} catch {
|
|
37
|
-
return {
|
|
38
|
-
token: null,
|
|
39
|
-
expired: false
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
async function readProfileCredential(options, now) {
|
|
44
|
-
try {
|
|
45
|
-
const payload = await (options.readFile ?? readFile)(credentialsPath(options), "utf8");
|
|
46
|
-
return credentialFromPayload(payload, now);
|
|
47
|
-
} catch {
|
|
48
|
-
return {
|
|
49
|
-
token: null,
|
|
50
|
-
expired: false
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
async function readKeychainCredential(options, now) {
|
|
55
|
-
const env = options.env ?? process.env;
|
|
56
|
-
const usesDefaultProfile = !nonEmptyText(env.CLAUDE_CONFIG_DIR);
|
|
57
|
-
if (!usesDefaultProfile || (options.platform ?? process.platform) !== "darwin") {
|
|
58
|
-
return {
|
|
59
|
-
token: null,
|
|
60
|
-
expired: false
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
try {
|
|
64
|
-
const payload = await (options.keychainRead ?? readClaudeKeychain)(CLAUDE_KEYCHAIN_SERVICE);
|
|
65
|
-
return credentialFromPayload(payload, now);
|
|
66
|
-
} catch {
|
|
67
|
-
return {
|
|
68
|
-
token: null,
|
|
69
|
-
expired: false
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
async function resolveToken(options) {
|
|
74
|
-
const env = options.env ?? process.env;
|
|
75
|
-
const environmentToken = nonEmptyText(env.CLAUDE_CODE_OAUTH_TOKEN);
|
|
76
|
-
if (environmentToken) return environmentToken;
|
|
77
|
-
const now = options.now?.() ?? new Date();
|
|
78
|
-
const profileCredential = await readProfileCredential(options, now);
|
|
79
|
-
if (profileCredential.token) return profileCredential.token;
|
|
80
|
-
const keychainCredential = await readKeychainCredential(options, now);
|
|
81
|
-
if (keychainCredential.token) return keychainCredential.token;
|
|
82
|
-
if (profileCredential.expired || keychainCredential.expired) {
|
|
83
|
-
throw new Error("Claude OAuth credentials expired");
|
|
84
|
-
}
|
|
85
|
-
throw new Error("Claude OAuth credentials not found or malformed");
|
|
86
|
-
}
|
|
87
|
-
function credentialFromRoot(root, now) {
|
|
88
|
-
const oauth = record(root?.claudeAiOauth);
|
|
89
|
-
const token = nonEmptyText(oauth?.accessToken);
|
|
90
|
-
if (!token) return {
|
|
91
|
-
token: null,
|
|
92
|
-
expired: false
|
|
93
|
-
};
|
|
94
|
-
const expired = typeof oauth?.expiresAt === "number" && Number.isFinite(oauth.expiresAt) && oauth.expiresAt <= now.getTime();
|
|
95
|
-
return {
|
|
96
|
-
token: expired ? null : token,
|
|
97
|
-
expired
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
async function readClaudeKeychain(service) {
|
|
101
|
-
try {
|
|
102
|
-
const { stdout } = await execFileAsync("/usr/bin/security", [
|
|
103
|
-
"find-generic-password",
|
|
104
|
-
"-s",
|
|
105
|
-
service,
|
|
106
|
-
"-w"
|
|
107
|
-
], {
|
|
108
|
-
encoding: "utf8",
|
|
109
|
-
timeout: 1500,
|
|
110
|
-
maxBuffer: 1024 * 1024
|
|
111
|
-
});
|
|
112
|
-
return nonEmptyText(stdout);
|
|
113
|
-
} catch {
|
|
114
|
-
return null;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
13
|
function resetTime(value) {
|
|
118
14
|
if (typeof value !== "string") return null;
|
|
119
15
|
const milliseconds = Date.parse(value);
|
|
@@ -146,9 +42,7 @@ function scopedWindows(value) {
|
|
|
146
42
|
continue;
|
|
147
43
|
}
|
|
148
44
|
const modelSlug = slug(identity);
|
|
149
|
-
if (!modelSlug || modelSlug === "all-models" || modelSlug.endsWith("-all-models"))
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
45
|
+
if (!modelSlug || modelSlug === "all-models" || modelSlug.endsWith("-all-models")) continue;
|
|
152
46
|
const id = `claude:weekly:${modelSlug}`;
|
|
153
47
|
if (seen.has(id)) continue;
|
|
154
48
|
seen.add(id);
|
|
@@ -203,7 +97,7 @@ function retryAfterTime(response, now) {
|
|
|
203
97
|
const milliseconds = Date.parse(raw);
|
|
204
98
|
return Number.isNaN(milliseconds) ? null : new Date(milliseconds).toISOString();
|
|
205
99
|
}
|
|
206
|
-
export function
|
|
100
|
+
export function parseAnthropicCapacity(raw) {
|
|
207
101
|
const input = record(raw);
|
|
208
102
|
if (!input) throw new Error("Claude usage response is malformed");
|
|
209
103
|
const windows = [
|
|
@@ -215,22 +109,16 @@ export function parseClaudeUsage(raw, checkedAt) {
|
|
|
215
109
|
extraUsageWindow(input.extra_usage)
|
|
216
110
|
].filter((window)=>window !== null);
|
|
217
111
|
return {
|
|
218
|
-
harness: "claude",
|
|
219
|
-
provider: "anthropic",
|
|
220
|
-
generatedAt: checkedAt,
|
|
221
112
|
authenticated: true,
|
|
222
113
|
available: availability(windows),
|
|
223
114
|
windows,
|
|
224
115
|
creditsRemaining: null
|
|
225
116
|
};
|
|
226
117
|
}
|
|
227
|
-
export async function
|
|
228
|
-
const token = await resolveToken(options);
|
|
229
|
-
const controller = new AbortController();
|
|
230
|
-
const timer = setTimeout(()=>controller.abort(), options.timeoutMs ?? 5000);
|
|
118
|
+
export async function fetchAnthropicCapacity(token, options = {}) {
|
|
231
119
|
let response;
|
|
232
120
|
try {
|
|
233
|
-
response = await (options.fetch ?? globalThis.fetch)(
|
|
121
|
+
response = await (options.fetch ?? globalThis.fetch)(ANTHROPIC_USAGE_URL, {
|
|
234
122
|
method: "GET",
|
|
235
123
|
headers: {
|
|
236
124
|
Accept: "application/json",
|
|
@@ -239,19 +127,13 @@ export async function probeClaudeCapacity(options) {
|
|
|
239
127
|
"User-Agent": "claude-code/2.1.0",
|
|
240
128
|
"anthropic-beta": "oauth-2025-04-20"
|
|
241
129
|
},
|
|
242
|
-
signal:
|
|
130
|
+
signal: AbortSignal.timeout(options.timeoutMs ?? 5000)
|
|
243
131
|
});
|
|
244
132
|
} catch {
|
|
245
133
|
throw new Error("Claude OAuth usage request failed");
|
|
246
|
-
} finally{
|
|
247
|
-
clearTimeout(timer);
|
|
248
|
-
}
|
|
249
|
-
if (response.status === 401) {
|
|
250
|
-
throw new Error("Claude OAuth request unauthorized (HTTP 401)");
|
|
251
|
-
}
|
|
252
|
-
if (response.status === 403) {
|
|
253
|
-
throw new Error("Claude OAuth request forbidden (HTTP 403)");
|
|
254
134
|
}
|
|
135
|
+
if (response.status === 401) throw new Error("Claude OAuth request unauthorized (HTTP 401)");
|
|
136
|
+
if (response.status === 403) throw new Error("Claude OAuth request forbidden (HTTP 403)");
|
|
255
137
|
if (response.status === 429) {
|
|
256
138
|
const retryAt = retryAfterTime(response, options.now?.() ?? new Date());
|
|
257
139
|
throw new Error(retryAt ? `Claude OAuth usage rate limited until ${retryAt}` : "Claude OAuth usage rate limited (HTTP 429)");
|
|
@@ -265,7 +147,7 @@ export async function probeClaudeCapacity(options) {
|
|
|
265
147
|
} catch {
|
|
266
148
|
throw new Error("Claude usage response is malformed");
|
|
267
149
|
}
|
|
268
|
-
return
|
|
150
|
+
return parseAnthropicCapacity(raw);
|
|
269
151
|
}
|
|
270
152
|
|
|
271
|
-
//# sourceMappingURL=
|
|
153
|
+
//# sourceMappingURL=anthropic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/capacity/providers/anthropic.ts"],"sourcesContent":["import type { Availability, CapacityWindow, ProviderCapacitySnapshot } from \"../types.js\";\n\nconst SESSION_DURATION_MINUTES = 5 * 60;\nconst WEEK_DURATION_MINUTES = 7 * 24 * 60;\nconst ANTHROPIC_USAGE_URL = \"https://api.anthropic.com/api/oauth/usage\";\n\nexport type AnthropicCapacityRequestOptions = {\n fetch?: typeof globalThis.fetch;\n timeoutMs?: number;\n now?: () => Date;\n};\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction percent(value: unknown): number | null {\n return typeof value === \"number\" && Number.isFinite(value) && value >= 0 && value <= 100\n ? value\n : null;\n}\n\nfunction nonEmptyText(value: unknown): string | null {\n return typeof value === \"string\" && value.trim() ? value.trim() : null;\n}\n\nfunction resetTime(value: unknown): string | null {\n if (typeof value !== \"string\") return null;\n const milliseconds = Date.parse(value);\n return Number.isNaN(milliseconds) ? null : new Date(milliseconds).toISOString();\n}\n\nfunction usageWindow(\n value: unknown,\n id: string,\n label: string,\n durationMinutes: number,\n): CapacityWindow | null {\n const input = record(value);\n if (!input) return null;\n return {\n id,\n label,\n durationMinutes,\n usedPercent: percent(input.utilization),\n resetsAt: resetTime(input.resets_at),\n };\n}\n\nfunction slug(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n}\n\nfunction scopedWindows(value: unknown): CapacityWindow[] {\n if (!Array.isArray(value)) return [];\n const seen = new Set<string>();\n const windows: CapacityWindow[] = [];\n for (const entry of value) {\n const limit = record(entry);\n const model = record(record(limit?.scope)?.model);\n const name = nonEmptyText(model?.display_name);\n const identity = nonEmptyText(model?.id) ?? name;\n if (limit?.kind !== \"weekly_scoped\" || limit.group !== \"weekly\" || !name || !identity) {\n continue;\n }\n const modelSlug = slug(identity);\n if (!modelSlug || modelSlug === \"all-models\" || modelSlug.endsWith(\"-all-models\")) continue;\n const id = `claude:weekly:${modelSlug}`;\n if (seen.has(id)) continue;\n seen.add(id);\n windows.push({\n id,\n label: `${name} weekly`,\n durationMinutes: WEEK_DURATION_MINUTES,\n usedPercent: percent(limit.percent),\n resetsAt: resetTime(limit.resets_at),\n });\n }\n return windows;\n}\n\nfunction finiteNumber(value: unknown): number | null {\n return typeof value === \"number\" && Number.isFinite(value) ? value : null;\n}\n\nfunction extraUsageWindow(value: unknown): CapacityWindow | null {\n const extra = record(value);\n if (!extra || extra.is_enabled !== true) return null;\n const limitMinor = finiteNumber(extra.monthly_limit);\n const usedMinor = finiteNumber(extra.used_credits);\n if (limitMinor === null || usedMinor === null) return null;\n const total = limitMinor / 100;\n const current = usedMinor / 100;\n const currency = nonEmptyText(extra.currency)?.toUpperCase() ?? \"USD\";\n return {\n id: \"claude:extra-usage\",\n label: `Extra usage · ${currency}`,\n limitType: \"CREDIT_LIMIT\",\n durationMinutes: null,\n usedPercent:\n percent(extra.utilization) ??\n (total > 0 ? Math.max(0, Math.min(100, (current / total) * 100)) : null),\n resetsAt: null,\n total,\n current,\n remaining: Math.max(0, total - current),\n };\n}\n\nfunction availability(windows: CapacityWindow[]): Availability {\n const known = windows.flatMap((window) =>\n window.usedPercent === null ? [] : [window.usedPercent],\n );\n if (known.length === 0) return \"unknown\";\n return known.some((used) => used < 100) ? \"yes\" : \"no\";\n}\n\nfunction retryAfterTime(response: Response, now: Date): string | null {\n const raw = response.headers.get(\"Retry-After\")?.trim();\n if (!raw) return null;\n const seconds = Number(raw);\n if (Number.isFinite(seconds) && seconds >= 0) {\n return new Date(now.getTime() + seconds * 1000).toISOString();\n }\n const milliseconds = Date.parse(raw);\n return Number.isNaN(milliseconds) ? null : new Date(milliseconds).toISOString();\n}\n\nexport function parseAnthropicCapacity(raw: unknown): ProviderCapacitySnapshot {\n const input = record(raw);\n if (!input) throw new Error(\"Claude usage response is malformed\");\n const windows = [\n usageWindow(input.five_hour, \"session\", \"Session\", SESSION_DURATION_MINUTES),\n usageWindow(input.seven_day, \"weekly\", \"Weekly\", WEEK_DURATION_MINUTES),\n usageWindow(\n input.seven_day_sonnet,\n \"claude:sonnet:weekly\",\n \"Sonnet weekly\",\n WEEK_DURATION_MINUTES,\n ),\n usageWindow(input.seven_day_opus, \"claude:opus:weekly\", \"Opus weekly\", WEEK_DURATION_MINUTES),\n ...scopedWindows(input.limits),\n extraUsageWindow(input.extra_usage),\n ].filter((window): window is CapacityWindow => window !== null);\n return {\n authenticated: true,\n available: availability(windows),\n windows,\n creditsRemaining: null,\n };\n}\n\nexport async function fetchAnthropicCapacity(\n token: string,\n options: AnthropicCapacityRequestOptions = {},\n): Promise<ProviderCapacitySnapshot> {\n let response: Response;\n try {\n response = await (options.fetch ?? globalThis.fetch)(ANTHROPIC_USAGE_URL, {\n method: \"GET\",\n headers: {\n Accept: \"application/json\",\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": \"claude-code/2.1.0\",\n \"anthropic-beta\": \"oauth-2025-04-20\",\n },\n signal: AbortSignal.timeout(options.timeoutMs ?? 5000),\n });\n } catch {\n throw new Error(\"Claude OAuth usage request failed\");\n }\n if (response.status === 401) throw new Error(\"Claude OAuth request unauthorized (HTTP 401)\");\n if (response.status === 403) throw new Error(\"Claude OAuth request forbidden (HTTP 403)\");\n if (response.status === 429) {\n const retryAt = retryAfterTime(response, options.now?.() ?? new Date());\n throw new Error(\n retryAt\n ? `Claude OAuth usage rate limited until ${retryAt}`\n : \"Claude OAuth usage rate limited (HTTP 429)\",\n );\n }\n if (!response.ok) {\n throw new Error(`Claude OAuth usage request failed (HTTP ${response.status})`);\n }\n let raw: unknown;\n try {\n raw = await response.json();\n } catch {\n throw new Error(\"Claude usage response is malformed\");\n }\n return parseAnthropicCapacity(raw);\n}\n"],"names":["SESSION_DURATION_MINUTES","WEEK_DURATION_MINUTES","ANTHROPIC_USAGE_URL","record","value","Array","isArray","percent","Number","isFinite","nonEmptyText","trim","resetTime","milliseconds","Date","parse","isNaN","toISOString","usageWindow","id","label","durationMinutes","input","usedPercent","utilization","resetsAt","resets_at","slug","toLowerCase","replace","scopedWindows","seen","Set","windows","entry","limit","model","scope","name","display_name","identity","kind","group","modelSlug","endsWith","has","add","push","finiteNumber","extraUsageWindow","extra","is_enabled","limitMinor","monthly_limit","usedMinor","used_credits","total","current","currency","toUpperCase","limitType","Math","max","min","remaining","availability","known","flatMap","window","length","some","used","retryAfterTime","response","now","raw","headers","get","seconds","getTime","parseAnthropicCapacity","Error","five_hour","seven_day","seven_day_sonnet","seven_day_opus","limits","extra_usage","filter","authenticated","available","creditsRemaining","fetchAnthropicCapacity","token","options","fetch","globalThis","method","Accept","Authorization","signal","AbortSignal","timeout","timeoutMs","status","retryAt","ok","json"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ProviderCapacitySnapshot } from "../types.js";
|
|
2
|
+
export type OpenAiUsageBucket = {
|
|
3
|
+
startMs: number;
|
|
4
|
+
tokens: number;
|
|
5
|
+
};
|
|
6
|
+
export type OpenAiPlatformCapacityOptions = {
|
|
7
|
+
checkedAt: string;
|
|
8
|
+
fetch?: typeof globalThis.fetch;
|
|
9
|
+
timeoutMs?: number;
|
|
10
|
+
};
|
|
11
|
+
export declare function parseOpenAiUsage(raw: unknown): OpenAiUsageBucket[];
|
|
12
|
+
export declare function buildOpenAiPlatformCapacity(buckets: OpenAiUsageBucket[], checkedAt: string): ProviderCapacitySnapshot;
|
|
13
|
+
export declare function fetchOpenAiPlatformCapacity(key: string, options: OpenAiPlatformCapacityOptions): Promise<ProviderCapacitySnapshot>;
|
|
14
|
+
//# sourceMappingURL=openai-platform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-platform.d.ts","sourceRoot":"","sources":["../../../src/capacity/providers/openai-platform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAQ5E,MAAM,MAAM,iBAAiB,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AACpE,MAAM,MAAM,6BAA6B,GAAG;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAyBF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,iBAAiB,EAAE,CAUlE;AAWD,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,iBAAiB,EAAE,EAC5B,SAAS,EAAE,MAAM,GAChB,wBAAwB,CAwC1B;AAuBD,wBAAsB,2BAA2B,CAC/C,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,wBAAwB,CAAC,CAqBnC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
const OPENAI_USAGE_BASE_URL = "https://api.openai.com/v1/organization/usage";
|
|
2
|
+
const OPENAI_MODELS_URL = "https://api.openai.com/v1/models";
|
|
3
|
+
const OPENAI_USAGE_ENDPOINTS = [
|
|
4
|
+
"completions",
|
|
5
|
+
"responses"
|
|
6
|
+
];
|
|
7
|
+
const USAGE_WINDOW_DAYS = 7;
|
|
8
|
+
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
9
|
+
function record(value) {
|
|
10
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
11
|
+
}
|
|
12
|
+
function finiteNumber(value) {
|
|
13
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
14
|
+
}
|
|
15
|
+
function bucketTokens(value) {
|
|
16
|
+
const results = Array.isArray(value) ? value : [];
|
|
17
|
+
return results.reduce((total, entry)=>total + (finiteNumber(record(entry)?.input_tokens) ?? 0) + (finiteNumber(record(entry)?.output_tokens) ?? 0), 0);
|
|
18
|
+
}
|
|
19
|
+
export function parseOpenAiUsage(raw) {
|
|
20
|
+
const data = record(raw)?.data;
|
|
21
|
+
if (!Array.isArray(data)) throw new Error("Invalid OpenAI usage response");
|
|
22
|
+
const buckets = [];
|
|
23
|
+
for (const entry of data){
|
|
24
|
+
const seconds = finiteNumber(record(entry)?.aggregation_timestamp);
|
|
25
|
+
if (seconds === null) continue;
|
|
26
|
+
buckets.push({
|
|
27
|
+
startMs: seconds * 1000,
|
|
28
|
+
tokens: bucketTokens(record(entry)?.results)
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return buckets;
|
|
32
|
+
}
|
|
33
|
+
function emptySnapshot(authenticated) {
|
|
34
|
+
return {
|
|
35
|
+
authenticated,
|
|
36
|
+
available: "unknown",
|
|
37
|
+
windows: [],
|
|
38
|
+
creditsRemaining: null
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export function buildOpenAiPlatformCapacity(buckets, checkedAt) {
|
|
42
|
+
const nowMs = Date.parse(checkedAt);
|
|
43
|
+
const todayStartMs = Math.floor(nowMs / DAY_MS) * DAY_MS;
|
|
44
|
+
const weekStartMs = todayStartMs - (USAGE_WINDOW_DAYS - 1) * DAY_MS;
|
|
45
|
+
let todayTokens = 0;
|
|
46
|
+
let weekTokens = 0;
|
|
47
|
+
for (const bucket of buckets){
|
|
48
|
+
if (bucket.startMs === todayStartMs) todayTokens += bucket.tokens;
|
|
49
|
+
if (bucket.startMs >= weekStartMs) weekTokens += bucket.tokens;
|
|
50
|
+
}
|
|
51
|
+
const windows = [
|
|
52
|
+
{
|
|
53
|
+
id: "openai:tokens:today",
|
|
54
|
+
label: "Tokens · today (UTC)",
|
|
55
|
+
limitType: "TOKENS_LIMIT",
|
|
56
|
+
durationMinutes: 24 * 60,
|
|
57
|
+
usedPercent: null,
|
|
58
|
+
resetsAt: new Date(todayStartMs + DAY_MS).toISOString(),
|
|
59
|
+
total: null,
|
|
60
|
+
current: todayTokens,
|
|
61
|
+
remaining: null
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: "openai:tokens:week",
|
|
65
|
+
label: "Tokens · 7 days",
|
|
66
|
+
limitType: "TOKENS_LIMIT",
|
|
67
|
+
durationMinutes: USAGE_WINDOW_DAYS * 24 * 60,
|
|
68
|
+
usedPercent: null,
|
|
69
|
+
resetsAt: null,
|
|
70
|
+
total: null,
|
|
71
|
+
current: weekTokens,
|
|
72
|
+
remaining: null
|
|
73
|
+
}
|
|
74
|
+
];
|
|
75
|
+
return {
|
|
76
|
+
authenticated: true,
|
|
77
|
+
available: "yes",
|
|
78
|
+
windows,
|
|
79
|
+
creditsRemaining: null
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
async function request(url, key, options) {
|
|
83
|
+
try {
|
|
84
|
+
return await (options.fetch ?? globalThis.fetch)(url, {
|
|
85
|
+
method: "GET",
|
|
86
|
+
headers: {
|
|
87
|
+
Authorization: `Bearer ${key}`
|
|
88
|
+
},
|
|
89
|
+
signal: AbortSignal.timeout(options.timeoutMs ?? 5000)
|
|
90
|
+
});
|
|
91
|
+
} catch {
|
|
92
|
+
throw new Error("OpenAI usage request failed");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async function verifyKey(key, options) {
|
|
96
|
+
const response = await request(OPENAI_MODELS_URL, key, options);
|
|
97
|
+
return response.status !== 401;
|
|
98
|
+
}
|
|
99
|
+
export async function fetchOpenAiPlatformCapacity(key, options) {
|
|
100
|
+
const endSeconds = Math.floor(Date.parse(options.checkedAt) / 1000);
|
|
101
|
+
const startSeconds = endSeconds - USAGE_WINDOW_DAYS * 24 * 60 * 60;
|
|
102
|
+
const query = `start_time=${startSeconds}&end_time=${endSeconds}`;
|
|
103
|
+
const payloads = [];
|
|
104
|
+
for (const endpoint of OPENAI_USAGE_ENDPOINTS){
|
|
105
|
+
const response = await request(`${OPENAI_USAGE_BASE_URL}/${endpoint}?${query}`, key, options);
|
|
106
|
+
if (response.status === 401) return emptySnapshot(false);
|
|
107
|
+
if (response.status === 403) return emptySnapshot(await verifyKey(key, options));
|
|
108
|
+
if (response.status !== 200) {
|
|
109
|
+
throw new Error(`OpenAI usage request failed: HTTP ${response.status}`);
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
payloads.push(await response.json());
|
|
113
|
+
} catch {
|
|
114
|
+
throw new Error("OpenAI usage response is not valid JSON");
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return buildOpenAiPlatformCapacity(payloads.flatMap(parseOpenAiUsage), options.checkedAt);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
//# sourceMappingURL=openai-platform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/capacity/providers/openai-platform.ts"],"sourcesContent":["import type { CapacityWindow, ProviderCapacitySnapshot } from \"../types.js\";\n\nconst OPENAI_USAGE_BASE_URL = \"https://api.openai.com/v1/organization/usage\";\nconst OPENAI_MODELS_URL = \"https://api.openai.com/v1/models\";\nconst OPENAI_USAGE_ENDPOINTS = [\"completions\", \"responses\"] as const;\nconst USAGE_WINDOW_DAYS = 7;\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nexport type OpenAiUsageBucket = { startMs: number; tokens: number };\nexport type OpenAiPlatformCapacityOptions = {\n checkedAt: string;\n fetch?: typeof globalThis.fetch;\n timeoutMs?: number;\n};\n\ntype UnknownRecord = Record<string, unknown>;\n\nfunction record(value: unknown): UnknownRecord | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as UnknownRecord)\n : null;\n}\n\nfunction finiteNumber(value: unknown): number | null {\n return typeof value === \"number\" && Number.isFinite(value) ? value : null;\n}\n\nfunction bucketTokens(value: unknown): number {\n const results = Array.isArray(value) ? value : [];\n return results.reduce(\n (total, entry) =>\n total +\n (finiteNumber(record(entry)?.input_tokens) ?? 0) +\n (finiteNumber(record(entry)?.output_tokens) ?? 0),\n 0,\n );\n}\n\nexport function parseOpenAiUsage(raw: unknown): OpenAiUsageBucket[] {\n const data = record(raw)?.data;\n if (!Array.isArray(data)) throw new Error(\"Invalid OpenAI usage response\");\n const buckets: OpenAiUsageBucket[] = [];\n for (const entry of data) {\n const seconds = finiteNumber(record(entry)?.aggregation_timestamp);\n if (seconds === null) continue;\n buckets.push({ startMs: seconds * 1000, tokens: bucketTokens(record(entry)?.results) });\n }\n return buckets;\n}\n\nfunction emptySnapshot(authenticated: boolean): ProviderCapacitySnapshot {\n return {\n authenticated,\n available: \"unknown\",\n windows: [],\n creditsRemaining: null,\n };\n}\n\nexport function buildOpenAiPlatformCapacity(\n buckets: OpenAiUsageBucket[],\n checkedAt: string,\n): ProviderCapacitySnapshot {\n const nowMs = Date.parse(checkedAt);\n const todayStartMs = Math.floor(nowMs / DAY_MS) * DAY_MS;\n const weekStartMs = todayStartMs - (USAGE_WINDOW_DAYS - 1) * DAY_MS;\n let todayTokens = 0;\n let weekTokens = 0;\n for (const bucket of buckets) {\n if (bucket.startMs === todayStartMs) todayTokens += bucket.tokens;\n if (bucket.startMs >= weekStartMs) weekTokens += bucket.tokens;\n }\n const windows: CapacityWindow[] = [\n {\n id: \"openai:tokens:today\",\n label: \"Tokens · today (UTC)\",\n limitType: \"TOKENS_LIMIT\",\n durationMinutes: 24 * 60,\n usedPercent: null,\n resetsAt: new Date(todayStartMs + DAY_MS).toISOString(),\n total: null,\n current: todayTokens,\n remaining: null,\n },\n {\n id: \"openai:tokens:week\",\n label: \"Tokens · 7 days\",\n limitType: \"TOKENS_LIMIT\",\n durationMinutes: USAGE_WINDOW_DAYS * 24 * 60,\n usedPercent: null,\n resetsAt: null,\n total: null,\n current: weekTokens,\n remaining: null,\n },\n ];\n return {\n authenticated: true,\n available: \"yes\",\n windows,\n creditsRemaining: null,\n };\n}\n\nasync function request(\n url: string,\n key: string,\n options: OpenAiPlatformCapacityOptions,\n): Promise<Response> {\n try {\n return await (options.fetch ?? globalThis.fetch)(url, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${key}` },\n signal: AbortSignal.timeout(options.timeoutMs ?? 5000),\n });\n } catch {\n throw new Error(\"OpenAI usage request failed\");\n }\n}\n\nasync function verifyKey(key: string, options: OpenAiPlatformCapacityOptions): Promise<boolean> {\n const response = await request(OPENAI_MODELS_URL, key, options);\n return response.status !== 401;\n}\n\nexport async function fetchOpenAiPlatformCapacity(\n key: string,\n options: OpenAiPlatformCapacityOptions,\n): Promise<ProviderCapacitySnapshot> {\n const endSeconds = Math.floor(Date.parse(options.checkedAt) / 1000);\n const startSeconds = endSeconds - USAGE_WINDOW_DAYS * 24 * 60 * 60;\n const query = `start_time=${startSeconds}&end_time=${endSeconds}`;\n const payloads: unknown[] = [];\n\n for (const endpoint of OPENAI_USAGE_ENDPOINTS) {\n const response = await request(`${OPENAI_USAGE_BASE_URL}/${endpoint}?${query}`, key, options);\n if (response.status === 401) return emptySnapshot(false);\n if (response.status === 403) return emptySnapshot(await verifyKey(key, options));\n if (response.status !== 200) {\n throw new Error(`OpenAI usage request failed: HTTP ${response.status}`);\n }\n try {\n payloads.push(await response.json());\n } catch {\n throw new Error(\"OpenAI usage response is not valid JSON\");\n }\n }\n\n return buildOpenAiPlatformCapacity(payloads.flatMap(parseOpenAiUsage), options.checkedAt);\n}\n"],"names":["OPENAI_USAGE_BASE_URL","OPENAI_MODELS_URL","OPENAI_USAGE_ENDPOINTS","USAGE_WINDOW_DAYS","DAY_MS","record","value","Array","isArray","finiteNumber","Number","isFinite","bucketTokens","results","reduce","total","entry","input_tokens","output_tokens","parseOpenAiUsage","raw","data","Error","buckets","seconds","aggregation_timestamp","push","startMs","tokens","emptySnapshot","authenticated","available","windows","creditsRemaining","buildOpenAiPlatformCapacity","checkedAt","nowMs","Date","parse","todayStartMs","Math","floor","weekStartMs","todayTokens","weekTokens","bucket","id","label","limitType","durationMinutes","usedPercent","resetsAt","toISOString","current","remaining","request","url","key","options","fetch","globalThis","method","headers","Authorization","signal","AbortSignal","timeout","timeoutMs","verifyKey","response","status","fetchOpenAiPlatformCapacity","endSeconds","startSeconds","query","payloads","endpoint","json","flatMap"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CapacityWindow, ProviderCapacitySnapshot } from "../types.js";
|
|
2
|
+
export type OpenAiSubscriptionCredential = {
|
|
3
|
+
access: string;
|
|
4
|
+
accountId: string;
|
|
5
|
+
};
|
|
6
|
+
export type OpenAiSubscriptionCapacityOptions = {
|
|
7
|
+
fetch?: typeof globalThis.fetch;
|
|
8
|
+
timeoutMs?: number;
|
|
9
|
+
};
|
|
10
|
+
export type WhamUsageSnapshot = {
|
|
11
|
+
windows: CapacityWindow[];
|
|
12
|
+
creditsRemaining: number | null;
|
|
13
|
+
};
|
|
14
|
+
export declare function resetTime(value: unknown): string | null;
|
|
15
|
+
export declare function safeIdentifier(value: unknown): string | null;
|
|
16
|
+
export declare function toRateWindow(value: unknown, id: string, label: string): CapacityWindow | null;
|
|
17
|
+
export declare function parseWhamUsage(raw: unknown): WhamUsageSnapshot;
|
|
18
|
+
export declare function fetchOpenAiSubscriptionCapacity(credential: OpenAiSubscriptionCredential, options?: OpenAiSubscriptionCapacityOptions): Promise<ProviderCapacitySnapshot>;
|
|
19
|
+
export declare function fetchOpenAiPatAccountId(token: string, options?: OpenAiSubscriptionCapacityOptions): Promise<string>;
|
|
20
|
+
//# sourceMappingURL=openai-subscription.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-subscription.d.ts","sourceRoot":"","sources":["../../../src/capacity/providers/openai-subscription.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAK5E,MAAM,MAAM,4BAA4B,GAAG;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,iCAAiC,GAAG;IAC9C,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC,CAAC;AAkBF,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAOvD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAK5D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAY7F;AAgBD,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,iBAAiB,CAY9D;AAED,wBAAsB,+BAA+B,CACnD,UAAU,EAAE,4BAA4B,EACxC,OAAO,GAAE,iCAAsC,GAC9C,OAAO,CAAC,wBAAwB,CAAC,CAuCnC;AAED,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,iCAAsC,GAC9C,OAAO,CAAC,MAAM,CAAC,CAoBjB"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
const WHAM_USAGE_URL = "https://chatgpt.com/backend-api/wham/usage";
|
|
2
|
+
const OPENAI_WHOAMI_URL = "https://auth.openai.com/api/accounts/v1/user-auth-credential/whoami";
|
|
3
|
+
function record(value) {
|
|
4
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
5
|
+
}
|
|
6
|
+
function finiteNumber(value) {
|
|
7
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
8
|
+
}
|
|
9
|
+
function nonEmptyText(value) {
|
|
10
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
11
|
+
}
|
|
12
|
+
export function resetTime(value) {
|
|
13
|
+
const seconds = finiteNumber(value);
|
|
14
|
+
if (seconds !== null) return new Date(seconds * 1000).toISOString();
|
|
15
|
+
if (typeof value === "string" && !Number.isNaN(Date.parse(value))) {
|
|
16
|
+
return new Date(value).toISOString();
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
export function safeIdentifier(value) {
|
|
21
|
+
const candidate = nonEmptyText(value);
|
|
22
|
+
if (!candidate || !/^[a-z][a-z0-9_-]{0,63}$/i.test(candidate)) return null;
|
|
23
|
+
if (/(?:account|token|secret|key)[_-]?\d{6,}/i.test(candidate)) return null;
|
|
24
|
+
return candidate;
|
|
25
|
+
}
|
|
26
|
+
export function toRateWindow(value, id, label) {
|
|
27
|
+
const input = record(value);
|
|
28
|
+
if (!input) return null;
|
|
29
|
+
const used = finiteNumber(input.used_percent);
|
|
30
|
+
const seconds = finiteNumber(input.limit_window_seconds);
|
|
31
|
+
return {
|
|
32
|
+
id,
|
|
33
|
+
label,
|
|
34
|
+
durationMinutes: seconds === null ? null : seconds / 60,
|
|
35
|
+
usedPercent: used,
|
|
36
|
+
resetsAt: resetTime(input.reset_at)
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function extraWindows(value) {
|
|
40
|
+
if (!Array.isArray(value)) return [];
|
|
41
|
+
return value.flatMap((entry, index)=>{
|
|
42
|
+
const limit = record(entry);
|
|
43
|
+
if (!limit) return [];
|
|
44
|
+
const scope = safeIdentifier(limit.limit_name) ?? `extra-${index + 1}`;
|
|
45
|
+
const windows = record(limit.rate_limit) ?? limit;
|
|
46
|
+
return [
|
|
47
|
+
toRateWindow(windows.primary_window, `${scope}:primary`, `${scope} primary`),
|
|
48
|
+
toRateWindow(windows.secondary_window, `${scope}:secondary`, `${scope} secondary`)
|
|
49
|
+
].filter((window)=>window !== null);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
export function parseWhamUsage(raw) {
|
|
53
|
+
const response = record(raw) ?? {};
|
|
54
|
+
const limits = record(response.rate_limit) ?? {};
|
|
55
|
+
const credits = record(response.credits) ?? {};
|
|
56
|
+
return {
|
|
57
|
+
windows: [
|
|
58
|
+
toRateWindow(limits.primary_window, "session", "Session"),
|
|
59
|
+
toRateWindow(limits.secondary_window, "weekly", "Weekly"),
|
|
60
|
+
...extraWindows(response.additional_rate_limits)
|
|
61
|
+
].filter((window)=>window !== null),
|
|
62
|
+
creditsRemaining: finiteNumber(credits.balance)
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export async function fetchOpenAiSubscriptionCapacity(credential, options = {}) {
|
|
66
|
+
let response;
|
|
67
|
+
try {
|
|
68
|
+
response = await (options.fetch ?? globalThis.fetch)(WHAM_USAGE_URL, {
|
|
69
|
+
method: "GET",
|
|
70
|
+
headers: {
|
|
71
|
+
Authorization: `Bearer ${credential.access}`,
|
|
72
|
+
"ChatGPT-Account-Id": credential.accountId
|
|
73
|
+
},
|
|
74
|
+
signal: AbortSignal.timeout(options.timeoutMs ?? 5000)
|
|
75
|
+
});
|
|
76
|
+
} catch {
|
|
77
|
+
throw new Error("OpenAI usage request failed");
|
|
78
|
+
}
|
|
79
|
+
if (response.status === 401 || response.status === 403) {
|
|
80
|
+
return {
|
|
81
|
+
authenticated: false,
|
|
82
|
+
available: "unknown",
|
|
83
|
+
windows: [],
|
|
84
|
+
creditsRemaining: null
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
if (response.status !== 200) {
|
|
88
|
+
throw new Error(`OpenAI usage request failed: HTTP ${response.status}`);
|
|
89
|
+
}
|
|
90
|
+
let raw;
|
|
91
|
+
try {
|
|
92
|
+
raw = await response.json();
|
|
93
|
+
} catch {
|
|
94
|
+
throw new Error("OpenAI usage response is not valid JSON");
|
|
95
|
+
}
|
|
96
|
+
const snapshot = parseWhamUsage(raw);
|
|
97
|
+
const hasUsage = snapshot.windows.some((window)=>window.usedPercent !== null);
|
|
98
|
+
return {
|
|
99
|
+
authenticated: true,
|
|
100
|
+
available: hasUsage ? "yes" : "unknown",
|
|
101
|
+
windows: snapshot.windows,
|
|
102
|
+
creditsRemaining: snapshot.creditsRemaining
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
export async function fetchOpenAiPatAccountId(token, options = {}) {
|
|
106
|
+
let response;
|
|
107
|
+
try {
|
|
108
|
+
response = await (options.fetch ?? globalThis.fetch)(OPENAI_WHOAMI_URL, {
|
|
109
|
+
headers: {
|
|
110
|
+
Authorization: `Bearer ${token}`
|
|
111
|
+
},
|
|
112
|
+
signal: AbortSignal.timeout(options.timeoutMs ?? 5000)
|
|
113
|
+
});
|
|
114
|
+
} catch {
|
|
115
|
+
throw new Error("OpenAI account request failed");
|
|
116
|
+
}
|
|
117
|
+
if (!response.ok) throw new Error("OpenAI account request failed");
|
|
118
|
+
let raw;
|
|
119
|
+
try {
|
|
120
|
+
raw = await response.json();
|
|
121
|
+
} catch {
|
|
122
|
+
throw new Error("OpenAI account response is not valid JSON");
|
|
123
|
+
}
|
|
124
|
+
const accountId = nonEmptyText(record(raw)?.chatgpt_account_id);
|
|
125
|
+
if (!accountId) throw new Error("OpenAI account unavailable");
|
|
126
|
+
return accountId;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
//# sourceMappingURL=openai-subscription.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/capacity/providers/openai-subscription.ts"],"sourcesContent":["import type { CapacityWindow, ProviderCapacitySnapshot } from \"../types.js\";\n\nconst WHAM_USAGE_URL = \"https://chatgpt.com/backend-api/wham/usage\";\nconst OPENAI_WHOAMI_URL = \"https://auth.openai.com/api/accounts/v1/user-auth-credential/whoami\";\n\nexport type OpenAiSubscriptionCredential = {\n access: string;\n accountId: string;\n};\n\nexport type OpenAiSubscriptionCapacityOptions = {\n fetch?: typeof globalThis.fetch;\n timeoutMs?: number;\n};\n\nexport type WhamUsageSnapshot = {\n windows: CapacityWindow[];\n creditsRemaining: number | null;\n};\n\ntype UnknownRecord = Record<string, unknown>;\n\nfunction record(value: unknown): UnknownRecord | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as UnknownRecord)\n : null;\n}\n\nfunction finiteNumber(value: unknown): number | null {\n return typeof value === \"number\" && Number.isFinite(value) ? value : null;\n}\n\nfunction nonEmptyText(value: unknown): string | null {\n return typeof value === \"string\" && value.length > 0 ? value : null;\n}\n\nexport function resetTime(value: unknown): string | null {\n const seconds = finiteNumber(value);\n if (seconds !== null) return new Date(seconds * 1000).toISOString();\n if (typeof value === \"string\" && !Number.isNaN(Date.parse(value))) {\n return new Date(value).toISOString();\n }\n return null;\n}\n\nexport function safeIdentifier(value: unknown): string | null {\n const candidate = nonEmptyText(value);\n if (!candidate || !/^[a-z][a-z0-9_-]{0,63}$/i.test(candidate)) return null;\n if (/(?:account|token|secret|key)[_-]?\\d{6,}/i.test(candidate)) return null;\n return candidate;\n}\n\nexport function toRateWindow(value: unknown, id: string, label: string): CapacityWindow | null {\n const input = record(value);\n if (!input) return null;\n const used = finiteNumber(input.used_percent);\n const seconds = finiteNumber(input.limit_window_seconds);\n return {\n id,\n label,\n durationMinutes: seconds === null ? null : seconds / 60,\n usedPercent: used,\n resetsAt: resetTime(input.reset_at),\n };\n}\n\nfunction extraWindows(value: unknown): CapacityWindow[] {\n if (!Array.isArray(value)) return [];\n return value.flatMap((entry, index) => {\n const limit = record(entry);\n if (!limit) return [];\n const scope = safeIdentifier(limit.limit_name) ?? `extra-${index + 1}`;\n const windows = record(limit.rate_limit) ?? limit;\n return [\n toRateWindow(windows.primary_window, `${scope}:primary`, `${scope} primary`),\n toRateWindow(windows.secondary_window, `${scope}:secondary`, `${scope} secondary`),\n ].filter((window): window is CapacityWindow => window !== null);\n });\n}\n\nexport function parseWhamUsage(raw: unknown): WhamUsageSnapshot {\n const response = record(raw) ?? {};\n const limits = record(response.rate_limit) ?? {};\n const credits = record(response.credits) ?? {};\n return {\n windows: [\n toRateWindow(limits.primary_window, \"session\", \"Session\"),\n toRateWindow(limits.secondary_window, \"weekly\", \"Weekly\"),\n ...extraWindows(response.additional_rate_limits),\n ].filter((window): window is CapacityWindow => window !== null),\n creditsRemaining: finiteNumber(credits.balance),\n };\n}\n\nexport async function fetchOpenAiSubscriptionCapacity(\n credential: OpenAiSubscriptionCredential,\n options: OpenAiSubscriptionCapacityOptions = {},\n): Promise<ProviderCapacitySnapshot> {\n let response: Response;\n try {\n response = await (options.fetch ?? globalThis.fetch)(WHAM_USAGE_URL, {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${credential.access}`,\n \"ChatGPT-Account-Id\": credential.accountId,\n },\n signal: AbortSignal.timeout(options.timeoutMs ?? 5000),\n });\n } catch {\n throw new Error(\"OpenAI usage request failed\");\n }\n if (response.status === 401 || response.status === 403) {\n return {\n authenticated: false,\n available: \"unknown\",\n windows: [],\n creditsRemaining: null,\n };\n }\n if (response.status !== 200) {\n throw new Error(`OpenAI usage request failed: HTTP ${response.status}`);\n }\n let raw: unknown;\n try {\n raw = await response.json();\n } catch {\n throw new Error(\"OpenAI usage response is not valid JSON\");\n }\n const snapshot = parseWhamUsage(raw);\n const hasUsage = snapshot.windows.some((window) => window.usedPercent !== null);\n return {\n authenticated: true,\n available: hasUsage ? \"yes\" : \"unknown\",\n windows: snapshot.windows,\n creditsRemaining: snapshot.creditsRemaining,\n };\n}\n\nexport async function fetchOpenAiPatAccountId(\n token: string,\n options: OpenAiSubscriptionCapacityOptions = {},\n): Promise<string> {\n let response: Response;\n try {\n response = await (options.fetch ?? globalThis.fetch)(OPENAI_WHOAMI_URL, {\n headers: { Authorization: `Bearer ${token}` },\n signal: AbortSignal.timeout(options.timeoutMs ?? 5000),\n });\n } catch {\n throw new Error(\"OpenAI account request failed\");\n }\n if (!response.ok) throw new Error(\"OpenAI account request failed\");\n let raw: unknown;\n try {\n raw = await response.json();\n } catch {\n throw new Error(\"OpenAI account response is not valid JSON\");\n }\n const accountId = nonEmptyText(record(raw)?.chatgpt_account_id);\n if (!accountId) throw new Error(\"OpenAI account unavailable\");\n return accountId;\n}\n"],"names":["WHAM_USAGE_URL","OPENAI_WHOAMI_URL","record","value","Array","isArray","finiteNumber","Number","isFinite","nonEmptyText","length","resetTime","seconds","Date","toISOString","isNaN","parse","safeIdentifier","candidate","test","toRateWindow","id","label","input","used","used_percent","limit_window_seconds","durationMinutes","usedPercent","resetsAt","reset_at","extraWindows","flatMap","entry","index","limit","scope","limit_name","windows","rate_limit","primary_window","secondary_window","filter","window","parseWhamUsage","raw","response","limits","credits","additional_rate_limits","creditsRemaining","balance","fetchOpenAiSubscriptionCapacity","credential","options","fetch","globalThis","method","headers","Authorization","access","accountId","signal","AbortSignal","timeout","timeoutMs","Error","status","authenticated","available","json","snapshot","hasUsage","some","fetchOpenAiPatAccountId","token","ok","chatgpt_account_id"],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ProviderCapacitySnapshot } from "../types.js";
|
|
2
|
+
export type ZaiRequestOptions = {
|
|
3
|
+
fetch?: typeof globalThis.fetch;
|
|
4
|
+
timeoutMs?: number;
|
|
5
|
+
};
|
|
6
|
+
export declare function parseZaiCapacity(raw: unknown): ProviderCapacitySnapshot;
|
|
7
|
+
export declare function fetchZaiCapacity(key: string, options?: ZaiRequestOptions): Promise<ProviderCapacitySnapshot>;
|
|
8
|
+
//# sourceMappingURL=zai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zai.d.ts","sourceRoot":"","sources":["../../../src/capacity/providers/zai.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,wBAAwB,EACzB,MAAM,aAAa,CAAC;AAgBrB,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAwFF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,wBAAwB,CAevE;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,wBAAwB,CAAC,CAsBnC"}
|