ag-common 0.0.911 → 0.0.913
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/api/helpers/index.d.ts +0 -2
- package/dist/api/helpers/index.js +0 -2
- package/dist/api/helpers/retryOnError.d.ts +19 -1
- package/dist/api/helpers/retryOnError.js +37 -5
- package/package.json +1 -1
- package/dist/api/helpers/ai/adapters/codex.d.ts +0 -12
- package/dist/api/helpers/ai/adapters/codex.js +0 -573
- package/dist/api/helpers/ai/adapters/google.d.ts +0 -12
- package/dist/api/helpers/ai/adapters/google.js +0 -429
- package/dist/api/helpers/ai/client.d.ts +0 -11
- package/dist/api/helpers/ai/client.js +0 -191
- package/dist/api/helpers/ai/index.d.ts +0 -3
- package/dist/api/helpers/ai/index.js +0 -18
- package/dist/api/helpers/ai/quota.d.ts +0 -55
- package/dist/api/helpers/ai/quota.js +0 -148
- package/dist/api/helpers/ai/types.d.ts +0 -118
- package/dist/api/helpers/ai/types.js +0 -2
- package/dist/api/helpers/google/apikey.d.ts +0 -5
- package/dist/api/helpers/google/apikey.js +0 -51
- package/dist/api/helpers/google/index.d.ts +0 -1
- package/dist/api/helpers/google/index.js +0 -17
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Reactive per-model rate-limit backoff.
|
|
3
|
-
*
|
|
4
|
-
* Strategy: never pace proactively and never hardcode provider limits. Every
|
|
5
|
-
* discovered model stays eligible until it returns a rate-limit response; that
|
|
6
|
-
* model is then skipped for a backoff window while rotation across the
|
|
7
|
-
* remaining models continues untouched.
|
|
8
|
-
*/
|
|
9
|
-
/** Stable message for deferred work. Must stay app-agnostic so error tracking groups it. */
|
|
10
|
-
export declare const AI_QUOTA_EXHAUSTED_MESSAGE = "AI model pool exhausted; job deferred with backoff";
|
|
11
|
-
/** Grouped error for quota-deferred queue rows. Cause chain preserves the original failure. */
|
|
12
|
-
export declare class QuotaDeferredError extends Error {
|
|
13
|
-
readonly deferredIds: string[];
|
|
14
|
-
readonly quotaCause?: unknown;
|
|
15
|
-
constructor(deferredIds: string[], options?: {
|
|
16
|
-
cause?: unknown;
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
/** True when any message in the cause chain signals model quota/capacity exhaustion. */
|
|
20
|
-
export declare const isQuotaExhaustedError: (cause: unknown) => boolean;
|
|
21
|
-
/**
|
|
22
|
-
* Honor the provider's retry delay when present (observed 9-57s). Returns undefined
|
|
23
|
-
* when the failure carries no usable delay, letting callers fall back to backoff.
|
|
24
|
-
*/
|
|
25
|
-
export declare const getQuotaRetryDelayMs: (cause: unknown) => number | undefined;
|
|
26
|
-
/**
|
|
27
|
-
* Queue backoff for a deferred row: exponential hours (1h, 2h, 4h ... capped at
|
|
28
|
-
* 24h) or the provider's own retry delay, whichever is longer, plus jitter.
|
|
29
|
-
*/
|
|
30
|
-
export declare const quotaBackoffDelayMs: (attempt: number, cause?: unknown, random?: () => number) => number;
|
|
31
|
-
/** First backoff rung after a rate-limit response; doubles per consecutive hit. */
|
|
32
|
-
export declare const MODEL_RATE_LIMIT_BASE_DELAY_MS = 60000;
|
|
33
|
-
/** Upper bound for per-model backoff. */
|
|
34
|
-
export declare const MODEL_RATE_LIMIT_MAX_DELAY_MS: number;
|
|
35
|
-
/** Small jitter so backed-off models do not resurface in lockstep. */
|
|
36
|
-
export declare const MODEL_RATE_LIMIT_JITTER_MS = 1000;
|
|
37
|
-
/**
|
|
38
|
-
* Record a rate-limit response for a model. The model is skipped until the
|
|
39
|
-
* backoff window elapses: the provider's own retry delay when present,
|
|
40
|
-
* otherwise an exponential window that doubles per consecutive hit.
|
|
41
|
-
* Returns the timestamp (ms) when the model becomes eligible again.
|
|
42
|
-
*/
|
|
43
|
-
export declare const recordModelRateLimit: (model: string, opt?: {
|
|
44
|
-
cause?: unknown;
|
|
45
|
-
nowMs?: number;
|
|
46
|
-
random?: () => number;
|
|
47
|
-
}) => number;
|
|
48
|
-
/** True while a rate-limited model is still inside its backoff window. */
|
|
49
|
-
export declare const isModelBackedOff: (model: string, nowMs?: number) => boolean;
|
|
50
|
-
/** Remaining backoff for a model in ms, or 0 when it is eligible. */
|
|
51
|
-
export declare const modelBackoffRemainingMs: (model: string, nowMs?: number) => number;
|
|
52
|
-
/** Mark a model eligible again, e.g. after it serves a request successfully. */
|
|
53
|
-
export declare const clearModelBackoff: (model: string) => void;
|
|
54
|
-
/** Test seam: clear all per-model backoff state. */
|
|
55
|
-
export declare const resetModelBackoff: () => void;
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resetModelBackoff = exports.clearModelBackoff = exports.modelBackoffRemainingMs = exports.isModelBackedOff = exports.recordModelRateLimit = exports.MODEL_RATE_LIMIT_JITTER_MS = exports.MODEL_RATE_LIMIT_MAX_DELAY_MS = exports.MODEL_RATE_LIMIT_BASE_DELAY_MS = exports.quotaBackoffDelayMs = exports.getQuotaRetryDelayMs = exports.isQuotaExhaustedError = exports.QuotaDeferredError = exports.AI_QUOTA_EXHAUSTED_MESSAGE = void 0;
|
|
4
|
-
const retryOnError_1 = require("../retryOnError");
|
|
5
|
-
/**
|
|
6
|
-
* Reactive per-model rate-limit backoff.
|
|
7
|
-
*
|
|
8
|
-
* Strategy: never pace proactively and never hardcode provider limits. Every
|
|
9
|
-
* discovered model stays eligible until it returns a rate-limit response; that
|
|
10
|
-
* model is then skipped for a backoff window while rotation across the
|
|
11
|
-
* remaining models continues untouched.
|
|
12
|
-
*/
|
|
13
|
-
/** Stable message for deferred work. Must stay app-agnostic so error tracking groups it. */
|
|
14
|
-
exports.AI_QUOTA_EXHAUSTED_MESSAGE = "AI model pool exhausted; job deferred with backoff";
|
|
15
|
-
/** Grouped error for quota-deferred queue rows. Cause chain preserves the original failure. */
|
|
16
|
-
class QuotaDeferredError extends Error {
|
|
17
|
-
deferredIds;
|
|
18
|
-
quotaCause;
|
|
19
|
-
constructor(deferredIds, options) {
|
|
20
|
-
super(`${exports.AI_QUOTA_EXHAUSTED_MESSAGE}: deferred ${deferredIds.length} job(s)`);
|
|
21
|
-
this.name = "QuotaDeferredError";
|
|
22
|
-
this.deferredIds = deferredIds;
|
|
23
|
-
if (options?.cause !== undefined) {
|
|
24
|
-
this.quotaCause = options.cause;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
exports.QuotaDeferredError = QuotaDeferredError;
|
|
29
|
-
/** True when any message in the cause chain signals model quota/capacity exhaustion. */
|
|
30
|
-
const isQuotaExhaustedError = (cause) => (0, retryOnError_1.isOverloadedApiKeyError)(cause);
|
|
31
|
-
exports.isQuotaExhaustedError = isQuotaExhaustedError;
|
|
32
|
-
const RETRY_DELAY_PATTERNS = [
|
|
33
|
-
/"retryDelay"\s*:\s*"(\d+(?:\.\d+)?)s"/i,
|
|
34
|
-
/retry in (\d+(?:\.\d+)?)\s*s/i,
|
|
35
|
-
];
|
|
36
|
-
const collectCauseText = (cause, seen = new Set()) => {
|
|
37
|
-
if (cause === null || cause === undefined || seen.has(cause)) {
|
|
38
|
-
return "";
|
|
39
|
-
}
|
|
40
|
-
if (typeof cause === "string") {
|
|
41
|
-
return cause;
|
|
42
|
-
}
|
|
43
|
-
seen.add(cause);
|
|
44
|
-
if (cause instanceof Error) {
|
|
45
|
-
const nested = cause.cause;
|
|
46
|
-
const nestedText = nested === undefined ? "" : `\n${collectCauseText(nested, seen)}`;
|
|
47
|
-
return `${cause.message}${nestedText}`;
|
|
48
|
-
}
|
|
49
|
-
if (typeof cause === "object") {
|
|
50
|
-
try {
|
|
51
|
-
return JSON.stringify(cause);
|
|
52
|
-
}
|
|
53
|
-
catch {
|
|
54
|
-
return Object.prototype.toString.call(cause);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return Object.prototype.toString.call(cause);
|
|
58
|
-
};
|
|
59
|
-
/**
|
|
60
|
-
* Honor the provider's retry delay when present (observed 9-57s). Returns undefined
|
|
61
|
-
* when the failure carries no usable delay, letting callers fall back to backoff.
|
|
62
|
-
*/
|
|
63
|
-
const getQuotaRetryDelayMs = (cause) => {
|
|
64
|
-
const combined = collectCauseText(cause);
|
|
65
|
-
for (const pattern of RETRY_DELAY_PATTERNS) {
|
|
66
|
-
const match = combined.match(pattern);
|
|
67
|
-
if (match?.[1]) {
|
|
68
|
-
const seconds = Number(match[1]);
|
|
69
|
-
if (Number.isFinite(seconds) && seconds > 0) {
|
|
70
|
-
return Math.min(Math.ceil(seconds * 1000), 15 * 60 * 1000);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return undefined;
|
|
75
|
-
};
|
|
76
|
-
exports.getQuotaRetryDelayMs = getQuotaRetryDelayMs;
|
|
77
|
-
/**
|
|
78
|
-
* Queue backoff for a deferred row: exponential hours (1h, 2h, 4h ... capped at
|
|
79
|
-
* 24h) or the provider's own retry delay, whichever is longer, plus jitter.
|
|
80
|
-
*/
|
|
81
|
-
const quotaBackoffDelayMs = (attempt, cause, random = Math.random) => {
|
|
82
|
-
// Cap the exponential component at 16h so attempt 5+ lands on the 16h rung
|
|
83
|
-
// with up to 1h jitter, still strictly under the 24h ceiling.
|
|
84
|
-
const clamped = Math.min(Math.max(Math.floor(attempt) || 1, 1), 5);
|
|
85
|
-
const exponential = Math.min(3_600_000 * 2 ** (clamped - 1), 16 * 3_600_000);
|
|
86
|
-
const serverDelay = cause === undefined ? undefined : (0, exports.getQuotaRetryDelayMs)(cause);
|
|
87
|
-
return Math.max(serverDelay ?? 0, exponential) + Math.floor(random() * 60_000);
|
|
88
|
-
};
|
|
89
|
-
exports.quotaBackoffDelayMs = quotaBackoffDelayMs;
|
|
90
|
-
/** First backoff rung after a rate-limit response; doubles per consecutive hit. */
|
|
91
|
-
exports.MODEL_RATE_LIMIT_BASE_DELAY_MS = 60_000;
|
|
92
|
-
/** Upper bound for per-model backoff. */
|
|
93
|
-
exports.MODEL_RATE_LIMIT_MAX_DELAY_MS = 15 * 60_000;
|
|
94
|
-
/** Small jitter so backed-off models do not resurface in lockstep. */
|
|
95
|
-
exports.MODEL_RATE_LIMIT_JITTER_MS = 1_000;
|
|
96
|
-
const modelBackoffUntilMs = new Map();
|
|
97
|
-
const modelBackoffHits = new Map();
|
|
98
|
-
/**
|
|
99
|
-
* Record a rate-limit response for a model. The model is skipped until the
|
|
100
|
-
* backoff window elapses: the provider's own retry delay when present,
|
|
101
|
-
* otherwise an exponential window that doubles per consecutive hit.
|
|
102
|
-
* Returns the timestamp (ms) when the model becomes eligible again.
|
|
103
|
-
*/
|
|
104
|
-
const recordModelRateLimit = (model, opt) => {
|
|
105
|
-
const now = opt?.nowMs ?? Date.now();
|
|
106
|
-
const serverDelay = opt?.cause === undefined ? undefined : (0, exports.getQuotaRetryDelayMs)(opt.cause);
|
|
107
|
-
const hits = (modelBackoffHits.get(model) ?? 0) + 1;
|
|
108
|
-
modelBackoffHits.set(model, hits);
|
|
109
|
-
const exponential = Math.min(exports.MODEL_RATE_LIMIT_BASE_DELAY_MS * 2 ** (hits - 1), exports.MODEL_RATE_LIMIT_MAX_DELAY_MS);
|
|
110
|
-
const jitter = Math.floor((opt?.random ?? Math.random)() * exports.MODEL_RATE_LIMIT_JITTER_MS);
|
|
111
|
-
const until = now + Math.max(serverDelay ?? 0, exponential) + jitter;
|
|
112
|
-
modelBackoffUntilMs.set(model, until);
|
|
113
|
-
return until;
|
|
114
|
-
};
|
|
115
|
-
exports.recordModelRateLimit = recordModelRateLimit;
|
|
116
|
-
/** True while a rate-limited model is still inside its backoff window. */
|
|
117
|
-
const isModelBackedOff = (model, nowMs) => {
|
|
118
|
-
const until = modelBackoffUntilMs.get(model);
|
|
119
|
-
if (until === undefined)
|
|
120
|
-
return false;
|
|
121
|
-
const now = nowMs ?? Date.now();
|
|
122
|
-
if (now >= until) {
|
|
123
|
-
modelBackoffUntilMs.delete(model);
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
return true;
|
|
127
|
-
};
|
|
128
|
-
exports.isModelBackedOff = isModelBackedOff;
|
|
129
|
-
/** Remaining backoff for a model in ms, or 0 when it is eligible. */
|
|
130
|
-
const modelBackoffRemainingMs = (model, nowMs) => {
|
|
131
|
-
const until = modelBackoffUntilMs.get(model);
|
|
132
|
-
if (until === undefined)
|
|
133
|
-
return 0;
|
|
134
|
-
return Math.max(0, until - (nowMs ?? Date.now()));
|
|
135
|
-
};
|
|
136
|
-
exports.modelBackoffRemainingMs = modelBackoffRemainingMs;
|
|
137
|
-
/** Mark a model eligible again, e.g. after it serves a request successfully. */
|
|
138
|
-
const clearModelBackoff = (model) => {
|
|
139
|
-
modelBackoffUntilMs.delete(model);
|
|
140
|
-
modelBackoffHits.delete(model);
|
|
141
|
-
};
|
|
142
|
-
exports.clearModelBackoff = clearModelBackoff;
|
|
143
|
-
/** Test seam: clear all per-model backoff state. */
|
|
144
|
-
const resetModelBackoff = () => {
|
|
145
|
-
modelBackoffUntilMs.clear();
|
|
146
|
-
modelBackoffHits.clear();
|
|
147
|
-
};
|
|
148
|
-
exports.resetModelBackoff = resetModelBackoff;
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
export type AIOutputType = "text" | "image" | "audio" | "video" | "file";
|
|
2
|
-
export type AIModelPreference = "fast" | "quality";
|
|
3
|
-
export type AIInputRole = "user" | "assistant" | "system" | "developer";
|
|
4
|
-
export type AITextPart = {
|
|
5
|
-
type: "text";
|
|
6
|
-
text: string;
|
|
7
|
-
};
|
|
8
|
-
export type AIMediaPart = {
|
|
9
|
-
type: Exclude<AIOutputType, "text">;
|
|
10
|
-
mimeType: string;
|
|
11
|
-
data: string;
|
|
12
|
-
name?: string;
|
|
13
|
-
};
|
|
14
|
-
export type AIPart = AITextPart | AIMediaPart;
|
|
15
|
-
export type AIInput = {
|
|
16
|
-
role: AIInputRole;
|
|
17
|
-
content: AIPart[];
|
|
18
|
-
};
|
|
19
|
-
/** A provider endpoint. Codex endpoints must be direct private LAN IPv4 URLs. */
|
|
20
|
-
export type AIEndpoint = {
|
|
21
|
-
protocol: "codex";
|
|
22
|
-
url: string;
|
|
23
|
-
token: string;
|
|
24
|
-
};
|
|
25
|
-
export type AIOutputSchema = {
|
|
26
|
-
name: string;
|
|
27
|
-
schema: Record<string, unknown>;
|
|
28
|
-
};
|
|
29
|
-
export type GenerationMetadata = {
|
|
30
|
-
model: string;
|
|
31
|
-
generatedAt: number;
|
|
32
|
-
};
|
|
33
|
-
export type GenerationUsage = {
|
|
34
|
-
inputTokens: number;
|
|
35
|
-
outputTokens: number;
|
|
36
|
-
totalTokens: number;
|
|
37
|
-
};
|
|
38
|
-
export type GenerationResult = GenerationMetadata & {
|
|
39
|
-
output: AIPart[];
|
|
40
|
-
usage?: GenerationUsage;
|
|
41
|
-
};
|
|
42
|
-
/**
|
|
43
|
-
* Provider-neutral model metadata. Providers may omit capabilities they do not
|
|
44
|
-
* publish; the model id is always preserved exactly as returned by the provider.
|
|
45
|
-
*/
|
|
46
|
-
export type AIModel = {
|
|
47
|
-
id: string;
|
|
48
|
-
inputModalities?: AIOutputType[];
|
|
49
|
-
outputModalities?: AIOutputType[];
|
|
50
|
-
supportedReasoningEfforts?: string[];
|
|
51
|
-
defaultReasoningEffort?: string;
|
|
52
|
-
prefer?: AIModelPreference[];
|
|
53
|
-
webSearch?: boolean;
|
|
54
|
-
isDefault?: boolean;
|
|
55
|
-
ready?: boolean;
|
|
56
|
-
};
|
|
57
|
-
export type AIRequest = {
|
|
58
|
-
instructions?: string;
|
|
59
|
-
input: AIInput[];
|
|
60
|
-
output?: AIOutputType[];
|
|
61
|
-
ident?: string;
|
|
62
|
-
endpoint?: AIEndpoint;
|
|
63
|
-
model?: string;
|
|
64
|
-
prefer?: "fast" | "quality";
|
|
65
|
-
reasoningEffort?: string;
|
|
66
|
-
maxOutputTokens?: number;
|
|
67
|
-
outputSchema?: AIOutputSchema;
|
|
68
|
-
webSearch?: boolean;
|
|
69
|
-
onGenerated?: (metadata: GenerationMetadata) => void;
|
|
70
|
-
signal?: AbortSignal;
|
|
71
|
-
timeoutMs?: number;
|
|
72
|
-
};
|
|
73
|
-
export type BinaryMedia = {
|
|
74
|
-
arraybuffer: ArrayBuffer;
|
|
75
|
-
type: string;
|
|
76
|
-
name?: string;
|
|
77
|
-
};
|
|
78
|
-
export type AIRequestOptions = Omit<AIRequest, "input" | "output"> & {
|
|
79
|
-
output?: AIOutputType[];
|
|
80
|
-
};
|
|
81
|
-
export type GenerateTextOptions = AIRequestOptions & {
|
|
82
|
-
prompt?: string;
|
|
83
|
-
input?: AIInput[];
|
|
84
|
-
images?: BinaryMedia[];
|
|
85
|
-
urls?: string[];
|
|
86
|
-
};
|
|
87
|
-
export type PromptDirectOptions = AIRequestOptions & {
|
|
88
|
-
prompt: string;
|
|
89
|
-
images?: BinaryMedia[];
|
|
90
|
-
};
|
|
91
|
-
export type PromptImageOptions = AIRequestOptions & {
|
|
92
|
-
prompt: string;
|
|
93
|
-
urls?: string[];
|
|
94
|
-
images?: BinaryMedia[];
|
|
95
|
-
};
|
|
96
|
-
export type AIClientDependencies = {
|
|
97
|
-
fetch?: typeof globalThis.fetch;
|
|
98
|
-
sleep?: (milliseconds: number) => Promise<void>;
|
|
99
|
-
now?: () => number;
|
|
100
|
-
createIdempotencyKey?: () => string;
|
|
101
|
-
};
|
|
102
|
-
export type AIClientDefaults = AIRequestOptions & AIClientDependencies & {
|
|
103
|
-
dependencies?: AIClientDependencies;
|
|
104
|
-
pollIntervalMs?: number;
|
|
105
|
-
maxPollIntervalMs?: number;
|
|
106
|
-
};
|
|
107
|
-
export type AIClient = {
|
|
108
|
-
generate: (request: AIRequest) => Promise<GenerationResult>;
|
|
109
|
-
generateText: {
|
|
110
|
-
(prompt: string, options?: GenerateTextOptions): Promise<string>;
|
|
111
|
-
(options: GenerateTextOptions): Promise<string>;
|
|
112
|
-
};
|
|
113
|
-
promptDirect: (options: PromptDirectOptions) => Promise<string>;
|
|
114
|
-
promptImage: (options: PromptImageOptions) => Promise<string>;
|
|
115
|
-
models: (options?: {
|
|
116
|
-
endpoint?: AIEndpoint;
|
|
117
|
-
}) => Promise<AIModel[]>;
|
|
118
|
-
};
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.blockKeyService = exports.getAvailableCombinations = void 0;
|
|
4
|
-
const array_1 = require("../../../common/helpers/array");
|
|
5
|
-
const log_1 = require("../../../common/helpers/log");
|
|
6
|
-
const node_cache_1 = require("../../../common/helpers/node-cache");
|
|
7
|
-
const truncate_1 = require("../../../common/helpers/string/truncate");
|
|
8
|
-
// Initialize NodeCache with 1 hour TTL for blocklisted key combinations
|
|
9
|
-
const blocklist = new node_cache_1.TypedNodeCache({ stdTTL: 3600 });
|
|
10
|
-
// Helper to generate blocklist key
|
|
11
|
-
const getBlocklistKey = (apiKey, service) => `${(0, truncate_1.truncate)(apiKey, 10)}_${service}`;
|
|
12
|
-
// Helper to check if a key+service combination is blocklisted
|
|
13
|
-
const isBlocklisted = (apiKey, service) => {
|
|
14
|
-
return blocklist.has(getBlocklistKey(apiKey, service));
|
|
15
|
-
};
|
|
16
|
-
// Helper to add a key+service combination to the blocklist
|
|
17
|
-
const addToBlocklist = (apiKey, service) => {
|
|
18
|
-
blocklist.set(getBlocklistKey(apiKey, service), true);
|
|
19
|
-
};
|
|
20
|
-
// Get available API keys from environment (internal use only)
|
|
21
|
-
const getApiKeys = () => {
|
|
22
|
-
return (process.env.GOOGLE_API_KEY ?? "").split(",").filter(array_1.notEmpty);
|
|
23
|
-
};
|
|
24
|
-
// Get available key+service combinations
|
|
25
|
-
const getAvailableCombinations = (service, resetIfExhausted = true) => {
|
|
26
|
-
const keys = getApiKeys();
|
|
27
|
-
(0, log_1.debug)(`got ${keys.length} GOOGLE_API_KEY keys`);
|
|
28
|
-
const combinations = [];
|
|
29
|
-
for (const key of keys) {
|
|
30
|
-
if (!isBlocklisted(key, service)) {
|
|
31
|
-
combinations.push({ service, key });
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
// If all combinations are blocklisted, clear the blocklist and try again
|
|
35
|
-
if (combinations.length === 0 && resetIfExhausted) {
|
|
36
|
-
(0, log_1.warn)(`All API key + service combinations were blocklisted for ${service}. Clearing blocklist and trying again.`);
|
|
37
|
-
blocklist.flushAll();
|
|
38
|
-
for (const key of keys) {
|
|
39
|
-
combinations.push({ service, key });
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
(0, log_1.debug)(`returning ${combinations.length} google combinations`);
|
|
43
|
-
return combinations;
|
|
44
|
-
};
|
|
45
|
-
exports.getAvailableCombinations = getAvailableCombinations;
|
|
46
|
-
// Block a key+service combination
|
|
47
|
-
const blockKeyService = (apiKey, service) => {
|
|
48
|
-
(0, log_1.warn)(`key+service blocklisted for ${service}`);
|
|
49
|
-
addToBlocklist(apiKey, service);
|
|
50
|
-
};
|
|
51
|
-
exports.blockKeyService = blockKeyService;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./apikey";
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./apikey"), exports);
|