agent-shim 11.75.0 → 11.76.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 +1 -1
- package/dist/cli.cjs +2148 -2084
- package/dist/index.cjs +73 -31
- package/dist/index.mjs +73 -31
- package/dist/types/index.d.ts +10 -0
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -28490,6 +28490,8 @@ var init_schema = __esm({
|
|
|
28490
28490
|
$schema: external_exports.string().optional(),
|
|
28491
28491
|
name: FileNameSchema,
|
|
28492
28492
|
defaultConfigProfile: StoredNameSchema.optional(),
|
|
28493
|
+
/** The provider this identity exists for: a launch on the identity routes through it unless `--provider`, `--no-provider` or a cascade layer's `launch.provider` says otherwise. Its sessions run on the provider's credential, so the identity needs no stored login. */
|
|
28494
|
+
provider: StoredNameSchema.optional(),
|
|
28493
28495
|
allowAmbientCredential: external_exports.boolean().default(false),
|
|
28494
28496
|
credential: CredentialSchema.optional(),
|
|
28495
28497
|
/** When this identity's five-hour window should be open: the front door opens one at each anchor if none is. Absent, nothing is opened on a schedule. */
|
|
@@ -37381,1099 +37383,744 @@ var init_proxyBypass2 = __esm({
|
|
|
37381
37383
|
}
|
|
37382
37384
|
});
|
|
37383
37385
|
|
|
37384
|
-
// src/
|
|
37385
|
-
function
|
|
37386
|
-
|
|
37386
|
+
// src/providerAliases.ts
|
|
37387
|
+
function parseAliases(file2, raw) {
|
|
37388
|
+
const parsed = ProviderAliasesSchema.safeParse(raw);
|
|
37389
|
+
if (!parsed.success) {
|
|
37390
|
+
throw new ConfigValidationError(file2, parsed.error.issues);
|
|
37391
|
+
}
|
|
37392
|
+
return parsed.data;
|
|
37387
37393
|
}
|
|
37388
|
-
function
|
|
37389
|
-
return
|
|
37394
|
+
function readProviderAliases(paths) {
|
|
37395
|
+
return readJson(paths.providerAliasesFile, ProviderAliasesSchema) ?? {};
|
|
37390
37396
|
}
|
|
37391
|
-
function
|
|
37392
|
-
|
|
37397
|
+
function loadProviderAliases(file2, port) {
|
|
37398
|
+
const raw = port.readConfigFile(file2);
|
|
37399
|
+
return raw === void 0 ? {} : parseAliases(file2, raw);
|
|
37393
37400
|
}
|
|
37394
|
-
function
|
|
37395
|
-
if (
|
|
37396
|
-
|
|
37401
|
+
function writeProviderAliases(paths, aliases) {
|
|
37402
|
+
if (Object.keys(aliases).length === 0) {
|
|
37403
|
+
import_node_fs9.default.rmSync(paths.providerAliasesFile, { force: true });
|
|
37404
|
+
return;
|
|
37397
37405
|
}
|
|
37398
|
-
|
|
37406
|
+
writeJsonAtomic(paths.providerAliasesFile, aliases);
|
|
37399
37407
|
}
|
|
37400
|
-
function
|
|
37401
|
-
|
|
37402
|
-
|
|
37403
|
-
return void 0;
|
|
37404
|
-
}
|
|
37405
|
-
let parsed;
|
|
37406
|
-
try {
|
|
37407
|
-
parsed = JSON.parse(raw);
|
|
37408
|
-
} catch {
|
|
37409
|
-
throw new AccountMetadataError(file2, "not valid JSON");
|
|
37410
|
-
}
|
|
37411
|
-
if (!isObject2(parsed)) {
|
|
37412
|
-
throw new AccountMetadataError(file2, "not a JSON object");
|
|
37413
|
-
}
|
|
37414
|
-
const oauthAccount = parsed.oauthAccount;
|
|
37415
|
-
if (!isObject2(oauthAccount)) {
|
|
37416
|
-
return void 0;
|
|
37408
|
+
function canonicalProviderName(name, defined, aliases) {
|
|
37409
|
+
if (defined(name)) {
|
|
37410
|
+
return name;
|
|
37417
37411
|
}
|
|
37418
|
-
|
|
37419
|
-
|
|
37420
|
-
|
|
37421
|
-
|
|
37422
|
-
|
|
37412
|
+
return aliases()[name] ?? name;
|
|
37413
|
+
}
|
|
37414
|
+
function aliasesAfterRename(aliases, from, to2) {
|
|
37415
|
+
const next = {};
|
|
37416
|
+
for (const [alias, target] of Object.entries(aliases)) {
|
|
37417
|
+
if (alias !== to2) {
|
|
37418
|
+
next[alias] = target === from ? to2 : target;
|
|
37423
37419
|
}
|
|
37424
37420
|
}
|
|
37425
|
-
|
|
37426
|
-
|
|
37427
|
-
|
|
37421
|
+
next[from] = to2;
|
|
37422
|
+
return next;
|
|
37423
|
+
}
|
|
37424
|
+
function aliasesOf(aliases, name) {
|
|
37425
|
+
return Object.entries(aliases).filter(([, target]) => target === name).map(([alias]) => alias).sort();
|
|
37426
|
+
}
|
|
37427
|
+
function removeProviderAlias(paths, alias) {
|
|
37428
|
+
const aliases = readProviderAliases(paths);
|
|
37429
|
+
if (!(alias in aliases)) {
|
|
37430
|
+
throw new ProviderAliasNotFoundError(alias);
|
|
37428
37431
|
}
|
|
37429
|
-
|
|
37432
|
+
writeProviderAliases(paths, Object.fromEntries(Object.entries(aliases).filter(([name]) => name !== alias)));
|
|
37430
37433
|
}
|
|
37431
|
-
function
|
|
37432
|
-
|
|
37433
|
-
|
|
37434
|
-
|
|
37435
|
-
throw new Error(`"${identity}" is not a valid identity name.`);
|
|
37434
|
+
function aliasFindings(aliases, providerNames) {
|
|
37435
|
+
return Object.entries(aliases).map(([alias, target]) => {
|
|
37436
|
+
if (!providerNames.has(target)) {
|
|
37437
|
+
return { level: "fail", alias, message: `${alias} is recorded as a former name of ${target}, which is not a provider. Run \`agent-shim provider unalias ${alias}\`.` };
|
|
37436
37438
|
}
|
|
37437
|
-
|
|
37438
|
-
|
|
37439
|
-
const cached2 = cache.get(identity);
|
|
37440
|
-
if (cached2?.stamp === stamp) {
|
|
37441
|
-
return cached2.account;
|
|
37439
|
+
if (providerNames.has(alias)) {
|
|
37440
|
+
return { level: "warn", alias, message: `${alias} is both a provider and a recorded former name of ${target}; the provider wins. Run \`agent-shim provider unalias ${alias}\`.` };
|
|
37442
37441
|
}
|
|
37443
|
-
|
|
37444
|
-
|
|
37445
|
-
|
|
37442
|
+
return { level: "pass", alias, message: `${alias} is a former name of ${target}, still honoured for sessions launched under it. Run \`agent-shim provider unalias ${alias}\` once none is running.` };
|
|
37443
|
+
});
|
|
37444
|
+
}
|
|
37445
|
+
function createProviderCanonicaliser(params) {
|
|
37446
|
+
const reported = /* @__PURE__ */ new Set();
|
|
37447
|
+
return (name) => {
|
|
37448
|
+
const current = canonicalProviderName(name, params.defined, () => {
|
|
37449
|
+
try {
|
|
37450
|
+
return params.aliases();
|
|
37451
|
+
} catch (error63) {
|
|
37452
|
+
params.log(`provider aliases ignored, the aliases file is unreadable: ${error63 instanceof Error ? error63.message : String(error63)}`);
|
|
37453
|
+
return {};
|
|
37454
|
+
}
|
|
37455
|
+
});
|
|
37456
|
+
if (current !== name && !reported.has(name)) {
|
|
37457
|
+
reported.add(name);
|
|
37458
|
+
params.log(`provider ${name} is a former name of ${current}; a session launched under it is still running`);
|
|
37459
|
+
}
|
|
37460
|
+
return current;
|
|
37446
37461
|
};
|
|
37447
37462
|
}
|
|
37448
|
-
var
|
|
37449
|
-
var
|
|
37450
|
-
"src/
|
|
37463
|
+
var import_node_fs9, ProviderAliasesSchema, ProviderAliasNotFoundError;
|
|
37464
|
+
var init_providerAliases = __esm({
|
|
37465
|
+
"src/providerAliases.ts"() {
|
|
37451
37466
|
"use strict";
|
|
37452
|
-
|
|
37467
|
+
import_node_fs9 = __toESM(require("node:fs"), 1);
|
|
37468
|
+
init_zod();
|
|
37453
37469
|
init_cliError();
|
|
37454
|
-
|
|
37455
|
-
|
|
37456
|
-
|
|
37457
|
-
|
|
37458
|
-
constructor(
|
|
37459
|
-
super(
|
|
37460
|
-
this.
|
|
37461
|
-
this.name = "
|
|
37470
|
+
init_load();
|
|
37471
|
+
init_store();
|
|
37472
|
+
ProviderAliasesSchema = external_exports.record(external_exports.string().min(1), external_exports.string().min(1));
|
|
37473
|
+
ProviderAliasNotFoundError = class extends CliError {
|
|
37474
|
+
constructor(alias) {
|
|
37475
|
+
super(`"${alias}" is not a former provider name. \`agent-shim provider list\` shows the ones recorded.`);
|
|
37476
|
+
this.alias = alias;
|
|
37477
|
+
this.name = "ProviderAliasNotFoundError";
|
|
37462
37478
|
}
|
|
37463
|
-
|
|
37479
|
+
alias;
|
|
37464
37480
|
};
|
|
37465
37481
|
}
|
|
37466
37482
|
});
|
|
37467
37483
|
|
|
37468
|
-
//
|
|
37469
|
-
|
|
37470
|
-
|
|
37471
|
-
|
|
37472
|
-
|
|
37473
|
-
|
|
37474
|
-
|
|
37475
|
-
|
|
37476
|
-
|
|
37477
|
-
|
|
37478
|
-
|
|
37479
|
-
|
|
37480
|
-
|
|
37481
|
-
}
|
|
37482
|
-
|
|
37483
|
-
|
|
37484
|
-
|
|
37485
|
-
"claude-code",
|
|
37486
|
-
"claude",
|
|
37487
|
-
"cli"
|
|
37488
|
-
],
|
|
37489
|
-
packageManager: "pnpm@12.4.1+sha512.2e81e399d73fe8390dab25e06aa788ab7a5908248d2f5a370f82b481147a6a7a367bf8048f9a6fdb6460f21a66f0542dedb8b94ca2c8723596741920b1656d4c",
|
|
37490
|
-
type: "module",
|
|
37491
|
-
engines: {
|
|
37492
|
-
node: "^22.18 || >=24"
|
|
37493
|
-
},
|
|
37494
|
-
bin: {
|
|
37495
|
-
"agent-shim": "dist/cli.cjs",
|
|
37496
|
-
"claude-use": "dist/cli.cjs"
|
|
37497
|
-
},
|
|
37498
|
-
files: [
|
|
37499
|
-
"dist/cli.cjs",
|
|
37500
|
-
"dist/index.mjs",
|
|
37501
|
-
"dist/index.cjs",
|
|
37502
|
-
"dist/types"
|
|
37503
|
-
],
|
|
37504
|
-
scripts: {
|
|
37505
|
-
prepare: "husky && node scripts/build.mts --bundle-only",
|
|
37506
|
-
typecheck: "turbo run _typecheck",
|
|
37507
|
-
_typecheck: "tsc --noEmit",
|
|
37508
|
-
lint: "turbo run _lint",
|
|
37509
|
-
_lint: "eslint . --cache --cache-location .eslintcache --max-warnings 0",
|
|
37510
|
-
test: "turbo run _test",
|
|
37511
|
-
_test: "vitest run",
|
|
37512
|
-
"test:coverage": "turbo run _test:coverage",
|
|
37513
|
-
"_test:coverage": "vitest run --coverage",
|
|
37514
|
-
knip: "turbo run _knip",
|
|
37515
|
-
_knip: "knip --cache",
|
|
37516
|
-
build: "turbo run _build",
|
|
37517
|
-
_build: "node scripts/build.mts",
|
|
37518
|
-
"build:bundle": "node scripts/build.mts --bundle-only",
|
|
37519
|
-
prepublishOnly: "pnpm build:bundle",
|
|
37520
|
-
schema: "node scripts/gen-schema.mts"
|
|
37521
|
-
},
|
|
37522
|
-
dependencies: {
|
|
37523
|
-
"@anthropic-ai/claude-agent-sdk": "0.3.292",
|
|
37524
|
-
"@clack/prompts": "^1.8.0",
|
|
37525
|
-
"@modelcontextprotocol/sdk": "1.32.0",
|
|
37526
|
-
"@orpc/client": "2.0.0-beta.43",
|
|
37527
|
-
"@orpc/openapi": "2.0.0-beta.43",
|
|
37528
|
-
"@orpc/server": "2.0.0-beta.43",
|
|
37529
|
-
commander: "^15.0.0",
|
|
37530
|
-
cosmiconfig: "^10.0.1",
|
|
37531
|
-
picomatch: "^4.0.7",
|
|
37532
|
-
"string-width": "8.3.0",
|
|
37533
|
-
trilean: "1.9.0",
|
|
37534
|
-
undici: "7.30.1",
|
|
37535
|
-
zod: "^4.6.7"
|
|
37536
|
-
},
|
|
37537
|
-
devDependencies: {
|
|
37538
|
-
"@commitlint/cli": "^21.2.2",
|
|
37539
|
-
"@commitlint/config-conventional": "^21.2.2",
|
|
37540
|
-
"@exadev/eslint-config": "2.12.1",
|
|
37541
|
-
"@semantic-release/changelog": "^7.0.0",
|
|
37542
|
-
"@semantic-release/git": "^11.0.1",
|
|
37543
|
-
"@semantic-release/npm": "^13.1.5",
|
|
37544
|
-
"@types/node": "^26.5.1",
|
|
37545
|
-
"@types/picomatch": "^4.0.3",
|
|
37546
|
-
"@vitest/coverage-v8": "^4.1.12",
|
|
37547
|
-
combinatrix: "2.0.1",
|
|
37548
|
-
"conventional-changelog-conventionalcommits": "^10.4.0",
|
|
37549
|
-
esbuild: "^0.28.2",
|
|
37550
|
-
eslint: "^10.10.0",
|
|
37551
|
-
globals: "^17.12.0",
|
|
37552
|
-
husky: "^9.1.7",
|
|
37553
|
-
jiti: "^2.7.0",
|
|
37554
|
-
knip: "^6.35.1",
|
|
37555
|
-
"lint-staged": "^17.5.0",
|
|
37556
|
-
rollup: "4.64.0",
|
|
37557
|
-
"rollup-plugin-dts": "6.5.1",
|
|
37558
|
-
"semantic-release": "^25.0.9",
|
|
37559
|
-
turbo: "^2.11.5",
|
|
37560
|
-
typescript: "^6.0.3",
|
|
37561
|
-
"typescript-eslint": "^8.70.0",
|
|
37562
|
-
vitest: "^4.1.12",
|
|
37563
|
-
yaml: "2.9.1"
|
|
37564
|
-
},
|
|
37565
|
-
main: "dist/index.cjs",
|
|
37566
|
-
module: "dist/index.mjs",
|
|
37567
|
-
types: "dist/types/index.d.ts",
|
|
37568
|
-
exports: {
|
|
37569
|
-
".": {
|
|
37570
|
-
types: "./dist/types/index.d.ts",
|
|
37571
|
-
import: "./dist/index.mjs",
|
|
37572
|
-
require: "./dist/index.cjs"
|
|
37573
|
-
},
|
|
37574
|
-
"./package.json": "./package.json"
|
|
37575
|
-
}
|
|
37576
|
-
};
|
|
37484
|
+
// src/models/identity.ts
|
|
37485
|
+
function withoutContextMarker(model) {
|
|
37486
|
+
return model.toLowerCase().endsWith(CONTEXT_MARKER_1M) ? model.slice(0, -CONTEXT_MARKER_1M.length) : model;
|
|
37487
|
+
}
|
|
37488
|
+
function canonicalText(name) {
|
|
37489
|
+
return name.trim().toLowerCase().replace(NON_IDENTITY_BRACKET_RE, "").replace(/[\s_]+/g, "-").replace(/([a-z])(\d+(?:\.\d+)+)/g, "$1-$2").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
37490
|
+
}
|
|
37491
|
+
function splitVariants(tokens) {
|
|
37492
|
+
const variants2 = [];
|
|
37493
|
+
let end = tokens.length;
|
|
37494
|
+
for (; ; ) {
|
|
37495
|
+
const token = tokens[end - 1];
|
|
37496
|
+
if (token === void 0 || !KNOWN_VARIANTS.has(token)) {
|
|
37497
|
+
return { familyTokens: tokens.slice(0, end), variants: variants2 };
|
|
37498
|
+
}
|
|
37499
|
+
variants2.unshift(token);
|
|
37500
|
+
end -= 1;
|
|
37577
37501
|
}
|
|
37578
|
-
}
|
|
37579
|
-
|
|
37580
|
-
|
|
37581
|
-
|
|
37582
|
-
|
|
37583
|
-
|
|
37584
|
-
|
|
37502
|
+
}
|
|
37503
|
+
function versionOf(tokens) {
|
|
37504
|
+
for (let index = 0; index < tokens.length; index += 1) {
|
|
37505
|
+
const token = tokens[index];
|
|
37506
|
+
const next = tokens[index + 1];
|
|
37507
|
+
if (token === void 0) {
|
|
37508
|
+
return "";
|
|
37509
|
+
}
|
|
37510
|
+
if (/^\d+$/.test(token) && next !== void 0 && /^\d+$/.test(next)) {
|
|
37511
|
+
return `${token}.${next}`;
|
|
37512
|
+
}
|
|
37513
|
+
const dotted = /^\d+(?:\.\d+)+$/.exec(token);
|
|
37514
|
+
if (dotted !== null) {
|
|
37515
|
+
return dotted[0];
|
|
37516
|
+
}
|
|
37585
37517
|
}
|
|
37586
|
-
|
|
37587
|
-
|
|
37588
|
-
|
|
37589
|
-
|
|
37518
|
+
return "";
|
|
37519
|
+
}
|
|
37520
|
+
function modelIdentity(rawName) {
|
|
37521
|
+
const segments = rawName.trim().toLowerCase().split("/");
|
|
37522
|
+
const stripped = canonicalText(segments[segments.length - 1] ?? "").split(":")[0] ?? "";
|
|
37523
|
+
const withoutDate = stripped.replace(DATE_STAMP_RE, "");
|
|
37524
|
+
const tokens = withoutDate.split("-").filter((token) => token !== "");
|
|
37525
|
+
const { familyTokens, variants: variants2 } = splitVariants(tokens);
|
|
37526
|
+
const version2 = versionOf(familyTokens);
|
|
37527
|
+
const versionless = familyTokens.filter((token, index) => {
|
|
37528
|
+
if (version2 === "") {
|
|
37529
|
+
return true;
|
|
37530
|
+
}
|
|
37531
|
+
const dotted = /^\d+(?:\.\d+)+$/.test(token);
|
|
37532
|
+
const previous = familyTokens[index - 1];
|
|
37533
|
+
const next = familyTokens[index + 1];
|
|
37534
|
+
const insideVersionRun = dotted || /^\d+$/.test(token) && (previous !== void 0 && /^\d+$/.test(previous) || next !== void 0 && /^\d+$/.test(next));
|
|
37535
|
+
return !insideVersionRun;
|
|
37536
|
+
});
|
|
37537
|
+
const family = versionless.join("-");
|
|
37538
|
+
const tokenVendor = familyTokens.find((token) => Object.keys(VENDOR_BY_TOKEN).some((key) => token === key || token.startsWith(key)));
|
|
37539
|
+
const namespace = segments.length >= 2 ? (segments[0] ?? "").split(":").pop() ?? "" : "";
|
|
37540
|
+
const namespaceVendor = VENDOR_BY_NAMESPACE[namespace] ?? "";
|
|
37541
|
+
const tokenVendorName = tokenVendor === void 0 ? "" : VENDOR_BY_TOKEN[Object.keys(VENDOR_BY_TOKEN).find((key) => tokenVendor === key || tokenVendor.startsWith(key)) ?? ""] ?? "";
|
|
37542
|
+
return {
|
|
37543
|
+
vendor: tokenVendorName === "" ? namespaceVendor : tokenVendorName,
|
|
37544
|
+
vendorConflict: tokenVendorName !== "" && namespaceVendor !== "" && tokenVendorName !== namespaceVendor,
|
|
37545
|
+
family,
|
|
37546
|
+
version: version2,
|
|
37547
|
+
variant: variants2.join("-"),
|
|
37548
|
+
familyAndVersion: version2 === "" ? family : `${family}-${version2.replace(/\./g, "-")}`
|
|
37549
|
+
};
|
|
37550
|
+
}
|
|
37551
|
+
function relateModels(left, right) {
|
|
37552
|
+
const a10 = modelIdentity(left);
|
|
37553
|
+
const b = modelIdentity(right);
|
|
37554
|
+
if (a10.familyAndVersion !== b.familyAndVersion) {
|
|
37555
|
+
return sameFamilyOtherVersion(a10, b) ? "similar" : "distinct";
|
|
37590
37556
|
}
|
|
37591
|
-
if (
|
|
37592
|
-
return
|
|
37557
|
+
if (a10.variant !== b.variant || a10.vendorConflict || b.vendorConflict || a10.vendor !== "" && b.vendor !== "" && a10.vendor !== b.vendor) {
|
|
37558
|
+
return "similar";
|
|
37593
37559
|
}
|
|
37594
|
-
|
|
37595
|
-
|
|
37596
|
-
|
|
37560
|
+
return "same";
|
|
37561
|
+
}
|
|
37562
|
+
function sameFamilyOtherVersion(a10, b) {
|
|
37563
|
+
if (a10.family !== b.family) {
|
|
37564
|
+
return false;
|
|
37597
37565
|
}
|
|
37598
|
-
|
|
37566
|
+
if (a10.vendor !== "" && b.vendor !== "" && a10.vendor !== b.vendor) {
|
|
37567
|
+
return false;
|
|
37568
|
+
}
|
|
37569
|
+
return true;
|
|
37599
37570
|
}
|
|
37600
|
-
var
|
|
37601
|
-
var
|
|
37602
|
-
"src/
|
|
37571
|
+
var NON_IDENTITY_BRACKET_RE, CONTEXT_MARKER_1M, DATE_STAMP_RE, KNOWN_VARIANTS, VENDOR_BY_NAMESPACE, VENDOR_BY_TOKEN;
|
|
37572
|
+
var init_identity2 = __esm({
|
|
37573
|
+
"src/models/identity.ts"() {
|
|
37603
37574
|
"use strict";
|
|
37604
|
-
|
|
37605
|
-
|
|
37606
|
-
|
|
37607
|
-
|
|
37608
|
-
|
|
37609
|
-
|
|
37610
|
-
|
|
37611
|
-
|
|
37612
|
-
|
|
37613
|
-
|
|
37614
|
-
|
|
37615
|
-
|
|
37616
|
-
|
|
37617
|
-
|
|
37618
|
-
|
|
37619
|
-
|
|
37620
|
-
|
|
37621
|
-
|
|
37622
|
-
|
|
37575
|
+
NON_IDENTITY_BRACKET_RE = /\[[^\]]*\]/g;
|
|
37576
|
+
CONTEXT_MARKER_1M = "[1m]";
|
|
37577
|
+
DATE_STAMP_RE = /-(?:19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])$/;
|
|
37578
|
+
KNOWN_VARIANTS = /* @__PURE__ */ new Set(["high", "medium", "low", "thinking", "xhigh", "max", "highspeed", "sol", "terra", "luna", "mini", "flash-lite", "turbo"]);
|
|
37579
|
+
VENDOR_BY_NAMESPACE = Object.freeze({
|
|
37580
|
+
anthropic: "anthropic",
|
|
37581
|
+
google: "google",
|
|
37582
|
+
openai: "openai",
|
|
37583
|
+
zai: "zai",
|
|
37584
|
+
"z-ai": "zai",
|
|
37585
|
+
minimax: "minimax",
|
|
37586
|
+
qwen: "qwen",
|
|
37587
|
+
deepseek: "deepseek",
|
|
37588
|
+
moonshot: "moonshot",
|
|
37589
|
+
meta: "meta",
|
|
37590
|
+
mistral: "mistral"
|
|
37591
|
+
});
|
|
37592
|
+
VENDOR_BY_TOKEN = Object.freeze({
|
|
37593
|
+
claude: "anthropic",
|
|
37594
|
+
gemini: "google",
|
|
37595
|
+
antigravity: "google",
|
|
37596
|
+
gpt: "openai",
|
|
37597
|
+
glm: "zai",
|
|
37598
|
+
minimax: "minimax",
|
|
37599
|
+
qwen: "qwen",
|
|
37600
|
+
deepseek: "deepseek",
|
|
37601
|
+
kimi: "moonshot",
|
|
37602
|
+
llama: "meta",
|
|
37603
|
+
mistral: "mistral",
|
|
37604
|
+
mixtral: "mistral"
|
|
37605
|
+
});
|
|
37623
37606
|
}
|
|
37624
37607
|
});
|
|
37625
37608
|
|
|
37626
|
-
// src/
|
|
37627
|
-
function
|
|
37628
|
-
const
|
|
37629
|
-
|
|
37630
|
-
|
|
37609
|
+
// src/models/families.ts
|
|
37610
|
+
function modelOf(ref) {
|
|
37611
|
+
const slash = ref.indexOf("/");
|
|
37612
|
+
return slash === -1 ? ref : ref.slice(slash + 1);
|
|
37613
|
+
}
|
|
37614
|
+
function familyKeyOf(rawModel) {
|
|
37615
|
+
const identity = modelIdentity(rawModel);
|
|
37616
|
+
return identity.variant === "" ? identity.familyAndVersion : `${identity.familyAndVersion}${VARIANT_SEPARATOR}${identity.variant}`;
|
|
37617
|
+
}
|
|
37618
|
+
function assertionsOf(models) {
|
|
37619
|
+
return { same: models?.same ?? [], distinct: models?.distinct ?? [] };
|
|
37620
|
+
}
|
|
37621
|
+
function sameModel(left, right, assertions) {
|
|
37622
|
+
if (assertions.distinct.some(([a10, b]) => a10 === left && b === right || a10 === right && b === left)) {
|
|
37623
|
+
return false;
|
|
37631
37624
|
}
|
|
37632
|
-
const
|
|
37633
|
-
const
|
|
37634
|
-
|
|
37635
|
-
|
|
37636
|
-
|
|
37637
|
-
|
|
37638
|
-
|
|
37639
|
-
}
|
|
37640
|
-
return
|
|
37625
|
+
const leftGroup = assertions.same.find((group) => group.includes(left));
|
|
37626
|
+
const rightGroup = assertions.same.find((group) => group.includes(right));
|
|
37627
|
+
if (leftGroup !== void 0 && leftGroup === rightGroup) {
|
|
37628
|
+
return true;
|
|
37629
|
+
}
|
|
37630
|
+
if (leftGroup !== void 0 && !leftGroup.includes(right) || rightGroup !== void 0 && !rightGroup.includes(left)) {
|
|
37631
|
+
return false;
|
|
37632
|
+
}
|
|
37633
|
+
return relateModels(modelOf(left), modelOf(right)) === "same";
|
|
37641
37634
|
}
|
|
37642
|
-
function
|
|
37643
|
-
|
|
37644
|
-
|
|
37635
|
+
function pinnedTo(settings2, ref) {
|
|
37636
|
+
return settings2?.names?.some((name) => name === ref || name === modelOf(ref)) === true;
|
|
37637
|
+
}
|
|
37638
|
+
function buildFamilies(refs, models) {
|
|
37639
|
+
const assertions = assertionsOf(models);
|
|
37640
|
+
const settingsByKey = models?.families ?? {};
|
|
37641
|
+
const groups = [];
|
|
37642
|
+
for (const ref of refs) {
|
|
37643
|
+
const pinnedKey = Object.entries(settingsByKey).find(([, settings2]) => pinnedTo(settings2, ref))?.[0];
|
|
37644
|
+
const joined3 = groups.find((group) => pinnedKey === void 0 ? group.refs.some((first) => sameModel(first, ref, assertions)) : group.key === pinnedKey);
|
|
37645
|
+
if (joined3 !== void 0) {
|
|
37646
|
+
joined3.refs.push(ref);
|
|
37647
|
+
} else {
|
|
37648
|
+
groups.push({ key: pinnedKey ?? familyKeyOf(modelOf(ref)), refs: [ref] });
|
|
37649
|
+
}
|
|
37650
|
+
}
|
|
37651
|
+
return groups.map((group) => ({ key: group.key, refs: group.refs, settings: settingsByKey[group.key] ?? {} }));
|
|
37652
|
+
}
|
|
37653
|
+
function familyNamed(families, member) {
|
|
37654
|
+
if (!member.startsWith(FAMILY_PREFIX)) {
|
|
37645
37655
|
return void 0;
|
|
37646
37656
|
}
|
|
37647
|
-
const
|
|
37648
|
-
return
|
|
37649
|
-
...type2 === void 0 ? {} : { type: type2 },
|
|
37650
|
-
...code === void 0 ? {} : { code: String(code) },
|
|
37651
|
-
...message === void 0 ? {} : { message }
|
|
37652
|
-
};
|
|
37657
|
+
const key = member.slice(FAMILY_PREFIX.length);
|
|
37658
|
+
return families.find((family) => family.key === key);
|
|
37653
37659
|
}
|
|
37654
|
-
function
|
|
37655
|
-
return
|
|
37660
|
+
function familyCapabilities(settings2) {
|
|
37661
|
+
return { vision: settings2.vision ?? true, tools: settings2.tools ?? true, thinking: settings2.thinking ?? true };
|
|
37656
37662
|
}
|
|
37657
|
-
function
|
|
37658
|
-
|
|
37659
|
-
|
|
37660
|
-
|
|
37661
|
-
|
|
37662
|
-
|
|
37663
|
+
function familyMode(settings2) {
|
|
37664
|
+
return settings2.mode ?? "ordered";
|
|
37665
|
+
}
|
|
37666
|
+
function sharedFamilies(families) {
|
|
37667
|
+
return families.filter((family) => family.refs.length > 1);
|
|
37668
|
+
}
|
|
37669
|
+
function expandFamilyMembers(members2, families) {
|
|
37670
|
+
const expanded = [];
|
|
37671
|
+
for (const member of members2) {
|
|
37672
|
+
for (const ref of member.startsWith(FAMILY_PREFIX) ? familyNamed(families, member)?.refs ?? [] : [member]) {
|
|
37673
|
+
if (!expanded.includes(ref)) {
|
|
37674
|
+
expanded.push(ref);
|
|
37675
|
+
}
|
|
37676
|
+
}
|
|
37663
37677
|
}
|
|
37678
|
+
return expanded;
|
|
37664
37679
|
}
|
|
37665
|
-
function
|
|
37666
|
-
|
|
37667
|
-
let usage;
|
|
37668
|
-
let error63;
|
|
37669
|
-
let eventName;
|
|
37670
|
-
let line = "";
|
|
37671
|
-
let skipping = false;
|
|
37672
|
-
let data = [];
|
|
37673
|
-
const dispatch = () => {
|
|
37674
|
-
if (data.length > 0) {
|
|
37675
|
-
const payload = parseJson2(data.join("\n"));
|
|
37676
|
-
if (isObject3(payload)) {
|
|
37677
|
-
const type2 = typeof payload.type === "string" ? payload.type : void 0;
|
|
37678
|
-
if (type2 === "message_start" && isObject3(payload.message)) {
|
|
37679
|
-
if (typeof payload.message.model === "string") {
|
|
37680
|
-
model = payload.message.model;
|
|
37681
|
-
}
|
|
37682
|
-
usage = mergeUsage(usage, payload.message.usage);
|
|
37683
|
-
} else if (type2 === "message_delta") {
|
|
37684
|
-
usage = mergeUsage(usage, payload.usage);
|
|
37685
|
-
} else if (type2 === "error") {
|
|
37686
|
-
error63 = errorInfo(payload.error) ?? error63;
|
|
37687
|
-
}
|
|
37688
|
-
}
|
|
37689
|
-
}
|
|
37690
|
-
eventName = void 0;
|
|
37691
|
-
data = [];
|
|
37692
|
-
};
|
|
37693
|
-
const worthKeeping = (partial2) => {
|
|
37694
|
-
if (!partial2.startsWith("data:")) {
|
|
37695
|
-
return true;
|
|
37696
|
-
}
|
|
37697
|
-
if (eventName !== void 0) {
|
|
37698
|
-
return METADATA_EVENTS.has(eventName);
|
|
37699
|
-
}
|
|
37700
|
-
const leading = LEADING_TYPE.exec(partial2.slice("data:".length));
|
|
37701
|
-
if (leading?.[1] !== void 0) {
|
|
37702
|
-
return METADATA_EVENTS.has(leading[1]);
|
|
37703
|
-
}
|
|
37704
|
-
return void 0;
|
|
37705
|
-
};
|
|
37706
|
-
const completeLine = (complete) => {
|
|
37707
|
-
const text5 = complete.endsWith("\r") ? complete.slice(0, -1) : complete;
|
|
37708
|
-
if (text5 === "") {
|
|
37709
|
-
dispatch();
|
|
37710
|
-
return;
|
|
37711
|
-
}
|
|
37712
|
-
if (text5.startsWith("event:")) {
|
|
37713
|
-
eventName = text5.slice("event:".length).trim();
|
|
37714
|
-
return;
|
|
37715
|
-
}
|
|
37716
|
-
if (text5.startsWith("data:")) {
|
|
37717
|
-
const value2 = text5.slice("data:".length);
|
|
37718
|
-
data.push(value2.startsWith(" ") ? value2.slice(1) : value2);
|
|
37719
|
-
}
|
|
37720
|
-
};
|
|
37721
|
-
return {
|
|
37722
|
-
push: (text5) => {
|
|
37723
|
-
let start = 0;
|
|
37724
|
-
for (; ; ) {
|
|
37725
|
-
const newline = text5.indexOf("\n", start);
|
|
37726
|
-
const piece = newline === -1 ? text5.slice(start) : text5.slice(start, newline);
|
|
37727
|
-
if (!skipping) {
|
|
37728
|
-
line += piece;
|
|
37729
|
-
if (worthKeeping(line) === false) {
|
|
37730
|
-
line = "";
|
|
37731
|
-
skipping = true;
|
|
37732
|
-
}
|
|
37733
|
-
}
|
|
37734
|
-
if (newline === -1) {
|
|
37735
|
-
return;
|
|
37736
|
-
}
|
|
37737
|
-
if (!skipping) {
|
|
37738
|
-
completeLine(line);
|
|
37739
|
-
}
|
|
37740
|
-
line = "";
|
|
37741
|
-
skipping = false;
|
|
37742
|
-
start = newline + 1;
|
|
37743
|
-
}
|
|
37744
|
-
},
|
|
37745
|
-
result: () => {
|
|
37746
|
-
if (!skipping && line !== "") {
|
|
37747
|
-
completeLine(line);
|
|
37748
|
-
line = "";
|
|
37749
|
-
}
|
|
37750
|
-
dispatch();
|
|
37751
|
-
return { model, usage, error: error63 };
|
|
37752
|
-
}
|
|
37753
|
-
};
|
|
37680
|
+
function familyOfRef(families, ref) {
|
|
37681
|
+
return families.find((family) => family.refs.includes(ref));
|
|
37754
37682
|
}
|
|
37755
|
-
function
|
|
37756
|
-
const
|
|
37757
|
-
|
|
37758
|
-
let inString = false;
|
|
37759
|
-
let escaped = false;
|
|
37760
|
-
let readingKey = false;
|
|
37761
|
-
let expectKey = false;
|
|
37762
|
-
let key = "";
|
|
37763
|
-
let capturing;
|
|
37764
|
-
let capture = "";
|
|
37765
|
-
let inValue = false;
|
|
37766
|
-
let currentKey = "";
|
|
37767
|
-
const endValue = () => {
|
|
37768
|
-
if (capturing !== void 0) {
|
|
37769
|
-
captured.set(capturing, capture.trim());
|
|
37770
|
-
}
|
|
37771
|
-
capturing = void 0;
|
|
37772
|
-
capture = "";
|
|
37773
|
-
inValue = false;
|
|
37774
|
-
};
|
|
37775
|
-
const step2 = (char) => {
|
|
37776
|
-
if (capturing !== void 0 && !(depth === 1 && !inString && (char === "," || char === "}"))) {
|
|
37777
|
-
capture += char;
|
|
37778
|
-
}
|
|
37779
|
-
if (inString) {
|
|
37780
|
-
if (escaped) {
|
|
37781
|
-
escaped = false;
|
|
37782
|
-
} else if (char === "\\") {
|
|
37783
|
-
escaped = true;
|
|
37784
|
-
} else if (char === '"') {
|
|
37785
|
-
inString = false;
|
|
37786
|
-
if (readingKey) {
|
|
37787
|
-
readingKey = false;
|
|
37788
|
-
currentKey = key;
|
|
37789
|
-
}
|
|
37790
|
-
return;
|
|
37791
|
-
}
|
|
37792
|
-
if (readingKey) {
|
|
37793
|
-
key += char;
|
|
37794
|
-
}
|
|
37795
|
-
return;
|
|
37796
|
-
}
|
|
37797
|
-
switch (char) {
|
|
37798
|
-
case '"':
|
|
37799
|
-
inString = true;
|
|
37800
|
-
if (depth === 1 && expectKey) {
|
|
37801
|
-
readingKey = true;
|
|
37802
|
-
expectKey = false;
|
|
37803
|
-
key = "";
|
|
37804
|
-
}
|
|
37805
|
-
return;
|
|
37806
|
-
case "{":
|
|
37807
|
-
case "[":
|
|
37808
|
-
depth += 1;
|
|
37809
|
-
if (depth === 1 && char === "{") {
|
|
37810
|
-
expectKey = true;
|
|
37811
|
-
}
|
|
37812
|
-
return;
|
|
37813
|
-
case "}":
|
|
37814
|
-
case "]":
|
|
37815
|
-
if (depth === 1) {
|
|
37816
|
-
endValue();
|
|
37817
|
-
}
|
|
37818
|
-
depth -= 1;
|
|
37819
|
-
return;
|
|
37820
|
-
case ":":
|
|
37821
|
-
if (depth === 1 && !inValue) {
|
|
37822
|
-
inValue = true;
|
|
37823
|
-
if (METADATA_KEYS.has(currentKey)) {
|
|
37824
|
-
capturing = currentKey;
|
|
37825
|
-
capture = "";
|
|
37826
|
-
}
|
|
37827
|
-
}
|
|
37828
|
-
return;
|
|
37829
|
-
case ",":
|
|
37830
|
-
if (depth === 1) {
|
|
37831
|
-
endValue();
|
|
37832
|
-
expectKey = true;
|
|
37833
|
-
}
|
|
37834
|
-
return;
|
|
37835
|
-
default:
|
|
37836
|
-
return;
|
|
37837
|
-
}
|
|
37838
|
-
};
|
|
37839
|
-
return {
|
|
37840
|
-
push: (text5) => {
|
|
37841
|
-
for (const char of text5) {
|
|
37842
|
-
step2(char);
|
|
37843
|
-
}
|
|
37844
|
-
},
|
|
37845
|
-
result: () => {
|
|
37846
|
-
const model = parseJson2(captured.get("model") ?? "");
|
|
37847
|
-
const usageRaw = parseJson2(captured.get("usage") ?? "");
|
|
37848
|
-
const errorRaw = parseJson2(captured.get("error") ?? "");
|
|
37849
|
-
return {
|
|
37850
|
-
model: typeof model === "string" ? model : void 0,
|
|
37851
|
-
usage: mergeUsage(void 0, usageRaw),
|
|
37852
|
-
error: errorInfo(errorRaw)
|
|
37853
|
-
};
|
|
37854
|
-
}
|
|
37855
|
-
};
|
|
37683
|
+
function accountRefsOf(models) {
|
|
37684
|
+
const named = [...(models?.same ?? []).flat(), ...Object.values(models?.families ?? {}).flatMap((settings2) => settings2.names ?? [])];
|
|
37685
|
+
return [...new Set(named.filter((ref) => ref.startsWith("acct:")))];
|
|
37856
37686
|
}
|
|
37857
|
-
var
|
|
37858
|
-
var
|
|
37859
|
-
"src/
|
|
37687
|
+
var FAMILY_PREFIX, VARIANT_SEPARATOR;
|
|
37688
|
+
var init_families = __esm({
|
|
37689
|
+
"src/models/families.ts"() {
|
|
37860
37690
|
"use strict";
|
|
37861
|
-
|
|
37862
|
-
|
|
37863
|
-
|
|
37864
|
-
output_tokens: external_exports.number().int().nonnegative().nullish(),
|
|
37865
|
-
cache_creation_input_tokens: external_exports.number().int().nonnegative().nullish(),
|
|
37866
|
-
cache_read_input_tokens: external_exports.number().int().nonnegative().nullish()
|
|
37867
|
-
});
|
|
37868
|
-
ErrorObjectSchema = external_exports.looseObject({
|
|
37869
|
-
type: external_exports.string().optional(),
|
|
37870
|
-
code: external_exports.union([external_exports.string(), external_exports.number()]).optional(),
|
|
37871
|
-
message: external_exports.string().optional()
|
|
37872
|
-
});
|
|
37873
|
-
METADATA_EVENTS = /* @__PURE__ */ new Set(["message_start", "message_delta", "error"]);
|
|
37874
|
-
LEADING_TYPE = /^\s*\{\s*"type"\s*:\s*"([^"]*)"/;
|
|
37875
|
-
METADATA_KEYS = /* @__PURE__ */ new Set(["model", "usage", "error"]);
|
|
37691
|
+
init_identity2();
|
|
37692
|
+
FAMILY_PREFIX = "family:";
|
|
37693
|
+
VARIANT_SEPARATOR = "+";
|
|
37876
37694
|
}
|
|
37877
37695
|
});
|
|
37878
37696
|
|
|
37879
|
-
// src/
|
|
37880
|
-
function
|
|
37881
|
-
|
|
37882
|
-
if (contentType.startsWith("text/event-stream")) {
|
|
37883
|
-
return createSseScanner();
|
|
37884
|
-
}
|
|
37885
|
-
if (contentType.startsWith("application/json")) {
|
|
37886
|
-
return createJsonScanner();
|
|
37887
|
-
}
|
|
37888
|
-
return void 0;
|
|
37697
|
+
// src/providersStore.ts
|
|
37698
|
+
function providerJsonPath(paths, name) {
|
|
37699
|
+
return providerFilePath(paths.providersDir, name);
|
|
37889
37700
|
}
|
|
37890
|
-
function
|
|
37891
|
-
|
|
37892
|
-
if (key.toLowerCase() === name) {
|
|
37893
|
-
return value2;
|
|
37894
|
-
}
|
|
37895
|
-
}
|
|
37896
|
-
return void 0;
|
|
37701
|
+
function providerFileDefined(lstat, providersDir, name) {
|
|
37702
|
+
return isStoredName(name) && lstat(providerFilePath(providersDir, name)) !== void 0;
|
|
37897
37703
|
}
|
|
37898
|
-
function
|
|
37899
|
-
|
|
37900
|
-
case void 0:
|
|
37901
|
-
case "":
|
|
37902
|
-
case "identity":
|
|
37903
|
-
return null;
|
|
37904
|
-
case "gzip":
|
|
37905
|
-
case "x-gzip":
|
|
37906
|
-
return zlib.createGunzip();
|
|
37907
|
-
case "deflate":
|
|
37908
|
-
return zlib.createInflate();
|
|
37909
|
-
case "br":
|
|
37910
|
-
return zlib.createBrotliDecompress();
|
|
37911
|
-
default:
|
|
37912
|
-
return void 0;
|
|
37913
|
-
}
|
|
37704
|
+
function providerExists(paths, name) {
|
|
37705
|
+
return import_node_fs10.default.existsSync(providerJsonPath(paths, name));
|
|
37914
37706
|
}
|
|
37915
|
-
function
|
|
37916
|
-
const
|
|
37917
|
-
if (
|
|
37918
|
-
|
|
37707
|
+
function requireProviderExists(paths, name) {
|
|
37708
|
+
const canonical = canonicalProviderName(name, (candidate) => providerExists(paths, candidate), () => readProviderAliases(paths));
|
|
37709
|
+
if (!providerExists(paths, canonical)) {
|
|
37710
|
+
throw new ProviderNotFoundError(name);
|
|
37919
37711
|
}
|
|
37920
|
-
return { provider: sessionProvider ?? ANTHROPIC_PROVIDER, endpoint: path73 };
|
|
37921
37712
|
}
|
|
37922
|
-
function
|
|
37923
|
-
|
|
37924
|
-
if (event.requestedModel === void 0 || servedModel === void 0 || event.requestedModel === servedModel) return void 0;
|
|
37925
|
-
return { requested: event.requestedModel, providers: [provider] };
|
|
37713
|
+
function isRecord4(value2) {
|
|
37714
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
37926
37715
|
}
|
|
37927
|
-
function
|
|
37928
|
-
|
|
37929
|
-
|
|
37930
|
-
|
|
37931
|
-
const
|
|
37932
|
-
const
|
|
37933
|
-
const
|
|
37934
|
-
|
|
37716
|
+
function legacyProviderConversion(raw) {
|
|
37717
|
+
if (!isRecord4(raw) || "credential" in raw) {
|
|
37718
|
+
return void 0;
|
|
37719
|
+
}
|
|
37720
|
+
const env = isRecord4(raw.env) ? raw.env : void 0;
|
|
37721
|
+
const legacyEnvKeys = env === void 0 ? [] : Object.keys(env).filter((key) => LEGACY_ENV_CREDENTIAL_KEYS.includes(key));
|
|
37722
|
+
const fields = [...LEGACY_PROVIDER_FIELDS.filter((field) => field in raw), ...legacyEnvKeys.map((key) => `env.${key}`)];
|
|
37723
|
+
if (fields.length === 0) {
|
|
37724
|
+
return void 0;
|
|
37725
|
+
}
|
|
37726
|
+
const sources = [];
|
|
37727
|
+
if (typeof raw.tokenEnv === "string") {
|
|
37728
|
+
sources.push({ env: raw.tokenEnv });
|
|
37729
|
+
}
|
|
37730
|
+
if (Array.isArray(raw.tokenCommand)) {
|
|
37731
|
+
sources.push({ command: raw.tokenCommand });
|
|
37732
|
+
}
|
|
37733
|
+
if (typeof env?.ANTHROPIC_AUTH_TOKEN === "string" && env.ANTHROPIC_AUTH_TOKEN !== "") {
|
|
37734
|
+
sources.push({ literal: LEGACY_LITERAL_PLACEHOLDER });
|
|
37735
|
+
}
|
|
37736
|
+
const remainingEnv = env === void 0 ? void 0 : Object.fromEntries(Object.entries(env).filter(([key]) => !LEGACY_ENV_CREDENTIAL_KEYS.includes(key)));
|
|
37737
|
+
const replacedKeys = [...LEGACY_PROVIDER_FIELDS, "env"];
|
|
37738
|
+
const rest = Object.fromEntries(Object.entries(raw).filter(([key]) => !replacedKeys.includes(key)));
|
|
37935
37739
|
return {
|
|
37936
|
-
|
|
37937
|
-
|
|
37938
|
-
|
|
37939
|
-
|
|
37940
|
-
|
|
37941
|
-
...event.clientSessionId === void 0 ? {} : { clientSessionId: event.clientSessionId },
|
|
37942
|
-
...projectId === void 0 ? {} : { project: projectId },
|
|
37943
|
-
viaHeadroom: event.viaHeadroom,
|
|
37944
|
-
route: event.route,
|
|
37945
|
-
method: event.method,
|
|
37946
|
-
endpoint,
|
|
37947
|
-
...scan?.model === void 0 ? {} : { model: scan.model },
|
|
37948
|
-
...choice === void 0 ? {} : { requestedModel: choice.requested },
|
|
37949
|
-
...choice !== void 0 && choice.providers.length > 1 ? { candidateProviders: [...choice.providers] } : {},
|
|
37950
|
-
status: event.status,
|
|
37951
|
-
latencyMs: Math.max(0, Math.round(context.headAt - event.receivedAt)),
|
|
37952
|
-
durationMs: Math.max(0, Math.round(context.endedAt - event.receivedAt)),
|
|
37953
|
-
outcome: context.outcome,
|
|
37954
|
-
...scan?.usage === void 0 ? {} : { usage: scan.usage },
|
|
37955
|
-
...rateLimitHeaders === void 0 ? {} : { rateLimitHeaders },
|
|
37956
|
-
...limit === void 0 ? {} : { limit },
|
|
37957
|
-
...requestId === void 0 ? {} : { requestId }
|
|
37958
|
-
};
|
|
37959
|
-
}
|
|
37960
|
-
function createUsageMiddleware(deps) {
|
|
37961
|
-
return (event) => {
|
|
37962
|
-
if (DOOR_ANSWERED_ROUTES.has(event.route)) {
|
|
37963
|
-
return void 0;
|
|
37964
|
-
}
|
|
37965
|
-
const headAt = deps.now();
|
|
37966
|
-
const scanner = scannerFor(event.headers);
|
|
37967
|
-
const decoder = scanner === void 0 ? null : decoderFor(headerValue(event.headers, "content-encoding"));
|
|
37968
|
-
let scanning = scanner !== void 0 && decoder !== void 0;
|
|
37969
|
-
const text5 = new TextDecoder();
|
|
37970
|
-
const feed = (bytes, final) => {
|
|
37971
|
-
if (!scanning || scanner === void 0) {
|
|
37972
|
-
return;
|
|
37973
|
-
}
|
|
37974
|
-
try {
|
|
37975
|
-
scanner.push(text5.decode(bytes, { stream: !final }));
|
|
37976
|
-
} catch (error63) {
|
|
37977
|
-
scanning = false;
|
|
37978
|
-
deps.log(`usage: body scan failed for ${event.route}: ${error63 instanceof Error ? error63.message : String(error63)}`);
|
|
37979
|
-
}
|
|
37980
|
-
};
|
|
37981
|
-
const finish = (outcome) => {
|
|
37982
|
-
const endedAt = deps.now();
|
|
37983
|
-
deps.defer(() => {
|
|
37984
|
-
try {
|
|
37985
|
-
deps.record(buildRecord(event, { headAt, endedAt, outcome, scan: scanning && scanner !== void 0 ? scanner.result() : void 0 }), event);
|
|
37986
|
-
} catch (error63) {
|
|
37987
|
-
deps.log(`usage: could not record ${event.method} ${event.path} (${String(event.status)}): ${error63 instanceof Error ? error63.message : String(error63)}`);
|
|
37988
|
-
}
|
|
37989
|
-
});
|
|
37990
|
-
};
|
|
37991
|
-
if (decoder === null || decoder === void 0) {
|
|
37992
|
-
return {
|
|
37993
|
-
chunk: (bytes) => {
|
|
37994
|
-
feed(bytes, false);
|
|
37995
|
-
},
|
|
37996
|
-
end: (outcome) => {
|
|
37997
|
-
feed(new Uint8Array(), true);
|
|
37998
|
-
finish(outcome);
|
|
37999
|
-
}
|
|
38000
|
-
};
|
|
37740
|
+
fields,
|
|
37741
|
+
replacement: {
|
|
37742
|
+
...rest,
|
|
37743
|
+
credential: { sources, ...raw.authScheme === "apiKey" ? { target: "apiKey" } : {} },
|
|
37744
|
+
...remainingEnv === void 0 || Object.keys(remainingEnv).length === 0 ? {} : { env: remainingEnv }
|
|
38001
37745
|
}
|
|
38002
|
-
let ended;
|
|
38003
|
-
let settled = false;
|
|
38004
|
-
const settle2 = () => {
|
|
38005
|
-
if (settled || ended === void 0) {
|
|
38006
|
-
return;
|
|
38007
|
-
}
|
|
38008
|
-
settled = true;
|
|
38009
|
-
feed(new Uint8Array(), true);
|
|
38010
|
-
finish(ended);
|
|
38011
|
-
};
|
|
38012
|
-
decoder.on("data", (bytes) => {
|
|
38013
|
-
feed(bytes, false);
|
|
38014
|
-
});
|
|
38015
|
-
decoder.on("error", (error63) => {
|
|
38016
|
-
scanning = false;
|
|
38017
|
-
deps.log(`usage: could not decompress the body of ${event.route}: ${error63.message}`);
|
|
38018
|
-
settle2();
|
|
38019
|
-
});
|
|
38020
|
-
decoder.on("end", settle2);
|
|
38021
|
-
return {
|
|
38022
|
-
chunk: (bytes) => {
|
|
38023
|
-
if (scanning) {
|
|
38024
|
-
decoder.write(bytes);
|
|
38025
|
-
}
|
|
38026
|
-
},
|
|
38027
|
-
end: (outcome) => {
|
|
38028
|
-
ended = outcome;
|
|
38029
|
-
if (!scanning || outcome === "aborted") {
|
|
38030
|
-
decoder.destroy();
|
|
38031
|
-
settle2();
|
|
38032
|
-
return;
|
|
38033
|
-
}
|
|
38034
|
-
decoder.end();
|
|
38035
|
-
}
|
|
38036
|
-
};
|
|
38037
37746
|
};
|
|
38038
37747
|
}
|
|
38039
|
-
|
|
38040
|
-
|
|
38041
|
-
|
|
38042
|
-
|
|
38043
|
-
zlib = __toESM(require("node:zlib"), 1);
|
|
38044
|
-
init_route();
|
|
38045
|
-
init_rateLimit();
|
|
38046
|
-
init_scan();
|
|
38047
|
-
init_schema2();
|
|
38048
|
-
ANTHROPIC_PROVIDER = "anthropic";
|
|
38049
|
-
DOOR_ANSWERED_ROUTES = /* @__PURE__ */ new Set(["(unauthorized)", "(unrouted)"]);
|
|
37748
|
+
function parseProviderFile(filePath, raw) {
|
|
37749
|
+
const conversion = legacyProviderConversion(raw);
|
|
37750
|
+
if (conversion !== void 0) {
|
|
37751
|
+
throw new LegacyProviderFileError(filePath, conversion);
|
|
38050
37752
|
}
|
|
38051
|
-
|
|
38052
|
-
|
|
38053
|
-
|
|
38054
|
-
|
|
38055
|
-
|
|
37753
|
+
const parsed = parseIgnoringUnrecognisedKeys(ProviderSchema, raw);
|
|
37754
|
+
if (!parsed.success) {
|
|
37755
|
+
throw new ConfigValidationError(filePath, parsed.issues);
|
|
37756
|
+
}
|
|
37757
|
+
noteIgnoredKeys(filePath, parsed.ignored);
|
|
37758
|
+
return parsed.data;
|
|
37759
|
+
}
|
|
37760
|
+
function readProvider(paths, name) {
|
|
37761
|
+
const filePath = providerJsonPath(paths, name);
|
|
37762
|
+
if (!import_node_fs10.default.existsSync(filePath)) {
|
|
38056
37763
|
return void 0;
|
|
38057
37764
|
}
|
|
38058
|
-
|
|
37765
|
+
const raw = JSON.parse(import_node_fs10.default.readFileSync(filePath, "utf8"));
|
|
37766
|
+
return parseProviderFile(filePath, raw);
|
|
38059
37767
|
}
|
|
38060
|
-
function
|
|
38061
|
-
const
|
|
38062
|
-
const
|
|
38063
|
-
|
|
38064
|
-
return { ...fiveHour === void 0 ? {} : { fiveHour }, ...sevenDay === void 0 ? {} : { sevenDay }, ...extraUsage === void 0 ? {} : { extraUsage } };
|
|
37768
|
+
function loadProvider(providersDir, name, port) {
|
|
37769
|
+
const filePath = providerFilePath(providersDir, name);
|
|
37770
|
+
const raw = port.readConfigFile(filePath);
|
|
37771
|
+
return raw === void 0 ? void 0 : parseProviderFile(filePath, raw);
|
|
38065
37772
|
}
|
|
38066
|
-
|
|
38067
|
-
|
|
38068
|
-
"src/usage/quotaFacts.ts"() {
|
|
38069
|
-
"use strict";
|
|
38070
|
-
init_rateLimit();
|
|
38071
|
-
MS_PER_HOUR = 36e5;
|
|
38072
|
-
}
|
|
38073
|
-
});
|
|
38074
|
-
|
|
38075
|
-
// src/usage/pick.ts
|
|
38076
|
-
function unifiedOf(state) {
|
|
38077
|
-
return state?.rateLimit?.unified;
|
|
37773
|
+
function reportInvalidProvider(name, message) {
|
|
37774
|
+
console.error(`agent-shim: providers/${name}.json is invalid and was skipped: ${message}`);
|
|
38078
37775
|
}
|
|
38079
|
-
function
|
|
38080
|
-
const
|
|
38081
|
-
|
|
38082
|
-
|
|
38083
|
-
|
|
38084
|
-
|
|
38085
|
-
|
|
37776
|
+
function listProviders(paths, onInvalid = reportInvalidProvider) {
|
|
37777
|
+
const names = listProviderNames(
|
|
37778
|
+
(dir) => import_node_fs10.default.readdirSync(dir),
|
|
37779
|
+
paths.providersDir
|
|
37780
|
+
);
|
|
37781
|
+
const result = [];
|
|
37782
|
+
for (const name of names) {
|
|
37783
|
+
let provider;
|
|
37784
|
+
try {
|
|
37785
|
+
provider = readProvider(paths, name);
|
|
37786
|
+
} catch (error63) {
|
|
37787
|
+
if (!(error63 instanceof ConfigValidationError || error63 instanceof LegacyProviderFileError || error63 instanceof UnsafeNameError)) {
|
|
37788
|
+
throw error63;
|
|
37789
|
+
}
|
|
37790
|
+
onInvalid(name, error63.message);
|
|
37791
|
+
continue;
|
|
37792
|
+
}
|
|
37793
|
+
if (provider !== void 0) {
|
|
37794
|
+
result.push({ name, provider });
|
|
37795
|
+
}
|
|
38086
37796
|
}
|
|
38087
|
-
|
|
38088
|
-
return until !== void 0 && until > nowMs ? until : void 0;
|
|
37797
|
+
return result;
|
|
38089
37798
|
}
|
|
38090
|
-
function
|
|
38091
|
-
|
|
38092
|
-
|
|
37799
|
+
function listProviderNames(readdir, providersDir) {
|
|
37800
|
+
let entries;
|
|
37801
|
+
try {
|
|
37802
|
+
entries = readdir(providersDir);
|
|
37803
|
+
} catch {
|
|
37804
|
+
return [];
|
|
37805
|
+
}
|
|
37806
|
+
return entries.filter((entry) => entry.endsWith(".json")).map((entry) => entry.slice(0, -".json".length)).sort();
|
|
38093
37807
|
}
|
|
38094
|
-
function
|
|
38095
|
-
|
|
38096
|
-
|
|
38097
|
-
const window = record2.rateLimitHeaders === void 0 ? void 0 : parseUnifiedRateLimit(record2.rateLimitHeaders)?.[which];
|
|
38098
|
-
if (window?.utilization !== void 0 && window.resetsAt !== void 0) {
|
|
38099
|
-
points.push({ resetsAt: window.resetsAt, point: { atMs: Date.parse(record2.at), utilization: window.utilization } });
|
|
38100
|
-
}
|
|
37808
|
+
function describeProviderEndpoint(provider) {
|
|
37809
|
+
if (isCodexProvider(provider)) {
|
|
37810
|
+
return "codex translation daemon";
|
|
38101
37811
|
}
|
|
38102
|
-
|
|
38103
|
-
|
|
38104
|
-
const first = current.at(0);
|
|
38105
|
-
const last = current.at(-1);
|
|
38106
|
-
if (first === void 0 || last === void 0 || last.atMs <= first.atMs || last.utilization <= first.utilization) {
|
|
38107
|
-
return void 0;
|
|
37812
|
+
if (isAntigravityProvider(provider)) {
|
|
37813
|
+
return (provider.antigravity?.mode ?? ANTIGRAVITY_DEFAULT_MODE) === "local" ? "antigravity local (ACP daemon)" : "antigravity cloud (Gemini API)";
|
|
38108
37814
|
}
|
|
38109
|
-
return (
|
|
37815
|
+
return isRouterProvider(provider) ? "the models block" : provider.baseUrl;
|
|
38110
37816
|
}
|
|
38111
|
-
function
|
|
38112
|
-
|
|
38113
|
-
return (usage?.inputTokens ?? 0) + (usage?.cacheCreationInputTokens ?? 0) + (usage?.outputTokens ?? 0);
|
|
37817
|
+
function isEmptyCodexConfig(config2) {
|
|
37818
|
+
return config2 === void 0 || config2.defaultModel === void 0 && config2.effort === void 0 && config2.login === void 0 && (config2.models === void 0 || Object.keys(config2.models).length === 0);
|
|
38114
37819
|
}
|
|
38115
|
-
function
|
|
38116
|
-
|
|
38117
|
-
|
|
38118
|
-
|
|
38119
|
-
|
|
38120
|
-
|
|
38121
|
-
}
|
|
37820
|
+
function isEmptyAntigravityConfig(config2) {
|
|
37821
|
+
return config2 === void 0 || config2.mode === void 0 && config2.defaultModel === void 0 && config2.effort === void 0 && config2.degradeDownTiers === void 0 && config2.cloud === void 0 && config2.local === void 0 && (config2.models === void 0 || Object.keys(config2.models).length === 0);
|
|
37822
|
+
}
|
|
37823
|
+
function addProvider(paths, name, input2) {
|
|
37824
|
+
if (providerExists(paths, name)) {
|
|
37825
|
+
throw new ProviderAlreadyExistsError(name);
|
|
38122
37826
|
}
|
|
38123
|
-
|
|
38124
|
-
const
|
|
38125
|
-
|
|
38126
|
-
|
|
38127
|
-
if (first === void 0 || last === void 0 || last.utilization <= first.utilization) {
|
|
38128
|
-
return void 0;
|
|
37827
|
+
requireNewProviderName(name);
|
|
37828
|
+
const kind = input2.kind ?? "http";
|
|
37829
|
+
if (kind === "codex" && input2.baseUrl !== void 0) {
|
|
37830
|
+
throw new ProviderKindMismatchError("A codex provider has no base URL: the launcher points its sessions at the front-door daemon. Drop --base-url.");
|
|
38129
37831
|
}
|
|
38130
|
-
|
|
38131
|
-
|
|
38132
|
-
}
|
|
38133
|
-
function windowRatio(records) {
|
|
38134
|
-
const points = [];
|
|
38135
|
-
for (const record2 of records) {
|
|
38136
|
-
const unified = record2.rateLimitHeaders === void 0 ? void 0 : parseUnifiedRateLimit(record2.rateLimitHeaders);
|
|
38137
|
-
const five = unified?.fiveHour;
|
|
38138
|
-
const seven = unified?.sevenDay;
|
|
38139
|
-
if (five?.utilization !== void 0 && five.resetsAt !== void 0 && seven?.utilization !== void 0 && seven.resetsAt !== void 0) {
|
|
38140
|
-
points.push({ fiveResetsAt: five.resetsAt, sevenResetsAt: seven.resetsAt, five: five.utilization, seven: seven.utilization });
|
|
38141
|
-
}
|
|
37832
|
+
if (kind === "antigravity" && input2.baseUrl !== void 0) {
|
|
37833
|
+
throw new ProviderKindMismatchError("An antigravity provider has no base URL: the launcher points its sessions at the front-door daemon. Drop --base-url.");
|
|
38142
37834
|
}
|
|
38143
|
-
|
|
38144
|
-
|
|
38145
|
-
const first = current.at(0);
|
|
38146
|
-
const last = current.at(-1);
|
|
38147
|
-
if (first === void 0 || last === void 0 || last.five <= first.five || last.seven <= first.seven) {
|
|
38148
|
-
return void 0;
|
|
37835
|
+
if (kind === "router" && input2.baseUrl !== void 0) {
|
|
37836
|
+
throw new ProviderKindMismatchError("A router provider has no base URL: it resolves each request's model name through the models block. Drop --base-url.");
|
|
38149
37837
|
}
|
|
38150
|
-
|
|
38151
|
-
|
|
38152
|
-
|
|
38153
|
-
|
|
37838
|
+
if (kind === "http" && input2.baseUrl === void 0) {
|
|
37839
|
+
throw new ProviderKindMismatchError("An http provider needs --base-url.");
|
|
37840
|
+
}
|
|
37841
|
+
if (kind === "router" && (input2.sources.length > 0 || input2.target !== void 0 || input2.env !== void 0 || input2.pickerModels !== void 0)) {
|
|
37842
|
+
throw new ProviderKindMismatchError("A router provider has no credential, env or picker models of its own: the models block's targets carry their own.");
|
|
37843
|
+
}
|
|
37844
|
+
if (kind !== "http" && kind !== "router" && input2.catalogue !== void 0) {
|
|
37845
|
+
throw new ProviderKindMismatchError("A model catalogue applies only to an http provider.");
|
|
37846
|
+
}
|
|
37847
|
+
if (kind !== "codex" && !isEmptyCodexConfig(input2.codex)) {
|
|
37848
|
+
throw new ProviderKindMismatchError("Codex settings apply only to a codex provider (--kind codex).");
|
|
37849
|
+
}
|
|
37850
|
+
if (kind !== "antigravity" && !isEmptyAntigravityConfig(input2.antigravity)) {
|
|
37851
|
+
throw new ProviderKindMismatchError("Antigravity settings apply only to an antigravity provider (--kind antigravity).");
|
|
37852
|
+
}
|
|
37853
|
+
const shared = {
|
|
37854
|
+
displayName: input2.displayName,
|
|
37855
|
+
credential: { sources: input2.sources, ...input2.target === void 0 ? {} : { target: input2.target } },
|
|
37856
|
+
...input2.env === void 0 || Object.keys(input2.env).length === 0 ? {} : { env: input2.env },
|
|
37857
|
+
...input2.pickerModels === void 0 || input2.pickerModels.length === 0 ? {} : { pickerModels: input2.pickerModels }
|
|
37858
|
+
};
|
|
37859
|
+
const parsed = ProviderSchema.safeParse(
|
|
37860
|
+
kind === "router" ? { kind, displayName: input2.displayName } : kind === "codex" ? { kind, ...shared, ...isEmptyCodexConfig(input2.codex) ? {} : { codex: input2.codex } } : kind === "antigravity" ? { kind, ...shared, ...isEmptyAntigravityConfig(input2.antigravity) ? {} : { antigravity: input2.antigravity } } : { ...shared, baseUrl: input2.baseUrl, ...input2.catalogue === void 0 ? {} : { catalogue: input2.catalogue } }
|
|
37861
|
+
);
|
|
37862
|
+
if (!parsed.success) {
|
|
37863
|
+
throw new ConfigValidationError(providerJsonPath(paths, name), parsed.error.issues);
|
|
37864
|
+
}
|
|
37865
|
+
writeJsonAtomic(providerJsonPath(paths, name), parsed.data);
|
|
37866
|
+
return parsed.data;
|
|
38154
37867
|
}
|
|
38155
|
-
function
|
|
38156
|
-
|
|
38157
|
-
|
|
37868
|
+
function updateProvider(paths, name, input2) {
|
|
37869
|
+
const existing = readProvider(paths, name);
|
|
37870
|
+
if (existing === void 0) {
|
|
37871
|
+
throw new ProviderNotFoundError(name);
|
|
38158
37872
|
}
|
|
38159
|
-
const
|
|
38160
|
-
const
|
|
38161
|
-
|
|
37873
|
+
const unset = new Set(input2.unsetEnv);
|
|
37874
|
+
const existingEnv = isRouterProvider(existing) ? {} : existing.env;
|
|
37875
|
+
const env = Object.fromEntries(Object.entries({ ...existingEnv, ...input2.env }).filter(([key]) => !unset.has(key)));
|
|
37876
|
+
const unsetPicker = new Set(input2.unsetPickerModels);
|
|
37877
|
+
const added = new Map((input2.pickerModels ?? []).map((entry) => [entry.model, entry]));
|
|
37878
|
+
const existingPicker = isRouterProvider(existing) ? [] : existing.pickerModels;
|
|
37879
|
+
const pickerModels = [
|
|
37880
|
+
...(existingPicker ?? []).filter((entry) => !unsetPicker.has(entry.model)).map((entry) => added.get(entry.model) ?? entry),
|
|
37881
|
+
...[...added.values()].filter((entry) => !(existingPicker ?? []).some((kept) => kept.model === entry.model))
|
|
37882
|
+
];
|
|
37883
|
+
const router = isRouterProvider(existing);
|
|
37884
|
+
const target = router ? void 0 : input2.target ?? existing.credential.target;
|
|
37885
|
+
const cache = router ? void 0 : input2.cache === void 0 ? existing.credential.cache : input2.cache === false ? void 0 : input2.cache;
|
|
37886
|
+
if (isCodexProvider(existing) && input2.baseUrl !== void 0) {
|
|
37887
|
+
throw new ProviderKindMismatchError(`Provider "${name}" is a codex provider, which has no base URL.`);
|
|
37888
|
+
}
|
|
37889
|
+
if (isAntigravityProvider(existing) && input2.baseUrl !== void 0) {
|
|
37890
|
+
throw new ProviderKindMismatchError(`Provider "${name}" is an antigravity provider, which has no base URL.`);
|
|
37891
|
+
}
|
|
37892
|
+
if ((isCodexProvider(existing) || isAntigravityProvider(existing)) && input2.catalogue !== void 0 && input2.catalogue !== false) {
|
|
37893
|
+
throw new ProviderKindMismatchError(`Provider "${name}" is not an http provider; a model catalogue applies only to an http provider.`);
|
|
37894
|
+
}
|
|
37895
|
+
if (!isCodexProvider(existing) && !isEmptyCodexConfig(input2.codex)) {
|
|
37896
|
+
throw new ProviderKindMismatchError(`Provider "${name}" is not a codex provider; codex settings apply only to a codex provider.`);
|
|
37897
|
+
}
|
|
37898
|
+
if (!isAntigravityProvider(existing) && !isEmptyAntigravityConfig(input2.antigravity)) {
|
|
37899
|
+
throw new ProviderKindMismatchError(`Provider "${name}" is not an antigravity provider; antigravity settings apply only to an antigravity provider.`);
|
|
37900
|
+
}
|
|
37901
|
+
const shared = {
|
|
37902
|
+
...input2.displayName === void 0 ? {} : { displayName: input2.displayName },
|
|
37903
|
+
...router ? {} : {
|
|
37904
|
+
credential: {
|
|
37905
|
+
sources: input2.sources ?? existing.credential.sources,
|
|
37906
|
+
...target === void 0 ? {} : { target },
|
|
37907
|
+
...cache === void 0 ? {} : { cache }
|
|
37908
|
+
}
|
|
37909
|
+
},
|
|
37910
|
+
env: Object.keys(env).length === 0 ? void 0 : env,
|
|
37911
|
+
pickerModels: pickerModels.length === 0 ? void 0 : pickerModels
|
|
37912
|
+
};
|
|
37913
|
+
let candidate;
|
|
37914
|
+
if (isCodexProvider(existing)) {
|
|
37915
|
+
const codex = {
|
|
37916
|
+
...existing.codex,
|
|
37917
|
+
...input2.codex,
|
|
37918
|
+
...existing.codex?.models === void 0 && input2.codex?.models === void 0 ? {} : { models: { ...existing.codex?.models, ...input2.codex?.models } }
|
|
37919
|
+
};
|
|
37920
|
+
candidate = { ...existing, ...shared, codex: isEmptyCodexConfig(codex) ? void 0 : codex };
|
|
37921
|
+
} else if (isAntigravityProvider(existing)) {
|
|
37922
|
+
const antigravity = {
|
|
37923
|
+
...existing.antigravity,
|
|
37924
|
+
...input2.antigravity,
|
|
37925
|
+
...existing.antigravity?.models === void 0 && input2.antigravity?.models === void 0 ? {} : { models: { ...existing.antigravity?.models, ...input2.antigravity?.models } }
|
|
37926
|
+
};
|
|
37927
|
+
candidate = { ...existing, ...shared, antigravity: isEmptyAntigravityConfig(antigravity) ? void 0 : antigravity };
|
|
37928
|
+
} else if (router) {
|
|
37929
|
+
candidate = { kind: "router", ...shared };
|
|
37930
|
+
} else {
|
|
37931
|
+
const catalogue = input2.catalogue === void 0 ? existing.catalogue : input2.catalogue === false ? void 0 : input2.catalogue;
|
|
37932
|
+
candidate = { ...existing, ...shared, catalogue, ...input2.baseUrl === void 0 ? {} : { baseUrl: input2.baseUrl } };
|
|
37933
|
+
}
|
|
37934
|
+
const parsed = ProviderSchema.safeParse(candidate);
|
|
37935
|
+
if (!parsed.success) {
|
|
37936
|
+
throw new ConfigValidationError(providerJsonPath(paths, name), parsed.error.issues);
|
|
37937
|
+
}
|
|
37938
|
+
writeJsonAtomic(providerJsonPath(paths, name), parsed.data);
|
|
37939
|
+
return parsed.data;
|
|
38162
37940
|
}
|
|
38163
|
-
function
|
|
38164
|
-
|
|
37941
|
+
function removeProvider(paths, name) {
|
|
37942
|
+
if (!providerExists(paths, name)) {
|
|
37943
|
+
throw new ProviderNotFoundError(name);
|
|
37944
|
+
}
|
|
37945
|
+
import_node_fs10.default.rmSync(providerJsonPath(paths, name));
|
|
38165
37946
|
}
|
|
38166
|
-
function
|
|
38167
|
-
|
|
38168
|
-
|
|
38169
|
-
|
|
38170
|
-
|
|
38171
|
-
class: "ineligible",
|
|
38172
|
-
...refusal2.blockedUntilMs === void 0 ? {} : { blockedUntilMs: refusal2.blockedUntilMs },
|
|
38173
|
-
plan: planOf(member.account),
|
|
38174
|
-
reasons: [refusal2.reason]
|
|
37947
|
+
function cascadeProviderName(cascade, identityProvider) {
|
|
37948
|
+
let name;
|
|
37949
|
+
for (const layer of assembleCascade(cascade).layers) {
|
|
37950
|
+
if (layer.launch?.provider !== void 0) {
|
|
37951
|
+
name = layer.launch.provider;
|
|
38175
37952
|
}
|
|
38176
|
-
}
|
|
37953
|
+
}
|
|
37954
|
+
return name ?? identityProvider;
|
|
38177
37955
|
}
|
|
38178
|
-
function
|
|
38179
|
-
const
|
|
38180
|
-
|
|
38181
|
-
|
|
37956
|
+
function selectProvider(params) {
|
|
37957
|
+
const cliName = params.cliProvider !== void 0 && params.cliProvider !== "" ? params.cliProvider : void 0;
|
|
37958
|
+
const named = cliName ?? (params.cascade === void 0 ? params.identityProvider : cascadeProviderName(params.cascade, params.identityProvider));
|
|
37959
|
+
if (named === void 0) {
|
|
37960
|
+
return void 0;
|
|
38182
37961
|
}
|
|
38183
|
-
|
|
38184
|
-
|
|
37962
|
+
const name = canonicalProviderName(named, (candidate) => loadProvider(params.paths.providersDir, candidate, params.port) !== void 0, () => loadProviderAliases(params.paths.providerAliasesFile, params.port));
|
|
37963
|
+
const definition = loadProvider(params.paths.providersDir, name, params.port);
|
|
37964
|
+
if (definition === void 0) {
|
|
37965
|
+
const known = listProviderNames(params.port.readdir, params.paths.providersDir);
|
|
37966
|
+
return {
|
|
37967
|
+
ok: false,
|
|
37968
|
+
status: 1,
|
|
37969
|
+
message: `agent-shim: no provider named "${name}". ` + (known.length > 0 ? `Known providers: ${known.join(", ")}.` : "No providers are defined yet; run `agent-shim provider add`.")
|
|
37970
|
+
};
|
|
38185
37971
|
}
|
|
38186
|
-
|
|
38187
|
-
return { ...assessment, candidate: { ...assessment.candidate, reasons: [`picked by pool "${nested.pool}"`, ...nested.reasons] } };
|
|
37972
|
+
return { ok: true, provider: { name, definition } };
|
|
38188
37973
|
}
|
|
38189
|
-
function
|
|
38190
|
-
const
|
|
38191
|
-
|
|
38192
|
-
|
|
38193
|
-
if (member.readError !== void 0) {
|
|
38194
|
-
return { candidate: { ...base, class: "unknown", reasons: [`usage state unreadable: ${member.readError}`, ...planReasons] } };
|
|
38195
|
-
}
|
|
38196
|
-
const state = member.snapshot?.providers[ANTHROPIC_PROVIDER];
|
|
38197
|
-
const unified = unifiedOf(state);
|
|
38198
|
-
if (member.snapshot === void 0 || state === void 0 || unified === void 0) {
|
|
38199
|
-
return { candidate: { ...base, class: "unknown", reasons: ["no usage recorded yet, so its quota is unknown (turn on trackUsage for it)", ...planReasons] } };
|
|
37974
|
+
function resolveProvider(params) {
|
|
37975
|
+
const selection = selectProvider(params);
|
|
37976
|
+
if (selection?.ok !== true) {
|
|
37977
|
+
return selection;
|
|
38200
37978
|
}
|
|
38201
|
-
const
|
|
38202
|
-
|
|
38203
|
-
|
|
38204
|
-
const five = fiveHourWindow === void 0 ? void 0 : effectiveWindow(fiveHourWindow, nowMs);
|
|
38205
|
-
const seven = sevenDayWindow === void 0 ? void 0 : effectiveWindow(sevenDayWindow, nowMs);
|
|
38206
|
-
const windowReasons = [
|
|
38207
|
-
...fiveHourWindow === void 0 || five === void 0 ? [] : [describeWindow("5h", fiveHourWindow, five, nowMs)],
|
|
38208
|
-
...sevenDayWindow === void 0 || seven === void 0 ? [] : [describeWindow("7d", sevenDayWindow, seven, nowMs)]
|
|
38209
|
-
];
|
|
38210
|
-
const overageWindow = soleOverageWindow(unified);
|
|
38211
|
-
const overage = overageWindow === void 0 ? void 0 : effectiveWindow(overageWindow, nowMs);
|
|
38212
|
-
const overageReasons = overageWindow === void 0 || overage === void 0 ? [] : [describeWindow("extra usage", overageWindow, overage, nowMs)];
|
|
38213
|
-
const blockedUntil = Math.max(
|
|
38214
|
-
windowBlockedUntil([five, seven, overage].flatMap((window) => window === void 0 ? [] : [window])) ?? 0,
|
|
38215
|
-
limitBlockedUntil(state, nowMs) ?? 0
|
|
38216
|
-
);
|
|
38217
|
-
if (blockedUntil > nowMs) {
|
|
38218
|
-
if (unified.overageStatus === "allowed") {
|
|
38219
|
-
return { candidate: { ...base, class: "pay-per-use", planReturnsAtMs: blockedUntil, reasons: [`plan exhausted until ${new Date(blockedUntil).toISOString()} (in ${formatAge(blockedUntil - nowMs)}), continues as extra usage`, ...windowReasons, ...planReasons] } };
|
|
38220
|
-
}
|
|
38221
|
-
return { candidate: { ...base, class: "ineligible", blockedUntilMs: blockedUntil, reasons: [`refused until ${new Date(blockedUntil).toISOString()} (in ${formatAge(blockedUntil - nowMs)})`, ...unified.fallbackAvailable === true ? ["a fallback is on offer, so requests for some models may still be served"] : [], ...windowReasons, ...overageReasons, ...planReasons] } };
|
|
37979
|
+
const { name, definition } = selection.provider;
|
|
37980
|
+
if (isRouterProvider(definition)) {
|
|
37981
|
+
return { ok: true, provider: { name, definition, credential: { target: "bearer", token: "", source: { env: "AGENT_SHIM_ROUTER" }, warnings: [] } }, warnings: [] };
|
|
38222
37982
|
}
|
|
38223
|
-
if (
|
|
38224
|
-
|
|
38225
|
-
return { candidate: { ...base, class: "pay-per-use", ...headroom === void 0 ? {} : { headroom }, reasons: [...plan.kind === "pay-per-use" ? planReasons : ["no plan windows reported, so usage bills as extra usage"], ...overageReasons] } };
|
|
37983
|
+
if (params.credentials === void 0) {
|
|
37984
|
+
return { ok: false, status: 1, message: `agent-shim: provider ${name} needs its credential resolved, but this launcher has no credential port wired` };
|
|
38226
37985
|
}
|
|
38227
|
-
const
|
|
38228
|
-
if (
|
|
38229
|
-
return {
|
|
37986
|
+
const resolution = resolveCredential({ credential: definition.credential, env: params.env, port: params.credentials, subject: `provider ${name}` });
|
|
37987
|
+
if (!resolution.ok) {
|
|
37988
|
+
return { ok: false, status: CREDENTIAL_UNAVAILABLE_EXIT, message: resolution.message };
|
|
38230
37989
|
}
|
|
38231
|
-
|
|
38232
|
-
const untilResetMs = basis.window.resetsAtMs === void 0 ? basis.windowMs : Math.max(basis.window.resetsAtMs - nowMs, MS_PER_SECOND5);
|
|
38233
|
-
const weeklyScore = remaining * plan.capacity / (untilResetMs / MS_PER_HOUR2);
|
|
38234
|
-
const fiveRemaining = five?.utilization === void 0 ? void 0 : Math.max(0, 1 - five.utilization);
|
|
38235
|
-
const fiveUntil = five?.resetsAtMs === void 0 ? FIVE_HOUR_WINDOW_MS : Math.max(five.resetsAtMs - nowMs, MS_PER_SECOND5);
|
|
38236
|
-
const ratio = windowRatio(member.records);
|
|
38237
|
-
const fiveHourScore = basis.name === "sevenDay" && fiveRemaining !== void 0 && ratio !== void 0 ? Math.min(fiveRemaining * ratio, remaining) * plan.capacity / (fiveUntil / MS_PER_HOUR2) : void 0;
|
|
38238
|
-
const fiveHourLeads = fiveHourScore !== void 0 && fiveHourScore > weeklyScore;
|
|
38239
|
-
const score = fiveHourLeads ? fiveHourScore : weeklyScore;
|
|
38240
|
-
const scoreWindow = fiveHourLeads ? "fiveHour" : basis.name;
|
|
38241
|
-
const fiveHourTermReasons = basis.name !== "sevenDay" || fiveRemaining === void 0 ? [] : ratio === void 0 ? ["5h reset not scored: no measured 5h to 7d ratio yet"] : fiveHourLeads ? [`5h term leads: ${percent(fiveRemaining)} of 5h unused is about ${percent(Math.min(fiveRemaining * ratio, remaining))} of the week at the measured ratio, resets in ${formatAge(fiveUntil)}`] : [];
|
|
38242
|
-
const burn = windowBurn(member.records, "fiveHour");
|
|
38243
|
-
const sevenRemaining = seven?.utilization === void 0 ? void 0 : Math.max(0, 1 - seven.utilization);
|
|
38244
|
-
const sevenUntil = seven?.resetsAtMs === void 0 ? SEVEN_DAY_WINDOW_MS : Math.max(seven.resetsAtMs - nowMs, MS_PER_SECOND5);
|
|
38245
|
-
const sevenDayBurn = windowBurn(member.records, "sevenDay");
|
|
38246
|
-
return {
|
|
38247
|
-
candidate: { ...base, class: "scored", score, scoreWindow, reasons: [...fiveHourTermReasons, ...windowReasons.map((reason, index) => index === windowReasons.length - 1 ? `${reason}${observedAgo}` : reason), ...planReasons] },
|
|
38248
|
-
...fiveRemaining === void 0 ? {} : { fiveHour: { remaining: fiveRemaining, untilResetMs: fiveUntil } },
|
|
38249
|
-
...burn === void 0 ? {} : { burn },
|
|
38250
|
-
...sevenRemaining === void 0 ? {} : { sevenDay: { remaining: sevenRemaining, untilResetMs: sevenUntil } },
|
|
38251
|
-
...sevenDayBurn === void 0 ? {} : { sevenDayBurn }
|
|
38252
|
-
};
|
|
38253
|
-
}
|
|
38254
|
-
function poolFactsOf(member, nowMs, resuming, sticky) {
|
|
38255
|
-
const { fiveHour, sevenDay, extraUsage } = quotaFactsOf(member.snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit?.unified, nowMs);
|
|
38256
|
-
const burn = windowBurn(member.records, "fiveHour");
|
|
38257
|
-
return {
|
|
38258
|
-
...fiveHour === void 0 ? {} : { fiveHour },
|
|
38259
|
-
...sevenDay === void 0 ? {} : { sevenDay },
|
|
38260
|
-
...extraUsage === void 0 ? {} : { extraUsage },
|
|
38261
|
-
...burn === void 0 ? {} : { burnPerHour: burn * MS_PER_HOUR2 },
|
|
38262
|
-
resuming,
|
|
38263
|
-
...sticky?.identity === member.identity ? { lastPickHoursAgo: Math.max(0, (nowMs - Date.parse(sticky.at)) / MS_PER_HOUR2) } : {}
|
|
38264
|
-
};
|
|
37990
|
+
return { ok: true, provider: { name, definition, credential: resolution.credential }, warnings: resolution.credential.warnings };
|
|
38265
37991
|
}
|
|
38266
|
-
function
|
|
38267
|
-
const {
|
|
38268
|
-
|
|
38269
|
-
|
|
38270
|
-
|
|
38271
|
-
const
|
|
38272
|
-
|
|
38273
|
-
|
|
38274
|
-
|
|
38275
|
-
|
|
38276
|
-
|
|
38277
|
-
|
|
38278
|
-
if (verdict.status === "indeterminate") {
|
|
38279
|
-
return { ...assessment, candidate: { ...candidate, policyDemoted: true, reasons: [`policy undecided (${verdict.checked.join(", ") === "predicate" ? "predicate" : verdict.checked.join(", ")}): ${verdict.reason}`, ...candidate.reasons] } };
|
|
38280
|
-
}
|
|
38281
|
-
if (verdict.passed) {
|
|
38282
|
-
return assessment;
|
|
38283
|
-
}
|
|
38284
|
-
return { ...assessment, candidate: { ...candidate, class: "ineligible", reasons: [`skipped by policy (${verdict.checked.join(", ")}: did not hold)`, ...candidate.reasons] } };
|
|
38285
|
-
});
|
|
38286
|
-
const candidates = guarded2.map((assessment) => {
|
|
38287
|
-
const { candidate, fiveHour, burn } = assessment;
|
|
38288
|
-
const pace = burn ?? (sharedDemand === void 0 ? void 0 : sharedDemand / capacityOf(candidate.plan));
|
|
38289
|
-
const { sevenDay, sevenDayBurn } = assessment;
|
|
38290
|
-
if (candidate.class !== "scored") {
|
|
38291
|
-
return { ...candidate, feasible: true };
|
|
38292
|
-
}
|
|
38293
|
-
const drySpots = [];
|
|
38294
|
-
const dryAfterMs = [];
|
|
38295
|
-
if (fiveHour !== void 0 && pace !== void 0) {
|
|
38296
|
-
const runsDryInMs = fiveHour.remaining / pace;
|
|
38297
|
-
if (runsDryInMs < fiveHour.untilResetMs) {
|
|
38298
|
-
dryAfterMs.push(runsDryInMs);
|
|
38299
|
-
drySpots.push(`5h window would run dry in ${formatAge(runsDryInMs)}, before it resets in ${formatAge(fiveHour.untilResetMs)}`);
|
|
38300
|
-
}
|
|
38301
|
-
}
|
|
38302
|
-
if (sevenDay !== void 0 && sevenDayBurn !== void 0) {
|
|
38303
|
-
const runsDryInMs = sevenDay.remaining / sevenDayBurn;
|
|
38304
|
-
if (runsDryInMs < sevenDay.untilResetMs) {
|
|
38305
|
-
dryAfterMs.push(runsDryInMs);
|
|
38306
|
-
drySpots.push(`7d window would run dry in ${formatAge(runsDryInMs)}, before it resets in ${formatAge(sevenDay.untilResetMs)}`);
|
|
37992
|
+
function resolveRoutedProviderCredentials(params) {
|
|
37993
|
+
const { models } = params;
|
|
37994
|
+
if (models === void 0) {
|
|
37995
|
+
return { ok: true, checked: [] };
|
|
37996
|
+
}
|
|
37997
|
+
const virtualNames = new Set(Object.keys(models.virtual ?? {}));
|
|
37998
|
+
const providerNames = /* @__PURE__ */ new Set();
|
|
37999
|
+
const families = () => buildFamilies(params.targets?.() ?? [], models);
|
|
38000
|
+
const collect = (ref) => {
|
|
38001
|
+
if (ref.startsWith(FAMILY_PREFIX)) {
|
|
38002
|
+
for (const target of expandFamilyMembers([ref], families())) {
|
|
38003
|
+
collect(target);
|
|
38307
38004
|
}
|
|
38005
|
+
return;
|
|
38308
38006
|
}
|
|
38309
|
-
|
|
38310
|
-
|
|
38311
|
-
if (input2.resuming && input2.resumeContextTokens !== void 0 && fiveHour !== void 0 && !warmHere) {
|
|
38312
|
-
const perToken = utilisationPerBilledToken(assessment.member.records);
|
|
38313
|
-
const committed = input2.committedContextTokens?.[candidate.identity] ?? 0;
|
|
38314
|
-
const cost = perToken === void 0 ? void 0 : (input2.resumeContextTokens + committed) * perToken;
|
|
38315
|
-
if (cost !== void 0 && cost > fiveHour.remaining) {
|
|
38316
|
-
dryAfterMs.push(0);
|
|
38317
|
-
const alongside = committed === 0 ? "" : ` (with ${String(committed)} tokens of other conversations already moving here)`;
|
|
38318
|
-
drySpots.push(`resuming a ${String(input2.resumeContextTokens)}-token conversation here${alongside} would cost about ${percent(cost)} of the 5h window, which has ${percent(fiveHour.remaining)} left`);
|
|
38319
|
-
}
|
|
38007
|
+
if (ref.startsWith("acct:") || virtualNames.has(ref)) {
|
|
38008
|
+
return;
|
|
38320
38009
|
}
|
|
38321
|
-
|
|
38322
|
-
|
|
38010
|
+
const [provider] = ref.split("/", 1);
|
|
38011
|
+
if (provider !== void 0 && provider !== "") {
|
|
38012
|
+
providerNames.add(provider);
|
|
38323
38013
|
}
|
|
38324
|
-
|
|
38325
|
-
})
|
|
38326
|
-
|
|
38327
|
-
|
|
38328
|
-
);
|
|
38329
|
-
const sticky = input2.sticky;
|
|
38330
|
-
const stickyIndex = sticky === void 0 ? -1 : ordered.findIndex((candidate) => candidate.identity === sticky.identity);
|
|
38331
|
-
const stickyCandidate = ordered[stickyIndex];
|
|
38332
|
-
const keepSticky = stickyCandidate?.class === "scored" && stickyCandidate.feasible;
|
|
38333
|
-
if (sticky !== void 0 && keepSticky) {
|
|
38334
|
-
const ageMs = nowMs - Date.parse(sticky.at);
|
|
38335
|
-
const warm = ageMs <= PROMPT_CACHE_TTL_MS;
|
|
38336
|
-
if (input2.resuming || warm) {
|
|
38337
|
-
const why = warm ? `used here ${formatAge(ageMs)} ago, prompt cache still warm` : "resuming a conversation started on this account";
|
|
38338
|
-
ordered.splice(stickyIndex, 1);
|
|
38339
|
-
ordered.unshift({ ...stickyCandidate, reasons: [why, ...stickyCandidate.reasons] });
|
|
38014
|
+
};
|
|
38015
|
+
for (const model of Object.values(models.virtual ?? {})) {
|
|
38016
|
+
for (const member of model.members) {
|
|
38017
|
+
collect(member);
|
|
38340
38018
|
}
|
|
38341
38019
|
}
|
|
38342
|
-
const
|
|
38343
|
-
|
|
38344
|
-
const returns = ordered.flatMap((candidate) => candidate.blockedUntilMs === void 0 ? [] : [{ identity: candidate.identity, atMs: candidate.blockedUntilMs }]);
|
|
38345
|
-
const earliestReturn = returns.length === 0 ? void 0 : returns.reduce((soonest, entry) => entry.atMs < soonest.atMs ? entry : soonest);
|
|
38346
|
-
const holdForReturn = pick2?.runsDryAtMs === void 0 ? void 0 : returns.filter((entry) => entry.atMs < (pick2.runsDryAtMs ?? 0)).reduce((soonest, entry) => soonest === void 0 || entry.atMs < soonest.atMs ? entry : soonest, void 0);
|
|
38347
|
-
return {
|
|
38348
|
-
candidates: ordered,
|
|
38349
|
-
...pick2 === void 0 ? { ...earliestReturn === void 0 ? {} : { earliestReturn } } : { pick: pick2 },
|
|
38350
|
-
...movedOff === void 0 || pick2 === void 0 ? {} : { movedOff },
|
|
38351
|
-
...pick2?.planReturnsAtMs === void 0 ? {} : { planReturn: { identity: pick2.identity, atMs: pick2.planReturnsAtMs } },
|
|
38352
|
-
...holdForReturn === void 0 ? {} : { holdForReturn }
|
|
38353
|
-
};
|
|
38354
|
-
}
|
|
38355
|
-
var MS_PER_SECOND5, MS_PER_HOUR2, HOURS_PER_DAY2, FIVE_HOURS, PROMPT_CACHE_TTL_HOURS, PERCENT, SEVEN_DAYS, FIVE_HOUR_WINDOW_MS, SEVEN_DAY_WINDOW_MS, PROMPT_CACHE_TTL_MS, CLASS_ORDER;
|
|
38356
|
-
var init_pick = __esm({
|
|
38357
|
-
"src/usage/pick.ts"() {
|
|
38358
|
-
"use strict";
|
|
38359
|
-
init_conditions();
|
|
38360
|
-
init_plan2();
|
|
38361
|
-
init_middleware();
|
|
38362
|
-
init_preflight();
|
|
38363
|
-
init_quotaFacts();
|
|
38364
|
-
init_rateLimit();
|
|
38365
|
-
MS_PER_SECOND5 = 1e3;
|
|
38366
|
-
MS_PER_HOUR2 = 36e5;
|
|
38367
|
-
HOURS_PER_DAY2 = 24;
|
|
38368
|
-
FIVE_HOURS = 5;
|
|
38369
|
-
PROMPT_CACHE_TTL_HOURS = 1;
|
|
38370
|
-
PERCENT = 100;
|
|
38371
|
-
SEVEN_DAYS = 7;
|
|
38372
|
-
FIVE_HOUR_WINDOW_MS = FIVE_HOURS * MS_PER_HOUR2;
|
|
38373
|
-
SEVEN_DAY_WINDOW_MS = SEVEN_DAYS * HOURS_PER_DAY2 * MS_PER_HOUR2;
|
|
38374
|
-
PROMPT_CACHE_TTL_MS = PROMPT_CACHE_TTL_HOURS * MS_PER_HOUR2;
|
|
38375
|
-
CLASS_ORDER = { scored: 0, unknown: 1, "pay-per-use": 2, ineligible: 3 };
|
|
38020
|
+
for (const ref of Object.values(models.tiers ?? {})) {
|
|
38021
|
+
collect(ref);
|
|
38376
38022
|
}
|
|
38377
|
-
|
|
38378
|
-
|
|
38379
|
-
|
|
38380
|
-
|
|
38381
|
-
|
|
38382
|
-
}
|
|
38383
|
-
|
|
38384
|
-
|
|
38385
|
-
|
|
38386
|
-
|
|
38387
|
-
|
|
38388
|
-
|
|
38389
|
-
const day = match?.[1];
|
|
38390
|
-
if (day === void 0) {
|
|
38391
|
-
return [];
|
|
38392
|
-
}
|
|
38393
|
-
return [{ name, day, endsAt: Date.parse(`${day}T00:00:00.000Z`) + DAY_MS }];
|
|
38394
|
-
}).sort((left, right) => left.day.localeCompare(right.day) || left.name.localeCompare(right.name));
|
|
38395
|
-
}
|
|
38396
|
-
function readUsageLog(fs31, logDir, options = {}) {
|
|
38397
|
-
const { sinceMs } = options;
|
|
38398
|
-
const records = [];
|
|
38399
|
-
let invalidLines = 0;
|
|
38400
|
-
for (const segment of listLogSegments(fs31, logDir)) {
|
|
38401
|
-
if (sinceMs !== void 0 && segment.endsAt <= sinceMs) {
|
|
38023
|
+
if (providerNames.size === 0) {
|
|
38024
|
+
return { ok: true, checked: [] };
|
|
38025
|
+
}
|
|
38026
|
+
if (params.credentials === void 0) {
|
|
38027
|
+
return { ok: false, status: 1, message: `agent-shim: the models block routes to providers ${[...providerNames].sort().join(", ")}, which need their credentials resolved, but this launcher has no credential port wired` };
|
|
38028
|
+
}
|
|
38029
|
+
const failures = [];
|
|
38030
|
+
let credentialFailure = false;
|
|
38031
|
+
for (const name of [...providerNames].sort()) {
|
|
38032
|
+
const definition = loadProvider(params.paths.providersDir, name, params.port);
|
|
38033
|
+
if (definition === void 0) {
|
|
38034
|
+
failures.push(`no provider named "${name}"`);
|
|
38402
38035
|
continue;
|
|
38403
38036
|
}
|
|
38404
|
-
|
|
38405
|
-
if (read === void 0) {
|
|
38037
|
+
if (isRouterProvider(definition)) {
|
|
38406
38038
|
continue;
|
|
38407
38039
|
}
|
|
38408
|
-
|
|
38409
|
-
|
|
38410
|
-
|
|
38411
|
-
|
|
38040
|
+
const resolution = resolveCredential({ credential: definition.credential, env: params.env, port: params.credentials, subject: `provider ${name}` });
|
|
38041
|
+
if (!resolution.ok) {
|
|
38042
|
+
failures.push(resolution.message.replace(/^agent-shim: /, ""));
|
|
38043
|
+
credentialFailure = true;
|
|
38044
|
+
}
|
|
38045
|
+
}
|
|
38046
|
+
if (failures.length > 0) {
|
|
38047
|
+
return { ok: false, status: credentialFailure ? CREDENTIAL_UNAVAILABLE_EXIT : 1, message: `agent-shim: this launch routes model names through the models block, but: ${failures.join("; ")}` };
|
|
38048
|
+
}
|
|
38049
|
+
return { ok: true, checked: [...providerNames].sort() };
|
|
38050
|
+
}
|
|
38051
|
+
var import_node_fs10, ProviderNotFoundError, ProviderAlreadyExistsError, LEGACY_PROVIDER_FIELDS, LEGACY_ENV_CREDENTIAL_KEYS, LEGACY_LITERAL_PLACEHOLDER, LegacyProviderFileError, ProviderKindMismatchError;
|
|
38052
|
+
var init_providersStore = __esm({
|
|
38053
|
+
"src/providersStore.ts"() {
|
|
38054
|
+
"use strict";
|
|
38055
|
+
import_node_fs10 = __toESM(require("node:fs"), 1);
|
|
38056
|
+
init_load();
|
|
38057
|
+
init_store();
|
|
38058
|
+
init_unrecognisedKeys();
|
|
38059
|
+
init_schema();
|
|
38060
|
+
init_cliError();
|
|
38061
|
+
init_providerAliases();
|
|
38062
|
+
init_credential();
|
|
38063
|
+
init_walk();
|
|
38064
|
+
init_families();
|
|
38065
|
+
init_names();
|
|
38066
|
+
ProviderNotFoundError = class extends CliError {
|
|
38067
|
+
constructor(name) {
|
|
38068
|
+
super(`No provider named "${name}". Run \`agent-shim provider add ${name}\` first.`);
|
|
38069
|
+
this.name = name;
|
|
38070
|
+
this.name = "ProviderNotFoundError";
|
|
38071
|
+
}
|
|
38072
|
+
name;
|
|
38073
|
+
};
|
|
38074
|
+
ProviderAlreadyExistsError = class extends CliError {
|
|
38075
|
+
constructor(providerName) {
|
|
38076
|
+
super(`A provider named "${providerName}" already exists.`);
|
|
38077
|
+
this.providerName = providerName;
|
|
38078
|
+
this.name = "ProviderAlreadyExistsError";
|
|
38079
|
+
}
|
|
38080
|
+
providerName;
|
|
38081
|
+
};
|
|
38082
|
+
LEGACY_PROVIDER_FIELDS = ["tokenEnv", "tokenCommand", "authScheme"];
|
|
38083
|
+
LEGACY_ENV_CREDENTIAL_KEYS = Object.values(CREDENTIAL_TARGET_VARS);
|
|
38084
|
+
LEGACY_LITERAL_PLACEHOLDER = "<the value of env.ANTHROPIC_AUTH_TOKEN>";
|
|
38085
|
+
LegacyProviderFileError = class extends CliError {
|
|
38086
|
+
constructor(filePath, conversion) {
|
|
38087
|
+
super(
|
|
38088
|
+
`${filePath} uses ${conversion.fields.join(", ")}, which a credential block replaced. Rewrite it as:
|
|
38089
|
+
` + JSON.stringify(conversion.replacement, null, 2)
|
|
38090
|
+
);
|
|
38091
|
+
this.filePath = filePath;
|
|
38092
|
+
this.conversion = conversion;
|
|
38093
|
+
this.name = "LegacyProviderFileError";
|
|
38412
38094
|
}
|
|
38413
|
-
|
|
38095
|
+
filePath;
|
|
38096
|
+
conversion;
|
|
38097
|
+
};
|
|
38098
|
+
ProviderKindMismatchError = class extends UsageError {
|
|
38099
|
+
constructor(message) {
|
|
38100
|
+
super(message);
|
|
38101
|
+
this.name = "ProviderKindMismatchError";
|
|
38102
|
+
}
|
|
38103
|
+
};
|
|
38414
38104
|
}
|
|
38415
|
-
|
|
38416
|
-
|
|
38105
|
+
});
|
|
38106
|
+
|
|
38107
|
+
// src/usage/account.ts
|
|
38108
|
+
function isObject2(value2) {
|
|
38109
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
38417
38110
|
}
|
|
38418
|
-
function
|
|
38419
|
-
|
|
38420
|
-
if (contents === void 0) {
|
|
38421
|
-
return void 0;
|
|
38422
|
-
}
|
|
38423
|
-
const records = [];
|
|
38424
|
-
let invalidLines = 0;
|
|
38425
|
-
const lines = contents.split("\n");
|
|
38426
|
-
lines.pop();
|
|
38427
|
-
for (const line of lines) {
|
|
38428
|
-
if (line === "") {
|
|
38429
|
-
continue;
|
|
38430
|
-
}
|
|
38431
|
-
let raw;
|
|
38432
|
-
try {
|
|
38433
|
-
raw = JSON.parse(line);
|
|
38434
|
-
} catch {
|
|
38435
|
-
invalidLines += 1;
|
|
38436
|
-
continue;
|
|
38437
|
-
}
|
|
38438
|
-
const parsed = UsageRecordSchema.safeParse(raw);
|
|
38439
|
-
if (!parsed.success) {
|
|
38440
|
-
invalidLines += 1;
|
|
38441
|
-
continue;
|
|
38442
|
-
}
|
|
38443
|
-
records.push(parsed.data);
|
|
38444
|
-
}
|
|
38445
|
-
return { records, invalidLines };
|
|
38111
|
+
function isIdentityName(name) {
|
|
38112
|
+
return IdentitySchema.shape.name.safeParse(name).success;
|
|
38446
38113
|
}
|
|
38447
|
-
function
|
|
38448
|
-
|
|
38449
|
-
for (const segment of listLogSegments(fs31, logDir)) {
|
|
38450
|
-
byDay.set(segment.day, [...byDay.get(segment.day) ?? [], segment]);
|
|
38451
|
-
}
|
|
38452
|
-
const days = [...byDay.values()];
|
|
38453
|
-
let records = [];
|
|
38454
|
-
for (let index = days.length - 1; index >= 0; index -= 1) {
|
|
38455
|
-
const dayRecords = [];
|
|
38456
|
-
for (const segment of days[index] ?? []) {
|
|
38457
|
-
dayRecords.push(...readSegment(fs31, logDir, segment)?.records ?? []);
|
|
38458
|
-
}
|
|
38459
|
-
records = [...dayRecords, ...records];
|
|
38460
|
-
records.sort((left, right) => left.at.localeCompare(right.at));
|
|
38461
|
-
const olderDay = days[index - 1]?.[0];
|
|
38462
|
-
const newestHeld = records[records.length - count2];
|
|
38463
|
-
if (olderDay === void 0 || newestHeld !== void 0 && Date.parse(newestHeld.at) >= olderDay.endsAt) {
|
|
38464
|
-
break;
|
|
38465
|
-
}
|
|
38466
|
-
}
|
|
38467
|
-
return records.slice(-count2);
|
|
38114
|
+
function claudeJsonPath(identitiesDir, identity) {
|
|
38115
|
+
return import_node_path24.default.join(identitiesDir, identity, CLAUDE_JSON);
|
|
38468
38116
|
}
|
|
38469
|
-
function
|
|
38117
|
+
function readAccountMetadata(fs31, identitiesDir, identity) {
|
|
38470
38118
|
if (!isIdentityName(identity)) {
|
|
38471
38119
|
throw new Error(`"${identity}" is not a valid identity name.`);
|
|
38472
38120
|
}
|
|
38473
|
-
return
|
|
38121
|
+
return readAccountMetadataFile(fs31, claudeJsonPath(identitiesDir, identity));
|
|
38474
38122
|
}
|
|
38475
|
-
function
|
|
38476
|
-
const file2 = snapshotPath(snapshotsDir, identity);
|
|
38123
|
+
function readAccountMetadataFile(fs31, file2) {
|
|
38477
38124
|
const raw = fs31.readFileUtf8(file2);
|
|
38478
38125
|
if (raw === void 0) {
|
|
38479
38126
|
return void 0;
|
|
@@ -38482,1225 +38129,1586 @@ function readUsageSnapshot(fs31, snapshotsDir, identity) {
|
|
|
38482
38129
|
try {
|
|
38483
38130
|
parsed = JSON.parse(raw);
|
|
38484
38131
|
} catch {
|
|
38485
|
-
throw new
|
|
38132
|
+
throw new AccountMetadataError(file2, "not valid JSON");
|
|
38486
38133
|
}
|
|
38487
|
-
|
|
38488
|
-
|
|
38489
|
-
throw new UsageSnapshotError(file2, snapshot.error.issues.map((issue2) => `${issue2.path.join(".")}: ${issue2.message}`).join("; "));
|
|
38134
|
+
if (!isObject2(parsed)) {
|
|
38135
|
+
throw new AccountMetadataError(file2, "not a JSON object");
|
|
38490
38136
|
}
|
|
38491
|
-
|
|
38492
|
-
|
|
38493
|
-
|
|
38494
|
-
|
|
38495
|
-
|
|
38496
|
-
|
|
38497
|
-
|
|
38498
|
-
|
|
38499
|
-
|
|
38500
|
-
return [];
|
|
38501
|
-
}
|
|
38502
|
-
const snapshot = readUsageSnapshot(fs31, snapshotsDir, identity);
|
|
38503
|
-
return snapshot === void 0 ? [] : [snapshot];
|
|
38504
|
-
}).sort((left, right) => left.identity.localeCompare(right.identity));
|
|
38505
|
-
}
|
|
38506
|
-
function summariseUsage(records) {
|
|
38507
|
-
const groups = /* @__PURE__ */ new Map();
|
|
38508
|
-
for (const record2 of records) {
|
|
38509
|
-
const key = `${record2.identity ?? ""}\0${record2.provider}`;
|
|
38510
|
-
const group = groups.get(key);
|
|
38511
|
-
if (group === void 0) {
|
|
38512
|
-
groups.set(key, [record2]);
|
|
38513
|
-
} else {
|
|
38514
|
-
group.push(record2);
|
|
38137
|
+
const oauthAccount = parsed.oauthAccount;
|
|
38138
|
+
if (!isObject2(oauthAccount)) {
|
|
38139
|
+
return void 0;
|
|
38140
|
+
}
|
|
38141
|
+
const picked = {};
|
|
38142
|
+
for (const key of Object.keys(AccountMetadataSchema.shape)) {
|
|
38143
|
+
const value2 = oauthAccount[key];
|
|
38144
|
+
if (value2 !== null && value2 !== void 0) {
|
|
38145
|
+
picked[key] = value2;
|
|
38515
38146
|
}
|
|
38516
38147
|
}
|
|
38517
|
-
const
|
|
38518
|
-
|
|
38519
|
-
|
|
38520
|
-
|
|
38521
|
-
|
|
38148
|
+
const account = AccountMetadataSchema.safeParse(picked);
|
|
38149
|
+
if (!account.success) {
|
|
38150
|
+
throw new AccountMetadataError(file2, account.error.issues.map((issue2) => `${issue2.path.join(".")}: ${issue2.message}`).join("; "));
|
|
38151
|
+
}
|
|
38152
|
+
return account.data;
|
|
38153
|
+
}
|
|
38154
|
+
function createAccountReader(fs31, identitiesDir) {
|
|
38155
|
+
const cache = /* @__PURE__ */ new Map();
|
|
38156
|
+
return (identity) => {
|
|
38157
|
+
if (!isIdentityName(identity)) {
|
|
38158
|
+
throw new Error(`"${identity}" is not a valid identity name.`);
|
|
38522
38159
|
}
|
|
38523
|
-
const
|
|
38524
|
-
|
|
38525
|
-
|
|
38526
|
-
|
|
38527
|
-
|
|
38160
|
+
const stat = fs31.lstat(claudeJsonPath(identitiesDir, identity));
|
|
38161
|
+
const stamp = stat === void 0 ? "absent" : `${String(stat.mtimeMs)}:${String(stat.sizeBytes)}`;
|
|
38162
|
+
const cached2 = cache.get(identity);
|
|
38163
|
+
if (cached2?.stamp === stamp) {
|
|
38164
|
+
return cached2.account;
|
|
38528
38165
|
}
|
|
38529
|
-
const
|
|
38530
|
-
|
|
38531
|
-
|
|
38532
|
-
|
|
38533
|
-
provider: first.provider,
|
|
38534
|
-
requests: group.length,
|
|
38535
|
-
failed: group.filter((record2) => record2.status >= FIRST_ERROR_STATUS).length,
|
|
38536
|
-
limits: {
|
|
38537
|
-
"rate-limited": group.filter((record2) => record2.limit?.kind === "rate-limited").length,
|
|
38538
|
-
"quota-exhausted": group.filter((record2) => record2.limit?.kind === "quota-exhausted").length
|
|
38539
|
-
},
|
|
38540
|
-
tokens: {
|
|
38541
|
-
inputTokens: sum2("inputTokens"),
|
|
38542
|
-
outputTokens: sum2("outputTokens"),
|
|
38543
|
-
cacheCreationInputTokens: sum2("cacheCreationInputTokens"),
|
|
38544
|
-
cacheReadInputTokens: sum2("cacheReadInputTokens")
|
|
38545
|
-
},
|
|
38546
|
-
firstAt: first.at,
|
|
38547
|
-
lastAt: last.at,
|
|
38548
|
-
models: [...modelCounts.entries()].sort((left, right) => right[1] - left[1] || left[0].localeCompare(right[0])).map(([model]) => model)
|
|
38549
|
-
}
|
|
38550
|
-
];
|
|
38551
|
-
});
|
|
38552
|
-
return summaries.sort((left, right) => (left.identity ?? "").localeCompare(right.identity ?? "") || left.provider.localeCompare(right.provider));
|
|
38166
|
+
const account = readAccountMetadata(fs31, identitiesDir, identity);
|
|
38167
|
+
cache.set(identity, { stamp, account });
|
|
38168
|
+
return account;
|
|
38169
|
+
};
|
|
38553
38170
|
}
|
|
38554
|
-
var
|
|
38555
|
-
var
|
|
38556
|
-
"src/usage/
|
|
38171
|
+
var import_node_path24, CLAUDE_JSON, AccountMetadataError;
|
|
38172
|
+
var init_account = __esm({
|
|
38173
|
+
"src/usage/account.ts"() {
|
|
38557
38174
|
"use strict";
|
|
38558
|
-
|
|
38559
|
-
|
|
38175
|
+
import_node_path24 = __toESM(require("node:path"), 1);
|
|
38176
|
+
init_cliError();
|
|
38177
|
+
init_schema();
|
|
38560
38178
|
init_schema2();
|
|
38561
|
-
|
|
38562
|
-
|
|
38563
|
-
UsageSnapshotError = class extends Error {
|
|
38179
|
+
CLAUDE_JSON = ".claude.json";
|
|
38180
|
+
AccountMetadataError = class extends CliError {
|
|
38564
38181
|
constructor(file2, detail) {
|
|
38565
|
-
super(`${file2}
|
|
38182
|
+
super(`${file2}: ${detail}, so its account metadata cannot be read.`);
|
|
38566
38183
|
this.file = file2;
|
|
38567
|
-
this.name = "
|
|
38184
|
+
this.name = "AccountMetadataError";
|
|
38568
38185
|
}
|
|
38569
38186
|
file;
|
|
38570
38187
|
};
|
|
38571
|
-
FIRST_ERROR_STATUS = 400;
|
|
38572
38188
|
}
|
|
38573
38189
|
});
|
|
38574
38190
|
|
|
38575
|
-
//
|
|
38576
|
-
|
|
38577
|
-
|
|
38578
|
-
|
|
38579
|
-
|
|
38580
|
-
|
|
38581
|
-
|
|
38582
|
-
|
|
38583
|
-
|
|
38584
|
-
|
|
38585
|
-
|
|
38586
|
-
|
|
38587
|
-
|
|
38588
|
-
|
|
38589
|
-
|
|
38590
|
-
|
|
38591
|
-
|
|
38592
|
-
|
|
38593
|
-
|
|
38594
|
-
|
|
38595
|
-
|
|
38596
|
-
|
|
38597
|
-
|
|
38598
|
-
|
|
38599
|
-
|
|
38600
|
-
|
|
38601
|
-
|
|
38602
|
-
|
|
38603
|
-
|
|
38604
|
-
|
|
38605
|
-
|
|
38606
|
-
|
|
38607
|
-
|
|
38608
|
-
|
|
38609
|
-
|
|
38610
|
-
|
|
38611
|
-
|
|
38612
|
-
|
|
38613
|
-
|
|
38614
|
-
|
|
38615
|
-
|
|
38616
|
-
|
|
38617
|
-
|
|
38618
|
-
|
|
38619
|
-
|
|
38620
|
-
|
|
38621
|
-
|
|
38622
|
-
|
|
38623
|
-
|
|
38624
|
-
|
|
38625
|
-
|
|
38626
|
-
|
|
38627
|
-
|
|
38628
|
-
|
|
38629
|
-
|
|
38630
|
-
|
|
38631
|
-
|
|
38632
|
-
|
|
38633
|
-
|
|
38634
|
-
|
|
38635
|
-
|
|
38636
|
-
|
|
38637
|
-
|
|
38638
|
-
|
|
38639
|
-
|
|
38640
|
-
|
|
38641
|
-
|
|
38642
|
-
|
|
38643
|
-
|
|
38644
|
-
|
|
38645
|
-
|
|
38646
|
-
|
|
38647
|
-
|
|
38648
|
-
|
|
38649
|
-
|
|
38650
|
-
|
|
38651
|
-
|
|
38652
|
-
|
|
38653
|
-
|
|
38654
|
-
|
|
38655
|
-
|
|
38656
|
-
|
|
38657
|
-
|
|
38658
|
-
|
|
38659
|
-
|
|
38660
|
-
|
|
38661
|
-
|
|
38662
|
-
|
|
38663
|
-
|
|
38664
|
-
|
|
38665
|
-
|
|
38666
|
-
|
|
38667
|
-
|
|
38668
|
-
|
|
38669
|
-
|
|
38670
|
-
|
|
38671
|
-
|
|
38672
|
-
|
|
38191
|
+
// package.json
|
|
38192
|
+
var package_default;
|
|
38193
|
+
var init_package = __esm({
|
|
38194
|
+
"package.json"() {
|
|
38195
|
+
package_default = {
|
|
38196
|
+
name: "agent-shim",
|
|
38197
|
+
version: "11.76.0",
|
|
38198
|
+
description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
|
|
38199
|
+
license: "MIT",
|
|
38200
|
+
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
38201
|
+
repository: {
|
|
38202
|
+
type: "git",
|
|
38203
|
+
url: "git+https://github.com/ExaDev/agent-shim.git"
|
|
38204
|
+
},
|
|
38205
|
+
homepage: "https://github.com/ExaDev/agent-shim#readme",
|
|
38206
|
+
bugs: "https://github.com/ExaDev/agent-shim/issues",
|
|
38207
|
+
keywords: [
|
|
38208
|
+
"claude-code",
|
|
38209
|
+
"claude",
|
|
38210
|
+
"cli"
|
|
38211
|
+
],
|
|
38212
|
+
packageManager: "pnpm@12.4.1+sha512.2e81e399d73fe8390dab25e06aa788ab7a5908248d2f5a370f82b481147a6a7a367bf8048f9a6fdb6460f21a66f0542dedb8b94ca2c8723596741920b1656d4c",
|
|
38213
|
+
type: "module",
|
|
38214
|
+
engines: {
|
|
38215
|
+
node: "^22.18 || >=24"
|
|
38216
|
+
},
|
|
38217
|
+
bin: {
|
|
38218
|
+
"agent-shim": "dist/cli.cjs",
|
|
38219
|
+
"claude-use": "dist/cli.cjs"
|
|
38220
|
+
},
|
|
38221
|
+
files: [
|
|
38222
|
+
"dist/cli.cjs",
|
|
38223
|
+
"dist/index.mjs",
|
|
38224
|
+
"dist/index.cjs",
|
|
38225
|
+
"dist/types"
|
|
38226
|
+
],
|
|
38227
|
+
scripts: {
|
|
38228
|
+
prepare: "husky && node scripts/build.mts --bundle-only",
|
|
38229
|
+
typecheck: "turbo run _typecheck",
|
|
38230
|
+
_typecheck: "tsc --noEmit",
|
|
38231
|
+
lint: "turbo run _lint",
|
|
38232
|
+
_lint: "eslint . --cache --cache-location .eslintcache --max-warnings 0",
|
|
38233
|
+
test: "turbo run _test",
|
|
38234
|
+
_test: "vitest run",
|
|
38235
|
+
"test:coverage": "turbo run _test:coverage",
|
|
38236
|
+
"_test:coverage": "vitest run --coverage",
|
|
38237
|
+
knip: "turbo run _knip",
|
|
38238
|
+
_knip: "knip --cache",
|
|
38239
|
+
build: "turbo run _build",
|
|
38240
|
+
_build: "node scripts/build.mts",
|
|
38241
|
+
"build:bundle": "node scripts/build.mts --bundle-only",
|
|
38242
|
+
prepublishOnly: "pnpm build:bundle",
|
|
38243
|
+
schema: "node scripts/gen-schema.mts"
|
|
38244
|
+
},
|
|
38245
|
+
dependencies: {
|
|
38246
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.292",
|
|
38247
|
+
"@clack/prompts": "^1.8.0",
|
|
38248
|
+
"@modelcontextprotocol/sdk": "1.32.0",
|
|
38249
|
+
"@orpc/client": "2.0.0-beta.43",
|
|
38250
|
+
"@orpc/openapi": "2.0.0-beta.43",
|
|
38251
|
+
"@orpc/server": "2.0.0-beta.43",
|
|
38252
|
+
commander: "^15.0.0",
|
|
38253
|
+
cosmiconfig: "^10.0.1",
|
|
38254
|
+
picomatch: "^4.0.7",
|
|
38255
|
+
"string-width": "8.3.0",
|
|
38256
|
+
trilean: "1.9.0",
|
|
38257
|
+
undici: "7.30.1",
|
|
38258
|
+
zod: "^4.6.7"
|
|
38259
|
+
},
|
|
38260
|
+
devDependencies: {
|
|
38261
|
+
"@commitlint/cli": "^21.2.2",
|
|
38262
|
+
"@commitlint/config-conventional": "^21.2.2",
|
|
38263
|
+
"@exadev/eslint-config": "2.12.1",
|
|
38264
|
+
"@semantic-release/changelog": "^7.0.0",
|
|
38265
|
+
"@semantic-release/git": "^11.0.1",
|
|
38266
|
+
"@semantic-release/npm": "^13.1.5",
|
|
38267
|
+
"@types/node": "^26.5.1",
|
|
38268
|
+
"@types/picomatch": "^4.0.3",
|
|
38269
|
+
"@vitest/coverage-v8": "^4.1.12",
|
|
38270
|
+
combinatrix: "2.0.1",
|
|
38271
|
+
"conventional-changelog-conventionalcommits": "^10.4.0",
|
|
38272
|
+
esbuild: "^0.28.2",
|
|
38273
|
+
eslint: "^10.10.0",
|
|
38274
|
+
globals: "^17.12.0",
|
|
38275
|
+
husky: "^9.1.7",
|
|
38276
|
+
jiti: "^2.7.0",
|
|
38277
|
+
knip: "^6.35.1",
|
|
38278
|
+
"lint-staged": "^17.5.0",
|
|
38279
|
+
rollup: "4.64.0",
|
|
38280
|
+
"rollup-plugin-dts": "6.5.1",
|
|
38281
|
+
"semantic-release": "^25.0.9",
|
|
38282
|
+
turbo: "^2.11.5",
|
|
38283
|
+
typescript: "^6.0.3",
|
|
38284
|
+
"typescript-eslint": "^8.70.0",
|
|
38285
|
+
vitest: "^4.1.12",
|
|
38286
|
+
yaml: "2.9.1"
|
|
38287
|
+
},
|
|
38288
|
+
main: "dist/index.cjs",
|
|
38289
|
+
module: "dist/index.mjs",
|
|
38290
|
+
types: "dist/types/index.d.ts",
|
|
38291
|
+
exports: {
|
|
38292
|
+
".": {
|
|
38293
|
+
types: "./dist/types/index.d.ts",
|
|
38294
|
+
import: "./dist/index.mjs",
|
|
38295
|
+
require: "./dist/index.cjs"
|
|
38296
|
+
},
|
|
38297
|
+
"./package.json": "./package.json"
|
|
38673
38298
|
}
|
|
38674
|
-
|
|
38675
|
-
return { ...current.providers, [provider]: { ...state, quota: keep ? state.quota : quota } };
|
|
38676
|
-
}),
|
|
38677
|
-
recordRateLimit: (identity, provider, rateLimit) => rewriteSnapshot(identity, (current) => {
|
|
38678
|
-
const state = current?.providers[provider] ?? {};
|
|
38679
|
-
const keep = state.rateLimit !== void 0 && state.rateLimit.observedAt.localeCompare(rateLimit.observedAt) > 0;
|
|
38680
|
-
const earlier = state.rateLimit;
|
|
38681
|
-
const merged = rateLimit.unified === void 0 ? { ...earlier ?? rateLimit, planWindowsUnavailableAt: rateLimit.observedAt } : { ...rateLimit, unified: { ...earlier?.unified === void 0 ? {} : overageFactsOf(earlier.unified), ...rateLimit.unified } };
|
|
38682
|
-
return { ...current?.providers, [provider]: { ...state, rateLimit: keep ? state.rateLimit : merged } };
|
|
38683
|
-
})
|
|
38684
|
-
};
|
|
38685
|
-
}
|
|
38686
|
-
var import_node_path27, DAY_MS2, DAYS_IN_WEEK2, USAGE_RETENTION_MS;
|
|
38687
|
-
var init_store2 = __esm({
|
|
38688
|
-
"src/usage/store.ts"() {
|
|
38689
|
-
"use strict";
|
|
38690
|
-
import_node_path27 = __toESM(require("node:path"), 1);
|
|
38691
|
-
init_account();
|
|
38692
|
-
init_rateLimit();
|
|
38693
|
-
init_read();
|
|
38694
|
-
init_schema2();
|
|
38695
|
-
DAY_MS2 = 864e5;
|
|
38696
|
-
DAYS_IN_WEEK2 = 7;
|
|
38697
|
-
USAGE_RETENTION_MS = DAYS_IN_WEEK2 * DAY_MS2;
|
|
38299
|
+
};
|
|
38698
38300
|
}
|
|
38699
38301
|
});
|
|
38700
38302
|
|
|
38701
|
-
// src/usage/
|
|
38702
|
-
function
|
|
38703
|
-
|
|
38704
|
-
|
|
38705
|
-
|
|
38706
|
-
const windowStartMs = nowMs - FIVE_HOUR_WINDOW_MS;
|
|
38707
|
-
const log = readUsageLog(fs31, paths.usageLogDir, { sinceMs: windowStartMs });
|
|
38708
|
-
return identities.map((identity) => {
|
|
38709
|
-
const records = log.records.filter((record2) => record2.identity === identity && record2.provider === ANTHROPIC_PROVIDER && Date.parse(record2.at) >= windowStartMs);
|
|
38710
|
-
try {
|
|
38711
|
-
const snapshot = readUsageSnapshot(fs31, paths.usageSnapshotsDir, identity);
|
|
38712
|
-
const account = readAccountMetadata(fs31, paths.identitiesDir, identity) ?? snapshot?.account;
|
|
38713
|
-
return { identity, records, ...snapshot === void 0 ? {} : { snapshot }, ...account === void 0 ? {} : { account } };
|
|
38714
|
-
} catch (error63) {
|
|
38715
|
-
if (error63 instanceof UsageSnapshotError || error63 instanceof AccountMetadataError) {
|
|
38716
|
-
return { identity, records, readError: errorMessage(error63) };
|
|
38717
|
-
}
|
|
38718
|
-
throw error63;
|
|
38719
|
-
}
|
|
38720
|
-
});
|
|
38721
|
-
}
|
|
38722
|
-
function rankPoolGraph(input2) {
|
|
38723
|
-
return rankNamedPool(input2, input2.poolName, [], input2.sticky);
|
|
38724
|
-
}
|
|
38725
|
-
function rankNamedPool(input2, poolName, stack, sticky) {
|
|
38726
|
-
const pool = input2.pools[poolName];
|
|
38727
|
-
if (pool === void 0) {
|
|
38728
|
-
throw new PoolGraphError(`No pool named "${poolName}". Run \`agent-shim pool add ${poolName} --identity <name>...\` first.`);
|
|
38303
|
+
// src/usage/plan.ts
|
|
38304
|
+
function planOf(account) {
|
|
38305
|
+
const userTier = account?.userRateLimitTier;
|
|
38306
|
+
if (userTier !== void 0 && ZERO_TIER.test(userTier)) {
|
|
38307
|
+
return { kind: "pay-per-use", tier: userTier };
|
|
38729
38308
|
}
|
|
38730
|
-
const
|
|
38731
|
-
const
|
|
38732
|
-
|
|
38733
|
-
|
|
38734
|
-
const members2 = [];
|
|
38735
|
-
for (const entry of pool.identities) {
|
|
38736
|
-
const nestedName = poolNameOf(poolMemberIdentity(entry));
|
|
38737
|
-
if (nestedName === void 0) {
|
|
38738
|
-
const member = loaded.get(poolMemberIdentity(entry));
|
|
38739
|
-
if (member !== void 0) {
|
|
38740
|
-
members2.push(typeof entry === "string" ? member : { ...member, policy: entry.when });
|
|
38741
|
-
}
|
|
38742
|
-
continue;
|
|
38743
|
-
}
|
|
38744
|
-
assertNestable(input2.pools, poolName, poolMemberIdentity(entry), nestedName, childStack);
|
|
38745
|
-
const nested = nestedMember(input2, nestedName, childStack, sticky);
|
|
38746
|
-
members2.push(typeof entry === "string" ? nested.member : { ...nested.member, policy: entry.when });
|
|
38747
|
-
missing.push(...nested.missing);
|
|
38309
|
+
const tier = account?.organizationRateLimitTier ?? userTier;
|
|
38310
|
+
const tierField = tier === void 0 ? {} : { tier };
|
|
38311
|
+
if (tier === void 0) {
|
|
38312
|
+
return { kind: "subscription", capacity: 1, recognised: false };
|
|
38748
38313
|
}
|
|
38749
|
-
|
|
38750
|
-
|
|
38751
|
-
|
|
38752
|
-
|
|
38753
|
-
|
|
38754
|
-
|
|
38755
|
-
|
|
38756
|
-
|
|
38757
|
-
});
|
|
38758
|
-
return { ranking, missing };
|
|
38314
|
+
if (ZERO_TIER.test(tier)) {
|
|
38315
|
+
return { kind: "pay-per-use", ...tierField };
|
|
38316
|
+
}
|
|
38317
|
+
const multiplier = TIER_MULTIPLIER.exec(tier)?.[1];
|
|
38318
|
+
if (multiplier !== void 0) {
|
|
38319
|
+
return { kind: "subscription", capacity: Number(multiplier), recognised: true, ...tierField };
|
|
38320
|
+
}
|
|
38321
|
+
return { kind: "subscription", capacity: 1, recognised: BASE_TIER.test(tier), ...tierField };
|
|
38759
38322
|
}
|
|
38760
|
-
|
|
38761
|
-
|
|
38762
|
-
|
|
38323
|
+
var PlanClassSchema, TIER_MULTIPLIER, ZERO_TIER, BASE_TIER;
|
|
38324
|
+
var init_plan2 = __esm({
|
|
38325
|
+
"src/usage/plan.ts"() {
|
|
38326
|
+
"use strict";
|
|
38327
|
+
init_zod();
|
|
38328
|
+
PlanClassSchema = external_exports.union([
|
|
38329
|
+
external_exports.strictObject({
|
|
38330
|
+
kind: external_exports.literal("subscription"),
|
|
38331
|
+
/** The plan's size as a multiple of the smallest subscription tier (Max is 5, Ultra is 20). */
|
|
38332
|
+
capacity: external_exports.number().positive(),
|
|
38333
|
+
/** False when the tier string named no multiplier and no tier this project knows, so `capacity` is the neutral 1 rather than a reading. */
|
|
38334
|
+
recognised: external_exports.boolean(),
|
|
38335
|
+
/** The tier string the classification rests on, when the account had one. */
|
|
38336
|
+
tier: external_exports.string().optional()
|
|
38337
|
+
}),
|
|
38338
|
+
external_exports.strictObject({
|
|
38339
|
+
kind: external_exports.literal("pay-per-use"),
|
|
38340
|
+
tier: external_exports.string().optional()
|
|
38341
|
+
})
|
|
38342
|
+
]);
|
|
38343
|
+
TIER_MULTIPLIER = /(?:^|_)(\d+)x$/;
|
|
38344
|
+
ZERO_TIER = /(?:^|_)zero$/;
|
|
38345
|
+
BASE_TIER = /(?:^|_)(?:pro|free)$/;
|
|
38763
38346
|
}
|
|
38764
|
-
|
|
38765
|
-
|
|
38347
|
+
});
|
|
38348
|
+
|
|
38349
|
+
// src/usage/scan.ts
|
|
38350
|
+
function mergeUsage(current, raw) {
|
|
38351
|
+
const parsed = AnthropicUsageSchema.safeParse(raw);
|
|
38352
|
+
if (!parsed.success) {
|
|
38353
|
+
return current;
|
|
38766
38354
|
}
|
|
38355
|
+
const usage = parsed.data;
|
|
38356
|
+
const merged = {
|
|
38357
|
+
...current,
|
|
38358
|
+
...typeof usage.input_tokens === "number" ? { inputTokens: usage.input_tokens } : {},
|
|
38359
|
+
...typeof usage.output_tokens === "number" ? { outputTokens: usage.output_tokens } : {},
|
|
38360
|
+
...typeof usage.cache_creation_input_tokens === "number" ? { cacheCreationInputTokens: usage.cache_creation_input_tokens } : {},
|
|
38361
|
+
...typeof usage.cache_read_input_tokens === "number" ? { cacheReadInputTokens: usage.cache_read_input_tokens } : {}
|
|
38362
|
+
};
|
|
38363
|
+
return Object.keys(merged).length === 0 ? current : merged;
|
|
38767
38364
|
}
|
|
38768
|
-
function
|
|
38769
|
-
const
|
|
38770
|
-
|
|
38771
|
-
|
|
38772
|
-
const [member] = loadPoolMembers(input2.fs, input2.paths, [pick2.identity], input2.nowMs);
|
|
38773
|
-
return { member: { ...member ?? { identity: pick2.identity, records: [] }, nested: { kind: "pick", pool: nestedName, reasons: pick2.reasons } }, missing: nested.missing };
|
|
38365
|
+
function errorInfo(raw) {
|
|
38366
|
+
const parsed = ErrorObjectSchema.safeParse(raw);
|
|
38367
|
+
if (!parsed.success) {
|
|
38368
|
+
return void 0;
|
|
38774
38369
|
}
|
|
38775
|
-
const
|
|
38370
|
+
const { type: type2, code, message } = parsed.data;
|
|
38776
38371
|
return {
|
|
38777
|
-
|
|
38778
|
-
|
|
38779
|
-
|
|
38780
|
-
nested: { kind: "refused", pool: nestedName, ...earliestReturn === void 0 ? {} : { earliestReturn } }
|
|
38781
|
-
},
|
|
38782
|
-
missing: nested.missing
|
|
38372
|
+
...type2 === void 0 ? {} : { type: type2 },
|
|
38373
|
+
...code === void 0 ? {} : { code: String(code) },
|
|
38374
|
+
...message === void 0 ? {} : { message }
|
|
38783
38375
|
};
|
|
38784
38376
|
}
|
|
38785
|
-
function
|
|
38786
|
-
|
|
38787
|
-
|
|
38788
|
-
|
|
38789
|
-
return { file: empty };
|
|
38790
|
-
}
|
|
38791
|
-
let parsed;
|
|
38377
|
+
function isObject3(value2) {
|
|
38378
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
38379
|
+
}
|
|
38380
|
+
function parseJson2(text5) {
|
|
38792
38381
|
try {
|
|
38793
|
-
parsed = JSON.parse(
|
|
38382
|
+
const parsed = JSON.parse(text5);
|
|
38383
|
+
return parsed;
|
|
38794
38384
|
} catch {
|
|
38795
|
-
return
|
|
38385
|
+
return void 0;
|
|
38796
38386
|
}
|
|
38797
|
-
const result = PicksFileSchema.safeParse(parsed);
|
|
38798
|
-
return result.success ? { file: result.data } : { file: empty, problem: `${file2} is not a picks file this agent-shim can read` };
|
|
38799
38387
|
}
|
|
38800
|
-
function
|
|
38801
|
-
|
|
38802
|
-
|
|
38803
|
-
|
|
38388
|
+
function createSseScanner() {
|
|
38389
|
+
let model;
|
|
38390
|
+
let usage;
|
|
38391
|
+
let error63;
|
|
38392
|
+
let eventName;
|
|
38393
|
+
let line = "";
|
|
38394
|
+
let skipping = false;
|
|
38395
|
+
let data = [];
|
|
38396
|
+
const dispatch = () => {
|
|
38397
|
+
if (data.length > 0) {
|
|
38398
|
+
const payload = parseJson2(data.join("\n"));
|
|
38399
|
+
if (isObject3(payload)) {
|
|
38400
|
+
const type2 = typeof payload.type === "string" ? payload.type : void 0;
|
|
38401
|
+
if (type2 === "message_start" && isObject3(payload.message)) {
|
|
38402
|
+
if (typeof payload.message.model === "string") {
|
|
38403
|
+
model = payload.message.model;
|
|
38404
|
+
}
|
|
38405
|
+
usage = mergeUsage(usage, payload.message.usage);
|
|
38406
|
+
} else if (type2 === "message_delta") {
|
|
38407
|
+
usage = mergeUsage(usage, payload.usage);
|
|
38408
|
+
} else if (type2 === "error") {
|
|
38409
|
+
error63 = errorInfo(payload.error) ?? error63;
|
|
38410
|
+
}
|
|
38411
|
+
}
|
|
38412
|
+
}
|
|
38413
|
+
eventName = void 0;
|
|
38414
|
+
data = [];
|
|
38415
|
+
};
|
|
38416
|
+
const worthKeeping = (partial2) => {
|
|
38417
|
+
if (!partial2.startsWith("data:")) {
|
|
38418
|
+
return true;
|
|
38419
|
+
}
|
|
38420
|
+
if (eventName !== void 0) {
|
|
38421
|
+
return METADATA_EVENTS.has(eventName);
|
|
38422
|
+
}
|
|
38423
|
+
const leading = LEADING_TYPE.exec(partial2.slice("data:".length));
|
|
38424
|
+
if (leading?.[1] !== void 0) {
|
|
38425
|
+
return METADATA_EVENTS.has(leading[1]);
|
|
38426
|
+
}
|
|
38427
|
+
return void 0;
|
|
38428
|
+
};
|
|
38429
|
+
const completeLine = (complete) => {
|
|
38430
|
+
const text5 = complete.endsWith("\r") ? complete.slice(0, -1) : complete;
|
|
38431
|
+
if (text5 === "") {
|
|
38432
|
+
dispatch();
|
|
38433
|
+
return;
|
|
38434
|
+
}
|
|
38435
|
+
if (text5.startsWith("event:")) {
|
|
38436
|
+
eventName = text5.slice("event:".length).trim();
|
|
38437
|
+
return;
|
|
38438
|
+
}
|
|
38439
|
+
if (text5.startsWith("data:")) {
|
|
38440
|
+
const value2 = text5.slice("data:".length);
|
|
38441
|
+
data.push(value2.startsWith(" ") ? value2.slice(1) : value2);
|
|
38442
|
+
}
|
|
38443
|
+
};
|
|
38444
|
+
return {
|
|
38445
|
+
push: (text5) => {
|
|
38446
|
+
let start = 0;
|
|
38447
|
+
for (; ; ) {
|
|
38448
|
+
const newline = text5.indexOf("\n", start);
|
|
38449
|
+
const piece = newline === -1 ? text5.slice(start) : text5.slice(start, newline);
|
|
38450
|
+
if (!skipping) {
|
|
38451
|
+
line += piece;
|
|
38452
|
+
if (worthKeeping(line) === false) {
|
|
38453
|
+
line = "";
|
|
38454
|
+
skipping = true;
|
|
38455
|
+
}
|
|
38456
|
+
}
|
|
38457
|
+
if (newline === -1) {
|
|
38458
|
+
return;
|
|
38459
|
+
}
|
|
38460
|
+
if (!skipping) {
|
|
38461
|
+
completeLine(line);
|
|
38462
|
+
}
|
|
38463
|
+
line = "";
|
|
38464
|
+
skipping = false;
|
|
38465
|
+
start = newline + 1;
|
|
38466
|
+
}
|
|
38467
|
+
},
|
|
38468
|
+
result: () => {
|
|
38469
|
+
if (!skipping && line !== "") {
|
|
38470
|
+
completeLine(line);
|
|
38471
|
+
line = "";
|
|
38472
|
+
}
|
|
38473
|
+
dispatch();
|
|
38474
|
+
return { model, usage, error: error63 };
|
|
38475
|
+
}
|
|
38476
|
+
};
|
|
38804
38477
|
}
|
|
38805
|
-
function
|
|
38806
|
-
const
|
|
38807
|
-
|
|
38808
|
-
|
|
38809
|
-
|
|
38810
|
-
|
|
38811
|
-
|
|
38478
|
+
function createJsonScanner() {
|
|
38479
|
+
const captured = /* @__PURE__ */ new Map();
|
|
38480
|
+
let depth = 0;
|
|
38481
|
+
let inString = false;
|
|
38482
|
+
let escaped = false;
|
|
38483
|
+
let readingKey = false;
|
|
38484
|
+
let expectKey = false;
|
|
38485
|
+
let key = "";
|
|
38486
|
+
let capturing;
|
|
38487
|
+
let capture = "";
|
|
38488
|
+
let inValue = false;
|
|
38489
|
+
let currentKey = "";
|
|
38490
|
+
const endValue = () => {
|
|
38491
|
+
if (capturing !== void 0) {
|
|
38492
|
+
captured.set(capturing, capture.trim());
|
|
38493
|
+
}
|
|
38494
|
+
capturing = void 0;
|
|
38495
|
+
capture = "";
|
|
38496
|
+
inValue = false;
|
|
38497
|
+
};
|
|
38498
|
+
const step2 = (char) => {
|
|
38499
|
+
if (capturing !== void 0 && !(depth === 1 && !inString && (char === "," || char === "}"))) {
|
|
38500
|
+
capture += char;
|
|
38501
|
+
}
|
|
38502
|
+
if (inString) {
|
|
38503
|
+
if (escaped) {
|
|
38504
|
+
escaped = false;
|
|
38505
|
+
} else if (char === "\\") {
|
|
38506
|
+
escaped = true;
|
|
38507
|
+
} else if (char === '"') {
|
|
38508
|
+
inString = false;
|
|
38509
|
+
if (readingKey) {
|
|
38510
|
+
readingKey = false;
|
|
38511
|
+
currentKey = key;
|
|
38512
|
+
}
|
|
38513
|
+
return;
|
|
38514
|
+
}
|
|
38515
|
+
if (readingKey) {
|
|
38516
|
+
key += char;
|
|
38517
|
+
}
|
|
38518
|
+
return;
|
|
38519
|
+
}
|
|
38520
|
+
switch (char) {
|
|
38521
|
+
case '"':
|
|
38522
|
+
inString = true;
|
|
38523
|
+
if (depth === 1 && expectKey) {
|
|
38524
|
+
readingKey = true;
|
|
38525
|
+
expectKey = false;
|
|
38526
|
+
key = "";
|
|
38527
|
+
}
|
|
38528
|
+
return;
|
|
38529
|
+
case "{":
|
|
38530
|
+
case "[":
|
|
38531
|
+
depth += 1;
|
|
38532
|
+
if (depth === 1 && char === "{") {
|
|
38533
|
+
expectKey = true;
|
|
38534
|
+
}
|
|
38535
|
+
return;
|
|
38536
|
+
case "}":
|
|
38537
|
+
case "]":
|
|
38538
|
+
if (depth === 1) {
|
|
38539
|
+
endValue();
|
|
38540
|
+
}
|
|
38541
|
+
depth -= 1;
|
|
38542
|
+
return;
|
|
38543
|
+
case ":":
|
|
38544
|
+
if (depth === 1 && !inValue) {
|
|
38545
|
+
inValue = true;
|
|
38546
|
+
if (METADATA_KEYS.has(currentKey)) {
|
|
38547
|
+
capturing = currentKey;
|
|
38548
|
+
capture = "";
|
|
38549
|
+
}
|
|
38550
|
+
}
|
|
38551
|
+
return;
|
|
38552
|
+
case ",":
|
|
38553
|
+
if (depth === 1) {
|
|
38554
|
+
endValue();
|
|
38555
|
+
expectKey = true;
|
|
38556
|
+
}
|
|
38557
|
+
return;
|
|
38558
|
+
default:
|
|
38559
|
+
return;
|
|
38560
|
+
}
|
|
38561
|
+
};
|
|
38562
|
+
return {
|
|
38563
|
+
push: (text5) => {
|
|
38564
|
+
for (const char of text5) {
|
|
38565
|
+
step2(char);
|
|
38566
|
+
}
|
|
38567
|
+
},
|
|
38568
|
+
result: () => {
|
|
38569
|
+
const model = parseJson2(captured.get("model") ?? "");
|
|
38570
|
+
const usageRaw = parseJson2(captured.get("usage") ?? "");
|
|
38571
|
+
const errorRaw = parseJson2(captured.get("error") ?? "");
|
|
38572
|
+
return {
|
|
38573
|
+
model: typeof model === "string" ? model : void 0,
|
|
38574
|
+
usage: mergeUsage(void 0, usageRaw),
|
|
38575
|
+
error: errorInfo(errorRaw)
|
|
38576
|
+
};
|
|
38577
|
+
}
|
|
38578
|
+
};
|
|
38812
38579
|
}
|
|
38813
|
-
var
|
|
38814
|
-
var
|
|
38815
|
-
"src/usage/
|
|
38580
|
+
var AnthropicUsageSchema, ErrorObjectSchema, METADATA_EVENTS, LEADING_TYPE, METADATA_KEYS;
|
|
38581
|
+
var init_scan = __esm({
|
|
38582
|
+
"src/usage/scan.ts"() {
|
|
38816
38583
|
"use strict";
|
|
38817
|
-
import_node_path28 = __toESM(require("node:path"), 1);
|
|
38818
38584
|
init_zod();
|
|
38819
|
-
|
|
38820
|
-
|
|
38821
|
-
|
|
38822
|
-
|
|
38823
|
-
|
|
38824
|
-
|
|
38825
|
-
|
|
38826
|
-
|
|
38827
|
-
|
|
38828
|
-
|
|
38829
|
-
super(message);
|
|
38830
|
-
this.name = "PoolGraphError";
|
|
38831
|
-
}
|
|
38832
|
-
};
|
|
38833
|
-
SCHEMA_VERSION = 1;
|
|
38834
|
-
PickEntrySchema = external_exports.strictObject({ identity: external_exports.string().min(1), at: external_exports.iso.datetime() });
|
|
38835
|
-
PicksFileSchema = external_exports.strictObject({
|
|
38836
|
-
schemaVersion: external_exports.literal(SCHEMA_VERSION),
|
|
38837
|
-
picks: external_exports.record(external_exports.string().min(1), PickEntrySchema)
|
|
38585
|
+
AnthropicUsageSchema = external_exports.looseObject({
|
|
38586
|
+
input_tokens: external_exports.number().int().nonnegative().nullish(),
|
|
38587
|
+
output_tokens: external_exports.number().int().nonnegative().nullish(),
|
|
38588
|
+
cache_creation_input_tokens: external_exports.number().int().nonnegative().nullish(),
|
|
38589
|
+
cache_read_input_tokens: external_exports.number().int().nonnegative().nullish()
|
|
38590
|
+
});
|
|
38591
|
+
ErrorObjectSchema = external_exports.looseObject({
|
|
38592
|
+
type: external_exports.string().optional(),
|
|
38593
|
+
code: external_exports.union([external_exports.string(), external_exports.number()]).optional(),
|
|
38594
|
+
message: external_exports.string().optional()
|
|
38838
38595
|
});
|
|
38596
|
+
METADATA_EVENTS = /* @__PURE__ */ new Set(["message_start", "message_delta", "error"]);
|
|
38597
|
+
LEADING_TYPE = /^\s*\{\s*"type"\s*:\s*"([^"]*)"/;
|
|
38598
|
+
METADATA_KEYS = /* @__PURE__ */ new Set(["model", "usage", "error"]);
|
|
38839
38599
|
}
|
|
38840
38600
|
});
|
|
38841
38601
|
|
|
38842
|
-
// src/
|
|
38843
|
-
function
|
|
38844
|
-
|
|
38602
|
+
// src/usage/middleware.ts
|
|
38603
|
+
function scannerFor(headers) {
|
|
38604
|
+
const contentType = headerValue(headers, "content-type")?.toLowerCase() ?? "";
|
|
38605
|
+
if (contentType.startsWith("text/event-stream")) {
|
|
38606
|
+
return createSseScanner();
|
|
38607
|
+
}
|
|
38608
|
+
if (contentType.startsWith("application/json")) {
|
|
38609
|
+
return createJsonScanner();
|
|
38610
|
+
}
|
|
38611
|
+
return void 0;
|
|
38845
38612
|
}
|
|
38846
|
-
function
|
|
38847
|
-
|
|
38848
|
-
|
|
38849
|
-
|
|
38850
|
-
|
|
38851
|
-
return void 0;
|
|
38613
|
+
function headerValue(headers, name) {
|
|
38614
|
+
for (const [key, value2] of Object.entries(headers)) {
|
|
38615
|
+
if (key.toLowerCase() === name) {
|
|
38616
|
+
return value2;
|
|
38617
|
+
}
|
|
38852
38618
|
}
|
|
38853
|
-
|
|
38854
|
-
return parsed.success ? parsed.data : void 0;
|
|
38619
|
+
return void 0;
|
|
38855
38620
|
}
|
|
38856
|
-
function
|
|
38857
|
-
|
|
38858
|
-
|
|
38621
|
+
function decoderFor(encoding) {
|
|
38622
|
+
switch (encoding?.trim().toLowerCase()) {
|
|
38623
|
+
case void 0:
|
|
38624
|
+
case "":
|
|
38625
|
+
case "identity":
|
|
38626
|
+
return null;
|
|
38627
|
+
case "gzip":
|
|
38628
|
+
case "x-gzip":
|
|
38629
|
+
return zlib.createGunzip();
|
|
38630
|
+
case "deflate":
|
|
38631
|
+
return zlib.createInflate();
|
|
38632
|
+
case "br":
|
|
38633
|
+
return zlib.createBrotliDecompress();
|
|
38634
|
+
default:
|
|
38635
|
+
return void 0;
|
|
38859
38636
|
}
|
|
38860
38637
|
}
|
|
38861
|
-
function
|
|
38862
|
-
const
|
|
38863
|
-
|
|
38638
|
+
function destinationOf(path73, sessionProvider) {
|
|
38639
|
+
const scoped = parseProviderPath(path73);
|
|
38640
|
+
if (scoped !== void 0) {
|
|
38641
|
+
return { provider: scoped.provider, endpoint: scoped.rest };
|
|
38642
|
+
}
|
|
38643
|
+
return { provider: sessionProvider ?? ANTHROPIC_PROVIDER, endpoint: path73 };
|
|
38864
38644
|
}
|
|
38865
|
-
|
|
38866
|
-
|
|
38867
|
-
|
|
38868
|
-
|
|
38869
|
-
let settled = false;
|
|
38870
|
-
const settle2 = (status) => {
|
|
38871
|
-
if (!settled) {
|
|
38872
|
-
settled = true;
|
|
38873
|
-
resolve3({ status, stdout: stdout2 });
|
|
38874
|
-
}
|
|
38875
|
-
};
|
|
38876
|
-
child.stdout.setEncoding("utf8");
|
|
38877
|
-
child.stdout.on("data", (chunk2) => {
|
|
38878
|
-
stdout2 += chunk2;
|
|
38879
|
-
});
|
|
38880
|
-
child.stdin.on("error", () => {
|
|
38881
|
-
});
|
|
38882
|
-
child.stdin.end(stdin2);
|
|
38883
|
-
child.once("error", () => {
|
|
38884
|
-
settle2(null);
|
|
38885
|
-
});
|
|
38886
|
-
child.once("close", settle2);
|
|
38887
|
-
});
|
|
38645
|
+
function modelChoiceOf(event, servedModel, provider) {
|
|
38646
|
+
if (event.modelChoice !== void 0) return event.modelChoice;
|
|
38647
|
+
if (event.requestedModel === void 0 || servedModel === void 0 || event.requestedModel === servedModel) return void 0;
|
|
38648
|
+
return { requested: event.requestedModel, providers: [provider] };
|
|
38888
38649
|
}
|
|
38889
|
-
function
|
|
38890
|
-
const
|
|
38891
|
-
const
|
|
38650
|
+
function buildRecord(event, context) {
|
|
38651
|
+
const { scan } = context;
|
|
38652
|
+
const { provider, endpoint } = destinationOf(event.servedPath, event.session.provider);
|
|
38653
|
+
const choice = modelChoiceOf(event, scan?.model, provider);
|
|
38654
|
+
const rateLimitHeaders = rateLimitHeadersOf(event.headers);
|
|
38655
|
+
const limit = classifyLimit({ status: event.status, headers: rateLimitHeaders ?? {}, error: scan?.error, nowMs: context.endedAt });
|
|
38656
|
+
const requestId = headerValue(event.headers, "request-id");
|
|
38657
|
+
const { identity, sessionId, projectId } = event.session;
|
|
38892
38658
|
return {
|
|
38893
|
-
|
|
38894
|
-
|
|
38895
|
-
|
|
38896
|
-
|
|
38897
|
-
|
|
38898
|
-
|
|
38899
|
-
|
|
38900
|
-
|
|
38901
|
-
|
|
38902
|
-
|
|
38903
|
-
|
|
38904
|
-
},
|
|
38905
|
-
|
|
38906
|
-
|
|
38907
|
-
|
|
38908
|
-
|
|
38909
|
-
|
|
38910
|
-
|
|
38911
|
-
|
|
38912
|
-
|
|
38913
|
-
|
|
38659
|
+
schemaVersion: USAGE_SCHEMA_VERSION,
|
|
38660
|
+
at: new Date(event.receivedAt).toISOString(),
|
|
38661
|
+
...identity === void 0 ? {} : { identity },
|
|
38662
|
+
provider,
|
|
38663
|
+
...sessionId === void 0 ? {} : { sessionId },
|
|
38664
|
+
...event.clientSessionId === void 0 ? {} : { clientSessionId: event.clientSessionId },
|
|
38665
|
+
...projectId === void 0 ? {} : { project: projectId },
|
|
38666
|
+
viaHeadroom: event.viaHeadroom,
|
|
38667
|
+
route: event.route,
|
|
38668
|
+
method: event.method,
|
|
38669
|
+
endpoint,
|
|
38670
|
+
...scan?.model === void 0 ? {} : { model: scan.model },
|
|
38671
|
+
...choice === void 0 ? {} : { requestedModel: choice.requested },
|
|
38672
|
+
...choice !== void 0 && choice.providers.length > 1 ? { candidateProviders: [...choice.providers] } : {},
|
|
38673
|
+
status: event.status,
|
|
38674
|
+
latencyMs: Math.max(0, Math.round(context.headAt - event.receivedAt)),
|
|
38675
|
+
durationMs: Math.max(0, Math.round(context.endedAt - event.receivedAt)),
|
|
38676
|
+
outcome: context.outcome,
|
|
38677
|
+
...scan?.usage === void 0 ? {} : { usage: scan.usage },
|
|
38678
|
+
...rateLimitHeaders === void 0 ? {} : { rateLimitHeaders },
|
|
38679
|
+
...limit === void 0 ? {} : { limit },
|
|
38680
|
+
...requestId === void 0 ? {} : { requestId }
|
|
38681
|
+
};
|
|
38682
|
+
}
|
|
38683
|
+
function createUsageMiddleware(deps) {
|
|
38684
|
+
return (event) => {
|
|
38685
|
+
if (DOOR_ANSWERED_ROUTES.has(event.route)) {
|
|
38686
|
+
return void 0;
|
|
38687
|
+
}
|
|
38688
|
+
const headAt = deps.now();
|
|
38689
|
+
const scanner = scannerFor(event.headers);
|
|
38690
|
+
const decoder = scanner === void 0 ? null : decoderFor(headerValue(event.headers, "content-encoding"));
|
|
38691
|
+
let scanning = scanner !== void 0 && decoder !== void 0;
|
|
38692
|
+
const text5 = new TextDecoder();
|
|
38693
|
+
const feed = (bytes, final) => {
|
|
38694
|
+
if (!scanning || scanner === void 0) {
|
|
38914
38695
|
return;
|
|
38915
38696
|
}
|
|
38916
|
-
|
|
38917
|
-
|
|
38918
|
-
|
|
38919
|
-
|
|
38920
|
-
|
|
38921
|
-
throw new Error(`could not write the keychain credential cache for ${owner}`);
|
|
38922
|
-
}
|
|
38923
|
-
},
|
|
38924
|
-
remove(store, owner) {
|
|
38925
|
-
if (store === "file") {
|
|
38926
|
-
import_node_fs9.default.rmSync(filePath(owner), { force: true });
|
|
38927
|
-
return;
|
|
38697
|
+
try {
|
|
38698
|
+
scanner.push(text5.decode(bytes, { stream: !final }));
|
|
38699
|
+
} catch (error63) {
|
|
38700
|
+
scanning = false;
|
|
38701
|
+
deps.log(`usage: body scan failed for ${event.route}: ${error63 instanceof Error ? error63.message : String(error63)}`);
|
|
38928
38702
|
}
|
|
38929
|
-
|
|
38930
|
-
|
|
38931
|
-
|
|
38932
|
-
|
|
38933
|
-
}
|
|
38934
|
-
function realCredentialCacheEnv(paths) {
|
|
38935
|
-
return { port: createRealCredentialCache(paths.root), platform: process.platform, now: () => Date.now() };
|
|
38936
|
-
}
|
|
38937
|
-
function createAsyncRealCredentialCache(root) {
|
|
38938
|
-
const dir = import_node_path29.default.join(root, "credential-cache");
|
|
38939
|
-
const filePath = (owner) => import_node_path29.default.join(dir, cacheFileNameFor(owner));
|
|
38940
|
-
return {
|
|
38941
|
-
async read(store, owner) {
|
|
38942
|
-
if (store === "file") {
|
|
38703
|
+
};
|
|
38704
|
+
const finish = (outcome) => {
|
|
38705
|
+
const endedAt = deps.now();
|
|
38706
|
+
deps.defer(() => {
|
|
38943
38707
|
try {
|
|
38944
|
-
|
|
38945
|
-
} catch {
|
|
38946
|
-
|
|
38708
|
+
deps.record(buildRecord(event, { headAt, endedAt, outcome, scan: scanning && scanner !== void 0 ? scanner.result() : void 0 }), event);
|
|
38709
|
+
} catch (error63) {
|
|
38710
|
+
deps.log(`usage: could not record ${event.method} ${event.path} (${String(event.status)}): ${error63 instanceof Error ? error63.message : String(error63)}`);
|
|
38947
38711
|
}
|
|
38948
|
-
}
|
|
38949
|
-
|
|
38950
|
-
|
|
38951
|
-
return
|
|
38952
|
-
|
|
38953
|
-
|
|
38954
|
-
|
|
38955
|
-
|
|
38956
|
-
|
|
38957
|
-
|
|
38958
|
-
|
|
38959
|
-
|
|
38960
|
-
|
|
38961
|
-
|
|
38712
|
+
});
|
|
38713
|
+
};
|
|
38714
|
+
if (decoder === null || decoder === void 0) {
|
|
38715
|
+
return {
|
|
38716
|
+
chunk: (bytes) => {
|
|
38717
|
+
feed(bytes, false);
|
|
38718
|
+
},
|
|
38719
|
+
end: (outcome) => {
|
|
38720
|
+
feed(new Uint8Array(), true);
|
|
38721
|
+
finish(outcome);
|
|
38722
|
+
}
|
|
38723
|
+
};
|
|
38724
|
+
}
|
|
38725
|
+
let ended;
|
|
38726
|
+
let settled = false;
|
|
38727
|
+
const settle2 = () => {
|
|
38728
|
+
if (settled || ended === void 0) {
|
|
38962
38729
|
return;
|
|
38963
38730
|
}
|
|
38964
|
-
|
|
38965
|
-
|
|
38966
|
-
|
|
38967
|
-
|
|
38968
|
-
|
|
38969
|
-
|
|
38731
|
+
settled = true;
|
|
38732
|
+
feed(new Uint8Array(), true);
|
|
38733
|
+
finish(ended);
|
|
38734
|
+
};
|
|
38735
|
+
decoder.on("data", (bytes) => {
|
|
38736
|
+
feed(bytes, false);
|
|
38737
|
+
});
|
|
38738
|
+
decoder.on("error", (error63) => {
|
|
38739
|
+
scanning = false;
|
|
38740
|
+
deps.log(`usage: could not decompress the body of ${event.route}: ${error63.message}`);
|
|
38741
|
+
settle2();
|
|
38742
|
+
});
|
|
38743
|
+
decoder.on("end", settle2);
|
|
38744
|
+
return {
|
|
38745
|
+
chunk: (bytes) => {
|
|
38746
|
+
if (scanning) {
|
|
38747
|
+
decoder.write(bytes);
|
|
38748
|
+
}
|
|
38749
|
+
},
|
|
38750
|
+
end: (outcome) => {
|
|
38751
|
+
ended = outcome;
|
|
38752
|
+
if (!scanning || outcome === "aborted") {
|
|
38753
|
+
decoder.destroy();
|
|
38754
|
+
settle2();
|
|
38755
|
+
return;
|
|
38756
|
+
}
|
|
38757
|
+
decoder.end();
|
|
38970
38758
|
}
|
|
38971
|
-
}
|
|
38759
|
+
};
|
|
38972
38760
|
};
|
|
38973
38761
|
}
|
|
38974
|
-
|
|
38975
|
-
|
|
38976
|
-
|
|
38977
|
-
var import_node_child_process4, import_node_fs9, import_node_path29, KEYCHAIN_CACHE_SERVICE, CACHE_DIR_MODE, CACHE_FILE_MODE;
|
|
38978
|
-
var init_realCredentialCache = __esm({
|
|
38979
|
-
"src/realCredentialCache.ts"() {
|
|
38762
|
+
var zlib, ANTHROPIC_PROVIDER, DOOR_ANSWERED_ROUTES;
|
|
38763
|
+
var init_middleware = __esm({
|
|
38764
|
+
"src/usage/middleware.ts"() {
|
|
38980
38765
|
"use strict";
|
|
38981
|
-
|
|
38982
|
-
|
|
38983
|
-
|
|
38984
|
-
|
|
38985
|
-
|
|
38986
|
-
|
|
38987
|
-
|
|
38988
|
-
CACHE_FILE_MODE = 384;
|
|
38766
|
+
zlib = __toESM(require("node:zlib"), 1);
|
|
38767
|
+
init_route();
|
|
38768
|
+
init_rateLimit();
|
|
38769
|
+
init_scan();
|
|
38770
|
+
init_schema2();
|
|
38771
|
+
ANTHROPIC_PROVIDER = "anthropic";
|
|
38772
|
+
DOOR_ANSWERED_ROUTES = /* @__PURE__ */ new Set(["(unauthorized)", "(unrouted)"]);
|
|
38989
38773
|
}
|
|
38990
38774
|
});
|
|
38991
38775
|
|
|
38992
|
-
// src/
|
|
38993
|
-
function
|
|
38994
|
-
|
|
38995
|
-
|
|
38996
|
-
throw new ConfigValidationError(file2, parsed.error.issues);
|
|
38776
|
+
// src/usage/quotaFacts.ts
|
|
38777
|
+
function windowFacts(window, nowMs) {
|
|
38778
|
+
if (window?.utilization === void 0 || window.resetsAt === void 0) {
|
|
38779
|
+
return void 0;
|
|
38997
38780
|
}
|
|
38998
|
-
return
|
|
38999
|
-
}
|
|
39000
|
-
function readProviderAliases(paths) {
|
|
39001
|
-
return readJson(paths.providerAliasesFile, ProviderAliasesSchema) ?? {};
|
|
38781
|
+
return { remaining: Math.max(0, 1 - window.utilization), utilization: window.utilization, hoursUntilReset: Math.max(0, (Date.parse(window.resetsAt) - nowMs) / MS_PER_HOUR) };
|
|
39002
38782
|
}
|
|
39003
|
-
function
|
|
39004
|
-
const
|
|
39005
|
-
|
|
38783
|
+
function quotaFactsOf(unified, nowMs) {
|
|
38784
|
+
const fiveHour = windowFacts(unified?.fiveHour, nowMs);
|
|
38785
|
+
const sevenDay = windowFacts(unified?.sevenDay, nowMs);
|
|
38786
|
+
const extraUsage = windowFacts(unified === void 0 ? void 0 : soleOverageWindow(unified), nowMs);
|
|
38787
|
+
return { ...fiveHour === void 0 ? {} : { fiveHour }, ...sevenDay === void 0 ? {} : { sevenDay }, ...extraUsage === void 0 ? {} : { extraUsage } };
|
|
39006
38788
|
}
|
|
39007
|
-
|
|
39008
|
-
|
|
39009
|
-
|
|
39010
|
-
|
|
38789
|
+
var MS_PER_HOUR;
|
|
38790
|
+
var init_quotaFacts = __esm({
|
|
38791
|
+
"src/usage/quotaFacts.ts"() {
|
|
38792
|
+
"use strict";
|
|
38793
|
+
init_rateLimit();
|
|
38794
|
+
MS_PER_HOUR = 36e5;
|
|
39011
38795
|
}
|
|
39012
|
-
|
|
38796
|
+
});
|
|
38797
|
+
|
|
38798
|
+
// src/usage/pick.ts
|
|
38799
|
+
function unifiedOf(state) {
|
|
38800
|
+
return state?.rateLimit?.unified;
|
|
39013
38801
|
}
|
|
39014
|
-
function
|
|
39015
|
-
|
|
39016
|
-
|
|
38802
|
+
function limitBlockedUntil(state, nowMs) {
|
|
38803
|
+
const limit = state?.lastLimit;
|
|
38804
|
+
if (state === void 0 || limit === void 0) {
|
|
38805
|
+
return void 0;
|
|
39017
38806
|
}
|
|
39018
|
-
|
|
39019
|
-
|
|
39020
|
-
function aliasesAfterRename(aliases, from, to2) {
|
|
39021
|
-
const next = {};
|
|
39022
|
-
for (const [alias, target] of Object.entries(aliases)) {
|
|
39023
|
-
if (alias !== to2) {
|
|
39024
|
-
next[alias] = target === from ? to2 : target;
|
|
39025
|
-
}
|
|
38807
|
+
if (state.lastRequestAt !== void 0 && Date.parse(state.lastRequestAt) > Date.parse(limit.observedAt)) {
|
|
38808
|
+
return void 0;
|
|
39026
38809
|
}
|
|
39027
|
-
|
|
39028
|
-
return
|
|
38810
|
+
const until = limit.resetAt === void 0 ? limit.retryAfterSeconds === void 0 ? void 0 : Date.parse(limit.observedAt) + limit.retryAfterSeconds * MS_PER_SECOND5 : Date.parse(limit.resetAt);
|
|
38811
|
+
return until !== void 0 && until > nowMs ? until : void 0;
|
|
39029
38812
|
}
|
|
39030
|
-
function
|
|
39031
|
-
|
|
38813
|
+
function windowBlockedUntil(windows) {
|
|
38814
|
+
const resets = windows.flatMap((window) => window.status === "rejected" && window.resetsAtMs !== void 0 ? [window.resetsAtMs] : []);
|
|
38815
|
+
return resets.length === 0 ? void 0 : Math.max(...resets);
|
|
39032
38816
|
}
|
|
39033
|
-
function
|
|
39034
|
-
const
|
|
39035
|
-
|
|
39036
|
-
|
|
38817
|
+
function windowBurn(records, which) {
|
|
38818
|
+
const points = [];
|
|
38819
|
+
for (const record2 of records) {
|
|
38820
|
+
const window = record2.rateLimitHeaders === void 0 ? void 0 : parseUnifiedRateLimit(record2.rateLimitHeaders)?.[which];
|
|
38821
|
+
if (window?.utilization !== void 0 && window.resetsAt !== void 0) {
|
|
38822
|
+
points.push({ resetsAt: window.resetsAt, point: { atMs: Date.parse(record2.at), utilization: window.utilization } });
|
|
38823
|
+
}
|
|
39037
38824
|
}
|
|
39038
|
-
|
|
38825
|
+
const latest = points.at(-1)?.resetsAt;
|
|
38826
|
+
const current = points.filter((entry) => entry.resetsAt === latest).map((entry) => entry.point);
|
|
38827
|
+
const first = current.at(0);
|
|
38828
|
+
const last = current.at(-1);
|
|
38829
|
+
if (first === void 0 || last === void 0 || last.atMs <= first.atMs || last.utilization <= first.utilization) {
|
|
38830
|
+
return void 0;
|
|
38831
|
+
}
|
|
38832
|
+
return (last.utilization - first.utilization) / (last.atMs - first.atMs);
|
|
39039
38833
|
}
|
|
39040
|
-
function
|
|
39041
|
-
|
|
39042
|
-
|
|
39043
|
-
return { level: "fail", alias, message: `${alias} is recorded as a former name of ${target}, which is not a provider. Run \`agent-shim provider unalias ${alias}\`.` };
|
|
39044
|
-
}
|
|
39045
|
-
if (providerNames.has(alias)) {
|
|
39046
|
-
return { level: "warn", alias, message: `${alias} is both a provider and a recorded former name of ${target}; the provider wins. Run \`agent-shim provider unalias ${alias}\`.` };
|
|
39047
|
-
}
|
|
39048
|
-
return { level: "pass", alias, message: `${alias} is a former name of ${target}, still honoured for sessions launched under it. Run \`agent-shim provider unalias ${alias}\` once none is running.` };
|
|
39049
|
-
});
|
|
38834
|
+
function billedTokensOf(record2) {
|
|
38835
|
+
const usage = record2.usage;
|
|
38836
|
+
return (usage?.inputTokens ?? 0) + (usage?.cacheCreationInputTokens ?? 0) + (usage?.outputTokens ?? 0);
|
|
39050
38837
|
}
|
|
39051
|
-
function
|
|
39052
|
-
const
|
|
39053
|
-
|
|
39054
|
-
const
|
|
39055
|
-
|
|
39056
|
-
|
|
39057
|
-
} catch (error63) {
|
|
39058
|
-
params.log(`provider aliases ignored, the aliases file is unreadable: ${error63 instanceof Error ? error63.message : String(error63)}`);
|
|
39059
|
-
return {};
|
|
39060
|
-
}
|
|
39061
|
-
});
|
|
39062
|
-
if (current !== name && !reported.has(name)) {
|
|
39063
|
-
reported.add(name);
|
|
39064
|
-
params.log(`provider ${name} is a former name of ${current}; a session launched under it is still running`);
|
|
38838
|
+
function utilisationPerBilledToken(records) {
|
|
38839
|
+
const points = [];
|
|
38840
|
+
for (const record2 of records) {
|
|
38841
|
+
const window = record2.rateLimitHeaders === void 0 ? void 0 : parseUnifiedRateLimit(record2.rateLimitHeaders)?.fiveHour;
|
|
38842
|
+
if (window?.utilization !== void 0 && window.resetsAt !== void 0) {
|
|
38843
|
+
points.push({ resetsAt: window.resetsAt, utilization: window.utilization, billed: billedTokensOf(record2) });
|
|
39065
38844
|
}
|
|
39066
|
-
return current;
|
|
39067
|
-
};
|
|
39068
|
-
}
|
|
39069
|
-
var import_node_fs10, ProviderAliasesSchema, ProviderAliasNotFoundError;
|
|
39070
|
-
var init_providerAliases = __esm({
|
|
39071
|
-
"src/providerAliases.ts"() {
|
|
39072
|
-
"use strict";
|
|
39073
|
-
import_node_fs10 = __toESM(require("node:fs"), 1);
|
|
39074
|
-
init_zod();
|
|
39075
|
-
init_cliError();
|
|
39076
|
-
init_load();
|
|
39077
|
-
init_store();
|
|
39078
|
-
ProviderAliasesSchema = external_exports.record(external_exports.string().min(1), external_exports.string().min(1));
|
|
39079
|
-
ProviderAliasNotFoundError = class extends CliError {
|
|
39080
|
-
constructor(alias) {
|
|
39081
|
-
super(`"${alias}" is not a former provider name. \`agent-shim provider list\` shows the ones recorded.`);
|
|
39082
|
-
this.alias = alias;
|
|
39083
|
-
this.name = "ProviderAliasNotFoundError";
|
|
39084
|
-
}
|
|
39085
|
-
alias;
|
|
39086
|
-
};
|
|
39087
38845
|
}
|
|
39088
|
-
|
|
39089
|
-
|
|
39090
|
-
|
|
39091
|
-
|
|
39092
|
-
|
|
39093
|
-
|
|
39094
|
-
|
|
39095
|
-
|
|
38846
|
+
const latest = points.at(-1)?.resetsAt;
|
|
38847
|
+
const current = points.filter((point) => point.resetsAt === latest);
|
|
38848
|
+
const first = current.at(0);
|
|
38849
|
+
const last = current.at(-1);
|
|
38850
|
+
if (first === void 0 || last === void 0 || last.utilization <= first.utilization) {
|
|
38851
|
+
return void 0;
|
|
38852
|
+
}
|
|
38853
|
+
const billed = current.slice(1).reduce((sum2, point) => sum2 + point.billed, 0);
|
|
38854
|
+
return billed > 0 ? (last.utilization - first.utilization) / billed : void 0;
|
|
39096
38855
|
}
|
|
39097
|
-
function
|
|
39098
|
-
const
|
|
39099
|
-
|
|
39100
|
-
|
|
39101
|
-
const
|
|
39102
|
-
|
|
39103
|
-
|
|
38856
|
+
function windowRatio(records) {
|
|
38857
|
+
const points = [];
|
|
38858
|
+
for (const record2 of records) {
|
|
38859
|
+
const unified = record2.rateLimitHeaders === void 0 ? void 0 : parseUnifiedRateLimit(record2.rateLimitHeaders);
|
|
38860
|
+
const five = unified?.fiveHour;
|
|
38861
|
+
const seven = unified?.sevenDay;
|
|
38862
|
+
if (five?.utilization !== void 0 && five.resetsAt !== void 0 && seven?.utilization !== void 0 && seven.resetsAt !== void 0) {
|
|
38863
|
+
points.push({ fiveResetsAt: five.resetsAt, sevenResetsAt: seven.resetsAt, five: five.utilization, seven: seven.utilization });
|
|
39104
38864
|
}
|
|
39105
|
-
variants2.unshift(token);
|
|
39106
|
-
end -= 1;
|
|
39107
38865
|
}
|
|
38866
|
+
const latest = points.at(-1);
|
|
38867
|
+
const current = points.filter((point) => point.fiveResetsAt === latest?.fiveResetsAt && point.sevenResetsAt === latest.sevenResetsAt);
|
|
38868
|
+
const first = current.at(0);
|
|
38869
|
+
const last = current.at(-1);
|
|
38870
|
+
if (first === void 0 || last === void 0 || last.five <= first.five || last.seven <= first.seven) {
|
|
38871
|
+
return void 0;
|
|
38872
|
+
}
|
|
38873
|
+
return (last.seven - first.seven) / (last.five - first.five);
|
|
39108
38874
|
}
|
|
39109
|
-
function
|
|
39110
|
-
|
|
39111
|
-
|
|
39112
|
-
|
|
39113
|
-
|
|
39114
|
-
|
|
39115
|
-
}
|
|
39116
|
-
if (/^\d+$/.test(token) && next !== void 0 && /^\d+$/.test(next)) {
|
|
39117
|
-
return `${token}.${next}`;
|
|
39118
|
-
}
|
|
39119
|
-
const dotted = /^\d+(?:\.\d+)+$/.exec(token);
|
|
39120
|
-
if (dotted !== null) {
|
|
39121
|
-
return dotted[0];
|
|
39122
|
-
}
|
|
38875
|
+
function percent(fraction) {
|
|
38876
|
+
return `${String(Math.round(fraction * PERCENT))}%`;
|
|
38877
|
+
}
|
|
38878
|
+
function describeWindow(label2, window, effective, nowMs) {
|
|
38879
|
+
if (effective.reset) {
|
|
38880
|
+
return `${label2} window has reset`;
|
|
39123
38881
|
}
|
|
39124
|
-
|
|
38882
|
+
const used = effective.utilization === void 0 ? "usage unknown" : `${percent(effective.utilization)} used`;
|
|
38883
|
+
const resets = effective.resetsAtMs === void 0 ? "" : `, resets in ${formatAge(effective.resetsAtMs - nowMs)}`;
|
|
38884
|
+
return `${label2} ${used}${resets}${window.status === "allowed_warning" ? " (nearly used)" : ""}`;
|
|
39125
38885
|
}
|
|
39126
|
-
function
|
|
39127
|
-
|
|
39128
|
-
|
|
39129
|
-
|
|
39130
|
-
const
|
|
39131
|
-
const { familyTokens, variants: variants2 } = splitVariants(tokens);
|
|
39132
|
-
const version2 = versionOf(familyTokens);
|
|
39133
|
-
const versionless = familyTokens.filter((token, index) => {
|
|
39134
|
-
if (version2 === "") {
|
|
39135
|
-
return true;
|
|
39136
|
-
}
|
|
39137
|
-
const dotted = /^\d+(?:\.\d+)+$/.test(token);
|
|
39138
|
-
const previous = familyTokens[index - 1];
|
|
39139
|
-
const next = familyTokens[index + 1];
|
|
39140
|
-
const insideVersionRun = dotted || /^\d+$/.test(token) && (previous !== void 0 && /^\d+$/.test(previous) || next !== void 0 && /^\d+$/.test(next));
|
|
39141
|
-
return !insideVersionRun;
|
|
39142
|
-
});
|
|
39143
|
-
const family = versionless.join("-");
|
|
39144
|
-
const tokenVendor = familyTokens.find((token) => Object.keys(VENDOR_BY_TOKEN).some((key) => token === key || token.startsWith(key)));
|
|
39145
|
-
const namespace = segments.length >= 2 ? (segments[0] ?? "").split(":").pop() ?? "" : "";
|
|
39146
|
-
const namespaceVendor = VENDOR_BY_NAMESPACE[namespace] ?? "";
|
|
39147
|
-
const tokenVendorName = tokenVendor === void 0 ? "" : VENDOR_BY_TOKEN[Object.keys(VENDOR_BY_TOKEN).find((key) => tokenVendor === key || tokenVendor.startsWith(key)) ?? ""] ?? "";
|
|
38886
|
+
function capacityOf(plan) {
|
|
38887
|
+
return plan.kind === "subscription" ? plan.capacity : 1;
|
|
38888
|
+
}
|
|
38889
|
+
function assessRefusedNested(member, nested, nowMs) {
|
|
38890
|
+
const refusal2 = nested.earliestReturn === void 0 ? { reason: `no member of pool "${nested.pool}" can be picked` } : { reason: `every member of pool "${nested.pool}" is refused; ${nested.earliestReturn.identity} returns at ${new Date(nested.earliestReturn.atMs).toISOString()} (in ${formatAge(nested.earliestReturn.atMs - nowMs)})`, blockedUntilMs: nested.earliestReturn.atMs };
|
|
39148
38891
|
return {
|
|
39149
|
-
|
|
39150
|
-
|
|
39151
|
-
|
|
39152
|
-
|
|
39153
|
-
|
|
39154
|
-
|
|
38892
|
+
candidate: {
|
|
38893
|
+
identity: member.identity,
|
|
38894
|
+
class: "ineligible",
|
|
38895
|
+
...refusal2.blockedUntilMs === void 0 ? {} : { blockedUntilMs: refusal2.blockedUntilMs },
|
|
38896
|
+
plan: planOf(member.account),
|
|
38897
|
+
reasons: [refusal2.reason]
|
|
38898
|
+
}
|
|
39155
38899
|
};
|
|
39156
38900
|
}
|
|
39157
|
-
function
|
|
39158
|
-
const
|
|
39159
|
-
|
|
39160
|
-
|
|
39161
|
-
return sameFamilyOtherVersion(a10, b) ? "similar" : "distinct";
|
|
38901
|
+
function assess(member, nowMs) {
|
|
38902
|
+
const nested = member.nested;
|
|
38903
|
+
if (nested === void 0) {
|
|
38904
|
+
return assessIdentity(member, nowMs);
|
|
39162
38905
|
}
|
|
39163
|
-
if (
|
|
39164
|
-
return
|
|
38906
|
+
if (nested.kind === "refused") {
|
|
38907
|
+
return assessRefusedNested(member, nested, nowMs);
|
|
39165
38908
|
}
|
|
39166
|
-
|
|
38909
|
+
const assessment = assessIdentity(member, nowMs);
|
|
38910
|
+
return { ...assessment, candidate: { ...assessment.candidate, reasons: [`picked by pool "${nested.pool}"`, ...nested.reasons] } };
|
|
39167
38911
|
}
|
|
39168
|
-
function
|
|
39169
|
-
|
|
39170
|
-
|
|
38912
|
+
function assessIdentity(member, nowMs) {
|
|
38913
|
+
const plan = planOf(member.account);
|
|
38914
|
+
const planReasons = plan.kind === "pay-per-use" ? ["billed by use (no plan allowance)"] : plan.recognised ? [`${String(plan.capacity)}x plan`] : [`plan tier ${plan.tier === void 0 ? "not known" : `"${plan.tier}" not recognised`}, counted as 1x`];
|
|
38915
|
+
const base = { identity: member.identity, plan };
|
|
38916
|
+
if (member.readError !== void 0) {
|
|
38917
|
+
return { candidate: { ...base, class: "unknown", reasons: [`usage state unreadable: ${member.readError}`, ...planReasons] } };
|
|
39171
38918
|
}
|
|
39172
|
-
|
|
39173
|
-
|
|
38919
|
+
const state = member.snapshot?.providers[ANTHROPIC_PROVIDER];
|
|
38920
|
+
const unified = unifiedOf(state);
|
|
38921
|
+
if (member.snapshot === void 0 || state === void 0 || unified === void 0) {
|
|
38922
|
+
return { candidate: { ...base, class: "unknown", reasons: ["no usage recorded yet, so its quota is unknown (turn on trackUsage for it)", ...planReasons] } };
|
|
39174
38923
|
}
|
|
39175
|
-
|
|
38924
|
+
const observedAgo = state.rateLimit === void 0 ? "" : ` (last seen ${formatAge(nowMs - Date.parse(state.rateLimit.observedAt))} ago)`;
|
|
38925
|
+
const fiveHourWindow = unified.fiveHour;
|
|
38926
|
+
const sevenDayWindow = unified.sevenDay;
|
|
38927
|
+
const five = fiveHourWindow === void 0 ? void 0 : effectiveWindow(fiveHourWindow, nowMs);
|
|
38928
|
+
const seven = sevenDayWindow === void 0 ? void 0 : effectiveWindow(sevenDayWindow, nowMs);
|
|
38929
|
+
const windowReasons = [
|
|
38930
|
+
...fiveHourWindow === void 0 || five === void 0 ? [] : [describeWindow("5h", fiveHourWindow, five, nowMs)],
|
|
38931
|
+
...sevenDayWindow === void 0 || seven === void 0 ? [] : [describeWindow("7d", sevenDayWindow, seven, nowMs)]
|
|
38932
|
+
];
|
|
38933
|
+
const overageWindow = soleOverageWindow(unified);
|
|
38934
|
+
const overage = overageWindow === void 0 ? void 0 : effectiveWindow(overageWindow, nowMs);
|
|
38935
|
+
const overageReasons = overageWindow === void 0 || overage === void 0 ? [] : [describeWindow("extra usage", overageWindow, overage, nowMs)];
|
|
38936
|
+
const blockedUntil = Math.max(
|
|
38937
|
+
windowBlockedUntil([five, seven, overage].flatMap((window) => window === void 0 ? [] : [window])) ?? 0,
|
|
38938
|
+
limitBlockedUntil(state, nowMs) ?? 0
|
|
38939
|
+
);
|
|
38940
|
+
if (blockedUntil > nowMs) {
|
|
38941
|
+
if (unified.overageStatus === "allowed") {
|
|
38942
|
+
return { candidate: { ...base, class: "pay-per-use", planReturnsAtMs: blockedUntil, reasons: [`plan exhausted until ${new Date(blockedUntil).toISOString()} (in ${formatAge(blockedUntil - nowMs)}), continues as extra usage`, ...windowReasons, ...planReasons] } };
|
|
38943
|
+
}
|
|
38944
|
+
return { candidate: { ...base, class: "ineligible", blockedUntilMs: blockedUntil, reasons: [`refused until ${new Date(blockedUntil).toISOString()} (in ${formatAge(blockedUntil - nowMs)})`, ...unified.fallbackAvailable === true ? ["a fallback is on offer, so requests for some models may still be served"] : [], ...windowReasons, ...overageReasons, ...planReasons] } };
|
|
38945
|
+
}
|
|
38946
|
+
if (plan.kind === "pay-per-use" || fiveHourWindow === void 0 && sevenDayWindow === void 0) {
|
|
38947
|
+
const headroom = overage?.utilization === void 0 ? void 0 : Math.max(0, 1 - overage.utilization);
|
|
38948
|
+
return { candidate: { ...base, class: "pay-per-use", ...headroom === void 0 ? {} : { headroom }, reasons: [...plan.kind === "pay-per-use" ? planReasons : ["no plan windows reported, so usage bills as extra usage"], ...overageReasons] } };
|
|
38949
|
+
}
|
|
38950
|
+
const basis = seven?.utilization !== void 0 ? { window: seven, windowMs: SEVEN_DAY_WINDOW_MS, name: "sevenDay" } : five?.utilization !== void 0 ? { window: five, windowMs: FIVE_HOUR_WINDOW_MS, name: "fiveHour" } : void 0;
|
|
38951
|
+
if (basis?.window.utilization === void 0) {
|
|
38952
|
+
return { candidate: { ...base, class: "unknown", reasons: ["quota windows reported no utilisation", ...windowReasons, ...planReasons] } };
|
|
38953
|
+
}
|
|
38954
|
+
const remaining = Math.max(0, 1 - basis.window.utilization);
|
|
38955
|
+
const untilResetMs = basis.window.resetsAtMs === void 0 ? basis.windowMs : Math.max(basis.window.resetsAtMs - nowMs, MS_PER_SECOND5);
|
|
38956
|
+
const weeklyScore = remaining * plan.capacity / (untilResetMs / MS_PER_HOUR2);
|
|
38957
|
+
const fiveRemaining = five?.utilization === void 0 ? void 0 : Math.max(0, 1 - five.utilization);
|
|
38958
|
+
const fiveUntil = five?.resetsAtMs === void 0 ? FIVE_HOUR_WINDOW_MS : Math.max(five.resetsAtMs - nowMs, MS_PER_SECOND5);
|
|
38959
|
+
const ratio = windowRatio(member.records);
|
|
38960
|
+
const fiveHourScore = basis.name === "sevenDay" && fiveRemaining !== void 0 && ratio !== void 0 ? Math.min(fiveRemaining * ratio, remaining) * plan.capacity / (fiveUntil / MS_PER_HOUR2) : void 0;
|
|
38961
|
+
const fiveHourLeads = fiveHourScore !== void 0 && fiveHourScore > weeklyScore;
|
|
38962
|
+
const score = fiveHourLeads ? fiveHourScore : weeklyScore;
|
|
38963
|
+
const scoreWindow = fiveHourLeads ? "fiveHour" : basis.name;
|
|
38964
|
+
const fiveHourTermReasons = basis.name !== "sevenDay" || fiveRemaining === void 0 ? [] : ratio === void 0 ? ["5h reset not scored: no measured 5h to 7d ratio yet"] : fiveHourLeads ? [`5h term leads: ${percent(fiveRemaining)} of 5h unused is about ${percent(Math.min(fiveRemaining * ratio, remaining))} of the week at the measured ratio, resets in ${formatAge(fiveUntil)}`] : [];
|
|
38965
|
+
const burn = windowBurn(member.records, "fiveHour");
|
|
38966
|
+
const sevenRemaining = seven?.utilization === void 0 ? void 0 : Math.max(0, 1 - seven.utilization);
|
|
38967
|
+
const sevenUntil = seven?.resetsAtMs === void 0 ? SEVEN_DAY_WINDOW_MS : Math.max(seven.resetsAtMs - nowMs, MS_PER_SECOND5);
|
|
38968
|
+
const sevenDayBurn = windowBurn(member.records, "sevenDay");
|
|
38969
|
+
return {
|
|
38970
|
+
candidate: { ...base, class: "scored", score, scoreWindow, reasons: [...fiveHourTermReasons, ...windowReasons.map((reason, index) => index === windowReasons.length - 1 ? `${reason}${observedAgo}` : reason), ...planReasons] },
|
|
38971
|
+
...fiveRemaining === void 0 ? {} : { fiveHour: { remaining: fiveRemaining, untilResetMs: fiveUntil } },
|
|
38972
|
+
...burn === void 0 ? {} : { burn },
|
|
38973
|
+
...sevenRemaining === void 0 ? {} : { sevenDay: { remaining: sevenRemaining, untilResetMs: sevenUntil } },
|
|
38974
|
+
...sevenDayBurn === void 0 ? {} : { sevenDayBurn }
|
|
38975
|
+
};
|
|
39176
38976
|
}
|
|
39177
|
-
|
|
39178
|
-
|
|
39179
|
-
|
|
39180
|
-
|
|
39181
|
-
|
|
39182
|
-
|
|
39183
|
-
|
|
39184
|
-
|
|
39185
|
-
|
|
39186
|
-
|
|
39187
|
-
|
|
39188
|
-
|
|
39189
|
-
|
|
39190
|
-
|
|
39191
|
-
|
|
39192
|
-
|
|
39193
|
-
|
|
39194
|
-
|
|
39195
|
-
|
|
39196
|
-
|
|
39197
|
-
|
|
39198
|
-
|
|
39199
|
-
|
|
39200
|
-
|
|
39201
|
-
|
|
39202
|
-
|
|
39203
|
-
|
|
39204
|
-
|
|
39205
|
-
|
|
39206
|
-
|
|
39207
|
-
|
|
39208
|
-
|
|
39209
|
-
|
|
39210
|
-
|
|
39211
|
-
|
|
38977
|
+
function poolFactsOf(member, nowMs, resuming, sticky) {
|
|
38978
|
+
const { fiveHour, sevenDay, extraUsage } = quotaFactsOf(member.snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit?.unified, nowMs);
|
|
38979
|
+
const burn = windowBurn(member.records, "fiveHour");
|
|
38980
|
+
return {
|
|
38981
|
+
...fiveHour === void 0 ? {} : { fiveHour },
|
|
38982
|
+
...sevenDay === void 0 ? {} : { sevenDay },
|
|
38983
|
+
...extraUsage === void 0 ? {} : { extraUsage },
|
|
38984
|
+
...burn === void 0 ? {} : { burnPerHour: burn * MS_PER_HOUR2 },
|
|
38985
|
+
resuming,
|
|
38986
|
+
...sticky?.identity === member.identity ? { lastPickHoursAgo: Math.max(0, (nowMs - Date.parse(sticky.at)) / MS_PER_HOUR2) } : {}
|
|
38987
|
+
};
|
|
38988
|
+
}
|
|
38989
|
+
function rankPool(input2) {
|
|
38990
|
+
const { members: members2, nowMs } = input2;
|
|
38991
|
+
const assessments = members2.map((member) => ({ member, ...assess(member, nowMs) }));
|
|
38992
|
+
const demands = assessments.flatMap(({ candidate, burn }) => burn === void 0 ? [] : [burn * capacityOf(candidate.plan)]);
|
|
38993
|
+
const sharedDemand = demands.length === 0 ? void 0 : Math.max(...demands);
|
|
38994
|
+
const guarded2 = assessments.map((assessment) => {
|
|
38995
|
+
const { candidate } = assessment;
|
|
38996
|
+
if (candidate.class === "ineligible" || assessment.member.policy === void 0) {
|
|
38997
|
+
return assessment;
|
|
38998
|
+
}
|
|
38999
|
+
const context = { nowMs, env: {}, pool: poolFactsOf(assessment.member, nowMs, input2.resuming, input2.sticky) };
|
|
39000
|
+
const verdict = evaluateWhen(assessment.member.policy, context);
|
|
39001
|
+
if (verdict.status === "indeterminate") {
|
|
39002
|
+
return { ...assessment, candidate: { ...candidate, policyDemoted: true, reasons: [`policy undecided (${verdict.checked.join(", ") === "predicate" ? "predicate" : verdict.checked.join(", ")}): ${verdict.reason}`, ...candidate.reasons] } };
|
|
39003
|
+
}
|
|
39004
|
+
if (verdict.passed) {
|
|
39005
|
+
return assessment;
|
|
39006
|
+
}
|
|
39007
|
+
return { ...assessment, candidate: { ...candidate, class: "ineligible", reasons: [`skipped by policy (${verdict.checked.join(", ")}: did not hold)`, ...candidate.reasons] } };
|
|
39008
|
+
});
|
|
39009
|
+
const candidates = guarded2.map((assessment) => {
|
|
39010
|
+
const { candidate, fiveHour, burn } = assessment;
|
|
39011
|
+
const pace = burn ?? (sharedDemand === void 0 ? void 0 : sharedDemand / capacityOf(candidate.plan));
|
|
39012
|
+
const { sevenDay, sevenDayBurn } = assessment;
|
|
39013
|
+
if (candidate.class !== "scored") {
|
|
39014
|
+
return { ...candidate, feasible: true };
|
|
39015
|
+
}
|
|
39016
|
+
const drySpots = [];
|
|
39017
|
+
const dryAfterMs = [];
|
|
39018
|
+
if (fiveHour !== void 0 && pace !== void 0) {
|
|
39019
|
+
const runsDryInMs = fiveHour.remaining / pace;
|
|
39020
|
+
if (runsDryInMs < fiveHour.untilResetMs) {
|
|
39021
|
+
dryAfterMs.push(runsDryInMs);
|
|
39022
|
+
drySpots.push(`5h window would run dry in ${formatAge(runsDryInMs)}, before it resets in ${formatAge(fiveHour.untilResetMs)}`);
|
|
39023
|
+
}
|
|
39024
|
+
}
|
|
39025
|
+
if (sevenDay !== void 0 && sevenDayBurn !== void 0) {
|
|
39026
|
+
const runsDryInMs = sevenDay.remaining / sevenDayBurn;
|
|
39027
|
+
if (runsDryInMs < sevenDay.untilResetMs) {
|
|
39028
|
+
dryAfterMs.push(runsDryInMs);
|
|
39029
|
+
drySpots.push(`7d window would run dry in ${formatAge(runsDryInMs)}, before it resets in ${formatAge(sevenDay.untilResetMs)}`);
|
|
39030
|
+
}
|
|
39031
|
+
}
|
|
39032
|
+
const { sticky: sticky2 } = input2;
|
|
39033
|
+
const warmHere = sticky2?.identity === candidate.identity && nowMs - Date.parse(sticky2.at) <= PROMPT_CACHE_TTL_MS;
|
|
39034
|
+
if (input2.resuming && input2.resumeContextTokens !== void 0 && fiveHour !== void 0 && !warmHere) {
|
|
39035
|
+
const perToken = utilisationPerBilledToken(assessment.member.records);
|
|
39036
|
+
const committed = input2.committedContextTokens?.[candidate.identity] ?? 0;
|
|
39037
|
+
const cost = perToken === void 0 ? void 0 : (input2.resumeContextTokens + committed) * perToken;
|
|
39038
|
+
if (cost !== void 0 && cost > fiveHour.remaining) {
|
|
39039
|
+
dryAfterMs.push(0);
|
|
39040
|
+
const alongside = committed === 0 ? "" : ` (with ${String(committed)} tokens of other conversations already moving here)`;
|
|
39041
|
+
drySpots.push(`resuming a ${String(input2.resumeContextTokens)}-token conversation here${alongside} would cost about ${percent(cost)} of the 5h window, which has ${percent(fiveHour.remaining)} left`);
|
|
39042
|
+
}
|
|
39043
|
+
}
|
|
39044
|
+
if (drySpots.length === 0) {
|
|
39045
|
+
return { ...candidate, feasible: true };
|
|
39046
|
+
}
|
|
39047
|
+
return { ...candidate, feasible: false, runsDryAtMs: nowMs + Math.min(...dryAfterMs), reasons: [...drySpots, ...candidate.reasons] };
|
|
39048
|
+
});
|
|
39049
|
+
const ordered = input2.preference === "listed" ? [...candidates] : [...candidates].sort(
|
|
39050
|
+
(left, right) => CLASS_ORDER[left.class] - CLASS_ORDER[right.class] || Number(left.policyDemoted ?? false) - Number(right.policyDemoted ?? false) || Number(right.feasible) - Number(left.feasible) || (right.headroom ?? 1) - (left.headroom ?? 1) || (right.score ?? 0) - (left.score ?? 0) || left.identity.localeCompare(right.identity)
|
|
39051
|
+
);
|
|
39052
|
+
const sticky = input2.sticky;
|
|
39053
|
+
const stickyIndex = sticky === void 0 ? -1 : ordered.findIndex((candidate) => candidate.identity === sticky.identity);
|
|
39054
|
+
const stickyCandidate = ordered[stickyIndex];
|
|
39055
|
+
const keepSticky = stickyCandidate?.class === "scored" && stickyCandidate.feasible;
|
|
39056
|
+
if (sticky !== void 0 && keepSticky) {
|
|
39057
|
+
const ageMs = nowMs - Date.parse(sticky.at);
|
|
39058
|
+
const warm = ageMs <= PROMPT_CACHE_TTL_MS;
|
|
39059
|
+
if (input2.resuming || warm) {
|
|
39060
|
+
const why = warm ? `used here ${formatAge(ageMs)} ago, prompt cache still warm` : "resuming a conversation started on this account";
|
|
39061
|
+
ordered.splice(stickyIndex, 1);
|
|
39062
|
+
ordered.unshift({ ...stickyCandidate, reasons: [why, ...stickyCandidate.reasons] });
|
|
39063
|
+
}
|
|
39064
|
+
}
|
|
39065
|
+
const movedOff = sticky !== void 0 && input2.resuming && !keepSticky ? { identity: sticky.identity, reason: stickyCandidate?.reasons[0] ?? "no longer among the pool's members" } : void 0;
|
|
39066
|
+
const pick2 = ordered.find((candidate) => candidate.class !== "ineligible");
|
|
39067
|
+
const returns = ordered.flatMap((candidate) => candidate.blockedUntilMs === void 0 ? [] : [{ identity: candidate.identity, atMs: candidate.blockedUntilMs }]);
|
|
39068
|
+
const earliestReturn = returns.length === 0 ? void 0 : returns.reduce((soonest, entry) => entry.atMs < soonest.atMs ? entry : soonest);
|
|
39069
|
+
const holdForReturn = pick2?.runsDryAtMs === void 0 ? void 0 : returns.filter((entry) => entry.atMs < (pick2.runsDryAtMs ?? 0)).reduce((soonest, entry) => soonest === void 0 || entry.atMs < soonest.atMs ? entry : soonest, void 0);
|
|
39070
|
+
return {
|
|
39071
|
+
candidates: ordered,
|
|
39072
|
+
...pick2 === void 0 ? { ...earliestReturn === void 0 ? {} : { earliestReturn } } : { pick: pick2 },
|
|
39073
|
+
...movedOff === void 0 || pick2 === void 0 ? {} : { movedOff },
|
|
39074
|
+
...pick2?.planReturnsAtMs === void 0 ? {} : { planReturn: { identity: pick2.identity, atMs: pick2.planReturnsAtMs } },
|
|
39075
|
+
...holdForReturn === void 0 ? {} : { holdForReturn }
|
|
39076
|
+
};
|
|
39077
|
+
}
|
|
39078
|
+
var MS_PER_SECOND5, MS_PER_HOUR2, HOURS_PER_DAY2, FIVE_HOURS, PROMPT_CACHE_TTL_HOURS, PERCENT, SEVEN_DAYS, FIVE_HOUR_WINDOW_MS, SEVEN_DAY_WINDOW_MS, PROMPT_CACHE_TTL_MS, CLASS_ORDER;
|
|
39079
|
+
var init_pick = __esm({
|
|
39080
|
+
"src/usage/pick.ts"() {
|
|
39081
|
+
"use strict";
|
|
39082
|
+
init_conditions();
|
|
39083
|
+
init_plan2();
|
|
39084
|
+
init_middleware();
|
|
39085
|
+
init_preflight();
|
|
39086
|
+
init_quotaFacts();
|
|
39087
|
+
init_rateLimit();
|
|
39088
|
+
MS_PER_SECOND5 = 1e3;
|
|
39089
|
+
MS_PER_HOUR2 = 36e5;
|
|
39090
|
+
HOURS_PER_DAY2 = 24;
|
|
39091
|
+
FIVE_HOURS = 5;
|
|
39092
|
+
PROMPT_CACHE_TTL_HOURS = 1;
|
|
39093
|
+
PERCENT = 100;
|
|
39094
|
+
SEVEN_DAYS = 7;
|
|
39095
|
+
FIVE_HOUR_WINDOW_MS = FIVE_HOURS * MS_PER_HOUR2;
|
|
39096
|
+
SEVEN_DAY_WINDOW_MS = SEVEN_DAYS * HOURS_PER_DAY2 * MS_PER_HOUR2;
|
|
39097
|
+
PROMPT_CACHE_TTL_MS = PROMPT_CACHE_TTL_HOURS * MS_PER_HOUR2;
|
|
39098
|
+
CLASS_ORDER = { scored: 0, unknown: 1, "pay-per-use": 2, ineligible: 3 };
|
|
39212
39099
|
}
|
|
39213
39100
|
});
|
|
39214
39101
|
|
|
39215
|
-
// src/
|
|
39216
|
-
function
|
|
39217
|
-
|
|
39218
|
-
return slash === -1 ? ref : ref.slice(slash + 1);
|
|
39219
|
-
}
|
|
39220
|
-
function familyKeyOf(rawModel) {
|
|
39221
|
-
const identity = modelIdentity(rawModel);
|
|
39222
|
-
return identity.variant === "" ? identity.familyAndVersion : `${identity.familyAndVersion}${VARIANT_SEPARATOR}${identity.variant}`;
|
|
39223
|
-
}
|
|
39224
|
-
function assertionsOf(models) {
|
|
39225
|
-
return { same: models?.same ?? [], distinct: models?.distinct ?? [] };
|
|
39102
|
+
// src/usage/read.ts
|
|
39103
|
+
function segmentDay(epochMs) {
|
|
39104
|
+
return new Date(epochMs).toISOString().slice(0, "YYYY-MM-DD".length);
|
|
39226
39105
|
}
|
|
39227
|
-
function
|
|
39228
|
-
|
|
39229
|
-
return false;
|
|
39230
|
-
}
|
|
39231
|
-
const leftGroup = assertions.same.find((group) => group.includes(left));
|
|
39232
|
-
const rightGroup = assertions.same.find((group) => group.includes(right));
|
|
39233
|
-
if (leftGroup !== void 0 && leftGroup === rightGroup) {
|
|
39234
|
-
return true;
|
|
39235
|
-
}
|
|
39236
|
-
if (leftGroup !== void 0 && !leftGroup.includes(right) || rightGroup !== void 0 && !rightGroup.includes(left)) {
|
|
39237
|
-
return false;
|
|
39238
|
-
}
|
|
39239
|
-
return relateModels(modelOf(left), modelOf(right)) === "same";
|
|
39106
|
+
function segmentName(day, pid) {
|
|
39107
|
+
return `${day}.${String(pid)}.jsonl`;
|
|
39240
39108
|
}
|
|
39241
|
-
function
|
|
39242
|
-
return
|
|
39109
|
+
function listLogSegments(fs31, logDir) {
|
|
39110
|
+
return fs31.readdir(logDir).flatMap((name) => {
|
|
39111
|
+
const match = SEGMENT_RE.exec(name);
|
|
39112
|
+
const day = match?.[1];
|
|
39113
|
+
if (day === void 0) {
|
|
39114
|
+
return [];
|
|
39115
|
+
}
|
|
39116
|
+
return [{ name, day, endsAt: Date.parse(`${day}T00:00:00.000Z`) + DAY_MS }];
|
|
39117
|
+
}).sort((left, right) => left.day.localeCompare(right.day) || left.name.localeCompare(right.name));
|
|
39243
39118
|
}
|
|
39244
|
-
function
|
|
39245
|
-
const
|
|
39246
|
-
const
|
|
39247
|
-
|
|
39248
|
-
for (const
|
|
39249
|
-
|
|
39250
|
-
|
|
39251
|
-
|
|
39252
|
-
|
|
39253
|
-
|
|
39254
|
-
|
|
39119
|
+
function readUsageLog(fs31, logDir, options = {}) {
|
|
39120
|
+
const { sinceMs } = options;
|
|
39121
|
+
const records = [];
|
|
39122
|
+
let invalidLines = 0;
|
|
39123
|
+
for (const segment of listLogSegments(fs31, logDir)) {
|
|
39124
|
+
if (sinceMs !== void 0 && segment.endsAt <= sinceMs) {
|
|
39125
|
+
continue;
|
|
39126
|
+
}
|
|
39127
|
+
const read = readSegment(fs31, logDir, segment);
|
|
39128
|
+
if (read === void 0) {
|
|
39129
|
+
continue;
|
|
39130
|
+
}
|
|
39131
|
+
invalidLines += read.invalidLines;
|
|
39132
|
+
for (const record2 of read.records) {
|
|
39133
|
+
if (sinceMs === void 0 || Date.parse(record2.at) >= sinceMs) {
|
|
39134
|
+
records.push(record2);
|
|
39135
|
+
}
|
|
39255
39136
|
}
|
|
39256
39137
|
}
|
|
39257
|
-
|
|
39138
|
+
records.sort((left, right) => left.at.localeCompare(right.at));
|
|
39139
|
+
return { records, invalidLines };
|
|
39258
39140
|
}
|
|
39259
|
-
function
|
|
39260
|
-
|
|
39141
|
+
function readSegment(fs31, logDir, segment) {
|
|
39142
|
+
const contents = fs31.readFileUtf8(import_node_path26.default.join(logDir, segment.name));
|
|
39143
|
+
if (contents === void 0) {
|
|
39261
39144
|
return void 0;
|
|
39262
39145
|
}
|
|
39263
|
-
const
|
|
39264
|
-
|
|
39265
|
-
|
|
39266
|
-
|
|
39267
|
-
|
|
39268
|
-
|
|
39269
|
-
|
|
39270
|
-
|
|
39271
|
-
|
|
39272
|
-
|
|
39273
|
-
|
|
39274
|
-
}
|
|
39275
|
-
|
|
39276
|
-
|
|
39277
|
-
|
|
39278
|
-
|
|
39279
|
-
|
|
39280
|
-
|
|
39281
|
-
|
|
39146
|
+
const records = [];
|
|
39147
|
+
let invalidLines = 0;
|
|
39148
|
+
const lines = contents.split("\n");
|
|
39149
|
+
lines.pop();
|
|
39150
|
+
for (const line of lines) {
|
|
39151
|
+
if (line === "") {
|
|
39152
|
+
continue;
|
|
39153
|
+
}
|
|
39154
|
+
let raw;
|
|
39155
|
+
try {
|
|
39156
|
+
raw = JSON.parse(line);
|
|
39157
|
+
} catch {
|
|
39158
|
+
invalidLines += 1;
|
|
39159
|
+
continue;
|
|
39160
|
+
}
|
|
39161
|
+
const parsed = UsageRecordSchema.safeParse(raw);
|
|
39162
|
+
if (!parsed.success) {
|
|
39163
|
+
invalidLines += 1;
|
|
39164
|
+
continue;
|
|
39282
39165
|
}
|
|
39166
|
+
records.push(parsed.data);
|
|
39283
39167
|
}
|
|
39284
|
-
return
|
|
39285
|
-
}
|
|
39286
|
-
function familyOfRef(families, ref) {
|
|
39287
|
-
return families.find((family) => family.refs.includes(ref));
|
|
39288
|
-
}
|
|
39289
|
-
function accountRefsOf(models) {
|
|
39290
|
-
const named = [...(models?.same ?? []).flat(), ...Object.values(models?.families ?? {}).flatMap((settings2) => settings2.names ?? [])];
|
|
39291
|
-
return [...new Set(named.filter((ref) => ref.startsWith("acct:")))];
|
|
39168
|
+
return { records, invalidLines };
|
|
39292
39169
|
}
|
|
39293
|
-
|
|
39294
|
-
|
|
39295
|
-
|
|
39296
|
-
|
|
39297
|
-
init_identity2();
|
|
39298
|
-
FAMILY_PREFIX = "family:";
|
|
39299
|
-
VARIANT_SEPARATOR = "+";
|
|
39170
|
+
function readRecentUsageRecords(fs31, logDir, count2) {
|
|
39171
|
+
const byDay = /* @__PURE__ */ new Map();
|
|
39172
|
+
for (const segment of listLogSegments(fs31, logDir)) {
|
|
39173
|
+
byDay.set(segment.day, [...byDay.get(segment.day) ?? [], segment]);
|
|
39300
39174
|
}
|
|
39301
|
-
|
|
39302
|
-
|
|
39303
|
-
|
|
39304
|
-
|
|
39305
|
-
|
|
39306
|
-
|
|
39307
|
-
|
|
39308
|
-
|
|
39309
|
-
|
|
39310
|
-
|
|
39311
|
-
|
|
39312
|
-
|
|
39313
|
-
|
|
39314
|
-
|
|
39175
|
+
const days = [...byDay.values()];
|
|
39176
|
+
let records = [];
|
|
39177
|
+
for (let index = days.length - 1; index >= 0; index -= 1) {
|
|
39178
|
+
const dayRecords = [];
|
|
39179
|
+
for (const segment of days[index] ?? []) {
|
|
39180
|
+
dayRecords.push(...readSegment(fs31, logDir, segment)?.records ?? []);
|
|
39181
|
+
}
|
|
39182
|
+
records = [...dayRecords, ...records];
|
|
39183
|
+
records.sort((left, right) => left.at.localeCompare(right.at));
|
|
39184
|
+
const olderDay = days[index - 1]?.[0];
|
|
39185
|
+
const newestHeld = records[records.length - count2];
|
|
39186
|
+
if (olderDay === void 0 || newestHeld !== void 0 && Date.parse(newestHeld.at) >= olderDay.endsAt) {
|
|
39187
|
+
break;
|
|
39188
|
+
}
|
|
39189
|
+
}
|
|
39190
|
+
return records.slice(-count2);
|
|
39315
39191
|
}
|
|
39316
|
-
function
|
|
39317
|
-
if (!
|
|
39318
|
-
|
|
39192
|
+
function snapshotPath(snapshotsDir, identity) {
|
|
39193
|
+
if (!isIdentityName(identity)) {
|
|
39194
|
+
throw new Error(`"${identity}" is not a valid identity name.`);
|
|
39319
39195
|
}
|
|
39320
|
-
|
|
39321
|
-
|
|
39322
|
-
|
|
39323
|
-
|
|
39196
|
+
return import_node_path26.default.join(snapshotsDir, `${identity}.json`);
|
|
39197
|
+
}
|
|
39198
|
+
function readUsageSnapshot(fs31, snapshotsDir, identity) {
|
|
39199
|
+
const file2 = snapshotPath(snapshotsDir, identity);
|
|
39200
|
+
const raw = fs31.readFileUtf8(file2);
|
|
39201
|
+
if (raw === void 0) {
|
|
39324
39202
|
return void 0;
|
|
39325
39203
|
}
|
|
39326
|
-
|
|
39327
|
-
|
|
39328
|
-
|
|
39204
|
+
let parsed;
|
|
39205
|
+
try {
|
|
39206
|
+
parsed = JSON.parse(raw);
|
|
39207
|
+
} catch {
|
|
39208
|
+
throw new UsageSnapshotError(file2, "not valid JSON");
|
|
39329
39209
|
}
|
|
39330
|
-
|
|
39331
|
-
|
|
39210
|
+
const snapshot = UsageSnapshotSchema.safeParse(parsed);
|
|
39211
|
+
if (!snapshot.success) {
|
|
39212
|
+
throw new UsageSnapshotError(file2, snapshot.error.issues.map((issue2) => `${issue2.path.join(".")}: ${issue2.message}`).join("; "));
|
|
39332
39213
|
}
|
|
39333
|
-
|
|
39334
|
-
|
|
39214
|
+
return snapshot.data;
|
|
39215
|
+
}
|
|
39216
|
+
function listUsageSnapshots(fs31, snapshotsDir) {
|
|
39217
|
+
return fs31.readdir(snapshotsDir).flatMap((name) => {
|
|
39218
|
+
if (!name.endsWith(".json")) {
|
|
39219
|
+
return [];
|
|
39220
|
+
}
|
|
39221
|
+
const identity = name.slice(0, -".json".length);
|
|
39222
|
+
if (!isIdentityName(identity)) {
|
|
39223
|
+
return [];
|
|
39224
|
+
}
|
|
39225
|
+
const snapshot = readUsageSnapshot(fs31, snapshotsDir, identity);
|
|
39226
|
+
return snapshot === void 0 ? [] : [snapshot];
|
|
39227
|
+
}).sort((left, right) => left.identity.localeCompare(right.identity));
|
|
39228
|
+
}
|
|
39229
|
+
function summariseUsage(records) {
|
|
39230
|
+
const groups = /* @__PURE__ */ new Map();
|
|
39231
|
+
for (const record2 of records) {
|
|
39232
|
+
const key = `${record2.identity ?? ""}\0${record2.provider}`;
|
|
39233
|
+
const group = groups.get(key);
|
|
39234
|
+
if (group === void 0) {
|
|
39235
|
+
groups.set(key, [record2]);
|
|
39236
|
+
} else {
|
|
39237
|
+
group.push(record2);
|
|
39238
|
+
}
|
|
39335
39239
|
}
|
|
39336
|
-
const
|
|
39337
|
-
|
|
39338
|
-
|
|
39339
|
-
|
|
39340
|
-
|
|
39341
|
-
replacement: {
|
|
39342
|
-
...rest,
|
|
39343
|
-
credential: { sources, ...raw.authScheme === "apiKey" ? { target: "apiKey" } : {} },
|
|
39344
|
-
...remainingEnv === void 0 || Object.keys(remainingEnv).length === 0 ? {} : { env: remainingEnv }
|
|
39240
|
+
const summaries = [...groups.values()].flatMap((group) => {
|
|
39241
|
+
const [first] = group;
|
|
39242
|
+
const last = group.at(-1);
|
|
39243
|
+
if (first === void 0 || last === void 0) {
|
|
39244
|
+
return [];
|
|
39345
39245
|
}
|
|
39346
|
-
|
|
39246
|
+
const modelCounts = /* @__PURE__ */ new Map();
|
|
39247
|
+
for (const record2 of group) {
|
|
39248
|
+
if (record2.model !== void 0) {
|
|
39249
|
+
modelCounts.set(record2.model, (modelCounts.get(record2.model) ?? 0) + 1);
|
|
39250
|
+
}
|
|
39251
|
+
}
|
|
39252
|
+
const sum2 = (field) => group.reduce((total, record2) => total + (record2.usage?.[field] ?? 0), 0);
|
|
39253
|
+
return [
|
|
39254
|
+
{
|
|
39255
|
+
identity: first.identity,
|
|
39256
|
+
provider: first.provider,
|
|
39257
|
+
requests: group.length,
|
|
39258
|
+
failed: group.filter((record2) => record2.status >= FIRST_ERROR_STATUS).length,
|
|
39259
|
+
limits: {
|
|
39260
|
+
"rate-limited": group.filter((record2) => record2.limit?.kind === "rate-limited").length,
|
|
39261
|
+
"quota-exhausted": group.filter((record2) => record2.limit?.kind === "quota-exhausted").length
|
|
39262
|
+
},
|
|
39263
|
+
tokens: {
|
|
39264
|
+
inputTokens: sum2("inputTokens"),
|
|
39265
|
+
outputTokens: sum2("outputTokens"),
|
|
39266
|
+
cacheCreationInputTokens: sum2("cacheCreationInputTokens"),
|
|
39267
|
+
cacheReadInputTokens: sum2("cacheReadInputTokens")
|
|
39268
|
+
},
|
|
39269
|
+
firstAt: first.at,
|
|
39270
|
+
lastAt: last.at,
|
|
39271
|
+
models: [...modelCounts.entries()].sort((left, right) => right[1] - left[1] || left[0].localeCompare(right[0])).map(([model]) => model)
|
|
39272
|
+
}
|
|
39273
|
+
];
|
|
39274
|
+
});
|
|
39275
|
+
return summaries.sort((left, right) => (left.identity ?? "").localeCompare(right.identity ?? "") || left.provider.localeCompare(right.provider));
|
|
39347
39276
|
}
|
|
39348
|
-
|
|
39349
|
-
|
|
39350
|
-
|
|
39351
|
-
|
|
39277
|
+
var import_node_path26, SEGMENT_RE, DAY_MS, UsageSnapshotError, FIRST_ERROR_STATUS;
|
|
39278
|
+
var init_read = __esm({
|
|
39279
|
+
"src/usage/read.ts"() {
|
|
39280
|
+
"use strict";
|
|
39281
|
+
import_node_path26 = __toESM(require("node:path"), 1);
|
|
39282
|
+
init_account();
|
|
39283
|
+
init_schema2();
|
|
39284
|
+
SEGMENT_RE = /^(\d{4}-\d{2}-\d{2})\.(\d+)\.jsonl$/;
|
|
39285
|
+
DAY_MS = 864e5;
|
|
39286
|
+
UsageSnapshotError = class extends Error {
|
|
39287
|
+
constructor(file2, detail) {
|
|
39288
|
+
super(`${file2} is not a usage snapshot this agent-shim can read (schema version ${String(USAGE_SCHEMA_VERSION)}): ${detail}`);
|
|
39289
|
+
this.file = file2;
|
|
39290
|
+
this.name = "UsageSnapshotError";
|
|
39291
|
+
}
|
|
39292
|
+
file;
|
|
39293
|
+
};
|
|
39294
|
+
FIRST_ERROR_STATUS = 400;
|
|
39352
39295
|
}
|
|
39353
|
-
|
|
39354
|
-
|
|
39355
|
-
|
|
39296
|
+
});
|
|
39297
|
+
|
|
39298
|
+
// src/usage/store.ts
|
|
39299
|
+
function pruneUsageLog(fs31, logDir, nowMs) {
|
|
39300
|
+
const cutoff = nowMs - USAGE_RETENTION_MS;
|
|
39301
|
+
for (const segment of listLogSegments(fs31, logDir)) {
|
|
39302
|
+
if (segment.endsAt <= cutoff) {
|
|
39303
|
+
fs31.removeRecursive(import_node_path27.default.join(logDir, segment.name));
|
|
39304
|
+
}
|
|
39356
39305
|
}
|
|
39357
|
-
noteIgnoredKeys(filePath, parsed.ignored);
|
|
39358
|
-
return parsed.data;
|
|
39359
39306
|
}
|
|
39360
|
-
function
|
|
39361
|
-
|
|
39362
|
-
if (!import_node_fs11.default.existsSync(filePath)) {
|
|
39363
|
-
return void 0;
|
|
39364
|
-
}
|
|
39365
|
-
const raw = JSON.parse(import_node_fs11.default.readFileSync(filePath, "utf8"));
|
|
39366
|
-
return parseProviderFile(filePath, raw);
|
|
39307
|
+
function later(left, right) {
|
|
39308
|
+
return left.localeCompare(right) >= 0 ? left : right;
|
|
39367
39309
|
}
|
|
39368
|
-
function
|
|
39369
|
-
|
|
39370
|
-
const raw = port.readConfigFile(filePath);
|
|
39371
|
-
return raw === void 0 ? void 0 : parseProviderFile(filePath, raw);
|
|
39310
|
+
function observedAt(record2) {
|
|
39311
|
+
return new Date(Date.parse(record2.at) + record2.latencyMs).toISOString();
|
|
39372
39312
|
}
|
|
39373
|
-
function
|
|
39374
|
-
|
|
39313
|
+
function foldProviderState(current, record2) {
|
|
39314
|
+
const seen = observedAt(record2);
|
|
39315
|
+
const newest = current?.lastRequestAt === void 0 || record2.at.localeCompare(current.lastRequestAt) >= 0;
|
|
39316
|
+
const rateLimit = record2.rateLimitHeaders === void 0 || current?.rateLimit !== void 0 && current.rateLimit.observedAt.localeCompare(seen) > 0 ? current?.rateLimit : (() => {
|
|
39317
|
+
const unified = parseUnifiedRateLimit(record2.rateLimitHeaders);
|
|
39318
|
+
return { observedAt: seen, headers: record2.rateLimitHeaders, ...unified === void 0 ? {} : { unified } };
|
|
39319
|
+
})();
|
|
39320
|
+
const lastLimit = record2.limit === void 0 || current?.lastLimit !== void 0 && current.lastLimit.observedAt.localeCompare(seen) > 0 ? current?.lastLimit : { ...record2.limit, observedAt: seen, status: record2.status };
|
|
39321
|
+
const lastModel = newest ? record2.model ?? current?.lastModel : current.lastModel ?? record2.model;
|
|
39322
|
+
return {
|
|
39323
|
+
lastRequestAt: current?.lastRequestAt === void 0 ? record2.at : later(current.lastRequestAt, record2.at),
|
|
39324
|
+
...newest ? { lastStatus: record2.status } : current.lastStatus === void 0 ? {} : { lastStatus: current.lastStatus },
|
|
39325
|
+
...lastModel === void 0 ? {} : { lastModel },
|
|
39326
|
+
...rateLimit === void 0 ? {} : { rateLimit },
|
|
39327
|
+
...lastLimit === void 0 ? {} : { lastLimit },
|
|
39328
|
+
...current?.quota === void 0 ? {} : { quota: current.quota }
|
|
39329
|
+
};
|
|
39375
39330
|
}
|
|
39376
|
-
function
|
|
39377
|
-
const
|
|
39378
|
-
|
|
39379
|
-
|
|
39380
|
-
|
|
39381
|
-
|
|
39382
|
-
|
|
39383
|
-
|
|
39331
|
+
function createUsageStore(deps) {
|
|
39332
|
+
const { fs: fs31, paths } = deps;
|
|
39333
|
+
let prunedDay;
|
|
39334
|
+
const rewriteSnapshot = (identity, fold) => {
|
|
39335
|
+
if (!isIdentityName(identity)) {
|
|
39336
|
+
deps.log(`usage: no snapshot for identity "${identity}", which is not a valid identity name`);
|
|
39337
|
+
return false;
|
|
39338
|
+
}
|
|
39339
|
+
let current;
|
|
39384
39340
|
try {
|
|
39385
|
-
|
|
39341
|
+
current = readUsageSnapshot(fs31, paths.usageSnapshotsDir, identity);
|
|
39386
39342
|
} catch (error63) {
|
|
39387
|
-
if (!(error63 instanceof
|
|
39343
|
+
if (!(error63 instanceof UsageSnapshotError)) {
|
|
39388
39344
|
throw error63;
|
|
39389
39345
|
}
|
|
39390
|
-
|
|
39391
|
-
continue;
|
|
39346
|
+
deps.log(`usage: replacing an unreadable snapshot: ${error63.message}`);
|
|
39392
39347
|
}
|
|
39393
|
-
|
|
39394
|
-
|
|
39348
|
+
const providers = fold(current);
|
|
39349
|
+
if (providers === void 0) {
|
|
39350
|
+
return false;
|
|
39395
39351
|
}
|
|
39396
|
-
|
|
39397
|
-
|
|
39398
|
-
|
|
39399
|
-
|
|
39400
|
-
|
|
39401
|
-
|
|
39402
|
-
|
|
39403
|
-
|
|
39404
|
-
|
|
39405
|
-
|
|
39406
|
-
|
|
39407
|
-
|
|
39408
|
-
|
|
39409
|
-
|
|
39410
|
-
|
|
39411
|
-
|
|
39412
|
-
|
|
39413
|
-
|
|
39414
|
-
|
|
39415
|
-
|
|
39416
|
-
|
|
39417
|
-
|
|
39418
|
-
return
|
|
39419
|
-
|
|
39420
|
-
|
|
39421
|
-
|
|
39422
|
-
|
|
39423
|
-
|
|
39424
|
-
|
|
39425
|
-
|
|
39426
|
-
|
|
39427
|
-
|
|
39428
|
-
|
|
39429
|
-
|
|
39430
|
-
|
|
39431
|
-
|
|
39432
|
-
|
|
39433
|
-
|
|
39434
|
-
|
|
39435
|
-
|
|
39436
|
-
|
|
39437
|
-
|
|
39438
|
-
|
|
39439
|
-
|
|
39440
|
-
|
|
39441
|
-
|
|
39442
|
-
|
|
39443
|
-
|
|
39444
|
-
|
|
39445
|
-
|
|
39446
|
-
|
|
39447
|
-
|
|
39448
|
-
|
|
39449
|
-
|
|
39450
|
-
|
|
39451
|
-
throw new ProviderKindMismatchError("Antigravity settings apply only to an antigravity provider (--kind antigravity).");
|
|
39452
|
-
}
|
|
39453
|
-
const shared = {
|
|
39454
|
-
displayName: input2.displayName,
|
|
39455
|
-
credential: { sources: input2.sources, ...input2.target === void 0 ? {} : { target: input2.target } },
|
|
39456
|
-
...input2.env === void 0 || Object.keys(input2.env).length === 0 ? {} : { env: input2.env },
|
|
39457
|
-
...input2.pickerModels === void 0 || input2.pickerModels.length === 0 ? {} : { pickerModels: input2.pickerModels }
|
|
39352
|
+
let account;
|
|
39353
|
+
try {
|
|
39354
|
+
account = deps.readAccount(identity);
|
|
39355
|
+
} catch (error63) {
|
|
39356
|
+
if (!(error63 instanceof AccountMetadataError)) {
|
|
39357
|
+
throw error63;
|
|
39358
|
+
}
|
|
39359
|
+
deps.log(`usage: snapshot for ${identity} written without account metadata: ${error63.message}`);
|
|
39360
|
+
}
|
|
39361
|
+
const snapshot = UsageSnapshotSchema.parse({
|
|
39362
|
+
schemaVersion: USAGE_SCHEMA_VERSION,
|
|
39363
|
+
identity,
|
|
39364
|
+
updatedAt: new Date(deps.now()).toISOString(),
|
|
39365
|
+
...account === void 0 ? {} : { account },
|
|
39366
|
+
providers
|
|
39367
|
+
});
|
|
39368
|
+
fs31.mkdirPrivate(paths.usageSnapshotsDir);
|
|
39369
|
+
fs31.writeFilePrivate(snapshotPath(paths.usageSnapshotsDir, identity), `${JSON.stringify(snapshot, null, 2)}
|
|
39370
|
+
`);
|
|
39371
|
+
deps.publish?.(snapshot);
|
|
39372
|
+
return true;
|
|
39373
|
+
};
|
|
39374
|
+
return {
|
|
39375
|
+
record: (input2) => {
|
|
39376
|
+
const record2 = UsageRecordSchema.parse(input2);
|
|
39377
|
+
const nowMs = deps.now();
|
|
39378
|
+
fs31.mkdirPrivate(paths.usageDir);
|
|
39379
|
+
fs31.mkdirPrivate(paths.usageLogDir);
|
|
39380
|
+
const day = segmentDay(nowMs);
|
|
39381
|
+
if (prunedDay !== day) {
|
|
39382
|
+
pruneUsageLog(fs31, paths.usageLogDir, nowMs);
|
|
39383
|
+
prunedDay = day;
|
|
39384
|
+
}
|
|
39385
|
+
fs31.appendFilePrivate(import_node_path27.default.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record2)}
|
|
39386
|
+
`);
|
|
39387
|
+
deps.onRecord?.(record2);
|
|
39388
|
+
if (record2.identity !== void 0) {
|
|
39389
|
+
rewriteSnapshot(record2.identity, (current) => ({ ...current?.providers, [record2.provider]: foldProviderState(current?.providers[record2.provider], record2) }));
|
|
39390
|
+
}
|
|
39391
|
+
},
|
|
39392
|
+
recordQuota: (identity, provider, quota) => rewriteSnapshot(identity, (current) => {
|
|
39393
|
+
const state = current?.providers[provider];
|
|
39394
|
+
if (current === void 0 || state === void 0) {
|
|
39395
|
+
return void 0;
|
|
39396
|
+
}
|
|
39397
|
+
const keep = state.quota !== void 0 && state.quota.observedAt.localeCompare(quota.observedAt) > 0;
|
|
39398
|
+
return { ...current.providers, [provider]: { ...state, quota: keep ? state.quota : quota } };
|
|
39399
|
+
}),
|
|
39400
|
+
recordRateLimit: (identity, provider, rateLimit) => rewriteSnapshot(identity, (current) => {
|
|
39401
|
+
const state = current?.providers[provider] ?? {};
|
|
39402
|
+
const keep = state.rateLimit !== void 0 && state.rateLimit.observedAt.localeCompare(rateLimit.observedAt) > 0;
|
|
39403
|
+
const earlier = state.rateLimit;
|
|
39404
|
+
const merged = rateLimit.unified === void 0 ? { ...earlier ?? rateLimit, planWindowsUnavailableAt: rateLimit.observedAt } : { ...rateLimit, unified: { ...earlier?.unified === void 0 ? {} : overageFactsOf(earlier.unified), ...rateLimit.unified } };
|
|
39405
|
+
return { ...current?.providers, [provider]: { ...state, rateLimit: keep ? state.rateLimit : merged } };
|
|
39406
|
+
})
|
|
39458
39407
|
};
|
|
39459
|
-
const parsed = ProviderSchema.safeParse(
|
|
39460
|
-
kind === "router" ? { kind, displayName: input2.displayName } : kind === "codex" ? { kind, ...shared, ...isEmptyCodexConfig(input2.codex) ? {} : { codex: input2.codex } } : kind === "antigravity" ? { kind, ...shared, ...isEmptyAntigravityConfig(input2.antigravity) ? {} : { antigravity: input2.antigravity } } : { ...shared, baseUrl: input2.baseUrl, ...input2.catalogue === void 0 ? {} : { catalogue: input2.catalogue } }
|
|
39461
|
-
);
|
|
39462
|
-
if (!parsed.success) {
|
|
39463
|
-
throw new ConfigValidationError(providerJsonPath(paths, name), parsed.error.issues);
|
|
39464
|
-
}
|
|
39465
|
-
writeJsonAtomic(providerJsonPath(paths, name), parsed.data);
|
|
39466
|
-
return parsed.data;
|
|
39467
39408
|
}
|
|
39468
|
-
|
|
39469
|
-
|
|
39470
|
-
|
|
39471
|
-
|
|
39409
|
+
var import_node_path27, DAY_MS2, DAYS_IN_WEEK2, USAGE_RETENTION_MS;
|
|
39410
|
+
var init_store2 = __esm({
|
|
39411
|
+
"src/usage/store.ts"() {
|
|
39412
|
+
"use strict";
|
|
39413
|
+
import_node_path27 = __toESM(require("node:path"), 1);
|
|
39414
|
+
init_account();
|
|
39415
|
+
init_rateLimit();
|
|
39416
|
+
init_read();
|
|
39417
|
+
init_schema2();
|
|
39418
|
+
DAY_MS2 = 864e5;
|
|
39419
|
+
DAYS_IN_WEEK2 = 7;
|
|
39420
|
+
USAGE_RETENTION_MS = DAYS_IN_WEEK2 * DAY_MS2;
|
|
39472
39421
|
}
|
|
39473
|
-
|
|
39474
|
-
|
|
39475
|
-
|
|
39476
|
-
|
|
39477
|
-
|
|
39478
|
-
|
|
39479
|
-
|
|
39480
|
-
|
|
39481
|
-
|
|
39482
|
-
|
|
39483
|
-
|
|
39484
|
-
|
|
39485
|
-
|
|
39486
|
-
|
|
39487
|
-
|
|
39422
|
+
});
|
|
39423
|
+
|
|
39424
|
+
// src/usage/poolPick.ts
|
|
39425
|
+
function errorMessage(error63) {
|
|
39426
|
+
return error63 instanceof Error ? error63.message : String(error63);
|
|
39427
|
+
}
|
|
39428
|
+
function loadPoolMembers(fs31, paths, identities, nowMs) {
|
|
39429
|
+
const windowStartMs = nowMs - FIVE_HOUR_WINDOW_MS;
|
|
39430
|
+
const log = readUsageLog(fs31, paths.usageLogDir, { sinceMs: windowStartMs });
|
|
39431
|
+
return identities.map((identity) => {
|
|
39432
|
+
const records = log.records.filter((record2) => record2.identity === identity && record2.provider === ANTHROPIC_PROVIDER && Date.parse(record2.at) >= windowStartMs);
|
|
39433
|
+
try {
|
|
39434
|
+
const snapshot = readUsageSnapshot(fs31, paths.usageSnapshotsDir, identity);
|
|
39435
|
+
const account = readAccountMetadata(fs31, paths.identitiesDir, identity) ?? snapshot?.account;
|
|
39436
|
+
return { identity, records, ...snapshot === void 0 ? {} : { snapshot }, ...account === void 0 ? {} : { account } };
|
|
39437
|
+
} catch (error63) {
|
|
39438
|
+
if (error63 instanceof UsageSnapshotError || error63 instanceof AccountMetadataError) {
|
|
39439
|
+
return { identity, records, readError: errorMessage(error63) };
|
|
39440
|
+
}
|
|
39441
|
+
throw error63;
|
|
39442
|
+
}
|
|
39443
|
+
});
|
|
39444
|
+
}
|
|
39445
|
+
function rankPoolGraph(input2) {
|
|
39446
|
+
return rankNamedPool(input2, input2.poolName, [], input2.sticky);
|
|
39447
|
+
}
|
|
39448
|
+
function rankNamedPool(input2, poolName, stack, sticky) {
|
|
39449
|
+
const pool = input2.pools[poolName];
|
|
39450
|
+
if (pool === void 0) {
|
|
39451
|
+
throw new PoolGraphError(`No pool named "${poolName}". Run \`agent-shim pool add ${poolName} --identity <name>...\` first.`);
|
|
39488
39452
|
}
|
|
39489
|
-
|
|
39490
|
-
|
|
39453
|
+
const childStack = [...stack, poolName];
|
|
39454
|
+
const direct = pool.identities.filter((entry) => poolNameOf(poolMemberIdentity(entry)) === void 0);
|
|
39455
|
+
const missing = direct.filter((entry) => !input2.identityExists(poolMemberIdentity(entry))).map((entry) => ({ pool: poolName, identity: poolMemberIdentity(entry) }));
|
|
39456
|
+
const loaded = new Map(loadPoolMembers(input2.fs, input2.paths, direct.filter((entry) => input2.identityExists(poolMemberIdentity(entry))).map(poolMemberIdentity), input2.nowMs).map((member) => [member.identity, member]));
|
|
39457
|
+
const members2 = [];
|
|
39458
|
+
for (const entry of pool.identities) {
|
|
39459
|
+
const nestedName = poolNameOf(poolMemberIdentity(entry));
|
|
39460
|
+
if (nestedName === void 0) {
|
|
39461
|
+
const member = loaded.get(poolMemberIdentity(entry));
|
|
39462
|
+
if (member !== void 0) {
|
|
39463
|
+
members2.push(typeof entry === "string" ? member : { ...member, policy: entry.when });
|
|
39464
|
+
}
|
|
39465
|
+
continue;
|
|
39466
|
+
}
|
|
39467
|
+
assertNestable(input2.pools, poolName, poolMemberIdentity(entry), nestedName, childStack);
|
|
39468
|
+
const nested = nestedMember(input2, nestedName, childStack, sticky);
|
|
39469
|
+
members2.push(typeof entry === "string" ? nested.member : { ...nested.member, policy: entry.when });
|
|
39470
|
+
missing.push(...nested.missing);
|
|
39491
39471
|
}
|
|
39492
|
-
|
|
39493
|
-
|
|
39472
|
+
const ranking = rankPool({
|
|
39473
|
+
members: members2,
|
|
39474
|
+
nowMs: input2.nowMs,
|
|
39475
|
+
resuming: input2.resuming,
|
|
39476
|
+
...input2.resumeContextTokens === void 0 ? {} : { resumeContextTokens: input2.resumeContextTokens },
|
|
39477
|
+
...input2.committedContextTokens === void 0 ? {} : { committedContextTokens: input2.committedContextTokens },
|
|
39478
|
+
...sticky === void 0 ? {} : { sticky },
|
|
39479
|
+
...pool.preference === void 0 ? {} : { preference: pool.preference }
|
|
39480
|
+
});
|
|
39481
|
+
return { ranking, missing };
|
|
39482
|
+
}
|
|
39483
|
+
function assertNestable(pools, poolName, member, nestedName, childStack) {
|
|
39484
|
+
if (pools[nestedName] === void 0) {
|
|
39485
|
+
throw new PoolGraphError(`Pool "${poolName}" member "${member}" names a pool that is not defined.`);
|
|
39494
39486
|
}
|
|
39495
|
-
if (
|
|
39496
|
-
throw new
|
|
39487
|
+
if (childStack.includes(nestedName)) {
|
|
39488
|
+
throw new PoolGraphError(`Pool "${poolName}" member "${member}" closes a cycle: ${[...childStack.slice(childStack.indexOf(nestedName)), nestedName].join(" -> ")}. A pool cannot nest itself, directly or through another pool.`);
|
|
39497
39489
|
}
|
|
39498
|
-
|
|
39499
|
-
|
|
39490
|
+
}
|
|
39491
|
+
function nestedMember(input2, nestedName, childStack, sticky) {
|
|
39492
|
+
const nested = rankNamedPool(input2, nestedName, childStack, sticky);
|
|
39493
|
+
const pick2 = nested.ranking.pick;
|
|
39494
|
+
if (pick2 !== void 0) {
|
|
39495
|
+
const [member] = loadPoolMembers(input2.fs, input2.paths, [pick2.identity], input2.nowMs);
|
|
39496
|
+
return { member: { ...member ?? { identity: pick2.identity, records: [] }, nested: { kind: "pick", pool: nestedName, reasons: pick2.reasons } }, missing: nested.missing };
|
|
39500
39497
|
}
|
|
39501
|
-
const
|
|
39502
|
-
|
|
39503
|
-
|
|
39504
|
-
|
|
39505
|
-
|
|
39506
|
-
|
|
39507
|
-
...cache === void 0 ? {} : { cache }
|
|
39508
|
-
}
|
|
39498
|
+
const earliestReturn = nested.ranking.earliestReturn;
|
|
39499
|
+
return {
|
|
39500
|
+
member: {
|
|
39501
|
+
identity: earliestReturn?.identity ?? `pool:${nestedName}`,
|
|
39502
|
+
records: [],
|
|
39503
|
+
nested: { kind: "refused", pool: nestedName, ...earliestReturn === void 0 ? {} : { earliestReturn } }
|
|
39509
39504
|
},
|
|
39510
|
-
|
|
39511
|
-
pickerModels: pickerModels.length === 0 ? void 0 : pickerModels
|
|
39505
|
+
missing: nested.missing
|
|
39512
39506
|
};
|
|
39513
|
-
|
|
39514
|
-
|
|
39515
|
-
|
|
39516
|
-
|
|
39517
|
-
|
|
39518
|
-
|
|
39519
|
-
};
|
|
39520
|
-
candidate = { ...existing, ...shared, codex: isEmptyCodexConfig(codex) ? void 0 : codex };
|
|
39521
|
-
} else if (isAntigravityProvider(existing)) {
|
|
39522
|
-
const antigravity = {
|
|
39523
|
-
...existing.antigravity,
|
|
39524
|
-
...input2.antigravity,
|
|
39525
|
-
...existing.antigravity?.models === void 0 && input2.antigravity?.models === void 0 ? {} : { models: { ...existing.antigravity?.models, ...input2.antigravity?.models } }
|
|
39526
|
-
};
|
|
39527
|
-
candidate = { ...existing, ...shared, antigravity: isEmptyAntigravityConfig(antigravity) ? void 0 : antigravity };
|
|
39528
|
-
} else if (router) {
|
|
39529
|
-
candidate = { kind: "router", ...shared };
|
|
39530
|
-
} else {
|
|
39531
|
-
const catalogue = input2.catalogue === void 0 ? existing.catalogue : input2.catalogue === false ? void 0 : input2.catalogue;
|
|
39532
|
-
candidate = { ...existing, ...shared, catalogue, ...input2.baseUrl === void 0 ? {} : { baseUrl: input2.baseUrl } };
|
|
39507
|
+
}
|
|
39508
|
+
function readPicksFile(fs31, file2) {
|
|
39509
|
+
const empty = { schemaVersion: SCHEMA_VERSION, picks: {} };
|
|
39510
|
+
const raw = fs31.readFileUtf8(file2);
|
|
39511
|
+
if (raw === void 0) {
|
|
39512
|
+
return { file: empty };
|
|
39533
39513
|
}
|
|
39534
|
-
|
|
39535
|
-
|
|
39536
|
-
|
|
39514
|
+
let parsed;
|
|
39515
|
+
try {
|
|
39516
|
+
parsed = JSON.parse(raw);
|
|
39517
|
+
} catch {
|
|
39518
|
+
return { file: empty, problem: `${file2} is not valid JSON` };
|
|
39537
39519
|
}
|
|
39538
|
-
|
|
39539
|
-
return
|
|
39520
|
+
const result = PicksFileSchema.safeParse(parsed);
|
|
39521
|
+
return result.success ? { file: result.data } : { file: empty, problem: `${file2} is not a picks file this agent-shim can read` };
|
|
39540
39522
|
}
|
|
39541
|
-
function
|
|
39542
|
-
|
|
39543
|
-
|
|
39544
|
-
}
|
|
39545
|
-
import_node_fs11.default.rmSync(providerJsonPath(paths, name));
|
|
39523
|
+
function readStickyPick(fs31, picksFile, directory) {
|
|
39524
|
+
const read = readPicksFile(fs31, picksFile);
|
|
39525
|
+
const entry = read.file.picks[directory];
|
|
39526
|
+
return { ...entry === void 0 ? {} : { sticky: entry }, ...read.problem === void 0 ? {} : { problem: read.problem } };
|
|
39546
39527
|
}
|
|
39547
|
-
function
|
|
39548
|
-
|
|
39549
|
-
|
|
39550
|
-
|
|
39551
|
-
|
|
39552
|
-
|
|
39553
|
-
|
|
39554
|
-
return name;
|
|
39528
|
+
function recordStickyPick(fs31, picksFile, directory, identity, nowMs) {
|
|
39529
|
+
const current = readPicksFile(fs31, picksFile).file.picks;
|
|
39530
|
+
const kept = Object.entries(current).filter(([, entry]) => nowMs - Date.parse(entry.at) <= USAGE_RETENTION_MS);
|
|
39531
|
+
const next = { schemaVersion: SCHEMA_VERSION, picks: { ...Object.fromEntries(kept), [directory]: { identity, at: new Date(nowMs).toISOString() } } };
|
|
39532
|
+
fs31.mkdirPrivate(import_node_path28.default.dirname(picksFile));
|
|
39533
|
+
fs31.writeFilePrivate(picksFile, `${JSON.stringify(next, null, 2)}
|
|
39534
|
+
`);
|
|
39555
39535
|
}
|
|
39556
|
-
|
|
39557
|
-
|
|
39558
|
-
|
|
39559
|
-
|
|
39560
|
-
|
|
39561
|
-
|
|
39562
|
-
|
|
39563
|
-
|
|
39564
|
-
|
|
39565
|
-
|
|
39566
|
-
|
|
39567
|
-
|
|
39568
|
-
|
|
39569
|
-
|
|
39536
|
+
var import_node_path28, PoolGraphError, SCHEMA_VERSION, PickEntrySchema, PicksFileSchema;
|
|
39537
|
+
var init_poolPick = __esm({
|
|
39538
|
+
"src/usage/poolPick.ts"() {
|
|
39539
|
+
"use strict";
|
|
39540
|
+
import_node_path28 = __toESM(require("node:path"), 1);
|
|
39541
|
+
init_zod();
|
|
39542
|
+
init_cliError();
|
|
39543
|
+
init_identity();
|
|
39544
|
+
init_schema();
|
|
39545
|
+
init_account();
|
|
39546
|
+
init_pick();
|
|
39547
|
+
init_read();
|
|
39548
|
+
init_middleware();
|
|
39549
|
+
init_store2();
|
|
39550
|
+
PoolGraphError = class extends CliError {
|
|
39551
|
+
constructor(message) {
|
|
39552
|
+
super(message);
|
|
39553
|
+
this.name = "PoolGraphError";
|
|
39554
|
+
}
|
|
39570
39555
|
};
|
|
39556
|
+
SCHEMA_VERSION = 1;
|
|
39557
|
+
PickEntrySchema = external_exports.strictObject({ identity: external_exports.string().min(1), at: external_exports.iso.datetime() });
|
|
39558
|
+
PicksFileSchema = external_exports.strictObject({
|
|
39559
|
+
schemaVersion: external_exports.literal(SCHEMA_VERSION),
|
|
39560
|
+
picks: external_exports.record(external_exports.string().min(1), PickEntrySchema)
|
|
39561
|
+
});
|
|
39571
39562
|
}
|
|
39572
|
-
|
|
39563
|
+
});
|
|
39564
|
+
|
|
39565
|
+
// src/realCredentialCache.ts
|
|
39566
|
+
function cacheFileNameFor(owner) {
|
|
39567
|
+
return `${owner.replace(/[^A-Za-z0-9._-]/g, "_")}.json`;
|
|
39573
39568
|
}
|
|
39574
|
-
function
|
|
39575
|
-
|
|
39576
|
-
|
|
39577
|
-
|
|
39578
|
-
}
|
|
39579
|
-
|
|
39580
|
-
if (isRouterProvider(definition)) {
|
|
39581
|
-
return { ok: true, provider: { name, definition, credential: { target: "bearer", token: "", source: { env: "AGENT_SHIM_ROUTER" }, warnings: [] } }, warnings: [] };
|
|
39582
|
-
}
|
|
39583
|
-
if (params.credentials === void 0) {
|
|
39584
|
-
return { ok: false, status: 1, message: `agent-shim: provider ${name} needs its credential resolved, but this launcher has no credential port wired` };
|
|
39585
|
-
}
|
|
39586
|
-
const resolution = resolveCredential({ credential: definition.credential, env: params.env, port: params.credentials, subject: `provider ${name}` });
|
|
39587
|
-
if (!resolution.ok) {
|
|
39588
|
-
return { ok: false, status: CREDENTIAL_UNAVAILABLE_EXIT, message: resolution.message };
|
|
39569
|
+
function parseEntry(raw) {
|
|
39570
|
+
let json2;
|
|
39571
|
+
try {
|
|
39572
|
+
json2 = JSON.parse(raw);
|
|
39573
|
+
} catch {
|
|
39574
|
+
return void 0;
|
|
39589
39575
|
}
|
|
39590
|
-
|
|
39576
|
+
const parsed = CachedCredentialSchema.safeParse(json2);
|
|
39577
|
+
return parsed.success ? parsed.data : void 0;
|
|
39591
39578
|
}
|
|
39592
|
-
function
|
|
39593
|
-
|
|
39594
|
-
|
|
39595
|
-
return { ok: true, checked: [] };
|
|
39579
|
+
function requireKeychain() {
|
|
39580
|
+
if (process.platform !== "darwin") {
|
|
39581
|
+
throw new Error("the keychain credential store needs macOS; use --credential-cache-store file");
|
|
39596
39582
|
}
|
|
39597
|
-
|
|
39598
|
-
|
|
39599
|
-
const
|
|
39600
|
-
|
|
39601
|
-
|
|
39602
|
-
|
|
39603
|
-
|
|
39583
|
+
}
|
|
39584
|
+
function security(args, stdin2) {
|
|
39585
|
+
const result = spawnSyncBlocking("a keychain call", "security", args, { encoding: "utf8", ...stdin2 === void 0 ? {} : { input: stdin2 }, stdio: ["pipe", "pipe", "ignore"] });
|
|
39586
|
+
return { status: result.status, stdout: result.stdout };
|
|
39587
|
+
}
|
|
39588
|
+
async function securityAsync(args, stdin2) {
|
|
39589
|
+
return await new Promise((resolve3) => {
|
|
39590
|
+
const child = (0, import_node_child_process4.spawn)("security", args, { stdio: ["pipe", "pipe", "ignore"] });
|
|
39591
|
+
let stdout2 = "";
|
|
39592
|
+
let settled = false;
|
|
39593
|
+
const settle2 = (status) => {
|
|
39594
|
+
if (!settled) {
|
|
39595
|
+
settled = true;
|
|
39596
|
+
resolve3({ status, stdout: stdout2 });
|
|
39604
39597
|
}
|
|
39605
|
-
|
|
39606
|
-
|
|
39607
|
-
|
|
39608
|
-
|
|
39609
|
-
}
|
|
39610
|
-
|
|
39611
|
-
|
|
39612
|
-
|
|
39598
|
+
};
|
|
39599
|
+
child.stdout.setEncoding("utf8");
|
|
39600
|
+
child.stdout.on("data", (chunk2) => {
|
|
39601
|
+
stdout2 += chunk2;
|
|
39602
|
+
});
|
|
39603
|
+
child.stdin.on("error", () => {
|
|
39604
|
+
});
|
|
39605
|
+
child.stdin.end(stdin2);
|
|
39606
|
+
child.once("error", () => {
|
|
39607
|
+
settle2(null);
|
|
39608
|
+
});
|
|
39609
|
+
child.once("close", settle2);
|
|
39610
|
+
});
|
|
39611
|
+
}
|
|
39612
|
+
function createRealCredentialCache(root) {
|
|
39613
|
+
const dir = import_node_path29.default.join(root, "credential-cache");
|
|
39614
|
+
const filePath = (owner) => import_node_path29.default.join(dir, cacheFileNameFor(owner));
|
|
39615
|
+
return {
|
|
39616
|
+
read(store, owner) {
|
|
39617
|
+
if (store === "file") {
|
|
39618
|
+
try {
|
|
39619
|
+
return parseEntry(import_node_fs11.default.readFileSync(filePath(owner), "utf8"));
|
|
39620
|
+
} catch {
|
|
39621
|
+
return void 0;
|
|
39622
|
+
}
|
|
39623
|
+
}
|
|
39624
|
+
requireKeychain();
|
|
39625
|
+
const result = security(["find-generic-password", "-s", KEYCHAIN_CACHE_SERVICE, "-a", owner, "-w"]);
|
|
39626
|
+
return result.status === 0 ? parseEntry(Buffer.from(result.stdout.trim(), "base64").toString("utf8")) : void 0;
|
|
39627
|
+
},
|
|
39628
|
+
write(store, owner, entry) {
|
|
39629
|
+
const serialised = JSON.stringify(entry);
|
|
39630
|
+
if (store === "file") {
|
|
39631
|
+
import_node_fs11.default.mkdirSync(dir, { recursive: true, mode: CACHE_DIR_MODE });
|
|
39632
|
+
import_node_fs11.default.chmodSync(dir, CACHE_DIR_MODE);
|
|
39633
|
+
const target = filePath(owner);
|
|
39634
|
+
const temp = `${target}.${String(process.pid)}.tmp`;
|
|
39635
|
+
import_node_fs11.default.writeFileSync(temp, serialised, { mode: CACHE_FILE_MODE });
|
|
39636
|
+
import_node_fs11.default.renameSync(temp, target);
|
|
39637
|
+
return;
|
|
39638
|
+
}
|
|
39639
|
+
requireKeychain();
|
|
39640
|
+
const encoded = Buffer.from(serialised, "utf8").toString("base64");
|
|
39641
|
+
const result = security(["-i"], `add-generic-password -U -s ${KEYCHAIN_CACHE_SERVICE} -a ${JSON.stringify(owner)} -w ${encoded}
|
|
39642
|
+
`);
|
|
39643
|
+
if (result.status !== 0) {
|
|
39644
|
+
throw new Error(`could not write the keychain credential cache for ${owner}`);
|
|
39645
|
+
}
|
|
39646
|
+
},
|
|
39647
|
+
remove(store, owner) {
|
|
39648
|
+
if (store === "file") {
|
|
39649
|
+
import_node_fs11.default.rmSync(filePath(owner), { force: true });
|
|
39650
|
+
return;
|
|
39651
|
+
}
|
|
39652
|
+
requireKeychain();
|
|
39653
|
+
security(["delete-generic-password", "-s", KEYCHAIN_CACHE_SERVICE, "-a", owner]);
|
|
39613
39654
|
}
|
|
39614
39655
|
};
|
|
39615
|
-
for (const model of Object.values(models.virtual ?? {})) {
|
|
39616
|
-
for (const member of model.members) {
|
|
39617
|
-
collect(member);
|
|
39618
|
-
}
|
|
39619
|
-
}
|
|
39620
|
-
for (const ref of Object.values(models.tiers ?? {})) {
|
|
39621
|
-
collect(ref);
|
|
39622
|
-
}
|
|
39623
|
-
if (providerNames.size === 0) {
|
|
39624
|
-
return { ok: true, checked: [] };
|
|
39625
|
-
}
|
|
39626
|
-
if (params.credentials === void 0) {
|
|
39627
|
-
return { ok: false, status: 1, message: `agent-shim: the models block routes to providers ${[...providerNames].sort().join(", ")}, which need their credentials resolved, but this launcher has no credential port wired` };
|
|
39628
|
-
}
|
|
39629
|
-
const failures = [];
|
|
39630
|
-
let credentialFailure = false;
|
|
39631
|
-
for (const name of [...providerNames].sort()) {
|
|
39632
|
-
const definition = loadProvider(params.paths.providersDir, name, params.port);
|
|
39633
|
-
if (definition === void 0) {
|
|
39634
|
-
failures.push(`no provider named "${name}"`);
|
|
39635
|
-
continue;
|
|
39636
|
-
}
|
|
39637
|
-
if (isRouterProvider(definition)) {
|
|
39638
|
-
continue;
|
|
39639
|
-
}
|
|
39640
|
-
const resolution = resolveCredential({ credential: definition.credential, env: params.env, port: params.credentials, subject: `provider ${name}` });
|
|
39641
|
-
if (!resolution.ok) {
|
|
39642
|
-
failures.push(resolution.message.replace(/^agent-shim: /, ""));
|
|
39643
|
-
credentialFailure = true;
|
|
39644
|
-
}
|
|
39645
|
-
}
|
|
39646
|
-
if (failures.length > 0) {
|
|
39647
|
-
return { ok: false, status: credentialFailure ? CREDENTIAL_UNAVAILABLE_EXIT : 1, message: `agent-shim: this launch routes model names through the models block, but: ${failures.join("; ")}` };
|
|
39648
|
-
}
|
|
39649
|
-
return { ok: true, checked: [...providerNames].sort() };
|
|
39650
39656
|
}
|
|
39651
|
-
|
|
39652
|
-
|
|
39653
|
-
|
|
39654
|
-
|
|
39655
|
-
|
|
39656
|
-
|
|
39657
|
-
|
|
39658
|
-
|
|
39659
|
-
|
|
39660
|
-
|
|
39661
|
-
|
|
39662
|
-
|
|
39663
|
-
|
|
39664
|
-
|
|
39665
|
-
init_names();
|
|
39666
|
-
ProviderNotFoundError = class extends CliError {
|
|
39667
|
-
constructor(name) {
|
|
39668
|
-
super(`No provider named "${name}". Run \`agent-shim provider add ${name}\` first.`);
|
|
39669
|
-
this.name = name;
|
|
39670
|
-
this.name = "ProviderNotFoundError";
|
|
39671
|
-
}
|
|
39672
|
-
name;
|
|
39673
|
-
};
|
|
39674
|
-
ProviderAlreadyExistsError = class extends CliError {
|
|
39675
|
-
constructor(providerName) {
|
|
39676
|
-
super(`A provider named "${providerName}" already exists.`);
|
|
39677
|
-
this.providerName = providerName;
|
|
39678
|
-
this.name = "ProviderAlreadyExistsError";
|
|
39657
|
+
function realCredentialCacheEnv(paths) {
|
|
39658
|
+
return { port: createRealCredentialCache(paths.root), platform: process.platform, now: () => Date.now() };
|
|
39659
|
+
}
|
|
39660
|
+
function createAsyncRealCredentialCache(root) {
|
|
39661
|
+
const dir = import_node_path29.default.join(root, "credential-cache");
|
|
39662
|
+
const filePath = (owner) => import_node_path29.default.join(dir, cacheFileNameFor(owner));
|
|
39663
|
+
return {
|
|
39664
|
+
async read(store, owner) {
|
|
39665
|
+
if (store === "file") {
|
|
39666
|
+
try {
|
|
39667
|
+
return parseEntry(await import_node_fs11.default.promises.readFile(filePath(owner), "utf8"));
|
|
39668
|
+
} catch {
|
|
39669
|
+
return void 0;
|
|
39670
|
+
}
|
|
39679
39671
|
}
|
|
39680
|
-
|
|
39681
|
-
|
|
39682
|
-
|
|
39683
|
-
|
|
39684
|
-
|
|
39685
|
-
|
|
39686
|
-
|
|
39687
|
-
|
|
39688
|
-
|
|
39689
|
-
|
|
39690
|
-
)
|
|
39691
|
-
|
|
39692
|
-
|
|
39693
|
-
|
|
39672
|
+
requireKeychain();
|
|
39673
|
+
const result = await securityAsync(["find-generic-password", "-s", KEYCHAIN_CACHE_SERVICE, "-a", owner, "-w"]);
|
|
39674
|
+
return result.status === 0 ? parseEntry(Buffer.from(result.stdout.trim(), "base64").toString("utf8")) : void 0;
|
|
39675
|
+
},
|
|
39676
|
+
async write(store, owner, entry) {
|
|
39677
|
+
const serialised = JSON.stringify(entry);
|
|
39678
|
+
if (store === "file") {
|
|
39679
|
+
await import_node_fs11.default.promises.mkdir(dir, { recursive: true, mode: CACHE_DIR_MODE });
|
|
39680
|
+
await import_node_fs11.default.promises.chmod(dir, CACHE_DIR_MODE);
|
|
39681
|
+
const target = filePath(owner);
|
|
39682
|
+
const temp = `${target}.${String(process.pid)}.tmp`;
|
|
39683
|
+
await import_node_fs11.default.promises.writeFile(temp, serialised, { mode: CACHE_FILE_MODE });
|
|
39684
|
+
await import_node_fs11.default.promises.rename(temp, target);
|
|
39685
|
+
return;
|
|
39694
39686
|
}
|
|
39695
|
-
|
|
39696
|
-
|
|
39697
|
-
|
|
39698
|
-
|
|
39699
|
-
|
|
39700
|
-
|
|
39701
|
-
this.name = "ProviderKindMismatchError";
|
|
39687
|
+
requireKeychain();
|
|
39688
|
+
const encoded = Buffer.from(serialised, "utf8").toString("base64");
|
|
39689
|
+
const result = await securityAsync(["-i"], `add-generic-password -U -s ${KEYCHAIN_CACHE_SERVICE} -a ${JSON.stringify(owner)} -w ${encoded}
|
|
39690
|
+
`);
|
|
39691
|
+
if (result.status !== 0) {
|
|
39692
|
+
throw new Error(`could not write the keychain credential cache for ${owner}`);
|
|
39702
39693
|
}
|
|
39703
|
-
}
|
|
39694
|
+
}
|
|
39695
|
+
};
|
|
39696
|
+
}
|
|
39697
|
+
function realAsyncCredentialCacheEnv(paths) {
|
|
39698
|
+
return { port: createAsyncRealCredentialCache(paths.root), platform: process.platform, now: () => Date.now() };
|
|
39699
|
+
}
|
|
39700
|
+
var import_node_child_process4, import_node_fs11, import_node_path29, KEYCHAIN_CACHE_SERVICE, CACHE_DIR_MODE, CACHE_FILE_MODE;
|
|
39701
|
+
var init_realCredentialCache = __esm({
|
|
39702
|
+
"src/realCredentialCache.ts"() {
|
|
39703
|
+
"use strict";
|
|
39704
|
+
import_node_child_process4 = require("node:child_process");
|
|
39705
|
+
import_node_fs11 = __toESM(require("node:fs"), 1);
|
|
39706
|
+
import_node_path29 = __toESM(require("node:path"), 1);
|
|
39707
|
+
init_blockingSpawn();
|
|
39708
|
+
init_credentialCache();
|
|
39709
|
+
KEYCHAIN_CACHE_SERVICE = "agent-shim-credential-cache";
|
|
39710
|
+
CACHE_DIR_MODE = 448;
|
|
39711
|
+
CACHE_FILE_MODE = 384;
|
|
39704
39712
|
}
|
|
39705
39713
|
});
|
|
39706
39714
|
|
|
@@ -39715,6 +39723,9 @@ function decideSignIn(facts) {
|
|
|
39715
39723
|
if (facts.hasCredentialBlock) {
|
|
39716
39724
|
return { state: "token", detail: "supplies its own credential through a credential block, so a stored login is not what a launch uses" };
|
|
39717
39725
|
}
|
|
39726
|
+
if (facts.provider !== void 0) {
|
|
39727
|
+
return { state: "token", detail: "runs provider sessions with the provider's credential, so a stored login is not what a launch uses" };
|
|
39728
|
+
}
|
|
39718
39729
|
if (facts.keychainItem === true) {
|
|
39719
39730
|
return { state: "signed-in", detail: "a login is stored in the macOS Keychain" };
|
|
39720
39731
|
}
|
|
@@ -39727,9 +39738,10 @@ function credentialsFilePath(farmRoot) {
|
|
|
39727
39738
|
return import_node_path30.default.join(farmRoot, CREDENTIALS_FILE);
|
|
39728
39739
|
}
|
|
39729
39740
|
function identitySignIn(fs31, probe, identity) {
|
|
39730
|
-
const probing = !identity.hasCredentialBlock;
|
|
39741
|
+
const probing = !identity.hasCredentialBlock && identity.provider === void 0;
|
|
39731
39742
|
return decideSignIn({
|
|
39732
39743
|
hasCredentialBlock: identity.hasCredentialBlock,
|
|
39744
|
+
provider: identity.provider,
|
|
39733
39745
|
keychainItem: probing && probe.platform === "darwin" && probe.run !== void 0 ? keychainHasItem(probe.run, identity.farmRoot) : void 0,
|
|
39734
39746
|
credentialsFile: probing && fs31.lstat(credentialsFilePath(identity.farmRoot)) !== void 0,
|
|
39735
39747
|
platform: probe.platform
|
|
@@ -69869,7 +69881,8 @@ function decideLaunch(params, readOnly) {
|
|
|
69869
69881
|
paths,
|
|
69870
69882
|
port: fs31,
|
|
69871
69883
|
...parsedArgv.provider === void 0 || parsedArgv.provider === false ? {} : { cliProvider: parsedArgv.provider },
|
|
69872
|
-
...farmContext === void 0 ? {} : { cascade: farmContext.cascade }
|
|
69884
|
+
...farmContext === void 0 ? {} : { cascade: farmContext.cascade },
|
|
69885
|
+
...loadedIdentity?.config.provider === void 0 ? {} : { identityProvider: loadedIdentity.config.provider }
|
|
69873
69886
|
};
|
|
69874
69887
|
let selectedProvider;
|
|
69875
69888
|
let resolvedProvider;
|
|
@@ -70339,7 +70352,7 @@ function realPrepareLaunchParams(paths, options) {
|
|
|
70339
70352
|
frontdoor: realFrontDoorPort(paths, options.spawnDaemon),
|
|
70340
70353
|
credentials: { ...realCredentialPort, cache: realCredentialCacheEnv(paths) },
|
|
70341
70354
|
hold: realHoldPort,
|
|
70342
|
-
hasStoredLogin: (identity) => identitySignIn(realFarmFs, { platform: process.platform, run: options.run ?? realRunPort }, { farmRoot: import_node_path44.default.join(paths.identitiesDir, identity), hasCredentialBlock: false }).state !== "signed-out",
|
|
70355
|
+
hasStoredLogin: (identity) => identitySignIn(realFarmFs, { platform: process.platform, run: options.run ?? realRunPort }, { farmRoot: import_node_path44.default.join(paths.identitiesDir, identity), hasCredentialBlock: false, provider: void 0 }).state !== "signed-out",
|
|
70343
70356
|
...farm.directoryIdentity === void 0 ? {} : { directoryPinnedIdentity: farm.directoryIdentity },
|
|
70344
70357
|
...farm.directoryConfigProfile === void 0 ? {} : { directoryRuleConfigProfile: farm.directoryConfigProfile },
|
|
70345
70358
|
...farm.globalDefaultConfigProfile === void 0 ? {} : { globalDefaultConfigProfile: farm.globalDefaultConfigProfile },
|
|
@@ -116380,6 +116393,12 @@ function setDefaultConfigProfile(paths, identityName, profileName) {
|
|
|
116380
116393
|
defaultConfigProfile: profileName
|
|
116381
116394
|
});
|
|
116382
116395
|
}
|
|
116396
|
+
function setIdentityProvider(paths, identityName, providerName) {
|
|
116397
|
+
if (!identityExists(paths, identityName)) {
|
|
116398
|
+
throw new IdentityNotFoundError(identityName);
|
|
116399
|
+
}
|
|
116400
|
+
return applyPatch(identityJsonPath(paths, identityName), IdentitySchema, { provider: providerName });
|
|
116401
|
+
}
|
|
116383
116402
|
function setAllowAmbientCredential(paths, identityName, allow) {
|
|
116384
116403
|
if (!identityExists(paths, identityName)) {
|
|
116385
116404
|
throw new IdentityNotFoundError(identityName);
|
|
@@ -117524,6 +117543,7 @@ function registerProfileCommand(program2, deps) {
|
|
|
117524
117543
|
}
|
|
117525
117544
|
|
|
117526
117545
|
// src/identityManager.ts
|
|
117546
|
+
init_providersStore();
|
|
117527
117547
|
init_identity();
|
|
117528
117548
|
init_realPorts();
|
|
117529
117549
|
|
|
@@ -117662,6 +117682,7 @@ function toIdentityView(paths, { entry, read }, sharesLoginWith) {
|
|
|
117662
117682
|
directory: import_node_path25.default.join(paths.identitiesDir, entry.name),
|
|
117663
117683
|
...entry.problem === void 0 ? {
|
|
117664
117684
|
...entry.identity.defaultConfigProfile === void 0 ? {} : { defaultConfigProfile: entry.identity.defaultConfigProfile },
|
|
117685
|
+
...entry.identity.provider === void 0 ? {} : { provider: entry.identity.provider },
|
|
117665
117686
|
allowAmbientCredential: entry.identity.allowAmbientCredential,
|
|
117666
117687
|
...entry.identity.credential === void 0 ? {} : { credential: summariseCredential(entry.identity.credential) },
|
|
117667
117688
|
...entry.identity.anchors === void 0 ? {} : { anchors: entry.identity.anchors }
|
|
@@ -117688,9 +117709,10 @@ function formatIdentityLine(entry, view) {
|
|
|
117688
117709
|
return `${marker}${entry.name} [unreadable: ${entry.problem}]${account}${accountProblem}`;
|
|
117689
117710
|
}
|
|
117690
117711
|
const defaultProfile = entry.identity.defaultConfigProfile === void 0 ? "" : ` (default profile: ${entry.identity.defaultConfigProfile})`;
|
|
117712
|
+
const provider = entry.identity.provider === void 0 ? "" : ` (provider: ${entry.identity.provider})`;
|
|
117691
117713
|
const ambient = entry.identity.allowAmbientCredential ? " [allows ambient credential]" : "";
|
|
117692
117714
|
const credential = entry.identity.credential === void 0 ? "" : ` [credential ${describeCredential(entry.identity.credential)}]`;
|
|
117693
|
-
return `${marker}${entry.name}${defaultProfile}${ambient}${credential}${account}${accountProblem}`;
|
|
117715
|
+
return `${marker}${entry.name}${defaultProfile}${provider}${ambient}${credential}${account}${accountProblem}`;
|
|
117694
117716
|
}
|
|
117695
117717
|
function registerIdentityCommand(program2, deps) {
|
|
117696
117718
|
const { paths } = deps;
|
|
@@ -117763,13 +117785,14 @@ function registerIdentityCommand(program2, deps) {
|
|
|
117763
117785
|
return;
|
|
117764
117786
|
}
|
|
117765
117787
|
console.log(`Default configuration profile: ${view.defaultConfigProfile ?? "(none)"}`);
|
|
117788
|
+
console.log(`Provider: ${view.provider ?? "(none)"}`);
|
|
117766
117789
|
console.log(`Allows ambient credential: ${view.allowAmbientCredential === true ? "yes" : "no"}`);
|
|
117767
117790
|
console.log(`Credential: ${entry.identity?.credential === void 0 ? "(none; uses its stored login)" : describeCredential(entry.identity.credential)}`);
|
|
117768
117791
|
console.log(`Anchors: ${view.anchors === void 0 ? "(none)" : view.anchors.map(formatAnchor).join(" ")}`);
|
|
117769
117792
|
}),
|
|
117770
117793
|
["agent-shim identity show work", "agent-shim identity show work --json"]
|
|
117771
117794
|
);
|
|
117772
|
-
const identitySet = identity.command("set <name>").description("Update an identity's settings.").option("--json", "Print the result as JSON.").option("--default-profile <profile>", "Configuration profile this identity uses when nothing more specific selects one.").option("--no-default-profile", "Clear this identity's default configuration profile.").option("--allow-ambient-credential", "Allow this identity to launch even with an ambient credential env var set.").option("--no-allow-ambient-credential", "Disallow ambient credential env vars for this identity (the default).").option(
|
|
117795
|
+
const identitySet = identity.command("set <name>").description("Update an identity's settings.").option("--json", "Print the result as JSON.").option("--default-profile <profile>", "Configuration profile this identity uses when nothing more specific selects one.").option("--no-default-profile", "Clear this identity's default configuration profile.").option("--provider <provider>", "Provider this identity exists for: a launch on it routes through the provider unless a flag, directory rule or profile selects another, and doctor expects no stored login.").option("--no-provider", "Clear this identity's provider.").option("--allow-ambient-credential", "Allow this identity to launch even with an ambient credential env var set.").option("--no-allow-ambient-credential", "Disallow ambient credential env vars for this identity (the default).").option(
|
|
117773
117796
|
"--credential <source>",
|
|
117774
117797
|
`Authenticate this identity from a token instead of its stored login, replacing any existing sources (repeatable, in the order tried): ${CREDENTIAL_SOURCE_SYNTAX}.`,
|
|
117775
117798
|
collectCredentialSource
|
|
@@ -117789,12 +117812,15 @@ function registerIdentityCommand(program2, deps) {
|
|
|
117789
117812
|
const { json: json2, ...options } = allOptions;
|
|
117790
117813
|
if (Object.entries(allOptions).every(([key, value2]) => key === "json" || value2 === void 0)) {
|
|
117791
117814
|
throw new UsageError(
|
|
117792
|
-
"Nothing to change: pass --default-profile, --no-default-profile, --allow-ambient-credential, --no-allow-ambient-credential, --credential, --no-credential, --credential-target, --anchor, --no-anchor or a --credential-cache option."
|
|
117815
|
+
"Nothing to change: pass --default-profile, --no-default-profile, --provider, --no-provider, --allow-ambient-credential, --no-allow-ambient-credential, --credential, --no-credential, --credential-target, --anchor, --no-anchor or a --credential-cache option."
|
|
117793
117816
|
);
|
|
117794
117817
|
}
|
|
117795
117818
|
if (!identityExists(paths, name)) {
|
|
117796
117819
|
throw new IdentityNotFoundError(name);
|
|
117797
117820
|
}
|
|
117821
|
+
if (typeof options.provider === "string") {
|
|
117822
|
+
requireProviderExists(paths, options.provider);
|
|
117823
|
+
}
|
|
117798
117824
|
const messages = [];
|
|
117799
117825
|
if (options.defaultProfile !== void 0) {
|
|
117800
117826
|
const profileName = options.defaultProfile === false ? void 0 : options.defaultProfile;
|
|
@@ -117806,6 +117832,11 @@ function registerIdentityCommand(program2, deps) {
|
|
|
117806
117832
|
profileName === void 0 ? `Identity "${name}" no longer has a default configuration profile.` : `Identity "${name}" now defaults to configuration profile "${profileName}".`
|
|
117807
117833
|
);
|
|
117808
117834
|
}
|
|
117835
|
+
if (options.provider !== void 0) {
|
|
117836
|
+
const providerName = options.provider === false ? void 0 : options.provider;
|
|
117837
|
+
setIdentityProvider(paths, name, providerName);
|
|
117838
|
+
messages.push(providerName === void 0 ? `Identity "${name}" no longer has a provider.` : `Identity "${name}" now runs on provider "${providerName}" unless something more specific selects one.`);
|
|
117839
|
+
}
|
|
117809
117840
|
if (options.allowAmbientCredential !== void 0) {
|
|
117810
117841
|
setAllowAmbientCredential(paths, name, options.allowAmbientCredential);
|
|
117811
117842
|
messages.push(`Identity "${name}" ${options.allowAmbientCredential ? "now allows" : "no longer allows"} an ambient credential.`);
|
|
@@ -117836,6 +117867,7 @@ function registerIdentityCommand(program2, deps) {
|
|
|
117836
117867
|
}),
|
|
117837
117868
|
[
|
|
117838
117869
|
"agent-shim identity set work --default-profile client-acme",
|
|
117870
|
+
"agent-shim identity set minimax --provider minimax",
|
|
117839
117871
|
"agent-shim identity set work --allow-ambient-credential",
|
|
117840
117872
|
"agent-shim identity set work --credential-target oauthToken --credential op:op://vault/claude-work/token",
|
|
117841
117873
|
"agent-shim identity set work --no-credential",
|
|
@@ -118352,7 +118384,7 @@ function collectCheckReport(params) {
|
|
|
118352
118384
|
read,
|
|
118353
118385
|
...configProfileDecision.name === void 0 ? {} : { baseConfigProfile: configProfileDecision.name }
|
|
118354
118386
|
}).input;
|
|
118355
|
-
const providerName = cascadeProviderName(cascade);
|
|
118387
|
+
const providerName = cascadeProviderName(cascade, identityConfig?.provider);
|
|
118356
118388
|
const provider = providerName === void 0 ? void 0 : loadCheckProvider(paths, providerName);
|
|
118357
118389
|
const farmRoot = identityDecision.name === void 0 ? void 0 : import_node_path31.default.join(paths.identitiesDir, identityDecision.name);
|
|
118358
118390
|
const settingsFiles = {
|
|
@@ -123579,6 +123611,7 @@ function runDoctor(params) {
|
|
|
123579
123611
|
}
|
|
123580
123612
|
}
|
|
123581
123613
|
const validProfileNames = new Set(profileSources.keys());
|
|
123614
|
+
const validProviderNames = /* @__PURE__ */ new Set([...params.providers.map((entry) => entry.name), ...Object.keys(params.providerAliases ?? {})]);
|
|
123582
123615
|
const validIdentityNames = /* @__PURE__ */ new Set();
|
|
123583
123616
|
for (const entry of params.identities) {
|
|
123584
123617
|
const validated2 = validate3(IdentitySchema, entry, "identity", entry.name);
|
|
@@ -123588,35 +123621,47 @@ function runDoctor(params) {
|
|
|
123588
123621
|
}
|
|
123589
123622
|
validIdentityNames.add(entry.name);
|
|
123590
123623
|
const defaultProfile = validated2.data.defaultConfigProfile;
|
|
123624
|
+
let consistent = true;
|
|
123591
123625
|
if (defaultProfile !== void 0 && !validProfileNames.has(defaultProfile)) {
|
|
123626
|
+
consistent = false;
|
|
123592
123627
|
push(
|
|
123593
123628
|
"identity",
|
|
123594
123629
|
"fail",
|
|
123595
123630
|
`Identity "${entry.name}" names configuration profile "${defaultProfile}" as its default, but no such profile exists.`,
|
|
123596
123631
|
entry.name
|
|
123597
123632
|
);
|
|
123598
|
-
} else {
|
|
123599
|
-
const credential = validated2.data.credential;
|
|
123600
|
-
const cache = credential === void 0 ? { text: "", unreadable: false } : cacheClause(params.credentialCache, `identity ${entry.name}`, credential);
|
|
123601
|
-
push(
|
|
123602
|
-
"identity",
|
|
123603
|
-
cache.unreadable ? "fail" : "pass",
|
|
123604
|
-
`${entry.name} is valid and authenticates with ${credential === void 0 ? "its stored login" : `credential ${describeCredential(credential)}`}${cache.text}.`,
|
|
123605
|
-
entry.name
|
|
123606
|
-
);
|
|
123607
|
-
const signIn = decideSignIn({
|
|
123608
|
-
hasCredentialBlock: credential !== void 0,
|
|
123609
|
-
keychainItem: params.platform === "darwin" && params.run !== void 0 ? keychainHasItem(params.run, entry.farmRoot) : void 0,
|
|
123610
|
-
credentialsFile: entry.credentialsFilePresent,
|
|
123611
|
-
platform: params.platform
|
|
123612
|
-
});
|
|
123613
|
-
push(
|
|
123614
|
-
"sign-in",
|
|
123615
|
-
signIn.state === "signed-out" ? "warn" : "pass",
|
|
123616
|
-
signIn.state === "signed-out" ? `${entry.name} is signed out (${signIn.detail}). Run \`agent-shim run @${entry.name}\` and sign in.` : `${entry.name} ${signIn.state === "token" ? "uses a credential block" : "is signed in"} (${signIn.detail}).`,
|
|
123617
|
-
entry.name
|
|
123618
|
-
);
|
|
123619
123633
|
}
|
|
123634
|
+
const identityProvider = validated2.data.provider;
|
|
123635
|
+
if (identityProvider !== void 0 && !validProviderNames.has(identityProvider)) {
|
|
123636
|
+
consistent = false;
|
|
123637
|
+
push("identity", "fail", `Identity "${entry.name}" names provider "${identityProvider}" as its provider, but no such provider exists.`, entry.name);
|
|
123638
|
+
}
|
|
123639
|
+
if (!consistent) {
|
|
123640
|
+
continue;
|
|
123641
|
+
}
|
|
123642
|
+
const credential = validated2.data.credential;
|
|
123643
|
+
const cache = credential === void 0 ? { text: "", unreadable: false } : cacheClause(params.credentialCache, `identity ${entry.name}`, credential);
|
|
123644
|
+
const authenticatesWith = credential !== void 0 ? `credential ${describeCredential(credential)}` : identityProvider !== void 0 ? `the credential of provider "${identityProvider}"` : "its stored login";
|
|
123645
|
+
push(
|
|
123646
|
+
"identity",
|
|
123647
|
+
cache.unreadable ? "fail" : "pass",
|
|
123648
|
+
`${entry.name} is valid and authenticates with ${authenticatesWith}${cache.text}.`,
|
|
123649
|
+
entry.name
|
|
123650
|
+
);
|
|
123651
|
+
const standing = credential !== void 0 ? "uses a credential block" : identityProvider !== void 0 ? `exists for provider "${identityProvider}"` : "is signed in";
|
|
123652
|
+
const signIn = decideSignIn({
|
|
123653
|
+
hasCredentialBlock: credential !== void 0,
|
|
123654
|
+
provider: identityProvider,
|
|
123655
|
+
keychainItem: params.platform === "darwin" && params.run !== void 0 ? keychainHasItem(params.run, entry.farmRoot) : void 0,
|
|
123656
|
+
credentialsFile: entry.credentialsFilePresent,
|
|
123657
|
+
platform: params.platform
|
|
123658
|
+
});
|
|
123659
|
+
push(
|
|
123660
|
+
"sign-in",
|
|
123661
|
+
signIn.state === "signed-out" ? "warn" : "pass",
|
|
123662
|
+
signIn.state === "signed-out" ? `${entry.name} is signed out (${signIn.detail}). Run \`agent-shim run @${entry.name}\` and sign in.` : `${entry.name} ${standing} (${signIn.detail}).`,
|
|
123663
|
+
entry.name
|
|
123664
|
+
);
|
|
123620
123665
|
}
|
|
123621
123666
|
const validatedGlobalConfig = params.globalConfig.raw === void 0 ? void 0 : validateJson(GlobalConfigSchema, params.globalConfig);
|
|
123622
123667
|
const pools = validatedGlobalConfig?.ok === true ? validatedGlobalConfig.data.pools ?? {} : {};
|
|
@@ -133043,6 +133088,7 @@ var storedMutationOutput = (kind, action, value2) => external_exports.strictObje
|
|
|
133043
133088
|
var IdentityValueSchema = external_exports.strictObject({
|
|
133044
133089
|
name: external_exports.string(),
|
|
133045
133090
|
defaultConfigProfile: external_exports.string().optional(),
|
|
133091
|
+
provider: external_exports.string().optional(),
|
|
133046
133092
|
allowAmbientCredential: external_exports.boolean(),
|
|
133047
133093
|
credential: CredentialSummarySchema2.optional(),
|
|
133048
133094
|
anchors: external_exports.array(AnchorSchema).optional()
|
|
@@ -133062,6 +133108,8 @@ var ConfigIdentityAddOutputSchema = storedMutationOutput("identity", "created",
|
|
|
133062
133108
|
var ConfigIdentitySetInputSchema = external_exports.strictObject({
|
|
133063
133109
|
name: external_exports.string().min(1),
|
|
133064
133110
|
defaultConfigProfile: external_exports.union([external_exports.string().min(1), external_exports.literal(false)]).optional(),
|
|
133111
|
+
/** The provider the identity exists for; `false` clears it. */
|
|
133112
|
+
provider: external_exports.union([external_exports.string().min(1), external_exports.literal(false)]).optional(),
|
|
133065
133113
|
allowAmbientCredential: external_exports.boolean().optional(),
|
|
133066
133114
|
credential: external_exports.union([external_exports.literal(false), CredentialWriteSchema(CREDENTIAL_TARGETS)]).optional(),
|
|
133067
133115
|
/** `false` removes the anchors; a list replaces them. */
|
|
@@ -133206,6 +133254,7 @@ function identityValue(name, paths) {
|
|
|
133206
133254
|
return {
|
|
133207
133255
|
name: identity.name,
|
|
133208
133256
|
...identity.defaultConfigProfile === void 0 ? {} : { defaultConfigProfile: identity.defaultConfigProfile },
|
|
133257
|
+
...identity.provider === void 0 ? {} : { provider: identity.provider },
|
|
133209
133258
|
allowAmbientCredential: identity.allowAmbientCredential,
|
|
133210
133259
|
...identity.credential === void 0 ? {} : { credential: summariseCredential(identity.credential) },
|
|
133211
133260
|
...identity.anchors === void 0 ? {} : { anchors: identity.anchors }
|
|
@@ -133238,18 +133287,24 @@ function createConfigApiRouter(deps) {
|
|
|
133238
133287
|
return { action: "created", kind: "identity", name: input2.name, value: identityValue(input2.name, paths) };
|
|
133239
133288
|
})
|
|
133240
133289
|
),
|
|
133241
|
-
set: route("/rest/config/identity/set", "Update an identity's default profile, ambient-credential setting, credential or anchors").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
|
|
133290
|
+
set: route("/rest/config/identity/set", "Update an identity's default profile, provider, ambient-credential setting, credential or anchors").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
|
|
133242
133291
|
({ input: input2 }) => guarded(() => {
|
|
133243
|
-
requireChange(input2.defaultConfigProfile !== void 0 || input2.allowAmbientCredential !== void 0 || input2.credential !== void 0 || input2.anchors !== void 0, "defaultConfigProfile, allowAmbientCredential, credential or anchors");
|
|
133292
|
+
requireChange(input2.defaultConfigProfile !== void 0 || input2.provider !== void 0 || input2.allowAmbientCredential !== void 0 || input2.credential !== void 0 || input2.anchors !== void 0, "defaultConfigProfile, provider, allowAmbientCredential, credential or anchors");
|
|
133244
133293
|
if (!identityExists(paths, input2.name)) {
|
|
133245
133294
|
throw new IdentityNotFoundError(input2.name);
|
|
133246
133295
|
}
|
|
133247
133296
|
if (typeof input2.defaultConfigProfile === "string") {
|
|
133248
133297
|
requireProfileExists(paths, input2.defaultConfigProfile);
|
|
133249
133298
|
}
|
|
133299
|
+
if (typeof input2.provider === "string") {
|
|
133300
|
+
requireProviderExists(paths, input2.provider);
|
|
133301
|
+
}
|
|
133250
133302
|
if (input2.defaultConfigProfile !== void 0) {
|
|
133251
133303
|
setDefaultConfigProfile(paths, input2.name, input2.defaultConfigProfile === false ? void 0 : input2.defaultConfigProfile);
|
|
133252
133304
|
}
|
|
133305
|
+
if (input2.provider !== void 0) {
|
|
133306
|
+
setIdentityProvider(paths, input2.name, input2.provider === false ? void 0 : input2.provider);
|
|
133307
|
+
}
|
|
133253
133308
|
if (input2.allowAmbientCredential !== void 0) {
|
|
133254
133309
|
setAllowAmbientCredential(paths, input2.name, input2.allowAmbientCredential);
|
|
133255
133310
|
}
|
|
@@ -156467,6 +156522,12 @@ function rewriteReferences(paths, from, to2) {
|
|
|
156467
156522
|
rewritten.push(`profile ${name}`);
|
|
156468
156523
|
}
|
|
156469
156524
|
}
|
|
156525
|
+
for (const entry of listIdentities(paths)) {
|
|
156526
|
+
if (entry.identity?.provider === from) {
|
|
156527
|
+
setIdentityProvider(paths, entry.name, to2);
|
|
156528
|
+
rewritten.push(`identity ${entry.name}`);
|
|
156529
|
+
}
|
|
156530
|
+
}
|
|
156470
156531
|
const rules = readDirectoryRules(paths);
|
|
156471
156532
|
const renamedRules = rules.rules.map((rule) => {
|
|
156472
156533
|
const launch = renamedLaunch(rule.launch, from, to2);
|
|
@@ -157426,12 +157487,15 @@ function collectAccounts(fs31, paths, identity, probe) {
|
|
|
157426
157487
|
requireIdentity(paths, identity);
|
|
157427
157488
|
}
|
|
157428
157489
|
const names = identity === void 0 ? listIdentities(paths).map((entry) => entry.name) : [identity];
|
|
157429
|
-
return names.map((name) =>
|
|
157430
|
-
|
|
157431
|
-
|
|
157432
|
-
|
|
157433
|
-
|
|
157434
|
-
|
|
157490
|
+
return names.map((name) => {
|
|
157491
|
+
const stored2 = readIdentity(paths, name);
|
|
157492
|
+
return {
|
|
157493
|
+
identity: name,
|
|
157494
|
+
account: readAccountMetadata(fs31, paths.identitiesDir, name),
|
|
157495
|
+
signIn: identitySignIn(fs31, probe, { farmRoot: import_node_path70.default.join(paths.identitiesDir, name), hasCredentialBlock: stored2?.credential !== void 0, provider: stored2?.provider }),
|
|
157496
|
+
usage: readUsageSnapshot(fs31, paths.usageSnapshotsDir, name)
|
|
157497
|
+
};
|
|
157498
|
+
});
|
|
157435
157499
|
}
|
|
157436
157500
|
function formatAccounts(views) {
|
|
157437
157501
|
if (views.length === 0) {
|