@omnicross/core 0.1.2 → 0.1.4

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 (184) hide show
  1. package/LICENSE +21 -21
  2. package/NOTICE +57 -57
  3. package/README.md +15 -15
  4. package/dist/auth/GeminiCodeAssistProjectResolver.cjs +6 -1
  5. package/dist/auth/GeminiCodeAssistProjectResolver.js +6 -1
  6. package/dist/chunk-3QFXFCHG.js +33 -0
  7. package/dist/chunk-4IH4EL7M.cjs +9 -0
  8. package/dist/chunk-4YINUUKQ.cjs +33 -0
  9. package/dist/chunk-5ENKBSWO.js +311 -0
  10. package/dist/chunk-6RPZADX3.cjs +92 -0
  11. package/dist/chunk-7Y47UCF2.js +142 -0
  12. package/dist/chunk-AEOZIDEB.cjs +32 -0
  13. package/dist/chunk-APYG5QD7.cjs +50 -0
  14. package/dist/{chunk-MNYKI4CI.js → chunk-BPKCU575.js} +29 -0
  15. package/dist/{chunk-SN3YWBX7.cjs → chunk-DKPXN34V.cjs} +2108 -538
  16. package/dist/{chunk-4NBS6KPV.cjs → chunk-DQ5VAYZ6.cjs} +7 -8
  17. package/dist/chunk-E3UCVHLP.cjs +142 -0
  18. package/dist/chunk-FCR77GYM.cjs +33 -0
  19. package/dist/{chunk-74TMJA7Z.js → chunk-HRRYG2AX.js} +8 -4
  20. package/dist/chunk-HUZZZ3JL.js +32 -0
  21. package/dist/{chunk-KUU2RNG6.cjs → chunk-HYN75H6G.cjs} +3 -0
  22. package/dist/{chunk-QOCNX236.js → chunk-IAXWICZU.js} +24 -1
  23. package/dist/{chunk-JO5NLTLY.js → chunk-IK3KE3AU.js} +3 -0
  24. package/dist/{chunk-V5KPWNYX.cjs → chunk-JMJBSACD.cjs} +3 -3
  25. package/dist/chunk-K5NM7VAH.js +33 -0
  26. package/dist/{chunk-N3V2J5ZO.cjs → chunk-KFI44N2R.cjs} +8 -4
  27. package/dist/chunk-L74VDN4A.cjs +32 -0
  28. package/dist/chunk-OCEUVQHW.cjs +112 -0
  29. package/dist/chunk-OE6TDIWW.js +22 -0
  30. package/dist/chunk-OZFM4X3S.js +18 -0
  31. package/dist/{chunk-LKZJEL6E.cjs → chunk-Q27JY5RG.cjs} +6 -4
  32. package/dist/{chunk-SPVWWUHX.cjs → chunk-QWBWGODS.cjs} +24 -1
  33. package/dist/{chunk-2FEVTJWG.js → chunk-QYTT6GE3.js} +1929 -359
  34. package/dist/{chunk-UYPEN5XE.cjs → chunk-RGTR7CIO.cjs} +6 -6
  35. package/dist/chunk-RPII3E6Z.cjs +145 -0
  36. package/dist/{chunk-XBSYYZIY.cjs → chunk-SNYBEXLB.cjs} +31 -2
  37. package/dist/{chunk-2DCNB7DF.cjs → chunk-SU2GCLAC.cjs} +30 -10
  38. package/dist/{chunk-5HTVET6E.js → chunk-TIER4SUC.js} +24 -4
  39. package/dist/chunk-TKJMZBAH.js +32 -0
  40. package/dist/{chunk-ZSVQT3PW.js → chunk-UBWEBKRC.js} +5 -6
  41. package/dist/chunk-UHGVBFU3.js +385 -0
  42. package/dist/chunk-UIBD2YY5.cjs +22 -0
  43. package/dist/chunk-UNEFIWXI.cjs +32 -0
  44. package/dist/chunk-VACWOIRE.cjs +385 -0
  45. package/dist/{chunk-O466Y272.js → chunk-VPBAUQ2M.js} +7 -7
  46. package/dist/chunk-VQY5W4YW.cjs +311 -0
  47. package/dist/chunk-WLYIIEAF.js +50 -0
  48. package/dist/chunk-WNY4WMRF.js +32 -0
  49. package/dist/chunk-XEKD23J5.js +9 -0
  50. package/dist/chunk-XK5CIRMQ.js +112 -0
  51. package/dist/chunk-XSVNC2UD.cjs +18 -0
  52. package/dist/chunk-XTEI64OU.js +145 -0
  53. package/dist/chunk-XX6NQJMA.js +92 -0
  54. package/dist/{chunk-745DV5FL.js → chunk-Y7FO65VT.js} +3 -3
  55. package/dist/{chunk-PXUJF5HS.js → chunk-ZY6KU6P3.js} +4 -2
  56. package/dist/completion/CompletionService.cjs +30 -17
  57. package/dist/completion/CompletionService.js +29 -16
  58. package/dist/completion/NativeSearchInjector.cjs +3 -3
  59. package/dist/completion/NativeSearchInjector.js +2 -2
  60. package/dist/completion/openrouter-headers.cjs +3 -6
  61. package/dist/completion/openrouter-headers.d.cts +9 -12
  62. package/dist/completion/openrouter-headers.d.ts +9 -12
  63. package/dist/completion/openrouter-headers.js +2 -5
  64. package/dist/completion/openrouter-models.cjs +4 -3
  65. package/dist/completion/openrouter-models.js +2 -1
  66. package/dist/completion.cjs +30 -17
  67. package/dist/completion.js +29 -16
  68. package/dist/index.cjs +151 -20
  69. package/dist/index.d.cts +44 -10
  70. package/dist/index.d.ts +44 -10
  71. package/dist/index.js +160 -29
  72. package/dist/keyPolicy-Cp0FntZl.d.cts +90 -0
  73. package/dist/keyPolicy-Cp0FntZl.d.ts +90 -0
  74. package/dist/outbound-api/auditCapture.cjs +9 -0
  75. package/dist/outbound-api/auditCapture.d.cts +52 -0
  76. package/dist/outbound-api/auditCapture.d.ts +52 -0
  77. package/dist/outbound-api/auditCapture.js +9 -0
  78. package/dist/outbound-api/auditRedact.cjs +8 -0
  79. package/dist/outbound-api/auditRedact.d.cts +30 -0
  80. package/dist/outbound-api/auditRedact.d.ts +30 -0
  81. package/dist/outbound-api/auditRedact.js +8 -0
  82. package/dist/outbound-api/billingCapture.cjs +8 -0
  83. package/dist/outbound-api/billingCapture.d.cts +61 -0
  84. package/dist/outbound-api/billingCapture.d.ts +61 -0
  85. package/dist/outbound-api/billingCapture.js +8 -0
  86. package/dist/outbound-api/quotaWarn.cjs +12 -0
  87. package/dist/outbound-api/quotaWarn.d.cts +43 -0
  88. package/dist/outbound-api/quotaWarn.d.ts +43 -0
  89. package/dist/outbound-api/quotaWarn.js +12 -0
  90. package/dist/outbound-api/routeResolver.cjs +5 -2
  91. package/dist/outbound-api/routeResolver.d.cts +9 -2
  92. package/dist/outbound-api/routeResolver.d.ts +9 -2
  93. package/dist/outbound-api/routeResolver.js +4 -1
  94. package/dist/outbound-api/types.cjs +6 -1
  95. package/dist/outbound-api/types.d.cts +12 -144
  96. package/dist/outbound-api/types.d.ts +12 -144
  97. package/dist/outbound-api/types.js +6 -0
  98. package/dist/outbound-api.cjs +144 -17
  99. package/dist/outbound-api.d.cts +655 -25
  100. package/dist/outbound-api.d.ts +655 -25
  101. package/dist/outbound-api.js +148 -21
  102. package/dist/pipeline/AuthSource.d.cts +29 -1
  103. package/dist/pipeline/AuthSource.d.ts +29 -1
  104. package/dist/pipeline/LlmConfigProviderAuth.cjs +3 -3
  105. package/dist/pipeline/LlmConfigProviderAuth.js +2 -2
  106. package/dist/pipeline/SubscriptionAccountHealth.cjs +22 -0
  107. package/dist/pipeline/SubscriptionAccountHealth.d.cts +235 -0
  108. package/dist/pipeline/SubscriptionAccountHealth.d.ts +235 -0
  109. package/dist/pipeline/SubscriptionAccountHealth.js +22 -0
  110. package/dist/pipeline/SubscriptionAuthSource.cjs +2 -2
  111. package/dist/pipeline/SubscriptionAuthSource.d.cts +3 -2
  112. package/dist/pipeline/SubscriptionAuthSource.d.ts +3 -2
  113. package/dist/pipeline/SubscriptionAuthSource.js +1 -1
  114. package/dist/pipeline/SubscriptionAuthStrategy.d.cts +30 -1
  115. package/dist/pipeline/SubscriptionAuthStrategy.d.ts +30 -1
  116. package/dist/pipeline/auditSink.cjs +14 -0
  117. package/dist/pipeline/auditSink.d.cts +48 -0
  118. package/dist/pipeline/auditSink.d.ts +48 -0
  119. package/dist/pipeline/auditSink.js +14 -0
  120. package/dist/pipeline/auditUsageStash.cjs +10 -0
  121. package/dist/pipeline/auditUsageStash.d.cts +37 -0
  122. package/dist/pipeline/auditUsageStash.d.ts +37 -0
  123. package/dist/pipeline/auditUsageStash.js +10 -0
  124. package/dist/pipeline/billingEmit.cjs +14 -0
  125. package/dist/pipeline/billingEmit.d.cts +49 -0
  126. package/dist/pipeline/billingEmit.d.ts +49 -0
  127. package/dist/pipeline/billingEmit.js +14 -0
  128. package/dist/pipeline/executeProviderCall.cjs +2 -2
  129. package/dist/pipeline/executeProviderCall.js +1 -1
  130. package/dist/pipeline/upstreamFetch.cjs +14 -0
  131. package/dist/pipeline/upstreamFetch.d.cts +83 -0
  132. package/dist/pipeline/upstreamFetch.d.ts +83 -0
  133. package/dist/pipeline/upstreamFetch.js +14 -0
  134. package/dist/pipeline/webhookEmit.cjs +10 -0
  135. package/dist/pipeline/webhookEmit.d.cts +36 -0
  136. package/dist/pipeline/webhookEmit.d.ts +36 -0
  137. package/dist/pipeline/webhookEmit.js +10 -0
  138. package/dist/ports/usage-event-store.d.cts +26 -1
  139. package/dist/ports/usage-event-store.d.ts +26 -1
  140. package/dist/ports.d.cts +8 -1
  141. package/dist/ports.d.ts +8 -1
  142. package/dist/provider-proxy/ProviderProxy.cjs +30 -17
  143. package/dist/provider-proxy/ProviderProxy.js +29 -16
  144. package/dist/provider-proxy/identity/SubscriptionIdentityStore.cjs +15 -0
  145. package/dist/provider-proxy/identity/SubscriptionIdentityStore.d.cts +121 -0
  146. package/dist/provider-proxy/identity/SubscriptionIdentityStore.d.ts +121 -0
  147. package/dist/provider-proxy/identity/SubscriptionIdentityStore.js +15 -0
  148. package/dist/provider-proxy/identity/fingerprintHeaders.cjs +20 -0
  149. package/dist/provider-proxy/identity/fingerprintHeaders.d.cts +89 -0
  150. package/dist/provider-proxy/identity/fingerprintHeaders.d.ts +89 -0
  151. package/dist/provider-proxy/identity/fingerprintHeaders.js +20 -0
  152. package/dist/provider-proxy/ingress/providerProxyShared.cjs +30 -17
  153. package/dist/provider-proxy/ingress/providerProxyShared.d.cts +11 -2
  154. package/dist/provider-proxy/ingress/providerProxyShared.d.ts +11 -2
  155. package/dist/provider-proxy/ingress/providerProxyShared.js +29 -16
  156. package/dist/provider-proxy/matchText.cjs +4 -2
  157. package/dist/provider-proxy/matchText.d.cts +14 -1
  158. package/dist/provider-proxy/matchText.d.ts +14 -1
  159. package/dist/provider-proxy/matchText.js +3 -1
  160. package/dist/provider-proxy/types.d.cts +30 -0
  161. package/dist/provider-proxy/types.d.ts +30 -0
  162. package/dist/provider-proxy.cjs +30 -17
  163. package/dist/provider-proxy.js +29 -16
  164. package/dist/{routeResolver-HE-ZO0fO.d.ts → routeResolver-C4T7yClx.d.ts} +36 -10
  165. package/dist/{routeResolver-BrbK6ja9.d.cts → routeResolver-CB3tvJKy.d.cts} +36 -10
  166. package/dist/transformer/transformers/OpenAIResponseTransformer.cjs +2 -2
  167. package/dist/transformer/transformers/OpenAIResponseTransformer.js +1 -1
  168. package/dist/transformer/transformers.cjs +7 -7
  169. package/dist/transformer/transformers.js +8 -8
  170. package/dist/transformer.cjs +9 -9
  171. package/dist/transformer.js +8 -8
  172. package/dist/types-B8Arpxn0.d.cts +754 -0
  173. package/dist/types-lgPYQuZS.d.ts +754 -0
  174. package/dist/usage/usage-recorder.cjs +3 -2
  175. package/dist/usage/usage-recorder.d.cts +19 -1
  176. package/dist/usage/usage-recorder.d.ts +19 -1
  177. package/dist/usage/usage-recorder.js +2 -1
  178. package/dist/usage.cjs +3 -2
  179. package/dist/usage.js +2 -1
  180. package/package.json +64 -62
  181. package/dist/chunk-3MEACFK3.js +0 -193
  182. package/dist/chunk-6VIXXLMX.cjs +0 -14
  183. package/dist/chunk-E3WHL7CO.js +0 -14
  184. package/dist/chunk-G2FUJNA2.cjs +0 -193
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Sayo
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sayo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/NOTICE CHANGED
@@ -1,57 +1,57 @@
1
- @omnicross/core — THIRD-PARTY NOTICES
2
- ======================================
3
-
4
- This package contains code adapted from, and depends on, the following
5
- third-party works. Their respective licenses apply to those portions.
6
-
7
- --------------------------------------------------------------------------------
8
- 1. musistudio/llms (MIT License)
9
- --------------------------------------------------------------------------------
10
-
11
- The transformer subsystem (`src/transformer/`) — the unified-IR request/response
12
- transformer chain (`TransformerService`, `TransformerChainExecutor`, and the
13
- built-in transformers) — is adapted from the `musistudio/llms` project, the
14
- upstream of the transformer intermediate representation.
15
-
16
- Copyright (c) 2025 musistudio
17
- https://github.com/musistudio/llms
18
-
19
- Permission is hereby granted, free of charge, to any person obtaining a copy
20
- of this software and associated documentation files (the "Software"), to deal
21
- in the Software without restriction, including without limitation the rights
22
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
23
- copies of the Software, and to permit persons to whom the Software is
24
- furnished to do so, subject to the following conditions:
25
-
26
- The above copyright notice and this permission notice shall be included in
27
- all copies or substantial portions of the Software.
28
-
29
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35
- SOFTWARE.
36
-
37
- --------------------------------------------------------------------------------
38
- 2. @mozilla/readability (Apache License 2.0)
39
- --------------------------------------------------------------------------------
40
-
41
- The built-in web-fetch tool (`src/completion/builtin-web-fetch.ts`) uses
42
- `@mozilla/readability` to extract readable article content from fetched HTML.
43
-
44
- Copyright Mozilla Foundation and contributors
45
- https://github.com/mozilla/readability
46
-
47
- Licensed under the Apache License, Version 2.0 (the "License"); you may not
48
- use this file except in compliance with the License. You may obtain a copy of
49
- the License at
50
-
51
- http://www.apache.org/licenses/LICENSE-2.0
52
-
53
- Unless required by applicable law or agreed to in writing, software
54
- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
55
- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
56
- License for the specific language governing permissions and limitations under
57
- the License.
1
+ @omnicross/core — THIRD-PARTY NOTICES
2
+ ======================================
3
+
4
+ This package contains code adapted from, and depends on, the following
5
+ third-party works. Their respective licenses apply to those portions.
6
+
7
+ --------------------------------------------------------------------------------
8
+ 1. musistudio/llms (MIT License)
9
+ --------------------------------------------------------------------------------
10
+
11
+ The transformer subsystem (`src/transformer/`) — the unified-IR request/response
12
+ transformer chain (`TransformerService`, `TransformerChainExecutor`, and the
13
+ built-in transformers) — is adapted from the `musistudio/llms` project, the
14
+ upstream of the transformer intermediate representation.
15
+
16
+ Copyright (c) 2025 musistudio
17
+ https://github.com/musistudio/llms
18
+
19
+ Permission is hereby granted, free of charge, to any person obtaining a copy
20
+ of this software and associated documentation files (the "Software"), to deal
21
+ in the Software without restriction, including without limitation the rights
22
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
23
+ copies of the Software, and to permit persons to whom the Software is
24
+ furnished to do so, subject to the following conditions:
25
+
26
+ The above copyright notice and this permission notice shall be included in
27
+ all copies or substantial portions of the Software.
28
+
29
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35
+ SOFTWARE.
36
+
37
+ --------------------------------------------------------------------------------
38
+ 2. @mozilla/readability (Apache License 2.0)
39
+ --------------------------------------------------------------------------------
40
+
41
+ The built-in web-fetch tool (`src/completion/builtin-web-fetch.ts`) uses
42
+ `@mozilla/readability` to extract readable article content from fetched HTML.
43
+
44
+ Copyright Mozilla Foundation and contributors
45
+ https://github.com/mozilla/readability
46
+
47
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not
48
+ use this file except in compliance with the License. You may obtain a copy of
49
+ the License at
50
+
51
+ http://www.apache.org/licenses/LICENSE-2.0
52
+
53
+ Unless required by applicable law or agreed to in writing, software
54
+ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
55
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
56
+ License for the specific language governing permissions and limitations under
57
+ the License.
package/README.md CHANGED
@@ -1,15 +1,15 @@
1
- # @omnicross/core
2
-
3
- The omnicross LLM serving core — provider dispatch, the completion pipeline, the transformer chain, the outbound API server, and the resident provider proxy. Embed it in any Node project, or run it via [`@omnicross/daemon`](https://www.npmjs.com/package/@omnicross/daemon).
4
-
5
- Part of the [omnicross](https://github.com/Dumoedss/omnicross) monorepo — see the root README for the full overview.
6
-
7
- ```bash
8
- npm install @omnicross/core @omnicross/contracts
9
- ```
10
-
11
- ## License
12
-
13
- [MIT](LICENSE)
14
-
15
- This package adapts third-party work under its own license — see the `NOTICE` file.
1
+ # @omnicross/core
2
+
3
+ The omnicross LLM serving core — provider dispatch, the completion pipeline, the transformer chain, the outbound API server, and the resident provider proxy. Embed it in any Node project, or run it via [`@omnicross/daemon`](https://www.npmjs.com/package/@omnicross/daemon).
4
+
5
+ Part of the [omnicross](https://github.com/Dumoedss/omnicross) monorepo — see the root README for the full overview.
6
+
7
+ ```bash
8
+ npm install @omnicross/core @omnicross/contracts
9
+ ```
10
+
11
+ ## License
12
+
13
+ [MIT](LICENSE)
14
+
15
+ This package adapts third-party work under its own license — see the `NOTICE` file.
@@ -4,6 +4,9 @@
4
4
  var _chunkRSJ3TWJQcjs = require('../chunk-RSJ3TWJQ.cjs');
5
5
  require('../chunk-YGXJGRFI.cjs');
6
6
 
7
+
8
+ var _chunkOCEUVQHWcjs = require('../chunk-OCEUVQHW.cjs');
9
+
7
10
  // src/auth/GeminiCodeAssistProjectResolver.ts
8
11
  var FREE_TIER_ID = "free-tier";
9
12
  var LEGACY_TIER_ID = "legacy-tier";
@@ -20,7 +23,9 @@ var GeminiCodeAssistHandshakeError = class extends Error {
20
23
 
21
24
  };
22
25
  var GeminiCodeAssistProjectResolver = (_class = class {
23
- constructor(fetchImpl = (url, init) => fetch(url, init)) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);
26
+ // upstream-proxy: the Code Assist handshake is upstream egress → honor the
27
+ // gemini proxy by default (still injectable for tests).
28
+ constructor(fetchImpl = (url, init) => _chunkOCEUVQHWcjs.fetchUpstream.call(void 0, url, init, { providerId: "gemini" })) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);
24
29
  this.fetchImpl = fetchImpl;
25
30
  }
26
31
 
@@ -3,6 +3,9 @@ import {
3
3
  resolveCodeAssistEndpoint
4
4
  } from "../chunk-Z7Y2NPHY.js";
5
5
  import "../chunk-S4WBV25P.js";
6
+ import {
7
+ fetchUpstream
8
+ } from "../chunk-XK5CIRMQ.js";
6
9
 
7
10
  // src/auth/GeminiCodeAssistProjectResolver.ts
8
11
  var FREE_TIER_ID = "free-tier";
@@ -20,7 +23,9 @@ var GeminiCodeAssistHandshakeError = class extends Error {
20
23
  code;
21
24
  };
22
25
  var GeminiCodeAssistProjectResolver = class {
23
- constructor(fetchImpl = (url, init) => fetch(url, init)) {
26
+ // upstream-proxy: the Code Assist handshake is upstream egress → honor the
27
+ // gemini proxy by default (still injectable for tests).
28
+ constructor(fetchImpl = (url, init) => fetchUpstream(url, init, { providerId: "gemini" })) {
24
29
  this.fetchImpl = fetchImpl;
25
30
  }
26
31
  fetchImpl;
@@ -0,0 +1,33 @@
1
+ // src/outbound-api/quotaWarn.ts
2
+ var WEBHOOK_QUOTA_WARN_RATIO = 0.8;
3
+ function computeQuotaWarnings(limits, spend, ratio = WEBHOOK_QUOTA_WARN_RATIO) {
4
+ const out = [];
5
+ const consider = (scope, limit, spent, windowStart) => {
6
+ if (limit == null || limit <= 0) return;
7
+ if (spent >= limit) return;
8
+ if (spent >= ratio * limit) out.push({ scope, limitUsd: limit, spentUsd: spent, windowStart });
9
+ };
10
+ consider("daily", limits.dailyUsd, spend.dailyUsd, spend.dailyWindowStart);
11
+ consider("weekly", limits.weeklyUsd, spend.weeklyUsd, spend.weeklyWindowStart);
12
+ consider("total", limits.totalUsd, spend.totalUsd, 0);
13
+ return out;
14
+ }
15
+ var WARN_GUARD_MAX = 1e4;
16
+ var warned = /* @__PURE__ */ new Set();
17
+ function markQuotaWarnedOnce(keyId, scope, windowStart) {
18
+ const key = `${keyId}\0${scope}\0${windowStart}`;
19
+ if (warned.has(key)) return false;
20
+ if (warned.size >= WARN_GUARD_MAX) warned.clear();
21
+ warned.add(key);
22
+ return true;
23
+ }
24
+ function __resetQuotaWarnGuardForTests() {
25
+ warned.clear();
26
+ }
27
+
28
+ export {
29
+ WEBHOOK_QUOTA_WARN_RATIO,
30
+ computeQuotaWarnings,
31
+ markQuotaWarnedOnce,
32
+ __resetQuotaWarnGuardForTests
33
+ };
@@ -0,0 +1,9 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/outbound-api/types.ts
2
+ var ENDPOINT_MODEL_KINDS = {
3
+ messages: ["fable", "opus", "sonnet", "haiku"],
4
+ responses: ["codex", "mini"]
5
+ };
6
+
7
+
8
+
9
+ exports.ENDPOINT_MODEL_KINDS = ENDPOINT_MODEL_KINDS;
@@ -0,0 +1,33 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/outbound-api/quotaWarn.ts
2
+ var WEBHOOK_QUOTA_WARN_RATIO = 0.8;
3
+ function computeQuotaWarnings(limits, spend, ratio = WEBHOOK_QUOTA_WARN_RATIO) {
4
+ const out = [];
5
+ const consider = (scope, limit, spent, windowStart) => {
6
+ if (limit == null || limit <= 0) return;
7
+ if (spent >= limit) return;
8
+ if (spent >= ratio * limit) out.push({ scope, limitUsd: limit, spentUsd: spent, windowStart });
9
+ };
10
+ consider("daily", limits.dailyUsd, spend.dailyUsd, spend.dailyWindowStart);
11
+ consider("weekly", limits.weeklyUsd, spend.weeklyUsd, spend.weeklyWindowStart);
12
+ consider("total", limits.totalUsd, spend.totalUsd, 0);
13
+ return out;
14
+ }
15
+ var WARN_GUARD_MAX = 1e4;
16
+ var warned = /* @__PURE__ */ new Set();
17
+ function markQuotaWarnedOnce(keyId, scope, windowStart) {
18
+ const key = `${keyId}\0${scope}\0${windowStart}`;
19
+ if (warned.has(key)) return false;
20
+ if (warned.size >= WARN_GUARD_MAX) warned.clear();
21
+ warned.add(key);
22
+ return true;
23
+ }
24
+ function __resetQuotaWarnGuardForTests() {
25
+ warned.clear();
26
+ }
27
+
28
+
29
+
30
+
31
+
32
+
33
+ exports.WEBHOOK_QUOTA_WARN_RATIO = WEBHOOK_QUOTA_WARN_RATIO; exports.computeQuotaWarnings = computeQuotaWarnings; exports.markQuotaWarnedOnce = markQuotaWarnedOnce; exports.__resetQuotaWarnGuardForTests = __resetQuotaWarnGuardForTests;
@@ -0,0 +1,311 @@
1
+ // src/pipeline/SubscriptionAccountHealth.ts
2
+ var OVERLOAD_TTL_MS = 10 * 6e4;
3
+ var OVERLOAD_ENABLED_DEFAULT = true;
4
+ var AUTH_ERROR_TTL_MS = 30 * 6e4;
5
+ var SERVER_ERROR_TTL_MS = 5 * 6e4;
6
+ var BAN_BODY_MARKERS = [
7
+ "this organization has been disabled",
8
+ "oauth authentication is currently not allowed"
9
+ ];
10
+ function readHeader(headers, name) {
11
+ if (typeof headers.get === "function") {
12
+ return headers.get(name);
13
+ }
14
+ const rec = headers;
15
+ return rec[name] ?? rec[name.toLowerCase()] ?? null;
16
+ }
17
+ function parseIntHeader(value) {
18
+ if (value == null) return null;
19
+ const n = Number.parseInt(value.trim(), 10);
20
+ return Number.isFinite(n) ? n : null;
21
+ }
22
+ function resolveResetSeconds(providerId, headers) {
23
+ const unified = parseIntHeader(readHeader(headers, "anthropic-ratelimit-unified-reset"));
24
+ if (providerId === "claude") {
25
+ return { resetHeaderSeconds: unified, retryAfterSeconds: null };
26
+ }
27
+ const providerReset = parseIntHeader(readHeader(headers, "x-ratelimit-reset")) ?? parseIntHeader(readHeader(headers, "ratelimit-reset"));
28
+ const retryAfter = parseIntHeader(readHeader(headers, "retry-after"));
29
+ return {
30
+ resetHeaderSeconds: unified ?? providerReset,
31
+ retryAfterSeconds: retryAfter
32
+ };
33
+ }
34
+ function isBanBody(bodyText) {
35
+ if (!bodyText) return false;
36
+ const lower = bodyText.toLowerCase();
37
+ return BAN_BODY_MARKERS.some((marker) => lower.includes(marker));
38
+ }
39
+ function isRecordEmpty(record) {
40
+ return record.rateLimitEndAt === void 0 && record.overloadUntil === void 0 && record.tempUnavailableUntil === void 0 && !record.blocked;
41
+ }
42
+ var KEY_SEP = "\0";
43
+ var SubscriptionAccountHealth = class {
44
+ records = /* @__PURE__ */ new Map();
45
+ listeners = /* @__PURE__ */ new Set();
46
+ anomalyListeners = /* @__PURE__ */ new Set();
47
+ now;
48
+ overloadEnabled;
49
+ overloadTtlMs;
50
+ authErrorTtlMs;
51
+ serverErrorTtlMs;
52
+ constructor(opts = {}) {
53
+ this.now = opts.now ?? Date.now;
54
+ this.overloadEnabled = opts.overloadEnabled ?? OVERLOAD_ENABLED_DEFAULT;
55
+ this.overloadTtlMs = opts.overloadTtlMs ?? OVERLOAD_TTL_MS;
56
+ this.authErrorTtlMs = opts.authErrorTtlMs ?? AUTH_ERROR_TTL_MS;
57
+ this.serverErrorTtlMs = opts.serverErrorTtlMs ?? SERVER_ERROR_TTL_MS;
58
+ }
59
+ /**
60
+ * Re-apply cooldown config to the LIVE shared instance (subscription-account-
61
+ * health, LEAD OQ1). `buildDaemon` is synchronous so it cannot await the
62
+ * persisted server config; the async `start.ts` path loads it and applies the
63
+ * `accountHealth` segment here — every strategy/relay/sweeper that already
64
+ * captured this instance picks the new values up. Only defined fields override.
65
+ */
66
+ configure(opts) {
67
+ if (opts.overloadEnabled !== void 0) this.overloadEnabled = opts.overloadEnabled;
68
+ if (opts.overloadTtlMs !== void 0) this.overloadTtlMs = opts.overloadTtlMs;
69
+ if (opts.authErrorTtlMs !== void 0) this.authErrorTtlMs = opts.authErrorTtlMs;
70
+ if (opts.serverErrorTtlMs !== void 0) this.serverErrorTtlMs = opts.serverErrorTtlMs;
71
+ }
72
+ /**
73
+ * Whether an account may be scheduled RIGHT NOW. `blocked` → false; any timer
74
+ * still in the future → false. Expired timers are lazily deleted on read (CRS
75
+ * lazy-clear parity) so an elapsed cooldown restores the account WITHOUT a
76
+ * timer — but the recovery SIGNAL is the sweeper's job (`sweepRecoveries`), so
77
+ * this read never emits (correctness is independent of the tick).
78
+ */
79
+ isSchedulable(providerId, accountId, now = this.now()) {
80
+ const key = this.key(providerId, accountId);
81
+ const record = this.records.get(key);
82
+ if (!record) return true;
83
+ if (record.blocked) return false;
84
+ const active = this.clearExpired(record, now);
85
+ if (!active && isRecordEmpty(record)) this.records.delete(key);
86
+ return !active;
87
+ }
88
+ /**
89
+ * The single marking entry point (design D3). Faithful to CRS status semantics:
90
+ * - 429 + authoritative reset → `rateLimitEndAt`; a non-claude 429 may use
91
+ * `retryAfterSeconds`; a bare 429 (no resolvable reset) is NOT marked;
92
+ * - 529 → `overloadUntil` (gated by `overloadEnabled`);
93
+ * - 403-ban body → `blocked` (permanent); plain 403 → transient;
94
+ * - final-401 → transient; 5xx / thrown(null) → transient;
95
+ * - non-429 4xx → NEUTRAL (never marked);
96
+ * - 2xx → clear rate-limit + transient state (keep `blocked`).
97
+ */
98
+ recordUpstreamOutcome(providerId, accountId, input) {
99
+ const now = input.now ?? this.now();
100
+ const key = this.key(providerId, accountId);
101
+ const preExisting = this.records.get(key);
102
+ const record = preExisting ?? {};
103
+ const status = input.status;
104
+ const wasUnhealthyBefore = preExisting ? this.isUnhealthyAt(preExisting, now) : false;
105
+ let anomalyState;
106
+ let recovered = false;
107
+ if (status === null) {
108
+ record.tempUnavailableUntil = now + this.serverErrorTtlMs;
109
+ } else if (status >= 200 && status < 300) {
110
+ const wasUnhealthy = record.rateLimitEndAt !== void 0 || record.overloadUntil !== void 0 || record.tempUnavailableUntil !== void 0;
111
+ delete record.rateLimitEndAt;
112
+ delete record.overloadUntil;
113
+ delete record.tempUnavailableUntil;
114
+ recovered = wasUnhealthy && !record.blocked;
115
+ } else if (status === 429) {
116
+ if (input.resetHeaderSeconds != null) {
117
+ record.rateLimitEndAt = input.resetHeaderSeconds * 1e3;
118
+ anomalyState = "rate_limited";
119
+ } else if (input.retryAfterSeconds != null) {
120
+ record.rateLimitEndAt = now + input.retryAfterSeconds * 1e3;
121
+ anomalyState = "rate_limited";
122
+ }
123
+ } else if (status === 529) {
124
+ if (this.overloadEnabled) {
125
+ record.overloadUntil = now + this.overloadTtlMs;
126
+ anomalyState = "overloaded";
127
+ }
128
+ } else if (status === 403) {
129
+ if (isBanBody(input.bodyText)) {
130
+ record.blocked = true;
131
+ anomalyState = "blocked";
132
+ } else {
133
+ record.tempUnavailableUntil = now + this.authErrorTtlMs;
134
+ anomalyState = "unauthorized";
135
+ }
136
+ } else if (status === 401) {
137
+ record.tempUnavailableUntil = now + this.authErrorTtlMs;
138
+ anomalyState = "unauthorized";
139
+ } else if (status >= 500) {
140
+ record.tempUnavailableUntil = now + this.serverErrorTtlMs;
141
+ }
142
+ if (isRecordEmpty(record)) this.records.delete(key);
143
+ else this.records.set(key, record);
144
+ if (recovered) this.emit({ providerId, accountId, at: now, kind: "rateLimitRecovery" });
145
+ if (anomalyState && !wasUnhealthyBefore) {
146
+ this.emitAnomaly({ providerId, accountId, at: now, state: anomalyState });
147
+ }
148
+ }
149
+ /** Whether a record is unhealthy at `now`: blocked, or any timer still future. */
150
+ isUnhealthyAt(record, now) {
151
+ if (record.blocked) return true;
152
+ if (record.rateLimitEndAt !== void 0 && now < record.rateLimitEndAt) return true;
153
+ if (record.overloadUntil !== void 0 && now < record.overloadUntil) return true;
154
+ if (record.tempUnavailableUntil !== void 0 && now < record.tempUnavailableUntil) return true;
155
+ return false;
156
+ }
157
+ /**
158
+ * Clear ONLY the auth/transient unavailability mark (`tempUnavailableUntil`) —
159
+ * the narrow healing a background PROBE is allowed to do (subscription-account-
160
+ * probe #8, review M1). A probe 2xx from the lightweight `GET /v1/models` attests
161
+ * the TOKEN works (so a final-401 / plain-403 / 5xx transient may be healed), but
162
+ * it does NOT prove the traffic endpoint's rate-limit / overload has recovered —
163
+ * so it MUST NOT touch `rateLimitEndAt` / `overloadUntil` (those clear only on the
164
+ * upstream's authoritative reset, or a REAL-traffic 2xx). `blocked` (a ban) is
165
+ * never cleared here. Distinct from `recordUpstreamOutcome`'s 2xx path, which is
166
+ * UNCHANGED and still clears rate + transient together because it IS traffic.
167
+ * Returns whether a transient mark was actually cleared. Does NOT emit a recovery
168
+ * signal (a probe is internal maintenance; the account is schedulable-on-read).
169
+ */
170
+ clearTransientMark(providerId, accountId) {
171
+ const key = this.key(providerId, accountId);
172
+ const record = this.records.get(key);
173
+ if (!record || record.tempUnavailableUntil === void 0) return false;
174
+ delete record.tempUnavailableUntil;
175
+ if (isRecordEmpty(record)) this.records.delete(key);
176
+ else this.records.set(key, record);
177
+ return true;
178
+ }
179
+ /**
180
+ * Proactively surface accounts that transitioned unhealthy → schedulable since
181
+ * the last sweep (design D6). Clears their expired timers, emits a recovery
182
+ * signal for each through `onRecovered`, and returns the list. A `blocked`
183
+ * account never recovers here. Correctness does NOT depend on this running —
184
+ * `isSchedulable` already restores an elapsed cooldown lazily; this adds the
185
+ * proactive signal (#5/#8) + lets the daemon nudge a token refresh.
186
+ */
187
+ sweepRecoveries(now = this.now()) {
188
+ const recovered = [];
189
+ for (const [key, record] of this.records) {
190
+ if (record.blocked) continue;
191
+ const hadTimer = record.rateLimitEndAt !== void 0 || record.overloadUntil !== void 0 || record.tempUnavailableUntil !== void 0;
192
+ const active = this.clearExpired(record, now);
193
+ if (hadTimer && !active && isRecordEmpty(record)) {
194
+ const [pid, aid] = this.parseKey(key);
195
+ recovered.push({ providerId: pid, accountId: aid, at: now, kind: "rateLimitRecovery" });
196
+ this.records.delete(key);
197
+ }
198
+ }
199
+ for (const event of recovered) this.emit(event);
200
+ return recovered;
201
+ }
202
+ /** Admin-facing coarse status + cooldown-until for one account (secret-free). */
203
+ getStatus(providerId, accountId, now = this.now()) {
204
+ const record = this.records.get(this.key(providerId, accountId));
205
+ if (!record) return { state: "healthy" };
206
+ if (record.blocked) return { state: "blocked" };
207
+ if (record.rateLimitEndAt !== void 0 && now < record.rateLimitEndAt) {
208
+ return { state: "rate_limited", cooldownUntil: record.rateLimitEndAt };
209
+ }
210
+ if (record.overloadUntil !== void 0 && now < record.overloadUntil) {
211
+ return { state: "overloaded", cooldownUntil: record.overloadUntil };
212
+ }
213
+ if (record.tempUnavailableUntil !== void 0 && now < record.tempUnavailableUntil) {
214
+ return { state: "transient", cooldownUntil: record.tempUnavailableUntil };
215
+ }
216
+ return { state: "healthy" };
217
+ }
218
+ /**
219
+ * Register a recovery listener (the OQ3 seam #5 webhooks + #8 health-cron
220
+ * consume). Returns an unsubscribe function. Two edges fire it:
221
+ * - TRAFFIC-DRIVEN: a `recordUpstreamOutcome` 2xx that clears an unhealthy
222
+ * account (guaranteed — the sweep would miss it, as the 2xx deletes the
223
+ * record first); and
224
+ * - PURE-IDLE: `sweepRecoveries` when an idle account's cooldown elapsed with
225
+ * no traffic (best-effort, on the 60s tick).
226
+ * A lazy `isSchedulable` read that heals an account does NOT emit (a request is
227
+ * already using it) — so consumers never double-count a recovery.
228
+ */
229
+ onRecovered(listener) {
230
+ this.listeners.add(listener);
231
+ return () => this.listeners.delete(listener);
232
+ }
233
+ emit(event) {
234
+ for (const listener of this.listeners) {
235
+ try {
236
+ listener(event);
237
+ } catch {
238
+ }
239
+ }
240
+ }
241
+ /**
242
+ * Register an anomaly listener (the ADDITIVE seam #5 webhooks consumes; the
243
+ * frozen `kind` discriminator on {@link AccountRecoveryEvent} anticipated it).
244
+ * Fires ONLY on the healthy→unhealthy EDGE inside `recordUpstreamOutcome`
245
+ * (de-duped: an already-unhealthy account escalating does NOT re-fire). Returns
246
+ * an unsubscribe function. Existing marking/recovery behavior is UNCHANGED.
247
+ */
248
+ onAnomaly(listener) {
249
+ this.anomalyListeners.add(listener);
250
+ return () => this.anomalyListeners.delete(listener);
251
+ }
252
+ emitAnomaly(event) {
253
+ for (const listener of this.anomalyListeners) {
254
+ try {
255
+ listener(event);
256
+ } catch {
257
+ }
258
+ }
259
+ }
260
+ /**
261
+ * Delete every EXPIRED timer field on the record in place; return whether any
262
+ * timer is STILL active (in the future). `blocked` is not a timer and is left
263
+ * untouched here (only an explicit reset / restart clears a ban).
264
+ */
265
+ clearExpired(record, now) {
266
+ let active = false;
267
+ if (record.rateLimitEndAt !== void 0) {
268
+ if (now >= record.rateLimitEndAt) delete record.rateLimitEndAt;
269
+ else active = true;
270
+ }
271
+ if (record.overloadUntil !== void 0) {
272
+ if (now >= record.overloadUntil) delete record.overloadUntil;
273
+ else active = true;
274
+ }
275
+ if (record.tempUnavailableUntil !== void 0) {
276
+ if (now >= record.tempUnavailableUntil) delete record.tempUnavailableUntil;
277
+ else active = true;
278
+ }
279
+ return active;
280
+ }
281
+ key(providerId, accountId) {
282
+ return `${providerId}${KEY_SEP}${accountId}`;
283
+ }
284
+ parseKey(key) {
285
+ const idx = key.indexOf(KEY_SEP);
286
+ return [key.slice(0, idx), key.slice(idx + 1)];
287
+ }
288
+ };
289
+ var _shared = null;
290
+ function getSharedAccountHealth() {
291
+ if (!_shared) _shared = new SubscriptionAccountHealth();
292
+ return _shared;
293
+ }
294
+ function setSharedAccountHealth(instance) {
295
+ _shared = instance;
296
+ }
297
+ function __resetSharedAccountHealthForTests() {
298
+ _shared = null;
299
+ }
300
+
301
+ export {
302
+ OVERLOAD_TTL_MS,
303
+ OVERLOAD_ENABLED_DEFAULT,
304
+ AUTH_ERROR_TTL_MS,
305
+ SERVER_ERROR_TTL_MS,
306
+ resolveResetSeconds,
307
+ SubscriptionAccountHealth,
308
+ getSharedAccountHealth,
309
+ setSharedAccountHealth,
310
+ __resetSharedAccountHealthForTests
311
+ };