audit-tools 0.30.2 → 0.30.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audit/cli/prompts.d.ts.map +1 -1
- package/dist/audit/cli/prompts.js +3 -1
- package/dist/audit/cli/prompts.js.map +1 -1
- package/dist/audit/quota/index.d.ts +5 -0
- package/dist/audit/quota/index.d.ts.map +1 -1
- package/dist/remediate/steps/dispatch.d.ts.map +1 -1
- package/dist/remediate/steps/dispatch.js +16 -22
- package/dist/remediate/steps/dispatch.js.map +1 -1
- package/dist/remediate/steps/nextStep.d.ts.map +1 -1
- package/dist/remediate/steps/nextStep.js +5 -1
- package/dist/remediate/steps/nextStep.js.map +1 -1
- package/dist/shared/dispatch/rollingDispatch.d.ts.map +1 -1
- package/dist/shared/dispatch/rollingDispatch.js +7 -3
- package/dist/shared/dispatch/rollingDispatch.js.map +1 -1
- package/dist/shared/index.d.ts +4 -1
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +3 -1
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/quota/apiPool.d.ts +1 -1
- package/dist/shared/quota/apiPool.d.ts.map +1 -1
- package/dist/shared/quota/apiPool.js +29 -7
- package/dist/shared/quota/apiPool.js.map +1 -1
- package/dist/shared/quota/capacity.d.ts +15 -0
- package/dist/shared/quota/capacity.d.ts.map +1 -1
- package/dist/shared/quota/capacity.js +5 -0
- package/dist/shared/quota/capacity.js.map +1 -1
- package/dist/shared/quota/claudeOAuthQuotaSource.d.ts +8 -0
- package/dist/shared/quota/claudeOAuthQuotaSource.d.ts.map +1 -1
- package/dist/shared/quota/claudeOAuthQuotaSource.js +15 -0
- package/dist/shared/quota/claudeOAuthQuotaSource.js.map +1 -1
- package/dist/shared/quota/codexQuotaSource.d.ts +3 -0
- package/dist/shared/quota/codexQuotaSource.d.ts.map +1 -1
- package/dist/shared/quota/codexQuotaSource.js +8 -0
- package/dist/shared/quota/codexQuotaSource.js.map +1 -1
- package/dist/shared/quota/compositeQuotaSource.d.ts +22 -0
- package/dist/shared/quota/compositeQuotaSource.d.ts.map +1 -1
- package/dist/shared/quota/compositeQuotaSource.js +42 -0
- package/dist/shared/quota/compositeQuotaSource.js.map +1 -1
- package/dist/shared/quota/coverage.d.ts +45 -0
- package/dist/shared/quota/coverage.d.ts.map +1 -0
- package/dist/shared/quota/coverage.js +77 -0
- package/dist/shared/quota/coverage.js.map +1 -0
- package/dist/shared/quota/httpQuotaSource.d.ts +24 -1
- package/dist/shared/quota/httpQuotaSource.d.ts.map +1 -1
- package/dist/shared/quota/httpQuotaSource.js +46 -6
- package/dist/shared/quota/httpQuotaSource.js.map +1 -1
- package/dist/shared/quota/quotaCoverageNudge.d.ts +26 -0
- package/dist/shared/quota/quotaCoverageNudge.d.ts.map +1 -0
- package/dist/shared/quota/quotaCoverageNudge.js +82 -0
- package/dist/shared/quota/quotaCoverageNudge.js.map +1 -0
- package/dist/shared/quota/quotaSource.d.ts +23 -0
- package/dist/shared/quota/quotaSource.d.ts.map +1 -1
- package/dist/shared/quota/quotaSource.js +15 -0
- package/dist/shared/quota/quotaSource.js.map +1 -1
- package/dist/shared/quota/scheduler.d.ts +10 -2
- package/dist/shared/quota/scheduler.d.ts.map +1 -1
- package/dist/shared/quota/scheduler.js +12 -3
- package/dist/shared/quota/scheduler.js.map +1 -1
- package/dist/shared/types/sessionConfig.d.ts +16 -0
- package/dist/shared/types/sessionConfig.d.ts.map +1 -1
- package/dist/shared/types/sessionConfig.js.map +1 -1
- package/package.json +1 -1
|
@@ -26,6 +26,15 @@ export declare class CompositeQuotaSource implements QuotaSource {
|
|
|
26
26
|
* every empty cascade as "no source configured".
|
|
27
27
|
*/
|
|
28
28
|
probeUsage(providerModelKey: string): Promise<QuotaProbeResult>;
|
|
29
|
+
/**
|
|
30
|
+
* Resolve the account id from the first source in the cascade that handles this
|
|
31
|
+
* provider and yields one (each source returns null for a provider it doesn't
|
|
32
|
+
* own). Never throws — a failing source is skipped so account resolution degrades
|
|
33
|
+
* to null rather than aborting pool construction.
|
|
34
|
+
*/
|
|
35
|
+
resolveAccountId(providerModelKey: string): Promise<string | null>;
|
|
36
|
+
/** Proactive coverage if ANY source in the cascade covers the provider. */
|
|
37
|
+
coversProvider(provider: string): boolean;
|
|
29
38
|
}
|
|
30
39
|
/**
|
|
31
40
|
* Builds the standard runtime quota snapshot cascade.
|
|
@@ -35,4 +44,17 @@ export declare class CompositeQuotaSource implements QuotaSource {
|
|
|
35
44
|
* CompositeQuotaSource skips throwing sources and returns the first snapshot.
|
|
36
45
|
*/
|
|
37
46
|
export declare function buildQuotaSource(options?: BuildQuotaSourceOptions): QuotaSource;
|
|
47
|
+
/**
|
|
48
|
+
* A quota source scoped to ONE dispatch source's own credential, for a source that
|
|
49
|
+
* authenticates as a different account than the host (its `credentials_path`). The
|
|
50
|
+
* returned source probes usage + resolves the account id from THAT file, so the
|
|
51
|
+
* source forms a pool keyed on its own `(provider, account)` — a distinct budget
|
|
52
|
+
* from the host's same-provider pool (docs/quota-dispatch-design.md §5b). Falls back
|
|
53
|
+
* to the shared source when no per-source credential is declared, or the provider has
|
|
54
|
+
* no per-account proactive endpoint (only Claude/Codex expose one).
|
|
55
|
+
*/
|
|
56
|
+
export declare function buildAccountScopedQuotaSource(source: {
|
|
57
|
+
provider: string;
|
|
58
|
+
credentials_path?: string;
|
|
59
|
+
}, fallback: QuotaSource): QuotaSource;
|
|
38
60
|
//# sourceMappingURL=compositeQuotaSource.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compositeQuotaSource.d.ts","sourceRoot":"","sources":["../../../src/shared/quota/compositeQuotaSource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"compositeQuotaSource.d.ts","sourceRoot":"","sources":["../../../src/shared/quota/compositeQuotaSource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAQ1F,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAEvD,MAAM,WAAW,uBAAuB;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,WAAW,EAAE,CAAC;IAClC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,WAAW,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;CACnC;AAED,qBAAa,oBAAqB,YAAW,WAAW;IACtD,QAAQ,CAAC,IAAI,eAAe;IAC5B,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,SAAS,CAAY;gBAEjB,OAAO,EAAE,WAAW,EAAE,EAAE,SAAS,CAAC,EAAE,SAAS;IAKnD,iBAAiB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAIrF;;;;;;;OAOG;IACG,UAAU,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAiCrE;;;;;OAKG;IACG,gBAAgB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAQxE,2EAA2E;IAC3E,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;CAG1C;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B,GAAG,WAAW,CAmBnF;AAED;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,EACvD,QAAQ,EAAE,WAAW,GACpB,WAAW,CAYb"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveAccountIdSafe } from "./quotaSource.js";
|
|
1
2
|
import { LearnedQuotaSource } from "./learnedQuotaSource.js";
|
|
2
3
|
import { ClaudeOAuthQuotaSource } from "./claudeOAuthQuotaSource.js";
|
|
3
4
|
import { CodexQuotaSource } from "./codexQuotaSource.js";
|
|
@@ -60,6 +61,24 @@ export class CompositeQuotaSource {
|
|
|
60
61
|
}
|
|
61
62
|
return { snapshot: null, status: sawDegraded ? "degraded" : "not_applicable" };
|
|
62
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Resolve the account id from the first source in the cascade that handles this
|
|
66
|
+
* provider and yields one (each source returns null for a provider it doesn't
|
|
67
|
+
* own). Never throws — a failing source is skipped so account resolution degrades
|
|
68
|
+
* to null rather than aborting pool construction.
|
|
69
|
+
*/
|
|
70
|
+
async resolveAccountId(providerModelKey) {
|
|
71
|
+
for (const source of this.sources) {
|
|
72
|
+
const account = await resolveAccountIdSafe(source, providerModelKey);
|
|
73
|
+
if (account)
|
|
74
|
+
return account;
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
/** Proactive coverage if ANY source in the cascade covers the provider. */
|
|
79
|
+
coversProvider(provider) {
|
|
80
|
+
return this.sources.some((s) => s.coversProvider?.(provider) ?? false);
|
|
81
|
+
}
|
|
63
82
|
}
|
|
64
83
|
/**
|
|
65
84
|
* Builds the standard runtime quota snapshot cascade.
|
|
@@ -83,4 +102,27 @@ export function buildQuotaSource(options = {}) {
|
|
|
83
102
|
new LearnedQuotaSource(options.halfLifeHours ?? 24),
|
|
84
103
|
], options.runLogger);
|
|
85
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* A quota source scoped to ONE dispatch source's own credential, for a source that
|
|
107
|
+
* authenticates as a different account than the host (its `credentials_path`). The
|
|
108
|
+
* returned source probes usage + resolves the account id from THAT file, so the
|
|
109
|
+
* source forms a pool keyed on its own `(provider, account)` — a distinct budget
|
|
110
|
+
* from the host's same-provider pool (docs/quota-dispatch-design.md §5b). Falls back
|
|
111
|
+
* to the shared source when no per-source credential is declared, or the provider has
|
|
112
|
+
* no per-account proactive endpoint (only Claude/Codex expose one).
|
|
113
|
+
*/
|
|
114
|
+
export function buildAccountScopedQuotaSource(source, fallback) {
|
|
115
|
+
const credentialsPath = source.credentials_path;
|
|
116
|
+
if (!credentialsPath)
|
|
117
|
+
return fallback;
|
|
118
|
+
switch (source.provider) {
|
|
119
|
+
case "claude":
|
|
120
|
+
case "claude-code":
|
|
121
|
+
return new ClaudeOAuthQuotaSource({ credentialsPath });
|
|
122
|
+
case "codex":
|
|
123
|
+
return new CodexQuotaSource({ credentialsPath });
|
|
124
|
+
default:
|
|
125
|
+
return fallback;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
86
128
|
//# sourceMappingURL=compositeQuotaSource.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compositeQuotaSource.js","sourceRoot":"","sources":["../../../src/shared/quota/compositeQuotaSource.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"compositeQuotaSource.js","sourceRoot":"","sources":["../../../src/shared/quota/compositeQuotaSource.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { QuotaSource } from "./quotaSource.js";
|
|
3
|
+
/**
|
|
4
|
+
* Whether audit-tools has PROACTIVE quota tracking wired for a host provider —
|
|
5
|
+
* the explicit signal that replaces silently falling back to reactive 429 in an
|
|
6
|
+
* as-yet-unsupported environment (docs/quota-dispatch-design.md §4):
|
|
7
|
+
*
|
|
8
|
+
* - `established` — a proactive QuotaSource in code covers this provider. The
|
|
9
|
+
* live-vs-missing-creds split is the orthogonal
|
|
10
|
+
* `quota_signal_degraded` flag.
|
|
11
|
+
* - `reactive_only` — this provider has NO proactive surface BY NATURE (a static
|
|
12
|
+
* API key / local model: NIM, vLLM, local-subprocess). Not a
|
|
13
|
+
* gap — reactive 429 is the correct and only signal.
|
|
14
|
+
* - `unestablished` — NO source in code covers this provider. The environment is
|
|
15
|
+
* not yet supported; the host agent is nudged to self-track or
|
|
16
|
+
* research a source rather than degrading blind.
|
|
17
|
+
*/
|
|
18
|
+
export declare const QuotaCoverageStatusSchema: z.ZodEnum<["established", "reactive_only", "unestablished"]>;
|
|
19
|
+
export type QuotaCoverageStatus = z.infer<typeof QuotaCoverageStatusSchema>;
|
|
20
|
+
/**
|
|
21
|
+
* Providers with no proactive quota endpoint by nature — a static API key or a
|
|
22
|
+
* local model. Their absence from the proactive set is intentional, NOT a missing
|
|
23
|
+
* integration, so they classify as `reactive_only` (no nudge). Reactive 429 /
|
|
24
|
+
* local-unbounded is the right model. Keyed by the resolved provider segment of a
|
|
25
|
+
* pool key.
|
|
26
|
+
*/
|
|
27
|
+
export declare const REACTIVE_ONLY_PROVIDERS: ReadonlySet<string>;
|
|
28
|
+
/**
|
|
29
|
+
* Classify a host provider's proactive-quota coverage. `covered` is the pure,
|
|
30
|
+
* no-credential capability check ({@link QuotaSource.coversProvider}); `probeStatus`
|
|
31
|
+
* is unused for the coverage axis (it drives the orthogonal degraded flag) and kept
|
|
32
|
+
* for call-site clarity.
|
|
33
|
+
*/
|
|
34
|
+
export declare function classifyQuotaCoverage(provider: string, covered: boolean): QuotaCoverageStatus;
|
|
35
|
+
/** True when the source advertises proactive coverage for `provider` (no creds read). */
|
|
36
|
+
export declare function sourceCoversProvider(source: QuotaSource, provider: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* The host-facing nudge emitted ONCE per unsupported environment (then a terse
|
|
39
|
+
* status). Two paths, conversation-first: self-report if the host has built-in
|
|
40
|
+
* access to its own usage, else OFFER to research an established source and act
|
|
41
|
+
* only on user consent — the progressive-coverage flywheel (the found endpoint /
|
|
42
|
+
* third-party tool becomes a new QuotaSource).
|
|
43
|
+
*/
|
|
44
|
+
export declare function renderUnestablishedQuotaNudge(provider: string): string;
|
|
45
|
+
//# sourceMappingURL=coverage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../../../src/shared/quota/coverage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAoB,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEtE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,yBAAyB,8DAIpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,CAMtD,CAAC;AAEH;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,GACf,mBAAmB,CAIrB;AAED,yFAAyF;AACzF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEnF;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAgBtE"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Whether audit-tools has PROACTIVE quota tracking wired for a host provider —
|
|
4
|
+
* the explicit signal that replaces silently falling back to reactive 429 in an
|
|
5
|
+
* as-yet-unsupported environment (docs/quota-dispatch-design.md §4):
|
|
6
|
+
*
|
|
7
|
+
* - `established` — a proactive QuotaSource in code covers this provider. The
|
|
8
|
+
* live-vs-missing-creds split is the orthogonal
|
|
9
|
+
* `quota_signal_degraded` flag.
|
|
10
|
+
* - `reactive_only` — this provider has NO proactive surface BY NATURE (a static
|
|
11
|
+
* API key / local model: NIM, vLLM, local-subprocess). Not a
|
|
12
|
+
* gap — reactive 429 is the correct and only signal.
|
|
13
|
+
* - `unestablished` — NO source in code covers this provider. The environment is
|
|
14
|
+
* not yet supported; the host agent is nudged to self-track or
|
|
15
|
+
* research a source rather than degrading blind.
|
|
16
|
+
*/
|
|
17
|
+
export const QuotaCoverageStatusSchema = z.enum([
|
|
18
|
+
"established",
|
|
19
|
+
"reactive_only",
|
|
20
|
+
"unestablished",
|
|
21
|
+
]);
|
|
22
|
+
/**
|
|
23
|
+
* Providers with no proactive quota endpoint by nature — a static API key or a
|
|
24
|
+
* local model. Their absence from the proactive set is intentional, NOT a missing
|
|
25
|
+
* integration, so they classify as `reactive_only` (no nudge). Reactive 429 /
|
|
26
|
+
* local-unbounded is the right model. Keyed by the resolved provider segment of a
|
|
27
|
+
* pool key.
|
|
28
|
+
*/
|
|
29
|
+
export const REACTIVE_ONLY_PROVIDERS = new Set([
|
|
30
|
+
"openai-compatible",
|
|
31
|
+
"nvidia-nim",
|
|
32
|
+
"nvidia-nim-local",
|
|
33
|
+
"local-subprocess",
|
|
34
|
+
"ollama",
|
|
35
|
+
]);
|
|
36
|
+
/**
|
|
37
|
+
* Classify a host provider's proactive-quota coverage. `covered` is the pure,
|
|
38
|
+
* no-credential capability check ({@link QuotaSource.coversProvider}); `probeStatus`
|
|
39
|
+
* is unused for the coverage axis (it drives the orthogonal degraded flag) and kept
|
|
40
|
+
* for call-site clarity.
|
|
41
|
+
*/
|
|
42
|
+
export function classifyQuotaCoverage(provider, covered) {
|
|
43
|
+
if (covered)
|
|
44
|
+
return "established";
|
|
45
|
+
if (REACTIVE_ONLY_PROVIDERS.has(provider))
|
|
46
|
+
return "reactive_only";
|
|
47
|
+
return "unestablished";
|
|
48
|
+
}
|
|
49
|
+
/** True when the source advertises proactive coverage for `provider` (no creds read). */
|
|
50
|
+
export function sourceCoversProvider(source, provider) {
|
|
51
|
+
return source.coversProvider?.(provider) ?? false;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The host-facing nudge emitted ONCE per unsupported environment (then a terse
|
|
55
|
+
* status). Two paths, conversation-first: self-report if the host has built-in
|
|
56
|
+
* access to its own usage, else OFFER to research an established source and act
|
|
57
|
+
* only on user consent — the progressive-coverage flywheel (the found endpoint /
|
|
58
|
+
* third-party tool becomes a new QuotaSource).
|
|
59
|
+
*/
|
|
60
|
+
export function renderUnestablishedQuotaNudge(provider) {
|
|
61
|
+
return [
|
|
62
|
+
`⚠️ Quota tracking is NOT established for host provider \`${provider}\`.`,
|
|
63
|
+
`audit-tools has no proactive quota source wired for it, so dispatch would fall`,
|
|
64
|
+
`back to reactive rate-limit (429) handling only — pacing blind until a wall is hit.`,
|
|
65
|
+
``,
|
|
66
|
+
`To establish proactive quota tracking for \`${provider}\`:`,
|
|
67
|
+
` 1. If you (the host agent) have BUILT-IN access to your own remaining usage/`,
|
|
68
|
+
` quota, report it now so the run can pace from it, and note the access method`,
|
|
69
|
+
` so it can be wired in as a QuotaSource.`,
|
|
70
|
+
` 2. Otherwise, OFFER to the user: search online for \`${provider}\`'s quota/usage`,
|
|
71
|
+
` endpoint, or a third-party tool that already tracks it, then — with their`,
|
|
72
|
+
` consent — report the findings (endpoint, auth/credential location, response`,
|
|
73
|
+
` shape) so a proactive source can be added (see`,
|
|
74
|
+
` docs/cross-provider-quota-matrix.md for the established recipes).`,
|
|
75
|
+
].join("\n");
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=coverage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage.js","sourceRoot":"","sources":["../../../src/shared/quota/coverage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,IAAI,CAAC;IAC9C,aAAa;IACb,eAAe;IACf,eAAe;CAChB,CAAC,CAAC;AAGH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAwB,IAAI,GAAG,CAAC;IAClE,mBAAmB;IACnB,YAAY;IACZ,kBAAkB;IAClB,kBAAkB;IAClB,QAAQ;CACT,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAAgB,EAChB,OAAgB;IAEhB,IAAI,OAAO;QAAE,OAAO,aAAa,CAAC;IAClC,IAAI,uBAAuB,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAE,OAAO,eAAe,CAAC;IAClE,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,oBAAoB,CAAC,MAAmB,EAAE,QAAgB;IACxE,OAAO,MAAM,CAAC,cAAc,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC;AACpD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,6BAA6B,CAAC,QAAgB;IAC5D,OAAO;QACL,4DAA4D,QAAQ,KAAK;QACzE,gFAAgF;QAChF,qFAAqF;QACrF,EAAE;QACF,+CAA+C,QAAQ,KAAK;QAC5D,gFAAgF;QAChF,mFAAmF;QACnF,8CAA8C;QAC9C,0DAA0D,QAAQ,kBAAkB;QACpF,gFAAgF;QAChF,kFAAkF;QAClF,qDAAqD;QACrD,wEAAwE;KACzE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
|
@@ -59,6 +59,8 @@ export declare abstract class BaseHttpQuotaSource implements QuotaSource {
|
|
|
59
59
|
constructor(options: HttpQuotaSourceOptions, defaultUserAgent: string);
|
|
60
60
|
/** Providers this source answers for. A non-matching key returns null (no I/O). */
|
|
61
61
|
protected abstract handlesProvider(provider: string): boolean;
|
|
62
|
+
/** A proactive HTTP source covers exactly the providers it handles (no creds read). */
|
|
63
|
+
coversProvider(provider: string): boolean;
|
|
62
64
|
/**
|
|
63
65
|
* Provider-specific: read the local credential, call the endpoint, and map the
|
|
64
66
|
* response to a snapshot. Return null to degrade (missing/expired creds,
|
|
@@ -74,9 +76,25 @@ export declare abstract class BaseHttpQuotaSource implements QuotaSource {
|
|
|
74
76
|
* Both paths return through here so the cache and the status stay consistent.
|
|
75
77
|
*/
|
|
76
78
|
probeUsage(providerModelKey: string): Promise<QuotaProbeResult>;
|
|
79
|
+
/**
|
|
80
|
+
* Resolve the account id from the source's credential (local, no network).
|
|
81
|
+
* Gated by provider; subclasses that key per-account override
|
|
82
|
+
* {@link readAccountId}. Default null = provider carries no account discriminator.
|
|
83
|
+
*/
|
|
84
|
+
resolveAccountId(providerModelKey: string): Promise<string | null>;
|
|
85
|
+
/** Read this credential's account id (local file/JWT read), or null. Override per provider. */
|
|
86
|
+
protected readAccountId(_provider: string): string | null;
|
|
77
87
|
/** Context for the reusable `fetchXxxUsage` helpers. */
|
|
78
88
|
protected fetchContext(): UsageFetchContext;
|
|
79
89
|
protected shouldSkipNetwork(): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Hermeticity guard for the LOCAL credential read behind {@link readAccountId}:
|
|
92
|
+
* reading the real machine credential under a test runner is machine-dependent,
|
|
93
|
+
* so skip it when the source points at its DEFAULT credential path (an explicitly
|
|
94
|
+
* injected path — a test fixture or a per-source `credentials_path` — is always
|
|
95
|
+
* honored). The kill-switch disables it outright.
|
|
96
|
+
*/
|
|
97
|
+
protected shouldSkipCredentialRead(usingDefaultCredentialsPath: boolean): boolean;
|
|
80
98
|
}
|
|
81
99
|
/** GET/POST a JSON endpoint; returns parsed JSON, or null on non-200/network/parse failure. */
|
|
82
100
|
export declare function fetchJsonOrNull(fetchImpl: FetchLike, url: string, init: {
|
|
@@ -84,9 +102,14 @@ export declare function fetchJsonOrNull(fetchImpl: FetchLike, url: string, init:
|
|
|
84
102
|
headers?: Record<string, string>;
|
|
85
103
|
body?: string;
|
|
86
104
|
}): Promise<unknown | null>;
|
|
87
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* Splits a `provider[#account]/model` quota key into its parts. `provider/*` and a
|
|
107
|
+
* bare `provider` → model null; no `#` → account null. The model tail may contain
|
|
108
|
+
* `/` (split on the FIRST `/` only); provider + optional account live in the head.
|
|
109
|
+
*/
|
|
88
110
|
export declare function parseProviderModelKey(key: string): {
|
|
89
111
|
provider: string;
|
|
112
|
+
account: string | null;
|
|
90
113
|
model: string | null;
|
|
91
114
|
};
|
|
92
115
|
/** Clamp to a 0–1 fraction (the scheduler's `remaining_pct` scale). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"httpQuotaSource.d.ts","sourceRoot":"","sources":["../../../src/shared/quota/httpQuotaSource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE1F;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9B;AACD,MAAM,MAAM,SAAS,GAAG,CACtB,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KACxE,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEhC,iFAAiF;AACjF,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,SAAS,CAAC;IACrB,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,4DAA4D;IAC5D,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAiBD,8BAAsB,mBAAoB,YAAW,WAAW;IAC9D,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAE/B,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IACxC,SAAS,CAAC,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IAC9C,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAC;IACrC,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IACtC,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IACrC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;gBAE/C,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM;IAQrE,mFAAmF;IACnF,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAE7D;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,aAAa,CAC9B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAE/B,iBAAiB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAIrF;;;;;;OAMG;IACG,UAAU,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA4BrE,wDAAwD;IACxD,SAAS,CAAC,YAAY,IAAI,iBAAiB;IAI3C,SAAS,CAAC,iBAAiB,IAAI,OAAO;
|
|
1
|
+
{"version":3,"file":"httpQuotaSource.d.ts","sourceRoot":"","sources":["../../../src/shared/quota/httpQuotaSource.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,6 +19,10 @@ export class BaseHttpQuotaSource {
|
|
|
19
19
|
this.cacheTtlMs = options.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;
|
|
20
20
|
this.userAgent = options.userAgent ?? defaultUserAgent;
|
|
21
21
|
}
|
|
22
|
+
/** A proactive HTTP source covers exactly the providers it handles (no creds read). */
|
|
23
|
+
coversProvider(provider) {
|
|
24
|
+
return this.handlesProvider(provider);
|
|
25
|
+
}
|
|
22
26
|
async queryCurrentUsage(providerModelKey) {
|
|
23
27
|
return (await this.probeUsage(providerModelKey)).snapshot;
|
|
24
28
|
}
|
|
@@ -53,6 +57,21 @@ export class BaseHttpQuotaSource {
|
|
|
53
57
|
this.cache.set(providerModelKey, result);
|
|
54
58
|
return { snapshot, status: classifyProbe(result) };
|
|
55
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Resolve the account id from the source's credential (local, no network).
|
|
62
|
+
* Gated by provider; subclasses that key per-account override
|
|
63
|
+
* {@link readAccountId}. Default null = provider carries no account discriminator.
|
|
64
|
+
*/
|
|
65
|
+
async resolveAccountId(providerModelKey) {
|
|
66
|
+
const { provider } = parseProviderModelKey(providerModelKey);
|
|
67
|
+
if (!this.handlesProvider(provider))
|
|
68
|
+
return null;
|
|
69
|
+
return this.readAccountId(provider);
|
|
70
|
+
}
|
|
71
|
+
/** Read this credential's account id (local file/JWT read), or null. Override per provider. */
|
|
72
|
+
readAccountId(_provider) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
56
75
|
/** Context for the reusable `fetchXxxUsage` helpers. */
|
|
57
76
|
fetchContext() {
|
|
58
77
|
return { fetchImpl: this.fetchImpl, now: this.now, userAgent: this.userAgent };
|
|
@@ -64,6 +83,20 @@ export class BaseHttpQuotaSource {
|
|
|
64
83
|
return true;
|
|
65
84
|
return false;
|
|
66
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Hermeticity guard for the LOCAL credential read behind {@link readAccountId}:
|
|
88
|
+
* reading the real machine credential under a test runner is machine-dependent,
|
|
89
|
+
* so skip it when the source points at its DEFAULT credential path (an explicitly
|
|
90
|
+
* injected path — a test fixture or a per-source `credentials_path` — is always
|
|
91
|
+
* honored). The kill-switch disables it outright.
|
|
92
|
+
*/
|
|
93
|
+
shouldSkipCredentialRead(usingDefaultCredentialsPath) {
|
|
94
|
+
if (isTruthyEnv(process.env.AUDIT_TOOLS_DISABLE_PROACTIVE_QUOTA))
|
|
95
|
+
return true;
|
|
96
|
+
if (usingDefaultCredentialsPath && isUnderTestRunner())
|
|
97
|
+
return true;
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
67
100
|
}
|
|
68
101
|
/** GET/POST a JSON endpoint; returns parsed JSON, or null on non-200/network/parse failure. */
|
|
69
102
|
export async function fetchJsonOrNull(fetchImpl, url, init) {
|
|
@@ -83,14 +116,21 @@ export async function fetchJsonOrNull(fetchImpl, url, init) {
|
|
|
83
116
|
return null;
|
|
84
117
|
}
|
|
85
118
|
}
|
|
86
|
-
/**
|
|
119
|
+
/**
|
|
120
|
+
* Splits a `provider[#account]/model` quota key into its parts. `provider/*` and a
|
|
121
|
+
* bare `provider` → model null; no `#` → account null. The model tail may contain
|
|
122
|
+
* `/` (split on the FIRST `/` only); provider + optional account live in the head.
|
|
123
|
+
*/
|
|
87
124
|
export function parseProviderModelKey(key) {
|
|
88
125
|
const idx = key.indexOf("/");
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
|
|
126
|
+
const head = idx < 0 ? key : key.slice(0, idx);
|
|
127
|
+
const rest = idx < 0 ? "" : key.slice(idx + 1);
|
|
128
|
+
const model = idx < 0 || rest === "" || rest === "*" ? null : rest;
|
|
129
|
+
const hashIdx = head.indexOf("#");
|
|
130
|
+
if (hashIdx < 0)
|
|
131
|
+
return { provider: head, account: null, model };
|
|
132
|
+
const account = head.slice(hashIdx + 1);
|
|
133
|
+
return { provider: head.slice(0, hashIdx), account: account === "" ? null : account, model };
|
|
94
134
|
}
|
|
95
135
|
/** Clamp to a 0–1 fraction (the scheduler's `remaining_pct` scale). */
|
|
96
136
|
export function clampFraction(n) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"httpQuotaSource.js","sourceRoot":"","sources":["../../../src/shared/quota/httpQuotaSource.ts"],"names":[],"mappings":"AA6DA,qFAAqF;AACrF,SAAS,aAAa,CAAC,MAAsB;IAC3C,IAAI,MAAM,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC;AAC1D,CAAC;AAED,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAEpC,MAAM,OAAgB,mBAAmB;IAGpB,SAAS,CAAY;IACrB,iBAAiB,CAAU;IAC3B,GAAG,CAAe;IAClB,UAAU,CAAS;IACnB,SAAS,CAAS;IACpB,KAAK,GAAG,IAAI,GAAG,EAA0B,CAAC;IAE3D,YAAY,OAA+B,EAAE,gBAAwB;QACnE,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC;QACzD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAK,KAA8B,CAAC;QACtE,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC7C,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,oBAAoB,CAAC;QAC7D,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,gBAAgB,CAAC;IACzD,CAAC;
|
|
1
|
+
{"version":3,"file":"httpQuotaSource.js","sourceRoot":"","sources":["../../../src/shared/quota/httpQuotaSource.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gate the full unestablished-quota nudge to ONCE per environment: the first time
|
|
3
|
+
* an unsupported host provider is seen in an artifact dir, emit the full two-path
|
|
4
|
+
* nudge ({@link renderUnestablishedQuotaNudge}); afterward callers carry only the
|
|
5
|
+
* terse `quota_coverage: unestablished` status. State is a per-provider marker file
|
|
6
|
+
* in the artifact dir, so it survives across steps/runs of the same run dir.
|
|
7
|
+
*
|
|
8
|
+
* Returns true exactly once per (artifactDir, provider) — it writes the marker on
|
|
9
|
+
* the first true. All fs failures are swallowed: a missing/unwritable artifact dir
|
|
10
|
+
* degrades to "emit" (better a repeated nudge than a silently-swallowed gap).
|
|
11
|
+
*/
|
|
12
|
+
export declare function shouldEmitQuotaNudge(artifactDir: string, provider: string): boolean;
|
|
13
|
+
/** Marker filename for a provider, with non-filename-safe chars folded to `-`. */
|
|
14
|
+
export declare function quotaNudgeMarkerName(provider: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Build the dispatch-prompt quota-coverage nudge block from a written
|
|
17
|
+
* `dispatch-quota.json`: for each DISTINCT provider whose pool reported
|
|
18
|
+
* `quota_coverage: "unestablished"`, emit the full two-path nudge the FIRST time
|
|
19
|
+
* (once per environment, via {@link shouldEmitQuotaNudge}) and a terse one-liner
|
|
20
|
+
* after. Returns "" when the file is absent/unreadable or no provider is
|
|
21
|
+
* unestablished — so a supported environment adds nothing to the prompt. Shared so
|
|
22
|
+
* both orchestrators surface the identical block (no drift). Reads the contract's
|
|
23
|
+
* `capacity_pools[]` (each `{ pool_id, quota_coverage }`) defensively.
|
|
24
|
+
*/
|
|
25
|
+
export declare function renderQuotaCoverageNudge(quotaPath: string | null | undefined, artifactsDir: string): string;
|
|
26
|
+
//# sourceMappingURL=quotaCoverageNudge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quotaCoverageNudge.d.ts","sourceRoot":"","sources":["../../../src/shared/quota/quotaCoverageNudge.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAcnF;AAED,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,YAAY,EAAE,MAAM,GACnB,MAAM,CA6BR"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { parseProviderModelKey } from "./httpQuotaSource.js";
|
|
4
|
+
import { renderUnestablishedQuotaNudge } from "./coverage.js";
|
|
5
|
+
/**
|
|
6
|
+
* Gate the full unestablished-quota nudge to ONCE per environment: the first time
|
|
7
|
+
* an unsupported host provider is seen in an artifact dir, emit the full two-path
|
|
8
|
+
* nudge ({@link renderUnestablishedQuotaNudge}); afterward callers carry only the
|
|
9
|
+
* terse `quota_coverage: unestablished` status. State is a per-provider marker file
|
|
10
|
+
* in the artifact dir, so it survives across steps/runs of the same run dir.
|
|
11
|
+
*
|
|
12
|
+
* Returns true exactly once per (artifactDir, provider) — it writes the marker on
|
|
13
|
+
* the first true. All fs failures are swallowed: a missing/unwritable artifact dir
|
|
14
|
+
* degrades to "emit" (better a repeated nudge than a silently-swallowed gap).
|
|
15
|
+
*/
|
|
16
|
+
export function shouldEmitQuotaNudge(artifactDir, provider) {
|
|
17
|
+
const markerPath = path.join(artifactDir, quotaNudgeMarkerName(provider));
|
|
18
|
+
try {
|
|
19
|
+
if (existsSync(markerPath))
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return true; // can't tell → emit
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
mkdirSync(artifactDir, { recursive: true });
|
|
27
|
+
writeFileSync(markerPath, provider);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// Couldn't persist the marker — still emit this time (may re-emit next time).
|
|
31
|
+
}
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
/** Marker filename for a provider, with non-filename-safe chars folded to `-`. */
|
|
35
|
+
export function quotaNudgeMarkerName(provider) {
|
|
36
|
+
const safe = provider.replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
37
|
+
return `quota-coverage-nudged-${safe}.marker`;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Build the dispatch-prompt quota-coverage nudge block from a written
|
|
41
|
+
* `dispatch-quota.json`: for each DISTINCT provider whose pool reported
|
|
42
|
+
* `quota_coverage: "unestablished"`, emit the full two-path nudge the FIRST time
|
|
43
|
+
* (once per environment, via {@link shouldEmitQuotaNudge}) and a terse one-liner
|
|
44
|
+
* after. Returns "" when the file is absent/unreadable or no provider is
|
|
45
|
+
* unestablished — so a supported environment adds nothing to the prompt. Shared so
|
|
46
|
+
* both orchestrators surface the identical block (no drift). Reads the contract's
|
|
47
|
+
* `capacity_pools[]` (each `{ pool_id, quota_coverage }`) defensively.
|
|
48
|
+
*/
|
|
49
|
+
export function renderQuotaCoverageNudge(quotaPath, artifactsDir) {
|
|
50
|
+
if (!quotaPath)
|
|
51
|
+
return "";
|
|
52
|
+
let pools;
|
|
53
|
+
try {
|
|
54
|
+
const data = JSON.parse(readFileSync(quotaPath, "utf8"));
|
|
55
|
+
pools = Array.isArray(data?.capacity_pools)
|
|
56
|
+
? data.capacity_pools
|
|
57
|
+
: [];
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return "";
|
|
61
|
+
}
|
|
62
|
+
const seen = new Set();
|
|
63
|
+
const providers = [];
|
|
64
|
+
for (const pool of pools) {
|
|
65
|
+
if (pool?.quota_coverage !== "unestablished")
|
|
66
|
+
continue;
|
|
67
|
+
const { provider } = parseProviderModelKey(String(pool.pool_id ?? ""));
|
|
68
|
+
if (!provider || seen.has(provider))
|
|
69
|
+
continue;
|
|
70
|
+
seen.add(provider);
|
|
71
|
+
providers.push(provider);
|
|
72
|
+
}
|
|
73
|
+
if (providers.length === 0)
|
|
74
|
+
return "";
|
|
75
|
+
return providers
|
|
76
|
+
.map((provider) => shouldEmitQuotaNudge(artifactsDir, provider)
|
|
77
|
+
? renderUnestablishedQuotaNudge(provider)
|
|
78
|
+
: `⚠️ quota_coverage: unestablished for \`${provider}\` — no proactive quota source wired; ` +
|
|
79
|
+
`pacing is reactive-429 only. See dispatch-quota.json and the earlier nudge.`)
|
|
80
|
+
.join("\n\n");
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=quotaCoverageNudge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quotaCoverageNudge.js","sourceRoot":"","sources":["../../../src/shared/quota/quotaCoverageNudge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAC;AAE9D;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAAmB,EAAE,QAAgB;IACxE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1E,IAAI,CAAC;QACH,IAAI,UAAU,CAAC,UAAU,CAAC;YAAE,OAAO,KAAK,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,CAAC,oBAAoB;IACnC,CAAC;IACD,IAAI,CAAC;QACH,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,aAAa,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,8EAA8E;IAChF,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACnD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;IACxD,OAAO,yBAAyB,IAAI,SAAS,CAAC;AAChD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB,CACtC,SAAoC,EACpC,YAAoB;IAEpB,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,CAAC;IAC1B,IAAI,KAA6D,CAAC;IAClE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAiC,CAAC;QACzF,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,cAAc,CAAC;YACzC,CAAC,CAAE,IAAI,CAAC,cAAyE;YACjF,CAAC,CAAC,EAAE,CAAC;IACT,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,EAAE,cAAc,KAAK,eAAe;YAAE,SAAS;QACvD,MAAM,EAAE,QAAQ,EAAE,GAAG,qBAAqB,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;QACvE,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,SAAS;QAC9C,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnB,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC3B,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACtC,OAAO,SAAS;SACb,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAChB,oBAAoB,CAAC,YAAY,EAAE,QAAQ,CAAC;QAC1C,CAAC,CAAC,6BAA6B,CAAC,QAAQ,CAAC;QACzC,CAAC,CAAC,0CAA0C,QAAQ,wCAAwC;YAC1F,6EAA6E,CAClF;SACA,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -57,7 +57,30 @@ export interface QuotaSource {
|
|
|
57
57
|
* derives a best-effort result for sources that don't implement it.
|
|
58
58
|
*/
|
|
59
59
|
probeUsage?(providerModelKey: string): Promise<QuotaProbeResult>;
|
|
60
|
+
/**
|
|
61
|
+
* Resolve the ACCOUNT identity this source reads for a provider, from its
|
|
62
|
+
* credential — never guessed (see docs/quota-dispatch-design.md §5). Used to
|
|
63
|
+
* stamp the account segment into the pool key so two same-provider accounts
|
|
64
|
+
* form distinct pools. Returns null when the source doesn't handle the provider,
|
|
65
|
+
* the credential is absent/unreadable, or the provider carries no account id.
|
|
66
|
+
* Local-only (no network). Optional so plain stubs stay valid.
|
|
67
|
+
*/
|
|
68
|
+
resolveAccountId?(providerModelKey: string): Promise<string | null>;
|
|
69
|
+
/**
|
|
70
|
+
* Pure capability check: does this source provide PROACTIVE quota tracking for
|
|
71
|
+
* `provider`? No credentials, no network — answers "is this provider supported in
|
|
72
|
+
* code", which is what separates an unsupported environment (`unestablished`) from
|
|
73
|
+
* a supported-but-degraded one. Reactive-only sources (learned, host-session) omit
|
|
74
|
+
* it. See {@link classifyQuotaCoverage}.
|
|
75
|
+
*/
|
|
76
|
+
coversProvider?(provider: string): boolean;
|
|
60
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Resolve a provider's account id via a source's {@link QuotaSource.resolveAccountId}
|
|
80
|
+
* when it has one, else null. Never throws — account resolution failure degrades to
|
|
81
|
+
* an unkeyed (account-null) pool rather than aborting pool construction.
|
|
82
|
+
*/
|
|
83
|
+
export declare function resolveAccountIdSafe(source: QuotaSource, providerModelKey: string): Promise<string | null>;
|
|
61
84
|
/**
|
|
62
85
|
* Probe a quota source, using its native {@link QuotaSource.probeUsage} when it
|
|
63
86
|
* has one and otherwise deriving a conservative result from
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quotaSource.d.ts","sourceRoot":"","sources":["../../../src/shared/quota/quotaSource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;EAS1B,CAAC;AACZ,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,UAAU,GAAG,gBAAgB,CAAC;AAEpE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACpC,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAChF;;;;;;OAMG;IACH,UAAU,CAAC,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"quotaSource.d.ts","sourceRoot":"","sources":["../../../src/shared/quota/quotaSource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;EAS1B,CAAC;AACZ,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,UAAU,GAAG,gBAAgB,CAAC;AAEpE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACpC,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAChF;;;;;;OAMG;IACH,UAAU,CAAC,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACjE;;;;;;;OAOG;IACH,gBAAgB,CAAC,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACpE;;;;;;OAMG;IACH,cAAc,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;CAC5C;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,WAAW,EACnB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOxB;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,WAAW,EACnB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAQ3B"}
|
|
@@ -9,6 +9,21 @@ export const QuotaUsageSnapshotSchema = z
|
|
|
9
9
|
source: z.string(),
|
|
10
10
|
})
|
|
11
11
|
.strict();
|
|
12
|
+
/**
|
|
13
|
+
* Resolve a provider's account id via a source's {@link QuotaSource.resolveAccountId}
|
|
14
|
+
* when it has one, else null. Never throws — account resolution failure degrades to
|
|
15
|
+
* an unkeyed (account-null) pool rather than aborting pool construction.
|
|
16
|
+
*/
|
|
17
|
+
export async function resolveAccountIdSafe(source, providerModelKey) {
|
|
18
|
+
if (!source.resolveAccountId)
|
|
19
|
+
return null;
|
|
20
|
+
try {
|
|
21
|
+
return await source.resolveAccountId(providerModelKey);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
12
27
|
/**
|
|
13
28
|
* Probe a quota source, using its native {@link QuotaSource.probeUsage} when it
|
|
14
29
|
* has one and otherwise deriving a conservative result from
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quotaSource.js","sourceRoot":"","sources":["../../../src/shared/quota/quotaSource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC;KACtC,MAAM,CAAC;IACN,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC/C,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC7C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;CACnB,CAAC;KACD,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"quotaSource.js","sourceRoot":"","sources":["../../../src/shared/quota/quotaSource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC;KACtC,MAAM,CAAC;IACN,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC/C,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC7C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;CACnB,CAAC;KACD,MAAM,EAAE,CAAC;AA2DZ;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAmB,EACnB,gBAAwB;IAExB,IAAI,CAAC,MAAM,CAAC,gBAAgB;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,CAAC;QACH,OAAO,MAAM,MAAM,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAmB,EACnB,gBAAwB;IAExB,IAAI,MAAM,CAAC,UAAU;QAAE,OAAO,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAClE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;QAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAChD,CAAC;AACH,CAAC"}
|
|
@@ -89,6 +89,14 @@ export declare const DEFAULT_FIRST_CONTACT_CONCURRENCY = 3;
|
|
|
89
89
|
export declare const QUOTA_REMAINING_PCT_CRITICAL = 0.1;
|
|
90
90
|
export declare const QUOTA_REMAINING_PCT_LOW = 0.3;
|
|
91
91
|
export declare function scheduleWave(options: ScheduleWaveOptions): WaveSchedule;
|
|
92
|
-
/**
|
|
93
|
-
|
|
92
|
+
/**
|
|
93
|
+
* Build the quota pool key used for indexing quota-state.json entries and gating
|
|
94
|
+
* sources. Pool identity is `(provider, account, model)` — quota is billed
|
|
95
|
+
* per-ACCOUNT, so two same-provider accounts must NOT alias to one pool (see
|
|
96
|
+
* docs/quota-dispatch-design.md §5). Format: `provider[#account]/model`. The
|
|
97
|
+
* account segment is OMITTED when null, so a single-account run keeps the legacy
|
|
98
|
+
* `provider/model` key (no migration). The `model` tail may itself contain `/`;
|
|
99
|
+
* provider + account live in the head before the first `/`.
|
|
100
|
+
*/
|
|
101
|
+
export declare function buildProviderModelKey(providerName: string, hostModel: string | null | undefined, account?: string | null): string;
|
|
94
102
|
//# sourceMappingURL=scheduler.d.ts.map
|