@omnicross/core 0.1.1 → 0.1.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/ApiConverter.cjs +3 -778
- package/dist/ApiConverter.js +12 -751
- package/dist/{CompletionService-DtOF_War.d.cts → CompletionService-D3a47vdU.d.cts} +2 -1
- package/dist/{CompletionService-7fCmKAP3.d.ts → CompletionService-DdWaAxq0.d.ts} +2 -1
- package/dist/auth/GeminiCodeAssistProjectResolver.cjs +32 -60
- package/dist/auth/GeminiCodeAssistProjectResolver.js +11 -10
- package/dist/builtin-web-fetch-77JZUZGM.cjs +100 -0
- package/dist/builtin-web-fetch-IGLBX2XY.js +100 -0
- package/dist/chunk-2DCNB7DF.cjs +514 -0
- package/dist/chunk-2FMI2B6V.cjs +6196 -0
- package/dist/chunk-3OPYJG76.cjs +266 -0
- package/dist/chunk-3QOSDDNI.cjs +130 -0
- package/dist/chunk-46RLHI7D.js +0 -0
- package/dist/chunk-46ZIFWYG.cjs +277 -0
- package/dist/chunk-4DECIFU7.js +6196 -0
- package/dist/chunk-4IH4EL7M.cjs +9 -0
- package/dist/chunk-4VAVYUZS.cjs +991 -0
- package/dist/chunk-5ENKBSWO.js +311 -0
- package/dist/chunk-5ERIZW3D.js +44 -0
- package/dist/chunk-5HTVET6E.js +514 -0
- package/dist/chunk-5ZQBEOMD.js +764 -0
- package/dist/chunk-6RPZADX3.cjs +92 -0
- package/dist/chunk-7VU7V2E4.js +0 -0
- package/dist/chunk-7YN22L2H.cjs +87 -0
- package/dist/chunk-A2YMUCBT.cjs +105 -0
- package/dist/chunk-AEOZIDEB.cjs +32 -0
- package/dist/chunk-AQ5TNQB7.js +13 -0
- package/dist/chunk-AVYJ4YBN.js +58 -0
- package/dist/chunk-BO4RFWBR.js +89 -0
- package/dist/chunk-C72S6TTV.cjs +49 -0
- package/dist/chunk-C7PSERMH.js +87 -0
- package/dist/chunk-CDHS2QDC.js +179 -0
- package/dist/chunk-CWM2ZDU5.js +130 -0
- package/dist/chunk-CZHZGRU7.js +383 -0
- package/dist/chunk-DK4A7DLE.js +266 -0
- package/dist/chunk-DQ5VAYZ6.cjs +42 -0
- package/dist/chunk-DRWHTIIZ.js +13 -0
- package/dist/chunk-DWKQZ2SK.cjs +254 -0
- package/dist/chunk-EYZYXJTJ.cjs +1 -0
- package/dist/chunk-FFALUUZZ.cjs +235 -0
- package/dist/chunk-FMOBD2OQ.js +39 -0
- package/dist/chunk-FTQ7IQUC.js +991 -0
- package/dist/chunk-FZ46M34D.cjs +1 -0
- package/dist/chunk-G2UTNSGU.js +277 -0
- package/dist/chunk-GBHYAGX3.cjs +26 -0
- package/dist/chunk-GMMT7RVN.cjs +39 -0
- package/dist/chunk-H5JUT3KV.js +105 -0
- package/dist/chunk-HQP3K7PU.cjs +431 -0
- package/dist/chunk-HUZZZ3JL.js +32 -0
- package/dist/chunk-IAXWICZU.js +69 -0
- package/dist/chunk-JMJBSACD.cjs +147 -0
- package/dist/chunk-JO5NLTLY.js +46 -0
- package/dist/chunk-JWC6APFQ.js +23 -0
- package/dist/chunk-KUU2RNG6.cjs +46 -0
- package/dist/chunk-L74VDN4A.cjs +32 -0
- package/dist/chunk-MQNDWYPN.js +235 -0
- package/dist/chunk-MZNPGW5Q.js +26 -0
- package/dist/chunk-N5QFKSDO.js +56 -0
- package/dist/chunk-NYUNU75A.cjs +44 -0
- package/dist/chunk-NZYN7C3P.cjs +179 -0
- package/dist/chunk-Q27JY5RG.cjs +126 -0
- package/dist/chunk-QBZJ7P2T.cjs +13 -0
- package/dist/chunk-QWBWGODS.cjs +69 -0
- package/dist/chunk-QXD4MV2X.cjs +23 -0
- package/dist/chunk-R3HK6R4B.cjs +13 -0
- package/dist/chunk-RPII3E6Z.cjs +145 -0
- package/dist/chunk-RSJ3TWJQ.cjs +186 -0
- package/dist/chunk-S4WBV25P.js +913 -0
- package/dist/chunk-S6JGLF3G.cjs +89 -0
- package/dist/chunk-SUEGJ75D.cjs +764 -0
- package/dist/chunk-SVNDB62D.cjs +58 -0
- package/dist/chunk-SVXC36MU.cjs +383 -0
- package/dist/chunk-TKJMZBAH.js +32 -0
- package/dist/chunk-UBWEBKRC.js +42 -0
- package/dist/chunk-UNEFIWXI.cjs +32 -0
- package/dist/chunk-VQY5W4YW.cjs +311 -0
- package/dist/chunk-VVEHS2LI.js +431 -0
- package/dist/chunk-WNY4WMRF.js +32 -0
- package/dist/chunk-XEKD23J5.js +9 -0
- package/dist/chunk-XTEI64OU.js +145 -0
- package/dist/chunk-XX6NQJMA.js +92 -0
- package/dist/chunk-Y6OM7EV7.cjs +56 -0
- package/dist/chunk-Y7FO65VT.js +147 -0
- package/dist/chunk-YGXJGRFI.cjs +913 -0
- package/dist/chunk-YMFAJFQT.cjs +173 -0
- package/dist/chunk-Z7LUNECE.js +49 -0
- package/dist/chunk-Z7Y2NPHY.js +186 -0
- package/dist/chunk-ZJZAOKI7.js +254 -0
- package/dist/chunk-ZLX3KGXX.js +173 -0
- package/dist/chunk-ZY6KU6P3.js +126 -0
- package/dist/completion/ApiKeyPoolService.cjs +23 -48
- package/dist/completion/ApiKeyPoolService.d.cts +150 -2
- package/dist/completion/ApiKeyPoolService.d.ts +150 -2
- package/dist/completion/BuiltinToolExecutor.cjs +9 -324
- package/dist/completion/BuiltinToolExecutor.js +6 -290
- package/dist/completion/CompletionService.cjs +45 -3487
- package/dist/completion/CompletionService.d.cts +3 -2
- package/dist/completion/CompletionService.d.ts +3 -2
- package/dist/completion/CompletionService.js +41 -3457
- package/dist/completion/NativeSearchInjector.cjs +8 -192
- package/dist/completion/NativeSearchInjector.js +7 -162
- package/dist/completion/ProviderSearchInjector.cjs +12 -39
- package/dist/completion/native-search-types.cjs +13 -66
- package/dist/completion/native-search-types.js +7 -31
- package/dist/completion/openrouter-headers.cjs +12 -71
- package/dist/completion/openrouter-headers.d.cts +9 -12
- package/dist/completion/openrouter-headers.d.ts +9 -12
- package/dist/completion/openrouter-headers.js +7 -36
- package/dist/completion/openrouter-models.cjs +11 -67
- package/dist/completion/openrouter-models.js +5 -34
- package/dist/completion/types.cjs +1 -18
- package/dist/completion/url-builder.cjs +24 -138
- package/dist/completion/url-builder.js +12 -92
- package/dist/completion.cjs +62 -3989
- package/dist/completion.d.cts +3 -2
- package/dist/completion.d.ts +3 -2
- package/dist/completion.js +70 -3953
- package/dist/index.cjs +319 -10429
- package/dist/index.d.cts +49 -12
- package/dist/index.d.ts +49 -12
- package/dist/index.js +248 -10269
- package/dist/logger-4GvQNzhE.d.cts +22 -0
- package/dist/logger-4GvQNzhE.d.ts +22 -0
- package/dist/outbound-api/routeResolver.cjs +10 -217
- package/dist/outbound-api/routeResolver.d.cts +10 -3
- package/dist/outbound-api/routeResolver.d.ts +10 -3
- package/dist/outbound-api/routeResolver.js +9 -187
- package/dist/outbound-api/subscriptionRegistryPort.cjs +7 -37
- package/dist/outbound-api/subscriptionRegistryPort.d.cts +2 -1
- package/dist/outbound-api/subscriptionRegistryPort.d.ts +2 -1
- package/dist/outbound-api/subscriptionRegistryPort.js +4 -8
- package/dist/outbound-api/types.cjs +5 -17
- package/dist/outbound-api/types.d.cts +12 -144
- package/dist/outbound-api/types.d.ts +12 -144
- package/dist/outbound-api/types.js +6 -0
- package/dist/outbound-api.cjs +197 -5265
- package/dist/outbound-api.d.cts +787 -25
- package/dist/outbound-api.d.ts +787 -25
- package/dist/outbound-api.js +173 -5195
- package/dist/pipeline/AuthSource.cjs +1 -18
- package/dist/pipeline/AuthSource.d.cts +23 -1
- package/dist/pipeline/AuthSource.d.ts +23 -1
- package/dist/pipeline/LlmConfigProviderAuth.cjs +5 -166
- package/dist/pipeline/LlmConfigProviderAuth.d.cts +2 -1
- package/dist/pipeline/LlmConfigProviderAuth.d.ts +2 -1
- package/dist/pipeline/LlmConfigProviderAuth.js +5 -139
- package/dist/pipeline/SubscriptionAccountHealth.cjs +22 -0
- package/dist/pipeline/SubscriptionAccountHealth.d.cts +235 -0
- package/dist/pipeline/SubscriptionAccountHealth.d.ts +235 -0
- package/dist/pipeline/SubscriptionAccountHealth.js +22 -0
- package/dist/pipeline/SubscriptionAuthSource.cjs +6 -128
- package/dist/pipeline/SubscriptionAuthSource.d.cts +3 -2
- package/dist/pipeline/SubscriptionAuthSource.d.ts +3 -2
- package/dist/pipeline/SubscriptionAuthSource.js +5 -99
- package/dist/pipeline/SubscriptionAuthStrategy.cjs +1 -18
- package/dist/pipeline/SubscriptionAuthStrategy.d.cts +24 -1
- package/dist/pipeline/SubscriptionAuthStrategy.d.ts +24 -1
- package/dist/pipeline/auditSink.cjs +14 -0
- package/dist/pipeline/auditSink.d.cts +48 -0
- package/dist/pipeline/auditSink.d.ts +48 -0
- package/dist/pipeline/auditSink.js +14 -0
- package/dist/pipeline/billingEmit.cjs +14 -0
- package/dist/pipeline/billingEmit.d.cts +49 -0
- package/dist/pipeline/billingEmit.d.ts +49 -0
- package/dist/pipeline/billingEmit.js +14 -0
- package/dist/pipeline/executeProviderCall.cjs +5 -69
- package/dist/pipeline/executeProviderCall.js +3 -42
- package/dist/pipeline/resolveProviderChain.cjs +5 -46
- package/dist/pipeline/resolveProviderChain.js +3 -19
- package/dist/pipeline/resolveSubscriptionChain.cjs +5 -67
- package/dist/pipeline/resolveSubscriptionChain.js +3 -40
- package/dist/ports/gemini-code-assist-resolver.cjs +7 -37
- package/dist/ports/gemini-code-assist-resolver.js +4 -8
- package/dist/ports/pricing-store.cjs +1 -0
- package/dist/ports/pricing-store.d.cts +50 -0
- package/dist/ports/pricing-store.d.ts +50 -0
- package/dist/ports/pricing-store.js +0 -0
- package/dist/ports/provider-config-source.cjs +1 -18
- package/dist/ports/usage-event-store.cjs +1 -0
- package/dist/ports/usage-event-store.d.cts +54 -0
- package/dist/ports/usage-event-store.d.ts +54 -0
- package/dist/ports/usage-event-store.js +0 -0
- package/dist/ports/web-search-backend.cjs +1 -18
- package/dist/ports.cjs +1 -18
- package/dist/ports.d.cts +13 -2
- package/dist/ports.d.ts +13 -2
- package/dist/provider-proxy/ProviderProxy.cjs +47 -4643
- package/dist/provider-proxy/ProviderProxy.d.cts +2 -1
- package/dist/provider-proxy/ProviderProxy.d.ts +2 -1
- package/dist/provider-proxy/ProviderProxy.js +42 -4613
- package/dist/provider-proxy/identity/SubscriptionIdentityStore.cjs +15 -0
- package/dist/provider-proxy/identity/SubscriptionIdentityStore.d.cts +121 -0
- package/dist/provider-proxy/identity/SubscriptionIdentityStore.d.ts +121 -0
- package/dist/provider-proxy/identity/SubscriptionIdentityStore.js +15 -0
- package/dist/provider-proxy/identity/fingerprintHeaders.cjs +20 -0
- package/dist/provider-proxy/identity/fingerprintHeaders.d.cts +89 -0
- package/dist/provider-proxy/identity/fingerprintHeaders.d.ts +89 -0
- package/dist/provider-proxy/identity/fingerprintHeaders.js +20 -0
- package/dist/provider-proxy/ingress/providerProxyShared.cjs +42 -2941
- package/dist/provider-proxy/ingress/providerProxyShared.d.cts +13 -3
- package/dist/provider-proxy/ingress/providerProxyShared.d.ts +13 -3
- package/dist/provider-proxy/ingress/providerProxyShared.js +48 -2914
- package/dist/provider-proxy/matchText.cjs +13 -72
- package/dist/provider-proxy/matchText.d.cts +14 -1
- package/dist/provider-proxy/matchText.d.ts +14 -1
- package/dist/provider-proxy/matchText.js +8 -39
- package/dist/provider-proxy/types.cjs +1 -18
- package/dist/provider-proxy/types.d.cts +25 -1
- package/dist/provider-proxy/types.d.ts +25 -1
- package/dist/provider-proxy.cjs +42 -4655
- package/dist/provider-proxy.d.cts +2 -1
- package/dist/provider-proxy.d.ts +2 -1
- package/dist/provider-proxy.js +46 -4628
- package/dist/{routeResolver-HE-ZO0fO.d.ts → routeResolver-B1NglTfe.d.ts} +36 -10
- package/dist/{routeResolver-BrbK6ja9.d.cts → routeResolver-CbG5uBgm.d.cts} +36 -10
- package/dist/serializeError.cjs +5 -81
- package/dist/serializeError.js +3 -54
- package/dist/sse-parser.cjs +7 -455
- package/dist/sse-parser.js +4 -426
- package/dist/transformer/TransformerChainExecutor.cjs +4 -318
- package/dist/transformer/TransformerChainExecutor.js +4 -291
- package/dist/transformer/TransformerService.cjs +5 -289
- package/dist/transformer/TransformerService.js +3 -262
- package/dist/transformer/anthropicBetaInject.cjs +7 -50
- package/dist/transformer/anthropicBetaInject.js +4 -21
- package/dist/transformer/transformers/AnthropicTransformer.cjs +3 -1014
- package/dist/transformer/transformers/AnthropicTransformer.js +3 -987
- package/dist/transformer/transformers/GeminiCodeAssistTransformer.cjs +4 -1106
- package/dist/transformer/transformers/GeminiCodeAssistTransformer.js +7 -1079
- package/dist/transformer/transformers/GeminiTransformer.cjs +4 -1010
- package/dist/transformer/transformers/GeminiTransformer.js +4 -983
- package/dist/transformer/transformers/OpenAIResponseTransformer.cjs +3 -535
- package/dist/transformer/transformers/OpenAIResponseTransformer.js +3 -510
- package/dist/transformer/transformers/OpenCodeGoTransformer.cjs +5 -72
- package/dist/transformer/transformers/OpenCodeGoTransformer.js +3 -45
- package/dist/transformer/transformers/ReasoningTransformer.cjs +3 -270
- package/dist/transformer/transformers/ReasoningTransformer.js +2 -249
- package/dist/transformer/transformers.cjs +10 -3177
- package/dist/transformer/transformers.js +23 -3158
- package/dist/transformer/types.cjs +1 -18
- package/dist/transformer.cjs +13 -3726
- package/dist/transformer.js +17 -3706
- package/dist/types-6OUY_xfA.d.ts +830 -0
- package/dist/types-aBFFXoBz.d.cts +830 -0
- package/dist/usage/pricing-engine.cjs +6 -0
- package/dist/usage/pricing-engine.d.cts +83 -0
- package/dist/usage/pricing-engine.d.ts +83 -0
- package/dist/usage/pricing-engine.js +6 -0
- package/dist/usage/usage-recorder.cjs +6 -0
- package/dist/usage/usage-recorder.d.cts +91 -0
- package/dist/usage/usage-recorder.d.ts +91 -0
- package/dist/usage/usage-recorder.js +6 -0
- package/dist/usage.cjs +11 -0
- package/dist/usage.d.cts +8 -0
- package/dist/usage.d.ts +8 -0
- package/dist/usage.js +11 -0
- package/package.json +4 -2
- package/dist/ApiKeyPoolService-BmMkau07.d.cts +0 -170
- package/dist/ApiKeyPoolService-BmMkau07.d.ts +0 -170
|
@@ -1,2 +1,150 @@
|
|
|
1
|
-
import '@omnicross/contracts/llm-config';
|
|
2
|
-
|
|
1
|
+
import { ApiKeyEntry } from '@omnicross/contracts/llm-config';
|
|
2
|
+
import { L as Logger } from '../logger-4GvQNzhE.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* ApiKeyPoolService - Multi-API-key load balancing with session affinity
|
|
6
|
+
*
|
|
7
|
+
* Manages a pool of API keys per provider, selecting keys via weighted
|
|
8
|
+
* round-robin and maintaining session-level key affinity to preserve
|
|
9
|
+
* prompt cache across requests within the same session.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** Live health snapshot for a single key currently in cooldown. */
|
|
13
|
+
interface KeyHealthEntry {
|
|
14
|
+
/** Epoch-ms when the cooldown expires */
|
|
15
|
+
until: number;
|
|
16
|
+
/** Number of consecutive errors */
|
|
17
|
+
errors: number;
|
|
18
|
+
/** HTTP status that triggered the most recent cooldown */
|
|
19
|
+
lastStatus: number | null;
|
|
20
|
+
}
|
|
21
|
+
/** Provider-scoped map of keyId → live cooldown health (cooling keys only). */
|
|
22
|
+
type KeyHealthMap = Record<string, KeyHealthEntry>;
|
|
23
|
+
/** Function type for loading API keys from the database */
|
|
24
|
+
type ApiKeysLoader = (providerId: string) => Promise<ApiKeyEntry[]>;
|
|
25
|
+
/** Function type for disabling a key in the database (on auth failure) */
|
|
26
|
+
type ApiKeyDisabler = (keyId: string) => Promise<boolean>;
|
|
27
|
+
/**
|
|
28
|
+
* Function type for auto-disabling a key in the database on auth failure,
|
|
29
|
+
* persisting the offending status + timestamp so the client UI can surface
|
|
30
|
+
* a per-key health indicator. Preferred over {@link ApiKeyDisabler} when set.
|
|
31
|
+
*/
|
|
32
|
+
type ApiKeyAutoDisabler = (keyId: string, status: number, at: number) => Promise<void>;
|
|
33
|
+
/** Function type for resolving environment variable references in API keys */
|
|
34
|
+
type ApiKeyResolver = (rawKey: string) => string;
|
|
35
|
+
declare class ApiKeyPoolService {
|
|
36
|
+
private loadKeys;
|
|
37
|
+
private resolveKey;
|
|
38
|
+
private logger;
|
|
39
|
+
private disableKey?;
|
|
40
|
+
private markAutoDisabled?;
|
|
41
|
+
/** Session 鈫?key binding (session affinity) */
|
|
42
|
+
private sessionBindings;
|
|
43
|
+
/** Provider 鈫?round-robin index */
|
|
44
|
+
private rrIndex;
|
|
45
|
+
/** Provider 鈫?cached key list */
|
|
46
|
+
private keyCache;
|
|
47
|
+
/** Key ID 鈫?cooldown state */
|
|
48
|
+
private cooldowns;
|
|
49
|
+
/** Cleanup interval handle */
|
|
50
|
+
private cleanupTimer;
|
|
51
|
+
private readonly DEFAULT_COOLDOWN_MS;
|
|
52
|
+
private readonly MAX_COOLDOWN_MS;
|
|
53
|
+
private readonly COOLDOWN_MULTIPLIER;
|
|
54
|
+
constructor(loadKeys: ApiKeysLoader, resolveKey: ApiKeyResolver, logger: Logger, disableKey?: ApiKeyDisabler | undefined, markAutoDisabled?: ApiKeyAutoDisabler | undefined);
|
|
55
|
+
/**
|
|
56
|
+
* Get the API key for a session. Implements session affinity.
|
|
57
|
+
*
|
|
58
|
+
* First call for a session binds it to a key via weighted round-robin.
|
|
59
|
+
* Subsequent calls return the same key (preserves prompt cache).
|
|
60
|
+
*
|
|
61
|
+
* @returns Resolved API key string, or empty string if no keys available
|
|
62
|
+
*/
|
|
63
|
+
/**
|
|
64
|
+
* Read which key id is currently bound to the given session, if any.
|
|
65
|
+
* Returns null when the session has not yet been bound (first call hasn't
|
|
66
|
+
* happened) or when the binding is for a different provider.
|
|
67
|
+
*
|
|
68
|
+
* Used by the usage-recorder attribution path: after `getKeyForSession`
|
|
69
|
+
* completes the caller looks up the keyId so the recorded usage
|
|
70
|
+
* row can attribute spend to a specific pool key.
|
|
71
|
+
*/
|
|
72
|
+
getKeyIdForSession(providerId: string, sessionId: string): string | null;
|
|
73
|
+
getKeyForSession(providerId: string, sessionId: string): Promise<string>;
|
|
74
|
+
/**
|
|
75
|
+
* Get a key without session affinity (for one-shot calls like testConnection).
|
|
76
|
+
*
|
|
77
|
+
* @returns Resolved API key string, or empty string if no keys available
|
|
78
|
+
*/
|
|
79
|
+
getKey(providerId: string): Promise<string>;
|
|
80
|
+
/**
|
|
81
|
+
* Report an error for the current session's key.
|
|
82
|
+
*
|
|
83
|
+
* - 429/529 (rate limit / overload): puts key in cooldown with exponential backoff
|
|
84
|
+
* - 401/403 (auth failure): permanently disables the key in the database
|
|
85
|
+
*
|
|
86
|
+
* In both cases, re-binds the session to a different key if available.
|
|
87
|
+
*
|
|
88
|
+
* @param statusCode HTTP status code
|
|
89
|
+
* @returns New resolved API key if re-binding succeeded, null if no keys available
|
|
90
|
+
*/
|
|
91
|
+
reportError(providerId: string, sessionId: string, statusCode: number): Promise<string | null>;
|
|
92
|
+
/**
|
|
93
|
+
* Report a successful request — resets cooldown counter for the session's key.
|
|
94
|
+
*/
|
|
95
|
+
reportSuccess(sessionId: string): void;
|
|
96
|
+
/**
|
|
97
|
+
* Release session binding (call when session ends or is deleted).
|
|
98
|
+
*/
|
|
99
|
+
releaseSession(sessionId: string): void;
|
|
100
|
+
/**
|
|
101
|
+
* Invalidate the key cache. Call after CRUD operations on API keys.
|
|
102
|
+
*/
|
|
103
|
+
invalidateCache(providerId?: string): void;
|
|
104
|
+
/**
|
|
105
|
+
* Check if a provider has any keys in the pool.
|
|
106
|
+
*/
|
|
107
|
+
hasKeys(providerId: string): Promise<boolean>;
|
|
108
|
+
/**
|
|
109
|
+
* Get the live (in-memory) rate-limit cooldown health for a provider's keys.
|
|
110
|
+
*
|
|
111
|
+
* Returns ONLY keys that are currently cooling down (cooldown `until` is in
|
|
112
|
+
* the future). A key absent from the returned map is not cooling. This is a
|
|
113
|
+
* pure read of the in-memory cooldown map — auth-failure auto-disable state
|
|
114
|
+
* is persisted on the key row itself (getApiKeys) and is NOT included here.
|
|
115
|
+
*/
|
|
116
|
+
getKeyHealth(providerId: string): Promise<KeyHealthMap>;
|
|
117
|
+
/**
|
|
118
|
+
* Dispose of the service (stop cleanup timer).
|
|
119
|
+
*/
|
|
120
|
+
dispose(): void;
|
|
121
|
+
/**
|
|
122
|
+
* Handle auth failure (401/403): disable the key in DB permanently.
|
|
123
|
+
*/
|
|
124
|
+
private handleAuthFailure;
|
|
125
|
+
/**
|
|
126
|
+
* Apply cooldown with exponential backoff for rate-limit errors (429/529).
|
|
127
|
+
*/
|
|
128
|
+
private applyCooldown;
|
|
129
|
+
/**
|
|
130
|
+
* Get all keys for a provider (with caching).
|
|
131
|
+
*/
|
|
132
|
+
private getAllKeys;
|
|
133
|
+
/**
|
|
134
|
+
* Get available keys: enabled AND not in cooldown.
|
|
135
|
+
*/
|
|
136
|
+
private getAvailableKeys;
|
|
137
|
+
/**
|
|
138
|
+
* Weighted round-robin selection.
|
|
139
|
+
*
|
|
140
|
+
* Each key's weight determines how many "slots" it occupies in the rotation.
|
|
141
|
+
* The round-robin index advances by 1 on each call per provider.
|
|
142
|
+
*/
|
|
143
|
+
private selectWeightedRoundRobin;
|
|
144
|
+
/**
|
|
145
|
+
* Clean up expired cooldowns.
|
|
146
|
+
*/
|
|
147
|
+
private cleanupExpiredCooldowns;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export { type ApiKeyAutoDisabler, type ApiKeyDisabler, ApiKeyPoolService, type ApiKeyResolver, type ApiKeysLoader, type KeyHealthEntry, type KeyHealthMap };
|
|
@@ -1,327 +1,12 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __esm = (fn, res) => function __init() {
|
|
9
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
-
};
|
|
11
|
-
var __export = (target, all) => {
|
|
12
|
-
for (var name in all)
|
|
13
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
|
-
};
|
|
15
|
-
var __copyProps = (to, from, except, desc) => {
|
|
16
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
17
|
-
for (let key of __getOwnPropNames(from))
|
|
18
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
19
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
20
|
-
}
|
|
21
|
-
return to;
|
|
22
|
-
};
|
|
23
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
-
mod
|
|
30
|
-
));
|
|
31
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
32
2
|
|
|
33
|
-
// src/completion/builtin-web-fetch.ts
|
|
34
|
-
var builtin_web_fetch_exports = {};
|
|
35
|
-
__export(builtin_web_fetch_exports, {
|
|
36
|
-
fetchAndExtractUrl: () => fetchAndExtractUrl
|
|
37
|
-
});
|
|
38
|
-
async function fetchAndExtractUrl(url, maxChars) {
|
|
39
|
-
const controller = new AbortController();
|
|
40
|
-
const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
41
|
-
try {
|
|
42
|
-
const res = await fetchWithRedirectLimit(url, controller.signal);
|
|
43
|
-
clearTimeout(timer);
|
|
44
|
-
const contentType = res.headers.get("content-type") ?? "";
|
|
45
|
-
const rawText = await readBodyWithLimit(res);
|
|
46
|
-
let text;
|
|
47
|
-
if (contentType.includes("json")) {
|
|
48
|
-
try {
|
|
49
|
-
text = JSON.stringify(JSON.parse(rawText), null, 2);
|
|
50
|
-
} catch {
|
|
51
|
-
text = rawText;
|
|
52
|
-
}
|
|
53
|
-
} else if (contentType.includes("html")) {
|
|
54
|
-
text = extractHtml(rawText, res.url || url);
|
|
55
|
-
} else {
|
|
56
|
-
text = rawText;
|
|
57
|
-
}
|
|
58
|
-
return text.length > maxChars ? text.slice(0, maxChars) + "\n\n[Content truncated]" : text;
|
|
59
|
-
} finally {
|
|
60
|
-
clearTimeout(timer);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
function extractHtml(html, url) {
|
|
64
|
-
const dom = new import_jsdom.JSDOM(html, { url });
|
|
65
|
-
const doc = dom.window.document;
|
|
66
|
-
for (const sel of ["script", "style", "noscript", "nav", "footer", "aside", "iframe"]) {
|
|
67
|
-
doc.querySelectorAll(sel).forEach((el) => el.remove());
|
|
68
|
-
}
|
|
69
|
-
const reader = new import_readability.Readability(doc);
|
|
70
|
-
const article = reader.parse();
|
|
71
|
-
if (article?.content) {
|
|
72
|
-
return turndown.turndown(article.content).replace(/\n{3,}/g, "\n\n");
|
|
73
|
-
}
|
|
74
|
-
const body = doc.body?.textContent || "";
|
|
75
|
-
return body.replace(/\s+/g, " ").trim();
|
|
76
|
-
}
|
|
77
|
-
async function fetchWithRedirectLimit(url, signal) {
|
|
78
|
-
let currentUrl = url;
|
|
79
|
-
for (let i = 0; i < MAX_REDIRECTS; i++) {
|
|
80
|
-
const res = await fetch(currentUrl, { signal, redirect: "manual", headers: FETCH_HEADERS });
|
|
81
|
-
if (res.status >= 300 && res.status < 400) {
|
|
82
|
-
const location = res.headers.get("location");
|
|
83
|
-
if (!location) return res;
|
|
84
|
-
currentUrl = new URL(location, currentUrl).href;
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
Object.defineProperty(res, "url", { value: currentUrl, writable: false });
|
|
88
|
-
return res;
|
|
89
|
-
}
|
|
90
|
-
throw new Error(`Too many redirects (>${MAX_REDIRECTS})`);
|
|
91
|
-
}
|
|
92
|
-
async function readBodyWithLimit(res) {
|
|
93
|
-
const reader = res.body?.getReader();
|
|
94
|
-
if (!reader) return "";
|
|
95
|
-
const chunks = [];
|
|
96
|
-
let totalBytes = 0;
|
|
97
|
-
while (true) {
|
|
98
|
-
const { done, value } = await reader.read();
|
|
99
|
-
if (done) break;
|
|
100
|
-
totalBytes += value.byteLength;
|
|
101
|
-
if (totalBytes > MAX_RESPONSE_BYTES) {
|
|
102
|
-
reader.cancel();
|
|
103
|
-
break;
|
|
104
|
-
}
|
|
105
|
-
chunks.push(value);
|
|
106
|
-
}
|
|
107
|
-
const combined = new Uint8Array(totalBytes > MAX_RESPONSE_BYTES ? MAX_RESPONSE_BYTES : totalBytes);
|
|
108
|
-
let offset = 0;
|
|
109
|
-
for (const chunk of chunks) {
|
|
110
|
-
const len = Math.min(chunk.byteLength, combined.byteLength - offset);
|
|
111
|
-
combined.set(chunk.subarray(0, len), offset);
|
|
112
|
-
offset += len;
|
|
113
|
-
if (offset >= combined.byteLength) break;
|
|
114
|
-
}
|
|
115
|
-
return new TextDecoder("utf-8", { fatal: false }).decode(combined);
|
|
116
|
-
}
|
|
117
|
-
var import_readability, import_jsdom, import_turndown, FETCH_TIMEOUT_MS, MAX_RESPONSE_BYTES, MAX_REDIRECTS, CHROME_UA, FETCH_HEADERS, turndown;
|
|
118
|
-
var init_builtin_web_fetch = __esm({
|
|
119
|
-
"src/completion/builtin-web-fetch.ts"() {
|
|
120
|
-
"use strict";
|
|
121
|
-
import_readability = require("@mozilla/readability");
|
|
122
|
-
import_jsdom = require("jsdom");
|
|
123
|
-
import_turndown = __toESM(require("turndown"), 1);
|
|
124
|
-
FETCH_TIMEOUT_MS = 15e3;
|
|
125
|
-
MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
|
|
126
|
-
MAX_REDIRECTS = 5;
|
|
127
|
-
CHROME_UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
|
|
128
|
-
FETCH_HEADERS = {
|
|
129
|
-
"User-Agent": CHROME_UA,
|
|
130
|
-
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
131
|
-
"Accept-Language": "en-US,en;q=0.9"
|
|
132
|
-
};
|
|
133
|
-
turndown = new import_turndown.default({
|
|
134
|
-
headingStyle: "atx",
|
|
135
|
-
codeBlockStyle: "fenced",
|
|
136
|
-
bulletListMarker: "-"
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
3
|
|
|
141
|
-
// src/completion/BuiltinToolExecutor.ts
|
|
142
|
-
var BuiltinToolExecutor_exports = {};
|
|
143
|
-
__export(BuiltinToolExecutor_exports, {
|
|
144
|
-
BuiltinToolExecutor: () => BuiltinToolExecutor,
|
|
145
|
-
convertBuiltinToolsToAnthropic: () => convertBuiltinToolsToAnthropic,
|
|
146
|
-
convertBuiltinToolsToOpenAI: () => convertBuiltinToolsToOpenAI,
|
|
147
|
-
getBuiltinSearchTools: () => getBuiltinSearchTools
|
|
148
|
-
});
|
|
149
|
-
module.exports = __toCommonJS(BuiltinToolExecutor_exports);
|
|
150
|
-
var DEFAULT_SEARCH_COUNT = 5;
|
|
151
|
-
var DEFAULT_FETCH_MAX_CHARS = 2e4;
|
|
152
|
-
var FALLBACK_ORDER = [
|
|
153
|
-
"tavily",
|
|
154
|
-
"jina",
|
|
155
|
-
"searxng",
|
|
156
|
-
"zhipu",
|
|
157
|
-
"z.ai",
|
|
158
|
-
"bocha",
|
|
159
|
-
"grok",
|
|
160
|
-
"local-google",
|
|
161
|
-
"local-bing",
|
|
162
|
-
"local-baidu",
|
|
163
|
-
"local-duckduckgo"
|
|
164
|
-
];
|
|
165
|
-
var IMPLICIT_LOCAL_FALLBACK = "local-google";
|
|
166
|
-
var WEB_SEARCH_TOOL = {
|
|
167
|
-
id: "builtin__web_search",
|
|
168
|
-
serverId: "builtin",
|
|
169
|
-
serverName: "builtin",
|
|
170
|
-
name: "web_search",
|
|
171
|
-
description: "Search the web for current information. Returns a list of results with title, URL, and snippet. Use web_fetch afterwards to get full page content if snippets are insufficient.",
|
|
172
|
-
inputSchema: {
|
|
173
|
-
type: "object",
|
|
174
|
-
properties: {
|
|
175
|
-
query: { type: "string", description: "The search query." },
|
|
176
|
-
count: { type: "integer", description: "Maximum number of results (1-10).", default: DEFAULT_SEARCH_COUNT }
|
|
177
|
-
},
|
|
178
|
-
required: ["query"]
|
|
179
|
-
},
|
|
180
|
-
type: "mcp",
|
|
181
|
-
isBuiltIn: true
|
|
182
|
-
};
|
|
183
|
-
var WEB_FETCH_TOOL = {
|
|
184
|
-
id: "builtin__web_fetch",
|
|
185
|
-
serverId: "builtin",
|
|
186
|
-
serverName: "builtin",
|
|
187
|
-
name: "web_fetch",
|
|
188
|
-
description: "Fetch and extract the main content of a web page as clean Markdown. Use this to read the full content of a URL found via web_search.",
|
|
189
|
-
inputSchema: {
|
|
190
|
-
type: "object",
|
|
191
|
-
properties: {
|
|
192
|
-
url: { type: "string", description: "The URL to fetch (http or https)." },
|
|
193
|
-
maxChars: { type: "integer", description: "Maximum characters to return.", default: DEFAULT_FETCH_MAX_CHARS }
|
|
194
|
-
},
|
|
195
|
-
required: ["url"]
|
|
196
|
-
},
|
|
197
|
-
type: "mcp",
|
|
198
|
-
isBuiltIn: true
|
|
199
|
-
};
|
|
200
|
-
var BuiltinToolExecutor = class {
|
|
201
|
-
constructor(webSearch) {
|
|
202
|
-
this.webSearch = webSearch;
|
|
203
|
-
}
|
|
204
|
-
webSearch;
|
|
205
|
-
async execute(toolName, args) {
|
|
206
|
-
switch (toolName) {
|
|
207
|
-
case "web_search":
|
|
208
|
-
return this.executeWebSearch(args);
|
|
209
|
-
case "web_fetch":
|
|
210
|
-
return this.executeWebFetch(args);
|
|
211
|
-
default:
|
|
212
|
-
return { isError: true, content: [{ type: "text", text: `Unknown built-in tool: ${toolName}` }] };
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
// -----------------------------------------------------------------------
|
|
216
|
-
// web_search
|
|
217
|
-
// -----------------------------------------------------------------------
|
|
218
|
-
async executeWebSearch(args) {
|
|
219
|
-
const query = String(args.query ?? "").trim();
|
|
220
|
-
if (!query) {
|
|
221
|
-
return { isError: true, content: [{ type: "text", text: "Error: query parameter is required." }] };
|
|
222
|
-
}
|
|
223
|
-
const count = Math.min(Math.max(Number(args.count ?? DEFAULT_SEARCH_COUNT), 1), 10);
|
|
224
|
-
const chain = this.resolveProviderChain();
|
|
225
|
-
let lastError = "";
|
|
226
|
-
for (const providerId of chain) {
|
|
227
|
-
try {
|
|
228
|
-
const result = await this.webSearch.search(query, providerId, { maxResults: count });
|
|
229
|
-
if (!result.success) {
|
|
230
|
-
lastError = result.error || "Unknown error";
|
|
231
|
-
console.log(`[BuiltinToolExecutor] Search provider ${providerId} failed: ${lastError}, trying next...`);
|
|
232
|
-
continue;
|
|
233
|
-
}
|
|
234
|
-
const items = result.results.slice(0, count);
|
|
235
|
-
if (items.length === 0) {
|
|
236
|
-
console.log(`[BuiltinToolExecutor] Search provider ${providerId} returned 0 results, trying next...`);
|
|
237
|
-
continue;
|
|
238
|
-
}
|
|
239
|
-
const text = items.map((r, i) => `${i + 1}. ${r.title}
|
|
240
|
-
URL: ${r.url}
|
|
241
|
-
${r.content || ""}`).join("\n\n");
|
|
242
|
-
return { isError: false, content: [{ type: "text", text }] };
|
|
243
|
-
} catch (err) {
|
|
244
|
-
lastError = err instanceof Error ? err.message : String(err);
|
|
245
|
-
console.log(`[BuiltinToolExecutor] Search provider ${providerId} threw: ${lastError}, trying next...`);
|
|
246
|
-
continue;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
return {
|
|
250
|
-
isError: false,
|
|
251
|
-
content: [{ type: "text", text: lastError ? `Search failed after trying ${chain.length} provider(s). Last error: ${lastError}` : `No results found for "${query}" after trying ${chain.length} provider(s). Try rephrasing your search.` }]
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
resolveProviderChain() {
|
|
255
|
-
const chain = [];
|
|
256
|
-
for (const id of FALLBACK_ORDER) {
|
|
257
|
-
if (this.webSearch.isProviderEnabled(id)) {
|
|
258
|
-
chain.push(id);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
if (!chain.includes(IMPLICIT_LOCAL_FALLBACK)) {
|
|
262
|
-
chain.push(IMPLICIT_LOCAL_FALLBACK);
|
|
263
|
-
}
|
|
264
|
-
return chain;
|
|
265
|
-
}
|
|
266
|
-
// -----------------------------------------------------------------------
|
|
267
|
-
// web_fetch
|
|
268
|
-
// -----------------------------------------------------------------------
|
|
269
|
-
async executeWebFetch(args) {
|
|
270
|
-
const url = String(args.url ?? "").trim();
|
|
271
|
-
if (!url) {
|
|
272
|
-
return { isError: true, content: [{ type: "text", text: "Error: url parameter is required." }] };
|
|
273
|
-
}
|
|
274
|
-
try {
|
|
275
|
-
const parsed = new URL(url);
|
|
276
|
-
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
277
|
-
return { isError: true, content: [{ type: "text", text: "Error: only http and https URLs are supported." }] };
|
|
278
|
-
}
|
|
279
|
-
} catch {
|
|
280
|
-
return { isError: true, content: [{ type: "text", text: `Error: invalid URL "${url}".` }] };
|
|
281
|
-
}
|
|
282
|
-
const maxChars = Number(args.maxChars ?? DEFAULT_FETCH_MAX_CHARS);
|
|
283
|
-
try {
|
|
284
|
-
const jinaResult = await this.webSearch.readUrl(url, { timeout: 15e3 });
|
|
285
|
-
if (jinaResult.success && jinaResult.content) {
|
|
286
|
-
const content = jinaResult.content.length > maxChars ? jinaResult.content.slice(0, maxChars) + "\n\n[Content truncated]" : jinaResult.content;
|
|
287
|
-
const header = jinaResult.title ? `# ${jinaResult.title}
|
|
288
4
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
return { isError: true, content: [{ type: "text", text: `Fetch error: ${message}` }] };
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
};
|
|
301
|
-
function getBuiltinSearchTools() {
|
|
302
|
-
return [WEB_SEARCH_TOOL, WEB_FETCH_TOOL];
|
|
303
|
-
}
|
|
304
|
-
function convertBuiltinToolsToOpenAI(tools) {
|
|
305
|
-
return tools.map((t) => ({
|
|
306
|
-
type: "function",
|
|
307
|
-
function: {
|
|
308
|
-
name: t.id,
|
|
309
|
-
description: t.description || t.name,
|
|
310
|
-
parameters: t.inputSchema
|
|
311
|
-
}
|
|
312
|
-
}));
|
|
313
|
-
}
|
|
314
|
-
function convertBuiltinToolsToAnthropic(tools) {
|
|
315
|
-
return tools.map((t) => ({
|
|
316
|
-
name: t.id,
|
|
317
|
-
description: t.description || t.name,
|
|
318
|
-
input_schema: t.inputSchema
|
|
319
|
-
}));
|
|
320
|
-
}
|
|
321
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
322
|
-
0 && (module.exports = {
|
|
323
|
-
BuiltinToolExecutor,
|
|
324
|
-
convertBuiltinToolsToAnthropic,
|
|
325
|
-
convertBuiltinToolsToOpenAI,
|
|
326
|
-
getBuiltinSearchTools
|
|
327
|
-
});
|
|
5
|
+
|
|
6
|
+
var _chunkNZYN7C3Pcjs = require('../chunk-NZYN7C3P.cjs');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
exports.BuiltinToolExecutor = _chunkNZYN7C3Pcjs.BuiltinToolExecutor; exports.convertBuiltinToolsToAnthropic = _chunkNZYN7C3Pcjs.convertBuiltinToolsToAnthropic; exports.convertBuiltinToolsToOpenAI = _chunkNZYN7C3Pcjs.convertBuiltinToolsToOpenAI; exports.getBuiltinSearchTools = _chunkNZYN7C3Pcjs.getBuiltinSearchTools;
|