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
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* source.ts — Where the passphrase that unlocks `enc:v1:` envelopes comes from.
|
|
3
|
+
*
|
|
4
|
+
* Resolution order (first match wins):
|
|
5
|
+
* 1. `SAROS_PASSPHRASE` in the environment — systemd / container friendly.
|
|
6
|
+
* 2. The OS secret store, always through the platform's own CLI:
|
|
7
|
+
* Linux secret-tool lookup service saros-proxy account <user>
|
|
8
|
+
* macOS security find-generic-password -s saros-proxy -a <user> -w
|
|
9
|
+
* Windows PowerShell DPAPI, blob in %APPDATA%\saros\secret.dpapi
|
|
10
|
+
* 3. A TTY prompt — only foreground `serve` asks; never a daemon child.
|
|
11
|
+
*
|
|
12
|
+
* Every source returns `{ value } | { reason }`. Reasons never contain the
|
|
13
|
+
* secret, so they are safe for `secret status`, logs and error messages.
|
|
14
|
+
*/
|
|
15
|
+
import { spawnSync } from 'node:child_process';
|
|
16
|
+
import { existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
17
|
+
import { homedir } from 'node:os';
|
|
18
|
+
import { dirname, join } from 'node:path';
|
|
19
|
+
import { createInterface } from 'node:readline';
|
|
20
|
+
import { Writable } from 'node:stream';
|
|
21
|
+
export const SERVICE_NAME = 'saros-proxy';
|
|
22
|
+
export const ENV_PASSPHRASE = 'SAROS_PASSPHRASE';
|
|
23
|
+
export const NO_SOURCE_MESSAGE = [
|
|
24
|
+
'Encrypted API keys found, but no passphrase source is available.',
|
|
25
|
+
' a. Set SAROS_PASSPHRASE in the environment (systemd: use systemd-creds).',
|
|
26
|
+
' b. Store the passphrase in the OS secret store: saros-proxy secret set',
|
|
27
|
+
' c. Run `saros-proxy serve` in a terminal to be prompted.',
|
|
28
|
+
].join('\n');
|
|
29
|
+
/**
|
|
30
|
+
* Raised when encrypted keys cannot be unlocked. The message is safe to log:
|
|
31
|
+
* it names sources and options, never a passphrase, plaintext or ciphertext.
|
|
32
|
+
*/
|
|
33
|
+
export class SecretSourceError extends Error {
|
|
34
|
+
constructor(message) {
|
|
35
|
+
super(message);
|
|
36
|
+
this.name = 'SecretSourceError';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function decryptFailureMessage(label, detail) {
|
|
40
|
+
return (`Cannot decrypt API key "${label}": ${detail}. ` +
|
|
41
|
+
'Check SAROS_PASSPHRASE or run `saros-proxy secret status`.');
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Run a platform CLI without a shell. Failures carry only a generic reason
|
|
45
|
+
* plus exit status and (bounded) stderr for the store classifier — callers
|
|
46
|
+
* never print stderr, and stdout is dropped.
|
|
47
|
+
*/
|
|
48
|
+
export function runCommand(command, args, options = {}) {
|
|
49
|
+
const result = spawnSync(command, args, {
|
|
50
|
+
encoding: 'utf8',
|
|
51
|
+
input: options.input,
|
|
52
|
+
env: options.env ? { ...process.env, ...options.env } : process.env,
|
|
53
|
+
timeout: 15_000,
|
|
54
|
+
windowsHide: true,
|
|
55
|
+
maxBuffer: 1024 * 1024,
|
|
56
|
+
});
|
|
57
|
+
if (result.error) {
|
|
58
|
+
const code = result.error.code;
|
|
59
|
+
return { ok: false, stdout: '', reason: code === 'ENOENT' ? `${command} is not installed` : `${command} could not be run` };
|
|
60
|
+
}
|
|
61
|
+
if (result.status !== 0) {
|
|
62
|
+
const detail = result.status === null ? 'was terminated' : `exited with code ${result.status}`;
|
|
63
|
+
return {
|
|
64
|
+
ok: false,
|
|
65
|
+
stdout: '',
|
|
66
|
+
reason: `${command} ${detail}`,
|
|
67
|
+
status: result.status,
|
|
68
|
+
// Diagnostics for the store classifier only; never printed verbatim.
|
|
69
|
+
stderr: (result.stderr || '').slice(0, 4096),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return { ok: true, stdout: result.stdout || '' };
|
|
73
|
+
}
|
|
74
|
+
/** Strip the trailing newline a CLI adds; keep spaces inside the secret. */
|
|
75
|
+
function firstLine(stdout) {
|
|
76
|
+
const line = stdout.split('\n')[0];
|
|
77
|
+
return line.replace(/\r$/, '');
|
|
78
|
+
}
|
|
79
|
+
/** `secret-tool`/`security` say "no match" through exit code and stderr. */
|
|
80
|
+
const STORE_NOT_FOUND = /not found|no such|does not exist|item could not be found|errSecItemNotFound/i;
|
|
81
|
+
const STORE_UNAVAILABLE = /(?:d-?bus|autolaunch|secret service|keyring|locked|denied|permission|not authorized|timed out)/i;
|
|
82
|
+
function lookupFailureReason(result, command) {
|
|
83
|
+
// Injected runners (tests/embedders) only provide a ready-made reason.
|
|
84
|
+
if (result.status === undefined)
|
|
85
|
+
return result.reason;
|
|
86
|
+
const stderr = result.stderr ?? '';
|
|
87
|
+
if (STORE_NOT_FOUND.test(stderr) ||
|
|
88
|
+
result.status === 44 ||
|
|
89
|
+
(result.status === 1 && stderr.trim().length === 0)) {
|
|
90
|
+
return `${command}: no entry for service ${SERVICE_NAME} (not found)`;
|
|
91
|
+
}
|
|
92
|
+
if (STORE_UNAVAILABLE.test(stderr)) {
|
|
93
|
+
return `${command}: OS secret store unavailable (keyring locked or error)`;
|
|
94
|
+
}
|
|
95
|
+
return result.reason;
|
|
96
|
+
}
|
|
97
|
+
function interpret(result, command, lookup = false) {
|
|
98
|
+
if (!result.ok) {
|
|
99
|
+
return { ok: false, reason: lookup ? lookupFailureReason(result, command) : result.reason };
|
|
100
|
+
}
|
|
101
|
+
const value = firstLine(result.stdout);
|
|
102
|
+
return value.length > 0
|
|
103
|
+
? { ok: true, value }
|
|
104
|
+
: { ok: false, reason: `${command} returned an empty secret` };
|
|
105
|
+
}
|
|
106
|
+
export function readEnvPassphrase(env = process.env) {
|
|
107
|
+
const value = env[ENV_PASSPHRASE];
|
|
108
|
+
return typeof value === 'string' && value.length > 0
|
|
109
|
+
? { ok: true, value }
|
|
110
|
+
: { ok: false, reason: `${ENV_PASSPHRASE} is not set` };
|
|
111
|
+
}
|
|
112
|
+
function currentUsername() {
|
|
113
|
+
return process.env.USER || process.env.USERNAME || 'user';
|
|
114
|
+
}
|
|
115
|
+
export function defaultDpapiPath(env = process.env) {
|
|
116
|
+
const appData = env.APPDATA || join(homedir(), 'AppData', 'Roaming');
|
|
117
|
+
return join(appData, 'saros', 'secret.dpapi');
|
|
118
|
+
}
|
|
119
|
+
const DPAPI_BLOB = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
120
|
+
function readDpapi(passphrasePath, run) {
|
|
121
|
+
if (!existsSync(passphrasePath)) {
|
|
122
|
+
return { ok: false, reason: `DPAPI blob not found at ${passphrasePath}` };
|
|
123
|
+
}
|
|
124
|
+
let blob;
|
|
125
|
+
try {
|
|
126
|
+
blob = readFileSync(passphrasePath, 'utf8').trim();
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return { ok: false, reason: `DPAPI blob at ${passphrasePath} could not be read` };
|
|
130
|
+
}
|
|
131
|
+
if (blob.length === 0) {
|
|
132
|
+
return { ok: false, reason: `DPAPI blob at ${passphrasePath} is empty` };
|
|
133
|
+
}
|
|
134
|
+
// Fail closed before PowerShell sees anything: a quote in the blob used to
|
|
135
|
+
// break out of the single-quoted string and run arbitrary commands.
|
|
136
|
+
if (!DPAPI_BLOB.test(blob) || blob.length % 4 !== 0) {
|
|
137
|
+
return { ok: false, reason: `DPAPI blob at ${passphrasePath} is not valid base64` };
|
|
138
|
+
}
|
|
139
|
+
// The blob travels in the child environment, never interpolated into the
|
|
140
|
+
// script, so no base64 character can become PowerShell syntax.
|
|
141
|
+
const script = "$ErrorActionPreference='Stop';" +
|
|
142
|
+
'Add-Type -AssemblyName System.Security;' +
|
|
143
|
+
'$b=[Convert]::FromBase64String($env:SAROS_DPAPI_BLOB);' +
|
|
144
|
+
"[System.Text.Encoding]::UTF8.GetString([System.Security.Cryptography.ProtectedData]::Unprotect($b, $null, 'CurrentUser'))";
|
|
145
|
+
return interpret(run('powershell', ['-NoProfile', '-NonInteractive', '-Command', script], {
|
|
146
|
+
env: { SAROS_DPAPI_BLOB: blob },
|
|
147
|
+
}), 'powershell');
|
|
148
|
+
}
|
|
149
|
+
/** Read the passphrase from the OS store. Never prompts. */
|
|
150
|
+
export function readStorePassphrase(options = {}) {
|
|
151
|
+
const platform = options.platform ?? process.platform;
|
|
152
|
+
const run = options.run ?? runCommand;
|
|
153
|
+
const username = options.username ?? currentUsername();
|
|
154
|
+
if (platform === 'linux') {
|
|
155
|
+
return interpret(run('secret-tool', ['lookup', 'service', SERVICE_NAME, 'account', username]), 'secret-tool', true);
|
|
156
|
+
}
|
|
157
|
+
if (platform === 'darwin') {
|
|
158
|
+
return interpret(run('security', ['find-generic-password', '-s', SERVICE_NAME, '-a', username, '-w']), 'security', true);
|
|
159
|
+
}
|
|
160
|
+
if (platform === 'win32') {
|
|
161
|
+
const path = options.dpapiPath ?? defaultDpapiPath(options.env);
|
|
162
|
+
return readDpapi(path, run);
|
|
163
|
+
}
|
|
164
|
+
return { ok: false, reason: `the OS secret store is not supported on ${platform}` };
|
|
165
|
+
}
|
|
166
|
+
export function isInteractive(input = process.stdin) {
|
|
167
|
+
return input.isTTY === true;
|
|
168
|
+
}
|
|
169
|
+
/** Read one line from stdin when it is piped (`secret set` in scripts). */
|
|
170
|
+
export async function readStdinLine(input) {
|
|
171
|
+
let buffer = '';
|
|
172
|
+
for await (const chunk of input) {
|
|
173
|
+
buffer += String(chunk);
|
|
174
|
+
const newline = buffer.indexOf('\n');
|
|
175
|
+
if (newline !== -1)
|
|
176
|
+
return buffer.slice(0, newline).replace(/\r$/, '');
|
|
177
|
+
}
|
|
178
|
+
return buffer.length > 0 ? buffer : null;
|
|
179
|
+
}
|
|
180
|
+
/** Hidden TTY prompt. Resolves null when there is no TTY or no input. */
|
|
181
|
+
export function promptHidden(options = {}) {
|
|
182
|
+
const input = options.input ?? process.stdin;
|
|
183
|
+
const output = options.output ?? process.stderr;
|
|
184
|
+
if (!isInteractive(input))
|
|
185
|
+
return Promise.resolve(null);
|
|
186
|
+
const promise = new Promise((resolve) => {
|
|
187
|
+
let settled = false;
|
|
188
|
+
const finish = (value) => {
|
|
189
|
+
if (settled)
|
|
190
|
+
return;
|
|
191
|
+
settled = true;
|
|
192
|
+
resolve(value);
|
|
193
|
+
};
|
|
194
|
+
// A sink as readline's output discards the echoed characters; the question
|
|
195
|
+
// itself is written to the real stderr.
|
|
196
|
+
const sink = new Writable({
|
|
197
|
+
write(_chunk, _encoding, callback) {
|
|
198
|
+
callback();
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
const rl = createInterface({ input, output: sink, terminal: true });
|
|
202
|
+
output.write(options.question ?? 'Passphrase: ');
|
|
203
|
+
rl.once('line', (line) => {
|
|
204
|
+
finish(line.length > 0 ? line : null);
|
|
205
|
+
output.write('\n');
|
|
206
|
+
rl.close();
|
|
207
|
+
});
|
|
208
|
+
rl.once('close', () => finish(null));
|
|
209
|
+
});
|
|
210
|
+
return promise;
|
|
211
|
+
}
|
|
212
|
+
export async function readTtyPassphrase(options = {}) {
|
|
213
|
+
if (!isInteractive(options.input ?? process.stdin)) {
|
|
214
|
+
return { ok: false, reason: 'stdin is not a TTY' };
|
|
215
|
+
}
|
|
216
|
+
const value = await promptHidden(options);
|
|
217
|
+
return value === null
|
|
218
|
+
? { ok: false, reason: 'no passphrase entered' }
|
|
219
|
+
: { ok: true, value };
|
|
220
|
+
}
|
|
221
|
+
function attempt(source, result) {
|
|
222
|
+
return result.ok ? { source, ok: true } : { source, ok: false, reason: result.reason };
|
|
223
|
+
}
|
|
224
|
+
/** One line per failed source; safe for errors, never includes a value. */
|
|
225
|
+
export function formatAttempts(attempts) {
|
|
226
|
+
return attempts
|
|
227
|
+
.filter((entry) => !entry.ok)
|
|
228
|
+
.map((entry) => ` ${entry.source}: ${entry.reason}`)
|
|
229
|
+
.join('\n');
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Resolve the passphrase in precedence order. The TTY source runs only when
|
|
233
|
+
* `allowTty` is true (foreground serve), never for the daemon child.
|
|
234
|
+
*/
|
|
235
|
+
export async function resolvePassphrase(options = {}) {
|
|
236
|
+
const attempts = [];
|
|
237
|
+
const envResult = readEnvPassphrase(options.env);
|
|
238
|
+
attempts.push(attempt('env', envResult));
|
|
239
|
+
if (envResult.ok) {
|
|
240
|
+
return { ok: true, value: envResult.value, source: 'env', attempts };
|
|
241
|
+
}
|
|
242
|
+
const storeResult = readStorePassphrase(options);
|
|
243
|
+
attempts.push(attempt('store', storeResult));
|
|
244
|
+
if (storeResult.ok) {
|
|
245
|
+
return { ok: true, value: storeResult.value, source: 'store', attempts };
|
|
246
|
+
}
|
|
247
|
+
if (options.allowTty !== true) {
|
|
248
|
+
attempts.push({
|
|
249
|
+
source: 'tty',
|
|
250
|
+
ok: false,
|
|
251
|
+
reason: 'interactive prompt is disabled in this context',
|
|
252
|
+
});
|
|
253
|
+
return { ok: false, attempts };
|
|
254
|
+
}
|
|
255
|
+
const ttyResult = await readTtyPassphrase(options);
|
|
256
|
+
attempts.push(attempt('tty', ttyResult));
|
|
257
|
+
return ttyResult.ok
|
|
258
|
+
? { ok: true, value: ttyResult.value, source: 'tty', attempts }
|
|
259
|
+
: { ok: false, attempts };
|
|
260
|
+
}
|
|
261
|
+
export function storeBackend(platform = process.platform) {
|
|
262
|
+
if (platform === 'linux')
|
|
263
|
+
return 'secret-tool (libsecret)';
|
|
264
|
+
if (platform === 'darwin')
|
|
265
|
+
return 'macOS Keychain (security)';
|
|
266
|
+
if (platform === 'win32')
|
|
267
|
+
return 'Windows DPAPI (CurrentUser)';
|
|
268
|
+
return `unsupported platform (${platform})`;
|
|
269
|
+
}
|
|
270
|
+
/** Read-only snapshot for `saros-proxy secret status`; never returns a value. */
|
|
271
|
+
export function getSecretStatus(options = {}) {
|
|
272
|
+
const env = readEnvPassphrase(options.env);
|
|
273
|
+
const store = readStorePassphrase(options);
|
|
274
|
+
const tty = isInteractive(options.input ?? process.stdin);
|
|
275
|
+
return {
|
|
276
|
+
env: env.ok,
|
|
277
|
+
store: {
|
|
278
|
+
backend: storeBackend(options.platform ?? process.platform),
|
|
279
|
+
populated: store.ok,
|
|
280
|
+
reason: store.ok ? '' : store.reason,
|
|
281
|
+
},
|
|
282
|
+
tty,
|
|
283
|
+
effective: env.ok ? 'env' : store.ok ? 'store' : tty ? 'tty' : null,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
/** Store a passphrase through the platform CLI (used by `secret set`). */
|
|
287
|
+
export function storePassphrase(passphrase, options = {}) {
|
|
288
|
+
const platform = options.platform ?? process.platform;
|
|
289
|
+
const backend = storeBackend(platform);
|
|
290
|
+
if (passphrase.length === 0) {
|
|
291
|
+
return { ok: false, backend, reason: 'passphrase must not be empty' };
|
|
292
|
+
}
|
|
293
|
+
const run = options.run ?? runCommand;
|
|
294
|
+
const username = options.username ?? currentUsername();
|
|
295
|
+
if (platform === 'linux') {
|
|
296
|
+
const result = run('secret-tool', ['store', '--label=saros-proxy passphrase', 'service', SERVICE_NAME, 'account', username], { input: passphrase });
|
|
297
|
+
return result.ok ? { ok: true, backend } : { ok: false, backend, reason: result.reason };
|
|
298
|
+
}
|
|
299
|
+
if (platform === 'darwin') {
|
|
300
|
+
const result = run('security', [
|
|
301
|
+
'add-generic-password',
|
|
302
|
+
'-U',
|
|
303
|
+
'-s',
|
|
304
|
+
SERVICE_NAME,
|
|
305
|
+
'-a',
|
|
306
|
+
username,
|
|
307
|
+
'-w',
|
|
308
|
+
passphrase,
|
|
309
|
+
]);
|
|
310
|
+
return result.ok ? { ok: true, backend } : { ok: false, backend, reason: result.reason };
|
|
311
|
+
}
|
|
312
|
+
if (platform === 'win32') {
|
|
313
|
+
const path = options.dpapiPath ?? defaultDpapiPath(options.env);
|
|
314
|
+
try {
|
|
315
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
return { ok: false, backend, reason: `could not create ${dirname(path)}` };
|
|
319
|
+
}
|
|
320
|
+
const script = "$ErrorActionPreference='Stop';" +
|
|
321
|
+
'Add-Type -AssemblyName System.Security;' +
|
|
322
|
+
'$b=[System.Text.Encoding]::UTF8.GetBytes($env:SAROS_SECRET_VALUE);' +
|
|
323
|
+
"$p=[System.Security.Cryptography.ProtectedData]::Protect($b,$null,'CurrentUser');" +
|
|
324
|
+
'[System.IO.File]::WriteAllText($env:SAROS_SECRET_BLOB,[Convert]::ToBase64String($p))';
|
|
325
|
+
const result = run('powershell', ['-NoProfile', '-NonInteractive', '-Command', script], {
|
|
326
|
+
env: { SAROS_SECRET_VALUE: passphrase, SAROS_SECRET_BLOB: path },
|
|
327
|
+
});
|
|
328
|
+
return result.ok ? { ok: true, backend } : { ok: false, backend, reason: result.reason };
|
|
329
|
+
}
|
|
330
|
+
return { ok: false, backend, reason: `the OS secret store is not supported on ${platform}` };
|
|
331
|
+
}
|
|
332
|
+
//# sourceMappingURL=source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source.js","sourceRoot":"","sources":["../../src/secrets/source.ts"],"names":[],"mappings":"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"}
|
package/dist/token-usage.d.ts
CHANGED
|
@@ -49,5 +49,12 @@ export declare function getKeyTokenUsage(): {
|
|
|
49
49
|
since: number;
|
|
50
50
|
keys: Record<string, KeyTokenUsage>;
|
|
51
51
|
};
|
|
52
|
-
/**
|
|
53
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Test seam: drop in-memory state and any pending debounced write. By default
|
|
54
|
+
* the persisted file is removed too, so counters cannot leak between tests
|
|
55
|
+
* that share a config dir; `keepFile` simulates a process restart that
|
|
56
|
+
* reloads existing history.
|
|
57
|
+
*/
|
|
58
|
+
export declare function resetTokenUsage(options?: {
|
|
59
|
+
keepFile?: boolean;
|
|
60
|
+
}): void;
|
package/dist/token-usage.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* Storage mirrors model-stats.ts: a tiny JSON file in the saros config dir,
|
|
12
12
|
* written behind a debounce so the request path never blocks on I/O.
|
|
13
13
|
*/
|
|
14
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync, renameSync } from 'node:fs';
|
|
14
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, renameSync, rmSync } from 'node:fs';
|
|
15
15
|
import { dirname } from 'node:path';
|
|
16
16
|
import { TOKEN_USAGE_SAVE_DEBOUNCE_MS } from './constants.js';
|
|
17
17
|
import { getSarosDir } from './config.js';
|
|
@@ -60,7 +60,10 @@ export function parseTokenCounts(usage) {
|
|
|
60
60
|
return {
|
|
61
61
|
promptTokens,
|
|
62
62
|
completionTokens,
|
|
63
|
-
|
|
63
|
+
// A stream merges counts per field, so a chunk can contribute a stale
|
|
64
|
+
// total while a later chunk raises prompt/completion. Never report a
|
|
65
|
+
// total below the parts the upstream itself reported.
|
|
66
|
+
totalTokens: Math.max(total, promptTokens + completionTokens),
|
|
64
67
|
};
|
|
65
68
|
}
|
|
66
69
|
function load() {
|
|
@@ -188,8 +191,13 @@ export function getKeyTokenUsage() {
|
|
|
188
191
|
load();
|
|
189
192
|
return { since, keys: Object.fromEntries(counters) };
|
|
190
193
|
}
|
|
191
|
-
/**
|
|
192
|
-
|
|
194
|
+
/**
|
|
195
|
+
* Test seam: drop in-memory state and any pending debounced write. By default
|
|
196
|
+
* the persisted file is removed too, so counters cannot leak between tests
|
|
197
|
+
* that share a config dir; `keepFile` simulates a process restart that
|
|
198
|
+
* reloads existing history.
|
|
199
|
+
*/
|
|
200
|
+
export function resetTokenUsage(options = {}) {
|
|
193
201
|
if (saveTimer !== undefined) {
|
|
194
202
|
clearTimeout(saveTimer);
|
|
195
203
|
saveTimer = undefined;
|
|
@@ -197,5 +205,13 @@ export function resetTokenUsage() {
|
|
|
197
205
|
counters.clear();
|
|
198
206
|
since = 0;
|
|
199
207
|
loaded = false;
|
|
208
|
+
if (options.keepFile)
|
|
209
|
+
return;
|
|
210
|
+
try {
|
|
211
|
+
rmSync(getTokenUsagePath(), { force: true });
|
|
212
|
+
}
|
|
213
|
+
catch (err) {
|
|
214
|
+
logger.debug({ err }, 'failed to remove token usage file');
|
|
215
|
+
}
|
|
200
216
|
}
|
|
201
217
|
//# sourceMappingURL=token-usage.js.map
|
package/dist/token-usage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-usage.js","sourceRoot":"","sources":["../src/token-usage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"token-usage.js","sourceRoot":"","sources":["../src/token-usage.ts"],"names":[],"mappings":"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"}
|
package/dist/usage-client.d.ts
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
|
|
@@ -13,9 +14,36 @@
|
|
|
13
14
|
*/
|
|
14
15
|
import { type ProxyState } from './proxy-logic.js';
|
|
15
16
|
import type { ProxyConfig } from './config.js';
|
|
17
|
+
import type { KeyProvider } from './providers/index.js';
|
|
18
|
+
/**
|
|
19
|
+
* Per-key quota usage, normalized as a percentage *of the provider's own
|
|
20
|
+
* budget* — never absolute capacity. `usedPercent` is the **monthly** window:
|
|
21
|
+
* 0 = untouched, 100 = monthly allowance spent. `exhausted` is true when any
|
|
22
|
+
* window (5h, weekly or monthly) reached 100%, which takes the key out of
|
|
23
|
+
* rotation regardless of how much of the month remains — otherwise a key with
|
|
24
|
+
* 50% monthly and a spent weekly window would keep receiving traffic and
|
|
25
|
+
* failing upstream.
|
|
26
|
+
*
|
|
27
|
+
* This normalization is the contract mixed-provider pools rely on:
|
|
28
|
+
* `pickWeighted` (`proxy-logic.ts`) compares the numbers from every provider
|
|
29
|
+
* directly, so "30%" must always mean "30% of that provider's monthly budget".
|
|
30
|
+
* Percent is the most saros can honestly compare — opencode-go's
|
|
31
|
+
* `/zen/go/v1/usage` publishes only percentages
|
|
32
|
+
* (`{"usage":{"rolling":{"percent":1},"weekly":{"percent":15},
|
|
33
|
+
* "monthly":{"percent":19}}}`), with no token counts or absolute caps, while
|
|
34
|
+
* CommandCode publishes `used`/`cap` per window plus the remaining monthly
|
|
35
|
+
* credits, and its parser converts them to the same percent scale.
|
|
36
|
+
*/
|
|
16
37
|
export interface KeyUsage {
|
|
17
|
-
/**
|
|
18
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Monthly used percent, 0-100, of this provider's own budget; null when the
|
|
40
|
+
* payload has no derivable monthly metric (the previous value must survive).
|
|
41
|
+
*/
|
|
42
|
+
usedPercent: number | null;
|
|
43
|
+
/** True when any window is at 100% — rotation weighs the key 0. */
|
|
44
|
+
exhausted: boolean;
|
|
45
|
+
/** False when the payload carries no monthly percentage (CLI shows n/a). */
|
|
46
|
+
monthlyAvailable: boolean;
|
|
19
47
|
rollingPercent: number;
|
|
20
48
|
weeklyPercent: number;
|
|
21
49
|
monthlyPercent: number;
|
|
@@ -43,15 +71,17 @@ export interface UsageFetchResult {
|
|
|
43
71
|
* problem, not an account one, and must not match.
|
|
44
72
|
*/
|
|
45
73
|
export declare function isEntitlementError(status: number, body: string): boolean;
|
|
46
|
-
/** Parse a usage API response body into KeyUsage (throws on contract violation). */
|
|
47
|
-
export declare function parseUsageResponse(body: string): KeyUsage;
|
|
48
74
|
/**
|
|
49
|
-
* Fetch current usage for one key
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
75
|
+
* Fetch current usage for one key from its provider's endpoint. The provider
|
|
76
|
+
* supplies the path, the identity headers (CommandCode and opencode-go both
|
|
77
|
+
* reject requests without a CLI User-Agent) and the response parser; this
|
|
78
|
+
* function only adds the bearer credential and the timeout.
|
|
79
|
+
*
|
|
80
|
+
* Failures (network, timeout, non-200, contract violation) yield
|
|
81
|
+
* `usage: null` — callers treat that as "no fresh data". A 403 entitlement
|
|
82
|
+
* rejection is reported separately because it is definitive, not transient.
|
|
53
83
|
*/
|
|
54
|
-
export declare function fetchKeyUsage(upstreamBaseUrl: string, apiKey: string,
|
|
84
|
+
export declare function fetchKeyUsage(upstreamBaseUrl: string, apiKey: string, provider?: KeyProvider): Promise<UsageFetchResult>;
|
|
55
85
|
/** Test seam: reset coordinator state. */
|
|
56
86
|
export declare function resetUsageRefreshState(): void;
|
|
57
87
|
/**
|