saros-proxy 0.10.2 → 1.0.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/README.md +261 -78
- package/dist/cli/daemon.d.ts +38 -6
- package/dist/cli/daemon.js +524 -109
- package/dist/cli/daemon.js.map +1 -1
- package/dist/cli/dsh-config.js +34 -9
- package/dist/cli/dsh-config.js.map +1 -1
- package/dist/cli/help.js +3 -0
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/key-state.d.ts +21 -0
- package/dist/cli/key-state.js +57 -0
- package/dist/cli/key-state.js.map +1 -0
- package/dist/cli/keys.d.ts +28 -0
- package/dist/cli/keys.js +185 -0
- package/dist/cli/keys.js.map +1 -0
- package/dist/cli/overview.js +6 -1
- package/dist/cli/overview.js.map +1 -1
- package/dist/cli/secret.d.ts +31 -0
- package/dist/cli/secret.js +89 -0
- package/dist/cli/secret.js.map +1 -0
- package/dist/cli/usage.js +20 -10
- package/dist/cli/usage.js.map +1 -1
- package/dist/config.d.ts +15 -1
- package/dist/config.js +98 -25
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +2 -0
- package/dist/constants.js.map +1 -1
- package/dist/debug-buffer.d.ts +58 -0
- package/dist/debug-buffer.js +42 -0
- package/dist/debug-buffer.js.map +1 -0
- package/dist/index.js +30 -4
- package/dist/index.js.map +1 -1
- package/dist/log-redact.d.ts +18 -0
- package/dist/log-redact.js +41 -0
- package/dist/log-redact.js.map +1 -0
- package/dist/logger.d.ts +6 -0
- package/dist/logger.js +30 -0
- package/dist/logger.js.map +1 -1
- package/dist/models-fetcher.js +2 -0
- package/dist/models-fetcher.js.map +1 -1
- package/dist/providers/commandcode.d.ts +20 -5
- package/dist/providers/commandcode.js +115 -7
- package/dist/providers/commandcode.js.map +1 -1
- package/dist/providers/index.d.ts +2 -2
- package/dist/providers/index.js +2 -2
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/infer.d.ts +11 -0
- package/dist/providers/infer.js.map +1 -1
- package/dist/providers/opencode-go.d.ts +8 -0
- package/dist/providers/opencode-go.js +35 -7
- package/dist/providers/opencode-go.js.map +1 -1
- package/dist/providers/types.d.ts +10 -2
- package/dist/proxy-logic.d.ts +101 -7
- package/dist/proxy-logic.js +197 -41
- package/dist/proxy-logic.js.map +1 -1
- package/dist/proxy.d.ts +33 -1
- package/dist/proxy.js +369 -67
- package/dist/proxy.js.map +1 -1
- package/dist/secrets/boot.d.ts +33 -0
- package/dist/secrets/boot.js +65 -0
- package/dist/secrets/boot.js.map +1 -0
- package/dist/secrets/envelope.d.ts +44 -0
- package/dist/secrets/envelope.js +132 -0
- package/dist/secrets/envelope.js.map +1 -0
- package/dist/secrets/source.d.ts +130 -0
- package/dist/secrets/source.js +332 -0
- package/dist/secrets/source.js.map +1 -0
- package/dist/token-usage.d.ts +9 -2
- package/dist/token-usage.js +20 -4
- package/dist/token-usage.js.map +1 -1
- package/dist/usage-client.d.ts +43 -13
- package/dist/usage-client.js +37 -54
- package/dist/usage-client.js.map +1 -1
- package/dist/validation.d.ts +3 -3
- package/dist/validation.js +3 -3
- package/dist/validation.js.map +1 -1
- package/package.json +1 -1
package/dist/usage-client.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* usage-client.ts — Per-key quota usage from
|
|
2
|
+
* usage-client.ts — Per-key quota usage from each provider's usage API.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Every provider owns its endpoint path, response parser and identity
|
|
5
|
+
* headers (opencode-go: `/zen/go/v1/usage` behind Cloudflare, which needs the
|
|
6
|
+
* CLI User-Agent; commandcode: `/alpha/billing/credits`, gated on the same
|
|
7
|
+
* CLI identity). `fetchKeyUsage` only adds the bearer credential.
|
|
7
8
|
*
|
|
8
9
|
* Refresh strategy: stale-while-revalidate on demand. `maybeRefreshUsage`
|
|
9
10
|
* is called on the request path; when data is older than USAGE_REFRESH_TTL_MS
|
|
@@ -12,9 +13,9 @@
|
|
|
12
13
|
* with slightly stale percentages).
|
|
13
14
|
*/
|
|
14
15
|
import { logger } from './logger.js';
|
|
15
|
-
import { USAGE_FETCH_TIMEOUT_MS,
|
|
16
|
-
import { updateKeyUsage, setKeyEntitlement } from './proxy-logic.js';
|
|
17
|
-
import { getProvider, inferProvider } from './providers/index.js';
|
|
16
|
+
import { USAGE_FETCH_TIMEOUT_MS, USAGE_REFRESH_TTL_MS } from './constants.js';
|
|
17
|
+
import { updateKeyUsage, setKeyEntitlement, } from './proxy-logic.js';
|
|
18
|
+
import { getProvider, inferProvider, opencodeGoProvider } from './providers/index.js';
|
|
18
19
|
/**
|
|
19
20
|
* 403 bodies that mean "this account has no plan for this provider":
|
|
20
21
|
* opencode-go → `{"error":{"type":"EntitlementError","message":"OpenCode Go
|
|
@@ -25,50 +26,29 @@ import { getProvider, inferProvider } from './providers/index.js';
|
|
|
25
26
|
export function isEntitlementError(status, body) {
|
|
26
27
|
return status === 403 && /subscription|entitlement|upgrade_required/i.test(body);
|
|
27
28
|
}
|
|
28
|
-
function parsePercent(window) {
|
|
29
|
-
const percent = window?.percent;
|
|
30
|
-
if (typeof percent !== 'number' || !Number.isFinite(percent))
|
|
31
|
-
return 0;
|
|
32
|
-
return Math.min(100, Math.max(0, percent));
|
|
33
|
-
}
|
|
34
|
-
/** Parse a usage API response body into KeyUsage (throws on contract violation). */
|
|
35
|
-
export function parseUsageResponse(body) {
|
|
36
|
-
let parsed;
|
|
37
|
-
try {
|
|
38
|
-
parsed = JSON.parse(body);
|
|
39
|
-
}
|
|
40
|
-
catch {
|
|
41
|
-
throw new Error('usage response is not valid JSON');
|
|
42
|
-
}
|
|
43
|
-
const usage = parsed?.usage;
|
|
44
|
-
if (!usage || typeof usage !== 'object') {
|
|
45
|
-
throw new Error('usage response missing "usage" object');
|
|
46
|
-
}
|
|
47
|
-
const rolling = parsePercent(usage.rolling);
|
|
48
|
-
const weekly = parsePercent(usage.weekly);
|
|
49
|
-
const monthly = parsePercent(usage.monthly);
|
|
50
|
-
return {
|
|
51
|
-
rollingPercent: rolling,
|
|
52
|
-
weeklyPercent: weekly,
|
|
53
|
-
monthlyPercent: monthly,
|
|
54
|
-
usedPercent: Math.max(rolling, weekly, monthly),
|
|
55
|
-
rollingResetsAt: typeof usage.rolling?.resetsAt === 'string' ? usage.rolling.resetsAt : undefined,
|
|
56
|
-
weeklyResetsAt: typeof usage.weekly?.resetsAt === 'string' ? usage.weekly.resetsAt : undefined,
|
|
57
|
-
monthlyResetsAt: typeof usage.monthly?.resetsAt === 'string' ? usage.monthly.resetsAt : undefined,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
29
|
/**
|
|
61
|
-
* Fetch current usage for one key
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
30
|
+
* Fetch current usage for one key from its provider's endpoint. The provider
|
|
31
|
+
* supplies the path, the identity headers (CommandCode and opencode-go both
|
|
32
|
+
* reject requests without a CLI User-Agent) and the response parser; this
|
|
33
|
+
* function only adds the bearer credential and the timeout.
|
|
34
|
+
*
|
|
35
|
+
* Failures (network, timeout, non-200, contract violation) yield
|
|
36
|
+
* `usage: null` — callers treat that as "no fresh data". A 403 entitlement
|
|
37
|
+
* rejection is reported separately because it is definitive, not transient.
|
|
65
38
|
*/
|
|
66
|
-
export async function fetchKeyUsage(upstreamBaseUrl, apiKey,
|
|
39
|
+
export async function fetchKeyUsage(upstreamBaseUrl, apiKey, provider = opencodeGoProvider) {
|
|
40
|
+
const usagePath = provider.usagePath();
|
|
41
|
+
if (!usagePath)
|
|
42
|
+
return { usage: null, noEntitlement: false };
|
|
67
43
|
const controller = new AbortController();
|
|
68
44
|
const timer = setTimeout(() => controller.abort(), USAGE_FETCH_TIMEOUT_MS);
|
|
69
45
|
try {
|
|
70
46
|
const response = await fetch(new URL(usagePath, upstreamBaseUrl), {
|
|
71
|
-
headers: {
|
|
47
|
+
headers: {
|
|
48
|
+
...provider.extraUpstreamHeaders?.(),
|
|
49
|
+
Authorization: `Bearer ${apiKey}`,
|
|
50
|
+
Accept: 'application/json',
|
|
51
|
+
},
|
|
72
52
|
signal: controller.signal,
|
|
73
53
|
});
|
|
74
54
|
// Keep the abort armed through the body read: a stalled body after a 200
|
|
@@ -79,7 +59,7 @@ export async function fetchKeyUsage(upstreamBaseUrl, apiKey, usagePath = USAGE_P
|
|
|
79
59
|
return { usage: null, noEntitlement: isEntitlementError(response.status, body) };
|
|
80
60
|
}
|
|
81
61
|
try {
|
|
82
|
-
return { usage: parseUsageResponse(body), noEntitlement: false };
|
|
62
|
+
return { usage: provider.parseUsageResponse(body), noEntitlement: false };
|
|
83
63
|
}
|
|
84
64
|
catch {
|
|
85
65
|
return { usage: null, noEntitlement: false };
|
|
@@ -117,20 +97,23 @@ export function maybeRefreshUsage(state, config) {
|
|
|
117
97
|
try {
|
|
118
98
|
const entries = await Promise.all(state.keys.map(async (k) => {
|
|
119
99
|
const provider = getProvider(inferProvider({ label: k.label, key: k.key, provider: k.provider }));
|
|
120
|
-
// Providers without a
|
|
121
|
-
//
|
|
100
|
+
// Providers without a usage endpoint are skipped — weighted
|
|
101
|
+
// rotation simply treats them as having no fresh data.
|
|
122
102
|
if (!provider || !provider.usagePath())
|
|
123
103
|
return [k.label, null];
|
|
124
104
|
const base = config.upstreams?.[provider.id] ?? (provider.id === 'opencode-go' ? config.upstreamBaseUrl : provider.baseUrl);
|
|
125
|
-
const usage = await fetchKeyUsage(base, k.key, provider
|
|
105
|
+
const usage = await fetchKeyUsage(base, k.key, provider);
|
|
126
106
|
return [k.label, usage];
|
|
127
107
|
}));
|
|
128
|
-
const
|
|
108
|
+
const metrics = new Map();
|
|
129
109
|
for (const [label, result] of entries) {
|
|
130
110
|
if (!result)
|
|
131
111
|
continue;
|
|
132
112
|
if (result.usage) {
|
|
133
|
-
|
|
113
|
+
metrics.set(label, {
|
|
114
|
+
usedPercent: result.usage.usedPercent,
|
|
115
|
+
exhausted: result.usage.exhausted,
|
|
116
|
+
});
|
|
134
117
|
// A key that answers the usage API is entitled again.
|
|
135
118
|
setKeyEntitlement(state, label, true);
|
|
136
119
|
}
|
|
@@ -139,9 +122,9 @@ export function maybeRefreshUsage(state, config) {
|
|
|
139
122
|
}
|
|
140
123
|
// Transient failures leave the previous entitlement untouched.
|
|
141
124
|
}
|
|
142
|
-
if (
|
|
143
|
-
updateKeyUsage(state,
|
|
144
|
-
logger.debug({ keys: [...
|
|
125
|
+
if (metrics.size > 0) {
|
|
126
|
+
updateKeyUsage(state, metrics);
|
|
127
|
+
logger.debug({ keys: [...metrics.keys()] }, 'key usage refreshed');
|
|
145
128
|
}
|
|
146
129
|
}
|
|
147
130
|
catch (err) {
|
package/dist/usage-client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage-client.js","sourceRoot":"","sources":["../src/usage-client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"usage-client.js","sourceRoot":"","sources":["../src/usage-client.ts"],"names":[],"mappings":"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"}
|
package/dist/validation.d.ts
CHANGED
|
@@ -12,9 +12,9 @@ export declare function isValidPort(value: unknown): value is number;
|
|
|
12
12
|
* Check if the given string looks like a valid API key.
|
|
13
13
|
*
|
|
14
14
|
* Multi-provider aware: accepts `oc_sk_` (OpenCode-Go), `sk-` (opencode-go /
|
|
15
|
-
* commandcode console keys) and `user_` (commandcode tokens) of at least
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* commandcode console keys) and `user_` (commandcode tokens) of at least 20
|
|
16
|
+
* characters. Structural check only — provider identity is confirmed by the
|
|
17
|
+
* smoke test in `identifyKey()`.
|
|
18
18
|
*/
|
|
19
19
|
export declare function isValidApiKey(key: unknown): key is string;
|
|
20
20
|
/**
|
package/dist/validation.js
CHANGED
|
@@ -21,9 +21,9 @@ export function isValidPort(value) {
|
|
|
21
21
|
* Check if the given string looks like a valid API key.
|
|
22
22
|
*
|
|
23
23
|
* Multi-provider aware: accepts `oc_sk_` (OpenCode-Go), `sk-` (opencode-go /
|
|
24
|
-
* commandcode console keys) and `user_` (commandcode tokens) of at least
|
|
25
|
-
*
|
|
26
|
-
*
|
|
24
|
+
* commandcode console keys) and `user_` (commandcode tokens) of at least 20
|
|
25
|
+
* characters. Structural check only — provider identity is confirmed by the
|
|
26
|
+
* smoke test in `identifyKey()`.
|
|
27
27
|
*/
|
|
28
28
|
export function isValidApiKey(key) {
|
|
29
29
|
return typeof key === 'string' && isPlausibleKey(key);
|
package/dist/validation.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,OAAO,KAAK,CAAC;QACzC,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,KAAK,CAAC;AAC9F,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,GAAY;IACxC,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC1C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,GAAG;IAChE,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IACzC,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACvC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC;AAC9B,CAAC"}
|