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

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 (243) hide show
  1. package/AUTHORING.md +268 -9
  2. package/CHANGELOG.md +4 -0
  3. package/README.md +1 -0
  4. package/bin/apifuse-check.ts +84 -2
  5. package/bin/apifuse-dev.ts +11 -31
  6. package/bin/apifuse-migrate-deployment.ts +200 -0
  7. package/bin/apifuse-pack-check.ts +11 -4
  8. package/bin/apifuse-pack-types.ts +187 -4
  9. package/bin/apifuse-record.ts +44 -32
  10. package/bin/apifuse-test.ts +3 -1
  11. package/dist/cli/commands.d.ts +1 -1
  12. package/dist/cli/commands.js +11 -0
  13. package/dist/cli/deployment-intent.d.ts +178 -0
  14. package/dist/cli/deployment-intent.js +277 -0
  15. package/dist/cli/migrate-deployment-intent.d.ts +132 -0
  16. package/dist/cli/migrate-deployment-intent.js +1552 -0
  17. package/dist/cli/migrate-provider-shape.d.ts +5 -1
  18. package/dist/cli/migrate-provider-shape.js +4 -2
  19. package/dist/cli/resolver-runtime.d.ts +21 -0
  20. package/dist/cli/resolver-runtime.js +31 -0
  21. package/dist/define.d.ts +3 -0
  22. package/dist/define.js +5 -0
  23. package/dist/dev.d.ts +3 -1
  24. package/dist/dev.js +6 -1
  25. package/dist/engine.d.ts +35 -1
  26. package/dist/engine.js +21 -2
  27. package/dist/error-resolution.d.ts +1 -0
  28. package/dist/error-resolution.js +54 -0
  29. package/dist/errors.d.ts +39 -1
  30. package/dist/errors.js +50 -0
  31. package/dist/i18n/error-messages.d.ts +86 -0
  32. package/dist/i18n/error-messages.js +192 -0
  33. package/dist/i18n/index.d.ts +1 -0
  34. package/dist/i18n/index.js +1 -0
  35. package/dist/i18n/keys.d.ts +12 -0
  36. package/dist/i18n/keys.js +76 -5
  37. package/dist/index.d.ts +7 -1
  38. package/dist/index.js +6 -0
  39. package/dist/lint.d.ts +10 -0
  40. package/dist/lint.js +412 -49
  41. package/dist/provider.d.ts +5 -5
  42. package/dist/provider.js +2 -2
  43. package/dist/runtime/browser-telemetry-binding.d.ts +5 -0
  44. package/dist/runtime/browser-telemetry-binding.js +83 -0
  45. package/dist/runtime/browser-telemetry.d.ts +76 -0
  46. package/dist/runtime/browser-telemetry.js +165 -0
  47. package/dist/runtime/browser.d.ts +3 -0
  48. package/dist/runtime/browser.js +208 -47
  49. package/dist/runtime/cache-telemetry.d.ts +71 -0
  50. package/dist/runtime/cache-telemetry.js +177 -0
  51. package/dist/runtime/cache.js +67 -7
  52. package/dist/runtime/capability-response.d.ts +3 -0
  53. package/dist/runtime/capability-response.js +56 -0
  54. package/dist/runtime/capability-telemetry.d.ts +46 -0
  55. package/dist/runtime/capability-telemetry.js +68 -0
  56. package/dist/runtime/diagnostic-env.d.ts +3 -0
  57. package/dist/runtime/diagnostic-env.js +10 -1
  58. package/dist/runtime/engine-mode.d.ts +74 -0
  59. package/dist/runtime/engine-mode.js +152 -0
  60. package/dist/runtime/http-telemetry-guard.d.ts +10 -0
  61. package/dist/runtime/http-telemetry-guard.js +62 -10
  62. package/dist/runtime/http.js +141 -35
  63. package/dist/runtime/instrumentation.js +92 -13
  64. package/dist/runtime/ocr-telemetry.d.ts +82 -0
  65. package/dist/runtime/ocr-telemetry.js +192 -0
  66. package/dist/runtime/ocr.js +30 -8
  67. package/dist/runtime/request-telemetry.d.ts +2 -0
  68. package/dist/runtime/request-telemetry.js +2 -1
  69. package/dist/runtime/resolver-runtime-options.d.ts +14 -0
  70. package/dist/runtime/resolver-runtime-options.js +33 -0
  71. package/dist/runtime/resolver-shared.d.ts +3 -2
  72. package/dist/runtime/resolver-shared.js +4 -4
  73. package/dist/runtime/resolver-telemetry.d.ts +1 -0
  74. package/dist/runtime/resolver-telemetry.js +1 -1
  75. package/dist/runtime/resolver-vendors/browser.d.ts +2 -0
  76. package/dist/runtime/resolver-vendors/browser.js +46 -0
  77. package/dist/runtime/resolver-vendors/hosts.d.ts +21 -0
  78. package/dist/runtime/resolver-vendors/hosts.js +35 -0
  79. package/dist/runtime/resolver-vendors/hypersolutions.js +2 -2
  80. package/dist/runtime/resolver-vendors/types.d.ts +5 -4
  81. package/dist/runtime/resolver.d.ts +4 -1
  82. package/dist/runtime/resolver.js +46 -13
  83. package/dist/runtime/state-telemetry.d.ts +79 -0
  84. package/dist/runtime/state-telemetry.js +194 -0
  85. package/dist/runtime/state.d.ts +3 -0
  86. package/dist/runtime/state.js +26 -7
  87. package/dist/runtime/stealth-cookies.d.ts +5 -1
  88. package/dist/runtime/stealth-cookies.js +21 -1
  89. package/dist/runtime/stealth-owned-headers.d.ts +26 -0
  90. package/dist/runtime/stealth-owned-headers.js +37 -0
  91. package/dist/runtime/stealth-telemetry.d.ts +92 -0
  92. package/dist/runtime/stealth-telemetry.js +179 -0
  93. package/dist/runtime/stealth.d.ts +4 -1
  94. package/dist/runtime/stealth.js +228 -85
  95. package/dist/runtime/stt-telemetry.d.ts +77 -0
  96. package/dist/runtime/stt-telemetry.js +176 -0
  97. package/dist/runtime/stt.js +15 -6
  98. package/dist/server/error-stack-frames.d.ts +35 -0
  99. package/dist/server/error-stack-frames.js +219 -0
  100. package/dist/server/index.d.ts +7 -0
  101. package/dist/server/index.js +4 -0
  102. package/dist/server/sdk-version.d.ts +3 -0
  103. package/dist/server/sdk-version.js +19 -0
  104. package/dist/server/self-test.js +1 -18
  105. package/dist/server/sensitive-values.d.ts +1 -1
  106. package/dist/server/sensitive-values.js +9 -0
  107. package/dist/server/serve-implementation.d.ts +51 -2
  108. package/dist/server/serve-implementation.js +337 -90
  109. package/dist/server/types.d.ts +1 -0
  110. package/dist/server/types.js +7 -0
  111. package/dist/stateful/stateful-provider-owner-forwarder.js +22 -0
  112. package/dist/stateful/stateful-provider-runtime-context.d.ts +3 -0
  113. package/dist/stateful/stateful-provider-runtime-context.js +1 -0
  114. package/dist/types.d.ts +94 -1
  115. package/package.json +6 -1
  116. package/src/cli/commands.ts +14 -0
  117. package/src/cli/deployment-intent.ts +364 -0
  118. package/src/cli/migrate-deployment-intent.ts +1908 -0
  119. package/src/cli/migrate-provider-shape.ts +10 -4
  120. package/src/cli/resolver-runtime.ts +72 -0
  121. package/src/define.ts +13 -0
  122. package/src/dev.ts +9 -2
  123. package/src/engine.ts +38 -2
  124. package/src/error-resolution.ts +58 -0
  125. package/src/errors.ts +77 -1
  126. package/src/i18n/error-messages.ts +255 -0
  127. package/src/i18n/index.ts +1 -0
  128. package/src/i18n/keys.ts +80 -6
  129. package/src/index.ts +72 -0
  130. package/src/lint.ts +522 -50
  131. package/src/provider.ts +10 -0
  132. package/src/runtime/browser-telemetry-binding.ts +92 -0
  133. package/src/runtime/browser-telemetry.ts +289 -0
  134. package/src/runtime/browser.ts +249 -65
  135. package/src/runtime/cache-telemetry.ts +247 -0
  136. package/src/runtime/cache.ts +68 -17
  137. package/src/runtime/capability-response.ts +53 -0
  138. package/src/runtime/capability-telemetry.ts +101 -0
  139. package/src/runtime/diagnostic-env.ts +11 -1
  140. package/src/runtime/engine-mode.ts +233 -0
  141. package/src/runtime/http-telemetry-guard.ts +66 -13
  142. package/src/runtime/http.ts +168 -37
  143. package/src/runtime/instrumentation.ts +105 -16
  144. package/src/runtime/ocr-telemetry.ts +308 -0
  145. package/src/runtime/ocr.ts +109 -74
  146. package/src/runtime/request-telemetry.ts +2 -1
  147. package/src/runtime/resolver-runtime-options.ts +50 -0
  148. package/src/runtime/resolver-shared.ts +9 -4
  149. package/src/runtime/resolver-telemetry.ts +1 -1
  150. package/src/runtime/resolver-vendors/browser.ts +65 -7
  151. package/src/runtime/resolver-vendors/hosts.ts +43 -0
  152. package/src/runtime/resolver-vendors/hypersolutions.ts +2 -2
  153. package/src/runtime/resolver-vendors/types.ts +5 -4
  154. package/src/runtime/resolver.ts +64 -21
  155. package/src/runtime/state-telemetry.ts +298 -0
  156. package/src/runtime/state.ts +46 -45
  157. package/src/runtime/stealth-cookies.ts +24 -1
  158. package/src/runtime/stealth-owned-headers.ts +41 -0
  159. package/src/runtime/stealth-telemetry.ts +304 -0
  160. package/src/runtime/stealth.ts +355 -150
  161. package/src/runtime/stt-telemetry.ts +282 -0
  162. package/src/runtime/stt.ts +93 -71
  163. package/src/server/error-stack-frames.ts +214 -0
  164. package/src/server/index.ts +53 -0
  165. package/src/server/sdk-version.ts +22 -0
  166. package/src/server/self-test.ts +1 -21
  167. package/src/server/sensitive-values.ts +14 -0
  168. package/src/server/serve-implementation.ts +569 -108
  169. package/src/server/types.ts +7 -0
  170. package/src/stateful/stateful-provider-owner-forwarder.ts +23 -0
  171. package/src/stateful/stateful-provider-runtime-context.ts +4 -0
  172. package/src/types.ts +99 -1
  173. package/src/cli/__tests__/fixtures/migrate-operation-declaration/approval-override.ts.txt +0 -6
  174. package/src/cli/__tests__/fixtures/migrate-operation-declaration/codemod-syntax.ts.txt +0 -3
  175. package/src/cli/__tests__/fixtures/migrate-operation-declaration/connection-precedence.ts.txt +0 -10
  176. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-a.ts.txt +0 -3
  177. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-b.ts.txt +0 -3
  178. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-barrel.ts.txt +0 -2
  179. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-index.ts.txt +0 -3
  180. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-computed.ts.txt +0 -6
  181. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-a.ts.txt +0 -1
  182. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-b.ts.txt +0 -1
  183. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-index.ts.txt +0 -3
  184. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-barrel.ts.txt +0 -7
  185. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-catalog.ts.txt +0 -19
  186. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-docs.ts.txt +0 -6
  187. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-index.ts.txt +0 -3
  188. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-stores.ts.txt +0 -8
  189. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-indirect-config.ts.txt +0 -5
  190. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-nonstatic.ts.txt +0 -4
  191. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-package-index.ts.txt +0 -3
  192. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-index.ts.txt +0 -3
  193. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-leaf.ts.txt +0 -10
  194. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-one.ts.txt +0 -1
  195. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-two.ts.txt +0 -1
  196. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-index.ts.txt +0 -3
  197. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-one.ts.txt +0 -6
  198. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-two.ts.txt +0 -6
  199. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-mixed-index.ts.txt +0 -14
  200. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-registry.ts.txt +0 -3
  201. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-barrel.ts.txt +0 -2
  202. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-index.ts.txt +0 -3
  203. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-leaf.ts.txt +0 -3
  204. package/src/cli/__tests__/fixtures/migrate-operation-declaration/docs-conflict.ts.txt +0 -8
  205. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-hoisted-array-spread.ts.txt +0 -15
  206. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-imported-array-spread.ts.txt +0 -9
  207. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-kebab-operation-id.ts.txt +0 -17
  208. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-map.ts.txt +0 -5
  209. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-mixed-array-spread.ts.txt +0 -24
  210. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-operation.ts.txt +0 -16
  211. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-snake-operation-id.ts.txt +0 -21
  212. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-duplicate-provider.ts.txt +0 -11
  213. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-id-unresolved.ts.txt +0 -7
  214. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-map.ts.txt +0 -3
  215. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-one-to-many.ts.txt +0 -18
  216. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-one-to-one.ts.txt +0 -13
  217. package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoist-all.ts.txt +0 -31
  218. package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoisted-const.ts.txt +0 -11
  219. package/src/cli/__tests__/fixtures/migrate-operation-declaration/imported-spread.ts.txt +0 -11
  220. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-map.ts.txt +0 -11
  221. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-cast-tail.ts.txt +0 -21
  222. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-ekitan.ts.txt +0 -11
  223. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-override.ts.txt +0 -14
  224. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-en.json +0 -1
  225. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-ja.json +0 -1
  226. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-ko.json +0 -1
  227. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-existing-operation-namespace-en.json +0 -8
  228. package/src/cli/__tests__/fixtures/migrate-operation-declaration/missing-english-locale.ts.txt +0 -7
  229. package/src/cli/__tests__/fixtures/migrate-operation-declaration/no-safety.ts.txt +0 -6
  230. package/src/cli/__tests__/fixtures/migrate-operation-declaration/non-literal.ts.txt +0 -7
  231. package/src/cli/__tests__/fixtures/migrate-operation-declaration/redundant-approval.ts.txt +0 -6
  232. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-binding-ambiguous.ts.txt +0 -12
  233. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-imported-other.ts.txt +0 -7
  234. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-imported.ts.txt +0 -5
  235. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-key-ambiguous.ts.txt +0 -19
  236. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-shorthand.ts.txt +0 -9
  237. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-typed.ts.txt +0 -11
  238. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-unrelated.ts.txt +0 -13
  239. package/src/cli/__tests__/fixtures/migrate-operation-declaration/safety-conflict.ts.txt +0 -7
  240. package/src/cli/__tests__/fixtures/migrate-operation-declaration/stream.ts.txt +0 -7
  241. package/src/cli/__tests__/fixtures/migrate-operation-declaration/tool-router-spread.ts.txt +0 -15
  242. package/src/cli/__tests__/fixtures/migrate-operation-declaration/unparseable.ts.txt +0 -4
  243. 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,14 @@ function createErrorOcrClient(options) {
39
41
  fix: options.fix,
40
42
  });
41
43
  };
42
- return {
44
+ return tagCapability({
43
45
  async recognize() {
44
46
  return unavailable();
45
47
  },
46
48
  async extractCaptchaText() {
47
49
  return unavailable();
48
50
  },
49
- };
51
+ }, { backend: "unavailable", engine: "custom" });
50
52
  }
51
53
  export function createUnsupportedOcrClient(reason) {
52
54
  return createErrorOcrClient({
@@ -179,6 +181,8 @@ function responseContent(payload, cloudflare, model) {
179
181
  if (!Array.isArray(choices))
180
182
  return undefined;
181
183
  const choice = unknownRecord(choices[0]);
184
+ if (typeof choice?.finish_reason === "string")
185
+ captureCapability({ finishReason: choice.finish_reason });
182
186
  if (typeof choice?.finish_reason === "string" && choice.finish_reason !== "stop") {
183
187
  throw incompleteResponseError(model, choice.finish_reason);
184
188
  }
@@ -233,8 +237,12 @@ function moondreamSseContent(body, model) {
233
237
  terminalFinishReason = chunk.finish_reason;
234
238
  }
235
239
  }
236
- if (finalAnswer)
240
+ if (finalAnswer) {
241
+ captureCapability({ finishReason: "stop" });
237
242
  return finalAnswer;
243
+ }
244
+ if (terminalFinishReason)
245
+ captureCapability({ finishReason: terminalFinishReason });
238
246
  if (terminalFinishReason)
239
247
  throw incompleteResponseError(model, terminalFinishReason);
240
248
  if (firstDecodingFailure)
@@ -285,7 +293,10 @@ function createOcrClient(model, recognize) {
285
293
  export function createCloudflareWorkersAiOcrClient(options) {
286
294
  const model = options.model ?? DEFAULT_CLOUDFLARE_WORKERS_AI_OCR_MODEL;
287
295
  const runFetch = options.fetch ?? fetch;
288
- return createOcrClient(model, async (request) => {
296
+ return tagCapability(createOcrClient(model, async (request) => {
297
+ registerCapabilityInput(request.image);
298
+ registerDiagnosticValue(options.apiToken);
299
+ registerDiagnosticValue(`Bearer ${options.apiToken}`);
289
300
  const timeout = createTimeoutController(request.timeoutMs ?? DEFAULT_OCR_TIMEOUT_MS);
290
301
  try {
291
302
  let response;
@@ -305,7 +316,10 @@ export function createCloudflareWorkersAiOcrClient(options) {
305
316
  catch (error) {
306
317
  throw toOcrTransportError(error);
307
318
  }
319
+ captureCapability({ status: response.status });
308
320
  if (!response.ok) {
321
+ const echoed = await readCapabilityErrorBody(response, timeout.controller.signal);
322
+ captureCapability({ diagnostics: echoed });
309
323
  throw new TransportError("OCR upstream request failed", {
310
324
  code: "OCR_UPSTREAM_FAILED",
311
325
  status: response.status,
@@ -325,12 +339,17 @@ export function createCloudflareWorkersAiOcrClient(options) {
325
339
  finally {
326
340
  timeout.clear();
327
341
  }
328
- });
342
+ }), { backend: "cloudflare-workers-ai", engine: "workers-ai", model });
329
343
  }
330
344
  export function createOpenAiCompatibleOcrClient(options) {
331
345
  const model = options.model;
332
346
  const runFetch = options.fetch ?? fetch;
333
- return createOcrClient(model, async (request) => {
347
+ return tagCapability(createOcrClient(model, async (request) => {
348
+ registerCapabilityInput(request.image);
349
+ if (options.apiKey) {
350
+ registerDiagnosticValue(options.apiKey);
351
+ registerDiagnosticValue(`Bearer ${options.apiKey}`);
352
+ }
334
353
  const headers = { "Content-Type": "application/json" };
335
354
  if (options.apiKey)
336
355
  headers.Authorization = `Bearer ${options.apiKey}`;
@@ -348,7 +367,10 @@ export function createOpenAiCompatibleOcrClient(options) {
348
367
  catch (error) {
349
368
  throw toOcrTransportError(error);
350
369
  }
370
+ captureCapability({ status: response.status });
351
371
  if (!response.ok) {
372
+ const echoed = await readCapabilityErrorBody(response, timeout.controller.signal);
373
+ captureCapability({ diagnostics: echoed });
352
374
  throw new TransportError("OCR upstream request failed", {
353
375
  code: "OCR_UPSTREAM_FAILED",
354
376
  status: response.status,
@@ -366,7 +388,7 @@ export function createOpenAiCompatibleOcrClient(options) {
366
388
  finally {
367
389
  timeout.clear();
368
390
  }
369
- });
391
+ }), { backend: "openai-compatible", engine: "openai-compatible", model });
370
392
  }
371
393
  function cleanCaptchaText(text) {
372
394
  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
@@ -11,15 +11,15 @@ export function inheritResolverTelemetryBinding(resolver, wrapper) {
11
11
  telemetryBindings.set(wrapper, bind);
12
12
  }
13
13
  /** SDK chains expose each vendor invocation; opaque host resolvers expose one custom invocation. */
14
- export function bindResolverTelemetry(resolver, sink) {
14
+ export function bindResolverTelemetry(resolver, sink, browserSink) {
15
15
  if (!sink)
16
16
  return resolver;
17
17
  const metadata = resolver[RESOLVER_INSTRUMENTATION_METADATA];
18
18
  if (metadata)
19
- return bindResolverTelemetry(metadata.target, sink);
19
+ return bindResolverTelemetry(metadata.target, sink, browserSink);
20
20
  const bind = telemetryBindings.get(resolver);
21
21
  if (bind)
22
- return bind(sink);
22
+ return bind(sink, browserSink);
23
23
  const wrapper = {
24
24
  async solve(challenge, signal, recorder) {
25
25
  const startedAt = Date.now();
@@ -54,7 +54,7 @@ export function bindResolverTelemetry(resolver, sink) {
54
54
  return wrapper;
55
55
  }
56
56
  function createOpaqueResolverTelemetryBinding(resolver) {
57
- return (sink) => bindResolverTelemetry(resolver, sink);
57
+ return (sink, browserSink) => bindResolverTelemetry(resolver, sink, browserSink);
58
58
  }
59
59
  export const RESOLVER_INSTRUMENTATION_METADATA = Symbol.for("@apifuse/provider-sdk/runtime/resolver-instrumentation-metadata");
60
60
  export function createUnsupportedResolverClient(reason) {