@omnicross/core 0.1.0 → 0.1.2

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.
Files changed (272) hide show
  1. package/dist/ApiConverter.cjs +24 -0
  2. package/dist/ApiConverter.d.cts +82 -0
  3. package/dist/ApiConverter.d.ts +82 -0
  4. package/dist/ApiConverter.js +24 -0
  5. package/dist/BuiltinToolExecutor-BluWyeob.d.ts +81 -0
  6. package/dist/BuiltinToolExecutor-CS2WpXhM.d.cts +81 -0
  7. package/dist/CompletionService-D3a47vdU.d.cts +213 -0
  8. package/dist/CompletionService-DdWaAxq0.d.ts +213 -0
  9. package/dist/{ProviderProxy-f_8ziIhW.d.cts → ProviderProxy-C-xqrkKi.d.ts} +7 -2
  10. package/dist/{ProviderProxy-vjt8sQQk.d.ts → ProviderProxy-CnMQYN59.d.cts} +7 -2
  11. package/dist/auth/GeminiCodeAssistProjectResolver.cjs +27 -60
  12. package/dist/auth/GeminiCodeAssistProjectResolver.js +5 -9
  13. package/dist/builtin-web-fetch-77JZUZGM.cjs +100 -0
  14. package/dist/builtin-web-fetch-IGLBX2XY.js +100 -0
  15. package/dist/chunk-2DCNB7DF.cjs +514 -0
  16. package/dist/chunk-2FEVTJWG.js +4400 -0
  17. package/dist/chunk-3MEACFK3.js +193 -0
  18. package/dist/chunk-3OPYJG76.cjs +266 -0
  19. package/dist/chunk-46RLHI7D.js +0 -0
  20. package/dist/chunk-46ZIFWYG.cjs +277 -0
  21. package/dist/chunk-4NBS6KPV.cjs +43 -0
  22. package/dist/chunk-4VAVYUZS.cjs +991 -0
  23. package/dist/chunk-5ERIZW3D.js +44 -0
  24. package/dist/chunk-5HTVET6E.js +514 -0
  25. package/dist/chunk-5ZQBEOMD.js +764 -0
  26. package/dist/chunk-6VIXXLMX.cjs +14 -0
  27. package/dist/chunk-745DV5FL.js +147 -0
  28. package/dist/chunk-74TMJA7Z.js +53 -0
  29. package/dist/chunk-7VU7V2E4.js +0 -0
  30. package/dist/chunk-7YN22L2H.cjs +87 -0
  31. package/dist/chunk-A2YMUCBT.cjs +105 -0
  32. package/dist/chunk-AQ5TNQB7.js +13 -0
  33. package/dist/chunk-AVYJ4YBN.js +58 -0
  34. package/dist/chunk-C72S6TTV.cjs +49 -0
  35. package/dist/chunk-C7PSERMH.js +87 -0
  36. package/dist/chunk-CDHS2QDC.js +179 -0
  37. package/dist/chunk-DK4A7DLE.js +266 -0
  38. package/dist/chunk-DRWHTIIZ.js +13 -0
  39. package/dist/chunk-DWKQZ2SK.cjs +254 -0
  40. package/dist/chunk-E3WHL7CO.js +14 -0
  41. package/dist/chunk-EYZYXJTJ.cjs +1 -0
  42. package/dist/chunk-FMOBD2OQ.js +39 -0
  43. package/dist/chunk-FTQ7IQUC.js +991 -0
  44. package/dist/chunk-FZ46M34D.cjs +1 -0
  45. package/dist/chunk-G2FUJNA2.cjs +193 -0
  46. package/dist/chunk-G2UTNSGU.js +277 -0
  47. package/dist/chunk-GBHYAGX3.cjs +26 -0
  48. package/dist/chunk-GMMT7RVN.cjs +39 -0
  49. package/dist/chunk-H5JUT3KV.js +105 -0
  50. package/dist/chunk-HQP3K7PU.cjs +431 -0
  51. package/dist/chunk-JO5NLTLY.js +46 -0
  52. package/dist/chunk-JWC6APFQ.js +23 -0
  53. package/dist/chunk-KUU2RNG6.cjs +46 -0
  54. package/dist/chunk-LKZJEL6E.cjs +124 -0
  55. package/dist/chunk-MNYKI4CI.js +94 -0
  56. package/dist/chunk-MZNPGW5Q.js +26 -0
  57. package/dist/chunk-N3V2J5ZO.cjs +53 -0
  58. package/dist/chunk-NYUNU75A.cjs +44 -0
  59. package/dist/chunk-NZYN7C3P.cjs +179 -0
  60. package/dist/chunk-O466Y272.js +235 -0
  61. package/dist/chunk-PXUJF5HS.js +124 -0
  62. package/dist/chunk-QBZJ7P2T.cjs +13 -0
  63. package/dist/chunk-QOCNX236.js +46 -0
  64. package/dist/chunk-QXD4MV2X.cjs +23 -0
  65. package/dist/chunk-R3HK6R4B.cjs +13 -0
  66. package/dist/chunk-RSJ3TWJQ.cjs +186 -0
  67. package/dist/chunk-S4WBV25P.js +913 -0
  68. package/dist/chunk-SN3YWBX7.cjs +4400 -0
  69. package/dist/chunk-SPVWWUHX.cjs +46 -0
  70. package/dist/chunk-SUEGJ75D.cjs +764 -0
  71. package/dist/chunk-SVNDB62D.cjs +58 -0
  72. package/dist/chunk-UYPEN5XE.cjs +235 -0
  73. package/dist/chunk-V5KPWNYX.cjs +147 -0
  74. package/dist/chunk-VVEHS2LI.js +431 -0
  75. package/dist/chunk-XBSYYZIY.cjs +94 -0
  76. package/dist/chunk-YGXJGRFI.cjs +913 -0
  77. package/dist/chunk-YMFAJFQT.cjs +173 -0
  78. package/dist/chunk-Z7LUNECE.js +49 -0
  79. package/dist/chunk-Z7Y2NPHY.js +186 -0
  80. package/dist/chunk-ZJZAOKI7.js +254 -0
  81. package/dist/chunk-ZLX3KGXX.js +173 -0
  82. package/dist/chunk-ZSVQT3PW.js +43 -0
  83. package/dist/completion/ApiKeyPoolService.cjs +23 -48
  84. package/dist/completion/ApiKeyPoolService.d.cts +150 -2
  85. package/dist/completion/ApiKeyPoolService.d.ts +150 -2
  86. package/dist/completion/BuiltinToolExecutor.cjs +12 -0
  87. package/dist/completion/BuiltinToolExecutor.d.cts +4 -0
  88. package/dist/completion/BuiltinToolExecutor.d.ts +4 -0
  89. package/dist/completion/BuiltinToolExecutor.js +12 -0
  90. package/dist/completion/CompletionService.cjs +38 -0
  91. package/dist/completion/CompletionService.d.cts +22 -0
  92. package/dist/completion/CompletionService.d.ts +22 -0
  93. package/dist/completion/CompletionService.js +38 -0
  94. package/dist/completion/NativeSearchInjector.cjs +12 -0
  95. package/dist/completion/NativeSearchInjector.d.cts +42 -0
  96. package/dist/completion/NativeSearchInjector.d.ts +42 -0
  97. package/dist/completion/NativeSearchInjector.js +12 -0
  98. package/dist/completion/ProviderSearchInjector.cjs +60 -0
  99. package/dist/completion/ProviderSearchInjector.d.cts +47 -0
  100. package/dist/completion/ProviderSearchInjector.d.ts +47 -0
  101. package/dist/completion/ProviderSearchInjector.js +60 -0
  102. package/dist/completion/native-search-types.cjs +14 -0
  103. package/dist/completion/native-search-types.d.cts +3 -0
  104. package/dist/completion/native-search-types.d.ts +3 -0
  105. package/dist/completion/native-search-types.js +14 -0
  106. package/dist/completion/openrouter-headers.cjs +16 -0
  107. package/dist/completion/openrouter-headers.d.cts +44 -0
  108. package/dist/completion/openrouter-headers.d.ts +44 -0
  109. package/dist/completion/openrouter-headers.js +16 -0
  110. package/dist/completion/openrouter-models.cjs +29 -0
  111. package/dist/completion/openrouter-models.d.cts +27 -0
  112. package/dist/completion/openrouter-models.d.ts +27 -0
  113. package/dist/completion/openrouter-models.js +29 -0
  114. package/dist/completion/types.cjs +1 -0
  115. package/dist/completion/types.d.cts +3 -0
  116. package/dist/completion/types.d.ts +3 -0
  117. package/dist/completion/types.js +0 -0
  118. package/dist/completion/url-builder.cjs +24 -0
  119. package/dist/completion/url-builder.d.cts +87 -0
  120. package/dist/completion/url-builder.d.ts +87 -0
  121. package/dist/completion/url-builder.js +24 -0
  122. package/dist/completion.cjs +55 -3989
  123. package/dist/completion.d.cts +150 -8
  124. package/dist/completion.d.ts +150 -8
  125. package/dist/completion.js +63 -3953
  126. package/dist/index.cjs +197 -10428
  127. package/dist/index.d.cts +35 -91
  128. package/dist/index.d.ts +35 -91
  129. package/dist/index.js +125 -10267
  130. package/dist/logger-4GvQNzhE.d.cts +22 -0
  131. package/dist/logger-4GvQNzhE.d.ts +22 -0
  132. package/dist/outbound-api/routeResolver.cjs +11 -0
  133. package/dist/outbound-api/routeResolver.d.cts +19 -0
  134. package/dist/outbound-api/routeResolver.d.ts +19 -0
  135. package/dist/outbound-api/routeResolver.js +11 -0
  136. package/dist/outbound-api/subscriptionRegistryPort.cjs +7 -37
  137. package/dist/outbound-api/subscriptionRegistryPort.d.cts +7 -3
  138. package/dist/outbound-api/subscriptionRegistryPort.d.ts +7 -3
  139. package/dist/outbound-api/subscriptionRegistryPort.js +4 -8
  140. package/dist/outbound-api/types.cjs +1 -0
  141. package/dist/{types-CbCN2NQP.d.ts → outbound-api/types.d.cts} +18 -3
  142. package/dist/{types-CGGrKqC_.d.cts → outbound-api/types.d.ts} +18 -3
  143. package/dist/outbound-api/types.js +0 -0
  144. package/dist/outbound-api.cjs +35 -5220
  145. package/dist/outbound-api.d.cts +16 -88
  146. package/dist/outbound-api.d.ts +16 -88
  147. package/dist/outbound-api.js +54 -5193
  148. package/dist/pipeline/AuthSource.cjs +1 -0
  149. package/dist/pipeline/AuthSource.d.cts +101 -0
  150. package/dist/pipeline/AuthSource.d.ts +101 -0
  151. package/dist/pipeline/AuthSource.js +0 -0
  152. package/dist/pipeline/LlmConfigProviderAuth.cjs +8 -0
  153. package/dist/pipeline/LlmConfigProviderAuth.d.cts +87 -0
  154. package/dist/pipeline/LlmConfigProviderAuth.d.ts +87 -0
  155. package/dist/pipeline/LlmConfigProviderAuth.js +8 -0
  156. package/dist/pipeline/SubscriptionAuthSource.cjs +6 -128
  157. package/dist/pipeline/SubscriptionAuthSource.d.cts +165 -3
  158. package/dist/pipeline/SubscriptionAuthSource.d.ts +165 -3
  159. package/dist/pipeline/SubscriptionAuthSource.js +5 -99
  160. package/dist/pipeline/SubscriptionAuthStrategy.cjs +1 -18
  161. package/dist/pipeline/executeProviderCall.cjs +6 -0
  162. package/dist/pipeline/executeProviderCall.d.cts +149 -0
  163. package/dist/pipeline/executeProviderCall.d.ts +149 -0
  164. package/dist/pipeline/executeProviderCall.js +6 -0
  165. package/dist/pipeline/resolveProviderChain.cjs +6 -0
  166. package/dist/pipeline/resolveProviderChain.d.cts +58 -0
  167. package/dist/pipeline/resolveProviderChain.d.ts +58 -0
  168. package/dist/pipeline/resolveProviderChain.js +6 -0
  169. package/dist/pipeline/resolveSubscriptionChain.cjs +6 -0
  170. package/dist/pipeline/resolveSubscriptionChain.d.cts +68 -0
  171. package/dist/pipeline/resolveSubscriptionChain.d.ts +68 -0
  172. package/dist/pipeline/resolveSubscriptionChain.js +6 -0
  173. package/dist/ports/gemini-code-assist-resolver.cjs +7 -37
  174. package/dist/ports/gemini-code-assist-resolver.js +4 -8
  175. package/dist/ports/pricing-store.cjs +1 -0
  176. package/dist/ports/pricing-store.d.cts +50 -0
  177. package/dist/ports/pricing-store.d.ts +50 -0
  178. package/dist/ports/pricing-store.js +0 -0
  179. package/dist/ports/provider-config-source.cjs +1 -0
  180. package/dist/ports/provider-config-source.d.cts +51 -0
  181. package/dist/ports/provider-config-source.d.ts +51 -0
  182. package/dist/ports/provider-config-source.js +0 -0
  183. package/dist/ports/usage-event-store.cjs +1 -0
  184. package/dist/ports/usage-event-store.d.cts +29 -0
  185. package/dist/ports/usage-event-store.d.ts +29 -0
  186. package/dist/ports/usage-event-store.js +0 -0
  187. package/dist/ports/web-search-backend.cjs +1 -0
  188. package/dist/ports/web-search-backend.d.cts +29 -0
  189. package/dist/ports/web-search-backend.d.ts +29 -0
  190. package/dist/ports/web-search-backend.js +0 -0
  191. package/dist/ports.cjs +1 -18
  192. package/dist/ports.d.cts +16 -8
  193. package/dist/ports.d.ts +16 -8
  194. package/dist/provider-proxy/ProviderProxy.cjs +40 -0
  195. package/dist/provider-proxy/ProviderProxy.d.cts +17 -0
  196. package/dist/provider-proxy/ProviderProxy.d.ts +17 -0
  197. package/dist/provider-proxy/ProviderProxy.js +40 -0
  198. package/dist/provider-proxy/ingress/providerProxyShared.cjs +35 -2941
  199. package/dist/provider-proxy/ingress/providerProxyShared.d.cts +7 -3
  200. package/dist/provider-proxy/ingress/providerProxyShared.d.ts +7 -3
  201. package/dist/provider-proxy/ingress/providerProxyShared.js +41 -2914
  202. package/dist/provider-proxy/matchText.cjs +11 -72
  203. package/dist/provider-proxy/matchText.js +6 -39
  204. package/dist/provider-proxy/types.cjs +1 -18
  205. package/dist/provider-proxy/types.d.cts +407 -8
  206. package/dist/provider-proxy/types.d.ts +407 -8
  207. package/dist/provider-proxy.cjs +35 -4654
  208. package/dist/provider-proxy.d.cts +10 -6
  209. package/dist/provider-proxy.d.ts +10 -6
  210. package/dist/provider-proxy.js +39 -4627
  211. package/dist/routeResolver-BrbK6ja9.d.cts +88 -0
  212. package/dist/routeResolver-HE-ZO0fO.d.ts +88 -0
  213. package/dist/serializeError.cjs +5 -81
  214. package/dist/serializeError.js +3 -54
  215. package/dist/sse-parser.cjs +7 -455
  216. package/dist/sse-parser.js +4 -426
  217. package/dist/transformer/TransformerChainExecutor.cjs +4 -318
  218. package/dist/transformer/TransformerChainExecutor.js +4 -291
  219. package/dist/transformer/TransformerService.cjs +5 -289
  220. package/dist/transformer/TransformerService.js +3 -262
  221. package/dist/transformer/anthropicBetaInject.cjs +8 -0
  222. package/dist/transformer/anthropicBetaInject.d.cts +20 -0
  223. package/dist/transformer/anthropicBetaInject.d.ts +20 -0
  224. package/dist/transformer/anthropicBetaInject.js +8 -0
  225. package/dist/transformer/transformers/AnthropicTransformer.cjs +6 -0
  226. package/dist/transformer/transformers/AnthropicTransformer.d.cts +148 -0
  227. package/dist/transformer/transformers/AnthropicTransformer.d.ts +148 -0
  228. package/dist/transformer/transformers/AnthropicTransformer.js +6 -0
  229. package/dist/transformer/transformers/GeminiCodeAssistTransformer.cjs +4 -1106
  230. package/dist/transformer/transformers/GeminiCodeAssistTransformer.js +7 -1079
  231. package/dist/transformer/transformers/GeminiTransformer.cjs +4 -1010
  232. package/dist/transformer/transformers/GeminiTransformer.js +4 -983
  233. package/dist/transformer/transformers/OpenAIResponseTransformer.cjs +3 -535
  234. package/dist/transformer/transformers/OpenAIResponseTransformer.js +3 -510
  235. package/dist/transformer/transformers/OpenCodeGoTransformer.cjs +5 -72
  236. package/dist/transformer/transformers/OpenCodeGoTransformer.js +3 -45
  237. package/dist/transformer/transformers/ReasoningTransformer.cjs +6 -0
  238. package/dist/transformer/transformers/ReasoningTransformer.d.cts +47 -0
  239. package/dist/transformer/transformers/ReasoningTransformer.d.ts +47 -0
  240. package/dist/transformer/transformers/ReasoningTransformer.js +6 -0
  241. package/dist/transformer/transformers.cjs +39 -0
  242. package/dist/transformer/transformers.d.cts +100 -0
  243. package/dist/transformer/transformers.d.ts +100 -0
  244. package/dist/transformer/transformers.js +39 -0
  245. package/dist/transformer/types.cjs +1 -18
  246. package/dist/transformer.cjs +13 -3726
  247. package/dist/transformer.d.cts +8 -31
  248. package/dist/transformer.d.ts +8 -31
  249. package/dist/transformer.js +17 -3706
  250. package/dist/types-BScIHmPr.d.cts +153 -0
  251. package/dist/types-BScIHmPr.d.ts +153 -0
  252. package/dist/usage/pricing-engine.cjs +6 -0
  253. package/dist/usage/pricing-engine.d.cts +83 -0
  254. package/dist/usage/pricing-engine.d.ts +83 -0
  255. package/dist/usage/pricing-engine.js +6 -0
  256. package/dist/usage/usage-recorder.cjs +6 -0
  257. package/dist/usage/usage-recorder.d.cts +73 -0
  258. package/dist/usage/usage-recorder.d.ts +73 -0
  259. package/dist/usage/usage-recorder.js +6 -0
  260. package/dist/usage.cjs +11 -0
  261. package/dist/usage.d.cts +8 -0
  262. package/dist/usage.d.ts +8 -0
  263. package/dist/usage.js +11 -0
  264. package/package.json +3 -3
  265. package/dist/ApiKeyPoolService-BmMkau07.d.cts +0 -170
  266. package/dist/ApiKeyPoolService-BmMkau07.d.ts +0 -170
  267. package/dist/SubscriptionAuthSource-Cr4fVEYY.d.cts +0 -264
  268. package/dist/SubscriptionAuthSource-D89zmiSS.d.ts +0 -264
  269. package/dist/index-BTSmc9Sm.d.ts +0 -645
  270. package/dist/index-DXazdTzZ.d.cts +0 -645
  271. package/dist/types-DCzHkhJt.d.ts +0 -467
  272. package/dist/types-DZIQbgp0.d.cts +0 -467
@@ -0,0 +1,173 @@
1
+ // src/usage/pricing-engine.ts
2
+ import { DEFAULT_LITELLM_PRICING_URL } from "@omnicross/contracts/pricing-types";
3
+ var PricingEngine = class {
4
+ constructor(store, logger, options = {}) {
5
+ this.store = store;
6
+ this.logger = logger;
7
+ this.options = options;
8
+ }
9
+ store;
10
+ logger;
11
+ options;
12
+ cache = /* @__PURE__ */ new Map();
13
+ /**
14
+ * Secondary index keyed by modelId alone. Used as a fallback when no exact
15
+ * (providerId, modelId) match exists — usage may be recorded under a
16
+ * runtime provider alias while pricing rows use the canonical provider id,
17
+ * so matching by model name lets the price still resolve. First
18
+ * non-wildcard entry per model wins.
19
+ */
20
+ cacheByModel = /* @__PURE__ */ new Map();
21
+ cacheLoaded = false;
22
+ // ===== Cache management =====
23
+ /** Lazy-load and cache the full pricing table. */
24
+ async ensureCache() {
25
+ if (this.cacheLoaded) return;
26
+ const rows = await this.store.getAll();
27
+ this.cache = new Map(rows.map((r) => [keyOf(r.providerId, r.modelId), r]));
28
+ this.cacheByModel = /* @__PURE__ */ new Map();
29
+ for (const r of rows) {
30
+ if (r.providerId === "*") continue;
31
+ if (!this.cacheByModel.has(r.modelId)) this.cacheByModel.set(r.modelId, r);
32
+ }
33
+ this.cacheLoaded = true;
34
+ }
35
+ /** Force a cache refresh — call after any write. */
36
+ async invalidateCache() {
37
+ this.cacheLoaded = false;
38
+ await this.ensureCache();
39
+ }
40
+ // ===== Read API =====
41
+ async getAll() {
42
+ await this.ensureCache();
43
+ return Array.from(this.cache.values());
44
+ }
45
+ /**
46
+ * Look up a price for (provider, model). Resolution order:
47
+ * 1. exact (providerId, modelId)
48
+ * 2. wildcard provider ('*', modelId)
49
+ * 3. model name alone (any provider) — tolerates a runtime-alias vs
50
+ * canonical provider-id mismatch for the same model.
51
+ */
52
+ async getEntry(providerId, modelId) {
53
+ await this.ensureCache();
54
+ return this.cache.get(keyOf(providerId, modelId)) ?? this.cache.get(keyOf("*", modelId)) ?? this.cacheByModel.get(modelId) ?? null;
55
+ }
56
+ // ===== Cost calculation =====
57
+ /**
58
+ * Compute the cost (and cache savings) for a single response.
59
+ *
60
+ * Cost formula (USD):
61
+ * cost = (input * inputPrice
62
+ * + output * outputPrice
63
+ * + cacheRead * (cacheReadPrice ?? inputPrice)
64
+ * + cacheWrite * (cacheWritePrice ?? inputPrice)
65
+ * ) / 1e6
66
+ *
67
+ * Cache savings:
68
+ * savings = cacheRead * (inputPrice - cacheReadPrice) / 1e6
69
+ * — clamped at 0 if cacheReadPrice is null or ≥ inputPrice.
70
+ */
71
+ async calculateCost(providerId, modelId, usage) {
72
+ const entry = await this.getEntry(providerId, modelId);
73
+ if (!entry) {
74
+ return { costUsd: 0, costSavedByCacheUsd: 0 };
75
+ }
76
+ const ip = entry.inputPricePer1m;
77
+ const op = entry.outputPricePer1m;
78
+ const crp = entry.cacheReadPricePer1m ?? ip;
79
+ const cwp = entry.cacheWritePricePer1m ?? ip;
80
+ const costUsd = (usage.inputTokens * ip + usage.outputTokens * op + usage.cacheReadTokens * crp + usage.cacheCreationTokens * cwp) / 1e6;
81
+ const savingsRate = entry.cacheReadPricePer1m == null ? 0 : Math.max(0, ip - crp);
82
+ const costSavedByCacheUsd = usage.cacheReadTokens * savingsRate / 1e6;
83
+ return { costUsd, costSavedByCacheUsd };
84
+ }
85
+ // ===== Manual upsert (used by inline editors) =====
86
+ async upsertManual(input) {
87
+ const updated = await this.store.upsert(
88
+ input,
89
+ /* asUserEdit */
90
+ true
91
+ );
92
+ this.cache.set(keyOf(updated.providerId, updated.modelId), updated);
93
+ if (updated.providerId !== "*") this.cacheByModel.set(updated.modelId, updated);
94
+ return updated;
95
+ }
96
+ // ===== Source refresh =====
97
+ async fetchLatestFromSource() {
98
+ const sourceUrl = this.options.sourceUrl ?? DEFAULT_LITELLM_PRICING_URL;
99
+ const fetchImpl = this.options.fetchImpl ?? fetch;
100
+ const fetchedAt = Date.now();
101
+ let json;
102
+ try {
103
+ const res = await fetchImpl(sourceUrl);
104
+ if (!res.ok) {
105
+ throw new Error(`Pricing-source fetch failed with status ${res.status}`);
106
+ }
107
+ json = await res.json();
108
+ } catch (e) {
109
+ this.logger.warn("[PricingEngine] pricing-source fetch failed", {
110
+ error: e instanceof Error ? e.message : String(e)
111
+ });
112
+ throw e;
113
+ }
114
+ const incoming = parseLitellmJson(json);
115
+ const { applied, conflicts } = await this.store.bulkApplyFromSource(incoming);
116
+ await this.invalidateCache();
117
+ return {
118
+ applied,
119
+ conflicts: conflicts.map((c) => ({
120
+ providerId: c.current.providerId,
121
+ modelId: c.current.modelId,
122
+ current: c.current,
123
+ incoming: c.incoming
124
+ })),
125
+ fetchedAt,
126
+ sourceUrl
127
+ };
128
+ }
129
+ // ===== Conflict resolution =====
130
+ async resolveConflicts(decisions, pendingIncoming) {
131
+ const resolutions = [];
132
+ for (const d of decisions) {
133
+ const incoming = pendingIncoming.get(keyOf(d.providerId, d.modelId));
134
+ if (!incoming) continue;
135
+ resolutions.push({ incoming, action: d.action });
136
+ }
137
+ const result = await this.store.applyResolutions(resolutions);
138
+ await this.invalidateCache();
139
+ return result;
140
+ }
141
+ };
142
+ var keyOf = (providerId, modelId) => `${providerId}::${modelId}`;
143
+ var PROVIDER_ALIASES = {
144
+ vertex_ai: "gemini",
145
+ google: "gemini",
146
+ bedrock: "anthropic",
147
+ azure: "openai"
148
+ };
149
+ var parseLitellmJson = (json) => {
150
+ const out = [];
151
+ for (const [modelId, entry] of Object.entries(json)) {
152
+ if (!entry || typeof entry !== "object") continue;
153
+ if (entry.input_cost_per_token == null || entry.output_cost_per_token == null) {
154
+ continue;
155
+ }
156
+ const rawProvider = entry.litellm_provider ?? "";
157
+ const providerId = PROVIDER_ALIASES[rawProvider] ?? rawProvider;
158
+ if (!providerId) continue;
159
+ out.push({
160
+ providerId,
161
+ modelId,
162
+ inputPricePer1m: entry.input_cost_per_token * 1e6,
163
+ outputPricePer1m: entry.output_cost_per_token * 1e6,
164
+ cacheReadPricePer1m: entry.cache_read_input_token_cost != null ? entry.cache_read_input_token_cost * 1e6 : null,
165
+ cacheWritePricePer1m: entry.cache_creation_input_token_cost != null ? entry.cache_creation_input_token_cost * 1e6 : null
166
+ });
167
+ }
168
+ return out;
169
+ };
170
+
171
+ export {
172
+ PricingEngine
173
+ };
@@ -0,0 +1,43 @@
1
+ // src/completion/openrouter-headers.ts
2
+ var OPENROUTER_DEFAULT_BASE_URL = "https://openrouter.ai/api/v1";
3
+ var OPENROUTER_HTTP_REFERER = "https://omnicross.dev";
4
+ var OPENROUTER_X_TITLE = "Omnicross";
5
+ function buildOpenRouterHeaders(credentials, options = {}) {
6
+ const apiKey = credentials.apiKey?.trim();
7
+ if (!apiKey) {
8
+ throw new Error("OpenRouter API key is required");
9
+ }
10
+ const headers = {
11
+ Authorization: `Bearer ${apiKey}`,
12
+ "HTTP-Referer": OPENROUTER_HTTP_REFERER,
13
+ "X-Title": OPENROUTER_X_TITLE
14
+ };
15
+ if (options.contentType !== false) {
16
+ headers["Content-Type"] = options.contentType ?? "application/json";
17
+ }
18
+ if (options.extra) {
19
+ for (const [key, value] of Object.entries(options.extra)) {
20
+ headers[key] = value;
21
+ }
22
+ }
23
+ return headers;
24
+ }
25
+ function resolveOpenRouterBaseUrl(endpoint) {
26
+ const raw = endpoint?.trim();
27
+ const base = raw && raw.length > 0 ? raw : OPENROUTER_DEFAULT_BASE_URL;
28
+ return base.replace(/\/+$/, "");
29
+ }
30
+ function buildOpenRouterUrl(endpoint, path) {
31
+ const base = resolveOpenRouterBaseUrl(endpoint);
32
+ const cleanPath = path.startsWith("/") ? path : `/${path}`;
33
+ return `${base}${cleanPath}`;
34
+ }
35
+
36
+ export {
37
+ OPENROUTER_DEFAULT_BASE_URL,
38
+ OPENROUTER_HTTP_REFERER,
39
+ OPENROUTER_X_TITLE,
40
+ buildOpenRouterHeaders,
41
+ resolveOpenRouterBaseUrl,
42
+ buildOpenRouterUrl
43
+ };
@@ -1,32 +1,8 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/completion/ApiKeyPoolService.ts
21
- var ApiKeyPoolService_exports = {};
22
- __export(ApiKeyPoolService_exports, {
23
- ApiKeyPoolService: () => ApiKeyPoolService
24
- });
25
- module.exports = __toCommonJS(ApiKeyPoolService_exports);
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;// src/completion/ApiKeyPoolService.ts
26
2
  var AUTH_FAILURE_CODES = /* @__PURE__ */ new Set([401, 403]);
27
3
  var RATE_LIMIT_CODES = /* @__PURE__ */ new Set([429, 529]);
28
- var ApiKeyPoolService = class {
29
- constructor(loadKeys, resolveKey, logger, disableKey, markAutoDisabled) {
4
+ var ApiKeyPoolService = (_class = class {
5
+ constructor(loadKeys, resolveKey, logger, disableKey, markAutoDisabled) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);_class.prototype.__init8.call(this);
30
6
  this.loadKeys = loadKeys;
31
7
  this.resolveKey = resolveKey;
32
8
  this.logger = logger;
@@ -34,27 +10,27 @@ var ApiKeyPoolService = class {
34
10
  this.markAutoDisabled = markAutoDisabled;
35
11
  this.cleanupTimer = setInterval(() => this.cleanupExpiredCooldowns(), 3e4);
36
12
  }
37
- loadKeys;
38
- resolveKey;
39
- logger;
40
- disableKey;
41
- markAutoDisabled;
13
+
14
+
15
+
16
+
17
+
42
18
  /** Session 鈫?key binding (session affinity) */
43
- sessionBindings = /* @__PURE__ */ new Map();
19
+ __init() {this.sessionBindings = /* @__PURE__ */ new Map()}
44
20
  /** Provider 鈫?round-robin index */
45
- rrIndex = /* @__PURE__ */ new Map();
21
+ __init2() {this.rrIndex = /* @__PURE__ */ new Map()}
46
22
  /** Provider 鈫?cached key list */
47
- keyCache = /* @__PURE__ */ new Map();
23
+ __init3() {this.keyCache = /* @__PURE__ */ new Map()}
48
24
  /** Key ID 鈫?cooldown state */
49
- cooldowns = /* @__PURE__ */ new Map();
25
+ __init4() {this.cooldowns = /* @__PURE__ */ new Map()}
50
26
  /** Cleanup interval handle */
51
- cleanupTimer = null;
27
+ __init5() {this.cleanupTimer = null}
52
28
  // Cooldown configuration
53
- DEFAULT_COOLDOWN_MS = 6e4;
29
+ __init6() {this.DEFAULT_COOLDOWN_MS = 6e4}
54
30
  // 60 seconds
55
- MAX_COOLDOWN_MS = 15 * 6e4;
31
+ __init7() {this.MAX_COOLDOWN_MS = 15 * 6e4}
56
32
  // 15 minutes
57
- COOLDOWN_MULTIPLIER = 2;
33
+ __init8() {this.COOLDOWN_MULTIPLIER = 2}
58
34
  /**
59
35
  * Get the API key for a session. Implements session affinity.
60
36
  *
@@ -202,7 +178,7 @@ var ApiKeyPoolService = class {
202
178
  health[key.id] = {
203
179
  until: cd.until,
204
180
  errors: cd.errors,
205
- lastStatus: cd.lastStatus ?? null
181
+ lastStatus: _nullishCoalesce(cd.lastStatus, () => ( null))
206
182
  };
207
183
  }
208
184
  }
@@ -252,7 +228,7 @@ var ApiKeyPoolService = class {
252
228
  */
253
229
  applyCooldown(keyId, providerId, statusCode) {
254
230
  const current = this.cooldowns.get(keyId);
255
- const errors = (current?.errors ?? 0) + 1;
231
+ const errors = (_nullishCoalesce(_optionalChain([current, 'optionalAccess', _ => _.errors]), () => ( 0))) + 1;
256
232
  const cooldownMs = Math.min(
257
233
  this.DEFAULT_COOLDOWN_MS * Math.pow(this.COOLDOWN_MULTIPLIER, errors - 1),
258
234
  this.MAX_COOLDOWN_MS
@@ -302,7 +278,7 @@ var ApiKeyPoolService = class {
302
278
  selectWeightedRoundRobin(providerId, keys) {
303
279
  if (keys.length === 1) return keys[0];
304
280
  const totalWeight = keys.reduce((sum, k) => sum + k.weight, 0);
305
- const idx = ((this.rrIndex.get(providerId) ?? -1) + 1) % totalWeight;
281
+ const idx = ((_nullishCoalesce(this.rrIndex.get(providerId), () => ( -1))) + 1) % totalWeight;
306
282
  this.rrIndex.set(providerId, idx);
307
283
  let accum = 0;
308
284
  for (const key of keys) {
@@ -324,8 +300,7 @@ var ApiKeyPoolService = class {
324
300
  }
325
301
  }
326
302
  }
327
- };
328
- // Annotate the CommonJS export names for ESM import in node:
329
- 0 && (module.exports = {
330
- ApiKeyPoolService
331
- });
303
+ }, _class);
304
+
305
+
306
+ exports.ApiKeyPoolService = ApiKeyPoolService;
@@ -1,2 +1,150 @@
1
- import '@omnicross/contracts/llm-config';
2
- export { a as ApiKeyAutoDisabler, b as ApiKeyDisabler, A as ApiKeyPoolService, c as ApiKeyResolver, d as ApiKeysLoader, K as KeyHealthEntry, e as KeyHealthMap } from '../ApiKeyPoolService-BmMkau07.cjs';
1
+ import { ApiKeyEntry } from '@omnicross/contracts/llm-config';
2
+ import { L as Logger } from '../logger-4GvQNzhE.cjs';
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,2 +1,150 @@
1
- import '@omnicross/contracts/llm-config';
2
- export { a as ApiKeyAutoDisabler, b as ApiKeyDisabler, A as ApiKeyPoolService, c as ApiKeyResolver, d as ApiKeysLoader, K as KeyHealthEntry, e as KeyHealthMap } from '../ApiKeyPoolService-BmMkau07.js';
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 };
@@ -0,0 +1,12 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
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;
@@ -0,0 +1,4 @@
1
+ import '@omnicross/contracts/mcp-types';
2
+ import '../ports/web-search-backend.cjs';
3
+ export { B as BuiltinToolExecutor, c as convertBuiltinToolsToAnthropic, a as convertBuiltinToolsToOpenAI, g as getBuiltinSearchTools } from '../BuiltinToolExecutor-CS2WpXhM.cjs';
4
+ import '@omnicross/contracts/websearch-types';
@@ -0,0 +1,4 @@
1
+ import '@omnicross/contracts/mcp-types';
2
+ import '../ports/web-search-backend.js';
3
+ export { B as BuiltinToolExecutor, c as convertBuiltinToolsToAnthropic, a as convertBuiltinToolsToOpenAI, g as getBuiltinSearchTools } from '../BuiltinToolExecutor-BluWyeob.js';
4
+ import '@omnicross/contracts/websearch-types';
@@ -0,0 +1,12 @@
1
+ import {
2
+ BuiltinToolExecutor,
3
+ convertBuiltinToolsToAnthropic,
4
+ convertBuiltinToolsToOpenAI,
5
+ getBuiltinSearchTools
6
+ } from "../chunk-CDHS2QDC.js";
7
+ export {
8
+ BuiltinToolExecutor,
9
+ convertBuiltinToolsToAnthropic,
10
+ convertBuiltinToolsToOpenAI,
11
+ getBuiltinSearchTools
12
+ };