@apifuse/provider-sdk 2.2.0-beta.61 → 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.
- package/AUTHORING.md +268 -9
- package/CHANGELOG.md +8 -0
- package/README.md +1 -0
- package/bin/apifuse-check.ts +84 -2
- package/bin/apifuse-dev.ts +11 -31
- package/bin/apifuse-migrate-deployment.ts +200 -0
- package/bin/apifuse-pack-check.ts +11 -4
- package/bin/apifuse-pack-types.ts +191 -4
- package/bin/apifuse-record.ts +44 -32
- package/bin/apifuse-test.ts +3 -1
- package/dist/cli/commands.d.ts +1 -1
- package/dist/cli/commands.js +11 -0
- package/dist/cli/deployment-intent.d.ts +178 -0
- package/dist/cli/deployment-intent.js +277 -0
- package/dist/cli/migrate-deployment-intent.d.ts +132 -0
- package/dist/cli/migrate-deployment-intent.js +1552 -0
- package/dist/cli/migrate-provider-shape.d.ts +5 -1
- package/dist/cli/migrate-provider-shape.js +4 -2
- package/dist/cli/resolver-runtime.d.ts +21 -0
- package/dist/cli/resolver-runtime.js +31 -0
- package/dist/define.d.ts +3 -0
- package/dist/define.js +5 -0
- package/dist/dev.d.ts +3 -1
- package/dist/dev.js +6 -1
- package/dist/engine.d.ts +35 -1
- package/dist/engine.js +21 -2
- package/dist/error-resolution.d.ts +1 -0
- package/dist/error-resolution.js +54 -0
- package/dist/errors.d.ts +39 -1
- package/dist/errors.js +50 -0
- package/dist/handle-meta.d.ts +18 -2
- package/dist/handle-meta.js +30 -2
- package/dist/handle.d.ts +33 -12
- package/dist/handle.js +69 -24
- package/dist/i18n/error-messages.d.ts +86 -0
- package/dist/i18n/error-messages.js +192 -0
- package/dist/i18n/index.d.ts +1 -0
- package/dist/i18n/index.js +1 -0
- package/dist/i18n/keys.d.ts +12 -0
- package/dist/i18n/keys.js +76 -5
- package/dist/index.d.ts +10 -2
- package/dist/index.js +9 -1
- package/dist/lint.d.ts +10 -0
- package/dist/lint.js +440 -57
- package/dist/provider.d.ts +7 -5
- package/dist/provider.js +4 -2
- package/dist/runtime/browser-telemetry-binding.d.ts +5 -0
- package/dist/runtime/browser-telemetry-binding.js +83 -0
- package/dist/runtime/browser-telemetry.d.ts +76 -0
- package/dist/runtime/browser-telemetry.js +165 -0
- package/dist/runtime/browser.d.ts +3 -0
- package/dist/runtime/browser.js +208 -47
- package/dist/runtime/cache-telemetry.d.ts +71 -0
- package/dist/runtime/cache-telemetry.js +177 -0
- package/dist/runtime/cache.js +67 -7
- package/dist/runtime/capability-response.d.ts +3 -0
- package/dist/runtime/capability-response.js +56 -0
- package/dist/runtime/capability-telemetry.d.ts +46 -0
- package/dist/runtime/capability-telemetry.js +68 -0
- package/dist/runtime/diagnostic-env.d.ts +3 -0
- package/dist/runtime/diagnostic-env.js +10 -1
- package/dist/runtime/engine-mode.d.ts +74 -0
- package/dist/runtime/engine-mode.js +152 -0
- package/dist/runtime/handle.js +15 -10
- package/dist/runtime/http-telemetry-binding.d.ts +10 -0
- package/dist/runtime/http-telemetry-binding.js +152 -0
- package/dist/runtime/http-telemetry-guard.d.ts +16 -0
- package/dist/runtime/http-telemetry-guard.js +202 -0
- package/dist/runtime/http-telemetry.d.ts +104 -0
- package/dist/runtime/http-telemetry.js +190 -0
- package/dist/runtime/http.d.ts +31 -0
- package/dist/runtime/http.js +356 -174
- package/dist/runtime/instrumentation.js +92 -13
- package/dist/runtime/ocr-telemetry.d.ts +82 -0
- package/dist/runtime/ocr-telemetry.js +192 -0
- package/dist/runtime/ocr.js +30 -8
- package/dist/runtime/request-telemetry.d.ts +2 -0
- package/dist/runtime/request-telemetry.js +2 -1
- package/dist/runtime/resolver-runtime-options.d.ts +14 -0
- package/dist/runtime/resolver-runtime-options.js +33 -0
- package/dist/runtime/resolver-shared.d.ts +3 -2
- package/dist/runtime/resolver-shared.js +4 -4
- package/dist/runtime/resolver-telemetry.d.ts +1 -0
- package/dist/runtime/resolver-telemetry.js +1 -1
- package/dist/runtime/resolver-vendors/browser.d.ts +2 -0
- package/dist/runtime/resolver-vendors/browser.js +46 -0
- package/dist/runtime/resolver-vendors/hosts.d.ts +21 -0
- package/dist/runtime/resolver-vendors/hosts.js +35 -0
- package/dist/runtime/resolver-vendors/hypersolutions.js +2 -2
- package/dist/runtime/resolver-vendors/types.d.ts +5 -4
- package/dist/runtime/resolver.d.ts +4 -1
- package/dist/runtime/resolver.js +46 -13
- package/dist/runtime/state-telemetry.d.ts +79 -0
- package/dist/runtime/state-telemetry.js +194 -0
- package/dist/runtime/state.d.ts +3 -0
- package/dist/runtime/state.js +26 -7
- package/dist/runtime/stealth-cookies.d.ts +5 -1
- package/dist/runtime/stealth-cookies.js +21 -1
- package/dist/runtime/stealth-owned-headers.d.ts +26 -0
- package/dist/runtime/stealth-owned-headers.js +37 -0
- package/dist/runtime/stealth-telemetry.d.ts +92 -0
- package/dist/runtime/stealth-telemetry.js +179 -0
- package/dist/runtime/stealth.d.ts +4 -1
- package/dist/runtime/stealth.js +228 -85
- package/dist/runtime/stt-telemetry.d.ts +77 -0
- package/dist/runtime/stt-telemetry.js +176 -0
- package/dist/runtime/stt.js +15 -6
- package/dist/server/error-stack-frames.d.ts +35 -0
- package/dist/server/error-stack-frames.js +219 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.js +5 -0
- package/dist/server/sdk-version.d.ts +3 -0
- package/dist/server/sdk-version.js +19 -0
- package/dist/server/self-test.js +1 -18
- package/dist/server/sensitive-values.d.ts +1 -1
- package/dist/server/sensitive-values.js +9 -0
- package/dist/server/serve-implementation.d.ts +53 -2
- package/dist/server/serve-implementation.js +369 -123
- package/dist/server/types.d.ts +1 -0
- package/dist/server/types.js +7 -0
- package/dist/stateful/stateful-provider-owner-forwarder.js +22 -0
- package/dist/stateful/stateful-provider-runtime-context.d.ts +3 -0
- package/dist/stateful/stateful-provider-runtime-context.js +1 -0
- package/dist/types.d.ts +94 -1
- package/package.json +6 -1
- package/src/cli/commands.ts +14 -0
- package/src/cli/deployment-intent.ts +364 -0
- package/src/cli/migrate-deployment-intent.ts +1908 -0
- package/src/cli/migrate-provider-shape.ts +10 -4
- package/src/cli/resolver-runtime.ts +72 -0
- package/src/define.ts +13 -0
- package/src/dev.ts +9 -2
- package/src/engine.ts +38 -2
- package/src/error-resolution.ts +58 -0
- package/src/errors.ts +77 -1
- package/src/handle-meta.ts +39 -4
- package/src/handle.ts +121 -38
- package/src/i18n/error-messages.ts +255 -0
- package/src/i18n/index.ts +1 -0
- package/src/i18n/keys.ts +80 -6
- package/src/index.ts +91 -0
- package/src/lint.ts +552 -57
- package/src/provider.ts +20 -0
- package/src/runtime/browser-telemetry-binding.ts +92 -0
- package/src/runtime/browser-telemetry.ts +289 -0
- package/src/runtime/browser.ts +249 -65
- package/src/runtime/cache-telemetry.ts +247 -0
- package/src/runtime/cache.ts +68 -17
- package/src/runtime/capability-response.ts +53 -0
- package/src/runtime/capability-telemetry.ts +101 -0
- package/src/runtime/diagnostic-env.ts +11 -1
- package/src/runtime/engine-mode.ts +233 -0
- package/src/runtime/handle.ts +20 -10
- package/src/runtime/http-telemetry-binding.ts +162 -0
- package/src/runtime/http-telemetry-guard.ts +208 -0
- package/src/runtime/http-telemetry.ts +292 -0
- package/src/runtime/http.ts +457 -204
- package/src/runtime/instrumentation.ts +105 -16
- package/src/runtime/ocr-telemetry.ts +308 -0
- package/src/runtime/ocr.ts +109 -74
- package/src/runtime/request-telemetry.ts +2 -1
- package/src/runtime/resolver-runtime-options.ts +50 -0
- package/src/runtime/resolver-shared.ts +9 -4
- package/src/runtime/resolver-telemetry.ts +1 -1
- package/src/runtime/resolver-vendors/browser.ts +65 -7
- package/src/runtime/resolver-vendors/hosts.ts +43 -0
- package/src/runtime/resolver-vendors/hypersolutions.ts +2 -2
- package/src/runtime/resolver-vendors/types.ts +5 -4
- package/src/runtime/resolver.ts +64 -21
- package/src/runtime/state-telemetry.ts +298 -0
- package/src/runtime/state.ts +46 -45
- package/src/runtime/stealth-cookies.ts +24 -1
- package/src/runtime/stealth-owned-headers.ts +41 -0
- package/src/runtime/stealth-telemetry.ts +304 -0
- package/src/runtime/stealth.ts +355 -150
- package/src/runtime/stt-telemetry.ts +282 -0
- package/src/runtime/stt.ts +93 -71
- package/src/server/error-stack-frames.ts +214 -0
- package/src/server/index.ts +66 -0
- package/src/server/sdk-version.ts +22 -0
- package/src/server/self-test.ts +1 -21
- package/src/server/sensitive-values.ts +14 -0
- package/src/server/serve-implementation.ts +601 -157
- package/src/server/types.ts +7 -0
- package/src/stateful/stateful-provider-owner-forwarder.ts +23 -0
- package/src/stateful/stateful-provider-runtime-context.ts +4 -0
- package/src/types.ts +99 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/approval-override.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/codemod-syntax.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/connection-precedence.ts.txt +0 -10
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-a.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-b.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-barrel.ts.txt +0 -2
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-computed.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-a.ts.txt +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-b.ts.txt +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-barrel.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-catalog.ts.txt +0 -19
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-docs.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-stores.ts.txt +0 -8
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-indirect-config.ts.txt +0 -5
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-nonstatic.ts.txt +0 -4
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-package-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-leaf.ts.txt +0 -10
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-one.ts.txt +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-two.ts.txt +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-one.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-two.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-mixed-index.ts.txt +0 -14
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-registry.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-barrel.ts.txt +0 -2
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-leaf.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/docs-conflict.ts.txt +0 -8
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-hoisted-array-spread.ts.txt +0 -15
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-imported-array-spread.ts.txt +0 -9
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-kebab-operation-id.ts.txt +0 -17
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-map.ts.txt +0 -5
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-mixed-array-spread.ts.txt +0 -24
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-operation.ts.txt +0 -16
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-snake-operation-id.ts.txt +0 -21
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-duplicate-provider.ts.txt +0 -11
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-id-unresolved.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-map.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-one-to-many.ts.txt +0 -18
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-one-to-one.ts.txt +0 -13
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoist-all.ts.txt +0 -31
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoisted-const.ts.txt +0 -11
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/imported-spread.ts.txt +0 -11
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-map.ts.txt +0 -11
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-cast-tail.ts.txt +0 -21
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-ekitan.ts.txt +0 -11
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-override.ts.txt +0 -14
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-en.json +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-ja.json +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-ko.json +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-existing-operation-namespace-en.json +0 -8
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/missing-english-locale.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/no-safety.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/non-literal.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/redundant-approval.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-binding-ambiguous.ts.txt +0 -12
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-imported-other.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-imported.ts.txt +0 -5
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-key-ambiguous.ts.txt +0 -19
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-shorthand.ts.txt +0 -9
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-typed.ts.txt +0 -11
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-unrelated.ts.txt +0 -13
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/safety-conflict.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/stream.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/tool-router-spread.ts.txt +0 -15
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/unparseable.ts.txt +0 -4
- 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([
|
|
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 &&
|
|
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
|
-
|
|
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
|
-
|
|
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: () =>
|
|
369
|
-
|
|
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
|
|
422
|
-
if (!
|
|
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
|
-
|
|
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: () =>
|
|
505
|
-
|
|
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
|
+
}
|
package/dist/runtime/ocr.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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) {
|