codex-multi-auth 2.11.0 → 2.12.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/.codex-plugin/plugin.json +1 -1
- package/README.md +1 -1
- package/dist/lib/capability-policy.d.ts.map +1 -1
- package/dist/lib/capability-policy.js +2 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +2 -1
- package/dist/lib/constants.d.ts +9 -0
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/constants.js +29 -0
- package/dist/lib/entitlement-cache.d.ts.map +1 -1
- package/dist/lib/entitlement-cache.js +2 -1
- package/dist/lib/policy/runtime-policy.d.ts +9 -1
- package/dist/lib/policy/runtime-policy.d.ts.map +1 -1
- package/dist/lib/policy/runtime-policy.js +1 -0
- package/dist/lib/request/error-classification.js +2 -2
- package/dist/lib/usage/ledger.d.ts +1 -1
- package/dist/lib/usage/ledger.d.ts.map +1 -1
- package/dist/lib/usage/ledger.js +9 -0
- package/dist/lib/usage/pricing.d.ts +16 -1
- package/dist/lib/usage/pricing.d.ts.map +1 -1
- package/dist/lib/usage/pricing.js +46 -8
- package/dist/lib/usage/redaction.d.ts +1 -1
- package/dist/lib/usage/redaction.d.ts.map +1 -1
- package/dist/lib/usage/redaction.js +13 -0
- package/dist/lib/usage/types.d.ts +33 -0
- package/dist/lib/usage/types.d.ts.map +1 -1
- package/dist/lib/usage/types.js +28 -1
- package/dist/lib/usage/usage-extraction.d.ts +2 -1
- package/dist/lib/usage/usage-extraction.d.ts.map +1 -1
- package/dist/lib/usage/usage-extraction.js +44 -4
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codex-multi-auth",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.12.0",
|
|
4
4
|
"description": "Install and operate codex-multi-auth for the official @openai/codex CLI with multi-account OAuth rotation, switching, health checks, and recovery tools.",
|
|
5
5
|
"interface": {
|
|
6
6
|
"composerIcon": "./assets/codex-multi-auth-icon.svg"
|
package/README.md
CHANGED
|
@@ -406,7 +406,7 @@ codex-multi-auth doctor --json
|
|
|
406
406
|
|
|
407
407
|
## Release Notes
|
|
408
408
|
|
|
409
|
-
- Current stable: [docs/releases/v2.
|
|
409
|
+
- Current stable: [docs/releases/v2.12.0.md](docs/releases/v2.12.0.md) — install via `npm i -g codex-multi-auth`
|
|
410
410
|
- Previous stable: [docs/releases/v2.8.3.md](docs/releases/v2.8.3.md)
|
|
411
411
|
- Previous stable: [docs/releases/v2.8.2.md](docs/releases/v2.8.2.md)
|
|
412
412
|
- Previous stable: [docs/releases/v2.7.1.md](docs/releases/v2.7.1.md)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability-policy.d.ts","sourceRoot":"","sources":["../../lib/capability-policy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"capability-policy.d.ts","sourceRoot":"","sources":["../../lib/capability-policy.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,wBAAwB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAyED,qBAAa,qBAAqB;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsC;IAE9D,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,IAAI;IAkBxE,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,IAAI;IAgBxE,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,IAAI;IAgB5E,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,MAAM;IAiBrE,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,wBAAwB,GAAG,IAAI;IAc/E,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAYxC,OAAO,CAAC,aAAa;CASrB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getNormalizedModel, resolveNormalizedModel, } from "./request/helpers/model-map.js";
|
|
2
|
+
import { stripModelEffortSuffix } from "./constants.js";
|
|
2
3
|
const MAX_ENTRIES = 2048;
|
|
3
4
|
const PASSIVE_RECOVERY_PER_MIN = 0.5;
|
|
4
5
|
/**
|
|
@@ -45,7 +46,7 @@ function normalizeModel(model) {
|
|
|
45
46
|
const trimmed = mapped.trim().toLowerCase();
|
|
46
47
|
if (!trimmed)
|
|
47
48
|
return null;
|
|
48
|
-
return trimmed
|
|
49
|
+
return stripModelEffortSuffix(trimmed);
|
|
49
50
|
}
|
|
50
51
|
/**
|
|
51
52
|
* Compose a storage key from an account key and a normalized model identifier.
|
package/dist/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../lib/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../lib/config.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/config.js
CHANGED
|
@@ -2,6 +2,7 @@ import { existsSync, promises as fs, readFileSync } from "node:fs";
|
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import { parseBooleanEnv } from "./env-parsing.js";
|
|
5
|
+
import { stripModelEffortSuffix } from "./constants.js";
|
|
5
6
|
import { withRetry, withRetrySync } from "./fs-retry.js";
|
|
6
7
|
import { logWarn } from "./logger.js";
|
|
7
8
|
import { StorageError } from "./errors.js";
|
|
@@ -949,7 +950,7 @@ export function getUnsupportedCodexFallbackChain(pluginConfig) {
|
|
|
949
950
|
const stripped = trimmed.includes("/")
|
|
950
951
|
? (trimmed.split("/").pop() ?? trimmed)
|
|
951
952
|
: trimmed;
|
|
952
|
-
return stripped
|
|
953
|
+
return stripModelEffortSuffix(stripped);
|
|
953
954
|
};
|
|
954
955
|
// Null-prototype: the keys come from user config, so a `__proto__` entry on a
|
|
955
956
|
// plain object would reassign this object's prototype rather than add a row.
|
package/dist/lib/constants.d.ts
CHANGED
|
@@ -104,4 +104,13 @@ export declare const REASONING_EFFORTS: readonly ["none", "minimal", "low", "med
|
|
|
104
104
|
export type ModelReasoningEffort = (typeof REASONING_EFFORTS)[number];
|
|
105
105
|
/** Effort levels the Responses API actually accepts. */
|
|
106
106
|
export type WireReasoningEffort = Exclude<ModelReasoningEffort, "ultra">;
|
|
107
|
+
/**
|
|
108
|
+
* Strip a trailing reasoning-effort suffix from a model id.
|
|
109
|
+
*
|
|
110
|
+
* Callers use this to collapse `gpt-5.6-sol-max` and `gpt-6-astra-ultra` onto
|
|
111
|
+
* the model they actually route to, so cache keys, policy keys and fallback
|
|
112
|
+
* chain lookups all agree on one id per model. Ids exempted above are returned
|
|
113
|
+
* untouched.
|
|
114
|
+
*/
|
|
115
|
+
export declare function stripModelEffortSuffix(modelId: string): string;
|
|
107
116
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../lib/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,uDAAuD;AACvD,eAAO,MAAM,WAAW,qBAAqB,CAAC;AAE9C,uCAAuC;AACvC,eAAO,MAAM,cAAc,oCAAoC,CAAC;AAEhE,gEAAgE;AAChE,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAE7C,yEAAyE;AACzE,eAAO,MAAM,WAAW,WAAW,CAAC;AAEpC;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,QAA0B,CAAC;AAE/D,wBAAwB;AACxB,eAAO,MAAM,WAAW;;;;;;;;;;CAUd,CAAC;AAEX,8BAA8B;AAC9B,eAAO,MAAM,cAAc;;;;;;CAMjB,CAAC;AAEX,oCAAoC;AACpC,eAAO,MAAM,oBAAoB;;;CAGvB,CAAC;AAEX,wBAAwB;AACxB,eAAO,MAAM,SAAS;;;;CAIZ,CAAC;AAEX,4CAA4C;AAC5C,eAAO,MAAM,cAAc,EAAG,6BAAsC,CAAC;AAErE,qBAAqB;AACrB,eAAO,MAAM,cAAc;;;;CAIjB,CAAC;AAEX,qCAAqC;AACrC,eAAO,MAAM,UAAU;;;;;CAKb,CAAC;AAEX,gDAAgD;AAChD,eAAO,MAAM,gBAAgB;;;;CAInB,CAAC;AAEX,iCAAiC;AACjC,eAAO,MAAM,WAAW;;;;;;CAQd,CAAC;AAEX,kCAAkC;AAClC,eAAO,MAAM,cAAc;IAC1B,8DAA8D;;IAE9D,sEAAsE;;IAEtE,uEAAuE;;CAE9D,CAAC;AAEX;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,gFASpB,CAAC;AAEX;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,wDAAwD;AACxD,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../lib/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,uDAAuD;AACvD,eAAO,MAAM,WAAW,qBAAqB,CAAC;AAE9C,uCAAuC;AACvC,eAAO,MAAM,cAAc,oCAAoC,CAAC;AAEhE,gEAAgE;AAChE,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAE7C,yEAAyE;AACzE,eAAO,MAAM,WAAW,WAAW,CAAC;AAEpC;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,QAA0B,CAAC;AAE/D,wBAAwB;AACxB,eAAO,MAAM,WAAW;;;;;;;;;;CAUd,CAAC;AAEX,8BAA8B;AAC9B,eAAO,MAAM,cAAc;;;;;;CAMjB,CAAC;AAEX,oCAAoC;AACpC,eAAO,MAAM,oBAAoB;;;CAGvB,CAAC;AAEX,wBAAwB;AACxB,eAAO,MAAM,SAAS;;;;CAIZ,CAAC;AAEX,4CAA4C;AAC5C,eAAO,MAAM,cAAc,EAAG,6BAAsC,CAAC;AAErE,qBAAqB;AACrB,eAAO,MAAM,cAAc;;;;CAIjB,CAAC;AAEX,qCAAqC;AACrC,eAAO,MAAM,UAAU;;;;;CAKb,CAAC;AAEX,gDAAgD;AAChD,eAAO,MAAM,gBAAgB;;;;CAInB,CAAC;AAEX,iCAAiC;AACjC,eAAO,MAAM,WAAW;;;;;;CAQd,CAAC;AAEX,kCAAkC;AAClC,eAAO,MAAM,cAAc;IAC1B,8DAA8D;;IAE9D,sEAAsE;;IAEtE,uEAAuE;;CAE9D,CAAC;AAEX;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,gFASpB,CAAC;AAEX;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,wDAAwD;AACxD,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC;AAuBzE;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAG9D"}
|
package/dist/lib/constants.js
CHANGED
|
@@ -104,3 +104,32 @@ export const REASONING_EFFORTS = [
|
|
|
104
104
|
"max",
|
|
105
105
|
"ultra",
|
|
106
106
|
];
|
|
107
|
+
/**
|
|
108
|
+
* Model ids whose final segment is an effort word but is part of the NAME.
|
|
109
|
+
*
|
|
110
|
+
* `codex-max` and `gpt-5.1-codex-max` are models. Stripping their trailing
|
|
111
|
+
* `-max` as if it were an effort suffix renames them to `codex` and
|
|
112
|
+
* `gpt-5.1-codex`, which silently retargets the unsupported-model fallback
|
|
113
|
+
* chain and splits their cache keys. This is the reason the strippers below
|
|
114
|
+
* omitted `max` and `ultra` for so long; naming the exception is what lets them
|
|
115
|
+
* be added.
|
|
116
|
+
*/
|
|
117
|
+
const EFFORT_SUFFIX_EXEMPT_PATTERN = /codex-max$/i;
|
|
118
|
+
/**
|
|
119
|
+
* Trailing `-<effort>` on a model id, derived from REASONING_EFFORTS so a new
|
|
120
|
+
* tier cannot be added to the union and missed here.
|
|
121
|
+
*/
|
|
122
|
+
const EFFORT_SUFFIX_PATTERN = new RegExp(`-(${REASONING_EFFORTS.join("|")})$`, "i");
|
|
123
|
+
/**
|
|
124
|
+
* Strip a trailing reasoning-effort suffix from a model id.
|
|
125
|
+
*
|
|
126
|
+
* Callers use this to collapse `gpt-5.6-sol-max` and `gpt-6-astra-ultra` onto
|
|
127
|
+
* the model they actually route to, so cache keys, policy keys and fallback
|
|
128
|
+
* chain lookups all agree on one id per model. Ids exempted above are returned
|
|
129
|
+
* untouched.
|
|
130
|
+
*/
|
|
131
|
+
export function stripModelEffortSuffix(modelId) {
|
|
132
|
+
if (EFFORT_SUFFIX_EXEMPT_PATTERN.test(modelId))
|
|
133
|
+
return modelId;
|
|
134
|
+
return modelId.replace(EFFORT_SUFFIX_PATTERN, "");
|
|
135
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entitlement-cache.d.ts","sourceRoot":"","sources":["../../lib/entitlement-cache.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"entitlement-cache.d.ts","sourceRoot":"","sources":["../../lib/entitlement-cache.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,mBAAmB,GAAG,kBAAkB,CAAC;IACjD,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,wBAAwB;IACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;CAC7C;AAKD,MAAM,WAAW,qBAAqB;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AA0BD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,qBAAqB,GAAG,MAAM,CAU/E;AAED,qBAAa,gBAAgB;IAC5B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAoD;IAEpF,WAAW,CACV,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,EAClC,KAAK,SAAuB,EAC5B,GAAG,SAAa,GACd,IAAI;IAqBP,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAc/C,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAA;KAAE;IAmBzI,KAAK,CAAC,GAAG,SAAa,GAAG,MAAM;IAmB/B,QAAQ,CAAC,GAAG,SAAa,GAAG,wBAAwB;CAUpD"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createLogger } from "./logger.js";
|
|
2
|
+
import { stripModelEffortSuffix } from "./constants.js";
|
|
2
3
|
const log = createLogger("entitlement-cache");
|
|
3
4
|
const DEFAULT_BLOCK_TTL_MS = 30 * 60_000;
|
|
4
5
|
const MAX_ACCOUNT_BUCKETS = 512;
|
|
@@ -18,7 +19,7 @@ function normalizeModel(model) {
|
|
|
18
19
|
if (!trimmed)
|
|
19
20
|
return null;
|
|
20
21
|
const stripped = trimmed.includes("/") ? (trimmed.split("/").pop() ?? trimmed) : trimmed;
|
|
21
|
-
return stripped
|
|
22
|
+
return stripModelEffortSuffix(stripped);
|
|
22
23
|
}
|
|
23
24
|
function normalizeEntitlementEmail(email) {
|
|
24
25
|
if (!email)
|
|
@@ -2,7 +2,7 @@ import type { CapabilityPolicyStore } from "../capability-policy.js";
|
|
|
2
2
|
import { type AccountPolicyStore } from "../account-policy.js";
|
|
3
3
|
import { type BudgetGuardEvaluation, type BudgetGuardStore } from "../budget-guard.js";
|
|
4
4
|
import { type ProjectRoutingProfileContext } from "../routing-profiles.js";
|
|
5
|
-
import { appendUsageLedgerRow, type UsageLedgerOperation, type UsageLedgerOutcome, type UsageLedgerSource } from "../usage/index.js";
|
|
5
|
+
import { appendUsageLedgerRow, type UsageLedgerOperation, type UsageLedgerOutcome, type UsageLedgerSource, type UsageServiceTier } from "../usage/index.js";
|
|
6
6
|
export interface RuntimePolicyAccount {
|
|
7
7
|
index: number;
|
|
8
8
|
accountId?: string | null;
|
|
@@ -46,6 +46,14 @@ export interface RuntimeUsageRecordInput {
|
|
|
46
46
|
cachedInputTokens?: number | null;
|
|
47
47
|
reasoningTokens?: number | null;
|
|
48
48
|
totalTokens?: number | null;
|
|
49
|
+
/**
|
|
50
|
+
* Billed service tier, when upstream reported one. Carried explicitly
|
|
51
|
+
* because the row below is rebuilt field by field: a spread from the
|
|
52
|
+
* usage deferral reaches this input, but anything not named here is
|
|
53
|
+
* dropped before the ledger, which would price a Fast response at the
|
|
54
|
+
* standard rate.
|
|
55
|
+
*/
|
|
56
|
+
serviceTier?: UsageServiceTier;
|
|
49
57
|
}
|
|
50
58
|
export declare function loadRuntimePolicyState(startDir?: string): Promise<RuntimePolicyState>;
|
|
51
59
|
export declare function evaluateRuntimePolicy(input: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-policy.d.ts","sourceRoot":"","sources":["../../../lib/policy/runtime-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAErE,OAAO,EAGN,KAAK,kBAAkB,EACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAKN,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEN,KAAK,4BAA4B,EACjC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,oBAAoB,EAGpB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,qBAAqB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACnC,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,iBAAiB,EAAE,qBAAqB,EAAE,CAAC;CAC3C;AAED,MAAM,WAAW,kBAAkB;IAClC,eAAe,EAAE,kBAAkB,CAAC;IACpC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,OAAO,EAAE,4BAA4B,CAAC;CACtC;AAED,MAAM,WAAW,oBAAoB;IACpC,MAAM,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,WAAW,EAAE,MAAM,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,uBAAuB;IACvC,OAAO,EAAE,kBAAkB,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACtC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"runtime-policy.d.ts","sourceRoot":"","sources":["../../../lib/policy/runtime-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAErE,OAAO,EAGN,KAAK,kBAAkB,EACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAKN,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEN,KAAK,4BAA4B,EACjC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,oBAAoB,EAGpB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,qBAAqB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACnC,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,iBAAiB,EAAE,qBAAqB,EAAE,CAAC;CAC3C;AAED,MAAM,WAAW,kBAAkB;IAClC,eAAe,EAAE,kBAAkB,CAAC;IACpC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,OAAO,EAAE,4BAA4B,CAAC;CACtC;AAED,MAAM,WAAW,oBAAoB;IACpC,MAAM,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,WAAW,EAAE,MAAM,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,uBAAuB;IACvC,OAAO,EAAE,kBAAkB,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACtC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AAED,wBAAsB,sBAAsB,CAC3C,QAAQ,SAAgB,GACtB,OAAO,CAAC,kBAAkB,CAAC,CAO7B;AA6DD,wBAAsB,qBAAqB,CAAC,KAAK,EAAE;IAClD,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,gBAAgB,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC;CACb,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA6GjC;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IACjD,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,EAAE,oBAAoB,CAAC;IAChC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,oBAAoB,CAAC;CACrC,GAAG,oBAAoB,CAiCvB"}
|
|
@@ -187,6 +187,7 @@ export function createRuntimeUsageRecorder(input) {
|
|
|
187
187
|
cachedInputTokens: recordInput.cachedInputTokens,
|
|
188
188
|
reasoningTokens: recordInput.reasoningTokens,
|
|
189
189
|
totalTokens: recordInput.totalTokens,
|
|
190
|
+
serviceTier: recordInput.serviceTier,
|
|
190
191
|
};
|
|
191
192
|
await append(row).catch(() => undefined);
|
|
192
193
|
},
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* re-exports the public symbols so existing importers are unchanged.
|
|
5
5
|
*/
|
|
6
6
|
import { isRecord } from "../utils.js";
|
|
7
|
-
import { HTTP_STATUS } from "../constants.js";
|
|
7
|
+
import { HTTP_STATUS, stripModelEffortSuffix } from "../constants.js";
|
|
8
8
|
/** @internal Exported only for sibling lib/request modules; import via fetch-helpers.ts elsewhere. */
|
|
9
9
|
export const CHATGPT_CODEX_UNSUPPORTED_MODEL_CODE = "model_not_supported_with_chatgpt_account";
|
|
10
10
|
const CHATGPT_CODEX_UNSUPPORTED_MODEL_PATTERN = /model is not supported when using codex with a chatgpt account/i;
|
|
@@ -72,7 +72,7 @@ function canonicalizeModelName(model) {
|
|
|
72
72
|
const stripped = trimmed.includes("/")
|
|
73
73
|
? (trimmed.split("/").pop() ?? trimmed)
|
|
74
74
|
: trimmed;
|
|
75
|
-
return stripped
|
|
75
|
+
return stripModelEffortSuffix(stripped);
|
|
76
76
|
}
|
|
77
77
|
function normalizeFallbackChain(customChain) {
|
|
78
78
|
// Null-prototype, because both the keys written here and the keys read out of
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type UsageLedgerAppendInput, type UsageLedgerPaths, type UsageLedgerQuery, type UsageLedgerRow, type UsageSummary, type UsageSummaryQuery } from "./types.js";
|
|
2
2
|
export declare function getUsageLedgerPaths(): UsageLedgerPaths;
|
|
3
3
|
export declare function appendUsageLedgerRow(input: UsageLedgerAppendInput): Promise<UsageLedgerRow>;
|
|
4
4
|
export declare function readUsageLedgerRows(query?: UsageLedgerQuery): Promise<UsageLedgerRow[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../../../lib/usage/ledger.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../../../lib/usage/ledger.ts"],"names":[],"mappings":"AASA,OAAO,EAEN,KAAK,sBAAsB,EAE3B,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EAErB,KAAK,cAAc,EAEnB,KAAK,YAAY,EAGjB,KAAK,iBAAiB,EAEtB,MAAM,YAAY,CAAC;AAqOpB,wBAAgB,mBAAmB,IAAI,gBAAgB,CAMtD;AAED,wBAAsB,oBAAoB,CACzC,KAAK,EAAE,sBAAsB,GAC3B,OAAO,CAAC,cAAc,CAAC,CASzB;AAuKD,wBAAsB,mBAAmB,CACxC,KAAK,GAAE,gBAAqB,GAC1B,OAAO,CAAC,cAAc,EAAE,CAAC,CAc3B;AAuDD,wBAAgB,kBAAkB,CACjC,IAAI,EAAE,cAAc,EAAE,EACtB,KAAK,GAAE,iBAAsB,GAC3B,YAAY,CAwBd;AAED,wBAAsB,oBAAoB,CACzC,KAAK,GAAE,iBAAsB,GAC3B,OAAO,CAAC,YAAY,CAAC,CAEvB;AAED,wBAAsB,iBAAiB,CAAC,OAAO,GAAE;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA2B9B;AAED,wBAAgB,6BAA6B,IAAI,IAAI,CAEpD"}
|
package/dist/lib/usage/ledger.js
CHANGED
|
@@ -4,6 +4,7 @@ import { getCodexMultiAuthDir } from "../runtime-paths.js";
|
|
|
4
4
|
import { logWarn } from "../logger.js";
|
|
5
5
|
import { isRecord, sleep } from "../utils.js";
|
|
6
6
|
import { normalizeUsageLedgerRow, usageRowToJsonLine, } from "./redaction.js";
|
|
7
|
+
import { isKnownServiceTier, } from "./types.js";
|
|
7
8
|
const USAGE_DIR_NAME = "usage";
|
|
8
9
|
const USAGE_LEDGER_FILE_NAME = "usage-ledger.jsonl";
|
|
9
10
|
const RETRYABLE_FS_CODES = new Set(["EBUSY", "EPERM"]);
|
|
@@ -287,6 +288,14 @@ function normalizeParsedUsageRow(value) {
|
|
|
287
288
|
Number.isFinite(value.tokens.totalTokens)
|
|
288
289
|
? Math.max(0, Math.trunc(value.tokens.totalTokens))
|
|
289
290
|
: 0,
|
|
291
|
+
// Validated against the union rather than passed through: the file is
|
|
292
|
+
// on disk and can be edited, and an unrecognised string would reach the
|
|
293
|
+
// pricer as a tier it has no rate for. Rebuilding only the numeric
|
|
294
|
+
// fields dropped this entirely, so a persisted Fast row read back as
|
|
295
|
+
// standard in `usage` reports.
|
|
296
|
+
...(isKnownServiceTier(value.tokens.serviceTier)
|
|
297
|
+
? { serviceTier: value.tokens.serviceTier }
|
|
298
|
+
: {}),
|
|
290
299
|
};
|
|
291
300
|
const account = isRecord(value.account)
|
|
292
301
|
? {
|
|
@@ -1,9 +1,24 @@
|
|
|
1
|
-
import type { UsageTokenCounts } from "./types.js";
|
|
1
|
+
import type { UsageServiceTier, UsageTokenCounts } from "./types.js";
|
|
2
2
|
export interface UsageModelPricing {
|
|
3
3
|
inputUsdPerMillion: number;
|
|
4
4
|
outputUsdPerMillion: number;
|
|
5
5
|
cachedInputUsdPerMillion?: number;
|
|
6
6
|
reasoningUsdPerMillion?: number;
|
|
7
|
+
/**
|
|
8
|
+
* Rates for non-standard service tiers, keyed by `UsageServiceTier`.
|
|
9
|
+
*
|
|
10
|
+
* Every entry in `MODEL_PRICING` is a STANDARD-tier rate. OpenAI's Fast tier
|
|
11
|
+
* costs more (2x for GPT-6 Astra), so pricing a Fast session off the standard
|
|
12
|
+
* row under-counts it by half and lets a `maxCostUsd` cap overrun.
|
|
13
|
+
*
|
|
14
|
+
* A tier absent from this map is deliberately NOT approximated from the
|
|
15
|
+
* standard rate. Only Astra's Fast multiplier is published; inventing one for
|
|
16
|
+
* the rest would move a budget's trip point on a guess, which is the failure
|
|
17
|
+
* this file exists to avoid. `estimateUsageCostUsd` reports an unlisted tier
|
|
18
|
+
* as unknown cost instead, so a budget fails closed the same way it does for
|
|
19
|
+
* an unpriced model.
|
|
20
|
+
*/
|
|
21
|
+
serviceTiers?: Partial<Record<UsageServiceTier, UsageModelPricing>>;
|
|
7
22
|
}
|
|
8
23
|
/**
|
|
9
24
|
* Models the router can normalize to that have no published rate here yet.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../../lib/usage/pricing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../../lib/usage/pricing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAErE,MAAM,WAAW,iBAAiB;IACjC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,CAAC,CAAC;CACpE;AAyFD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,wBAAwB,0MAkB3B,CAAC;AAOX,wBAAgB,oBAAoB,CACnC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC9B,iBAAiB,GAAG,IAAI,CAiB1B;AAmBD,wBAAgB,oBAAoB,CACnC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,MAAM,EAAE,gBAAgB,GACtB,MAAM,GAAG,IAAI,CA8Bf;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAEzE"}
|
|
@@ -1,16 +1,33 @@
|
|
|
1
1
|
const MODEL_PRICING = {
|
|
2
2
|
// GPT-6 Astra, published at the 2026-09-03 launch: $10 / 1M input,
|
|
3
|
-
// $50 / 1M output on the standard service tier
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// input rate
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
3
|
+
// $50 / 1M output on the standard service tier, and $20 / $100 on Fast,
|
|
4
|
+
// carried in `serviceTiers` below.
|
|
5
|
+
//
|
|
6
|
+
// The cached-input rate is the platform-wide 90% cached discount, which every
|
|
7
|
+
// other row in this table already encodes at exactly input/10. It shipped
|
|
8
|
+
// absent at first, on the reasoning that no Astra-specific cached figure was
|
|
9
|
+
// published; that made Astra the only model billing cached tokens at the FULL
|
|
10
|
+
// input rate, over-stating a cache-heavy session tenfold and tripping a
|
|
11
|
+
// `maxCostUsd` cap far too early. Over-stating is the safer direction than
|
|
12
|
+
// under-stating, but a 10x error blocks legitimate work, and the discount is
|
|
13
|
+
// a uniform platform rate rather than a per-model guess.
|
|
10
14
|
"gpt-6-astra": {
|
|
11
15
|
inputUsdPerMillion: 10,
|
|
12
16
|
outputUsdPerMillion: 50,
|
|
17
|
+
cachedInputUsdPerMillion: 1,
|
|
13
18
|
reasoningUsdPerMillion: 50,
|
|
19
|
+
serviceTiers: {
|
|
20
|
+
// Published at launch alongside the standard rate: Fast mode is up to
|
|
21
|
+
// 2.5x the speed at 2x the price, $20 / $100 per 1M. This is the only
|
|
22
|
+
// tier multiplier OpenAI has published for any model in this table,
|
|
23
|
+
// which is why it is the only one listed anywhere in this file.
|
|
24
|
+
priority: {
|
|
25
|
+
inputUsdPerMillion: 20,
|
|
26
|
+
outputUsdPerMillion: 100,
|
|
27
|
+
cachedInputUsdPerMillion: 2,
|
|
28
|
+
reasoningUsdPerMillion: 100,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
14
31
|
},
|
|
15
32
|
"gpt-5-codex": {
|
|
16
33
|
inputUsdPerMillion: 1.25,
|
|
@@ -122,8 +139,29 @@ export function getUsageModelPricing(model) {
|
|
|
122
139
|
}
|
|
123
140
|
return MODEL_PRICING[normalized] ?? null;
|
|
124
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Pick the rate that applies to a response's service tier.
|
|
144
|
+
*
|
|
145
|
+
* Returns `null` when the tier is real but this table has no rate for it, which
|
|
146
|
+
* the caller turns into an unknown cost. `standard` and an absent tier both use
|
|
147
|
+
* the base row, because every entry in `MODEL_PRICING` is a standard-tier rate.
|
|
148
|
+
*/
|
|
149
|
+
function resolveServiceTierPricing(pricing, serviceTier) {
|
|
150
|
+
if (!serviceTier || serviceTier === "standard") {
|
|
151
|
+
return pricing;
|
|
152
|
+
}
|
|
153
|
+
return pricing.serviceTiers?.[serviceTier] ?? null;
|
|
154
|
+
}
|
|
125
155
|
export function estimateUsageCostUsd(model, tokens) {
|
|
126
|
-
const
|
|
156
|
+
const basePricing = getUsageModelPricing(model);
|
|
157
|
+
if (!basePricing) {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
// Resolve the tier BEFORE any arithmetic. A response billed at a tier this
|
|
161
|
+
// table has no rate for must report unknown cost, not a standard-tier
|
|
162
|
+
// figure: under-counting is what lets a `maxCostUsd` cap overrun, and
|
|
163
|
+
// `evaluateBudgetGuard` already knows how to fail closed on `null`.
|
|
164
|
+
const pricing = resolveServiceTierPricing(basePricing, tokens.serviceTier);
|
|
127
165
|
if (!pricing) {
|
|
128
166
|
return null;
|
|
129
167
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type UsageLedgerAccountRef, type UsageLedgerAppendInput, type UsageLedgerRow } from "./types.js";
|
|
2
2
|
export declare function hashUsageIdentifier(value: string): string;
|
|
3
3
|
export declare function createUsageAccountRef(input: {
|
|
4
4
|
accountId?: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../../../lib/usage/redaction.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../../../lib/usage/redaction.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAG3B,KAAK,cAAc,EAGnB,MAAM,YAAY,CAAC;AA2EpB,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC5C,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,GAAG,qBAAqB,GAAG,IAAI,CAkB/B;AAkCD,wBAAgB,uBAAuB,CACtC,KAAK,EAAE,sBAAsB,GAC3B,cAAc,CA0BhB;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAE9D"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
import { isKnownServiceTier, } from "./types.js";
|
|
2
3
|
import { estimateUsageCostUsd } from "./pricing.js";
|
|
3
4
|
const VALID_SOURCES = new Set([
|
|
4
5
|
"runtime-proxy",
|
|
@@ -98,6 +99,18 @@ function normalizeTokens(input) {
|
|
|
98
99
|
totalTokens: providedTotal === null
|
|
99
100
|
? computedTotal
|
|
100
101
|
: Math.max(0, Math.trunc(providedTotal)),
|
|
102
|
+
// Carried through so `estimateUsageCostUsd` below can refuse to price a
|
|
103
|
+
// tier it has no rate for. Dropping it here would silently restore the
|
|
104
|
+
// standard-rate under-count this field exists to prevent.
|
|
105
|
+
//
|
|
106
|
+
// Validated, not passed through on truthiness. Every other field in this
|
|
107
|
+
// normaliser is checked against its allowed set (`normalizeSource`,
|
|
108
|
+
// `normalizeOperation`, `normalizeOutcome`), and the ledger READ path
|
|
109
|
+
// already rejects an unknown tier. Accepting one here made the write
|
|
110
|
+
// path the only unvalidated way onto a row.
|
|
111
|
+
...(isKnownServiceTier(input.serviceTier)
|
|
112
|
+
? { serviceTier: input.serviceTier }
|
|
113
|
+
: {}),
|
|
101
114
|
};
|
|
102
115
|
}
|
|
103
116
|
export function normalizeUsageLedgerRow(input) {
|
|
@@ -1,12 +1,40 @@
|
|
|
1
1
|
export type UsageLedgerSource = "runtime-proxy" | "plugin-host" | "local-bridge" | "cli" | "unknown";
|
|
2
2
|
export type UsageLedgerOperation = "responses" | "models" | "thread-goal" | "auth-refresh" | "diagnostic" | "unknown";
|
|
3
3
|
export type UsageLedgerOutcome = "success" | "failure" | "blocked" | "cancelled";
|
|
4
|
+
/**
|
|
5
|
+
* The service tier a response was actually billed at.
|
|
6
|
+
*
|
|
7
|
+
* OpenAI's Fast/priority tier costs more than standard (2x for GPT-6 Astra), so
|
|
8
|
+
* a rate table with no tier dimension under-counts such a session. `standard`
|
|
9
|
+
* and `default` are the same thing on the wire; anything this union does not
|
|
10
|
+
* name is normalised to `unknown`, which is treated as unpriced rather than
|
|
11
|
+
* assumed cheap.
|
|
12
|
+
*/
|
|
13
|
+
export declare const USAGE_SERVICE_TIERS: readonly ["standard", "priority", "flex", "batch", "scale", "unknown"];
|
|
14
|
+
export type UsageServiceTier = (typeof USAGE_SERVICE_TIERS)[number];
|
|
15
|
+
/**
|
|
16
|
+
* Narrow an unvalidated value to a known tier.
|
|
17
|
+
*
|
|
18
|
+
* The ledger is JSONL on disk and can be hand-edited, so a value read back from
|
|
19
|
+
* it is untrusted. An unrecognised string reaching the pricer would be treated
|
|
20
|
+
* as a tier with no rate and silently make every affected row unpriced.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isKnownServiceTier(value: unknown): value is UsageServiceTier;
|
|
4
23
|
export interface UsageTokenCounts {
|
|
5
24
|
inputTokens: number;
|
|
6
25
|
outputTokens: number;
|
|
7
26
|
cachedInputTokens: number;
|
|
8
27
|
reasoningTokens: number;
|
|
9
28
|
totalTokens: number;
|
|
29
|
+
/**
|
|
30
|
+
* Rides on the token counts rather than a separate parameter so it reaches
|
|
31
|
+
* the ledger through every existing path: the `onUsage` callback in
|
|
32
|
+
* `response-handler.ts` carries this shape, and both the streaming scanner
|
|
33
|
+
* and the non-streaming branch already funnel through
|
|
34
|
+
* `extractResponsesUsage`. Absent when the response did not report one,
|
|
35
|
+
* which is the common case and is priced as `standard`.
|
|
36
|
+
*/
|
|
37
|
+
serviceTier?: UsageServiceTier;
|
|
10
38
|
}
|
|
11
39
|
export interface UsageLedgerAccountRef {
|
|
12
40
|
accountHash?: string;
|
|
@@ -50,6 +78,11 @@ export interface UsageLedgerAppendInput {
|
|
|
50
78
|
cachedInputTokens?: number | null;
|
|
51
79
|
reasoningTokens?: number | null;
|
|
52
80
|
totalTokens?: number | null;
|
|
81
|
+
/**
|
|
82
|
+
* The tier the response reported. Absent means standard, which is what every
|
|
83
|
+
* rate in `MODEL_PRICING` is quoted at.
|
|
84
|
+
*/
|
|
85
|
+
serviceTier?: UsageServiceTier;
|
|
53
86
|
costUsd?: number | null;
|
|
54
87
|
}
|
|
55
88
|
export type UsageSummaryGroupBy = "model" | "account" | "project" | "outcome" | "day";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../lib/usage/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAC1B,eAAe,GACf,aAAa,GACb,cAAc,GACd,KAAK,GACL,SAAS,CAAC;AAEb,MAAM,MAAM,oBAAoB,GAC7B,WAAW,GACX,QAAQ,GACR,aAAa,GACb,cAAc,GACd,YAAY,GACZ,SAAS,CAAC;AAEb,MAAM,MAAM,kBAAkB,GAC3B,SAAS,GACT,SAAS,GACT,SAAS,GACT,WAAW,CAAC;AAEf,MAAM,WAAW,gBAAgB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../lib/usage/types.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/usage/types.js
CHANGED
|
@@ -1 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* The service tier a response was actually billed at.
|
|
3
|
+
*
|
|
4
|
+
* OpenAI's Fast/priority tier costs more than standard (2x for GPT-6 Astra), so
|
|
5
|
+
* a rate table with no tier dimension under-counts such a session. `standard`
|
|
6
|
+
* and `default` are the same thing on the wire; anything this union does not
|
|
7
|
+
* name is normalised to `unknown`, which is treated as unpriced rather than
|
|
8
|
+
* assumed cheap.
|
|
9
|
+
*/
|
|
10
|
+
export const USAGE_SERVICE_TIERS = [
|
|
11
|
+
"standard",
|
|
12
|
+
"priority",
|
|
13
|
+
"flex",
|
|
14
|
+
"batch",
|
|
15
|
+
"scale",
|
|
16
|
+
"unknown",
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* Narrow an unvalidated value to a known tier.
|
|
20
|
+
*
|
|
21
|
+
* The ledger is JSONL on disk and can be hand-edited, so a value read back from
|
|
22
|
+
* it is untrusted. An unrecognised string reaching the pricer would be treated
|
|
23
|
+
* as a tier with no rate and silently make every affected row unpriced.
|
|
24
|
+
*/
|
|
25
|
+
export function isKnownServiceTier(value) {
|
|
26
|
+
return (typeof value === "string" &&
|
|
27
|
+
USAGE_SERVICE_TIERS.includes(value));
|
|
28
|
+
}
|
|
@@ -17,7 +17,8 @@ import type { UsageTokenCounts } from "./types.js";
|
|
|
17
17
|
export declare function extractUsageTokenCounts(usage: unknown): UsageTokenCounts | null;
|
|
18
18
|
/**
|
|
19
19
|
* Pull the `usage` object out of a Responses payload, whether it arrived as a
|
|
20
|
-
* bare response object (non-streaming) or wrapped in a stream event envelope
|
|
20
|
+
* bare response object (non-streaming) or wrapped in a stream event envelope,
|
|
21
|
+
* and attach the tier it was billed at.
|
|
21
22
|
*/
|
|
22
23
|
export declare function extractResponsesUsage(payload: unknown): UsageTokenCounts | null;
|
|
23
24
|
export interface UsageStreamScanner {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage-extraction.d.ts","sourceRoot":"","sources":["../../../lib/usage/usage-extraction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"usage-extraction.d.ts","sourceRoot":"","sources":["../../../lib/usage/usage-extraction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA+BrE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CACtC,KAAK,EAAE,OAAO,GACZ,gBAAgB,GAAG,IAAI,CA+BzB;AAoCD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,CAa/E;AAED,MAAM,WAAW,kBAAkB;IAClC,8CAA8C;IAC9C,IAAI,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAClC,2EAA2E;IAC3E,MAAM,EAAE,MAAM,gBAAgB,GAAG,IAAI,CAAC;CACtC;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IACjD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,GAAG,kBAAkB,CA6ErB"}
|
|
@@ -66,18 +66,58 @@ export function extractUsageTokenCounts(usage) {
|
|
|
66
66
|
totalTokens: providedTotal,
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Read the billed service tier off a Responses payload.
|
|
71
|
+
*
|
|
72
|
+
* `service_tier` sits on the response object, not inside `usage`, and a stream
|
|
73
|
+
* event wraps that object one level down. An unrecognised value becomes
|
|
74
|
+
* `unknown` rather than being dropped, because dropping it would price the row
|
|
75
|
+
* at standard rates and under-count a more expensive tier.
|
|
76
|
+
*/
|
|
77
|
+
function extractServiceTier(payload) {
|
|
78
|
+
const raw = payload.service_tier ??
|
|
79
|
+
(isRecord(payload.response) ? payload.response.service_tier : undefined);
|
|
80
|
+
if (typeof raw !== "string")
|
|
81
|
+
return undefined;
|
|
82
|
+
const normalized = raw.trim().toLowerCase();
|
|
83
|
+
if (normalized.length === 0)
|
|
84
|
+
return undefined;
|
|
85
|
+
// `default` is what the API calls the standard tier on the wire.
|
|
86
|
+
if (normalized === "default" || normalized === "standard")
|
|
87
|
+
return "standard";
|
|
88
|
+
// The upstream catalog names this tier `priority` with the display name
|
|
89
|
+
// "Fast", and lists `fast` in `additional_speed_tiers`, so a response can
|
|
90
|
+
// report either spelling. Without this it becomes `unknown`, which prices
|
|
91
|
+
// as unpriced and fails a cost budget closed on a tier we DO have a rate
|
|
92
|
+
// for.
|
|
93
|
+
if (normalized === "fast")
|
|
94
|
+
return "priority";
|
|
95
|
+
if (normalized === "priority" ||
|
|
96
|
+
normalized === "flex" ||
|
|
97
|
+
normalized === "batch" ||
|
|
98
|
+
normalized === "scale") {
|
|
99
|
+
return normalized;
|
|
100
|
+
}
|
|
101
|
+
return "unknown";
|
|
102
|
+
}
|
|
69
103
|
/**
|
|
70
104
|
* Pull the `usage` object out of a Responses payload, whether it arrived as a
|
|
71
|
-
* bare response object (non-streaming) or wrapped in a stream event envelope
|
|
105
|
+
* bare response object (non-streaming) or wrapped in a stream event envelope,
|
|
106
|
+
* and attach the tier it was billed at.
|
|
72
107
|
*/
|
|
73
108
|
export function extractResponsesUsage(payload) {
|
|
74
109
|
if (!isRecord(payload))
|
|
75
110
|
return null;
|
|
111
|
+
const serviceTier = extractServiceTier(payload);
|
|
76
112
|
const direct = extractUsageTokenCounts(payload.usage);
|
|
77
|
-
if (direct)
|
|
78
|
-
return direct;
|
|
113
|
+
if (direct) {
|
|
114
|
+
return serviceTier ? { ...direct, serviceTier } : direct;
|
|
115
|
+
}
|
|
79
116
|
if (isRecord(payload.response)) {
|
|
80
|
-
|
|
117
|
+
const nested = extractUsageTokenCounts(payload.response.usage);
|
|
118
|
+
if (!nested)
|
|
119
|
+
return null;
|
|
120
|
+
return serviceTier ? { ...nested, serviceTier } : nested;
|
|
81
121
|
}
|
|
82
122
|
return null;
|
|
83
123
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codex-multi-auth",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.12.0",
|
|
4
4
|
"description": "Codex CLI multi-account OAuth manager with account switching, health checks, runtime rotation, diagnostics, and recovery tools for @openai/codex",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|