@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,8 +1,4 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
import { join } from "node:path";
|
|
4
1
|
const ZAI_QUOTA_URL = "https://api.z.ai/api/monitor/usage/quota/limit";
|
|
5
|
-
const MISSING_API_KEY_MESSAGE = "z.ai API key not found; set Z_AI_API_KEY or configure Pi provider zai";
|
|
6
2
|
const LIMIT_METADATA = {
|
|
7
3
|
TOKENS_LIMIT: {
|
|
8
4
|
id: "tokens",
|
|
@@ -50,9 +46,6 @@ const UNIT_METADATA = new Map([
|
|
|
50
46
|
function record(value) {
|
|
51
47
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
52
48
|
}
|
|
53
|
-
function nonEmptyText(value) {
|
|
54
|
-
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
55
|
-
}
|
|
56
49
|
function optionalNumber(value, field) {
|
|
57
50
|
if (value === undefined || value === null) return null;
|
|
58
51
|
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
@@ -60,26 +53,23 @@ function optionalNumber(value, field) {
|
|
|
60
53
|
}
|
|
61
54
|
return value;
|
|
62
55
|
}
|
|
63
|
-
function clampPercent(value) {
|
|
64
|
-
return Math.max(0, Math.min(100, value));
|
|
65
|
-
}
|
|
66
56
|
function integer(value) {
|
|
67
57
|
return typeof value === "number" && Number.isInteger(value) ? value : null;
|
|
68
58
|
}
|
|
69
59
|
function isCapacityLimitType(value) {
|
|
70
60
|
return Object.hasOwn(LIMIT_METADATA, value);
|
|
71
61
|
}
|
|
72
|
-
function durationMinutes(unit,
|
|
73
|
-
if (type === "TIME_LIMIT" && unit === 5 &&
|
|
62
|
+
function durationMinutes(unit, count, type) {
|
|
63
|
+
if (type === "TIME_LIMIT" && unit === 5 && count === 1) return 30 * 24 * 60;
|
|
74
64
|
const metadata = UNIT_METADATA.get(unit);
|
|
75
|
-
return metadata === undefined ||
|
|
65
|
+
return metadata === undefined || count <= 0 ? null : metadata.minutes * count;
|
|
76
66
|
}
|
|
77
|
-
function windowLabel(type, unit,
|
|
78
|
-
if (type === "TIME_LIMIT" && unit === 5 &&
|
|
67
|
+
function windowLabel(type, unit, count) {
|
|
68
|
+
if (type === "TIME_LIMIT" && unit === 5 && count === 1) return "MCP · monthly";
|
|
79
69
|
const kind = LIMIT_METADATA[type].label;
|
|
80
70
|
const unitLabel = UNIT_METADATA.get(unit)?.label;
|
|
81
71
|
if (!unitLabel) return kind;
|
|
82
|
-
return `${kind} · ${
|
|
72
|
+
return `${kind} · ${count} ${unitLabel}${count === 1 ? "" : "s"}`;
|
|
83
73
|
}
|
|
84
74
|
function resetTime(value) {
|
|
85
75
|
const milliseconds = optionalNumber(value, "limit nextResetTime");
|
|
@@ -90,10 +80,7 @@ function resetTime(value) {
|
|
|
90
80
|
}
|
|
91
81
|
function availability(windows) {
|
|
92
82
|
if (windows.length === 0) return "unknown";
|
|
93
|
-
|
|
94
|
-
return "yes";
|
|
95
|
-
}
|
|
96
|
-
return "no";
|
|
83
|
+
return windows.some((window)=>window.usedPercent !== null && window.usedPercent < 100) ? "yes" : "no";
|
|
97
84
|
}
|
|
98
85
|
function parseLimit(value, index) {
|
|
99
86
|
const limit = record(value);
|
|
@@ -121,39 +108,14 @@ function parseLimit(value, index) {
|
|
|
121
108
|
label: windowLabel(limit.type, unit, count),
|
|
122
109
|
limitType: limit.type,
|
|
123
110
|
durationMinutes: durationMinutes(unit, count, limit.type),
|
|
124
|
-
usedPercent:
|
|
111
|
+
usedPercent: Math.max(0, Math.min(100, usedPercent)),
|
|
125
112
|
resetsAt: resetTime(limit.nextResetTime),
|
|
126
113
|
total,
|
|
127
114
|
current,
|
|
128
115
|
remaining
|
|
129
116
|
};
|
|
130
117
|
}
|
|
131
|
-
export
|
|
132
|
-
const env = options.env ?? process.env;
|
|
133
|
-
const environmentKey = nonEmptyText(env.Z_AI_API_KEY);
|
|
134
|
-
if (environmentKey) return environmentKey;
|
|
135
|
-
const authPath = join(env.HOME || homedir(), ".pi", "agent", "auth.json");
|
|
136
|
-
let parsed;
|
|
137
|
-
try {
|
|
138
|
-
const contents = await (options.readFile ?? readFile)(authPath, "utf8");
|
|
139
|
-
const root = record(JSON.parse(contents));
|
|
140
|
-
if (!root) throw new Error("invalid");
|
|
141
|
-
parsed = root;
|
|
142
|
-
} catch (error) {
|
|
143
|
-
if (record(error)?.code === "ENOENT") {
|
|
144
|
-
throw new Error(MISSING_API_KEY_MESSAGE);
|
|
145
|
-
}
|
|
146
|
-
throw new Error("z.ai Pi auth file is malformed");
|
|
147
|
-
}
|
|
148
|
-
const credential = record(parsed.zai);
|
|
149
|
-
if (!credential) {
|
|
150
|
-
throw new Error(MISSING_API_KEY_MESSAGE);
|
|
151
|
-
}
|
|
152
|
-
const key = credential.type === "api_key" ? nonEmptyText(credential.key) : null;
|
|
153
|
-
if (!key) throw new Error("z.ai Pi auth file has a malformed zai credential");
|
|
154
|
-
return key;
|
|
155
|
-
}
|
|
156
|
-
export function parseZaiQuota(raw, checkedAt) {
|
|
118
|
+
export function parseZaiCapacity(raw) {
|
|
157
119
|
const root = record(raw);
|
|
158
120
|
const data = record(root?.data);
|
|
159
121
|
if (root?.success !== true || root.code !== 200 || !data || !Array.isArray(data.limits)) {
|
|
@@ -161,19 +123,13 @@ export function parseZaiQuota(raw, checkedAt) {
|
|
|
161
123
|
}
|
|
162
124
|
const windows = data.limits.map(parseLimit).filter((window)=>window !== null);
|
|
163
125
|
return {
|
|
164
|
-
harness: "pi",
|
|
165
|
-
provider: "zai",
|
|
166
|
-
generatedAt: checkedAt,
|
|
167
126
|
authenticated: true,
|
|
168
127
|
available: availability(windows),
|
|
169
128
|
windows,
|
|
170
129
|
creditsRemaining: null
|
|
171
130
|
};
|
|
172
131
|
}
|
|
173
|
-
export async function
|
|
174
|
-
const key = await resolveZaiApiKey(options);
|
|
175
|
-
const controller = new AbortController();
|
|
176
|
-
const timer = setTimeout(()=>controller.abort(), options.timeoutMs ?? 5000);
|
|
132
|
+
export async function fetchZaiCapacity(key, options = {}) {
|
|
177
133
|
let response;
|
|
178
134
|
try {
|
|
179
135
|
response = await (options.fetch ?? globalThis.fetch)(ZAI_QUOTA_URL, {
|
|
@@ -181,23 +137,22 @@ export async function probeZaiCapacity(options) {
|
|
|
181
137
|
headers: {
|
|
182
138
|
Authorization: `Bearer ${key}`
|
|
183
139
|
},
|
|
184
|
-
signal:
|
|
140
|
+
signal: AbortSignal.timeout(options.timeoutMs ?? 5000)
|
|
185
141
|
});
|
|
186
142
|
} catch {
|
|
187
143
|
throw new Error("z.ai quota request failed");
|
|
188
|
-
} finally{
|
|
189
|
-
clearTimeout(timer);
|
|
190
144
|
}
|
|
191
145
|
if (response.status !== 200) {
|
|
192
146
|
throw new Error(`z.ai quota request failed: HTTP ${response.status}`);
|
|
193
147
|
}
|
|
194
|
-
let raw;
|
|
195
148
|
try {
|
|
196
|
-
|
|
197
|
-
} catch
|
|
198
|
-
|
|
149
|
+
return parseZaiCapacity(await response.json());
|
|
150
|
+
} catch (error) {
|
|
151
|
+
if (error instanceof SyntaxError) {
|
|
152
|
+
throw new Error("z.ai quota response is not valid JSON");
|
|
153
|
+
}
|
|
154
|
+
throw error;
|
|
199
155
|
}
|
|
200
|
-
return parseZaiQuota(raw, options.checkedAt);
|
|
201
156
|
}
|
|
202
157
|
|
|
203
158
|
//# sourceMappingURL=zai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/capacity/providers/zai.ts"],"sourcesContent":["import type {\n Availability,\n CapacityLimitType,\n CapacityWindow,\n ProviderCapacitySnapshot,\n} from \"../types.js\";\n\nconst ZAI_QUOTA_URL = \"https://api.z.ai/api/monitor/usage/quota/limit\";\nconst LIMIT_METADATA = {\n TOKENS_LIMIT: { id: \"tokens\", label: \"Tokens\" },\n CREDIT_LIMIT: { id: \"credit\", label: \"Credit\" },\n TIME_LIMIT: { id: \"time\", label: \"Time\" },\n} as const satisfies Record<CapacityLimitType, { id: string; label: string }>;\nconst UNIT_METADATA = new Map<number, { minutes: number; label: string }>([\n [1, { minutes: 24 * 60, label: \"day\" }],\n [3, { minutes: 60, label: \"hour\" }],\n [5, { minutes: 1, label: \"minute\" }],\n [6, { minutes: 7 * 24 * 60, label: \"week\" }],\n]);\ntype UnknownRecord = Record<string, unknown>;\n\nexport type ZaiRequestOptions = {\n fetch?: typeof globalThis.fetch;\n timeoutMs?: number;\n};\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 optionalNumber(value: unknown, field: string): number | null {\n if (value === undefined || value === null) return null;\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`Invalid z.ai quota ${field}`);\n }\n return value;\n}\n\nfunction integer(value: unknown): number | null {\n return typeof value === \"number\" && Number.isInteger(value) ? value : null;\n}\n\nfunction isCapacityLimitType(value: string): value is CapacityLimitType {\n return Object.hasOwn(LIMIT_METADATA, value);\n}\n\nfunction durationMinutes(unit: number, count: number, type: CapacityLimitType): number | null {\n if (type === \"TIME_LIMIT\" && unit === 5 && count === 1) return 30 * 24 * 60;\n const metadata = UNIT_METADATA.get(unit);\n return metadata === undefined || count <= 0 ? null : metadata.minutes * count;\n}\n\nfunction windowLabel(type: CapacityLimitType, unit: number, count: number): string {\n if (type === \"TIME_LIMIT\" && unit === 5 && count === 1) return \"MCP · monthly\";\n const kind = LIMIT_METADATA[type].label;\n const unitLabel = UNIT_METADATA.get(unit)?.label;\n if (!unitLabel) return kind;\n return `${kind} · ${count} ${unitLabel}${count === 1 ? \"\" : \"s\"}`;\n}\n\nfunction resetTime(value: unknown): string | null {\n const milliseconds = optionalNumber(value, \"limit nextResetTime\");\n if (milliseconds === null) return null;\n const date = new Date(milliseconds);\n if (Number.isNaN(date.getTime())) throw new Error(\"Invalid z.ai quota limit nextResetTime\");\n return date.toISOString();\n}\n\nfunction availability(windows: CapacityWindow[]): Availability {\n if (windows.length === 0) return \"unknown\";\n return windows.some((window) => window.usedPercent !== null && window.usedPercent < 100)\n ? \"yes\"\n : \"no\";\n}\n\nfunction parseLimit(value: unknown, index: number): CapacityWindow | null {\n const limit = record(value);\n if (!limit) throw new Error(\"Invalid z.ai quota limit entry\");\n const unit = integer(limit.unit);\n const count = integer(limit.number);\n if (typeof limit.type !== \"string\" || unit === null || count === null) {\n throw new Error(\"Invalid z.ai quota limit entry\");\n }\n const serverPercent = optionalNumber(limit.percentage, \"limit percentage\");\n if (serverPercent === null) throw new Error(\"Invalid z.ai quota limit percentage\");\n if (!isCapacityLimitType(limit.type)) return null;\n\n const total = optionalNumber(limit.usage, \"limit usage\");\n const current = optionalNumber(limit.currentValue, \"limit currentValue\");\n const remaining = optionalNumber(limit.remaining, \"limit remaining\");\n let consumed = total !== null && remaining !== null ? total - remaining : null;\n if (current !== null) consumed = Math.max(consumed ?? current, current);\n let usedPercent = serverPercent;\n if (total !== null && total > 0 && consumed !== null) {\n usedPercent = (consumed / total) * 100;\n }\n const metadata = LIMIT_METADATA[limit.type];\n return {\n id: `zai:${metadata.id}:${index + 1}`,\n label: windowLabel(limit.type, unit, count),\n limitType: limit.type,\n durationMinutes: durationMinutes(unit, count, limit.type),\n usedPercent: Math.max(0, Math.min(100, usedPercent)),\n resetsAt: resetTime(limit.nextResetTime),\n total,\n current,\n remaining,\n };\n}\n\nexport function parseZaiCapacity(raw: unknown): ProviderCapacitySnapshot {\n const root = record(raw);\n const data = record(root?.data);\n if (root?.success !== true || root.code !== 200 || !data || !Array.isArray(data.limits)) {\n throw new Error(\"Invalid z.ai quota response\");\n }\n const windows = data.limits\n .map(parseLimit)\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 fetchZaiCapacity(\n key: string,\n options: ZaiRequestOptions = {},\n): Promise<ProviderCapacitySnapshot> {\n let response: Response;\n try {\n response = await (options.fetch ?? globalThis.fetch)(ZAI_QUOTA_URL, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${key}` },\n signal: AbortSignal.timeout(options.timeoutMs ?? 5000),\n });\n } catch {\n throw new Error(\"z.ai quota request failed\");\n }\n if (response.status !== 200) {\n throw new Error(`z.ai quota request failed: HTTP ${response.status}`);\n }\n try {\n return parseZaiCapacity(await response.json());\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(\"z.ai quota response is not valid JSON\");\n }\n throw error;\n }\n}\n"],"names":["ZAI_QUOTA_URL","LIMIT_METADATA","TOKENS_LIMIT","id","label","CREDIT_LIMIT","TIME_LIMIT","UNIT_METADATA","Map","minutes","record","value","Array","isArray","optionalNumber","field","undefined","Number","isFinite","Error","integer","isInteger","isCapacityLimitType","Object","hasOwn","durationMinutes","unit","count","type","metadata","get","windowLabel","kind","unitLabel","resetTime","milliseconds","date","Date","isNaN","getTime","toISOString","availability","windows","length","some","window","usedPercent","parseLimit","index","limit","number","serverPercent","percentage","total","usage","current","currentValue","remaining","consumed","Math","max","limitType","min","resetsAt","nextResetTime","parseZaiCapacity","raw","root","data","success","code","limits","map","filter","authenticated","available","creditsRemaining","fetchZaiCapacity","key","options","response","fetch","globalThis","method","headers","Authorization","signal","AbortSignal","timeout","timeoutMs","status","json","error","SyntaxError"],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type AnthropicCapacityRequestOptions } from "../providers/anthropic.js";
|
|
2
|
+
import type { CapacityReport } from "../types.js";
|
|
3
|
+
import { type ClaudeCredentialOptions } from "../../harnesses/claude/credentials.js";
|
|
4
|
+
export type ClaudeCapacityOptions = ClaudeCredentialOptions & AnthropicCapacityRequestOptions;
|
|
5
|
+
export type ClaudeProbeOptions = ClaudeCapacityOptions & {
|
|
6
|
+
checkedAt: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function probeClaudeCapacity(options: ClaudeProbeOptions): Promise<CapacityReport>;
|
|
9
|
+
//# sourceMappingURL=claude.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../../src/capacity/sources/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,+BAA+B,EACrC,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,cAAc,EAA4B,MAAM,aAAa,CAAC;AAC5E,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,uCAAuC,CAAC;AAE/C,MAAM,MAAM,qBAAqB,GAAG,uBAAuB,GAAG,+BAA+B,CAAC;AAE9F,MAAM,MAAM,kBAAkB,GAAG,qBAAqB,GAAG;IACvD,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAWF,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CAI9F"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { fetchAnthropicCapacity } from "../providers/anthropic.js";
|
|
2
|
+
import { resolveClaudeAnthropicToken } from "../../harnesses/claude/credentials.js";
|
|
3
|
+
function claudeReport(snapshot, checkedAt) {
|
|
4
|
+
return {
|
|
5
|
+
harness: "claude",
|
|
6
|
+
provider: "anthropic",
|
|
7
|
+
generatedAt: checkedAt,
|
|
8
|
+
...snapshot
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export async function probeClaudeCapacity(options) {
|
|
12
|
+
const token = await resolveClaudeAnthropicToken(options);
|
|
13
|
+
const snapshot = await fetchAnthropicCapacity(token, options);
|
|
14
|
+
return claudeReport(snapshot, options.checkedAt);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/capacity/sources/claude.ts"],"sourcesContent":["import {\n fetchAnthropicCapacity,\n type AnthropicCapacityRequestOptions,\n} from \"../providers/anthropic.js\";\nimport type { CapacityReport, ProviderCapacitySnapshot } from \"../types.js\";\nimport {\n resolveClaudeAnthropicToken,\n type ClaudeCredentialOptions,\n} from \"../../harnesses/claude/credentials.js\";\n\nexport type ClaudeCapacityOptions = ClaudeCredentialOptions & AnthropicCapacityRequestOptions;\n\nexport type ClaudeProbeOptions = ClaudeCapacityOptions & {\n checkedAt: string;\n};\n\nfunction claudeReport(snapshot: ProviderCapacitySnapshot, checkedAt: string): CapacityReport {\n return {\n harness: \"claude\",\n provider: \"anthropic\",\n generatedAt: checkedAt,\n ...snapshot,\n };\n}\n\nexport async function probeClaudeCapacity(options: ClaudeProbeOptions): Promise<CapacityReport> {\n const token = await resolveClaudeAnthropicToken(options);\n const snapshot = await fetchAnthropicCapacity(token, options);\n return claudeReport(snapshot, options.checkedAt);\n}\n"],"names":["fetchAnthropicCapacity","resolveClaudeAnthropicToken","claudeReport","snapshot","checkedAt","harness","provider","generatedAt","probeClaudeCapacity","options","token"],"mappings":"AAAA,SACEA,sBAAsB,QAEjB,4BAA4B;AAEnC,SACEC,2BAA2B,QAEtB,wCAAwC;AAQ/C,SAASC,aAAaC,QAAkC,EAAEC,SAAiB;IACzE,OAAO;QACLC,SAAS;QACTC,UAAU;QACVC,aAAaH;QACb,GAAGD,QAAQ;IACb;AACF;AAEA,OAAO,eAAeK,oBAAoBC,OAA2B;IACnE,MAAMC,QAAQ,MAAMT,4BAA4BQ;IAChD,MAAMN,WAAW,MAAMH,uBAAuBU,OAAOD;IACrD,OAAOP,aAAaC,UAAUM,QAAQL,SAAS;AACjD"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { CapacityReport, CapacityWindow } from "
|
|
2
|
-
|
|
1
|
+
import type { CapacityReport, CapacityWindow } from "../types.js";
|
|
2
|
+
import { type CodexCredentialOptions } from "../../harnesses/codex/credentials.js";
|
|
3
3
|
type CodexUsageSource = "pat" | "oauth" | "cli";
|
|
4
4
|
type UsageSnapshot = {
|
|
5
5
|
windows: CapacityWindow[];
|
|
@@ -17,20 +17,16 @@ type CliResponses = {
|
|
|
17
17
|
account: unknown;
|
|
18
18
|
};
|
|
19
19
|
type CodexRpc = (messages: RpcMessage[]) => Promise<CliResponses>;
|
|
20
|
-
export
|
|
21
|
-
type CodexProbeOptions = {
|
|
20
|
+
export type CodexProbeOptions = CodexCredentialOptions & {
|
|
22
21
|
installed: boolean;
|
|
23
22
|
checkedAt: string;
|
|
24
|
-
readFile?: (path: string, encoding: BufferEncoding) => Promise<string>;
|
|
25
23
|
fetch?: typeof globalThis.fetch;
|
|
26
24
|
rpc?: CodexRpc;
|
|
27
25
|
timeoutMs?: number;
|
|
28
|
-
env?: NodeJS.ProcessEnv;
|
|
29
|
-
now?: () => Date;
|
|
30
26
|
};
|
|
31
|
-
export declare
|
|
27
|
+
export declare const CODEX_APP_SERVER_ARGS: readonly ["-s", "read-only", "-a", "untrusted", "app-server"];
|
|
32
28
|
export declare function parseUsage(raw: unknown, source: "pat" | "oauth"): UsageSnapshot;
|
|
33
|
-
export declare function parseCliUsage(raw: unknown): UsageSnapshot;
|
|
34
29
|
export declare function codexUnavailableReport(checkedAt: string): CapacityReport;
|
|
35
30
|
export declare function probeCodexCapacity(options: CodexProbeOptions): Promise<CapacityReport>;
|
|
31
|
+
export {};
|
|
36
32
|
//# sourceMappingURL=codex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../../src/capacity/sources/codex.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,sCAAsC,CAAC;AAE9C,KAAK,gBAAgB,GAAG,KAAK,GAAG,OAAO,GAAG,KAAK,CAAC;AAChD,KAAK,aAAa,GAAG;IACnB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,gBAAgB,CAAC;CAC1B,CAAC;AAEF,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC7C,KAAK,UAAU,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,aAAa,CAAA;CAAE,CAAC;AAC1E,KAAK,YAAY,GAAG;IAAE,UAAU,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAC9D,KAAK,QAAQ,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAElE,MAAM,MAAM,iBAAiB,GAAG,sBAAsB,GAAG;IACvD,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,qBAAqB,+DAAgE,CAAC;AAgBnG,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,GAAG,OAAO,GAAG,aAAa,CAG/E;AA8GD,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAUxE;AAuDD,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CAiC5F"}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { parseWhamUsage, resetTime, safeIdentifier } from "./wham.js";
|
|
5
|
-
export { toRateWindow } from "./wham.js";
|
|
2
|
+
import { fetchOpenAiPatAccountId, fetchOpenAiSubscriptionCapacity, parseWhamUsage, resetTime, safeIdentifier } from "../providers/openai-subscription.js";
|
|
3
|
+
import { resolveCodexCredentials } from "../../harnesses/codex/credentials.js";
|
|
6
4
|
export const CODEX_APP_SERVER_ARGS = [
|
|
7
5
|
"-s",
|
|
8
6
|
"read-only",
|
|
@@ -19,10 +17,6 @@ function finiteNumber(value) {
|
|
|
19
17
|
function nonEmptyText(value) {
|
|
20
18
|
return typeof value === "string" && value.length > 0 ? value : null;
|
|
21
19
|
}
|
|
22
|
-
export function resolveCodexAuthPath(env = process.env) {
|
|
23
|
-
const root = env.CODEX_HOME || join(env.HOME || "", ".codex");
|
|
24
|
-
return join(root, "auth.json");
|
|
25
|
-
}
|
|
26
20
|
export function parseUsage(raw, source) {
|
|
27
21
|
const { windows, creditsRemaining } = parseWhamUsage(raw);
|
|
28
22
|
return {
|
|
@@ -51,13 +45,15 @@ function cliSnapshotWindows(value, fallbackId) {
|
|
|
51
45
|
cliWindow(snapshot.secondary, `${scope}:secondary`, `${scope} secondary`)
|
|
52
46
|
].filter((item)=>item !== null);
|
|
53
47
|
}
|
|
54
|
-
|
|
48
|
+
function parseCliUsage(raw) {
|
|
55
49
|
const response = record(raw) ?? {};
|
|
56
50
|
const primary = record(response.rateLimits);
|
|
57
51
|
const windows = primary ? cliSnapshotWindows(primary, "codex") : [];
|
|
58
52
|
const buckets = record(response.rateLimitsByLimitId);
|
|
59
53
|
if (buckets) {
|
|
60
|
-
for (const [id, snapshot] of Object.entries(buckets))
|
|
54
|
+
for (const [id, snapshot] of Object.entries(buckets)){
|
|
55
|
+
windows.push(...cliSnapshotWindows(snapshot, id));
|
|
56
|
+
}
|
|
61
57
|
}
|
|
62
58
|
const unique = [
|
|
63
59
|
...new Map(windows.map((window)=>[
|
|
@@ -71,7 +67,7 @@ export function parseCliUsage(raw) {
|
|
|
71
67
|
source: "cli"
|
|
72
68
|
};
|
|
73
69
|
}
|
|
74
|
-
function capacityFromSnapshot(snapshot,
|
|
70
|
+
function capacityFromSnapshot(snapshot, options, raw) {
|
|
75
71
|
const hasUsage = snapshot.windows.some((window)=>window.usedPercent !== null);
|
|
76
72
|
const rateLimits = record(record(raw)?.rateLimits);
|
|
77
73
|
const reached = nonEmptyText(rateLimits?.rateLimitReachedType);
|
|
@@ -79,56 +75,13 @@ function capacityFromSnapshot(snapshot, context, raw) {
|
|
|
79
75
|
return {
|
|
80
76
|
harness: "codex",
|
|
81
77
|
provider: "openai",
|
|
82
|
-
generatedAt:
|
|
78
|
+
generatedAt: options.checkedAt,
|
|
83
79
|
authenticated: true,
|
|
84
80
|
available: reached ? "no" : hasUsage ? "yes" : "unknown",
|
|
85
81
|
windows: snapshot.windows,
|
|
86
82
|
creditsRemaining: snapshot.creditsRemaining ?? finiteNumber(resetCredits?.availableCount)
|
|
87
83
|
};
|
|
88
84
|
}
|
|
89
|
-
function jwtExpiry(token) {
|
|
90
|
-
const part = token.split(".")[1];
|
|
91
|
-
if (!part) return null;
|
|
92
|
-
try {
|
|
93
|
-
return finiteNumber(record(JSON.parse(Buffer.from(part, "base64url").toString("utf8")))?.exp);
|
|
94
|
-
} catch {
|
|
95
|
-
return null;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
function staleOAuth(tokens, token, now) {
|
|
99
|
-
const metadata = tokens.expires_at ?? tokens.expiresAt ?? tokens.expiry;
|
|
100
|
-
let expiry = finiteNumber(metadata);
|
|
101
|
-
if (typeof metadata === "string") {
|
|
102
|
-
const parsed = Date.parse(metadata);
|
|
103
|
-
expiry = Number.isNaN(parsed) ? null : parsed / 1000;
|
|
104
|
-
}
|
|
105
|
-
expiry ??= jwtExpiry(token);
|
|
106
|
-
return expiry !== null && expiry <= now.getTime() / 1000;
|
|
107
|
-
}
|
|
108
|
-
async function fetchJson(fetcher, url, init, timeoutMs) {
|
|
109
|
-
const controller = new AbortController();
|
|
110
|
-
const timer = setTimeout(()=>controller.abort(), timeoutMs);
|
|
111
|
-
try {
|
|
112
|
-
const response = await fetcher(url, {
|
|
113
|
-
...init,
|
|
114
|
-
signal: controller.signal
|
|
115
|
-
});
|
|
116
|
-
if (!response.ok) throw new Error(response.status === 401 ? "unauthorized" : "request failed");
|
|
117
|
-
return await response.json();
|
|
118
|
-
} finally{
|
|
119
|
-
clearTimeout(timer);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
async function apiSnapshot(token, accountId, source, options) {
|
|
123
|
-
const fetcher = options.fetch ?? globalThis.fetch;
|
|
124
|
-
const raw = await fetchJson(fetcher, "https://chatgpt.com/backend-api/wham/usage", {
|
|
125
|
-
headers: {
|
|
126
|
-
Authorization: `Bearer ${token}`,
|
|
127
|
-
"ChatGPT-Account-Id": accountId
|
|
128
|
-
}
|
|
129
|
-
}, options.timeoutMs ?? 5000);
|
|
130
|
-
return parseUsage(raw, source);
|
|
131
|
-
}
|
|
132
85
|
function appServerRpc(messages, timeoutMs = 5000) {
|
|
133
86
|
return new Promise((resolve, reject)=>{
|
|
134
87
|
const child = spawn("codex", CODEX_APP_SERVER_ARGS, {
|
|
@@ -195,11 +148,8 @@ export function codexUnavailableReport(checkedAt) {
|
|
|
195
148
|
creditsRemaining: null
|
|
196
149
|
};
|
|
197
150
|
}
|
|
198
|
-
function unavailable(options) {
|
|
199
|
-
return codexUnavailableReport(options.checkedAt);
|
|
200
|
-
}
|
|
201
151
|
async function cliFallback(options) {
|
|
202
|
-
if (!options.installed) return
|
|
152
|
+
if (!options.installed) return codexUnavailableReport(options.checkedAt);
|
|
203
153
|
const messages = [
|
|
204
154
|
{
|
|
205
155
|
id: 1,
|
|
@@ -236,40 +186,37 @@ async function cliFallback(options) {
|
|
|
236
186
|
}
|
|
237
187
|
return result;
|
|
238
188
|
} catch {
|
|
239
|
-
return
|
|
189
|
+
return codexUnavailableReport(options.checkedAt);
|
|
240
190
|
}
|
|
241
191
|
}
|
|
192
|
+
async function subscriptionSnapshot(access, accountId, source, options) {
|
|
193
|
+
const snapshot = await fetchOpenAiSubscriptionCapacity({
|
|
194
|
+
access,
|
|
195
|
+
accountId
|
|
196
|
+
}, options);
|
|
197
|
+
if (snapshot.authenticated === false) throw new Error("unauthorized");
|
|
198
|
+
return {
|
|
199
|
+
windows: snapshot.windows,
|
|
200
|
+
creditsRemaining: snapshot.creditsRemaining,
|
|
201
|
+
source
|
|
202
|
+
};
|
|
203
|
+
}
|
|
242
204
|
export async function probeCodexCapacity(options) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
parsed = record(JSON.parse(contents));
|
|
247
|
-
} catch {
|
|
248
|
-
return cliFallback(options);
|
|
249
|
-
}
|
|
250
|
-
const auth = parsed ?? {};
|
|
251
|
-
const pat = nonEmptyText(auth.personal_access_token);
|
|
252
|
-
if (pat) {
|
|
205
|
+
const credentials = await resolveCodexCredentials(options);
|
|
206
|
+
if (!credentials) return cliFallback(options);
|
|
207
|
+
if (credentials.personalAccessToken) {
|
|
253
208
|
try {
|
|
254
|
-
const
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
Authorization: `Bearer ${pat}`
|
|
258
|
-
}
|
|
259
|
-
}, options.timeoutMs ?? 5000));
|
|
260
|
-
const accountId = nonEmptyText(whoami?.chatgpt_account_id);
|
|
261
|
-
if (!accountId) throw new Error("account unavailable");
|
|
262
|
-
return capacityFromSnapshot(await apiSnapshot(pat, accountId, "pat", options), options);
|
|
209
|
+
const accountId = await fetchOpenAiPatAccountId(credentials.personalAccessToken, options);
|
|
210
|
+
const snapshot = await subscriptionSnapshot(credentials.personalAccessToken, accountId, "pat", options);
|
|
211
|
+
return capacityFromSnapshot(snapshot, options);
|
|
263
212
|
} catch {
|
|
264
213
|
// Continue to a separately available OAuth credential before using the CLI.
|
|
265
214
|
}
|
|
266
215
|
}
|
|
267
|
-
|
|
268
|
-
const accessToken = nonEmptyText(tokens?.access_token);
|
|
269
|
-
const accountId = nonEmptyText(tokens?.account_id);
|
|
270
|
-
if (tokens && accessToken && accountId && !staleOAuth(tokens, accessToken, (options.now ?? (()=>new Date()))())) {
|
|
216
|
+
if (credentials.oauth) {
|
|
271
217
|
try {
|
|
272
|
-
|
|
218
|
+
const snapshot = await subscriptionSnapshot(credentials.oauth.access, credentials.oauth.accountId, "oauth", options);
|
|
219
|
+
return capacityFromSnapshot(snapshot, options);
|
|
273
220
|
} catch {
|
|
274
221
|
return cliFallback(options);
|
|
275
222
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/capacity/sources/codex.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport {\n fetchOpenAiPatAccountId,\n fetchOpenAiSubscriptionCapacity,\n parseWhamUsage,\n resetTime,\n safeIdentifier,\n} from \"../providers/openai-subscription.js\";\nimport type { CapacityReport, CapacityWindow } from \"../types.js\";\nimport {\n resolveCodexCredentials,\n type CodexCredentialOptions,\n} from \"../../harnesses/codex/credentials.js\";\n\ntype CodexUsageSource = \"pat\" | \"oauth\" | \"cli\";\ntype UsageSnapshot = {\n windows: CapacityWindow[];\n creditsRemaining: number | null;\n source: CodexUsageSource;\n};\n\ntype UnknownRecord = Record<string, unknown>;\ntype RpcMessage = { id?: number; method: string; params?: UnknownRecord };\ntype CliResponses = { rateLimits: unknown; account: unknown };\ntype CodexRpc = (messages: RpcMessage[]) => Promise<CliResponses>;\n\nexport type CodexProbeOptions = CodexCredentialOptions & {\n installed: boolean;\n checkedAt: string;\n fetch?: typeof globalThis.fetch;\n rpc?: CodexRpc;\n timeoutMs?: number;\n};\n\nexport const CODEX_APP_SERVER_ARGS = [\"-s\", \"read-only\", \"-a\", \"untrusted\", \"app-server\"] as const;\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 parseUsage(raw: unknown, source: \"pat\" | \"oauth\"): UsageSnapshot {\n const { windows, creditsRemaining } = parseWhamUsage(raw);\n return { windows, creditsRemaining, source };\n}\n\nfunction cliWindow(value: unknown, id: string, label: string): CapacityWindow | null {\n const input = record(value);\n if (!input) return null;\n return {\n id,\n label,\n durationMinutes: finiteNumber(input.windowDurationMins),\n usedPercent: finiteNumber(input.usedPercent),\n resetsAt: resetTime(input.resetsAt),\n };\n}\n\nfunction cliSnapshotWindows(value: unknown, fallbackId: string): CapacityWindow[] {\n const snapshot = record(value);\n if (!snapshot) return [];\n const scope = safeIdentifier(snapshot.limitId) ?? safeIdentifier(fallbackId) ?? \"codex\";\n return [\n cliWindow(snapshot.primary, `${scope}:primary`, `${scope} primary`),\n cliWindow(snapshot.secondary, `${scope}:secondary`, `${scope} secondary`),\n ].filter((item): item is CapacityWindow => item !== null);\n}\n\nfunction parseCliUsage(raw: unknown): UsageSnapshot {\n const response = record(raw) ?? {};\n const primary = record(response.rateLimits);\n const windows = primary ? cliSnapshotWindows(primary, \"codex\") : [];\n const buckets = record(response.rateLimitsByLimitId);\n if (buckets) {\n for (const [id, snapshot] of Object.entries(buckets)) {\n windows.push(...cliSnapshotWindows(snapshot, id));\n }\n }\n const unique = [...new Map(windows.map((window) => [window.id, window])).values()];\n return { windows: unique, creditsRemaining: null, source: \"cli\" };\n}\n\nfunction capacityFromSnapshot(\n snapshot: UsageSnapshot,\n options: CodexProbeOptions,\n raw?: unknown,\n): CapacityReport {\n const hasUsage = snapshot.windows.some((window) => window.usedPercent !== null);\n const rateLimits = record(record(raw)?.rateLimits);\n const reached = nonEmptyText(rateLimits?.rateLimitReachedType);\n const resetCredits =\n record(record(raw)?.rateLimitResetCredits) ?? record(record(raw)?.usageLimitResetCredits);\n return {\n harness: \"codex\",\n provider: \"openai\",\n generatedAt: options.checkedAt,\n authenticated: true,\n available: reached ? \"no\" : hasUsage ? \"yes\" : \"unknown\",\n windows: snapshot.windows,\n creditsRemaining: snapshot.creditsRemaining ?? finiteNumber(resetCredits?.availableCount),\n };\n}\n\nfunction appServerRpc(messages: RpcMessage[], timeoutMs = 5000): Promise<CliResponses> {\n return new Promise((resolve, reject) => {\n const child = spawn(\"codex\", CODEX_APP_SERVER_ARGS, { stdio: [\"pipe\", \"pipe\", \"ignore\"] });\n const results: Partial<CliResponses> = {};\n let buffer = \"\";\n let settled = false;\n const finish = (error?: Error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n child.kill();\n if (error) reject(error);\n else resolve(results as CliResponses);\n };\n const timer = setTimeout(() => finish(new Error(\"codex probe timed out\")), timeoutMs);\n child.once(\"error\", () => finish(new Error(\"codex app-server unavailable\")));\n child.once(\"exit\", () => {\n if (!settled) finish(new Error(\"codex app-server exited\"));\n });\n child.stdout.setEncoding(\"utf8\");\n child.stdout.on(\"data\", (chunk: string) => {\n buffer += chunk;\n for (;;) {\n const newline = buffer.indexOf(\"\\n\");\n if (newline < 0) break;\n const line = buffer.slice(0, newline).trim();\n buffer = buffer.slice(newline + 1);\n if (!line) continue;\n let message: UnknownRecord;\n try {\n message = JSON.parse(line) as UnknownRecord;\n } catch {\n continue;\n }\n if (message.id === 1) {\n for (const request of messages.slice(1))\n child.stdin.write(`${JSON.stringify(request)}\\n`);\n } else if (message.id === 2) {\n if (message.error) finish(new Error(\"codex rate-limit method failed\"));\n else results.rateLimits = message.result;\n } else if (message.id === 3) {\n if (message.error) finish(new Error(\"codex account method failed\"));\n else results.account = message.result;\n }\n if (\"rateLimits\" in results && \"account\" in results) finish();\n }\n });\n child.stdin.write(`${JSON.stringify(messages[0])}\\n`);\n });\n}\n\nexport function codexUnavailableReport(checkedAt: string): CapacityReport {\n return {\n harness: \"codex\",\n provider: \"openai\",\n generatedAt: checkedAt,\n authenticated: null,\n available: \"unknown\",\n windows: [],\n creditsRemaining: null,\n };\n}\n\nasync function cliFallback(options: CodexProbeOptions): Promise<CapacityReport> {\n if (!options.installed) return codexUnavailableReport(options.checkedAt);\n const messages: RpcMessage[] = [\n {\n id: 1,\n method: \"initialize\",\n params: {\n clientInfo: { name: \"ai-devkit\", title: null, version: \"1\" },\n capabilities: null,\n },\n },\n { method: \"initialized\" },\n { id: 2, method: \"account/rateLimits/read\" },\n { id: 3, method: \"account/read\" },\n ];\n try {\n const rpc = options.rpc ?? ((requests) => appServerRpc(requests, options.timeoutMs));\n const response = await rpc(messages);\n const result = capacityFromSnapshot(\n parseCliUsage(response.rateLimits),\n options,\n response.rateLimits,\n );\n const accountEnvelope = record(response.account);\n if (\n accountEnvelope &&\n Object.hasOwn(accountEnvelope, \"account\") &&\n !record(accountEnvelope.account)\n ) {\n result.authenticated = false;\n result.available = \"unknown\";\n }\n return result;\n } catch {\n return codexUnavailableReport(options.checkedAt);\n }\n}\n\nasync function subscriptionSnapshot(\n access: string,\n accountId: string,\n source: \"pat\" | \"oauth\",\n options: CodexProbeOptions,\n): Promise<UsageSnapshot> {\n const snapshot = await fetchOpenAiSubscriptionCapacity({ access, accountId }, options);\n if (snapshot.authenticated === false) throw new Error(\"unauthorized\");\n return {\n windows: snapshot.windows,\n creditsRemaining: snapshot.creditsRemaining,\n source,\n };\n}\n\nexport async function probeCodexCapacity(options: CodexProbeOptions): Promise<CapacityReport> {\n const credentials = await resolveCodexCredentials(options);\n if (!credentials) return cliFallback(options);\n\n if (credentials.personalAccessToken) {\n try {\n const accountId = await fetchOpenAiPatAccountId(credentials.personalAccessToken, options);\n const snapshot = await subscriptionSnapshot(\n credentials.personalAccessToken,\n accountId,\n \"pat\",\n options,\n );\n return capacityFromSnapshot(snapshot, options);\n } catch {\n // Continue to a separately available OAuth credential before using the CLI.\n }\n }\n\n if (credentials.oauth) {\n try {\n const snapshot = await subscriptionSnapshot(\n credentials.oauth.access,\n credentials.oauth.accountId,\n \"oauth\",\n options,\n );\n return capacityFromSnapshot(snapshot, options);\n } catch {\n return cliFallback(options);\n }\n }\n return cliFallback(options);\n}\n"],"names":["spawn","fetchOpenAiPatAccountId","fetchOpenAiSubscriptionCapacity","parseWhamUsage","resetTime","safeIdentifier","resolveCodexCredentials","CODEX_APP_SERVER_ARGS","record","value","Array","isArray","finiteNumber","Number","isFinite","nonEmptyText","length","parseUsage","raw","source","windows","creditsRemaining","cliWindow","id","label","input","durationMinutes","windowDurationMins","usedPercent","resetsAt","cliSnapshotWindows","fallbackId","snapshot","scope","limitId","primary","secondary","filter","item","parseCliUsage","response","rateLimits","buckets","rateLimitsByLimitId","Object","entries","push","unique","Map","map","window","values","capacityFromSnapshot","options","hasUsage","some","reached","rateLimitReachedType","resetCredits","rateLimitResetCredits","usageLimitResetCredits","harness","provider","generatedAt","checkedAt","authenticated","available","availableCount","appServerRpc","messages","timeoutMs","Promise","resolve","reject","child","stdio","results","buffer","settled","finish","error","clearTimeout","timer","kill","setTimeout","Error","once","stdout","setEncoding","on","chunk","newline","indexOf","line","slice","trim","message","JSON","parse","request","stdin","write","stringify","result","account","codexUnavailableReport","cliFallback","installed","method","params","clientInfo","name","title","version","capabilities","rpc","requests","accountEnvelope","hasOwn","subscriptionSnapshot","access","accountId","probeCodexCapacity","credentials","personalAccessToken","oauth"],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { CapacityReport } from "../types.js";
|
|
2
|
+
import { type PiCredentialOptions } from "../../harnesses/pi/credentials.js";
|
|
3
|
+
export type PiAnthropicCapacityOptions = PiCredentialOptions & {
|
|
4
|
+
now?: () => Date;
|
|
5
|
+
fetch?: typeof globalThis.fetch;
|
|
6
|
+
timeoutMs?: number;
|
|
7
|
+
};
|
|
8
|
+
export type PiAnthropicProbeOptions = PiAnthropicCapacityOptions & {
|
|
9
|
+
checkedAt: string;
|
|
10
|
+
};
|
|
11
|
+
export type PiOpenAiCapacityOptions = PiCredentialOptions & {
|
|
12
|
+
now?: () => Date;
|
|
13
|
+
fetch?: typeof globalThis.fetch;
|
|
14
|
+
timeoutMs?: number;
|
|
15
|
+
};
|
|
16
|
+
export type PiOpenAiProbeOptions = PiOpenAiCapacityOptions & {
|
|
17
|
+
checkedAt: string;
|
|
18
|
+
};
|
|
19
|
+
export type PiZaiCapacityOptions = PiCredentialOptions & {
|
|
20
|
+
now?: () => Date;
|
|
21
|
+
fetch?: typeof globalThis.fetch;
|
|
22
|
+
timeoutMs?: number;
|
|
23
|
+
};
|
|
24
|
+
export type PiZaiProbeOptions = PiZaiCapacityOptions & {
|
|
25
|
+
checkedAt: string;
|
|
26
|
+
};
|
|
27
|
+
export declare function probePiAnthropicCapacity(options: PiAnthropicProbeOptions): Promise<CapacityReport>;
|
|
28
|
+
export declare function probeOpenAiCapacity(options: PiOpenAiProbeOptions): Promise<CapacityReport>;
|
|
29
|
+
export declare function probeZaiCapacity(options: PiZaiProbeOptions): Promise<CapacityReport>;
|
|
30
|
+
//# sourceMappingURL=pi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi.d.ts","sourceRoot":"","sources":["../../../src/capacity/sources/pi.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAA4B,MAAM,aAAa,CAAC;AAC5E,OAAO,EAIL,KAAK,mBAAmB,EAEzB,MAAM,mCAAmC,CAAC;AAE3C,MAAM,MAAM,0BAA0B,GAAG,mBAAmB,GAAG;IAC7D,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,0BAA0B,GAAG;IACjE,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,mBAAmB,GAAG;IAC1D,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,uBAAuB,GAAG;IAC3D,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,mBAAmB,GAAG;IACvD,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,GAAG;IACrD,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,cAAc,CAAC,CAqBzB;AAgCD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CAqBhG;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CAS1F"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { fetchAnthropicCapacity } from "../providers/anthropic.js";
|
|
2
|
+
import { fetchOpenAiPlatformCapacity } from "../providers/openai-platform.js";
|
|
3
|
+
import { fetchOpenAiSubscriptionCapacity } from "../providers/openai-subscription.js";
|
|
4
|
+
import { fetchZaiCapacity } from "../providers/zai.js";
|
|
5
|
+
import { resolvePiAnthropicCredential, resolvePiOpenAiCredential, resolvePiZaiApiKey } from "../../harnesses/pi/credentials.js";
|
|
6
|
+
export async function probePiAnthropicCapacity(options) {
|
|
7
|
+
const credential = await resolvePiAnthropicCredential(options);
|
|
8
|
+
const now = options.now?.() ?? new Date();
|
|
9
|
+
if (credential.expiresMs !== null && credential.expiresMs <= now.getTime()) {
|
|
10
|
+
return {
|
|
11
|
+
harness: "pi",
|
|
12
|
+
provider: "anthropic",
|
|
13
|
+
generatedAt: options.checkedAt,
|
|
14
|
+
authenticated: true,
|
|
15
|
+
available: "unknown",
|
|
16
|
+
windows: [],
|
|
17
|
+
creditsRemaining: null
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const snapshot = await fetchAnthropicCapacity(credential.access, options);
|
|
21
|
+
return {
|
|
22
|
+
harness: "pi",
|
|
23
|
+
provider: "anthropic",
|
|
24
|
+
generatedAt: options.checkedAt,
|
|
25
|
+
...snapshot
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function piOpenAiReport(snapshot, checkedAt) {
|
|
29
|
+
return {
|
|
30
|
+
harness: "pi",
|
|
31
|
+
provider: "openai",
|
|
32
|
+
generatedAt: checkedAt,
|
|
33
|
+
...snapshot
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function jwtExpiryMs(token) {
|
|
37
|
+
const part = token.split(".")[1];
|
|
38
|
+
if (!part) return null;
|
|
39
|
+
try {
|
|
40
|
+
const payload = JSON.parse(Buffer.from(part, "base64url").toString("utf8"));
|
|
41
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) return null;
|
|
42
|
+
const exp = payload.exp;
|
|
43
|
+
return typeof exp === "number" && Number.isFinite(exp) ? exp * 1000 : null;
|
|
44
|
+
} catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function oauthExpired(credential, nowMs) {
|
|
49
|
+
const expiryMs = credential.expiresMs ?? jwtExpiryMs(credential.access);
|
|
50
|
+
return expiryMs !== null && expiryMs <= nowMs;
|
|
51
|
+
}
|
|
52
|
+
export async function probeOpenAiCapacity(options) {
|
|
53
|
+
const credential = await resolvePiOpenAiCredential(options);
|
|
54
|
+
if (credential.kind === "platform") {
|
|
55
|
+
const snapshot = await fetchOpenAiPlatformCapacity(credential.key, options);
|
|
56
|
+
return piOpenAiReport(snapshot, options.checkedAt);
|
|
57
|
+
}
|
|
58
|
+
const nowMs = Date.parse(options.checkedAt);
|
|
59
|
+
if (Number.isNaN(nowMs) || oauthExpired(credential, nowMs)) {
|
|
60
|
+
return piOpenAiReport({
|
|
61
|
+
authenticated: true,
|
|
62
|
+
available: "unknown",
|
|
63
|
+
windows: [],
|
|
64
|
+
creditsRemaining: null
|
|
65
|
+
}, options.checkedAt);
|
|
66
|
+
}
|
|
67
|
+
const snapshot = await fetchOpenAiSubscriptionCapacity(credential, options);
|
|
68
|
+
return piOpenAiReport(snapshot, options.checkedAt);
|
|
69
|
+
}
|
|
70
|
+
export async function probeZaiCapacity(options) {
|
|
71
|
+
const key = await resolvePiZaiApiKey(options);
|
|
72
|
+
const snapshot = await fetchZaiCapacity(key, options);
|
|
73
|
+
return {
|
|
74
|
+
harness: "pi",
|
|
75
|
+
provider: "zai",
|
|
76
|
+
generatedAt: options.checkedAt,
|
|
77
|
+
...snapshot
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
//# sourceMappingURL=pi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/capacity/sources/pi.ts"],"sourcesContent":["import { fetchAnthropicCapacity } from \"../providers/anthropic.js\";\nimport { fetchOpenAiPlatformCapacity } from \"../providers/openai-platform.js\";\nimport { fetchOpenAiSubscriptionCapacity } from \"../providers/openai-subscription.js\";\nimport { fetchZaiCapacity } from \"../providers/zai.js\";\nimport type { CapacityReport, ProviderCapacitySnapshot } from \"../types.js\";\nimport {\n resolvePiAnthropicCredential,\n resolvePiOpenAiCredential,\n resolvePiZaiApiKey,\n type PiCredentialOptions,\n type PiOpenAiCredential,\n} from \"../../harnesses/pi/credentials.js\";\n\nexport type PiAnthropicCapacityOptions = PiCredentialOptions & {\n now?: () => Date;\n fetch?: typeof globalThis.fetch;\n timeoutMs?: number;\n};\n\nexport type PiAnthropicProbeOptions = PiAnthropicCapacityOptions & {\n checkedAt: string;\n};\n\nexport type PiOpenAiCapacityOptions = PiCredentialOptions & {\n now?: () => Date;\n fetch?: typeof globalThis.fetch;\n timeoutMs?: number;\n};\n\nexport type PiOpenAiProbeOptions = PiOpenAiCapacityOptions & {\n checkedAt: string;\n};\n\nexport type PiZaiCapacityOptions = PiCredentialOptions & {\n now?: () => Date;\n fetch?: typeof globalThis.fetch;\n timeoutMs?: number;\n};\n\nexport type PiZaiProbeOptions = PiZaiCapacityOptions & {\n checkedAt: string;\n};\n\nexport async function probePiAnthropicCapacity(\n options: PiAnthropicProbeOptions,\n): Promise<CapacityReport> {\n const credential = await resolvePiAnthropicCredential(options);\n const now = options.now?.() ?? new Date();\n if (credential.expiresMs !== null && credential.expiresMs <= now.getTime()) {\n return {\n harness: \"pi\",\n provider: \"anthropic\",\n generatedAt: options.checkedAt,\n authenticated: true,\n available: \"unknown\",\n windows: [],\n creditsRemaining: null,\n };\n }\n const snapshot = await fetchAnthropicCapacity(credential.access, options);\n return {\n harness: \"pi\",\n provider: \"anthropic\",\n generatedAt: options.checkedAt,\n ...snapshot,\n };\n}\n\nfunction piOpenAiReport(snapshot: ProviderCapacitySnapshot, checkedAt: string): CapacityReport {\n return {\n harness: \"pi\",\n provider: \"openai\",\n generatedAt: checkedAt,\n ...snapshot,\n };\n}\n\nfunction jwtExpiryMs(token: string): number | null {\n const part = token.split(\".\")[1];\n if (!part) return null;\n try {\n const payload = JSON.parse(Buffer.from(part, \"base64url\").toString(\"utf8\")) as unknown;\n if (!payload || typeof payload !== \"object\" || Array.isArray(payload)) return null;\n const exp = (payload as Record<string, unknown>).exp;\n return typeof exp === \"number\" && Number.isFinite(exp) ? exp * 1000 : null;\n } catch {\n return null;\n }\n}\n\nfunction oauthExpired(\n credential: Extract<PiOpenAiCredential, { kind: \"oauth\" }>,\n nowMs: number,\n): boolean {\n const expiryMs = credential.expiresMs ?? jwtExpiryMs(credential.access);\n return expiryMs !== null && expiryMs <= nowMs;\n}\n\nexport async function probeOpenAiCapacity(options: PiOpenAiProbeOptions): Promise<CapacityReport> {\n const credential = await resolvePiOpenAiCredential(options);\n if (credential.kind === \"platform\") {\n const snapshot = await fetchOpenAiPlatformCapacity(credential.key, options);\n return piOpenAiReport(snapshot, options.checkedAt);\n }\n\n const nowMs = Date.parse(options.checkedAt);\n if (Number.isNaN(nowMs) || oauthExpired(credential, nowMs)) {\n return piOpenAiReport(\n {\n authenticated: true,\n available: \"unknown\",\n windows: [],\n creditsRemaining: null,\n },\n options.checkedAt,\n );\n }\n const snapshot = await fetchOpenAiSubscriptionCapacity(credential, options);\n return piOpenAiReport(snapshot, options.checkedAt);\n}\n\nexport async function probeZaiCapacity(options: PiZaiProbeOptions): Promise<CapacityReport> {\n const key = await resolvePiZaiApiKey(options);\n const snapshot = await fetchZaiCapacity(key, options);\n return {\n harness: \"pi\",\n provider: \"zai\",\n generatedAt: options.checkedAt,\n ...snapshot,\n };\n}\n"],"names":["fetchAnthropicCapacity","fetchOpenAiPlatformCapacity","fetchOpenAiSubscriptionCapacity","fetchZaiCapacity","resolvePiAnthropicCredential","resolvePiOpenAiCredential","resolvePiZaiApiKey","probePiAnthropicCapacity","options","credential","now","Date","expiresMs","getTime","harness","provider","generatedAt","checkedAt","authenticated","available","windows","creditsRemaining","snapshot","access","piOpenAiReport","jwtExpiryMs","token","part","split","payload","JSON","parse","Buffer","from","toString","Array","isArray","exp","Number","isFinite","oauthExpired","nowMs","expiryMs","probeOpenAiCapacity","kind","key","isNaN","probeZaiCapacity"],"mappings":"AAAA,SAASA,sBAAsB,QAAQ,4BAA4B;AACnE,SAASC,2BAA2B,QAAQ,kCAAkC;AAC9E,SAASC,+BAA+B,QAAQ,sCAAsC;AACtF,SAASC,gBAAgB,QAAQ,sBAAsB;AAEvD,SACEC,4BAA4B,EAC5BC,yBAAyB,EACzBC,kBAAkB,QAGb,oCAAoC;AAgC3C,OAAO,eAAeC,yBACpBC,OAAgC;IAEhC,MAAMC,aAAa,MAAML,6BAA6BI;IACtD,MAAME,MAAMF,QAAQE,GAAG,QAAQ,IAAIC;IACnC,IAAIF,WAAWG,SAAS,KAAK,QAAQH,WAAWG,SAAS,IAAIF,IAAIG,OAAO,IAAI;QAC1E,OAAO;YACLC,SAAS;YACTC,UAAU;YACVC,aAAaR,QAAQS,SAAS;YAC9BC,eAAe;YACfC,WAAW;YACXC,SAAS,EAAE;YACXC,kBAAkB;QACpB;IACF;IACA,MAAMC,WAAW,MAAMtB,uBAAuBS,WAAWc,MAAM,EAAEf;IACjE,OAAO;QACLM,SAAS;QACTC,UAAU;QACVC,aAAaR,QAAQS,SAAS;QAC9B,GAAGK,QAAQ;IACb;AACF;AAEA,SAASE,eAAeF,QAAkC,EAAEL,SAAiB;IAC3E,OAAO;QACLH,SAAS;QACTC,UAAU;QACVC,aAAaC;QACb,GAAGK,QAAQ;IACb;AACF;AAEA,SAASG,YAAYC,KAAa;IAChC,MAAMC,OAAOD,MAAME,KAAK,CAAC,IAAI,CAAC,EAAE;IAChC,IAAI,CAACD,MAAM,OAAO;IAClB,IAAI;QACF,MAAME,UAAUC,KAAKC,KAAK,CAACC,OAAOC,IAAI,CAACN,MAAM,aAAaO,QAAQ,CAAC;QACnE,IAAI,CAACL,WAAW,OAAOA,YAAY,YAAYM,MAAMC,OAAO,CAACP,UAAU,OAAO;QAC9E,MAAMQ,MAAM,AAACR,QAAoCQ,GAAG;QACpD,OAAO,OAAOA,QAAQ,YAAYC,OAAOC,QAAQ,CAACF,OAAOA,MAAM,OAAO;IACxE,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA,SAASG,aACP/B,UAA0D,EAC1DgC,KAAa;IAEb,MAAMC,WAAWjC,WAAWG,SAAS,IAAIa,YAAYhB,WAAWc,MAAM;IACtE,OAAOmB,aAAa,QAAQA,YAAYD;AAC1C;AAEA,OAAO,eAAeE,oBAAoBnC,OAA6B;IACrE,MAAMC,aAAa,MAAMJ,0BAA0BG;IACnD,IAAIC,WAAWmC,IAAI,KAAK,YAAY;QAClC,MAAMtB,WAAW,MAAMrB,4BAA4BQ,WAAWoC,GAAG,EAAErC;QACnE,OAAOgB,eAAeF,UAAUd,QAAQS,SAAS;IACnD;IAEA,MAAMwB,QAAQ9B,KAAKoB,KAAK,CAACvB,QAAQS,SAAS;IAC1C,IAAIqB,OAAOQ,KAAK,CAACL,UAAUD,aAAa/B,YAAYgC,QAAQ;QAC1D,OAAOjB,eACL;YACEN,eAAe;YACfC,WAAW;YACXC,SAAS,EAAE;YACXC,kBAAkB;QACpB,GACAb,QAAQS,SAAS;IAErB;IACA,MAAMK,WAAW,MAAMpB,gCAAgCO,YAAYD;IACnE,OAAOgB,eAAeF,UAAUd,QAAQS,SAAS;AACnD;AAEA,OAAO,eAAe8B,iBAAiBvC,OAA0B;IAC/D,MAAMqC,MAAM,MAAMvC,mBAAmBE;IACrC,MAAMc,WAAW,MAAMnB,iBAAiB0C,KAAKrC;IAC7C,OAAO;QACLM,SAAS;QACTC,UAAU;QACVC,aAAaR,QAAQS,SAAS;QAC9B,GAAGK,QAAQ;IACb;AACF"}
|
package/dist/capacity/types.d.ts
CHANGED
|
@@ -22,4 +22,6 @@ export interface CapacityReport {
|
|
|
22
22
|
windows: CapacityWindow[];
|
|
23
23
|
creditsRemaining: number | null;
|
|
24
24
|
}
|
|
25
|
+
/** Provider quota data before a harness/source identity is attached. */
|
|
26
|
+
export type ProviderCapacitySnapshot = Omit<CapacityReport, "harness" | "provider" | "generatedAt">;
|
|
25
27
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/capacity/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;AACpD,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,cAAc,GAAG,YAAY,CAAC;AAE/E,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,YAAY,CAAC;IACxB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/capacity/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;AACpD,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,cAAc,GAAG,YAAY,CAAC;AAE/E,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,YAAY,CAAC;IACxB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,wEAAwE;AACxE,MAAM,MAAM,wBAAwB,GAAG,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,UAAU,GAAG,aAAa,CAAC,CAAC"}
|