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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (261) hide show
  1. package/AUTHORING.md +367 -9
  2. package/CHANGELOG.md +8 -0
  3. package/LICENSE +21 -0
  4. package/README.md +1 -0
  5. package/bin/apifuse-check.ts +84 -2
  6. package/bin/apifuse-dev.ts +11 -31
  7. package/bin/apifuse-migrate-deployment.ts +200 -0
  8. package/bin/apifuse-pack-check.ts +11 -4
  9. package/bin/apifuse-pack-types.ts +187 -4
  10. package/bin/apifuse-record.ts +44 -32
  11. package/bin/apifuse-submit-check.ts +9 -5
  12. package/bin/apifuse-test.ts +3 -1
  13. package/dist/cli/commands.d.ts +1 -1
  14. package/dist/cli/commands.js +11 -0
  15. package/dist/cli/deployment-intent.d.ts +178 -0
  16. package/dist/cli/deployment-intent.js +277 -0
  17. package/dist/cli/migrate-deployment-intent.d.ts +132 -0
  18. package/dist/cli/migrate-deployment-intent.js +1552 -0
  19. package/dist/cli/migrate-provider-shape.d.ts +5 -1
  20. package/dist/cli/migrate-provider-shape.js +4 -2
  21. package/dist/cli/resolver-runtime.d.ts +21 -0
  22. package/dist/cli/resolver-runtime.js +31 -0
  23. package/dist/define.d.ts +3 -0
  24. package/dist/define.js +5 -0
  25. package/dist/dev.d.ts +3 -1
  26. package/dist/dev.js +6 -1
  27. package/dist/engine.d.ts +35 -1
  28. package/dist/engine.js +21 -2
  29. package/dist/error-resolution.d.ts +1 -0
  30. package/dist/error-resolution.js +54 -0
  31. package/dist/errors.d.ts +39 -1
  32. package/dist/errors.js +50 -0
  33. package/dist/handle-meta.d.ts +36 -1
  34. package/dist/handle-meta.js +16 -0
  35. package/dist/handle.d.ts +23 -5
  36. package/dist/handle.js +54 -8
  37. package/dist/health-scenario.d.ts +38 -0
  38. package/dist/i18n/error-messages.d.ts +86 -0
  39. package/dist/i18n/error-messages.js +192 -0
  40. package/dist/i18n/index.d.ts +1 -0
  41. package/dist/i18n/index.js +1 -0
  42. package/dist/i18n/keys.d.ts +12 -0
  43. package/dist/i18n/keys.js +76 -5
  44. package/dist/index.d.ts +11 -3
  45. package/dist/index.js +9 -1
  46. package/dist/lint.d.ts +15 -0
  47. package/dist/lint.js +469 -82
  48. package/dist/provider.d.ts +6 -6
  49. package/dist/provider.js +3 -3
  50. package/dist/runtime/browser-telemetry-binding.d.ts +5 -0
  51. package/dist/runtime/browser-telemetry-binding.js +83 -0
  52. package/dist/runtime/browser-telemetry.d.ts +76 -0
  53. package/dist/runtime/browser-telemetry.js +165 -0
  54. package/dist/runtime/browser.d.ts +3 -0
  55. package/dist/runtime/browser.js +208 -47
  56. package/dist/runtime/cache-telemetry.d.ts +71 -0
  57. package/dist/runtime/cache-telemetry.js +177 -0
  58. package/dist/runtime/cache.js +67 -7
  59. package/dist/runtime/capability-response.d.ts +3 -0
  60. package/dist/runtime/capability-response.js +56 -0
  61. package/dist/runtime/capability-telemetry.d.ts +46 -0
  62. package/dist/runtime/capability-telemetry.js +68 -0
  63. package/dist/runtime/diagnostic-env.d.ts +3 -0
  64. package/dist/runtime/diagnostic-env.js +10 -1
  65. package/dist/runtime/engine-mode.d.ts +74 -0
  66. package/dist/runtime/engine-mode.js +152 -0
  67. package/dist/runtime/handle.js +9 -1
  68. package/dist/runtime/http-telemetry-guard.d.ts +10 -0
  69. package/dist/runtime/http-telemetry-guard.js +62 -10
  70. package/dist/runtime/http.js +141 -35
  71. package/dist/runtime/instrumentation.js +92 -13
  72. package/dist/runtime/ocr-telemetry.d.ts +82 -0
  73. package/dist/runtime/ocr-telemetry.js +192 -0
  74. package/dist/runtime/ocr.js +35 -8
  75. package/dist/runtime/request-telemetry.d.ts +2 -0
  76. package/dist/runtime/request-telemetry.js +2 -1
  77. package/dist/runtime/resolver-runtime-options.d.ts +14 -0
  78. package/dist/runtime/resolver-runtime-options.js +33 -0
  79. package/dist/runtime/resolver-shared.d.ts +3 -2
  80. package/dist/runtime/resolver-shared.js +4 -4
  81. package/dist/runtime/resolver-telemetry.d.ts +1 -0
  82. package/dist/runtime/resolver-telemetry.js +1 -1
  83. package/dist/runtime/resolver-vendors/browser.d.ts +2 -0
  84. package/dist/runtime/resolver-vendors/browser.js +46 -0
  85. package/dist/runtime/resolver-vendors/hosts.d.ts +21 -0
  86. package/dist/runtime/resolver-vendors/hosts.js +35 -0
  87. package/dist/runtime/resolver-vendors/hypersolutions.js +2 -2
  88. package/dist/runtime/resolver-vendors/types.d.ts +5 -4
  89. package/dist/runtime/resolver.d.ts +4 -1
  90. package/dist/runtime/resolver.js +46 -13
  91. package/dist/runtime/state-telemetry.d.ts +79 -0
  92. package/dist/runtime/state-telemetry.js +194 -0
  93. package/dist/runtime/state.d.ts +3 -0
  94. package/dist/runtime/state.js +26 -7
  95. package/dist/runtime/stealth-cookies.d.ts +5 -1
  96. package/dist/runtime/stealth-cookies.js +21 -1
  97. package/dist/runtime/stealth-owned-headers.d.ts +26 -0
  98. package/dist/runtime/stealth-owned-headers.js +37 -0
  99. package/dist/runtime/stealth-telemetry.d.ts +92 -0
  100. package/dist/runtime/stealth-telemetry.js +179 -0
  101. package/dist/runtime/stealth.d.ts +4 -1
  102. package/dist/runtime/stealth.js +228 -85
  103. package/dist/runtime/stt-telemetry.d.ts +77 -0
  104. package/dist/runtime/stt-telemetry.js +176 -0
  105. package/dist/runtime/stt.js +15 -6
  106. package/dist/runtime-boundary-lint.d.ts +132 -0
  107. package/dist/runtime-boundary-lint.js +586 -0
  108. package/dist/server/error-stack-frames.d.ts +35 -0
  109. package/dist/server/error-stack-frames.js +219 -0
  110. package/dist/server/index.d.ts +7 -0
  111. package/dist/server/index.js +4 -0
  112. package/dist/server/sdk-version.d.ts +3 -0
  113. package/dist/server/sdk-version.js +19 -0
  114. package/dist/server/self-test.js +1 -18
  115. package/dist/server/sensitive-values.d.ts +1 -1
  116. package/dist/server/sensitive-values.js +9 -0
  117. package/dist/server/serve-implementation.d.ts +51 -2
  118. package/dist/server/serve-implementation.js +337 -90
  119. package/dist/server/types.d.ts +1 -0
  120. package/dist/server/types.js +7 -0
  121. package/dist/stateful/stateful-provider-owner-forwarder.js +22 -0
  122. package/dist/stateful/stateful-provider-runtime-context.d.ts +3 -0
  123. package/dist/stateful/stateful-provider-runtime-context.js +1 -0
  124. package/dist/types.d.ts +123 -1
  125. package/dist/typescript-module.d.ts +39 -0
  126. package/dist/typescript-module.js +72 -0
  127. package/package.json +6 -1
  128. package/src/cli/commands.ts +14 -0
  129. package/src/cli/deployment-intent.ts +364 -0
  130. package/src/cli/migrate-deployment-intent.ts +1908 -0
  131. package/src/cli/migrate-provider-shape.ts +10 -4
  132. package/src/cli/resolver-runtime.ts +72 -0
  133. package/src/define.ts +13 -0
  134. package/src/dev.ts +9 -2
  135. package/src/engine.ts +38 -2
  136. package/src/error-resolution.ts +58 -0
  137. package/src/errors.ts +77 -1
  138. package/src/handle-meta.ts +51 -1
  139. package/src/handle.ts +92 -10
  140. package/src/health-scenario.ts +38 -0
  141. package/src/i18n/error-messages.ts +255 -0
  142. package/src/i18n/index.ts +1 -0
  143. package/src/i18n/keys.ts +80 -6
  144. package/src/index.ts +86 -0
  145. package/src/lint.ts +604 -91
  146. package/src/provider.ts +12 -0
  147. package/src/runtime/browser-telemetry-binding.ts +92 -0
  148. package/src/runtime/browser-telemetry.ts +289 -0
  149. package/src/runtime/browser.ts +249 -65
  150. package/src/runtime/cache-telemetry.ts +247 -0
  151. package/src/runtime/cache.ts +68 -17
  152. package/src/runtime/capability-response.ts +53 -0
  153. package/src/runtime/capability-telemetry.ts +101 -0
  154. package/src/runtime/diagnostic-env.ts +11 -1
  155. package/src/runtime/engine-mode.ts +233 -0
  156. package/src/runtime/handle.ts +9 -1
  157. package/src/runtime/http-telemetry-guard.ts +66 -13
  158. package/src/runtime/http.ts +168 -37
  159. package/src/runtime/instrumentation.ts +105 -16
  160. package/src/runtime/ocr-telemetry.ts +308 -0
  161. package/src/runtime/ocr.ts +114 -74
  162. package/src/runtime/request-telemetry.ts +2 -1
  163. package/src/runtime/resolver-runtime-options.ts +50 -0
  164. package/src/runtime/resolver-shared.ts +9 -4
  165. package/src/runtime/resolver-telemetry.ts +1 -1
  166. package/src/runtime/resolver-vendors/browser.ts +65 -7
  167. package/src/runtime/resolver-vendors/hosts.ts +43 -0
  168. package/src/runtime/resolver-vendors/hypersolutions.ts +2 -2
  169. package/src/runtime/resolver-vendors/types.ts +5 -4
  170. package/src/runtime/resolver.ts +64 -21
  171. package/src/runtime/state-telemetry.ts +298 -0
  172. package/src/runtime/state.ts +46 -45
  173. package/src/runtime/stealth-cookies.ts +24 -1
  174. package/src/runtime/stealth-owned-headers.ts +41 -0
  175. package/src/runtime/stealth-telemetry.ts +304 -0
  176. package/src/runtime/stealth.ts +355 -150
  177. package/src/runtime/stt-telemetry.ts +282 -0
  178. package/src/runtime/stt.ts +93 -71
  179. package/src/runtime-boundary-lint.ts +703 -0
  180. package/src/server/error-stack-frames.ts +214 -0
  181. package/src/server/index.ts +53 -0
  182. package/src/server/sdk-version.ts +22 -0
  183. package/src/server/self-test.ts +1 -21
  184. package/src/server/sensitive-values.ts +14 -0
  185. package/src/server/serve-implementation.ts +569 -108
  186. package/src/server/types.ts +7 -0
  187. package/src/stateful/stateful-provider-owner-forwarder.ts +23 -0
  188. package/src/stateful/stateful-provider-runtime-context.ts +4 -0
  189. package/src/types.ts +128 -1
  190. package/src/typescript-module.ts +100 -0
  191. package/src/cli/__tests__/fixtures/migrate-operation-declaration/approval-override.ts.txt +0 -6
  192. package/src/cli/__tests__/fixtures/migrate-operation-declaration/codemod-syntax.ts.txt +0 -3
  193. package/src/cli/__tests__/fixtures/migrate-operation-declaration/connection-precedence.ts.txt +0 -10
  194. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-a.ts.txt +0 -3
  195. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-b.ts.txt +0 -3
  196. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-barrel.ts.txt +0 -2
  197. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-index.ts.txt +0 -3
  198. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-computed.ts.txt +0 -6
  199. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-a.ts.txt +0 -1
  200. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-b.ts.txt +0 -1
  201. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-index.ts.txt +0 -3
  202. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-barrel.ts.txt +0 -7
  203. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-catalog.ts.txt +0 -19
  204. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-docs.ts.txt +0 -6
  205. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-index.ts.txt +0 -3
  206. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-stores.ts.txt +0 -8
  207. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-indirect-config.ts.txt +0 -5
  208. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-nonstatic.ts.txt +0 -4
  209. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-package-index.ts.txt +0 -3
  210. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-index.ts.txt +0 -3
  211. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-leaf.ts.txt +0 -10
  212. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-one.ts.txt +0 -1
  213. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-two.ts.txt +0 -1
  214. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-index.ts.txt +0 -3
  215. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-one.ts.txt +0 -6
  216. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-two.ts.txt +0 -6
  217. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-mixed-index.ts.txt +0 -14
  218. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-registry.ts.txt +0 -3
  219. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-barrel.ts.txt +0 -2
  220. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-index.ts.txt +0 -3
  221. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-leaf.ts.txt +0 -3
  222. package/src/cli/__tests__/fixtures/migrate-operation-declaration/docs-conflict.ts.txt +0 -8
  223. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-hoisted-array-spread.ts.txt +0 -15
  224. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-imported-array-spread.ts.txt +0 -9
  225. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-kebab-operation-id.ts.txt +0 -17
  226. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-map.ts.txt +0 -5
  227. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-mixed-array-spread.ts.txt +0 -24
  228. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-operation.ts.txt +0 -16
  229. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-snake-operation-id.ts.txt +0 -21
  230. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-duplicate-provider.ts.txt +0 -11
  231. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-id-unresolved.ts.txt +0 -7
  232. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-map.ts.txt +0 -3
  233. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-one-to-many.ts.txt +0 -18
  234. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-one-to-one.ts.txt +0 -13
  235. package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoist-all.ts.txt +0 -31
  236. package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoisted-const.ts.txt +0 -11
  237. package/src/cli/__tests__/fixtures/migrate-operation-declaration/imported-spread.ts.txt +0 -11
  238. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-map.ts.txt +0 -11
  239. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-cast-tail.ts.txt +0 -21
  240. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-ekitan.ts.txt +0 -11
  241. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-override.ts.txt +0 -14
  242. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-en.json +0 -1
  243. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-ja.json +0 -1
  244. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-ko.json +0 -1
  245. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-existing-operation-namespace-en.json +0 -8
  246. package/src/cli/__tests__/fixtures/migrate-operation-declaration/missing-english-locale.ts.txt +0 -7
  247. package/src/cli/__tests__/fixtures/migrate-operation-declaration/no-safety.ts.txt +0 -6
  248. package/src/cli/__tests__/fixtures/migrate-operation-declaration/non-literal.ts.txt +0 -7
  249. package/src/cli/__tests__/fixtures/migrate-operation-declaration/redundant-approval.ts.txt +0 -6
  250. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-binding-ambiguous.ts.txt +0 -12
  251. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-imported-other.ts.txt +0 -7
  252. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-imported.ts.txt +0 -5
  253. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-key-ambiguous.ts.txt +0 -19
  254. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-shorthand.ts.txt +0 -9
  255. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-typed.ts.txt +0 -11
  256. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-unrelated.ts.txt +0 -13
  257. package/src/cli/__tests__/fixtures/migrate-operation-declaration/safety-conflict.ts.txt +0 -7
  258. package/src/cli/__tests__/fixtures/migrate-operation-declaration/stream.ts.txt +0 -7
  259. package/src/cli/__tests__/fixtures/migrate-operation-declaration/tool-router-spread.ts.txt +0 -15
  260. package/src/cli/__tests__/fixtures/migrate-operation-declaration/unparseable.ts.txt +0 -4
  261. package/src/cli/__tests__/fixtures/migrate-operation-declaration/verbatim-template.ts.txt +0 -12
@@ -0,0 +1,282 @@
1
+ import type { SttContext } from "../types.js";
2
+ import {
3
+ add,
4
+ capabilityErrorText,
5
+ capabilityFacts,
6
+ capabilityMetadata,
7
+ capabilityText,
8
+ inputBytes,
9
+ integer,
10
+ observeCapability,
11
+ registerCapabilityInput,
12
+ } from "./capability-telemetry.js";
13
+ import {
14
+ type ClosedEnum,
15
+ closedEnum,
16
+ type SpanIndex,
17
+ type TelemetryContributor,
18
+ } from "./request-telemetry.js";
19
+ export type SttTelemetryBackend = "cloudflare-workers-ai" | "custom" | "unavailable";
20
+ export type SttTelemetryEngine = "workers-ai" | "custom";
21
+ export type SttTelemetryErrorCode =
22
+ | "STT_UNAVAILABLE"
23
+ | "UNSUPPORTED_STT_BACKEND"
24
+ | "STT_UPSTREAM_FAILED"
25
+ | "STT_AUDIO_TOO_LARGE"
26
+ | "UNSUPPORTED_STT_OPTION"
27
+ | "INVALID_STT_AUDIO"
28
+ | "INVALID_STT_VERIFICATION_CODE_OPTIONS"
29
+ | "NO_CODE_FOUND"
30
+ | "AMBIGUOUS_CODE"
31
+ | "transport_network_error"
32
+ | "transport_timeout"
33
+ | "other";
34
+ export type SttTelemetryModel = "whisper-large-v3-turbo";
35
+ const ERROR_CODES: ReadonlySet<string> = new Set([
36
+ "STT_UNAVAILABLE",
37
+ "UNSUPPORTED_STT_BACKEND",
38
+ "STT_UPSTREAM_FAILED",
39
+ "STT_AUDIO_TOO_LARGE",
40
+ "UNSUPPORTED_STT_OPTION",
41
+ "INVALID_STT_AUDIO",
42
+ "INVALID_STT_VERIFICATION_CODE_OPTIONS",
43
+ "NO_CODE_FOUND",
44
+ "AMBIGUOUS_CODE",
45
+ "transport_network_error",
46
+ "transport_timeout",
47
+ "other",
48
+ ]);
49
+ const MODELS = new Map<string, SttTelemetryModel>([
50
+ ["@cf/openai/whisper-large-v3-turbo", "whisper-large-v3-turbo"],
51
+ ]);
52
+ function errorCode(error: unknown): SttTelemetryErrorCode {
53
+ const code = error && typeof error === "object" && "code" in error ? error.code : undefined;
54
+ return typeof code === "string" && ERROR_CODES.has(code)
55
+ ? (code as SttTelemetryErrorCode)
56
+ : "other";
57
+ }
58
+ export type SttTelemetryEvent = {
59
+ backend: SttTelemetryBackend;
60
+ engine: SttTelemetryEngine;
61
+ model?: string;
62
+ ms: number;
63
+ status?: number;
64
+ audioBytes?: number;
65
+ durationMs?: number;
66
+ usage?: number;
67
+ warnings?: number;
68
+ errorCode?: SttTelemetryErrorCode;
69
+ diagnostics?: string;
70
+ };
71
+ export interface SttTelemetrySink {
72
+ record(event: SttTelemetryEvent): void;
73
+ markTelemetryFailed?(): void;
74
+ }
75
+ export type SttTelemetryLogPayload = {
76
+ telemetryFailed?: true;
77
+ diagnostics?: string[];
78
+ backend: SttTelemetryBackend;
79
+ engine: SttTelemetryEngine;
80
+ model?: string;
81
+ ms: number;
82
+ status?: number;
83
+ audioBytes: number;
84
+ durationMs: number;
85
+ usage: number;
86
+ warnings: number;
87
+ lastErrorCode?: SttTelemetryErrorCode;
88
+
89
+ samples?: Array<Omit<SttTelemetryEvent, "backend" | "engine" | "model" | "diagnostics">>;
90
+ samplesDropped?: number;
91
+ };
92
+ export type SttTelemetryHeaderPayload = {
93
+ backend: ClosedEnum<SttTelemetryBackend>;
94
+ engine: ClosedEnum<SttTelemetryEngine>;
95
+ model?: ClosedEnum<SttTelemetryModel>;
96
+ ms: number;
97
+ status?: number;
98
+ audioBytes: number;
99
+ durationMs: number;
100
+ usage: number;
101
+ warnings: number;
102
+ lastErrorCode?: ClosedEnum<SttTelemetryErrorCode>;
103
+
104
+ samples?: Array<{
105
+ ms: number;
106
+ status?: number;
107
+ audioBytes?: number;
108
+ durationMs?: number;
109
+ usage?: number;
110
+ warnings?: number;
111
+ errorCode?: ClosedEnum<SttTelemetryErrorCode>;
112
+ }>;
113
+ samplesDropped?: number;
114
+ };
115
+ export class SttTelemetryCollector
116
+ implements
117
+ SttTelemetrySink,
118
+ TelemetryContributor<SttTelemetryLogPayload, SttTelemetryHeaderPayload>
119
+ {
120
+ readonly key = "stt" as const;
121
+ readonly #redact?: (text: string) => string;
122
+ #samples: NonNullable<SttTelemetryLogPayload["samples"]> = [];
123
+ #summary: Omit<SttTelemetryLogPayload, "samples" | "samplesDropped"> | undefined;
124
+ #diagnostics: string[] = [];
125
+ #dropped = 0;
126
+ #failed = false;
127
+ constructor(options: { redact?: (text: string) => string } = {}) {
128
+ this.#redact = options.redact;
129
+ }
130
+ markTelemetryFailed(): void {
131
+ this.#failed = true;
132
+ this.#summary ??= {
133
+ backend: "custom",
134
+ engine: "custom",
135
+ ms: 0,
136
+ audioBytes: 0,
137
+ durationMs: 0,
138
+ usage: 0,
139
+ warnings: 0,
140
+ };
141
+ }
142
+ record(event: SttTelemetryEvent): void {
143
+ const sample = {
144
+ ms: integer(event.ms),
145
+ ...(event.status === undefined ? {} : { status: integer(event.status) }),
146
+ ...(event.audioBytes === undefined ? {} : { audioBytes: integer(event.audioBytes) }),
147
+ ...(event.durationMs === undefined ? {} : { durationMs: integer(event.durationMs) }),
148
+ ...(event.usage === undefined ? {} : { usage: integer(event.usage) }),
149
+ ...(event.warnings === undefined ? {} : { warnings: integer(event.warnings) }),
150
+ ...(event.errorCode ? { errorCode: event.errorCode } : {}),
151
+
152
+ ...(event.diagnostics === undefined
153
+ ? {}
154
+ : { diagnostics: capabilityText(event.diagnostics, this.#redact, true) }),
155
+ };
156
+ const prior = this.#summary;
157
+ this.#summary = {
158
+ backend: event.backend,
159
+ engine: event.engine,
160
+ ...(event.model === undefined ? {} : { model: capabilityText(event.model, this.#redact) }),
161
+ ms: add(prior?.ms ?? 0, sample.ms),
162
+ ...(sample.status === undefined ? {} : { status: sample.status }),
163
+ audioBytes: add(prior?.audioBytes ?? 0, sample.audioBytes ?? 0),
164
+ durationMs: add(prior?.durationMs ?? 0, sample.durationMs ?? 0),
165
+ usage: add(prior?.usage ?? 0, sample.usage ?? 0),
166
+ warnings: add(prior?.warnings ?? 0, sample.warnings ?? 0),
167
+ ...(event.errorCode ? { lastErrorCode: event.errorCode } : {}),
168
+ };
169
+ if (this.#samples.length < 24) {
170
+ const { diagnostics, ...closedSample } = sample;
171
+ this.#samples.push(closedSample);
172
+ if (diagnostics !== undefined) this.#diagnostics.push(diagnostics);
173
+ } else this.#dropped = add(this.#dropped, 1);
174
+ }
175
+ toLogPayload(_spans: SpanIndex): SttTelemetryLogPayload | undefined {
176
+ if (!this.#summary) return undefined;
177
+ return {
178
+ ...this.#summary,
179
+ ...(this.#diagnostics.length ? { diagnostics: [...this.#diagnostics] } : {}),
180
+ ...(this.#failed ? { telemetryFailed: true as const } : {}),
181
+ samples: this.#samples.map((s) => ({ ...s })),
182
+ ...(this.#dropped ? { samplesDropped: this.#dropped } : {}),
183
+ };
184
+ }
185
+ toHeaderPayload(log: SttTelemetryLogPayload): SttTelemetryHeaderPayload {
186
+ return {
187
+ backend: closedEnum(log.backend),
188
+ engine: closedEnum(log.engine),
189
+ ...(log.model && MODELS.has(log.model) ? { model: closedEnum(MODELS.get(log.model)!) } : {}),
190
+ ms: log.ms,
191
+ ...(log.status === undefined ? {} : { status: log.status }),
192
+ audioBytes: log.audioBytes,
193
+ durationMs: log.durationMs,
194
+ usage: log.usage,
195
+ warnings: log.warnings,
196
+ ...(log.lastErrorCode ? { lastErrorCode: closedEnum(log.lastErrorCode) } : {}),
197
+
198
+ ...(log.samples
199
+ ? {
200
+ samples: log.samples.map((s) => ({
201
+ ms: s.ms,
202
+ ...(s.status === undefined ? {} : { status: s.status }),
203
+ ...(s.audioBytes === undefined ? {} : { audioBytes: s.audioBytes }),
204
+ ...(s.durationMs === undefined ? {} : { durationMs: s.durationMs }),
205
+ ...(s.usage === undefined ? {} : { usage: s.usage }),
206
+ ...(s.warnings === undefined ? {} : { warnings: s.warnings }),
207
+ ...(s.errorCode ? { errorCode: closedEnum(s.errorCode) } : {}),
208
+ })),
209
+ }
210
+ : {}),
211
+ ...(log.samplesDropped ? { samplesDropped: log.samplesDropped } : {}),
212
+ };
213
+ }
214
+ }
215
+ export function bindSttTelemetry(
216
+ context: SttContext,
217
+ sink: SttTelemetrySink,
218
+ options: { backend?: SttTelemetryBackend; engine?: SttTelemetryEngine; model?: string } = {},
219
+ ): SttContext {
220
+ const metadata = capabilityMetadata(context);
221
+ const backend =
222
+ options.backend ?? (metadata?.backend as SttTelemetryBackend | undefined) ?? "custom";
223
+ const engine = options.engine ?? (metadata?.engine as SttTelemetryEngine | undefined) ?? "custom";
224
+ const model = options.model ?? metadata?.model;
225
+ async function run<
226
+ T extends {
227
+ text: string;
228
+ durationMs?: number;
229
+ usage?: { audioBytes?: number; audioDurationMs?: number };
230
+ warnings?: readonly unknown[];
231
+ },
232
+ >(input: { kind: string; data?: string; url?: string }, operation: () => Promise<T>): Promise<T> {
233
+ const started = performance.now();
234
+ const facts: { status?: number; finishReason?: string; diagnostics?: string } = {};
235
+ observeCapability(sink, () => registerCapabilityInput(input));
236
+ let result: T;
237
+ try {
238
+ result = await capabilityFacts.run(facts, operation);
239
+ } catch (error) {
240
+ observeCapability(sink, () => {
241
+ const status =
242
+ error &&
243
+ typeof error === "object" &&
244
+ "status" in error &&
245
+ typeof error.status === "number"
246
+ ? error.status
247
+ : undefined;
248
+ return sink.record({
249
+ backend,
250
+ engine,
251
+ model,
252
+ ms: performance.now() - started,
253
+ status: facts.status ?? status,
254
+ audioBytes: inputBytes(input),
255
+ errorCode: errorCode(error),
256
+
257
+ diagnostics: `${capabilityErrorText(error)} ${facts.diagnostics ?? ""}`,
258
+ });
259
+ });
260
+ throw error;
261
+ }
262
+ observeCapability(sink, () =>
263
+ sink.record({
264
+ backend,
265
+ engine,
266
+ model: model,
267
+ ms: performance.now() - started,
268
+ status: facts.status,
269
+ audioBytes: result.usage?.audioBytes ?? inputBytes(input),
270
+ durationMs: result.durationMs,
271
+ usage: result.usage?.audioDurationMs,
272
+ warnings: result.warnings?.length ?? 0,
273
+ }),
274
+ );
275
+ return result;
276
+ }
277
+ return {
278
+ ...context,
279
+ transcribe: (request) => run(request.audio, () => context.transcribe(request)),
280
+ extractVerificationCode: (text, opts) => context.extractVerificationCode(text, opts),
281
+ };
282
+ }
@@ -1,4 +1,3 @@
1
- import { readDiagnosticEnv } from "./diagnostic-env.js";
2
1
  import { ProviderError, TransportError, ValidationError } from "../errors.js";
3
2
  import type {
4
3
  Bcp47Locale,
@@ -15,6 +14,13 @@ import type {
15
14
  VerificationCodeCandidateSource,
16
15
  VerificationCodeExtractionResult,
17
16
  } from "../types.js";
17
+ import { readCapabilityErrorBody } from "./capability-response.js";
18
+ import {
19
+ captureCapability,
20
+ registerCapabilityInput,
21
+ tagCapability,
22
+ } from "./capability-telemetry.js";
23
+ import { readDiagnosticEnv, registerDiagnosticValue } from "./diagnostic-env.js";
18
24
  import { createTimeoutController, isTimeoutLikeError } from "./timeout.js";
19
25
 
20
26
  export const APIFUSE__STT__BACKEND_ENV = "APIFUSE__STT__BACKEND";
@@ -50,15 +56,18 @@ function providerError(message: string, options: { code: string; fix?: string })
50
56
  }
51
57
 
52
58
  function createErrorSttClient(options: ErrorSttClientOptions): SttContext {
53
- return {
54
- async transcribe() {
55
- throw providerError(options.message, {
56
- code: options.code,
57
- fix: options.fix,
58
- });
59
+ return tagCapability(
60
+ {
61
+ async transcribe() {
62
+ throw providerError(options.message, {
63
+ code: options.code,
64
+ fix: options.fix,
65
+ });
66
+ },
67
+ extractVerificationCode,
59
68
  },
60
- extractVerificationCode,
61
- };
69
+ { backend: "unavailable", engine: "custom" },
70
+ );
62
71
  }
63
72
 
64
73
  export function createUnsupportedSttClient(reason?: string): SttContext {
@@ -273,72 +282,85 @@ export function createCloudflareWorkersAiSttClient(
273
282
  ): SttContext {
274
283
  const model = options.model ?? DEFAULT_CLOUDFLARE_WORKERS_AI_STT_MODEL;
275
284
  const runFetch = options.fetch ?? fetch;
276
- return {
277
- async transcribe(request) {
278
- const warnings = [];
279
- if (request.initialPrompt && effectivePromptPolicy(request) !== "custom-hint") {
280
- const warning = warnOrThrowUnsupportedOption(
281
- request,
282
- "initialPrompt is honored only when promptPolicy is custom-hint",
283
- );
284
- if (warning) warnings.push(warning);
285
- }
286
- const audioBytes = assertBase64Audio(request.audio, request.maxAudioBytes);
287
- const timeout = createTimeoutController(request.timeoutMs ?? DEFAULT_STT_TIMEOUT_MS);
288
- try {
289
- let response: Response;
290
- try {
291
- response = await runFetch(
292
- `https://api.cloudflare.com/client/v4/accounts/${encodeURIComponent(options.accountId)}/ai/run/${model}`,
293
- {
294
- method: "POST",
295
- headers: {
296
- Authorization: `Bearer ${options.apiToken}`,
297
- "Content-Type": "application/json",
298
- },
299
- body: JSON.stringify(toCloudflareInput(request)),
300
- signal: timeout.controller.signal,
301
- },
285
+ return tagCapability(
286
+ {
287
+ async transcribe(request) {
288
+ registerCapabilityInput(request.audio);
289
+ registerDiagnosticValue(options.apiToken);
290
+ registerDiagnosticValue(`Bearer ${options.apiToken}`);
291
+ const warnings = [];
292
+ if (request.initialPrompt && effectivePromptPolicy(request) !== "custom-hint") {
293
+ const warning = warnOrThrowUnsupportedOption(
294
+ request,
295
+ "initialPrompt is honored only when promptPolicy is custom-hint",
302
296
  );
303
- } catch (error) {
304
- throw toSttTransportError(error);
297
+ if (warning) warnings.push(warning);
305
298
  }
306
- const payload = await response.json().catch(() => undefined);
307
- if (!response.ok) {
308
- throw new TransportError("STT upstream request failed", {
309
- code: "STT_UPSTREAM_FAILED",
310
- status: response.status,
311
- upstreamStatus: response.status,
312
- });
313
- }
314
- const envelope = unknownRecord(payload);
315
- if (envelope?.success === false) {
316
- throw new TransportError("STT upstream returned an error", {
317
- code: "STT_UPSTREAM_FAILED",
318
- status: 502,
319
- });
320
- }
321
- const transcript = toSttTranscript(payload, audioBytes);
322
- const withWarnings =
323
- warnings.length > 0
324
- ? {
325
- ...transcript,
326
- warnings: [...(transcript.warnings ?? []), ...warnings],
327
- }
328
- : transcript;
329
- if (request.mode === "otp" || request.verificationCode) {
330
- return {
331
- ...withWarnings,
332
- verificationCode: extractVerificationCode(withWarnings.text, request.verificationCode),
333
- };
299
+ const audioBytes = assertBase64Audio(request.audio, request.maxAudioBytes);
300
+ const timeout = createTimeoutController(request.timeoutMs ?? DEFAULT_STT_TIMEOUT_MS);
301
+ try {
302
+ let response: Response;
303
+ try {
304
+ response = await runFetch(
305
+ `https://api.cloudflare.com/client/v4/accounts/${encodeURIComponent(options.accountId)}/ai/run/${model}`,
306
+ {
307
+ method: "POST",
308
+ headers: {
309
+ Authorization: `Bearer ${options.apiToken}`,
310
+ "Content-Type": "application/json",
311
+ },
312
+ body: JSON.stringify(toCloudflareInput(request)),
313
+ signal: timeout.controller.signal,
314
+ },
315
+ );
316
+ } catch (error) {
317
+ throw toSttTransportError(error);
318
+ }
319
+ captureCapability({ status: response.status });
320
+ if (!response.ok) {
321
+ const echoed = await readCapabilityErrorBody(response, timeout.controller.signal);
322
+ captureCapability({ diagnostics: echoed });
323
+ throw new TransportError("STT upstream request failed", {
324
+ code: "STT_UPSTREAM_FAILED",
325
+ status: response.status,
326
+ upstreamStatus: response.status,
327
+ });
328
+ }
329
+ const payload = await response.json().catch(() => undefined);
330
+ const envelope = unknownRecord(payload);
331
+ if (envelope?.success === false) {
332
+ captureCapability({ diagnostics: JSON.stringify(payload) });
333
+ throw new TransportError("STT upstream returned an error", {
334
+ code: "STT_UPSTREAM_FAILED",
335
+ status: 502,
336
+ });
337
+ }
338
+ const transcript = toSttTranscript(payload, audioBytes);
339
+ const withWarnings =
340
+ warnings.length > 0
341
+ ? {
342
+ ...transcript,
343
+ warnings: [...(transcript.warnings ?? []), ...warnings],
344
+ }
345
+ : transcript;
346
+ if (request.mode === "otp" || request.verificationCode) {
347
+ return {
348
+ ...withWarnings,
349
+ verificationCode: extractVerificationCode(
350
+ withWarnings.text,
351
+ request.verificationCode,
352
+ ),
353
+ };
354
+ }
355
+ return withWarnings;
356
+ } finally {
357
+ timeout.clear();
334
358
  }
335
- return withWarnings;
336
- } finally {
337
- timeout.clear();
338
- }
359
+ },
360
+ extractVerificationCode,
339
361
  },
340
- extractVerificationCode,
341
- };
362
+ { backend: "cloudflare-workers-ai", engine: "workers-ai", model },
363
+ );
342
364
  }
343
365
 
344
366
  const EN_DIGITS: Record<string, string> = {