@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,8 @@
1
+ export { CostCalculation, PricingEngine, PricingEngineOptions } from './usage/pricing-engine.js';
2
+ export { UsageRecordInput, UsageRecorder, UsageRecorderOptions } from './usage/usage-recorder.js';
3
+ import '@omnicross/contracts/pricing-types';
4
+ import '@omnicross/contracts/usage-types';
5
+ import './logger-4GvQNzhE.js';
6
+ import './ports/pricing-store.js';
7
+ import '@omnicross/contracts/usage-stats-types';
8
+ import './ports/usage-event-store.js';
package/dist/usage.js ADDED
@@ -0,0 +1,11 @@
1
+ import "./chunk-7VU7V2E4.js";
2
+ import {
3
+ PricingEngine
4
+ } from "./chunk-ZLX3KGXX.js";
5
+ import {
6
+ UsageRecorder
7
+ } from "./chunk-MNYKI4CI.js";
8
+ export {
9
+ PricingEngine,
10
+ UsageRecorder
11
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omnicross/core",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Omnicross LLM serving core — provider dispatch, completion pipeline, transformers, and the provider proxy.",
5
5
  "license": "MIT",
6
6
  "author": "Sayo (https://github.com/Dumoedss)",
@@ -54,9 +54,9 @@
54
54
  "typecheck": "tsc -p tsconfig.typecheck.json --noEmit"
55
55
  },
56
56
  "dependencies": {
57
+ "@mozilla/readability": "^0.6.0",
57
58
  "@omnicross/contracts": "^0.1.0",
58
- "turndown": "^7.2.2",
59
59
  "jsdom": "^24.1.3",
60
- "@mozilla/readability": "^0.6.0"
60
+ "turndown": "^7.2.2"
61
61
  }
62
62
  }
@@ -1,170 +0,0 @@
1
- import { ApiKeyEntry } from '@omnicross/contracts/llm-config';
2
-
3
- /**
4
- * `Logger` — core-owned port for the structured logger the serving core uses.
5
- *
6
- * The serving core MUST depend on THIS interface, never on the concrete host
7
- * `LoggerService` class as a type. The host (`LoggerService`) already exposes a
8
- * superset of this surface, so it is passed directly with NO adapter.
9
- *
10
- * `error` uses the WIDEST signature `(message, error?, meta?)` so every core
11
- * call site — `error(msg)`, `error(msg, errInstance)`, `error(msg, err, meta)` —
12
- * stays assignable (design Q2). `info`/`warn`/`debug` take an optional `meta`
13
- * bag matching the host's `Record<string, unknown> | Error | object`.
14
- *
15
- * @module ports/logger
16
- */
17
- interface Logger {
18
- info(message: string, meta?: Record<string, unknown> | Error | object): void;
19
- warn(message: string, meta?: Record<string, unknown> | Error | object): void;
20
- error(message: string, error?: unknown, meta?: Record<string, unknown> | object): void;
21
- debug(message: string, meta?: Record<string, unknown> | Error | object): void;
22
- }
23
-
24
- /**
25
- * ApiKeyPoolService - Multi-API-key load balancing with session affinity
26
- *
27
- * Manages a pool of API keys per provider, selecting keys via weighted
28
- * round-robin and maintaining session-level key affinity to preserve
29
- * prompt cache across requests within the same session.
30
- */
31
-
32
- /** Live health snapshot for a single key currently in cooldown. */
33
- interface KeyHealthEntry {
34
- /** Epoch-ms when the cooldown expires */
35
- until: number;
36
- /** Number of consecutive errors */
37
- errors: number;
38
- /** HTTP status that triggered the most recent cooldown */
39
- lastStatus: number | null;
40
- }
41
- /** Provider-scoped map of keyId → live cooldown health (cooling keys only). */
42
- type KeyHealthMap = Record<string, KeyHealthEntry>;
43
- /** Function type for loading API keys from the database */
44
- type ApiKeysLoader = (providerId: string) => Promise<ApiKeyEntry[]>;
45
- /** Function type for disabling a key in the database (on auth failure) */
46
- type ApiKeyDisabler = (keyId: string) => Promise<boolean>;
47
- /**
48
- * Function type for auto-disabling a key in the database on auth failure,
49
- * persisting the offending status + timestamp so the client UI can surface
50
- * a per-key health indicator. Preferred over {@link ApiKeyDisabler} when set.
51
- */
52
- type ApiKeyAutoDisabler = (keyId: string, status: number, at: number) => Promise<void>;
53
- /** Function type for resolving environment variable references in API keys */
54
- type ApiKeyResolver = (rawKey: string) => string;
55
- declare class ApiKeyPoolService {
56
- private loadKeys;
57
- private resolveKey;
58
- private logger;
59
- private disableKey?;
60
- private markAutoDisabled?;
61
- /** Session 鈫?key binding (session affinity) */
62
- private sessionBindings;
63
- /** Provider 鈫?round-robin index */
64
- private rrIndex;
65
- /** Provider 鈫?cached key list */
66
- private keyCache;
67
- /** Key ID 鈫?cooldown state */
68
- private cooldowns;
69
- /** Cleanup interval handle */
70
- private cleanupTimer;
71
- private readonly DEFAULT_COOLDOWN_MS;
72
- private readonly MAX_COOLDOWN_MS;
73
- private readonly COOLDOWN_MULTIPLIER;
74
- constructor(loadKeys: ApiKeysLoader, resolveKey: ApiKeyResolver, logger: Logger, disableKey?: ApiKeyDisabler | undefined, markAutoDisabled?: ApiKeyAutoDisabler | undefined);
75
- /**
76
- * Get the API key for a session. Implements session affinity.
77
- *
78
- * First call for a session binds it to a key via weighted round-robin.
79
- * Subsequent calls return the same key (preserves prompt cache).
80
- *
81
- * @returns Resolved API key string, or empty string if no keys available
82
- */
83
- /**
84
- * Read which key id is currently bound to the given session, if any.
85
- * Returns null when the session has not yet been bound (first call hasn't
86
- * happened) or when the binding is for a different provider.
87
- *
88
- * Used by the usage-recorder attribution path: after `getKeyForSession`
89
- * completes the caller looks up the keyId so the recorded usage
90
- * row can attribute spend to a specific pool key.
91
- */
92
- getKeyIdForSession(providerId: string, sessionId: string): string | null;
93
- getKeyForSession(providerId: string, sessionId: string): Promise<string>;
94
- /**
95
- * Get a key without session affinity (for one-shot calls like testConnection).
96
- *
97
- * @returns Resolved API key string, or empty string if no keys available
98
- */
99
- getKey(providerId: string): Promise<string>;
100
- /**
101
- * Report an error for the current session's key.
102
- *
103
- * - 429/529 (rate limit / overload): puts key in cooldown with exponential backoff
104
- * - 401/403 (auth failure): permanently disables the key in the database
105
- *
106
- * In both cases, re-binds the session to a different key if available.
107
- *
108
- * @param statusCode HTTP status code
109
- * @returns New resolved API key if re-binding succeeded, null if no keys available
110
- */
111
- reportError(providerId: string, sessionId: string, statusCode: number): Promise<string | null>;
112
- /**
113
- * Report a successful request — resets cooldown counter for the session's key.
114
- */
115
- reportSuccess(sessionId: string): void;
116
- /**
117
- * Release session binding (call when session ends or is deleted).
118
- */
119
- releaseSession(sessionId: string): void;
120
- /**
121
- * Invalidate the key cache. Call after CRUD operations on API keys.
122
- */
123
- invalidateCache(providerId?: string): void;
124
- /**
125
- * Check if a provider has any keys in the pool.
126
- */
127
- hasKeys(providerId: string): Promise<boolean>;
128
- /**
129
- * Get the live (in-memory) rate-limit cooldown health for a provider's keys.
130
- *
131
- * Returns ONLY keys that are currently cooling down (cooldown `until` is in
132
- * the future). A key absent from the returned map is not cooling. This is a
133
- * pure read of the in-memory cooldown map — auth-failure auto-disable state
134
- * is persisted on the key row itself (getApiKeys) and is NOT included here.
135
- */
136
- getKeyHealth(providerId: string): Promise<KeyHealthMap>;
137
- /**
138
- * Dispose of the service (stop cleanup timer).
139
- */
140
- dispose(): void;
141
- /**
142
- * Handle auth failure (401/403): disable the key in DB permanently.
143
- */
144
- private handleAuthFailure;
145
- /**
146
- * Apply cooldown with exponential backoff for rate-limit errors (429/529).
147
- */
148
- private applyCooldown;
149
- /**
150
- * Get all keys for a provider (with caching).
151
- */
152
- private getAllKeys;
153
- /**
154
- * Get available keys: enabled AND not in cooldown.
155
- */
156
- private getAvailableKeys;
157
- /**
158
- * Weighted round-robin selection.
159
- *
160
- * Each key's weight determines how many "slots" it occupies in the rotation.
161
- * The round-robin index advances by 1 on each call per provider.
162
- */
163
- private selectWeightedRoundRobin;
164
- /**
165
- * Clean up expired cooldowns.
166
- */
167
- private cleanupExpiredCooldowns;
168
- }
169
-
170
- export { ApiKeyPoolService as A, type KeyHealthEntry as K, type Logger as L, type ApiKeyAutoDisabler as a, type ApiKeyDisabler as b, type ApiKeyResolver as c, type ApiKeysLoader as d, type KeyHealthMap as e };
@@ -1,170 +0,0 @@
1
- import { ApiKeyEntry } from '@omnicross/contracts/llm-config';
2
-
3
- /**
4
- * `Logger` — core-owned port for the structured logger the serving core uses.
5
- *
6
- * The serving core MUST depend on THIS interface, never on the concrete host
7
- * `LoggerService` class as a type. The host (`LoggerService`) already exposes a
8
- * superset of this surface, so it is passed directly with NO adapter.
9
- *
10
- * `error` uses the WIDEST signature `(message, error?, meta?)` so every core
11
- * call site — `error(msg)`, `error(msg, errInstance)`, `error(msg, err, meta)` —
12
- * stays assignable (design Q2). `info`/`warn`/`debug` take an optional `meta`
13
- * bag matching the host's `Record<string, unknown> | Error | object`.
14
- *
15
- * @module ports/logger
16
- */
17
- interface Logger {
18
- info(message: string, meta?: Record<string, unknown> | Error | object): void;
19
- warn(message: string, meta?: Record<string, unknown> | Error | object): void;
20
- error(message: string, error?: unknown, meta?: Record<string, unknown> | object): void;
21
- debug(message: string, meta?: Record<string, unknown> | Error | object): void;
22
- }
23
-
24
- /**
25
- * ApiKeyPoolService - Multi-API-key load balancing with session affinity
26
- *
27
- * Manages a pool of API keys per provider, selecting keys via weighted
28
- * round-robin and maintaining session-level key affinity to preserve
29
- * prompt cache across requests within the same session.
30
- */
31
-
32
- /** Live health snapshot for a single key currently in cooldown. */
33
- interface KeyHealthEntry {
34
- /** Epoch-ms when the cooldown expires */
35
- until: number;
36
- /** Number of consecutive errors */
37
- errors: number;
38
- /** HTTP status that triggered the most recent cooldown */
39
- lastStatus: number | null;
40
- }
41
- /** Provider-scoped map of keyId → live cooldown health (cooling keys only). */
42
- type KeyHealthMap = Record<string, KeyHealthEntry>;
43
- /** Function type for loading API keys from the database */
44
- type ApiKeysLoader = (providerId: string) => Promise<ApiKeyEntry[]>;
45
- /** Function type for disabling a key in the database (on auth failure) */
46
- type ApiKeyDisabler = (keyId: string) => Promise<boolean>;
47
- /**
48
- * Function type for auto-disabling a key in the database on auth failure,
49
- * persisting the offending status + timestamp so the client UI can surface
50
- * a per-key health indicator. Preferred over {@link ApiKeyDisabler} when set.
51
- */
52
- type ApiKeyAutoDisabler = (keyId: string, status: number, at: number) => Promise<void>;
53
- /** Function type for resolving environment variable references in API keys */
54
- type ApiKeyResolver = (rawKey: string) => string;
55
- declare class ApiKeyPoolService {
56
- private loadKeys;
57
- private resolveKey;
58
- private logger;
59
- private disableKey?;
60
- private markAutoDisabled?;
61
- /** Session 鈫?key binding (session affinity) */
62
- private sessionBindings;
63
- /** Provider 鈫?round-robin index */
64
- private rrIndex;
65
- /** Provider 鈫?cached key list */
66
- private keyCache;
67
- /** Key ID 鈫?cooldown state */
68
- private cooldowns;
69
- /** Cleanup interval handle */
70
- private cleanupTimer;
71
- private readonly DEFAULT_COOLDOWN_MS;
72
- private readonly MAX_COOLDOWN_MS;
73
- private readonly COOLDOWN_MULTIPLIER;
74
- constructor(loadKeys: ApiKeysLoader, resolveKey: ApiKeyResolver, logger: Logger, disableKey?: ApiKeyDisabler | undefined, markAutoDisabled?: ApiKeyAutoDisabler | undefined);
75
- /**
76
- * Get the API key for a session. Implements session affinity.
77
- *
78
- * First call for a session binds it to a key via weighted round-robin.
79
- * Subsequent calls return the same key (preserves prompt cache).
80
- *
81
- * @returns Resolved API key string, or empty string if no keys available
82
- */
83
- /**
84
- * Read which key id is currently bound to the given session, if any.
85
- * Returns null when the session has not yet been bound (first call hasn't
86
- * happened) or when the binding is for a different provider.
87
- *
88
- * Used by the usage-recorder attribution path: after `getKeyForSession`
89
- * completes the caller looks up the keyId so the recorded usage
90
- * row can attribute spend to a specific pool key.
91
- */
92
- getKeyIdForSession(providerId: string, sessionId: string): string | null;
93
- getKeyForSession(providerId: string, sessionId: string): Promise<string>;
94
- /**
95
- * Get a key without session affinity (for one-shot calls like testConnection).
96
- *
97
- * @returns Resolved API key string, or empty string if no keys available
98
- */
99
- getKey(providerId: string): Promise<string>;
100
- /**
101
- * Report an error for the current session's key.
102
- *
103
- * - 429/529 (rate limit / overload): puts key in cooldown with exponential backoff
104
- * - 401/403 (auth failure): permanently disables the key in the database
105
- *
106
- * In both cases, re-binds the session to a different key if available.
107
- *
108
- * @param statusCode HTTP status code
109
- * @returns New resolved API key if re-binding succeeded, null if no keys available
110
- */
111
- reportError(providerId: string, sessionId: string, statusCode: number): Promise<string | null>;
112
- /**
113
- * Report a successful request — resets cooldown counter for the session's key.
114
- */
115
- reportSuccess(sessionId: string): void;
116
- /**
117
- * Release session binding (call when session ends or is deleted).
118
- */
119
- releaseSession(sessionId: string): void;
120
- /**
121
- * Invalidate the key cache. Call after CRUD operations on API keys.
122
- */
123
- invalidateCache(providerId?: string): void;
124
- /**
125
- * Check if a provider has any keys in the pool.
126
- */
127
- hasKeys(providerId: string): Promise<boolean>;
128
- /**
129
- * Get the live (in-memory) rate-limit cooldown health for a provider's keys.
130
- *
131
- * Returns ONLY keys that are currently cooling down (cooldown `until` is in
132
- * the future). A key absent from the returned map is not cooling. This is a
133
- * pure read of the in-memory cooldown map — auth-failure auto-disable state
134
- * is persisted on the key row itself (getApiKeys) and is NOT included here.
135
- */
136
- getKeyHealth(providerId: string): Promise<KeyHealthMap>;
137
- /**
138
- * Dispose of the service (stop cleanup timer).
139
- */
140
- dispose(): void;
141
- /**
142
- * Handle auth failure (401/403): disable the key in DB permanently.
143
- */
144
- private handleAuthFailure;
145
- /**
146
- * Apply cooldown with exponential backoff for rate-limit errors (429/529).
147
- */
148
- private applyCooldown;
149
- /**
150
- * Get all keys for a provider (with caching).
151
- */
152
- private getAllKeys;
153
- /**
154
- * Get available keys: enabled AND not in cooldown.
155
- */
156
- private getAvailableKeys;
157
- /**
158
- * Weighted round-robin selection.
159
- *
160
- * Each key's weight determines how many "slots" it occupies in the rotation.
161
- * The round-robin index advances by 1 on each call per provider.
162
- */
163
- private selectWeightedRoundRobin;
164
- /**
165
- * Clean up expired cooldowns.
166
- */
167
- private cleanupExpiredCooldowns;
168
- }
169
-
170
- export { ApiKeyPoolService as A, type KeyHealthEntry as K, type Logger as L, type ApiKeyAutoDisabler as a, type ApiKeyDisabler as b, type ApiKeyResolver as c, type ApiKeysLoader as d, type KeyHealthMap as e };
@@ -1,264 +0,0 @@
1
- import { OpenCodeGoTokenConfig, OpenCodeGoScenario, OpenCodeGoModelEntry } from '@omnicross/contracts/subscription-types';
2
- import { AuthStrategy } from './pipeline/SubscriptionAuthStrategy.cjs';
3
-
4
- /**
5
- * AuthSource — unified outbound-authentication strategy for the provider
6
- * request pipeline.
7
- *
8
- * Phase 2 of the `provider-request-pipeline` OpenSpec change (design D3).
9
- *
10
- * The three consumer paths (the wire-format proxy handler, the host engine
11
- * adapter, TransformerHandler) each authenticate differently:
12
- *
13
- * - provider-key (+ ApiKeyPool failover) — LLM-config provider rows
14
- * - subscription `AuthStrategy` (+ 401 refresh + fallback) — code-cli OAuth
15
- * - OAuth pass-through — SDK forwards its own Bearer
16
- *
17
- * `AuthSource` is the single contract that unifies these. THIS PHASE ONLY
18
- * DEFINES the interface and provides three behavior-preserving WRAPPERS
19
- * (`LlmConfigProviderAuth`, `SubscriptionAuthSource`, `OAuthPassThroughAuth`)
20
- * around the existing logic. NO caller is routed through it yet — the core
21
- * (`executeProviderCall`) is NOT changed to consume `ctx.auth`, and
22
- * the host handler's branch structure is UNCHANGED. Wiring (and
23
- * the `onResult` pool-rotation integration) is Phase 3.
24
- *
25
- * @module pipeline/AuthSource
26
- */
27
- /**
28
- * Hints an `AuthSource` may need to vary header formatting per request.
29
- *
30
- * Mirrors the subscription-side `AuthApplyHints` (which uses optional
31
- * `upstreamUrl` / `resolvedModel`) but with REQUIRED fields, since the
32
- * pipeline always knows both at the point it applies headers. Adapters that
33
- * wrap the looser subscription shape map these across at the boundary.
34
- */
35
- interface AuthApplyHints {
36
- /** Resolved upstream URL the request will be sent to. */
37
- upstreamUrl: string;
38
- /** Resolved model id for the request. */
39
- model: string;
40
- }
41
- /**
42
- * Result of {@link AuthSource.onResult}.
43
- *
44
- * `rebound` is `true` when the auth source rotated to a different credential
45
- * (e.g. ApiKeyPool re-bound the session to a new key after a 429). `newKey`
46
- * carries the freshly-resolved key string when a rotation produced one, so a
47
- * caller MAY retry the same call once with it. Mirrors the
48
- * `{ newKey | null }` contract of `ApiKeyPoolService.reportError` lifted into
49
- * a structured shape.
50
- */
51
- interface AuthResultOutcome {
52
- /** Whether the credential was rotated/re-bound as a result of this status. */
53
- rebound: boolean;
54
- /** The new resolved key when a rotation produced one; omitted otherwise. */
55
- newKey?: string;
56
- }
57
- /**
58
- * A pluggable outbound-authentication source for one provider request.
59
- *
60
- * Implementations OWN exactly the auth concern: which headers carry the
61
- * credential, how to recover from a 401, where the request should be sent
62
- * (when the credential dictates the endpoint), and how to react to a final
63
- * HTTP status (pool rotation / refresh). The pipeline core composes the rest.
64
- */
65
- interface AuthSource {
66
- /**
67
- * Inject the authentication headers for this request, mutating `headers`
68
- * in place. Implementations MAY refresh expiring tokens here.
69
- *
70
- * NOTE (Phase 2 boundary, see report): exactly WHAT this owns vs what the
71
- * ingress assembles (content-type, OpenRouter app headers, proxy auth
72
- * stripping) is intentionally left to the caller this phase. The wrappers
73
- * preserve their source's CURRENT header behavior verbatim.
74
- */
75
- applyHeaders(headers: Record<string, string>, hints: AuthApplyHints): Promise<void> | void;
76
- /**
77
- * Called when the upstream returns 401. Return `true` to ask the caller to
78
- * retry once with freshly-applied headers; `false` to surface the 401.
79
- * Optional — sources without a refresh notion omit it.
80
- */
81
- onUnauthorized?(): Promise<boolean>;
82
- /**
83
- * Resolve the upstream URL the request should target, when the credential
84
- * dictates it (e.g. a subscription profile's per-model endpoint). Returns
85
- * `undefined` when the source does not override the URL (the ingress keeps
86
- * its own URL logic). Optional.
87
- */
88
- resolveUpstreamUrl?(model: string): string | undefined;
89
- /**
90
- * React to a final HTTP status (pool participation seam — design D5).
91
- *
92
- * For the provider-key source this reports the status to the
93
- * `ApiKeyPoolService` (cooldown / disable / re-bind) and returns whether it
94
- * rotated plus any new key. THIS PHASE ONLY: `onResult` is implemented and
95
- * unit-tested in isolation; NO caller invokes it yet. Phase 3 wires it into
96
- * `fetchWithRetry`. Optional.
97
- *
98
- * @param status The final HTTP status, or `null` for non-HTTP failures
99
- * (e.g. network errors). Non-reportable statuses no-op.
100
- */
101
- onResult?(status: number | null): Promise<AuthResultOutcome>;
102
- }
103
-
104
- /**
105
- * SubscriptionAuthSource — `AuthSource` wrapping a subscription `AuthStrategy`.
106
- *
107
- * Phase 2 of the `provider-request-pipeline` OpenSpec change (design D3, task 4.3).
108
- *
109
- * Re-expresses the subscription auth used by `SubscriptionDispatcher` behind
110
- * the unified `AuthSource` contract, delegating to the existing
111
- * `AuthStrategy` so the OAuth refresh / token formatting logic is NOT
112
- * rewritten:
113
- *
114
- * - `applyHeaders` → `stripAuthHeaders(headers)` then
115
- * `authStrategy.applyHeaders(headers, { upstreamUrl, resolvedModel })`,
116
- * wrapped in the same best-effort try/catch as
117
- * `SubscriptionDispatcher.applyHeadersWithRetry` (a thrown
118
- * `applyHeaders` is logged + swallowed, NOT propagated — preserved
119
- * verbatim).
120
- * - `onUnauthorized` → `authStrategy.onUnauthorized()`.
121
- * - `resolveUpstreamUrl` → `profile.resolveUpstreamUrl?.(model)`.
122
- *
123
- * IMPORTANT (Phase 2 scope): this WRAPS the strategy + strip behavior but does
124
- * NOT re-route `SubscriptionDispatcher` through it. The dispatcher's fragile
125
- * 401-refresh + fallback loop is left UNCHANGED (task 4.5 deferred). This
126
- * class is unit-tested in isolation only.
127
- *
128
- * @module pipeline/SubscriptionAuthSource
129
- */
130
-
131
- /**
132
- * Lightweight summary derived from the inbound request body — consumed by a
133
- * profile's `modelMapper` (scenario routing). Structural mirror of
134
- * `provider-proxy/types.ts`'s `SubscriptionRequestSummary`, declared here so
135
- * `SubscriptionAuthProfile.modelMapper` is type-identical WITHOUT a circular
136
- * import back into `provider-proxy/types` (which imports THIS module).
137
- */
138
- interface SubscriptionRequestSummary {
139
- messageCount: number;
140
- estimatedInputTokens: number;
141
- /**
142
- * OPTIONAL bounded per-message match-text slice — kept structurally identical
143
- * to the canonical declaration in `provider-proxy/types.ts` (the two are
144
- * deliberate mirrors, not one shared import). Consumed only by the OpenCodeGo
145
- * keyword matcher in `@omnicross/subscriptions`; core writes, never reads it.
146
- */
147
- matchText?: string[];
148
- }
149
- /**
150
- * The subset of a `SubscriptionDispatchProfile` the subscription paths need.
151
- * Kept structural (not the full profile type) so the wrapper does not pull in
152
- * the whole registry surface. The full `SubscriptionDispatchProfile` (which IS
153
- * what gets passed here) satisfies this shape; the optional `mode` + `modelMapper`
154
- * are read by the built-in `/v1/messages` subscription path (RT2.1) to decide the
155
- * verbatim-vs-transformer shape and to apply opencodego scenario routing.
156
- */
157
- interface SubscriptionAuthProfile {
158
- readonly authStrategy: AuthStrategy;
159
- /** Per-model upstream URL resolver (transformer profiles). Optional for
160
- * pass-through profiles that hard-code their endpoint upstream. The OPTIONAL
161
- * 2nd `config` arg (opencodego `baseUrl` override, D1) is additive — existing
162
- * one-arg callers compile unchanged; mirrors the full
163
- * `SubscriptionDispatchProfile.resolveUpstreamUrl` so the registry profile
164
- * stays assignable. */
165
- readonly resolveUpstreamUrl?: (resolvedModel: string, config?: OpenCodeGoTokenConfig) => string;
166
- /**
167
- * Names of provider-level transformers (registered in `TransformerService`)
168
- * to run on the subscription chain — re-encode Unified → the upstream's wire.
169
- * The full `SubscriptionDispatchProfile` (which IS what gets passed here)
170
- * carries these; exposing them on the narrow structural type lets the
171
- * Responses ingress build the profile's REAL chain (cross-vendor route-to,
172
- * task #29) instead of hard-coding `['openai-response']`. Absent/empty →
173
- * the ingress falls back to its endpoint transformer (codex byte-identity).
174
- */
175
- readonly providerTransformerNames?: readonly string[];
176
- /** Names of model-specific transformers — usually empty. See above. */
177
- readonly modelTransformerNames?: readonly string[];
178
- /**
179
- * OPTIONAL shape-aware provider transformer-name resolver (opencodego zen).
180
- * Type-identical to `SubscriptionDispatchProfile.resolveProviderTransformerNames`
181
- * so the registry profile stays assignable. The built-in `/v1/messages`
182
- * subscription path (Phase 3) consults it via
183
- * `profile.resolveProviderTransformerNames?.(model, route.subscriptionConfig)`
184
- * to pick the right zen chain per resolved shape. `config` is `unknown` (core
185
- * opaque-config discipline — no `@omnicross/subscriptions` import). When ABSENT
186
- * the path reads the static `providerTransformerNames` exactly as today (codex
187
- * byte-identity).
188
- */
189
- readonly resolveProviderTransformerNames?: (model: string, config?: unknown) => readonly string[];
190
- /**
191
- * Pass-through (claude) vs transformer (codex / opencodego / gemini). The
192
- * built-in `/v1/messages` subscription path (RT2.1) reads this for its
193
- * core-local same-format signal (pass-through ⇒ always verbatim relay).
194
- * Optional on the narrow type — partial profiles built by other route-minting
195
- * sites may omit it.
196
- */
197
- readonly mode?: 'pass-through' | 'transformer';
198
- /**
199
- * Optional model placeholder rewriter — only set for OpenCodeGo. Type-identical
200
- * to `SubscriptionDispatchProfile.modelMapper` so the registry profile stays
201
- * assignable. Applied by the built-in `/v1/messages` subscription path BEFORE
202
- * resolving the upstream URL (so scenario-based shape routing picks the right
203
- * Anthropic-shape vs OpenAI-shape upstream).
204
- */
205
- readonly modelMapper?: (sdkModel: string, summary: SubscriptionRequestSummary, config: OpenCodeGoTokenConfig | undefined) => {
206
- resolvedModel: string;
207
- scenario: OpenCodeGoScenario;
208
- };
209
- /**
210
- * Optional fallback resolver — only set for OpenCodeGo. Type-identical to
211
- * `SubscriptionDispatchProfile.nextFallback` so the registry profile stays
212
- * assignable. Read by the built-in `/v1/messages` fallback loop (D6b) to pick
213
- * the next model after an unrecoverable upstream failure; returns `null` when
214
- * exhausted (claude / codex / gemini omit it → no fallback attempted).
215
- */
216
- readonly nextFallback?: (scenario: OpenCodeGoScenario, attempted: readonly string[], config: OpenCodeGoTokenConfig | undefined) => OpenCodeGoModelEntry | null;
217
- /**
218
- * Optional circuit-breaker admission gate for the PRIMARY (mapped) model (D5
219
- * primary-gating). Type-identical to `SubscriptionDispatchProfile.allowModel`.
220
- * Only OpenCodeGo sets it; the core `/v1/messages` loop consults it for the
221
- * primary before its first attempt and jumps to the first admitting
222
- * `nextFallback` candidate when the primary's circuit is open. Absent ⇒ the
223
- * primary is always admitted (claude / codex / gemini — no breaker).
224
- */
225
- readonly allowModel?: (modelId: string) => boolean;
226
- /**
227
- * Optional record-outcome callback (D5 record seam). Type-identical to
228
- * `SubscriptionDispatchProfile.recordModelOutcome`. The core `/v1/messages`
229
- * loop calls `profile.recordModelOutcome?.(model, ok)` THROUGH this optional
230
- * field after each attempt, so `@omnicross/core` gains NO import of
231
- * `@omnicross/subscriptions` (the cross-layer litmus stays 0 — exactly the
232
- * `nextFallback` precedent). `ok: true` on `2xx`; `ok: false` on
233
- * thrown/`5xx`/`429`; a non-429 `4xx` is NEUTRAL (the loop does NOT call it).
234
- * Absent for claude / codex / gemini ⇒ no-op.
235
- */
236
- readonly recordModelOutcome?: (modelId: string, ok: boolean) => void;
237
- }
238
- /**
239
- * Drop auth headers the transformer chain may have set so the `AuthStrategy`
240
- * is the single source of truth for outbound authentication. Byte-identical
241
- * to `SubscriptionDispatcher.stripAuthHeaders`.
242
- */
243
- declare function stripAuthHeaders(headers: Record<string, string>): void;
244
- declare class SubscriptionAuthSource implements AuthSource {
245
- private readonly profile;
246
- constructor(profile: SubscriptionAuthProfile);
247
- /**
248
- * Strip any transformer-set auth headers, then delegate to the bound
249
- * strategy. Mirrors `SubscriptionDispatcher`'s
250
- * `stripAuthHeaders(...)` + `applyHeadersWithRetry(...)` sequence, including
251
- * the best-effort swallow-and-warn around a throwing `applyHeaders`.
252
- *
253
- * The strategy's looser `AuthApplyHints` (optional `upstreamUrl` /
254
- * `resolvedModel`) is fed from the pipeline's required `{ upstreamUrl,
255
- * model }` at the boundary.
256
- */
257
- applyHeaders(headers: Record<string, string>, hints: AuthApplyHints): Promise<void>;
258
- /** Delegate the 401-refresh decision to the bound strategy. */
259
- onUnauthorized(): Promise<boolean>;
260
- /** Resolve the upstream URL from the profile, when it provides one. */
261
- resolveUpstreamUrl(model: string): string | undefined;
262
- }
263
-
264
- export { type AuthSource as A, type SubscriptionAuthProfile as S, SubscriptionAuthSource as a, type SubscriptionRequestSummary as b, stripAuthHeaders as s };