@omnicross/core 0.1.10 → 0.2.1

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 (204) hide show
  1. package/README.md +7 -0
  2. package/dist/{BuiltinToolExecutor-CS2WpXhM.d.cts → BuiltinToolExecutor-BHgH-EaZ.d.cts} +25 -2
  3. package/dist/{BuiltinToolExecutor-BluWyeob.d.ts → BuiltinToolExecutor-Bi1LmiTP.d.ts} +25 -2
  4. package/dist/{CompletionService-kNA17cfI.d.cts → CompletionService-BniP7j88.d.cts} +2 -2
  5. package/dist/{CompletionService-C3BX0Ovy.d.ts → CompletionService-BqrKPwfA.d.ts} +2 -2
  6. package/dist/{ProviderProxy-QdwNV6l1.d.cts → ProviderProxy-Bz_nkOwq.d.cts} +1 -1
  7. package/dist/{ProviderProxy--ROec6VI.d.ts → ProviderProxy-Ckr6oTrE.d.ts} +1 -1
  8. package/dist/auth/GeminiCodeAssistProjectResolver.cjs +6 -6
  9. package/dist/auth/GeminiCodeAssistProjectResolver.js +4 -4
  10. package/dist/{chunk-NGYOO5TO.js → chunk-2C3TTBS7.js} +7 -7
  11. package/dist/{chunk-QUSEZNYS.cjs → chunk-32SRZFFP.cjs} +4 -1
  12. package/dist/chunk-4JOU54M5.js +200 -0
  13. package/dist/{chunk-2UTGX6FM.js → chunk-4VVCXVB7.js} +1 -1
  14. package/dist/{chunk-RJUONLUQ.cjs → chunk-4Z3ZLLC2.cjs} +14 -8
  15. package/dist/chunk-6DDYNS2B.cjs +384 -0
  16. package/dist/{chunk-GXEZ2R3E.js → chunk-6OKXH2TW.js} +18 -7
  17. package/dist/{chunk-YWL7YZWS.cjs → chunk-7LRTPNFL.cjs} +5 -0
  18. package/dist/{chunk-CCVRRJOX.js → chunk-7PIUVCKK.js} +9 -2
  19. package/dist/chunk-7RJI3NDI.cjs +236 -0
  20. package/dist/{chunk-IIRPUVPH.cjs → chunk-7ZHBN75N.cjs} +3 -1
  21. package/dist/chunk-D4WNI6BR.cjs +386 -0
  22. package/dist/chunk-DBBR6RHF.js +236 -0
  23. package/dist/chunk-E4QHVXV5.cjs +118 -0
  24. package/dist/{chunk-HKB656B4.js → chunk-EUZRH544.js} +55 -287
  25. package/dist/{chunk-WNKWAEUR.js → chunk-EYGBM2VC.js} +3 -1
  26. package/dist/{chunk-UWDW6PN3.cjs → chunk-FX325I5Q.cjs} +20 -9
  27. package/dist/chunk-G4CZIUIB.cjs +200 -0
  28. package/dist/chunk-HCOQQAZE.cjs +123 -0
  29. package/dist/chunk-HL2YSPL7.cjs +673 -0
  30. package/dist/{chunk-55FMGZ3L.js → chunk-HN74IGEO.js} +1 -1
  31. package/dist/{chunk-ZY6KU6P3.js → chunk-HOMUGKHR.js} +8 -5
  32. package/dist/{chunk-AOFWNWLT.cjs → chunk-IUL4VWNU.cjs} +22 -1
  33. package/dist/{chunk-5LNYGCIW.cjs → chunk-KIQ2HA2A.cjs} +5 -5
  34. package/dist/{chunk-MUHWHQVM.cjs → chunk-KQBLZMP6.cjs} +4 -3
  35. package/dist/chunk-LFEH7CEO.js +384 -0
  36. package/dist/chunk-LFPQ2OVH.js +386 -0
  37. package/dist/{chunk-FEBAQI5A.js → chunk-LKDAN4D7.js} +6363 -1350
  38. package/dist/chunk-LQYS2N47.js +3923 -0
  39. package/dist/{chunk-NZYN7C3P.cjs → chunk-MPXOKQJP.cjs} +53 -53
  40. package/dist/chunk-MZEGQSKQ.js +118 -0
  41. package/dist/chunk-N76KU6F5.js +123 -0
  42. package/dist/chunk-NLUOTJWB.js +673 -0
  43. package/dist/{chunk-CMVXX7ON.cjs → chunk-NOITAVHA.cjs} +114 -58
  44. package/dist/{chunk-Q27JY5RG.cjs → chunk-OIKREZVQ.cjs} +7 -4
  45. package/dist/{chunk-ZQQUD66M.cjs → chunk-POUTD5AM.cjs} +63 -295
  46. package/dist/{chunk-6D4W22P4.js → chunk-QIIAMBTM.js} +4 -1
  47. package/dist/{chunk-56QD3YW6.cjs → chunk-QWNUOR7F.cjs} +11 -4
  48. package/dist/{chunk-S3DYFEBE.js → chunk-R4VCO2CB.js} +10 -1
  49. package/dist/{chunk-4VZX5F4T.cjs → chunk-T6NWPIYZ.cjs} +5 -2
  50. package/dist/{chunk-EBLFCNPY.js → chunk-U47LQXPB.js} +5 -2
  51. package/dist/chunk-UPQIWJIE.cjs +3923 -0
  52. package/dist/{chunk-N7OOJI5V.js → chunk-V2UKUTJ3.js} +5 -0
  53. package/dist/{chunk-45FHEOKW.js → chunk-V53ZEFXC.js} +92 -36
  54. package/dist/{chunk-RJ5ZGNI3.js → chunk-VL5TUDTM.js} +8 -2
  55. package/dist/{chunk-TIT74RIL.cjs → chunk-VSYQ6XYN.cjs} +6837 -1824
  56. package/dist/{chunk-OC6DOOFX.cjs → chunk-VXRTQZF2.cjs} +5 -5
  57. package/dist/{chunk-RICPANBY.cjs → chunk-WX2E2G7H.cjs} +13 -4
  58. package/dist/{chunk-DE2SRBFZ.js → chunk-X335TJNS.js} +4 -3
  59. package/dist/{chunk-CDHS2QDC.js → chunk-Y4CRNHJO.js} +53 -53
  60. package/dist/{chunk-P7EM6BND.cjs → chunk-ZAPN7XA6.cjs} +10 -10
  61. package/dist/{chunk-N2EIM2XJ.js → chunk-ZLNHPUFA.js} +22 -1
  62. package/dist/completion/BuiltinToolExecutor.cjs +2 -2
  63. package/dist/completion/BuiltinToolExecutor.d.cts +3 -1
  64. package/dist/completion/BuiltinToolExecutor.d.ts +3 -1
  65. package/dist/completion/BuiltinToolExecutor.js +1 -1
  66. package/dist/completion/CompletionService.cjs +32 -28
  67. package/dist/completion/CompletionService.d.cts +7 -3
  68. package/dist/completion/CompletionService.d.ts +7 -3
  69. package/dist/completion/CompletionService.js +31 -27
  70. package/dist/completion.cjs +40 -36
  71. package/dist/completion.d.cts +7 -3
  72. package/dist/completion.d.ts +7 -3
  73. package/dist/completion.js +39 -35
  74. package/dist/egress-I46O_p5L.d.cts +126 -0
  75. package/dist/egress-I46O_p5L.d.ts +126 -0
  76. package/dist/frontends-Doz0RaWu.d.cts +97 -0
  77. package/dist/frontends-Doz0RaWu.d.ts +97 -0
  78. package/dist/image-generation.cjs +52 -0
  79. package/dist/image-generation.d.cts +96 -0
  80. package/dist/image-generation.d.ts +96 -0
  81. package/dist/image-generation.js +52 -0
  82. package/dist/index.cjs +142 -32
  83. package/dist/index.d.cts +16 -8
  84. package/dist/index.d.ts +16 -8
  85. package/dist/index.js +159 -49
  86. package/dist/openai-operation.cjs +18 -0
  87. package/dist/openai-operation.d.cts +22 -0
  88. package/dist/openai-operation.d.ts +22 -0
  89. package/dist/openai-operation.js +18 -0
  90. package/dist/outbound-api/auditCapture.cjs +3 -3
  91. package/dist/outbound-api/auditCapture.d.cts +13 -2
  92. package/dist/outbound-api/auditCapture.d.ts +13 -2
  93. package/dist/outbound-api/auditCapture.js +2 -2
  94. package/dist/outbound-api/auditRedact.cjs +2 -2
  95. package/dist/outbound-api/auditRedact.js +1 -1
  96. package/dist/outbound-api/routeResolver.cjs +2 -2
  97. package/dist/outbound-api/routeResolver.d.cts +11 -4
  98. package/dist/outbound-api/routeResolver.d.ts +11 -4
  99. package/dist/outbound-api/routeResolver.js +1 -1
  100. package/dist/outbound-api/subscriptionRegistryPort.d.cts +5 -1
  101. package/dist/outbound-api/subscriptionRegistryPort.d.ts +5 -1
  102. package/dist/outbound-api/types.d.cts +10 -3
  103. package/dist/outbound-api/types.d.ts +10 -3
  104. package/dist/outbound-api.cjs +65 -33
  105. package/dist/outbound-api.d.cts +205 -10
  106. package/dist/outbound-api.d.ts +205 -10
  107. package/dist/outbound-api.js +64 -32
  108. package/dist/pipeline/AccountAllowanceScheduling.d.cts +22 -15
  109. package/dist/pipeline/AccountAllowanceScheduling.d.ts +22 -15
  110. package/dist/pipeline/LlmConfigProviderAuth.cjs +3 -3
  111. package/dist/pipeline/LlmConfigProviderAuth.js +2 -2
  112. package/dist/pipeline/SubscriptionAccountHealth.cjs +2 -2
  113. package/dist/pipeline/SubscriptionAccountHealth.d.cts +7 -0
  114. package/dist/pipeline/SubscriptionAccountHealth.d.ts +7 -0
  115. package/dist/pipeline/SubscriptionAccountHealth.js +1 -1
  116. package/dist/pipeline/executeProviderCall.cjs +2 -2
  117. package/dist/pipeline/executeProviderCall.d.cts +11 -6
  118. package/dist/pipeline/executeProviderCall.d.ts +11 -6
  119. package/dist/pipeline/executeProviderCall.js +1 -1
  120. package/dist/pipeline/upstreamFetch.cjs +2 -2
  121. package/dist/pipeline/upstreamFetch.d.cts +5 -0
  122. package/dist/pipeline/upstreamFetch.d.ts +5 -0
  123. package/dist/pipeline/upstreamFetch.js +1 -1
  124. package/dist/ports.d.cts +10 -3
  125. package/dist/ports.d.ts +10 -3
  126. package/dist/provider-proxy/ProviderProxy.cjs +32 -28
  127. package/dist/provider-proxy/ProviderProxy.d.cts +6 -2
  128. package/dist/provider-proxy/ProviderProxy.d.ts +6 -2
  129. package/dist/provider-proxy/ProviderProxy.js +31 -27
  130. package/dist/provider-proxy/identity/codexCliHeaders.cjs +4 -2
  131. package/dist/provider-proxy/identity/codexCliHeaders.d.cts +26 -6
  132. package/dist/provider-proxy/identity/codexCliHeaders.d.ts +26 -6
  133. package/dist/provider-proxy/identity/codexCliHeaders.js +5 -3
  134. package/dist/provider-proxy/ingress/providerProxyShared.cjs +36 -28
  135. package/dist/provider-proxy/ingress/providerProxyShared.d.cts +41 -9
  136. package/dist/provider-proxy/ingress/providerProxyShared.d.ts +41 -9
  137. package/dist/provider-proxy/ingress/providerProxyShared.js +35 -27
  138. package/dist/provider-proxy/types.d.cts +17 -483
  139. package/dist/provider-proxy/types.d.ts +17 -483
  140. package/dist/provider-proxy.cjs +46 -28
  141. package/dist/provider-proxy.d.cts +34 -8
  142. package/dist/provider-proxy.d.ts +34 -8
  143. package/dist/provider-proxy.js +45 -27
  144. package/dist/proxy-UZTtjPZx.d.cts +18 -0
  145. package/dist/proxy-UZTtjPZx.d.ts +18 -0
  146. package/dist/{routeResolver-CVFE8KKe.d.cts → routeResolver-Da0yvkL1.d.cts} +4 -2
  147. package/dist/{routeResolver-C0mkkZaM.d.ts → routeResolver-STwMz_G4.d.ts} +4 -2
  148. package/dist/runtime-6QXNU526.cjs +8 -0
  149. package/dist/runtime-M5WXLD2R.js +8 -0
  150. package/dist/runtime-t8AZacFF.d.cts +233 -0
  151. package/dist/runtime-t8AZacFF.d.ts +233 -0
  152. package/dist/search/api.cjs +761 -0
  153. package/dist/search/api.d.cts +370 -0
  154. package/dist/search/api.d.ts +370 -0
  155. package/dist/search/api.js +761 -0
  156. package/dist/search/http.cjs +37 -0
  157. package/dist/search/http.d.cts +269 -0
  158. package/dist/search/http.d.ts +269 -0
  159. package/dist/search/http.js +37 -0
  160. package/dist/search.cjs +57 -0
  161. package/dist/search.d.cts +113 -0
  162. package/dist/search.d.ts +113 -0
  163. package/dist/search.js +57 -0
  164. package/dist/transformer/TransformerChainExecutor.cjs +2 -2
  165. package/dist/transformer/TransformerChainExecutor.d.cts +2 -2
  166. package/dist/transformer/TransformerChainExecutor.d.ts +2 -2
  167. package/dist/transformer/TransformerChainExecutor.js +1 -1
  168. package/dist/transformer/transformers/AnthropicOpenAIToAnthropicStream.cjs +16 -0
  169. package/dist/transformer/transformers/AnthropicOpenAIToAnthropicStream.d.cts +53 -0
  170. package/dist/transformer/transformers/AnthropicOpenAIToAnthropicStream.d.ts +53 -0
  171. package/dist/transformer/transformers/AnthropicOpenAIToAnthropicStream.js +16 -0
  172. package/dist/transformer/transformers/AnthropicTransformer.cjs +4 -3
  173. package/dist/transformer/transformers/AnthropicTransformer.js +3 -2
  174. package/dist/transformer/transformers/GeminiCodeAssistTransformer.cjs +4 -4
  175. package/dist/transformer/transformers/GeminiCodeAssistTransformer.js +3 -3
  176. package/dist/transformer/transformers/GeminiTransformer.cjs +4 -4
  177. package/dist/transformer/transformers/GeminiTransformer.js +3 -3
  178. package/dist/transformer/transformers/OpenAIResponseTransformer.cjs +3 -3
  179. package/dist/transformer/transformers/OpenAIResponseTransformer.js +2 -2
  180. package/dist/transformer/transformers/OpenAITransformer.cjs +3 -3
  181. package/dist/transformer/transformers/OpenAITransformer.js +2 -2
  182. package/dist/transformer/transformers.cjs +11 -10
  183. package/dist/transformer/transformers.js +12 -11
  184. package/dist/transformer/types.d.cts +39 -4
  185. package/dist/transformer/types.d.ts +39 -4
  186. package/dist/transformer.cjs +14 -13
  187. package/dist/transformer.js +13 -12
  188. package/dist/types-BSIJdsyl.d.cts +1130 -0
  189. package/dist/types-Be-yt_6T.d.cts +196 -0
  190. package/dist/types-By9Tg6-I.d.ts +1130 -0
  191. package/dist/types-CbCZqLGg.d.cts +127 -0
  192. package/dist/types-CbCZqLGg.d.ts +127 -0
  193. package/dist/{types-C2MwkLah.d.cts → types-D-oHYusb.d.cts} +250 -21
  194. package/dist/types-Dm4_36V4.d.ts +196 -0
  195. package/dist/{types-BB8pxk_3.d.ts → types-Dvlpjn0d.d.ts} +250 -21
  196. package/dist/usage.cjs +2 -2
  197. package/dist/usage.d.cts +6 -1
  198. package/dist/usage.d.ts +6 -1
  199. package/dist/usage.js +1 -1
  200. package/package.json +71 -64
  201. package/dist/chunk-FCR77GYM.cjs +0 -33
  202. package/dist/chunk-K5NM7VAH.js +0 -33
  203. /package/dist/{chunk-XXFYLL7R.js → chunk-ECZ3ZE2C.js} +0 -0
  204. /package/dist/{chunk-3SCOLIPT.cjs → chunk-MXI2PWIC.cjs} +0 -0
@@ -0,0 +1,236 @@
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; }// src/search/egress.ts
2
+ var _dns = require('dns');
3
+ var _net = require('net');
4
+
5
+
6
+
7
+ var _searchtypes = require('@omnicross/contracts/search-types');
8
+ var _undici = require('undici');
9
+ var DEFAULT_SEARCH_EGRESS_POLICY = Object.freeze({});
10
+ var ALLOWED_SCHEMES = /* @__PURE__ */ new Set(["http:", "https:"]);
11
+ var METADATA_HOSTNAMES = /* @__PURE__ */ new Set(["metadata.google.internal"]);
12
+ var DENIAL_TEXT = Object.freeze({
13
+ scheme: "only http and https are permitted",
14
+ malformed: "the request target is not a valid absolute URL",
15
+ loopback: "loopback addresses are not permitted",
16
+ unspecified: "unspecified addresses are not permitted",
17
+ "link-local": "link-local addresses are not permitted",
18
+ private: "private addresses are not permitted",
19
+ "unique-local": "unique-local addresses are not permitted",
20
+ metadata: "cloud metadata endpoints are not permitted"
21
+ });
22
+ function validateEgressUrl(url, policy = DEFAULT_SEARCH_EGRESS_POLICY, providerId) {
23
+ let parsed;
24
+ try {
25
+ parsed = url instanceof URL ? url : new URL(url);
26
+ } catch (e) {
27
+ throw egressDenied("unknown-host", "malformed", providerId);
28
+ }
29
+ if (!ALLOWED_SCHEMES.has(parsed.protocol)) {
30
+ throw egressDenied(parsed.hostname || "unknown-host", "scheme", providerId, parsed.protocol);
31
+ }
32
+ const hostname = parsed.hostname;
33
+ if (isAllowlisted(hostname, policy)) return parsed;
34
+ const denial = classifyHostname(hostname);
35
+ if (denial) throw egressDenied(hostname, denial, providerId);
36
+ return parsed;
37
+ }
38
+ function assertEgressAddressAllowed(address, hostname, policy = DEFAULT_SEARCH_EGRESS_POLICY, providerId) {
39
+ if (isAllowlisted(hostname, policy)) return;
40
+ const denial = classifyAddress(address);
41
+ if (denial) throw egressDenied(hostname, denial, providerId, void 0, address);
42
+ }
43
+ function isAllowlisted(hostname, policy) {
44
+ const allowed = policy.allowedPrivateHosts;
45
+ if (!allowed || allowed.length === 0) return false;
46
+ const normalized = normalizeHostname(hostname);
47
+ return allowed.some((entry) => normalizeHostname(entry) === normalized);
48
+ }
49
+ function normalizeHostname(hostname) {
50
+ const trimmed = hostname.trim().toLowerCase().replace(/\.+$/, "");
51
+ return trimmed.startsWith("[") && trimmed.endsWith("]") ? trimmed.slice(1, -1) : trimmed;
52
+ }
53
+ function classifyHostname(hostname) {
54
+ const candidate = normalizeHostname(hostname);
55
+ if (candidate === "") return "malformed";
56
+ const version = _net.isIP.call(void 0, candidate);
57
+ if (version !== 0) return classifyAddress(candidate);
58
+ if (candidate === "localhost" || candidate.endsWith(".localhost")) return "loopback";
59
+ if (METADATA_HOSTNAMES.has(candidate)) return "metadata";
60
+ return void 0;
61
+ }
62
+ function classifyAddress(address) {
63
+ const candidate = normalizeHostname(address);
64
+ const version = _net.isIP.call(void 0, candidate);
65
+ if (version === 4) return classifyIPv4(candidate);
66
+ if (version === 6) return classifyIPv6(candidate);
67
+ return "malformed";
68
+ }
69
+ function classifyIPv4(address) {
70
+ const octets = address.split(".").map((part) => Number.parseInt(part, 10));
71
+ if (octets.length !== 4 || octets.some((octet) => !Number.isInteger(octet))) return "malformed";
72
+ const [a, b, c, d] = octets;
73
+ if (a === 127) return "loopback";
74
+ if (a === 0) return "unspecified";
75
+ if (a === 10) return "private";
76
+ if (a === 172 && b >= 16 && b <= 31) return "private";
77
+ if (a === 192 && b === 168) return "private";
78
+ if (a === 169 && b === 254 && c === 169 && d === 254) return "metadata";
79
+ if (a === 169 && b === 254) return "link-local";
80
+ return void 0;
81
+ }
82
+ function classifyIPv6(address) {
83
+ const pieces = parseIPv6Pieces(address);
84
+ if (!pieces) return "malformed";
85
+ const topIsZero = pieces.slice(0, 5).every((piece) => piece === 0);
86
+ if (topIsZero && (pieces[5] === 65535 || pieces[5] === 0)) {
87
+ const embedded = [pieces[6] >> 8, pieces[6] & 255, pieces[7] >> 8, pieces[7] & 255];
88
+ const isLoopbackOrUnspecified = pieces[5] === 0 && pieces[6] === 0 && pieces[7] <= 1;
89
+ if (isLoopbackOrUnspecified) return pieces[7] === 1 ? "loopback" : "unspecified";
90
+ return classifyIPv4(embedded.join("."));
91
+ }
92
+ if ((pieces[0] & 65472) === 65152) return "link-local";
93
+ if ((pieces[0] & 65024) === 64512) return "unique-local";
94
+ return void 0;
95
+ }
96
+ function parseIPv6Pieces(address) {
97
+ let text = address.split("%")[0];
98
+ const lastColon = text.lastIndexOf(":");
99
+ const tail = text.slice(lastColon + 1);
100
+ if (tail.includes(".")) {
101
+ if (_net.isIP.call(void 0, tail) !== 4) return void 0;
102
+ const octets = tail.split(".").map((part) => Number.parseInt(part, 10));
103
+ const high = (octets[0] << 8 | octets[1]).toString(16);
104
+ const low = (octets[2] << 8 | octets[3]).toString(16);
105
+ text = `${text.slice(0, lastColon + 1)}${high}:${low}`;
106
+ }
107
+ const halves = text.split("::");
108
+ if (halves.length > 2) return void 0;
109
+ const head = halves[0] === "" ? [] : halves[0].split(":");
110
+ const rest = halves.length === 2 ? halves[1] === "" ? [] : halves[1].split(":") : [];
111
+ let groups;
112
+ if (halves.length === 1) {
113
+ if (head.length !== 8) return void 0;
114
+ groups = head;
115
+ } else {
116
+ const zeros = 8 - head.length - rest.length;
117
+ if (zeros < 1) return void 0;
118
+ groups = [...head, ...Array.from({ length: zeros }, () => "0"), ...rest];
119
+ }
120
+ const pieces = [];
121
+ for (const group of groups) {
122
+ if (!/^[0-9a-f]{1,4}$/i.test(group)) return void 0;
123
+ pieces.push(Number.parseInt(group, 16));
124
+ }
125
+ return pieces;
126
+ }
127
+ function egressDenied(hostname, reason, providerId, scheme, resolvedAddress) {
128
+ const subject = scheme ? `scheme "${scheme}"` : `host "${hostname}"`;
129
+ const via = resolvedAddress ? ` (resolved to a ${reason} address)` : "";
130
+ const details = { host: hostname, egressClass: reason };
131
+ if (resolvedAddress) details.egressStage = "dns";
132
+ return new (0, _searchtypes.SearchProviderError)(
133
+ "policy_denied",
134
+ `egress policy denied ${subject}${via}: ${DENIAL_TEXT[reason]}`,
135
+ {
136
+ providerId,
137
+ retryable: false,
138
+ details
139
+ }
140
+ );
141
+ }
142
+ function findEgressDenial(error) {
143
+ let current = error;
144
+ for (let depth = 0; depth < 6 && current !== void 0 && current !== null; depth += 1) {
145
+ if (_searchtypes.isSearchProviderError.call(void 0, current) && current.code === "policy_denied") {
146
+ return current;
147
+ }
148
+ current = current instanceof Error ? current.cause : void 0;
149
+ }
150
+ return void 0;
151
+ }
152
+ function createEgressGuardedLookup(policy = DEFAULT_SEARCH_EGRESS_POLICY, lookupImpl = _dns.lookup) {
153
+ const guarded = (hostname, options, callback) => {
154
+ const requestedAll = Boolean(_optionalChain([options, 'optionalAccess', _ => _.all]));
155
+ const lookupOptions = { ...options, all: true };
156
+ lookupImpl(hostname, lookupOptions, (error, addresses) => {
157
+ if (error) {
158
+ callback(error);
159
+ return;
160
+ }
161
+ const entries = Array.isArray(addresses) ? addresses : [];
162
+ if (entries.length === 0) {
163
+ callback(new Error(`no addresses resolved for ${hostname}`));
164
+ return;
165
+ }
166
+ try {
167
+ for (const entry of entries) assertEgressAddressAllowed(entry.address, hostname, policy);
168
+ } catch (denial) {
169
+ callback(denial);
170
+ return;
171
+ }
172
+ if (requestedAll) callback(null, entries);
173
+ else callback(null, entries[0].address, entries[0].family);
174
+ });
175
+ };
176
+ return guarded;
177
+ }
178
+ var guardedDispatchers = /* @__PURE__ */ new Map();
179
+ function createEgressGuardedDispatcher(policy = DEFAULT_SEARCH_EGRESS_POLICY, lookupImpl) {
180
+ if (lookupImpl) {
181
+ return new (0, _undici.Agent)({ connect: { lookup: createEgressGuardedLookup(policy, lookupImpl) } });
182
+ }
183
+ const signature = JSON.stringify(normalizePolicy(policy));
184
+ const cached = guardedDispatchers.get(signature);
185
+ if (cached) return cached;
186
+ const dispatcher = new (0, _undici.Agent)({ connect: { lookup: createEgressGuardedLookup(policy) } });
187
+ guardedDispatchers.set(signature, dispatcher);
188
+ return dispatcher;
189
+ }
190
+ function normalizePolicy(policy) {
191
+ return {
192
+ allowedPrivateHosts: [..._nullishCoalesce(policy.allowedPrivateHosts, () => ( []))].map(normalizeHostname).sort((left, right) => left < right ? -1 : left > right ? 1 : 0)
193
+ };
194
+ }
195
+
196
+ // src/search/http/proxy.ts
197
+
198
+ var cachedProxySignature = "";
199
+ var cachedProxyDispatcher;
200
+ function resolveSearchProxySettings(env = process.env) {
201
+ const allProxy = firstNonEmpty(env.all_proxy, env.ALL_PROXY);
202
+ const httpProxy = firstNonEmpty(env.http_proxy, env.HTTP_PROXY, allProxy);
203
+ const httpsProxy = firstNonEmpty(env.https_proxy, env.HTTPS_PROXY, allProxy);
204
+ if (!httpProxy && !httpsProxy) return void 0;
205
+ const noProxy = firstNonEmpty(env.no_proxy, env.NO_PROXY);
206
+ return {
207
+ ...httpProxy ? { httpProxy } : {},
208
+ ...httpsProxy ? { httpsProxy } : {},
209
+ ...noProxy ? { noProxy } : {}
210
+ };
211
+ }
212
+ function getSearchProxyDispatcher(proxy) {
213
+ const signature = JSON.stringify(proxy);
214
+ if (cachedProxyDispatcher && cachedProxySignature === signature) return cachedProxyDispatcher;
215
+ cachedProxySignature = signature;
216
+ cachedProxyDispatcher = new (0, _undici.EnvHttpProxyAgent)(proxy);
217
+ return cachedProxyDispatcher;
218
+ }
219
+ function firstNonEmpty(...values) {
220
+ for (const value of values) {
221
+ const trimmed = _optionalChain([value, 'optionalAccess', _2 => _2.trim, 'call', _3 => _3()]);
222
+ if (trimmed) return trimmed;
223
+ }
224
+ return void 0;
225
+ }
226
+
227
+
228
+
229
+
230
+
231
+
232
+
233
+
234
+
235
+
236
+ exports.DEFAULT_SEARCH_EGRESS_POLICY = DEFAULT_SEARCH_EGRESS_POLICY; exports.validateEgressUrl = validateEgressUrl; exports.assertEgressAddressAllowed = assertEgressAddressAllowed; exports.findEgressDenial = findEgressDenial; exports.createEgressGuardedLookup = createEgressGuardedLookup; exports.createEgressGuardedDispatcher = createEgressGuardedDispatcher; exports.resolveSearchProxySettings = resolveSearchProxySettings; exports.getSearchProxyDispatcher = getSearchProxyDispatcher;
@@ -30,6 +30,7 @@ var TransformerChainExecutor = class {
30
30
  providerName: provider.name
31
31
  };
32
32
  let requestBody = request;
33
+ let endpointRequest;
33
34
  let config = {};
34
35
  let bypass = false;
35
36
  bypass = this.shouldBypassTransformers(
@@ -60,6 +61,7 @@ var TransformerChainExecutor = class {
60
61
  this.logger.error(`transformRequestOut error: ${this.getErrorMessage(error)}`);
61
62
  throw error;
62
63
  }
64
+ endpointRequest = requestBody;
63
65
  }
64
66
  if (!bypass && chain.providerTransformers.length > 0) {
65
67
  this.logger.debug(`Executing ${chain.providerTransformers.length} provider transformers`);
@@ -118,7 +120,7 @@ var TransformerChainExecutor = class {
118
120
  true
119
121
  );
120
122
  }
121
- return { requestBody, config, bypass };
123
+ return { requestBody, endpointRequest, config, bypass };
122
124
  }
123
125
  /**
124
126
  * Execute the response transformation chain
@@ -0,0 +1,386 @@
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;
2
+
3
+ var _chunkHL2YSPL7cjs = require('./chunk-HL2YSPL7.cjs');
4
+
5
+ // src/search/orchestrator.ts
6
+ var _searchtypes = require('@omnicross/contracts/search-types');
7
+ var _crypto = require('crypto');
8
+
9
+ // src/search/normalize.ts
10
+ var DEFAULT_NORMALIZED_MAX_RESULTS = 5;
11
+ var SERP_REDIRECT_RULES = [
12
+ { domain: "google.com", paths: ["/search", "/goto"] },
13
+ { domain: "bing.com", paths: ["/search"] },
14
+ { domain: "duckduckgo.com", paths: ["/html/", "/l/"] },
15
+ { domain: "baidu.com", paths: ["/s"] }
16
+ ];
17
+ function isDirectResultUrl(rawUrl) {
18
+ let url;
19
+ try {
20
+ url = new URL(rawUrl);
21
+ } catch (e) {
22
+ return false;
23
+ }
24
+ if (url.protocol !== "http:" && url.protocol !== "https:") return false;
25
+ const host = url.hostname.toLowerCase();
26
+ for (const rule of SERP_REDIRECT_RULES) {
27
+ if (host !== rule.domain && !host.endsWith(`.${rule.domain}`)) continue;
28
+ if (rule.paths.includes(url.pathname)) return false;
29
+ }
30
+ return true;
31
+ }
32
+ function normalizedResultLimit(maxResults) {
33
+ const requested = maxResults === void 0 || !Number.isFinite(maxResults) ? DEFAULT_NORMALIZED_MAX_RESULTS : Math.floor(maxResults);
34
+ return Math.max(1, requested);
35
+ }
36
+ function normalizeSearchResults(results, maxResults) {
37
+ const limit = normalizedResultLimit(maxResults);
38
+ const seenUrls = /* @__PURE__ */ new Set();
39
+ const normalized = [];
40
+ for (const result of results) {
41
+ if (result === null || typeof result !== "object") continue;
42
+ const title = typeof result.title === "string" ? result.title.trim() : "";
43
+ const url = typeof result.url === "string" ? result.url.trim() : "";
44
+ if (title.length === 0 || !isDirectResultUrl(url)) continue;
45
+ if (seenUrls.has(url)) continue;
46
+ seenUrls.add(url);
47
+ normalized.push({
48
+ title,
49
+ url,
50
+ content: typeof result.content === "string" ? result.content.trim() : ""
51
+ });
52
+ if (normalized.length >= limit) break;
53
+ }
54
+ return normalized;
55
+ }
56
+
57
+ // src/search/orchestrator.ts
58
+ var QUERY_HASH_LENGTH = 12;
59
+ function hashSearchQuery(query) {
60
+ return _crypto.createHash.call(void 0, "sha256").update(query).digest("hex").slice(0, QUERY_HASH_LENGTH);
61
+ }
62
+ var SearchOrchestrator = class {
63
+
64
+
65
+
66
+ constructor(registry, options = {}) {
67
+ this.registry = registry;
68
+ this.defaultPolicy = _nullishCoalesce(options.policy, () => ( {}));
69
+ this.onEvent = options.onEvent;
70
+ }
71
+ /**
72
+ * Run one search.
73
+ *
74
+ * @param request - the query, an optional pinned provider, and per-request
75
+ * options. `options` is passed to the provider untouched: providers own
76
+ * their own timeouts and the orchestrator adds no second timeout layer.
77
+ * @param policyOverride - per-request policy, merged field-by-field over the
78
+ * orchestrator's default.
79
+ * @throws {SearchProviderError} when no provider produced a response.
80
+ */
81
+ async search(request, policyOverride) {
82
+ const policy = { ...this.defaultPolicy, ...policyOverride };
83
+ const requestId = _crypto.randomUUID.call(void 0, );
84
+ const queryHash = hashSearchQuery(request.query);
85
+ const startedAt = Date.now();
86
+ const attempts = [];
87
+ const emitComplete = (providerId, resultCount) => {
88
+ this.emit({
89
+ type: "search_complete",
90
+ requestId,
91
+ queryHash,
92
+ ...providerId === void 0 ? {} : { providerId },
93
+ resultCount,
94
+ fallbackCount: fallbackCountOf(attempts),
95
+ durationMs: Date.now() - startedAt
96
+ });
97
+ };
98
+ let plan;
99
+ try {
100
+ plan = this.planCandidates(request, policy);
101
+ } catch (error) {
102
+ emitComplete(void 0, 0);
103
+ throw error;
104
+ }
105
+ if (plan.skippedPreferred !== void 0) {
106
+ this.emit({
107
+ type: "search_attempt",
108
+ requestId,
109
+ queryHash,
110
+ providerId: plan.skippedPreferred.providerId,
111
+ outcome: "failed",
112
+ errorCode: plan.skippedPreferred.errorCode,
113
+ durationMs: 0
114
+ });
115
+ }
116
+ let lastError;
117
+ for (const candidate of plan.candidates) {
118
+ const attemptStartedAt = Date.now();
119
+ try {
120
+ const produced = await candidate.provider.search(request.query, request.options);
121
+ const durationMs = Date.now() - attemptStartedAt;
122
+ const results = normalizeSearchResults(produced, _optionalChain([request, 'access', _ => _.options, 'optionalAccess', _2 => _2.maxResults]));
123
+ attempts.push({
124
+ providerId: candidate.id,
125
+ outcome: "success",
126
+ resultCount: results.length,
127
+ durationMs
128
+ });
129
+ this.emit({
130
+ type: "search_attempt",
131
+ requestId,
132
+ queryHash,
133
+ providerId: candidate.id,
134
+ outcome: "success",
135
+ resultCount: results.length,
136
+ durationMs
137
+ });
138
+ emitComplete(candidate.id, results.length);
139
+ return {
140
+ query: request.query,
141
+ providerId: candidate.id,
142
+ results,
143
+ attempts,
144
+ fallbackCount: fallbackCountOf(attempts)
145
+ };
146
+ } catch (error) {
147
+ const durationMs = Date.now() - attemptStartedAt;
148
+ const shape = _searchtypes.toSearchErrorShape.call(void 0, error);
149
+ const isCancelled = shape.code === "cancelled" || _optionalChain([request, 'access', _3 => _3.options, 'optionalAccess', _4 => _4.signal, 'optionalAccess', _5 => _5.aborted]) === true;
150
+ const errorCode = isCancelled ? "cancelled" : shape.code;
151
+ attempts.push({
152
+ providerId: candidate.id,
153
+ outcome: "failed",
154
+ errorCode,
155
+ durationMs
156
+ });
157
+ this.emit({
158
+ type: "search_attempt",
159
+ requestId,
160
+ queryHash,
161
+ providerId: candidate.id,
162
+ outcome: "failed",
163
+ errorCode,
164
+ durationMs
165
+ });
166
+ if (isCancelled) {
167
+ emitComplete(void 0, 0);
168
+ throw shape.code === "cancelled" ? error : new (0, _searchtypes.SearchProviderError)("cancelled", "search was cancelled by the caller", {
169
+ providerId: candidate.id,
170
+ retryable: false,
171
+ cause: error
172
+ });
173
+ }
174
+ lastError = asSearchProviderError(error, shape.code, shape.message, candidate.id);
175
+ }
176
+ }
177
+ emitComplete(void 0, 0);
178
+ throw exhaustionError(attempts, lastError);
179
+ }
180
+ /** Resolve the candidate list for one request. */
181
+ planCandidates(request, policy) {
182
+ if (request.provider !== void 0) {
183
+ const pinned = this.registry.get(request.provider);
184
+ if (pinned === void 0) {
185
+ throw new (0, _searchtypes.SearchProviderError)(
186
+ "upstream_unavailable",
187
+ `search provider '${request.provider}' is not registered in this runtime`,
188
+ { providerId: request.provider, retryable: false }
189
+ );
190
+ }
191
+ if (!isAllowed(pinned.id, policy)) {
192
+ throw new (0, _searchtypes.SearchProviderError)(
193
+ "policy_denied",
194
+ `search provider '${request.provider}' is not allowed by the active search policy`,
195
+ { providerId: request.provider, retryable: false }
196
+ );
197
+ }
198
+ return { candidates: [pinned] };
199
+ }
200
+ const allowed = this.registry.list().filter((entry) => isAllowed(entry.id, policy));
201
+ let ordered = allowed;
202
+ let skippedPreferred;
203
+ if (policy.preferred !== void 0) {
204
+ const preferred = allowed.find((entry) => entry.id === policy.preferred);
205
+ if (preferred === void 0) {
206
+ skippedPreferred = {
207
+ providerId: policy.preferred,
208
+ errorCode: this.registry.has(policy.preferred) ? "policy_denied" : "upstream_unavailable"
209
+ };
210
+ } else {
211
+ ordered = [preferred, ...allowed.filter((entry) => entry.id !== preferred.id)];
212
+ }
213
+ }
214
+ if (policy.fallbackEnabled === false) ordered = ordered.slice(0, 1);
215
+ if (policy.maxAttempts !== void 0) {
216
+ ordered = ordered.slice(0, Math.max(0, Math.floor(policy.maxAttempts)));
217
+ }
218
+ return { candidates: ordered, ...skippedPreferred === void 0 ? {} : { skippedPreferred } };
219
+ }
220
+ /** Deliver one event. A listener that throws must never fail a search. */
221
+ emit(event) {
222
+ if (this.onEvent === void 0) return;
223
+ try {
224
+ this.onEvent(event);
225
+ } catch (e2) {
226
+ }
227
+ }
228
+ };
229
+ function fallbackCountOf(attempts) {
230
+ return Math.max(0, attempts.length - 1);
231
+ }
232
+ function isAllowed(id, policy) {
233
+ return policy.allowed === void 0 || policy.allowed.includes(id);
234
+ }
235
+ function asSearchProviderError(error, code, message, providerId) {
236
+ if (error instanceof _searchtypes.SearchProviderError) return error;
237
+ return new (0, _searchtypes.SearchProviderError)(code, message, { providerId, cause: error });
238
+ }
239
+ function exhaustionError(attempts, lastError) {
240
+ if (attempts.length === 1 && lastError !== void 0) return lastError;
241
+ if (attempts.length === 0) {
242
+ return new (0, _searchtypes.SearchProviderError)(
243
+ "upstream_unavailable",
244
+ "no eligible search provider was available (0 attempts)",
245
+ { retryable: false }
246
+ );
247
+ }
248
+ const trail = attempts.map((attempt) => `${attempt.providerId}:${_nullishCoalesce(attempt.errorCode, () => ( "unknown"))}`).join(",");
249
+ return new (0, _searchtypes.SearchProviderError)(
250
+ _nullishCoalesce(_optionalChain([lastError, 'optionalAccess', _6 => _6.code]), () => ( "upstream_unavailable")),
251
+ `search failed after ${attempts.length} attempt(s)`,
252
+ { retryable: _optionalChain([lastError, 'optionalAccess', _7 => _7.retryable]), details: { attempts: trail }, cause: lastError }
253
+ );
254
+ }
255
+
256
+ // src/search/registry.ts
257
+ var SearchRegistryError = class _SearchRegistryError extends Error {
258
+ constructor(message) {
259
+ super(message);
260
+ this.name = "SearchRegistryError";
261
+ Object.setPrototypeOf(this, _SearchRegistryError.prototype);
262
+ }
263
+ };
264
+ var SearchProviderRegistry = (_class = class {
265
+ __init() {this.entries = /* @__PURE__ */ new Map()}
266
+
267
+ __init2() {this.nextSequence = 0}
268
+ constructor(options = {}) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);
269
+ this.allowBuiltinOverride = options.allowBuiltinOverride === true;
270
+ }
271
+ /**
272
+ * Register one provider.
273
+ *
274
+ * @param contribution - the provider with its origin, transport, and
275
+ * capabilities declared.
276
+ * @param context - who is registering, for a Phase-2 host. Retained as-is;
277
+ * no rule reads it today, and the parameter exists so adding one later is
278
+ * not a signature change for every caller.
279
+ * @throws {SearchRegistryError} on a blank id, a duplicate id, or a host
280
+ * contribution colliding with a builtin without `allowBuiltinOverride`.
281
+ */
282
+ register(contribution, context) {
283
+ const id = contribution.id;
284
+ if (typeof id !== "string" || id.trim().length === 0) {
285
+ throw new SearchRegistryError("a search provider contribution needs a non-blank id");
286
+ }
287
+ const existing = this.entries.get(id);
288
+ let sequence = this.nextSequence;
289
+ if (existing !== void 0) {
290
+ const isPermittedOverride = this.allowBuiltinOverride && contribution.source === "host" && existing.contribution.source === "builtin";
291
+ if (!isPermittedOverride) {
292
+ throw new SearchRegistryError(
293
+ existing.contribution.source === "builtin" && contribution.source === "host" ? `search provider '${id}' is a builtin; overriding it requires allowBuiltinOverride` : `search provider '${id}' is already registered`
294
+ );
295
+ }
296
+ sequence = existing.sequence;
297
+ } else {
298
+ this.nextSequence += 1;
299
+ }
300
+ this.entries.set(id, { contribution, context, sequence });
301
+ }
302
+ /** Whether an id is currently registered. */
303
+ has(id) {
304
+ return this.entries.has(id);
305
+ }
306
+ /** The contribution registered under `id`, if any. */
307
+ get(id) {
308
+ return _optionalChain([this, 'access', _8 => _8.entries, 'access', _9 => _9.get, 'call', _10 => _10(id), 'optionalAccess', _11 => _11.contribution]);
309
+ }
310
+ /**
311
+ * Remove a provider.
312
+ *
313
+ * The Phase-2 host-disconnect hook: when a host goes away its contributions
314
+ * go with it, and the id becomes free to register again.
315
+ *
316
+ * @returns whether something was removed.
317
+ */
318
+ unregister(id) {
319
+ return this.entries.delete(id);
320
+ }
321
+ /**
322
+ * Every registered contribution, in candidate order.
323
+ *
324
+ * `priorityHint` ascending; contributions without a hint come AFTER every
325
+ * hinted one (an absent hint is "no opinion", not "highest priority"); ties
326
+ * keep registration order. The builtin HTTP contributions carry no hints, so
327
+ * today this is exactly registration order.
328
+ */
329
+ list() {
330
+ return [...this.entries.values()].sort((a, b) => {
331
+ const aHint = a.contribution.priorityHint;
332
+ const bHint = b.contribution.priorityHint;
333
+ if (aHint !== bHint) {
334
+ if (aHint === void 0) return 1;
335
+ if (bHint === void 0) return -1;
336
+ return aHint - bHint;
337
+ }
338
+ return a.sequence - b.sequence;
339
+ }).map((entry) => entry.contribution);
340
+ }
341
+ }, _class);
342
+
343
+ // src/search/runtime.ts
344
+ function createSearchRuntime(options = {}) {
345
+ const registry = new SearchProviderRegistry({
346
+ allowBuiltinOverride: options.allowBuiltinOverride === true
347
+ });
348
+ for (const contribution of _nullishCoalesce(options.contributions, () => ( _chunkHL2YSPL7cjs.builtinHttpSearchContributions.call(void 0, )))) {
349
+ registry.register(contribution);
350
+ }
351
+ const orchestrator = new SearchOrchestrator(registry, {
352
+ ...options.policy === void 0 ? {} : { policy: options.policy },
353
+ ...options.onEvent === void 0 ? {} : { onEvent: options.onEvent }
354
+ });
355
+ return {
356
+ search(request) {
357
+ return orchestrator.search(request);
358
+ },
359
+ registerContribution(contribution, context) {
360
+ registry.register(contribution, context);
361
+ },
362
+ unregisterContribution(id) {
363
+ return registry.unregister(id);
364
+ },
365
+ listProviders() {
366
+ return registry.list().map((contribution) => ({
367
+ id: contribution.id,
368
+ source: contribution.source,
369
+ kind: contribution.kind,
370
+ capabilities: { ...contribution.capabilities }
371
+ }));
372
+ }
373
+ };
374
+ }
375
+
376
+
377
+
378
+
379
+
380
+
381
+
382
+
383
+
384
+
385
+
386
+ exports.DEFAULT_NORMALIZED_MAX_RESULTS = DEFAULT_NORMALIZED_MAX_RESULTS; exports.isDirectResultUrl = isDirectResultUrl; exports.normalizedResultLimit = normalizedResultLimit; exports.normalizeSearchResults = normalizeSearchResults; exports.hashSearchQuery = hashSearchQuery; exports.SearchOrchestrator = SearchOrchestrator; exports.SearchRegistryError = SearchRegistryError; exports.SearchProviderRegistry = SearchProviderRegistry; exports.createSearchRuntime = createSearchRuntime;