@apifuse/provider-sdk 2.2.0-beta.62 → 2.2.0-beta.64

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 (261) hide show
  1. package/AUTHORING.md +367 -9
  2. package/CHANGELOG.md +8 -0
  3. package/LICENSE +21 -0
  4. package/README.md +1 -0
  5. package/bin/apifuse-check.ts +84 -2
  6. package/bin/apifuse-dev.ts +11 -31
  7. package/bin/apifuse-migrate-deployment.ts +200 -0
  8. package/bin/apifuse-pack-check.ts +11 -4
  9. package/bin/apifuse-pack-types.ts +187 -4
  10. package/bin/apifuse-record.ts +44 -32
  11. package/bin/apifuse-submit-check.ts +9 -5
  12. package/bin/apifuse-test.ts +3 -1
  13. package/dist/cli/commands.d.ts +1 -1
  14. package/dist/cli/commands.js +11 -0
  15. package/dist/cli/deployment-intent.d.ts +178 -0
  16. package/dist/cli/deployment-intent.js +277 -0
  17. package/dist/cli/migrate-deployment-intent.d.ts +132 -0
  18. package/dist/cli/migrate-deployment-intent.js +1552 -0
  19. package/dist/cli/migrate-provider-shape.d.ts +5 -1
  20. package/dist/cli/migrate-provider-shape.js +4 -2
  21. package/dist/cli/resolver-runtime.d.ts +21 -0
  22. package/dist/cli/resolver-runtime.js +31 -0
  23. package/dist/define.d.ts +3 -0
  24. package/dist/define.js +5 -0
  25. package/dist/dev.d.ts +3 -1
  26. package/dist/dev.js +6 -1
  27. package/dist/engine.d.ts +35 -1
  28. package/dist/engine.js +21 -2
  29. package/dist/error-resolution.d.ts +1 -0
  30. package/dist/error-resolution.js +54 -0
  31. package/dist/errors.d.ts +39 -1
  32. package/dist/errors.js +50 -0
  33. package/dist/handle-meta.d.ts +36 -1
  34. package/dist/handle-meta.js +16 -0
  35. package/dist/handle.d.ts +23 -5
  36. package/dist/handle.js +54 -8
  37. package/dist/health-scenario.d.ts +38 -0
  38. package/dist/i18n/error-messages.d.ts +86 -0
  39. package/dist/i18n/error-messages.js +192 -0
  40. package/dist/i18n/index.d.ts +1 -0
  41. package/dist/i18n/index.js +1 -0
  42. package/dist/i18n/keys.d.ts +12 -0
  43. package/dist/i18n/keys.js +76 -5
  44. package/dist/index.d.ts +11 -3
  45. package/dist/index.js +9 -1
  46. package/dist/lint.d.ts +15 -0
  47. package/dist/lint.js +469 -82
  48. package/dist/provider.d.ts +6 -6
  49. package/dist/provider.js +3 -3
  50. package/dist/runtime/browser-telemetry-binding.d.ts +5 -0
  51. package/dist/runtime/browser-telemetry-binding.js +83 -0
  52. package/dist/runtime/browser-telemetry.d.ts +76 -0
  53. package/dist/runtime/browser-telemetry.js +165 -0
  54. package/dist/runtime/browser.d.ts +3 -0
  55. package/dist/runtime/browser.js +208 -47
  56. package/dist/runtime/cache-telemetry.d.ts +71 -0
  57. package/dist/runtime/cache-telemetry.js +177 -0
  58. package/dist/runtime/cache.js +67 -7
  59. package/dist/runtime/capability-response.d.ts +3 -0
  60. package/dist/runtime/capability-response.js +56 -0
  61. package/dist/runtime/capability-telemetry.d.ts +46 -0
  62. package/dist/runtime/capability-telemetry.js +68 -0
  63. package/dist/runtime/diagnostic-env.d.ts +3 -0
  64. package/dist/runtime/diagnostic-env.js +10 -1
  65. package/dist/runtime/engine-mode.d.ts +74 -0
  66. package/dist/runtime/engine-mode.js +152 -0
  67. package/dist/runtime/handle.js +9 -1
  68. package/dist/runtime/http-telemetry-guard.d.ts +10 -0
  69. package/dist/runtime/http-telemetry-guard.js +62 -10
  70. package/dist/runtime/http.js +141 -35
  71. package/dist/runtime/instrumentation.js +92 -13
  72. package/dist/runtime/ocr-telemetry.d.ts +82 -0
  73. package/dist/runtime/ocr-telemetry.js +192 -0
  74. package/dist/runtime/ocr.js +35 -8
  75. package/dist/runtime/request-telemetry.d.ts +2 -0
  76. package/dist/runtime/request-telemetry.js +2 -1
  77. package/dist/runtime/resolver-runtime-options.d.ts +14 -0
  78. package/dist/runtime/resolver-runtime-options.js +33 -0
  79. package/dist/runtime/resolver-shared.d.ts +3 -2
  80. package/dist/runtime/resolver-shared.js +4 -4
  81. package/dist/runtime/resolver-telemetry.d.ts +1 -0
  82. package/dist/runtime/resolver-telemetry.js +1 -1
  83. package/dist/runtime/resolver-vendors/browser.d.ts +2 -0
  84. package/dist/runtime/resolver-vendors/browser.js +46 -0
  85. package/dist/runtime/resolver-vendors/hosts.d.ts +21 -0
  86. package/dist/runtime/resolver-vendors/hosts.js +35 -0
  87. package/dist/runtime/resolver-vendors/hypersolutions.js +2 -2
  88. package/dist/runtime/resolver-vendors/types.d.ts +5 -4
  89. package/dist/runtime/resolver.d.ts +4 -1
  90. package/dist/runtime/resolver.js +46 -13
  91. package/dist/runtime/state-telemetry.d.ts +79 -0
  92. package/dist/runtime/state-telemetry.js +194 -0
  93. package/dist/runtime/state.d.ts +3 -0
  94. package/dist/runtime/state.js +26 -7
  95. package/dist/runtime/stealth-cookies.d.ts +5 -1
  96. package/dist/runtime/stealth-cookies.js +21 -1
  97. package/dist/runtime/stealth-owned-headers.d.ts +26 -0
  98. package/dist/runtime/stealth-owned-headers.js +37 -0
  99. package/dist/runtime/stealth-telemetry.d.ts +92 -0
  100. package/dist/runtime/stealth-telemetry.js +179 -0
  101. package/dist/runtime/stealth.d.ts +4 -1
  102. package/dist/runtime/stealth.js +228 -85
  103. package/dist/runtime/stt-telemetry.d.ts +77 -0
  104. package/dist/runtime/stt-telemetry.js +176 -0
  105. package/dist/runtime/stt.js +15 -6
  106. package/dist/runtime-boundary-lint.d.ts +132 -0
  107. package/dist/runtime-boundary-lint.js +586 -0
  108. package/dist/server/error-stack-frames.d.ts +35 -0
  109. package/dist/server/error-stack-frames.js +219 -0
  110. package/dist/server/index.d.ts +7 -0
  111. package/dist/server/index.js +4 -0
  112. package/dist/server/sdk-version.d.ts +3 -0
  113. package/dist/server/sdk-version.js +19 -0
  114. package/dist/server/self-test.js +1 -18
  115. package/dist/server/sensitive-values.d.ts +1 -1
  116. package/dist/server/sensitive-values.js +9 -0
  117. package/dist/server/serve-implementation.d.ts +51 -2
  118. package/dist/server/serve-implementation.js +337 -90
  119. package/dist/server/types.d.ts +1 -0
  120. package/dist/server/types.js +7 -0
  121. package/dist/stateful/stateful-provider-owner-forwarder.js +22 -0
  122. package/dist/stateful/stateful-provider-runtime-context.d.ts +3 -0
  123. package/dist/stateful/stateful-provider-runtime-context.js +1 -0
  124. package/dist/types.d.ts +123 -1
  125. package/dist/typescript-module.d.ts +39 -0
  126. package/dist/typescript-module.js +72 -0
  127. package/package.json +6 -1
  128. package/src/cli/commands.ts +14 -0
  129. package/src/cli/deployment-intent.ts +364 -0
  130. package/src/cli/migrate-deployment-intent.ts +1908 -0
  131. package/src/cli/migrate-provider-shape.ts +10 -4
  132. package/src/cli/resolver-runtime.ts +72 -0
  133. package/src/define.ts +13 -0
  134. package/src/dev.ts +9 -2
  135. package/src/engine.ts +38 -2
  136. package/src/error-resolution.ts +58 -0
  137. package/src/errors.ts +77 -1
  138. package/src/handle-meta.ts +51 -1
  139. package/src/handle.ts +92 -10
  140. package/src/health-scenario.ts +38 -0
  141. package/src/i18n/error-messages.ts +255 -0
  142. package/src/i18n/index.ts +1 -0
  143. package/src/i18n/keys.ts +80 -6
  144. package/src/index.ts +86 -0
  145. package/src/lint.ts +604 -91
  146. package/src/provider.ts +12 -0
  147. package/src/runtime/browser-telemetry-binding.ts +92 -0
  148. package/src/runtime/browser-telemetry.ts +289 -0
  149. package/src/runtime/browser.ts +249 -65
  150. package/src/runtime/cache-telemetry.ts +247 -0
  151. package/src/runtime/cache.ts +68 -17
  152. package/src/runtime/capability-response.ts +53 -0
  153. package/src/runtime/capability-telemetry.ts +101 -0
  154. package/src/runtime/diagnostic-env.ts +11 -1
  155. package/src/runtime/engine-mode.ts +233 -0
  156. package/src/runtime/handle.ts +9 -1
  157. package/src/runtime/http-telemetry-guard.ts +66 -13
  158. package/src/runtime/http.ts +168 -37
  159. package/src/runtime/instrumentation.ts +105 -16
  160. package/src/runtime/ocr-telemetry.ts +308 -0
  161. package/src/runtime/ocr.ts +114 -74
  162. package/src/runtime/request-telemetry.ts +2 -1
  163. package/src/runtime/resolver-runtime-options.ts +50 -0
  164. package/src/runtime/resolver-shared.ts +9 -4
  165. package/src/runtime/resolver-telemetry.ts +1 -1
  166. package/src/runtime/resolver-vendors/browser.ts +65 -7
  167. package/src/runtime/resolver-vendors/hosts.ts +43 -0
  168. package/src/runtime/resolver-vendors/hypersolutions.ts +2 -2
  169. package/src/runtime/resolver-vendors/types.ts +5 -4
  170. package/src/runtime/resolver.ts +64 -21
  171. package/src/runtime/state-telemetry.ts +298 -0
  172. package/src/runtime/state.ts +46 -45
  173. package/src/runtime/stealth-cookies.ts +24 -1
  174. package/src/runtime/stealth-owned-headers.ts +41 -0
  175. package/src/runtime/stealth-telemetry.ts +304 -0
  176. package/src/runtime/stealth.ts +355 -150
  177. package/src/runtime/stt-telemetry.ts +282 -0
  178. package/src/runtime/stt.ts +93 -71
  179. package/src/runtime-boundary-lint.ts +703 -0
  180. package/src/server/error-stack-frames.ts +214 -0
  181. package/src/server/index.ts +53 -0
  182. package/src/server/sdk-version.ts +22 -0
  183. package/src/server/self-test.ts +1 -21
  184. package/src/server/sensitive-values.ts +14 -0
  185. package/src/server/serve-implementation.ts +569 -108
  186. package/src/server/types.ts +7 -0
  187. package/src/stateful/stateful-provider-owner-forwarder.ts +23 -0
  188. package/src/stateful/stateful-provider-runtime-context.ts +4 -0
  189. package/src/types.ts +128 -1
  190. package/src/typescript-module.ts +100 -0
  191. package/src/cli/__tests__/fixtures/migrate-operation-declaration/approval-override.ts.txt +0 -6
  192. package/src/cli/__tests__/fixtures/migrate-operation-declaration/codemod-syntax.ts.txt +0 -3
  193. package/src/cli/__tests__/fixtures/migrate-operation-declaration/connection-precedence.ts.txt +0 -10
  194. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-a.ts.txt +0 -3
  195. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-b.ts.txt +0 -3
  196. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-barrel.ts.txt +0 -2
  197. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-index.ts.txt +0 -3
  198. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-computed.ts.txt +0 -6
  199. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-a.ts.txt +0 -1
  200. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-b.ts.txt +0 -1
  201. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-index.ts.txt +0 -3
  202. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-barrel.ts.txt +0 -7
  203. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-catalog.ts.txt +0 -19
  204. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-docs.ts.txt +0 -6
  205. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-index.ts.txt +0 -3
  206. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-stores.ts.txt +0 -8
  207. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-indirect-config.ts.txt +0 -5
  208. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-nonstatic.ts.txt +0 -4
  209. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-package-index.ts.txt +0 -3
  210. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-index.ts.txt +0 -3
  211. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-leaf.ts.txt +0 -10
  212. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-one.ts.txt +0 -1
  213. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-two.ts.txt +0 -1
  214. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-index.ts.txt +0 -3
  215. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-one.ts.txt +0 -6
  216. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-two.ts.txt +0 -6
  217. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-mixed-index.ts.txt +0 -14
  218. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-registry.ts.txt +0 -3
  219. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-barrel.ts.txt +0 -2
  220. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-index.ts.txt +0 -3
  221. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-leaf.ts.txt +0 -3
  222. package/src/cli/__tests__/fixtures/migrate-operation-declaration/docs-conflict.ts.txt +0 -8
  223. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-hoisted-array-spread.ts.txt +0 -15
  224. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-imported-array-spread.ts.txt +0 -9
  225. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-kebab-operation-id.ts.txt +0 -17
  226. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-map.ts.txt +0 -5
  227. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-mixed-array-spread.ts.txt +0 -24
  228. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-operation.ts.txt +0 -16
  229. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-snake-operation-id.ts.txt +0 -21
  230. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-duplicate-provider.ts.txt +0 -11
  231. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-id-unresolved.ts.txt +0 -7
  232. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-map.ts.txt +0 -3
  233. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-one-to-many.ts.txt +0 -18
  234. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-one-to-one.ts.txt +0 -13
  235. package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoist-all.ts.txt +0 -31
  236. package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoisted-const.ts.txt +0 -11
  237. package/src/cli/__tests__/fixtures/migrate-operation-declaration/imported-spread.ts.txt +0 -11
  238. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-map.ts.txt +0 -11
  239. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-cast-tail.ts.txt +0 -21
  240. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-ekitan.ts.txt +0 -11
  241. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-override.ts.txt +0 -14
  242. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-en.json +0 -1
  243. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-ja.json +0 -1
  244. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-ko.json +0 -1
  245. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-existing-operation-namespace-en.json +0 -8
  246. package/src/cli/__tests__/fixtures/migrate-operation-declaration/missing-english-locale.ts.txt +0 -7
  247. package/src/cli/__tests__/fixtures/migrate-operation-declaration/no-safety.ts.txt +0 -6
  248. package/src/cli/__tests__/fixtures/migrate-operation-declaration/non-literal.ts.txt +0 -7
  249. package/src/cli/__tests__/fixtures/migrate-operation-declaration/redundant-approval.ts.txt +0 -6
  250. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-binding-ambiguous.ts.txt +0 -12
  251. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-imported-other.ts.txt +0 -7
  252. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-imported.ts.txt +0 -5
  253. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-key-ambiguous.ts.txt +0 -19
  254. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-shorthand.ts.txt +0 -9
  255. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-typed.ts.txt +0 -11
  256. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-unrelated.ts.txt +0 -13
  257. package/src/cli/__tests__/fixtures/migrate-operation-declaration/safety-conflict.ts.txt +0 -7
  258. package/src/cli/__tests__/fixtures/migrate-operation-declaration/stream.ts.txt +0 -7
  259. package/src/cli/__tests__/fixtures/migrate-operation-declaration/tool-router-spread.ts.txt +0 -15
  260. package/src/cli/__tests__/fixtures/migrate-operation-declaration/unparseable.ts.txt +0 -4
  261. package/src/cli/__tests__/fixtures/migrate-operation-declaration/verbatim-template.ts.txt +0 -12
@@ -1,9 +1,19 @@
1
+ import { runCapabilitySpan } from "./capability-telemetry.js";
1
2
  import { registerDiagnosticSensitiveValues } from "./diagnostic-redactor.js";
2
3
  import { readableBytes, readableLines, readableTextChunks } from "../stream.js";
3
4
  import { parseHttpRequestInvocation, isSensitiveKey, redactSensitiveError, redactSensitiveText, redactUrlQueryParams, requestOptionsFromHttpInvocation, serializeRequestUrl, } from "./request-options.js";
4
5
  import { createTraceContext, getTraceRecorder, } from "./trace.js";
5
6
  import { RESOLVER_INSTRUMENTATION_METADATA } from "./resolver-shared.js";
6
- const BROWSER_PAGE_METHODS = new Set(["goto", "fill", "click", "type", "waitForSelector"]);
7
+ const BROWSER_PAGE_METHODS = new Set([
8
+ "goto",
9
+ "fill",
10
+ "click",
11
+ "type",
12
+ "waitForSelector",
13
+ "evaluate",
14
+ "content",
15
+ "screenshot",
16
+ ]);
7
17
  const DIAGNOSTIC_BASE_URL = "http://apifuse-instrumentation.invalid";
8
18
  function isThenable(value) {
9
19
  return ((typeof value === "object" || typeof value === "function") &&
@@ -254,9 +264,18 @@ function buildSpanAttributes(namespace, methodName, args, result, error, diagnos
254
264
  if (method) {
255
265
  attributes.method = method;
256
266
  }
257
- if (status !== undefined && (namespace === "http" || namespace === "stealth")) {
267
+ if (status !== undefined &&
268
+ (namespace === "http" || namespace === "stealth" || namespace === "ocr" || namespace === "stt")) {
258
269
  attributes.status = status;
259
270
  }
271
+ if ((namespace === "ocr" || namespace === "stt") && result && typeof result === "object") {
272
+ if ("model" in result && typeof result.model === "string")
273
+ attributes.model = result.model;
274
+ if ("durationMs" in result && typeof result.durationMs === "number")
275
+ attributes.duration_ms = result.durationMs;
276
+ if ("warnings" in result && Array.isArray(result.warnings))
277
+ attributes.warnings = result.warnings.length;
278
+ }
260
279
  if (duration !== undefined) {
261
280
  attributes.duration_ms = duration;
262
281
  }
@@ -359,14 +378,30 @@ function wrapPage(page, trace) {
359
378
  const methodName = String(property);
360
379
  const wrapped = (...args) => {
361
380
  let elapsedMs = 0;
362
- return recorder.runSpan(`browser.page.${methodName}`, async () => {
381
+ const diagnostics = snapshotRequestDiagnostics("browser", methodName, args);
382
+ registerDiagnosticSensitiveValues(trace, diagnostics.sensitiveValues);
383
+ return recorder.runSpan(["evaluate", "content", "screenshot"].includes(methodName)
384
+ ? `browser.${methodName}`
385
+ : `browser.page.${methodName}`, async () => {
363
386
  const startedAt = Date.now();
364
- const result = await Reflect.apply(value, pageTarget, args);
387
+ let result;
388
+ try {
389
+ result = await Reflect.apply(value, pageTarget, args);
390
+ }
391
+ catch (error) {
392
+ throw sanitizeRequestError(error, diagnostics);
393
+ }
365
394
  elapsedMs = Date.now() - startedAt;
366
395
  return result;
367
396
  }, {
368
- onSuccess: () => getBrowserPageAttributes(methodName, args, elapsedMs),
369
- onError: (error) => getBrowserPageAttributes(methodName, args, undefined, error),
397
+ onSuccess: () => ({
398
+ ...getBrowserPageAttributes(methodName, args, elapsedMs),
399
+ ...(diagnostics.traceUrl ? { url: diagnostics.traceUrl } : {}),
400
+ }),
401
+ onError: (error) => ({
402
+ ...getBrowserPageAttributes(methodName, args, undefined, error),
403
+ ...(diagnostics.traceUrl ? { url: diagnostics.traceUrl } : {}),
404
+ }),
370
405
  });
371
406
  };
372
407
  wrappedMethods.set(property, wrapped);
@@ -418,10 +453,14 @@ function wrapStealthSession(session, trace) {
418
453
  });
419
454
  }
420
455
  function wrapNamespace(namespace, target, trace, shouldInstrument) {
421
- const recorder = getTraceRecorder(trace);
422
- if (!recorder) {
456
+ const baseRecorder = getTraceRecorder(trace);
457
+ if (!baseRecorder)
423
458
  return target;
424
- }
459
+ const recorder = namespace === "ocr" || namespace === "stt"
460
+ ? {
461
+ runSpan: (name, fn, options) => runCapabilitySpan(target, () => baseRecorder.runSpan(name, fn, options)),
462
+ }
463
+ : baseRecorder;
425
464
  const wrappedMethods = new Map();
426
465
  const resolverMetadata = namespace === "resolver" ? { target, traceRecorder: recorder } : undefined;
427
466
  return new Proxy(target, {
@@ -488,6 +527,30 @@ function wrapNamespace(namespace, target, trace, shouldInstrument) {
488
527
  wrappedMethods.set(property, wrapped);
489
528
  return wrapped;
490
529
  }
530
+ if (namespace === "browser" && property === "rawPage") {
531
+ if (wrappedMethods.has(property))
532
+ return wrappedMethods.get(property);
533
+ const wrapped = (...args) => recorder.runSpan("browser.rawPage", async () => {
534
+ const page = await Reflect.apply(value, namespaceTarget, args);
535
+ return wrapPage(page, trace);
536
+ });
537
+ wrappedMethods.set(property, wrapped);
538
+ return wrapped;
539
+ }
540
+ if (namespace === "browser" && property === "withIsolatedContext") {
541
+ if (wrappedMethods.has(property))
542
+ return wrappedMethods.get(property);
543
+ const wrapped = (handler, ...args) => recorder.runSpan("browser.withIsolatedContext", async () => {
544
+ if (typeof handler !== "function")
545
+ return Reflect.apply(value, namespaceTarget, [handler, ...args]);
546
+ return Reflect.apply(value, namespaceTarget, [
547
+ (page) => Reflect.apply(handler, undefined, [wrapPage(page, trace)]),
548
+ ...args,
549
+ ]);
550
+ });
551
+ wrappedMethods.set(property, wrapped);
552
+ return wrapped;
553
+ }
491
554
  if (wrappedMethods.has(property)) {
492
555
  return wrappedMethods.get(property);
493
556
  }
@@ -495,14 +558,28 @@ function wrapNamespace(namespace, target, trace, shouldInstrument) {
495
558
  if (namespace === "browser") {
496
559
  const wrapped = (...args) => {
497
560
  let elapsedMs = 0;
561
+ const diagnostics = snapshotRequestDiagnostics("browser", methodName, args);
562
+ registerDiagnosticSensitiveValues(trace, diagnostics.sensitiveValues);
498
563
  return recorder.runSpan(`browser.${methodName}`, async () => {
499
564
  const startedAt = Date.now();
500
- const result = await Reflect.apply(value, namespaceTarget, args);
565
+ let result;
566
+ try {
567
+ result = await Reflect.apply(value, namespaceTarget, args);
568
+ }
569
+ catch (error) {
570
+ throw sanitizeRequestError(error, diagnostics);
571
+ }
501
572
  elapsedMs = Date.now() - startedAt;
502
573
  return result;
503
574
  }, {
504
- onSuccess: () => getBrowserPageAttributes(methodName, args, elapsedMs),
505
- onError: (error) => getBrowserPageAttributes(methodName, args, undefined, error),
575
+ onSuccess: () => ({
576
+ ...getBrowserPageAttributes(methodName, args, elapsedMs),
577
+ ...(diagnostics.traceUrl ? { url: diagnostics.traceUrl } : {}),
578
+ }),
579
+ onError: (error) => ({
580
+ ...getBrowserPageAttributes(methodName, args, undefined, error),
581
+ ...(diagnostics.traceUrl ? { url: diagnostics.traceUrl } : {}),
582
+ }),
506
583
  });
507
584
  };
508
585
  wrappedMethods.set(property, wrapped);
@@ -601,7 +678,9 @@ export function wrapWithInstrumentation(ctx, options = {}) {
601
678
  property === "browser" ||
602
679
  property === "session" ||
603
680
  property === "state" ||
604
- property === "resolver") {
681
+ property === "resolver" ||
682
+ property === "ocr" ||
683
+ property === "stt") {
605
684
  const namespace = property;
606
685
  if (wrappedTargets.has(namespace)) {
607
686
  return wrappedTargets.get(namespace);
@@ -0,0 +1,82 @@
1
+ import type { OcrContext } from "../types.js";
2
+ import { type ClosedEnum, type SpanIndex, type TelemetryContributor } from "./request-telemetry.js";
3
+ export type OcrTelemetryBackend = "cloudflare-workers-ai" | "openai-compatible" | "custom" | "unavailable";
4
+ export type OcrTelemetryEngine = "workers-ai" | "openai-compatible" | "custom";
5
+ export type OcrTelemetryErrorCode = "OCR_UNAVAILABLE" | "UNSUPPORTED_OCR_BACKEND" | "OCR_UPSTREAM_FAILED" | "OCR_INCOMPLETE_RESPONSE" | "transport_network_error" | "transport_timeout" | "other";
6
+ export type OcrTelemetryModel = "gemma-4-26b-a4b-it" | "glm-ocr" | "moondream3.1-9B-A2B" | "kimi-k2.7-code";
7
+ export type OcrTelemetryFinishReason = "stop" | "length" | "content_filter" | "tool_calls" | "function_call" | "error" | "unknown";
8
+ export type OcrTelemetryEvent = {
9
+ backend: OcrTelemetryBackend;
10
+ engine: OcrTelemetryEngine;
11
+ model?: string;
12
+ ms: number;
13
+ status?: number;
14
+ bytesIn?: number;
15
+ bytesOut?: number;
16
+ candidates?: number;
17
+ warnings?: number;
18
+ errorCode?: OcrTelemetryErrorCode;
19
+ diagnostics?: string;
20
+ finishReason?: OcrTelemetryFinishReason;
21
+ };
22
+ export interface OcrTelemetrySink {
23
+ record(event: OcrTelemetryEvent): void;
24
+ markTelemetryFailed?(): void;
25
+ }
26
+ export type OcrTelemetryLogPayload = {
27
+ telemetryFailed?: true;
28
+ diagnostics?: string[];
29
+ backend: OcrTelemetryBackend;
30
+ engine: OcrTelemetryEngine;
31
+ model?: string;
32
+ ms: number;
33
+ status?: number;
34
+ bytesIn: number;
35
+ bytesOut: number;
36
+ candidates: number;
37
+ warnings: number;
38
+ lastErrorCode?: OcrTelemetryErrorCode;
39
+ finishReason?: OcrTelemetryFinishReason;
40
+ samples?: Array<Omit<OcrTelemetryEvent, "backend" | "engine" | "model" | "diagnostics">>;
41
+ samplesDropped?: number;
42
+ };
43
+ export type OcrTelemetryHeaderPayload = {
44
+ backend: ClosedEnum<OcrTelemetryBackend>;
45
+ engine: ClosedEnum<OcrTelemetryEngine>;
46
+ model?: ClosedEnum<OcrTelemetryModel>;
47
+ ms: number;
48
+ status?: number;
49
+ bytesIn: number;
50
+ bytesOut: number;
51
+ candidates: number;
52
+ warnings: number;
53
+ lastErrorCode?: ClosedEnum<OcrTelemetryErrorCode>;
54
+ finishReason?: ClosedEnum<OcrTelemetryFinishReason>;
55
+ samples?: Array<{
56
+ ms: number;
57
+ status?: number;
58
+ bytesIn?: number;
59
+ bytesOut?: number;
60
+ candidates?: number;
61
+ warnings?: number;
62
+ errorCode?: ClosedEnum<OcrTelemetryErrorCode>;
63
+ finishReason?: ClosedEnum<OcrTelemetryFinishReason>;
64
+ }>;
65
+ samplesDropped?: number;
66
+ };
67
+ export declare class OcrTelemetryCollector implements OcrTelemetrySink, TelemetryContributor<OcrTelemetryLogPayload, OcrTelemetryHeaderPayload> {
68
+ #private;
69
+ readonly key: "ocr";
70
+ constructor(options?: {
71
+ redact?: (text: string) => string;
72
+ });
73
+ markTelemetryFailed(): void;
74
+ record(event: OcrTelemetryEvent): void;
75
+ toLogPayload(_spans: SpanIndex): OcrTelemetryLogPayload | undefined;
76
+ toHeaderPayload(log: OcrTelemetryLogPayload): OcrTelemetryHeaderPayload;
77
+ }
78
+ export declare function bindOcrTelemetry(context: OcrContext, sink: OcrTelemetrySink, options?: {
79
+ backend?: OcrTelemetryBackend;
80
+ engine?: OcrTelemetryEngine;
81
+ model?: string;
82
+ }): OcrContext;
@@ -0,0 +1,192 @@
1
+ import { add, capabilityErrorText, capabilityFacts, capabilityMetadata, capabilityText, inputBytes, integer, observeCapability, registerCapabilityInput, } from "./capability-telemetry.js";
2
+ import { closedEnum, } from "./request-telemetry.js";
3
+ const ERROR_CODES = new Set([
4
+ "OCR_UNAVAILABLE",
5
+ "UNSUPPORTED_OCR_BACKEND",
6
+ "OCR_UPSTREAM_FAILED",
7
+ "OCR_INCOMPLETE_RESPONSE",
8
+ "transport_network_error",
9
+ "transport_timeout",
10
+ "other",
11
+ ]);
12
+ const MODELS = new Map([
13
+ ["@cf/google/gemma-4-26b-a4b-it", "gemma-4-26b-a4b-it"],
14
+ ["zai-org/GLM-OCR", "glm-ocr"],
15
+ ["@cf/moondream/moondream3.1-9B-A2B", "moondream3.1-9B-A2B"],
16
+ ["@cf/moonshotai/kimi-k2.7-code", "kimi-k2.7-code"],
17
+ ]);
18
+ function errorCode(error) {
19
+ const code = error && typeof error === "object" && "code" in error ? error.code : undefined;
20
+ return typeof code === "string" && ERROR_CODES.has(code)
21
+ ? code
22
+ : "other";
23
+ }
24
+ function finishReason(value, failed) {
25
+ switch (value) {
26
+ case "stop":
27
+ case "length":
28
+ case "content_filter":
29
+ case "tool_calls":
30
+ case "function_call":
31
+ return value;
32
+ default:
33
+ return value === undefined ? (failed ? "error" : "stop") : "unknown";
34
+ }
35
+ }
36
+ export class OcrTelemetryCollector {
37
+ key = "ocr";
38
+ #redact;
39
+ #samples = [];
40
+ #summary;
41
+ #diagnostics = [];
42
+ #dropped = 0;
43
+ #failed = false;
44
+ constructor(options = {}) {
45
+ this.#redact = options.redact;
46
+ }
47
+ markTelemetryFailed() {
48
+ this.#failed = true;
49
+ this.#summary ??= {
50
+ backend: "custom",
51
+ engine: "custom",
52
+ ms: 0,
53
+ bytesIn: 0,
54
+ bytesOut: 0,
55
+ candidates: 0,
56
+ warnings: 0,
57
+ };
58
+ }
59
+ record(event) {
60
+ const sample = {
61
+ ms: integer(event.ms),
62
+ ...(event.status === undefined ? {} : { status: integer(event.status) }),
63
+ ...(event.bytesIn === undefined ? {} : { bytesIn: integer(event.bytesIn) }),
64
+ ...(event.bytesOut === undefined ? {} : { bytesOut: integer(event.bytesOut) }),
65
+ ...(event.candidates === undefined ? {} : { candidates: integer(event.candidates) }),
66
+ ...(event.warnings === undefined ? {} : { warnings: integer(event.warnings) }),
67
+ ...(event.errorCode ? { errorCode: event.errorCode } : {}),
68
+ ...(event.finishReason ? { finishReason: event.finishReason } : {}),
69
+ ...(event.diagnostics === undefined
70
+ ? {}
71
+ : { diagnostics: capabilityText(event.diagnostics, this.#redact, true) }),
72
+ };
73
+ const prior = this.#summary;
74
+ this.#summary = {
75
+ backend: event.backend,
76
+ engine: event.engine,
77
+ ...(event.model === undefined ? {} : { model: capabilityText(event.model, this.#redact) }),
78
+ ms: add(prior?.ms ?? 0, sample.ms),
79
+ ...(sample.status === undefined ? {} : { status: sample.status }),
80
+ bytesIn: add(prior?.bytesIn ?? 0, sample.bytesIn ?? 0),
81
+ bytesOut: add(prior?.bytesOut ?? 0, sample.bytesOut ?? 0),
82
+ candidates: add(prior?.candidates ?? 0, sample.candidates ?? 0),
83
+ warnings: add(prior?.warnings ?? 0, sample.warnings ?? 0),
84
+ ...(event.errorCode ? { lastErrorCode: event.errorCode } : {}),
85
+ ...(event.finishReason ? { finishReason: event.finishReason } : {}),
86
+ };
87
+ if (this.#samples.length < 24) {
88
+ const { diagnostics, ...closedSample } = sample;
89
+ this.#samples.push(closedSample);
90
+ if (diagnostics !== undefined)
91
+ this.#diagnostics.push(diagnostics);
92
+ }
93
+ else
94
+ this.#dropped = add(this.#dropped, 1);
95
+ }
96
+ toLogPayload(_spans) {
97
+ if (!this.#summary)
98
+ return undefined;
99
+ return {
100
+ ...this.#summary,
101
+ ...(this.#diagnostics.length ? { diagnostics: [...this.#diagnostics] } : {}),
102
+ ...(this.#failed ? { telemetryFailed: true } : {}),
103
+ samples: this.#samples.map((s) => ({ ...s })),
104
+ ...(this.#dropped ? { samplesDropped: this.#dropped } : {}),
105
+ };
106
+ }
107
+ toHeaderPayload(log) {
108
+ return {
109
+ backend: closedEnum(log.backend),
110
+ engine: closedEnum(log.engine),
111
+ ...(log.model && MODELS.has(log.model) ? { model: closedEnum(MODELS.get(log.model)) } : {}),
112
+ ms: log.ms,
113
+ ...(log.status === undefined ? {} : { status: log.status }),
114
+ bytesIn: log.bytesIn,
115
+ bytesOut: log.bytesOut,
116
+ candidates: log.candidates,
117
+ warnings: log.warnings,
118
+ ...(log.lastErrorCode ? { lastErrorCode: closedEnum(log.lastErrorCode) } : {}),
119
+ ...(log.finishReason ? { finishReason: closedEnum(log.finishReason) } : {}),
120
+ ...(log.samples
121
+ ? {
122
+ samples: log.samples.map((s) => ({
123
+ ms: s.ms,
124
+ ...(s.status === undefined ? {} : { status: s.status }),
125
+ ...(s.bytesIn === undefined ? {} : { bytesIn: s.bytesIn }),
126
+ ...(s.bytesOut === undefined ? {} : { bytesOut: s.bytesOut }),
127
+ ...(s.candidates === undefined ? {} : { candidates: s.candidates }),
128
+ ...(s.warnings === undefined ? {} : { warnings: s.warnings }),
129
+ ...(s.errorCode ? { errorCode: closedEnum(s.errorCode) } : {}),
130
+ ...(s.finishReason ? { finishReason: closedEnum(s.finishReason) } : {}),
131
+ })),
132
+ }
133
+ : {}),
134
+ ...(log.samplesDropped ? { samplesDropped: log.samplesDropped } : {}),
135
+ };
136
+ }
137
+ }
138
+ export function bindOcrTelemetry(context, sink, options = {}) {
139
+ const metadata = capabilityMetadata(context);
140
+ const backend = options.backend ?? metadata?.backend ?? "custom";
141
+ const engine = options.engine ?? metadata?.engine ?? "custom";
142
+ const model = options.model ?? metadata?.model;
143
+ async function run(input, operation) {
144
+ const started = performance.now();
145
+ const facts = {};
146
+ observeCapability(sink, () => registerCapabilityInput(input));
147
+ let result;
148
+ try {
149
+ result = await capabilityFacts.run(facts, operation);
150
+ }
151
+ catch (error) {
152
+ observeCapability(sink, () => {
153
+ const status = error &&
154
+ typeof error === "object" &&
155
+ "status" in error &&
156
+ typeof error.status === "number"
157
+ ? error.status
158
+ : undefined;
159
+ return sink.record({
160
+ backend,
161
+ engine,
162
+ model,
163
+ ms: performance.now() - started,
164
+ status: facts.status ?? status,
165
+ bytesIn: inputBytes(input),
166
+ errorCode: errorCode(error),
167
+ finishReason: finishReason(facts.finishReason, true),
168
+ diagnostics: `${capabilityErrorText(error)} ${facts.diagnostics ?? ""}`,
169
+ });
170
+ });
171
+ throw error;
172
+ }
173
+ observeCapability(sink, () => sink.record({
174
+ backend,
175
+ engine,
176
+ model: result.model,
177
+ ms: performance.now() - started,
178
+ status: facts.status,
179
+ bytesIn: inputBytes(input),
180
+ bytesOut: Buffer.byteLength(result.text),
181
+ candidates: result.candidates?.length ?? 0,
182
+ finishReason: finishReason(facts.finishReason, false),
183
+ warnings: result.warnings?.length ?? 0,
184
+ }));
185
+ return result;
186
+ }
187
+ return {
188
+ ...context,
189
+ recognize: (request) => run(request.image, () => context.recognize(request)),
190
+ extractCaptchaText: (image, opts) => run(image, () => context.extractCaptchaText(image, opts)),
191
+ };
192
+ }
@@ -1,5 +1,7 @@
1
- import { readDiagnosticEnv } from "./diagnostic-env.js";
2
1
  import { ProviderError, TransportError } from "../errors.js";
2
+ import { readCapabilityErrorBody } from "./capability-response.js";
3
+ import { captureCapability, registerCapabilityInput, tagCapability, } from "./capability-telemetry.js";
4
+ import { readDiagnosticEnv, registerDiagnosticValue } from "./diagnostic-env.js";
3
5
  import { CLOUDFLARE_ACCOUNT_ID_ENV } from "./stt.js";
4
6
  import { createTimeoutController, isTimeoutLikeError } from "./timeout.js";
5
7
  export { CLOUDFLARE_ACCOUNT_ID_ENV } from "./stt.js";
@@ -39,14 +41,18 @@ function createErrorOcrClient(options) {
39
41
  fix: options.fix,
40
42
  });
41
43
  };
42
- return {
44
+ return tagCapability({
45
+ // Own data property: `bindOcrTelemetry` re-spreads the context, so a
46
+ // getter or prototype member would silently vanish before reaching
47
+ // provider code.
48
+ available: false,
43
49
  async recognize() {
44
50
  return unavailable();
45
51
  },
46
52
  async extractCaptchaText() {
47
53
  return unavailable();
48
54
  },
49
- };
55
+ }, { backend: "unavailable", engine: "custom" });
50
56
  }
51
57
  export function createUnsupportedOcrClient(reason) {
52
58
  return createErrorOcrClient({
@@ -179,6 +185,8 @@ function responseContent(payload, cloudflare, model) {
179
185
  if (!Array.isArray(choices))
180
186
  return undefined;
181
187
  const choice = unknownRecord(choices[0]);
188
+ if (typeof choice?.finish_reason === "string")
189
+ captureCapability({ finishReason: choice.finish_reason });
182
190
  if (typeof choice?.finish_reason === "string" && choice.finish_reason !== "stop") {
183
191
  throw incompleteResponseError(model, choice.finish_reason);
184
192
  }
@@ -233,8 +241,12 @@ function moondreamSseContent(body, model) {
233
241
  terminalFinishReason = chunk.finish_reason;
234
242
  }
235
243
  }
236
- if (finalAnswer)
244
+ if (finalAnswer) {
245
+ captureCapability({ finishReason: "stop" });
237
246
  return finalAnswer;
247
+ }
248
+ if (terminalFinishReason)
249
+ captureCapability({ finishReason: terminalFinishReason });
238
250
  if (terminalFinishReason)
239
251
  throw incompleteResponseError(model, terminalFinishReason);
240
252
  if (firstDecodingFailure)
@@ -266,6 +278,7 @@ function toOcrTransportError(error) {
266
278
  }
267
279
  function createOcrClient(model, recognize) {
268
280
  return {
281
+ available: true,
269
282
  recognize,
270
283
  async extractCaptchaText(image, options = {}) {
271
284
  const result = await recognize({ image, hint: "captcha" });
@@ -285,7 +298,10 @@ function createOcrClient(model, recognize) {
285
298
  export function createCloudflareWorkersAiOcrClient(options) {
286
299
  const model = options.model ?? DEFAULT_CLOUDFLARE_WORKERS_AI_OCR_MODEL;
287
300
  const runFetch = options.fetch ?? fetch;
288
- return createOcrClient(model, async (request) => {
301
+ return tagCapability(createOcrClient(model, async (request) => {
302
+ registerCapabilityInput(request.image);
303
+ registerDiagnosticValue(options.apiToken);
304
+ registerDiagnosticValue(`Bearer ${options.apiToken}`);
289
305
  const timeout = createTimeoutController(request.timeoutMs ?? DEFAULT_OCR_TIMEOUT_MS);
290
306
  try {
291
307
  let response;
@@ -305,7 +321,10 @@ export function createCloudflareWorkersAiOcrClient(options) {
305
321
  catch (error) {
306
322
  throw toOcrTransportError(error);
307
323
  }
324
+ captureCapability({ status: response.status });
308
325
  if (!response.ok) {
326
+ const echoed = await readCapabilityErrorBody(response, timeout.controller.signal);
327
+ captureCapability({ diagnostics: echoed });
309
328
  throw new TransportError("OCR upstream request failed", {
310
329
  code: "OCR_UPSTREAM_FAILED",
311
330
  status: response.status,
@@ -325,12 +344,17 @@ export function createCloudflareWorkersAiOcrClient(options) {
325
344
  finally {
326
345
  timeout.clear();
327
346
  }
328
- });
347
+ }), { backend: "cloudflare-workers-ai", engine: "workers-ai", model });
329
348
  }
330
349
  export function createOpenAiCompatibleOcrClient(options) {
331
350
  const model = options.model;
332
351
  const runFetch = options.fetch ?? fetch;
333
- return createOcrClient(model, async (request) => {
352
+ return tagCapability(createOcrClient(model, async (request) => {
353
+ registerCapabilityInput(request.image);
354
+ if (options.apiKey) {
355
+ registerDiagnosticValue(options.apiKey);
356
+ registerDiagnosticValue(`Bearer ${options.apiKey}`);
357
+ }
334
358
  const headers = { "Content-Type": "application/json" };
335
359
  if (options.apiKey)
336
360
  headers.Authorization = `Bearer ${options.apiKey}`;
@@ -348,7 +372,10 @@ export function createOpenAiCompatibleOcrClient(options) {
348
372
  catch (error) {
349
373
  throw toOcrTransportError(error);
350
374
  }
375
+ captureCapability({ status: response.status });
351
376
  if (!response.ok) {
377
+ const echoed = await readCapabilityErrorBody(response, timeout.controller.signal);
378
+ captureCapability({ diagnostics: echoed });
352
379
  throw new TransportError("OCR upstream request failed", {
353
380
  code: "OCR_UPSTREAM_FAILED",
354
381
  status: response.status,
@@ -366,7 +393,7 @@ export function createOpenAiCompatibleOcrClient(options) {
366
393
  finally {
367
394
  timeout.clear();
368
395
  }
369
- });
396
+ }), { backend: "openai-compatible", engine: "openai-compatible", model });
370
397
  }
371
398
  function cleanCaptchaText(text) {
372
399
  const afterColon = text.slice(text.lastIndexOf(":") + 1).trim();
@@ -45,6 +45,8 @@ export type RequestTelemetryLogPayload = {
45
45
  proxy?: ProxyTelemetryLogPayload;
46
46
  resolver?: ResolverTelemetryLogPayload;
47
47
  } & Partial<Record<Exclude<TelemetryKey, "proxy" | "resolver">, object>>;
48
+ /** @internal */
49
+ export declare const HEADER_PRIORITY: readonly ["proxy", "resolver", "native", "http", "stealth", "browser", "ocr", "stt", "cache", "state"];
48
50
  /**
49
51
  * Bounded structural defence in depth against casts and accidental free text.
50
52
  * Closed-enum brands are erased at runtime; the type-level guard is the contract,
@@ -13,7 +13,8 @@ const MAX_INGESTIBLE_ARRAY_LENGTH = 64;
13
13
  const MAX_INGESTIBLE_OBJECT_KEYS = 32;
14
14
  const MAX_INGESTIBLE_DEPTH = 4;
15
15
  const INGESTIBLE_TOKEN = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,63}$/;
16
- const HEADER_PRIORITY = [
16
+ /** @internal */
17
+ export const HEADER_PRIORITY = [
17
18
  "proxy",
18
19
  "resolver",
19
20
  "native",
@@ -0,0 +1,14 @@
1
+ import type { ProviderCache, ProviderDefinition, ProviderProxyPolicy } from "../types.js";
2
+ import type { ResolverRuntimeOptions } from "./resolver.js";
3
+ import type { ResolverTelemetrySink } from "./resolver-telemetry.js";
4
+ import type { BrowserTelemetrySink } from "./browser-telemetry.js";
5
+ /** Normalize the `proxy` declaration shorthand (`true`/`false`) into the policy object the resolver chain consumes. */
6
+ export declare function resolveNativeProxyPolicy(provider: ProviderDefinition): ProviderProxyPolicy | undefined;
7
+ /**
8
+ * One option set for every SDK-built resolver chain — the server's ctx.resolver and automatic
9
+ * SBSD solve, and the CLI helper contexts — so they share allowed hosts, cache, identity scope,
10
+ * proxy intent, and the telemetry sink. `identityScope` is server-owned; CLI contexts pass none.
11
+ */
12
+ export declare function createResolverRuntimeOptions(provider: ProviderDefinition, cache: ProviderCache, identityScope: string | undefined, proxyPolicy: ProviderProxyPolicy | undefined, proxyClientOptions: Omit<NonNullable<ResolverRuntimeOptions["proxyIntent"]>, "mode" | "userAgent">, stealthProfile: {
13
+ readonly userAgent: string;
14
+ } | undefined, telemetry: ResolverTelemetrySink, browserTelemetry?: BrowserTelemetrySink): ResolverRuntimeOptions;
@@ -0,0 +1,33 @@
1
+ /** Normalize the `proxy` declaration shorthand (`true`/`false`) into the policy object the resolver chain consumes. */
2
+ export function resolveNativeProxyPolicy(provider) {
3
+ if (typeof provider.proxy === "object")
4
+ return provider.proxy;
5
+ if (provider.proxy === true)
6
+ return { mode: "optional" };
7
+ if (provider.proxy === false)
8
+ return { mode: "disabled" };
9
+ return undefined;
10
+ }
11
+ /**
12
+ * One option set for every SDK-built resolver chain — the server's ctx.resolver and automatic
13
+ * SBSD solve, and the CLI helper contexts — so they share allowed hosts, cache, identity scope,
14
+ * proxy intent, and the telemetry sink. `identityScope` is server-owned; CLI contexts pass none.
15
+ */
16
+ export function createResolverRuntimeOptions(provider, cache, identityScope, proxyPolicy, proxyClientOptions, stealthProfile, telemetry, browserTelemetry) {
17
+ return {
18
+ allowedHosts: provider.allowedHosts,
19
+ cache,
20
+ telemetry,
21
+ browserTelemetry,
22
+ ...(identityScope === undefined ? {} : { identityScope }),
23
+ ...(proxyPolicy
24
+ ? {
25
+ proxyIntent: {
26
+ mode: proxyPolicy.mode,
27
+ ...proxyClientOptions,
28
+ ...(stealthProfile ? { userAgent: stealthProfile.userAgent } : {}),
29
+ },
30
+ }
31
+ : {}),
32
+ };
33
+ }
@@ -1,13 +1,14 @@
1
1
  import type { ChallengeSolution, ProviderChallenge, ResolverContext } from "../types.js";
2
2
  import type { TraceRecorder } from "./trace.js";
3
3
  import type { ResolverTelemetrySink } from "./resolver-telemetry.js";
4
- type ResolverTelemetryBinding = (sink: ResolverTelemetrySink) => ResolverContext;
4
+ import type { BrowserTelemetrySink } from "./browser-telemetry.js";
5
+ type ResolverTelemetryBinding = (sink: ResolverTelemetrySink, browserSink?: BrowserTelemetrySink) => ResolverContext;
5
6
  /** Internal contract: reconstruct a chain with a new request sink, without mutating the host chain. */
6
7
  export declare function registerResolverTelemetryBinding(resolver: ResolverContext, bind: ResolverTelemetryBinding): void;
7
8
  /** Preserve reconstruction across SDK wrappers without capturing their current request sink. */
8
9
  export declare function inheritResolverTelemetryBinding(resolver: ResolverContext, wrapper: ResolverContext): void;
9
10
  /** SDK chains expose each vendor invocation; opaque host resolvers expose one custom invocation. */
10
- export declare function bindResolverTelemetry(resolver: ResolverContext, sink: ResolverTelemetrySink | undefined): ResolverContext;
11
+ export declare function bindResolverTelemetry(resolver: ResolverContext, sink: ResolverTelemetrySink | undefined, browserSink?: BrowserTelemetrySink): ResolverContext;
11
12
  export declare const RESOLVER_INSTRUMENTATION_METADATA: unique symbol;
12
13
  /**
13
14
  * Internal solve surface. The instrumentation layer threads its recorder as a